int read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len) { XEvent ev; int nbytes; /* Read a key from the keyboard. */ do { XMaskEvent (dpy, KeyPressMask|KeyRelease, &ev); *modifiers = ev.xkey.state; nbytes = cook_keycode (&ev.xkey, keysym, modifiers, keysym_name, len, 0); } while (IsModifierKey (*keysym) || ev.xkey.type == KeyRelease); return nbytes; }
/* Called by the kbd q'd irq handler when a key code is available in a cooked console. */ static void cooked_use_key(struct kbd *kbd, int shift_state, u_char key_code, u_char up_code) { struct cooked_kbd *ck = (struct cooked_kbd *)kbd; DB(("cuk: kbd=%p, shift_state=%#x, key_code=%#x, up_code=%#x\n", kbd, shift_state, key_code, up_code)); if(up_code == 0) { char *str; switch(key_code) { case K_CAPS_LOCK: DB(("cuk: toggling caps_lock\n")); toggle_lock_state(ck, L_CAPS_LOCK); break; case K_NUM_LOCK: DB(("cuk: toggling num_lock\n")); toggle_lock_state(ck, L_NUM_LOCK); break; case K_SCROLL_LOCK: DB(("cuk: toggling scroll_lock\n")); toggle_lock_state(ck, L_SCROLL_LOCK); break; } str = cook_keycode(key_code, shift_state, ck->lock_state); if(str != NULL) { switch(ck->type) { case ct_Func: DB(("cuk: feeding `%s' to function %p\n", str, ck->func)); while(*str) ck->receiver.func(*str++); break; case ct_Task: { int len = strlen(str); while(len-- > 0) { int new_in = ((ck->receiver.task.in + 1) % COOKED_BUFSIZ); if(new_in == ck->receiver.task.out) break; ck->receiver.task.buf[ck->receiver.task.in] = *str++; ck->receiver.task.in = new_in; } if(ck->receiver.task.task != NULL) { kernel->wake_task(ck->receiver.task.task); ck->receiver.task.task = NULL; } break; } case ct_None: break; } } } }