func initKeyboardMapping() { const ( keyLo = 8 keyHi = 255 ) km, err := xp.GetKeyboardMapping(xConn, keyLo, keyHi-keyLo+1).Reply() if err != nil { log.Fatal(err) } if km == nil { log.Fatal("couldn't get keyboard mapping") } n := int(km.KeysymsPerKeycode) if n < 2 { log.Fatalf("too few keysyms per keycode: %d", n) } for i := keyLo; i <= keyHi; i++ { keysyms[i][0] = km.Keysyms[(i-keyLo)*n+0] keysyms[i][1] = km.Keysyms[(i-keyLo)*n+1] } toGrabs := []xp.Keysym{wmKeysym} if doAudioActions { toGrabs = append(toGrabs, xkAudioLowerVolume, xkAudioMute, xkAudioRaiseVolume) } for _, toGrab := range toGrabs { keycode := xp.Keycode(0) for i := keyLo; i <= keyHi; i++ { if keysyms[i][0] == toGrab || keysyms[i][1] == toGrab { keycode = xp.Keycode(i) } } if keycode == 0 { if toGrab != wmKeysym { continue } log.Fatalf("could not find the window manager key %s", keysymString(toGrab)) } if err := xp.GrabKeyChecked(xConn, false, rootXWin, xp.ModMaskAny, keycode, xp.GrabModeAsync, xp.GrabModeAsync).Check(); err != nil { log.Fatal(err) } } // Disable Caps Lock if it is the wmKeysym. if wmKeysym == xkCapsLock { // On Ubuntu 12.04, disabling Caps Lock involved the equivalent of // `xmodmap -e "clear lock"`. On Ubuntu 14.04, XKB has replaced xmodmap, // possibly because this facilitates per-window keyboard layouts, so the // equivalent of `xmodmap -e "clear lock"` doesn't work. As of October // 2014, github.com/BurntSushi/xgb doesn't support XKB, so we exec the // setxkbmap program instead of speaking the X11 protocol directly to // disable Caps Lock. if err := exec.Command("setxkbmap", "-option", "caps:none").Run(); err != nil { log.Fatalf("setxkbmap failed: %v", err) } } }
func NewKeyboard(s *xproto.SetupInfo, c *xgb.Conn) (*Keyboard, error) { min, max := minMaxKeycodeGet(s) keymap, err := xproto.GetKeyboardMapping(c, min, byte(max-min+1)).Reply() if err != nil { return nil, UnMappable("keyboard", err) } return &Keyboard{ Min: min, Max: max, GetKeyboardMappingReply: keymap, }, nil }
func (s *screenImpl) initKeyboardMapping() error { const keyLo, keyHi = 8, 255 km, err := xproto.GetKeyboardMapping(s.xc, keyLo, keyHi-keyLo+1).Reply() if err != nil { return err } n := int(km.KeysymsPerKeycode) if n < 2 { return fmt.Errorf("x11driver: too few keysyms per keycode: %d", n) } for i := keyLo; i <= keyHi; i++ { s.keysyms[i][0] = km.Keysyms[(i-keyLo)*n+0] s.keysyms[i][1] = km.Keysyms[(i-keyLo)*n+1] } return nil }
// A convenience function to grab the KeyboardMapping and ModifierMapping // from X. We need to do this on startup (see Initialize) and whenever we // get a MappingNotify event. func MapsGet(xu *xgbutil.XUtil) (*xproto.GetKeyboardMappingReply, *xproto.GetModifierMappingReply) { min, max := minMaxKeycodeGet(xu) newKeymap, keyErr := xproto.GetKeyboardMapping(xu.Conn(), min, byte(max-min+1)).Reply() newModmap, modErr := xproto.GetModifierMapping(xu.Conn()).Reply() // If there are errors, we really need to panic. We just can't do // any key binding without a mapping from the server. if keyErr != nil { panic(fmt.Sprintf("COULD NOT GET KEYBOARD MAPPING: %v\n"+ "THIS IS AN UNRECOVERABLE ERROR.\n", keyErr)) } if modErr != nil { panic(fmt.Sprintf("COULD NOT GET MODIFIER MAPPING: %v\n"+ "THIS IS AN UNRECOVERABLE ERROR.\n", keyErr)) } return newKeymap, newModmap }