#line 471 "/home/travis/build/felix-lang/felix/src/packages/sdl.fdoc"
  
  open class SDL_events_h
  {
    requires package "sdl2";
  
    cenum SDL_EventType =
        SDL_FIRSTEVENT,             /**< Unused (do not remove) */
  
        /* Application events */
        SDL_QUIT,                   /**< User-requested quit */
  
        /* These application events have special meaning on iOS, see README.iOS for details */
        SDL_APP_TERMINATING,        /**< The application is being terminated by the OS
                                         Called on iOS in applicationWillTerminate()
                                         Called on Android in onDestroy()
                                    */
        SDL_APP_LOWMEMORY,          /**< The application is low on memory, free memory if possible.
                                         Called on iOS in applicationDidReceiveMemoryWarning()
                                         Called on Android in onLowMemory()
                                    */
        SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background
                                         Called on iOS in applicationWillResignActive()
                                         Called on Android in onPause()
                                    */
        SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time
                                         Called on iOS in applicationDidEnterBackground()
                                         Called on Android in onPause()
                                    */
        SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground
                                         Called on iOS in applicationWillEnterForeground()
                                         Called on Android in onResume()
                                    */
        SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive
                                         Called on iOS in applicationDidBecomeActive()
                                         Called on Android in onResume()
                                    */
  
        /* Window events */
        SDL_WINDOWEVENT,            /**< Window state change */
        SDL_SYSWMEVENT,             /**< System specific event */
  
        /* Keyboard events */
        SDL_KEYDOWN,                /**< Key pressed */
        SDL_KEYUP,                  /**< Key released */
        SDL_TEXTEDITING,            /**< Keyboard text editing (composition) */
        SDL_TEXTINPUT,              /**< Keyboard text input */
  
        /* Mouse events */
        SDL_MOUSEMOTION,            /**< Mouse moved */
        SDL_MOUSEBUTTONDOWN,        /**< Mouse button pressed */
        SDL_MOUSEBUTTONUP,          /**< Mouse button released */
        SDL_MOUSEWHEEL,             /**< Mouse wheel motion */
  
        /* Joystick events */
        SDL_JOYAXISMOTION,          /**< Joystick axis motion */
        SDL_JOYBALLMOTION,          /**< Joystick trackball motion */
        SDL_JOYHATMOTION,           /**< Joystick hat position change */
        SDL_JOYBUTTONDOWN,          /**< Joystick button pressed */
        SDL_JOYBUTTONUP,            /**< Joystick button released */
        SDL_JOYDEVICEADDED,         /**< A new joystick has been inserted into the system */
        SDL_JOYDEVICEREMOVED,       /**< An opened joystick has been removed */
  
        /* Game controller events */
        SDL_CONTROLLERAXISMOTION,          /**< Game controller axis motion */
        SDL_CONTROLLERBUTTONDOWN,          /**< Game controller button pressed */
        SDL_CONTROLLERBUTTONUP,            /**< Game controller button released */
        SDL_CONTROLLERDEVICEADDED,         /**< A new Game controller has been inserted into the system */
        SDL_CONTROLLERDEVICEREMOVED,       /**< An opened Game controller has been removed */
        SDL_CONTROLLERDEVICEREMAPPED,      /**< The controller mapping was updated */
  
        /* Touch events */
        SDL_FINGERDOWN,
        SDL_FINGERUP,
        SDL_FINGERMOTION,
  
        /* Gesture events */
        SDL_DOLLARGESTURE,
        SDL_DOLLARRECORD,
        SDL_MULTIGESTURE,
  
        /* Clipboard events */
        SDL_CLIPBOARDUPDATE,         /**< The clipboard changed */
  
        /* Drag and drop events */
        SDL_DROPFILE,                 /**< The system requests a file open */
  
        /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
         *  and should be allocated with SDL_RegisterEvents()
         */
        SDL_USEREVENT,
  
        /**
         *  This last event is only for bounding internal arrays
         */
        SDL_LASTEVENT    /* 0xFFFF */
    ;
  
    instance Str[SDL_EventType] {
      fun str: SDL_EventType -> string =
        | $(SDL_FIRSTEVENT) => "SDL_FIRSTEVENT"
        | $(SDL_QUIT) => "SDL_QUIT"
        | $(SDL_APP_TERMINATING) => "SDL_APP_TERMINATING"
        | $(SDL_APP_LOWMEMORY) => "SDL_APP_LOWMEMORY"
        | $(SDL_APP_WILLENTERBACKGROUND) => "SDL_APP_WILLENTERBACKGROUND"
        | $(SDL_APP_DIDENTERBACKGROUND) => "SDL_APP_DIDENTERBACKGROUND"
        | $(SDL_APP_WILLENTERFOREGROUND) => "SDL_APP_WILLENTERFOREGROUND"
        | $(SDL_APP_DIDENTERFOREGROUND) => "SDL_APP_DIDENTERFOREGROUND"
        | $(SDL_WINDOWEVENT) => "SDL_WINDOWEVENT"
        | $(SDL_SYSWMEVENT) => "SDL_SYSWMEVENT"
        | $(SDL_KEYDOWN) => "SDL_KEYDOWN"
        | $(SDL_KEYUP) => "SDL_KEYUP"
        | $(SDL_TEXTEDITING) => "SDL_TEXTEDITING"
        | $(SDL_TEXTINPUT) => "SDL_TEXTINPUT"
        | $(SDL_MOUSEMOTION) => "SDL_MOUSEMOTION"
        | $(SDL_MOUSEBUTTONDOWN) => "SDL_MOUSEBUTTONDOWN"
        | $(SDL_MOUSEBUTTONUP) => "SDL_MOUSEBUTTONUP"
        | $(SDL_MOUSEWHEEL) => "SDL_MOUSEWHEEL"
        | $(SDL_JOYAXISMOTION) => "SDL_JOYAXISMOTION"
        | $(SDL_JOYBALLMOTION) => "SDL_JOYBALLMOTION"
        | $(SDL_JOYHATMOTION) => "SDL_JOYHATMOTION"
        | $(SDL_JOYBUTTONDOWN) => "SDL_JOYBUTTONDOWN"
        | $(SDL_JOYBUTTONUP) => "SDL_JOYBUTTONUP"
        | $(SDL_JOYDEVICEADDED) => "SDL_JOYDEVICEADDED"
        | $(SDL_JOYDEVICEREMOVED) => "SDL_JOYDEVICEREMOVED"
        | $(SDL_CONTROLLERAXISMOTION) => "SDL_CONTROLLERAXISMOTION"
        | $(SDL_CONTROLLERBUTTONDOWN) => "SDL_CONTROLLERBUTTONDOWN"
        | $(SDL_CONTROLLERBUTTONUP) => "SDL_CONTROLLERBUTTONUP"
        | $(SDL_CONTROLLERDEVICEADDED) => "SDL_CONTROLLERDEVICEADDED"
        | $(SDL_CONTROLLERDEVICEREMOVED) => "SDL_CONTROLLERDEVICEREMOVED"
        | $(SDL_CONTROLLERDEVICEREMAPPED) => "SDL_CONTROLLERDEVICEREMAPPED"
        | $(SDL_FINGERDOWN) => "SDL_FINGERDOWN"
        | $(SDL_FINGERUP) => "SDL_FINGERUP"
        | $(SDL_FINGERMOTION) => "SDL_FINGERMOTION"
        | $(SDL_DOLLARGESTURE) => "SDL_DOLLARGESTURE"
        | $(SDL_DOLLARRECORD) => "SDL_DOLLARRECORD"
        | $(SDL_MULTIGESTURE) => "SDL_MULTIGESTURE"
        | $(SDL_CLIPBOARDUPDATE) => "SDL_CLIPBOARDUPDATE"
        | $(SDL_DROPFILE) => "SDL_DROPFILE"
        | $(SDL_USEREVENT) => "SDL_USEREVENT"
        | x => "UNKNOWN_EVENT #"+x.uint32.str
      ;
    }
  
    ctor uint32 : SDL_EventType = "(uint32_t)$1";
    ctor SDL_EventType : uint32 = "(SDL_EventType)$1";
  
    cenum SDL_WindowEventID =
      SDL_WINDOWEVENT_NONE,
      SDL_WINDOWEVENT_SHOWN,
      SDL_WINDOWEVENT_HIDDEN,
      SDL_WINDOWEVENT_EXPOSED,
      SDL_WINDOWEVENT_MOVED,
      SDL_WINDOWEVENT_RESIZED,
      SDL_WINDOWEVENT_SIZE_CHANGED,
      SDL_WINDOWEVENT_MINIMIZED,
      SDL_WINDOWEVENT_MAXIMIZED,
      SDL_WINDOWEVENT_RESTORED,
      SDL_WINDOWEVENT_ENTER,
      SDL_WINDOWEVENT_LEAVE,
      SDL_WINDOWEVENT_FOCUS_GAINED,
      SDL_WINDOWEVENT_FOCUS_LOST,
      SDL_WINDOWEVENT_CLOSE
    ;
    instance Str[SDL_WindowEventID] {
      fun str : SDL_WindowEventID -> string =
      | $(SDL_WINDOWEVENT_NONE) => "none"
      | $(SDL_WINDOWEVENT_SHOWN) => "shown"
      | $(SDL_WINDOWEVENT_HIDDEN) => "hidden"
      | $(SDL_WINDOWEVENT_EXPOSED) => "exposed"
      | $(SDL_WINDOWEVENT_MOVED) => "moved"
      | $(SDL_WINDOWEVENT_RESIZED) => "resized"
      | $(SDL_WINDOWEVENT_SIZE_CHANGED) => "size_changed"
      | $(SDL_WINDOWEVENT_MINIMIZED) => "minimised"
      | $(SDL_WINDOWEVENT_MAXIMIZED) => "maximised"
      | $(SDL_WINDOWEVENT_RESTORED) => "restored"
      | $(SDL_WINDOWEVENT_ENTER) => "enter"
      | $(SDL_WINDOWEVENT_LEAVE) => "leave"
      | $(SDL_WINDOWEVENT_FOCUS_GAINED) => "focus_gained"
      | $(SDL_WINDOWEVENT_FOCUS_LOST) => "focus_lost"
      | $(SDL_WINDOWEVENT_CLOSE) => "close"
      | x => "UnknownWindowEvent #"+x.uint8.str
      ;
    }
    ctor uint8 : SDL_WindowEventID = "(uint8_t)$1";
    ctor SDL_WindowEventID : uint8 = "(SDL_WindowEventID)$1";
  
    // Warning: inaccurate cstructs are
    // perfectly fine for reading and writing data,
    // even in this case, where the real
    // data is actually a union. All that is important
    // are the field names.
    //
    // However you must NOT constuct one with a
    // struct constructor!
    cstruct SDL_Event {
      type     : uint32;
      window   : SDL_WindowEvent;
      key      : SDL_KeyboardEvent;
      edit     : SDL_TextEditingEvent;
      text     : SDL_TextInputEvent;
      motion   : SDL_MouseMotionEvent;
      button   : SDL_MouseButtonEvent;
      wheel    : SDL_MouseWheelEvent;
      //jaxis    : SDL_JoystickAxisEvent;
      //jball    : SDL_JoystickBallEvent;
      //jhat     : SDL_JoystickHatEvent;
      //jbutton  : SDL_JoystickButtonEvent;
      quit     : SDL_QuitEvent;
      user     : SDL_UserEvent;
      syswm    : SDL_SysWMEvent;
      //tfinger  : SDL_TouchFingerEvent;
      //tbutton  : SDL_TouchButtonEvent;
      //mgesture : SDL_MultiGestureEvent;
      //dgesture : SDL_DollarGestureEvent;
      drop     : SDL_DropEvent;
    };
  
    /**
     *  \brief Fields shared by every event
     */
    typedef struct SDL_CommonEvent
    {
        uint32 type;
        uint32 timestamp;
    } SDL_CommonEvent;
  
    /**
     *  \brief Window state change event data (event.window.*)
     */
    typedef struct SDL_WindowEvent
    {
        uint32 type;        /**< ::SDL_WINDOWEVENT */
        uint32 timestamp;
        uint32 windowID;    /**< The associated window */
        uint8 event;        /**< ::SDL_WindowEventID */
        uint8 padding1;
        uint8 padding2;
        uint8 padding3;
        int32 data1;       /**< event dependent data */
        int32 data2;       /**< event dependent data */
    } SDL_WindowEvent;
  
    /**
     *  \brief Keyboard button event structure (event.key.*)
     */
    typedef struct SDL_KeyboardEvent
    {
        uint32 type;        /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
        uint32 timestamp;
        uint32 windowID;    /**< The window with keyboard focus, if any */
        uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
        uint8 repeat;       /**< Non-zero if this is a key repeat */
        uint8 padding2;
        uint8 padding3;
        SDL_Keysym keysym;  /**< The key that was pressed or released */
    } SDL_KeyboardEvent;
  
    macro val SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32;
    /**
     *  \brief Keyboard text editing event structure (event.edit.*)
     */
    typedef struct SDL_TextEditingEvent
    {
        uint32 type;                                /**< ::SDL_TEXTEDITING */
        uint32 timestamp;
        uint32 windowID;                            /**< The window with keyboard focus, if any */
        +char text;    /* actually a buffer size 32 */ /**< The editing text */
        int32 start;                               /**< The start cursor of selected editing text */
        int32 length;                              /**< The length of selected editing text */
    } SDL_TextEditingEvent;
  
    macro val SDL_TEXTINPUTEVENT_TEXT_SIZE = 32;
    /**
     *  \brief Keyboard text input event structure (event.text.*)
     */
    typedef struct SDL_TextInputEvent
    {
        uint32 type;                              /**< ::SDL_TEXTINPUT */
        uint32 timestamp;
        uint32 windowID;                          /**< The window with keyboard focus, if any */
        +char text;       /* actually a buffer */ /**< The input text */
    } SDL_TextInputEvent;
  
    /**
     *  \brief Mouse motion event structure (event.motion.*)
     */
    typedef struct SDL_MouseMotionEvent
    {
        uint32 type;        /**< ::SDL_MOUSEMOTION */
        uint32 timestamp;
        uint32 windowID;    /**< The window with mouse focus, if any */
        uint32 which;       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
        uint32 state;       /**< The current button state */
        int32 x;           /**< X coordinate, relative to window */
        int32 y;           /**< Y coordinate, relative to window */
        int32 xrel;        /**< The relative motion in the X direction */
        int32 yrel;        /**< The relative motion in the Y direction */
    } SDL_MouseMotionEvent;
  
    /**
     *  \brief Mouse button event structure (event.button.*)
     */
    typedef struct SDL_MouseButtonEvent
    {
        uint32 type;        /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
        uint32 timestamp;
        uint32 windowID;    /**< The window with mouse focus, if any */
        uint32 which;       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
        uint8 button;       /**< The mouse button index */
        uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
        uint8 padding1;
        uint8 padding2;
        int32 x;           /**< X coordinate, relative to window */
        int32 y;           /**< Y coordinate, relative to window */
    } SDL_MouseButtonEvent;
  
    /**
     *  \brief Mouse wheel event structure (event.wheel.*)
     */
    typedef struct SDL_MouseWheelEvent
    {
        uint32 type;        /**< ::SDL_MOUSEWHEEL */
        uint32 timestamp;
        uint32 windowID;    /**< The window with mouse focus, if any */
        uint32 which;       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
        int32 x;           /**< The amount scrolled horizontally */
        int32 y;           /**< The amount scrolled vertically */
    } SDL_MouseWheelEvent;
  
  /*
    /**
     *  \brief Joystick axis motion event structure (event.jaxis.*)
     */
    typedef struct SDL_JoyAxisEvent
    {
        uint32 type;        /**< ::SDL_JOYAXISMOTION */
        uint32 timestamp;
        SDL_JoystickID which; /**< The joystick instance id */
        uint8 axis;         /**< The joystick axis index */
        uint8 padding1;
        uint8 padding2;
        uint8 padding3;
        int16 value;       /**< The axis value (range: -32768 to 32767) */
        uint16 padding4;
    } SDL_JoyAxisEvent;
  */
    /**
     *  \brief Joystick trackball motion event structure (event.jball.*)
     */
  /*
    typedef struct SDL_JoyBallEvent
    {
        uint32 type;        /**< ::SDL_JOYBALLMOTION */
        uint32 timestamp;
        SDL_JoystickID which; /**< The joystick instance id */
        uint8 ball;         /**< The joystick trackball index */
        uint8 padding1;
        uint8 padding2;
        uint8 padding3;
        int16 xrel;        /**< The relative motion in the X direction */
        int16 yrel;        /**< The relative motion in the Y direction */
    } SDL_JoyBallEvent;
  */
    /**
     *  \brief Joystick hat position change event structure (event.jhat.*)
     */
  /*
    typedef struct SDL_JoyHatEvent
    {
        uint32 type;        /**< ::SDL_JOYHATMOTION */
        uint32 timestamp;
        SDL_JoystickID which; /**< The joystick instance id */
        uint8 hat;          /**< The joystick hat index */
        uint8 value;        /**< The hat position value.
                             *   \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP
                             *   \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT
                             *   \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN
                             *
                             *   Note that zero means the POV is centered.
                             */
        uint8 padding1;
        uint8 padding2;
    } SDL_JoyHatEvent;
  */
  /*
    /**
     *  \brief Joystick button event structure (event.jbutton.*)
     */
    typedef struct SDL_JoyButtonEvent
    {
        uint32 type;        /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */
        uint32 timestamp;
        SDL_JoystickID which; /**< The joystick instance id */
        uint8 button;       /**< The joystick button index */
        uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
        uint8 padding1;
        uint8 padding2;
    } SDL_JoyButtonEvent;
  */
  /*
    /**
     *  \brief Joystick device event structure (event.jdevice.*)
     */
    typedef struct SDL_JoyDeviceEvent
    {
        uint32 type;        /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */
        uint32 timestamp;
        int32 which;       /**< The joystick device index for the ADDED event, instance id for the REMOVED event */
    } SDL_JoyDeviceEvent;
  
  */
    /**
     *  \brief Game controller axis motion event structure (event.caxis.*)
     */
  /*
    typedef struct SDL_ControllerAxisEvent
    {
        uint32 type;        /**< ::SDL_CONTROLLERAXISMOTION */
        uint32 timestamp;
        SDL_JoystickID which; /**< The joystick instance id */
        uint8 axis;         /**< The controller axis (SDL_GameControllerAxis) */
        uint8 padding1;
        uint8 padding2;
        uint8 padding3;
        int16 value;       /**< The axis value (range: -32768 to 32767) */
        uint16 padding4;
    } SDL_ControllerAxisEvent;
  */
  /*
    /**
     *  \brief Game controller button event structure (event.cbutton.*)
     */
    typedef struct SDL_ControllerButtonEvent
    {
        uint32 type;        /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */
        uint32 timestamp;
        SDL_JoystickID which; /**< The joystick instance id */
        uint8 button;       /**< The controller button (SDL_GameControllerButton) */
        uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
        uint8 padding1;
        uint8 padding2;
    } SDL_ControllerButtonEvent;
  */
  /*
    /**
     *  \brief Controller device event structure (event.cdevice.*)
     */
    typedef struct SDL_ControllerDeviceEvent
    {
        uint32 type;        /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */
        uint32 timestamp;
        int32 which;       /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
    } SDL_ControllerDeviceEvent;
  
  */
  /*
    /**
     *  \brief Touch finger event structure (event.tfinger.*)
     */
    typedef struct SDL_TouchFingerEvent
    {
        uint32 type;        /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */
        uint32 timestamp;
        SDL_TouchID touchId; /**< The touch device id */
        SDL_FingerID fingerId;
        float x;            /**< Normalized in the range 0...1 */
        float y;            /**< Normalized in the range 0...1 */
        float dx;           /**< Normalized in the range 0...1 */
        float dy;           /**< Normalized in the range 0...1 */
        float pressure;     /**< Normalized in the range 0...1 */
    } SDL_TouchFingerEvent;
  
  */
  /*
    /**
     *  \brief Multiple Finger Gesture Event (event.mgesture.*)
     */
    typedef struct SDL_MultiGestureEvent
    {
        uint32 type;        /**< ::SDL_MULTIGESTURE */
        uint32 timestamp;
        SDL_TouchID touchId; /**< The touch device index */
        float dTheta;
        float dDist;
        float x;
        float y;
        uint16 numFingers;
        uint16 padding;
    } SDL_MultiGestureEvent;
  */
  /*
    /* (event.dgesture.*) */
    typedef struct SDL_DollarGestureEvent
    {
        uint32 type;        /**< ::SDL_DOLLARGESTURE */
        uint32 timestamp;
        SDL_TouchID touchId; /**< The touch device id */
        SDL_GestureID gestureId;
        uint32 numFingers;
        float error;
        float x;            /**< Normalized center of gesture */
        float y;            /**< Normalized center of gesture */
    } SDL_DollarGestureEvent;
  */
  
    /**
     *  \brief An event used to request a file open by the system (event.drop.*)
     *         This event is disabled by default, you can enable it with SDL_EventState()
     *  \note If you enable this event, you must free the filename in the event.
     */
    typedef struct SDL_DropEvent
    {
        uint32 type;        /**< ::SDL_DROPFILE */
        uint32 timestamp;
        +char file;         /**< The file name, which should be freed with SDL_free() */
    } SDL_DropEvent;
  
  
    /**
     *  \brief The "quit requested" event
     */
    typedef struct SDL_QuitEvent
    {
        uint32 type;        /**< ::SDL_QUIT */
        uint32 timestamp;
    } SDL_QuitEvent;
  
    /**
     *  \brief OS Specific event
     */
    typedef struct SDL_OSEvent
    {
        uint32 type;        /**< ::SDL_QUIT */
        uint32 timestamp;
    } SDL_OSEvent;
  
    /**
     *  \brief A user-defined event type (event.user.*)
     */
    typedef struct SDL_UserEvent
    {
        uint32 type;        /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */
        uint32 timestamp;
        uint32 windowID;    /**< The associated window if any */
        int32 n"code";        /**< User defined event code */
        address data1;        /**< User defined data pointer */
        address data2;        /**< User defined data pointer */
    } SDL_UserEvent;
  
  
    /*
    struct SDL_SysWMmsg;
    typedef struct SDL_SysWMmsg SDL_SysWMmsg;
    */
  
    /**
     *  \brief A video driver dependent system event (event.syswm.*)
     *         This event is disabled by default, you can enable it with SDL_EventState()
     *
     *  \note If you want to use this event, you should include SDL_syswm.h.
     */
    typedef struct SDL_SysWMEvent
    {
        uint32 type;        /**< ::SDL_SYSWMEVENT */
        uint32 timestamp;
        //SDL_SysWMmsg *msg;  /**< driver dependent data, defined in SDL_syswm.h */
        address msg;  /**< driver dependent data, defined in SDL_syswm.h */
    } SDL_SysWMEvent;
  
    fun SDL_GetWindowID (w:SDL_Event) : opt[uint32] =>
      match w.type.SDL_EventType with
      | $(SDL_WINDOWEVENT) => Some w.window.windowID
      | $(SDL_KEYDOWN) => Some w.key.windowID
      | $(SDL_KEYUP) => Some w.key.windowID
      | $(SDL_TEXTEDITING) => Some w.edit.windowID
      | $(SDL_TEXTINPUT) => Some w.text.windowID
      | $(SDL_MOUSEMOTION) => Some w.motion.windowID
      | $(SDL_MOUSEBUTTONDOWN) => Some w.button.windowID
      | $(SDL_MOUSEBUTTONUP) => Some w.button.windowID
      | $(SDL_MOUSEWHEEL) => Some w.wheel.windowID
      | _ => None[uint32]
      endmatch
    ;
  
    cenum SDL_eventaction =
      SDL_ADDEVENT,
      SDL_PEEKEVENT,
      SDL_GETEVENT
    ;
  
    gen SDL_PeepEvents:
      +SDL_Event * int /* numevents*/ *
      SDL_eventaction *
      uint32 /* minType */ * uint32 /* maxType */
      -> int
    ;
  
  /*@}*/
  /**
   *  Pumps the event loop, gathering events from the input devices.
   *
   *  This function updates the event queue and internal input device state.
   *
   *  This should only be run in the thread that sets the video mode.
   */
  
    proc SDL_PumpEvents: 1;
  
  /**
   *  Checks to see if certain event types are in the event queue.
   */
    fun SDL_HasEvent:uint32 /* type */ -> bool;
    fun SDL_HasEvents:uint32 /* minType */ * uint32 /* maxType */ -> bool;
  
  /**
   *  This function clears events from the event queue
   */
    proc SDL_FlushEvent:uint32;
    proc SDL_FlushEvents: uint32 /* minType */ * uint32 /* maxType */;
  
  /**
   *  \brief Polls for currently pending events.
   *
   *  \return 1 if there are any pending events, or 0 if there are none available.
   *
   *  \param event If not NULL, the next event is removed from the queue and
   *               stored in that area.
   */
   gen SDL_PollEvent: &SDL_Event -> int;
  
  /**
   *  \brief Waits indefinitely for the next available event.
   *
   *  \return 1, or 0 if there was an error while waiting for events.
   *
   *  \param event If not NULL, the next event is removed from the queue and
   *               stored in that area.
   */
    gen SDL_WaitEvent: &SDL_Event -> int;
  
  
  /**
   *  \brief Waits until the specified timeout (in milliseconds) for the next
   *         available event.
   *
   *  \return 1, or 0 if there was an error while waiting for events.
   *
   *  \param event If not NULL, the next event is removed from the queue and
   *               stored in that area.
   *  \param timeout The timeout (in milliseconds) to wait for next event.
   */
    gen SDL_WaitEventTimeout: &SDL_Event * int -> int;
  
  /**
   *  \brief Add an event to the event queue.
   *
   *  \return 1 on success, 0 if the event was filtered, or -1 if the event queue
   *          was full or there was some other error.
   */
    gen SDL_PushEvent: &SDL_Event -> int;
  
    typedef SDL_EventFilter =  address *  &SDL_Event --> int;
  
  /**
   *  Sets up a filter to process all events before they change internal state and
   *  are posted to the internal event queue.
   *
   *  The filter is prototyped as:
   *  \code
   *      int SDL_EventFilter(void *userdata, SDL_Event * event);
   *  \endcode
   *
   *  If the filter returns 1, then the event will be added to the internal queue.
   *  If it returns 0, then the event will be dropped from the queue, but the
   *  internal state will still be updated.  This allows selective filtering of
   *  dynamically arriving events.
   *
   *  \warning  Be very careful of what you do in the event filter function, as
   *            it may run in a different thread!
   *
   *  There is one caveat when dealing with the ::SDL_QuitEvent event type.  The
   *  event filter is only called when the window manager desires to close the
   *  application window.  If the event filter returns 1, then the window will
   *  be closed, otherwise the window will remain open if possible.
   *
   *  If the quit event is generated by an interrupt signal, it will bypass the
   *  internal queue and be delivered to the application at the next event poll.
   */
  
  /* TODO: convert to use Felix closures! */
  
    proc SDL_SetEventFilter: SDL_EventFilter * address;
  
  /**
   *  Return the current event filter - can be used to "chain" filters.
   *  If there is no event filter set, this function returns SDL_FALSE.
   */
    gen SDL_GetEventFilter: &SDL_EventFilter * &address -> bool;
  
  /**
   *  Add a function which is called when an event is added to the queue.
   */
    proc SDL_AddEventWatch: SDL_EventFilter * address;
  
  /**
   *  Remove an event watch function added with SDL_AddEventWatch()
   */
   proc SDL_DelEventWatch: SDL_EventFilter * address;
  
  /**
   *  Run the filter function on the current event queue, removing any
   *  events for which the filter returns 0.
   */
    proc SDL_FilterEvents:SDL_EventFilter * address;
  
    const SDL_QUERY : int; // -1
    const SDL_IGNORE: int; // 0
    const SDL_DISABLE : int; // 0
    const SDL_ENABLE : int; // 1
  
  /**
   *  This function allows you to set the state of processing certain events.
   *   - If \c state is set to ::SDL_IGNORE, that event will be automatically
   *     dropped from the event queue and will not event be filtered.
   *   - If \c state is set to ::SDL_ENABLE, that event will be processed
   *     normally.
   *   - If \c state is set to ::SDL_QUERY, SDL_EventState() will return the
   *     current processing state of the specified event.
   */
  
    gen SDL_EventState:uint32 * int -> int = "(int)SDL_EventState ($1,$2)";
  
  /**
   *  This function allocates a set of user-defined events, and returns
   *  the beginning event number for that set of events.
   *
   *  If there aren't enough user-defined events left, this function
   *  returns (Uint32)-1
   */
  /*
  extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);
  */
  
  
  }