diff options
Diffstat (limited to 'src/input.c')
-rw-r--r-- | src/input.c | 127 |
1 files changed, 95 insertions, 32 deletions
diff --git a/src/input.c b/src/input.c index 60e3932..c9a276a 100644 --- a/src/input.c +++ b/src/input.c @@ -9,51 +9,102 @@ #include "ratpoison.h" +/* Return the name of the keysym. caller must free returned pointer */ +char * +keysym_to_string (KeySym keysym, unsigned int modifier) +{ + const unsigned int mod_table[] = {ControlMask, + Mod1Mask, + Mod2Mask, + Mod3Mask, + Mod4Mask, + Mod5Mask}; + const unsigned char str_table[] = "CM2345"; + + unsigned char *name; + int pos, i; + + name = malloc (15); + if (name == NULL) + { + PRINT_ERROR ("Out of memory!\n"); + exit (EXIT_FAILURE); + } + + for (pos = 0, i = 0; i < 6; i++) + { + if (modifier & mod_table[i]) + { + name[pos] = str_table[i]; + name[pos+1] = '-'; + pos += 2; + } + } + + name[pos] = keysym; + name[pos+1] = '\0'; + + return name; +} + /* Cooks a keycode + modifier into a keysym + modifier. This should be used anytime meaningful key information is to be extracted from a KeyPress or KeyRelease event. */ void -cook_keycode (KeyCode keycode, KeySym *keysym, int *mod) +cook_keycode (KeyCode keycode, KeySym *keysym, unsigned int *mod) { KeySym normal, shifted; - if (*mod & ShiftMask) - { - normal = XKeycodeToKeysym(dpy, keycode, 0); - shifted = XKeycodeToKeysym(dpy, keycode, 1); + normal = XKeycodeToKeysym(dpy, keycode, 0); + shifted = XKeycodeToKeysym(dpy, keycode, 1); - /* if the shifted code is not defined, then we use the normal keysym and keep the shift mask */ + /* FIXME: eew, this looks gross. */ + if (*mod & (ShiftMask | LockMask)) + { + /* if the shifted code is not defined, then we use the normal + keysym and keep the shift mask */ if (shifted == NoSymbol) { *keysym = normal; } - /* But if the shifted code is defined, we use it and remove the shift mask */ - else + else if (*mod & ShiftMask) + { + *keysym = shifted; + *mod &= ~(ShiftMask | LockMask); + } + else if (normal >= XK_a + && normal <= XK_z + && *mod & LockMask) { *keysym = shifted; - *mod &= ~ShiftMask; + } + /* But if the shifted code is defined, we use it and remove the + shift mask */ + else + { + *keysym = normal; } } else { - *keysym = XKeycodeToKeysym(dpy, keycode, 0); + *keysym = normal; } - PRINT_DEBUG ("cooked keysym: %ld '%c' mask: %d\n", *keysym, *keysym, *mod); + PRINT_DEBUG ("cooked keysym: %ld '%c' mask: %d\n", + *keysym, (char)*keysym, *mod); } -static KeySym -read_key () +void +read_key (KeySym *keysym, unsigned int *modifiers) { - KeySym keysym; - int mod; XEvent ev; - XMaskEvent (dpy, KeyPressMask, &ev); - mod = ev.xkey.state; - cook_keycode (ev.xkey.keycode, &keysym, &mod); - - return keysym; + do + { + XMaskEvent (dpy, KeyPressMask, &ev); + *modifiers = ev.xkey.state; + cook_keycode (ev.xkey.keycode, keysym, modifiers); + } while (IsModifierKey (*keysym)); } /* pass in a pointer a string and how much room we have, and fill it @@ -63,6 +114,7 @@ get_input (screen_info *s, char *prompt, char *str, int len) { int cur_len; /* Current length of the string. */ KeySym ch; + unsigned int modifier; int revert; Window fwin; int prompt_width = XTextWidth (s->font, prompt, strlen (prompt)); @@ -73,38 +125,49 @@ get_input (screen_info *s, char *prompt, char *str, int len) XMapWindow (dpy, s->input_window); XMoveResizeWindow (dpy, s->input_window, - bar_x (s, width), bar_y (s), width, (FONT_HEIGHT (s->font) + BAR_PADDING * 2)); + bar_x (s, width), bar_y (s), width, + (FONT_HEIGHT (s->font) + BAR_Y_PADDING * 2)); XClearWindow (dpy, s->input_window); XRaiseWindow (dpy, s->input_window); /* draw the window prompt. */ - XDrawString (dpy, s->input_window, s->bold_gc, 5, - BAR_PADDING + s->font->max_bounds.ascent, prompt, strlen (prompt)); + XDrawString (dpy, s->input_window, s->bold_gc, BAR_X_PADDING, + BAR_Y_PADDING + s->font->max_bounds.ascent, prompt, + strlen (prompt)); XGetInputFocus (dpy, &fwin, &revert); XSetInputFocus (dpy, s->input_window, RevertToPointerRoot, CurrentTime); + /* XSync (dpy, False); */ cur_len = 0; - while ((ch = read_key ()) != XK_Return) + + read_key (&ch, &modifier); + while (ch != XK_Return) { - PRINT_DEBUG ("key %d\n", ch); + PRINT_DEBUG ("key %ld\n", ch); if (ch == XK_BackSpace) { if (cur_len > 0) cur_len--; XClearWindow (dpy, s->input_window); - XDrawString (dpy, s->input_window, s->bold_gc, 5, - BAR_PADDING + s->font->max_bounds.ascent, prompt, strlen (prompt)); - XDrawString (dpy, s->input_window, s->bold_gc, 5 + prompt_width, - BAR_PADDING + s->font->max_bounds.ascent, str, cur_len); + XDrawString (dpy, s->input_window, s->bold_gc, BAR_X_PADDING, + BAR_Y_PADDING + s->font->max_bounds.ascent, prompt, + strlen (prompt)); + XDrawString (dpy, s->input_window, s->bold_gc, + BAR_X_PADDING + prompt_width, + BAR_Y_PADDING + s->font->max_bounds.ascent, str, + cur_len); } - else if (!IsModifierKey (ch)) + else { str[cur_len] = ch; if (cur_len < len - 1) cur_len++; - XDrawString (dpy, s->input_window, s->bold_gc, 5 + prompt_width, - BAR_PADDING + s->font->max_bounds.ascent, str, cur_len); + XDrawString (dpy, s->input_window, s->bold_gc, + BAR_X_PADDING + prompt_width, + BAR_Y_PADDING + s->font->max_bounds.ascent, str, cur_len); } + + read_key (&ch, &modifier); } str[cur_len] = 0; |