{-# LANGUAGE DeriveAnyClass #-}
{-|
Module      : KMonad.Keyboard.Keycode
Description : Description of all possible keycodes.
Copyright   : (c) David Janssen, 2019
License     : MIT
Maintainer  : janssen.dhj@gmail.com
Stability   : experimental
Portability : portable

'Keycode's are represented as a large enum lining up the keycodes defined in the Linux headers.

-}
module KMonad.Keyboard.Keycode
  ( -- * The core Keycode type
    -- $typ
    Keycode(..)

    -- * Naming utilities to refer to Keycodes
    -- $names
  , keyNames

  )
where

import KMonad.Prelude

import qualified KMonad.Util.MultiMap     as Q
import qualified RIO.HashSet       as S
import qualified RIO.Text          as T
import qualified RIO.Text.Partial  as T (head)

--------------------------------------------------------------------------------
-- $typ
--
-- 'Keycode's are defined as a large ADT that mimics the keycodes from the Linux
-- headers:
-- https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h.
--
-- Anywhere there are missing regions in the Linux headers, we've defined
-- @MissingXX@ values for the ADT.
--
-- Calling 'RIO.Partial.toEnum' on a Linux keycode value should produce the
-- corresponding 'Keycode' value and vice-versa.

-- | The 'Keycode' datatype, as an 'Enum' of all the values a 'Keycode' can take.
data Keycode
  = KeyReserved
  | KeyEsc
  | Key1
  | Key2
  | Key3
  | Key4
  | Key5
  | Key6
  | Key7
  | Key8
  | Key9
  | Key0
  | KeyMinus
  | KeyEqual
  | KeyBackspace
  | KeyTab
  | KeyQ
  | KeyW
  | KeyE
  | KeyR
  | KeyT
  | KeyY
  | KeyU
  | KeyI
  | KeyO
  | KeyP
  | KeyLeftBrace
  | KeyRightBrace
  | KeyEnter
  | KeyLeftCtrl
  | KeyA
  | KeyS
  | KeyD
  | KeyF
  | KeyG
  | KeyH
  | KeyJ
  | KeyK
  | KeyL
  | KeySemicolon
  | KeyApostrophe
  | KeyGrave
  | KeyLeftShift
  | KeyBackslash
  | KeyZ
  | KeyX
  | KeyC
  | KeyV
  | KeyB
  | KeyN
  | KeyM
  | KeyComma
  | KeyDot
  | KeySlash
  | KeyRightShift
  | KeyKpAsterisk
  | KeyLeftAlt
  | KeySpace
  | KeyCapsLock
  | KeyF1
  | KeyF2
  | KeyF3
  | KeyF4
  | KeyF5
  | KeyF6
  | KeyF7
  | KeyF8
  | KeyF9
  | KeyF10
  | KeyNumLock
  | KeyScrollLock
  | KeyKp7
  | KeyKp8
  | KeyKp9
  | KeyKpMinus
  | KeyKp4
  | KeyKp5
  | KeyKp6
  | KeyKpPlus
  | KeyKp1
  | KeyKp2
  | KeyKp3
  | KeyKp0
  | KeyKpDot
  | Missing84
  | KeyZenkakuHankaku
  | Key102nd
  | KeyF11
  | KeyF12
  | KeyRo
  | KeyKatakana
  | KeyHiragana
  | KeyHenkan
  | KeyKatakanaHiragana
  | KeyMuhenkan
  | KeyKpjpcomma
  | KeyKpEnter
  | KeyRightCtrl
  | KeyKpSlash
  | KeySysRq
  | KeyRightAlt
  | KeyLinefeed
  | KeyHome
  | KeyUp
  | KeyPageUp
  | KeyLeft
  | KeyRight
  | KeyEnd
  | KeyDown
  | KeyPageDown
  | KeyInsert
  | KeyDelete
  | KeyMacro
  | KeyMute
  | KeyVolumeDown
  | KeyVolumeUp
  | KeyPower
  | KeyKpEqual
  | KeyKpPlusMinus
  | KeyPause
  | KeyScale
  | KeyKpComma
  | KeyHangeul
  | KeyHanja
  | KeyYen
  | KeyLeftMeta
  | KeyRightMeta
  | KeyCompose
  | KeyStop
  | KeyAgain
  | KeyProps
  | KeyUndo
  | KeyFront
  | KeyCopy
  | KeyOpen
  | KeyPaste
  | KeyFind
  | KeyCut
  | KeyHelp
  | KeyMenu
  | KeyCalc
  | KeySetup
  | KeySleep
  | KeyWakeUp
  | KeyFile
  | KeySendFile
  | KeyDeleteFile
  | KeyXfer
  | KeyProg1
  | KeyProg2
  | KeyWww
  | KeyMsDos
  | KeyCoffee
  | KeyDirection
  | KeyCycleWindows
  | KeyMail
  | KeyBookmarks
  | KeyComputer
  | KeyBack
  | KeyForward
  | KeyCloseCd
  | KeyEjectCd
  | KeyEjectCloseCd
  | KeyNextSong
  | KeyPlayPause
  | KeyPreviousSong
  | KeyStopCd
  | KeyRecord
  | KeyRewind
  | KeyPhone
  | KeyIso
  | KeyConfig
  | KeyHomepage
  | KeyRefresh
  | KeyExit
  | KeyMove
  | KeyEdit
  | KeyScrollUp
  | KeyScrollDown
  | KeyKpLeftParen
  | KeyKpRightParen
  | KeyNew
  | KeyRedo
  | KeyF13
  | KeyF14
  | KeyF15
  | KeyF16
  | KeyF17
  | KeyF18
  | KeyF19
  | KeyF20
  | KeyF21
  | KeyF22
  | KeyF23
  | KeyF24
  | Missing195
  | Missing196
  | Missing197
  | Missing198
  | Missing199
  | KeyPlayCd
  | KeyPauseCd
  | KeyProg3
  | KeyProg4
  | KeyDashboard
  | KeySuspend
  | KeyClose
  | KeyPlay
  | KeyFastForward
  | KeyBassBoost
  | KeyPrint
  | KeyHp
  | KeyCamera
  | KeySound
  | KeyQuestion
  | KeyEmail
  | KeyChat
  | KeySearch
  | KeyConnect
  | KeyFinance
  | KeySport
  | KeyShop
  | KeyAlterase
  | KeyCancel
  | KeyBrightnessDown
  | KeyBrightnessUp
  | KeyMedia
  | KeySwitchVideoMode
  | KeyKbdIllumToggle
  | KeyKbdIllumDown
  | KeyKbdIllumUp
  | KeySend
  | KeyReply
  | KeyForwardMail
  | KeySave
  | KeyDocuments
  | KeyBattery
  | KeyBluetooth
  | KeyWlan
  | KeyUwb
  | KeyUnknown
  | KeyVideoNext
  | KeyVideoPrev
  | KeyBrightnessCycle
  | KeyBrightnessZero
  | KeyDisplayOff
  | KeyWimax
  | KeyRfkill
  | KeyMicmute
  | Missing249
  | Missing250
  | Missing251
  | Missing252
  | Missing253
  | Missing254
  | Missing255
  | Btn0
  | Btn1
  | Btn2
  | Btn3
  | Btn4
  | Btn5
  | Btn6
  | Btn7
  | Btn8
  | Btn9
  | Missing0x10a
  | Missing0x10b
  | Missing0x10c
  | Missing0x10d
  | Missing0x10e
  | Missing0x10f
  | BtnLeft
  | BtnRight
  | BtnMiddle
  | BtnSide
  | BtnExtra
  | BtnForward
  | BtnBack
  | BtnTask
  | Missing0x118
  | Missing0x119
  | Missing0x11a
  | Missing0x11b
  | Missing0x11c
  | Missing0x11d
  | Missing0x11e
  | Missing0x11f
  | BtnJoystick
  | BtnThumb
  | BtnThumb2
  | BtnTop
  | BtnTop2
  | BtnPinkie
  | BtnBase
  | BtnBase2
  | BtnBase3
  | BtnBase4
  | BtnBase5
  | BtnBase6
  | Missing0x12c
  | Missing0x12d
  | Missing0x12e
  | BtnDead
  | BtnGamepad
  | BtnB
  | BtnC
  | BtnX
  | BtnY
  | BtnZ
  | BtnTL
  | BtnTR
  | BtnTL2
  | BtnTR2
  | BtnSelect
  | BtnStart
  | BtnMode
  | BtnThumbL
  | BtnThumbR
  | Missing0x13f
  | BtnDigi
  | BtnToolRubber
  | BtnToolBrush
  | BtnToolPencil
  | BtnToolAirbrush
  | BtnToolFinger
  | BtnToolMouse
  | BtnToolLens
  | BtnToolQuinttap
  | BtnStylus3
  | BtnTouch
  | BtnStylus
  | BtnStylus2
  | BtnToolDoubletap
  | BtnToolTripletap
  | BtnToolQuadtap
  | BtnGearDown
  | BtnGearUp
  | Missing0x152
  | Missing0x153
  | Missing0x154
  | Missing0x155
  | Missing0x156
  | Missing0x157
  | Missing0x158
  | Missing0x159
  | Missing0x15a
  | Missing0x15b
  | Missing0x15c
  | Missing0x15d
  | Missing0x15e
  | Missing0x15f
  | KeyOk
  | KeySelect
  | KeyGoTo
  | KeyClear
  | KeyPower2
  | KeyOption
  | KeyInfo
  | KeyTime
  | KeyVendor
  | KeyArchive
  | KeyProgram
  | KeyChannel
  | KeyFavorites
  | KeyEpg
  | KeyPvr
  | KeyMhp
  | KeyLanguage
  | KeyTitle
  | KeySubtitle
  | KeyAngle
  | KeyZoom
  | KeyMode
  | KeyKeyboard
  | KeyScreen
  | KeyPc
  | KeyTv
  | KeyTv2
  | KeyVcr
  | KeyVcr2
  | KeySat
  | KeySat2
  | KeyCd
  | KeyTape
  | KeyRadio
  | KeyTuner
  | KeyPlayer
  | KeyText
  | KeyDvd
  | KeyAux
  | KeyMp3
  | KeyAudio
  | KeyVideo
  | KeyDirectory
  | KeyList
  | KeyMemo
  | KeyCalendar
  | KeyRed
  | KeyGreen
  | KeyYellow
  | KeyBlue
  | KeyChannelUp
  | KeyChannelDown
  | KeyFirst
  | KeyLast
  | KeyAb
  | KeyNextTask -- Should be `KeyNext` but conflicts with alias for `KeyNextSong`. So we take the HID Name
  | KeyRestart
  | KeySlow
  | KeyShuffle
  | KeyBreak
  | KeyPreviousTask -- See `KeyNextTask`
  | KeyDigits
  | KeyTeen
  | KeyTwen
  | KeyVideoPhone
  | KeyGames
  | KeyZoomIn
  | KeyZoomOut
  | KeyZoomReset
  | KeyWordProcessor
  | KeyEditor
  | KeySpreadSheet
  | KeyGraphicsEditor
  | KeyPresentation
  | KeyDatabase
  | KeyNews
  | KeyVoicemail
  | KeyAddressBook
  | KeyMessenger
  | KeyBrightnessToggle
  | KeySpellCheck
  | KeyLogoff
  | KeyDollar
  | KeyEuro
  | KeyFrameBack
  | KeyFrameForward
  | KeyContextMenu
  | KeyMediaRepeat
  | Key10channelsUp
  | Key10channelsDown
  | KeyImages
  | Missing0x1bb
  | KeyNotificationCenter
  | KeyPickupPhone
  | KeyHangupPhone
  | Missing0x1bf
  | KeyDelEol
  | KeyDelEos
  | KeyInsLine
  | KeyDelLine
  | Missing0x1c4
  | Missing0x1c5
  | Missing0x1c6
  | Missing0x1c7
  | Missing0x1c8
  | Missing0x1c9
  | Missing0x1ca
  | Missing0x1cb
  | Missing0x1cc
  | Missing0x1cd
  | Missing0x1ce
  | Missing0x1cf
  | KeyFn
  | KeyFnEsc
  | KeyFnF1
  | KeyFnF2
  | KeyFnF3
  | KeyFnF4
  | KeyFnF5
  | KeyFnF6
  | KeyFnF7
  | KeyFnF8
  | KeyFnF9
  | KeyFnF10
  | KeyFnF11
  | KeyFnF12
  | KeyFn1
  | KeyFn2
  | KeyFnD
  | KeyFnE
  | KeyFnF
  | KeyFnS
  | KeyFnB
  | KeyFnRightShift
  | Missing0x1e6
  | Missing0x1e7
  | Missing0x1e8
  | Missing0x1e9
  | Missing0x1ea
  | Missing0x1eb
  | Missing0x1ec
  | Missing0x1ed
  | Missing0x1ee
  | Missing0x1ef
  | Missing0x1f0
  | KeyBrlDot1
  | KeyBrlDot2
  | KeyBrlDot3
  | KeyBrlDot4
  | KeyBrlDot5
  | KeyBrlDot6
  | KeyBrlDot7
  | KeyBrlDot8
  | KeyBrlDot9
  | KeyBrlDot10
  | Missing0x1fb
  | Missing0x1fc
  | Missing0x1fd
  | Missing0x1fe
  | Missing0x1ff
  | KeyNumeric0
  | KeyNumeric1
  | KeyNumeric2
  | KeyNumeric3
  | KeyNumeric4
  | KeyNumeric5
  | KeyNumeric6
  | KeyNumeric7
  | KeyNumeric8
  | KeyNumeric9
  | KeyNumericStar
  | KeyNumericPound
  | KeyNumericA
  | KeyNumericB
  | KeyNumericC
  | KeyNumericD
  | KeyCameraFocus
  | KeyWpsButton
  | KeyTouchpadToggle
  | KeyTouchpadOn
  | KeyTouchpadOff
  | KeyCameraZoomIn
  | KeyCameraZoomOut
  | KeyCameraUp
  | KeyCameraDown
  | KeyCameraLeft
  | KeyCameraRight
  | KeyAttendantOn
  | KeyAttendantOff
  | KeyAttendantToggle
  | KeyLightsToggle
  | Missing0x21f
  | BtnDpadUp
  | BtnDpadDown
  | BtnDpadLeft
  | BtnDpadRight
  | Missing0x224
  | Missing0x225
  | Missing0x226
  | Missing0x227
  | Missing0x228
  | Missing0x229
  | Missing0x22a
  | Missing0x22b
  | Missing0x22c
  | Missing0x22d
  | Missing0x22e
  | Missing0x22f
  | KeyAlsToggle
  | KeyRotateLockToggle
  | KeyRefreshRateToggle
  | Missing0x233
  | Missing0x234
  | Missing0x235
  | Missing0x236
  | Missing0x237
  | Missing0x238
  | Missing0x239
  | Missing0x23a
  | Missing0x23b
  | Missing0x23c
  | Missing0x23d
  | Missing0x23e
  | Missing0x23f
  | KeyButtonconfig
  | KeyTaskmanager
  | KeyJournal
  | KeyControlPanel
  | KeyAppSelect
  | KeyScreenSaver
  | KeyVoicecommand
  | KeyAssistant
  | KeyKbdLayoutNext
  | KeyEmojiPicker
  | KeyDictate
  | KeyCameraAccessEnable
  | KeyCameraAccessDisable
  | KeyCameraAccessToggle
  | KeyAccessibility
  | KeyDoNotDisturb
  | KeyBrightnessMin
  | KeyBrightnessMax
  | Missing0x252
  | Missing0x253
  | Missing0x254
  | Missing0x255
  | Missing0x256
  | Missing0x257
  | Missing0x258
  | Missing0x259
  | Missing0x25a
  | Missing0x25b
  | Missing0x25c
  | Missing0x25d
  | Missing0x25e
  | Missing0x25f
  | KeyKbdInputAssistPrev
  | KeyKbdInputAssistNext
  | KeyKbdInputAssistPrevgroup
  | KeyKbdInputAssistNextgroup
  | KeyKbdInputAssistAccept
  | KeyKbdInputAssistCancel
  | KeyRightUp
  | KeyRightDown
  | KeyLeftUp
  | KeyLeftDown
  | KeyRootMenu
  | KeyMediaTopMenu
  | KeyNumeric11
  | KeyNumeric12
  | KeyAudioDesc
  | Key3dMode
  | KeyNextFavorite
  | KeyStopRecord
  | KeyPauseRecord
  | KeyVod
  | KeyUnmute
  | KeyFastreverse
  | KeySlowreverse
  | KeyData
  | KeyOnScreenKeyboard
  | KeyPrivacyScreenToggle
  | KeySelectiveScreenshot
  | KeyNextElement
  | KeyPreviousElement
  | KeyAutopilotEngageToggle
  | KeyMarkWaypoint
  | KeySos
  | KeyNavChart
  | KeyFishingChart
  | KeySingleRangeRadar
  | KeyDualRangeRadar
  | KeyRadarOverlay
  | KeyTraditionalSonar
  | KeyClearvuSonar
  | KeySidevuSonar
  | KeyNavInfo
  | KeyBrightnessMenu
  | Missing0x28a
  | Missing0x28b
  | Missing0x28c
  | Missing0x28d
  | Missing0x28e
  | Missing0x28f
  | KeyMacro1
  | KeyMacro2
  | KeyMacro3
  | KeyMacro4
  | KeyMacro5
  | KeyMacro6
  | KeyMacro7
  | KeyMacro8
  | KeyMacro9
  | KeyMacro10
  | KeyMacro11
  | KeyMacro12
  | KeyMacro13
  | KeyMacro14
  | KeyMacro15
  | KeyMacro16
  | KeyMacro17
  | KeyMacro18
  | KeyMacro19
  | KeyMacro20
  | KeyMacro21
  | KeyMacro22
  | KeyMacro23
  | KeyMacro24
  | KeyMacro25
  | KeyMacro26
  | KeyMacro27
  | KeyMacro28
  | KeyMacro29
  | KeyMacro30
  | Missing0x2ae
  | Missing0x2af
  | KeyMacroRecordStart
  | KeyMacroRecordStop
  | KeyMacroPresetCycle
  | KeyMacroPreset1
  | KeyMacroPreset2
  | KeyMacroPreset3
  | Missing0x2b6
  | Missing0x2b7
  | KeyKbdLcdMenu1
  | KeyKbdLcdMenu2
  | KeyKbdLcdMenu3
  | KeyKbdLcdMenu4
  | KeyKbdLcdMenu5
  | Missing0x2bd
  | Missing0x2be
  | Missing0x2bf
  | BtnTriggerHappy
  | BtnTriggerHappy2
  | BtnTriggerHappy3
  | BtnTriggerHappy4
  | BtnTriggerHappy5
  | BtnTriggerHappy6
  | BtnTriggerHappy7
  | BtnTriggerHappy8
  | BtnTriggerHappy9
  | BtnTriggerHappy10
  | BtnTriggerHappy11
  | BtnTriggerHappy12
  | BtnTriggerHappy13
  | BtnTriggerHappy14
  | BtnTriggerHappy15
  | BtnTriggerHappy16
  | BtnTriggerHappy17
  | BtnTriggerHappy18
  | BtnTriggerHappy19
  | BtnTriggerHappy20
  | BtnTriggerHappy21
  | BtnTriggerHappy22
  | BtnTriggerHappy23
  | BtnTriggerHappy24
  | BtnTriggerHappy25
  | BtnTriggerHappy26
  | BtnTriggerHappy27
  | BtnTriggerHappy28
  | BtnTriggerHappy29
  | BtnTriggerHappy30
  | BtnTriggerHappy31
  | BtnTriggerHappy32
  | BtnTriggerHappy33
  | BtnTriggerHappy34
  | BtnTriggerHappy35
  | BtnTriggerHappy36
  | BtnTriggerHappy37
  | BtnTriggerHappy38
  | BtnTriggerHappy39
  | BtnTriggerHappy40
  | Missing0x2e8
  | Missing0x2e9
  | Missing0x2ea
  | Missing0x2eb
  | Missing0x2ec
  | Missing0x2ed
  | Missing0x2ee
  | Missing0x2ef
  | Missing0x2f0
  | Missing0x2f1
  | Missing0x2f2
  | Missing0x2f3
  | Missing0x2f4
  | Missing0x2f5
  | Missing0x2f6
  | Missing0x2f7
  | Missing0x2f8
  | Missing0x2f9
  | Missing0x2fa
  | Missing0x2fb
  | Missing0x2fc
  | Missing0x2fd
  | Missing0x2fe
  -- Darwin
  | KeyLaunchpad
  | KeyMissionCtrl
  | KeySpotlight
  | KeyDictation
  deriving (Keycode -> Keycode -> Bool
(Keycode -> Keycode -> Bool)
-> (Keycode -> Keycode -> Bool) -> Eq Keycode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Keycode -> Keycode -> Bool
== :: Keycode -> Keycode -> Bool
$c/= :: Keycode -> Keycode -> Bool
/= :: Keycode -> Keycode -> Bool
Eq, Int -> Keycode -> ShowS
[Keycode] -> ShowS
Keycode -> String
(Int -> Keycode -> ShowS)
-> (Keycode -> String) -> ([Keycode] -> ShowS) -> Show Keycode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Keycode -> ShowS
showsPrec :: Int -> Keycode -> ShowS
$cshow :: Keycode -> String
show :: Keycode -> String
$cshowList :: [Keycode] -> ShowS
showList :: [Keycode] -> ShowS
Show, Keycode
Keycode -> Keycode -> Bounded Keycode
forall a. a -> a -> Bounded a
$cminBound :: Keycode
minBound :: Keycode
$cmaxBound :: Keycode
maxBound :: Keycode
Bounded, Int -> Keycode
Keycode -> Int
Keycode -> [Keycode]
Keycode -> Keycode
Keycode -> Keycode -> [Keycode]
Keycode -> Keycode -> Keycode -> [Keycode]
(Keycode -> Keycode)
-> (Keycode -> Keycode)
-> (Int -> Keycode)
-> (Keycode -> Int)
-> (Keycode -> [Keycode])
-> (Keycode -> Keycode -> [Keycode])
-> (Keycode -> Keycode -> [Keycode])
-> (Keycode -> Keycode -> Keycode -> [Keycode])
-> Enum Keycode
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Keycode -> Keycode
succ :: Keycode -> Keycode
$cpred :: Keycode -> Keycode
pred :: Keycode -> Keycode
$ctoEnum :: Int -> Keycode
toEnum :: Int -> Keycode
$cfromEnum :: Keycode -> Int
fromEnum :: Keycode -> Int
$cenumFrom :: Keycode -> [Keycode]
enumFrom :: Keycode -> [Keycode]
$cenumFromThen :: Keycode -> Keycode -> [Keycode]
enumFromThen :: Keycode -> Keycode -> [Keycode]
$cenumFromTo :: Keycode -> Keycode -> [Keycode]
enumFromTo :: Keycode -> Keycode -> [Keycode]
$cenumFromThenTo :: Keycode -> Keycode -> Keycode -> [Keycode]
enumFromThenTo :: Keycode -> Keycode -> Keycode -> [Keycode]
Enum, Eq Keycode
Eq Keycode =>
(Keycode -> Keycode -> Ordering)
-> (Keycode -> Keycode -> Bool)
-> (Keycode -> Keycode -> Bool)
-> (Keycode -> Keycode -> Bool)
-> (Keycode -> Keycode -> Bool)
-> (Keycode -> Keycode -> Keycode)
-> (Keycode -> Keycode -> Keycode)
-> Ord Keycode
Keycode -> Keycode -> Bool
Keycode -> Keycode -> Ordering
Keycode -> Keycode -> Keycode
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Keycode -> Keycode -> Ordering
compare :: Keycode -> Keycode -> Ordering
$c< :: Keycode -> Keycode -> Bool
< :: Keycode -> Keycode -> Bool
$c<= :: Keycode -> Keycode -> Bool
<= :: Keycode -> Keycode -> Bool
$c> :: Keycode -> Keycode -> Bool
> :: Keycode -> Keycode -> Bool
$c>= :: Keycode -> Keycode -> Bool
>= :: Keycode -> Keycode -> Bool
$cmax :: Keycode -> Keycode -> Keycode
max :: Keycode -> Keycode -> Keycode
$cmin :: Keycode -> Keycode -> Keycode
min :: Keycode -> Keycode -> Keycode
Ord, (forall x. Keycode -> Rep Keycode x)
-> (forall x. Rep Keycode x -> Keycode) -> Generic Keycode
forall x. Rep Keycode x -> Keycode
forall x. Keycode -> Rep Keycode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Keycode -> Rep Keycode x
from :: forall x. Keycode -> Rep Keycode x
$cto :: forall x. Rep Keycode x -> Keycode
to :: forall x. Rep Keycode x -> Keycode
Generic, Eq Keycode
Eq Keycode =>
(Int -> Keycode -> Int) -> (Keycode -> Int) -> Hashable Keycode
Int -> Keycode -> Int
Keycode -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Keycode -> Int
hashWithSalt :: Int -> Keycode -> Int
$chash :: Keycode -> Int
hash :: Keycode -> Int
Hashable, Typeable, Typeable Keycode
Typeable Keycode =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Keycode -> c Keycode)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Keycode)
-> (Keycode -> Constr)
-> (Keycode -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Keycode))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Keycode))
-> ((forall b. Data b => b -> b) -> Keycode -> Keycode)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Keycode -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Keycode -> r)
-> (forall u. (forall d. Data d => d -> u) -> Keycode -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Keycode -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Keycode -> m Keycode)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Keycode -> m Keycode)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Keycode -> m Keycode)
-> Data Keycode
Keycode -> Constr
Keycode -> DataType
(forall b. Data b => b -> b) -> Keycode -> Keycode
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Keycode -> u
forall u. (forall d. Data d => d -> u) -> Keycode -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Keycode -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Keycode -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Keycode
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Keycode -> c Keycode
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Keycode)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Keycode)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Keycode -> c Keycode
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Keycode -> c Keycode
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Keycode
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Keycode
$ctoConstr :: Keycode -> Constr
toConstr :: Keycode -> Constr
$cdataTypeOf :: Keycode -> DataType
dataTypeOf :: Keycode -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Keycode)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Keycode)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Keycode)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Keycode)
$cgmapT :: (forall b. Data b => b -> b) -> Keycode -> Keycode
gmapT :: (forall b. Data b => b -> b) -> Keycode -> Keycode
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Keycode -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Keycode -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Keycode -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Keycode -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Keycode -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Keycode -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Keycode -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Keycode -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Keycode -> m Keycode
Data)


