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 int num_screens;
extern uint8_t root_depth;
extern bool xkb_supported;
extern xcb_atom_t atoms[NUM_ATOMS];
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;
LOG("(removed upper 8 bits, state = %d)\n", state_filtered);
/* 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
provide them reliably (it works in Xephyr, it does not in real X) */
XkbStateRec state;
if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success && (state.group+1) == 2)
state_filtered |= BIND_MODE_SWITCH;
if (xkb_supported) {
/* 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
provide them reliably (it works in Xephyr, it does not in real X) */
XkbStateRec state;
if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success && (state.group+1) == 2)
state_filtered |= BIND_MODE_SWITCH;
}
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) */
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.
* See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop
@ -245,25 +248,27 @@ int main(int argc, char *argv[], char *env[]) {
int evBase, errBase;
if ((xkbdpy = XkbOpenDisplay(getenv("DISPLAY"), &evBase, &errBase, &major, &minor, &error)) == NULL) {
fprintf(stderr, "XkbOpenDisplay() failed\n");
return 1;
LOG("ERROR: XkbOpenDisplay() failed, disabling XKB support\n");
xkb_supported = false;
}
if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) {
fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
return 1;
}
if (xkb_supported) {
if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) {
fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
return 1;
}
int i1;
if (!XkbQueryExtension(xkbdpy,&i1,&evBase,&errBase,&major,&minor)) {
fprintf(stderr, "XKB not supported by X-server\n");
return 1;
}
/* end of ugliness */
int i1;
if (!XkbQueryExtension(xkbdpy,&i1,&evBase,&errBase,&major,&minor)) {
fprintf(stderr, "XKB not supported by X-server\n");
return 1;
}
/* end of ugliness */
if (!XkbSelectEvents(xkbdpy, XkbUseCoreKbd, XkbMapNotifyMask, XkbMapNotifyMask)) {
fprintf(stderr, "Could not set XKB event mask\n");
return 1;
if (!XkbSelectEvents(xkbdpy, XkbUseCoreKbd, XkbMapNotifyMask, XkbMapNotifyMask)) {
fprintf(stderr, "Could not set XKB event mask\n");
return 1;
}
}
/* Initialize event loop using libev */
@ -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_start(loop, xcb_watcher);
ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ);
ev_io_start(loop, xkb);
if (xkb_supported) {
ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ);
ev_io_start(loop, xkb);
/* Flush the buffer so that libev can properly get new events */
XFlush(xkbdpy);
/* Flush the buffer so that libev can properly get new events */
XFlush(xkbdpy);
}
ev_check_init(xcb_check, xcb_check_cb);
ev_check_start(loop, xcb_check);