From 31db690182d01b3850574c40ccdcaeec5c39e96c Mon Sep 17 00:00:00 2001 From: "David G. Holm" Date: Sat, 28 Apr 2001 02:30:53 +0000 Subject: [PATCH] See ChangeLog entry 2001-04-27 22:30 UTC-0400 David G. Holm --- harbour/ChangeLog | 63 +++ harbour/doc/en/input.txt | 62 ++- harbour/include/hbapigt.h | 9 +- harbour/include/hbinkey.ch | 348 ++++++++++++ harbour/include/inkey.ch | 4 +- harbour/source/rtl/gt_tpl/gt_tpl.c | 7 + harbour/source/rtl/gtapi.c | 5 + harbour/source/rtl/gtcgi/gtcgi.c | 4 + harbour/source/rtl/gtcrs/kbdcrs.c | 4 + harbour/source/rtl/gtdos/gtdos.c | 4 + harbour/source/rtl/gtos2/gtos2.c | 4 + harbour/source/rtl/gtpca/gtpca.c | 5 + harbour/source/rtl/gtsln/kbsln.c | 4 + harbour/source/rtl/gtstd/gtstd.c | 5 + harbour/source/rtl/gtwin/gtwin.c | 272 +--------- harbour/source/rtl/inkey.c | 834 +++++++++++++++++++++++++++-- harbour/tests/inkeytst.prg | 6 +- 17 files changed, 1328 insertions(+), 312 deletions(-) create mode 100644 harbour/include/hbinkey.ch diff --git a/harbour/ChangeLog b/harbour/ChangeLog index c883482ac2..d2647dac3d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,66 @@ +2001-04-27 22:30 UTC-0400 David G. Holm + + * doc/en/input.txt + * include/hbapigt.h + + include/hbinkey.ch + * include/inkey.ch + * source/rtl/gtapi.c + * source/rtl/inkey.c + * source/rtl/gt_tpl/gt_tpl.c + * source/rtl/gtcgi/gtcgi.c + * source/rtl/gtcrs/kbdcrs.c + * source/rtl/gtdos/gtdos.c + * source/rtl/gtos2/gtos2.c + * source/rtl/gtpca/gtpca.c + * source/rtl/gtsln/kbsln.c + * source/rtl/gtstd/gtstd.c + * source/rtl/gtwin/gtwin.c + * tests/inkeytst.prg + + Added a new HB_INKEY_EXTENDED mode that extends the number of + unique keys that Harbour can distinguish between. The first + implementation is for gtwin only, so the gtapi has a new API + function that the inkey.c module uses to determine if the GT + module supports the new HB_INKEY_EXTENDED mode. This way, it + is not necessary to convert all GT drivers to support the new + input mode at the same time. The new GT API function is named + hb_gtExtendedKeySupport() and returns zero if the new mode is + not supported or non-zero if the new extended mode is supported. + * The INKEY() family of functions defaults to the normal Clipper- + compatible key code mode. In order to use the extended code mode, + you either need to set the global input mask to include the new + HB_INKEY_EXTENDED value or include it in the second parameter for + INKEY() and the new optional NEXTKEY() and LASTKEY() parameter. + + A GT driver that supports extended key code mode must *always* use + extended key codes. A new translation function in inkey.c is used + to translate between extended and normal key codes when the new + HB_INKEY_EXTENDED mode is not in use. + + The new hbinkey.ch module defines and documents the new extended + mode key codes, which are not compatible with the normal codes + (with the obvious exception of character codes 0 through 255). + These manifest constants use the HB_ prefix and are also defined + for many duplicate codes (such as HB_K_CTRL_A, HB_ENTER, etc.) + + Extended key codes consist of the PC keyboard scan code and one + or more offset values. If no keyboard modifier was used, then + HB_INKEY_NONE is added. The Alt key adds HB_INKEY_ALT, the Ctrl + key adds HB_INKEY_CTRL, the Shift key adds HB_INKEY_SHIFT, and + enhanced keys (KeyPad+/ and CursorPad keys) add HB_INKEY_ENHANCED. + For example, F1 is scan code 59, so if you just press F1, you get + key code 315, but Alt+F1 gives 443, Ctrl+F1 gives 571, and Shift+ + F1 gives 699. And NumPad+/ gives 1077, 1205, 1333, and 1461. At + this time, the only value that can combine with other values is + HB_INKEY_ENHANCED (i.e., there are no Alt+Ctl combinations, etc.) + + Note: The extended key code set is larger than the normal key code + set. As a result, if you switch between the normal and extended + modes, you need to be aware that some codes get translated into a + zero in normal mode (because there is no corresponding code in + normal mode) and that these codes get removed from the keyboard + input buffer in normal mode and you won't be able to go back and + fetch them later in extended mode. + + In order to allow testing the new extended mode, the inkeytst.prg + module has been extended to interpret the second parameter. If it + is not present, then normal mode is used. If it starts with an "R" + (or "r"), then raw mode is used. Otherwise, extended mode is used. + 2001-04-27 15:00 UTC-0400 David G. Holm * include/achoice.ch diff --git a/harbour/doc/en/input.txt b/harbour/doc/en/input.txt index 1871fa1624..92e07ac594 100644 --- a/harbour/doc/en/input.txt +++ b/harbour/doc/en/input.txt @@ -40,27 +40,49 @@ * type of input event, simply add the various mask names together. * * - * inkey.ch Meaning + * inkey.ch Meaning * - * INKEY_MOVE Mouse motion events are allowed - * INKEY_LDOWN The mouse left click down event is allowed - * INKEY_LUP The mouse left click up event is allowed - * INKEY_RDOWN The mouse right click down event is allowed - * INKEY_RUP The mouse right click up event is allowed - * INKEY_KEYBOARD All keyboard events are allowed - * INKEY_ALL All mouse and keyboard events are allowed + * INKEY_MOVE Mouse motion events are allowed + * INKEY_LDOWN The mouse left click down event is allowed + * INKEY_LUP The mouse left click up event is allowed + * INKEY_RDOWN The mouse right click down event is allowed + * INKEY_RUP The mouse right click up event is allowed + * INKEY_KEYBOARD All keyboard events are allowed + * INKEY_ALL All mouse and keyboard events are allowed + * HB_INKEY_EXTENDED Extended keyboard codes are used. *
* If the parameter is not numeric, it will be treated as if it were set * to hb_set.HB_SET_EVENTMASK. * $RETURNS$ * 0 in case of timeout with no input event, otherwise returns a value - * in the range -39 to 386 for keyboard events or the range 1001 to 1007 + * in the range -47 to 386 for keyboard events or the range 1001 to 1007 * for mouse events. Mouse events and non-printable keyboard events are * represented by the K_ values listed in inkey.ch. Keyboard * event return codes in the range 32 through 127 are equivalent to the * printable ASCII character set. Keyboard event return codes in the * range 128 through 255 are assumed to be printable, but results may - * vary based on hardware and nationality. + * vary based on hardware and nationality. If HB_INKEY_EXTENDED mode is + * used, then the return value for keyboard events ranges from 1 through + * 767 and 1077 through 1491, although not all codes are used. + * + * Extended key codes consist of the PC keyboard scan code and one + * or more offset values. If no keyboard modifier was used, then + * HB_INKEY_NONE is added. The Alt key adds HB_INKEY_ALT, the Ctrl + * key adds HB_INKEY_CTRL, the Shift key adds HB_INKEY_SHIFT, and + * enhanced keys (KeyPad+/ and CursorPad keys) add HB_INKEY_ENHANCED. + * For example, F1 is scan code 59, so if you just press F1, you get + * key code 315, but Alt+F1 gives 443, Ctrl+F1 gives 571, and Shift+ + * F1 gives 699. And NumPad+/ gives 1077, 1205, 1333, and 1461. At + * this time, the only value that can combine with other values is + * HB_INKEY_ENHANCED (i.e., there are no Alt+Ctl combinations, etc.) + * + * Note: The extended key code set is larger than the normal key code + * set. As a result, if you switch between the normal and extended + * modes, you need to be aware that some codes get translated into a + * zero in normal mode (because there is no corresponding code in + * normal mode) and that these codes get removed from the keyboard + * input buffer in normal mode and you won't be able to go back and + * fetch them later in extended mode. * $DESCRIPTION$ * INKEY() can be used to detect input events, such as keypress, mouse * movement, or mouse key clicks (up and/or down). @@ -178,9 +200,12 @@ * $ONELINER$ * Get the next key code in the buffer without extracting it. * $SYNTAX$ - * NEXTKEY() --> nKey + * NEXTKEY( [] ) --> nKey * $ARGUMENTS$ - * None + * nInputMask is an optional integer value composed of one or more + * INKEY_ or HB_INKEY_ constants. The sole purpose of this argument + * is to allow switching between using HB_INKEY_EXTENDED key codes + * and using the normal Clipper-compatible key codes * $RETURNS$ * The value of the next key in the Harbour keyboard buffer. * $DESCRIPTION$ @@ -208,7 +233,8 @@ * $STATUS$ * R * $COMPLIANCE$ - * NEXTKEY() is compliant with CA-Clipper 5.3 + * NEXTKEY() is compliant with CA-Clipper 5.3, but has been extended + * for Harbour. * $FILES$ * Library is rtl * $SEEALSO$ @@ -224,9 +250,12 @@ * $ONELINER$ * Get the last key extracted from the keyboard buffer. * $SYNTAX$ - * LASTKEY() --> nKey + * LASTKEY( [] ) --> nKey * $ARGUMENTS$ - * None + * nInputMask is an optional integer value composed of one or more + * INKEY_ or HB_INKEY_ constants. The sole purpose of this argument + * is to allow switching between using HB_INKEY_EXTENDED key codes + * and using the normal Clipper-compatible key codes * $RETURNS$ * The last key extracted from the keyboard buffer. * $DESCRIPTION$ @@ -247,7 +276,8 @@ * $STATUS$ * R * $COMPLIANCE$ - * LASTKEY() is compliant with CA-Clipper 5.3 + * LASTKEY() is compliant with CA-Clipper 5.3, but has been extended + * for Harbour. * $FILES$ * Library is rtl * $SEEALSO$ diff --git a/harbour/include/hbapigt.h b/harbour/include/hbapigt.h index 04efbed28c..f4e8670418 100644 --- a/harbour/include/hbapigt.h +++ b/harbour/include/hbapigt.h @@ -171,6 +171,7 @@ extern USHORT hb_gtPostExt( void ); extern USHORT hb_gtPreExt( void ); extern USHORT hb_gtSuspend( void ); /* prepare the reminal for shell output */ extern USHORT hb_gtResume( void ); /* resume the terminal after the shell output */ +extern int hb_gtExtendedKeySupport( void ); extern int hb_gtReadKey( HB_inkey_enum eventmask ); extern USHORT hb_gtRectSize( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, USHORT * puiBuffSize ); extern USHORT hb_gtRepChar( USHORT uiRow, USHORT uiCol, BYTE byChar, USHORT uiCount ); @@ -240,6 +241,7 @@ extern BOOL hb_gt_Suspend( void ); /* suspend the terminal before the shell ca extern BOOL hb_gt_Resume( void ); /* resume the terminal after the shell call */ extern void hb_gt_Puts( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE * pbyStr, ULONG ulLen ); extern void hb_gt_PutText( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbySrc ); +extern int hb_gt_ExtendedKeySupport(); extern int hb_gt_ReadKey( HB_inkey_enum eventmask ); extern int hb_gt_RectSize( USHORT rows, USHORT cols ); extern void hb_gt_Replicate( USHORT uiTop, USHORT uiLeft, BYTE byAttr, BYTE byChar, ULONG ulLen ); @@ -262,12 +264,13 @@ extern USHORT hb_gt_VertLine( USHORT uiCol, USHORT uiTop, USHORT uiBottom, BYTE /* Harbour keyboard support functions */ extern int hb_inkey( BOOL bWait, double dSeconds, HB_inkey_enum event_mask ); /* Wait for keyboard input */ -extern int hb_inkeyGet( void ); /* Extract the next key from the Harbour keyboard buffer */ +extern int hb_inkeyGet( HB_inkey_enum event_mask ); /* Extract the next key from the Harbour keyboard buffer */ extern void hb_inkeyPut( int ch ); /* Inserts an inkey code into the keyboard buffer */ -extern int hb_inkeyLast( void ); /* Return the value of the last key that was extracted */ -extern int hb_inkeyNext( void ); /* Return the next key without extracting it */ +extern int hb_inkeyLast( HB_inkey_enum event_mask ); /* Return the value of the last key that was extracted */ +extern int hb_inkeyNext( HB_inkey_enum event_mask ); /* Return the next key without extracting it */ extern void hb_inkeyPoll( void ); /* Poll the console keyboard to stuff the Harbour buffer */ extern void hb_inkeyReset( BOOL allocate ); /* Reset the Harbour keyboard buffer */ +extern int hb_inkeyTranslate( int key, HB_inkey_enum event_make ); /* Translation extended codes to normal codes, if needed */ /* Mouse related declarations */ diff --git a/harbour/include/hbinkey.ch b/harbour/include/hbinkey.ch new file mode 100644 index 0000000000..4641c0a1fc --- /dev/null +++ b/harbour/include/hbinkey.ch @@ -0,0 +1,348 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Header file for INKEY() function + * + * Copyright 2001 David G. Holm + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +/* NOTE: This file is also used by C code. */ + +#ifndef HB_HBINKEY_CH_ +#define HB_HBINKEY_CH_ + +#define HB_INKEY_NONE 256 +#define HB_INKEY_ALT 384 +#define HB_INKEY_CTRL 512 +#define HB_INKEY_SHIFT 640 +#define HB_INKEY_ENHANCED 768 + +#define HB_K_ALT_A 414 +#define HB_K_ALT_B 432 +#define HB_K_ALT_C 430 +#define HB_K_ALT_D 416 +#define HB_K_ALT_E 402 +#define HB_K_ALT_F 417 +#define HB_K_ALT_G 418 +#define HB_K_ALT_H 419 +#define HB_K_ALT_I 407 +#define HB_K_ALT_J 420 +#define HB_K_ALT_K 421 +#define HB_K_ALT_L 422 +#define HB_K_ALT_M 434 +#define HB_K_ALT_N 433 +#define HB_K_ALT_O 408 +#define HB_K_ALT_P 409 +#define HB_K_ALT_Q 400 +#define HB_K_ALT_R 403 +#define HB_K_ALT_S 415 +#define HB_K_ALT_T 404 +#define HB_K_ALT_U 406 +#define HB_K_ALT_V 431 +#define HB_K_ALT_W 401 +#define HB_K_ALT_X 429 +#define HB_K_ALT_Y 405 +#define HB_K_ALT_Z 428 + +#define HB_K_CTRL_A 1 +#define HB_K_CTRL_B 2 +#define HB_K_CTRL_C 3 +#define HB_K_CTRL_D 4 +#define HB_K_CTRL_E 5 +#define HB_K_CTRL_F 6 +#define HB_K_CTRL_G 7 +#define HB_K_CTRL_H 8 +#define HB_K_CTRL_I 9 +#define HB_K_CTRL_J 10 +#define HB_K_CTRL_K 11 +#define HB_K_CTRL_L 12 +#define HB_K_CTRL_M 13 +#define HB_K_CTRL_N 14 +#define HB_K_CTRL_O 15 +#define HB_K_CTRL_P 16 +#define HB_K_CTRL_Q 17 +#define HB_K_CTRL_R 18 +#define HB_K_CTRL_S 19 +#define HB_K_CTRL_T 20 +#define HB_K_CTRL_U 21 +#define HB_K_CTRL_V 22 +#define HB_K_CTRL_W 23 +#define HB_K_CTRL_X 24 +#define HB_K_CTRL_Y 25 +#define HB_K_CTRL_Z 26 +#define HB_K_CTRL_LEFT_SQUARE 27 +#define HB_K_CTRL_BACK_SLASH 28 +#define HB_K_CTRL_RIGHT_SQUARE 29 +#define HB_K_CTRL_HAT 30 +#define HB_K_CTRL_UNDERSCORE 31 + +#define HB_K_SPACE 32 + +#define HB_K_ALT_1 386 +#define HB_K_ALT_2 387 +#define HB_K_ALT_3 388 +#define HB_K_ALT_4 389 +#define HB_K_ALT_5 390 +#define HB_K_ALT_6 391 +#define HB_K_ALT_7 392 +#define HB_K_ALT_8 393 +#define HB_K_ALT_9 394 +#define HB_K_ALT_0 395 +#define HB_K_ALT_EQUAL 397 + +#define HB_K_CTRL_1 514 +#define HB_K_CTRL_2 515 +#define HB_K_CTRL_3 516 +#define HB_K_CTRL_4 517 +#define HB_K_CTRL_5 518 +#define HB_K_CTRL_6 519 +#define HB_K_CTRL_7 520 +#define HB_K_CTRL_8 521 +#define HB_K_CTRL_9 522 +#define HB_K_CTRL_0 523 +#define HB_K_CTRL_COLON 551 +#define HB_K_CTRL_SEMI_COLON 551 +#define HB_K_CTRL_COMMA 563 +#define HB_K_CTRL_PERIOD 564 +#define HB_K_CTRL_SLASH 565 + +#define HB_K_CTRL_MINUS 524 +#define HB_K_CTRL_EQUALS 525 +#define HB_K_CTRL_PLUS 525 +#define HB_K_CTRL_LEFT_CURLY 538 +#define HB_K_CTRL_RIGHT_CURLY 539 + +#define HB_K_BACKSPACE 8 +#define HB_K_ALT_BACKSPACE 398 +#define HB_K_CTRL_BACKSPACE 127 +#define HB_K_SHIFT_BACKSPACE + +#define HB_K_ENTER 13 +#define HB_K_ALT_ENTER 412 +#define HB_K_CTRL_ENTER 10 +#define HB_K_SHIFT_ENTER 668 + +#define HB_K_ESC 27 +#define HB_K_ALT_ESC 385 +#define HB_K_CTRL_ESC 513 +#define HB_K_SHIFT_ESC 641 + +#define HB_K_TAB 9 +#define HB_K_ALT_TAB 399 +#define HB_K_CTRL_TAB 527 +#define HB_K_SHIFT_TAB 655 + +#define HB_K_F1 315 +#define HB_K_F2 316 +#define HB_K_F3 317 +#define HB_K_F4 318 +#define HB_K_F5 319 +#define HB_K_F6 320 +#define HB_K_F7 321 +#define HB_K_F8 322 +#define HB_K_F9 323 +#define HB_K_F10 324 +#define HB_K_F11 343 +#define HB_K_F12 344 + +#define HB_K_ALT_F1 443 +#define HB_K_ALT_F2 444 +#define HB_K_ALT_F3 445 +#define HB_K_ALT_F4 446 +#define HB_K_ALT_F5 447 +#define HB_K_ALT_F6 448 +#define HB_K_ALT_F7 449 +#define HB_K_ALT_F8 450 +#define HB_K_ALT_F9 451 +#define HB_K_ALT_F10 452 +#define HB_K_ALT_F11 471 +#define HB_K_ALT_F12 472 + +#define HB_K_CTRL_F1 571 +#define HB_K_CTRL_F2 572 +#define HB_K_CTRL_F3 573 +#define HB_K_CTRL_F4 574 +#define HB_K_CTRL_F5 575 +#define HB_K_CTRL_F6 576 +#define HB_K_CTRL_F7 577 +#define HB_K_CTRL_F8 578 +#define HB_K_CTRL_F9 579 +#define HB_K_CTRL_F10 580 +#define HB_K_CTRL_F11 599 +#define HB_K_CTRL_F12 600 + +#define HB_K_SHIFT_F1 699 +#define HB_K_SHIFT_F2 700 +#define HB_K_SHIFT_F3 701 +#define HB_K_SHIFT_F4 702 +#define HB_K_SHIFT_F5 703 +#define HB_K_SHIFT_F6 704 +#define HB_K_SHIFT_F7 705 +#define HB_K_SHIFT_F8 706 +#define HB_K_SHIFT_F9 707 +#define HB_K_SHIFT_F10 708 +#define HB_K_SHIFT_F11 727 +#define HB_K_SHIFT_F12 728 + +#define HB_KP_MINUS 330 +#define HB_KP_ALT_MINUS 458 +#define HB_KP_CTRL_MINUS 586 +#define HB_KP_SHIFT_MINUS 714 + +#define HB_KP_PLUS 334 +#define HB_KP_ALT_PLUS 462 +#define HB_KP_CTRL_PLUS 590 +#define HB_KP_SHIFT_PLUS 718 + +#define HB_KP_SLASH 1077 +#define HB_KP_ALT_SLASH 1205 +#define HB_KP_CTRL_SLASH 1333 +#define HB_KP_SHIFT_SLASH 1461 + +#define HB_KP_STAR 311 +#define HB_KP_ALT_STAR 439 +#define HB_KP_CTRL_STAR 567 +#define HB_KP_SHIFT_STAR 695 + +#define HB_KP_ENTER 284 +#define HB_KP_ALT_ENTER 412 +#define HB_KP_CTRL_ENTER 540 +#define HB_KP_SHIFT_ENTER 668 + +#define HB_KP_HOME 327 +#define HB_KP_UP 328 +#define HB_KP_PG_UP 329 +#define HB_KP_LEFT 331 +#define HB_KP_5 332 +#define HB_KP_RIGHT 333 +#define HB_KP_END 335 +#define HB_KP_DOWN 336 +#define HB_KP_PG_DN 337 +#define HB_KP_INS 338 +#define HB_KP_DEL 339 + +#define HB_KP_ALT_HOME 455 +#define HB_KP_ALT_UP 456 +#define HB_KP_ALT_PG_UP 457 +#define HB_KP_ALT_LEFT 459 +#define HB_KP_ALT_5 460 +#define HB_KP_ALT_RIGHT 461 +#define HB_KP_ALT_END 463 +#define HB_KP_ALT_DOWN 463 +#define HB_KP_ALT_PG_DN 465 +#define HB_KP_ALT_INS 466 +#define HB_KP_ALT_DEL 467 + +#define HB_KP_CTRL_HOME 583 +#define HB_KP_CTRL_UP 584 +#define HB_KP_CTRL_PG_UP 585 +#define HB_KP_CTRL_LEFT 587 +#define HB_KP_CTRL_5 588 +#define HB_KP_CTRL_RIGHT 589 +#define HB_KP_CTRL_END 591 +#define HB_KP_CTRL_DOWN 592 +#define HB_KP_CTRL_PG_DN 593 +#define HB_KP_CTRL_INS 594 +#define HB_KP_CTRL_DEL 595 + +#define HB_KP_SHIFT_HOME 711 +#define HB_KP_SHIFT_UP 712 +#define HB_KP_SHIFT_PG_UP 713 +#define HB_KP_SHIFT_LEFT 715 +#define HB_KP_SHIFT_5 716 +#define HB_KP_SHIFT_RIGHT 717 +#define HB_KP_SHIFT_END 719 +#define HB_KP_SHIFT_DOWN 720 +#define HB_KP_SHIFT_PG_DN 721 +#define HB_KP_SHIFT_INS 722 +#define HB_KP_SHIFT_DEL 723 + +#define HB_K_HOME 1095 +#define HB_K_UP 1096 +#define HB_K_PG_UP 1097 +#define HB_K_LEFT 1099 +#define HB_K_RIGHT 1101 +#define HB_K_END 1103 +#define HB_K_DOWN 1104 +#define HB_K_PG_DN 1105 +#define HB_K_INS 1106 +#define HB_K_DEL 1107 + +#define HB_K_ALT_HOME 1223 +#define HB_K_ALT_UP 1224 +#define HB_K_ALT_PG_UP 1225 +#define HB_K_ALT_LEFT 1227 +#define HB_K_ALT_RIGHT 1229 +#define HB_K_ALT_END 1231 +#define HB_K_ALT_DOWN 1231 +#define HB_K_ALT_PG_DN 1233 +#define HB_K_ALT_INS 1234 +#define HB_K_ALT_DEL 1235 + +#define HB_K_CTRL_HOME 1351 +#define HB_K_CTRL_UP 1352 +#define HB_K_CTRL_PG_UP 1353 +#define HB_K_CTRL_LEFT 1355 +#define HB_K_CTRL_RIGHT 1357 +#define HB_K_CTRL_END 1359 +#define HB_K_CTRL_DOWN 1360 +#define HB_K_CTRL_PG_DN 1361 +#define HB_K_CTRL_INS 1362 +#define HB_K_CTRL_DEL 1363 + +#define HB_K_SHIFT_HOME 1479 +#define HB_K_SHIFT_UP 1480 +#define HB_K_SHIFT_PG_UP 1481 +#define HB_K_SHIFT_LEFT 1483 +#define HB_K_SHIFT_RIGHT 1485 +#define HB_K_SHIFT_END 1487 +#define HB_K_SHIFT_DOWN 1488 +#define HB_K_SHIFT_PG_DN 1489 +#define HB_K_SHIFT_INS 1490 +#define HB_K_SHIFT_DEL 1491 + +#endif /* HB_HBINKEY_CH_ */ diff --git a/harbour/include/inkey.ch b/harbour/include/inkey.ch index 5da54306ee..aee8091bff 100644 --- a/harbour/include/inkey.ch +++ b/harbour/include/inkey.ch @@ -67,7 +67,9 @@ #define INKEY_RUP 16 #define INKEY_KEYBOARD 128 #define INKEY_ALL 159 -#define INKEY_RAW 256 /* Harbour extension */ + +#define HB_INKEY_RAW 256 /* Harbour extension */ +#define HB_INKEY_EXTENDED 512 /* Harbour extension */ /* Mouse events */ diff --git a/harbour/source/rtl/gt_tpl/gt_tpl.c b/harbour/source/rtl/gt_tpl/gt_tpl.c index 1008fd3670..dcebfc2edc 100644 --- a/harbour/source/rtl/gt_tpl/gt_tpl.c +++ b/harbour/source/rtl/gt_tpl/gt_tpl.c @@ -57,6 +57,13 @@ void hb_gt_Exit( void ) /* TODO: */ } +int hb_gt_ExtendedKeySupport() +{ + /* TODO: If this GTAPI supports the Harbour extended key + codes, then change the return value from 0 to 1. */ + return 0; +} + int hb_gt_ReadKey( HB_inkey_enum eventmask ) { HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) eventmask)); diff --git a/harbour/source/rtl/gtapi.c b/harbour/source/rtl/gtapi.c index 89e7dcc4ef..bfd3250ceb 100644 --- a/harbour/source/rtl/gtapi.c +++ b/harbour/source/rtl/gtapi.c @@ -125,6 +125,11 @@ void hb_gtExit( void ) hb_xfree( s_pColor ); } +int hb_gtExtendedKeySupport() +{ + return hb_gt_ExtendedKeySupport(); +} + int hb_gtReadKey( HB_inkey_enum eventmask ) { HB_TRACE(HB_TR_DEBUG, ("hb_gtReadKey(%d)", (int) eventmask)); diff --git a/harbour/source/rtl/gtcgi/gtcgi.c b/harbour/source/rtl/gtcgi/gtcgi.c index 341d241fca..594f6754c1 100644 --- a/harbour/source/rtl/gtcgi/gtcgi.c +++ b/harbour/source/rtl/gtcgi/gtcgi.c @@ -94,6 +94,10 @@ static void out_newline( void ) out_stdout( s_szCrLf, s_ulCrLf ); } +int hb_gt_ExtendedKeySupport() +{ + return 0; +} int hb_gt_ReadKey( HB_inkey_enum eventmask ) { HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) eventmask)); diff --git a/harbour/source/rtl/gtcrs/kbdcrs.c b/harbour/source/rtl/gtcrs/kbdcrs.c index ad487df9dc..aeaf063eb5 100644 --- a/harbour/source/rtl/gtcrs/kbdcrs.c +++ b/harbour/source/rtl/gtcrs/kbdcrs.c @@ -237,6 +237,10 @@ void hb_gt_keyboard_Exit( void ) } } +int hb_gt_ExtendedKeySupport() +{ + return 0; +} int hb_gt_ReadKey( HB_inkey_enum eventmask ) { static char key_codes[ HB_MAX_KEYMAP_CHARS + 1 ]; /* buffer for multi-characters keycodes */ diff --git a/harbour/source/rtl/gtdos/gtdos.c b/harbour/source/rtl/gtdos/gtdos.c index 8f1a750e94..6cc54e5db8 100644 --- a/harbour/source/rtl/gtdos/gtdos.c +++ b/harbour/source/rtl/gtdos/gtdos.c @@ -236,6 +236,10 @@ void hb_gt_Exit( void ) #endif } +int hb_gt_ExtendedKeySupport() +{ + return 0; +} int hb_gt_ReadKey( HB_inkey_enum eventmask ) { int ch = 0; diff --git a/harbour/source/rtl/gtos2/gtos2.c b/harbour/source/rtl/gtos2/gtos2.c index 0a2dc34891..10bdaa9e6d 100644 --- a/harbour/source/rtl/gtos2/gtos2.c +++ b/harbour/source/rtl/gtos2/gtos2.c @@ -207,6 +207,10 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) return TRUE; } +int hb_gt_ExtendedKeySupport() +{ + return 0; +} int hb_gt_ReadKey( HB_inkey_enum eventmask ) { diff --git a/harbour/source/rtl/gtpca/gtpca.c b/harbour/source/rtl/gtpca/gtpca.c index 38e5ecd232..f6857a8311 100644 --- a/harbour/source/rtl/gtpca/gtpca.c +++ b/harbour/source/rtl/gtpca/gtpca.c @@ -202,6 +202,11 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) return TRUE; } +int hb_gt_ExtendedKeySupport() +{ + return 0; +} + #ifdef HARBOUR_GCC_OS2 #include "..\..\kbdos2.gcc" #else diff --git a/harbour/source/rtl/gtsln/kbsln.c b/harbour/source/rtl/gtsln/kbsln.c index a760b2b8a7..a333880ded 100644 --- a/harbour/source/rtl/gtsln/kbsln.c +++ b/harbour/source/rtl/gtsln/kbsln.c @@ -254,6 +254,10 @@ int hb_gt_Init_Terminal( int phase ) #undef DO_LOCAL_DEBUG /* #define DO_LOCAL_DEBUG */ +int hb_gt_ExtendedKeySupport() +{ + return 0; +} int hb_gt_ReadKey( HB_inkey_enum eventmask ) { static int InDeadState = FALSE; diff --git a/harbour/source/rtl/gtstd/gtstd.c b/harbour/source/rtl/gtstd/gtstd.c index f878940762..559b2d28ac 100644 --- a/harbour/source/rtl/gtstd/gtstd.c +++ b/harbour/source/rtl/gtstd/gtstd.c @@ -109,6 +109,11 @@ void hb_gt_Exit( void ) #endif } +int hb_gt_ExtendedKeySupport() +{ + return 0; +} + int hb_gt_ReadKey( HB_inkey_enum eventmask ) { int ch; diff --git a/harbour/source/rtl/gtwin/gtwin.c b/harbour/source/rtl/gtwin/gtwin.c index ccf541899c..cdb0a8b3d1 100644 --- a/harbour/source/rtl/gtwin/gtwin.c +++ b/harbour/source/rtl/gtwin/gtwin.c @@ -62,10 +62,11 @@ #define HB_OS_WIN_32_USED -#include "hbapigt.h" -#include "hbset.h" /* For Ctrl+Break handling */ -#include "hbvm.h" /* For Ctrl+Break handling */ -#include "inkey.ch" +#include +#include /* For Ctrl+Break handling */ +#include /* For Ctrl+Break handling */ +#include +#include #if defined(__IBMCPP__) #undef WORD /* 2 bytes unsigned */ @@ -277,69 +278,7 @@ static int StdFnKeys( WORD wKey, BOOL bEnhanced ) { int ch; /* Normal function key */ - if( wKey == 53 && bEnhanced ) ch = '/'; /* Num Pad / */ - else switch( wKey ) - { - case 1: /* Esc */ - ch = K_ESC; - break; - case 28: /* Num Pad Enter */ - ch = K_ENTER; - break; - case 59: /* F1 */ - ch = K_F1; - break; - case 60: /* F2 */ - case 61: /* F3 */ - case 62: /* F4 */ - case 63: /* F5 */ - case 64: /* F6 */ - case 65: /* F7 */ - case 66: /* F8 */ - case 67: /* F9 */ - case 68: /* F10 */ - ch = 59 - wKey; - break; - case 71: /* Home */ - ch = K_HOME; - break; - case 79: /* End */ - ch = K_END; - break; - case 73: /* Page Up */ - ch = K_PGUP; - break; - case 81: /* Page Down */ - ch = K_PGDN; - break; - case 72: /* Up */ - ch = K_UP; - break; - case 75: /* Left */ - ch = K_LEFT; - break; - case 77: /* Right */ - ch = K_RIGHT; - break; - case 76: /* Num Pad 5 */ - ch = 332; - break; - case 80: /* Down */ - ch = K_DOWN; - break; - case 82: /* Ins */ - ch = K_INS; - break; - case 83: /* Del */ - ch = K_DEL; - break; - case 87: /* F11 */ - case 88: /* F12 */ - ch = 47 - wKey; - break; - default: - ch = wKey; - } + ch = wKey + HB_INKEY_NONE; return ch; } @@ -364,6 +303,11 @@ static int IgnoreKeyCodes( int wKey ) return ignore; } +int hb_gt_ExtendedKeySupport() +{ + return 1; +} + int hb_gt_ReadKey( HB_inkey_enum eventmask ) { int ch = 0, extended = 0; @@ -449,8 +393,7 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) fprintf( stdout, "0" ); #endif if( ( ( ch == 0 || ch == -32 || ch == -16 ) && ( dwState & ( SHIFT_PRESSED | LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED ) ) ) - || ( ( dwState & ( ENHANCED_KEY | LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED ) ) - && ! ( ( dwState & ( RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED ) ) == ( RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED ) ) ) ) + || ( ( dwState & ( ENHANCED_KEY | LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED ) ) ) ) { extended = 1; #ifdef HB_DEBUG_KEYBOARD @@ -524,6 +467,7 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) BOOL bAlt = dwState & ( LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED ); BOOL bCtrl = dwState & ( LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED ); BOOL bShift = dwState & SHIFT_PRESSED; + BOOL bAltGr = ( dwState & ( LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED ) ) == ( LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED ); BOOL bEnhanced = dwState & ENHANCED_KEY; #ifdef HB_DEBUG_KEYBOARD fprintf( stdout, "8" ); @@ -537,27 +481,14 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) fprintf( stdout, "9" ); #endif /* Alt key held */ - if( ch == 0 || ch == wChar || tolower( ch ) == tolower( wChar ) ) + if( bAltGr && ch ) { /* It's actually Alt+Gr */ } + else { #ifdef HB_DEBUG_KEYBOARD fprintf( stdout, "a" ); #endif - /* Only translate if not AltGr */ - if( wKey == 1 ) ch = K_ALT_ESC; /* Esc */ - else if( wKey == 15 ) ch = K_ALT_TAB; /* Tab */ - else if( wKey <= 12 ) ch = wKey + 374; /* Numeric row */ - else if( wKey == 28 ) ch = KP_ALT_ENTER; /* Num Pad Enter */ - else if( wKey <= 52 ) ch = wKey + 256; /* Alpha rows */ - else if( wKey == 53 && bEnhanced ) ch = KP_ALT_SLASH; /* Num Pad / */ - else if( wKey == 55 ) ch = KP_ALT_ASTERISK; /* Num Pad * */ - else if( wKey <= 58 ) ch = wKey + 367; /* ? */ - else if( wKey <= 68 ) ch = 29 - wKey; /* F1 - F10 */ - else if( wKey == 74 ) ch = KP_ALT_MINUS; /* Num Pad - */ - else if( wKey == 76 ) ch = KP_ALT_5; /* Num Pad 5 */ - else if( wKey == 78 ) ch = KP_ALT_PLUS; /* Num Pad + */ - else if( wKey <= 86 ) ch = wKey + 336; /* Cursor */ - else if( wKey <= 88 ) ch = 41 - wKey; /* F11, F12 */ - else ch = wKey + 384; + ch = wKey + HB_INKEY_ALT; + if( bEnhanced ) ch += HB_INKEY_ENHANCED; } } else if( bCtrl ) @@ -566,103 +497,8 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) fprintf( stdout, "b" ); #endif /* Ctrl key held */ - if( wKey == 53 && bEnhanced ) ch = KP_CTRL_SLASH; /* Num Pad / */ - else switch( wKey ) - { - case 1: /* Esc */ - ch = K_ESC; - break; - case 3: /* 2 */ - ch = 259; - break; - case 7: /* 6 */ - ch = K_CTRL_PGDN; - break; - case 12: /* - */ - ch = K_CTRL_PGUP; - break; - case 14: /* Backspace */ - ch = K_CTRL_BS; - break; - case 15: /* Tab */ - ch = K_CTRL_TAB; - break; - case 26: /* [ */ - ch = K_ESC; - break; - case 27: /* ] */ - ch = K_CTRL_HOME; - break; - case 28: /* Num Pad Enter */ - ch = K_CTRL_ENTER; - break; - case 43: /* \ */ - ch = K_F1; - break; - case 55: /* Num Pad * */ - ch = KP_CTRL_ASTERISK; - break; - case 59: /* F1 */ - case 60: /* F2 */ - case 61: /* F3 */ - case 62: /* F4 */ - case 63: /* F5 */ - case 64: /* F6 */ - case 65: /* F7 */ - case 66: /* F8 */ - case 67: /* F9 */ - case 68: /* F10 */ - ch = 39 - wKey; - break; - case 71: /* Home */ - ch = K_CTRL_HOME; - break; - case 72: /* Up */ - ch = K_CTRL_UP; - break; - case 73: /* PgUp */ - ch = K_CTRL_PGUP; - break; - case 74: /* Num Pad - */ - ch = KP_CTRL_MINUS; - break; - case 75: /* Left */ - ch = K_CTRL_LEFT; - break; - case 76: /* Num Pad 5 */ - ch = KP_CTRL_5; - break; - case 77: /* Right */ - ch = K_CTRL_RIGHT; - break; - case 78: /* Num Pad + */ - ch = KP_CTRL_PLUS; - break; - case 79: /* End */ - ch = K_CTRL_END; - break; - case 80: /* Down */ - ch = K_CTRL_DOWN; - break; - case 81: /* PgDn */ - ch = K_CTRL_PGDN; - break; - case 82: /* Ins */ - ch = K_CTRL_INS; - break; - case 83: /* Del */ - ch = K_CTRL_DEL; - break; - case 87: /* F11 */ - case 88: /* F12 */ - ch = 43 - wKey; - break; - default: - /* Keep Ctrl+Alpha, but scrap everything - else that hasn't been translated yet. */ - if( ch < 1 || ch > 26 ) - ch = 0; - } + if( ch == 0 || bEnhanced ) ch = wKey + HB_INKEY_CTRL; + if( bEnhanced ) ch += HB_INKEY_ENHANCED; } else if( bShift ) { @@ -670,73 +506,8 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) fprintf( stdout, "c" ); #endif /* Shift key held */ - if( wKey == 53 && bEnhanced ) ch = '/'; /* Num Pad / */ - else switch( wKey ) - { - case 1: /* Esc */ - ch = K_ESC; - break; - case 15: /* Tab */ - ch = K_SH_TAB; - break; - case 28: /* Num Pad Enter */ - ch = K_ENTER; - break; - case 59: /* F1 */ - case 60: /* F2 */ - case 61: /* F3 */ - case 62: /* F4 */ - case 63: /* F5 */ - case 64: /* F6 */ - case 65: /* F7 */ - case 66: /* F8 */ - case 67: /* F9 */ - case 68: /* F10 */ - ch = 49 - wKey; - break; - case 71: /* Home */ - ch = K_HOME; - break; - case 72: /* Up */ - ch = K_UP; - break; - case 73: /* Page Up */ - ch = K_PGUP; - break; - case 75: /* Left */ - ch = K_LEFT; - break; - case 76: /* Num Pad 5 */ - ch = '5'; - break; - case 77: /* Right */ - ch = K_RIGHT; - break; - case 79: /* End */ - ch = K_END; - break; - case 80: /* Down */ - ch = K_DOWN; - break; - case 81: /* Page Down */ - ch = K_PGDN; - break; - case 82: /* Ins */ - ch = K_INS; - break; - case 83: /* Del */ - ch = K_DEL; - break; - case 87: /* F11 */ - case 88: /* F12 */ - ch = 45 - wKey; - break; - default: - /* Only provide a translation for those key - codes that don't have a character code. */ - if( ch == 0 ) - ch = wKey + 128; - } + if( ch == 0 || bEnhanced ) ch = wKey + HB_INKEY_SHIFT; + if( bEnhanced ) ch += HB_INKEY_ENHANCED; } else { @@ -744,6 +515,7 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) fprintf( stdout, "d" ); #endif ch = StdFnKeys( wKey, bEnhanced ); + if( bEnhanced ) ch += HB_INKEY_ENHANCED; } } } diff --git a/harbour/source/rtl/inkey.c b/harbour/source/rtl/inkey.c index cb2d432869..4250574598 100644 --- a/harbour/source/rtl/inkey.c +++ b/harbour/source/rtl/inkey.c @@ -71,6 +71,7 @@ #include "hbapigt.h" #include "hbvm.h" #include "hbset.h" +#include "hbinkey.ch" #include "inkey.ch" #include @@ -86,6 +87,32 @@ static BOOL s_inkeyPoll; /* Flag to override no polling when TYPEAHEAD i static int s_inkeyForce; /* Variable to hold keyboard input when TYPEAHEAD is 0 */ static HB_inkey_enum s_eventmask; +static int hb_inkeyFetch( void ) /* Extract the next key from the keyboard buffer */ +{ + int key; + + HB_TRACE(HB_TR_DEBUG, ("hb_inkeyFetch()")); + + hb_inkeyPoll(); + if( hb_set.HB_SET_TYPEAHEAD ) + { + /* Proper typeahead support is set */ + if( s_inkeyHead == s_inkeyTail ) key = 0; /* Keyboard buffer is empty */ + else + { /* Keyboard buffer is not empty */ + s_inkeyLast = s_inkeyBuffer[ s_inkeyTail++ ]; + if( s_inkeyTail >= hb_set.HB_SET_TYPEAHEAD ) + s_inkeyTail = 0; + key = s_inkeyLast; + } + } + else + key = s_inkeyLast = s_inkeyForce; /* Typeahead support is disabled */ + s_inkeyForce = 0; + + return key; +} + int hb_inkey( BOOL bWait, double dSeconds, HB_inkey_enum event_mask ) { int key; @@ -103,7 +130,7 @@ int hb_inkey( BOOL bWait, double dSeconds, HB_inkey_enum event_mask ) /* There is no point in waiting forever for no input events! */ if( ( event_mask & ( INKEY_ALL + INKEY_RAW ) ) != 0 ) { - while( hb_inkeyNext() == 0 ) + while( hb_inkeyNext( event_mask ) == 0 ) { hb_idleState(); } @@ -120,12 +147,12 @@ int hb_inkey( BOOL bWait, double dSeconds, HB_inkey_enum event_mask ) struct tms tm; end_clock = times( &tm ) + ( clock_t ) ( dSeconds * 100 ); - while( hb_inkeyNext() == 0 && (times( &tm ) < end_clock) ) + while( hb_inkeyNext( event_mask ) == 0 && (times( &tm ) < end_clock) ) #else clock_t end_clock = clock() + ( clock_t ) ( dSeconds * CLOCKS_PER_SEC ); - while( hb_inkeyNext() == 0 && clock() < end_clock ) -#endif + while( hb_inkeyNext( event_mask ) == 0 && clock() < end_clock ) +#endif { hb_idleState(); } @@ -133,52 +160,27 @@ int hb_inkey( BOOL bWait, double dSeconds, HB_inkey_enum event_mask ) } } - key = hb_inkeyGet(); /* Get the current input event or 0 */ + key = hb_inkeyFetch(); /* Get the current input event or 0 */ s_inkeyPoll = FALSE; /* Stop forced polling */ s_eventmask = hb_set.HB_SET_EVENTMASK; /* Restore original input event mask */ - return key; + return hb_inkeyTranslate( key, event_mask ); } -int hb_inkeyGet( void ) /* Extract the next key from the keyboard buffer */ -{ - int key; - - HB_TRACE(HB_TR_DEBUG, ("hb_inkeyGet()")); - - hb_inkeyPoll(); - if( hb_set.HB_SET_TYPEAHEAD ) - { - /* Proper typeahead support is set */ - if( s_inkeyHead == s_inkeyTail ) key = 0; /* Keyboard buffer is empty */ - else - { /* Keyboard buffer is not empty */ - s_inkeyLast = s_inkeyBuffer[ s_inkeyTail++ ]; - if( s_inkeyTail >= hb_set.HB_SET_TYPEAHEAD ) - s_inkeyTail = 0; - key = s_inkeyLast; - } - } - else - key = s_inkeyLast = s_inkeyForce; /* Typeahead support is disabled */ - - s_inkeyForce = 0; - - return key; -} - -int hb_inkeyLast( void ) /* Return the value of the last key that was extracted */ +int hb_inkeyLast( HB_inkey_enum event_mask ) /* Return the value of the last key that was extracted */ { HB_TRACE(HB_TR_DEBUG, ("hb_inkeyLast()")); hb_inkeyPoll(); - return s_inkeyLast; + return hb_inkeyTranslate( s_inkeyLast, event_mask ); } -int hb_inkeyNext( void ) /* Return the next key without extracting it */ +int hb_inkeyNext( HB_inkey_enum event_mask ) /* Return the next key without extracting it */ { + int key = s_inkeyForce; /* Assume that typeahead support is disabled */ + HB_TRACE(HB_TR_DEBUG, ("hb_inkeyNext()")); hb_inkeyPoll(); @@ -187,12 +189,12 @@ int hb_inkeyNext( void ) /* Return the next key without extracting it */ { /* Proper typeahead support is enabled */ if( s_inkeyHead == s_inkeyTail ) - return 0; /* No key */ + key = 0; else - return s_inkeyBuffer[ s_inkeyTail ]; /* Next key */ + key = s_inkeyBuffer[ s_inkeyTail ]; /* Next key */ } - return s_inkeyForce; /* Typeahead support is disabled */ + return hb_inkeyTranslate( key, event_mask ); } void hb_inkeyPoll( void ) /* Poll the console keyboard to stuff the Harbour buffer */ @@ -327,11 +329,761 @@ HB_FUNC( HB_KEYPUT ) HB_FUNC( NEXTKEY ) { - hb_retni( hb_inkeyNext() ); + hb_retni( hb_inkeyNext( ISNUM( 1 ) ? ( HB_inkey_enum ) hb_parni( 1 ) : hb_set.HB_SET_EVENTMASK ) ); } HB_FUNC( LASTKEY ) { - hb_retni( s_inkeyLast ); + hb_retni( hb_inkeyTranslate( s_inkeyLast, hb_inkeyNext( ISNUM( 1 ) ? ( HB_inkey_enum ) hb_parni( 1 ) : hb_set.HB_SET_EVENTMASK ) ) ); } +int hb_inkeyTranslate( int key, HB_inkey_enum event_mask ) +{ + if( key && hb_gtExtendedKeySupport() && ! ( event_mask & HB_INKEY_EXTENDED ) ) + { + /* Translate the Harbour extended key codes to + Clipper-compatible key codes */ + switch( key ) { + case HB_K_ALT_A: + key = K_ALT_A; + break; + case HB_K_ALT_B: + key = K_ALT_B; + break; + case HB_K_ALT_C: + key = K_ALT_C; + break; + case HB_K_ALT_D: + key = K_ALT_D; + break; + case HB_K_ALT_E: + key = K_ALT_E; + break; + case HB_K_ALT_F: + key = K_ALT_F; + break; + case HB_K_ALT_G: + key = K_ALT_G; + break; + case HB_K_ALT_H: + key = K_ALT_H; + break; + case HB_K_ALT_I: + key = K_ALT_I; + break; + case HB_K_ALT_J: + key = K_ALT_J; + break; + case HB_K_ALT_K: + key = K_ALT_K; + break; + case HB_K_ALT_L: + key = K_ALT_L; + break; + case HB_K_ALT_M: + key = K_ALT_M; + break; + case HB_K_ALT_N: + key = K_ALT_N; + break; + case HB_K_ALT_O: + key = K_ALT_O; + break; + case HB_K_ALT_P: + key = K_ALT_P; + break; + case HB_K_ALT_Q: + key = K_ALT_Q; + break; + case HB_K_ALT_R: + key = K_ALT_R; + break; + case HB_K_ALT_S: + key = K_ALT_S; + break; + case HB_K_ALT_T: + key = K_ALT_T; + break; + case HB_K_ALT_U: + key = K_ALT_U; + break; + case HB_K_ALT_V: + key = K_ALT_V; + break; + case HB_K_ALT_W: + key = K_ALT_W; + break; + case HB_K_ALT_X: + key = K_ALT_X; + break; + case HB_K_ALT_Y: + key = K_ALT_Y; + break; + case HB_K_ALT_Z: + key = K_ALT_Z; + break; + case HB_K_CTRL_A: + key = K_CTRL_A; + break; + case HB_K_CTRL_B: + key = K_CTRL_B; + break; + case HB_K_CTRL_C: + key = K_CTRL_C; + break; + case HB_K_CTRL_D: + key = K_CTRL_D; + break; + case HB_K_CTRL_E: + key = K_CTRL_E; + break; + case HB_K_CTRL_F: + key = K_CTRL_F; + break; + case HB_K_CTRL_G: + key = K_CTRL_G; + break; + case HB_K_CTRL_H: + key = K_CTRL_H; + break; + case HB_K_CTRL_I: + key = K_CTRL_I; + break; + case HB_K_CTRL_J: + key = K_CTRL_J; + break; + case HB_K_CTRL_K: + key = K_CTRL_K; + break; + case HB_K_CTRL_L: + key = K_CTRL_L; + break; + case HB_K_CTRL_M: + key = K_CTRL_M; + break; + case HB_K_CTRL_N: + key = K_CTRL_N; + break; + case HB_K_CTRL_O: + key = K_CTRL_O; + break; + case HB_K_CTRL_P: + key = K_CTRL_P; + break; + case HB_K_CTRL_Q: + key = K_CTRL_Q; + break; + case HB_K_CTRL_R: + key = K_CTRL_R; + break; + case HB_K_CTRL_S: + key = K_CTRL_S; + break; + case HB_K_CTRL_T: + key = K_CTRL_T; + break; + case HB_K_CTRL_U: + key = K_CTRL_U; + break; + case HB_K_CTRL_V: + key = K_CTRL_V; + break; + case HB_K_CTRL_W: + key = K_CTRL_W; + break; + case HB_K_CTRL_X: + key = K_CTRL_X; + break; + case HB_K_CTRL_Y: + key = K_CTRL_Y; + break; + case HB_K_CTRL_Z: + key = K_CTRL_Z; + break; + case HB_K_CTRL_LEFT_SQUARE: + key = K_ESC; + break; + case HB_K_CTRL_BACK_SLASH: + key = K_F1; + break; + case HB_K_CTRL_RIGHT_SQUARE: + key = K_CTRL_HOME; + break; + case HB_K_CTRL_HAT: + key = K_CTRL_PGDN; + break; + case HB_K_CTRL_UNDERSCORE: + key = K_CTRL_PGUP; + break; + case HB_K_SPACE: + key = K_SPACE; + break; + case HB_K_ALT_1: + key = K_ALT_1; + break; + case HB_K_ALT_2: + key = K_ALT_2; + break; + case HB_K_ALT_3: + key = K_ALT_3; + break; + case HB_K_ALT_4: + key = K_ALT_4; + break; + case HB_K_ALT_5: + key = K_ALT_5; + break; + case HB_K_ALT_6: + key = K_ALT_6; + break; + case HB_K_ALT_7: + key = K_ALT_7; + break; + case HB_K_ALT_8: + key = K_ALT_8; + break; + case HB_K_ALT_9: + key = K_ALT_9; + break; + case HB_K_ALT_0: + key = K_ALT_0; + break; + case HB_K_ALT_EQUAL: + key = 269; + break; + case HB_K_CTRL_1: + key = -99; + break; + case HB_K_CTRL_2: + key = 259; + break; + case HB_K_CTRL_3: + key = -99; + break; + case HB_K_CTRL_4: + key = -99; + break; + case HB_K_CTRL_5: + key = -99; + break; + case HB_K_CTRL_6: + key = K_CTRL_PGDN; + break; + case HB_K_CTRL_7: + key = -99; + break; + case HB_K_CTRL_8: + key = -99; + break; + case HB_K_CTRL_9: + key = -99; + break; + case HB_K_CTRL_0: + key = -99; + break; + case HB_K_CTRL_SEMI_COLON: + key = -99; + break; + case HB_K_CTRL_COMMA: + key = -99; + break; + case HB_K_CTRL_PERIOD: + key = -99; + break; + case HB_K_CTRL_SLASH: + key = -99; + break; + case HB_K_CTRL_MINUS: + key = K_CTRL_PGUP; + break; + case HB_K_CTRL_PLUS: + key = -99; + break; + case HB_K_CTRL_LEFT_CURLY: + key = K_ESC; + break; + case HB_K_CTRL_RIGHT_CURLY: + key = K_CTRL_HOME; + break; + case HB_K_ALT_BACKSPACE: + key = 270; + break; + case HB_K_CTRL_BACKSPACE: + key = 127; + break; + case HB_K_ALT_ENTER: + key = K_ALT_ENTER; + break; + case HB_K_SHIFT_ENTER: + key = K_ENTER; + break; + case HB_K_ALT_ESC: + key = K_ALT_ESC; + break; + case HB_K_CTRL_ESC: + key = K_ESC; + break; + case HB_K_SHIFT_TAB: + key = K_SH_TAB; + break; + case HB_K_ALT_TAB: + key = K_ALT_TAB; + break; + case HB_K_CTRL_TAB: + key = K_CTRL_TAB; + break; + case HB_K_F1: + key = K_F1; + break; + case HB_K_F2: + key = K_F2; + break; + case HB_K_F3: + key = K_F3; + break; + case HB_K_F4: + key = K_F4; + break; + case HB_K_F5: + key = K_F5; + break; + case HB_K_F6: + key = K_F6; + break; + case HB_K_F7: + key = K_F7; + break; + case HB_K_F8: + key = K_F8; + break; + case HB_K_F9: + key = K_F9; + break; + case HB_K_F10: + key = K_F10; + break; + case HB_K_F11: + key = K_F11; + break; + case HB_K_F12: + key = K_F12; + break; + case HB_K_ALT_F1: + key = K_ALT_F1; + break; + case HB_K_ALT_F2: + key = K_ALT_F2; + break; + case HB_K_ALT_F3: + key = K_ALT_F3; + break; + case HB_K_ALT_F4: + key = K_ALT_F4; + break; + case HB_K_ALT_F5: + key = K_ALT_F5; + break; + case HB_K_ALT_F6: + key = K_ALT_F6; + break; + case HB_K_ALT_F7: + key = K_ALT_F7; + break; + case HB_K_ALT_F8: + key = K_ALT_F8; + break; + case HB_K_ALT_F9: + key = K_ALT_F9; + break; + case HB_K_ALT_F10: + key = K_ALT_F10; + break; + case HB_K_ALT_F11: + key = K_ALT_F11; + break; + case HB_K_ALT_F12: + key = K_ALT_F12; + break; + case HB_K_CTRL_F1: + key = K_CTRL_F1; + break; + case HB_K_CTRL_F2: + key = K_CTRL_F2; + break; + case HB_K_CTRL_F3: + key = K_CTRL_F3; + break; + case HB_K_CTRL_F4: + key = K_CTRL_F4; + break; + case HB_K_CTRL_F5: + key = K_CTRL_F5; + break; + case HB_K_CTRL_F6: + key = K_CTRL_F6; + break; + case HB_K_CTRL_F7: + key = K_CTRL_F7; + break; + case HB_K_CTRL_F8: + key = K_CTRL_F8; + break; + case HB_K_CTRL_F9: + key = K_CTRL_F9; + break; + case HB_K_CTRL_F10: + key = K_CTRL_F10; + break; + case HB_K_CTRL_F11: + key = K_CTRL_F11; + break; + case HB_K_CTRL_F12: + key = K_CTRL_F12; + break; + case HB_K_SHIFT_F1: + key = K_SH_F1; + break; + case HB_K_SHIFT_F2: + key = K_SH_F2; + break; + case HB_K_SHIFT_F3: + key = K_SH_F3; + break; + case HB_K_SHIFT_F4: + key = K_SH_F4; + break; + case HB_K_SHIFT_F5: + key = K_SH_F5; + break; + case HB_K_SHIFT_F6: + key = K_SH_F6; + break; + case HB_K_SHIFT_F7: + key = K_SH_F7; + break; + case HB_K_SHIFT_F8: + key = K_SH_F8; + break; + case HB_K_SHIFT_F9: + key = K_SH_F9; + break; + case HB_K_SHIFT_F10: + key = K_SH_F10; + break; + case HB_K_SHIFT_F11: + key = K_SH_F11; + break; + case HB_K_SHIFT_F12: + key = K_SH_F12; + break; + case HB_KP_MINUS: + key = '-'; + break; + case HB_KP_ALT_MINUS: + key = KP_ALT_MINUS; + break; + case HB_KP_CTRL_MINUS: + key = KP_CTRL_MINUS; + break; + case HB_KP_SHIFT_MINUS: + key = '-'; + break; + case HB_KP_PLUS: + key = '+'; + break; + case HB_KP_ALT_PLUS: + key = KP_ALT_PLUS; + break; + case HB_KP_CTRL_PLUS: + key = KP_CTRL_PLUS; + break; + case HB_KP_SHIFT_PLUS: + key = '+'; + break; + case HB_KP_SLASH: + key = '/'; + break; + case HB_KP_ALT_SLASH: + key = KP_ALT_SLASH; + break; + case HB_KP_CTRL_SLASH: + key = KP_CTRL_SLASH; + break; + case HB_KP_SHIFT_SLASH: + key = '/'; + break; + case HB_KP_STAR: + key = '*'; + break; + case HB_KP_ALT_STAR: + key = KP_ALT_ASTERISK; + break; + case HB_KP_CTRL_STAR: + key = KP_CTRL_ASTERISK; + break; + case HB_KP_SHIFT_STAR: + key = '*'; + break; + case HB_KP_ENTER: + key = K_ENTER; + break; + case HB_KP_CTRL_ENTER: + key = K_CTRL_ENTER; + break; + case HB_K_HOME: + key = K_HOME; + break; + case HB_K_UP: + key = K_UP; + break; + case HB_K_PG_UP: + key = K_PGUP; + break; + case HB_K_LEFT: + key = K_LEFT; + break; + case HB_K_RIGHT: + key = K_RIGHT; + break; + case HB_K_END: + key = K_END; + break; + case HB_K_DOWN: + key = K_DOWN; + break; + case HB_K_PG_DN: + key = K_PGDN; + break; + case HB_K_INS: + key = K_INS; + break; + case HB_K_DEL: + key = K_DEL; + break; + case HB_K_ALT_HOME: + key = K_ALT_HOME; + break; + case HB_K_ALT_UP: + key = K_ALT_UP; + break; + case HB_K_ALT_PG_UP: + key = K_ALT_PGUP; + break; + case HB_K_ALT_LEFT: + key = K_ALT_LEFT; + break; + case HB_K_ALT_RIGHT: + key = K_ALT_RIGHT; + break; + case HB_K_ALT_END: + key = K_ALT_END; + break; + case HB_K_ALT_PG_DN: + key = K_ALT_PGDN; + break; + case HB_K_ALT_INS: + key = K_ALT_INS; + break; + case HB_K_ALT_DEL: + key = K_ALT_DEL; + break; + case HB_K_CTRL_HOME: + key = K_CTRL_HOME; + break; + case HB_K_CTRL_UP: + key = K_CTRL_UP; + break; + case HB_K_CTRL_PG_UP: + key = K_CTRL_PGUP; + break; + case HB_K_CTRL_LEFT: + key = K_CTRL_LEFT; + break; + case HB_K_CTRL_RIGHT: + key = K_CTRL_RIGHT; + break; + case HB_K_CTRL_END: + key = K_CTRL_END; + break; + case HB_K_CTRL_DOWN: + key = K_CTRL_DOWN; + break; + case HB_K_CTRL_PG_DN: + key = K_CTRL_PGDN; + break; + case HB_K_CTRL_INS: + key = K_CTRL_INS; + break; + case HB_K_CTRL_DEL: + key = K_CTRL_DEL; + break; + case HB_K_SHIFT_HOME: + key = K_HOME; + break; + case HB_K_SHIFT_UP: + key = K_UP; + break; + case HB_K_SHIFT_PG_UP: + key = K_PGUP; + break; + case HB_K_SHIFT_LEFT: + key = K_LEFT; + break; + case HB_K_SHIFT_RIGHT: + key = K_RIGHT; + break; + case HB_K_SHIFT_END: + key = K_END; + break; + case HB_K_SHIFT_DOWN: + key = K_DOWN; + break; + case HB_K_SHIFT_PG_DN: + key = K_PGDN; + break; + case HB_K_SHIFT_INS: + key = K_INS; + break; + case HB_K_SHIFT_DEL: + key = K_DEL; + break; + case HB_KP_HOME: + key = K_HOME; + break; + case HB_KP_UP: + key = K_UP; + break; + case HB_KP_PG_UP: + key = K_PGUP; + break; + case HB_KP_LEFT: + key = K_LEFT; + break; + case HB_KP_5: + key = K_UP; + break; + case HB_KP_RIGHT: + key = K_RIGHT; + break; + case HB_KP_END: + key = K_END; + break; + case HB_KP_DOWN: + key = K_DOWN; + break; + case HB_KP_PG_DN: + key = K_PGDN; + break; + case HB_KP_INS: + key = K_INS; + break; + case HB_KP_DEL: + key = K_DEL; + break; + case HB_KP_ALT_HOME: + key = K_ALT_HOME; + break; + case HB_KP_ALT_UP: + key = K_ALT_UP; + break; + case HB_KP_ALT_PG_UP: + key = K_ALT_PGUP; + break; + case HB_KP_ALT_LEFT: + key = K_ALT_LEFT; + break; + case HB_KP_ALT_5: + key = K_ALT_5; + break; + case HB_KP_ALT_RIGHT: + key = K_ALT_RIGHT; + break; + case HB_KP_ALT_END: + key = K_ALT_END; + break; + case HB_KP_ALT_PG_DN: + key = K_ALT_PGDN; + break; + case HB_KP_ALT_INS: + key = K_ALT_INS; + break; + case HB_KP_ALT_DEL: + key = K_ALT_DEL; + break; + case HB_KP_CTRL_HOME: + key = K_CTRL_HOME; + break; + case HB_KP_CTRL_UP: + key = K_CTRL_UP; + break; + case HB_KP_CTRL_PG_UP: + key = K_CTRL_PGUP; + break; + case HB_KP_CTRL_LEFT: + key = K_CTRL_LEFT; + break; + case HB_KP_CTRL_5: + key = KP_CTRL_5; + break; + case HB_KP_CTRL_RIGHT: + key = K_CTRL_RIGHT; + break; + case HB_KP_CTRL_END: + key = K_CTRL_END; + break; + case HB_KP_CTRL_DOWN: + key = K_CTRL_DOWN; + break; + case HB_KP_CTRL_PG_DN: + key = K_CTRL_PGDN; + break; + case HB_KP_CTRL_INS: + key = K_CTRL_INS; + break; + case HB_KP_CTRL_DEL: + key = K_CTRL_DEL; + break; + case HB_KP_SHIFT_HOME: + key = K_HOME; + break; + case HB_KP_SHIFT_UP: + key = K_UP; + break; + case HB_KP_SHIFT_PG_UP: + key = K_PGUP; + break; + case HB_KP_SHIFT_LEFT: + key = K_LEFT; + break; + case HB_KP_SHIFT_5: + key = '5'; + break; + case HB_KP_SHIFT_RIGHT: + key = K_RIGHT; + break; + case HB_KP_SHIFT_END: + key = K_END; + break; + case HB_KP_SHIFT_DOWN: + key = K_DOWN; + break; + case HB_KP_SHIFT_PG_DN: + key = K_PGDN; + break; + case HB_KP_SHIFT_INS: + key = K_INS; + break; + case HB_KP_SHIFT_DEL: + key = K_DEL; + break; + } + } + if( key == -99 ) + { + /* Ignore this key code by extracting it from the input buffer + and discarding it. */ + hb_inkeyFetch(); + key = 0; + } + return key; +} diff --git a/harbour/tests/inkeytst.prg b/harbour/tests/inkeytst.prg index 696c0053d9..4d1d25e8cd 100644 --- a/harbour/tests/inkeytst.prg +++ b/harbour/tests/inkeytst.prg @@ -202,7 +202,11 @@ LOCAL nKey, nMask, cText nMask := INKEY_ALL IF ! EMPTY( cRaw ) - nMask += INKEY_RAW + IF UPPER( LEFT( cRaw, 1 ) ) == "R" + nMask += HB_INKEY_RAW + ELSE + nMask += HB_INKEY_EXTENDED + END IF END IF SET(_SET_EVENTMASK, nMask)