static void EvdevPtrMotion(KdPointerInfo * pi, struct input_event *ev) { Kevdev *ke = pi->driverPrivate; int i; int flags = KD_MOUSE_DELTA | pi->buttonState; for (i = 0; i <= ke->max_rel; i++) if (ke->rel[i]) { int a; for (a = 0; a <= ke->max_rel; a++) { if (ISBITSET(ke->relbits, a)) { if (a == 0) KdEnqueuePointerEvent(pi, flags, ke->rel[a], 0, 0); else if (a == 1) KdEnqueuePointerEvent(pi, flags, 0, ke->rel[a], 0); } ke->rel[a] = 0; } break; } for (i = 0; i < ke->max_abs; i++) if (ke->abs[i] != ke->prevabs[i]) { int a; ErrorF("abs"); for (a = 0; a <= ke->max_abs; a++) { if (ISBITSET(ke->absbits, a)) ErrorF(" %d=%d", a, ke->abs[a]); ke->prevabs[a] = ke->abs[a]; } ErrorF("\n"); break; } if (ev->code == REL_WHEEL) { for (i = 0; i < abs(ev->value); i++) { if (ev->value > 0) flags |= KD_BUTTON_4; else flags |= KD_BUTTON_5; KdEnqueuePointerEvent(pi, flags, 0, 0, 0); if (ev->value > 0) flags &= ~KD_BUTTON_4; else flags &= ~KD_BUTTON_5; KdEnqueuePointerEvent(pi, flags, 0, 0, 0); } } }
/* * Standard PS/2 mouse protocol */ static Bool ps2Parse (KdPointerInfo *pi, unsigned char *ev, int ne) { Kmouse *km = pi->driverPrivate; int dx, dy, dz; unsigned long flags; unsigned long flagsrelease = 0; flags = KD_MOUSE_DELTA; if (ev[0] & 4) flags |= KD_BUTTON_2; if (ev[0] & 2) flags |= KD_BUTTON_3; if (ev[0] & 1) flags |= KD_BUTTON_1; if (ne > 3) { dz = (int) (signed char) ev[3]; if (dz < 0) { flags |= KD_BUTTON_4; flagsrelease = KD_BUTTON_4; } else if (dz > 0) { flags |= KD_BUTTON_5; flagsrelease = KD_BUTTON_5; } } dx = ev[1]; if (ev[0] & 0x10) dx -= 256; dy = ev[2]; if (ev[0] & 0x20) dy -= 256; dy = -dy; if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) { KdEnqueuePointerEvent (pi, flags, dx, dy, 0); if (flagsrelease) { flags &= ~flagsrelease; KdEnqueuePointerEvent (pi, flags, dx, dy, 0); } } return TRUE; }
static int BusRead (int adbPort, void *closure) { unsigned char buf[3]; int n; int dx, dy; unsigned long flags; n = read (adbPort, buf, 3); if (n == 3) { flags = KD_MOUSE_DELTA; dx = (char) buf[1]; dy = -(char) buf[2]; if ((buf[0] & 4) == 0) flags |= KD_BUTTON_1; if ((buf[0] & 2) == 0) flags |= KD_BUTTON_2; if ((buf[0] & 1) == 0) flags |= KD_BUTTON_3; KdEnqueuePointerEvent (closure, flags, dx, dy, 0); } return 0; }
static Bool logiParse (KdPointerInfo *pi, unsigned char *ev, int ne) { Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; flags = KD_MOUSE_DELTA; if (ne == 3) { if (ev[0] & 0x20) flags |= KD_BUTTON_1; if (ev[0] & 0x10) flags |= KD_BUTTON_3; dx = (signed char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F)); dy = (signed char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F)); flags |= km->state & KD_BUTTON_2; } else { if (ev[0] & 0x20) flags |= KD_BUTTON_2; dx = 0; dy = 0; flags |= km->state & (KD_BUTTON_1|KD_BUTTON_3); } if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; }
static void EvdevPtrBtn(KdPointerInfo * pi, struct input_event *ev) { int flags = KD_MOUSE_DELTA | pi->buttonState; if (ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK) { switch (ev->code) { case BTN_LEFT: if (ev->value == 1) flags |= KD_BUTTON_1; else flags &= ~KD_BUTTON_1; break; case BTN_MIDDLE: if (ev->value == 1) flags |= KD_BUTTON_2; else flags &= ~KD_BUTTON_2; break; case BTN_RIGHT: if (ev->value == 1) flags |= KD_BUTTON_3; else flags &= ~KD_BUTTON_3; break; default: /* Unknow button */ break; } KdEnqueuePointerEvent(pi, flags, 0, 0, 0); } }
static void ephyrProcessMouseMotion(xcb_generic_event_t *xev) { xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev; KdScreenInfo *screen = screen_from_window(motion->event); if (!ephyrMouse || !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) { EPHYR_LOG("skipping mouse motion:%d\n", screen->pScreen->myNum); return; } if (ephyrCursorScreen != screen->pScreen) { EPHYR_LOG("warping mouse cursor. " "cur_screen:%d, motion_screen:%d\n", ephyrCursorScreen->myNum, screen->pScreen->myNum); ephyrWarpCursor(inputInfo.pointer, screen->pScreen, motion->event_x, motion->event_y); } else { int x = 0, y = 0; #ifdef XF86DRI EphyrWindowPair *pair = NULL; #endif EPHYR_LOG("enqueuing mouse motion:%d\n", screen->pScreen->myNum); x = motion->event_x; y = motion->event_y; EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y); #ifdef XF86DRI EPHYR_LOG("is this window peered by a gl drawable ?\n"); if (findWindowPairFromRemote(motion->event, &pair)) { EPHYR_LOG("yes, it is peered\n"); x += pair->local->drawable.x; y += pair->local->drawable.y; } else { EPHYR_LOG("no, it is not peered\n"); } EPHYR_LOG("final (x,y):(%d,%d)\n", x, y); #endif /* convert coords into desktop-wide coordinates. * fill_pointer_events will convert that back to * per-screen coordinates where needed */ x += screen->pScreen->x; y += screen->pScreen->y; KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_POINTER_DESKTOP, x, y, 0); } }
static void TsRead (int tsPort, void *closure) { KdPointerInfo *pi = closure; TS_EVENT event; int n; long x, y; unsigned long flags; n = TsReadBytes (tsPort, (char *) &event, sizeof (event), sizeof (event)); if (n == sizeof (event)) { if (event.pressure) { /* * HACK ATTACK. (static global variables used !) * Here we test for the touch screen driver actually being on the * touch screen, if it is we send absolute coordinates. If not, * then we send delta's so that we can track the entire vga screen. */ if (KdCurScreen == KdTsPhyScreen) { flags = KD_BUTTON_1; x = event.x; y = event.y; } else { flags = /* KD_BUTTON_1 |*/ KD_MOUSE_DELTA; if ((lastx == 0) || (lasty == 0)) { x = 0; y = 0; } else { x = event.x - lastx; y = event.y - lasty; } lastx = event.x; lasty = event.y; } } else { flags = KD_MOUSE_DELTA; x = 0; y = 0; lastx = 0; lasty = 0; } KdEnqueuePointerEvent (pi, flags, x, y, 0); } }
static void ephyrProcessButtonRelease(xcb_generic_event_t *xev) { xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev; if (!ephyrMouse || !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) { return; } ephyrUpdateModifierState(button->state); mouseState &= ~(1 << (button->detail - 1)); EPHYR_LOG("enqueuing mouse release:%d\n", screen_from_window(button->event)->pScreen->myNum); KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0); }
static int Ps2Read (int ps2Port, void *closure) { unsigned char buf[3 * 200]; unsigned char *b; int n; int dx, dy; unsigned long flags; unsigned long left_button = KD_BUTTON_1; unsigned long right_button = KD_BUTTON_3; #undef SWAP_USB #ifdef SWAP_USB if (id == 2) { left_button = KD_BUTTON_3; right_button = KD_BUTTON_1; } #endif while ((n = Ps2ReadBytes (ps2Port, (char *) buf, sizeof (buf), 3)) > 0) { b = buf; while (n >= 3) { flags = KD_MOUSE_DELTA; if (b[0] & 4) flags |= KD_BUTTON_2; if (b[0] & 2) flags |= right_button; if (b[0] & 1) flags |= left_button; dx = b[1]; if (b[0] & 0x10) dx -= 256; dy = b[2]; if (b[0] & 0x20) dy -= 256; dy = -dy; n -= 3; b += 3; KdEnqueuePointerEvent (closure, flags, dx, dy, 0); } } return 0; }
static void wsmouseRead(int mousePort, void *closure) { KdPointerInfo *pi = closure; static struct wscons_event eventList[NUMEVENTS]; struct wscons_event *event = eventList; int n; n = read(mousePort, &eventList, NUMEVENTS * sizeof(struct wscons_event)); if (n <= 0) return; n /= sizeof(struct wscons_event); while (n--) { int dx = 0, dy = 0; unsigned long flags = 0; switch(event->type) { case WSCONS_EVENT_MOUSE_UP: flags &= ~kdbuttons[event->value]; break; case WSCONS_EVENT_MOUSE_DOWN: flags |= kdbuttons[1<<event->value]; break; case WSCONS_EVENT_MOUSE_DELTA_X: dx = event->value; flags |= KD_MOUSE_DELTA; break; case WSCONS_EVENT_MOUSE_DELTA_Y: dy = event->value; flags |= KD_MOUSE_DELTA; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_X: dx = event->value; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: dy = event->value; break; default: ErrorF("wsmouseRead: bad wsmouse event type=%d\n", event->type); continue; } /* case */ KdEnqueuePointerEvent(pi, flags, dx, dy, 0); } }
static void ephyrProcessButtonPress(xcb_generic_event_t *xev) { xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev; if (!ephyrMouse || !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) { EPHYR_LOG("skipping mouse press:%d\n", screen_from_window(button->event)->pScreen->myNum); return; } ephyrUpdateModifierState(button->state); /* This is a bit hacky. will break for button 5 ( defined as 0x10 ) * Check KD_BUTTON defines in kdrive.h */ mouseState |= 1 << (button->detail - 1); EPHYR_LOG("enqueuing mouse press:%d\n", screen_from_window(button->event)->pScreen->myNum); KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0); }
static Bool busParse (KdPointerInfo *pi, unsigned char *ev, int ne) { Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; flags = KD_MOUSE_DELTA; dx = (signed char) ev[1]; dy = -(signed char) ev[2]; if ((ev[0] & 4) == 0) flags |= KD_BUTTON_1; if ((ev[0] & 2) == 0) flags |= KD_BUTTON_2; if ((ev[0] & 1) == 0) flags |= KD_BUTTON_3; if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; }
/* * Mouse systems protocol, 5 bytes */ static Bool mscParse (KdPointerInfo *pi, unsigned char *ev, int ne) { Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; flags = KD_MOUSE_DELTA; if (!(ev[0] & 0x4)) flags |= KD_BUTTON_1; if (!(ev[0] & 0x2)) flags |= KD_BUTTON_2; if (!(ev[0] & 0x1)) flags |= KD_BUTTON_3; dx = (signed char)(ev[1]) + (signed char)(ev[3]); dy = - ((signed char)(ev[2]) + (signed char)(ev[4])); if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; }
static void ephyrProcessMouseMotion(xcb_generic_event_t *xev) { xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev; KdScreenInfo *screen = screen_from_window(motion->event); if (!ephyrMouse || !((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) { EPHYR_LOG("skipping mouse motion:%d\n", screen->pScreen->myNum); return; } if (ephyrCursorScreen != screen->pScreen) { EPHYR_LOG("warping mouse cursor. " "cur_screen:%d, motion_screen:%d\n", ephyrCursorScreen->myNum, screen->pScreen->myNum); ephyrWarpCursor(inputInfo.pointer, screen->pScreen, motion->event_x, motion->event_y); } else { int x = 0, y = 0; EPHYR_LOG("enqueuing mouse motion:%d\n", screen->pScreen->myNum); x = motion->event_x; y = motion->event_y; EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y); /* convert coords into desktop-wide coordinates. * fill_pointer_events will convert that back to * per-screen coordinates where needed */ x += screen->pScreen->x; y += screen->pScreen->y; KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_POINTER_DESKTOP, x, y, 0); } }
static void sdlPollInput(void) { static int buttonState=0; static int pressure = 0; SDL_Event event; //printf("sdlPollInput() %d\n", SDL_GetTicks()); while ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_MOUSEMOTION: //printf("SDL_MOUSEMOTION pressure %d\n", pressure); KdEnqueuePointerEvent(sdlPointer, mouseState, event.motion.x, event.motion.y, pressure); break; case SDL_MOUSEBUTTONDOWN: switch(event.button.button) { case SDL_BUTTON_LEFT: buttonState = KD_BUTTON_1; break; case SDL_BUTTON_MIDDLE: buttonState = KD_BUTTON_2; break; case SDL_BUTTON_RIGHT: buttonState = KD_BUTTON_3; break; case SDL_BUTTON_WHEELUP: buttonState = KD_BUTTON_4; break; case SDL_BUTTON_WHEELDOWN: buttonState = KD_BUTTON_5; break; /* case SDL_BUTTON_X1: buttonState = KD_BUTTON_6; break; case SDL_BUTTON_X2: buttonState = KD_BUTTON_7; break; */ default: buttonState = 1 << (event.button.button - 1); break; } mouseState |= buttonState; KdEnqueuePointerEvent(sdlPointer, mouseState|KD_MOUSE_DELTA, 0, 0, pressure); break; case SDL_MOUSEBUTTONUP: switch(event.button.button) { case SDL_BUTTON_LEFT: buttonState = KD_BUTTON_1; pressure = 0; break; case SDL_BUTTON_MIDDLE: buttonState = KD_BUTTON_2; break; case SDL_BUTTON_RIGHT: buttonState = KD_BUTTON_3; break; case SDL_BUTTON_WHEELUP: buttonState = KD_BUTTON_4; break; case SDL_BUTTON_WHEELDOWN: buttonState = KD_BUTTON_5; break; /* case SDL_BUTTON_X1: buttonState = KD_BUTTON_6; break; case SDL_BUTTON_X2: buttonState = KD_BUTTON_7; break; */ default: buttonState = 1 << (event.button.button - 1); break; } mouseState &= ~buttonState; KdEnqueuePointerEvent(sdlPointer, mouseState|KD_MOUSE_DELTA, 0, 0, pressure); break; case SDL_KEYDOWN: case SDL_KEYUP: //printf("Key sym %d scancode %d unicode %d", event.key.keysym.sym, event.key.keysym.scancode, event.key.keysym.unicode); #ifdef __ANDROID__ if (event.key.keysym.sym == SDLK_HELP) { if(event.type == SDL_KEYUP) SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput(); } else #endif if (event.key.keysym.sym == SDLK_UNDO) { if(event.type == SDL_KEYUP) { // Send Ctrl-Z KdEnqueueKeyboardEvent (sdlKeyboard, 37, 0); // LCTRL KdEnqueueKeyboardEvent (sdlKeyboard, 52, 0); // Z KdEnqueueKeyboardEvent (sdlKeyboard, 52, 1); // Z KdEnqueueKeyboardEvent (sdlKeyboard, 37, 1); // LCTRL } } /* * On some platforms (OSX) keystrokes like (Alt-X) have a unicode * character associated with them: ≈. * OSX makes the choice to propagate this character with key events. * Multi-byte IMEs likely do the same, but without a keycode. * * The Android port this was based on uses the approach of shelling * out to xset using the clipboard as a mechanism to emit unicode reliably. * Unfortunately our NaCl port doesn't yet have this utility. * Additionally, even if it did, it is unclear if passing along all unicode * this way is desirable, as for instance this blocks Emacs from receiving * Alt-X. For Android it was clear cut that using the Android IME would be * preferred over the remote one, but this is less clear on the desktop. * * Sending only raw key codes for now. */ #if !defined(__native_client__) else if((event.key.keysym.unicode & 0xFF80) != 0) { send_unicode (event.key.keysym.unicode); } #endif else KdEnqueueKeyboardEvent (sdlKeyboard, event.key.keysym.scancode, event.type==SDL_KEYUP); // Force SDL screen update, so SDL virtual on-screen buttons will change their images { SDL_Rect r = {0, 0, 1, 1}; SDL_UpdateRects(SDL_GetVideoSurface(), 1, &r); } break; case SDL_JOYAXISMOTION: if (event.jaxis.which == 0 && event.jaxis.axis == 4 && pressure != event.jaxis.value) { pressure = event.jaxis.value; if (mouseState & KD_BUTTON_1) KdEnqueuePointerEvent(sdlPointer, mouseState|KD_MOUSE_DELTA, 0, 0, pressure); } break; case SDL_ACTIVEEVENT: // We need this to re-init OpenGL and redraw screen // And we need to also call this when OpenGL context was destroyed // Oherwise SDL will stuck and we will get a permanent black screen SDL_Flip(SDL_GetVideoSurface()); break; //case SDL_QUIT: /* this should never happen */ //SDL_Quit(); // SDL_Quit() on Android is buggy } } /* if ( nextFullScreenRefresh && nextFullScreenRefresh < SDL_GetTicks() ) { //printf("SDL_Flip from sdlPollInput"); SDL_Flip(SDL_GetVideoSurface()); nextFullScreenRefresh = 0; } */ }