From 7ddafb70d232a446f9acf5a371bc80e4c4276a1b Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 19 Mar 2000 18:17:31 +0000 Subject: [PATCH] 20000319-19:11 GMT+1 Victor Szakats --- harbour/ChangeLog | 14 + harbour/include/hbapigt.h | 32 +- harbour/source/rtl/diskspac.c | 6 +- harbour/source/rtl/filesys.c | 5 +- harbour/source/rtl/gt/gt_tpl.c | 6 +- harbour/source/rtl/gt/gtcrs.c | 390 +++++++++++++-------- harbour/source/rtl/gt/gtdos.c | 223 ++++++++++-- harbour/source/rtl/gt/gtos2.c | 156 ++++++++- harbour/source/rtl/gt/gtpca.c | 23 +- harbour/source/rtl/gt/gtsln.c | 6 +- harbour/source/rtl/gt/gtstd.c | 11 +- harbour/source/rtl/gt/gtwin.c | 407 ++++++++++++++++++++- harbour/source/rtl/gtapi.c | 57 +-- harbour/source/rtl/inkey.c | 621 +-------------------------------- 14 files changed, 1090 insertions(+), 867 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 342490060d..9805f350f8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,17 @@ +20000319-19:11 GMT+1 Victor Szakats + * include/hbapigt.h + source/rtl/gtapi.c + source/rtl/inkey.c + source/rtl/gt/*.c + + The multiplatform inkeypoll code has been moved to the proper GT + drivers. Now the GT driver is completely self containing. + !! WARNING !! Please test this on your system with your compiler. + Tested with: W32/BCC55, DOS/BCC31 + * source/rtl/filesys.c + % Double #include removed. + * source/rtl/diskspac.c + ! Fix for DOS. + 20000319-17:47 GMT+1 Victor Szakats * include/hbsetup.h ! __WINDOWS__ -> _WINDOWS_ diff --git a/harbour/include/hbapigt.h b/harbour/include/hbapigt.h index ed0b7938a0..7e1ac896e2 100644 --- a/harbour/include/hbapigt.h +++ b/harbour/include/hbapigt.h @@ -68,6 +68,20 @@ #define _B_SINGLE_DOUBLE "ÖÄ·º½ÄÓº" #define _B_DOUBLE_SINGLE "Õ͸³¾ÍÔ³" +/* Keyboard filters */ + +typedef enum +{ + INKEY_MOVE = 1, /* Mouse Events */ + INKEY_LDOWN = 2, /* Mouse Left Click Down */ + INKEY_LUP = 4, /* Mouse Left Click Up */ + INKEY_RDOWN = 8, /* Mouse Right Click Down */ + INKEY_RUP = 16, /* Mouse Right Click Up */ + INKEY_KEYBOARD = 128, /* Keyboard Events */ + INKEY_ALL = 159, /* All Mouse and Keyboard Events */ + INKEY_EXTENDED = 256 /* Extended Keyboard Events */ +} HB_inkey_enum; + /* Cursor style constants */ typedef enum @@ -83,7 +97,7 @@ typedef enum extern void hb_gtInit( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr ); extern void hb_gtExit( void ); -extern int hb_gtReadKey( void ); +extern int hb_gtReadKey( HB_inkey_enum eventmask ); extern void hb_gtAdjustPos( int iHandle, char * pStr, ULONG ulLen ); extern USHORT hb_gtBox( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbyBoxString ); extern USHORT hb_gtBoxD( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight ); @@ -125,7 +139,7 @@ extern void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr extern BOOL hb_gt_IsColor( void ); extern void hb_gt_Done( void ); extern BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ); -extern int hb_gt_ReadKey( void ); +extern int hb_gt_ReadKey( HB_inkey_enum eventmask ); extern USHORT hb_gt_GetScreenWidth( void ); extern USHORT hb_gt_GetScreenHeight( void ); extern void hb_gt_SetPos( SHORT iRow, SHORT iCol ); @@ -148,17 +162,9 @@ extern void hb_gt_Tone( double dFrequency, double dDuration ); /* Keyboard related declarations */ -typedef enum -{ - INKEY_MOVE = 1, /* Mouse Events */ - INKEY_LDOWN = 2, /* Mouse Left Click Down */ - INKEY_LUP = 4, /* Mouse Left Click Up */ - INKEY_RDOWN = 8, /* Mouse Right Click Down */ - INKEY_RUP = 16, /* Mouse Right Click Up */ - INKEY_KEYBOARD = 128, /* Keyboard Events */ - INKEY_ALL = 159, /* All Mouse and Keyboard Events */ - INKEY_EXTENDED = 256 /* Extended Keyboard Events */ -} HB_inkey_enum; +#define HB_BREAK_FLAG 256 /* 256, because that's what DJGPP returns Ctrl+Break as. + Clipper has no key code 256, so it may as well be + used for all the Harbour builds that need it */ /* Harbour keyboard support functions */ extern int hb_inkey ( double seconds, HB_inkey_enum event_mask, BOOL wait, BOOL forever ); /* Wait for keyboard input */ diff --git a/harbour/source/rtl/diskspac.c b/harbour/source/rtl/diskspac.c index 63f6bc37ed..d6d06ff184 100644 --- a/harbour/source/rtl/diskspac.c +++ b/harbour/source/rtl/diskspac.c @@ -48,13 +48,13 @@ #include +#include "hbapi.h" +#include "hbapierr.h" + #if defined(DOS) || defined(__WATCOMC__) #include #endif -#include "hbapi.h" -#include "hbapierr.h" - HARBOUR HB_DISKSPACE( void ) { ULONG ulSpaceFree = 0; diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index 0ed5f062e1..3237730720 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -117,11 +117,10 @@ #if defined(__BORLANDC__) || defined(__IBMCPP__) || defined(_MSC_VER) || defined(__MINGW32__) #include - #include - #include #include - #include + #include #include + #include #if defined(__BORLANDC__) #include #include diff --git a/harbour/source/rtl/gt/gt_tpl.c b/harbour/source/rtl/gt/gt_tpl.c index f454e358a6..b72397a482 100644 --- a/harbour/source/rtl/gt/gt_tpl.c +++ b/harbour/source/rtl/gt/gt_tpl.c @@ -53,9 +53,11 @@ void hb_gt_Done( void ) /* TODO: */ } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); + + HB_SYMBOL_UNUSED( eventmask ); /* TODO: */ diff --git a/harbour/source/rtl/gt/gtcrs.c b/harbour/source/rtl/gt/gtcrs.c index d8c0da3dc8..de476f7bd4 100644 --- a/harbour/source/rtl/gt/gtcrs.c +++ b/harbour/source/rtl/gt/gtcrs.c @@ -7,7 +7,6 @@ * Video subsystem based on ncurses. * * Copyright 1999 Gonzalo Diethelm - * * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify @@ -36,14 +35,17 @@ #include -#include "gtapi.h" -#include "inkey.ch" +#include "hbapigt.h" +#include "hbinit.h" static void gt_GetMaxRC(int* r, int* c); static void gt_GetRC(int* r, int* c); static void gt_SetRC(int r, int c); -static int iKeyTable[] = { +static struct termios startup_attributes; + +static int iKeyTable[] = +{ KEY_DOWN, K_DOWN, KEY_UP, K_UP, KEY_LEFT, K_LEFT, @@ -77,288 +79,372 @@ static int iKeyTable[] = { KEY_F(20), K_SH_F10, KEY_F(21), K_CTRL_F1, KEY_BTAB, K_SH_TAB - }; +}; +#if defined(OS_UNIX_COMPATIBLE) +#include +#include -void hb_gt_Init( void ) +static void restore_input_mode( void ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Init()")); + HB_TRACE(HB_TR_DEBUG, ("restore_input_mode()")); - initscr(); - if( has_colors() ) - { - int i; - start_color(); - for( i = 1; i <= COLOR_PAIRS; i++ ) - { - init_pair( i, i % COLORS, i / COLORS ); - } - /* NOTE: color order= - COLOR_BLACK - COLOR_RED - COLOR_GREEN - COLOR_YELLOW - COLOR_BLUE - COLOR_MAGENTA - COLOR_CYAN - COLOR_WHITE - */ - } - cbreak(); - noecho(); - nodelay(stdscr, 1); - keypad( stdscr, TRUE ); + tcsetattr( STDIN_FILENO, TCSANOW, &startup_attributes ); +} + +HB_CALL_ON_STARTUP_BEGIN( init_input_mode ) + struct termios ta; + + tcgetattr( STDIN_FILENO, &startup_attributes ); + atexit( restore_input_mode ); + + tcgetattr( STDIN_FILENO, &ta ); + ta.c_lflag &= ~( ICANON | ECHO ); + ta.c_iflag &= ~ICRNL; + ta.c_cc[ VMIN ] = 0; + ta.c_cc[ VTIME ] = 0; + tcsetattr( STDIN_FILENO, TCSAFLUSH, &ta ); +HB_CALL_ON_STARTUP_END( init_input_mode ) + +void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Init()")); + + initscr(); + if( has_colors() ) + { + int i; + start_color(); + for( i = 1; i <= COLOR_PAIRS; i++ ) + { + init_pair( i, i % COLORS, i / COLORS ); + } + /* NOTE: color order= + COLOR_BLACK + COLOR_RED + COLOR_GREEN + COLOR_YELLOW + COLOR_BLUE + COLOR_MAGENTA + COLOR_CYAN + COLOR_WHITE + */ + } + cbreak(); + noecho(); + nodelay( stdscr, 1 ); + keypad( stdscr, TRUE ); } void hb_gt_Done( void ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Done()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Done()")); - refresh(); - endwin(); + refresh(); + endwin(); } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { int ch; - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); + + HB_SYMBOL_UNUSED( eventmask ); ch = getch(); - if (ch == ERR) { - ch = 0; - } + if( ch == ERR ) + ch = 0; else { - int i; - for( i=0; i<(sizeof(iKeyTable)/sizeof(int)); i++ ) - if( iKeyTable[ i++ ] == ch ) - return iKeyTable[ i ]; + int i; + for( i = 0; i < ( sizeof( iKeyTable ) / sizeof( int ) ); i++ ) + if( iKeyTable[ i++ ] == ch ) + return iKeyTable[ i ]; } - + return ch; } +BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) +{ + int row, col, max_row, max_col; + ULONG ulCount; + + HB_TRACE(HB_TR_DEBUG, ("hb_gt_AdjustPos(%s, %lu)", pStr, ulLen )); + + gt_GetRC( &row, &col ); + gt_GetMaxRC( &max_row, &max_col ); + for( ulCount = 0; ulCount < ulLen; ulCount++ ) + { + switch( *pStr++ ) + { + case HB_CHAR_BEL: + break; + + case HB_CHAR_BS: + if( col ) + col--; + else + { + col = max_col; + if( row ) + row--; + } + break; + + case HB_CHAR_LF: + if( row < max_row ) + row++; + break; + + case HB_CHAR_CR: + col = 0; + break; + + default: + if( col < max_col ) + col++; + else + { + col = 0; + if( row < max_row ) + row++; + } + } + } + gt_SetRC( row, col ); + return TRUE; +} + BOOL hb_gt_IsColor( void ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_IsColor()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_IsColor()")); - return has_colors(); /* returns TRUE or FALSE */ + return has_colors(); /* returns TRUE or FALSE */ } USHORT hb_gt_GetScreenWidth( void ) { - int r, c; + int r, c; - HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenWidth()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenWidth()")); - gt_GetMaxRC(&r, &c); - return c; + gt_GetMaxRC(&r, &c); + return c; } USHORT hb_gt_GetScreenHeight( void ) { - int r, c; + int r, c; - HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenHeight()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenHeight()")); - gt_GetMaxRC(&r, &c); - return r; + gt_GetMaxRC(&r, &c); + return r; } -void hb_gt_SetPos( USHORT uiRow, USHORT uiCol ) +void hb_gt_SetPos( SHORT iRow, SHORT iCol ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetPos(%hu, %hu)", uiRow, uiCol)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetPos(%hd, %hd)", iRow, iCol)); - gt_SetRC(uiRow, uiCol); + gt_SetRC(iRow, iCol); } -USHORT hb_gt_Col( void ) +SHORT hb_gt_Col( void ) { - int r, c; + int r, c; - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Col()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Col()")); - gt_GetRC(&r, &c); - return c; + gt_GetRC(&r, &c); + return c; } -USHORT hb_gt_Row( void ) +SHORT hb_gt_Row( void ) { - int r, c; + int r, c; - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Row()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Row()")); - gt_GetRC(&r, &c); - return r; + gt_GetRC(&r, &c); + return r; } USHORT hb_gt_GetCursorStyle( void ) { - USHORT usOldCursor = curs_set( 0 ); - - HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetCursorStyle()")); - curs_set( usOldCursor ); - - return (usOldCursor ? SC_INSERT : SC_NONE); + USHORT usOldCursor = curs_set( 0 ); + + HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetCursorStyle()")); + + curs_set( usOldCursor ); + + return usOldCursor ? SC_INSERT : SC_NONE; } void hb_gt_SetCursorStyle( USHORT uiStyle ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetCursorStyle(%hu)", uiStyle)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetCursorStyle(%hu)", uiStyle)); - /* TODO: How to set the cursor shape? */ - if( uiStyle == SC_NONE ) + /* TODO: How to set the cursor shape? */ + if( uiStyle == SC_NONE ) curs_set( 0 ); - else + else curs_set( 1 ); } void hb_gt_Puts( USHORT uiRow, - USHORT uiCol, - BYTE byAttr, - BYTE * pbyStr, - ULONG ulLen ) + USHORT uiCol, + BYTE byAttr, + BYTE * pbyStr, + ULONG ulLen ) { - ULONG i; + ULONG i; - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Puts(%hu, %hu, %d, %p, %lu)", uiRow, uiCol, (int) byAttr, pbyStr, ulLen)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Puts(%hu, %hu, %d, %p, %lu)", uiRow, uiCol, (int) byAttr, pbyStr, ulLen)); - move(uiRow, uiCol); - attron( COLOR_PAIR( byAttr ) ); - for (i = 0; i < ulLen; ++i) { - addch(pbyStr[i]); - } + move( uiRow, uiCol ); + attron( COLOR_PAIR( byAttr ) ); + for( i = 0; i < ulLen; ++i ) + addch( pbyStr[ i ] ); } void hb_gt_GetText( USHORT uiTop, - USHORT uiLeft, - USHORT uiBottom, - USHORT uiRight, - BYTE * pbyDst ) + USHORT uiLeft, + USHORT uiBottom, + USHORT uiRight, + BYTE * pbyDst ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetText(%hu, %hu, %hu, %hu, %p)", uiTop, uiLeft, uiBottom, uiRight, pbyDst)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetText(%hu, %hu, %hu, %hu, %p)", uiTop, uiLeft, uiBottom, uiRight, pbyDst)); - /* TODO */ + /* TODO */ } void hb_gt_PutText( USHORT uiTop, - USHORT uiLeft, - USHORT uiBottom, - USHORT uiRight, - BYTE * pbySrc ) + USHORT uiLeft, + USHORT uiBottom, + USHORT uiRight, + BYTE * pbySrc ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_PutText(%hu, %hu, %hu, %hu, %p)", uiTop, uiLeft, uiBottom, uiRight, pbySrc)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_PutText(%hu, %hu, %hu, %hu, %p)", uiTop, uiLeft, uiBottom, uiRight, pbySrc)); - /* TODO */ + /* TODO */ } void hb_gt_SetAttribute( USHORT uiTop, - USHORT uiLeft, - USHORT uiBottom, - USHORT uiRight, - BYTE byAttr ) + USHORT uiLeft, + USHORT uiBottom, + USHORT uiRight, + BYTE byAttr ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetAttribute(%hu, %hu, %hu, %hu, %d)", uiTop, uiLeft, uiBottom, uiRight, (int) byAttr)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetAttribute(%hu, %hu, %hu, %hu, %d)", uiTop, uiLeft, uiBottom, uiRight, (int) byAttr)); - /* TODO: we want to take a screen that is say bright white on blue, - and change the attributes only for a section of the screen - to white on black. - */ + /* TODO: we want to take a screen that is say bright white on blue, + and change the attributes only for a section of the screen + to white on black. + */ } void hb_gt_Scroll( USHORT uiTop, - USHORT uiLeft, - USHORT uiBottom, - USHORT uiRight, - BYTE byAttr, - SHORT iRows, - SHORT iCols ) + USHORT uiLeft, + USHORT uiBottom, + USHORT uiRight, + BYTE byAttr, + SHORT iRows, + SHORT iCols ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Scroll(%hu, %hu, %hu, %hu, %d, %hd, %hd)", uiTop, uiLeft, uiBottom, uiRight, (int) byAttr, iRows, iCols)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Scroll(%hu, %hu, %hu, %hu, %d, %hd, %hd)", uiTop, uiLeft, uiBottom, uiRight, (int) byAttr, iRows, iCols)); - /* TODO */ + /* TODO */ } void hb_gt_DispBegin( void ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispBegin()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispBegin()")); - /* TODO: Is there a way to change screen buffers? - ie: can we write somewhere without it going to the screen - and then update the screen from this buffer at a later time? - We will initially want to copy the current screen to this buffer. - */ + /* TODO: Is there a way to change screen buffers? + ie: can we write somewhere without it going to the screen + and then update the screen from this buffer at a later time? + We will initially want to copy the current screen to this buffer. + */ } void hb_gt_DispEnd() { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispEnd()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispEnd()")); - /* TODO: here we flush the buffer, and restore normal screen writes */ + /* TODO: here we flush the buffer, and restore normal screen writes */ } BOOL hb_gt_SetMode( USHORT uiRows, USHORT uiCols ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetMode(%hu, %hu)", uiRows, uiCols)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetMode(%hu, %hu)", uiRows, uiCols)); - /* TODO: How to change the size of the screen? */ - return TRUE; + /* TODO: How to change the size of the screen? */ + return TRUE; } void hb_gt_Replicate( BYTE byChar, ULONG ulLen ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_Replicate(%d, %lu)", (int) byChar, ulLen)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Replicate(%d, %lu)", (int) byChar, ulLen)); - /* TODO: this will write character c nlength times to the screen. - Note that it is not used yet - If there is no native function that supports this, it is - already handled in a generic way by higher level functions. - */ + /* TODO: this will write character c nlength times to the screen. + Note that it is not used yet + If there is no native function that supports this, it is + already handled in a generic way by higher level functions. + */ } BOOL hb_gt_GetBlink() { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetBlink()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetBlink()")); - /* TODO: under dos, the background 'intensity' bit can be switched - from intensity to 'blinking' - does this work under your platform? - */ - return FALSE; + /* TODO: under dos, the background 'intensity' bit can be switched + from intensity to 'blinking' + does this work under your platform? + */ + return FALSE; } void hb_gt_SetBlink( BOOL bBlink ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetBlink(%d)", (int) bBlink)); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetBlink(%d)", (int) bBlink)); - /* TODO: set the bit if it's supported */ if( bBlink ) attron( A_BLINK ); else attroff( A_BLINK ); } +void hb_gt_Tone( double dFrequency, double dDuration ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_Tone(%lf, %lf)", dFrequency, dDuration)); + + /* TODO: Implement this */ + + HB_SYMBOL_UNUSED( dFrequency ); + HB_SYMBOL_UNUSED( dDuration ); +} static void gt_GetMaxRC(int* r, int* c) { - int y, x; - getmaxyx(stdscr, y, x); - *r = y; - *c = x; + int y, x; + getmaxyx(stdscr, y, x); + *r = y; + *c = x; } static void gt_GetRC(int* r, int* c) { - int y, x; - getyx(stdscr, y, x); - *r = y; - *c = x; + int y, x; + getyx(stdscr, y, x); + *r = y; + *c = x; } static void gt_SetRC(int r, int c) { - move(r, c); - refresh(); + move(r, c); + refresh(); } diff --git a/harbour/source/rtl/gt/gtdos.c b/harbour/source/rtl/gt/gtdos.c index 68e623f7b1..5f14e7e6f0 100644 --- a/harbour/source/rtl/gt/gtdos.c +++ b/harbour/source/rtl/gt/gtdos.c @@ -52,24 +52,41 @@ /* NOTE: User programs should never call this layer directly! */ -#include -#include - -/* For hb_gt_Tone() support */ -#if defined(__DJGPP__) - #include - #include -#elif defined(__BORLANDC__) - #include -#elif defined(__WATCOMC__) - #include - #include -#endif - #include "hbapigt.h" #include "hbset.h" /* For Ctrl+Break handling */ #include "hbvm.h" /* For Ctrl+Break handling */ +#include "inkey.ch" +#include +#include +#include +#include + +#if defined(__DJGPP__) + #include + #include + #include +#elif defined(__WATCOMC__) + #include +#endif + +#if defined(__WATCOMC__) + #if defined(__386__) && !defined(__WINDOWS_386__) + #define INT_86 int386 + #define DOS_REGS REGS + #else + #define INT_86 int86 + #define DOS_REGS REGS + #endif +#elif defined(_MSC_VER) + #define INT_86 _int86 + #define DOS_REGS _REGS +#else + #define INT_86 int86 + #define DOS_REGS REGS +#endif + +/* For screen support */ #if defined(__POWERC) || (defined(__TURBOC__) && !defined(__BORLANDC__)) || \ (defined(__ZTC__) && !defined(__SC__)) #define FAR far @@ -79,11 +96,7 @@ #define FAR #endif -#if defined(__DJGPP__) - #include - #include - #include -#else +#if !defined(__DJGPP__) #ifndef MK_FP #define MK_FP( seg, off ) \ ((void FAR *)(((unsigned long)(seg) << 16)|(unsigned)(off))) @@ -110,7 +123,7 @@ static void hb_gt_GetCursorSize( char * start, char * end ); #endif #ifndef __DJGPP__ -BOOL hb_gtBreak = FALSE; /* Used to signal Ctrl+Break to hb_inkeyPoll() */ +static BOOL s_bBreak = FALSE; /* Used to signal Ctrl+Break to hb_inkeyPoll() */ #if defined(__WATCOMC__) static void hb_gt_Watcom_CtrlBreak_Handler( int iSignal ) { @@ -118,7 +131,7 @@ static void hb_gt_Watcom_CtrlBreak_Handler( int iSignal ) /* NOTE: the layout of this function is forced by the Watcom compiler */ HB_SYMBOL_UNUSED( iSignal ); - hb_gtBreak = TRUE; + s_bBreak = TRUE; } #else static int s_iOldCtrlBreak = 0; @@ -126,7 +139,7 @@ static int s_iOldCtrlBreak = 0; static int hb_gt_CtrlBrkHandler( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_gt_CtrlBrkHandler()")); - hb_gtBreak = TRUE; + s_bBreak = TRUE; return 1; } #endif @@ -185,13 +198,171 @@ void hb_gt_Done( void ) #endif } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + int ch = 0; - /* TODO: */ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); - return 0; +#if defined(__DJGPP__) + /* Check to see if Ctrl+Break has been detected */ + 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 */ + } +#else + /* First check for Ctrl+Break, which is handled by gt/gtdos.c, + with the exception of the DJGPP compiler */ + if( s_bBreak ) + { + s_bBreak = FALSE; /* Indicate that Ctrl+Break has been handled */ + ch = 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( eventmask & INKEY_EXTENDED ) ch = getxkey(); + else ch = getkey(); + if( ch == 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; +#else + /* A key code is available in the BIOS keyboard buffer */ + ch = getch(); /* Get the key code */ + 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; + } + else if( ch == 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( eventmask & INKEY_EXTENDED ) ch = getch() + 512; + else ch = getch() + 256; + } +#endif + } + + /* Perform key translations */ + switch( ch ) + { + case -1: /* No key available */ + return 0; + case 328: /* Up arrow */ + ch = K_UP; + break; + case 336: /* Down arrow */ + ch = K_DOWN; + break; + case 331: /* Left arrow */ + ch = K_LEFT; + break; + case 333: /* Right arrow */ + ch = K_RIGHT; + break; + case 327: /* Home */ + ch = K_HOME; + break; + case 335: /* End */ + ch = K_END; + break; + case 329: /* Page Up */ + ch = K_PGUP; + break; + case 337: /* Page Down */ + ch = K_PGDN; + break; + case 371: /* Ctrl + Left arrow */ + ch = K_CTRL_LEFT; + break; + case 372: /* Ctrl + Right arrow */ + ch = K_CTRL_RIGHT; + break; + case 375: /* Ctrl + Home */ + ch = K_CTRL_HOME; + break; + case 373: /* Ctrl + End */ + ch = K_CTRL_END; + break; + case 388: /* Ctrl + Page Up */ + ch = K_CTRL_PGUP; + break; + case 374: /* Ctrl + Page Down */ + ch = K_CTRL_PGDN; + break; + case 338: /* Insert */ + ch = K_INS; + break; + case 339: /* Delete */ + ch = K_DEL; + break; + case 315: /* F1 */ + ch = K_F1; + 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 */ + ch = 315 - ch; + 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 */ + ch = 330 - ch; + 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 */ + ch = 349 - ch; + } + + return ch; } BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) diff --git a/harbour/source/rtl/gt/gtos2.c b/harbour/source/rtl/gt/gtos2.c index 768a9f3e14..8806255098 100644 --- a/harbour/source/rtl/gt/gtos2.c +++ b/harbour/source/rtl/gt/gtos2.c @@ -100,13 +100,161 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) return TRUE; } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + int ch; - /* TODO: */ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); - return 0; +#if defined(HARBOUR_GCC_OS2) + + /* Read from the keyboard with no echo, no wait, and no SIGSEV on Ctrl-C */ + ch = _read_kbd( 0, 0, 0 ); + if( ch == 0 ) + { + /* It's a function key lead-in, so read the function key scan code */ + ch = _read_kbd( 0, 0, 0 ); + if( ch != -1 ) ch += 256; /* If it's really a scan code, offset it */ + } + /* _read_kbd() returns -1 for no key, the switch statement will handle + this. */ +#else + + if( kbhit() ) + { + /* A key code is available in the BIOS keyboard buffer, so read it */ + ch = getch(); /* Get the key code */ + 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; + } + else if( ch == 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( s_eventmask & INKEY_EXTENDED ) ch = getch() + 512; + else ch = getch() + 256; + } + } + else + ch = 0; +#endif + + /* Perform key translations */ + switch( ch ) + { + case -1: /* No key available */ + return; + case 328: /* Up arrow */ + ch = K_UP; + break; + case 336: /* Down arrow */ + ch = K_DOWN; + break; + case 331: /* Left arrow */ + ch = K_LEFT; + break; + case 333: /* Right arrow */ + ch = K_RIGHT; + break; + case 327: /* Home */ + ch = K_HOME; + break; + case 335: /* End */ + ch = K_END; + break; + case 329: /* Page Up */ + ch = K_PGUP; + break; + case 337: /* Page Down */ + ch = K_PGDN; + break; + case 371: /* Ctrl + Left arrow */ + ch = K_CTRL_LEFT; + break; + case 372: /* Ctrl + Right arrow */ + ch = K_CTRL_RIGHT; + break; + case 375: /* Ctrl + Home */ + ch = K_CTRL_HOME; + break; + case 373: /* Ctrl + End */ + ch = K_CTRL_END; + break; + case 388: /* Ctrl + Page Up */ + ch = K_CTRL_PGUP; + break; + case 374: /* Ctrl + Page Down */ + ch = K_CTRL_PGDN; + break; + case 338: /* Insert */ + ch = K_INS; + break; + case 339: /* Delete */ + ch = K_DEL; + break; + case 315: /* F1 */ + ch = K_F1; + 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 */ + ch = 315 - ch; + 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 */ + ch = 330 - ch; + 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 */ + ch = 349 - ch; + } + + return ch; } BOOL hb_gt_IsColor( void ) diff --git a/harbour/source/rtl/gt/gtpca.c b/harbour/source/rtl/gt/gtpca.c index 1bedc59aa9..e874f14da9 100644 --- a/harbour/source/rtl/gt/gtpca.c +++ b/harbour/source/rtl/gt/gtpca.c @@ -40,19 +40,20 @@ /* NOTE: User programs should never call this layer directly! */ +#if defined(__GNUC__) && ! defined(__MINGW32__) + #include + #if defined(__DJGPP__) || defined(__CYGWIN__) || defined(HARBOUR_GCC_OS2) + #include + #endif +#else + #include +#endif #include #include #include "hbapigt.h" #include "hbset.h" -#if defined(__GNUC__) && ! defined(__MINGW32__) - #include -#endif -#if !defined(OS_UNIX_COMPATIBLE) - #include -#endif - static USHORT s_usRow, s_usCol, s_usMaxRow, s_usMaxCol; static int s_iFilenoStdin, s_iFilenoStdout, s_iFilenoStderr; static int s_iAttribute; @@ -176,10 +177,14 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) return TRUE; } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); + + HB_SYMBOL_UNUSED( eventmask ); + /* TODO: */ + return 0; } diff --git a/harbour/source/rtl/gt/gtsln.c b/harbour/source/rtl/gt/gtsln.c index 94b7ddd6ae..e6ff5c080a 100644 --- a/harbour/source/rtl/gt/gtsln.c +++ b/harbour/source/rtl/gt/gtsln.c @@ -61,9 +61,11 @@ void hb_gt_Done( void ) SLang_reset_tty(); } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); + + HB_SYMBOL_UNUSED( eventmask ); /* TODO: */ diff --git a/harbour/source/rtl/gt/gtstd.c b/harbour/source/rtl/gt/gtstd.c index 93f377adae..8348d2b599 100644 --- a/harbour/source/rtl/gt/gtstd.c +++ b/harbour/source/rtl/gt/gtstd.c @@ -71,9 +71,16 @@ void hb_gt_Done( void ) HB_TRACE(HB_TR_DEBUG, ("hb_gt_Done()")); } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); + + HB_SYMBOL_UNUSED( eventmask ); + +#if defined(OS_UNIX_COMPATIBLE) + if( ! read( STDIN_FILENO, &ch, 1 ) ) + ch = 0; +#endif /* TODO: */ diff --git a/harbour/source/rtl/gt/gtwin.c b/harbour/source/rtl/gt/gtwin.c index 5db71b6332..7d7a2ae2cc 100644 --- a/harbour/source/rtl/gt/gtwin.c +++ b/harbour/source/rtl/gt/gtwin.c @@ -62,6 +62,7 @@ #include "hbapigt.h" #include "hbset.h" /* For Ctrl+Break handling */ #include "hbvm.h" /* For Ctrl+Break handling */ +#include "inkey.ch" #if defined(__IBMCPP__) #undef WORD /* 2 bytes unsigned */ @@ -90,9 +91,18 @@ static HANDLE s_HOutput = INVALID_HANDLE_VALUE; static HANDLE s_HActive = INVALID_HANDLE_VALUE; static HANDLE s_HInactive = INVALID_HANDLE_VALUE; static BOOL s_bOldCursor = TRUE; +static HANDLE s_HInput = INVALID_HANDLE_VALUE; +static BOOL s_bBreak = FALSE; -HANDLE hb_gtHInput = INVALID_HANDLE_VALUE; -BOOL hb_gtBreak = FALSE; /* Used to signal Ctrl+Break to hb_inkeyPoll() */ +#define INPUT_BUFFER_LEN 128 + +static DWORD s_cNumRead = 0; /* Ok to use DWORD here, because this is specific... */ +static DWORD s_cNumIndex = 0; /* ...to the Windows API, which defines DWORD, etc. */ +static INPUT_RECORD s_irInBuf[ INPUT_BUFFER_LEN ]; +static int s_mouseLast; /* Last mouse button to be pressed */ + +extern int hb_mouse_iCol; +extern int hb_mouse_iRow; static BOOL WINAPI hb_gt_CtrlHandler( DWORD dwCtrlType ) { @@ -107,7 +117,7 @@ static BOOL WINAPI hb_gt_CtrlHandler( DWORD dwCtrlType ) break; case CTRL_BREAK_EVENT: - hb_gtBreak = TRUE; + s_bBreak = TRUE; bHandled = TRUE; break; @@ -124,6 +134,7 @@ static BOOL WINAPI hb_gt_CtrlHandler( DWORD dwCtrlType ) void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr ) { HB_TRACE(HB_TR_DEBUG, ("hb_gt_Init(): %d, %d, %d", iFilenoStdin, iFilenoStdout, iFilenoStderr)); + HB_SYMBOL_UNUSED( iFilenoStdin ); HB_SYMBOL_UNUSED( iFilenoStdout ); HB_SYMBOL_UNUSED( iFilenoStderr ); @@ -131,17 +142,17 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr ) /* Add Ctrl+Break handler [vszakats] */ SetConsoleCtrlHandler( hb_gt_CtrlHandler, TRUE ); - if( ( hb_gtHInput = GetStdHandle( STD_INPUT_HANDLE ) ) == INVALID_HANDLE_VALUE ) + if( ( s_HInput = GetStdHandle( STD_INPUT_HANDLE ) ) == INVALID_HANDLE_VALUE ) { if( hb_dynsymFindName( "__DBGENTRY" ) ) /* the debugger is linked */ { AllocConsole(); /* It is a Windows app without a console, so we create one */ - hb_gtHInput = GetStdHandle( STD_INPUT_HANDLE ); + s_HInput = GetStdHandle( STD_INPUT_HANDLE ); } } - if( hb_gtHInput != INVALID_HANDLE_VALUE ) - SetConsoleMode( hb_gtHInput, ENABLE_MOUSE_INPUT ); + if( s_HInput != INVALID_HANDLE_VALUE ) + SetConsoleMode( s_HInput, ENABLE_MOUSE_INPUT ); /* ptucker */ s_HOriginal = CreateFile( "CONOUT$", /* filename */ @@ -201,8 +212,8 @@ void hb_gt_Done( void ) } /* NOTE: There's no need to close these explicitly, moreover if we close them functions using stdout will not show anything. - CloseHandle( hb_gtHInput ); - hb_gtHInput = INVALID_HANDLE_VALUE; + CloseHandle( s_HInput ); + s_HInput = INVALID_HANDLE_VALUE; CloseHandle( s_HOutput ); s_HOutput = INVALID_HANDLE_VALUE; */ @@ -217,13 +228,381 @@ void hb_gt_Done( void ) SetConsoleCtrlHandler( hb_gt_CtrlHandler, FALSE ); } -int hb_gt_ReadKey( void ) +int hb_gt_ReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey()")); + int ch = 0; - /* TODO: */ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_ReadKey(%d)", (int) event_mask)); - return 0; + /* First check for Ctrl+Break, which is handled by gt/gtwin.c */ + if( s_bBreak ) + { + /* Reset the global Ctrl+Break flag */ + s_bBreak = FALSE; + ch = HB_BREAK_FLAG; /* Indicate that Ctrl+Break was pressed */ + } + /* Check for events only when the event buffer is exhausted. */ + else if( s_cNumRead <= s_cNumIndex ) + { + /* Check for keyboard input */ + s_cNumRead = 0; + GetNumberOfConsoleInputEvents( s_HInput, &s_cNumRead ); + if( s_cNumRead ) + { + /* Read keyboard input */ + ReadConsoleInput( + s_HInput, /* input buffer handle */ + s_irInBuf, /* buffer to read into */ + INPUT_BUFFER_LEN, /* size of read buffer */ + &s_cNumRead); /* number of records read */ + /* Set up to process the first input event */ + s_cNumIndex = 0; + } + } + /* Only process one keyboard event at a time. */ + if( s_cNumRead > s_cNumIndex ) + { + if( s_irInBuf[ s_cNumIndex ].EventType == KEY_EVENT ) + { + /* Only process key down events */ + if( s_irInBuf[ s_cNumIndex ].Event.KeyEvent.bKeyDown ) + { + /* Save the keyboard state and ASCII key code */ + DWORD dwState = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.dwControlKeyState; + ch = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.uChar.AsciiChar; + if( ch < 0 ) + { + /* Process international key codes */ + ch += 256; + } + else if( ch == 0 || ( dwState & ( ENHANCED_KEY | LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED | RIGHT_CTRL_PRESSED | SHIFT_PRESSED ) ) ) + { + /* Process non-ASCII key codes */ + WORD wKey; + if( eventmask & INKEY_EXTENDED ) + wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualKeyCode; + else + wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualScanCode; + /* Discard standalone state key presses for normal mode only */ + if( ( eventmask & INKEY_EXTENDED ) == 0 ) switch( wKey ) + { + /* Virtual scan codes to ignore */ + case 29: /* Ctrl */ + case 42: /* Left Shift */ + case 54: /* Right Shift */ + case 56: /* Alt */ + case 69: /* Num Lock */ + case 70: /* Pause or Scroll Lock */ + wKey = 0; + } + if( wKey == 0 ) ch = 0; + else + { + if( eventmask & INKEY_EXTENDED ) + { + /* Pass along all virtual key codes with all + enhanced and state indicators accounted for */ + wKey += 256; + if( dwState & ENHANCED_KEY ) wKey += 512; + if( dwState & SHIFT_PRESSED ) wKey += 1024; + if( dwState & LEFT_CTRL_PRESSED ) wKey += 2048; + if( dwState & RIGHT_CTRL_PRESSED ) wKey += 4096; + if( dwState & LEFT_ALT_PRESSED ) wKey += 8192; + if( dwState & RIGHT_ALT_PRESSED ) wKey += 16384; + ch = wKey; + } + else + { + /* Translate virtual scan codes to Clipper codes */ + BOOL bAlt = dwState & ( LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED ); + BOOL bCtrl = dwState & ( LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED ); + BOOL bShift = dwState & SHIFT_PRESSED; + BOOL bEnhanced = dwState & ENHANCED_KEY; + + HB_TRACE(HB_TR_INFO, ("hb_inkeyPoll: wKey is %d, dwState is %d, ch is %d", wKey, dwState, ch)); + + if( bAlt ) + { + /* Alt key held */ + 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; + } + else if( bCtrl ) + { + /* Ctrl key held */ + if( wKey == 53 && bEnhanced ) ch = KP_CTRL_SLASH; /* Num Pad / */ + else if( wKey >= 59 && wKey <= 68 ) ch = 39 - wKey; /* F1 - F10 */ + 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 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; + } + } + else if( bShift ) + { + /* Shift key held */ + if( wKey == 53 && bEnhanced ) ch = '/'; /* Num Pad / */ + else if( wKey >= 59 && wKey <= 68 ) ch = 49 - wKey; /* F1 - F10 */ + 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 76: /* Num Pad 5 */ + ch = '5'; + break; + case 87: /* F11 */ + case 88: /* F12 */ + ch = 45 - wKey; + break; + case 82: /* Ins */ + ch = K_INS; + break; + case 83: /* Del */ + ch = K_DEL; + 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 80: /* Down */ + ch = K_DOWN; + break; + case 77: /* Right */ + ch = K_RIGHT; + break; + case 75: /* Left */ + ch = K_LEFT; + break; + default: /* Any thing not explicitly translated */ + if( ch == 0 ) + /* Only provide a translation for those key + codes that don't have a default one. */ + ch = wKey + 128; + } + } + else + { + /* Normal key */ + if( wKey == 28 ) ch = K_ENTER; /* Num Pad Enter */ + else if( wKey == 53 && bEnhanced ) ch = '/'; /* Num Pad / */ + else if( wKey == 59 ) ch = K_F1; /* F1 */ + else if( wKey > 59 && wKey <= 68 ) ch = 59 - wKey; /* F2 - F10 */ + else if( wKey == 76 ) ch = 332; /* Num Pad 5 */ + else if( wKey == 87 || wKey == 88 ) ch = 47 - wKey; /* F11, F12 */ + else switch( wKey ) + { + case 82: /* Ins */ + ch = K_INS; + break; + case 83: /* Del */ + ch = K_DEL; + 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 80: /* Down */ + ch = K_DOWN; + break; + case 77: /* Right */ + ch = K_RIGHT; + break; + case 75: /* Left */ + ch = K_LEFT; + break; + case 76: /* Num Pad 5 */ + ch = 332; + break; + case 28: /* Num pad Enter */ + ch = K_ENTER; + break; + default: + ch = wKey + 128; + } + } + } + } + } + +#if 0 + /* Debug code: */ + else + { + WORD wKey; + if( eventmask & INKEY_EXTENDED ) + wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualKeyCode; + else + wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualScanCode; + HB_TRACE(HB_TR_INFO, ("hb_inkeyPoll: wKey is %d", wKey)); + } +#endif + } + } + else if( eventmask & ~( INKEY_KEYBOARD | INKEY_EXTENDED ) + && s_irInBuf[ s_cNumIndex ].EventType == MOUSE_EVENT ) + { + + hb_mouse_iCol = s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwMousePosition.X; + hb_mouse_iRow = s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwMousePosition.Y; + + if( eventmask & INKEY_MOVE && s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == MOUSE_MOVED ) + ch = K_MOUSEMOVE; + + else if( eventmask & INKEY_LDOWN && s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwButtonState & + FROM_LEFT_1ST_BUTTON_PRESSED ) + { + if( s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == DOUBLE_CLICK ) + ch = K_LDBLCLK; + else + ch = K_LBUTTONDOWN; + + s_mouseLast = K_LBUTTONDOWN; + } + else if( eventmask & INKEY_RDOWN && s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwButtonState & + RIGHTMOST_BUTTON_PRESSED ) + { + if( s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == DOUBLE_CLICK ) + ch = K_RDBLCLK; + else + ch = K_RBUTTONDOWN; + + s_mouseLast = K_RBUTTONDOWN; + } + else if( s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == 0 && + s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwButtonState == 0 ) + { + if( eventmask & INKEY_LUP && s_mouseLast == K_LBUTTONDOWN ) + ch = K_LBUTTONUP; + else if( eventmask & INKEY_RUP && s_mouseLast == K_RBUTTONDOWN ) + ch = K_RBUTTONUP; + } + } + /* Set up to process the next input event (if any) */ + s_cNumIndex++; + } + + return ch; } BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) @@ -238,7 +617,7 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen ) GetConsoleScreenBufferInfo( s_HActive, &csbi ); hb_gtSetPos( csbi.dwCursorPosition.Y, csbi.dwCursorPosition.X ); - + return TRUE; } diff --git a/harbour/source/rtl/gtapi.c b/harbour/source/rtl/gtapi.c index 8d0cf7ad49..d3bdc5d911 100644 --- a/harbour/source/rtl/gtapi.c +++ b/harbour/source/rtl/gtapi.c @@ -55,18 +55,20 @@ * */ +#if defined(__GNUC__) && ! defined(__MINGW32__) + #include + #if defined(__DJGPP__) || defined(__CYGWIN__) || defined(HARBOUR_GCC_OS2) + #include + #endif +#else + #include +#endif + #include #include "hbapigt.h" #include "hbset.h" -#if defined(__GNUC__) && ! defined(__MINGW32__) - #include -#endif -#if !defined(OS_UNIX_COMPATIBLE) - #include -#endif - static SHORT s_iCurrentRow = 0; static SHORT s_iCurrentCol = 0; static USHORT s_uiDispCount = 0; @@ -111,11 +113,11 @@ void hb_gtExit( void ) hb_xfree( s_Color ); } -int hb_gtReadKey( void ) +int hb_gtReadKey( HB_inkey_enum eventmask ) { - HB_TRACE(HB_TR_DEBUG, ("hb_gtReadKey()")); + HB_TRACE(HB_TR_DEBUG, ("hb_gtReadKey(%d)", (int) event_mask)); - return hb_gt_ReadKey(); + return hb_gt_ReadKey( eventmask ); } void hb_gtAdjustPos( int iHandle, char * pStr, ULONG ulLen ) @@ -159,7 +161,9 @@ USHORT hb_gtBox( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, B if( uiTop > uiMaxRow || uiBottom > uiMaxRow || uiLeft > uiMaxCol || uiRight > uiMaxCol ) + { return 1; + } /* For full compatibility, pad box string with last char if too short */ @@ -184,6 +188,9 @@ USHORT hb_gtBox( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, B uiRight = tmp; } + uiRow = uiTop; + uiCol = uiLeft; + /* Draw the box or line as specified */ height = uiBottom - uiTop + 1; width = uiRight - uiLeft + 1; @@ -191,22 +198,17 @@ USHORT hb_gtBox( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, B hb_gtDispBegin(); if( height > 1 && width > 1 ) - hb_gtWriteAt( uiTop, uiLeft, pszBox + 0, sizeof( BYTE ) ); /* Upper left corner */ + hb_gtWriteAt( uiRow, uiCol, pszBox + 0, sizeof( BYTE ) ); /* Upper left corner */ - if( height == 1 ) - { - if( width > 1 ) - hb_gtRepChar( uiTop, uiLeft, pszBox[ 1 ], uiRight - uiLeft + 1 ); /* Top line */ - else - hb_gtRepChar( uiTop, uiLeft, pszBox[ 1 ], 1 ); /* Top line */ - } - else if( width > 2 ) - hb_gtRepChar( uiTop, uiLeft + 1, pszBox[ 1 ], uiRight - uiLeft - 1 ); /* Top line */ + uiCol = ( height > 1 ? uiLeft + 1 : uiLeft ); + + if( uiCol <= uiRight ) + hb_gtRepChar( uiRow, uiCol, pszBox[ 1 ], uiRight - uiLeft + ( height > 1 ? -1 : 1 ) ); /* Top line */ if( height > 1 && width > 1 ) - hb_gtWriteAt( uiTop, uiRight, pszBox + 2, sizeof( BYTE ) ); /* Upper right corner */ + hb_gtWriteAt( uiRow, uiRight, pszBox + 2, sizeof( BYTE ) ); /* Upper right corner */ - if( pszBox[ 8 ] && width > 2 && height > 2 ) + if( pszBox[ 8 ] && height > 2 && width > 2 ) { for( uiRow = uiTop + 1; uiRow < uiBottom; uiRow++ ) { @@ -216,7 +218,7 @@ USHORT hb_gtBox( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, B hb_gtWriteAt( uiRow, uiRight, pszBox + 3, sizeof( BYTE ) ); /* Right side */ } } - else if( height > 1 ) + else { for( uiRow = ( width > 1 ? uiTop + 1 : uiTop ); uiRow < ( width > 1 ? uiBottom : uiBottom + 1 ); uiRow++ ) { @@ -228,8 +230,13 @@ USHORT hb_gtBox( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, B if( height > 1 && width > 1 ) { - hb_gtWriteAt( uiBottom, uiLeft, pszBox + 6, sizeof( BYTE ) ); /* Bottom left corner */ - hb_gtRepChar( uiBottom, uiLeft + 1, pszBox[ 5 ], uiRight - uiLeft - 1 ); /* Bottom line */ + hb_gtWriteAt( uiBottom, uiCol , pszBox + 6, sizeof( BYTE ) ); /* Bottom left corner */ + + uiCol = ( height > 1 ? uiLeft + 1 : uiLeft ); + + if( uiCol <= uiRight && height > 1 ) + hb_gtRepChar( uiBottom, uiCol, pszBox[ 5 ], uiRight - uiLeft + ( height > 1 ? -1 : 1 ) ); /* Bottom line */ + hb_gtWriteAt( uiBottom, uiRight, pszBox + 4, sizeof( BYTE ) ); /* Bottom right corner */ } diff --git a/harbour/source/rtl/inkey.c b/harbour/source/rtl/inkey.c index 98219bb238..b1bdd0a522 100644 --- a/harbour/source/rtl/inkey.c +++ b/harbour/source/rtl/inkey.c @@ -96,24 +96,6 @@ #include "hbvm.h" #include "hbset.h" #include "inkey.ch" -#include "hbinit.h" - -#if (defined(_WINDOWS_) || defined(__NT__) || defined(WINNT)) && defined(HARBOUR_USE_WIN_GTAPI) - extern int hb_mouse_iCol; - extern int hb_mouse_iRow; - extern BOOL hb_gtBreak; /* This variable is located in source/rtl/gt/gtwin.c */ - extern HANDLE hb_gtHInput; /* This variable is located in source/rtl/gt/gtwin.c */ - - #define INPUT_BUFFER_LEN 128 - - static DWORD s_cNumRead = 0; /* Ok to use DWORD here, because this is specific... */ - static DWORD s_cNumIndex = 0; /* ...to the Windows API, which defines DWORD, etc. */ - static INPUT_RECORD s_irInBuf[ INPUT_BUFFER_LEN ]; -#endif - -#define HB_BREAK_FLAG 256 /* 256, because that's what DJGPP returns Ctrl+Break as. - Clipper has no key code 256, so it may as well be - used for all the Harbour builds that need it */ #if defined(__TURBOC__) || defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__) #include @@ -155,44 +137,12 @@ ULONG DosSleep( ULONG ulMilliseconds ); #endif -#if defined(OS_UNIX_COMPATIBLE) -#include -#include - -static struct termios startup_attributes; - -static void restore_input_mode( void ) -{ - HB_TRACE(HB_TR_DEBUG, ("restore_input_mode()")); - - tcsetattr( STDIN_FILENO, TCSANOW, &startup_attributes ); -} - -HB_CALL_ON_STARTUP_BEGIN( init_input_mode ) - struct termios ta; - - tcgetattr( STDIN_FILENO, &startup_attributes ); - atexit( restore_input_mode ); - - tcgetattr( STDIN_FILENO, &ta ); - ta.c_lflag &= ~( ICANON | ECHO ); - ta.c_iflag &= ~ICRNL; - ta.c_cc[ VMIN ] = 0; - ta.c_cc[ VTIME ] = 0; - tcsetattr( STDIN_FILENO, TCSAFLUSH, &ta ); -HB_CALL_ON_STARTUP_END( init_input_mode ) - -#elif defined(HARBOUR_USE_DOS_GTAPI) && ! defined(__DJGPP__) - extern BOOL hb_gtBreak; /* This variable is located in source/rtl/gt/gtdos.c */ -#endif - -static int * s_inkeyBuffer = 0; /* Harbour keyboard buffer (empty if head == tail) */ -static int s_inkeyHead; /* Harbour keyboard buffer head pointer (next insert) */ -static int s_inkeyTail; /* Harbour keyboard buffer tail pointer (next extract) */ -static int s_inkeyLast; /* Last key extracted from Harbour keyboard buffer */ -static int s_mouseLast; /* Last mouse button to be pressed */ -static BOOL s_inkeyPoll; /* Flag to override no polling when TYPEAHEAD is 0 */ -static int s_inkeyForce; /* Variable to hold keyboard input when TYPEAHEAD is 0 */ +static int * s_inkeyBuffer = 0; /* Harbour keyboard buffer (empty if head == tail) */ +static int s_inkeyHead; /* Harbour keyboard buffer head pointer (next insert) */ +static int s_inkeyTail; /* Harbour keyboard buffer tail pointer (next extract) */ +static int s_inkeyLast; /* Last key extracted from Harbour keyboard buffer */ +static BOOL s_inkeyPoll; /* Flag to override no polling when TYPEAHEAD is 0 */ +static int s_inkeyForce; /* Variable to hold keyboard input when TYPEAHEAD is 0 */ static HB_inkey_enum s_eventmask; void hb_releaseCPU( void ) @@ -278,9 +228,7 @@ int hb_inkeyGet( void ) /* Extract the next key from the keyboard buffer * { /* Keyboard buffer is not empty */ s_inkeyLast = s_inkeyBuffer[ s_inkeyTail++ ]; if( s_inkeyTail >= hb_set.HB_SET_TYPEAHEAD ) - { /* Limit keyboard buffer to set size */ s_inkeyTail = 0; - } key = s_inkeyLast; } } @@ -324,562 +272,10 @@ void hb_inkeyPoll( void ) /* Poll the console keyboard to stuff the Harbour { HB_TRACE(HB_TR_DEBUG, ("hb_inkeyPoll()")); - /* TODO: Add mouse support */ if( hb_set.HB_SET_TYPEAHEAD || s_inkeyPoll ) { - int ch = 0; -#if defined(HARBOUR_USE_CRS_GTAPI) || defined(HARBOUR_USE_SLN_GTAPI) - ch = hb_gtReadKey(); -#elif defined(OS_UNIX_COMPATIBLE) - if( ! read( STDIN_FILENO, &ch, 1 ) ) - ch = 0; -#elif (defined(_WINDOWS_) || defined(__NT__) || defined(WINNT)) && defined(HARBOUR_USE_WIN_GTAPI) - /* First check for Ctrl+Break, which is handled by gt/gtwin.c */ - if( hb_gtBreak ) - { - /* Reset the global Ctrl+Break flag */ - hb_gtBreak = FALSE; - ch = HB_BREAK_FLAG; /* Indicate that Ctrl+Break was pressed */ - } - /* Check for events only when the event buffer is exhausted. */ - else if( s_cNumRead <= s_cNumIndex ) - { - /* Check for keyboard input */ - s_cNumRead = 0; - GetNumberOfConsoleInputEvents( hb_gtHInput, &s_cNumRead ); - if( s_cNumRead ) - { - /* Read keyboard input */ - ReadConsoleInput( - hb_gtHInput, /* input buffer handle */ - s_irInBuf, /* buffer to read into */ - INPUT_BUFFER_LEN, /* size of read buffer */ - &s_cNumRead); /* number of records read */ - /* Set up to process the first input event */ - s_cNumIndex = 0; - } - } - /* Only process one keyboard event at a time. */ - if( s_cNumRead > s_cNumIndex ) - { - if( s_irInBuf[ s_cNumIndex ].EventType == KEY_EVENT ) - { - /* Only process key down events */ - if( s_irInBuf[ s_cNumIndex ].Event.KeyEvent.bKeyDown ) - { - /* Save the keyboard state and ASCII key code */ - DWORD dwState = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.dwControlKeyState; - ch = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.uChar.AsciiChar; - if( ch < 0 ) - { - /* Process international key codes */ - ch += 256; - } - else if( ch == 0 || ( dwState & ( ENHANCED_KEY | LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED | RIGHT_CTRL_PRESSED | SHIFT_PRESSED ) ) ) - { - /* Process non-ASCII key codes */ - WORD wKey; - if( s_eventmask & INKEY_EXTENDED ) - wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualKeyCode; - else - wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualScanCode; - /* Discard standalone state key presses for normal mode only */ - if( ( s_eventmask & INKEY_EXTENDED ) == 0 ) switch( wKey ) - { - /* Virtual scan codes to ignore */ - case 29: /* Ctrl */ - case 42: /* Left Shift */ - case 54: /* Right Shift */ - case 56: /* Alt */ - case 69: /* Num Lock */ - case 70: /* Pause or Scroll Lock */ - wKey = 0; - } - if( wKey == 0 ) ch = 0; - else - { - if( s_eventmask & INKEY_EXTENDED ) - { - /* Pass along all virtual key codes with all - enhanced and state indicators accounted for */ - wKey += 256; - if( dwState & ENHANCED_KEY ) wKey += 512; - if( dwState & SHIFT_PRESSED ) wKey += 1024; - if( dwState & LEFT_CTRL_PRESSED ) wKey += 2048; - if( dwState & RIGHT_CTRL_PRESSED ) wKey += 4096; - if( dwState & LEFT_ALT_PRESSED ) wKey += 8192; - if( dwState & RIGHT_ALT_PRESSED ) wKey += 16384; - ch = wKey; - } - else - { - /* Translate virtual scan codes to Clipper codes */ - BOOL bAlt = dwState & ( LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED ); - BOOL bCtrl = dwState & ( LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED ); - BOOL bShift = dwState & SHIFT_PRESSED; - BOOL bEnhanced = dwState & ENHANCED_KEY; - - HB_TRACE(HB_TR_INFO, ("hb_inkeyPoll: wKey is %d, dwState is %d, ch is %d", wKey, dwState, ch)); - - if( bAlt ) - { - /* Alt key held */ - 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; - } - else if( bCtrl ) - { - /* Ctrl key held */ - if( wKey == 53 && bEnhanced ) ch = KP_CTRL_SLASH; /* Num Pad / */ - else if( wKey >= 59 && wKey <= 68 ) ch = 39 - wKey; /* F1 - F10 */ - 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 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; - } - } - else if( bShift ) - { - /* Shift key held */ - if( wKey == 53 && bEnhanced ) ch = '/'; /* Num Pad / */ - else if( wKey >= 59 && wKey <= 68 ) ch = 49 - wKey; /* F1 - F10 */ - 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 76: /* Num Pad 5 */ - ch = '5'; - break; - case 87: /* F11 */ - case 88: /* F12 */ - ch = 45 - wKey; - break; - case 82: /* Ins */ - ch = K_INS; - break; - case 83: /* Del */ - ch = K_DEL; - 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 80: /* Down */ - ch = K_DOWN; - break; - case 77: /* Right */ - ch = K_RIGHT; - break; - case 75: /* Left */ - ch = K_LEFT; - break; - default: /* Any thing not explicitly translated */ - if( ch == 0 ) - /* Only provide a translation for those key - codes that don't have a default one. */ - ch = wKey + 128; - } - } - else - { - /* Normal key */ - if( wKey == 28 ) ch = K_ENTER; /* Num Pad Enter */ - else if( wKey == 53 && bEnhanced ) ch = '/'; /* Num Pad / */ - else if( wKey == 59 ) ch = K_F1; /* F1 */ - else if( wKey > 59 && wKey <= 68 ) ch = 59 - wKey; /* F2 - F10 */ - else if( wKey == 76 ) ch = 332; /* Num Pad 5 */ - else if( wKey == 87 || wKey == 88 ) ch = 47 - wKey; /* F11, F12 */ - else switch( wKey ) - { - case 82: /* Ins */ - ch = K_INS; - break; - case 83: /* Del */ - ch = K_DEL; - 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 80: /* Down */ - ch = K_DOWN; - break; - case 77: /* Right */ - ch = K_RIGHT; - break; - case 75: /* Left */ - ch = K_LEFT; - break; - case 76: /* Num Pad 5 */ - ch = 332; - break; - case 28: /* Num pad Enter */ - ch = K_ENTER; - break; - default: - ch = wKey + 128; - } - } - } - } - } - -#if 0 - /* Debug code: */ - else - { - - WORD wKey; - if( s_eventmask & INKEY_EXTENDED ) - wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualKeyCode; - else - wKey = s_irInBuf[ s_cNumIndex ].Event.KeyEvent.wVirtualScanCode; - HB_TRACE(HB_TR_INFO, ("hb_inkeyPoll: wKey is %d", wKey)); - } -#endif - } - } - else if( s_eventmask & ~( INKEY_KEYBOARD | INKEY_EXTENDED ) - && s_irInBuf[ s_cNumIndex ].EventType == MOUSE_EVENT ) - { - - hb_mouse_iCol = s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwMousePosition.X; - hb_mouse_iRow = s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwMousePosition.Y; - - if( s_eventmask & INKEY_MOVE && s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == MOUSE_MOVED ) - ch = K_MOUSEMOVE; - - else if( s_eventmask & INKEY_LDOWN && s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwButtonState & - FROM_LEFT_1ST_BUTTON_PRESSED ) - { - if( s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == DOUBLE_CLICK ) - ch = K_LDBLCLK; - else - ch = K_LBUTTONDOWN; - - s_mouseLast = K_LBUTTONDOWN; - } - else if( s_eventmask & INKEY_RDOWN && s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwButtonState & - RIGHTMOST_BUTTON_PRESSED ) - { - if( s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == DOUBLE_CLICK ) - ch = K_RDBLCLK; - else - ch = K_RBUTTONDOWN; - - s_mouseLast = K_RBUTTONDOWN; - } - else if( s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwEventFlags == 0 && - s_irInBuf[ s_cNumIndex ].Event.MouseEvent.dwButtonState == 0 ) - { - if( s_eventmask & INKEY_LUP && s_mouseLast == K_LBUTTONDOWN ) - ch = K_LBUTTONUP; - else if( s_eventmask & INKEY_RUP && s_mouseLast == K_RBUTTONDOWN ) - ch = K_RBUTTONUP; - } - } - /* Set up to process the next input event (if any) */ - s_cNumIndex++; - } -#elif defined(OS_DOS_COMPATIBLE) || defined(HARBOUR_GCC_OS2) || defined(__IBMCPP__) - /* The reason for including _WINDOWS_ here is that kbhit() and getch() appear - to work properly in console mode. For true Windows mode, changes are needed. */ - #if defined(HARBOUR_GCC_OS2) - /* Read from the keyboard with no echo, no wait, and no SIGSEV on Ctrl-C */ - ch = _read_kbd( 0, 0, 0 ); - if( ch == 0 ) - { - /* It's a function key lead-in, so read the function key scan code */ - ch = _read_kbd( 0, 0, 0 ); - if( ch != -1 ) ch += 256; /* If it's really a scan code, offset it */ - } - /* _read_kbd() returns -1 for no key, the switch statement will handle - this. */ - #else - #if defined(HARBOUR_USE_DOS_GTAPI) - #if defined(__DJGPP__) - /* Check to see if Ctrl+Break has been detected */ - 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 */ - } - #else - /* First check for Ctrl+Break, which is handled by gt/gtdos.c, - with the exception of the DJGPP compiler */ - if( hb_gtBreak ) - { - hb_gtBreak = FALSE; /* Indicate that Ctrl+Break has been handled */ - ch = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */ - } - #endif - else - #endif - if( kbhit() ) - { - /* A key code is available in the BIOS keyboard buffer, so read it */ - #if defined(__DJGPP__) - if( s_eventmask & INKEY_EXTENDED ) ch = getxkey(); - else ch = getkey(); - if( ch == 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; - #else - /* A key code is available in the BIOS keyboard buffer */ - ch = getch(); /* Get the key code */ - 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; - } - else if( ch == 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( s_eventmask & INKEY_EXTENDED ) ch = getch() + 512; - else ch = getch() + 256; - } - #endif - } - #endif - /* Perform key translations */ - switch( ch ) - { - case -1: /* No key available */ - return; - case 328: /* Up arrow */ - ch = K_UP; - break; - case 336: /* Down arrow */ - ch = K_DOWN; - break; - case 331: /* Left arrow */ - ch = K_LEFT; - break; - case 333: /* Right arrow */ - ch = K_RIGHT; - break; - case 327: /* Home */ - ch = K_HOME; - break; - case 335: /* End */ - ch = K_END; - break; - case 329: /* Page Up */ - ch = K_PGUP; - break; - case 337: /* Page Down */ - ch = K_PGDN; - break; - case 371: /* Ctrl + Left arrow */ - ch = K_CTRL_LEFT; - break; - case 372: /* Ctrl + Right arrow */ - ch = K_CTRL_RIGHT; - break; - case 375: /* Ctrl + Home */ - ch = K_CTRL_HOME; - break; - case 373: /* Ctrl + End */ - ch = K_CTRL_END; - break; - case 388: /* Ctrl + Page Up */ - ch = K_CTRL_PGUP; - break; - case 374: /* Ctrl + Page Down */ - ch = K_CTRL_PGDN; - break; - case 338: /* Insert */ - ch = K_INS; - break; - case 339: /* Delete */ - ch = K_DEL; - break; - case 315: /* F1 */ - ch = K_F1; - 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 */ - ch = 315 - ch; - 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 */ - ch = 330 - ch; - 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 */ - ch = 349 - ch; - } -#else - /* TODO: Support for other platforms, such as Mac */ -#endif + int ch = hb_gtReadKey( s_eventmask ); + switch( ch ) { case HB_BREAK_FLAG: /* Check for Ctrl+Break */ @@ -889,6 +285,7 @@ void hb_inkeyPoll( void ) /* Poll the console keyboard to stuff the Harbour case K_ALT_C: /* Alt+C was pressed */ hb_vmRequestCancel(); } + hb_inkeyPut( ch ); } }