x11key.go (7783B)
1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:generate go run gen.go 6 7 // x11key contains X11 numeric codes for the keyboard and mouse. 8 package x11key // import "golang.org/x/exp/shiny/driver/internal/x11key" 9 10 import ( 11 "unicode" 12 13 "golang.org/x/mobile/event/key" 14 ) 15 16 // These constants come from /usr/include/X11/X.h 17 const ( 18 ShiftMask = 1 << 0 19 LockMask = 1 << 1 20 ControlMask = 1 << 2 21 Mod1Mask = 1 << 3 22 Mod2Mask = 1 << 4 23 Mod3Mask = 1 << 5 24 Mod4Mask = 1 << 6 25 Mod5Mask = 1 << 7 26 Button1Mask = 1 << 8 27 Button2Mask = 1 << 9 28 Button3Mask = 1 << 10 29 Button4Mask = 1 << 11 30 Button5Mask = 1 << 12 31 ) 32 33 type KeysymTable [256][2]uint32 34 35 func (t *KeysymTable) Lookup(detail uint8, state uint16, numLockMod uint16) (rune, key.Code) { 36 // The key event's rune depends on whether the shift key is down. 37 unshifted := rune(t[detail][0]) 38 r := unshifted 39 if state&numLockMod != 0 && isKeypad(t[detail][1]) { 40 if state&ShiftMask == 0 { 41 r = rune(t[detail][1]) 42 } 43 } else if state&ShiftMask != 0 { 44 r = rune(t[detail][1]) 45 // In X11, a zero keysym when shift is down means to use what the 46 // keysym is when shift is up. 47 if r == 0 { 48 r = unshifted 49 } 50 } 51 52 // The key event's code is independent of whether the shift key is down. 53 var c key.Code 54 if 0 <= unshifted && unshifted < 0x80 { 55 c = asciiKeycodes[unshifted] 56 if state&LockMask != 0 { 57 r = unicode.ToUpper(r) 58 } 59 } else if kk, isKeypad := keypadKeysyms[r]; isKeypad { 60 r, c = kk.rune, kk.code 61 } else if nuk := nonUnicodeKeycodes[unshifted]; nuk != key.CodeUnknown { 62 r, c = -1, nuk 63 } else { 64 r = keysymCodePoints[r] 65 if state&LockMask != 0 { 66 r = unicode.ToUpper(r) 67 } 68 } 69 70 return r, c 71 } 72 73 func isKeypad(keysym uint32) bool { 74 return keysym >= 0xff80 && keysym <= 0xffbd 75 } 76 77 func KeyModifiers(state uint16) (m key.Modifiers) { 78 if state&ShiftMask != 0 { 79 m |= key.ModShift 80 } 81 if state&ControlMask != 0 { 82 m |= key.ModControl 83 } 84 if state&Mod1Mask != 0 { 85 m |= key.ModAlt 86 } 87 if state&Mod4Mask != 0 { 88 m |= key.ModMeta 89 } 90 return m 91 } 92 93 // These constants come from /usr/include/X11/{keysymdef,XF86keysym}.h 94 const ( 95 xkISOLeftTab = 0xfe20 96 xkBackSpace = 0xff08 97 xkTab = 0xff09 98 xkReturn = 0xff0d 99 xkEscape = 0xff1b 100 xkMultiKey = 0xff20 101 xkHome = 0xff50 102 xkLeft = 0xff51 103 xkUp = 0xff52 104 xkRight = 0xff53 105 xkDown = 0xff54 106 xkPageUp = 0xff55 107 xkPageDown = 0xff56 108 xkEnd = 0xff57 109 xkInsert = 0xff63 110 xkMenu = 0xff67 111 xkHelp = 0xff6a 112 113 xkNumLock = 0xff7f 114 xkKeypadEnter = 0xff8d 115 xkKeypadHome = 0xff95 116 xkKeypadLeft = 0xff96 117 xkKeypadUp = 0xff97 118 xkKeypadRight = 0xff98 119 xkKeypadDown = 0xff99 120 xkKeypadPageUp = 0xff9a 121 xkKeypadPageDown = 0xff9b 122 xkKeypadEnd = 0xff9c 123 xkKeypadInsert = 0xff9e 124 xkKeypadDelete = 0xff9f 125 xkKeypadEqual = 0xffbd 126 xkKeypadMultiply = 0xffaa 127 xkKeypadAdd = 0xffab 128 xkKeypadSubtract = 0xffad 129 xkKeypadDecimal = 0xffae 130 xkKeypadDivide = 0xffaf 131 xkKeypad0 = 0xffb0 132 xkKeypad1 = 0xffb1 133 xkKeypad2 = 0xffb2 134 xkKeypad3 = 0xffb3 135 xkKeypad4 = 0xffb4 136 xkKeypad5 = 0xffb5 137 xkKeypad6 = 0xffb6 138 xkKeypad7 = 0xffb7 139 xkKeypad8 = 0xffb8 140 xkKeypad9 = 0xffb9 141 142 xkF1 = 0xffbe 143 xkF2 = 0xffbf 144 xkF3 = 0xffc0 145 xkF4 = 0xffc1 146 xkF5 = 0xffc2 147 xkF6 = 0xffc3 148 xkF7 = 0xffc4 149 xkF8 = 0xffc5 150 xkF9 = 0xffc6 151 xkF10 = 0xffc7 152 xkF11 = 0xffc8 153 xkF12 = 0xffc9 154 xkShiftL = 0xffe1 155 xkShiftR = 0xffe2 156 xkControlL = 0xffe3 157 xkControlR = 0xffe4 158 xkCapsLock = 0xffe5 159 xkAltL = 0xffe9 160 xkAltR = 0xffea 161 xkSuperL = 0xffeb 162 xkSuperR = 0xffec 163 xkDelete = 0xffff 164 165 xf86xkAudioLowerVolume = 0x1008ff11 166 xf86xkAudioMute = 0x1008ff12 167 xf86xkAudioRaiseVolume = 0x1008ff13 168 ) 169 170 // nonUnicodeKeycodes maps from those xproto.Keysym values (converted to runes) 171 // that do not correspond to a Unicode code point, such as "Page Up", "F1" or 172 // "Left Shift", to key.Code values. 173 var nonUnicodeKeycodes = map[rune]key.Code{ 174 xkISOLeftTab: key.CodeTab, 175 xkBackSpace: key.CodeDeleteBackspace, 176 xkTab: key.CodeTab, 177 xkReturn: key.CodeReturnEnter, 178 xkEscape: key.CodeEscape, 179 xkHome: key.CodeHome, 180 xkLeft: key.CodeLeftArrow, 181 xkUp: key.CodeUpArrow, 182 xkRight: key.CodeRightArrow, 183 xkDown: key.CodeDownArrow, 184 xkPageUp: key.CodePageUp, 185 xkPageDown: key.CodePageDown, 186 xkEnd: key.CodeEnd, 187 xkInsert: key.CodeInsert, 188 xkMenu: key.CodeRightGUI, // TODO: CodeRightGUI or CodeMenu?? 189 xkHelp: key.CodeHelp, 190 xkNumLock: key.CodeKeypadNumLock, 191 xkMultiKey: key.CodeCompose, 192 193 xkKeypadEnter: key.CodeKeypadEnter, 194 xkKeypadHome: key.CodeHome, 195 xkKeypadLeft: key.CodeLeftArrow, 196 xkKeypadUp: key.CodeUpArrow, 197 xkKeypadRight: key.CodeRightArrow, 198 xkKeypadDown: key.CodeDownArrow, 199 xkKeypadPageUp: key.CodePageUp, 200 xkKeypadPageDown: key.CodePageDown, 201 xkKeypadEnd: key.CodeEnd, 202 xkKeypadInsert: key.CodeInsert, 203 xkKeypadDelete: key.CodeDeleteForward, 204 205 xkF1: key.CodeF1, 206 xkF2: key.CodeF2, 207 xkF3: key.CodeF3, 208 xkF4: key.CodeF4, 209 xkF5: key.CodeF5, 210 xkF6: key.CodeF6, 211 xkF7: key.CodeF7, 212 xkF8: key.CodeF8, 213 xkF9: key.CodeF9, 214 xkF10: key.CodeF10, 215 xkF11: key.CodeF11, 216 xkF12: key.CodeF12, 217 218 xkShiftL: key.CodeLeftShift, 219 xkShiftR: key.CodeRightShift, 220 xkControlL: key.CodeLeftControl, 221 xkControlR: key.CodeRightControl, 222 xkCapsLock: key.CodeCapsLock, 223 xkAltL: key.CodeLeftAlt, 224 xkAltR: key.CodeRightAlt, 225 xkSuperL: key.CodeLeftGUI, 226 xkSuperR: key.CodeRightGUI, 227 228 xkDelete: key.CodeDeleteForward, 229 230 xf86xkAudioRaiseVolume: key.CodeVolumeUp, 231 xf86xkAudioLowerVolume: key.CodeVolumeDown, 232 xf86xkAudioMute: key.CodeMute, 233 } 234 235 // asciiKeycodes maps lower-case ASCII runes to key.Code values. 236 var asciiKeycodes = [0x80]key.Code{ 237 'a': key.CodeA, 238 'b': key.CodeB, 239 'c': key.CodeC, 240 'd': key.CodeD, 241 'e': key.CodeE, 242 'f': key.CodeF, 243 'g': key.CodeG, 244 'h': key.CodeH, 245 'i': key.CodeI, 246 'j': key.CodeJ, 247 'k': key.CodeK, 248 'l': key.CodeL, 249 'm': key.CodeM, 250 'n': key.CodeN, 251 'o': key.CodeO, 252 'p': key.CodeP, 253 'q': key.CodeQ, 254 'r': key.CodeR, 255 's': key.CodeS, 256 't': key.CodeT, 257 'u': key.CodeU, 258 'v': key.CodeV, 259 'w': key.CodeW, 260 'x': key.CodeX, 261 'y': key.CodeY, 262 'z': key.CodeZ, 263 264 '1': key.Code1, 265 '2': key.Code2, 266 '3': key.Code3, 267 '4': key.Code4, 268 '5': key.Code5, 269 '6': key.Code6, 270 '7': key.Code7, 271 '8': key.Code8, 272 '9': key.Code9, 273 '0': key.Code0, 274 275 ' ': key.CodeSpacebar, 276 '-': key.CodeHyphenMinus, 277 '=': key.CodeEqualSign, 278 '[': key.CodeLeftSquareBracket, 279 ']': key.CodeRightSquareBracket, 280 '\\': key.CodeBackslash, 281 ';': key.CodeSemicolon, 282 '\'': key.CodeApostrophe, 283 '`': key.CodeGraveAccent, 284 ',': key.CodeComma, 285 '.': key.CodeFullStop, 286 '/': key.CodeSlash, 287 } 288 289 type keypadKeysym struct { 290 rune rune 291 code key.Code 292 } 293 294 var keypadKeysyms = map[rune]keypadKeysym{ 295 xkKeypadEqual: {'=', key.CodeKeypadEqualSign}, 296 xkKeypadMultiply: {'*', key.CodeKeypadAsterisk}, 297 xkKeypadAdd: {'+', key.CodeKeypadPlusSign}, 298 xkKeypadSubtract: {'-', key.CodeKeypadHyphenMinus}, 299 xkKeypadDecimal: {'.', key.CodeKeypadFullStop}, 300 xkKeypadDivide: {'/', key.CodeKeypadSlash}, 301 xkKeypad0: {'0', key.CodeKeypad0}, 302 xkKeypad1: {'1', key.CodeKeypad1}, 303 xkKeypad2: {'2', key.CodeKeypad2}, 304 xkKeypad3: {'3', key.CodeKeypad3}, 305 xkKeypad4: {'4', key.CodeKeypad4}, 306 xkKeypad5: {'5', key.CodeKeypad5}, 307 xkKeypad6: {'6', key.CodeKeypad6}, 308 xkKeypad7: {'7', key.CodeKeypad7}, 309 xkKeypad8: {'8', key.CodeKeypad8}, 310 xkKeypad9: {'9', key.CodeKeypad9}, 311 }