/**************************************************************************** PARAMETERS: what - Event code message - Event message x,y - Mouse position at time of event but_stat - Mouse button status at time of event REMARKS: Adds a new mouse event to the event queue. This routine is called from within the mouse interrupt subroutine, so it must be efficient. NOTE: Interrupts MUST be OFF while this routine is called to ensure we have mutually exclusive access to our internal data structures for interrupt driven systems (like under DOS). ****************************************************************************/ static void addMouseEvent( uint what, uint message, int x, int y, int mickeyX, int mickeyY, uint but_stat) { event_t evt; if (count < EVENTQSIZE) { /* Save information in event record. */ evt.when = _EVT_getTicks(); evt.what = what; evt.message = message; evt.modifiers = but_stat; evt.where_x = x; /* Save mouse event position */ evt.where_y = y; evt.relative_x = mickeyX; evt.relative_y = mickeyY; evt.modifiers |= keyModifiers; addEvent(&evt); /* Add to tail of event queue */ } }
/**************************************************************************** REMARKS: Obtains and pumps mouse and joystick messages into our event queue. ****************************************************************************/ static void _EVT_pumpMessages(void) { uchar buttons; uchar oldButtons; int dx, dy, dz; event_t evt; /* Poll mouse events */ while (GetMouseUpdate (&buttons, &oldButtons, &dx, &dy, &dz)) { 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.when = _EVT_getTicks(); evt.where_x = EVT.mx; evt.where_y = EVT.my; evt.relative_x = dx; evt.relative_y = dy; evt.modifiers = _PM_modifiers; if (buttons & MOUSE_RBUTTON) evt.modifiers |= EVT_RIGHTBUT; if (buttons & MOUSE_MBUTTON) evt.modifiers |= EVT_MIDDLEBUT; if (buttons & MOUSE_LBUTTON) evt.modifiers |= EVT_LEFTBUT; /* Left click events */ if ((buttons & MOUSE_LBUTTON) != (oldButtons & MOUSE_LBUTTON)) { evt.what = buttons & MOUSE_LBUTTON ? EVT_MOUSEDOWN : EVT_MOUSEUP ; evt.message = EVT_LEFTBMASK; EVT.oldMove = -1; if (EVT.count < EVENTQSIZE) addEvent(&evt); } /* Right click events */ if ((buttons & MOUSE_RBUTTON) != (oldButtons & MOUSE_RBUTTON)) { evt.what = buttons & MOUSE_RBUTTON ? EVT_MOUSEDOWN : EVT_MOUSEUP ; evt.message = EVT_RIGHTBMASK; EVT.oldMove = -1; if (EVT.count < EVENTQSIZE) addEvent(&evt); } /* Middle click events */ if ((buttons & MOUSE_MBUTTON) != (oldButtons & MOUSE_MBUTTON)) { evt.what = buttons & MOUSE_MBUTTON ? EVT_MOUSEDOWN : 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); } } /* Mouse wheel event */ if (dz) { evt.what = EVT_MOUSEWHEEL; evt.message = MW_HORZWHEEL ; if (dz > 0) evt.message |= EVT_WHEELDIRMASK ; else dz = -dz ; evt.message |= dz & 0x0f ; if (EVT.count < EVENTQSIZE) addEvent(&evt); } } /* 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); } } } } }
static int _EVT_eventThread( #endif void *arg) { event_t evt; int c; char ch; static struct kbentry ke; static ushort repeatKey[128] = {0}; fd_set s; struct timeval *ptv = NULL; for (;;) { FD_ZERO(&s); FD_SET(_PM_console_fd, &s); while (select(_PM_console_fd+1, &s, NULL, NULL, ptv) > 0) { if (read(_PM_console_fd, &ch, 1) > 0) { evt.when = _EVT_getTicks(); ENTER_CRITICAL_SECTION(); if (_PM_haveConsole) { /* Handle keyboard for real consoles */ c = ch & 0x7F; if (ch & 0x80) { /* 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; } 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; } 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; if ((_PM_leds & LED_NUM) && (getKeyMapping(keypad, NB_KEYPAD, c) != c)) asc = getKeyMapping(keypad, NB_KEYPAD, c); else { 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)"); 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); } } else { /* Handle serial/SSH console support with the keyboard */ // TODO: Add some basic translation for arrow keys etc! evt.what = EVT_KEYDOWN; evt.modifiers = 0; evt.message = ch; if (EVT.count < EVENTQSIZE) addEvent(&evt); evt.what = EVT_KEYUP; if (EVT.count < EVENTQSIZE) addEvent(&evt); } LEAVE_CRITICAL_SECTION(); } FD_ZERO(&s); FD_SET(_PM_console_fd, &s); } } return 0; }