static void EvdevRead1 (int evdevPort, void *closure) { int i, n, xk; struct input_event events[NUM_EVENTS]; n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event)); if (n <= 0) return; n /= sizeof (struct input_event); for (i = 0; i < n; i++) { switch (events[i].type) { case EV_SYN: break; case EV_KEY: xk = events[i].code; if (events[i].code < 0x100) ErrorF ("key %d %d xk %d\n", events[i].code, events[i].value, xk); else ErrorF ("key 0x%x %d xk %d\n", events[i].code, events[i].value, xk); if (events[i].value == 2) { //KdEnqueueKeyboardEvent (xk, 0); KdEnqueueKeyboardEvent (xk, 0); } else KdEnqueueKeyboardEvent (xk, !events[i].value); break; } } }
/* * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug. * See https://bugs.freedesktop.org/show_bug.cgi?id=3030 */ void ephyrUpdateModifierState(unsigned int state) { DeviceIntPtr pDev = inputInfo.keyboard; KeyClassPtr keyc = pDev->key; int i; CARD8 mask; int xkb_state; if (!pDev) return; xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); state = state & 0xff; if (xkb_state == state) return; for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { int key; /* Modifier is down, but shouldn't be */ if ((xkb_state & mask) && !(state & mask)) { int count = keyc->modifierKeyCount[i]; for (key = 0; key < MAP_LENGTH; key++) if (keyc->xkbInfo->desc->map->modmap[key] & mask) { if (mask == XCB_MOD_MASK_LOCK) { KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); } else if (key_is_down(pDev, key, KEY_PROCESSED)) KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); if (--count == 0) break; } } /* Modifier shoud be down, but isn't */ if (!(xkb_state & mask) && (state & mask)) for (key = 0; key < MAP_LENGTH; key++) if (keyc->xkbInfo->desc->map->modmap[key] & mask) { KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); if (mask == XCB_MOD_MASK_LOCK) KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); break; } } }
void VxMouseRead (int mousePort) { Event ev; int dx, dy; unsigned long flags; unsigned long mask; int n; while (eventQueue->head != eventQueue->tail) { ev = *eventQueue->head; if (eventQueue->head >= &eventQueue->events[eventQueue->size-1]) eventQueue->head = &eventQueue->events[0]; else eventQueue->head++; switch (ev.e_type) { case E_BUTTON: switch (ev.e_device) { case E_MOUSE: switch (ev.e_key) { case BUTTON1: mask = KD_BUTTON_1; break; case BUTTON2: mask = KD_BUTTON_2; break; case BUTTON3: mask = KD_BUTTON_3; break; default: mask = 0; break; } if (ev.e_direction == E_KBUP) mouseState &= ~mask; else mouseState |= mask; KdEnqueueMouseEvent (mouseState | KD_MOUSE_DELTA, 0, 0); break; case E_DKB: KdEnqueueKeyboardEvent (ev.e_key, ev.e_direction == E_KBUP); break; } break; case E_MMOTION: KdEnqueueMouseEvent (mouseState | KD_MOUSE_DELTA, ev.e_x, ev.e_y); break; } } }
static void ephyrProcessKeyPress(xcb_generic_event_t *xev) { xcb_key_press_event_t *key = (xcb_key_press_event_t *)xev; if (!ephyrKbd || !((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) { return; } ephyrUpdateModifierState(key->state); KdEnqueueKeyboardEvent(ephyrKbd, key->detail, FALSE); }
static void *send_unicode_thread(void *param) { // International text input - copy symbol to clipboard, and send copypaste key int unicode = (int)param; char cmd[1024] = ""; char c[5] = ""; sprintf (cmd, "127.0.0.1:%s", display); setenv ("DISPLAY", cmd, 1); UnicodeToUtf8 (unicode, c); //sprintf(cmd, "echo '%s' | %s/usr/bin/xsel -b -i >/dev/null 2>&1", c, getenv("APPDIR")); //sprintf(cmd, "echo '%s' >/dev/null 2>&1", c); //sprintf(cmd, "%s/usr/bin/xsel -b", getenv("APPDIR")); //printf("Launching cmd: %s", cmd); //int ret = system(cmd); //printf("Cmd ret: %d", ret); sprintf(cmd, "%s/usr/bin/xsel -b -i >/dev/null 2>&1", getenv("APPDIR")); execute_command(cmd, "w", c, 5); KdEnqueueKeyboardEvent (sdlKeyboard, 37, 0); // LCTRL KdEnqueueKeyboardEvent (sdlKeyboard, 55, 0); // V KdEnqueueKeyboardEvent (sdlKeyboard, 55, 1); // V KdEnqueueKeyboardEvent (sdlKeyboard, 37, 1); // LCTRL return NULL; }
void LinuxKeyboardRead (int fd, void *closure) { unsigned char buf[256], *b; int n; while ((n = read (fd, buf, sizeof (buf))) > 0) { b = buf; while (n--) { KdEnqueueKeyboardEvent (b[0] & 0x7f, b[0] & 0x80); b++; } } }
static void EvdevKbdRead(int evdevPort, void *closure) { KdKeyboardInfo *ki = closure; struct input_event events[NUM_EVENTS]; int i, n; n = read(evdevPort, &events, NUM_EVENTS * sizeof(struct input_event)); if (n <= 0) { if (errno == ENODEV) DeleteInputDeviceRequest(ki->dixdev); return; } n /= sizeof(struct input_event); for (i = 0; i < n; i++) { if (events[i].type == EV_KEY) KdEnqueueKeyboardEvent(ki, events[i].code, !events[i].value); /* FIXME: must implement other types of events else ErrorF("Event type (%d) not delivered\n", events[i].type); */ } }
static void ephyrProcessKeyRelease(xcb_generic_event_t *xev) { xcb_connection_t *conn = hostx_get_xcbconn(); xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev; static xcb_key_symbols_t *keysyms; static int grabbed_screen = -1; int mod1_down = ephyrUpdateGrabModifierState(key->state); if (!keysyms) keysyms = xcb_key_symbols_alloc(conn); if (!EphyrWantNoHostGrab && (((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R) && (key->state & XCB_MOD_MASK_CONTROL)) || ((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_L || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_R) && (key->state & XCB_MOD_MASK_SHIFT)))) { KdScreenInfo *screen = screen_from_window(key->event); EphyrScrPriv *scrpriv = screen->driver; if (grabbed_screen != -1) { xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME); xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME); grabbed_screen = -1; hostx_set_win_title(screen, "(ctrl+shift grabs mouse and keyboard)"); } else if (!mod1_down) { /* Attempt grab */ xcb_grab_keyboard_cookie_t kbgrabc = xcb_grab_keyboard(conn, TRUE, scrpriv->win, XCB_TIME_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_keyboard_reply_t *kbgrabr; xcb_grab_pointer_cookie_t pgrabc = xcb_grab_pointer(conn, TRUE, scrpriv->win, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, scrpriv->win, XCB_NONE, XCB_TIME_CURRENT_TIME); xcb_grab_pointer_reply_t *pgrabr; kbgrabr = xcb_grab_keyboard_reply(conn, kbgrabc, NULL); if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) { xcb_discard_reply(conn, pgrabc.sequence); xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME); } else { pgrabr = xcb_grab_pointer_reply(conn, pgrabc, NULL); if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS) { xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME); } else { grabbed_screen = scrpriv->mynum; hostx_set_win_title (screen, "(ctrl+shift releases mouse and keyboard)"); } } } } if (!ephyrKbd || !((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) { return; } /* Still send the release event even if above has happened server * will get confused with just an up event. Maybe it would be * better to just block shift+ctrls getting to kdrive all * together. */ ephyrUpdateModifierState(key->state); KdEnqueueKeyboardEvent(ephyrKbd, key->detail, TRUE); }
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; } */ }