instance Display Keycode where
  textDisplay :: Keycode -> Text
textDisplay Keycode
c = (\Text
t -> Text
"<" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
">") (Text -> Text) -> (Maybe Text -> Text) -> Maybe Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (Keycode -> Text
forall a. Show a => a -> Text
tshow Keycode
c)
    (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Getting (Endo (Endo (Maybe Text))) (Maybe (HashSet Text)) Text
-> (Text -> Text -> Ordering) -> Maybe (HashSet Text) -> Maybe Text
forall a s.
Getting (Endo (Endo (Maybe a))) s a
-> (a -> a -> Ordering) -> s -> Maybe a
minimumByOf ((HashSet Text -> Const (Endo (Endo (Maybe Text))) (HashSet Text))
-> Maybe (HashSet Text)
-> Const (Endo (Endo (Maybe Text))) (Maybe (HashSet Text))
forall a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Maybe a) (f (Maybe b))
_Just ((HashSet Text -> Const (Endo (Endo (Maybe Text))) (HashSet Text))
 -> Maybe (HashSet Text)
 -> Const (Endo (Endo (Maybe Text))) (Maybe (HashSet Text)))
-> ((Text -> Const (Endo (Endo (Maybe Text))) Text)
    -> HashSet Text -> Const (Endo (Endo (Maybe Text))) (HashSet Text))
-> Getting (Endo (Endo (Maybe Text))) (Maybe (HashSet Text)) Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const (Endo (Endo (Maybe Text))) Text)
-> HashSet Text -> Const (Endo (Endo (Maybe Text))) (HashSet Text)
forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
IndexedFold Int (HashSet Text) Text
folded) Text -> Text -> Ordering
cmpName (MultiMap Keycode Text
keyNames MultiMap Keycode Text
-> Getting
     (Maybe (HashSet Text))
     (MultiMap Keycode Text)
     (Maybe (HashSet Text))
-> Maybe (HashSet Text)
forall s a. s -> Getting a s a -> a
^. Index (MultiMap Keycode Text)
-> Lens'
     (MultiMap Keycode Text) (Maybe (IxValue (MultiMap Keycode Text)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (MultiMap Keycode Text)
Keycode
c)
    where cmpName :: Text -> Text -> Ordering
cmpName Text
a Text
b =
            -- Prefer the shortest, and if equal, lowercased version
            case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Text -> Int
T.length Text
a) (Text -> Int
T.length Text
b) of
              Ordering
EQ -> Char -> Char -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (HasCallStack => Text -> Char
Text -> Char
T.head Text
b) (HasCallStack => Text -> Char
Text -> Char
T.head Text
a)
              Ordering
o  -> Ordering
o

--------------------------------------------------------------------------------
-- $sets

-- | The set of all existing 'Keycode'
kcAll :: S.HashSet Keycode
kcAll :: HashSet Keycode
kcAll = [Keycode] -> HashSet Keycode
forall a. (Eq a, Hashable a) => [a] -> HashSet a
S.fromList [Keycode
forall a. Bounded a => a
minBound .. Keycode
forall a. Bounded a => a
maxBound]

-- | The set of all 'Keycode' that are not of the MissingXX pattern
kcNotMissing :: S.HashSet Keycode
kcNotMissing :: HashSet Keycode
kcNotMissing = [Keycode] -> HashSet Keycode
forall a. (Eq a, Hashable a) => [a] -> HashSet a
S.fromList ([Keycode] -> HashSet Keycode) -> [Keycode] -> HashSet Keycode
forall a b. (a -> b) -> a -> b
$ HashSet Keycode
kcAll HashSet Keycode
-> Getting (Endo [Keycode]) (HashSet Keycode) Keycode -> [Keycode]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. Getting (Endo [Keycode]) (HashSet Keycode) Keycode
forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
IndexedFold Int (HashSet Keycode) Keycode
folded Getting (Endo [Keycode]) (HashSet Keycode) Keycode
-> ((Keycode -> Const (Endo [Keycode]) Keycode)
    -> Keycode -> Const (Endo [Keycode]) Keycode)
-> Getting (Endo [Keycode]) (HashSet Keycode) Keycode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Keycode -> Bool)
-> (Keycode -> Const (Endo [Keycode]) Keycode)
-> Keycode
-> Const (Endo [Keycode]) Keycode
forall (p :: * -> * -> *) (f :: * -> *) a.
(Choice p, Applicative f) =>
(a -> Bool) -> Optic' p f a a
filtered (Text -> Text -> Bool
T.isPrefixOf Text
"Key" (Text -> Bool) -> (Keycode -> Text) -> Keycode -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Keycode -> Text
forall a. Show a => a -> Text
tshow)

