| /**************************************************************************** |
| * |
| * SciTech Multi-platform Graphics Library |
| * |
| * ======================================================================== |
| * |
| * The contents of this file are subject to the SciTech MGL Public |
| * License Version 1.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at http://www.scitechsoft.com/mgl-license.txt |
| * |
| * Software distributed under the License is distributed on an |
| * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| * implied. See the License for the specific language governing |
| * rights and limitations under the License. |
| * |
| * The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc. |
| * |
| * The Initial Developer of the Original Code is SciTech Software, Inc. |
| * All Rights Reserved. |
| * |
| * ======================================================================== |
| * |
| * Language: ANSI C |
| * Environment: Linux |
| * |
| * Description: Linux fullscreen console implementation for the SciTech |
| * cross platform event library. |
| * Portions ripped straigth from the gpm source code for mouse |
| * handling. |
| * |
| ****************************************************************************/ |
| |
| /*---------------------------- Global Variables ---------------------------*/ |
| |
| extern int _PM_console_fd; |
| static ushort keyUpMsg[256] = {0}; |
| static int _EVT_mouse_fd = 0; |
| static int range_x, range_y; |
| static int opt_baud = 1200, opt_sample = 100; |
| #ifdef USE_OS_JOYSTICK |
| static short *axis0 = NULL, *axis1 = NULL; |
| static uchar *buts0 = NULL, *buts1 = NULL; |
| static int joystick0_fd = 0, joystick1_fd = 0; |
| static int js_version = 0; |
| #endif |
| |
| /* This defines the supported mouse drivers */ |
| |
| typedef enum { |
| EVT_noMouse = -1, |
| EVT_microsoft = 0, |
| EVT_ps2, |
| EVT_mousesystems, |
| EVT_gpm, |
| EVT_MMseries, |
| EVT_logitech, |
| EVT_busmouse, |
| EVT_mouseman, |
| EVT_intellimouse, |
| EVT_intellimouse_ps2, |
| } mouse_drivers_t; |
| |
| static mouse_drivers_t mouse_driver = EVT_noMouse; |
| static char mouse_dev[20] = "/dev/mouse"; |
| |
| typedef struct { |
| char *name; |
| int flags; |
| void (*init)(void); |
| uchar proto[4]; |
| int packet_len; |
| int read; |
| } mouse_info; |
| |
| #define STD_FLG (CREAD | CLOCAL | HUPCL) |
| |
| static void _EVT_mouse_init(void); |
| static void _EVT_logitech_init(void); |
| static void _EVT_pnpmouse_init(void); |
| |
| mouse_info mouse_infos[] = { |
| {"Microsoft", CS7 | B1200 | STD_FLG, _EVT_mouse_init, {0x40, 0x40, 0x40, 0x00}, 3, 1}, |
| {"PS2", STD_FLG, NULL, {0xc0, 0x00, 0x00, 0x00}, 3, 1}, |
| {"MouseSystems", CS8 | CSTOPB | STD_FLG, _EVT_mouse_init, {0xf8, 0x80, 0x00, 0x00}, 5, 5}, |
| {"GPM", CS8 | CSTOPB | STD_FLG, NULL, {0xf8, 0x80, 0x00, 0x00}, 5, 5}, |
| {"MMSeries", CS8 | PARENB | PARODD | STD_FLG, _EVT_mouse_init, {0xe0, 0x80, 0x80, 0x00}, 3, 1}, |
| {"Logitech", CS8 | CSTOPB | STD_FLG, _EVT_logitech_init, {0xe0, 0x80, 0x80, 0x00}, 3, 3}, |
| {"BusMouse", STD_FLG, NULL, {0xf8, 0x80, 0x00, 0x00}, 3, 3}, |
| {"MouseMan", CS7 | STD_FLG, _EVT_mouse_init, {0x40, 0x40, 0x40, 0x00}, 3, 1}, |
| {"IntelliMouse", CS7 | STD_FLG, _EVT_pnpmouse_init, {0xc0, 0x40, 0xc0, 0x00}, 4, 1}, |
| {"IMPS2", CS7 | STD_FLG, NULL, {0xc0, 0x40, 0xc0, 0x00}, 4, 1}, /* ? */ |
| }; |
| |
| #define NB_MICE (sizeof(mouse_infos)/sizeof(mouse_info)) |
| |
| /* The name of the environment variables that are used to change the defaults above */ |
| |
| #define ENV_MOUSEDRV "MGL_MOUSEDRV" |
| #define ENV_MOUSEDEV "MGL_MOUSEDEV" |
| #define ENV_MOUSESPD "MGL_MOUSESPD" |
| #define ENV_JOYDEV0 "MGL_JOYDEV1" |
| #define ENV_JOYDEV1 "MGL_JOYDEV2" |
| |
| /* Scancode mappings on Linux for special keys */ |
| |
| typedef struct { |
| int scan; |
| int map; |
| } keymap; |
| |
| /* TODO: Fix this and set it up so we can do a binary search! */ |
| |
| keymap keymaps[] = { |
| {96, KB_padEnter}, |
| {74, KB_padMinus}, |
| {78, KB_padPlus}, |
| {55, KB_padTimes}, |
| {98, KB_padDivide}, |
| {71, KB_padHome}, |
| {72, KB_padUp}, |
| {73, KB_padPageUp}, |
| {75, KB_padLeft}, |
| {76, KB_padCenter}, |
| {77, KB_padRight}, |
| {79, KB_padEnd}, |
| {80, KB_padDown}, |
| {81, KB_padPageDown}, |
| {82, KB_padInsert}, |
| {83, KB_padDelete}, |
| {105,KB_left}, |
| {108,KB_down}, |
| {106,KB_right}, |
| {103,KB_up}, |
| {110,KB_insert}, |
| {102,KB_home}, |
| {104,KB_pageUp}, |
| {111,KB_delete}, |
| {107,KB_end}, |
| {109,KB_pageDown}, |
| {125,KB_leftWindows}, |
| {126,KB_rightWindows}, |
| {127,KB_menu}, |
| {100,KB_rightAlt}, |
| {97,KB_rightCtrl}, |
| }; |
| |
| /* And the keypad with num lock turned on (changes the ASCII code only) */ |
| |
| keymap keypad[] = { |
| {71, ASCII_7}, |
| {72, ASCII_8}, |
| {73, ASCII_9}, |
| {75, ASCII_4}, |
| {76, ASCII_5}, |
| {77, ASCII_6}, |
| {79, ASCII_1}, |
| {80, ASCII_2}, |
| {81, ASCII_3}, |
| {82, ASCII_0}, |
| {83, ASCII_period}, |
| }; |
| |
| #define NB_KEYMAPS (sizeof(keymaps)/sizeof(keymaps[0])) |
| #define NB_KEYPAD (sizeof(keypad)/sizeof(keypad[0])) |
| |
| typedef struct { |
| int sample; |
| char code[2]; |
| } sample_rate; |
| |
| sample_rate sampletab[]={ |
| { 0,"O"}, |
| { 15,"J"}, |
| { 27,"K"}, |
| { 42,"L"}, |
| { 60,"R"}, |
| { 85,"M"}, |
| {125,"Q"}, |
| {1E9,"N"}, |
| }; |
| |
| /* Number of keycodes to read at a time from the console */ |
| |
| #define KBDREADBUFFERSIZE 32 |
| |
| /*---------------------------- Implementation -----------------------------*/ |
| |
| /* These are not used under Linux */ |
| #define _EVT_disableInt() 1 |
| #define _EVT_restoreInt(flaps) |
| |
| /**************************************************************************** |
| PARAMETERS: |
| scanCode - Scan code to test |
| |
| REMARKS: |
| This macro determines if a specified key is currently down at the |
| time that the call is made. |
| ****************************************************************************/ |
| #define _EVT_isKeyDown(scanCode) (keyUpMsg[scanCode] != 0) |
| |
| /**************************************************************************** |
| REMARKS: |
| This function is used to return the number of ticks since system |
| startup in milliseconds. This should be the same value that is placed into |
| the time stamp fields of events, and is used to implement auto mouse down |
| events. |
| ****************************************************************************/ |
| ulong _EVT_getTicks(void) |
| { |
| static uint starttime = 0; |
| struct timeval t; |
| |
| gettimeofday(&t, NULL); |
| if (starttime == 0) |
| starttime = t.tv_sec * 1000 + (t.tv_usec/1000); |
| return ((t.tv_sec * 1000 + (t.tv_usec/1000)) - starttime); |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Small Unix function that checks for availability on a file using select() |
| ****************************************************************************/ |
| static ibool dataReady( |
| int fd) |
| { |
| static struct timeval t = { 0L, 0L }; |
| fd_set fds; |
| |
| FD_ZERO(&fds); |
| FD_SET(fd, &fds); |
| return select(fd+1, &fds, NULL, NULL, &t) > 0; |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Reads mouse data according to the selected mouse driver. |
| ****************************************************************************/ |
| static ibool readMouseData( |
| int *buttons, |
| int *dx, |
| int *dy) |
| { |
| static uchar data[32],prev = 0; |
| int cnt = 0,ret; |
| mouse_info *drv; |
| |
| /* Read the first byte to check for the protocol */ |
| drv = &mouse_infos[mouse_driver]; |
| if (read(_EVT_mouse_fd, data, drv->read) != drv->read) { |
| perror("read"); |
| return false; |
| } |
| if ((data[0] & drv->proto[0]) != drv->proto[1]) |
| return false; |
| |
| /* Load a whole protocol packet */ |
| cnt += drv->read; |
| while (cnt < drv->packet_len) { |
| ret = read(_EVT_mouse_fd, data+cnt, drv->read); |
| if (ret == drv->read) |
| cnt += ret; |
| else { |
| perror("read"); |
| return false; |
| } |
| } |
| if ((data[1] & drv->proto[2]) != drv->proto[3]) |
| return false; |
| |
| /* Now decode the protocol packet */ |
| switch (mouse_driver) { |
| case EVT_microsoft: |
| if (data[0] == 0x40 && !(prev|data[1]|data[2])) |
| *buttons = 2; /* Third button on MS compatible mouse */ |
| else |
| *buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4); |
| prev = *buttons; |
| *dx = (char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F)); |
| *dy = (char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F)); |
| break; |
| case EVT_ps2: |
| *buttons = !!(data[0]&1) * 4 + !!(data[0]&2) * 1 + !!(data[0]&4) * 2; |
| if (data[1] != 0) |
| *dx = (data[0] & 0x10) ? data[1]-256 : data[1]; |
| else |
| *dx = 0; |
| if (data[2] != 0) |
| *dy = -((data[0] & 0x20) ? data[2]-256 : data[2]); |
| else |
| *dy = 0; |
| break; |
| case EVT_mousesystems: case EVT_gpm: |
| *buttons = (~data[0]) & 0x07; |
| *dx = (char)(data[1]) + (char)(data[3]); |
| *dy = -((char)(data[2]) + (char)(data[4])); |
| break; |
| case EVT_logitech: |
| *buttons= data[0] & 0x07; |
| *dx = (data[0] & 0x10) ? data[1] : - data[1]; |
| *dy = (data[0] & 0x08) ? - data[2] : data[2]; |
| break; |
| case EVT_busmouse: |
| *buttons= (~data[0]) & 0x07; |
| *dx = (char)data[1]; |
| *dy = -(char)data[2]; |
| break; |
| case EVT_MMseries: |
| *buttons = data[0] & 0x07; |
| *dx = (data[0] & 0x10) ? data[1] : - data[1]; |
| *dy = (data[0] & 0x08) ? - data[2] : data[2]; |
| break; |
| case EVT_intellimouse: |
| *buttons = ((data[0] & 0x20) >> 3) /* left */ |
| | ((data[3] & 0x10) >> 3) /* middle */ |
| | ((data[0] & 0x10) >> 4); /* right */ |
| *dx = (char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F)); |
| *dy = (char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F)); |
| break; |
| case EVT_intellimouse_ps2: |
| *buttons = (data[0] & 0x04) >> 1 /* Middle */ |
| | (data[0] & 0x02) >> 1 /* Right */ |
| | (data[0] & 0x01) << 2; /* Left */ |
| *dx = (data[0] & 0x10) ? data[1]-256 : data[1]; |
| *dy = (data[0] & 0x20) ? -(data[2]-256) : -data[2]; |
| break; |
| case EVT_mouseman: { |
| static int getextra; |
| static uchar prev=0; |
| uchar b; |
| |
| /* The damned MouseMan has 3/4 bytes packets. The extra byte |
| * is only there if the middle button is active. |
| * I get the extra byte as a packet with magic numbers in it. |
| * and then switch to 4-byte mode. |
| */ |
| if (data[1] == 0xAA && data[2] == 0x55) { |
| /* Got unexpected fourth byte */ |
| if ((b = (*data>>4)) > 0x3) |
| return false; /* just a sanity check */ |
| *dx = *dy = 0; |
| drv->packet_len=4; |
| getextra=0; |
| } |
| else { |
| /* Got 3/4, as expected */ |
| /* Motion is independent of packetlen... */ |
| *dx = (char)(((data[0] & 0x03) << 6) | (data[1] & 0x3F)); |
| *dy = (char)(((data[0] & 0x0C) << 4) | (data[2] & 0x3F)); |
| prev = ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4); |
| if (drv->packet_len==4) |
| b = data[3]>>4; |
| } |
| if (drv->packet_len == 4) { |
| if (b == 0) { |
| drv->packet_len = 3; |
| getextra = 1; |
| } |
| else { |
| if (b & 0x2) |
| prev |= 2; |
| } |
| } |
| *buttons = prev; |
| |
| /* This "chord-middle" behaviour was reported by David A. van Leeuwen */ |
| if (((prev ^ *buttons) & 5) == 5) |
| *buttons = *buttons ? 2 : 0; |
| prev = *buttons; |
| break; |
| } |
| case EVT_noMouse: |
| return false; |
| break; |
| } |
| return true; |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Map a keypress via the key mapping table |
| ****************************************************************************/ |
| static int getKeyMapping( |
| keymap *tab, |
| int nb, |
| int key) |
| { |
| int i; |
| |
| for(i = 0; i < nb; i++) { |
| if (tab[i].scan == key) |
| return tab[i].map; |
| } |
| return key; |
| } |
| |
| #ifdef USE_OS_JOYSTICK |
| |
| static char js0_axes = 0, js0_buttons = 0; |
| static char js1_axes = 0, js1_buttons = 0; |
| static char joystick0_dev[20] = "/dev/js0"; |
| static char joystick1_dev[20] = "/dev/js1"; |
| |
| /**************************************************************************** |
| REMARKS: |
| Create a joystick event from the joystick data |
| ****************************************************************************/ |
| static void makeJoyEvent( |
| event_t *evt) |
| { |
| evt->message = 0; |
| if (buts0 && axis0) { |
| if (buts0[0]) evt->message |= EVT_JOY1_BUTTONA; |
| if (buts0[1]) evt->message |= EVT_JOY1_BUTTONB; |
| evt->where_x = axis0[0]; |
| evt->where_y = axis0[1]; |
| } |
| else |
| evt->where_x = evt->where_y = 0; |
| if (buts1 && axis1) { |
| if (buts1[0]) evt->message |= EVT_JOY2_BUTTONA; |
| if (buts1[1]) evt->message |= EVT_JOY2_BUTTONB; |
| evt->where_x = axis1[0]; |
| evt->where_y = axis1[1]; |
| } |
| else |
| evt->where_x = evt->where_y = 0; |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Read the joystick axis data |
| ****************************************************************************/ |
| int EVTAPI _EVT_readJoyAxis( |
| int jmask, |
| int *axis) |
| { |
| int mask = 0; |
| |
| if ((js_version & ~0xffff) == 0) { |
| /* Old 0.x driver */ |
| struct JS_DATA_TYPE js; |
| if (joystick0_fd && read(joystick0_fd, &js, JS_RETURN) == JS_RETURN) { |
| if (jmask & EVT_JOY_AXIS_X1) |
| axis[0] = js.x; |
| if (jmask & EVT_JOY_AXIS_Y1) |
| axis[1] = js.y; |
| mask |= EVT_JOY_AXIS_X1|EVT_JOY_AXIS_Y1; |
| } |
| if (joystick1_fd && read(joystick1_fd, &js, JS_RETURN) == JS_RETURN) { |
| if (jmask & EVT_JOY_AXIS_X2) |
| axis[2] = js.x; |
| if (jmask & EVT_JOY_AXIS_Y2) |
| axis[3] = js.y; |
| mask |= EVT_JOY_AXIS_X2|EVT_JOY_AXIS_Y2; |
| } |
| } |
| else { |
| if (axis0) { |
| if (jmask & EVT_JOY_AXIS_X1) |
| axis[0] = axis0[0]; |
| if (jmask & EVT_JOY_AXIS_Y1) |
| axis[1] = axis0[1]; |
| mask |= EVT_JOY_AXIS_X1 | EVT_JOY_AXIS_Y1; |
| } |
| if (axis1) { |
| if (jmask & EVT_JOY_AXIS_X2) |
| axis[2] = axis1[0]; |
| if (jmask & EVT_JOY_AXIS_Y2) |
| axis[3] = axis1[1]; |
| mask |= EVT_JOY_AXIS_X2 | EVT_JOY_AXIS_Y2; |
| } |
| } |
| return mask; |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Read the joystick button data |
| ****************************************************************************/ |
| int EVTAPI _EVT_readJoyButtons(void) |
| { |
| int buts = 0; |
| |
| if ((js_version & ~0xffff) == 0) { |
| /* Old 0.x driver */ |
| struct JS_DATA_TYPE js; |
| if (joystick0_fd && read(joystick0_fd, &js, JS_RETURN) == JS_RETURN) |
| buts = js.buttons; |
| if (joystick1_fd && read(joystick1_fd, &js, JS_RETURN) == JS_RETURN) |
| buts |= js.buttons << 2; |
| } |
| else { |
| if (buts0) |
| buts |= EVT_JOY1_BUTTONA*buts0[0] + EVT_JOY1_BUTTONB*buts0[1]; |
| if (buts1) |
| buts |= EVT_JOY2_BUTTONA*buts1[0] + EVT_JOY2_BUTTONB*buts1[1]; |
| } |
| return buts; |
| } |
| |
| /**************************************************************************** |
| DESCRIPTION: |
| Returns the mask indicating what joystick axes are attached. |
| |
| HEADER: |
| event.h |
| |
| REMARKS: |
| This function is used to detect the attached joysticks, and determine |
| what axes are present and functioning. This function will re-detect any |
| attached joysticks when it is called, so if the user forgot to attach |
| the joystick when the application started, you can call this function to |
| re-detect any newly attached joysticks. |
| |
| SEE ALSO: |
| EVT_joySetLowerRight, EVT_joySetCenter, EVT_joyIsPresent |
| ****************************************************************************/ |
| int EVTAPI EVT_joyIsPresent(void) |
| { |
| static int mask = 0; |
| int i; |
| char *tmp, name0[128], name1[128]; |
| static ibool inited = false; |
| |
| if (inited) |
| return mask; |
| memset(EVT.joyMin,0,sizeof(EVT.joyMin)); |
| memset(EVT.joyCenter,0,sizeof(EVT.joyCenter)); |
| memset(EVT.joyMax,0,sizeof(EVT.joyMax)); |
| memset(EVT.joyPrev,0,sizeof(EVT.joyPrev)); |
| EVT.joyButState = 0; |
| if ((tmp = getenv(ENV_JOYDEV0)) != NULL) |
| strcpy(joystick0_dev,tmp); |
| if ((tmp = getenv(ENV_JOYDEV1)) != NULL) |
| strcpy(joystick1_dev,tmp); |
| if ((joystick0_fd = open(joystick0_dev, O_RDONLY)) < 0) |
| joystick0_fd = 0; |
| if ((joystick1_fd = open(joystick1_dev, O_RDONLY)) < 0) |
| joystick1_fd = 0; |
| if (!joystick0_fd && !joystick1_fd) /* No joysticks detected */ |
| return 0; |
| inited = true; |
| if (ioctl(joystick0_fd ? joystick0_fd : joystick1_fd, JSIOCGVERSION, &js_version) < 0) |
| return 0; |
| |
| /* Initialise joystick 0 */ |
| if (joystick0_fd) { |
| ioctl(joystick0_fd, JSIOCGNAME(sizeof(name0)), name0); |
| if (js_version & ~0xffff) { |
| struct js_event js; |
| |
| ioctl(joystick0_fd, JSIOCGAXES, &js0_axes); |
| ioctl(joystick0_fd, JSIOCGBUTTONS, &js0_buttons); |
| axis0 = PM_calloc((int)js0_axes, sizeof(short)); |
| buts0 = PM_malloc((int)js0_buttons); |
| /* Read the initial events */ |
| while(dataReady(joystick0_fd) |
| && read(joystick0_fd, &js, sizeof(struct js_event)) == sizeof(struct js_event) |
| && (js.type & JS_EVENT_INIT) |
| ) { |
| if (js.type & JS_EVENT_BUTTON) |
| buts0[js.number] = js.value; |
| else if (js.type & JS_EVENT_AXIS) |
| axis0[js.number] = scaleJoyAxis(js.value,js.number); |
| } |
| } |
| else { |
| js0_axes = 2; |
| js0_buttons = 2; |
| axis0 = PM_calloc((int)js0_axes, sizeof(short)); |
| buts0 = PM_malloc((int)js0_buttons); |
| } |
| } |
| |
| /* Initialise joystick 1 */ |
| if (joystick1_fd) { |
| ioctl(joystick1_fd, JSIOCGNAME(sizeof(name1)), name1); |
| if (js_version & ~0xffff) { |
| struct js_event js; |
| |
| ioctl(joystick1_fd, JSIOCGAXES, &js1_axes); |
| ioctl(joystick1_fd, JSIOCGBUTTONS, &js1_buttons); |
| axis1 = PM_calloc((int)js1_axes, sizeof(short)); |
| buts1 = PM_malloc((int)js1_buttons); |
| /* Read the initial events */ |
| while(dataReady(joystick1_fd) |
| && read(joystick1_fd, &js, sizeof(struct js_event))==sizeof(struct js_event) |
| && (js.type & JS_EVENT_INIT) |
| ) { |
| if (js.type & JS_EVENT_BUTTON) |
| buts1[js.number] = js.value; |
| else if (js.type & JS_EVENT_AXIS) |
| axis1[js.number] = scaleJoyAxis(js.value,js.number<<2); |
| } |
| } |
| else { |
| js1_axes = 2; |
| js1_buttons = 2; |
| axis1 = PM_calloc((int)js1_axes, sizeof(short)); |
| buts1 = PM_malloc((int)js1_buttons); |
| } |
| } |
| |
| #ifdef CHECKED |
| fprintf(stderr,"Using joystick driver version %d.%d.%d\n", |
| js_version >> 16, (js_version >> 8) & 0xff, js_version & 0xff); |
| if (joystick0_fd) |
| fprintf(stderr,"Joystick 1 (%s): %s\n", joystick0_dev, name0); |
| if (joystick1_fd) |
| fprintf(stderr,"Joystick 2 (%s): %s\n", joystick1_dev, name1); |
| #endif |
| mask = _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter); |
| if (mask) { |
| for (i = 0; i < JOY_NUM_AXES; i++) |
| EVT.joyMax[i] = EVT.joyCenter[i]*2; |
| } |
| return mask; |
| } |
| |
| /**************************************************************************** |
| DESCRIPTION: |
| Polls the joystick for position and button information. |
| |
| HEADER: |
| event.h |
| |
| REMARKS: |
| This routine is used to poll analogue joysticks for button and position |
| information. It should be called once for each main loop of the user |
| application, just before processing all pending events via EVT_getNext. |
| All information polled from the joystick will be posted to the event |
| queue for later retrieval. |
| |
| Note: Most analogue joysticks will provide readings that change even |
| though the joystick has not moved. Hence if you call this routine |
| you will likely get an EVT_JOYMOVE event every time through your |
| event loop. |
| |
| SEE ALSO: |
| EVT_getNext, EVT_peekNext, EVT_joySetUpperLeft, EVT_joySetLowerRight, |
| EVT_joySetCenter, EVT_joyIsPresent |
| ****************************************************************************/ |
| void EVTAPI EVT_pollJoystick(void) |
| { |
| event_t evt; |
| int i,axis[JOY_NUM_AXES],newButState,mask,moved,ps; |
| |
| if ((js_version & ~0xFFFF) == 0 && EVT.joyMask) { |
| /* Read joystick axes and post movement events if they have |
| * changed since the last time we polled. Until the events are |
| * actually flushed, we keep modifying the same joystick movement |
| * event, so you won't get multiple movement event |
| */ |
| mask = _EVT_readJoyAxis(EVT.joyMask,axis); |
| newButState = _EVT_readJoyButtons(); |
| moved = false; |
| for (i = 0; i < JOY_NUM_AXES; i++) { |
| if (mask & (EVT_JOY_AXIS_X1 << i)) |
| axis[i] = scaleJoyAxis(axis[i],i); |
| else |
| axis[i] = EVT.joyPrev[i]; |
| if (axis[i] != EVT.joyPrev[i]) |
| moved = true; |
| } |
| if (moved) { |
| memcpy(EVT.joyPrev,axis,sizeof(EVT.joyPrev)); |
| ps = _EVT_disableInt(); |
| if (EVT.oldJoyMove != -1) { |
| /* Modify the existing joystick movement event */ |
| EVT.evtq[EVT.oldJoyMove].message = newButState; |
| EVT.evtq[EVT.oldJoyMove].where_x = EVT.joyPrev[0]; |
| EVT.evtq[EVT.oldJoyMove].where_y = EVT.joyPrev[1]; |
| EVT.evtq[EVT.oldJoyMove].relative_x = EVT.joyPrev[2]; |
| EVT.evtq[EVT.oldJoyMove].relative_y = EVT.joyPrev[3]; |
| } |
| else if (EVT.count < EVENTQSIZE) { |
| /* Add a new joystick movement event */ |
| EVT.oldJoyMove = EVT.freeHead; |
| memset(&evt,0,sizeof(evt)); |
| evt.what = EVT_JOYMOVE; |
| evt.message = EVT.joyButState; |
| evt.where_x = EVT.joyPrev[0]; |
| evt.where_y = EVT.joyPrev[1]; |
| evt.relative_x = EVT.joyPrev[2]; |
| evt.relative_y = EVT.joyPrev[3]; |
| addEvent(&evt); |
| } |
| _EVT_restoreInt(ps); |
| } |
| |
| /* Read the joystick buttons, and post events to reflect the change |
| * in state for the joystick buttons. |
| */ |
| if (newButState != EVT.joyButState) { |
| if (EVT.count < EVENTQSIZE) { |
| /* Add a new joystick movement event */ |
| ps = _EVT_disableInt(); |
| memset(&evt,0,sizeof(evt)); |
| evt.what = EVT_JOYCLICK; |
| evt.message = newButState; |
| EVT.evtq[EVT.oldJoyMove].where_x = EVT.joyPrev[0]; |
| EVT.evtq[EVT.oldJoyMove].where_y = EVT.joyPrev[1]; |
| EVT.evtq[EVT.oldJoyMove].relative_x = EVT.joyPrev[2]; |
| EVT.evtq[EVT.oldJoyMove].relative_y = EVT.joyPrev[3]; |
| addEvent(&evt); |
| _EVT_restoreInt(ps); |
| } |
| EVT.joyButState = newButState; |
| } |
| } |
| } |
| |
| /**************************************************************************** |
| DESCRIPTION: |
| Calibrates the joystick upper left position |
| |
| HEADER: |
| event.h |
| |
| REMARKS: |
| This function can be used to zero in on better joystick calibration factors, |
| which may work better than the default simplistic calibration (which assumes |
| the joystick is centered when the event library is initialised). |
| To use this function, ask the user to hold the stick in the upper left |
| position and then have them press a key or button. and then call this |
| function. This function will then read the joystick and update the |
| calibration factors. |
| |
| Usually, assuming that the stick was centered when the event library was |
| initialized, you really only need to call EVT_joySetLowerRight since the |
| upper left position is usually always 0,0 on most joysticks. However, the |
| safest procedure is to call all three calibration functions. |
| |
| SEE ALSO: |
| EVT_joySetUpperLeft, EVT_joySetLowerRight, EVT_joyIsPresent |
| ****************************************************************************/ |
| void EVTAPI EVT_joySetUpperLeft(void) |
| { |
| _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyMin); |
| } |
| |
| /**************************************************************************** |
| DESCRIPTION: |
| Calibrates the joystick lower right position |
| |
| HEADER: |
| event.h |
| |
| REMARKS: |
| This function can be used to zero in on better joystick calibration factors, |
| which may work better than the default simplistic calibration (which assumes |
| the joystick is centered when the event library is initialised). |
| To use this function, ask the user to hold the stick in the lower right |
| position and then have them press a key or button. and then call this |
| function. This function will then read the joystick and update the |
| calibration factors. |
| |
| Usually, assuming that the stick was centered when the event library was |
| initialized, you really only need to call EVT_joySetLowerRight since the |
| upper left position is usually always 0,0 on most joysticks. However, the |
| safest procedure is to call all three calibration functions. |
| |
| SEE ALSO: |
| EVT_joySetUpperLeft, EVT_joySetCenter, EVT_joyIsPresent |
| ****************************************************************************/ |
| void EVTAPI EVT_joySetLowerRight(void) |
| { |
| _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyMax); |
| } |
| |
| /**************************************************************************** |
| DESCRIPTION: |
| Calibrates the joystick center position |
| |
| HEADER: |
| event.h |
| |
| REMARKS: |
| This function can be used to zero in on better joystick calibration factors, |
| which may work better than the default simplistic calibration (which assumes |
| the joystick is centered when the event library is initialised). |
| To use this function, ask the user to hold the stick in the center |
| position and then have them press a key or button. and then call this |
| function. This function will then read the joystick and update the |
| calibration factors. |
| |
| Usually, assuming that the stick was centered when the event library was |
| initialized, you really only need to call EVT_joySetLowerRight since the |
| upper left position is usually always 0,0 on most joysticks. However, the |
| safest procedure is to call all three calibration functions. |
| |
| SEE ALSO: |
| EVT_joySetUpperLeft, EVT_joySetLowerRight, EVT_joySetCenter |
| ****************************************************************************/ |
| void EVTAPI EVT_joySetCenter(void) |
| { |
| _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter); |
| } |
| #endif |
| |
| /**************************************************************************** |
| REMARKS: |
| Pumps all messages in the message queue from Linux into our event queue. |
| ****************************************************************************/ |
| static void _EVT_pumpMessages(void) |
| { |
| event_t evt; |
| int i,numkeys, c; |
| ibool release; |
| static struct kbentry ke; |
| static char buf[KBDREADBUFFERSIZE]; |
| static ushort repeatKey[128] = {0}; |
| |
| /* Poll keyboard events */ |
| while (dataReady(_PM_console_fd) && (numkeys = read(_PM_console_fd, buf, KBDREADBUFFERSIZE)) > 0) { |
| for (i = 0; i < numkeys; i++) { |
| c = buf[i]; |
| release = c & 0x80; |
| c &= 0x7F; |
| |
| /* TODO: This is wrong! We need this to be the time stamp at */ |
| /* ** interrupt ** time!! One solution would be to */ |
| /* put the keyboard and mouse polling loops into */ |
| /* a separate thread that can block on I/O to the */ |
| /* necessay file descriptor. */ |
| evt.when = _EVT_getTicks(); |
| |
| if (release) { |
| /* Key released */ |
| evt.what = EVT_KEYUP; |
| switch (c) { |
| case KB_leftShift: |
| _PM_modifiers &= ~EVT_LEFTSHIFT; |
| break; |
| case KB_rightShift: |
| _PM_modifiers &= ~EVT_RIGHTSHIFT; |
| break; |
| case 29: |
| _PM_modifiers &= ~(EVT_LEFTCTRL|EVT_CTRLSTATE); |
| break; |
| case 97: /* Control */ |
| _PM_modifiers &= ~EVT_CTRLSTATE; |
| break; |
| case 56: |
| _PM_modifiers &= ~(EVT_LEFTALT|EVT_ALTSTATE); |
| break; |
| case 100: |
| _PM_modifiers &= ~EVT_ALTSTATE; |
| break; |
| default: |
| } |
| evt.modifiers = _PM_modifiers; |
| evt.message = keyUpMsg[c]; |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| keyUpMsg[c] = 0; |
| repeatKey[c] = 0; |
| } |
| else { |
| /* Key pressed */ |
| evt.what = EVT_KEYDOWN; |
| switch (c) { |
| case KB_leftShift: |
| _PM_modifiers |= EVT_LEFTSHIFT; |
| break; |
| case KB_rightShift: |
| _PM_modifiers |= EVT_RIGHTSHIFT; |
| break; |
| case 29: |
| _PM_modifiers |= EVT_LEFTCTRL|EVT_CTRLSTATE; |
| break; |
| case 97: /* Control */ |
| _PM_modifiers |= EVT_CTRLSTATE; |
| break; |
| case 56: |
| _PM_modifiers |= EVT_LEFTALT|EVT_ALTSTATE; |
| break; |
| case 100: |
| _PM_modifiers |= EVT_ALTSTATE; |
| break; |
| case KB_capsLock: /* Caps Lock */ |
| _PM_leds ^= LED_CAP; |
| ioctl(_PM_console_fd, KDSETLED, _PM_leds); |
| break; |
| case KB_numLock: /* Num Lock */ |
| _PM_leds ^= LED_NUM; |
| ioctl(_PM_console_fd, KDSETLED, _PM_leds); |
| break; |
| case KB_scrollLock: /* Scroll Lock */ |
| _PM_leds ^= LED_SCR; |
| ioctl(_PM_console_fd, KDSETLED, _PM_leds); |
| break; |
| default: |
| } |
| evt.modifiers = _PM_modifiers; |
| if (keyUpMsg[c]) { |
| evt.what = EVT_KEYREPEAT; |
| evt.message = keyUpMsg[c] | (repeatKey[c]++ << 16); |
| } |
| else { |
| int asc; |
| |
| evt.message = getKeyMapping(keymaps, NB_KEYMAPS, c) << 8; |
| ke.kb_index = c; |
| ke.kb_table = 0; |
| if ((_PM_modifiers & EVT_SHIFTKEY) || (_PM_leds & LED_CAP)) |
| ke.kb_table |= K_SHIFTTAB; |
| if (_PM_modifiers & (EVT_LEFTALT | EVT_ALTSTATE)) |
| ke.kb_table |= K_ALTTAB; |
| if (ioctl(_PM_console_fd, KDGKBENT, (unsigned long)&ke)<0) |
| perror("ioctl(KDGKBENT)"); |
| if ((_PM_leds & LED_NUM) && (getKeyMapping(keypad, NB_KEYPAD, c)!=c)) { |
| asc = getKeyMapping(keypad, NB_KEYPAD, c); |
| } |
| else { |
| switch (c) { |
| case 14: |
| asc = ASCII_backspace; |
| break; |
| case 15: |
| asc = ASCII_tab; |
| break; |
| case 28: |
| case 96: |
| asc = ASCII_enter; |
| break; |
| case 1: |
| asc = ASCII_esc; |
| default: |
| asc = ke.kb_value & 0xFF; |
| if (asc < 0x1B) |
| asc = 0; |
| break; |
| } |
| } |
| if ((_PM_modifiers & (EVT_CTRLSTATE|EVT_LEFTCTRL)) && isalpha(asc)) |
| evt.message |= toupper(asc) - 'A' + 1; |
| else |
| evt.message |= asc; |
| keyUpMsg[c] = evt.message; |
| repeatKey[c]++; |
| } |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| } |
| } |
| |
| /* Poll mouse events */ |
| if (_EVT_mouse_fd) { |
| int dx, dy, buts; |
| static int oldbuts; |
| |
| while (dataReady(_EVT_mouse_fd)) { |
| if (readMouseData(&buts, &dx, &dy)) { |
| EVT.mx += dx; |
| EVT.my += dy; |
| if (EVT.mx < 0) EVT.mx = 0; |
| if (EVT.my < 0) EVT.my = 0; |
| if (EVT.mx > range_x) EVT.mx = range_x; |
| if (EVT.my > range_y) EVT.my = range_y; |
| evt.where_x = EVT.mx; |
| evt.where_y = EVT.my; |
| evt.relative_x = dx; |
| evt.relative_y = dy; |
| |
| /* TODO: This is wrong! We need this to be the time stamp at */ |
| /* ** interrupt ** time!! One solution would be to */ |
| /* put the keyboard and mouse polling loops into */ |
| /* a separate thread that can block on I/O to the */ |
| /* necessay file descriptor. */ |
| evt.when = _EVT_getTicks(); |
| evt.modifiers = _PM_modifiers; |
| if (buts & 4) |
| evt.modifiers |= EVT_LEFTBUT; |
| if (buts & 1) |
| evt.modifiers |= EVT_RIGHTBUT; |
| if (buts & 2) |
| evt.modifiers |= EVT_MIDDLEBUT; |
| |
| /* Left click events */ |
| if ((buts&4) != (oldbuts&4)) { |
| if (buts&4) |
| evt.what = EVT_MOUSEDOWN; |
| else |
| evt.what = EVT_MOUSEUP; |
| evt.message = EVT_LEFTBMASK; |
| EVT.oldMove = -1; |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| |
| /* Right click events */ |
| if ((buts&1) != (oldbuts&1)) { |
| if (buts&1) |
| evt.what = EVT_MOUSEDOWN; |
| else |
| evt.what = EVT_MOUSEUP; |
| evt.message = EVT_RIGHTBMASK; |
| EVT.oldMove = -1; |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| |
| /* Middle click events */ |
| if ((buts&2) != (oldbuts&2)) { |
| if (buts&2) |
| evt.what = EVT_MOUSEDOWN; |
| else |
| evt.what = EVT_MOUSEUP; |
| evt.message = EVT_MIDDLEBMASK; |
| EVT.oldMove = -1; |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| |
| /* Mouse movement event */ |
| if (dx || dy) { |
| evt.what = EVT_MOUSEMOVE; |
| evt.message = 0; |
| if (EVT.oldMove != -1) { |
| /* Modify existing movement event */ |
| EVT.evtq[EVT.oldMove].where_x = evt.where_x; |
| EVT.evtq[EVT.oldMove].where_y = evt.where_y; |
| } |
| else { |
| /* Save id of this movement event */ |
| EVT.oldMove = EVT.freeHead; |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| } |
| oldbuts = buts; |
| } |
| } |
| } |
| |
| #ifdef USE_OS_JOYSTICK |
| /* Poll joystick events using the 1.x joystick driver API in the 2.2 kernels */ |
| if (js_version & ~0xffff) { |
| static struct js_event js; |
| |
| /* Read joystick axis 0 */ |
| evt.when = 0; |
| evt.modifiers = _PM_modifiers; |
| if (joystick0_fd && dataReady(joystick0_fd) && |
| read(joystick0_fd, &js, sizeof(js)) == sizeof(js)) { |
| if (js.type & JS_EVENT_BUTTON) { |
| if (js.number < 2) { /* Only 2 buttons for now :( */ |
| buts0[js.number] = js.value; |
| evt.what = EVT_JOYCLICK; |
| makeJoyEvent(&evt); |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| } |
| else if (js.type & JS_EVENT_AXIS) { |
| axis0[js.number] = scaleJoyAxis(js.value,js.number); |
| evt.what = EVT_JOYMOVE; |
| if (EVT.oldJoyMove != -1) { |
| makeJoyEvent(&EVT.evtq[EVT.oldJoyMove]); |
| } |
| else if (EVT.count < EVENTQSIZE) { |
| EVT.oldJoyMove = EVT.freeHead; |
| makeJoyEvent(&evt); |
| addEvent(&evt); |
| } |
| } |
| } |
| |
| /* Read joystick axis 1 */ |
| if (joystick1_fd && dataReady(joystick1_fd) && |
| read(joystick1_fd, &js, sizeof(js))==sizeof(js)) { |
| if (js.type & JS_EVENT_BUTTON) { |
| if (js.number < 2) { /* Only 2 buttons for now :( */ |
| buts1[js.number] = js.value; |
| evt.what = EVT_JOYCLICK; |
| makeJoyEvent(&evt); |
| if (EVT.count < EVENTQSIZE) |
| addEvent(&evt); |
| } |
| } |
| else if (js.type & JS_EVENT_AXIS) { |
| axis1[js.number] = scaleJoyAxis(js.value,js.number<<2); |
| evt.what = EVT_JOYMOVE; |
| if (EVT.oldJoyMove != -1) { |
| makeJoyEvent(&EVT.evtq[EVT.oldJoyMove]); |
| } |
| else if (EVT.count < EVENTQSIZE) { |
| EVT.oldJoyMove = EVT.freeHead; |
| makeJoyEvent(&evt); |
| addEvent(&evt); |
| } |
| } |
| } |
| } |
| #endif |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| This macro/function is used to converts the scan codes reported by the |
| keyboard to our event libraries normalised format. We only have one scan |
| code for the 'A' key, and use shift _PM_modifiers to determine if it is a |
| Ctrl-F1, Alt-F1 etc. The raw scan codes from the keyboard work this way, |
| but the OS gives us 'cooked' scan codes, we have to translate them back |
| to the raw format. |
| ****************************************************************************/ |
| #define _EVT_maskKeyCode(evt) |
| |
| /**************************************************************************** |
| REMARKS: |
| Set the speed of the serial port |
| ****************************************************************************/ |
| static int setspeed( |
| int fd, |
| int old, |
| int new, |
| unsigned short flags) |
| { |
| struct termios tty; |
| char *c; |
| |
| tcgetattr(fd, &tty); |
| tty.c_iflag = IGNBRK | IGNPAR; |
| tty.c_oflag = 0; |
| tty.c_lflag = 0; |
| tty.c_line = 0; |
| tty.c_cc[VTIME] = 0; |
| tty.c_cc[VMIN] = 1; |
| switch (old) { |
| case 9600: tty.c_cflag = flags | B9600; break; |
| case 4800: tty.c_cflag = flags | B4800; break; |
| case 2400: tty.c_cflag = flags | B2400; break; |
| case 1200: |
| default: tty.c_cflag = flags | B1200; break; |
| } |
| tcsetattr(fd, TCSAFLUSH, &tty); |
| switch (new) { |
| case 9600: c = "*q"; tty.c_cflag = flags | B9600; break; |
| case 4800: c = "*p"; tty.c_cflag = flags | B4800; break; |
| case 2400: c = "*o"; tty.c_cflag = flags | B2400; break; |
| case 1200: |
| default: c = "*n"; tty.c_cflag = flags | B1200; break; |
| } |
| write(fd, c, 2); |
| usleep(100000); |
| tcsetattr(fd, TCSAFLUSH, &tty); |
| return 0; |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Generic mouse driver init code |
| ****************************************************************************/ |
| static void _EVT_mouse_init(void) |
| { |
| int i; |
| |
| /* Change from any available speed to the chosen one */ |
| for (i = 9600; i >= 1200; i /= 2) |
| setspeed(_EVT_mouse_fd, i, opt_baud, mouse_infos[mouse_driver].flags); |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Logitech mouse driver init code |
| ****************************************************************************/ |
| static void _EVT_logitech_init(void) |
| { |
| int i; |
| struct stat buf; |
| int busmouse; |
| |
| /* is this a serial- or a bus- mouse? */ |
| if (fstat(_EVT_mouse_fd,&buf) == -1) |
| perror("fstat"); |
| i = MAJOR(buf.st_rdev); |
| if (stat("/dev/ttyS0",&buf) == -1) |
| perror("stat"); |
| busmouse=(i != MAJOR(buf.st_rdev)); |
| |
| /* Fix the howmany field, so that serial mice have 1, while busmice have 3 */ |
| mouse_infos[mouse_driver].read = busmouse ? 3 : 1; |
| |
| /* Change from any available speed to the chosen one */ |
| for (i = 9600; i >= 1200; i /= 2) |
| setspeed(_EVT_mouse_fd, i, opt_baud, mouse_infos[mouse_driver].flags); |
| |
| /* This stuff is peculiar of logitech mice, also for the serial ones */ |
| write(_EVT_mouse_fd, "S", 1); |
| setspeed(_EVT_mouse_fd, opt_baud, opt_baud,CS8 |PARENB |PARODD |CREAD |CLOCAL |HUPCL); |
| |
| /* Configure the sample rate */ |
| for (i = 0; opt_sample <= sampletab[i].sample; i++) |
| ; |
| write(_EVT_mouse_fd,sampletab[i].code,1); |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Microsoft Intellimouse init code |
| ****************************************************************************/ |
| static void _EVT_pnpmouse_init(void) |
| { |
| struct termios tty; |
| |
| tcgetattr(_EVT_mouse_fd, &tty); |
| tty.c_iflag = IGNBRK | IGNPAR; |
| tty.c_oflag = 0; |
| tty.c_lflag = 0; |
| tty.c_line = 0; |
| tty.c_cc[VTIME] = 0; |
| tty.c_cc[VMIN] = 1; |
| tty.c_cflag = mouse_infos[mouse_driver].flags | B1200; |
| tcsetattr(_EVT_mouse_fd, TCSAFLUSH, &tty); /* set parameters */ |
| } |
| |
| /**************************************************************************** |
| PARAMETERS: |
| mouseMove - Callback function to call wheneve the mouse needs to be moved |
| |
| REMARKS: |
| Initiliase the event handling module. Here we install our mouse handling ISR |
| to be called whenever any button's are pressed or released. We also build |
| the free list of events in the event queue. |
| |
| We use handler number 2 of the mouse libraries interrupt handlers for our |
| event handling routines. |
| ****************************************************************************/ |
| void EVTAPI EVT_init( |
| _EVT_mouseMoveHandler mouseMove) |
| { |
| int i; |
| char *tmp; |
| |
| /* Initialise the event queue */ |
| EVT.mouseMove = mouseMove; |
| initEventQueue(); |
| for (i = 0; i < 256; i++) |
| keyUpMsg[i] = 0; |
| |
| /* Keyboard initialization */ |
| if (_PM_console_fd == -1) |
| PM_fatalError("You must first call PM_openConsole to use the EVT functions!"); |
| _PM_keyboard_rawmode(); |
| fcntl(_PM_console_fd,F_SETFL,fcntl(_PM_console_fd,F_GETFL) | O_NONBLOCK); |
| |
| /* Mouse initialization */ |
| if ((tmp = getenv(ENV_MOUSEDRV)) != NULL) { |
| for (i = 0; i < NB_MICE; i++) { |
| if (!strcasecmp(tmp, mouse_infos[i].name)) { |
| mouse_driver = i; |
| break; |
| } |
| } |
| if (i == NB_MICE) { |
| fprintf(stderr,"Unknown mouse driver: %s\n", tmp); |
| mouse_driver = EVT_noMouse; |
| _EVT_mouse_fd = 0; |
| } |
| } |
| if (mouse_driver != EVT_noMouse) { |
| if (mouse_driver == EVT_gpm) |
| strcpy(mouse_dev,"/dev/gpmdata"); |
| if ((tmp = getenv(ENV_MOUSEDEV)) != NULL) |
| strcpy(mouse_dev,tmp); |
| #ifdef CHECKED |
| fprintf(stderr,"Using the %s MGL mouse driver on %s.\n", mouse_infos[mouse_driver].name, mouse_dev); |
| #endif |
| if ((_EVT_mouse_fd = open(mouse_dev, O_RDWR)) < 0) { |
| perror("open"); |
| fprintf(stderr, "Unable to open mouse device %s, dropping mouse support.\n", mouse_dev); |
| sleep(1); |
| mouse_driver = EVT_noMouse; |
| _EVT_mouse_fd = 0; |
| } |
| else { |
| char c; |
| |
| /* Init and flush the mouse pending input queue */ |
| if (mouse_infos[mouse_driver].init) |
| mouse_infos[mouse_driver].init(); |
| while(dataReady(_EVT_mouse_fd) && read(_EVT_mouse_fd, &c, 1) == 1) |
| ; |
| } |
| } |
| } |
| |
| /**************************************************************************** |
| REMARKS |
| Changes the range of coordinates returned by the mouse functions to the |
| specified range of values. This is used when changing between graphics |
| modes set the range of mouse coordinates for the new display mode. |
| ****************************************************************************/ |
| void EVTAPI EVT_setMouseRange( |
| int xRes, |
| int yRes) |
| { |
| range_x = xRes; |
| range_y = yRes; |
| } |
| |
| /**************************************************************************** |
| REMARKS |
| Modifes the mouse coordinates as necessary if scaling to OS coordinates, |
| and sets the OS mouse cursor position. |
| ****************************************************************************/ |
| #define _EVT_setMousePos(x,y) |
| |
| /**************************************************************************** |
| REMARKS: |
| Initiailises the internal event handling modules. The EVT_suspend function |
| can be called to suspend event handling (such as when shelling out to DOS), |
| and this function can be used to resume it again later. |
| ****************************************************************************/ |
| void EVT_resume(void) |
| { |
| /* Do nothing for Linux */ |
| } |
| |
| /**************************************************************************** |
| REMARKS |
| Suspends all of our event handling operations. This is also used to |
| de-install the event handling code. |
| ****************************************************************************/ |
| void EVT_suspend(void) |
| { |
| /* Do nothing for Linux */ |
| } |
| |
| /**************************************************************************** |
| REMARKS |
| Exits the event module for program terminatation. |
| ****************************************************************************/ |
| void EVT_exit(void) |
| { |
| /* Restore signal handlers */ |
| _PM_restore_kb_mode(); |
| if (_EVT_mouse_fd) { |
| close(_EVT_mouse_fd); |
| _EVT_mouse_fd = 0; |
| } |
| #ifdef USE_OS_JOYSTICK |
| if (joystick0_fd) { |
| close(joystick0_fd); |
| free(axis0); |
| free(buts0); |
| joystick0_fd = 0; |
| } |
| if (joystick1_fd) { |
| close(joystick1_fd); |
| free(axis1); |
| free(buts1); |
| joystick1_fd = 0; |
| } |
| #endif |
| } |