113 lines
4.1 KiB
C
113 lines
4.1 KiB
C
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
#include <string.h>
|
|
#include <wayland-server-core.h>
|
|
#include <wlr/types/wlr_keyboard.h>
|
|
#include <wlr/types/wlr_seat.h>
|
|
#include <wlr/util/log.h>
|
|
#include <wlr/backend/session.h>
|
|
#include <xkbcommon/xkbcommon.h>
|
|
#include "../../screen.h"
|
|
|
|
/* Forward declarations */
|
|
int wWaylandKeyPress(unsigned int keycode, unsigned int modifiers);
|
|
#include "wl_types.h"
|
|
#include <WINGs/WINGsP.h>
|
|
|
|
/* Forward declarations */
|
|
WMScreen *wl_get_wmscreen(void);
|
|
void W_WL_EnqueueEvent(struct W_Screen *scr, const WMEvent *ev, struct W_View *target);
|
|
|
|
|
|
void
|
|
handle_keyboard_key(struct wl_listener *listener, void *data)
|
|
{
|
|
struct wlr_keyboard_key_event *event = data;
|
|
(void)listener;
|
|
|
|
if (!wl_state.seat)
|
|
return;
|
|
|
|
struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard;
|
|
if (!kb) {
|
|
wwarning("handle_keyboard_key: no seat keyboard for event keycode=%u dev=%p", event->keycode, (void*)wl_state.keyboard_dev);
|
|
return;
|
|
}
|
|
|
|
wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers);
|
|
|
|
uint32_t keycode = event->keycode + 8;
|
|
uint32_t modifiers = wlr_keyboard_get_modifiers(kb);
|
|
|
|
if (wl_state.session && event->state == WL_KEYBOARD_KEY_STATE_PRESSED &&
|
|
(modifiers & (WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT)) ==
|
|
(WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT)) {
|
|
xkb_keysym_t sym = xkb_state_key_get_one_sym(kb->xkb_state, keycode);
|
|
if (sym >= XKB_KEY_XF86Switch_VT_1 && sym <= XKB_KEY_XF86Switch_VT_12) {
|
|
wlr_session_change_vt(wl_state.session, sym - XKB_KEY_XF86Switch_VT_1 + 1);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
|
if (!wl_state.keyboard_grabbed && wWaylandKeyPress((unsigned int)keycode, (unsigned int)modifiers))
|
|
return;
|
|
}
|
|
|
|
WMScreen *wmscr = wl_get_wmscreen();
|
|
if (wmscr) {
|
|
WMEvent ev;
|
|
memset(&ev, 0, sizeof(ev));
|
|
ev.type = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
|
? WME_KEY_PRESS : WME_KEY_RELEASE;
|
|
|
|
W_FocusInfo *finfo = wmscr->focusInfo;
|
|
W_View *target = (finfo && finfo->focused) ? finfo->focused
|
|
: (finfo && finfo->toplevel) ? finfo->toplevel : NULL;
|
|
if (!target && wmscr->modalView)
|
|
target = wmscr->modalView;
|
|
ev.window = target ? (WNativeWindow)target->window : WNATIVE_NONE;
|
|
|
|
ev.u.key.keycode = keycode;
|
|
ev.u.key.state = modifiers;
|
|
ev.u.key.time = event->time_msec;
|
|
ev.u.key.x = wl_state.pointer_x;
|
|
ev.u.key.y = wl_state.pointer_y;
|
|
ev.u.key.x_root = wl_state.pointer_x;
|
|
ev.u.key.y_root = wl_state.pointer_y;
|
|
|
|
if (kb->xkb_state) {
|
|
ev.u.key.keysym = xkb_state_key_get_one_sym(kb->xkb_state, keycode);
|
|
ev.u.key.utf8_len = xkb_state_key_get_utf8(kb->xkb_state, keycode,
|
|
ev.u.key.utf8, sizeof(ev.u.key.utf8));
|
|
if (ev.u.key.utf8_len >= (int)sizeof(ev.u.key.utf8))
|
|
ev.u.key.utf8_len = 0;
|
|
} else {
|
|
wwarning("handle_keyboard_key: kb->xkb_state is NULL, dropping key event (keycode=%u dev=%p seat_kb=%p)",
|
|
keycode, (void*)wl_state.keyboard_dev, (void*)kb);
|
|
return;
|
|
}
|
|
|
|
W_WL_EnqueueEvent(wmscr, &ev, NULL);
|
|
}
|
|
|
|
if (!wl_state.keyboard_grabbed && wl_state.seat->keyboard_state.focused_surface)
|
|
wlr_seat_keyboard_notify_key(wl_state.seat,
|
|
event->time_msec, event->keycode, event->state);
|
|
}
|
|
|
|
void
|
|
handle_keyboard_modifiers(struct wl_listener *listener, void *data)
|
|
{
|
|
(void)listener; (void)data;
|
|
if (!wl_state.seat) return;
|
|
struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard;
|
|
if (!kb) return;
|
|
wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers);
|
|
/* Cache the real keyboard's depressed modifiers so pointer button
|
|
* handlers can read them regardless of which keyboard the seat
|
|
* currently has focused (e.g. XWayland virtual keyboard). */
|
|
wl_state.current_mods = kb->modifiers.depressed;
|
|
}
|