int tele_receive_reply(ggi_visual *vis, TeleEvent *ev, long type, long seq) { ggi_tele_priv *priv = TELE_PRIV(vis); ev->size = 0; priv->wait_event = ev; priv->wait_type = type; priv->wait_sequence = seq; DPRINT_EVENTS("display-tele: WAITING FOR (type=0x%08lx " "seq=0x%08lx)\n", type, seq); for (;;) { struct timeval tv; tv.tv_sec = tv.tv_usec = 0; GII_tele_poll(priv->input, NULL); if (ev->size != 0) { break; } ggUSleep(MINSLEEPTIME); } DPRINT_EVENTS("display-tele: WAIT OVER (type=0x%08lx " "seq=0x%08lx)\n", type, seq); priv->wait_event = NULL; return 0; }
static gii_event_mask GII_keyboard_poll(gii_input *inp, void *arg) { linkbd_priv *priv = LINKBD_PRIV(inp); unsigned char buf[256]; gii_event_mask result = 0; int readlen, i; DPRINT_EVENTS("GII_keyboard_poll(%p, %p) called\n", inp, arg); if (priv->eof) { /* End-of-file, don't do any polling */ return 0; } if (arg == NULL) { fd_set fds = inp->fdset; struct timeval tv = { 0, 0 }; if (select(inp->maxfd, &fds, NULL, NULL, &tv) <= 0) { return 0; } } else { if (! FD_ISSET(priv->fd, ((fd_set*)arg))) { /* Nothing to read on our fd */ DPRINT_EVENTS("GII_keyboard_poll: dummypoll\n"); return 0; } } /* Read keyboard data */ while ((readlen = read(priv->fd, buf, 256)) > 0) { for (i = 0; i < readlen; i++) { result |= GII_keyboard_handle_data(inp, buf[i]); } if (readlen != 256) break; else { fd_set fds = inp->fdset; struct timeval tv = { 0, 0 }; if (select(inp->maxfd, &fds, NULL, NULL, &tv) <= 0) { return 0; } } } if (readlen == 0) { /* End-of-file occured */ if (errno != EINTR) { priv->eof = 1; } DPRINT_EVENTS("Linux-kbd: EOF occured on fd: %d\n", priv->fd); } else if (readlen < 0) { /* Error, we try again next time */ perror("Linux-kbd: Error reading keyboard"); } return result; }
ggi_event_mask GII_aa_poll(gii_input_t inp, void *arg) { ggi_aa_priv *priv = inp->priv; ggi_event_mask evmask = 0; unsigned int aatype; DPRINT_EVENTS("GII_aa_poll\n"); if (!priv->context) return 0; while ((aatype = aa_getevent(priv->context, 0)) != AA_NONE) { DPRINT_EVENTS("AA: got event %x\n", aatype); if (aatype == AA_MOUSE) { evmask |= do_mouse(inp, priv); } else if (aatype >= 1 && aatype <= AA_RELEASE) { if (priv->lastkey == 0) { /* First hit */ evmask |= emKeyPress; add_key_event(inp, aatype, evKeyPress); } else if (priv->lastkey == aatype) { /* Repeated keypress */ evmask |= emKeyRepeat; add_key_event(inp, aatype, evKeyRepeat); } else { if (!priv->haverelease) { /* Whoops, different key! We send a release for the lastkey first. */ evmask |= emKeyRelease; add_key_event(inp, priv->lastkey, evKeyRelease); } evmask |= emKeyPress; add_key_event(inp, aatype, evKeyPress); } priv->lastkey = aatype; } else if (aatype > AA_RELEASE) { /* Release given key. It should match lastkey, but if it doesn't, tough luck, we clear it anyway. */ evmask |= emKeyRelease; add_key_event(inp, aatype, evKeyRelease); priv->lastkey = 0; priv->haverelease = 1; } else if (aatype == AA_RESIZE || aatype == AA_UNKNOWN) { } } if (!priv->haverelease && priv->lastkey) { /* No more events. If priv->lastkey != 0, we release that key. */ evmask |= emKeyRelease; add_key_event(inp, priv->lastkey, evKeyRelease); priv->lastkey = 0; } return evmask; }
gii_event_mask GII_tele_poll(gii_input *inp, void *arg) { ggi_tele_priv *priv = (ggi_tele_priv *) inp->priv; gii_event_mask evmask = 0; gii_event ev; TeleEvent th_ev; int err; DPRINT_EVENTS("display-tele: poll event.\n"); if (! priv->connected) { return 0; } if (tclient_poll(priv->client)) { err = tclient_read(priv->client, &th_ev); if (err == TELE_ERROR_SHUTDOWN) { TELE_HANDLE_SHUTDOWN; } else if (err < 0) { DPRINT_EVENTS("tclient_read: ZERO\n"); return 0; } DPRINT_EVENTS("display-tele: got event (type=0x%08x " "seq=0x%08x)\n", (int) th_ev.type, (int) th_ev.sequence); if ((th_ev.type & TELE_EVENT_TYPE_MASK) == TELE_CMD_BASE) { handle_telecmd_event(priv, &th_ev); } else if (translate_to_ggi(inp, &ev, &th_ev) == 0) { evmask |= (1 << ev.any.type); _giiEvQueueAdd(inp, &ev); } } return evmask; }
static inline gii_event_mask GII_keyboard_flush_keys(gii_input *inp) { linkbd_priv *priv = LINKBD_PRIV(inp); gii_event_mask rc = 0; gii_event ev; int code; for (code=0; code < 128; code++) { if (! priv->keydown_buf[code]) continue; priv->keydown_buf[code] = 0; if (! (inp->curreventmask & emKeyRelease)) continue; /* Send a key-release event */ _giiEventBlank(&ev, sizeof(gii_key_event)); ev.any.type = evKeyRelease; ev.any.size = sizeof(gii_key_event); ev.any.origin = inp->origin; ev.key.button = code; ev.key.sym = priv->keydown_sym[code]; ev.key.label = priv->keydown_label[code]; ev.key.modifiers = priv->modifiers; DPRINT_EVENTS("Linux-kbd: flushing key: button=0x%02x " "modifiers=0x%02x sym=0x%04x label=0x%04x.\n", ev.key.button, ev.key.modifiers, ev.key.sym, ev.key.label); _giiEvQueueAdd(inp, &ev); rc |= emKeyRelease; } priv->normalmod = 0; priv->modifiers = priv->lockedmod; if (priv->needctrl2switch) { priv->ctrlstate = 0; } return rc; }
static void handle_telecmd_event(ggi_tele_priv *priv, TeleEvent *ev) { /* handle TELE_CMD_CLOSE ??? */ if ((priv->wait_event == NULL) || (priv->wait_type != ev->type) || (priv->wait_sequence != ev->sequence)) { DPRINT_MISC("display-tele: UNEXPECTED CMD EVENT " "(type=0x%08x seq=0x%08x)\n", ev->type, ev->sequence); return; } DPRINT_EVENTS("display-tele: GOT REPLY (type=0x%08lx " "seq=0x%08lx)\n", ev->type, ev->sequence); memcpy(priv->wait_event, ev, ev->size * sizeof(long)); }
static inline gii_event_mask GII_keyboard_handle_data(gii_input *inp, int code) { linkbd_priv *priv = LINKBD_PRIV(inp); gii_event ev; struct kbentry entry; int symval, labelval; gii_event_mask mask; _giiEventBlank(&ev, sizeof(gii_key_event)); if (code & 0x80) { code &= 0x7f; ev.key.type = evKeyRelease; priv->keydown_buf[code] = 0; } else if (priv->keydown_buf[code] == 0) { ev.key.type = evKeyPress; priv->keydown_buf[code] = 1; } else { ev.key.type = evKeyRepeat; } ev.key.button = code; /* First update modifiers here so linkey.c can use the value */ ev.key.modifiers = priv->modifiers; if (ev.key.type == evKeyRelease && GII_KTYP(priv->keydown_sym[code]) != GII_KT_MOD && priv->keydown_sym[code] != GIIK_VOID) { /* We can use the cached values */ ev.key.sym = priv->keydown_sym[code]; ev.key.label = priv->keydown_label[code]; } else { /* Temporarily switch back to the old mode because unicodes aren't available through table lookup in MEDIUMRAW */ if (ioctl(priv->fd, KDSKBMODE, priv->old_mode) < 0) { DPRINT_MISC("Linux-kbd: ioctl(KDSKBMODE) failed.\n"); return 0; } /* Look up the keysym without modifiers, which will give us * the key label (more or less). */ entry.kb_table = 0; entry.kb_index = code; if (ioctl(priv->fd, KDGKBENT, &entry) < 0) { DPRINT_MISC("Linux-kbd: ioctl(KDGKBENT) failed.\n"); return 0; } labelval = entry.kb_value; if (priv->old_mode == K_UNICODE) labelval &= 0x0fff; /* Now look up the full keysym in the kernel's table */ /* calculate kernel-like shift value */ entry.kb_table = ((priv->modifiers & GII_MOD_SHIFT) ? (1<<KG_SHIFT) : 0) | ((priv->modifiers & GII_MOD_CTRL) ? (1<<KG_CTRL) : 0) | ((priv->modifiers & GII_MOD_ALT) ? (1<<KG_ALT) : 0) | ((priv->modifiers & GII_MOD_ALTGR) ? (1<<KG_ALTGR) : 0) | ((priv->modifiers & GII_MOD_META) ? (1<<KG_ALT) : 0) | ((priv->modifiers & GII_MOD_CAPS) ? (1<<KG_CAPSSHIFT) : 0); entry.kb_index = code; if (ioctl(priv->fd, KDGKBENT, &entry) < 0) { DPRINT_MISC("Linux-kbd: ioctl(KDGKBENT) failed.\n"); return 0; } /* Switch back to MEDIUMRAW */ if (ioctl(priv->fd, KDSKBMODE, K_MEDIUMRAW) < 0) { DPRINT_MISC("Linux-kbd: ioctl(KDSKBMODE) failed.\n"); return 0; } switch (entry.kb_value) { case K_HOLE: DPRINT_EVENTS("Linux-kbd: NOSUCHKEY\n"); break; case K_NOSUCHMAP: DPRINT_EVENTS("Linux-kbd: NOSUCHMAP\n"); entry.kb_value = K_HOLE; break; } symval = entry.kb_value; if (priv->old_mode == K_UNICODE) symval &= 0x0fff; _gii_linkey_trans(code, labelval, symval, &ev.key); if (ev.key.type == evKeyPress) { if (priv->accent) { if (GII_KTYP(ev.key.sym) != GII_KT_MOD) { handle_accent(priv, symval, &ev); } } else if (KTYP(symval) == KT_DEAD) { priv->accent = GII_KVAL(ev.key.sym); } } if (GII_KTYP(ev.key.sym) == GII_KT_DEAD) { ev.key.sym = GIIK_VOID; } } /* Keep track of modifier state */ if (GII_KTYP(ev.key.label) == GII_KT_MOD) { /* Modifers don't repeat */ if (ev.key.type == evKeyRepeat) return 0; handle_modifier(priv, &ev); } /* Now update modifiers again to get the value _after_ the current event */ ev.key.modifiers = priv->modifiers; if (ev.any.type == evKeyPress) { priv->keydown_sym[code] = ev.key.sym; priv->keydown_label[code] = ev.key.label; } DPRINT_EVENTS("KEY-%s button=0x%02x modifiers=0x%02x " "sym=0x%04x label=0x%04x\n", (ev.key.type == evKeyRelease) ? "UP" : ((ev.key.type == evKeyPress) ? "DN" : "RP"), ev.key.button, ev.key.modifiers, ev.key.sym, ev.key.label); if (priv->call_vtswitch) { if (ev.key.label == GIIK_CtrlL && priv->needctrl2switch) { if (ev.key.type == evKeyRelease) { priv->ctrlstate = 0; } else if (ev.key.type == evKeyPress) { priv->ctrlstate = 1; } } /* Check for console switch. Unfortunately, the kernel doesn't * recognize KT_CONS when the keyboard is in RAW or MEDIUMRAW * mode, so _we_ have to. Sigh. */ if ((ev.key.type == evKeyPress) && (KTYP(entry.kb_value) == KT_CONS) && priv->ctrlstate) { int rc; int new_cons = 1+KVAL(entry.kb_value); /* Clear the keydown buffer, since we'll never know what keys the user pressed (or released) while they were away. */ DPRINT_MISC("Flushing all keys.\n"); rc = GII_keyboard_flush_keys(inp); DPRINT_MISC("Switching to console %d.\n", new_cons); if (ioctl(priv->fd, VT_ACTIVATE, new_cons) < 0) { perror("ioctl(VT_ACTIVATE)"); } return rc; } } mask = (1 << ev.any.type); if (! (inp->curreventmask & mask)) return 0; /* finally queue the key event */ ev.any.size = sizeof(gii_key_event); ev.any.origin = inp->origin; _giiEvQueueAdd(inp, &ev); return (1 << ev.any.type); }
static long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LPCREATESTRUCT lpcs; PAINTSTRUCT ps; RECT dirty; HDC hdc; struct ggi_visual *vis = (struct ggi_visual *) GetWindowLong(hWnd, GWL_USERDATA); directx_priv *priv = NULL; HRESULT hr; if (vis) priv = GGIDIRECTX_PRIV(vis); switch (message) { case WM_DDSETPALETTE: { int setpalette; GGI_directx_Lock(priv->spincs); setpalette = priv->setpalette; GGI_directx_Unlock(priv->spincs); if(setpalette) /* setpalette canceled */ return 0; } if(GGI_directx_TryLock(priv->cs)) { /* spin */ PostMessage(hWnd, message, wParam, lParam); return 0; } if(priv->lpddp) GGI_directx_DDChangePalette(vis); GGI_directx_Lock(priv->spincs); priv->setpalette = 1; GGI_directx_Unlock(priv->spincs); GGI_directx_Unlock(priv->cs); return 0; case WM_TIMER: if (wParam != 1) break; if (GGI_directx_TryLock(priv->cs)) { int redraw = 0; GGI_directx_Lock(priv->spincs); redraw = priv->redraw; priv->redraw = 0; GGI_directx_Unlock(priv->spincs); if (redraw) /* spin */ PostMessage(hWnd, WM_USER, wParam, lParam); return 0; } GGI_directx_DDRedrawAll(vis); GGI_directx_Unlock(priv->cs); return 0; case WM_PAINT: if (GGI_directx_TryLock(priv->cs)) { int redraw = 0; GGI_directx_Lock(priv->spincs); redraw = priv->redraw; priv->redraw = 0; GGI_directx_Unlock(priv->spincs); if (redraw) /* spin */ InvalidateRect(hWnd, NULL, 0); return 0; } if (GetUpdateRect(hWnd, &dirty, FALSE)) { /* I have a back buffer to update from, * no need to involve the application... if (priv->inp) { gii_event ev; ev.any.size = sizeof(gii_expose_event); ev.any.type = evExpose; ev.any.target = priv->inp->origin; ev.expose.x = vis->origin_x + dirty.left; ev.expose.y = vis->origin_y + dirty.top; ev.expose.w = dirty.right - dirty.left; ev.expose.h = dirty.bottom - dirty.top; giiEventSend(priv->inp, &ev); } */ hr = IDirectDrawSurface_IsLost(priv->lppdds); if (hr == DDERR_SURFACELOST) hr = IDirectDrawSurface_Restore( priv->lppdds); hdc = BeginPaint(hWnd, &ps); GGI_directx_DDRedraw( vis, vis->origin_x + ps.rcPaint.left, vis->origin_y + ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); EndPaint(hWnd, &ps); } GGI_directx_Unlock(priv->cs); return 0; case WM_SIZING: GGI_directx_Lock(priv->sizingcs); if (priv->xstep < 0) { GGI_directx_Unlock(priv->sizingcs); break; } DDSizing(vis, wParam, (LPRECT) lParam); GGI_directx_Unlock(priv->sizingcs); return TRUE; case WM_SIZE: switch(wParam) { case SIZE_MAXIMIZED: case SIZE_RESTORED: break; default: return 0; } GGI_directx_Lock(priv->sizingcs); if (priv->xstep < 0) { GGI_directx_Unlock(priv->sizingcs); break; } DDNotifyResize(vis, LOWORD(lParam), HIWORD(lParam)); GGI_directx_Unlock(priv->sizingcs); return 0; case WM_QUERYNEWPALETTE: if(GGI_directx_TryLock(priv->cs)) { int setpalette = 0; GGI_directx_Lock(priv->spincs); setpalette = priv->setpalette; priv->redraw = 0; GGI_directx_Unlock(priv->spincs); if(setpalette) /* spin */ PostMessage(hWnd, WM_DDSETPALETTE, wParam, lParam); return 0; } if(!priv->lpddp) { GGI_directx_Unlock(priv->cs); break; } GGI_directx_DDChangePalette(vis); GGI_directx_Unlock(priv->cs); return TRUE; case WM_CREATE: lpcs = (LPCREATESTRUCT) lParam; SetWindowLong(hWnd, GWL_USERDATA, (DWORD) lpcs->lpCreateParams); return 0; case WM_CLOSE: DPRINT_EVENTS("WM_CLOSE\n"); if (priv->hParent) break; ggBroadcast(vis->instance.channel, GGI_CMDCODE_CLOSE, NULL); if (priv->exit_on_close_window) exit(0); return 0; case WM_RENDERFORMAT: case WM_RENDERALLFORMATS: { struct ggi_directx_cmddata_render_cb format; format.format = wParam; ggBroadcast(vis->instance.channel, GGI_DIRECTX_RENDERCLIPBOARD, &format); return 0; } case WM_DESTROYCLIPBOARD: ggBroadcast(vis->instance.channel, GGI_DIRECTX_DESTROYCLIPBOARD, NULL); return 0; #if 0 /* WM_CLIPBOARDUPDATE is >= Vista :-( */ case WM_CLIPBOARDUPDATE: ggBroadcast(vis->instance.channel, GGI_DIRECTX_CLIPBOARDUPDATE, NULL); return 0; #endif case WM_SETTINGCHANGE: GGI_directx_Lock(priv->cs); if (priv->settings_changed) { DPRINT("tell inputlib about " "new system parameters\n"); priv->settings_changed(priv->settings_changed_arg); GGI_directx_Unlock(priv->cs); return 0; } GGI_directx_Unlock(priv->cs); break; case WM_SETFOCUS: if (priv->grab_hotkeys) { DPRINT("Grab hotkeys (focus)\n"); PostThreadMessage(priv->nThreadID, WM_DDHOTKEY, 1, 0); } priv->focus = 1; break; case WM_KILLFOCUS: if (priv->grab_hotkeys) { DPRINT("Ungrab hotkeys (unfocus)\n"); PostThreadMessage(priv->nThreadID, WM_DDHOTKEY, 0, 0); } priv->focus = 0; break; case WM_HOTKEY: if (priv->grab_hotkeys && priv->inp) { gii_inputdx_hotkey hotkey; hotkey.id = wParam; hotkey.mod = LOWORD(lParam); hotkey.vk = HIWORD(lParam); DPRINT("WM_HOTKEY id=%d, mod=%04x, vk=%d\n", hotkey.id, hotkey.mod, hotkey.vk); ggControl(priv->inp->channel, GII_INPUTDX_HOTKEY, &hotkey); } break; } return DefWindowProc(hWnd, message, wParam, lParam); }
static int transKeyQuartz2GII(gii_event *ev, uint32_t macKeyCode, char macCharCodes, uint32_t modifiers) { uint32_t symbol; uint32_t label; uint32_t button = macCharCodes; switch (macKeyCode) { case QUARTZ_F1: symbol = label = GIIK_F1; break; case QUARTZ_F2: symbol = label = GIIK_F2; break; case QUARTZ_F3: symbol = label = GIIK_F3; break; case QUARTZ_F4: symbol = label = GIIK_F4; break; case QUARTZ_F5: symbol = label = GIIK_F5; break; case QUARTZ_F6: symbol = label = GIIK_F6; break; case QUARTZ_F7: symbol = label = GIIK_F7; break; case QUARTZ_F8: symbol = label = GIIK_F8; break; case QUARTZ_F9: symbol = label = GIIK_F9; break; case QUARTZ_F10: symbol = label = GIIK_F10; break; case QUARTZ_F11: symbol = label = GIIK_F11; break; case QUARTZ_F12: symbol = label = GIIK_F12; break; case QUARTZ_KP_DIVIDE: symbol = label = GIIK_PSlash; break; case QUARTZ_KP_ENTER: symbol = label = GIIK_PEnter; break; case QUARTZ_KP_EQUALS: symbol = label = GIIK_PEqual; break; case QUARTZ_KP_MINUS: symbol = label = GIIK_PMinus; break; case QUARTZ_KP_MULTIPLY: symbol = label = GIIK_PAsterisk; break; case QUARTZ_KP_PERIOD: fprintf(stderr, "Pressed QUATRZ_KP_PERIOD key!\n"); symbol = GIIUC_PeriodCentered; label = GIIK_P5; break; case QUARTZ_KP_PLUS: symbol = label = GIIK_PMinus; break; case QUARTZ_KP0: symbol = label = GIIK_P0; break; case QUARTZ_KP1: symbol = label = GIIK_P1; break; case QUARTZ_KP2: symbol = label = GIIK_P2; break; case QUARTZ_KP3: symbol = label = GIIK_P3; break; case QUARTZ_KP4: symbol = label = GIIK_P4; break; case QUARTZ_KP5: symbol = label = GIIK_P5; break; case QUARTZ_KP6: symbol = label = GIIK_P6; break; case QUARTZ_KP7: symbol = label = GIIK_P7; break; case QUARTZ_KP8: symbol = label = GIIK_P8; break; case QUARTZ_KP9: symbol = label = GIIK_P9; break; case QUARTZ_CAPSLOCK: symbol = label = GIIK_CapsLock; break; case QUARTZ_NUMLOCK: symbol = label = GIIK_NumLock; break; case QUARTZ_PAUSE: symbol = label = GIIK_Pause; break; case QUARTZ_POWER: symbol = label = GIIK_Power; break; case QUARTZ_PRINT: symbol = label = GIIK_PrintScreen; break; case QUARTZ_SCROLLOCK: symbol = label = GIIK_ScrollLock; break; case QUARTZ_BACKQUOTE: symbol = GIIUC_Circumflex; label = GIIUC_Apostrophe; break; case QUARTZ_DELETE: symbol = label = GIIUC_Delete; break; case QUARTZ_INSERT: symbol = label = GIIK_Insert; break; case QUARTZ_LSHIFT: #if 0 case QUARTZ_RSHIFT: #endif symbol = label = GIIK_Shift; break; case QUARTZ_LCTRL: #if 0 case QUARTZ_RCTRL: #endif symbol = label = GIIK_Ctrl; break; case QUARTZ_LALT: #if 0 case QUARTZ_RALT: #endif symbol = label = GIIK_Alt; break; case QUARTZ_LMETA: #if 0 case QUARTZ_RMETA: #endif symbol = label = GIIK_Meta; break; case QUARTZ_HOME: symbol = label = GIIK_Home; break; case QUARTZ_PAGEUP: symbol = label = GIIK_PageUp; break; case QUARTZ_END: symbol = label = GIIK_End; break; case QUARTZ_PAGEDOWN: symbol = label = GIIK_PageDown; break; case QUARTZ_LEFT: symbol = label = GIIK_Left; break; case QUARTZ_DOWN: symbol = label = GIIK_Down; break; case QUARTZ_RIGHT: symbol = label = GIIK_Right; break; case QUARTZ_UP: symbol = label = GIIK_Up; break; case QUARTZ_NOTEBOOK_ENTER: symbol = label = GIIK_Enter; break; case QUARTZ_NOTEBOOK_LEFT: symbol = label = GIIK_Left; break; case QUARTZ_NOTEBOOK_RIGHT: symbol = label = GIIK_Right; break; case QUARTZ_NOTEBOOK_DOWN: symbol = label = GIIK_Down; break; case QUARTZ_NOTEBOOK_UP: symbol = label = GIIK_Up; break; default: /* handle all ASCII codes as symbols */ DPRINT_EVENTS("macKeyCode = %X, macCharCodes = %X\n", macKeyCode, macCharCodes); symbol = macCharCodes; #if 0 label = macKeyCode; #else label = toupper((unsigned char)macCharCodes); #endif break; } /* switch */ ev->key.sym = symbol; ev->key.label = label; ev->key.button = button; return 0; } /* transKeyQuartz2GII */