示例#1
0
文件: nilwm.c 项目: nqv/nilwm
/** Get KeySymbol from a KeyCode according to its state
 */
xcb_keysym_t get_keysym(xcb_keycode_t keycode, uint16_t state) {
    xcb_keysym_t k0, k1;

    /* Mode_Switch is ON */
    if (state & nil_.mask_modeswitch) {
        k0 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 2);
        k1 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 3);
    } else {
        k0 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 0);
        k1 = xcb_key_symbols_get_keysym(nil_.key_syms, keycode, 1);
    }
    if (k1 == XCB_NO_SYMBOL) {
        k1 = k0;
    }
    /* NUM on and is from keypad */
    if ((state & nil_.mask_numlock) && xcb_is_keypad_key(k1)) {
        if ((state & XCB_MOD_MASK_SHIFT)
            || ((state & XCB_MOD_MASK_LOCK) && (state & nil_.mask_shiftlock))) {
            return k0;
        } else {
            return k1;
        }
    }
    if (!(state & XCB_MOD_MASK_SHIFT)) {
        if (!(state & XCB_MOD_MASK_LOCK)) {         /* SHIFT off, CAPS off */
            return k0;
        } else if (state & nil_.mask_capslock) {    /* SHIFT off, CAPS on */
            return k1;
        }
    } else {
        return k1;
    }
    NIL_ERR("no symbol: state=0x%x keycode=0x%x", state, keycode);
    return XCB_NO_SYMBOL;
}
示例#2
0
xcb_keysym_t keyboard::get_keysym( xcb_keycode_t code, uint16_t state )
{
	xcb_keysym_t k0, k1;

	if ( state & _modeswitch )
	{
		k0 = xcb_key_symbols_get_keysym( _keysyms, code, 2 );
		k1 = xcb_key_symbols_get_keysym( _keysyms, code, 3 );
	}
	else
	{
		k0 = xcb_key_symbols_get_keysym( _keysyms, code, 0 );
		k1 = xcb_key_symbols_get_keysym( _keysyms, code, 1 );
	}

	if ( k1 == XCB_NO_SYMBOL )
		k1 = k0;

	if ( ( state & _numlock ) && xcb_is_keypad_key( k1 ) )
	{
		if( ( state & XCB_MOD_MASK_SHIFT ) || (state & XCB_MOD_MASK_LOCK && ( state & _shiftlock ) ) )
			return k0;
		else
			return k1;
	}
	else if ( ! ( state & XCB_MOD_MASK_SHIFT ) && ! ( state & XCB_MOD_MASK_LOCK ) )
		return k0;
	else if ( ! ( state & XCB_MOD_MASK_SHIFT ) && ( state & XCB_MOD_MASK_LOCK && ( state & _capslock ) ) )
		return k1;
	else if ( ( state & XCB_MOD_MASK_SHIFT ) && ( state & XCB_MOD_MASK_LOCK && ( state & _capslock ) ) )
		return k1;
	else if ( ( state & XCB_MOD_MASK_SHIFT ) || ( state & XCB_MOD_MASK_LOCK && ( state & _shiftlock ) ) )
		return k1;

	return XCB_NO_SYMBOL;
}
示例#3
0
/** Return the keysym from keycode.
 * \param detail The keycode received.
 * \param state The modifier state.
 * \return A keysym.
 */
