         [ 3drop ]
     } cond ;
 
+HINTS: record-controller { controller-state alien } ;
+
 : ?set-nth ( value nth seq -- )
     2dup bounds-check? [ set-nth-unsafe ] [ 3drop ] if ;
 
-: record-keyboard ( value -- )
-    dup IOHIDValueGetElement keyboard-key? [
+: record-keyboard ( keyboard-state value -- )
+    dup IOHIDValueGetElement dup keyboard-key? [
         [ IOHIDValueGetIntegerValue c-bool> ]
-        [ IOHIDValueGetElement IOHIDElementGetUsage ] bi
-        +keyboard-state+ get ?set-nth
-    ] [ drop ] if ;
-
-: record-mouse ( value -- )
+        [ IOHIDElementGetUsage ] bi*
+        rot ?set-nth
+    ] [ 3drop ] if ;
+
+HINTS: record-keyboard { array alien } ;
+
+: record-mouse ( mouse-state value -- )
     dup IOHIDValueGetElement {
-        { [ dup button? ] [ +mouse-state+ get record-button ] }
+        { [ dup button? ] [ record-button ] }
         { [ dup axis? ] [ {
-            { [ dup x-axis? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-dx drop ] }
-            { [ dup y-axis? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-dy drop ] }
-            { [ dup wheel?  ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-scroll-dx drop ] }
-            { [ dup z-axis? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-scroll-dy drop ] }
-            [ 2drop ]
+            { [ dup x-axis? ] [ drop mouse-axis-value [ + ] curry change-dx drop ] }
+            { [ dup y-axis? ] [ drop mouse-axis-value [ + ] curry change-dy drop ] }
+            { [ dup wheel?  ] [ drop mouse-axis-value [ + ] curry change-scroll-dx drop ] }
+            { [ dup z-axis? ] [ drop mouse-axis-value [ + ] curry change-scroll-dy drop ] }
+            [ 3drop ]
         } cond ] }
-        [ 2drop ]
+        [ 3drop ]
     } cond ;
+
+HINTS: record-mouse { mouse-state alien } ;
 
 M: iokit-game-input-backend read-mouse
     +mouse-state+ get ;

    } cleave ;

M: iokit-game-input-backend (reset-game-input)
    { +hid-manager+ +keyboard-state+ +controller-states+ }
    [ f swap set-global ] each ;

M: iokit-game-input-backend (close-game-input)

            { [ sender controller-device? ] [
                sender +controller-states+ get at value record-controller
            ] }
            { [ sender mouse-device? ] [ +mouse-state+ get value record-mouse ] }
            [ +keyboard-state+ get value record-keyboard ]
        } cond
    ] IOHIDValueCallback ;

