module KMonad.Keyboard.IO.Mac.Types
  ( MacError(..)
  , MacKeyEvent
  , toMacKeyEvent
  , fromMacKeyEvent
  , kcMapRaw
  )

where

import KMonad.Prelude

import Foreign.Storable
import KMonad.Keyboard

import qualified RIO.HashMap as M
import RIO.List (sortOn)


----------------------------------------------------------------------------
-- $err

-- | Everything that can go wrong with Mac Key-IO
data MacError
  = NoMacKeycodeTo   Keycode    -- ^ Error translating to 'MacKeycode'
  | NoMacKeycodeFrom MacKeycode -- ^ Error translating from 'MacKeycode'
  | BadMacSwitch     MacSwitch  -- ^ Error interpreting 'MacSwitch'

instance Exception MacError
instance Show MacError where
  show :: MacError -> String
show MacError
e = case MacError
e of
    NoMacKeycodeTo   Keycode
c -> String
"Cannot translate to mac keycode: "   String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Keycode -> String
forall a. Show a => a -> String
show Keycode
c
    NoMacKeycodeFrom MacKeycode
i -> String
"Cannot translate from mac keycode: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> MacKeycode -> String
forall a. Show a => a -> String
show MacKeycode
i
    BadMacSwitch     MacSwitch
s -> String
"Cannot interpret mac switch: "       String -> ShowS
forall a. Semigroup a => a -> a -> a
<> MacSwitch -> String
forall a. Show a => a -> String
show MacSwitch
s
instance Exception [MacError]

--------------------------------------------------------------------------------
-- $typ

type MacSwitch  = Word64           -- ^ Type alias for the switch value
type MacKeycode = (Word32, Word32) -- ^ Type alias for the Mac keycode

-- | 'MacKeyEvent' is the C-representation of a a 'KeyEvent' for our Mac API.
--
-- It contains a 'Word8' signifying whether the event was a Press (0)
-- or Release (1), and a 'Word32' (uint32_t) signifying the Mac
-- keycode (the upper 16 bits represent the IOKit usage page, and the
-- lower 16 bits represent the IOKit usage).
--
-- NOTE: Mac and Linux keycodes do not line up. Internally we use Linux
-- Keycodes for everything, we translate at the KeyIO stage (here).
newtype MacKeyEvent = MacKeyEvent (MacSwitch, MacKeycode)
  deriving (MacKeyEvent -> MacKeyEvent -> Bool
(MacKeyEvent -> MacKeyEvent -> Bool)
-> (MacKeyEvent -> MacKeyEvent -> Bool) -> Eq MacKeyEvent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MacKeyEvent -> MacKeyEvent -> Bool
== :: MacKeyEvent -> MacKeyEvent -> Bool
$c/= :: MacKeyEvent -> MacKeyEvent -> Bool
/= :: MacKeyEvent -> MacKeyEvent -> Bool
Eq, Eq MacKeyEvent
Eq MacKeyEvent =>
(MacKeyEvent -> MacKeyEvent -> Ordering)
-> (MacKeyEvent -> MacKeyEvent -> Bool)
-> (MacKeyEvent -> MacKeyEvent -> Bool)
-> (MacKeyEvent -> MacKeyEvent -> Bool)
-> (MacKeyEvent -> MacKeyEvent -> Bool)
-> (MacKeyEvent -> MacKeyEvent -> MacKeyEvent)
-> (MacKeyEvent -> MacKeyEvent -> MacKeyEvent)
-> Ord MacKeyEvent
MacKeyEvent -> MacKeyEvent -> Bool
MacKeyEvent -> MacKeyEvent -> Ordering
MacKeyEvent -> MacKeyEvent -> MacKeyEvent
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 :: MacKeyEvent -> MacKeyEvent -> Ordering
compare :: MacKeyEvent -> MacKeyEvent -> Ordering
$c< :: MacKeyEvent -> MacKeyEvent -> Bool
< :: MacKeyEvent -> MacKeyEvent -> Bool
$c<= :: MacKeyEvent -> MacKeyEvent -> Bool
<= :: MacKeyEvent -> MacKeyEvent -> Bool
$c> :: MacKeyEvent -> MacKeyEvent -> Bool
> :: MacKeyEvent -> MacKeyEvent -> Bool
$c>= :: MacKeyEvent -> MacKeyEvent -> Bool
>= :: MacKeyEvent -> MacKeyEvent -> Bool
$cmax :: MacKeyEvent -> MacKeyEvent -> MacKeyEvent
max :: MacKeyEvent -> MacKeyEvent -> MacKeyEvent
$cmin :: MacKeyEvent -> MacKeyEvent -> MacKeyEvent
min :: MacKeyEvent -> MacKeyEvent -> MacKeyEvent
Ord, Int -> MacKeyEvent -> ShowS
[MacKeyEvent] -> ShowS
MacKeyEvent -> String
(Int -> MacKeyEvent -> ShowS)
-> (MacKeyEvent -> String)
-> ([MacKeyEvent] -> ShowS)
-> Show MacKeyEvent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MacKeyEvent -> ShowS
showsPrec :: Int -> MacKeyEvent -> ShowS
$cshow :: MacKeyEvent -> String
show :: MacKeyEvent -> String
$cshowList :: [MacKeyEvent] -> ShowS
showList :: [MacKeyEvent] -> ShowS
Show)

-- | This lets us send 'MacKeyEvent's between Haskell and C.
instance Storable MacKeyEvent where
  alignment :: MacKeyEvent -> Int
alignment MacKeyEvent
_ = Int
4
  sizeOf :: MacKeyEvent -> Int
sizeOf    MacKeyEvent
_ = Int
16
  peek :: Ptr MacKeyEvent -> IO MacKeyEvent
peek Ptr MacKeyEvent
ptr = do
    MacSwitch
s <- Ptr MacKeyEvent -> Int -> IO MacSwitch
forall b. Ptr b -> Int -> IO MacSwitch
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr MacKeyEvent
ptr Int
0
    Word32
p <- Ptr MacKeyEvent -> Int -> IO Word32
forall b. Ptr b -> Int -> IO Word32
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr MacKeyEvent
ptr Int
8
    Word32
u <- Ptr MacKeyEvent -> Int -> IO Word32
forall b. Ptr b -> Int -> IO Word32
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr MacKeyEvent
ptr Int
12
    MacKeyEvent -> IO MacKeyEvent
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (MacKeyEvent -> IO MacKeyEvent) -> MacKeyEvent -> IO MacKeyEvent
forall a b. (a -> b) -> a -> b
$ (MacSwitch, MacKeycode) -> MacKeyEvent
MacKeyEvent (MacSwitch
s, (Word32
p, Word32
u))
  poke :: Ptr MacKeyEvent -> MacKeyEvent -> IO ()
poke Ptr MacKeyEvent
ptr (MacKeyEvent (MacSwitch
s, (Word32
p, Word32
u))) = do
    Ptr MacKeyEvent -> Int -> MacSwitch -> IO ()
forall b. Ptr b -> Int -> MacSwitch -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr MacKeyEvent
ptr Int
0 MacSwitch
s
    Ptr MacKeyEvent -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr MacKeyEvent
ptr Int
8 Word32
p
    Ptr MacKeyEvent -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr MacKeyEvent
ptr Int
12 Word32
u

--------------------------------------------------------------------------------
-- $conv

fromMacSwitch :: MacSwitch -> Maybe Switch
fromMacSwitch :: MacSwitch -> Maybe Switch
fromMacSwitch MacSwitch
s = case MacSwitch
s of
  MacSwitch
1 -> Switch -> Maybe Switch
forall a. a -> Maybe a
Just Switch
Press
  MacSwitch