xcb_keysym_t
keyresolv_get_keysym(xcb_keycode_t detail, uint16_t state)
{
    xcb_keysym_t k0, k1;

    /* 'col' (third parameter) is used to get the proper KeySym
     * according to modifier (XCB doesn't provide an equivalent to
     * XLookupString()).
     *
     * If Mode_Switch is ON we look into second group.
     */
    if(state & globalconf.modeswitchmask)
    {
        k0 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 4);
        k1 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 5);
    }
    else
    {
        k0 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 0);
        k1 = xcb_key_symbols_get_keysym(globalconf.keysyms, detail, 1);
    }

    /* If the second column does not exists use the first one. */
    if(k1 == XCB_NO_SYMBOL)
        k1 = k0;

    /* The numlock modifier is on and the second KeySym is a keypad
     * KeySym */
    if((state & globalconf.numlockmask) && xcb_is_keypad_key(k1))
    {
        /* The Shift modifier is on, or if the Lock modifier is on and
         * is interpreted as ShiftLock, use the first KeySym */
        if((state & XCB_MOD_MASK_SHIFT)
           || (state & XCB_MOD_MASK_LOCK && (state & globalconf.shiftlockmask)))
            return k0;
        else
            return k1;
    }

    /* The Shift and Lock modifers are both off, use the first
     * KeySym */
    else if(!(state & XCB_MOD_MASK_SHIFT) && !(state & XCB_MOD_MASK_LOCK))
        return k0;

    /* The Shift modifier is off and the Lock modifier is on and is
     * interpreted as CapsLock */
    else if(!(state & XCB_MOD_MASK_SHIFT)
            && (state & XCB_MOD_MASK_LOCK && (state & globalconf.capslockmask)))
        /* The first Keysym is used but if that KeySym is lowercase
         * alphabetic, then the corresponding uppercase KeySym is used
         * instead */
        return k1;

    /* The Shift modifier is on, and the Lock modifier is on and is
     * interpreted as CapsLock */
    else if((state & XCB_MOD_MASK_SHIFT)
            && (state & XCB_MOD_MASK_LOCK && (state & globalconf.capslockmask)))
        /* The second Keysym is used but if that KeySym is lowercase
         * alphabetic, then the corresponding uppercase KeySym is used
         * instead */
        return k1;

    /* The Shift modifier is on, or the Lock modifier is on and is
     * interpreted as ShiftLock, or both */
    else if((state & XCB_MOD_MASK_SHIFT)
            || (state & XCB_MOD_MASK_LOCK && (state & globalconf.shiftlockmask)))
        return k1;

    return XCB_NO_SYMBOL;
}
示例#4
0
文件: i3lock.c 项目: seirl/i3lock
/*
 * Handle key presses. Fixes state, then looks up the key symbol for the
 * given keycode, then looks up the key symbol (as UCS-2), converts it to
 * UTF-8 and stores it in the password array.
 *
 */
static void handle_key_press(xcb_key_press_event_t *event) {
    xkb_keysym_t ksym;
    char buffer[128];
    int n;
    bool ctrl;
    bool composed = false;

    ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
    ctrl = xkb_state_mod_name_is_active(xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED);

    /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
    memset(buffer, '\0', sizeof(buffer));

    if (xkb_compose_state && xkb_compose_state_feed(xkb_compose_state, ksym) == XKB_COMPOSE_FEED_ACCEPTED) {
        switch (xkb_compose_state_get_status(xkb_compose_state)) {
        case XKB_COMPOSE_NOTHING:
            break;
        case XKB_COMPOSE_COMPOSING:
            return;
        case XKB_COMPOSE_COMPOSED:
            /* xkb_compose_state_get_utf8 doesn't include the terminating byte in the return value
            * as xkb_keysym_to_utf8 does. Adding one makes the variable n consistent. */
            n = xkb_compose_state_get_utf8(xkb_compose_state, buffer, sizeof(buffer)) + 1;
            ksym = xkb_compose_state_get_one_sym(xkb_compose_state);
            composed = true;
            break;
        case XKB_COMPOSE_CANCELLED:
            xkb_compose_state_reset(xkb_compose_state);
            return;
        }
    }

    if (!composed) {
        n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));
    }

    switch (ksym) {
    case XKB_KEY_Return:
    case XKB_KEY_KP_Enter:
    case XKB_KEY_XF86ScreenSaver:
        if (pam_state == STATE_PAM_WRONG)
            return;

        if (skip_without_validation()) {
            clear_input();
            return;
        }
        password[input_position] = '\0';
        unlock_state = STATE_KEY_PRESSED;
        redraw_screen();
        input_done();
        skip_repeated_empty_password = true;
        return;
    default:
        skip_repeated_empty_password = false;
    }

    switch (ksym) {
    case XKB_KEY_u:
        if (ctrl) {
            DEBUG("C-u pressed\n");
            clear_input();
            return;
        }
        break;

    case XKB_KEY_Escape:
        clear_input();
        return;

    case XKB_KEY_BackSpace:
        if (input_position == 0)
            return;

        /* decrement input_position to point to the previous glyph */
        u8_dec(password, &input_position);
        password[input_position] = '\0';

        /* Hide the unlock indicator after a bit if the password buffer is
        * empty. */
        START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
        unlock_state = STATE_BACKSPACE_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;
        return;
    }

    if ((input_position + 8) >= sizeof(password))
        return;

