Index: CMake/resources.cmake
===================================================================
--- CMake/resources.cmake	(revision 10344)
+++ CMake/resources.cmake	(working copy)
@@ -40,6 +40,7 @@
 find_file(HAVE_SYS_SELECT_H sys/select.h)
 find_file(HAVE_SYS_STDTYPES_H sys/stdtypes.h)
 find_path(HAVE_XDBE_H Xdbe.h PATH_SUFFIXES X11/extensions extensions)
+find_file(HAVE_X11_XKBLIB_H X11/XKBlib.h)
 
 mark_as_advanced(HAVE_ALSA_ASOUNDLIB_H HAVE_DIRENT_H HAVE_DLFCN_H)
 mark_as_advanced(HAVE_FREETYPE_H HAVE_GL_GL_H HAVE_GL_GLU_H)
@@ -47,7 +48,7 @@
 mark_as_advanced(HAVE_OPENGL_GLU_H HAVE_PNG_H HAVE_PTHREAD_H)
 mark_as_advanced(HAVE_STDIO_H HAVE_STRINGS_H HAVE_SYS_DIR_H)
 mark_as_advanced(HAVE_SYS_NDIR_H HAVE_SYS_SELECT_H)
-mark_as_advanced(HAVE_SYS_STDTYPES_H HAVE_XDBE_H)
+mark_as_advanced(HAVE_SYS_STDTYPES_H HAVE_XDBE_H HAVE_X11_XKBLIB_H))
 
 # where to find freetype headers
 find_path(FREETYPE_PATH freetype.h PATH_SUFFIXES freetype2)
Index: configh.cmake.in
===================================================================
--- configh.cmake.in	(revision 10344)
+++ configh.cmake.in	(working copy)
@@ -196,6 +196,8 @@
 #cmakedefine HAVE_SCANDIR @HAVE_SCANDIR@
 #cmakedefine HAVE_SCANDIR_POSIX @HAVE_SCANDIR_POSIX@
 
+#cmakedefine HAVE_X11_XKBLIB_H @HAVE_X11_XKBLIB_H@
+
 /*
  * Possibly missing sprintf-style functions:
  */
Index: configh.in
===================================================================
--- configh.in	(revision 10344)
+++ configh.in	(working copy)
@@ -199,6 +199,7 @@
 #undef HAVE_NDIR_H
 #undef HAVE_SCANDIR
 #undef HAVE_SCANDIR_POSIX
+#undef HAVE_X11_XKBLIB_H
 
 /*
  * Possibly missing sprintf-style functions:
Index: configure.in
===================================================================
--- configure.in	(revision 10344)
+++ configure.in	(working copy)
@@ -482,6 +482,7 @@
 AC_HEADER_DIRENT
 AC_CHECK_HEADER(sys/select.h,AC_DEFINE(HAVE_SYS_SELECT_H))
 AC_CHECK_HEADER(sys/stdtypes.h,AC_DEFINE(HAVE_SYS_SELECT_H))
+AC_CHECK_HEADER(X11/XKBlib.h, AC_DEFINE(HAVE_X11_XKBLIB_H))
 
 dnl Do we have the POSIX compatible scandir() prototype?
 AC_CACHE_CHECK([whether we have the POSIX compatible scandir() prototype],
Index: src/Fl_x.cxx
===================================================================
--- src/Fl_x.cxx	(revision 10344)
+++ src/Fl_x.cxx	(working copy)
@@ -69,6 +69,15 @@
 #  if HAVE_XCURSOR
 #    include <X11/Xcursor/Xcursor.h>
 #  endif
+
+#ifdef HAVE_X11_XKBLIB_H
+#include <X11/XKBlib.h>
+#define _KeycodeToKeysym(d, k, g, l) \
+    (XkbKeycodeToKeysym((d), (k), (g), (l)))
+#else
+#define _KeycodeToKeysym(d, k, i, x) (XKeycodeToKeysym((d), (k), (i)))
+#endif
+
 static Fl_Xlib_Graphics_Driver fl_xlib_driver;
 static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
 Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
@@ -1784,7 +1793,7 @@
 	  len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
 			     kp_buffer, kp_buffer_len, &keysym, &status);
 	}
-	keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+	keysym = _KeycodeToKeysym(fl_display, keycode, 0, 0);
       } else {
         //static XComposeStatus compose;
         len = XLookupString((XKeyEvent*)&(xevent.xkey),
@@ -1796,7 +1805,7 @@
           if (len < 1) len = 1;
           // ignore all effects of shift on the keysyms, which makes it a lot
           // easier to program shortcuts and is Windoze-compatible:
-          keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+          keysym = _KeycodeToKeysym(fl_display, keycode, 0, 0);
         }
       }
       kp_buffer[len] = 0;
@@ -1839,7 +1848,7 @@
       event = FL_KEYUP;
       fl_key_vector[keycode/8] &= ~(1 << (keycode%8));
       // keyup events just get the unshifted keysym:
-      keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+      keysym = _KeycodeToKeysym(fl_display, keycode, 0, 0);
     }
 #  ifdef __sgi
     // You can plug a microsoft keyboard into an sgi but the extra shift
@@ -1932,7 +1941,7 @@
     if (keysym >= 0xff91 && keysym <= 0xff9f) {
       // Map keypad keysym to character or keysym depending on
       // numlock state...
-      unsigned long keysym1 = XKeycodeToKeysym(fl_display, keycode, 1);
+      unsigned long keysym1 = _KeycodeToKeysym(fl_display, keycode, 1, 0);
       if (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))
         Fl::e_original_keysym = (int)(keysym1 | FL_KP);
       if ((xevent.xkey.state & Mod2Mask) &&
