~ubuntu-branches/ubuntu/lucid/mc/lucid

« back to all changes in this revision

Viewing changes to slang/slw32tty.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-09-16 10:38:59 UTC
  • mfrom: (3.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080916103859-2uwn8w61xk5mbxxq
Tags: 2:4.6.2~git20080311-4
Corrected fix for odt2txt issue (Closes: #492019) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 1992, 1999, 2001, 2002, 2003 John E. Davis
2
 
 * This file is part of the S-Lang library.
3
 
 *
4
 
 * You may distribute under the terms of either the GNU General Public
5
 
 * License or the Perl Artistic License.
6
 
 */
7
 
 
8
 
#include "slinclud.h"
9
 
 
10
 
#include <windows.h>
11
 
#include <winbase.h>
12
 
 
13
 
#include "slang.h"
14
 
#include "_slang.h"
15
 
 
16
 
#ifdef __cplusplus
17
 
# define _DOTS_ ...
18
 
#else
19
 
# define _DOTS_ void
20
 
#endif
21
 
 
22
 
static int Process_Mouse_Events;
23
 
 
24
 
/*----------------------------------------------------------------------*\
25
 
 *  Function:   static void set_ctrl_break (int state);
26
 
 *
27
 
 * set the control-break setting
28
 
\*----------------------------------------------------------------------*/
29
 
static void set_ctrl_break (int state)
30
 
{
31
 
}
32
 
 
33
 
/*----------------------------------------------------------------------*\
34
 
 *  Function:   int SLang_init_tty (int abort_char, int no_flow_control,
35
 
 *                                  int opost);
36
 
 *
37
 
 * initialize the keyboard interface and attempt to set-up the interrupt 9
38
 
 * handler if ABORT_CHAR is non-zero.
39
 
 * NO_FLOW_CONTROL and OPOST are only for compatiblity and are ignored.
40
 
\*----------------------------------------------------------------------*/
41
 
 
42
 
HANDLE _SLw32_Hstdin = INVALID_HANDLE_VALUE;
43
 
 
44
 
int SLang_init_tty (int abort_char, int no_flow_control, int opost)
45
 
{
46
 
   (void) opost;
47
 
   (void) no_flow_control;
48
 
 
49
 
   if (_SLw32_Hstdin != INVALID_HANDLE_VALUE)
50
 
     return 0;
51
 
 
52
 
#if 1
53
 
   /* stdin may have been redirected.  So try this */
54
 
   _SLw32_Hstdin = CreateFile ("CONIN$", GENERIC_READ|GENERIC_WRITE, 
55
 
                               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 
56
 
                               OPEN_EXISTING, 0, NULL);
57
 
   if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
58
 
     return -1;
59
 
#else
60
 
   if (INVALID_HANDLE_VALUE == (_SLw32_Hstdin = GetStdHandle(STD_INPUT_HANDLE)))
61
 
     return -1;
62
 
#endif
63
 
 
64
 
   if (FALSE == SetConsoleMode(_SLw32_Hstdin, ENABLE_WINDOW_INPUT|ENABLE_MOUSE_INPUT))
65
 
     {
66
 
        _SLw32_Hstdin = INVALID_HANDLE_VALUE;
67
 
        return -1;
68
 
     }
69
 
   
70
 
   if (abort_char > 0)
71
 
     SLang_Abort_Char = abort_char;
72
 
 
73
 
   return 0;
74
 
}
75
 
/* SLang_init_tty */
76
 
 
77
 
/*----------------------------------------------------------------------*\
78
 
 *  Function:   void SLang_reset_tty (void);
79
 
 *
80
 
 * reset the tty before exiting
81
 
\*----------------------------------------------------------------------*/
82
 
void SLang_reset_tty (void)
83
 
{
84
 
   _SLw32_Hstdin = INVALID_HANDLE_VALUE;
85
 
   set_ctrl_break (1);
86
 
}
87
 
 
88
 
static int process_mouse_event (MOUSE_EVENT_RECORD *m)
89
 
{
90
 
   char buf [8];
91
 
 
92
 
   if (Process_Mouse_Events == 0)
93
 
     return -1;
94
 
 
95
 
   if (m->dwEventFlags)
96
 
     return -1;                        /* double click or movement event */
97
 
 
98
 
   /* A button was either pressed or released.  Now make sure that
99
 
    * the shift keys were not also pressed.
100
 
    */
101
 
   if (m->dwControlKeyState
102
 
       & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED
103
 
          |LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED
104
 
          |SHIFT_PRESSED))
105
 
     return -1;
106
 
 
107
 
   /* We have a simple press or release.  Encode it as an escape sequence
108
 
    * and buffer the result.  The encoding is:
109
 
    *   'ESC [ M b x y'
110
 
    *  where b represents the button state, and x,y represent the coordinates.
111
 
    * The ESC is handled by the calling routine.
112
 
    */
113
 
   if (m->dwButtonState & 1) buf[3] = ' ';
114
 
   else if (m->dwButtonState & 2) buf[3] = ' ' + 2;
115
 
   else if (m->dwButtonState & 4) buf[3] = ' ' + 1;
116
 
   else return -1;
117
 
 
118
 
   buf[0] = 27;
119
 
   buf[1] = '[';
120
 
   buf[2] = 'M';
121
 
 
122
 
 
123
 
   buf[4] = 1 + ' ' + m->dwMousePosition.X;
124
 
   buf[5] = 1 + ' ' + m->dwMousePosition.Y;
125
 
 
126
 
   return SLang_buffer_keystring ((unsigned char *)buf, 6);
127
 
}
128
 
 
129
 
static int process_key_event (KEY_EVENT_RECORD *key)
130
 
{
131
 
   unsigned int key_state = 0;
132
 
   unsigned int scan;
133
 
   char c1;
134
 
   DWORD d = key->dwControlKeyState;
135
 
   unsigned char buf[4];
136
 
 
137
 
   if (!key->bKeyDown) return 0;
138
 
   if (d & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
139
 
     key_state |= _SLTT_KEY_ALT;
140
 
   if (d & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) 
141
 
     key_state |= _SLTT_KEY_CTRL;
142
 
   if (d & SHIFT_PRESSED)
143
 
     key_state |= _SLTT_KEY_SHIFT;
144
 
 
145
 
   scan = key->wVirtualScanCode;
146
 
 
147
 
   switch (scan)
148
 
     {
149
 
      case 0x00E:                      /* backspace */
150
 
        return SLang_buffer_keystring ((unsigned char *)"\x7F", 1);
151
 
 
152
 
      case 0x003:                      /* 2 key */
153
 
        if (key_state & _SLTT_KEY_ALT)
154
 
          break;
155
 
        /* Drop */
156
 
      case 0x039:                      /* space */
157
 
        if (key_state & _SLTT_KEY_CTRL)
158
 
          return SLang_buffer_keystring ((unsigned char *)"\x00\x03", 2);
159
 
        break;
160
 
 
161
 
      case 0x007:                      /* 6 key */
162
 
        if (_SLTT_KEY_CTRL == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL)))
163
 
          return SLang_buffer_keystring ((unsigned char *)"\x1E", 1);   /* Ctrl-^ */
164
 
        break;
165
 
 
166
 
      case 0x00C:                      /* -/_ key */
167
 
        if (_SLTT_KEY_CTRL == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL)))
