]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/pm/linux/event.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / pm / linux / event.c
1 /****************************************************************************
2 *
3 *                   SciTech Multi-platform Graphics Library
4 *
5 *  ========================================================================
6 *
7 *    The contents of this file are subject to the SciTech MGL Public
8 *    License Version 1.0 (the "License"); you may not use this file
9 *    except in compliance with the License. You may obtain a copy of
10 *    the License at http://www.scitechsoft.com/mgl-license.txt
11 *
12 *    Software distributed under the License is distributed on an
13 *    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 *    implied. See the License for the specific language governing
15 *    rights and limitations under the License.
16 *
17 *    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 *
19 *    The Initial Developer of the Original Code is SciTech Software, Inc.
20 *    All Rights Reserved.
21 *
22 *  ========================================================================
23 *
24 * Language:     ANSI C
25 * Environment:  Linux
26 *
27 * Description:  Linux fullscreen console implementation for the SciTech
28 *               cross platform event library.
29 *               Portions ripped straigth from the gpm source code for mouse
30 *               handling.
31 *
32 ****************************************************************************/
33
34 /*---------------------------- Global Variables ---------------------------*/
35
36 extern int              _PM_console_fd;
37 static ushort           keyUpMsg[256] = {0};
38 static int              _EVT_mouse_fd = 0;
39 static int              range_x, range_y;
40 static int              opt_baud = 1200, opt_sample = 100;
41 #ifdef USE_OS_JOYSTICK
42 static short            *axis0 = NULL, *axis1 = NULL;
43 static uchar            *buts0 = NULL, *buts1 = NULL;
44 static int              joystick0_fd = 0, joystick1_fd = 0;
45 static int              js_version = 0;
46 #endif
47
48 /* This defines the supported mouse drivers */
49
50 typedef enum {
51     EVT_noMouse = -1,
52     EVT_microsoft = 0,
53     EVT_ps2,
54     EVT_mousesystems,
55     EVT_gpm,
56     EVT_MMseries,
57     EVT_logitech,
58     EVT_busmouse,
59     EVT_mouseman,
60     EVT_intellimouse,
61     EVT_intellimouse_ps2,
62     } mouse_drivers_t;
63
64 static mouse_drivers_t mouse_driver = EVT_noMouse;
65 static char mouse_dev[20] = "/dev/mouse";
66
67 typedef struct {
68     char    *name;
69     int     flags;
70     void    (*init)(void);
71     uchar   proto[4];
72     int     packet_len;
73     int     read;
74     } mouse_info;
75
76 #define STD_FLG (CREAD | CLOCAL | HUPCL)
77
78 static void _EVT_mouse_init(void);
79 static void _EVT_logitech_init(void);
80 static void _EVT_pnpmouse_init(void);
81
82 mouse_info mouse_infos[] = {
83     {"Microsoft",       CS7 | B1200 | STD_FLG,              _EVT_mouse_init,    {0x40, 0x40, 0x40, 0x00}, 3, 1},
84     {"PS2",             STD_FLG,                            NULL,               {0xc0, 0x00, 0x00, 0x00}, 3, 1},
85     {"MouseSystems",    CS8 | CSTOPB | STD_FLG,             _EVT_mouse_init,    {0xf8, 0x80, 0x00, 0x00}, 5, 5},
86     {"GPM",             CS8 | CSTOPB | STD_FLG,             NULL,               {0xf8, 0x80, 0x00, 0x00}, 5, 5},
87     {"MMSeries",        CS8 | PARENB | PARODD | STD_FLG,    _EVT_mouse_init,    {0xe0, 0x80, 0x80, 0x00}, 3, 1},
88     {"Logitech",        CS8 | CSTOPB | STD_FLG,             _EVT_logitech_init, {0xe0, 0x80, 0x80, 0x00}, 3, 3},
89     {"BusMouse",        STD_FLG,                            NULL,               {0xf8, 0x80, 0x00, 0x00}, 3, 3},
90     {"MouseMan",        CS7 | STD_FLG,                      _EVT_mouse_init,    {0x40, 0x40, 0x40, 0x00}, 3, 1},
91     {"IntelliMouse",    CS7 | STD_FLG,                      _EVT_pnpmouse_init, {0xc0, 0x40, 0xc0, 0x00}, 4, 1},
92     {"IMPS2",           CS7 | STD_FLG,                      NULL,               {0xc0, 0x40, 0xc0, 0x00}, 4, 1}, // ?
93     };
94
95 #define NB_MICE (sizeof(mouse_infos)/sizeof(mouse_info))
96
97 /* The name of the environment variables that are used to change the defaults above */
98
99 #define ENV_MOUSEDRV "MGL_MOUSEDRV"
100 #define ENV_MOUSEDEV "MGL_MOUSEDEV"
101 #define ENV_MOUSESPD "MGL_MOUSESPD"
102 #define ENV_JOYDEV0  "MGL_JOYDEV1"
103 #define ENV_JOYDEV1  "MGL_JOYDEV2"
104
105 /* Scancode mappings on Linux for special keys */
106
107 typedef struct {
108     int scan;
109     int map;
110     } keymap;
111
112 // TODO: Fix this and set it up so we can do a binary search!
113
114 keymap keymaps[] = {
115     {96, KB_padEnter},
116     {74, KB_padMinus},
117     {78, KB_padPlus},
118     {55, KB_padTimes},
119     {98, KB_padDivide},
120     {71, KB_padHome},
121     {72, KB_padUp},
122     {73, KB_padPageUp},
123     {75, KB_padLeft},
124     {76, KB_padCenter},
125     {77, KB_padRight},
126     {79, KB_padEnd},
127     {80, KB_padDown},
128     {81, KB_padPageDown},
129     {82, KB_padInsert},
130     {83, KB_padDelete},
131     {105,KB_left},
132     {108,KB_down},
133     {106,KB_right},
134     {103,KB_up},
135     {110,KB_insert},
136     {102,KB_home},
137     {104,KB_pageUp},
138     {111,KB_delete},
139     {107,KB_end},
140     {109,KB_pageDown},
141     {125,KB_leftWindows},
142     {126,KB_rightWindows},
143     {127,KB_menu},
144     {100,KB_rightAlt},
145     {97,KB_rightCtrl},
146     };
147
148 /* And the keypad with num lock turned on (changes the ASCII code only) */
149
150 keymap keypad[] = {
151     {71, ASCII_7},
152     {72, ASCII_8},
153     {73, ASCII_9},
154     {75, ASCII_4},
155     {76, ASCII_5},
156     {77, ASCII_6},
157     {79, ASCII_1},
158     {80, ASCII_2},
159     {81, ASCII_3},
160     {82, ASCII_0},
161     {83, ASCII_period},
162     };
163
164 #define NB_KEYMAPS (sizeof(keymaps)/sizeof(keymaps[0]))
165 #define NB_KEYPAD (sizeof(keypad)/sizeof(keypad[0]))
166
167 typedef struct {
168     int     sample;
169     char    code[2];
170     } sample_rate;
171
172 sample_rate sampletab[]={
173     {  0,"O"},
174     { 15,"J"},
175     { 27,"K"},
176     { 42,"L"},
177     { 60,"R"},
178     { 85,"M"},
179     {125,"Q"},
180     {1E9,"N"},
181     };
182
183 /* Number of keycodes to read at a time from the console */
184
185 #define KBDREADBUFFERSIZE 32
186
187 /*---------------------------- Implementation -----------------------------*/
188
189 /* These are not used under Linux */
190 #define _EVT_disableInt()       1
191 #define _EVT_restoreInt(flaps)
192
193 /****************************************************************************
194 PARAMETERS:
195 scanCode    - Scan code to test
196
197 REMARKS:
198 This macro determines if a specified key is currently down at the
199 time that the call is made.
200 ****************************************************************************/
201 #define _EVT_isKeyDown(scanCode)    (keyUpMsg[scanCode] != 0)
202
203 /****************************************************************************
204 REMARKS:
205 This function is used to return the number of ticks since system
206 startup in milliseconds. This should be the same value that is placed into
207 the time stamp fields of events, and is used to implement auto mouse down
208 events.
209 ****************************************************************************/
210 ulong _EVT_getTicks(void)
211 {
212     static uint     starttime = 0;
213     struct timeval  t;
214
215     gettimeofday(&t, NULL);
216     if (starttime == 0)
217       starttime = t.tv_sec * 1000 + (t.tv_usec/1000);
218     return ((t.tv_sec * 1000 + (t.tv_usec/1000)) - starttime);
219 }
220
221 /****************************************************************************
222 REMARKS:
223 Small Unix function that checks for availability on a file using select()
224 ****************************************************************************/
225 static ibool dataReady(
226     int fd)
227 {
228     static struct timeval   t = { 0L, 0L };
229     fd_set                  fds;
230
231     FD_ZERO(&fds);
232     FD_SET(fd, &fds);
233     return select(fd+1, &fds, NULL, NULL, &t) > 0;
234 }
235
236 /****************************************************************************
237 REMARKS:
238 Reads mouse data according to the selected mouse driver.
239 ****************************************************************************/
240 static ibool readMouseData(
241     int *buttons,
242     int *dx,
243     int *dy)
244 {
245     static uchar    data[32],prev = 0;
246     int             cnt = 0,ret;
247     mouse_info      *drv;
248
249     /* Read the first byte to check for the protocol */
250     drv = &mouse_infos[mouse_driver];
251     if (read(_EVT_mouse_fd, data, drv->read) != drv->read) {
252         perror("read");
253         return false;
254         }
255     if ((data[0] & drv->proto[0]) != drv->proto[1])
256         return false;
257
258     /* Load a whole protocol packet */
259     cnt += drv->read;
260     while (cnt < drv->packet_len) {
261         ret = read(_EVT_mouse_fd, data+cnt, drv->read);
262         if (ret == drv->read)
263             cnt += ret;
264         else {
265             perror("read");
266             return false;
267             }
268         }
269     if ((data[1] & drv->proto[2]) != drv->proto[3])
270         return false;
271
272     /* Now decode the protocol packet */
273     switch (mouse_driver) {
274         case EVT_microsoft:
275             if (data[0] == 0x40 && !(prev|data[1]|data[2]))
276                 *buttons = 2;   /* Third button on MS compatible mouse */
277             else
278                 *buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4);
279             prev = *buttons;
280             *dx = (char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
281             *dy = (char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
282             break;
283         case EVT_ps2:
284             *buttons = !!(data[0]&1) * 4 + !!(data[0]&2) * 1 + !!(data[0]&4) * 2;
285             if (data[1] != 0)
286                 *dx = (data[0] & 0x10) ? data[1]-256 : data[1];
287             else
288                 *dx = 0;
289             if (data[2] != 0)
290                 *dy = -((data[0] & 0x20) ? data[2]-256 : data[2]);
291             else
292                 *dy = 0;
293             break;
294         case EVT_mousesystems: case EVT_gpm:
295             *buttons = (~data[0]) & 0x07;
296             *dx = (char)(data[1]) + (char)(data[3]);
297             *dy = -((char)(data[2]) + (char)(data[4]));
298             break;
299         case EVT_logitech:
300             *buttons= data[0] & 0x07;
301             *dx = (data[0] & 0x10) ?   data[1] : - data[1];
302             *dy = (data[0] & 0x08) ? - data[2] :   data[2];
303             break;
304         case EVT_busmouse:
305             *buttons= (~data[0]) & 0x07;
306             *dx = (char)data[1];
307             *dy = -(char)data[2];
308             break;
309         case EVT_MMseries:
310             *buttons = data[0] & 0x07;
311             *dx = (data[0] & 0x10) ?   data[1] : - data[1];
312             *dy = (data[0] & 0x08) ? - data[2] :   data[2];
313             break;
314         case EVT_intellimouse:
315             *buttons = ((data[0] & 0x20) >> 3)  /* left */
316                      | ((data[3] & 0x10) >> 3)  /* middle */
317                      | ((data[0] & 0x10) >> 4); /* right */
318             *dx = (char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
319             *dy = (char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
320             break;
321         case EVT_intellimouse_ps2:
322             *buttons = (data[0] & 0x04) >> 1 /* Middle */
323                 | (data[0] & 0x02) >> 1 /* Right */
324                 | (data[0] & 0x01) << 2; /* Left */
325             *dx = (data[0] & 0x10) ?    data[1]-256  :  data[1];
326             *dy = (data[0] & 0x20) ?  -(data[2]-256) : -data[2];
327             break;
328         case EVT_mouseman: {
329             static int      getextra;
330             static uchar    prev=0;
331             uchar           b;
332
333             /* The damned MouseMan has 3/4 bytes packets. The extra byte
334              * is only there if the middle button is active.
335              * I get the extra byte as a packet with magic numbers in it.
336              * and then switch to 4-byte mode.
337              */
338             if (data[1] == 0xAA && data[2] == 0x55) {
339                 /* Got unexpected fourth byte */
340                 if ((b = (*data>>4)) > 0x3)
341                     return false;  /* just a sanity check */
342                 *dx = *dy = 0;
343                 drv->packet_len=4;
344                 getextra=0;
345                 }
346             else {
347                 /* Got 3/4, as expected */
348                 /* Motion is independent of packetlen... */
349                 *dx = (char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F));
350                 *dy = (char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F));
351                 prev = ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4);
352                 if (drv->packet_len==4)
353                     b = data[3]>>4;
354                 }
355             if (drv->packet_len == 4) {
356                 if (b == 0) {
357                     drv->packet_len = 3;
358                     getextra = 1;
359                     }
360                 else {
361                     if (b & 0x2)
362                         prev |= 2;
363                     }
364                 }
365             *buttons = prev;
366
367             /* This "chord-middle" behaviour was reported by David A. van Leeuwen */
368             if (((prev ^ *buttons) & 5) == 5)
369                 *buttons = *buttons ? 2 : 0;
370             prev = *buttons;
371             break;
372             }
373         case EVT_noMouse:
374             return false;
375             break;
376         }
377     return true;
378 }
379
380 /****************************************************************************
381 REMARKS:
382 Map a keypress via the key mapping table
383 ****************************************************************************/
384 static int getKeyMapping(
385     keymap *tab,
386     int nb,
387     int key)
388 {
389     int i;
390
391     for(i = 0; i < nb; i++) {
392         if (tab[i].scan == key)
393             return tab[i].map;
394         }
395     return key;
396 }
397
398 #ifdef USE_OS_JOYSTICK
399
400 static char js0_axes = 0, js0_buttons = 0;
401 static char js1_axes = 0, js1_buttons = 0;
402 static char joystick0_dev[20] = "/dev/js0";
403 static char joystick1_dev[20] = "/dev/js1";
404
405 /****************************************************************************
406 REMARKS:
407 Create a joystick event from the joystick data
408 ****************************************************************************/
409 static void makeJoyEvent(
410     event_t *evt)
411 {
412     evt->message = 0;
413     if (buts0 && axis0) {
414         if (buts0[0]) evt->message |= EVT_JOY1_BUTTONA;
415         if (buts0[1]) evt->message |= EVT_JOY1_BUTTONB;
416         evt->where_x = axis0[0];
417         evt->where_y = axis0[1];
418         }
419     else
420         evt->where_x = evt->where_y = 0;
421     if (buts1 && axis1) {
422         if (buts1[0]) evt->message |= EVT_JOY2_BUTTONA;
423         if (buts1[1]) evt->message |= EVT_JOY2_BUTTONB;
424         evt->where_x = axis1[0];
425         evt->where_y = axis1[1];
426         }
427     else
428         evt->where_x = evt->where_y = 0;
429 }
430
431 /****************************************************************************
432 REMARKS:
433 Read the joystick axis data
434 ****************************************************************************/
435 int EVTAPI _EVT_readJoyAxis(
436     int jmask,
437     int *axis)
438 {
439     int mask = 0;
440
441     if ((js_version & ~0xffff) == 0) {
442         /* Old 0.x driver */
443         struct JS_DATA_TYPE js;
444         if (joystick0_fd && read(joystick0_fd, &js, JS_RETURN) == JS_RETURN) {
445             if (jmask & EVT_JOY_AXIS_X1)
446                 axis[0] = js.x;
447             if (jmask & EVT_JOY_AXIS_Y1)
448                 axis[1] = js.y;
449             mask |= EVT_JOY_AXIS_X1|EVT_JOY_AXIS_Y1;
450             }
451         if (joystick1_fd && read(joystick1_fd, &js, JS_RETURN) == JS_RETURN) {
452             if (jmask & EVT_JOY_AXIS_X2)
453                 axis[2] = js.x;
454             if (jmask & EVT_JOY_AXIS_Y2)
455                 axis[3] = js.y;
456             mask |= EVT_JOY_AXIS_X2|EVT_JOY_AXIS_Y2;
457             }
458         }
459     else {
460         if (axis0) {
461             if (jmask & EVT_JOY_AXIS_X1)
462                 axis[0] = axis0[0];
463             if (jmask & EVT_JOY_AXIS_Y1)
464                 axis[1] = axis0[1];
465             mask |= EVT_JOY_AXIS_X1 | EVT_JOY_AXIS_Y1;
466             }
467         if (axis1) {
468             if (jmask & EVT_JOY_AXIS_X2)
469                 axis[2] = axis1[0];
470             if (jmask & EVT_JOY_AXIS_Y2)
471                 axis[3] = axis1[1];
472             mask |= EVT_JOY_AXIS_X2 | EVT_JOY_AXIS_Y2;
473             }
474         }
475     return mask;
476 }
477
478 /****************************************************************************
479 REMARKS:
480 Read the joystick button data
481 ****************************************************************************/
482 int EVTAPI _EVT_readJoyButtons(void)
483 {
484     int buts = 0;
485
486     if ((js_version & ~0xffff) == 0) {
487         /* Old 0.x driver */
488         struct JS_DATA_TYPE js;
489         if (joystick0_fd && read(joystick0_fd, &js, JS_RETURN) == JS_RETURN)
490             buts = js.buttons;
491         if (joystick1_fd && read(joystick1_fd, &js, JS_RETURN) == JS_RETURN)
492             buts |= js.buttons << 2;
493         }
494     else {
495         if (buts0)
496             buts |= EVT_JOY1_BUTTONA*buts0[0] + EVT_JOY1_BUTTONB*buts0[1];
497         if (buts1)
498             buts |= EVT_JOY2_BUTTONA*buts1[0] + EVT_JOY2_BUTTONB*buts1[1];
499         }
500     return buts;
501 }
502
503 /****************************************************************************
504 DESCRIPTION:
505 Returns the mask indicating what joystick axes are attached.
506
507 HEADER:
508 event.h
509
510 REMARKS:
511 This function is used to detect the attached joysticks, and determine
512 what axes are present and functioning. This function will re-detect any
513 attached joysticks when it is called, so if the user forgot to attach
514 the joystick when the application started, you can call this function to
515 re-detect any newly attached joysticks.
516
517 SEE ALSO:
518 EVT_joySetLowerRight, EVT_joySetCenter, EVT_joyIsPresent
519 ****************************************************************************/
520 int EVTAPI EVT_joyIsPresent(void)
521 {
522     static int      mask = 0;
523     int             i;
524     char            *tmp, name0[128], name1[128];
525     static ibool    inited = false;
526
527     if (inited)
528         return mask;
529     memset(EVT.joyMin,0,sizeof(EVT.joyMin));
530     memset(EVT.joyCenter,0,sizeof(EVT.joyCenter));
531     memset(EVT.joyMax,0,sizeof(EVT.joyMax));
532     memset(EVT.joyPrev,0,sizeof(EVT.joyPrev));
533     EVT.joyButState = 0;
534     if ((tmp = getenv(ENV_JOYDEV0)) != NULL)
535         strcpy(joystick0_dev,tmp);
536     if ((tmp = getenv(ENV_JOYDEV1)) != NULL)
537         strcpy(joystick1_dev,tmp);
538     if ((joystick0_fd = open(joystick0_dev, O_RDONLY)) < 0)
539         joystick0_fd = 0;
540     if ((joystick1_fd = open(joystick1_dev, O_RDONLY)) < 0)
541         joystick1_fd = 0;
542     if (!joystick0_fd && !joystick1_fd) // No joysticks detected
543         return 0;
544     inited = true;
545     if (ioctl(joystick0_fd ? joystick0_fd : joystick1_fd, JSIOCGVERSION, &js_version) < 0)
546         return 0;
547
548     /* Initialise joystick 0 */
549     if (joystick0_fd) {
550         ioctl(joystick0_fd, JSIOCGNAME(sizeof(name0)), name0);
551         if (js_version & ~0xffff) {
552             struct js_event js;
553
554             ioctl(joystick0_fd, JSIOCGAXES, &js0_axes);
555             ioctl(joystick0_fd, JSIOCGBUTTONS, &js0_buttons);
556             axis0 = PM_calloc((int)js0_axes, sizeof(short));
557             buts0 = PM_malloc((int)js0_buttons);
558             /* Read the initial events */
559             while(dataReady(joystick0_fd)
560                   && read(joystick0_fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)
561                   && (js.type & JS_EVENT_INIT)
562                   ) {
563                 if (js.type & JS_EVENT_BUTTON)
564                     buts0[js.number] = js.value;
565                 else if (js.type & JS_EVENT_AXIS)
566                     axis0[js.number] = scaleJoyAxis(js.value,js.number);
567                 }
568             }
569         else {
570             js0_axes = 2;
571             js0_buttons = 2;
572             axis0 = PM_calloc((int)js0_axes, sizeof(short));
573             buts0 = PM_malloc((int)js0_buttons);
574             }
575         }
576
577     /* Initialise joystick 1 */
578     if (joystick1_fd) {
579         ioctl(joystick1_fd, JSIOCGNAME(sizeof(name1)), name1);
580         if (js_version & ~0xffff) {
581             struct js_event js;
582
583             ioctl(joystick1_fd, JSIOCGAXES, &js1_axes);
584             ioctl(joystick1_fd, JSIOCGBUTTONS, &js1_buttons);
585             axis1 = PM_calloc((int)js1_axes, sizeof(short));
586             buts1 = PM_malloc((int)js1_buttons);
587             /* Read the initial events */
588             while(dataReady(joystick1_fd)
589                   && read(joystick1_fd, &js, sizeof(struct js_event))==sizeof(struct js_event)
590                   && (js.type & JS_EVENT_INIT)
591                   ) {
592                 if (js.type & JS_EVENT_BUTTON)
593                     buts1[js.number] = js.value;
594                 else if (js.type & JS_EVENT_AXIS)
595                     axis1[js.number] = scaleJoyAxis(js.value,js.number<<2);
596                 }
597             }
598         else {
599             js1_axes = 2;
600             js1_buttons = 2;
601             axis1 = PM_calloc((int)js1_axes, sizeof(short));
602             buts1 = PM_malloc((int)js1_buttons);
603             }
604         }
605
606 #ifdef  CHECKED
607     fprintf(stderr,"Using joystick driver version %d.%d.%d\n", 
608             js_version >> 16, (js_version >> 8) & 0xff, js_version & 0xff);
609     if (joystick0_fd)
610         fprintf(stderr,"Joystick 1 (%s): %s\n", joystick0_dev, name0);
611     if (joystick1_fd)
612         fprintf(stderr,"Joystick 2 (%s): %s\n", joystick1_dev, name1);
613 #endif
614     mask = _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter);
615     if (mask) {
616         for (i = 0; i < JOY_NUM_AXES; i++)
617             EVT.joyMax[i] = EVT.joyCenter[i]*2;
618         }
619     return mask;
620 }
621
622 /****************************************************************************
623 DESCRIPTION:
624 Polls the joystick for position and button information.
625
626 HEADER:
627 event.h
628
629 REMARKS:
630 This routine is used to poll analogue joysticks for button and position
631 information. It should be called once for each main loop of the user
632 application, just before processing all pending events via EVT_getNext.
633 All information polled from the joystick will be posted to the event
634 queue for later retrieval.
635
636 Note:   Most analogue joysticks will provide readings that change even
637         though the joystick has not moved. Hence if you call this routine
638         you will likely get an EVT_JOYMOVE event every time through your
639         event loop.
640
641 SEE ALSO:
642 EVT_getNext, EVT_peekNext, EVT_joySetUpperLeft, EVT_joySetLowerRight,
643 EVT_joySetCenter, EVT_joyIsPresent
644 ****************************************************************************/
645 void EVTAPI EVT_pollJoystick(void)
646 {
647     event_t evt;
648     int     i,axis[JOY_NUM_AXES],newButState,mask,moved,ps;
649
650     if ((js_version & ~0xFFFF) == 0 && EVT.joyMask) {
651         /* Read joystick axes and post movement events if they have
652          * changed since the last time we polled. Until the events are
653          * actually flushed, we keep modifying the same joystick movement
654          * event, so you won't get multiple movement event
655          */
656         mask = _EVT_readJoyAxis(EVT.joyMask,axis);
657         newButState = _EVT_readJoyButtons();
658         moved = false;
659         for (i = 0; i < JOY_NUM_AXES; i++) {
660             if (mask & (EVT_JOY_AXIS_X1 << i))
661                 axis[i] = scaleJoyAxis(axis[i],i);
662             else
663                 axis[i] = EVT.joyPrev[i];
664             if (axis[i] != EVT.joyPrev[i])
665                 moved = true;
666             }
667         if (moved) {
668             memcpy(EVT.joyPrev,axis,sizeof(EVT.joyPrev));
669             ps = _EVT_disableInt();
670             if (EVT.oldJoyMove != -1) {
671                 /* Modify the existing joystick movement event */
672                 EVT.evtq[EVT.oldJoyMove].message = newButState;
673                 EVT.evtq[EVT.oldJoyMove].where_x = EVT.joyPrev[0];
674                 EVT.evtq[EVT.oldJoyMove].where_y = EVT.joyPrev[1];
675                 EVT.evtq[EVT.oldJoyMove].relative_x = EVT.joyPrev[2];
676                 EVT.evtq[EVT.oldJoyMove].relative_y = EVT.joyPrev[3];
677                 }
678             else if (EVT.count < EVENTQSIZE) {
679                 /* Add a new joystick movement event */
680                 EVT.oldJoyMove = EVT.freeHead;
681                 memset(&evt,0,sizeof(evt));
682                 evt.what = EVT_JOYMOVE;
683                 evt.message = EVT.joyButState;
684                 evt.where_x = EVT.joyPrev[0];
685                 evt.where_y = EVT.joyPrev[1];
686                 evt.relative_x = EVT.joyPrev[2];
687                 evt.relative_y = EVT.joyPrev[3];
688                 addEvent(&evt);
689                 }
690             _EVT_restoreInt(ps);
691             }
692
693         /* Read the joystick buttons, and post events to reflect the change
694          * in state for the joystick buttons.
695          */
696         if (newButState != EVT.joyButState) {
697             if (EVT.count < EVENTQSIZE) {
698                 /* Add a new joystick movement event */
699                 ps = _EVT_disableInt();
700                 memset(&evt,0,sizeof(evt));
701                 evt.what = EVT_JOYCLICK;
702                 evt.message = newButState;
703                 EVT.evtq[EVT.oldJoyMove].where_x = EVT.joyPrev[0];
704                 EVT.evtq[EVT.oldJoyMove].where_y = EVT.joyPrev[1];
705                 EVT.evtq[EVT.oldJoyMove].relative_x = EVT.joyPrev[2];
706                 EVT.evtq[EVT.oldJoyMove].relative_y = EVT.joyPrev[3];
707                 addEvent(&evt);
708                 _EVT_restoreInt(ps);
709                 }
710             EVT.joyButState = newButState;
711             }
712         }
713 }
714
715 /****************************************************************************
716 DESCRIPTION:
717 Calibrates the joystick upper left position
718
719 HEADER:
720 event.h
721
722 REMARKS:
723 This function can be used to zero in on better joystick calibration factors,
724 which may work better than the default simplistic calibration (which assumes
725 the joystick is centered when the event library is initialised).
726 To use this function, ask the user to hold the stick in the upper left
727 position and then have them press a key or button. and then call this
728 function. This function will then read the joystick and update the
729 calibration factors.
730
731 Usually, assuming that the stick was centered when the event library was
732 initialized, you really only need to call EVT_joySetLowerRight since the
733 upper left position is usually always 0,0 on most joysticks. However, the
734 safest procedure is to call all three calibration functions.
735
736 SEE ALSO:
737 EVT_joySetUpperLeft, EVT_joySetLowerRight, EVT_joyIsPresent
738 ****************************************************************************/
739 void EVTAPI EVT_joySetUpperLeft(void)
740 {
741     _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyMin);
742 }
743
744 /****************************************************************************
745 DESCRIPTION:
746 Calibrates the joystick lower right position
747
748 HEADER:
749 event.h
750
751 REMARKS:
752 This function can be used to zero in on better joystick calibration factors,
753 which may work better than the default simplistic calibration (which assumes
754 the joystick is centered when the event library is initialised).
755 To use this function, ask the user to hold the stick in the lower right
756 position and then have them press a key or button. and then call this
757 function. This function will then read the joystick and update the
758 calibration factors.
759
760 Usually, assuming that the stick was centered when the event library was
761 initialized, you really only need to call EVT_joySetLowerRight since the
762 upper left position is usually always 0,0 on most joysticks. However, the
763 safest procedure is to call all three calibration functions.
764
765 SEE ALSO:
766 EVT_joySetUpperLeft, EVT_joySetCenter, EVT_joyIsPresent
767 ****************************************************************************/
768 void EVTAPI EVT_joySetLowerRight(void)
769 {
770     _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyMax);
771 }
772
773 /****************************************************************************
774 DESCRIPTION:
775 Calibrates the joystick center position
776
777 HEADER:
778 event.h
779
780 REMARKS:
781 This function can be used to zero in on better joystick calibration factors,
782 which may work better than the default simplistic calibration (which assumes
783 the joystick is centered when the event library is initialised).
784 To use this function, ask the user to hold the stick in the center
785 position and then have them press a key or button. and then call this
786 function. This function will then read the joystick and update the
787 calibration factors.
788
789 Usually, assuming that the stick was centered when the event library was
790 initialized, you really only need to call EVT_joySetLowerRight since the
791 upper left position is usually always 0,0 on most joysticks. However, the
792 safest procedure is to call all three calibration functions.
793
794 SEE ALSO:
795 EVT_joySetUpperLeft, EVT_joySetLowerRight, EVT_joySetCenter
796 ****************************************************************************/
797 void EVTAPI EVT_joySetCenter(void)
798 {
799     _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter);
800 }
801 #endif
802
803 /****************************************************************************
804 REMARKS:
805 Pumps all messages in the message queue from Linux into our event queue.
806 ****************************************************************************/
807 static void _EVT_pumpMessages(void)
808 {
809     event_t                 evt;
810     int                     i,numkeys, c;
811     ibool                   release;
812     static struct kbentry   ke;
813     static char             buf[KBDREADBUFFERSIZE];
814     static ushort           repeatKey[128] = {0};
815
816     /* Poll keyboard events */
817     while (dataReady(_PM_console_fd) && (numkeys = read(_PM_console_fd, buf, KBDREADBUFFERSIZE)) > 0) {
818         for (i = 0; i < numkeys; i++) {
819             c = buf[i];
820             release = c & 0x80;
821             c &= 0x7F;
822
823             // TODO:    This is wrong! We need this to be the time stamp at
824             //          ** interrupt ** time!! One solution would be to
825             //          put the keyboard and mouse polling loops into
826             //          a separate thread that can block on I/O to the
827             //          necessay file descriptor.
828             evt.when = _EVT_getTicks();
829
830             if (release) {
831                 /* Key released */
832                 evt.what = EVT_KEYUP;
833                 switch (c) {
834                     case KB_leftShift:
835                         _PM_modifiers &= ~EVT_LEFTSHIFT;
836                         break;
837                     case KB_rightShift:
838                         _PM_modifiers &= ~EVT_RIGHTSHIFT;
839                         break;
840                     case 29:
841                         _PM_modifiers &= ~(EVT_LEFTCTRL|EVT_CTRLSTATE);
842                         break;
843                     case 97:            /* Control */
844                         _PM_modifiers &= ~EVT_CTRLSTATE;
845                         break;
846                     case 56:
847                         _PM_modifiers &= ~(EVT_LEFTALT|EVT_ALTSTATE);
848                         break;
849                     case 100:
850                         _PM_modifiers &= ~EVT_ALTSTATE;
851                         break;
852                     default:
853                     }
854                 evt.modifiers = _PM_modifiers;
855                 evt.message = keyUpMsg[c];
856                 if (EVT.count < EVENTQSIZE)
857                     addEvent(&evt);
858                 keyUpMsg[c] = 0;
859                 repeatKey[c] = 0;
860                 }
861             else {
862                 /* Key pressed */
863                 evt.what = EVT_KEYDOWN;
864                 switch (c) {
865                     case KB_leftShift:
866                         _PM_modifiers |= EVT_LEFTSHIFT;
867                         break;
868                     case KB_rightShift:
869                         _PM_modifiers |= EVT_RIGHTSHIFT;
870                         break;
871                     case 29:
872                         _PM_modifiers |= EVT_LEFTCTRL|EVT_CTRLSTATE;
873                         break;
874                     case 97:            /* Control */
875                         _PM_modifiers |= EVT_CTRLSTATE;
876                         break;
877                     case 56:
878                         _PM_modifiers |= EVT_LEFTALT|EVT_ALTSTATE;
879                         break;
880                     case 100:
881                         _PM_modifiers |= EVT_ALTSTATE;
882                         break;
883                     case KB_capsLock:   /* Caps Lock */
884                         _PM_leds ^= LED_CAP;
885                         ioctl(_PM_console_fd, KDSETLED, _PM_leds);
886                         break;
887                     case KB_numLock:    /* Num Lock */
888                         _PM_leds ^= LED_NUM;
889                         ioctl(_PM_console_fd, KDSETLED, _PM_leds);
890                         break;
891                     case KB_scrollLock: /* Scroll Lock */
892                         _PM_leds ^= LED_SCR;
893                         ioctl(_PM_console_fd, KDSETLED, _PM_leds);
894                         break;
895                     default:
896                     }
897                 evt.modifiers = _PM_modifiers;
898                 if (keyUpMsg[c]) {
899                     evt.what = EVT_KEYREPEAT;
900                     evt.message = keyUpMsg[c] | (repeatKey[c]++ << 16);
901                     }
902                 else {
903                     int asc;
904
905                     evt.message = getKeyMapping(keymaps, NB_KEYMAPS, c) << 8;
906                     ke.kb_index = c;
907                     ke.kb_table = 0;
908                     if ((_PM_modifiers & EVT_SHIFTKEY) || (_PM_leds & LED_CAP))
909                         ke.kb_table |= K_SHIFTTAB;
910                     if (_PM_modifiers & (EVT_LEFTALT | EVT_ALTSTATE))
911                         ke.kb_table |= K_ALTTAB;
912                     if (ioctl(_PM_console_fd, KDGKBENT, (unsigned long)&ke)<0)
913                         perror("ioctl(KDGKBENT)");
914                     if ((_PM_leds & LED_NUM) && (getKeyMapping(keypad, NB_KEYPAD, c)!=c)) {
915                         asc = getKeyMapping(keypad, NB_KEYPAD, c);
916                         }
917                     else {
918                         switch (c) {
919                             case 14:
920                                 asc = ASCII_backspace;
921                                 break;
922                             case 15:
923                                 asc = ASCII_tab;
924                                 break;
925                             case 28:
926                             case 96:
927                                 asc = ASCII_enter;
928                                 break;
929                             case 1:
930                                 asc = ASCII_esc;
931                             default:
932                                 asc = ke.kb_value & 0xFF;
933                                 if (asc < 0x1B)
934                                     asc = 0;
935                                 break;
936                             }
937                         }
938                     if ((_PM_modifiers & (EVT_CTRLSTATE|EVT_LEFTCTRL)) && isalpha(asc))
939                         evt.message |= toupper(asc) - 'A' + 1;
940                     else
941                         evt.message |= asc;
942                     keyUpMsg[c] = evt.message;
943                     repeatKey[c]++;
944                     }
945                 if (EVT.count < EVENTQSIZE)
946                     addEvent(&evt);
947                 }
948             }
949         }
950
951     /* Poll mouse events */
952     if (_EVT_mouse_fd) {
953         int         dx, dy, buts;
954         static int  oldbuts;
955
956         while (dataReady(_EVT_mouse_fd)) {
957             if (readMouseData(&buts, &dx, &dy)) {
958                 EVT.mx += dx;
959                 EVT.my += dy;
960                 if (EVT.mx < 0) EVT.mx = 0;
961                 if (EVT.my < 0) EVT.my = 0;
962                 if (EVT.mx > range_x) EVT.mx = range_x;
963                 if (EVT.my > range_y) EVT.my = range_y;
964                 evt.where_x = EVT.mx;
965                 evt.where_y = EVT.my;
966                 evt.relative_x = dx;
967                 evt.relative_y = dy;
968
969                 // TODO:    This is wrong! We need this to be the time stamp at
970                 //          ** interrupt ** time!! One solution would be to
971                 //          put the keyboard and mouse polling loops into
972                 //          a separate thread that can block on I/O to the
973                 //          necessay file descriptor.
974                 evt.when = _EVT_getTicks();
975                 evt.modifiers = _PM_modifiers;
976                 if (buts & 4)
977                     evt.modifiers |= EVT_LEFTBUT;
978                 if (buts & 1)
979                     evt.modifiers |= EVT_RIGHTBUT;
980                 if (buts & 2)
981                     evt.modifiers |= EVT_MIDDLEBUT;
982
983                 /* Left click events */
984                 if ((buts&4) != (oldbuts&4)) {
985                     if (buts&4)
986                         evt.what = EVT_MOUSEDOWN;
987                     else
988                         evt.what = EVT_MOUSEUP;
989                     evt.message = EVT_LEFTBMASK;
990                     EVT.oldMove = -1;
991                     if (EVT.count < EVENTQSIZE)
992                         addEvent(&evt);
993                     }
994
995                 /* Right click events */
996                 if ((buts&1) != (oldbuts&1)) {
997                     if (buts&1)
998                         evt.what = EVT_MOUSEDOWN;
999                     else
1000                         evt.what = EVT_MOUSEUP;
1001                     evt.message = EVT_RIGHTBMASK;
1002                     EVT.oldMove = -1;
1003                     if (EVT.count < EVENTQSIZE)
1004                         addEvent(&evt);
1005                     }
1006
1007                 /* Middle click events */
1008                 if ((buts&2) != (oldbuts&2)) {
1009                     if (buts&2)
1010                         evt.what = EVT_MOUSEDOWN;
1011                     else
1012                         evt.what = EVT_MOUSEUP;
1013                     evt.message = EVT_MIDDLEBMASK;
1014                     EVT.oldMove = -1;
1015                     if (EVT.count < EVENTQSIZE)
1016                         addEvent(&evt);
1017                     }
1018
1019                 /* Mouse movement event */
1020                 if (dx || dy) {
1021                     evt.what = EVT_MOUSEMOVE;
1022                     evt.message = 0;
1023                     if (EVT.oldMove != -1) {
1024                         /* Modify existing movement event */
1025                         EVT.evtq[EVT.oldMove].where_x = evt.where_x;
1026                         EVT.evtq[EVT.oldMove].where_y = evt.where_y;
1027                         }
1028                     else {
1029                         /* Save id of this movement event */
1030                         EVT.oldMove = EVT.freeHead;
1031                         if (EVT.count < EVENTQSIZE)
1032                             addEvent(&evt);
1033                         }
1034                     }
1035                 oldbuts = buts;
1036                 }
1037             }
1038         }
1039
1040 #ifdef USE_OS_JOYSTICK
1041     // Poll joystick events using the 1.x joystick driver API in the 2.2 kernels
1042     if (js_version & ~0xffff) {
1043         static struct js_event  js;
1044
1045         /* Read joystick axis 0 */
1046         evt.when = 0;
1047         evt.modifiers = _PM_modifiers;
1048         if (joystick0_fd && dataReady(joystick0_fd) &&
1049                 read(joystick0_fd, &js, sizeof(js)) == sizeof(js)) {
1050             if (js.type & JS_EVENT_BUTTON) {
1051                 if (js.number < 2) { /* Only 2 buttons for now :( */
1052                     buts0[js.number] = js.value;
1053                     evt.what = EVT_JOYCLICK;
1054                     makeJoyEvent(&evt);
1055                     if (EVT.count < EVENTQSIZE)
1056                         addEvent(&evt);
1057                     }
1058                 }
1059             else if (js.type & JS_EVENT_AXIS) {
1060                 axis0[js.number] = scaleJoyAxis(js.value,js.number);
1061                 evt.what = EVT_JOYMOVE;
1062                 if (EVT.oldJoyMove != -1) {
1063                     makeJoyEvent(&EVT.evtq[EVT.oldJoyMove]);
1064                     }
1065                 else if (EVT.count < EVENTQSIZE) {
1066                     EVT.oldJoyMove = EVT.freeHead;
1067                     makeJoyEvent(&evt);
1068                     addEvent(&evt);
1069                     }
1070                 }
1071             }
1072
1073         /* Read joystick axis 1 */
1074         if (joystick1_fd && dataReady(joystick1_fd) &&
1075                 read(joystick1_fd, &js, sizeof(js))==sizeof(js)) {
1076             if (js.type & JS_EVENT_BUTTON) {
1077                 if (js.number < 2) { /* Only 2 buttons for now :( */
1078                     buts1[js.number] = js.value;
1079                     evt.what = EVT_JOYCLICK;
1080                     makeJoyEvent(&evt);
1081                     if (EVT.count < EVENTQSIZE)
1082                         addEvent(&evt);
1083                     }
1084                 }
1085             else if (js.type & JS_EVENT_AXIS) {
1086                 axis1[js.number] = scaleJoyAxis(js.value,js.number<<2);
1087                 evt.what = EVT_JOYMOVE;
1088                 if (EVT.oldJoyMove != -1) {
1089                     makeJoyEvent(&EVT.evtq[EVT.oldJoyMove]);
1090                     }
1091                 else if (EVT.count < EVENTQSIZE) {
1092                     EVT.oldJoyMove = EVT.freeHead;
1093                     makeJoyEvent(&evt);
1094                     addEvent(&evt);
1095                     }
1096                 }
1097             }
1098         }
1099 #endif
1100 }
1101
1102 /****************************************************************************
1103 REMARKS:
1104 This macro/function is used to converts the scan codes reported by the
1105 keyboard to our event libraries normalised format. We only have one scan
1106 code for the 'A' key, and use shift _PM_modifiers to determine if it is a
1107 Ctrl-F1, Alt-F1 etc. The raw scan codes from the keyboard work this way,
1108 but the OS gives us 'cooked' scan codes, we have to translate them back
1109 to the raw format.
1110 ****************************************************************************/
1111 #define _EVT_maskKeyCode(evt)
1112
1113 /****************************************************************************
1114 REMARKS:
1115 Set the speed of the serial port
1116 ****************************************************************************/
1117 static int setspeed(
1118     int fd,
1119     int old,
1120     int new,
1121     unsigned short flags)
1122 {
1123     struct termios tty;
1124     char *c;
1125   
1126     tcgetattr(fd, &tty);
1127     tty.c_iflag = IGNBRK | IGNPAR;
1128     tty.c_oflag = 0;
1129     tty.c_lflag = 0;
1130     tty.c_line = 0;
1131     tty.c_cc[VTIME] = 0;
1132     tty.c_cc[VMIN] = 1;
1133     switch (old) {
1134         case 9600:  tty.c_cflag = flags | B9600; break;
1135         case 4800:  tty.c_cflag = flags | B4800; break;
1136         case 2400:  tty.c_cflag = flags | B2400; break;
1137         case 1200:
1138         default:    tty.c_cflag = flags | B1200; break;
1139         }
1140     tcsetattr(fd, TCSAFLUSH, &tty);
1141     switch (new) {
1142         case 9600:  c = "*q";  tty.c_cflag = flags | B9600; break;
1143         case 4800:  c = "*p";  tty.c_cflag = flags | B4800; break;
1144         case 2400:  c = "*o";  tty.c_cflag = flags | B2400; break;
1145         case 1200:
1146         default:    c = "*n";  tty.c_cflag = flags | B1200; break;
1147         }
1148     write(fd, c, 2);
1149     usleep(100000);
1150     tcsetattr(fd, TCSAFLUSH, &tty);
1151     return 0;
1152 }
1153
1154 /****************************************************************************
1155 REMARKS:
1156 Generic mouse driver init code
1157 ****************************************************************************/
1158 static void _EVT_mouse_init(void)
1159 {
1160     int i;
1161
1162     /* Change from any available speed to the chosen one */
1163     for (i = 9600; i >= 1200; i /= 2)
1164         setspeed(_EVT_mouse_fd, i, opt_baud, mouse_infos[mouse_driver].flags);
1165 }
1166
1167 /****************************************************************************
1168 REMARKS:
1169 Logitech mouse driver init code
1170 ****************************************************************************/
1171 static void _EVT_logitech_init(void)
1172 {
1173     int         i;
1174     struct stat buf;
1175     int         busmouse;
1176     
1177     /* is this a serial- or a bus- mouse? */
1178     if (fstat(_EVT_mouse_fd,&buf) == -1)
1179         perror("fstat");
1180     i = MAJOR(buf.st_rdev);
1181     if (stat("/dev/ttyS0",&buf) == -1)
1182         perror("stat");
1183     busmouse=(i != MAJOR(buf.st_rdev));
1184     
1185     /* Fix the howmany field, so that serial mice have 1, while busmice have 3 */
1186     mouse_infos[mouse_driver].read = busmouse ? 3 : 1;
1187     
1188     /* Change from any available speed to the chosen one */
1189     for (i = 9600; i >= 1200; i /= 2)
1190         setspeed(_EVT_mouse_fd, i, opt_baud, mouse_infos[mouse_driver].flags);
1191   
1192     /* This stuff is peculiar of logitech mice, also for the serial ones */
1193     write(_EVT_mouse_fd, "S", 1);
1194     setspeed(_EVT_mouse_fd, opt_baud, opt_baud,CS8 |PARENB |PARODD |CREAD |CLOCAL |HUPCL);
1195   
1196     /* Configure the sample rate */
1197     for (i = 0; opt_sample <= sampletab[i].sample; i++)
1198         ;
1199     write(_EVT_mouse_fd,sampletab[i].code,1);
1200 }
1201
1202 /****************************************************************************
1203 REMARKS:
1204 Microsoft Intellimouse init code
1205 ****************************************************************************/
1206 static void _EVT_pnpmouse_init(void)
1207 {
1208     struct termios tty;
1209   
1210     tcgetattr(_EVT_mouse_fd, &tty);
1211     tty.c_iflag = IGNBRK | IGNPAR;
1212     tty.c_oflag = 0;
1213     tty.c_lflag = 0;
1214     tty.c_line = 0;
1215     tty.c_cc[VTIME] = 0;
1216     tty.c_cc[VMIN] = 1;
1217     tty.c_cflag = mouse_infos[mouse_driver].flags | B1200;
1218     tcsetattr(_EVT_mouse_fd, TCSAFLUSH, &tty); /* set parameters */
1219 }
1220
1221 /****************************************************************************
1222 PARAMETERS:
1223 mouseMove   - Callback function to call wheneve the mouse needs to be moved
1224
1225 REMARKS:
1226 Initiliase the event handling module. Here we install our mouse handling ISR
1227 to be called whenever any button's are pressed or released. We also build
1228 the free list of events in the event queue.
1229
1230 We use handler number 2 of the mouse libraries interrupt handlers for our
1231 event handling routines.
1232 ****************************************************************************/
1233 void EVTAPI EVT_init(
1234     _EVT_mouseMoveHandler mouseMove)
1235 {
1236     int         i;
1237     char        *tmp;
1238
1239     /* Initialise the event queue */
1240     EVT.mouseMove = mouseMove;
1241     initEventQueue();
1242     for (i = 0; i < 256; i++)
1243         keyUpMsg[i] = 0;
1244
1245     /* Keyboard initialization */
1246     if (_PM_console_fd == -1)
1247         PM_fatalError("You must first call PM_openConsole to use the EVT functions!");
1248     _PM_keyboard_rawmode();
1249     fcntl(_PM_console_fd,F_SETFL,fcntl(_PM_console_fd,F_GETFL) | O_NONBLOCK);
1250
1251     /* Mouse initialization */
1252     if ((tmp = getenv(ENV_MOUSEDRV)) != NULL) {
1253         for (i = 0; i < NB_MICE; i++) {
1254             if (!strcasecmp(tmp, mouse_infos[i].name)) {
1255                 mouse_driver = i;
1256                 break;
1257                 }
1258             }
1259         if (i == NB_MICE) {
1260             fprintf(stderr,"Unknown mouse driver: %s\n", tmp);
1261             mouse_driver = EVT_noMouse;
1262             _EVT_mouse_fd = 0;
1263             }
1264         }
1265     if (mouse_driver != EVT_noMouse) {
1266         if (mouse_driver == EVT_gpm)
1267             strcpy(mouse_dev,"/dev/gpmdata");
1268         if ((tmp = getenv(ENV_MOUSEDEV)) != NULL)
1269             strcpy(mouse_dev,tmp);
1270 #ifdef  CHECKED
1271         fprintf(stderr,"Using the %s MGL mouse driver on %s.\n", mouse_infos[mouse_driver].name, mouse_dev);
1272 #endif
1273         if ((_EVT_mouse_fd = open(mouse_dev, O_RDWR)) < 0) {
1274             perror("open");
1275             fprintf(stderr, "Unable to open mouse device %s, dropping mouse support.\n", mouse_dev);
1276             sleep(1);
1277             mouse_driver = EVT_noMouse;
1278             _EVT_mouse_fd = 0;
1279             }
1280         else {
1281             char c;
1282
1283             /* Init and flush the mouse pending input queue */
1284             if (mouse_infos[mouse_driver].init)
1285                 mouse_infos[mouse_driver].init();
1286             while(dataReady(_EVT_mouse_fd) && read(_EVT_mouse_fd, &c, 1) == 1)
1287                 ;
1288             }
1289         }
1290 }
1291
1292 /****************************************************************************
1293 REMARKS
1294 Changes the range of coordinates returned by the mouse functions to the
1295 specified range of values. This is used when changing between graphics
1296 modes set the range of mouse coordinates for the new display mode.
1297 ****************************************************************************/
1298 void EVTAPI EVT_setMouseRange(
1299     int xRes,
1300     int yRes)
1301 {
1302     range_x = xRes;
1303     range_y = yRes;
1304 }
1305
1306 /****************************************************************************
1307 REMARKS
1308 Modifes the mouse coordinates as necessary if scaling to OS coordinates,
1309 and sets the OS mouse cursor position.
1310 ****************************************************************************/
1311 #define _EVT_setMousePos(x,y)
1312
1313 /****************************************************************************
1314 REMARKS:
1315 Initiailises the internal event handling modules. The EVT_suspend function
1316 can be called to suspend event handling (such as when shelling out to DOS),
1317 and this function can be used to resume it again later.
1318 ****************************************************************************/
1319 void EVT_resume(void)
1320 {
1321     // Do nothing for Linux
1322 }
1323
1324 /****************************************************************************
1325 REMARKS
1326 Suspends all of our event handling operations. This is also used to
1327 de-install the event handling code.
1328 ****************************************************************************/
1329 void EVT_suspend(void)
1330 {
1331     // Do nothing for Linux
1332 }
1333
1334 /****************************************************************************
1335 REMARKS
1336 Exits the event module for program terminatation.
1337 ****************************************************************************/
1338 void EVT_exit(void)
1339 {
1340     /* Restore signal handlers */
1341     _PM_restore_kb_mode();
1342     if (_EVT_mouse_fd) {
1343         close(_EVT_mouse_fd);
1344         _EVT_mouse_fd = 0;
1345         }
1346 #ifdef USE_OS_JOYSTICK
1347     if (joystick0_fd) {
1348         close(joystick0_fd);
1349         free(axis0);
1350         free(buts0);
1351         joystick0_fd = 0;
1352         }
1353     if (joystick1_fd) {
1354         close(joystick1_fd);
1355         free(axis1);
1356         free(buts1);
1357         joystick1_fd = 0;
1358         }
1359 #endif
1360 }
1361