aboutsummaryrefslogtreecommitdiff
path: root/backend/x11/backend.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/x11/backend.c')
-rw-r--r--backend/x11/backend.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index 36d72d9e..8abc5d84 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -7,6 +7,7 @@
#include <wayland-server.h>
#include <wlr/backend/interface.h>
#include <wlr/backend/x11.h>
+#include <wlr/config.h>
#include <wlr/interfaces/wlr_input_device.h>
#include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/interfaces/wlr_output.h>
@@ -21,6 +22,9 @@
#elif __FreeBSD__
#include <dev/evdev/input-event-codes.h>
#endif
+#ifdef WLR_HAS_XCB_XKB
+#include <xcb/xkb.h>
+#endif
#include "backend/x11.h"
#include "util/signal.h"
@@ -108,10 +112,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e
struct wlr_event_pointer_motion_absolute abs = {
.device = &x11->pointer_dev,
.time_msec = ev->time,
- .x_mm = ev->event_x,
- .y_mm = ev->event_y,
- .width_mm = output->wlr_output.width,
- .height_mm = output->wlr_output.height,
+ .x = (double)ev->event_x / output->wlr_output.width,
+ .y = (double)ev->event_y / output->wlr_output.height,
};
wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs);
@@ -136,10 +138,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e
struct wlr_event_pointer_motion_absolute abs = {
.device = &x11->pointer_dev,
.time_msec = x11->time,
- .x_mm = pointer->root_x,
- .y_mm = pointer->root_y,
- .width_mm = output->wlr_output.width,
- .height_mm = output->wlr_output.height,
+ .x = (double)pointer->root_x / output->wlr_output.width,
+ .y = (double)pointer->root_y / output->wlr_output.height,
};
wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs);
@@ -157,6 +157,14 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e
break;
}
default:
+#ifdef WLR_HAS_XCB_XKB
+ if (x11->xkb_supported && event->response_type == x11->xkb_base_event) {
+ xcb_xkb_state_notify_event_t *ev =
+ (xcb_xkb_state_notify_event_t *)event;
+ wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods,
+ ev->latchedMods, ev->lockedMods, ev->lockedGroup);
+ }
+#endif
break;
}
@@ -282,6 +290,32 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) {
strlen(title), title);
}
+#ifdef WLR_HAS_XCB_XKB
+ const xcb_query_extension_reply_t *reply =
+ xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id);
+ if (reply != NULL && reply->present) {
+ x11->xkb_base_event = reply->first_event;
+ x11->xkb_base_error = reply->first_error;
+
+ xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension(
+ x11->xcb_conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
+ xcb_xkb_use_extension_reply_t *reply =
+ xcb_xkb_use_extension_reply(x11->xcb_conn, cookie, NULL);
+ if (reply != NULL && reply->supported) {
+ x11->xkb_supported = true;
+
+ xcb_xkb_select_events(x11->xcb_conn,
+ XCB_XKB_ID_USE_CORE_KBD,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
+ 0,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
+ 0,
+ 0,
+ 0);
+ }
+ }
+#endif
+
xcb_map_window(x11->xcb_conn, output->win);
xcb_flush(x11->xcb_conn);
wlr_output_update_enabled(&output->wlr_output, true);