168
 
          return SLang_buffer_keystring ((unsigned char *)"\x1F", 1);
169
 
        break;
170
 
 
171
 
      case 0x00F:                      /* TAB */
172
 
        if (_SLTT_KEY_SHIFT == key_state)
173
 
          return SLang_buffer_keystring ((unsigned char *)"\x00\x09", 2);
174
 
        break;
175
 
 
176
 
      case 0xE02F:                     /* KEYPAD SLASH */
177
 
      case 0x037:                      /* KEYPAD STAR */
178
 
      case 0x04A:                      /* KEYPAD MINUS */
179
 
      case 0x04E:                      /* KEYPAD PLUS */
180
 
        if (d & NUMLOCK_ON)
181
 
          break;
182
 
      case 0x047:                      /* KEYPAD HOME */
183
 
      case 0x048:                      /* KEYPAD UP */
184
 
      case 0x049:                      /* KEYPAD PGUP */
185
 
      case 0x04B:                      /* KEYPAD LEFT */
186
 
      case 0x04C:                      /* KEYPAD 5 */
187
 
      case 0x04D:                      /* KEYPAD RIGHT */
188
 
      case 0x04F:                      /* KEYPAD END */
189
 
      case 0x050:                      /* KEYPAD DOWN */
190
 
      case 0x051:                      /* KEYPAD PGDN */
191
 
      case 0x052:                      /* KEYPAD INSERT */
192
 
      case 0x053:                      /* KEYPAD DEL */
193
 
        if (d & ENHANCED_KEY)
194
 
          scan |= 0xE000;
195
 
        else
196
 
          {
197
 
             if (d & NUMLOCK_ON)
198
 
               break;
199
 
          }
200
 
        (void) _SLpc_convert_scancode (scan, key_state, 0);
201
 
        return 0;
202
 
 
203
 
      case 0x3b:                       /* F1 */
204
 
      case 0x3c:
205
 
      case 0x3d:
206
 
      case 0x3e:
207
 
      case 0x3f:
208
 
      case 0x40:
209
 
      case 0x41:
210
 
      case 0x42:
211
 
      case 0x43:
212
 
      case 0x44:
213
 
      case 0x57:
214
 
      case 0x58:                       /* F12 */
215
 
        (void) _SLpc_convert_scancode (scan, key_state, 0);
216
 
     }
217
 
   
218
 
   c1 = key->uChar.AsciiChar;
219
 
   if (c1 != 0)
220
 
     {
221
 
        if (_SLTT_KEY_ALT == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL)))
