#endif /* USE_MOTIF */
+\f
+/***********************************************************************
+ Keyboard
+ ***********************************************************************/
+
+#ifdef HAVE_XKBGETKEYBOARD
+#include <X11/XKBlib.h>
+#include <X11/keysym.h>
+#endif
+
+DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
+ Sx_backspace_delete_keys_p, 0, 1, 0,
+ "Check if both Backspace and Delete keys are on the keyboard of FRAME.\n\
+FRAME nil means use the selected frame.\n\
+Value is t if we know that both keys are present, and are mapped to the\n\
+usual X keysyms.")
+ (frame)
+ Lisp_Object frame;
+{
+#ifdef HAVE_XKBGETKEYBOARD
+ XkbDescPtr kb;
+ struct frame *f = check_x_frame (frame);
+ Display *dpy = FRAME_X_DISPLAY (f);
+ Lisp_Object have_keys;
+
+ have_keys = Qnil;
+
+ BLOCK_INPUT;
+ kb = XkbGetKeyboard (dpy, XkbAllComponentsMask, XkbUseCoreKbd);
+ if (kb)
+ {
+ int delete_keycode = 0, backspace_keycode = 0, i;
+
+ for (i = kb->min_key_code;
+ (i < kb->max_key_code
+ && (delete_keycode == 0 || backspace_keycode == 0));
+ ++i)
+ {
+ /* The XKB symbolic key names can be seen most easily
+ in the PS file generated by `xkbprint -label name $DISPLAY'. */
+ if (bcmp ("DELE", kb->names->keys[i].name, 4) == 0)
+ delete_keycode = i;
+ else if (bcmp ("BKSP", kb->names->keys[i].name, 4) == 0)
+ backspace_keycode = i;
+ }
+
+ XkbFreeKeyboard (kb, XkbAllComponentsMask, True);
+
+ if (delete_keycode
+ && backspace_keycode
+ && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
+ && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
+ have_keys = Qt;
+ }
+ UNBLOCK_INPUT;
+ return have_keys;
+#else /* not HAVE_XKBGETKEYBOARD */
+ return Qnil;
+#endif /* not HAVE_XKBGETKEYBOARD */
+}
+
+
\f
/***********************************************************************
Initialization
defsubr (&Sx_display_list);
defsubr (&Sx_synchronize);
defsubr (&Sx_focus_frame);
-
+ defsubr (&Sx_backspace_delete_keys_p);
+
/* Setting callback functions for fontset handler. */
get_font_info_func = x_get_font_info;