--------------------------------------------------------------------------------
-- $names

-- | Helper function to generate easy name maps
nameKC :: Foldable t
  => (Keycode -> Text)
  -> t Keycode
  -> Q.MultiMap Keycode Text
nameKC :: forall (t :: * -> *).
Foldable t =>
(Keycode -> Text) -> t Keycode -> MultiMap Keycode Text
nameKC Keycode -> Text
f = [(Keycode, [Text])] -> MultiMap Keycode Text
forall (t1 :: * -> *) (t2 :: * -> *) k v.
(Foldable t1, Foldable t2, CanMM k v) =>
t1 (k, t2 v) -> MultiMap k v
Q.mkMultiMap ([(Keycode, [Text])] -> MultiMap Keycode Text)
-> (t Keycode -> [(Keycode, [Text])])
-> t Keycode
-> MultiMap Keycode Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Keycode -> (Keycode, [Text])) -> [Keycode] -> [(Keycode, [Text])]
forall a b. (a -> b) -> [a] -> [b]
map Keycode -> (Keycode, [Text])
go ([Keycode] -> [(Keycode, [Text])])
-> (t Keycode -> [Keycode]) -> t Keycode -> [(Keycode, [Text])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t Keycode -> [Keycode]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
  where go :: Keycode -> (Keycode, [Text])
go Keycode
k = (Keycode
k, [Keycode -> Text
f Keycode
k, Text -> Text
T.toLower (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Keycode -> Text
f Keycode
k])

-- | A collection of 'Keycode' to 'Text' mappings
keyNames :: Q.MultiMap Keycode Text
keyNames :: MultiMap Keycode Text
keyNames = [MultiMap Keycode Text] -> MultiMap Keycode Text
forall a. Monoid a => [a] -> a
mconcat
  [ (Keycode -> Text) -> HashSet Keycode -> MultiMap Keycode Text
forall (t :: * -> *).
Foldable t =>
(Keycode -> Text) -> t Keycode -> MultiMap Keycode Text
nameKC Keycode -> Text
forall a. Show a => a -> Text
tshow               HashSet Keycode
kcAll
  , (Keycode -> Text) -> HashSet Keycode -> MultiMap Keycode Text
forall (t :: * -> *).
Foldable t =>
(Keycode -> Text) -> t Keycode -> MultiMap Keycode Text
nameKC (Int -> Text -> Text
T.drop Int
3 (Text -> Text) -> (Keycode -> Text) -> Keycode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Keycode -> Text
forall a. Show a => a -> Text
tshow)  HashSet Keycode
kcNotMissing
  , MultiMap Keycode Text
aliases
  ]

-- | A collection of useful aliases to refer to keycode names
aliases :: Q.MultiMap Keycode Text
aliases :: MultiMap Keycode Text
aliases = [(Keycode, [Text])] -> MultiMap Keycode Text
forall (t1 :: * -> *) (t2 :: * -> *) k v.
(Foldable t1, Foldable t2, CanMM k v) =>
t1 (k, t2 v) -> MultiMap k v
Q.mkMultiMap
  [ (Keycode
KeyEnter,            [Text
"ret", Text
"return", Text
"ent"])
  , (Keycode
KeyMinus,            [Text
"min", Text
"-"])
  , (Keycode
KeyEqual,            [Text
"eql", Text
"="])
  , (Keycode
KeySleep,            [Text
"zzz"])
  , (Keycode
KeySpace,            [Text
"spc"])
  , (Keycode
KeyPageUp,           [Text
"pgup"])
  , (Keycode
KeyPageDown,         [Text
"pgdn"])
  , (Keycode
KeyInsert,           [Text
"ins"])
  , (Keycode
KeyDelete,           [Text
"del"])
  , (Keycode
KeyVolumeUp,         [Text
"volu"])
  , (Keycode
KeyVolumeDown,       [Text
"voldwn", Text
"vold"])
  , (Keycode
KeyBrightnessUp,     [Text
"brup", Text
"bru"])
  , (Keycode
KeyBrightnessDown,   [Text
"brdown", Text
"brdwn", Text
"brdn"])
  , (Keycode
KeyLeftAlt,          [Text
"lalt", Text
"alt"])
  , (Keycode
KeyRightAlt,         [Text
"ralt"])
  , (Keycode
KeyCompose,          [Text
"comp", Text
"cmps", Text
"cmp"])
  , (Keycode
KeyLeftShift,        [Text
"lshift", Text
"lshft", Text
"lsft", Text
"shft", Text
"sft"])
  , (Keycode
KeyRightShift,       [Text
"rshift", Text
"rshft", Text
"rsft"])
  , (Keycode
KeyLeftCtrl,         [Text
"lctrl", Text
"lctl", Text
"ctl"])
  , (Keycode
KeyRightCtrl,        [Text
"rctrl", Text
"rctl"])
  , (Keycode
KeyLeftMeta,         [Text
"lmeta", Text
"lmet", Text
"met"])
  , (Keycode
KeyRightMeta,        [Text
"rmeta", Text
"rmet"])
  , (Keycode
KeyBackspace,        [Text
"bks", Text
"bspc"])
  , (Keycode
KeyCapsLock,         [Text
"caps"])
  , (Keycode
Key102nd,            [Text
"102d", Text
"lsgt", Text
"nubs"])
  , (Keycode
KeyForward,          [Text
"fwd"])
  , (Keycode
KeyScrollLock,       [Text
"scrlck", Text
"slck"])
  , (Keycode
KeyScrollUp,         [Text
"scrup", Text
"sup"])
  , (Keycode
KeyScrollDown,       [Text
"scrdn", Text
"sdwn", Text
"sdn"])
  , (Keycode
KeyPrint,            [Text
"prnt"])
  , (Keycode
KeyWakeUp,           [Text
"wkup"])
  , (Keycode
KeyLeft,             [Text
"lft"])
  , (Keycode
KeyRight,            [Text
"rght"])
  , (Keycode
KeyLeftBrace,        [Text
"lbrc", Text
"["])
  , (Keycode
KeyRightBrace,       [Text
"rbrc", Text
"]"])
  , (Keycode
KeySemicolon,        [Text
"scln", Text
";"])
  , (Keycode
KeyApostrophe,       [Text
"apos", Text
"'", Text
"apo"])
  , (Keycode
KeyGrave,            [Text
"grv", Text
"`"])
  , (Keycode
KeyBackslash,        [Text
"bksl", Text
"\\"]) -- NOTE: "\\" here is a 1char string, the first \ is consumed by Haskell as an escape character
  , (Keycode
KeyComma,            [Text
"comm", Text
","])
  , (Keycode
KeyDot,              [Text
"."])
  , (Keycode
KeySlash,            [Text
"/"])
  , (Keycode
KeyNumLock,          [Text
"nlck"])
  , (Keycode
KeyKpSlash,          [Text
"kp/"])
  , (Keycode
KeyKpEnter,          [Text
"kprt"])
  , (Keycode
KeyKpPlus,           [Text
"kp+"])
  , (Keycode
KeyKpAsterisk,       [Text
"kp*"])
  , (Keycode
KeyKpMinus,          [Text
"kp-"])
  , (Keycode
KeyKpDot,            [Text
"kp."])
  , (Keycode
KeySysRq,            [Text
"ssrq", Text
"sys"])
  , (Keycode
KeyKbdIllumDown,     [Text
"bldn"])
  , (Keycode
KeyKbdIllumUp,       [Text
"blup"])
  , (Keycode
KeyNextSong,         [Text
"next"])
  , (Keycode
KeyPlayPause,        [Text
"pp"])
  , (Keycode
KeyPreviousSong,     [Text
"prev"])
  , (Keycode
KeyMicmute,          [Text
"micm"])
  , (Keycode
KeyCoffee,           [Text
"lock"])
  -- Darwin
  , (Keycode
KeyLaunchpad,        [Text
"lp"])
  , (Keycode
KeyMissionCtrl,      [Text
"mctl"])
  , (Keycode
KeySpotlight,        [Text
"spot"])
  , (Keycode
KeyDictation,        [Text
"dict"])
  -- Japanese
  , (Keycode
KeyZenkakuHankaku,   [Text
"zeh"])
  , (Keycode
KeyMuhenkan,         [Text
"muh"])
  , (Keycode
KeyHenkan,           [Text
"hen"])
  , (Keycode
KeyKatakanaHiragana, [Text
"kah"])
  -- Aliases from `input-event-codes.h`
  , (Keycode
KeyMute,            [Text
"mininteresting"])
  , (Keycode
KeyHangeul,         [Text
"hanguel"])
  , (Keycode
KeyCoffee,          [Text
"screenlock"])
  , (Keycode
KeyDirection,       [Text
"rotatedisplay"])
  , (Keycode
KeyDashboard,       [Text
"allapplications"])
  , (Keycode
KeyBrightnessZero,  [Text
"brightnessauto"])
  , (Keycode
KeyWimax,           [Text
"wwan"])
  , (Keycode
Btn0,               [Text
"btnmisc"])
  , (Keycode
BtnLeft,            [Text
"btnmouse"])
  , (Keycode
BtnJoystick,        [Text
"btntrigger"])
  , (Keycode
BtnGamepad,         [Text
"btna", Text
"btnsouth"])
  , (Keycode
BtnB,               [Text
"btneast"])
  , (Keycode
BtnX,               [Text
"btnnorth"])
  , (Keycode
BtnY,               [Text
"btnwest"])
  , (Keycode
BtnDigi,            [Text
"btntoolpen"])
  , (Keycode
BtnGearDown,        [Text
"btnwheel"])
  , (Keycode
KeyZoom,            [Text
"fullscreen"])
  , (Keycode
KeyScreen,          [Text
"aspectratio"])
  , (Keycode
KeyBrightnessToggle,[Text
"displaytoggle"])
  , (Keycode
BtnTriggerHappy,    [Text
"btntriggerhappy1"])
  -- HID Usage Names
  , (Keycode
KeyBackslash,        [Text
"nonuspound"])
  , (Keycode
KeyCompose,          [Text
"app", Text
"application"])
  , (Keycode
KeyOpen,             [Text
"exec", Text
"execute"])
  --, (KeyFront,            ["sel", "select"]) -- conflict with KeySelect
  , (Keycode
KeyRo,               [Text
"i1", Text
"int1", Text
"international1"])
  , (Keycode
KeyKatakanaHiragana, [Text
"i2", Text
"int2", Text
"international2"])
  , (Keycode
KeyYen,              [Text
"i3", Text
"int3", Text
"international3"])
  , (Keycode
KeyHenkan,           [Text
"i4", Text
"int4", Text
"international4"])
  , (Keycode
KeyMuhenkan,         [Text
"i5", Text
"int5", Text
"international5"])
  , (Keycode
KeyKpjpcomma,        [Text
"i6", Text
"int6", Text
"international6"])
  , (Keycode
KeyHangeul,          [Text
"l1", Text
"lang1"])
  , (Keycode
KeyHanja,            [Text
"l2", Text
"lang2"])
  , (Keycode
KeyKatakana,         [Text
"l3", Text
"lang3"])
  , (Keycode
KeyHiragana,         [Text
"l4", Text
"lang4"])
  , (Keycode
KeyZenkakuHankaku,   [Text
"l5", Text
"lang5"])
  , (Keycode
KeyExit,             [Text
"quit"])
  , (Keycode
KeyNextSong,         [Text
"nexttrack"])
  , (Keycode
KeyPreviousSong,     [Text
"previoustrack"])
  -- , (KeyStopCd,           ["stop"]) -- conflict with KeyStop
  , (Keycode
KeyEjectCd,          [Text
"eject"])
  , (Keycode
KeyVolumeUp,         [Text
"volumeincrement"])
  , (Keycode
KeyVolumeDown,       [Text
"volumedecrement"])
  , (Keycode
KeyMail,             [Text
"emailreader"])
  , (Keycode
KeyFinance,          [Text
"checkbook"])
  , (Keycode
KeyCalc,             [Text
"calculator"])
  , (Keycode
KeyFile,             [Text
"localmachinebrowser"])
  , (Keycode
KeyWww,              [Text
"internetbrowser"])
  , (Keycode
KeyCoffee,           [Text
"termlock"]) -- conflict with KeyScreenSaver: "screensaver"
  , (Keycode
KeyHelp,             [Text
"helpcenter"])
  , (Keycode
KeyMedia,            [Text
"imagebrowser"])
  , (Keycode
KeySound,            [Text
"audiobrowser"])
  , (Keycode
KeyProps,            [Text
"properties"])
  -- , (KeyHomepage,         ["home"]) -- conflict with KeyHome
  , (Keycode
KeyForwardMail,      [Text
"forwardmessage"])
  , (Keycode
KeyProgram,          [Text
"guide"])
  , (Keycode
KeyMemo,             [Text
"messages"])
  , (Keycode
KeyTv2,              [Text
"cable"])
  -- , (KeyPvr,              ["home"]) -- conflict with KeyHome
  , (Keycode
KeySubtitle,         [Text
"caption"])
  , (Keycode
KeyVcr2,             [Text
"vcr+"])
  , (Keycode
KeyMediaRepeat,      [Text
"repeat"])
  , (Keycode
KeyEditor,           [Text
"texteditor"])
  , (Keycode
KeyNews,             [Text
"newsreader"])
  , (Keycode
KeyAddressBook,      [Text
"contacts"])
  , (Keycode
KeyCalendar,         [Text
"schedule"])
  , (Keycode
KeyMessenger,        [Text
"instantmessaging"])
  , (Keycode
KeyInfo,             [Text
"featurebrowser", Text
"tipsbrowser"])
  -- , (KeyZoomReset,        ["zoom"]) -- conflict with KeyZoom
  ]