222
 
          {
223
 
             buf[0] = 27;
224
 
             buf[1] = c1;
225
 
             return SLang_buffer_keystring (buf, 2);
226
 
          }
227
 
        if (c1 == SLang_Abort_Char)
228
 
          {
229
 
             if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
230
 
             SLKeyBoard_Quit = 1;
231
 
          }
232
 
        buf[0] = c1;
233
 
        return SLang_buffer_keystring (buf, 1);
234
 
     }
235
 
   return 0;
236
 
}
237
 
 
238
 
 
239
 
static void process_console_records(void)
240
 
{
241
 
   INPUT_RECORD record;
242
 
   DWORD bytesRead;
243
 
   DWORD n = 0;
244
 
 
245
 
   if (FALSE == GetNumberOfConsoleInputEvents(_SLw32_Hstdin, &n))
246
 
     return;
247
 
 
248
 
   while (n > 0)
249
 
     {
250
 
        ReadConsoleInput(_SLw32_Hstdin, &record, 1, &bytesRead);
251
 
        switch (record.EventType)
252
 
          {
253
 
           case KEY_EVENT:
254
 
             (void) process_key_event(&record.Event.KeyEvent);
255
 
             break;
256
 
 
257
 
           case MOUSE_EVENT:
258
 
             process_mouse_event(&record.Event.MouseEvent);
259
 
             break;
260
 
 
261
 
           case WINDOW_BUFFER_SIZE_EVENT:
262
 
             /* process_resize_records(&record.Event.WindowBufferSizeEvent); */
263
 
             break;
264
 
          }
265
 
        n--;
266
 
     }
267
 
}
268
 
 
269
 
/*----------------------------------------------------------------------*\
270
 
 *  Function:   int _SLsys_input_pending (int tsecs);
271
 
 *
272
 
 *  sleep for *tsecs tenths of a sec waiting for input
273
 
\*----------------------------------------------------------------------*/
274
 
int _SLsys_input_pending (int tsecs)
275
 
{
276
 
   long ms;
277
 
 
278
 
   if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
279
 
     return -1;
280
 
 
281
 
   if (tsecs < 0) ms = -tsecs;         /* specifies 1/1000 */
282
 
   else ms = tsecs * 100L;             /* convert 1/10 to 1/1000 secs */
283
 
 
284
 
   process_console_records ();
285
 
   while ((ms > 0)
286
 
          && (SLang_Input_Buffer_Len == 0))
287
 
     {
288
 
        long t;
289
 
 
290
 
        t = GetTickCount ();
291
 
 
292
 
        (void) WaitForSingleObject (_SLw32_Hstdin, ms);
293
 
        process_console_records ();
294
 
        ms -= GetTickCount () - t;
295
 
     }
296
 
   
297
 
   return SLang_Input_Buffer_Len;
298
 
}
299
 
 
300
 
/*----------------------------------------------------------------------*\
301
 
 *  Function:   unsigned int _SLsys_getkey (void);
302
 
 *
303
 
 * wait for and get the next available keystroke.
304
 
 * Also re-maps some useful keystrokes.
305
 
 *
306
 
 *      Backspace (^H)  =>      Del (127)
307
 
 *      Ctrl-Space      =>      ^@      (^@^3 - a pc NUL char)
308
 
 *      extended keys are prefixed by a null character
309
 
\*----------------------------------------------------------------------*/
310
 
unsigned int _SLsys_getkey (void)
311
 
{
312
 
   /* Check the input buffer because _SLsys_input_pending may have been 
313
 
    * called prior to this to stuff the input buffer.
314
 
    */
315
 
   if (SLang_Input_Buffer_Len)
316
 
     return SLang_getkey ();
317
 
 
318
 
   if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
319
 
     return SLANG_GETKEY_ERROR;
320
 
 
321
 
   while (1)
322
 
     {
323
 
        int status;
324
 
 
325
 
        if (SLKeyBoard_Quit)
326
 
          return SLang_Abort_Char;
327
 
        
328
 
        status = _SLsys_input_pending (600);
329
 
        if (status == -1)
330
 
          return SLANG_GETKEY_ERROR;
331
 
        
332
 
        if (status > 0)
333
 
          return SLang_getkey ();
334
 
     }
335
 
}
336
 
 
337
 
/*----------------------------------------------------------------------*\
338
 
 *  Function:   int SLang_set_abort_signal (void (*handler)(int));
339
 
\*----------------------------------------------------------------------*/
340
 
int SLang_set_abort_signal (void (*handler)(int))
341
 
{
342
 
   if (_SLw32_Hstdin == INVALID_HANDLE_VALUE)
343
 
     return -1;
344
 
 
345
 
   return 0;
346
 
}
347
 
 
348
 
int SLtt_set_mouse_mode (int mode, int force)
349
 
{
350
 
   (void) force;
351
 
 
352
 
   Process_Mouse_Events = mode;
353
 
   return 0;
354
 
}