123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- /* Copyright (c) 1992, 1999, 2001, 2002, 2003 John E. Davis
- * This file is part of the S-Lang library.
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Perl Artistic License.
- */
- #include "slinclud.h"
- #include <windows.h>
- #include <winbase.h>
- #include "slang.h"
- #include "_slang.h"
- #ifdef __cplusplus
- # define _DOTS_ ...
- #else
- # define _DOTS_ void
- #endif
- static int Process_Mouse_Events;
- /*----------------------------------------------------------------------*\
- * Function: static void set_ctrl_break (int state);
- *
- * set the control-break setting
- \*----------------------------------------------------------------------*/
- static void set_ctrl_break (int state)
- {
- }
- /*----------------------------------------------------------------------*\
- * Function: int SLang_init_tty (int abort_char, int no_flow_control,
- * int opost);
- *
- * initialize the keyboard interface and attempt to set-up the interrupt 9
- * handler if ABORT_CHAR is non-zero.
- * NO_FLOW_CONTROL and OPOST are only for compatiblity and are ignored.
- \*----------------------------------------------------------------------*/
- HANDLE _SLw32_Hstdin = INVALID_HANDLE_VALUE;
- int SLang_init_tty (int abort_char, int no_flow_control, int opost)
- {
- (void) opost;
- (void) no_flow_control;
- if (_SLw32_Hstdin != INVALID_HANDLE_VALUE)
- return 0;
- #if 1
- /* stdin may have been redirected. So try this */
- _SLw32_Hstdin = CreateFile ("CONIN$", GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, 0, NULL);
- if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
- return -1;
- #else
- if (INVALID_HANDLE_VALUE == (_SLw32_Hstdin = GetStdHandle(STD_INPUT_HANDLE)))
- return -1;
- #endif
- if (FALSE == SetConsoleMode(_SLw32_Hstdin, ENABLE_WINDOW_INPUT|ENABLE_MOUSE_INPUT))
- {
- _SLw32_Hstdin = INVALID_HANDLE_VALUE;
- return -1;
- }
-
- if (abort_char > 0)
- SLang_Abort_Char = abort_char;
- return 0;
- }
- /* SLang_init_tty */
- /*----------------------------------------------------------------------*\
- * Function: void SLang_reset_tty (void);
- *
- * reset the tty before exiting
- \*----------------------------------------------------------------------*/
- void SLang_reset_tty (void)
- {
- _SLw32_Hstdin = INVALID_HANDLE_VALUE;
- set_ctrl_break (1);
- }
- static int process_mouse_event (MOUSE_EVENT_RECORD *m)
- {
- char buf [8];
- if (Process_Mouse_Events == 0)
- return -1;
- if (m->dwEventFlags)
- return -1; /* double click or movement event */
- /* A button was either pressed or released. Now make sure that
- * the shift keys were not also pressed.
- */
- if (m->dwControlKeyState
- & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED
- |LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED
- |SHIFT_PRESSED))
- return -1;
- /* We have a simple press or release. Encode it as an escape sequence
- * and buffer the result. The encoding is:
- * 'ESC [ M b x y'
- * where b represents the button state, and x,y represent the coordinates.
- * The ESC is handled by the calling routine.
- */
- if (m->dwButtonState & 1) buf[3] = ' ';
- else if (m->dwButtonState & 2) buf[3] = ' ' + 2;
- else if (m->dwButtonState & 4) buf[3] = ' ' + 1;
- else return -1;
- buf[0] = 27;
- buf[1] = '[';
- buf[2] = 'M';
- buf[4] = 1 + ' ' + m->dwMousePosition.X;
- buf[5] = 1 + ' ' + m->dwMousePosition.Y;
- return SLang_buffer_keystring ((unsigned char *)buf, 6);
- }
- static int process_key_event (KEY_EVENT_RECORD *key)
- {
- unsigned int key_state = 0;
- unsigned int scan;
- char c1;
- DWORD d = key->dwControlKeyState;
- unsigned char buf[4];
- if (!key->bKeyDown) return 0;
- if (d & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
- key_state |= _SLTT_KEY_ALT;
- if (d & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- key_state |= _SLTT_KEY_CTRL;
- if (d & SHIFT_PRESSED)
- key_state |= _SLTT_KEY_SHIFT;
- scan = key->wVirtualScanCode;
- switch (scan)
- {
- case 0x00E: /* backspace */
- return SLang_buffer_keystring ((unsigned char *)"\x7F", 1);
- case 0x003: /* 2 key */
- if (key_state & _SLTT_KEY_ALT)
- break;
- /* Drop */
- case 0x039: /* space */
- if (key_state & _SLTT_KEY_CTRL)
- return SLang_buffer_keystring ((unsigned char *)"\x00\x03", 2);
- break;
- case 0x007: /* 6 key */
- if (_SLTT_KEY_CTRL == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL)))
- return SLang_buffer_keystring ((unsigned char *)"\x1E", 1); /* Ctrl-^ */
- break;
- case 0x00C: /* -/_ key */
- if (_SLTT_KEY_CTRL == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL)))
- return SLang_buffer_keystring ((unsigned char *)"\x1F", 1);
- break;
- case 0x00F: /* TAB */
- if (_SLTT_KEY_SHIFT == key_state)
- return SLang_buffer_keystring ((unsigned char *)"\x00\x09", 2);
- break;
- case 0xE02F: /* KEYPAD SLASH */
- case 0x037: /* KEYPAD STAR */
- case 0x04A: /* KEYPAD MINUS */
- case 0x04E: /* KEYPAD PLUS */
- if (d & NUMLOCK_ON)
- break;
- case 0x047: /* KEYPAD HOME */
- case 0x048: /* KEYPAD UP */
- case 0x049: /* KEYPAD PGUP */
- case 0x04B: /* KEYPAD LEFT */
- case 0x04C: /* KEYPAD 5 */
- case 0x04D: /* KEYPAD RIGHT */
- case 0x04F: /* KEYPAD END */
- case 0x050: /* KEYPAD DOWN */
- case 0x051: /* KEYPAD PGDN */
- case 0x052: /* KEYPAD INSERT */
- case 0x053: /* KEYPAD DEL */
- if (d & ENHANCED_KEY)
- scan |= 0xE000;
- else
- {
- if (d & NUMLOCK_ON)
- break;
- }
- (void) _SLpc_convert_scancode (scan, key_state, 0);
- return 0;
- case 0x3b: /* F1 */
- case 0x3c:
- case 0x3d:
- case 0x3e:
- case 0x3f:
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x57:
- case 0x58: /* F12 */
- (void) _SLpc_convert_scancode (scan, key_state, 0);
- }
-
- c1 = key->uChar.AsciiChar;
- if (c1 != 0)
- {
- if (_SLTT_KEY_ALT == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL)))
- {
- buf[0] = 27;
- buf[1] = c1;
- return SLang_buffer_keystring (buf, 2);
- }
- if (c1 == SLang_Abort_Char)
- {
- if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
- SLKeyBoard_Quit = 1;
- }
- buf[0] = c1;
- return SLang_buffer_keystring (buf, 1);
- }
- return 0;
- }
- static void process_console_records(void)
- {
- INPUT_RECORD record;
- DWORD bytesRead;
- DWORD n = 0;
- if (FALSE == GetNumberOfConsoleInputEvents(_SLw32_Hstdin, &n))
- return;
- while (n > 0)
- {
- ReadConsoleInput(_SLw32_Hstdin, &record, 1, &bytesRead);
- switch (record.EventType)
- {
- case KEY_EVENT:
- (void) process_key_event(&record.Event.KeyEvent);
- break;
- case MOUSE_EVENT:
- process_mouse_event(&record.Event.MouseEvent);
- break;
- case WINDOW_BUFFER_SIZE_EVENT:
- /* process_resize_records(&record.Event.WindowBufferSizeEvent); */
- break;
- }
- n--;
- }
- }
- /*----------------------------------------------------------------------*\
- * Function: int _SLsys_input_pending (int tsecs);
- *
- * sleep for *tsecs tenths of a sec waiting for input
- \*----------------------------------------------------------------------*/
- int _SLsys_input_pending (int tsecs)
- {
- long ms;
- if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
- return -1;
- if (tsecs < 0) ms = -tsecs; /* specifies 1/1000 */
- else ms = tsecs * 100L; /* convert 1/10 to 1/1000 secs */
- process_console_records ();
- while ((ms > 0)
- && (SLang_Input_Buffer_Len == 0))
- {
- long t;
- t = GetTickCount ();
- (void) WaitForSingleObject (_SLw32_Hstdin, ms);
- process_console_records ();
- ms -= GetTickCount () - t;
- }
-
- return SLang_Input_Buffer_Len;
- }
- /*----------------------------------------------------------------------*\
- * Function: unsigned int _SLsys_getkey (void);
- *
- * wait for and get the next available keystroke.
- * Also re-maps some useful keystrokes.
- *
- * Backspace (^H) => Del (127)
- * Ctrl-Space => ^@ (^@^3 - a pc NUL char)
- * extended keys are prefixed by a null character
- \*----------------------------------------------------------------------*/
- unsigned int _SLsys_getkey (void)
- {
- /* Check the input buffer because _SLsys_input_pending may have been
- * called prior to this to stuff the input buffer.
- */
- if (SLang_Input_Buffer_Len)
- return SLang_getkey ();
- if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
- return SLANG_GETKEY_ERROR;
- while (1)
- {
- int status;
- if (SLKeyBoard_Quit)
- return SLang_Abort_Char;
-
- status = _SLsys_input_pending (600);
- if (status == -1)
- return SLANG_GETKEY_ERROR;
-
- if (status > 0)
- return SLang_getkey ();
- }
- }
- /*----------------------------------------------------------------------*\
- * Function: int SLang_set_abort_signal (void (*handler)(int));
- \*----------------------------------------------------------------------*/
- int SLang_set_abort_signal (void (*handler)(int))
- {
- if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
- return -1;
- return 0;
- }
- int SLtt_set_mouse_mode (int mode, int force)
- {
- (void) force;
- Process_Mouse_Events = mode;
- return 0;
- }
|