Exemplo n.º 1
0
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)
		}
	}
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
// 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
}