++ libxklavier-4.0/debian/patches/92_handle_xi_errors.patch # # Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libxklavier/+bug/409621 # Description: FreeNX does not support DevicePresence and therefore XSelectExtensionEvent will # generate XI_BadClass errors when called with this event class. Trap these # errors and don't crash the users of libxklavier # diff -Nur -x '*.orig' -x '*~' libxklavier-4.0/libxklavier/xklavier_evt.c libxklavier-4.0.new/libxklavier/xklavier_evt.c --- libxklavier-4.0/libxklavier/xklavier_evt.c 2009-10-17 13:30:58.823386935 +0100 +++ libxklavier-4.0.new/libxklavier/xklavier_evt.c 2009-10-17 13:30:59.523390339 +0100 @@ -492,6 +492,22 @@ break; } default: + if (engine != NULL + && xkl_engine_priv(engine, process_x_error)) { + if (xkl_engine_priv(engine, process_x_error) + (engine, evt)) { + xkl_debug(200, + "X ERROR processed by the engine: %p, " + WINID_FORMAT ", %d [%s], " + "X11 request: %d, minor code: %d\n", + dpy, + (unsigned long) evt->resourceid, + (int) evt->error_code, buf, + (int) evt->request_code, + (int) evt->minor_code); + break; + } + } xkl_debug(200, "Unexpected by libxklavier X ERROR: %p, " WINID_FORMAT ", %d [%s], " diff -Nur -x '*.orig' -x '*~' libxklavier-4.0/libxklavier/xklavier_evt_xkb.c libxklavier-4.0.new/libxklavier/xklavier_evt_xkb.c --- libxklavier-4.0/libxklavier/xklavier_evt_xkb.c 2008-11-17 00:14:44.000000000 +0000 +++ libxklavier-4.0.new/libxklavier/xklavier_evt_xkb.c 2009-10-17 15:55:19.925893628 +0100 @@ -162,6 +162,22 @@ #endif } +/* + * XKB error handler + */ +gint +xkl_xkb_process_x_error(XklEngine * engine, XErrorEvent * xerev) +{ +#ifdef HAVE_XINPUT + /* Ignore XInput errors */ + if (xerev->error_code >= xkl_engine_backend(engine, XklXkb, xi_error_code) + && xerev->error_code <= (xkl_engine_backend(engine, XklXkb, xi_error_code) + XI_BadClass)) + return 1; +#endif + + return 0; +} + void xkl_xkb_set_indicators(XklEngine * engine, const XklState * window_state) { diff -Nur -x '*.orig' -x '*~' libxklavier-4.0/libxklavier/xklavier_private.h libxklavier-4.0.new/libxklavier/xklavier_private.h --- libxklavier-4.0/libxklavier/xklavier_private.h 2009-06-23 23:40:38.000000000 +0100 +++ libxklavier-4.0.new/libxklavier/xklavier_private.h 2009-10-17 13:30:59.523390339 +0100 @@ -157,6 +157,13 @@ gint(*process_x_event) (XklEngine * engine, XEvent * xev); /* + * Handles X errors. + * return 0 if further processing is needed + * 1 if error was handled + */ + gint(*process_x_error) (XklEngine * engine, XErrorEvent * xerev); + + /* * Flushes the cached server config info. * xkb: frees XkbDesc * xmodmap: frees internal XklConfigRec diff -Nur -x '*.orig' -x '*~' libxklavier-4.0/libxklavier/xklavier_private_xkb.h libxklavier-4.0.new/libxklavier/xklavier_private_xkb.h --- libxklavier-4.0/libxklavier/xklavier_private_xkb.h 2009-06-23 14:59:52.000000000 +0100 +++ libxklavier-4.0.new/libxklavier/xklavier_private_xkb.h 2009-10-17 13:30:59.523390339 +0100 @@ -48,6 +48,8 @@ #ifdef HAVE_XINPUT gint xi_event_type; + + gint xi_error_code; #endif } XklXkb; @@ -86,7 +88,9 @@ const XklConfigRec * data, const gboolean binary); -extern gint xkl_xkb_process_x_event(XklEngine * engine, XEvent * kev); +extern gint xkl_xkb_process_x_event(XklEngine * engine, XEvent * xev); + +extern gint xkl_xkb_process_x_error(XklEngine * engine, XErrorEvent * xerev); extern void xkl_xkb_free_all_info(XklEngine * engine); diff -Nur -x '*.orig' -x '*~' libxklavier-4.0/libxklavier/xklavier_xkb.c libxklavier-4.0.new/libxklavier/xklavier_xkb.c --- libxklavier-4.0/libxklavier/xklavier_xkb.c 2009-04-24 23:07:31.000000000 +0100 +++ libxklavier-4.0.new/libxklavier/xklavier_xkb.c 2009-10-17 13:30:59.523390339 +0100 @@ -353,8 +353,8 @@ ¤t_state_out->indicators)) current_state_out->indicators &= xkl_engine_backend(engine, XklXkb, - cached_desc)-> - indicators->phys_indicators; + cached_desc)->indicators-> + phys_indicators; else current_state_out->indicators = 0; } @@ -402,8 +402,8 @@ xkl_engine_backend (engine, XklXkb, device_id), - cached-> - names->indicators + cached->names-> + indicators [indicator_num], set, False, NULL); else { @@ -541,7 +541,7 @@ #ifdef LIBXKBFILE_PRESENT gint opcode; gboolean xkl_xkb_ext_present; - int xi_opc, xi_event_type, xi_error_code; + int xi_opc; xkl_engine_priv(engine, backend_id) = "XKB"; xkl_engine_priv(engine, features) = XKLF_CAN_TOGGLE_INDICATORS | @@ -564,6 +564,7 @@ xkl_engine_priv(engine, get_num_groups) = xkl_xkb_get_num_groups; xkl_engine_priv(engine, lock_group) = xkl_xkb_lock_group; xkl_engine_priv(engine, process_x_event) = xkl_xkb_process_x_event; + xkl_engine_priv(engine, process_x_error) = xkl_xkb_process_x_error; xkl_engine_priv(engine, free_all_info) = xkl_xkb_free_all_info; xkl_engine_priv(engine, if_cached_info_equals_actual) = xkl_xkb_if_cached_info_equals_actual; @@ -615,14 +616,24 @@ xkl_engine_priv(engine, features) |= XKLF_MULTIPLE_LAYOUTS_SUPPORTED; +#if HAVE_XINPUT if (XQueryExtension (display, "XInputExtension", &xi_opc, - &xi_event_type, &xi_error_code)) { + &xkl_engine_backend(engine, XklXkb, xi_event_type), + &xkl_engine_backend(engine, XklXkb, xi_error_code))) { xkl_debug(150, "XInputExtension found (%d, %d, %d)\n", - xi_opc, xi_event_type, xi_error_code); + xi_opc, + xkl_engine_backend(engine, XklXkb, + xi_event_type), + xkl_engine_backend(engine, XklXkb, + xi_error_code)); xkl_engine_priv(engine, features) |= XKLF_DEVICE_DISCOVERY; - } else + } else { xkl_debug(0, "XInputExtension not found\n"); + xkl_engine_backend(engine, XklXkb, xi_event_type) = -1; + xkl_engine_backend(engine, XklXkb, xi_error_code) = -1; + } +#endif return 0; #else xkl_debug(160, diff -Nur -x '*.orig' -x '*~' libxklavier-4.0/libxklavier/xklavier_xmm.c libxklavier-4.0.new/libxklavier/xklavier_xmm.c --- libxklavier-4.0/libxklavier/xklavier_xmm.c 2008-09-05 20:56:33.000000000 +0100 +++ libxklavier-4.0.new/libxklavier/xklavier_xmm.c 2009-10-17 13:30:59.523390339 +0100 @@ -327,6 +327,7 @@ xkl_engine_priv(engine, lock_group) = xkl_xmm_lock_group; xkl_engine_priv(engine, process_x_event) = xkl_xmm_process_x_event; + xkl_engine_priv(engine, process_x_error) = NULL; xkl_engine_priv(engine, free_all_info) = xkl_xmm_free_all_info; xkl_engine_priv(engine, if_cached_info_equals_actual) = xkl_xmm_if_cached_info_equals_actual;