2022-10-20 15:21:20 +02:00
|
|
|
package main
|
|
|
|
|
2023-04-19 14:23:05 +02:00
|
|
|
import (
|
|
|
|
"git.sr.ht/~geb/dotool/xkb"
|
|
|
|
"github.com/bendahl/uinput"
|
2023-08-15 17:57:53 +02:00
|
|
|
"unicode"
|
2023-04-19 14:23:05 +02:00
|
|
|
)
|
2022-10-20 15:21:20 +02:00
|
|
|
|
2023-09-12 13:49:35 +02:00
|
|
|
var super, altgr, ctrl, alt, shift int
|
|
|
|
|
2023-04-19 14:23:05 +02:00
|
|
|
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},
|
|
|
|
|
2023-05-11 12:03:36 +02:00
|
|
|
// Potentially overwritten by initKeys()
|
2023-04-19 14:23:05 +02:00
|
|
|
"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,
|
2022-10-20 15:21:20 +02:00
|
|
|
}
|
|
|
|
|
2023-04-19 14:23:05 +02:00
|
|
|
var XKeys = map[string]Chord{}
|
|
|
|
|
2023-08-15 17:57:53 +02:00
|
|
|
type DeadKeyResult struct {
|
|
|
|
DeadKey, Key string
|
|
|
|
Result rune
|
|
|
|
}
|
|
|
|
|
|
|
|
// this relies on a conventional keymap
|
|
|
|
// this isn't exhaustive (e.g. acircumflexacute)
|
|
|
|
var DeadKeyResults = []DeadKeyResult{
|
|
|
|
{"dead_abovedot", "B", 'Ḃ'},
|
|
|
|
{"dead_abovedot", "C", 'Ċ'},
|
|
|
|
{"dead_abovedot", "D", 'Ḋ'},
|
|
|
|
{"dead_abovedot", "E", 'Ė'},
|
|
|
|
{"dead_abovedot", "F", 'Ḟ'},
|
|
|
|
{"dead_abovedot", "G", 'Ġ'},
|
|
|
|
{"dead_abovedot", "I", 'İ'},
|
|
|
|
{"dead_abovedot", "M", 'Ṁ'},
|
|
|
|
{"dead_abovedot", "P", 'Ṗ'},
|
|
|
|
{"dead_abovedot", "S", 'Ṡ'},
|
|
|
|
{"dead_abovedot", "T", 'Ṫ'},
|
|
|
|
{"dead_abovedot", "X", 'Ẋ'},
|
|
|
|
{"dead_abovedot", "Z", 'Ż'},
|
|
|
|
{"dead_acute", "A", 'Á'},
|
|
|
|
{"dead_acute", "C", 'Ć'},
|
|
|
|
{"dead_acute", "E", 'É'},
|
|
|
|
{"dead_acute", "I", 'Í'},
|
|
|
|
{"dead_acute", "L", 'Ĺ'},
|
|
|
|
{"dead_acute", "N", 'Ń'},
|
|
|
|
{"dead_acute", "O", 'Ó'},
|
|
|
|
{"dead_acute", "R", 'Ŕ'},
|
|
|
|
{"dead_acute", "S", 'Ś'},
|
|
|
|
{"dead_acute", "U", 'Ú'},
|
|
|
|
{"dead_acute", "W", 'Ẃ'},
|
|
|
|
{"dead_acute", "Y", 'Ý'},
|
|
|
|
{"dead_acute", "Z", 'Ź'},
|
|
|
|
{"dead_belowdot", "A", 'Ạ'},
|
|
|
|
{"dead_belowdot", "E", 'Ẹ'},
|
|
|
|
{"dead_belowdot", "I", 'Ị'},
|
|
|
|
{"dead_belowdot", "L", 'Ḷ'},
|
|
|
|
{"dead_belowdot", "O", 'Ọ'},
|
|
|
|
{"dead_belowdot", "U", 'Ụ'},
|
|
|
|
{"dead_belowdot", "Y", 'Ỵ'},
|
|
|
|
{"dead_breve", "A", 'Ă'},
|
|
|
|
{"dead_breve", "G", 'Ğ'},
|
|
|
|
{"dead_breve", "I", 'Ĭ'},
|
|
|
|
{"dead_breve", "U", 'Ŭ'},
|
|
|
|
{"dead_caron", "C", 'Č'},
|
|
|
|
{"dead_caron", "D", 'Ď'},
|
|
|
|
{"dead_caron", "E", 'Ě'},
|
|
|
|
{"dead_caron", "G", 'Ǧ'},
|
|
|
|
{"dead_caron", "L", 'Ľ'},
|
|
|
|
{"dead_caron", "N", 'Ň'},
|
|
|
|
{"dead_caron", "O", 'Ǒ'},
|
|
|
|
{"dead_caron", "R", 'Ř'},
|
|
|
|
{"dead_caron", "S", 'Š'},
|
|
|
|
{"dead_caron", "T", 'Ť'},
|
|
|
|
{"dead_caron", "Z", 'Ž'},
|
|
|
|
{"dead_cedilla", "C", 'Ç'},
|
|
|
|
{"dead_cedilla", "G", 'Ģ'},
|
|
|
|
{"dead_cedilla", "K", 'Ķ'},
|
|
|
|
{"dead_cedilla", "L", 'Ļ'},
|
|
|
|
{"dead_cedilla", "N", 'Ņ'},
|
|
|
|
{"dead_cedilla", "R", 'Ŗ'},
|
|
|
|
{"dead_cedilla", "S", 'Ş'},
|
|
|
|
{"dead_cedilla", "T", 'Ţ'},
|
|
|
|
{"dead_circumflex", "A", 'Â'},
|
|
|
|
{"dead_circumflex", "C", 'Ĉ'},
|
|
|
|
{"dead_circumflex", "E", 'Ê'},
|
|
|
|
{"dead_circumflex", "G", 'Ĝ'},
|
|
|
|
{"dead_circumflex", "H", 'Ĥ'},
|
|
|
|
{"dead_circumflex", "I", 'Î'},
|
|
|
|
{"dead_circumflex", "J", 'Ĵ'},
|
|
|
|
{"dead_circumflex", "O", 'Ô'},
|
|
|
|
{"dead_circumflex", "S", 'Ŝ'},
|
|
|
|
{"dead_circumflex", "U", 'Û'},
|
|
|
|
{"dead_circumflex", "W", 'Ŵ'},
|
|
|
|
{"dead_circumflex", "Y", 'Ŷ'},
|
|
|
|
{"dead_diaeresis", "A", 'Ä'},
|
|
|
|
{"dead_diaeresis", "E", 'Ë'},
|
|
|
|
{"dead_diaeresis", "I", 'Ï'},
|
|
|
|
{"dead_diaeresis", "O", 'Ö'},
|
|
|
|
{"dead_diaeresis", "U", 'Ü'},
|
|
|
|
{"dead_diaeresis", "W", 'Ẅ'},
|
|
|
|
{"dead_diaeresis", "Y", 'Ÿ'},
|
|
|
|
{"dead_doubleacute", "O", 'Ő'},
|
|
|
|
{"dead_doubleacute", "U", 'Ű'},
|
|
|
|
{"dead_grave", "A", 'À'},
|
|
|
|
{"dead_grave", "E", 'È'},
|
|
|
|
{"dead_grave", "I", 'Ì'},
|
|
|
|
{"dead_grave", "O", 'Ò'},
|
|
|
|
{"dead_grave", "U", 'Ù'},
|
|
|
|
{"dead_grave", "W", 'Ẁ'},
|
|
|
|
{"dead_grave", "Y", 'Ỳ'},
|
|
|
|
{"dead_hook", "A", 'Ả'},
|
|
|
|
{"dead_hook", "E", 'Ẻ'},
|
|
|
|
{"dead_hook", "I", 'Ỉ'},
|
|
|
|
{"dead_hook", "O", 'Ỏ'},
|
|
|
|
{"dead_hook", "U", 'Ủ'},
|
|
|
|
{"dead_hook", "Y", 'Ỷ'},
|
|
|
|
{"dead_horn", "O", 'Ơ'},
|
|
|
|
{"dead_horn", "T", 'Þ'},
|
|
|
|
{"dead_horn", "U", 'Ư'},
|
|
|
|
{"dead_macron", "A", 'Ā'},
|
|
|
|
{"dead_macron", "E", 'Ē'},
|
|
|
|
{"dead_macron", "I", 'Ī'},
|
|
|
|
{"dead_macron", "O", 'Ō'},
|
|
|
|
{"dead_macron", "U", 'Ū'},
|
|
|
|
{"dead_ogonek", "A", 'Ą'},
|
|
|
|
{"dead_ogonek", "E", 'Ę'},
|
|
|
|
{"dead_ogonek", "I", 'Į'},
|
|
|
|
{"dead_ogonek", "U", 'Ų'},
|
|
|
|
{"dead_stroke", "D", 'Đ'},
|
|
|
|
{"dead_stroke", "H", 'Ħ'},
|
|
|
|
{"dead_stroke", "L", 'Ł'},
|
|
|
|
{"dead_stroke", "Z", 'Ƶ'},
|
|
|
|
{"dead_tilde", "A", 'Ã'},
|
|
|
|
{"dead_tilde", "E", 'Ẽ'},
|
|
|
|
{"dead_tilde", "I", 'Ĩ'},
|
|
|
|
{"dead_tilde", "N", 'Ñ'},
|
|
|
|
{"dead_tilde", "O", 'Õ'},
|
|
|
|
{"dead_tilde", "U", 'Ũ'},
|
|
|
|
{"dead_tilde", "Y", 'Ỹ'},
|
|
|
|
}
|
|
|
|
|
2023-11-05 17:34:27 +01:00
|
|
|
func newChord(keymap *xkb.Keymap, code, level uint32) Chord {
|
2023-04-19 14:23:05 +02:00
|
|
|
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)
|
2023-11-05 17:34:27 +01:00
|
|
|
|
|
|
|
// TODO support layouts other than 0
|
|
|
|
mask := keymap.KeyGetMod(code, 0, level)
|
2023-04-19 14:23:05 +02:00
|
|
|
return Chord{
|
|
|
|
false,
|
|
|
|
(mask & altGrMask) != 0,
|
|
|
|
(mask & ctrlMask) != 0,
|
|
|
|
(mask & altMask) != 0,
|
|
|
|
(mask & shiftMask) != 0,
|
|
|
|
int(code) - 8,
|
2023-11-05 17:34:27 +01:00
|
|
|
level,
|
2023-04-19 14:23:05 +02:00
|
|
|
}
|
2022-10-20 15:21:20 +02:00
|
|
|
}
|
|
|
|
|
2023-05-11 12:03:36 +02:00
|
|
|
func initKeys(keymap *xkb.Keymap) {
|
2023-04-19 14:23:05 +02:00
|
|
|
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) {
|
2023-11-05 17:34:27 +01:00
|
|
|
chord := newChord(keymap, code, level)
|
2023-05-11 12:03:36 +02:00
|
|
|
for name, s := range linuxXSyms {
|
|
|
|
if s == sym {
|
2023-11-05 17:34:27 +01:00
|
|
|
if l, ok := LinuxKeys[name]; !ok || level < l.level {
|
2023-09-12 13:27:27 +02:00
|
|
|
LinuxKeys[name] = chord
|
|
|
|
}
|
2023-04-19 14:23:05 +02:00
|
|
|
}
|
|
|
|
}
|
2023-09-12 13:27:27 +02:00
|
|
|
name := xkb.KeysymGetName(sym)
|
2023-11-05 17:34:27 +01:00
|
|
|
if x, ok := XKeys[name]; !ok || level < x.level {
|
2023-09-12 13:27:27 +02:00
|
|
|
XKeys[name] = chord
|
|
|
|
}
|
2023-04-19 14:23:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-12 13:49:35 +02:00
|
|
|
super = XKeys["Super_L"].Key
|
|
|
|
altgr = XKeys["ISO_Level3_Shift"].Key
|
|
|
|
ctrl = XKeys["Control_L"].Key
|
|
|
|
alt = XKeys["Alt_L"].Key
|
|
|
|
shift = XKeys["Shift_L"].Key
|
2022-10-20 15:21:20 +02:00
|
|
|
}
|
|
|
|
|
2023-04-19 14:23:05 +02:00
|
|
|
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 {
|
2023-11-05 17:34:27 +01:00
|
|
|
return newChord(keymap, code, level)
|
2023-04-19 14:23:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Chord{}
|
2022-10-20 15:21:20 +02:00
|
|
|
}
|
2023-08-15 17:57:53 +02:00
|
|
|
|
|
|
|
func getDeadChords(keymap *xkb.Keymap, result rune) (Chord, Chord) {
|
|
|
|
r := unicode.ToUpper(result)
|
|
|
|
for _, d := range DeadKeyResults {
|
|
|
|
if d.Result == r {
|
|
|
|
deadKey := XKeys[d.DeadKey]
|
|
|
|
key := XKeys[d.Key]
|
|
|
|
if deadKey.Key != 0 && key.Key != 0 {
|
|
|
|
key.Shift = d.Result == result
|
|
|
|
return deadKey, key
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Chord{}, Chord{}
|
|
|
|
}
|