sig
  type subsystem =
      [ `AUDIO
      | `EVENTS
      | `GAMECONTROLLER
      | `HAPTIC
      | `JOYSTICK
      | `TIMER
      | `VIDEO ]
  external init :
    [< `AUDIO
     | `EVENTS
     | `EVERYTHING
     | `GAMECONTROLLER
     | `HAPTIC
     | `JOYSTICK
     | `NOPARACHUTE
     | `TIMER
     | `VIDEO ]
    list -> unit = "caml_SDL_Init"
  external init_subsystem : Sdl.subsystem list -> unit
    = "caml_SDL_InitSubSystem"
  external quit : unit -> unit = "caml_SDL_Quit"
  external quit_requested : unit -> bool = "caml_SDL_QuitRequested"
  external get_platform : unit -> string = "caml_SDL_GetPlatform"
  module Init :
    sig
      type subsystem =
          [ `AUDIO
          | `EVENTS
          | `GAMECONTROLLER
          | `HAPTIC
          | `JOYSTICK
          | `TIMER
          | `VIDEO ]
      external init :
        [< `AUDIO
         | `EVENTS
         | `EVERYTHING
         | `GAMECONTROLLER
         | `HAPTIC
         | `JOYSTICK
         | `NOPARACHUTE
         | `TIMER
         | `VIDEO ]
        list -> unit = "caml_SDL_Init"
      external init_subsystem : Sdl.Init.subsystem list -> unit
        = "caml_SDL_InitSubSystem"
    end
  module Quit :
    sig
      external quit : unit -> unit = "caml_SDL_Quit"
      external quit_requested : unit -> bool = "caml_SDL_QuitRequested"
    end
  module Window :
    sig
      type t = Sdlwindow.t
      type window_flags =
        Sdlwindow.window_flags =
          FullScreen
        | OpenGL
        | Shown
        | Hidden
        | Borderless
        | Resizable
        | Minimized
        | Maximized
        | Input_Grabbed
        | Input_Focus
        | Mouse_Focus
        | FullScreen_Desktop
        | Foreign
        | Allow_HighDPI
      type window_pos = [ `centered | `pos of int | `undefined ]
      external create :
        title:string ->
        pos:Sdl.Window.window_pos * Sdl.Window.window_pos ->
        dims:int * int -> flags:Sdl.Window.window_flags list -> Sdl.Window.t
        = "caml_SDL_CreateWindow"
      external create2 :
        title:string ->
        x:Sdl.Window.window_pos ->
        y:Sdl.Window.window_pos ->
        width:int ->
        height:int -> flags:Sdl.Window.window_flags list -> Sdl.Window.t
        = "caml_SDL_CreateWindow2_bc" "caml_SDL_CreateWindow2"
      external set_title : window:Sdl.Window.t -> title:string -> unit
        = "caml_SDL_SetWindowTitle"
      external show : Sdl.Window.t -> unit = "caml_SDL_ShowWindow"
      external hide : Sdl.Window.t -> unit = "caml_SDL_HideWindow"
      external raise_win : Sdl.Window.t -> unit = "caml_SDL_RaiseWindow"
      external maximize : Sdl.Window.t -> unit = "caml_SDL_MaximizeWindow"
      external minimize : Sdl.Window.t -> unit = "caml_SDL_MinimizeWindow"
      external restore : Sdl.Window.t -> unit = "caml_SDL_RestoreWindow"
      external get_surface : Sdl.Window.t -> Sdlsurface.t
        = "caml_SDL_GetWindowSurface"
      external update_surface : Sdl.Window.t -> unit
        = "caml_SDL_UpdateWindowSurface"
      external set_brightness : Sdl.Window.t -> brightness:float -> unit
        = "caml_SDL_SetWindowBrightness"
      external get_brightness : Sdl.Window.t -> float
        = "caml_SDL_GetWindowBrightness"
      external destroy : Sdl.Window.t -> unit = "caml_SDL_DestroyWindow"
      external get_size : Sdl.Window.t -> int * int
        = "caml_SDL_GetWindowSize"
    end
  module Surface :
    sig
      type t = Sdlsurface.t
      external create_rgb :
        width:int -> height:int -> depth:int -> Sdl.Surface.t
        = "caml_SDL_CreateRGBSurface"
      external free : Sdl.Surface.t -> unit = "caml_SDL_FreeSurface"
      external load_bmp : filename:string -> Sdl.Surface.t
        = "caml_SDL_LoadBMP"
      external save_bmp : Sdl.Surface.t -> filename:string -> unit
        = "caml_SDL_SaveBMP"
      external fill_rect :
        dst:Sdl.Surface.t -> rect:Sdlrect.t -> color:int32 -> unit
        = "caml_SDL_FillRect"
      external blit_surface :
        src:Sdl.Surface.t ->
        src_rect:Sdlrect.t ->
        dst:Sdl.Surface.t -> dst_rect:Sdlrect.t -> Sdlrect.t
        = "caml_SDL_BlitSurface"
      external blit_surf :
        src:Sdl.Surface.t ->
        dst:Sdl.Surface.t -> dst_rect:Sdlrect.t -> Sdlrect.t
        = "caml_SDL_BlitSurf"
      external blit_surfs :
        src:Sdl.Surface.t -> dst:Sdl.Surface.t -> dst_rect:Sdlrect.t -> unit
        = "caml_SDL_BlitSurfs"
      external blit_pixels_unsafe : Sdl.Surface.t -> string -> unit
        = "caml_SDL_Surface_Blit_Pixels"
      external set_color_key :
        Sdl.Surface.t -> enable:bool -> key:int32 -> unit
        = "caml_SDL_SetColorKey"
      external set_color_key_map_rgb :
        Sdl.Surface.t -> enable:bool -> rgb:int * int * int -> unit
        = "caml_SDL_SetColorKey_MapRGB"
      external get_width : Sdl.Surface.t -> int = "caml_SDL_SurfaceGetWidth"
      external get_height : Sdl.Surface.t -> int
        = "caml_SDL_SurfaceGetHeight"
      external get_dims : Sdl.Surface.t -> int * int
        = "caml_SDL_SurfaceGetDims"
      external get_pitch : Sdl.Surface.t -> int = "caml_SDL_SurfaceGetPitch"
      external get_pixel32_unsafe : Sdl.Surface.t -> x:int -> y:int -> int32
        = "caml_SDL_SurfaceGetPixel32"
      external get_pixel16_unsafe : Sdl.Surface.t -> x:int -> y:int -> int32
        = "caml_SDL_SurfaceGetPixel16"
      external get_pixel8_unsafe : Sdl.Surface.t -> x:int -> y:int -> int32
        = "caml_SDL_SurfaceGetPixel8"
      external get_bits_per_pixel : Sdl.Surface.t -> int
        = "caml_SDL_SurfaceGetBitsPerPixel"
      external has_palette : Sdl.Surface.t -> bool
        = "caml_SDL_SurfaceHasPalette"
      external palette_num_colors : Sdl.Surface.t -> int
        = "caml_SDL_SurfacePaletteColors"
      external set_blend_mode : Sdl.Surface.t -> SdlblendMode.t -> unit
        = "caml_SDL_SetSurfaceBlendMode"
      external get_pixelformat_t : Sdl.Surface.t -> SdlpixelFormat.t
        = "caml_SDL_Surface_get_pixelformat_t"
      external get_pixels : Sdl.Surface.t -> string
        = "caml_SDL_Surface_get_pixels"
    end
  module Render :
    sig
      type t = Sdltype.renderer
      external create_window_and_renderer :
        width:int ->
        height:int ->
        flags:Sdlwindow.window_flags list -> Sdlwindow.t * Sdl.Render.t
        = "caml_SDL_CreateWindowAndRenderer"
      type renderer_flags =
        Sdlrender.renderer_flags =
          Software
        | Accelerated
        | PresentVSync
        | TargetTexture
      val string_of_renderer_flags : Sdl.Render.renderer_flags -> string
      val renderer_flags_of_string : string -> Sdl.Render.renderer_flags
      external create_renderer :
        win:Sdlwindow.t ->
        index:int -> flags:Sdl.Render.renderer_flags list -> Sdl.Render.t
        = "caml_SDL_CreateRenderer"
      external get_output_size : Sdl.Render.t -> int * int
        = "caml_SDL_GetRendererOutputSize"
      external set_logical_size : Sdl.Render.t -> int * int -> unit
        = "caml_SDL_RenderSetLogicalSize"
      external set_logical_size2 :
        Sdl.Render.t -> width:int -> height:int -> unit
        = "caml_SDL_RenderSetLogicalSize2"
      external set_viewport : Sdl.Render.t -> Sdlrect.t -> unit
        = "caml_SDL_RenderSetViewport"
      external set_clip_rect : Sdl.Render.t -> Sdlrect.t -> unit
        = "caml_SDL_RenderSetClipRect"
      external set_draw_color :
        Sdl.Render.t -> rgb:int * int * int -> a:int -> unit
        = "caml_SDL_SetRenderDrawColor"
      external set_draw_color3 :
        Sdl.Render.t -> r:int -> g:int -> b:int -> a:int -> unit
        = "caml_SDL_SetRenderDrawColor3"
      external set_draw_blend_mode : Sdl.Render.t -> SdlblendMode.t -> unit
        = "caml_SDL_SetRenderDrawBlendMode"
      external draw_point : Sdl.Render.t -> int * int -> unit
        = "caml_SDL_RenderDrawPoint"
      external draw_point2 : Sdl.Render.t -> x:int -> y:int -> unit
        = "caml_SDL_RenderDrawPoint2"
      external draw_points : Sdl.Render.t -> points:(int * int) array -> unit
        = "caml_SDL_RenderDrawPoints"
      external draw_line : Sdl.Render.t -> (int * int) * (int * int) -> unit
        = "caml_SDL_RenderDrawLine"
      external draw_line2 :
        Sdl.Render.t -> p1:int * int -> p2:int * int -> unit
        = "caml_SDL_RenderDrawLine2"
      external draw_lines : Sdl.Render.t -> (int * int) array -> unit
        = "caml_SDL_RenderDrawLines"
      external draw_rect : Sdl.Render.t -> Sdlrect.t -> unit
        = "caml_SDL_RenderDrawRect"
      external draw_rects : Sdl.Render.t -> Sdlrect.t array -> unit
        = "caml_SDL_RenderDrawRects"
      external fill_rect : Sdl.Render.t -> Sdlrect.t -> unit
        = "caml_SDL_RenderFillRect"
      external fill_rects : Sdl.Render.t -> Sdlrect.t array -> unit
        = "caml_SDL_RenderFillRects"
      external copy :
        Sdl.Render.t ->
        texture:Sdltexture.t ->
        ?src_rect:Sdlrect.t -> ?dst_rect:Sdlrect.t -> unit -> unit
        = "caml_SDL_RenderCopy"
      type renderer_flip =
        Sdlrender.renderer_flip =
          Flip_None
        | Flip_Horizontal
        | Flip_Vertical
      external copyEx :
        Sdl.Render.t ->
        texture:Sdltexture.t ->
        ?src_rect:Sdlrect.t ->
        ?dst_rect:Sdlrect.t ->
        ?angle:float ->
        ?center:int * int -> ?flip:Sdl.Render.renderer_flip -> unit -> unit
        = "caml_SDL_RenderCopyEx_bc" "caml_SDL_RenderCopyEx"
      external set_scale : Sdl.Render.t -> float * float -> unit
        = "caml_SDL_RenderSetScale"
      external render_present : Sdl.Render.t -> unit
        = "caml_SDL_RenderPresent"
      external clear : Sdl.Render.t -> unit = "caml_SDL_RenderClear"
      type renderer_info =
        Sdlrender.renderer_info = {
        name : string;
        max_texture_width : int;
        max_texture_height : int;
      }
      external get_render_drivers : unit -> Sdl.Render.renderer_info array
        = "caml_SDL_GetRenderDrivers"
      external read_pixels :
        Sdl.Render.t -> ?rect:Sdlrect.t -> Sdlsurface.t -> unit
        = "caml_SDL_RenderReadPixels"
      external set_render_target :
        Sdl.Render.t -> Sdltexture.t option -> unit
        = "caml_SDL_SetRenderTarget"
    end
  module Texture :
    sig
      type t = Sdltexture.t
      external create :
        Sdltype.renderer ->
        SdlpixelFormat.t -> SdltextureAccess.t -> int -> int -> Sdl.Texture.t
        = "caml_SDL_CreateTexture"
      external create_from_surface :
        Sdltype.renderer -> Sdlsurface.t -> Sdl.Texture.t
        = "caml_SDL_CreateTextureFromSurface"
      external destroy : Sdl.Texture.t -> unit = "caml_SDL_DestroyTexture"
      external set_blend_mode : Sdl.Texture.t -> SdlblendMode.t -> unit
        = "caml_SDL_SetTextureBlendMode" [@@noalloc]
      external get_blend_mode : Sdl.Texture.t -> SdlblendMode.t
        = "caml_SDL_GetTextureBlendMode"
      external set_alpha_mod : Sdl.Texture.t -> alpha:int -> unit
        = "caml_SDL_SetTextureAlphaMod"
      external get_alpha_mod : Sdl.Texture.t -> int
        = "caml_SDL_GetTextureAlphaMod"
      external set_color_mod : Sdl.Texture.t -> int * int * int -> unit
        = "caml_SDL_SetTextureColorMod"
      external set_color_mod3 :
        Sdl.Texture.t -> r:int -> g:int -> b:int -> unit
        = "caml_SDL_SetTextureColorMod3"
      external get_color_mod : Sdl.Texture.t -> int * int * int
        = "caml_SDL_GetTextureColorMod"
    end
  module TextureAccess :
    sig
      type t = SdltextureAccess.t = Static | Streaming | Target
      val to_string : Sdl.TextureAccess.t -> string
      val of_string : string -> Sdl.TextureAccess.t
    end
  module PixelFormat :
    sig
      type t =
        SdlpixelFormat.t =
          Unknown
        | Index1LSB
        | Index1MSB
        | Index4LSB
        | Index4MSB
        | Index8
        | RGB332
        | RGB444
        | RGB555
        | BGR555
        | ARGB4444
        | RGBA4444
        | ABGR4444
        | BGRA4444
        | ARGB1555
        | RGBA5551
        | ABGR1555
        | BGRA5551
        | RGB565
        | BGR565
        | RGB24
        | BGR24
        | RGB888
        | RGBX8888
        | BGR888
        | BGRX8888
        | ARGB8888
        | RGBA8888
        | ABGR8888
        | BGRA8888
        | ARGB2101010
        | YV12
        | IYUV
        | YUY2
        | UYVY
        | YVYU
      val to_string : Sdl.PixelFormat.t -> string
      val of_string : string -> Sdl.PixelFormat.t
    end
  module Pixel :
    sig
      external get_pixel_format_name : SdlpixelFormat.t -> string
        = "caml_SDL_GetPixelFormatName"
      type pixel_format = Sdlpixel.pixel_format
      external alloc_format : SdlpixelFormat.t -> Sdl.Pixel.pixel_format
        = "caml_SDL_AllocFormat"
      external free_format : Sdl.Pixel.pixel_format -> unit
        = "caml_SDL_FreeFormat"
      type uint8 = int
      type rgb = Sdl.Pixel.uint8 * Sdl.Pixel.uint8 * Sdl.Pixel.uint8
      type rgba =
          Sdl.Pixel.uint8 * Sdl.Pixel.uint8 * Sdl.Pixel.uint8 *
          Sdl.Pixel.uint8
      external map_RGB : Sdl.Pixel.pixel_format -> rgb:Sdl.Pixel.rgb -> int32
        = "caml_SDL_MapRGB"
      external map_RGBA :
        Sdl.Pixel.pixel_format -> rgba:Sdl.Pixel.rgba -> int32
        = "caml_SDL_MapRGBA"
      external get_RGB :
        pixel:int32 -> fmt:Sdl.Pixel.pixel_format -> Sdl.Pixel.rgb
        = "caml_SDL_GetRGB"
      external get_RGBA :
        pixel:int32 -> fmt:Sdl.Pixel.pixel_format -> Sdl.Pixel.rgba
        = "caml_SDL_GetRGBA"
    end
  module BlendMode :
    sig
      type t = SdlblendMode.t = BNone | Blend | Add | Mod
      val to_string : Sdl.BlendMode.t -> string
      val of_string : string -> Sdl.BlendMode.t
    end
  module Event :
    sig
      type state = Sdlevent.state = Released | Pressed
      val string_of_state : Sdl.Event.state -> string
      type keyboard_event =
        Sdlevent.keyboard_event = {
        ke_timestamp : int32;
        ke_window_id : int32;
        ke_state : Sdl.Event.state;
        ke_repeat : int;
        scancode : Sdlscancode.t;
        keycode : Sdlkeycode.t;
        keymod : Sdlkeymod.t list;
      }
      type mouse_motion_event =
        Sdlevent.mouse_motion_event = {
        mm_timestamp : int32;
        mm_window_id : int32;
        mm_buttons : int list;
        mm_x : int;
        mm_y : int;
        mm_xrel : int;
        mm_yrel : int;
      }
      type mouse_button_event =
        Sdlevent.mouse_button_event = {
        mb_timestamp : int32;
        mb_window_id : int32;
        mb_button : int;
        mb_state : Sdl.Event.state;
        mb_x : int;
        mb_y : int;
      }
      type mouse_wheel_event =
        Sdlevent.mouse_wheel_event = {
        mw_timestamp : int32;
        mw_window_id : int32;
        mw_x : int;
        mw_y : int;
      }
      type joy_axis_event =
        Sdlevent.joy_axis_event = {
        ja_timestamp : int32;
        ja_which : int;
        ja_axis : int;
        ja_value : int;
      }
      type joy_button_event =
        Sdlevent.joy_button_event = {
        jb_timestamp : int32;
        jb_which : int;
        jb_button : int;
        jb_state : Sdl.Event.state;
      }
      type joy_hat_event =
        Sdlevent.joy_hat_event = {
        jh_timestamp : int32;
        jh_which : int;
        jh_hat : int;
        jh_dir : Sdlhat.direction;
        jh_pos : Sdlhat.positions;
      }
      type joy_device_change =
        Sdlevent.joy_device_change =
          JoyDevice_Added
        | JoyDevice_Removed
      val string_of_joy_device_change : Sdl.Event.joy_device_change -> string
      type joy_device_event =
        Sdlevent.joy_device_event = {
        jd_timestamp : int32;
        jd_which : int;
        jd_change : Sdl.Event.joy_device_change;
      }
      type window_event_xy =
        Sdlevent.window_event_xy = {
        win_x : int;
        win_y : int;
      }
      type window_event_kind =
        Sdlevent.window_event_kind =
          WindowEvent_None
        | WindowEvent_Shown
        | WindowEvent_Hidden
        | WindowEvent_Exposed
        | WindowEvent_Moved of Sdl.Event.window_event_xy
        | WindowEvent_Resized of Sdl.Event.window_event_xy
        | WindowEvent_Size_Changed of Sdl.Event.window_event_xy
        | WindowEvent_Minimized
        | WindowEvent_Maximized
        | WindowEvent_Restored
        | WindowEvent_Enter
        | WindowEvent_Leave
        | WindowEvent_Focus_Gained
        | WindowEvent_Focus_Lost
        | WindowEvent_Close
        | WindowEvent_Take_Focus
        | WindowEvent_Hit_Test
      val string_of_window_event_kind : Sdl.Event.window_event_kind -> string
      type window_event =
        Sdlevent.window_event = {
        we_timestamp : int32;
        window_ID : int32;
        kind : Sdl.Event.window_event_kind;
      }
      type quit_event = Sdlevent.quit_event = { quit_timestamp : int32; }
      type text_editing_event =
        Sdlevent.text_editing_event = {
        te_timestamp : int32;
        te_window_ID : int32;
        te_text : string;
        te_begin : int;
        te_length : int;
      }
      type text_input_event =
        Sdlevent.text_input_event = {
        ti_timestamp : int32;
        ti_window_ID : int32;
        ti_text : string;
      }
      type t =
        Sdlevent.t =
          Quit of Sdl.Event.quit_event
        | Mouse_Motion of Sdl.Event.mouse_motion_event
        | Mouse_Button_Down of Sdl.Event.mouse_button_event
        | Mouse_Button_Up of Sdl.Event.mouse_button_event
        | Mouse_Wheel of Sdl.Event.mouse_wheel_event
        | KeyDown of Sdl.Event.keyboard_event
        | KeyUp of Sdl.Event.keyboard_event
        | Text_Editing of Sdl.Event.text_editing_event
        | Text_Input of Sdl.Event.text_input_event
        | Joy_Axis_Motion of Sdl.Event.joy_axis_event
        | Joy_Ball_Motion
        | Joy_Hat_Motion of Sdl.Event.joy_hat_event
        | Joy_Button_Down of Sdl.Event.joy_button_event
        | Joy_Button_Up of Sdl.Event.joy_button_event
        | Joy_Device_Added of Sdl.Event.joy_device_event
        | Joy_Device_Removed of Sdl.Event.joy_device_event
        | Controller_Axis_Motion
        | Controller_Button_Down
        | Controller_Button_Up
        | Controller_Device_Added
        | Controller_Device_Removed
        | Controller_Device_Remapped
        | Finger_Down
        | Finger_Up
        | Finger_Motion
        | Dollar_Gesture
        | Dollar_Record
        | Multi_Gesture
        | Clipboard_Update
        | Drop_File
        | User_Event
        | Window_Event of Sdl.Event.window_event
        | SysWM_Event
        | APP_Terminating
        | APP_LowMemory
        | APP_Will_Enter_Background
        | APP_Did_Enter_Background
        | APP_Will_Enter_Foreground
        | APP_Did_Enter_Foreground
        | Display_Event
        | Keymap_Changed
        | Drop_Text
        | Drop_Begin
        | Drop_Complete
        | Audio_Device_Added
        | Audio_Device_Removed
        | Sensor_Update
        | Render_Targets_Reset
        | Render_Device_Reset
      external poll_event : unit -> Sdl.Event.t option = "caml_SDL_PollEvent"
      val to_string : Sdl.Event.t -> string
    end
  module Keyboard :
    sig
      external start_text_input : unit -> unit = "caml_SDL_StartTextInput"
      external stop_text_input : unit -> unit = "caml_SDL_StopTextInput"
      external is_text_input_active : unit -> bool
        = "caml_SDL_IsTextInputActive"
      external set_text_input_rect : Sdlrect.t -> unit
        = "caml_SDL_SetTextInputRect"
      external has_screen_keyboard_support : unit -> bool
        = "caml_SDL_HasScreenKeyboardSupport"
    end
  module Keycode :
    sig
      type t =
        Sdlkeycode.t =
          Unknown
        | Return
        | Escape
        | Backspace
        | Tab
        | Space
        | Exclaim
        | QuoteDBL
        | Hash
        | Percent
        | Dollar
        | Ampersand
        | Quote
        | LeftParen
        | RightParen
        | Asterisk
        | Plus
        | Comma
        | Minus
        | Period
        | Slash
        | Num0
        | Num1
        | Num2
        | Num3
        | Num4
        | Num5
        | Num6
        | Num7
        | Num8
        | Num9
        | Colon
        | SemiColon
        | Less
        | Equals
        | Greater
        | Question
        | At
        | LeftBracket
        | BackSlash
        | RightBracket
        | Caret
        | Underscore
        | BackQuote
        | A
        | B
        | C
        | D
        | E
        | F
        | G
        | H
        | I
        | J
        | K
        | L
        | M
        | N
        | O
        | P
        | Q
        | R
        | S
        | T
        | U
        | V
        | W
        | X
        | Y
        | Z
        | CapsLock
        | F1
        | F2
        | F3
        | F4
        | F5
        | F6
        | F7
        | F8
        | F9
        | F10
        | F11
        | F12
        | PrintScreen
        | ScrollLock
        | Pause
        | Insert
        | Home
        | PageUp
        | Delete
        | End
        | PageDown
        | Right
        | Left
        | Down
        | Up
        | NumLockClear
        | KP_Divide
        | KP_Multiply
        | KP_Minus
        | KP_Plus
        | KP_Enter
        | KP_1
        | KP_2
        | KP_3
        | KP_4
        | KP_5
        | KP_6
        | KP_7
        | KP_8
        | KP_9
        | KP_0
        | KP_Period
        | Application
        | Power
        | KP_Equals
        | F13
        | F14
        | F15
        | F16
        | F17
        | F18
        | F19
        | F20
        | F21
        | F22
        | F23
        | F24
        | Execute
        | Help
        | Menu
        | Select
        | Stop
        | Again
        | Undo
        | Cut
        | Copy
        | Paste
        | Find
        | Mute
        | VolumeUp
        | VolumeDown
        | KP_Comma
        | KP_EqualsAs400
        | ALTERASE
        | SYSREQ
        | CANCEL
        | CLEAR
        | PRIOR
        | RETURN2
        | SEPARATOR
        | OUT
        | OPER
        | CLEARAGAIN
        | CRSEL
        | EXSEL
        | KP_00
        | KP_000
        | ThousandsSeparator
        | DecimalSeparator
        | CurrencyUnit
        | CurrencySubunit
        | KP_LeftParen
        | KP_RightParen
        | KP_LeftBrace
        | KP_RightBrace
        | KP_Tab
        | KP_Backspace
        | KP_A
        | KP_B
        | KP_C
        | KP_D
        | KP_E
        | KP_F
        | KP_Xor
        | KP_Power
        | KP_Percent
        | KP_Less
        | KP_Greater
        | KP_Ampersand
        | KP_DBLAmpersand
        | KP_VerticalBar
        | KP_DBLVerticalBar
        | KP_Colon
        | KP_Hash
        | KP_Space
        | KP_At
        | KP_Exclam
        | KP_MemStore
        | KP_MemRecall
        | KP_MemClear
        | KP_MemAdd
        | KP_MemSubtract
        | KP_MemMultiply
        | KP_MemDivide
        | KP_PlusMinus
        | KP_Clear
        | KP_Clearentry
        | KP_Binary
        | KP_Octal
        | KP_Decimal
        | KP_Hexadecimal
        | LCtrl
        | LShift
        | LAlt
        | LGui
        | RCtrl
        | RShift
        | RAlt
        | RGUI
        | MODE
        | AudioNext
        | AudioPrev
        | AudioStop
        | AudioPlay
        | AudioMute
        | MediaSelect
        | WWW
        | Mail
        | Calculator
        | Computer
        | AC_Search
        | AC_Home
        | AC_Back
        | AC_Forward
        | AC_Stop
        | AC_Refresh
        | AC_Bookmarks
        | BrightnessDown
        | BrightnessUp
        | DisplaySwitch
        | KBDIllumToggle
        | KBDIllumDown
        | KBDIllumUp
        | Eject
        | Sleep
      val to_string : Sdl.Keycode.t -> string
      val of_string : string -> Sdl.Keycode.t
    end
  module Scancode :
    sig
      type t =
        Sdlscancode.t =
          UNKNOWN
        | A
        | B
        | C
        | D
        | E
        | F
        | G
        | H
        | I
        | J
        | K
        | L
        | M
        | N
        | O
        | P
        | Q
        | R
        | S
        | T
        | U
        | V
        | W
        | X
        | Y
        | Z
        | Num1
        | Num2
        | Num3
        | Num4
        | Num5
        | Num6
        | Num7
        | Num8
        | Num9
        | Num0
        | RETURN
        | ESCAPE
        | BACKSPACE
        | TAB
        | SPACE
        | MINUS
        | EQUALS
        | LEFTBRACKET
        | RIGHTBRACKET
        | BACKSLASH
        | NONUSHASH
        | SEMICOLON
        | APOSTROPHE
        | GRAVE
        | COMMA
        | PERIOD
        | SLASH
        | CAPSLOCK
        | F1
        | F2
        | F3
        | F4
        | F5
        | F6
        | F7
        | F8
        | F9
        | F10
        | F11
        | F12
        | PRINTSCREEN
        | SCROLLLOCK
        | PAUSE
        | INSERT
        | HOME
        | PAGEUP
        | DELETE
        | END
        | PAGEDOWN
        | RIGHT
        | LEFT
        | DOWN
        | UP
        | NUMLOCKCLEAR
        | KP_DIVIDE
        | KP_MULTIPLY
        | KP_MINUS
        | KP_PLUS
        | KP_ENTER
        | KP_1
        | KP_2
        | KP_3
        | KP_4
        | KP_5
        | KP_6
        | KP_7
        | KP_8
        | KP_9
        | KP_0
        | KP_PERIOD
        | NONUSBACKSLASH
        | APPLICATION
        | POWER
        | KP_EQUALS
        | F13
        | F14
        | F15
        | F16
        | F17
        | F18
        | F19
        | F20
        | F21
        | F22
        | F23
        | F24
        | EXECUTE
        | HELP
        | MENU
        | SELECT
        | STOP
        | AGAIN
        | UNDO
        | CUT
        | COPY
        | PASTE
        | FIND
        | MUTE
        | VOLUMEUP
        | VOLUMEDOWN
        | KP_COMMA
        | KP_EQUALSAS400
        | INTERNATIONAL1
        | INTERNATIONAL2
        | INTERNATIONAL3
        | INTERNATIONAL4
        | INTERNATIONAL5
        | INTERNATIONAL6
        | INTERNATIONAL7
        | INTERNATIONAL8
        | INTERNATIONAL9
        | LANG1
        | LANG2
        | LANG3
        | LANG4
        | LANG5
        | LANG6
        | LANG7
        | LANG8
        | LANG9
        | ALTERASE
        | SYSREQ
        | CANCEL
        | CLEAR
        | PRIOR
        | RETURN2
        | SEPARATOR
        | OUT
        | OPER
        | CLEARAGAIN
        | CRSEL
        | EXSEL
        | KP_00
        | KP_000
        | THOUSANDSSEPARATOR
        | DECIMALSEPARATOR
        | CURRENCYUNIT
        | CURRENCYSUBUNIT
        | KP_LEFTPAREN
        | KP_RIGHTPAREN
        | KP_LEFTBRACE
        | KP_RIGHTBRACE
        | KP_TAB
        | KP_BACKSPACE
        | KP_A
        | KP_B
        | KP_C
        | KP_D
        | KP_E
        | KP_F
        | KP_XOR
        | KP_POWER
        | KP_PERCENT
        | KP_LESS
        | KP_GREATER
        | KP_AMPERSAND
        | KP_DBLAMPERSAND
        | KP_VERTICALBAR
        | KP_DBLVERTICALBAR
        | KP_COLON
        | KP_HASH
        | KP_SPACE
        | KP_AT
        | KP_EXCLAM
        | KP_MEMSTORE
        | KP_MEMRECALL
        | KP_MEMCLEAR
        | KP_MEMADD
        | KP_MEMSUBTRACT
        | KP_MEMMULTIPLY
        | KP_MEMDIVIDE
        | KP_PLUSMINUS
        | KP_CLEAR
        | KP_CLEARENTRY
        | KP_BINARY
        | KP_OCTAL
        | KP_DECIMAL
        | KP_HEXADECIMAL
        | LCTRL
        | LSHIFT
        | LALT
        | LGUI
        | RCTRL
        | RSHIFT
        | RALT
        | RGUI
        | MODE
        | AUDIONEXT
        | AUDIOPREV
        | AUDIOSTOP
        | AUDIOPLAY
        | AUDIOMUTE
        | MEDIASELECT
        | WWW
        | MAIL
        | CALCULATOR
        | COMPUTER
        | AC_SEARCH
        | AC_HOME
        | AC_BACK
        | AC_FORWARD
        | AC_STOP
        | AC_REFRESH
        | AC_BOOKMARKS
        | BRIGHTNESSDOWN
        | BRIGHTNESSUP
        | DISPLAYSWITCH
        | KBDILLUMTOGGLE
        | KBDILLUMDOWN
        | KBDILLUMUP
        | EJECT
        | SLEEP
      val to_string : Sdl.Scancode.t -> string
      val of_string : string -> Sdl.Scancode.t
    end
  module Keymod :
    sig
      type t =
        Sdlkeymod.t =
          LShift
        | RShift
        | LCtrl
        | RCtrl
        | LAlt
        | RAlt
        | LGUI
        | RGUI
        | NUM
        | CAPS
        | MODE
      val to_string : Sdl.Keymod.t -> string
      val of_string : string -> Sdl.Keymod.t
    end
  module Mouse :
    sig
      type button =
        Sdlmouse.button =
          Button_Left
        | Button_Middle
        | Button_Right
        | Button_X1
        | Button_X2
        | Button_X3
        | Button_X4
        | Button_X5
      type pos = int * int
      external get_state : unit -> Sdl.Mouse.pos * Sdl.Mouse.button list
        = "caml_SDL_GetMouseState"
      external get_buttons : unit -> Sdl.Mouse.button list
        = "caml_SDL_GetMouseButtons"
      external get_pos : unit -> Sdl.Mouse.pos = "caml_SDL_GetMousePos"
      external warp_in_window : Sdlwindow.t -> x:int -> y:int -> unit
        = "caml_SDL_WarpMouseInWindow"
      external set_relative_mode : enabled:bool -> unit
        = "caml_SDL_SetRelativeMouseMode"
      external show_cursor : toggle:bool -> unit = "caml_SDL_ShowCursor"
      external cursor_is_shown : unit -> bool = "caml_SDL_ShowCursor_Query"
      val to_string : Sdl.Mouse.button -> string
      val of_string : string -> Sdl.Mouse.button
    end
  module Joystick :
    sig
      type t = Sdljoystick.t
      external num_joysticks : unit -> int = "caml_SDL_NumJoysticks"
      external name_for_index : device_index:int -> string
        = "caml_SDL_JoystickNameForIndex"
      external j_open : device_index:int -> Sdl.Joystick.t
        = "caml_SDL_JoystickOpen"
      external close : Sdl.Joystick.t -> unit = "caml_SDL_JoystickClose"
      external num_axes : Sdl.Joystick.t -> int = "caml_SDL_JoystickNumAxes"
      external num_hats : Sdl.Joystick.t -> int = "caml_SDL_JoystickNumHats"
      external get_axis : Sdl.Joystick.t -> axis:int -> int
        = "caml_SDL_JoystickGetAxis"
      external get_button : Sdl.Joystick.t -> button:int -> int
        = "caml_SDL_JoystickGetButton"
    end
  module Hat :
    sig
      type positions =
        Sdlhat.positions = {
        left : bool;
        right : bool;
        up : bool;
        down : bool;
      }
      val string_of_pos : Sdl.Hat.positions -> string
      type direction =
        Sdlhat.direction =
          Centered
        | Up
        | Right
        | Down
        | Left
        | Right_Up
        | Right_Down
        | Left_Up
        | Left_Down
      val string_of_dir : Sdl.Hat.direction -> string
      val dir_of_string : string -> Sdl.Hat.direction
    end
  module Rect :
    sig
      type t = Sdlrect.t = { x : int; y : int; w : int; h : int; }
      val make : pos:int * int -> dims:int * int -> Sdl.Rect.t
      val make1 : int * int * int * int -> Sdl.Rect.t
      val make2 : pos:int * int -> dims:int * int -> Sdl.Rect.t
      val make4 : x:int -> y:int -> w:int -> h:int -> Sdl.Rect.t
      val move : Sdl.Rect.t -> x:int -> y:int -> Sdl.Rect.t
      external has_intersection : a:Sdl.Rect.t -> b:Sdl.Rect.t -> bool
        = "caml_SDL_HasIntersection"
      external intersect_rect_and_line :
        rect:Sdl.Rect.t ->
        p1:int * int -> p2:int * int -> (int * int * int * int) option
        = "caml_SDL_IntersectRectAndLine"
      external point_in_rect : p:int * int -> r:Sdl.Rect.t -> bool
        = "caml_SDL_PointInRect"
    end
  module Timer :
    sig
      external get_ticks : unit -> int = "caml_SDL_GetTicks" [@@noalloc]
      module D = Sdltimer.D
      external delay : ms:int -> unit = "caml_SDL_Delay"
    end
  module Clipboard :
    sig
      external set_text : text:string -> int = "caml_SDL_SetClipboardText"
      external get_text : unit -> string = "caml_SDL_GetClipboardText"
      external has_text : unit -> bool = "caml_SDL_HasClipboardText"
    end
  module GL :
    sig
      type context = Sdlgl.context
      external create_context : win:Sdlwindow.t -> Sdl.GL.context
        = "caml_SDL_GL_CreateContext"
      external make_current : win:Sdlwindow.t -> ctx:Sdl.GL.context -> int
        = "caml_SDL_GL_MakeCurrent"
      external unload_library : unit -> unit = "caml_SDL_GL_UnloadLibrary"
      external extension_supported : extension:string -> bool
        = "caml_SDL_GL_ExtensionSupported"
      external set_swap_interval : interval:int -> unit
        = "caml_SDL_GL_SetSwapInterval"
      external get_swap_interval : unit -> int
        = "caml_SDL_GL_GetSwapInterval"
      external swap_window : Sdlwindow.t -> unit = "caml_SDL_GL_SwapWindow"
      external delete_context : Sdl.GL.context -> unit
        = "caml_SDL_GL_DeleteContext"
      type gl_attr =
        Sdlgl.gl_attr =
          GL_RED_SIZE
        | GL_GREEN_SIZE
        | GL_BLUE_SIZE
        | GL_ALPHA_SIZE
        | GL_BUFFER_SIZE
        | GL_DOUBLEBUFFER
        | GL_DEPTH_SIZE
        | GL_STENCIL_SIZE
        | GL_ACCUM_RED_SIZE
        | GL_ACCUM_GREEN_SIZE
        | GL_ACCUM_BLUE_SIZE
        | GL_ACCUM_ALPHA_SIZE
        | GL_STEREO
        | GL_MULTISAMPLEBUFFERS
        | GL_MULTISAMPLESAMPLES
        | GL_ACCELERATED_VISUAL
        | GL_RETAINED_BACKING
        | GL_CONTEXT_MAJOR_VERSION
        | GL_CONTEXT_MINOR_VERSION
        | GL_CONTEXT_EGL
        | GL_CONTEXT_FLAGS
        | GL_CONTEXT_PROFILE_MASK
        | GL_SHARE_WITH_CURRENT_CONTEXT
      external set_attribute : Sdl.GL.gl_attr -> int -> unit
        = "caml_SDL_GL_SetAttribute"
      external get_attribute : Sdl.GL.gl_attr -> int
        = "caml_SDL_GL_GetAttribute"
    end
  module Audio :
    sig
      type t = Sdlaudio.t
      type format =
        Sdlaudio.format =
          AUDIO_U8
        | AUDIO_S8
        | AUDIO_U16LSB
        | AUDIO_S16LSB
        | AUDIO_U16MSB
        | AUDIO_S16MSB
        | AUDIO_U16
        | AUDIO_S16
        | AUDIO_S32LSB
        | AUDIO_S32MSB
        | AUDIO_S32
        | AUDIO_F32LSB
        | AUDIO_F32MSB
        | AUDIO_F32
        | AUDIO_U16SYS
        | AUDIO_S16SYS
        | AUDIO_S32SYS
        | AUDIO_F32SYS
      external get_drivers : unit -> string array
        = "caml_SDL_GetAudioDrivers"
      external init : driver_name:string -> unit = "caml_SDL_AudioInit"
      external quit : unit -> unit = "caml_SDL_AudioQuit"
      external get_current_driver : unit -> string
        = "caml_SDL_GetCurrentAudioDriver"
      type status = Sdlaudio.status = Stopped | Playing | Paused
      external get_status : unit -> Sdl.Audio.status
        = "caml_SDL_GetAudioStatus"
      val string_of_status : Sdl.Audio.status -> string
      external pause : pause_on:bool -> unit = "caml_SDL_PauseAudio"
      external lock : unit -> unit = "caml_SDL_LockAudio"
      external unlock : unit -> unit = "caml_SDL_UnlockAudio"
      external close : unit -> unit = "caml_SDL_CloseAudio"
      type audio_spec = Sdlaudio.audio_spec
      external new_audio_spec : unit -> Sdl.Audio.audio_spec
        = "caml_SDL_alloc_audio_spec"
      external free_audio_spec : Sdl.Audio.audio_spec -> unit
        = "caml_SDL_free_audio_spec"
      type audio_buffer = Sdlaudio.audio_buffer
      external load_wav :
        filename:string ->
        spec:Sdl.Audio.audio_spec -> Sdl.Audio.audio_buffer * int32
        = "caml_SDL_LoadWAV"
      external free_wav : Sdl.Audio.audio_buffer -> unit = "caml_SDL_FreeWAV"
      type audio_device_id = Sdlaudio.audio_device_id
      external open_audio_device_simple :
        Sdl.Audio.audio_spec -> Sdl.Audio.audio_device_id
        = "caml_SDL_OpenAudioDevice_simple"
      external queue_audio :
        Sdl.Audio.audio_device_id -> Sdl.Audio.audio_buffer -> int32 -> unit
        = "caml_SDL_QueueAudio"
      external unpause_audio_device : Sdl.Audio.audio_device_id -> unit
        = "caml_SDL_UnpauseAudioDevice"
      external pause_audio_device : Sdl.Audio.audio_device_id -> unit
        = "caml_SDL_PauseAudioDevice"
      external close_audio_device : Sdl.Audio.audio_device_id -> unit
        = "caml_SDL_CloseAudioDevice"
    end
  module Filesystem :
    sig
      external get_base_path : unit -> string = "caml_SDL_GetBasePath"
      external get_pref_path : org:string -> app:string -> string
        = "caml_SDL_GetPrefPath"
    end
  module Version :
    sig
      type version = int * int * int
      external get_runtime_version : unit -> Sdl.Version.version
        = "caml_SDL_GetRunTimeVersion"
      external get_compiled_version : unit -> Sdl.Version.version
        = "caml_SDL_GetCompiledVersion"
      external get_revision_string : unit -> string
        = "caml_SDL_GetRevisionString"
      external get_revision_number : unit -> int
        = "caml_SDL_GetRevisionNumber"
      module R = Sdlversion.R
    end
  module CPUInfo :
    sig external get_CPU_count : unit -> int = "caml_SDL_GetCPUCount" end
  module Power :
    sig
      type power_state =
          [ `powerstate_Charged
          | `powerstate_Charging
          | `powerstate_No_Battery
          | `powerstate_On_Battery
          | `powerstate_Unknown ]
      external get_power_info : unit -> Sdl.Power.power_state * int * int
        = "caml_SDL_GetPowerInfo"
    end
  module RWops :
    sig
      type t = Sdlrwops.t
      external from_mem : bytes -> Sdl.RWops.t = "caml_SDL_RWFromMem"
      external from_const_mem : string -> Sdl.RWops.t
        = "caml_SDL_RWFromConstMem"
      external from_file : filename:string -> mode:string -> Sdl.RWops.t
        = "caml_SDL_RWFromFile"
      type input =
          [ `Buffer of bytes | `Filename of string | `String of string ]
      val from_input :
        [< `Buffer of bytes | `Filename of string | `String of string ] ->
        Sdl.RWops.t
      val from_input_opt :
        [> `Buffer of bytes | `Filename of string | `String of string ] ->
        Sdl.RWops.t option
      external alloc : unit -> Sdl.RWops.t = "caml_SDL_AllocRW"
      external free : Sdl.RWops.t -> unit = "caml_SDL_FreeRW"
      external close : Sdl.RWops.t -> unit = "caml_SDL_CloseRW"
      external size : Sdl.RWops.t -> int64 = "caml_SDL_RWsize"
      type seek = Sdlrwops.seek = SEEK_SET | SEEK_CUR | SEEK_END
      external seek : Sdl.RWops.t -> offset:int64 -> Sdl.RWops.seek -> int64
        = "caml_SDL_RWseek"
      external tell : Sdl.RWops.t -> int64 = "caml_SDL_RWtell"
      type uint8 = int
      type uint16 = int
      type uint32 = int32
      type uint64 = int64
      external readU8 : Sdl.RWops.t -> Sdl.RWops.uint8 = "caml_SDL_ReadU8"
      external writeU8 : Sdl.RWops.t -> Sdl.RWops.uint8 -> unit
        = "caml_SDL_WriteU8"
      module BigEndian = Sdlrwops.BigEndian
      module LittleEndian = Sdlrwops.LittleEndian
    end
  module Error :
    sig
      external get_error : unit -> string = "caml_SDL_GetError"
      external clear_error : unit -> unit = "caml_SDL_ClearError"
    end
  module Hint :
    sig
      type t =
        Sdlhint.t =
          AccelerometerAsJoystick
        | AndroidApkExpansionMainFileVersion
        | AndroidApkExpansionPatchFileVersion
        | AndroidSeparateMouseAndTouch
        | AppleTvControllerUiEvents
        | AppleTvRemoteAllowRotation
        | BmpSaveLegacyFormat
        | EmscriptenAsyncify
        | EmscriptenKeyboardElement
        | FramebufferAcceleration
        | Gamecontrollerconfig
        | GrabKeyboard
        | IdleTimerDisabled
        | ImeInternalEditing
        | JoystickAllowBackgroundEvents
        | MacBackgroundApp
        | MacCtrlClickEmulateRightClick
        | MouseFocusClickthrough
        | MouseRelativeModeWarp
        | MouseRelativeScaling
        | NoSignalHandlers
        | Orientations
        | RenderDirect3d11Debug
        | RenderDirect3dThreadsafe
        | RenderDriver
        | RenderOpenglShaders
        | RenderScaleQuality
        | RenderVsync
        | RpiVideoLayer
        | ThreadStackSize
        | TimerResolution
        | VideoAllowScreensaver
        | VideoHighdpiDisabled
        | VideoMacFullscreenSpaces
        | VideoMinimizeOnFocusLoss
        | VideoWinD3dcompiler
        | VideoWindowSharePixelFormat
        | VideoX11NetWmPing
        | VideoX11Xinerama
        | VideoX11Xrandr
        | VideoX11Xvidmode
        | WindowFrameUsableWhileCursorHidden
        | WindowsDisableThreadNaming
        | WindowsEnableMessageloop
        | WindowsNoCloseOnAltF4
        | WinrtHandleBackButton
        | WinrtPrivacyPolicyLabel
        | WinrtPrivacyPolicyUrl
        | XinputEnabled
        | XinputUseOldJoystickMapping
      type priority = Sdlhint.priority = Default | Normal | Override
      val to_string : Sdl.Hint.t -> string
      val of_string : string -> Sdl.Hint.t
      val set : Sdl.Hint.t -> string -> bool
      val set_with_priority :
        Sdl.Hint.t -> string -> Sdl.Hint.priority -> bool
    end
end