Switch branches/tags
Nothing to show
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



Files related to X11 and keyboards.

  • xquartz-87.lisp - A keyboard for use with Xquartz that provides a sane mapping for an 87-key keyboard, extremely similar to the default X keyboard. View Keyboard Layout
  • xquartz-87-enh.lisp - An improved keyboard with better mappings. View Enhanced Layout. I use a physical keyboard with this layout over X11 from Xquartz.
  • vncserver-87-enh.lisp - A version of the above layout that works if you want to run Genera on vnc4server so you can access the desktop through an SSH tunnel and VNC when you're not home. Doesn't work nearly as well, but at least it mostly works. Use RealVNC VNC Viewer and the provided vncserver.xmodmap to map some additional keys (like Super, F13-15, etc.).
  • xquartz-macbook.lisp - Similar to :xquartz-87-enhanced above, but with a few changes to make it suitable for a MacBook Pro/Air keyboard.
    • F5 -> Help
    • Right Command -> Right Symbol
    • Right Option -> Right
    • Shift Return -> Line
    • Shift F6/7/8 -> Square/Circle/Triangle
    • Shift Delete -> Backspace
    • Fn Delete -> Backspace
    • Home -> (noop)
  • xlib-patch.lisp - A Genera patch file that fixes errors when Genera calls the xlib:set-modifier-mapping method by replacing it with a noop. See source code for details.
  • set-x-kb-map.lisp - Command processor command Set X Keyboard Mapping that lets Genera 8.3 switch keyboard mappings on the fly from the command line. I didn't write this; I cobbled it together from two files found on the Internet.

If you're using Xquartz, load the patch and then the keyboards you want, then Save World (for ease of reuse). Then Start X Screen. The keyboard type will be picked up automatically (from the server signature) and configured properly.

This was designed for Xquartz 2.7.0_beta10 running on macOS 10.11.5 while using an 87-key Tenkeyless standard keyboard.

You can see details of the mappings with these commands (and appropriate parameters):

  • Show X Keyboard Mapping
  • Show Keyboard Layout
  • Select Activity Keyboard Control


$ xmodmap -pk | sed 's/^ *//' | grep -v '^[0-9]* *.$' >xquartz-default-xmodmap.txt

Note that there are two entries for the Escape keysym, one for key code 61, the other for 79.

  • 61 is generated by the regular ESC key on the keyboard
  • 79 is generated by the Num Lock key on the Japanese Windows USB keyboard I have.

The entry for 79 can be cleared with xmodmap -e "keycode 79 = ".


  • sys:*consoles* contains a list of all consoles.
(#<X-SCREEN::X-CONSOLE ...> ...)

Genera seems to read the xmodmap once when the screen is started, to get all the keynums and keysyms. If you change the xmodmap, it doesn't seem to pick up on that later.

  • (x-screen::default-x-screen) returns the default X-Windows screen. It seems to be the current one, as it will return a different value for each X-Windows connection, e.g.:
    • #<X-REAL-SCREEN X Screen INTERNET| 0 (Genera on BERYLLIUM) 1004206265 exposed>

You can get a display by opening it, but I don't see how to get the current one out of Flavors yet.

  • (xlib:open-display "INTERNET|")
    • This will give an error: Error: INTERNET| does not support X-WINDOW-SYSTEM service.
    • Simply respond s-A: Use protocol X-WINDOW-SYSTEM on medium TCP.
  • (xlib:display-vendor-name \*)
    • "The X.Org Foundation"

You can find out a lot of information with the various functions. Search for def-clx-class (display in the clx.lisp file to see what all the parts of the display structure are.

  • (xlib:display-vendor-name ...)
  • (xlib:display-release-number ...)
  • (xlib:display-host ...)
  • (xlib:display-default-screen ...)
  • (xlib:display-vendor ...) - returns multiple values, vendor-name and release-number
  • (xlib::display-keysym-mapping ...) - nil?
  • (xlib::display-modifier-mapping ...) - nil?
  • (xlib::display-keysym-tanslation ...) - nil?
  • (xlib:display-min-keycode ...)
  • (xlib:display-max-keycode ...)
  • (xlib:display-roots ...)
  • (xlib:display-xdefaults ...) - nil?

So the keyboard-signature seems to be a way for Genera to automatically figure out which keyboard is in use at the destination X screen and set the mappings appropriately! As it turns out, the Xquarts 2.7.10_beta2 on macOS 10.11.5 returns these relevant data about its screen:

  • min-keycode: 8 - which is mapped to the keycode-offset when creating a signature
  • vendor-name: The X.Org Foundation
  • vendor-version: 118030000

Indeed, I created a test keyboard signature starting with the below:

(define-keyboard-signature :xquartz-87-tenkeyless
                           (:keycode-offset 8
                            :vendor-name "The X.Org Foundation"
                            :vendor-version 11803000)

When I started a new X screen (Start X Screen INTERNET| :Reuse No), and immediately checked the maping (Show X Keyboard Mapping), it responded as I would hope:

The keyboard layout type is :XQUARTZ-87-TENKEYLESS.

Now, the next matter turns to the define-keyboard-mapping to try to set the key mapping reasonably usably.

(define-keyboard-mapping :xquartz-87-tenkeyless ()

Mapping Notes

The only function that reads *keyboard-mappings* is x-screen::layout-type-keyboard-mapping, and that seems to be used in only three locations:

  • x-screen::fill-keyboard-table-specific
  • x-screen::layout-type-leds
  • x-screen::x-console-describe-keyboard-mapping - Handles Show X Keyboard Mapping display

The fill-keyboard-table-specific is of great interest, as it seems to translate code-keys into the actual Symbolics key that Genera sees. Viz, from the function in x-console.lisp:

           ;; key code specific key mappings have the highest priority
           ;; Next comes shift specific key mappings 
           ;; finally mappings based on the unshifted keysym

This is in turn called by fill-keyboard-table which calls all the fill-keyboard-table-* methods:

(defun-in-flavor (fill-keyboard-table x-console) (table layout-type)
  (clear-keyboard-table table)
  (fill-keyboard-table-general table layout-type)
  (fill-keyboard-table-specific table layout-type)
  (fill-keyboard-table-symbol table layout-type)
  (fill-keyboard-table-fixup table layout-type))

And fill-keyboard-table is itself called by x-console-update-keyboard-mapping.

This is hard to figure out, though, as I cannot seem to call these methods manually since cli::keyboard seems to be unbound. However, it seems that it is part of the x-keyboard flavor, from this:

(defflavor x-keyboard
        ((last-shifts nil)
         (leds nil))


Here's the mapping. Note that some characters don't show up correctly because I don't have a conversion from Genera's character encoding to UTF-8 (yet).

Also, note that the key codes shown below are off by 8, because the :keycode-offset was set to 8 above. That means the actual X-Windows keycodes are all 8 higher. The Mac keycodes are those lower (8 lower) numbers.

The desired mapping of the bottom row is:

Genera:    Control   Super  Meta      SPACE    Meta    Control Symbol    Hyper
Mac:       Control   Option Command   SPACE    Command Option  Menu      Control
Keycode:   67        66     63        57       69      71      118       70
Keysym+    Control-L Alt_L  Meta_L    space    Alt_R   Meta_R  NoSymbol  Control_R