#if 0
    /* FIXME: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
#endif

    if (n < 2)
        return;

    /* store it in the password array as UTF-8 */
    memcpy(password + input_position, buffer, n - 1);
    input_position += n - 1;
    DEBUG("current password = %.*s\n", input_position, password);

    if (unlock_indicator) {
        unlock_state = STATE_KEY_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;

        struct ev_timer *timeout = NULL;
        START_TIMER(timeout, TSTAMP_N_SECS(0.25), redraw_timeout);
        STOP_TIMER(clear_indicator_timeout);
    }

    START_TIMER(discard_passwd_timeout, TSTAMP_N_MINS(3), discard_passwd_cb);
}
示例#5
0
/*
 * Handle key presses. Fixes state, then looks up the key symbol for the
 * given keycode, then looks up the key symbol (as UCS-2), converts it to
 * UTF-8 and stores it in the password array.
 *
 */
static void handle_key_press(xcb_key_press_event_t *event) {
    xkb_keysym_t ksym;
    char buffer[128];
    int n;
    bool ctrl;

    ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
    ctrl = xkb_state_mod_name_is_active(xkb_state, "Control", XKB_STATE_MODS_DEPRESSED);
    xkb_state_update_key(xkb_state, event->detail, XKB_KEY_DOWN);

    /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
    memset(buffer, '\0', sizeof(buffer));
    n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));

    switch (ksym) {
    case XKB_KEY_Return:
    case XKB_KEY_KP_Enter:
    case XKB_KEY_XF86ScreenSaver:
        password[input_position] = '\0';
        unlock_state = STATE_KEY_PRESSED;
        redraw_screen();
        input_done();
        return;

    case XKB_KEY_u:
        if (ctrl) {
            DEBUG("C-u pressed\n");
            clear_input();
            return;
        }
        break;

    case XKB_KEY_Escape:
        clear_input();
        return;

    case XKB_KEY_BackSpace:
        if (input_position == 0)
            return;

        /* decrement input_position to point to the previous glyph */
        u8_dec(password, &input_position);
        password[input_position] = '\0';

        /* Hide the unlock indicator after a bit if the password buffer is
         * empty. */
        start_clear_indicator_timeout();
        unlock_state = STATE_BACKSPACE_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;
        return;
    }

    if ((input_position + 8) >= sizeof(password))
        return;

#if 0
    /* FIXME: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
#endif

    if (n < 2)
        return;

    /* store it in the password array as UTF-8 */
    memcpy(password+input_position, buffer, n-1);
    input_position += n-1;
    DEBUG("current password = %.*s\n", input_position, password);

    unlock_state = STATE_KEY_ACTIVE;
    redraw_screen();
    unlock_state = STATE_KEY_PRESSED;

    struct ev_timer *timeout = calloc(sizeof(struct ev_timer), 1);
    if (timeout) {
        ev_timer_init(timeout, redraw_timeout, 0.25, 0.);
        ev_timer_start(main_loop, timeout);
    }

    stop_clear_indicator_timeout();
}
示例#6
0
文件: i3lock.c 项目: Kamori/i3lock
/*
 * Handle key presses. Fixes state, then looks up the key symbol for the
 * given keycode, then looks up the key symbol (as UCS-2), converts it to
 * UTF-8 and stores it in the password array.
 *
 */
