]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/MAI/bios_emulator/scitech/src/pm/linux/event.c
* Code cleanup:
[people/ms/u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / linux / event.c
CommitLineData
c7de829c
WD
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
36extern int _PM_console_fd;
37static ushort keyUpMsg[256] = {0};
38static int _EVT_mouse_fd = 0;
39static int range_x, range_y;
40static int opt_baud = 1200, opt_sample = 100;
41#ifdef USE_OS_JOYSTICK
42static short *axis0 = NULL, *axis1 = NULL;
43static uchar *buts0 = NULL, *buts1 = NULL;
44static int joystick0_fd = 0, joystick1_fd = 0;
45static int js_version = 0;
46#endif
47
48/* This defines the supported mouse drivers */
49
50typedef 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
64static mouse_drivers_t mouse_driver = EVT_noMouse;
65static char mouse_dev[20] = "/dev/mouse";
66
67typedef 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
78static void _EVT_mouse_init(void);
79static void _EVT_logitech_init(void);
80static void _EVT_pnpmouse_init(void);
81
82mouse_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},
8bde7f77 92 {"IMPS2", CS7 | STD_FLG, NULL, {0xc0, 0x40, 0xc0, 0x00}, 4, 1}, /* ? */
c7de829c
WD
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
107typedef struct {
108 int scan;
109 int map;
110 } keymap;
111
8bde7f77 112/* TODO: Fix this and set it up so we can do a binary search! */
c7de829c
WD
113
114keymap 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
150keymap 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
167typedef struct {
168 int sample;
169 char code[2];
170 } sample_rate;
171
172sample_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/****************************************************************************
194PARAMETERS:
195scanCode - Scan code to test
196
197REMARKS:
198This macro determines if a specified key is currently down at the
199time that the call is made.
200****************************************************************************/
201#define _EVT_isKeyDown(scanCode) (keyUpMsg[scanCode] != 0)
202
203/****************************************************************************
204REMARKS:
205This function is used to return the number of ticks since system
206startup in milliseconds. This should be the same value that is placed into
207the time stamp fields of events, and is used to implement auto mouse down
208events.
209****************************************************************************/
210ulong _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/****************************************************************************
222REMARKS:
223Small Unix function that checks for availability on a file using select()
224****************************************************************************/
225static 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/****************************************************************************
237REMARKS:
238Reads mouse data according to the selected mouse driver.
239****************************************************************************/
240static 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) {
8bde7f77
WD
252 perror("read");
253 return false;
254 }
c7de829c 255 if ((data[0] & drv->proto[0]) != drv->proto[1])
8bde7f77 256 return false;
c7de829c
WD
257
258 /* Load a whole protocol packet */
259 cnt += drv->read;
260 while (cnt < drv->packet_len) {
8bde7f77
WD
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 }
c7de829c 269 if ((data[1] & drv->proto[2]) != drv->proto[3])
8bde7f77 270 return false;
c7de829c
WD
271
272 /* Now decode the protocol packet */
273 switch (mouse_driver) {
8bde7f77
WD
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 }
c7de829c
WD
377 return true;
378}
379
380/****************************************************************************
381REMARKS:
382Map a keypress via the key mapping table
383****************************************************************************/
384static int getKeyMapping(
385 keymap *tab,
386 int nb,
387 int key)
388{
389 int i;
390
391 for(i = 0; i < nb; i++) {
8bde7f77
WD
392 if (tab[i].scan == key)
393 return tab[i].map;
394 }
c7de829c
WD
395 return key;
396}
397
398#ifdef USE_OS_JOYSTICK
399
400static char js0_axes = 0, js0_buttons = 0;
401static char js1_axes = 0, js1_buttons = 0;
402static char joystick0_dev[20] = "/dev/js0";
403static char joystick1_dev[20] = "/dev/js1";
404
405/****************************************************************************
406REMARKS:
407Create a joystick event from the joystick data
408****************************************************************************/
409static void makeJoyEvent(
410 event_t *evt)
411{
412 evt->message = 0;
413 if (buts0 && axis0) {
8bde7f77
WD
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 }
c7de829c 419 else
8bde7f77 420 evt->where_x = evt->where_y = 0;
c7de829c 421 if (buts1 && axis1) {
8bde7f77
WD
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 }
c7de829c 427 else
8bde7f77 428 evt->where_x = evt->where_y = 0;
c7de829c
WD
429}
430
431/****************************************************************************
432REMARKS:
433Read the joystick axis data
434****************************************************************************/
435int EVTAPI _EVT_readJoyAxis(
436 int jmask,
437 int *axis)
438{
439 int mask = 0;
440
441 if ((js_version & ~0xffff) == 0) {
8bde7f77
WD
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 }
c7de829c 459 else {
8bde7f77
WD
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 }
c7de829c
WD
475 return mask;
476}
477
478/****************************************************************************
479REMARKS:
480Read the joystick button data
481****************************************************************************/
482int EVTAPI _EVT_readJoyButtons(void)
483{
484 int buts = 0;
485
486 if ((js_version & ~0xffff) == 0) {
8bde7f77
WD
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 }
c7de829c 494 else {
8bde7f77
WD
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 }
c7de829c
WD
500 return buts;
501}
502
503/****************************************************************************
504DESCRIPTION:
505Returns the mask indicating what joystick axes are attached.
506
507HEADER:
508event.h
509
510REMARKS:
511This function is used to detect the attached joysticks, and determine
512what axes are present and functioning. This function will re-detect any
513attached joysticks when it is called, so if the user forgot to attach
514the joystick when the application started, you can call this function to
515re-detect any newly attached joysticks.
516
517SEE ALSO:
518EVT_joySetLowerRight, EVT_joySetCenter, EVT_joyIsPresent
519****************************************************************************/
520int 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)
8bde7f77 528 return mask;
c7de829c
WD
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)
8bde7f77 535 strcpy(joystick0_dev,tmp);
c7de829c 536 if ((tmp = getenv(ENV_JOYDEV1)) != NULL)
8bde7f77 537 strcpy(joystick1_dev,tmp);
c7de829c 538 if ((joystick0_fd = open(joystick0_dev, O_RDONLY)) < 0)
8bde7f77 539 joystick0_fd = 0;
c7de829c 540 if ((joystick1_fd = open(joystick1_dev, O_RDONLY)) < 0)
8bde7f77
WD
541 joystick1_fd = 0;
542 if (!joystick0_fd && !joystick1_fd) /* No joysticks detected */
543 return 0;
c7de829c
WD
544 inited = true;
545 if (ioctl(joystick0_fd ? joystick0_fd : joystick1_fd, JSIOCGVERSION, &js_version) < 0)
8bde7f77 546 return 0;
c7de829c
WD
547
548 /* Initialise joystick 0 */
549 if (joystick0_fd) {
8bde7f77
WD
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 }
c7de829c
WD
576
577 /* Initialise joystick 1 */
578 if (joystick1_fd) {
8bde7f77
WD
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 }
c7de829c
WD
605
606#ifdef CHECKED
8bde7f77
WD
607 fprintf(stderr,"Using joystick driver version %d.%d.%d\n",
608 js_version >> 16, (js_version >> 8) & 0xff, js_version & 0xff);
c7de829c 609 if (joystick0_fd)
8bde7f77 610 fprintf(stderr,"Joystick 1 (%s): %s\n", joystick0_dev, name0);
c7de829c 611 if (joystick1_fd)
8bde7f77 612 fprintf(stderr,"Joystick 2 (%s): %s\n", joystick1_dev, name1);
c7de829c
WD
613#endif
614 mask = _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter);
615 if (mask) {
8bde7f77
WD
616 for (i = 0; i < JOY_NUM_AXES; i++)
617 EVT.joyMax[i] = EVT.joyCenter[i]*2;
618 }
c7de829c
WD
619 return mask;
620}
621
622/****************************************************************************
623DESCRIPTION:
624Polls the joystick for position and button information.
625
626HEADER:
627event.h
628
629REMARKS:
630This routine is used to poll analogue joysticks for button and position
631information. It should be called once for each main loop of the user
632application, just before processing all pending events via EVT_getNext.
633All information polled from the joystick will be posted to the event
634queue for later retrieval.
635
636Note: Most analogue joysticks will provide readings that change even
8bde7f77
WD
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.
c7de829c
WD
640
641SEE ALSO:
642EVT_getNext, EVT_peekNext, EVT_joySetUpperLeft, EVT_joySetLowerRight,
643EVT_joySetCenter, EVT_joyIsPresent
644****************************************************************************/
645void 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) {
8bde7f77
WD
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 }
c7de829c
WD
713}
714
715/****************************************************************************
716DESCRIPTION:
717Calibrates the joystick upper left position
718
719HEADER:
720event.h
721
722REMARKS:
723This function can be used to zero in on better joystick calibration factors,
724which may work better than the default simplistic calibration (which assumes
725the joystick is centered when the event library is initialised).
726To use this function, ask the user to hold the stick in the upper left
727position and then have them press a key or button. and then call this
728function. This function will then read the joystick and update the
729calibration factors.
730
731Usually, assuming that the stick was centered when the event library was
732initialized, you really only need to call EVT_joySetLowerRight since the
733upper left position is usually always 0,0 on most joysticks. However, the
734safest procedure is to call all three calibration functions.
735
736SEE ALSO:
737EVT_joySetUpperLeft, EVT_joySetLowerRight, EVT_joyIsPresent
738****************************************************************************/
739void EVTAPI EVT_joySetUpperLeft(void)
740{
741 _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyMin);
742}
743
744/****************************************************************************
745DESCRIPTION:
746Calibrates the joystick lower right position
747
748HEADER:
749event.h
750
751REMARKS:
752This function can be used to zero in on better joystick calibration factors,
753which may work better than the default simplistic calibration (which assumes
754the joystick is centered when the event library is initialised).
755To use this function, ask the user to hold the stick in the lower right
756position and then have them press a key or button. and then call this
757function. This function will then read the joystick and update the
758calibration factors.
759
760Usually, assuming that the stick was centered when the event library was
761initialized, you really only need to call EVT_joySetLowerRight since the
762upper left position is usually always 0,0 on most joysticks. However, the
763safest procedure is to call all three calibration functions.
764
765SEE ALSO:
766EVT_joySetUpperLeft, EVT_joySetCenter, EVT_joyIsPresent
767****************************************************************************/
768void EVTAPI EVT_joySetLowerRight(void)
769{
770 _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyMax);
771}
772
773/****************************************************************************
774DESCRIPTION:
775Calibrates the joystick center position
776
777HEADER:
778event.h
779
780REMARKS:
781This function can be used to zero in on better joystick calibration factors,
782which may work better than the default simplistic calibration (which assumes
783the joystick is centered when the event library is initialised).
784To use this function, ask the user to hold the stick in the center
785position and then have them press a key or button. and then call this
786function. This function will then read the joystick and update the
787calibration factors.
788
789Usually, assuming that the stick was centered when the event library was
790initialized, you really only need to call EVT_joySetLowerRight since the
791upper left position is usually always 0,0 on most joysticks. However, the
792safest procedure is to call all three calibration functions.
793
794SEE ALSO:
795EVT_joySetUpperLeft, EVT_joySetLowerRight, EVT_joySetCenter
796****************************************************************************/
797void EVTAPI EVT_joySetCenter(void)
798{
799 _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter);
800}
801#endif
802
803/****************************************************************************
804REMARKS:
805Pumps all messages in the message queue from Linux into our event queue.
806****************************************************************************/
807static 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) {
8bde7f77
WD
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 }
c7de829c
WD
950
951 /* Poll mouse events */
952 if (_EVT_mouse_fd) {
8bde7f77
WD
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 }
c7de829c
WD
1039
1040#ifdef USE_OS_JOYSTICK
8bde7f77 1041 /* Poll joystick events using the 1.x joystick driver API in the 2.2 kernels */
c7de829c 1042 if (js_version & ~0xffff) {
8bde7f77
WD
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 }
c7de829c
WD
1099#endif
1100}
1101
1102/****************************************************************************
1103REMARKS:
1104This macro/function is used to converts the scan codes reported by the
1105keyboard to our event libraries normalised format. We only have one scan
1106code for the 'A' key, and use shift _PM_modifiers to determine if it is a
1107Ctrl-F1, Alt-F1 etc. The raw scan codes from the keyboard work this way,
1108but the OS gives us 'cooked' scan codes, we have to translate them back
1109to the raw format.
1110****************************************************************************/
1111#define _EVT_maskKeyCode(evt)
1112
1113/****************************************************************************
1114REMARKS:
1115Set the speed of the serial port
1116****************************************************************************/
1117static int setspeed(
1118 int fd,
1119 int old,
1120 int new,
1121 unsigned short flags)
1122{
1123 struct termios tty;
1124 char *c;
8bde7f77 1125
c7de829c
WD
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) {
8bde7f77
WD
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 }
c7de829c
WD
1140 tcsetattr(fd, TCSAFLUSH, &tty);
1141 switch (new) {
8bde7f77
WD
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 }
c7de829c
WD
1148 write(fd, c, 2);
1149 usleep(100000);
1150 tcsetattr(fd, TCSAFLUSH, &tty);
1151 return 0;
1152}
1153
1154/****************************************************************************
1155REMARKS:
1156Generic mouse driver init code
1157****************************************************************************/
1158static 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)
8bde7f77 1164 setspeed(_EVT_mouse_fd, i, opt_baud, mouse_infos[mouse_driver].flags);
c7de829c
WD
1165}
1166
1167/****************************************************************************
1168REMARKS:
1169Logitech mouse driver init code
1170****************************************************************************/
1171static void _EVT_logitech_init(void)
1172{
1173 int i;
1174 struct stat buf;
1175 int busmouse;
8bde7f77 1176
c7de829c
WD
1177 /* is this a serial- or a bus- mouse? */
1178 if (fstat(_EVT_mouse_fd,&buf) == -1)
8bde7f77 1179 perror("fstat");
c7de829c
WD
1180 i = MAJOR(buf.st_rdev);
1181 if (stat("/dev/ttyS0",&buf) == -1)
8bde7f77 1182 perror("stat");
c7de829c 1183 busmouse=(i != MAJOR(buf.st_rdev));
8bde7f77 1184
c7de829c
WD
1185 /* Fix the howmany field, so that serial mice have 1, while busmice have 3 */
1186 mouse_infos[mouse_driver].read = busmouse ? 3 : 1;
8bde7f77 1187
c7de829c
WD
1188 /* Change from any available speed to the chosen one */
1189 for (i = 9600; i >= 1200; i /= 2)
8bde7f77
WD
1190 setspeed(_EVT_mouse_fd, i, opt_baud, mouse_infos[mouse_driver].flags);
1191
c7de829c
WD
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);
8bde7f77 1195
c7de829c
WD
1196 /* Configure the sample rate */
1197 for (i = 0; opt_sample <= sampletab[i].sample; i++)
8bde7f77 1198 ;
c7de829c
WD
1199 write(_EVT_mouse_fd,sampletab[i].code,1);
1200}
1201
1202/****************************************************************************
1203REMARKS:
1204Microsoft Intellimouse init code
1205****************************************************************************/
1206static void _EVT_pnpmouse_init(void)
1207{
1208 struct termios tty;
8bde7f77 1209
c7de829c
WD
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/****************************************************************************
1222PARAMETERS:
1223mouseMove - Callback function to call wheneve the mouse needs to be moved
1224
1225REMARKS:
1226Initiliase the event handling module. Here we install our mouse handling ISR
1227to be called whenever any button's are pressed or released. We also build
1228the free list of events in the event queue.
1229
1230We use handler number 2 of the mouse libraries interrupt handlers for our
1231event handling routines.
1232****************************************************************************/
1233void 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++)
8bde7f77 1243 keyUpMsg[i] = 0;
c7de829c
WD
1244
1245 /* Keyboard initialization */
1246 if (_PM_console_fd == -1)
8bde7f77 1247 PM_fatalError("You must first call PM_openConsole to use the EVT functions!");
c7de829c
WD
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) {
8bde7f77
WD
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 }
c7de829c 1265 if (mouse_driver != EVT_noMouse) {
8bde7f77
WD
1266 if (mouse_driver == EVT_gpm)
1267 strcpy(mouse_dev,"/dev/gpmdata");
1268 if ((tmp = getenv(ENV_MOUSEDEV)) != NULL)
1269 strcpy(mouse_dev,tmp);
c7de829c 1270#ifdef CHECKED
8bde7f77 1271 fprintf(stderr,"Using the %s MGL mouse driver on %s.\n", mouse_infos[mouse_driver].name, mouse_dev);
c7de829c 1272#endif
8bde7f77
WD
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 }
c7de829c
WD
1290}
1291
1292/****************************************************************************
1293REMARKS
1294Changes the range of coordinates returned by the mouse functions to the
1295specified range of values. This is used when changing between graphics
1296modes set the range of mouse coordinates for the new display mode.
1297****************************************************************************/
1298void EVTAPI EVT_setMouseRange(
1299 int xRes,
1300 int yRes)
1301{
1302 range_x = xRes;
1303 range_y = yRes;
1304}
1305
1306/****************************************************************************
1307REMARKS
1308Modifes the mouse coordinates as necessary if scaling to OS coordinates,
1309and sets the OS mouse cursor position.
1310****************************************************************************/
1311#define _EVT_setMousePos(x,y)
1312
1313/****************************************************************************
1314REMARKS:
1315Initiailises the internal event handling modules. The EVT_suspend function
1316can be called to suspend event handling (such as when shelling out to DOS),
1317and this function can be used to resume it again later.
1318****************************************************************************/
1319void EVT_resume(void)
1320{
8bde7f77 1321 /* Do nothing for Linux */
c7de829c
WD
1322}
1323
1324/****************************************************************************
1325REMARKS
1326Suspends all of our event handling operations. This is also used to
1327de-install the event handling code.
1328****************************************************************************/
1329void EVT_suspend(void)
1330{
8bde7f77 1331 /* Do nothing for Linux */
c7de829c
WD
1332}
1333
1334/****************************************************************************
1335REMARKS
1336Exits the event module for program terminatation.
1337****************************************************************************/
1338void EVT_exit(void)
1339{
1340 /* Restore signal handlers */
1341 _PM_restore_kb_mode();
1342 if (_EVT_mouse_fd) {
8bde7f77
WD
1343 close(_EVT_mouse_fd);
1344 _EVT_mouse_fd = 0;
1345 }
c7de829c
WD
1346#ifdef USE_OS_JOYSTICK
1347 if (joystick0_fd) {
8bde7f77
WD
1348 close(joystick0_fd);
1349 free(axis0);
1350 free(buts0);
1351 joystick0_fd = 0;
1352 }
c7de829c 1353 if (joystick1_fd) {
8bde7f77
WD
1354 close(joystick1_fd);
1355 free(axis1);
1356 free(buts1);
1357 joystick1_fd = 0;
1358 }
c7de829c
WD
1359#endif
1360}