static inline void map_key(gii_key_event * ge, Visual_Key_Event_Type * ve) { switch(GII_KTYP(ge->sym)) { case GII_KT_FN : ve->state = 0; /* FIXME: CTRL and ALT */ switch(ge->sym) { case GIIK_F1 : case GIIK_F2 : case GIIK_F3 : case GIIK_F4 : case GIIK_F5 : case GIIK_F6 : case GIIK_F7 : case GIIK_F8 : case GIIK_F9 : case GIIK_F10 : ve->keycode = GII_KVAL(ge->sym) - GII_KVAL(GIIK_F1) + VDI_KSCAN(VDI_K_F1); break; case GIIK_F11 : case GIIK_F12 : case GIIK_F13 : case GIIK_F14 : case GIIK_F15 : case GIIK_F16 : case GIIK_F17 : case GIIK_F18 : case GIIK_F19 : case GIIK_F20 : ve->keycode = GII_KVAL(ge->sym) - GII_KVAL(GIIK_F11) + VDI_KSCAN(VDI_K_F11); break; default : ; /* FIXME */ } ve->ascii = 0; break; default : ve->state = 0; ve->keycode = ge->label; ve->ascii = GII_KVAL(ge->sym); } }
int main(int argc, const char *argv[]) { ggi_visual_t vis; ggi_mode mode; int i, j, cx, cy, c; char buf[80]; /* Set up the random number generator */ srandom((unsigned)time(NULL)); /* Initialize LibGGI */ if (giiInit() < 0) { fprintf(stderr, "Cannot initialize LibGII!\n"); return 1; } if (ggiInit() < 0) { fprintf(stderr, "Cannot initialize LibGGI!\n"); giiExit(); return 1; } vis = ggNewStem(NULL); if (!vis) { fprintf(stderr, "Cannot open create stem!\n"); ggiExit(); giiExit(); return 1; } if (giiAttach(vis) < 0) { fprintf(stderr, "Cannot attach LibGII!\n"); ggDelStem(vis); ggiExit(); giiExit(); return 1; } if (ggiAttach(vis) < 0) { fprintf(stderr, "Cannot attach LibGGI!\n"); ggDelStem(vis); ggiExit(); giiExit(); return 1; } /* Open default visual */ if (ggiOpen(vis, NULL) < 0) { fprintf(stderr, "Cannot open default visual!\n"); ggDelStem(vis); ggiExit(); giiExit(); return 1; } /* Set visual to async mode (drawing not immediate) */ ggiSetFlags(vis, GGIFLAG_ASYNC); /* Set default mode, but with multiple buffering */ if (argc > 1) { ggiParseMode(argv[1], &mode); } else { ggiParseMode("", &mode); if (mode.frames < 2) mode.frames = 2; } if (ggiSetMode(vis, &mode)) { fprintf(stderr, "Cannot set mode!\n"); ggDelStem(vis); ggiExit(); giiExit(); return 1; } ggiGetCharSize(vis, &cx, &cy); /* Setup palette */ if (GT_SCHEME(mode.graphtype) == GT_PALETTE) { ggiSetColorfulPalette(vis); } /* Write something into each frame */ for (i = 0; i < mode.frames; i++) { if (ggiSetWriteFrame(vis, i)) { fprintf(stderr, "Cannot set write frame!\n"); ggDelStem(vis); ggiExit(); giiExit(); return 1; } ggiSetGCBackground(vis, ggiMapColor(vis, &white)); ggiSetGCForeground(vis, ggiMapColor(vis, &white)); ggiFillscreen(vis); } /* Clip a small border so that clipping can be verified. */ ggiSetGCClipping(vis, 5, 5, mode.virt.x - 5, mode.virt.y - 5); /* Write something into each frame */ for (i = 0; i < mode.frames; i++) { ggiSetWriteFrame(vis, i); ggiSetGCBackground(vis, ggiMapColor(vis, &black)); ggiSetGCForeground(vis, ggiMapColor(vis, &black)); ggiFillscreen(vis); snprintf(buf, sizeof(buf), "Hello World #%d!", i); for (j = 0; j < mode.virt.y; j += cy) { ggi_color col; int x = random() % mode.virt.x; int h = (random() & 0x7fff) + 0x8000; int l = (random() & 0x7fff); /* Use different colors for different frames */ col.r = ((i + 1) & 1) ? h : l; col.g = ((i + 1) & 2) ? h : l; col.b = ((i + 1) & 4) ? h : l; ggiSetGCForeground(vis, ggiMapColor(vis, &col)); ggiPuts(vis, x, j, buf); } /* Flush commands before proceeding to the next frame */ ggiFlush(vis); } /* Cycle through frames */ i = 0; j = 0; do { if (ggiSetDisplayFrame(vis, i)) { ggPanic("Cannot set display frame!\n"); } /* Wait */ c = GIIK_VOID; do { struct timeval tv = { 0, 0 }; int key; /* Flush command before waiting for input */ ggiFlush(vis); key = giiEventPoll(vis, emKeyPress, &tv); if (key & emKeyPress) c = giiGetc(vis); ggUSleep(50000); animate(vis, &mode, j); j++; } while (c == GIIK_VOID || GII_KTYP(c) == GII_KT_MOD); i = (i + 1) % mode.frames; } while (c != 'q' && c != 'Q' && c != 'x' && c != 'X' && c != GIIUC_Escape); ggiClose(vis); ggDelStem(vis); ggiExit(); giiExit(); return 0; }
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 int XLateKey (ggi_key_event * ev) { int key = 0; if (GII_KTYP (ev->label) == GII_KT_DEAD) { ev->label = GII_KVAL (ev->label); } switch (ev->label) { case GIIK_P9: key = KP_PGUP; break; case GIIK_PageUp: key = K_PGUP; break; case GIIK_P3: key = KP_PGDN; break; case GIIK_PageDown: key = K_PGDN; break; case GIIK_P7: key = KP_HOME; break; case GIIK_Home: key = K_HOME; break; case GIIK_P1: key = KP_END; break; case GIIK_End: key = K_END; break; case GIIK_P4: key = KP_LEFTARROW; break; case GIIK_Left: key = K_LEFTARROW; break; case GIIK_P6: key = KP_RIGHTARROW; break; case GIIK_Right: key = K_RIGHTARROW; break; case GIIK_P2: key = KP_DOWNARROW; break; case GIIK_Down: key = K_DOWNARROW; break; case GIIK_P8: key = KP_UPARROW; break; case GIIK_Up: key = K_UPARROW; break; case GIIK_P5: key = KP_5; break; case GIIK_PBegin: key = K_AUX32; break; case GIIK_P0: key = KP_INS; break; case GIIK_Insert: key = K_INS; break; case GIIK_PSeparator: case GIIK_PDecimal: key = KP_DEL; break; case GIIUC_Delete: key = K_DEL; break; case GIIK_PStar: key = KP_MULTIPLY; break; case GIIK_PPlus: key = KP_PLUS; break; case GIIK_PMinus: key = KP_MINUS; break; case GIIK_PSlash: key = KP_DIVIDE; break; case GIIK_PEnter: key = KP_ENTER; break; case GIIUC_Return: key = K_ENTER; break; case GIIUC_Escape: key = K_ESCAPE; break; case GIIUC_Tab: key = K_TAB; break; case GIIK_F1: key = K_F1; break; case GIIK_F2: key = K_F2; break; case GIIK_F3: key = K_F3; break; case GIIK_F4: key = K_F4; break; case GIIK_F5: key = K_F5; break; case GIIK_F6: key = K_F6; break; case GIIK_F7: key = K_F7; break; case GIIK_F8: key = K_F8; break; case GIIK_F9: key = K_F9; break; case GIIK_F10: key = K_F10; break; case GIIK_F11: key = K_F11; break; case GIIK_F12: key = K_F12; break; case GIIUC_BackSpace: key = K_BACKSPACE; break; case GIIK_ShiftL: case GIIK_ShiftR: key = K_SHIFT; break; case GIIK_Execute: case GIIK_CtrlL: case GIIK_CtrlR: key = K_CTRL; break; case GIIK_AltL: case GIIK_MetaL: case GIIK_AltR: case GIIK_MetaR: case GIIK_AltGr: case GIIK_ModeSwitch: key = K_ALT; break; case GIIK_Caps: key = K_CAPSLOCK; break; case GIIK_PrintScreen: key = K_PRNTSCR; break; case GIIK_ScrollLock: key = K_SCRLCK; break; case GIIK_Pause: key = K_PAUSE; break; case GIIK_NumLock: key = KP_NUMLCK; break; case GIIUC_Comma: case GIIUC_Minus: case GIIUC_Period: key = ev->label; break; case GIIUC_Section: key = '~'; break; default: if (ev->label >= 0 && ev->label <= 9) return ev->label; if (ev->label >= 'A' && ev->label <= 'Z') { return ev->label - 'A' + 'a'; } if (ev->label >= 'a' && ev->label <= 'z') return ev->label; if (ev->sym <= 0x7f) { key = ev->sym; if (key >= 'A' && key <= 'Z') { key = key - 'A' + 'a'; } return key; } if (ev->label <= 0x7f) { return ev->label; } break; } return key; }