static void handle_key_press(xcb_key_press_event_t *event) {
    xkb_keysym_t ksym;
    char buffer[128];
    int n;
    bool ctrl;

    ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
    ctrl = xkb_state_mod_name_is_active(xkb_state, "Control", XKB_STATE_MODS_DEPRESSED);

    /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
    memset(buffer, '\0', sizeof(buffer));
    n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));

    switch (ksym) {
    case XKB_KEY_Return:
    case XKB_KEY_KP_Enter:
    case XKB_KEY_XF86ScreenSaver:
        if (skip_without_validation()) {
            clear_input();
            return;
        }
        password[input_position] = '\0';
        unlock_state = STATE_KEY_PRESSED;
        redraw_screen();
        input_done();
        skip_repeated_empty_password = true;
        return;
    default:
        skip_repeated_empty_password = false;
    }

    switch (ksym) {
    case XKB_KEY_u:
        if (ctrl) {
            DEBUG("C-u pressed\n");
            clear_input();
            return;
        }
        break;

    case XKB_KEY_Escape:
        clear_input();
        return;

    case XKB_KEY_BackSpace:
        if (input_position == 0)
            return;

        /* decrement input_position to point to the previous glyph */
        u8_dec(password, &input_position);
        password[input_position] = '\0';

        /* Hide the unlock indicator after a bit if the password buffer is
         * empty. */
        START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
        unlock_state = STATE_BACKSPACE_ACTIVE;
        redraw_screen();
        unlock_state = STATE_KEY_PRESSED;
        return;
    }

    if ((input_position + 8) >= sizeof(password))
        return;

#if 0
    /* FIXME: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
#endif

    if (n < 2)
        return;

    /* store it in the password array as UTF-8 */
    memcpy(password+input_position, buffer, n-1);
    input_position += n-1;
    DEBUG("current password = %.*s\n", input_position, password);

    unlock_state = STATE_KEY_ACTIVE;
    redraw_screen();
    unlock_state = STATE_KEY_PRESSED;

    struct ev_timer *timeout = NULL;
    START_TIMER(timeout, TSTAMP_N_SECS(0.25), redraw_timeout);
    STOP_TIMER(clear_indicator_timeout);
    START_TIMER(discard_passwd_timeout, TSTAMP_N_MINS(3), discard_passwd_cb);
}
示例#7
0
/*
 * Handles keypresses by converting the keycodes to keysymbols, then the
 * keysymbols to UCS-2. If the conversion succeeded, the glyph is saved in the
 * internal buffers and displayed in the input window.
 *
 * Also handles backspace (deleting one character) and return (sending the
 * command to i3).
 *
 */
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
    printf("Keypress %d, state raw = %d\n", event->detail, event->state);

    // TODO: port the input handling code from i3lock once libxkbcommon ≥ 0.5.0
    // is available in distros.

    /* See the documentation of xcb_key_symbols_get_keysym for this one.
     * Basically: We get either col 0 or col 1, depending on whether shift is
     * pressed. */
    int col = (event->state & XCB_MOD_MASK_SHIFT);

    /* If modeswitch is currently active, we need to look in group 2 or 3,
     * respectively. */
    if (modeswitch_active)
        col += 2;

    xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, col);
    if (sym == XK_Mode_switch) {
        printf("Mode switch enabled\n");
        modeswitch_active = true;
        return 1;
    }

    if (sym == XK_Return)
        finish_input();

    if (sym == XK_BackSpace) {
        if (input_position == 0)
            return 1;

        input_position--;
        free(glyphs_utf8[input_position]);

        handle_expose(NULL, conn, NULL);
        return 1;
    }
    if (sym == XK_Escape) {
        exit(0);
    }

    /* TODO: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));

    if (xcb_is_modifier_key(sym) || xcb_is_cursor_key(sym))
        return 1;

    printf("sym = %c (%d)\n", sym, sym);

    /* convert the keysym to UCS */
    uint16_t ucs = keysym2ucs(sym);
    if ((int16_t)ucs == -1) {
        fprintf(stderr, "Keysym could not be converted to UCS, skipping\n");
        return 1;
    }

    xcb_char2b_t inp;
    inp.byte1 = (ucs & 0xff00) >> 2;
    inp.byte2 = (ucs & 0x00ff) >> 0;

    printf("inp.byte1 = %02x, inp.byte2 = %02x\n", inp.byte1, inp.byte2);
    /* convert it to UTF-8 */
    char *out = convert_ucs2_to_utf8(&inp, 1);
    printf("converted to %s\n", out);

    glyphs_ucs[input_position] = inp;
    glyphs_utf8[input_position] = out;
    input_position++;

    if (input_position == limit)
        finish_input();

    handle_expose(NULL, conn, NULL);
    return 1;
}