Skip to content

Commit

Permalink
WIP: xinput support
Browse files Browse the repository at this point in the history
related to #112
  • Loading branch information
stapelberg committed Feb 23, 2020
1 parent f3b0612 commit 482f5b0
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 3 deletions.
4 changes: 3 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ i3lock_SOURCES = \
unlock_indicator.c \
unlock_indicator.h \
xcb.c \
xcb.h
xcb.h \
xinput.h \
xinput.c

EXTRA_DIST = \
$(pamd_files) \
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ AC_SEARCH_LIBS([iconv_open], [iconv], , [AC_MSG_FAILURE([cannot find the require

dnl Each prefix corresponds to a source tarball which users might have
dnl downloaded in a newer version and would like to overwrite.
PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr])
PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-xinput])
PKG_CHECK_MODULES([XCB_IMAGE], [xcb-image])
PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util xcb-atom])
PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm])
Expand Down
4 changes: 4 additions & 0 deletions i3lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "unlock_indicator.h"
#include "randr.h"
#include "dpi.h"
#include "xinput.h"

#define TSTAMP_N_SECS(n) (n * 1.0)
#define TSTAMP_N_MINS(n) (60 * TSTAMP_N_SECS(n))
Expand Down Expand Up @@ -1196,6 +1197,8 @@ int main(int argc, char *argv[]) {
randr_init(&randr_base, screen->root);
randr_query(screen->root);

xinput_init();

last_resolution[0] = screen->width_in_pixels;
last_resolution[1] = screen->height_in_pixels;

Expand Down Expand Up @@ -1310,6 +1313,7 @@ int main(int argc, char *argv[]) {
DEBUG("restoring focus to X11 window 0x%08x\n", stolen_focus);
xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
xcb_ungrab_keyboard(conn, XCB_CURRENT_TIME);
xinput_ungrab();
xcb_destroy_window(conn, win);
set_focused_window(conn, screen->root, stolen_focus);
xcb_aux_sync(conn);
Expand Down
7 changes: 6 additions & 1 deletion xcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "cursors.h"
#include "unlock_indicator.h"
#include "xinput.h"

extern auth_state_t auth_state;

Expand Down Expand Up @@ -303,7 +304,11 @@ bool grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb
}
}

return (tries > 0);
if (tries == 0) {
return false;
}

return xinput_grab(screen->root);
}

xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice) {
Expand Down
139 changes: 139 additions & 0 deletions xinput.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* vim:ts=4:sw=4:expandtab
*
* © 2010 Michael Stapelberg
*
* See LICENSE for licensing information
*
*/
#include "xinput.h"

#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xinput.h>

#include "i3lock.h"
#include "xcb.h"

extern bool debug_mode;

static bool xinput_available = false;

void xinput_init(void) {
const xcb_query_extension_reply_t *extreply;

extreply = xcb_get_extension_data(conn, &xcb_input_id);
if (!extreply->present) {
DEBUG("xinput is not present\n");
return;
}

DEBUG("xinput: querying version\n");
xcb_generic_error_t *err = NULL;
xcb_input_xi_query_version_reply_t *xinput_version =
xcb_input_xi_query_version_reply(
conn, xcb_input_xi_query_version(conn, XCB_INPUT_MAJOR_VERSION, XCB_INPUT_MINOR_VERSION), &err);
if (err != NULL) {
DEBUG("Could not query xinput version: X11 error code %d\n", err->error_code);
return;
}
DEBUG("xinput %d.%d found\n",
xinput_version->major_version,
xinput_version->minor_version);
free(xinput_version);

xinput_available = true;
}

bool xinput_grab(xcb_window_t root_window) {
if (!xinput_available) {
return true;
}

xcb_generic_error_t *err = NULL;
xcb_input_xi_query_device_reply_t *devices =
xcb_input_xi_query_device_reply(
conn, xcb_input_xi_query_device(conn, XCB_INPUT_DEVICE_ALL_MASTER), &err);
if (err != NULL) {
DEBUG("xinput: querying devices: X11 error code %d\n", err->error_code);
return false;
}

xcb_input_xi_device_info_iterator_t device_iter;
for (device_iter = xcb_input_xi_query_device_infos_iterator(devices);
device_iter.rem;
xcb_input_xi_device_info_next(&device_iter)) {
xcb_input_xi_device_info_t *device_info = device_iter.data;
DEBUG("device %s\n",
xcb_input_xi_device_info_name(device_info));
// TODO: skip virtual core pointer/keyboard

const uint32_t mask =
XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS |
XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE |
XCB_INPUT_XI_EVENT_MASK_MOTION |
XCB_INPUT_XI_EVENT_MASK_ENTER |
XCB_INPUT_XI_EVENT_MASK_LEAVE;

xcb_input_xi_grab_device_reply_t *reply =
xcb_input_xi_grab_device_reply(
conn,
xcb_input_xi_grab_device(conn,
root_window,
XCB_TIME_CURRENT_TIME,
XCB_CURSOR_NONE,
device_info->deviceid,
XCB_INPUT_GRAB_MODE_22_ASYNC,
XCB_INPUT_GRAB_MODE_22_ASYNC,
true /* owner_events */,
1,
&mask),
&err);
if (err != NULL) {
DEBUG("xinput: grabbing device %s: X11 error code %d\n",
xcb_input_xi_device_info_name(device_info),
err->error_code);
free(devices);
return false;
}
if (reply->status != 0 /* XiGrabSuccess */) {
free(reply);
free(devices);
return false;
}
free(reply);
}

free(devices);
return true;
}

void xinput_ungrab(void) {
if (!xinput_available) {
return;
}

xcb_generic_error_t *err = NULL;
xcb_input_xi_query_device_reply_t *devices =
xcb_input_xi_query_device_reply(
conn, xcb_input_xi_query_device(conn, XCB_INPUT_DEVICE_ALL_MASTER), &err);
if (err != NULL) {
DEBUG("xinput: querying devices: X11 error code %d\n", err->error_code);
return;
}

xcb_input_xi_device_info_iterator_t device_iter;
for (device_iter = xcb_input_xi_query_device_infos_iterator(devices);
device_iter.rem;
xcb_input_xi_device_info_next(&device_iter)) {
xcb_input_xi_device_info_t *device_info = device_iter.data;
// TODO: skip virtual core pointer/keyboard

xcb_input_xi_ungrab_device(conn, XCB_TIME_CURRENT_TIME, device_info->deviceid);
}

free(devices);
}
11 changes: 11 additions & 0 deletions xinput.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _XINPUT_H
#define _XINPUT_H

#include <stdbool.h>
#include <xcb.h>

void xinput_init(void);
bool xinput_grab(xcb_window_t root_window);
void xinput_ungrab(void);

#endif

0 comments on commit 482f5b0

Please sign in to comment.