0 -> Switch -> Maybe Switch
forall a. a -> Maybe a
Just Switch
Release
  MacSwitch
_ -> Maybe Switch
forall a. Maybe a
Nothing

toMacSwitch :: Switch -> MacSwitch
toMacSwitch :: Switch -> MacSwitch
toMacSwitch Switch
s = if Switch
s Switch -> Switch -> Bool
forall a. Eq a => a -> a -> Bool
== Switch
Press then MacSwitch
1 else MacSwitch
0

-- | Lookup the corresponding 'Keycode' for this 'MacKeycode'
fromMacKeycode :: MacKeycode -> Maybe Keycode
fromMacKeycode :: MacKeycode -> Maybe Keycode
fromMacKeycode = (MacKeycode -> HashMap MacKeycode Keycode -> Maybe Keycode)
-> HashMap MacKeycode Keycode -> MacKeycode -> Maybe Keycode
forall a b c. (a -> b -> c) -> b -> a -> c
flip MacKeycode -> HashMap MacKeycode Keycode -> Maybe Keycode
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup HashMap MacKeycode Keycode
kcMap

-- | Lookup the correspondig 'MacKeycode' for this 'Keycode'
toMacKeycode :: Keycode -> Maybe MacKeycode
toMacKeycode :: Keycode -> Maybe MacKeycode
toMacKeycode = (Keycode -> HashMap Keycode MacKeycode -> Maybe MacKeycode)
-> HashMap Keycode MacKeycode -> Keycode -> Maybe MacKeycode
forall a b c. (a -> b -> c) -> b -> a -> c
flip Keycode -> HashMap Keycode MacKeycode -> Maybe MacKeycode
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup HashMap Keycode MacKeycode
revMap
  -- We sort the reversed list, since some keycodes are duplicates (e.g.: KeyBackslash) and the later takes precedence
  where revMap :: HashMap Keycode MacKeycode
revMap = [(Keycode, MacKeycode)] -> HashMap Keycode MacKeycode
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ([(Keycode, MacKeycode)] -> HashMap Keycode MacKeycode)
-> ([(Keycode, MacKeycode)] -> [(Keycode, MacKeycode)])
-> [(Keycode, MacKeycode)]
-> HashMap Keycode MacKeycode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Keycode, MacKeycode) -> Down MacKeycode)
-> [(Keycode, MacKeycode)] -> [(Keycode, MacKeycode)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (MacKeycode -> Down MacKeycode
forall a. a -> Down a
Down (MacKeycode -> Down MacKeycode)
-> ((Keycode, MacKeycode) -> MacKeycode)
-> (Keycode, MacKeycode)
-> Down MacKeycode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Keycode, MacKeycode) -> MacKeycode
forall a b. (a, b) -> b
snd) ([(Keycode, MacKeycode)] -> HashMap Keycode MacKeycode)
-> [(Keycode, MacKeycode)] -> HashMap Keycode MacKeycode
forall a b. (a -> b) -> a -> b
$ HashMap MacKeycode Keycode -> [(MacKeycode, Keycode)]
forall k v. HashMap k v -> [(k, v)]
M.toList HashMap MacKeycode Keycode
kcMap [(MacKeycode, Keycode)]
-> Getting
     (Endo [(Keycode, MacKeycode)])
     [(MacKeycode, Keycode)]
     (Keycode, MacKeycode)
-> [(Keycode, MacKeycode)]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ((MacKeycode, Keycode)
 -> Const (Endo [(Keycode, MacKeycode)]) (MacKeycode, Keycode))
-> [(MacKeycode, Keycode)]
-> Const (Endo [(Keycode, MacKeycode)]) [(MacKeycode, Keycode)]
forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
IndexedFold Int [(MacKeycode, Keycode)] (MacKeycode, Keycode)
folded (((MacKeycode, Keycode)
  -> Const (Endo [(Keycode, MacKeycode)]) (MacKeycode, Keycode))
 -> [(MacKeycode, Keycode)]
 -> Const (Endo [(Keycode, MacKeycode)]) [(MacKeycode, Keycode)])
-> (((Keycode, MacKeycode)
     -> Const (Endo [(Keycode, MacKeycode)]) (Keycode, MacKeycode))
    -> (MacKeycode, Keycode)
    -> Const (Endo [(Keycode, MacKeycode)]) (MacKeycode, Keycode))
-> Getting
     (Endo [(Keycode, MacKeycode)])
     [(MacKeycode, Keycode)]
     (Keycode, MacKeycode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Keycode, MacKeycode)
 -> Const (Endo [(Keycode, MacKeycode)]) (Keycode, MacKeycode))
-> (MacKeycode, Keycode)
-> Const (Endo [(Keycode, MacKeycode)]) (MacKeycode, Keycode)
forall (p :: * -> * -> *) a b c d.
Swap p =>
Iso (p a b) (p c d) (p b a) (p d c)
Iso
  (MacKeycode, Keycode)
  (MacKeycode, Keycode)
  (Keycode, MacKeycode)
  (Keycode, MacKeycode)
swapped

-- | Convert a 'KeyEvent' to a 'MacKeyEvent'
--
-- NOTE: Mac keycodes are different, and I am not confident I have full
-- coverage, therefore this conversion is not total. We are going to leave this
-- error-handling in until we are sure this is covered well. Once it lines up
-- perfectly, this is essentially an Iso.
toMacKeyEvent :: KeyEvent -> Either MacError MacKeyEvent
toMacKeyEvent :: KeyEvent -> Either MacError MacKeyEvent
toMacKeyEvent KeyEvent
e = case Keycode -> Maybe MacKeycode
toMacKeycode (Keycode -> Maybe MacKeycode) -> Keycode -> Maybe MacKeycode
forall a b. (a -> b) -> a -> b
$ KeyEvent
eKeyEvent -> Getting Keycode KeyEvent Keycode -> Keycode
forall s a. s -> Getting a s a -> a
^.Getting Keycode KeyEvent Keycode
forall c. HasKeyEvent c => Lens' c Keycode
Lens' KeyEvent Keycode
keycode of
  Just MacKeycode
c  -> MacKeyEvent -> Either MacError MacKeyEvent
forall a b. b -> Either a b
Right (MacKeyEvent -> Either MacError MacKeyEvent)
-> MacKeyEvent -> Either MacError MacKeyEvent
forall a b. (a -> b) -> a -> b
$ (MacSwitch, MacKeycode) -> MacKeyEvent
MacKeyEvent (Switch -> MacSwitch
toMacSwitch (KeyEvent
eKeyEvent -> Getting Switch KeyEvent Switch -> Switch
forall s a. s -> Getting a s a -> a
^.Getting Switch KeyEvent Switch
forall c. HasKeyEvent c => Lens' c Switch
Lens' KeyEvent Switch
switch), MacKeycode
c)
  Maybe MacKeycode
Nothing -> MacError -> Either MacError MacKeyEvent
forall a b. a -> Either a b
Left (MacError -> Either MacError MacKeyEvent)
-> (Keycode -> MacError) -> Keycode -> Either MacError MacKeyEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Keycode -> MacError
NoMacKeycodeTo (Keycode -> Either MacError MacKeyEvent)
-> Keycode -> Either MacError MacKeyEvent
forall a b. (a -> b) -> a -> b
$ KeyEvent
eKeyEvent -> Getting Keycode KeyEvent Keycode -> Keycode
forall s a. s -> Getting a s a -> a
^.Getting Keycode KeyEvent Keycode
forall c. HasKeyEvent c => Lens' c Keycode
Lens' KeyEvent Keycode
keycode

