zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

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 }