blob: d70f1c34317520689ccd91082fc61eaae4cd7a42 [file] [log] [blame]
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:generate stringer -type=Code
// Package key defines an event for physical keyboard keys.
//
// On-screen software keyboards do not send key events.
//
// See the golang.org/x/mobile/app package for details on the event model.
package key
import (
"fmt"
"strings"
)
// Event is a key event.
type Event struct {
// Rune is the meaning of the key event as determined by the
// operating system. The mapping is determined by system-dependent
// current layout, modifiers, lock-states, etc.
//
// If non-negative, it is a Unicode codepoint: pressing the 'a' key
// generates different Runes 'a' or 'A' (but the same Code) depending on
// the state of the shift key.
//
// If -1, the key does not generate a Unicode codepoint. To distinguish
// them, look at Code.
Rune rune
// Code is the identity of the physical key relative to a notional
// "standard" keyboard, independent of current layout, modifiers,
// lock-states, etc
//
// For standard key codes, its value matches USB HID key codes.
// Compare its value to uint32-typed constants in this package, such
// as CodeLeftShift and CodeEscape.
//
// Pressing the regular '2' key and number-pad '2' key (with Num-Lock)
// generate different Codes (but the same Rune).
Code Code
// Modifiers is a bitmask representing a set of modifier keys: ModShift,
// ModAlt, etc.
Modifiers Modifiers
// Direction is the direction of the key event: DirPress, DirRelease,
// or DirNone (for key repeats).
Direction Direction
// TODO: add a Device ID, for multiple input devices?
// TODO: add a time.Time?
}
func (e Event) String() string {
if e.Rune >= 0 {
return fmt.Sprintf("key.Event{%q (%v), %v, %v}", e.Rune, e.Code, e.Modifiers, e.Direction)
}
return fmt.Sprintf("key.Event{(%v), %v, %v}", e.Code, e.Modifiers, e.Direction)
}
// Direction is the direction of the key event.
type Direction uint8
const (
DirNone Direction = 0
DirPress Direction = 1
DirRelease Direction = 2
)
// Modifiers is a bitmask representing a set of modifier keys.
type Modifiers uint32
const (
ModShift Modifiers = 1 << 0
ModControl Modifiers = 1 << 1
ModAlt Modifiers = 1 << 2
ModMeta Modifiers = 1 << 3 // called "Command" on OS X
)
// Code is the identity of a key relative to a notional "standard" keyboard.
type Code uint32
// Physical key codes.
//
// For standard key codes, its value matches USB HID key codes.
// TODO: add missing codes.
const (
CodeUnknown Code = 0
CodeA Code = 4
CodeB Code = 5
CodeC Code = 6
CodeD Code = 7
CodeE Code = 8
CodeF Code = 9
CodeG Code = 10
CodeH Code = 11
CodeI Code = 12
CodeJ Code = 13
CodeK Code = 14
CodeL Code = 15
CodeM Code = 16
CodeN Code = 17
CodeO Code = 18
CodeP Code = 19
CodeQ Code = 20
CodeR Code = 21
CodeS Code = 22
CodeT Code = 23
CodeU Code = 24
CodeV Code = 25
CodeW Code = 26
CodeX Code = 27
CodeY Code = 28
CodeZ Code = 29
Code1 Code = 30
Code2 Code = 31
Code3 Code = 32
Code4 Code = 33
Code5 Code = 34
Code6 Code = 35
Code7 Code = 36
Code8 Code = 37
Code9 Code = 38
Code0 Code = 39
CodeReturnEnter Code = 40
CodeEscape Code = 41
CodeDeleteBackspace Code = 42
CodeTab Code = 43
CodeSpacebar Code = 44
CodeHyphenMinus Code = 45 // -
CodeEqualSign Code = 46 // =
CodeLeftSquareBracket Code = 47 // [
CodeRightSquareBracket Code = 48 // ]
CodeBackslash Code = 49 // \
CodeSemicolon Code = 51 // ;
CodeApostrophe Code = 52 // '
CodeGraveAccent Code = 53 // `
CodeComma Code = 54 // ,
CodeFullStop Code = 55 // .
CodeSlash Code = 56 // /
CodeCapsLock Code = 57
CodeF1 Code = 58
CodeF2 Code = 59
CodeF3 Code = 60
CodeF4 Code = 61
CodeF5 Code = 62
CodeF6 Code = 63
CodeF7 Code = 64
CodeF8 Code = 65
CodeF9 Code = 66
CodeF10 Code = 67
CodeF11 Code = 68
CodeF12 Code = 69
CodePause Code = 72
CodeInsert Code = 73
CodeHome Code = 74
CodePageUp Code = 75
CodeDeleteForward Code = 76
CodeEnd Code = 77
CodePageDown Code = 78
CodeRightArrow Code = 79
CodeLeftArrow Code = 80
CodeDownArrow Code = 81
CodeUpArrow Code = 82
CodeKeypadNumLock Code = 83
CodeKeypadSlash Code = 84 // /
CodeKeypadAsterisk Code = 85 // *
CodeKeypadHyphenMinus Code = 86 // -
CodeKeypadPlusSign Code = 87 // +
CodeKeypadEnter Code = 88
CodeKeypad1 Code = 89
CodeKeypad2 Code = 90
CodeKeypad3 Code = 91
CodeKeypad4 Code = 92
CodeKeypad5 Code = 93
CodeKeypad6 Code = 94
CodeKeypad7 Code = 95
CodeKeypad8 Code = 96
CodeKeypad9 Code = 97
CodeKeypad0 Code = 98
CodeKeypadFullStop Code = 99 // .
CodeKeypadEqualSign Code = 103 // =
CodeF13 Code = 104
CodeF14 Code = 105
CodeF15 Code = 106
CodeF16 Code = 107
CodeF17 Code = 108
CodeF18 Code = 109
CodeF19 Code = 110
CodeF20 Code = 111
CodeF21 Code = 112
CodeF22 Code = 113
CodeF23 Code = 114
CodeF24 Code = 115
CodeHelp Code = 117
CodeMute Code = 127
CodeVolumeUp Code = 128
CodeVolumeDown Code = 129
CodeLeftControl Code = 224
CodeLeftShift Code = 225
CodeLeftAlt Code = 226
CodeLeftGUI Code = 227
CodeRightControl Code = 228
CodeRightShift Code = 229
CodeRightAlt Code = 230
CodeRightGUI Code = 231
// The following codes are not part of the standard USB HID Usage IDs for
// keyboards. See http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
//
// Usage IDs are uint16s, so these non-standard values start at 0x10000.
// CodeCompose is the Code for a compose key, sometimes called a multi key,
// used to input non-ASCII characters such as ñ being composed of n and ~.
//
// See https://en.wikipedia.org/wiki/Compose_key
CodeCompose Code = 0x10000
)
// TODO: Given we use runes outside the unicode space, should we provide a
// printing function? Related: it's a little unfortunate that printing a
// key.Event with %v gives not very readable output like:
// {100 7 key.Modifiers() Press}
var mods = [...]struct {
m Modifiers
s string
}{
{ModShift, "Shift"},
{ModControl, "Control"},
{ModAlt, "Alt"},
{ModMeta, "Meta"},
}
func (m Modifiers) String() string {
var match []string
for _, mod := range mods {
if mod.m&m != 0 {
match = append(match, mod.s)
}
}
return "key.Modifiers(" + strings.Join(match, "|") + ")"
}
func (d Direction) String() string {
switch d {
case DirNone:
return "None"
case DirPress:
return "Press"
case DirRelease:
return "Release"
default:
return fmt.Sprintf("key.Direction(%d)", d)
}
}