diff --git a/ChangeLog.txt b/ChangeLog.txt index 9807a3584f..78946becb8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,42 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2015-10-28 15:44 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbgtinfo.ch + * removed unused HB_GTI_KBD_* macros + * redefined few other HB_GTI_KBD_* macros to be more HB_KF_* friendly. + [INCOMPATIBLE] + ; Warning this modification is not binary compatible so if someone uses + HB_GTI_KBD_SCROLOCK, HB_GTI_KBD_NUMLOCK, HB_GTI_KBD_CAPSLOCK, + HB_GTI_KBD_LSHIFT, HB_GTI_KBD_RSHIFT, + HB_GTI_KBD_LCTRL, HB_GTI_KBD_RCTRL, + HB_GTI_KBD_LALT, HB_GTI_KBD_RALT, + HB_GTI_KBD_LWIN, HB_GTI_KBD_RWIN or + HB_GTI_KBD_MENU + then he should recompile his code with new hbgtinfo.ch header files. + + * include/hbgtcore.h + * src/rtl/gtkeycod.c + * src/rtl/gtdos/gtdos.c + * src/rtl/gtos2/gtos2.c + * src/rtl/gtpca/gtpca.c + * src/rtl/gtstd/gtstd.c + + added support for Harbour extended keycodes + + * src/rtl/gtos2/gtos2.c + + added support for HB_GTI_KBDSHIFTS + + * src/rtl/gtdos/gtdos.c + ! fixed CTRL+C and CTRL+BREAK handling in OpenWatcom builds + + * src/rtl/inkeyapi.c + ! fixed translation for CTRL + @ + + * tests/gtkeys.prg + + added raw keyboard test - it disables any additional interactions + * modified Harbour output to show more information about extended + keycodes + 2015-10-22 10:13 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rtl/gtwvt/gtwvt.c * src/rtl/gtwvt/gtwvt.h diff --git a/include/hbgtcore.h b/include/hbgtcore.h index ed930d85c4..dc7594d53f 100644 --- a/include/hbgtcore.h +++ b/include/hbgtcore.h @@ -639,7 +639,7 @@ extern HB_EXPORT void hb_gt_winapi_setKbdState( int kbdShifts ); extern HB_EXPORT void hb_gt_winapi_tone( double dFrequency, double dDuration ); #endif /* HB_OS_WIN */ #if defined( HB_OS_DOS ) || defined( HB_OS_WIN ) || defined( HB_OS_OS2 ) -extern int hb_gt_dos_keyCodeTranslate( int iKey ); +extern int hb_gt_dos_keyCodeTranslate( int iKey, int iFlags, PHB_CODEPAGE cdp ); #endif /* HB_OS_DOS || HB_OS_WIN || HB_OS_OS2 */ HB_EXTERN_END diff --git a/include/hbgtinfo.ch b/include/hbgtinfo.ch index 071b8a6d9d..b2a50226bd 100644 --- a/include/hbgtinfo.ch +++ b/include/hbgtinfo.ch @@ -175,24 +175,20 @@ #define HB_GTI_KBD_SHIFT 0x000001 #define HB_GTI_KBD_CTRL 0x000002 #define HB_GTI_KBD_ALT 0x000004 -#define HB_GTI_KBD_LWIN 0x000008 -#define HB_GTI_KBD_RWIN 0x000010 -#define HB_GTI_KBD_MENU 0x000020 +#define HB_GTI_KBD_KEYPAD 0x000008 +#define HB_GTI_KBD_SCROLOCK 0x000010 +#define HB_GTI_KBD_NUMLOCK 0x000020 +#define HB_GTI_KBD_CAPSLOCK 0x000040 #define HB_GTI_KBD_INSERT 0x000080 -#define HB_GTI_KBD_SCROLOCK 0x000100 -#define HB_GTI_KBD_NUMLOCK 0x000200 -#define HB_GTI_KBD_CAPSLOCK 0x000400 -#define HB_GTI_KBD_INALTSEQ 0x000800 -#define HB_GTI_KBD_ACCENT1 0x001000 -#define HB_GTI_KBD_ACCENT2 0x002000 -#define HB_GTI_KBD_ACCENT3 0x004000 -#define HB_GTI_KBD_ACCENT4 0x008000 -#define HB_GTI_KBD_LSHIFT 0x010000 -#define HB_GTI_KBD_RSHIFT 0x020000 -#define HB_GTI_KBD_LCTRL 0x040000 -#define HB_GTI_KBD_RCTRL 0x080000 -#define HB_GTI_KBD_LALT 0x100000 -#define HB_GTI_KBD_RALT 0x200000 +#define HB_GTI_KBD_LSHIFT 0x000100 +#define HB_GTI_KBD_RSHIFT 0x000200 +#define HB_GTI_KBD_LCTRL 0x000400 +#define HB_GTI_KBD_RCTRL 0x000800 +#define HB_GTI_KBD_LALT 0x001000 +#define HB_GTI_KBD_RALT 0x002000 +#define HB_GTI_KBD_LWIN 0x004000 +#define HB_GTI_KBD_RWIN 0x008000 +#define HB_GTI_KBD_MENU 0x010000 #ifdef HB_LEGACY_LEVEL4 /* Harbour GT callback events - WORK IN PROGRESS */ diff --git a/src/rtl/gtdos/gtdos.c b/src/rtl/gtdos/gtdos.c index 68d3cd00ca..3cc434065a 100644 --- a/src/rtl/gtdos/gtdos.c +++ b/src/rtl/gtdos/gtdos.c @@ -178,8 +178,13 @@ static void hb_gt_dos_CtrlBreak_Handler( int iSignal ) /* Ctrl-Break was pressed */ /* NOTE: the layout of this function is forced by the compiler */ - HB_SYMBOL_UNUSED( iSignal ); s_bBreak = HB_TRUE; + +#if defined( __WATCOMC__ ) + signal( iSignal, hb_gt_dos_CtrlBreak_Handler ); +#else + HB_SYMBOL_UNUSED( iSignal ); +#endif } #else static int s_iOldCtrlBreak = 0; @@ -196,6 +201,7 @@ static void hb_gt_dos_CtrlBrkRestore( void ) HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_CtrlBrkRestore()" ) ); #if defined( __WATCOMC__ ) + signal( SIGINT, SIG_DFL ); signal( SIGBREAK, SIG_DFL ); #elif defined( _MSC_VER ) signal( SIGINT, SIG_DFL ); @@ -205,6 +211,53 @@ static void hb_gt_dos_CtrlBrkRestore( void ) } #endif +#define HB_BIOS_LSHIFT 0x01 +#define HB_BIOS_RSHIFT 0x02 +#define HB_BIOS_CTRL 0x04 +#define HB_BIOS_ALT 0x08 +#define HB_BIOS_SHIFT ( HB_BIOS_LSHIFT | HB_BIOS_RSHIFT ) +#define HB_BIOS_SCROLL 0x10 +#define HB_BIOS_NUMLOCK 0x20 +#define HB_BIOS_CAPSLOCK 0x40 +#define HB_BIOS_INSERT 0x80 + +static int hb_gt_dos_getKbdState( void ) +{ + int iKbdState = 0; + HB_UCHAR ucStat; + + ucStat = HB_PEEK_BYTE( 0x0040, 0x0017 ); + + if( ucStat & HB_BIOS_SHIFT ) iKbdState |= HB_GTI_KBD_SHIFT; + if( ucStat & HB_BIOS_CTRL ) iKbdState |= HB_GTI_KBD_CTRL; + if( ucStat & HB_BIOS_ALT ) iKbdState |= HB_GTI_KBD_ALT; + if( ucStat & HB_BIOS_SCROLL ) iKbdState |= HB_GTI_KBD_SCROLOCK; + if( ucStat & HB_BIOS_NUMLOCK ) iKbdState |= HB_GTI_KBD_NUMLOCK; + if( ucStat & HB_BIOS_CAPSLOCK ) iKbdState |= HB_GTI_KBD_CAPSLOCK; + if( ucStat & HB_BIOS_INSERT ) iKbdState |= HB_GTI_KBD_INSERT; + if( ucStat & HB_BIOS_LSHIFT ) iKbdState |= HB_GTI_KBD_LSHIFT; + if( ucStat & HB_BIOS_RSHIFT ) iKbdState |= HB_GTI_KBD_RSHIFT; + + return iKbdState; +} + +static void hb_gt_dos_setKbdState( int iKbdState ) +{ + HB_UCHAR ucStat = 0; + + ucStat |= ( iKbdState & HB_GTI_KBD_SHIFT ) ? HB_BIOS_SHIFT : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_CTRL ) ? HB_BIOS_CTRL : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_ALT ) ? HB_BIOS_ALT : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_SCROLOCK ) ? HB_BIOS_SCROLL : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_NUMLOCK ) ? HB_BIOS_NUMLOCK : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_CAPSLOCK ) ? HB_BIOS_CAPSLOCK : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_INSERT ) ? HB_BIOS_INSERT : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_LSHIFT ) ? HB_BIOS_LSHIFT : 0; + ucStat |= ( iKbdState & HB_GTI_KBD_RSHIFT ) ? HB_BIOS_RSHIFT : 0; + + HB_POKE_BYTE( 0x0040, 0x0017, ucStat ); +} + static int hb_gt_dos_GetScreenMode( void ) { HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_GetScreenMode()" ) ); @@ -786,6 +839,8 @@ static void hb_gt_dos_Init( PHB_GT pGT, HB_FHANDLE hFilenoStdin, HB_FHANDLE hFil #elif defined( __WATCOMC__ ) + break_off(); + signal( SIGINT, hb_gt_dos_CtrlBreak_Handler ); signal( SIGBREAK, hb_gt_dos_CtrlBreak_Handler ); atexit( hb_gt_dos_CtrlBrkRestore ); @@ -827,7 +882,7 @@ static void hb_gt_dos_Exit( PHB_GT pGT ) static int hb_gt_dos_ReadKey( PHB_GT pGT, int iEventMask ) { - int ch = 0; + int iKey = 0, iFlags = 0; HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_ReadKey(%p,%d)", pGT, iEventMask ) ); @@ -836,7 +891,7 @@ static int hb_gt_dos_ReadKey( PHB_GT pGT, int iEventMask ) if( __djgpp_cbrk_count ) { __djgpp_cbrk_count = 0; /* Indicate that Ctrl+Break has been handled */ - ch = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */ + iKey = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */ } #else /* First check for Ctrl+Break, which is handled by gt/gtdos.c, @@ -844,57 +899,55 @@ static int hb_gt_dos_ReadKey( PHB_GT pGT, int iEventMask ) if( s_bBreak ) { s_bBreak = HB_FALSE; /* Indicate that Ctrl+Break has been handled */ - ch = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */ + iKey = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */ } #endif else if( kbhit() ) { /* A key code is available in the BIOS keyboard buffer, so read it */ #if defined( __DJGPP__ ) - if( iEventMask & HB_INKEY_RAW ) - ch = getxkey(); - else - ch = getkey(); - if( ch == 256 ) + iKey = getxkey(); + if( iKey == 256 ) /* Ignore Ctrl+Break, because it is being handled as soon as it happens (see above) rather than waiting for it to show up in the keyboard input queue */ - ch = -1; + iKey = -1; + iFlags = HB_KF_KEYPAD; #else /* A key code is available in the BIOS keyboard buffer */ - ch = getch(); /* Get the key code */ - if( ch == 0 && kbhit() ) + iKey = getch(); /* Get the key code */ + if( iKey == 0 && kbhit() ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ - ch = getch() + 256; + iKey = getch(); + if( iKey != -1 ) + iKey += 256; } - else if( ch == 224 && kbhit() ) +#if ! ( defined( __WATCOMC__ ) || defined( __BORLANDC__ ) ) + /* Watcom and Borland C use only 0x00 to indicate extended keycode + and do not use 224 (0xE0) */ + else if( iKey == 224 && kbhit() ) { - /* It was an extended function key lead-in code, so read - the actual function key and then offset it by 256, - unless extended keyboard events are allowed, in which - case offset it by 512 */ - if( iEventMask & HB_INKEY_RAW ) - ch = getch() + 512; - else - ch = getch() + 256; + iKey = getch(); + if( iKey != -1 ) + iKey += 256; } +#endif #endif } - ch = hb_gt_dos_keyCodeTranslate( ch ); - - if( ch == 0 ) - ch = HB_GTSELF_MOUSEREADKEY( pGT, iEventMask ); - else + if( iKey == 0 || iKey == -1 ) { - int u = HB_GTSELF_KEYTRANS( pGT, ch ); - if( u ) - ch = HB_INKEY_NEW_UNICODE( u ); + iKey = HB_GTSELF_MOUSEREADKEY( pGT, iEventMask ); + if( iKey != 0 && ! HB_INKEY_ISEXT( iKey ) && iKey != K_MOUSEMOVE ) + iKey = HB_INKEY_NEW_MKEY( iKey, hb_gt_dos_getKbdState() ); } + else + iKey = hb_gt_dos_keyCodeTranslate( iKey, hb_gt_dos_getKbdState() | iFlags, + HB_GTSELF_CPIN( pGT ) ); - return ch; + return iKey; } static HB_BOOL hb_gt_dos_IsColor( PHB_GT pGT ) @@ -1291,49 +1344,6 @@ static void hb_gt_dos_Refresh( PHB_GT pGT ) hb_gt_dos_SetCursorStyle( iStyle ); } -#define HB_BIOS_LSHIFT 0x01 -#define HB_BIOS_RSHIFT 0x02 -#define HB_BIOS_CTRL 0x04 -#define HB_BIOS_ALT 0x08 -#define HB_BIOS_SHIFT ( HB_BIOS_LSHIFT | HB_BIOS_RSHIFT ) -#define HB_BIOS_SCROLL 0x10 -#define HB_BIOS_NUMLOCK 0x20 -#define HB_BIOS_CAPSLOCK 0x40 -#define HB_BIOS_INSERT 0x80 - -static int hb_gt_dos_getKbdState( void ) -{ - int iKbdState = 0; - HB_UCHAR ucStat; - - ucStat = HB_PEEK_BYTE( 0x0040, 0x0017 ); - - if( ucStat & HB_BIOS_SHIFT ) iKbdState |= HB_GTI_KBD_SHIFT; - if( ucStat & HB_BIOS_CTRL ) iKbdState |= HB_GTI_KBD_CTRL; - if( ucStat & HB_BIOS_ALT ) iKbdState |= HB_GTI_KBD_ALT; - if( ucStat & HB_BIOS_SCROLL ) iKbdState |= HB_GTI_KBD_SCROLOCK; - if( ucStat & HB_BIOS_NUMLOCK ) iKbdState |= HB_GTI_KBD_NUMLOCK; - if( ucStat & HB_BIOS_CAPSLOCK ) iKbdState |= HB_GTI_KBD_CAPSLOCK; - if( ucStat & HB_BIOS_INSERT ) iKbdState |= HB_GTI_KBD_INSERT; - - return iKbdState; -} - -static void hb_gt_dos_setKbdState( int iKbdState ) -{ - HB_UCHAR ucStat = 0; - - ucStat |= ( iKbdState & HB_GTI_KBD_SHIFT ) ? HB_BIOS_SHIFT : 0; - ucStat |= ( iKbdState & HB_GTI_KBD_CTRL ) ? HB_BIOS_CTRL : 0; - ucStat |= ( iKbdState & HB_GTI_KBD_ALT ) ? HB_BIOS_ALT : 0; - ucStat |= ( iKbdState & HB_GTI_KBD_SCROLOCK ) ? HB_BIOS_SCROLL : 0; - ucStat |= ( iKbdState & HB_GTI_KBD_NUMLOCK ) ? HB_BIOS_NUMLOCK : 0; - ucStat |= ( iKbdState & HB_GTI_KBD_CAPSLOCK ) ? HB_BIOS_CAPSLOCK : 0; - ucStat |= ( iKbdState & HB_GTI_KBD_INSERT ) ? HB_BIOS_INSERT : 0; - - HB_POKE_BYTE( 0x0040, 0x0017, ucStat ); -} - static HB_BOOL hb_gt_dos_Info( PHB_GT pGT, int iType, PHB_GT_INFO pInfo ) { HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_Info(%p,%d,%p)", pGT, iType, pInfo ) ); diff --git a/src/rtl/gtkeycod.c b/src/rtl/gtkeycod.c index 5f62184208..7b015a21a0 100644 --- a/src/rtl/gtkeycod.c +++ b/src/rtl/gtkeycod.c @@ -7,6 +7,9 @@ * based on hb_gt_ReadKey() from GTDOS code by: * Copyright 1999 David G. Holm * + * Copyright 2006, 2015 Przemyslaw Czerpak + * www - http://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) @@ -55,120 +58,618 @@ #if defined( HB_OS_DOS ) || defined( HB_OS_WIN ) || defined( HB_OS_OS2 ) -int hb_gt_dos_keyCodeTranslate( int iKey ) +int hb_gt_dos_keyCodeTranslate( int iKey, int iFlags, PHB_CODEPAGE cdp ) { + int iKeyPad = iFlags & HB_KF_KEYPAD; + + iFlags &= ( HB_KF_SHIFT | HB_KF_CTRL | HB_KF_ALT ); + +/* +TODO: + 259: K_CTRL_AT + 127: K_CTRL_BS + 270: K_ALT_BS + 271: K_SHIFT_TAB + 404: K_CTRL_TAB + 421: K_ALT_TAB + 272 - 283: ALT + qwertyuiop[] + 284: K_ALT_RETURN + 285: ??? + 286 - 296: ALT + asdfghjkl;' + 297: K_ALT_BACKQUOTE + 298: ??? + + 299: K_ALT_BACKSLASH + 300 - 309: ALT + zxcvbnm,./ + 310: ??? + 312 - 314: ??? + + 370: K_CTRL_PRINT + 376 - 387: ALT + 1234567890-= +*/ + /* Perform key translations */ switch( iKey ) { - case -1: /* No key available */ - iKey = 0; + case 0: + case -1: /* No key available */ + return 0; + + case 8: /* BackSpace or CTRL + H */ + iKey = iFlags & HB_KF_CTRL ? 'H' : HB_KX_BS; break; - case 328: /* Up arrow */ - iKey = K_UP; + + case 9: /* Tab or CTRL + I */ + iKey = iFlags & HB_KF_CTRL ? 'I' : HB_KX_TAB; break; - case 336: /* Down arrow */ - iKey = K_DOWN; + + case 10: /* CTRL + ENTER or CTRL + J - we cannot guess :( */ + iKey = HB_KX_ENTER; + iFlags |= HB_KF_CTRL; break; - case 331: /* Left arrow */ - iKey = K_LEFT; + + case 13: /* ENTER or CTRL + M */ + iKey = iFlags & HB_KF_CTRL ? 'M' : HB_KX_ENTER; break; - case 333: /* Right arrow */ - iKey = K_RIGHT; + + case 127: /* CTRL + BackSpace */ + iKey = HB_KX_BS; + iFlags |= HB_KF_CTRL; break; - case 327: /* Home */ - iKey = K_HOME; + + case 259: /* CTRL + "@" */ + iKey = '@'; + iFlags |= HB_KF_CTRL; break; - case 335: /* End */ - iKey = K_END; + + case 270: /* ALT + BackSpace */ + iKey = HB_KX_BS; + iFlags |= HB_KF_ALT; break; - case 329: /* Page Up */ - iKey = K_PGUP; + + case 271: /* SHIFT + TAB */ + iKey = HB_KX_TAB; + iFlags |= HB_KF_SHIFT; break; - case 337: /* Page Down */ - iKey = K_PGDN; + + case 404: /* CTRL + TAB */ + iKey = HB_KX_TAB; + iFlags |= HB_KF_CTRL; break; - case 371: /* Ctrl + Left arrow */ - iKey = K_CTRL_LEFT; + + case 272: /* Alt + Q */ + iKey = 'Q'; + iFlags |= HB_KF_ALT; break; - case 372: /* Ctrl + Right arrow */ - iKey = K_CTRL_RIGHT; + case 273: /* Alt + W */ + iKey = 'W'; + iFlags |= HB_KF_ALT; break; - case 375: /* Ctrl + Home */ - iKey = K_CTRL_HOME; + case 274: /* Alt + E */ + iKey = 'E'; + iFlags |= HB_KF_ALT; break; - case 373: /* Ctrl + End */ - iKey = K_CTRL_END; + case 275: /* Alt + R */ + iKey = 'R'; + iFlags |= HB_KF_ALT; break; - case 388: /* Ctrl + Page Up */ - iKey = K_CTRL_PGUP; + case 276: /* Alt + T */ + iKey = 'T'; + iFlags |= HB_KF_ALT; break; - case 374: /* Ctrl + Page Down */ - iKey = K_CTRL_PGDN; + case 277: /* Alt + Y */ + iKey = 'Y'; + iFlags |= HB_KF_ALT; break; - case 338: /* Insert */ - iKey = K_INS; + case 278: /* Alt + U */ + iKey = 'U'; + iFlags |= HB_KF_ALT; break; - case 339: /* Delete */ - iKey = K_DEL; + case 279: /* Alt + I */ + iKey = 'I'; + iFlags |= HB_KF_ALT; break; - case 315: /* F1 */ - iKey = K_F1; + case 280: /* Alt + O */ + iKey = 'O'; + iFlags |= HB_KF_ALT; break; - case 316: /* F2 */ - case 317: /* F3 */ - case 318: /* F4 */ - case 319: /* F5 */ - case 320: /* F6 */ - case 321: /* F7 */ - case 322: /* F8 */ - case 323: /* F9 */ - case 324: /* F10 */ - iKey = 315 - iKey; + case 281: /* Alt + P */ + iKey = 'P'; + iFlags |= HB_KF_ALT; break; - case 340: /* Shift + F1 */ - case 341: /* Shift + F2 */ - case 342: /* Shift + F3 */ - case 343: /* Shift + F4 */ - case 344: /* Shift + F5 */ - case 345: /* Shift + F6 */ - case 346: /* Shift + F7 */ - case 347: /* Shift + F8 */ - case 348: /* Shift + F9 */ - case 349: /* Shift + F10 */ - case 350: /* Ctrl + F1 */ - case 351: /* Ctrl + F2 */ - case 352: /* Ctrl + F3 */ - case 353: /* Ctrl + F4 */ - case 354: /* Ctrl + F5 */ - case 355: /* Ctrl + F6 */ - case 356: /* Ctrl + F7 */ - case 357: /* Ctrl + F8 */ - case 358: /* Ctrl + F9 */ - case 359: /* Ctrl + F10 */ - case 360: /* Alt + F1 */ - case 361: /* Alt + F2 */ - case 362: /* Alt + F3 */ - case 363: /* Alt + F4 */ - case 364: /* Alt + F5 */ - case 365: /* Alt + F6 */ - case 366: /* Alt + F7 */ - case 367: /* Alt + F8 */ - case 368: /* Alt + F9 */ - case 369: /* Alt + F10 */ - iKey = 330 - iKey; + case 282: /* Alt + [ */ + iKey = '['; + iFlags |= HB_KF_ALT; break; - case 389: /* F11 */ - case 390: /* F12 */ - case 391: /* Shift + F11 */ - case 392: /* Shift + F12 */ - case 393: /* Ctrl + F11 */ - case 394: /* Ctrl + F12 */ - case 395: /* Alt + F11 */ - case 396: /* Alt + F12 */ - iKey = 349 - iKey; + case 283: /* Alt + ] */ + iKey = ']'; + iFlags |= HB_KF_ALT; + break; + case 284: /* ALT + ENTER */ + iKey = HB_KX_ENTER; + iFlags |= HB_KF_ALT; + break; + + case 286: /* Alt + A */ + iKey = 'A'; + iFlags |= HB_KF_ALT; + break; + case 287: /* Alt + S */ + iKey = 'S'; + iFlags |= HB_KF_ALT; + break; + case 288: /* Alt + D */ + iKey = 'D'; + iFlags |= HB_KF_ALT; + break; + case 289: /* Alt + F */ + iKey = 'F'; + iFlags |= HB_KF_ALT; + break; + case 290: /* Alt + G */ + iKey = 'G'; + iFlags |= HB_KF_ALT; + break; + case 291: /* Alt + H */ + iKey = 'H'; + iFlags |= HB_KF_ALT; + break; + case 292: /* Alt + J */ + iKey = 'J'; + iFlags |= HB_KF_ALT; + break; + case 293: /* Alt + K */ + iKey = 'K'; + iFlags |= HB_KF_ALT; + break; + case 294: /* Alt + L */ + iKey = 'L'; + iFlags |= HB_KF_ALT; + break; + case 295: /* Alt + ; */ + iKey = ';'; + iFlags |= HB_KF_ALT; + break; + case 296: /* Alt + ' */ + iKey = '\''; + iFlags |= HB_KF_ALT; + break; + case 297: /* Alt + ` */ + iKey = '`'; + iFlags |= HB_KF_ALT; + break; + case 299: /* Alt + \ */ + iKey = '\\'; + iFlags |= HB_KF_ALT; + break; + + case 300: /* Alt + Z */ + iKey = 'Z'; + iFlags |= HB_KF_ALT; + break; + case 301: /* Alt + X */ + iKey = 'X'; + iFlags |= HB_KF_ALT; + break; + case 302: /* Alt + C */ + iKey = 'C'; + iFlags |= HB_KF_ALT; + break; + case 303: /* Alt + V */ + iKey = 'V'; + iFlags |= HB_KF_ALT; + break; + case 304: /* Alt + B */ + iKey = 'B'; + iFlags |= HB_KF_ALT; + break; + case 305: /* Alt + N */ + iKey = 'N'; + iFlags |= HB_KF_ALT; + break; + case 306: /* Alt + M */ + iKey = 'M'; + iFlags |= HB_KF_ALT; + break; + case 307: /* Alt + , */ + iKey = ','; + iFlags |= HB_KF_ALT; + break; + case 308: /* Alt + . */ + iKey = '.'; + iFlags |= HB_KF_ALT; + break; + case 309: /* Alt + / */ + iKey = '/'; + iFlags |= HB_KF_ALT; + break; + + case 376: /* Alt + 1 */ + case 377: /* Alt + 2 */ + case 378: /* Alt + 3 */ + case 379: /* Alt + 4 */ + case 380: /* Alt + 5 */ + case 381: /* Alt + 6 */ + case 382: /* Alt + 7 */ + case 383: /* Alt + 8 */ + case 384: /* Alt + 9 */ + iKey = iKey - ( 376 - '1' ); + iFlags |= HB_KF_ALT; + break; + case 385: /* Alt + 0 */ + iKey = '0'; + iFlags |= HB_KF_ALT; + break; + case 386: /* Alt + - */ + iKey = '-'; + iFlags |= HB_KF_ALT; + break; + case 387: /* Alt + = */ + iKey = '='; + iFlags |= HB_KF_ALT; + break; + + case 421: /* ALT + TAB */ + iKey = HB_KX_TAB; + iFlags |= HB_KF_ALT; + break; + + case 327: /* Home */ + iKey = HB_KX_HOME; + iFlags |= iKeyPad; + break; + case 328: /* Up arrow */ + iKey = HB_KX_UP; + iFlags |= iKeyPad; + break; + case 329: /* Page Up */ + iKey = HB_KX_PGUP; + iFlags |= iKeyPad; + break; + case 331: /* Left arrow */ + iKey = HB_KX_LEFT; + iFlags |= iKeyPad; + break; + case 333: /* Right arrow */ + iKey = HB_KX_RIGHT; + iFlags |= iKeyPad; + break; + case 335: /* End */ + iKey = HB_KX_END; + iFlags |= iKeyPad; + break; + case 336: /* Down arrow */ + iKey = HB_KX_DOWN; + iFlags |= iKeyPad; + break; + case 337: /* Page Down */ + iKey = HB_KX_PGDN; + iFlags |= iKeyPad; + break; + case 338: /* Insert */ + iKey = HB_KX_INS; + iFlags |= iKeyPad; + break; + case 339: /* Delete */ + iKey = HB_KX_DEL; + iFlags |= iKeyPad; + break; + + case 370: /* Ctrl + Print */ + iKey = HB_KX_PRTSCR; + iFlags |= HB_KF_CTRL; + break; + + case 371: /* Ctrl + Left arrow */ + iKey = HB_KX_LEFT; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 372: /* Ctrl + Right arrow */ + iKey = HB_KX_RIGHT; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 373: /* Ctrl + End */ + iKey = HB_KX_END; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 374: /* Ctrl + Page Down */ + iKey = HB_KX_PGDN; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 375: /* Ctrl + Home */ + iKey = HB_KX_HOME; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + + case 388: /* Ctrl + Page Up */ + iKey = HB_KX_PGUP; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 397: /* Ctrl + Up arrow */ + iKey = HB_KX_LEFT; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 401: /* Ctrl + Down arrow */ + iKey = HB_KX_RIGHT; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + + case 315: /* F1 */ + case 316: /* F2 */ + case 317: /* F3 */ + case 318: /* F4 */ + case 319: /* F5 */ + case 320: /* F6 */ + case 321: /* F7 */ + case 322: /* F8 */ + case 323: /* F9 */ + case 324: /* F10 */ + iKey = iKey - ( 315 - HB_KX_F1 ); + break; + case 389: /* F11 */ + iKey = HB_KX_F11; + break; + case 390: /* F12 */ + iKey = HB_KX_F12; + break; + + case 340: /* Shift + F1 */ + case 341: /* Shift + F2 */ + case 342: /* Shift + F3 */ + case 343: /* Shift + F4 */ + case 344: /* Shift + F5 */ + case 345: /* Shift + F6 */ + case 346: /* Shift + F7 */ + case 347: /* Shift + F8 */ + case 348: /* Shift + F9 */ + case 349: /* Shift + F10 */ + iKey = iKey - ( 340 - HB_KX_F1 ); + iFlags |= HB_KF_SHIFT; + break; + case 391: /* Shift + F11 */ + iKey = HB_KX_F11; + iFlags |= HB_KF_SHIFT; + break; + case 392: /* Shift + F12 */ + iKey = HB_KX_F12; + iFlags |= HB_KF_SHIFT; + break; + + case 350: /* Ctrl + F1 */ + case 351: /* Ctrl + F2 */ + case 352: /* Ctrl + F3 */ + case 353: /* Ctrl + F4 */ + case 354: /* Ctrl + F5 */ + case 355: /* Ctrl + F6 */ + case 356: /* Ctrl + F7 */ + case 357: /* Ctrl + F8 */ + case 358: /* Ctrl + F9 */ + case 359: /* Ctrl + F10 */ + iKey = iKey - ( 350 - HB_KX_F1 ); + iFlags |= HB_KF_CTRL; + break; + case 393: /* Ctrl + F11 */ + iKey = HB_KX_F11; + iFlags |= HB_KF_CTRL; + break; + case 394: /* Ctrl + F12 */ + iKey = HB_KX_F12; + iFlags |= HB_KF_CTRL; + break; + + case 360: /* Alt + F1 */ + case 361: /* Alt + F2 */ + case 362: /* Alt + F3 */ + case 363: /* Alt + F4 */ + case 364: /* Alt + F5 */ + case 365: /* Alt + F6 */ + case 366: /* Alt + F7 */ + case 367: /* Alt + F8 */ + case 368: /* Alt + F9 */ + case 369: /* Alt + F10 */ + iKey = iKey - ( 360 - HB_KX_F1 ); + iFlags |= HB_KF_ALT; + break; + case 395: /* Alt + F11 */ + iKey = HB_KX_F11; + iFlags |= HB_KF_ALT; + break; + case 396: /* Alt + F12 */ + iKey = HB_KX_F12; + iFlags |= HB_KF_ALT; + break; + + case 332: + iKey = HB_KX_CENTER; + iFlags |= HB_KF_KEYPAD; + break; + + case 311: + iKey = '*'; + iFlags |= HB_KF_KEYPAD | HB_KF_ALT; + break; + case 330: + iKey = '-'; + iFlags |= HB_KF_KEYPAD | HB_KF_ALT; + break; + case 334: + iKey = '+'; + iFlags |= HB_KF_KEYPAD | HB_KF_ALT; + break; + + case 398: + iKey = '-'; + iFlags |= HB_KF_KEYPAD | HB_KF_CTRL; + break; + case 399: + iKey = HB_KX_CENTER; + iFlags |= HB_KF_KEYPAD | HB_KF_CTRL; + break; + case 400: + iKey = '+'; + iFlags |= HB_KF_KEYPAD | HB_KF_CTRL; + break; + case 402: + iKey = HB_KX_INS; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 403: + iKey = HB_KX_DEL; + iFlags |= HB_KF_CTRL | iKeyPad; + break; + case 405: + iKey = '/'; + iFlags |= HB_KF_KEYPAD | HB_KF_CTRL; + break; + case 406: + iKey = '*'; + iFlags |= HB_KF_KEYPAD | HB_KF_CTRL; + break; + + case 407: + iKey = HB_KX_HOME; + iFlags |= HB_KF_ALT; + break; + case 408: + iKey = HB_KX_UP; + iFlags |= HB_KF_ALT; + break; + case 409: + iKey = HB_KX_PGUP; + iFlags |= HB_KF_ALT; + break; + case 411: + iKey = HB_KX_LEFT; + iFlags |= HB_KF_ALT; + break; + case 413: + iKey = HB_KX_RIGHT; + iFlags |= HB_KF_ALT; + break; + case 415: + iKey = HB_KX_END; + iFlags |= HB_KF_ALT; + break; + case 416: + iKey = HB_KX_DOWN; + iFlags |= HB_KF_ALT; + break; + case 417: + iKey = HB_KX_PGDN; + iFlags |= HB_KF_ALT; + break; + case 418: + iKey = HB_KX_INS; + iFlags |= HB_KF_ALT; + break; + case 419: + iKey = HB_KX_DEL; + iFlags |= HB_KF_ALT; + break; + + case 420: + iKey = '/'; + iFlags |= HB_KF_KEYPAD | HB_KF_ALT; + break; + case 422: + iKey = HB_KX_ENTER; + iFlags |= HB_KF_KEYPAD | HB_KF_ALT; + break; + + case 583: + iKey = HB_KX_HOME; + break; + case 584: + iKey = HB_KX_UP; + break; + case 585: + iKey = HB_KX_PGUP; + break; + case 587: + iKey = HB_KX_LEFT; + break; + case 589: + iKey = HB_KX_RIGHT; + break; + case 591: + iKey = HB_KX_END; + break; + case 592: + iKey = HB_KX_DOWN; + break; + case 593: + iKey = HB_KX_PGDN; + break; + case 594: + iKey = HB_KX_INS; + break; + case 595: + iKey = HB_KX_DEL; + break; + + case 627: + iKey = HB_KX_LEFT; + iFlags |= HB_KF_CTRL; + break; + case 628: + iKey = HB_KX_RIGHT; + iFlags |= HB_KF_CTRL; + break; + case 629: + iKey = HB_KX_END; + iFlags |= HB_KF_CTRL; + break; + case 630: + iKey = HB_KX_PGDN; + iFlags |= HB_KF_CTRL; + break; + case 631: + iKey = HB_KX_HOME; + iFlags |= HB_KF_CTRL; + break; + case 644: + iKey = HB_KX_PGUP; + iFlags |= HB_KF_CTRL; + break; + case 653: + iKey = HB_KX_UP; + iFlags |= HB_KF_CTRL; + break; + case 657: + iKey = HB_KX_DOWN; + iFlags |= HB_KF_CTRL; + break; + case 658: + iKey = HB_KX_INS; + iFlags |= HB_KF_CTRL; + break; + case 659: + iKey = HB_KX_DEL; + iFlags |= HB_KF_CTRL; + break; + + default: + if( iKey >= 0 && iKey < 32 && ( iFlags & HB_KF_CTRL ) != 0 ) + { + iFlags |= HB_KF_CTRL; + iKey += 'A' - 1; + } + else if( iKey <= 255 && + ( iKey >= 128 || ( iFlags & ( HB_KF_CTRL | HB_KF_ALT ) ) == 0 ) ) + { + if( cdp ) + { + int uc = hb_cdpGetWC( cdp, ( HB_UCHAR ) ( iKey ), 0 ); + if( uc ) + return HB_INKEY_NEW_UNICODEF( uc, iFlags ); + } + return HB_INKEY_NEW_CHARF( iKey, iFlags ); + } + else + return iKey; } - return iKey; + return HB_INKEY_NEW_KEY( iKey, iFlags ); } #endif /* HB_OS_DOS || HB_OS_WIN || HB_OS_OS2 */ diff --git a/src/rtl/gtos2/gtos2.c b/src/rtl/gtos2/gtos2.c index 4acad77b4b..0a0f64e68b 100644 --- a/src/rtl/gtos2/gtos2.c +++ b/src/rtl/gtos2/gtos2.c @@ -140,12 +140,62 @@ static VIOMODEINFO s_vi; /* keyboard event record */ static PKBDKEYINFO s_key; -/* keyboard handle, 0 == default */ -static PHKBD s_hk; + +/* keyboard status data */ +static PKBDINFO s_kbd; /* mouse logical handle */ static HMOU s_uMouHandle; + +/* helper functions */ + +#ifndef KBDSTF_SHIFT + #define KBDSTF_SHIFT ( KBDSTF_RIGHTSHIFT | KBDSTF_LEFTSHIFT ) +#endif + +static int hb_gt_os2_keyFlags( HB_USHORT fsState ) +{ + int iFlags = 0; + + if( fsState & KBDSTF_SHIFT ) + iFlags |= HB_KF_SHIFT; + if( fsState & KBDSTF_CONTROL ) + iFlags |= HB_KF_CTRL; + if( fsState & KBDSTF_ALT ) + iFlags |= HB_KF_ALT; + + return iFlags; +} + +static int hb_gt_os2_getKbdState( void ) +{ + int iKbdState = 0; + + memset( s_kbd, 0, sizeof( KBDINFO ) ); + if( KbdGetStatus( s_kbd, 0 ) == NO_ERROR ) + { + if( s_kbd->fsState & KBDSTF_SHIFT ) iKbdState |= HB_GTI_KBD_SHIFT; + if( s_kbd->fsState & KBDSTF_CONTROL ) iKbdState |= HB_GTI_KBD_CTRL; + if( s_kbd->fsState & KBDSTF_ALT ) iKbdState |= HB_GTI_KBD_ALT; + if( s_kbd->fsState & KBDSTF_SCROLLLOCK_ON ) iKbdState |= HB_GTI_KBD_SCROLOCK; + if( s_kbd->fsState & KBDSTF_NUMLOCK_ON ) iKbdState |= HB_GTI_KBD_NUMLOCK; + if( s_kbd->fsState & KBDSTF_CAPSLOCK_ON ) iKbdState |= HB_GTI_KBD_CAPSLOCK; + if( s_kbd->fsState & KBDSTF_INSERT_ON ) iKbdState |= HB_GTI_KBD_INSERT; + if( s_kbd->fsState & KBDSTF_LEFTSHIFT ) iKbdState |= HB_GTI_KBD_LSHIFT; + if( s_kbd->fsState & KBDSTF_RIGHTSHIFT ) iKbdState |= HB_GTI_KBD_RSHIFT; + if( s_kbd->fsState & KBDSTF_LEFTCONTROL ) iKbdState |= HB_GTI_KBD_LCTRL; + if( s_kbd->fsState & KBDSTF_RIGHTCONTROL ) iKbdState |= HB_GTI_KBD_RCTRL; + if( s_kbd->fsState & KBDSTF_LEFTALT ) iKbdState |= HB_GTI_KBD_LALT; + if( s_kbd->fsState & KBDSTF_RIGHTALT ) iKbdState |= HB_GTI_KBD_RALT; + } + + return iKbdState; +} + + +/* GT methods */ + static void hb_gt_os2_mouse_Init( PHB_GT pGT ) { USHORT fsEvents = MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_BN1_DOWN | @@ -539,10 +589,8 @@ static void hb_gt_os2_Init( PHB_GT pGT, HB_FHANDLE hFilenoStdin, HB_FHANDLE hFil VioGetMode( &s_vi, 0 ); /* fill structure with current video mode settings */ /* Alloc tileable memory for calling a 16 subsystem */ - s_hk = ( PHKBD ) hb_gt_os2_allocMem( sizeof( HKBD ) ); - /* it is a long after all, so I set it to zero only one time since it never changes */ - memset( s_hk, 0, sizeof( HKBD ) ); s_key = ( PKBDKEYINFO ) hb_gt_os2_allocMem( sizeof( KBDKEYINFO ) ); + s_kbd = ( PKBDINFO ) hb_gt_os2_allocMem( sizeof( KBDINFO ) ); /* TODO: Is anything else required to initialize the video subsystem? I (Maurilio Longo) think that we should set correct codepage @@ -603,13 +651,13 @@ static void hb_gt_os2_Exit( PHB_GT pGT ) } DosFreeMem( s_key ); - DosFreeMem( s_hk ); + DosFreeMem( s_kbd ); VioSetCp( 0, s_usOldCodePage, 0 ); } static int hb_gt_os2_ReadKey( PHB_GT pGT, int iEventMask ) { - int ch; /* next char if any */ + int iKey = 0, iFlags = 0; HB_TRACE( HB_TR_DEBUG, ( "hb_gt_os2_ReadKey(%p,%d)", pGT, iEventMask ) ); @@ -617,36 +665,51 @@ static int hb_gt_os2_ReadKey( PHB_GT pGT, int iEventMask ) memset( s_key, 0, sizeof( KBDKEYINFO ) ); /* Get next character without wait */ - KbdCharIn( s_key, IO_NOWAIT, ( HKBD ) *s_hk ); - - /* extended key codes have 00h or E0h as chChar */ - if( ( s_key->fbStatus & KBDTRF_EXTENDED_CODE ) && - ( s_key->chChar == 0x00 || s_key->chChar == 0xE0 ) ) + if( KbdCharIn( s_key, IO_NOWAIT, ( HKBD ) 0 ) == NO_ERROR ) { - /* It was an extended function key lead-in code, so read the actual function key and then offset it by 256, - unless extended keyboard events are allowed, in which case offset it by 512 */ - if( ( s_key->chChar == 0xE0 ) && ( iEventMask & HB_INKEY_RAW ) ) - ch = ( int ) s_key->chScan + 512; - else - ch = ( int ) s_key->chScan + 256; - } - else if( s_key->fbStatus & KBDTRF_FINAL_CHAR_IN ) - ch = ( int ) s_key->chChar; - else - ch = 0; + iFlags = hb_gt_os2_keyFlags( s_key->fsState ); - ch = hb_gt_dos_keyCodeTranslate( ch ); - - if( ch == 0 ) - ch = HB_GTSELF_MOUSEREADKEY( pGT, iEventMask ); - else - { - int u = HB_GTSELF_KEYTRANS( pGT, ch ); - if( u ) - ch = HB_INKEY_NEW_UNICODE( u ); + /* extended key codes have 00h or E0h as chChar */ + if( ( s_key->fbStatus & KBDTRF_EXTENDED_CODE ) && + ( s_key->chChar == 0x00 || s_key->chChar == 0xE0 ) ) + iKey = hb_gt_dos_keyCodeTranslate( ( int ) s_key->chScan + 256, + iFlags, HB_GTSELF_CPIN( pGT ) ); + else if( s_key->fbStatus & KBDTRF_FINAL_CHAR_IN ) + { + iKey = ( int ) s_key->chChar; + if( ( iFlags & HB_KF_CTRL ) != 0 && ( iKey >= 0 && iKey < 32 ) ) + { + iKey += 'A' - 1; + iKey = HB_INKEY_NEW_KEY( iKey, iFlags ); + } + else if( iKey < 128 && ( iFlags & ( HB_KF_CTRL | HB_KF_ALT ) ) ) + { + iKey = HB_INKEY_NEW_KEY( iKey, iFlags ); + } + else + { + int uc = HB_GTSELF_KEYTRANS( pGT, iKey ); + if( uc ) + iKey = HB_INKEY_NEW_UNICODEF( uc, iFlags ); + else + iKey = HB_INKEY_NEW_CHARF( iKey, iFlags ); + } + } } - return ch; + if( iKey == 0 ) + { + iKey = HB_GTSELF_MOUSEREADKEY( pGT, iEventMask ); + if( iKey != 0 && ! HB_INKEY_ISEXT( iKey ) && iKey != K_MOUSEMOVE ) + { + memset( s_kbd, 0, sizeof( KBDINFO ) ); + if( KbdGetStatus( s_kbd, 0 ) == NO_ERROR ) + iFlags = hb_gt_os2_keyFlags( s_kbd->fsState ); + iKey = HB_INKEY_NEW_MKEY( iKey, iFlags ); + } + } + + return iKey; } static HB_BOOL hb_gt_os2_IsColor( PHB_GT pGT ) @@ -858,6 +921,10 @@ static HB_BOOL hb_gt_os2_Info( PHB_GT pGT, int iType, PHB_GT_INFO pInfo ) pInfo->pResult = hb_itemPutL( pInfo->pResult, HB_TRUE ); break; + case HB_GTI_KBDSHIFTS: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, hb_gt_os2_getKbdState() ); + break; + case HB_GTI_CODEPAGE: { USHORT usCodePageNew = ( USHORT ) hb_itemGetNI( pInfo->pNewVal ); diff --git a/src/rtl/gtpca/gtpca.c b/src/rtl/gtpca/gtpca.c index 6dc61ade59..6be9ec54a0 100644 --- a/src/rtl/gtpca/gtpca.c +++ b/src/rtl/gtpca/gtpca.c @@ -612,7 +612,7 @@ static int hb_gt_pca_ReadKey( PHB_GT pGT, int iEventMask ) /* _read_kbd() returns -1 for no key, the switch statement will handle this. */ - ch = hb_gt_dos_keyCodeTranslate( ch ); + ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); #elif defined( HB_HAS_TERMIOS ) { struct timeval tv; @@ -638,9 +638,11 @@ static int hb_gt_pca_ReadKey( PHB_GT pGT, int iEventMask ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ - ch = _getch() + 256; + ch = _getch(); + if( ch != -1 ) + ch += 256; } - ch = hb_gt_dos_keyCodeTranslate( ch ); + ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); } } else if( ! _eof( ( int ) s_hFilenoStdin ) ) @@ -663,13 +665,15 @@ static int hb_gt_pca_ReadKey( PHB_GT pGT, int iEventMask ) if( kbhit() ) { ch = getch(); - if( ( ch == 0 || ch == 224 ) && kbhit() ) + if( ch == 0 && kbhit() ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ - ch = getch() + 256; + ch = getch(); + if( ch != -1 ) + ch += 256; } - ch = hb_gt_dos_keyCodeTranslate( ch ); + ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); } } else if( ! eof( s_hFilenoStdin ) ) diff --git a/src/rtl/gtstd/gtstd.c b/src/rtl/gtstd/gtstd.c index a434f85bf0..1d1ed8c151 100644 --- a/src/rtl/gtstd/gtstd.c +++ b/src/rtl/gtstd/gtstd.c @@ -356,9 +356,11 @@ static int hb_gt_std_ReadKey( PHB_GT pGT, int iEventMask ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ - ch = _getch() + 256; + ch = _getch(); + if( ch != -1 ) + ch += 256; } - ch = hb_gt_dos_keyCodeTranslate( ch ); + ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); } } else if( ! _eof( ( int ) pGTSTD->hStdin ) ) @@ -402,13 +404,15 @@ static int hb_gt_std_ReadKey( PHB_GT pGT, int iEventMask ) if( kbhit() ) { ch = getch(); - if( ( ch == 0 || ch == 224 ) && kbhit() ) + if( ch == 0 && kbhit() ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ - ch = getch() + 256; + ch = getch(); + if( ch != -1 ) + ch += 256; } - ch = hb_gt_dos_keyCodeTranslate( ch ); + ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); } } else if( ! eof( pGTSTD->hStdin ) ) diff --git a/src/rtl/inkeyapi.c b/src/rtl/inkeyapi.c index 486737167a..d89967abb3 100644 --- a/src/rtl/inkeyapi.c +++ b/src/rtl/inkeyapi.c @@ -153,7 +153,7 @@ static const HB_KEY_VALUE s_transKeyStd[] = { { '=', K_ALT_EQUALS, 0, 0 }, /* 61 */ { '>', 0, 0, 0 }, /* 62 */ { '?', 0, K_CTRL_QUESTION, 0 }, /* 63 */ - { '@', 0, 0, 0 }, /* 64 */ + { '@', 0, 259, 0 }, /* 64 */ { 'A', K_ALT_A, K_CTRL_A, 0 }, /* 65 */ { 'B', K_ALT_B, K_CTRL_B, 0 }, /* 66 */ { 'C', K_ALT_C, K_CTRL_C, 0 }, /* 67 */ diff --git a/tests/gtkeys.prg b/tests/gtkeys.prg index 546ae8cf2e..02d3b6eeb8 100644 --- a/tests/gtkeys.prg +++ b/tests/gtkeys.prg @@ -17,16 +17,16 @@ REQUEST HB_CODEPAGE_PL852 REQUEST HB_CODEPAGE_PLWIN REQUEST HB_CODEPAGE_UTF8EX #else -#xtranslate hb_keyStd( n ) ( n ) -#xtranslate hb_keyCode( n ) Asc( n ) -#xtranslate hb_keyChar( c ) iif( c >= 32 .AND. c <= 255, Chr( c ), "" ) -#xtranslate hb_ntos( n ) LTrim( Str( n ) ) +#xtranslate hb_keyStd( ) => ( ) +#xtranslate hb_keyCode( ) => Asc( ) +#xtranslate hb_keyChar( ) => iif( >= 32 .AND. <= 255 .AND. != 127, Chr( ), "" ) +#xtranslate hb_ntos( ) => LTrim( Str( ) ) #endif #ifndef HB_K_RESIZE #define HB_K_RESIZE 1101 #endif -PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) +PROCEDURE Main( cTermCP, cHostCP, lBoxChar, lRawKey ) LOCAL k, kX, i, s LOCAL aKeys := { ; @@ -58,10 +58,10 @@ PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) { "K_RETURN", 13, "Return, Ctrl-M" }, ; { "K_SPACE", 32, "Space bar" }, ; { "K_ESC", 27, "Esc, Ctrl-[" }, ; - { "K_CTRL_ENTER", 10, "Ctrl-Enter" }, ; - { "K_CTRL_RETURN", 10, "Ctrl-Return" }, ; + { "K_CTRL_ENTER", 10, "Ctrl-Enter, Ctrl-J" }, ; + { "K_CTRL_RETURN", 10, "Ctrl-Return, Ctrl-J" }, ; { "K_CTRL_RET", 10, "Ctrl-Return (Compat.)" }, ; - { "K_CTRL_PRTSCR", 379, "Ctrl-Print Screen" }, ; + { "K_CTRL_PRTSCR", 379, "Ctrl-Print Screen, Alt-4" }, ; { "K_ALT_COMMA", 307, "Alt-," }, ; { "K_ALT_PERIOD", 308, "Alt-." }, ; { "K_CTRL_QUESTION", 309, "Ctrl-?, Alt-Slash" }, ; @@ -262,6 +262,14 @@ PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) // hb_gtInfo( HB_GTI_ALTENTER, .T. ) hb_gtInfo( HB_GTI_CLOSABLE, .F. ) hb_gtInfo( HB_GTI_SELECTCOPY, .T. ) + IF PCount() >= 4 + lRawKey := !Empty( lRawKey ) + ELSEIF ! Empty( cTermCP ) .AND. Upper( cTermCP ) = "X" + lRawKey := .T. + cTermCP := NIL + ELSE + lRawKey := .F. + ENDIF IF Empty( cTermCP ) cTermCP := "UTF8" ELSE @@ -279,6 +287,7 @@ PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) #ifdef _SET_EVENTMASK Set( _SET_EVENTMASK, INKEY_ALL ) #endif + lRawKey := .f. #endif MDblClk( 250 ) @@ -298,18 +307,31 @@ PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) k := hb_keyStd( kX ) IF ( i := AScan( aKeys, {| x | x[ 2 ] == k } ) ) != 0 ? " key:" + Str( aKeys[ i, 2 ], 7 ) + " " + PadR( aKeys[ i, 1 ], 18 ) + aKeys[ i, 3 ] +#ifdef __HARBOUR__ + IF kX != k + ?? " ext: 0x" + hb_numToHex( kX, 8 ) + " -> " + ; + hb_numToHex( hb_keyMod( kX ), 2 ) + ":" + hb_numToHex( hb_keyVal( kX ), 8 ) + ; + " [" + hb_keyChar( k ) + "]" + ENDIF +#endif ELSEIF ( k >= 32 .AND. k <= 126 ) .OR. ( k >= 160 .AND. k <= 255 ) .OR. ; Len( hb_keyChar( k ) ) > 0 #ifdef __HARBOUR__ ? "char:" + iif( k > 256, " U+" + hb_numToHex( hb_keyVal( k ), 4 ), Str( k, 7 ) ) + ; " " + hb_keyChar( k ) + IF kX != k .or. k > 256 + ?? " ext: 0x" + hb_numToHex( kX, 8 ) + " -> " + ; + hb_numToHex( hb_keyMod( kX ), 2 ) + ":" + hb_numToHex( hb_keyVal( kX ), 8 ) + ; + " [" + hb_keyChar( k ) + "]" + ENDIF #else ? "char:" + Str( k, 7 ) + " " + hb_keyChar( k ) #endif ELSE #ifdef __HARBOUR__ ? " key:" + Str( k, 7 ) + " ext: 0x" + hb_numToHex( kX, 8 ) + " -> " + ; - hb_numToHex( hb_keyMod( kX ), 2 ) + ":" + hb_numToHex( hb_keyVal( kX ), 8 ) + hb_numToHex( hb_keyMod( kX ), 2 ) + ":" + hb_numToHex( hb_keyVal( kX ), 8 ) + ; + " [" + hb_keyChar( k ) + "]" #else ? " key:" + Str( k, 7 ) #endif @@ -318,7 +340,7 @@ PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) IF k == hb_keyCode( "@" ) .AND. NextKey() == 0 EXIT - ELSEIF k == K_INS + ELSEIF k == K_INS .AND. ! lRawKey Set( _SET_CURSOR, ( Set( _SET_CURSOR ) + 1 ) % 5 ) ?? " cursor:" + hb_ntos( Set( _SET_CURSOR ) ) ELSEIF k == HB_K_RESIZE @@ -326,12 +348,12 @@ PROCEDURE Main( cTermCP, cHostCP, lBoxChar ) ELSEIF k >= 1000 .AND. k < 1100 ?? " mpos(" + hb_ntos( MRow() ) + "," + hb_ntos( MCol() ) + ")" #ifdef __HARBOUR__ - ELSEIF k == K_CTRL_INS + ELSEIF k == K_CTRL_INS .AND. ! lRawKey IF Alert( "Would you like to show clipboard text?", { "YES", "NO" } ) == 1 s := hb_gtInfo( HB_GTI_CLIPBOARDDATA ) ? "Clipboard text: [" + s + "]" ENDIF - ELSEIF k == K_CTRL_END + ELSEIF k == K_CTRL_END .AND. ! lRawKey IF Alert( "Would you like to set clipboard text?", { "YES", "NO" } ) == 1 s := hb_TSToStr( hb_DateTime() ) + hb_eol() + ; "Harbour GT" + hb_gtVersion() + " clipboard test" + hb_eol()