dotool/keys.go
2023-04-21 11:25:08 +01:00

531 lines
15 KiB
Go

package main
import (
"git.sr.ht/~geb/dotool/xkb"
"github.com/bendahl/uinput"
)
var LinuxKeys = map[string]Chord{
// Linux Only
"micmute": Chord{Key: uinput.KeyMicmute},
"unknown": Chord{Key: uinput.KeyUnknown},
"alterase": Chord{Key: uinput.KeyAlterase},
"question": Chord{Key: uinput.KeyQuestion},
"hp": Chord{Key: uinput.KeyHp},
"bassboost": Chord{Key: uinput.KeyBassboost},
"play": Chord{Key: uinput.KeyPlay},
"close": Chord{Key: uinput.KeyClose},
"edit": Chord{Key: uinput.KeyEdit},
"move": Chord{Key: uinput.KeyMove},
"iso": Chord{Key: uinput.KeyIso},
"closecd": Chord{Key: uinput.KeyClosecd},
"deletefile": Chord{Key: uinput.KeyDeletefile},
"setup": Chord{Key: uinput.KeySetup},
"yen": Chord{Key: uinput.KeyYen},
"macro": Chord{Key: uinput.KeyMacro},
"kpjpcomma": Chord{Key: uinput.KeyKpjpcomma},
"ro": Chord{Key: uinput.KeyRo},
"zenkakuhankaku": Chord{Key: uinput.KeyZenkakuhankaku},
"esc": Chord{Key: uinput.KeyEsc},
"1": Chord{Key: uinput.Key1},
"2": Chord{Key: uinput.Key2},
"3": Chord{Key: uinput.Key3},
"4": Chord{Key: uinput.Key4},
"5": Chord{Key: uinput.Key5},
"6": Chord{Key: uinput.Key6},
"7": Chord{Key: uinput.Key7},
"8": Chord{Key: uinput.Key8},
"9": Chord{Key: uinput.Key9},
"0": Chord{Key: uinput.Key0},
"minus": Chord{Key: uinput.KeyMinus},
"equal": Chord{Key: uinput.KeyEqual},
"backspace": Chord{Key: uinput.KeyBackspace},
"tab": Chord{Key: uinput.KeyTab},
"q": Chord{Key: uinput.KeyQ},
"w": Chord{Key: uinput.KeyW},
"e": Chord{Key: uinput.KeyE},
"r": Chord{Key: uinput.KeyR},
"t": Chord{Key: uinput.KeyT},
"y": Chord{Key: uinput.KeyY},
"u": Chord{Key: uinput.KeyU},
"i": Chord{Key: uinput.KeyI},
"o": Chord{Key: uinput.KeyO},
"p": Chord{Key: uinput.KeyP},
"leftbrace": Chord{Key: uinput.KeyLeftbrace},
"rightbrace": Chord{Key: uinput.KeyRightbrace},
"enter": Chord{Key: uinput.KeyEnter},
"leftctrl": Chord{Key: uinput.KeyLeftctrl},
"a": Chord{Key: uinput.KeyA},
"s": Chord{Key: uinput.KeyS},
"d": Chord{Key: uinput.KeyD},
"f": Chord{Key: uinput.KeyF},
"g": Chord{Key: uinput.KeyG},
"h": Chord{Key: uinput.KeyH},
"j": Chord{Key: uinput.KeyJ},
"k": Chord{Key: uinput.KeyK},
"l": Chord{Key: uinput.KeyL},
"semicolon": Chord{Key: uinput.KeySemicolon},
"apostrophe": Chord{Key: uinput.KeyApostrophe},
"grave": Chord{Key: uinput.KeyGrave},
"leftshift": Chord{Key: uinput.KeyLeftshift},
"backslash": Chord{Key: uinput.KeyBackslash},
"z": Chord{Key: uinput.KeyZ},
"x": Chord{Key: uinput.KeyX},
"c": Chord{Key: uinput.KeyC},
"v": Chord{Key: uinput.KeyV},
"b": Chord{Key: uinput.KeyB},
"n": Chord{Key: uinput.KeyN},
"m": Chord{Key: uinput.KeyM},
"comma": Chord{Key: uinput.KeyComma},
"dot": Chord{Key: uinput.KeyDot},
"slash": Chord{Key: uinput.KeySlash},
"rightshift": Chord{Key: uinput.KeyRightshift},
"kpasterisk": Chord{Key: uinput.KeyKpasterisk},
"leftalt": Chord{Key: uinput.KeyLeftalt},
"space": Chord{Key: uinput.KeySpace},
"capslock": Chord{Key: uinput.KeyCapslock},
"f1": Chord{Key: uinput.KeyF1},
"f2": Chord{Key: uinput.KeyF2},
"f3": Chord{Key: uinput.KeyF3},
"f4": Chord{Key: uinput.KeyF4},
"f5": Chord{Key: uinput.KeyF5},
"f6": Chord{Key: uinput.KeyF6},
"f7": Chord{Key: uinput.KeyF7},
"f8": Chord{Key: uinput.KeyF8},
"f9": Chord{Key: uinput.KeyF9},
"f10": Chord{Key: uinput.KeyF10},
"numlock": Chord{Key: uinput.KeyNumlock},
"scrolllock": Chord{Key: uinput.KeyScrolllock},
"kp7": Chord{Key: uinput.KeyKp7},
"kp8": Chord{Key: uinput.KeyKp8},
"kp9": Chord{Key: uinput.KeyKp9},
"kpminus": Chord{Key: uinput.KeyKpminus},
"kp4": Chord{Key: uinput.KeyKp4},
"kp5": Chord{Key: uinput.KeyKp5},
"kp6": Chord{Key: uinput.KeyKp6},
"kpplus": Chord{Key: uinput.KeyKpplus},
"kp1": Chord{Key: uinput.KeyKp1},
"kp2": Chord{Key: uinput.KeyKp2},
"kp3": Chord{Key: uinput.KeyKp3},
"kp0": Chord{Key: uinput.KeyKp0},
"kpdot": Chord{Key: uinput.KeyKpdot},
"102nd": Chord{Key: uinput.Key102Nd},
"f11": Chord{Key: uinput.KeyF11},
"f12": Chord{Key: uinput.KeyF12},
"katakana": Chord{Key: uinput.KeyKatakana},
"hiragana": Chord{Key: uinput.KeyHiragana},
"henkan": Chord{Key: uinput.KeyHenkan},
"katakanahiragana": Chord{Key: uinput.KeyKatakanahiragana},
"muhenkan": Chord{Key: uinput.KeyMuhenkan},
"kpenter": Chord{Key: uinput.KeyKpenter},
"rightctrl": Chord{Key: uinput.KeyRightctrl},
"kpslash": Chord{Key: uinput.KeyKpslash},
"sysrq": Chord{Key: uinput.KeySysrq},
"rightalt": Chord{Key: uinput.KeyRightalt},
"linefeed": Chord{Key: uinput.KeyLinefeed},
"home": Chord{Key: uinput.KeyHome},
"up": Chord{Key: uinput.KeyUp},
"pageup": Chord{Key: uinput.KeyPageup},
"left": Chord{Key: uinput.KeyLeft},
"right": Chord{Key: uinput.KeyRight},
"end": Chord{Key: uinput.KeyEnd},
"down": Chord{Key: uinput.KeyDown},
"pagedown": Chord{Key: uinput.KeyPagedown},
"insert": Chord{Key: uinput.KeyInsert},
"delete": Chord{Key: uinput.KeyDelete},
"mute": Chord{Key: uinput.KeyMute},
"volumedown": Chord{Key: uinput.KeyVolumedown},
"volumeup": Chord{Key: uinput.KeyVolumeup},
"power": Chord{Key: uinput.KeyPower},
"kpequal": Chord{Key: uinput.KeyKpequal},
"kpplusminus": Chord{Key: uinput.KeyKpplusminus},
"pause": Chord{Key: uinput.KeyPause},
"scale": Chord{Key: uinput.KeyScale},
"kpcomma": Chord{Key: uinput.KeyKpcomma},
"hangeul": Chord{Key: uinput.KeyHangeul},
"hanja": Chord{Key: uinput.KeyHanja},
"leftmeta": Chord{Key: uinput.KeyLeftmeta},
"rightmeta": Chord{Key: uinput.KeyRightmeta},
"compose": Chord{Key: uinput.KeyCompose},
"stop": Chord{Key: uinput.KeyStop},
"again": Chord{Key: uinput.KeyAgain},
"props": Chord{Key: uinput.KeyProps},
"undo": Chord{Key: uinput.KeyUndo},
"front": Chord{Key: uinput.KeyFront},
"copy": Chord{Key: uinput.KeyCopy},
"open": Chord{Key: uinput.KeyOpen},
"paste": Chord{Key: uinput.KeyPaste},
"find": Chord{Key: uinput.KeyFind},
"cut": Chord{Key: uinput.KeyCut},
"help": Chord{Key: uinput.KeyHelp},
"menu": Chord{Key: uinput.KeyMenu},
"calc": Chord{Key: uinput.KeyCalc},
"sleep": Chord{Key: uinput.KeySleep},
"wakeup": Chord{Key: uinput.KeyWakeup},
"file": Chord{Key: uinput.KeyFile},
"sendfile": Chord{Key: uinput.KeySendfile},
"xfer": Chord{Key: uinput.KeyXfer},
"prog1": Chord{Key: uinput.KeyProg1},
"prog2": Chord{Key: uinput.KeyProg2},
"www": Chord{Key: uinput.KeyWww},
"msdos": Chord{Key: uinput.KeyMsdos},
"coffee": Chord{Key: uinput.KeyCoffee},
"direction": Chord{Key: uinput.KeyDirection},
"cyclewindows": Chord{Key: uinput.KeyCyclewindows},
"mail": Chord{Key: uinput.KeyMail},
"bookmarks": Chord{Key: uinput.KeyBookmarks},
"computer": Chord{Key: uinput.KeyComputer},
"back": Chord{Key: uinput.KeyBack},
"forward": Chord{Key: uinput.KeyForward},
"ejectcd": Chord{Key: uinput.KeyEjectcd},
"ejectclosecd": Chord{Key: uinput.KeyEjectclosecd},
"nextsong": Chord{Key: uinput.KeyNextsong},
"playpause": Chord{Key: uinput.KeyPlaypause},
"previoussong": Chord{Key: uinput.KeyPrevioussong},
"stopcd": Chord{Key: uinput.KeyStopcd},
"record": Chord{Key: uinput.KeyRecord},
"rewind": Chord{Key: uinput.KeyRewind},
"phone": Chord{Key: uinput.KeyPhone},
"config": Chord{Key: uinput.KeyConfig},
"homepage": Chord{Key: uinput.KeyHomepage},
"refresh": Chord{Key: uinput.KeyRefresh},
"exit": Chord{Key: uinput.KeyExit},
"scrollup": Chord{Key: uinput.KeyScrollup},
"scrolldown": Chord{Key: uinput.KeyScrolldown},
"kpleftparen": Chord{Key: uinput.KeyKpleftparen},
"kprightparen": Chord{Key: uinput.KeyKprightparen},
"new": Chord{Key: uinput.KeyNew},
"redo": Chord{Key: uinput.KeyRedo},
"f13": Chord{Key: uinput.KeyF13},
"f14": Chord{Key: uinput.KeyF14},
"f15": Chord{Key: uinput.KeyF15},
"f16": Chord{Key: uinput.KeyF16},
"f17": Chord{Key: uinput.KeyF17},
"f18": Chord{Key: uinput.KeyF18},
"f19": Chord{Key: uinput.KeyF19},
"f20": Chord{Key: uinput.KeyF20},
"f21": Chord{Key: uinput.KeyF21},
"f22": Chord{Key: uinput.KeyF22},
"f23": Chord{Key: uinput.KeyF23},
"f24": Chord{Key: uinput.KeyF24},
"playcd": Chord{Key: uinput.KeyPlaycd},
"pausecd": Chord{Key: uinput.KeyPausecd},
"prog3": Chord{Key: uinput.KeyProg3},
"prog4": Chord{Key: uinput.KeyProg4},
"dashboard": Chord{Key: uinput.KeyDashboard},
"suspend": Chord{Key: uinput.KeySuspend},
"fastforward": Chord{Key: uinput.KeyFastforward},
"print": Chord{Key: uinput.KeyPrint},
"camera": Chord{Key: uinput.KeyCamera},
"sound": Chord{Key: uinput.KeySound},
"email": Chord{Key: uinput.KeyEmail},
"chat": Chord{Key: uinput.KeyChat},
"search": Chord{Key: uinput.KeySearch},
"connect": Chord{Key: uinput.KeyConnect},
"finance": Chord{Key: uinput.KeyFinance},
"sport": Chord{Key: uinput.KeySport},
"shop": Chord{Key: uinput.KeyShop},
"cancel": Chord{Key: uinput.KeyCancel},
"brightnessdown": Chord{Key: uinput.KeyBrightnessdown},
"brightnessup": Chord{Key: uinput.KeyBrightnessup},
"media": Chord{Key: uinput.KeyMedia},
"switchvideomode": Chord{Key: uinput.KeySwitchvideomode},
"kbdillumtoggle": Chord{Key: uinput.KeyKbdillumtoggle},
"kbdillumdown": Chord{Key: uinput.KeyKbdillumdown},
"kbdillumup": Chord{Key: uinput.KeyKbdillumup},
"send": Chord{Key: uinput.KeySend},
"reply": Chord{Key: uinput.KeyReply},
"forwardmail": Chord{Key: uinput.KeyForwardmail},
"save": Chord{Key: uinput.KeySave},
"documents": Chord{Key: uinput.KeyDocuments},
"battery": Chord{Key: uinput.KeyBattery},
"bluetooth": Chord{Key: uinput.KeyBluetooth},
"wlan": Chord{Key: uinput.KeyWlan},
"uwb": Chord{Key: uinput.KeyUwb},
"videonext": Chord{Key: uinput.KeyVideoNext},
"videoprev": Chord{Key: uinput.KeyVideoPrev},
"brightnesscycle": Chord{Key: uinput.KeyBrightnessCycle},
"brightnesszero": Chord{Key: uinput.KeyBrightnessZero},
"displayoff": Chord{Key: uinput.KeyDisplayOff},
"wimax": Chord{Key: uinput.KeyWimax},
"rfkill": Chord{Key: uinput.KeyRfkill},
}
var linuxXSyms = map[string]uint32{
"esc": 0xff1b,
"1": 0x31,
"2": 0x32,
"3": 0x33,
"4": 0x34,
"5": 0x35,
"6": 0x36,
"7": 0x37,
"8": 0x38,
"9": 0x39,
"0": 0x30,
"minus": 0x2d,
"equal": 0x3d,
"backspace": 0xff08,
"tab": 0xff09,
"q": 0x71,
"w": 0x77,
"e": 0x65,
"r": 0x72,
"t": 0x74,
"y": 0x79,
"u": 0x75,
"i": 0x69,
"o": 0x6f,
"p": 0x70,
"leftbrace": 0x5b,
"rightbrace": 0x5d,
"enter": 0xff0d,
"leftctrl": 0xffe3,
"a": 0x61,
"s": 0x73,
"d": 0x64,
"f": 0x66,
"g": 0x67,
"h": 0x68,
"j": 0x6a,
"k": 0x6b,
"l": 0x6c,
"semicolon": 0x3b,
"apostrophe": 0x27,
"grave": 0x60,
"leftshift": 0xffe1,
"backslash": 0x5c,
"z": 0x7a,
"x": 0x78,
"c": 0x63,
"v": 0x76,
"b": 0x62,
"n": 0x6e,
"m": 0x6d,
"comma": 0x2c,
"dot": 0x2e,
"slash": 0x2f,
"rightshift": 0xffe2,
"kpasterisk": 0xffaa,
"leftalt": 0xffe9,
"space": 0x20,
"capslock": 0xffe5,
"f1": 0xffbe,
"f2": 0xffbf,
"f3": 0xffc0,
"f4": 0xffc1,
"f5": 0xffc2,
"f6": 0xffc3,
"f7": 0xffc4,
"f8": 0xffc5,
"f9": 0xffc6,
"f10": 0xffc7,
"numlock": 0xff7f,
"scrolllock": 0xff14,
"kp7": 0xff95,
"kp8": 0xff97,
"kp9": 0xff9a,
"kpminus": 0xffad,
"kp4": 0xff96,
"kp5": 0xff9d,
"kp6": 0xff98,
"kpplus": 0xffab,
"kp1": 0xff9c,
"kp2": 0xff99,
"kp3": 0xff9b,
"kp0": 0xff9e,
"kpdot": 0xff9f,
"102nd": 0x3c,
"f11": 0xffc8,
"f12": 0xffc9,
"katakana": 0xff26,
"hiragana": 0xff25,
"henkan": 0xff23,
"katakanahiragana": 0xff27,
"muhenkan": 0xff22,
"kpenter": 0xff8d,
"rightctrl": 0xffe4,
"kpslash": 0xffaf,
"sysrq": 0xff61,
"rightalt": 0xffea,
"linefeed": 0xff0a,
"home": 0xff50,
"up": 0xff52,
"pageup": 0xff55,
"left": 0xff51,
"right": 0xff53,
"end": 0xff57,
"down": 0xff54,
"pagedown": 0xff56,
"insert": 0xff63,
"delete": 0xffff,
"mute": 0x1008ff12,
"volumedown": 0x1008ff11,
"volumeup": 0x1008ff13,
"power": 0x1008ff2a,
"kpequal": 0xffbd,
"kpplusminus": 0xb1,
"pause": 0xff13,
"scale": 0x1008ff4a,
"kpcomma": 0xffae,
"hangeul": 0xff31,
"hanja": 0xff34,
"leftmeta": 0xffeb,
"rightmeta": 0xffec,
"compose": 0xff67,
"stop": 0xff69,
"again": 0xff66,
"props": 0x1005ff70,
"undo": 0xff65,
"front": 0x1005ff71,
"copy": 0x1008ff57,
"open": 0x1008ff6b,
"paste": 0x1008ff6d,
"find": 0xff68,
"cut": 0x1008ff58,
"help": 0xff6a,
"menu": 0x1008ff65,
"calc": 0x1008ff1d,
"sleep": 0x1008ff2f,
"wakeup": 0x1008ff2b,
"file": 0x1008ff5d,
"sendfile": 0x1008ff7b,
"xfer": 0x1008ff8a,
"prog1": 0x1008ff41,
"prog2": 0x1008ff42,
"www": 0x1008ff2e,
"msdos": 0x1008ff5a,
"coffee": 0x1008ff2d,
"direction": 0x1008ff74,
"cyclewindows": 0x1008ff7f,
"mail": 0x1008ff19,
"bookmarks": 0x1008ff30,
"computer": 0x1008ff33,
"back": 0x1008ff26,
"forward": 0x1008ff27,
"ejectcd": 0x1008ff2c,
"ejectclosecd": 0x1008ff2c,
"nextsong": 0x1008ff17,
"playpause": 0x1008ff14,
"previoussong": 0x1008ff16,
"stopcd": 0x1008ff15,
"record": 0x1008ff1c,
"rewind": 0x1008ff3e,
"phone": 0x1008ff6e,
"config": 0x1008ff81,
"homepage": 0x1008ff18,
"refresh": 0x1008ff73,
"exit": 0x1008ff56,
"scrollup": 0x1008ff78,
"scrolldown": 0x1008ff79,
"kpleftparen": 0x28,
"kprightparen": 0x29,
"new": 0x1008ff68,
"redo": 0xff66,
"f13": 0xffca,
"f14": 0xffcb,
"f15": 0xffcc,
"f16": 0xffcd,
"f17": 0xffce,
"f18": 0xffcf,
"f19": 0xffd0,
"f20": 0xffd1,
"f21": 0xffd2,
"f22": 0xffd3,
"f23": 0xffd4,
"f24": 0xffd5,
"playcd": 0x1008ff14,
"pausecd": 0x1008ff31,
"prog3": 0x1008ff43,
"prog4": 0x1008ff44,
"dashboard": 0x1008ff4b,
"suspend": 0x1008ffa7,
"fastforward": 0x1008ff97,
"print": 0xff61,
"camera": 0x1008ff8f,
"sound": 0x1008ffb6,
"email": 0x1008ff19,
"chat": 0x1008ff8e,
"search": 0x1008ff1b,
"connect": 0x1008ff5f,
"finance": 0x1008ff3c,
"sport": 0x1008ff5e,
"shop": 0x1008ff36,
"cancel": 0xff69,
"brightnessdown": 0x1008ff03,
"brightnessup": 0x1008ff02,
"media": 0x1008ff32,
"switchvideomode": 0x1008ff59,
"kbdillumtoggle": 0x1008ff04,
"kbdillumdown": 0x1008ff06,
"kbdillumup": 0x1008ff05,
"send": 0x1008ff7b,
"reply": 0x1008ff72,
"forwardmail": 0x1008ff90,
"save": 0x1008ff77,
"documents": 0x1008ff5b,
"battery": 0x1008ff93,
"bluetooth": 0x1008ff94,
"wlan": 0x1008ff95,
"uwb": 0x1008ff96,
"videonext": 0x1008fe22,
"videoprev": 0x1008fe23,
"brightnesscycle": 0x1008ff07,
"brightnesszero": 0x100810f4,
"displayoff": 0x100810f5,
"wimax": 0x1008ffb4,
"rfkill": 0x1008ffb5,
}
var XKeys = map[string]Chord{}
func newChord(keymap *xkb.Keymap, mask, code uint32) Chord{
altGrMask := uint32(1) << keymap.ModGetIndex("Mod5")
ctrlMask := uint32(1) << keymap.ModGetIndex(xkb.ModNameCtrl)
altMask := uint32(1) << keymap.ModGetIndex(xkb.ModNameAlt)
shiftMask := uint32(1) << keymap.ModGetIndex(xkb.ModNameShift)
return Chord{
false,
(mask & altGrMask) != 0,
(mask & ctrlMask) != 0,
(mask & altMask) != 0,
(mask & shiftMask) != 0,
int(code) - 8,
}
}
func initKeys(keymap *xkb.Keymap, linux bool) {
maxCode := keymap.MaxKeycode()
for code := keymap.MinKeycode(); code <= maxCode && code < 256; code++ {
numLevels := keymap.NumLevelsForKey(code, 0)
for level := uint32(0); level < numLevels; level++ {
for _, sym := range keymap.KeyGetSymsByLevel(code, 0, level) {
chord := newChord(keymap, keymap.KeyGetMod(code, 0, level), code)
if linux {
for name, s := range linuxXSyms {
if s == sym {
LinuxKeys[name] = chord
}
}
}
XKeys[xkb.KeysymGetName(sym)] = chord
}
}
}
}
func getChord(keymap *xkb.Keymap, keysym uint32) Chord {
maxCode := keymap.MaxKeycode()
for code := keymap.MinKeycode(); code <= maxCode && code < 256; code++ {
numLevels := keymap.NumLevelsForKey(code, 0)
for level := uint32(0); level < numLevels; level++ {
for _, sym := range keymap.KeyGetSymsByLevel(code, 0, level) {
if sym == keysym {
return newChord(keymap, keymap.KeyGetMod(code, 0, level), code)
}
}
}
}
return Chord{}
}