-- | Convert a 'MacKeyEvent' to a 'KeyEvent'
--
-- NOTE: Same limitations as 'toMacKeyEvent' apply
fromMacKeyEvent :: MacKeyEvent -> Maybe (Either [MacError] KeyEvent)
fromMacKeyEvent :: MacKeyEvent -> Maybe (Either [MacError] KeyEvent)
fromMacKeyEvent (MacKeyEvent (MacSwitch
s, (Word32
p, Word32
u)))
  | Word32
p Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
7 Bool -> Bool -> Bool
&& Word32
u Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word32
0x3    = Maybe (Either [MacError] KeyEvent)
forall a. Maybe a
Nothing
  | Word32
p Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
7 Bool -> Bool -> Bool
&& Word32
u Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
0xFFFF = Maybe (Either [MacError] KeyEvent)
forall a. Maybe a
Nothing
  | Bool
otherwise             = case (MacKeycode -> Maybe Keycode
fromMacKeycode (Word32
p, Word32
u), MacSwitch -> Maybe Switch
fromMacSwitch MacSwitch
s) of
      (Just Keycode
c', Just Switch
s') -> Either [MacError] KeyEvent -> Maybe (Either [MacError] KeyEvent)
forall a. a -> Maybe a
Just (KeyEvent -> Either [MacError] KeyEvent
forall a b. b -> Either a b
Right (KeyEvent -> Either [MacError] KeyEvent)
-> KeyEvent -> Either [MacError] KeyEvent
forall a b. (a -> b) -> a -> b
$ Switch -> Keycode -> KeyEvent
mkKeyEvent Switch
s' Keycode
c')
      (Just Keycode
_, Maybe Switch
Nothing)  -> Either [MacError] KeyEvent -> Maybe (Either [MacError] KeyEvent)
forall a. a -> Maybe a
Just ([MacError] -> Either [MacError] KeyEvent
forall a b. a -> Either a b
Left [MacSwitch -> MacError
BadMacSwitch MacSwitch
s])
      (Maybe Keycode
Nothing, Just Switch
_)  -> Either [MacError] KeyEvent -> Maybe (Either [MacError] KeyEvent)
forall a. a -> Maybe a
Just ([MacError] -> Either [MacError] KeyEvent
forall a b. a -> Either a b
Left [MacKeycode -> MacError
NoMacKeycodeFrom (Word32
p,Word32
u)])
      (Maybe Keycode
Nothing, Maybe Switch
Nothing) -> Either [MacError] KeyEvent -> Maybe (Either [MacError] KeyEvent)
forall a. a -> Maybe a
Just ([MacError] -> Either [MacError] KeyEvent
forall a b. a -> Either a b
Left [MacSwitch -> MacError
BadMacSwitch MacSwitch
s, MacKeycode -> MacError
NoMacKeycodeFrom (Word32
p,Word32
u)])

--------------------------------------------------------------------------------
-- $kc

-- | Mac mostly uses the HID names instead. Since Linux doesn't we need to translate.
--
-- For Mac keycodes see https://github.com/apple-opensource/IOHIDFamily/blob/master/IOHIDFamily/IOHIDUsageTables.h
--
-- For HID to Linux mappings:
-- - See the source code where it's defined at https://github.com/torvalds/linux/blob/master/drivers/hid/hid-input.c
-- - See the table provided by the android docs at https://source.android.com/docs/core/interaction/input/keyboard-devices
kcMap :: M.HashMap MacKeycode Keycode
kcMap :: HashMap MacKeycode Keycode
kcMap = [(MacKeycode, Keycode)] -> HashMap MacKeycode Keycode
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList [(MacKeycode, Keycode)]
kcMapRaw

kcMapRaw :: [(MacKeycode, Keycode)]
kcMapRaw :: [(MacKeycode, Keycode)]
kcMapRaw =
  [ ((Word32
0x7,Word32
0x4), Keycode
KeyA)
  , ((Word32
0x7,Word32
0x5), Keycode
KeyB)
  , ((Word32
0x7,Word32
0x6), Keycode
KeyC)
  , ((Word32
0x7,Word32
0x7), Keycode
KeyD)
  , ((Word32
0x7,Word32
0x8), Keycode
KeyE)
  , ((Word32
0x7,Word32
0x9), Keycode
KeyF)
  , ((Word32
0x7,Word32
0xA), Keycode
KeyG)
  , ((Word32
0x7,Word32
0xB), Keycode
KeyH)
  , ((Word32
0x7,Word32
0xC), Keycode
KeyI)
  , ((Word32
0x7,Word32
0xD), Keycode
KeyJ)
  , ((Word32
0x7,Word32
0xE), Keycode
KeyK)
  , ((Word32
0x7,Word32
0xF), Keycode
KeyL)
  , ((Word32
0x7,Word32
0x10), Keycode
KeyM)
  , ((Word32
0x7,Word32
0x11), Keycode
KeyN)
  , ((Word32
0x7,Word32
0x12), Keycode
KeyO)
  , ((Word32
0x7,Word32
0x13), Keycode
KeyP)
  , ((Word32
0x7,Word32
0x14), Keycode
KeyQ)
  , ((Word32
0x7,Word32
0x15), Keycode
KeyR)
  , ((Word32
0x7,Word32
0x16), Keycode
KeyS)
  , ((Word32
0x7,Word32
0x17), Keycode
KeyT)
  , ((Word32
0x7,Word32
0x18), Keycode
KeyU)
  , ((Word32
0x7,Word32
0x19), Keycode
KeyV)
  , ((Word32
0x7,Word32
0x1A), Keycode
KeyW)
  , ((Word32
0x7,Word32
0x1B), Keycode
KeyX)
  , ((Word32
0x7,Word32
0x1C), Keycode
KeyY)
  , ((Word32
0x7,Word32
0x1D), Keycode
KeyZ)
  , ((Word32
0x7,Word32
0x1E), Keycode
Key1)
  , ((Word32
0x7,Word32
0x1F), Keycode
Key2)
  , ((Word32
0x7,Word32
0x20), Keycode
Key3)
  , ((Word32
0x7,Word32
0x21), Keycode
Key4)
  , ((Word32
0x7,Word32
0x22), Keycode
Key5)
  , ((Word32
0x7,Word32
0x23), Keycode
Key6)
  , ((Word32
0x7,Word32
0x24), Keycode
Key7)
  , ((Word32
0x7,Word32
0x25), Keycode
Key8)
  , ((Word32
0x7,Word32
0x26), Keycode
Key9)
  , ((Word32
0x7,Word32
0x27), Keycode
Key0)
  , ((Word32
0x7,Word32
0x28), Keycode
KeyEnter)
  , ((Word32
0x7,Word32
0x29), Keycode
KeyEsc)
  , ((Word32
0x7,Word32
0x2A), Keycode
KeyBackspace)
  , ((Word32
0x7,Word32
0x2B), Keycode
KeyTab)
  , ((Word32
0x7,Word32
0x2C), Keycode
KeySpace)
  , ((Word32
0x7,Word32
0x2D), Keycode
KeyMinus)
  , ((Word32
0x7,Word32
0x2E), Keycode
KeyEqual)
  , ((Word32
0x7,Word32
0x2F), Keycode
KeyLeftBrace)
  , ((Word32
0x7,Word32
0x30), Keycode
KeyRightBrace)
  , ((Word32
0x7,Word32
0x31), Keycode
KeyBackslash)
  , ((Word32
0x7,Word32
0x32), Keycode
KeyBackslash) -- NonUsPound
  , ((Word32
0x7,Word32
0x33), Keycode
KeySemicolon)
  , ((Word32
0x7,Word32
0x34), Keycode
KeyApostrophe)
  , ((Word32
0x7,Word32
0x35), Keycode
KeyGrave)
  , ((Word32
0x7,Word32
0x36), Keycode
KeyComma)
  , ((Word32
0x7,Word32
0x37), Keycode
KeyDot)
  , ((Word32
0x7,Word32
0x38), Keycode
KeySlash)
  , ((Word32
0x7,Word32
0x39), Keycode
KeyCapsLock)
  , ((Word32
0x7,Word32
0x3A), Keycode
KeyF1)
  , ((Word32
0x7,Word32
0x3B), Keycode
KeyF2)
  , ((Word32
0x7,Word32
0x3C), Keycode
KeyF3)
  , ((Word32
0x7,Word32
0x3D), Keycode
KeyF4)
  , ((Word32
0x7,Word32
0x3E), Keycode
KeyF5)
  , ((Word32
0x7,Word32
0x3F), Keycode
KeyF6)
  , ((Word32
0x7,Word32
0x40), Keycode
KeyF7)
  , ((Word32
0x7,Word32
0x41), Keycode
KeyF8)
  , ((Word32
0x7,Word32
0x42), Keycode
KeyF9)
  , ((Word32
0x7,Word32
0x43), Keycode
KeyF10)
  , ((Word32
0x7,Word32
0x44), Keycode
KeyF11)
  , ((Word32
0x7,Word32
0x45), Keycode
KeyF12)
  , ((Word32
0x7,Word32
0x46), Keycode
KeyPrint) -- KeySysRq
  , ((Word32
0x7,Word32
0x47), Keycode
KeyScrollLock)
  , ((Word32
0x7,Word32
0x48), Keycode
KeyPause)
  , ((Word32
0x7,Word32
0x49), Keycode
KeyInsert)
  , ((Word32
0x7,Word32
0x4A), Keycode
KeyHome)
  , ((Word32
0x7,Word32
0x4B), Keycode
KeyPageUp)
  , ((Word32
0x7,Word32
0x4C), Keycode
KeyDelete)
  , ((Word32
0x7,Word32
0x4D), Keycode
KeyEnd)
  , ((Word32
0x7,Word32
0x4E), Keycode
KeyPageDown)
  , ((Word32
0x7,Word32
0x4F), Keycode
KeyRight)
  , ((Word32
0x7,Word32
0x50), Keycode
KeyLeft)
  , ((Word32
0x7,Word32
0x51), Keycode
KeyDown)
  , ((Word32
0x7,Word32
0x52), Keycode
KeyUp)
  , ((Word32
0x7,Word32
0x53), Keycode
KeyNumLock)
  , ((Word32
0x7,Word32
0x54), Keycode
KeyKpSlash)
  , ((Word32
0x7,Word32
0x55), Keycode
KeyKpAsterisk)
  , ((Word32
0x7,Word32
0x56), Keycode
KeyKpMinus)
  , ((Word32
0x7,Word32
0x57), Keycode
KeyKpPlus)
  , ((Word32
0x7,Word32
0x58), Keycode
KeyKpEnter)
  , ((Word32
0x7,Word32
0x59), Keycode
KeyKp1)
  , ((Word32
0x7,Word32
0x5A), Keycode
KeyKp2)
  , ((Word32
0x7,Word32
0x5B), Keycode
KeyKp3)
  , ((Word32
0x7,Word32
0x5C), Keycode
KeyKp4)
  , ((Word32
0x7,Word32
0x5D), Keycode
KeyKp5)
  , ((Word32
0x7,Word32
0x5E), Keycode
KeyKp6)
  , ((Word32
0x7,Word32
0x5F), Keycode
KeyKp7)
  , ((Word32
0x7,Word32
0x60), Keycode
KeyKp8)
  , ((Word32
0x7,Word32
0x61), Keycode
KeyKp9)
  , ((Word32
0x7,Word32
0x62), Keycode
KeyKp0)
  , ((Word32
0x7,Word32
0x63), Keycode
KeyKpDot)
  , ((Word32
0x7,Word32
0x64), Keycode
Key102nd)
  , ((Word32
0x7,Word32
0x65), Keycode
KeyCompose)
  , ((Word32
0x7,Word32
0x66), Keycode
KeyPower)
  , ((Word32
0x7,Word32
0x67), Keycode
KeyKpEqual)
  , ((Word32
0x7,Word32
0x68), Keycode
KeyF13)
  , ((Word32
0x7,Word32
0x69), Keycode
KeyF14)
  , ((Word32
0x7,Word32
0x6A), Keycode
KeyF15)
  , ((Word32
0x7,Word32
0x6B), Keycode
KeyF16)
  , ((Word32
0x7,Word32
0x6C), Keycode
KeyF17)
  , ((Word32
0x7,Word32
0x6D), Keycode
KeyF18)
  , ((Word32
0x7,Word32
0x6E), Keycode
KeyF19)
  , ((Word32
0x7,Word32
0x6F), Keycode
KeyF20)
  , ((Word32
0x7,Word32
0x70), Keycode
KeyF21)
  , ((Word32
0x7,Word32
0x71), Keycode
KeyF22)
  , ((Word32
0x7,Word32
0x72), Keycode
KeyF23)
  , ((Word32
0x7,Word32
0x73), Keycode
KeyF24)
  , ((Word32
0x7,Word32
0x74), Keycode
KeyOpen)
  , ((Word32
0x7,Word32
0x75), Keycode
KeyHelp)
  , ((Word32
0x7,Word32
0x76), Keycode
KeyMenu) -- KeyProps
  , ((Word32
0x7,Word32
0x77), Keycode
KeyFront)
  , ((Word32
0x7,Word32
0x78), Keycode
KeyStop)
  , ((Word32
0x7,Word32
0x79), Keycode
KeyAgain)
  , ((Word32
0x7,Word32
0x7A), Keycode
KeyUndo)
  , ((Word32
0x7,Word32
0x7B), Keycode
KeyCut)
  , ((Word32
0x7,Word32
0x7C), Keycode
KeyCopy)
  , ((Word32
0x7,Word32
0x7D), Keycode
KeyPaste)
  , ((Word32
0x7,Word32
0x7E), Keycode
KeyFind)
  , ((Word32
0x7,Word32
0x7F), Keycode
KeyMute)
  , ((Word32
0x7,Word32
0x80), Keycode
KeyVolumeUp)
  , ((Word32
0x7,Word32
0x81), Keycode
KeyVolumeDown)
  -- , ((0x7,0x82), KeyLockingCapsLock)
  -- , ((0x7,0x83), KeyLockingNumLock)
  -- , ((0x7,0x84), KeyLockingScrollLock)
  , ((Word32
0x7,Word32
0x85), Keycode
KeyKpComma)
  -- , ((0x7,0x86), KeyKpEqualSignAS400)
  , ((Word32
0x7,Word32
0x87), Keycode
KeyRo)
  , ((Word32
0x7,Word32
0x88), Keycode
KeyKatakanaHiragana)
  , ((Word32
0x7,Word32
0x89), Keycode
KeyYen)
  , ((Word32
0x7,Word32
0x8A), Keycode
KeyHenkan)
  , ((Word32
0x7,Word32
0x8B), Keycode
KeyMuhenkan)
  , ((Word32
0x7,Word32
0x8C), Keycode
KeyKpjpcomma)
  -- , ((0x7,0x8D), KeyInternational7)
  -- , ((0x7,0x8E), KeyInternational8)
  -- , ((0x7,0x8F), KeyInternational9)
  , ((Word32
0x7,Word32
0x90), Keycode
KeyHangeul)
  , ((Word32
0x7,Word32
0x91), Keycode
KeyHanja)
  , ((Word32
0x7,Word32
0x92), Keycode
KeyKatakana)
  , ((Word32
0x7,Word32
0x93), Keycode
KeyHiragana)
  , ((Word32
0x7,Word32
0x94), Keycode
KeyZenkakuHankaku)
  -- , ((0x7,0x95), KeyLANG6)
  -- , ((0x7,0x96), KeyLANG7)
  -- , ((0x7,0x97), KeyLANG8)
  -- , ((0x7,0x98), KeyLANG9)
  -- , ((0x7,0x99), KeyAlternateErase)
  -- , ((0x7,0x9A), KeySysReqOrAttention)
  , ((Word32
0x7,Word32
0x9B), Keycode
KeyCancel) -- Does not exists in Linux
  -- , ((0x7,0x9C), KeyClear)
  -- , ((0x7,0x9D), KeyPrior)
  -- , ((0x7,0x9E), KeyReturn)
  -- , ((0x7,0x9F), KeySeparator)
  -- , ((0x7,0xA0), KeyOut)
  -- , ((0x7,0xA1), KeyOper)
  -- , ((0x7,0xA2), KeyClearOrAgain)
  -- , ((0x7,0xA3), KeyCrSelOrProps)
  -- , ((0x7,0xA4), KeyExSel)
  -- (0x7,0xA5) - (0x7,0xDF) Reserved
  , ((Word32
0x7,Word32
0xE0), Keycode
KeyLeftCtrl)
  , ((Word32
0x7,Word32
0xE1), Keycode
KeyLeftShift)
  , ((Word32
0x7,Word32
0xE2), Keycode
KeyLeftAlt)
  , ((Word32
0x7,Word32
0xE3), Keycode
KeyLeftMeta)
  , ((Word32
0x7,Word32
0xE4), Keycode
KeyRightCtrl)
  , ((Word32
0x7,Word32
0xE5), Keycode
KeyRightShift)
  , ((Word32
0x7,Word32
0xE6), Keycode
KeyRightAlt)
  , ((Word32
0x7,Word32
0xE7), Keycode
KeyRightMeta)
  -- (0x7,0xE8) - (0x7,0xFFFF) Reserved
  , ((Word32
0xC,Word32
0x34), Keycode
KeySleep)
  , ((Word32
0xC,Word32
0x40), Keycode
KeyMenu)
  , ((Word32
0xC,Word32
0x45), Keycode
KeyRight)
  , ((Word32
0xC,Word32
0x61), Keycode
KeySubtitle)
  , ((Word32
0xC,Word32
0x69), Keycode
KeyRed)
  , ((Word32
0xC,Word32
0x6A), Keycode
KeyGreen)
  , ((Word32
0xC,Word32
0x6B), Keycode
KeyBlue)
  , ((Word32
0xC,Word32
0x6C), Keycode
KeyYellow)
  , ((Word32
0xC,Word32
0x83), Keycode
KeyLast)
  -- , ((0xC,0x84), Key???) -- Enter Channel
  -- , ((0xC,0x85), Key???) -- Order Movie
  , ((Word32
0xC,Word32
0x88), Keycode
KeyPc)
  , ((Word32
0xC,Word32
0x89), Keycode
KeyTv)
  , ((Word32
0xC,Word32
0x8A), Keycode
KeyWww)
  , ((Word32
0xC,Word32
0x8B), Keycode
KeyDvd)
  , ((Word32
0xC,Word32
0x8C), Keycode
KeyPhone)
  , ((Word32
0xC,Word32
0x8D), Keycode
KeyProgram)
  , ((Word32
0xC,Word32
0x8E), Keycode
KeyVideoPhone)
  , ((Word32
0xC,Word32
0x8F), Keycode
KeyGames)
  , ((Word32
0xC,Word32
0x90), Keycode
KeyMemo)
  , ((Word32
0xC,Word32
0x91), Keycode
KeyCd)
  , ((Word32
0xC,Word32
0x92), Keycode
KeyVcr)
  , ((Word32
0xC,Word32
0x93), Keycode
KeyTuner)
  , ((Word32
0xC,Word32
0x94), Keycode
KeyExit)
  , ((Word32
0xC,Word32
0x95), Keycode
KeyHelp)
  , ((Word32
0xC,Word32
0x96), Keycode
KeyTape)
  , ((Word32
0xC,Word32
0x97), Keycode
KeyTv2)
  , ((Word32
0xC,Word32
0x98), Keycode
KeySat)
  -- , ((0xC,0x99), Key???) -- Media Select Security
  , ((Word32
0xC,Word32
0x9A), Keycode
KeyPvr)
  -- , ((0xC,0x9B), Key???) -- MediaSelectCall
  , ((Word32
0xC,Word32
0x9C), Keycode
KeyChannelUp)
  , ((Word32
0xC,Word32
0x9D), Keycode
KeyChannelDown)
  -- , ((0xC,0x9E), Key???) -- Media Select SAP (MacOS: Media)
  , ((Word32
0xC,Word32
0xA0), Keycode
KeyVcr2)
  -- , ((0xC,0xA1), Key???) -- Once
  -- , ((0xC,0xA2), Key???) -- Daily
  -- , ((0xC,0xA3), Key???) -- Weekly
  -- , ((0xC,0xA4), Key???) -- Monthly
  , ((Word32
0xC,Word32
0xB0), Keycode
KeyPlay)
  , ((Word32
0xC,Word32
0xB1), Keycode
KeyPause)
  , ((Word32
0xC,Word32
0xB2), Keycode
KeyRecord)
  , ((Word32
0xC,Word32
0xB3), Keycode
KeyFastForward)
  , ((Word32
0xC,Word32
0xB4), Keycode
KeyRewind)
  , ((Word32
0xC,Word32
0xB5), Keycode
KeyNextSong)
  , ((Word32
0xC,Word32
0xB6), Keycode
KeyPreviousSong)
  , ((Word32
0xC,Word32
0xB7), Keycode
KeyStopCd)
  , ((Word32
0xC,Word32
0xB8), Keycode
KeyEjectCd)
  -- , ((0xC,0xB9), Key???) -- Random Play
  -- , ((0xC,0xBA), Key???) -- Select Disc
  -- , ((0xC,0xBB), Key???) -- Enter Disc
  , ((Word32
0xC,Word32
0xBC), Keycode
KeyMediaRepeat)
  -- , ((0xC,0xBD), Key???) -- MacOS: Tracking
  -- , ((0xC,0xBE), Key???) -- Track Normal
  -- , ((0xC,0xBF), Key???) -- MacOS: SlowTraciking
  -- , ((0xC,0xC0), Key???) -- Frame Forward
  -- , ((0xC,0xC1), Key???) -- Frame Back
  -- , ((0xC,0xC2), Key???) -- Mark
  -- , ((0xC,0xC3), Key???) -- Clear Mark
  -- , ((0xC,0xC4), Key???) -- Repeat From Mark
  -- , ((0xC,0xC5), Key???) -- Return To Mark
  -- , ((0xC,0xC6), Key???) -- Search Mark Forward
  -- , ((0xC,0xC7), Key???) -- Search Mark Backwards
  -- , ((0xC,0xC8), Key???) -- Counter Reset
  -- , ((0xC,0xC9), Key???) -- Show Counter
  -- , ((0xC,0xCA), Key???) -- Tracking Increment
  -- , ((0xC,0xCB), Key???) -- Tracking Decrement
  -- , ((0xC,0xCC), Key???) -- Stop / Eject
  , ((Word32
0xC,Word32
0xCD), Keycode
KeyPlayPause)
  -- , ((0xC,0xCE), Key???) -- Play / Skip
  , ((Word32
0xC,Word32
0xCF), Keycode
KeyDictation) -- No HID
  -- , ((0xC,0xE0), Key???) -- MacOS: Volume (linear control)
  -- , ((0xC,0xE1), Key???) -- MacOS: Balance (linear control)
  , ((Word32
0xC,Word32
0xE2), Keycode
KeyPlayPause)
  -- , ((0xC,0xE3), Key???) -- MacOS: Bass (linear control)
  -- , ((0xC,0xE4), Key???) -- MacOS: Treble (linear control)
  , ((Word32
0xC,Word32
0xE5), Keycode
KeyBassBoost)
  -- , ((0xC,0xE6), Key???) -- Surround Mode
  -- , ((0xC,0xE7), Key???) -- Loudness
  -- , ((0xC,0xE8), Key???) -- MPX
  , ((Word32
0xC,Word32
0xE9), Keycode
KeyVolumeUp) -- VolumeIncrement
  , ((Word32
0xC,Word32
0xEA), Keycode
KeyVolumeDown) -- VolumentDecrement
  -- , ((0xC,0x100), KeyFanEnable)
  -- , ((0xC,0x101), KeyFanSpeed) -- (linear control)
  -- , ((0xC,0x102), KeyLightEnable)
  -- , ((0xC,0x103), KeyLightIlluminationLevel) -- (linear control)
  -- , ((0xC,0x104), KeyClimateControlEnable)
  -- , ((0xC,0x105), KeyRoomTemperature) -- (linear control)
  -- , ((0xC,0x106), KeySecurityEnable)
  -- , ((0xC,0x107), KeyFireAlarm)
  -- , ((0xC,0x108), KeyPoliceAlarm)
  -- , ((0xC,0x109), KeyProximity) -- (linear control)
  -- , ((0xC,0x10A), KeyMotion)
  -- , ((0xC,0x10B), KeyDuressAlarm)
  -- , ((0xC,0x10C), KeyHoldupAlarm)
  -- , ((0xC,0x10D), KeyMedicalAlarm)
  -- 0x10E - 0x14F Reserved
  -- , ((0xC,0x150), KeyBalanceRight)
  -- , ((0xC,0x151), KeyBalanceLeft)
  -- , ((0xC,0x152), KeyBassIncrement)
  -- , ((0xC,0x153), KeyBassDecrement)
  -- , ((0xC,0x154), KeyTrebleIncrement)
  -- , ((0xC,0x155), KeyTrebleDecrement)
  -- 0x156 - 0x15F Reserved
  -- , ((0xC,0x160), KeySpeakerSystem)
  -- , ((0xC,0x161), KeyChannelLeft)
  -- , ((0xC,0x162), KeyChannelRight)
  -- , ((0xC,0x163), KeyChannelCenter)
  -- , ((0xC,0x164), KeyChannelFront)
  -- , ((0xC,0x165), KeyChannelCenterFront)
  -- , ((0xC,0x166), KeyChannelSide)
  -- , ((0xC,0x167), KeyChannelSurround)
  -- , ((0xC,0x168), KeyChannelLowFrequencyEnhancement)
  -- , ((0xC,0x169), KeyChannelTop)
  -- , ((0xC,0x16A), KeyChannelUnknown)
  -- 0x16B - 0x16F Reserved
  -- , ((0xC,0x170), KeySubChannel) -- (linear control)
  -- , ((0xC,0x171), KeySubChannelIncrement)
  -- , ((0xC,0x172), KeySubChannelDecrement)
  -- , ((0xC,0x173), KeyAlternateAudioIncrement)
  -- , ((0xC,0x174), KeyAlternateAudioDecrement)
  -- 0x175 - 0x17F Reserved
  -- , ((0xC,0x180), KeyApplicationLaunchButtons)
  -- , ((0xC,0x181), KeyALLaunchButtonConfigurationTool)
  , ((Word32
0xC,Word32
0x182), Keycode
KeyBookmarks) -- KeyALProgrammableButtonConfiguration
  , ((Word32
0xC,Word32
0x183), Keycode
KeyConfig) -- KeyALConsumerControlConfiguration
  , ((Word32
0xC,Word32
0x184), Keycode
KeyWordProcessor)
  , ((Word32
0xC,Word32
0x185), Keycode
KeyEditor)
  , ((Word32
0xC,Word32
0x186), Keycode
KeySpreadSheet)
  , ((Word32
0xC,Word32
0x187), Keycode
KeyGraphicsEditor)
  , ((Word32
0xC,Word32
0x188), Keycode
KeyPresentation)
  , ((Word32
0xC,Word32
0x189), Keycode
KeyDatabase)
  , ((Word32
0xC,Word32
0x18A), Keycode
KeyMail)
  , ((Word32
0xC,Word32
0x18B), Keycode
KeyNews)
  , ((Word32
0xC,Word32
0x18C), Keycode
KeyVoicemail)
  , ((Word32
0xC,Word32
0x18D), Keycode
KeyAddressBook)
  , ((Word32
0xC,Word32
0x18E), Keycode
KeyCalendar)
  -- , ((0xC,0x18F), KeyALTaskOrProjectManager)
  -- , ((0xC,0x190), KeyALLogOrJournalOrTimecard)
  , ((Word32
0xC,Word32
0x191), Keycode
KeyFinance)
  , ((Word32
0xC,Word32
0x192), Keycode
KeyCalc)
  -- , ((0xC,0x193), KeyALAOrVCaptureOrPlayback)
  , ((Word32
0xC,Word32
0x194), Keycode
KeyFile)
  -- , ((0xC,0x195), KeyALLANOrWANBrowser)
  , ((Word32
0xC,Word32
0x196), Keycode
KeyWww)
  -- , ((0xC,0x197), KeyALRemoteNetworkingOrISPConnect)
  -- , ((0xC,0x198), KeyALNetworkConference)
  , ((Word32
0xC,Word32
0x199), Keycode
KeyChat)
  -- , ((0xC,0x19A), KeyALTelephonyOrDialer)
  -- , ((0xC,0x19B), KeyALLogon)
  , ((Word32
0xC,Word32
0x19C), Keycode
KeyLogoff)
  -- , ((0xC,0x19D), KeyALLogonOrLogoff)
  , ((Word32
0xC,Word32
0x19E), Keycode
KeyCoffee)
  -- , ((0xC,0x19F), KeyALControlPanel)
  -- , ((0xC,0x1A0), KeyALCommandLineProcessorOrRun)
  -- , ((0xC,0x1A1), KeyALProcessOrTaskManager)
  -- , ((0xC,0x1A2), KeyAL)
  -- , ((0xC,0x1A3), KeyALNextTaskOrApplication)
  -- , ((0xC,0x1A4), KeyALPreviousTaskOrApplication)
  -- , ((0xC,0x1A5), KeyALPreemptiveHaltTaskOrApplication)
  , ((Word32
0xC,Word32
0x1A6), Keycode
KeyHelp) -- KeyALIntegratedHelpCenter
  , ((Word32
0xC,Word32
0x1A7), Keycode
KeyDocuments)
  -- , ((0xC,0x1A8), KeyALThesaurus)
  -- , ((0xC,0x1A9), KeyALDictionary)
  -- , ((0xC,0x1AA), KeyALDesktop)
  , ((Word32
0xC,Word32
0x1AB), Keycode
KeySpellCheck)
  -- , ((0xC,0x1AC), KeyALGrammerCheck)
  -- , ((0xC,0x1AD), KeyALWirelessStatus)
  -- , ((0xC,0x1AE), KeyALKeyboardLayout)
  -- , ((0xC,0x1AF), KeyALVirusProtection)
  -- , ((0xC,0x1B0), KeyALEncryption)
  -- , ((0xC,0x1B1), KeyALScreenSaver)
  -- , ((0xC,0x1B2), KeyALAlarms)
  -- , ((0xC,0x1B3), KeyALClock)
  -- , ((0xC,0x1B4), KeyALFileBrowser)
  -- , ((0xC,0x1B5), KeyALPowerStatus)
  , ((Word32
0xC,Word32
0x1B6), Keycode
KeyMedia)
  , ((Word32
0xC,Word32
0x1B7), Keycode
KeySound)
  -- , ((0xC,0x1B8), KeyALMovieBrowser)
  -- , ((0xC,0x1B9), KeyALDigitalRightsManager)
  -- , ((0xC,0x1BA), KeyALDigitalWallet)
  -- 0x1BB Reserved
  , ((Word32
0xC,Word32
0x1BC), Keycode
KeyMessenger)
  , ((Word32
0xC,Word32
0x1BD), Keycode
KeyInfo)
  -- , ((0xC,0x1BE), KeyALOEMHelp)
  -- , ((0xC,0x1BF), KeyALOnlineCommunity)
  -- , ((0xC,0x1C0), KeyALEntertainmentContentBrowser)
  -- , ((0xC,0x1C1), KeyALOnlineShoppingBrowswer)
  -- , ((0xC,0x1C2), KeyALSmartCardInformationOrHelp)
  -- , ((0xC,0x1C3), KeyALMarketMonitorOrFinanceBrowser)
  -- , ((0xC,0x1C4), KeyALCustomizedCorporateNewsBrowser)
  -- , ((0xC,0x1C5), KeyALOnlineActivityBrowswer)
  -- , ((0xC,0x1C6), KeyALResearchOrSearchBrowswer)
  -- , ((0xC,0x1C7), KeyALAudioPlayer)
  -- , ((0xC,0x1C8), KeyALMessageStatus)
  -- , ((0xC,0x1C9), KeyALContactSync)
  -- , ((0xC,0x1CA), KeyALNavigation)
  -- , ((0xC,0x1CB), KeyALContextawareDesktopAssistant)
  -- 0x1CC - 0x1FF Reserved
  -- , ((0xC,0x200), KeyGenericGUIApplicationControls)
  , ((Word32
0xC,Word32
0x201), Keycode
KeyNew)
  , ((Word32
0xC,Word32
0x202), Keycode
KeyOpen)
  , ((Word32
0xC,Word32
0x203), Keycode
KeyClose)
  , ((Word32
0xC,Word32
0x204), Keycode
KeyExit)
  -- , ((0xC,0x205), KeyACMaximize)
  -- , ((0xC,0x206), KeyACMinimize)
  , ((Word32
0xC,Word32
0x207), Keycode
KeySave)
  , ((Word32
0xC,Word32
0x208), Keycode
KeyPrint)
  , ((Word32
0xC,Word32
0x209), Keycode
KeyProps)
  , ((Word32
0xC,Word32
0x21A), Keycode
KeyUndo)
  , ((Word32
0xC,Word32
0x21B), Keycode
KeyCopy)
  , ((Word32
0xC,Word32
0x21C), Keycode
KeyCut)
  , ((Word32
0xC,Word32
0x21D), Keycode
KeyPaste)
  -- , ((0xC,0x21E), KeyAC) -- AC Select All
  , ((Word32
0xC,Word32
0x21F), Keycode
KeyFind)
  -- , ((0xC,0x220), KeyACFindandReplace)
  , ((Word32
0xC,Word32
0x221), Keycode
KeySearch)
  , ((Word32
0xC,Word32
0x222), Keycode
KeyGoTo)
  , ((Word32
0xC,Word32
0x223), Keycode
KeyHomepage)
  , ((Word32
0xC,Word32
0x224), Keycode
KeyBack)
  , ((Word32
0xC,Word32
0x225), Keycode
KeyForward)
  , ((Word32
0xC,Word32
0x226), Keycode
KeyStop)
  , ((Word32
0xC,Word32
0x227), Keycode
KeyRefresh)
  -- , ((0xC,0x228), KeyACPreviousLink)
  -- , ((0xC,0x229), KeyACNextLink)
  , ((Word32
0xC,Word32
0x22A), Keycode
KeyBookmarks)
  -- , ((0xC,0x22B), KeyACHistory)
  -- , ((0xC,0x22C), KeyACSubscriptions)
  , ((Word32
0xC,Word32
0x22D), Keycode
KeyZoomIn)
  , ((Word32
0xC,Word32
0x22E), Keycode
KeyZoomOut)
  , ((Word32
0xC,Word32
0x22F), Keycode
KeyZoomReset)
  -- , ((0xC,0x230), KeyACFullScreenView)
  -- , ((0xC,0x231), KeyACNormalView)
  -- , ((0xC,0x232), KeyACViewToggle)
  , ((Word32
0xC,Word32
0x233), Keycode
KeyScrollUp)
  , ((Word32
0xC,Word32
0x234), Keycode
KeyScrollDown)
  -- , ((0xC,0x235), KeyACScroll)
  -- , ((0xC,0x236), KeyACPanLeft)
  -- , ((0xC,0x237), KeyACPanRight)
  -- , ((0xC,0x238), KeyACPan)
  -- , ((0xC,0x239), KeyACNewWindow)
  -- , ((0xC,0x23A), KeyACTileHorizontally)
  -- , ((0xC,0x23B), KeyACTileVertically)
  -- , ((0xC,0x23C), KeyACFormat)
  -- , ((0xC,0x23D), KeyACEdit)
  -- , ((0xC,0x23E), KeyACBold)
  -- , ((0xC,0x23F), KeyACItalics)
  -- , ((0xC,0x240), KeyACUnderline)
  -- , ((0xC,0x241), KeyACStrikethrough)
  -- , ((0xC,0x242), KeyACSubscript)
  -- , ((0xC,0x243), KeyACSuperscript)
  -- , ((0xC,0x244), KeyACAllCaps)
  -- , ((0xC,0x245), KeyACRotate)
  -- , ((0xC,0x246), KeyACResize)
  -- , ((0xC,0x247), KeyACFlipHorizontal)
  -- , ((0xC,0x248), KeyACFlipVertical)
  -- , ((0xC,0x249), KeyACMirrorHorizontal)
  -- , ((0xC,0x24A), KeyACMirrorVertical)
  -- , ((0xC,0x24B), KeyACFontSelect)
  -- , ((0xC,0x24C), KeyACFontColor)
  -- , ((0xC,0x24D), KeyACFontSize)
  -- , ((0xC,0x24E), KeyACJustifyLeft)
  -- , ((0xC,0x24F), KeyACJustifyCenterH)
  -- , ((0xC,0x250), KeyACJustifyRight)
  -- , ((0xC,0x251), KeyACJustifyBlockH)
  -- , ((0xC,0x252), KeyACJustifyTop)
  -- , ((0xC,0x253), KeyACJustifyCenterV)
  -- , ((0xC,0x254), KeyACJustifyBottom)
  -- , ((0xC,0x255), KeyACJustifyBlockV)
  -- , ((0xC,0x256), KeyACIndentyDecrease)
  -- , ((0xC,0x257), KeyACIndentyIncrease)
  -- , ((0xC,0x258), KeyACNumberedList)
  -- , ((0xC,0x259), KeyACRestartNumbering)
  -- , ((0xC,0x25A), KeyACBulletedList)
  -- , ((0xC,0x25B), KeyACPromote)
  -- , ((0xC,0x25C), KeyACDemote)
  -- , ((0xC,0x25D), KeyACYes)
  -- , ((0xC,0x25E), KeyACNo)
  , ((Word32
0xC,Word32
0x25F), Keycode
KeyCancel) -- AC Cancel
  -- , ((0xC,0x260), KeyACCatalog)
  -- , ((0xC,0x261), KeyACBuyOrCheckout)
  -- , ((0xC,0x262), KeyACAddToCart)
  -- , ((0xC,0x263), KeyACExpand)
  -- , ((0xC,0x264), KeyACExpandAll)
  -- , ((0xC,0x265), KeyACCollapse)
  -- , ((0xC,0x266), KeyACCollapseAll)
  -- , ((0xC,0x267), KeyACPrintPreview)
  -- , ((0xC,0x268), KeyACPasteSpecial)
  -- , ((0xC,0x269), KeyACInsertMode)
  -- , ((0xC,0x26A), KeyACDelete)
  -- , ((0xC,0x26B), KeyACLock)
  -- , ((0xC,0x26C), KeyACUnlock)
  -- , ((0xC,0x26D), KeyACProtect)
  -- , ((0xC,0x26E), KeyACUnprotect)
  -- , ((0xC,0x26F), KeyACAttachComment)
  -- , ((0xC,0x270), KeyACDetachComment)
  -- , ((0xC,0x271), KeyACViewComment)
  -- , ((0xC,0x272), KeyACSelectWord)
  -- , ((0xC,0x273), KeyACSelectSentence)
  -- , ((0xC,0x274), KeyACSelectParagraph)
  -- , ((0xC,0x275), KeyACSelectColumn)
  -- , ((0xC,0x276), KeyACSelectRow)
  -- , ((0xC,0x277), KeyACSelectTable)
  -- , ((0xC,0x278), KeyACSelectObject)
  , ((Word32
0xC,Word32
0x279), Keycode
KeyRedo)
  -- , ((0xC,0x27A), KeyACSort)
  -- , ((0xC,0x27B), KeyACSortAscending)
  -- , ((0xC,0x27C), KeyACSortDescending)
  -- , ((0xC,0x27D), KeyACFilter)
  -- , ((0xC,0x27E), KeyACSetClock)
  -- , ((0xC,0x27F), KeyACViewClock)
  -- , ((0xC,0x280), KeyACSelectTimeZone)
  -- , ((0xC,0x281), KeyACEditTimeZones)
  -- , ((0xC,0x282), KeyACSetAlarm)
  -- , ((0xC,0x283), KeyACClearAlarm)
  -- , ((0xC,0x284), KeyACSnoozeAlarm)
  -- , ((0xC,0x285), KeyACResetAlarm)
  -- , ((0xC,0x286), KeyACSynchronize)
  -- , ((0xC,0x287), KeyACSendOrReceive)
  -- , ((0xC,0x288), KeyACSendTo)
  , ((Word32
0xC,Word32
0x289), Keycode
KeyReply)
  -- , ((0xC,0x28A), KeyACReplyAll)
  , ((Word32
0xC,Word32
0x28B), Keycode
KeyForwardMail)
  , ((Word32
0xC,Word32
0x28C), Keycode
KeySend)
  -- , ((0xC,0x28D), KeyACAttachFile)
  -- , ((0xC,0x28E), KeyACUpload)
  -- , ((0xC,0x28F), KeyACDownload)
  -- , ((0xC,0x290), KeyACSetBorders)
  -- , ((0xC,0x291), KeyACInsertRow)
  -- , ((0xC,0x292), KeyACInsertColumn)
  -- , ((0xC,0x293), KeyACInsertFile)
  -- , ((0xC,0x294), KeyACInsertPicture)
  -- , ((0xC,0x295), KeyACInsertObject)
  -- , ((0xC,0x296), KeyACInsertSymbol)
  -- , ((0xC,0x297), KeyACSaveAndClose)
  -- , ((0xC,0x298), KeyACRename)
  -- , ((0xC,0x299), KeyACMerge)
  -- , ((0xC,0x29A), KeyACSplit)
  -- , ((0xC,0x29B), KeyACDistributeH)
  -- , ((0xC,0x29C), KeyACDistributeV)
  -- , ((0xC,0x29D), KeyACKeyboardLayoutSelect)
  -- , ((0xC,0x29E), KeyACNavigationGuidance)
  -- , ((0xC,0x29F), KeyACDesktopShowAllWindows)
  -- , ((0xC,0x2A0), KeyACSoftKeyLeft)
  -- , ((0xC,0x2A1), KeyACSoftKeyRight)
  -- , ((0xC,0x2A2), KeyACDesktopShowAllApplications)
  -- 0x02A3 - 0x02AF Reserved
  -- , ((0xC,0x2B0), KeyACIdleKeepAlive)
  -- 0x02B1 - 0x02BF Reserved
  -- , ((0xC,0x2C0), KeyExtendedKeyboardAttributesCollection)
  -- , ((0xC,0x2C1), KeyKeyboardFormFactor)
  -- , ((0xC,0x2C2), KeyKeyboardKeyType)
  -- , ((0xC,0x2C3), KeyKeyboardPhysicalLayout)
  -- , ((0xC,0x2C4), KeyVendorSpecificKeyboardPhysicalLayout)
  -- , ((0xC,0x2C5), KeyKeyboardIETFLanguageTagIndex)
  -- , ((0xC,0x2C6), KeyImplementedKeyboardInputAssistControls)
  -- , ((0xC,0x2C7), KeyKeyboardInputAssistPrevious)
  -- , ((0xC,0x2C8), KeyKeyboardInputAssistNext)
  -- , ((0xC,0x2C9), KeyKeyboardInputAssistPreviousGroup)
  -- , ((0xC,0x2CA), KeyKeyboardInputAssistNextGroup)
  -- , ((0xC,0x2CB), KeyKeyboardInputAssistAccept)
  -- , ((0xC,0x2CC), KeyKeyboardInputAssistCancel)
  -- 0x02CD - 0x04FF Reserved
  -- , ((0xC,0x500), KeyContactEdited)
  -- , ((0xC,0x501), KeyContactAdded)
  -- , ((0xC,0x502), KeyContactRecordActive)
  -- , ((0xC,0x503), KeyContactIndex)
  -- , ((0xC,0x504), KeyContactNickname)
  -- , ((0xC,0x505), KeyContactFirstName)
  -- , ((0xC,0x506), KeyContactLastName)
  -- , ((0xC,0x507), KeyContactFullName)
  -- , ((0xC,0x508), KeyContactPhoneNumberPersonal)
  -- , ((0xC,0x509), KeyContactPhoneNumberBusiness)
  -- , ((0xC,0x50A), KeyContactPhoneNumberMobile)
  -- , ((0xC,0x50B), KeyContactPhoneNumberPager)
  -- , ((0xC,0x50C), KeyContactPhoneNumberFax)
  -- , ((0xC,0x50D), KeyContactPhoneNumberOther)
  -- , ((0xC,0x50E), KeyContactEmailPersonal)
  -- , ((0xC,0x50F), KeyContactEmailBusiness)
  -- , ((0xC,0x510), KeyContactEmailOther)
  -- , ((0xC,0x511), KeyContactEmailMain)
  -- , ((0xC,0x512), KeyContactSpeedDialNumber)
  -- , ((0xC,0x513), KeyContactStatusFlag)
  -- , ((0xC,0x514), KeyContactMisc)
  , ((Word32
0xFF,Word32
0x3), Keycode
KeyFn)
  , ((Word32
0xFF,Word32
0x4), Keycode
KeyBrightnessUp)
  , ((Word32
0xFF,Word32
0x5), Keycode
KeyBrightnessDown)
  , ((Word32
0xFF,Word32
0x8), Keycode
KeyKbdIllumUp)
  , ((Word32
0xFF,Word32
0x9), Keycode
KeyKbdIllumDown)
  , ((Word32
0xFF01,Word32
0x1), Keycode
KeySpotlight)
  , ((Word32
0xFF01,Word32
0x4), Keycode
KeyLaunchpad)
  , ((Word32
0xFF01,Word32
0x10), Keycode
KeyMissionCtrl)
  ]