Disable XKB instead of quitting with an error (Thanks sur5r)

This is necessary for running i3 in Xvnc for example.
This commit is contained in:
Michael Stapelberg 2009-11-13 00:30:42 +01:00
parent 4b1bb7d19a
commit c0c4dd2978
3 changed files with 35 additions and 25 deletions

View File

@ -34,6 +34,7 @@ extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
extern xcb_event_handlers_t evenths; extern xcb_event_handlers_t evenths;
extern int num_screens; extern int num_screens;
extern uint8_t root_depth; extern uint8_t root_depth;
extern bool xkb_supported;
extern xcb_atom_t atoms[NUM_ATOMS]; extern xcb_atom_t atoms[NUM_ATOMS];
extern xcb_window_t root; extern xcb_window_t root;

View File

@ -105,12 +105,14 @@ int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_
state_filtered &= 0xFF; state_filtered &= 0xFF;
LOG("(removed upper 8 bits, state = %d)\n", state_filtered); LOG("(removed upper 8 bits, state = %d)\n", state_filtered);
if (xkb_supported) {
/* We need to get the keysym group (There are group 1 to group 4, each holding /* We need to get the keysym group (There are group 1 to group 4, each holding
two keysyms (without shift and with shift) using Xkb because X fails to two keysyms (without shift and with shift) using Xkb because X fails to
provide them reliably (it works in Xephyr, it does not in real X) */ provide them reliably (it works in Xephyr, it does not in real X) */
XkbStateRec state; XkbStateRec state;
if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success && (state.group+1) == 2) if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success && (state.group+1) == 2)
state_filtered |= BIND_MODE_SWITCH; state_filtered |= BIND_MODE_SWITCH;
}
LOG("(checked mode_switch, state %d)\n", state_filtered); LOG("(checked mode_switch, state %d)\n", state_filtered);

View File

@ -83,6 +83,9 @@ int num_screens = 0;
/* The depth of the root screen (used e.g. for creating new pixmaps later) */ /* The depth of the root screen (used e.g. for creating new pixmaps later) */
uint8_t root_depth; uint8_t root_depth;
/* We hope that XKB is supported and set this to false */
bool xkb_supported = true;
/* /*
* This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb. * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb.
* See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop * See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop
@ -245,10 +248,11 @@ int main(int argc, char *argv[], char *env[]) {
int evBase, errBase; int evBase, errBase;
if ((xkbdpy = XkbOpenDisplay(getenv("DISPLAY"), &evBase, &errBase, &major, &minor, &error)) == NULL) { if ((xkbdpy = XkbOpenDisplay(getenv("DISPLAY"), &evBase, &errBase, &major, &minor, &error)) == NULL) {
fprintf(stderr, "XkbOpenDisplay() failed\n"); LOG("ERROR: XkbOpenDisplay() failed, disabling XKB support\n");
return 1; xkb_supported = false;
} }
if (xkb_supported) {
if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) { if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) {
fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n"); fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
return 1; return 1;
@ -265,6 +269,7 @@ int main(int argc, char *argv[], char *env[]) {
fprintf(stderr, "Could not set XKB event mask\n"); fprintf(stderr, "Could not set XKB event mask\n");
return 1; return 1;
} }
}
/* Initialize event loop using libev */ /* Initialize event loop using libev */
struct ev_loop *loop = ev_default_loop(0); struct ev_loop *loop = ev_default_loop(0);
@ -279,11 +284,13 @@ int main(int argc, char *argv[], char *env[]) {
ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ); ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
ev_io_start(loop, xcb_watcher); ev_io_start(loop, xcb_watcher);
if (xkb_supported) {
ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ); ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ);
ev_io_start(loop, xkb); ev_io_start(loop, xkb);
/* Flush the buffer so that libev can properly get new events */ /* Flush the buffer so that libev can properly get new events */
XFlush(xkbdpy); XFlush(xkbdpy);
}
ev_check_init(xcb_check, xcb_check_cb); ev_check_init(xcb_check, xcb_check_cb);
ev_check_start(loop, xcb_check); ev_check_start(loop, xcb_check);