summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/video
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/video')
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_RLEaccel.c1581
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_RLEaccel_c.h38
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit.c296
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit.h553
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_0.c483
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_1.c552
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_A.c1388
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_N.c2700
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_auto.c7419
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_auto.h30
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_copy.c162
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_copy.h29
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_slow.c164
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_blit_slow.h31
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_bmp.c702
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_clipboard.c90
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_egl.c920
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_egl_c.h150
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_fillrect.c343
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_pixels.c1125
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_pixels_c.h46
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_rect.c531
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_rect_c.h31
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_shape.c309
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_shape_internals.h69
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_stretch.c353
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_surface.c1246
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_sysvideo.h467
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_video.c4161
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_vulkan_internal.h91
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_vulkan_utils.c172
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_yuv.c1835
-rw-r--r--source/3rd-party/SDL2/src/video/SDL_yuv_c.h36
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.c48
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.h32
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidevents.c123
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidevents.h27
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidgl.c62
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidgl.h34
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.c391
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.h36
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.c37
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.h29
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidmouse.c266
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidmouse.h33
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidtouch.c151
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidtouch.h29
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidvideo.c259
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidvideo.h51
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.c175
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.h52
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidwindow.c183
-rw-r--r--source/3rd-party/SDL2/src/video/android/SDL_androidwindow.h45
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.h36
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.m103
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.h32
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.m483
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.h36
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.m720
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.h29
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.m145
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.h63
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.m138
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.h46
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.m490
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.h52
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.m477
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.h34
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.m286
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.h68
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.m436
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.h49
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.m132
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.h45
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.m113
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.h118
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.m262
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.h55
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.m230
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.h155
-rw-r--r--source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.m1905
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.c413
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.h56
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.c117
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.h41
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c748
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.h34
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.c414
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.h59
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.c389
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.h44
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.c332
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.h64
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.c1335
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.h25
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.c131
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.h38
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.c418
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.h170
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.c565
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.h82
-rw-r--r--source/3rd-party/SDL2/src/video/dummy/SDL_nullevents.c41
-rw-r--r--source/3rd-party/SDL2/src/video/dummy/SDL_nullevents_c.h33
-rw-r--r--source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer.c89
-rw-r--r--source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer_c.h33
-rw-r--r--source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.c144
-rw-r--r--source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.h30
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.c716
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.h40
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.c178
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.h32
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.c275
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.h42
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.c121
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.h49
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.c354
-rw-r--r--source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.h58
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_BWin.h679
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.cc95
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.h33
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bevents.cc41
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bevents.h39
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.cc259
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.h47
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.cc190
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.h44
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.cc333
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.h48
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.cc176
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.h55
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.cc177
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.h44
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.cc233
-rw-r--r--source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.h55
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/EGL/egl.h303
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/EGL/eglext.h1241
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/EGL/eglplatform.h132
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/GLES2/gl2.h675
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/GLES2/gl2ext.h3505
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/GLES2/gl2platform.h38
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/KHR/khrplatform.h284
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/vulkan/vk_platform.h120
-rw-r--r--source/3rd-party/SDL2/src/video/khronos/vulkan/vulkan.h6458
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c171
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h53
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c42
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h31
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c501
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h45
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c189
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h48
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h99
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c739
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h125
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.c170
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.h53
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirevents.c321
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirevents.h37
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.c134
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.h47
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.c292
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.h37
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_miropengl.c78
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_miropengl.h53
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirsym.h143
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.c423
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.h49
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.c176
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.h52
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.c374
-rw-r--r--source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.h93
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclevents.c438
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclevents_c.h30
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclglue.c24
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.c174
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.h38
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.c183
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.h67
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.c79
-rw-r--r--source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.h32
-rw-r--r--source/3rd-party/SDL2/src/video/pandora/SDL_pandora.c838
-rw-r--r--source/3rd-party/SDL2/src/video/pandora/SDL_pandora.h101
-rw-r--r--source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.c38
-rw-r--r--source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.h25
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspevents.c290
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspevents_c.h31
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspgl.c210
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspgl_c.h54
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspmouse.c41
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspmouse_c.h24
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.c333
-rw-r--r--source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.h102
-rw-r--r--source/3rd-party/SDL2/src/video/qnx/gl.c285
-rw-r--r--source/3rd-party/SDL2/src/video/qnx/keyboard.c133
-rw-r--r--source/3rd-party/SDL2/src/video/qnx/sdl_qnx.h48
-rw-r--r--source/3rd-party/SDL2/src/video/qnx/video.c364
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents.c45
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents_c.h31
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.c386
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.h43
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.c71
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.h49
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.c442
-rw-r--r--source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.h104
-rw-r--r--source/3rd-party/SDL2/src/video/sdlgenblit.pl535
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h47
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m516
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h35
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m111
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h30
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m73
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h31
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m208
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h58
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m132
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h54
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m380
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h40
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m250
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h60
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m384
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h46
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m249
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h41
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m328
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h91
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m553
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h54
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m222
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h56
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m465
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/keyinfotable.h174
-rw-r--r--source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.c47
-rw-r--r--source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.h48
-rw-r--r--source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.c54
-rw-r--r--source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.h47
-rw-r--r--source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.c409
-rw-r--r--source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.h91
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.c123
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.h32
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.c468
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.h103
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.c178
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.h107
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents.c1136
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents_c.h51
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.c396
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.h31
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.c93
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.h49
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandsym.h127
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.c265
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.h352
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.c517
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.h85
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.c176
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.h52
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.c676
-rw-r--r--source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.h88
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_msctf.h242
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_vkeys.h76
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.c160
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.h36
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.c1236
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.h36
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.c127
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.h27
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.c1579
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.h40
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.c905
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.h29
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.c407
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.h47
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.c320
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.h33
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.c895
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.h142
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.c131
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.h49
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.c110
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.h40
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowstaskdialog.h156
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.c452
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.h199
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.c176
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.h52
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.c996
-rw-r--r--source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.h87
-rw-r--r--source/3rd-party/SDL2/src/video/windows/wmmsg.h1052
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp154
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h82
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp196
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h35
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp430
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp112
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h29
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp224
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h40
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp203
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h70
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp415
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp842
-rw-r--r--source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h106
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.c199
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.h33
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.c212
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.h111
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11events.c1500
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11events.h31
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.c257
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.h37
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.c543
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.h36
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.c872
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.h33
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11modes.c1112
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11modes.h85
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.c448
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.h31
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.c946
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.h84
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.c109
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.h56
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11shape.c115
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11shape.h39
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11sym.h337
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11touch.c54
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11touch.h32
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11video.c497
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11video.h156
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.c243
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.h48
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11window.c1619
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11window.h111
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.c313
-rw-r--r--source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.h42
-rw-r--r--source/3rd-party/SDL2/src/video/x11/edid-parse.c754
-rw-r--r--source/3rd-party/SDL2/src/video/x11/edid.h167
-rw-r--r--source/3rd-party/SDL2/src/video/x11/imKStoUCS.c350
-rw-r--r--source/3rd-party/SDL2/src/video/x11/imKStoUCS.h32
-rw-r--r--source/3rd-party/SDL2/src/video/yuv2rgb/LICENSE27
-rw-r--r--source/3rd-party/SDL2/src/video/yuv2rgb/README.md63
-rw-r--r--source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.c687
-rw-r--r--source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.h381
-rw-r--r--source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_sse_func.h498
-rw-r--r--source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_std_func.h228
346 files changed, 106973 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/video/SDL_RLEaccel.c b/source/3rd-party/SDL2/src/video/SDL_RLEaccel.c
new file mode 100644
index 0000000..661cb1f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_RLEaccel.c
@@ -0,0 +1,1581 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/*
+ * RLE encoding for software colorkey and alpha-channel acceleration
+ *
+ * Original version by Sam Lantinga
+ *
+ * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and
+ * decoder. Added per-surface alpha blitter. Added per-pixel alpha
+ * format, encoder and blitter.
+ *
+ * Many thanks to Xark and johns for hints, benchmarks and useful comments
+ * leading to this code.
+ *
+ * Welcome to Macro Mayhem.
+ */
+
+/*
+ * The encoding translates the image data to a stream of segments of the form
+ *
+ * <skip> <run> <data>
+ *
+ * where <skip> is the number of transparent pixels to skip,
+ * <run> is the number of opaque pixels to blit,
+ * and <data> are the pixels themselves.
+ *
+ * This basic structure is used both for colorkeyed surfaces, used for simple
+ * binary transparency and for per-surface alpha blending, and for surfaces
+ * with per-pixel alpha. The details differ, however:
+ *
+ * Encoding of colorkeyed surfaces:
+ *
+ * Encoded pixels always have the same format as the target surface.
+ * <skip> and <run> are unsigned 8 bit integers, except for 32 bit depth
+ * where they are 16 bit. This makes the pixel data aligned at all times.
+ * Segments never wrap around from one scan line to the next.
+ *
+ * The end of the sequence is marked by a zero <skip>,<run> pair at the *
+ * beginning of a line.
+ *
+ * Encoding of surfaces with per-pixel alpha:
+ *
+ * The sequence begins with a struct RLEDestFormat describing the target
+ * pixel format, to provide reliable un-encoding.
+ *
+ * Each scan line is encoded twice: First all completely opaque pixels,
+ * encoded in the target format as described above, and then all
+ * partially transparent (translucent) pixels (where 1 <= alpha <= 254),
+ * in the following 32-bit format:
+ *
+ * For 32-bit targets, each pixel has the target RGB format but with
+ * the alpha value occupying the highest 8 bits. The <skip> and <run>
+ * counts are 16 bit.
+ *
+ * For 16-bit targets, each pixel has the target RGB format, but with
+ * the middle component (usually green) shifted 16 steps to the left,
+ * and the hole filled with the 5 most significant bits of the alpha value.
+ * i.e. if the target has the format rrrrrggggggbbbbb,
+ * the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb.
+ * The <skip> and <run> counts are 8 bit for the opaque lines, 16 bit
+ * for the translucent lines. Two padding bytes may be inserted
+ * before each translucent line to keep them 32-bit aligned.
+ *
+ * The end of the sequence is marked by a zero <skip>,<run> pair at the
+ * beginning of an opaque line.
+ */
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_RLEaccel_c.h"
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define PIXEL_COPY(to, from, len, bpp) \
+ SDL_memcpy(to, from, (size_t)(len) * (bpp))
+
+/*
+ * Various colorkey blit methods, for opaque and per-surface alpha
+ */
+
+#define OPAQUE_BLIT(to, from, length, bpp, alpha) \
+ PIXEL_COPY(to, from, length, bpp)
+
+/*
+ * For 32bpp pixels on the form 0x00rrggbb:
+ * If we treat the middle component separately, we can process the two
+ * remaining in parallel. This is safe to do because of the gap to the left
+ * of each component, so the bits from the multiplication don't collide.
+ * This can be used for any RGB permutation of course.
+ */
+#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint32 *src = (Uint32 *)(from); \
+ Uint32 *dst = (Uint32 *)(to); \
+ for (i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ Uint32 s1 = s & 0xff00ff; \
+ Uint32 d1 = d & 0xff00ff; \
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \
+ s &= 0xff00; \
+ d &= 0xff00; \
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \
+ *dst++ = d1 | d; \
+ } \
+ } while (0)
+
+/*
+ * For 16bpp pixels we can go a step further: put the middle component
+ * in the high 16 bits of a 32 bit word, and process all three RGB
+ * components at the same time. Since the smallest gap is here just
+ * 5 bits, we have to scale alpha down to 5 bits as well.
+ */
+#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint16 *src = (Uint16 *)(from); \
+ Uint16 *dst = (Uint16 *)(to); \
+ Uint32 ALPHA = alpha >> 3; \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ s = (s | s << 16) & 0x07e0f81f; \
+ d = (d | d << 16) & 0x07e0f81f; \
+ d += (s - d) * ALPHA >> 5; \
+ d &= 0x07e0f81f; \
+ *dst++ = (Uint16)(d | d >> 16); \
+ } \
+ } while(0)
+
+#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint16 *src = (Uint16 *)(from); \
+ Uint16 *dst = (Uint16 *)(to); \
+ Uint32 ALPHA = alpha >> 3; \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ s = (s | s << 16) & 0x03e07c1f; \
+ d = (d | d << 16) & 0x03e07c1f; \
+ d += (s - d) * ALPHA >> 5; \
+ d &= 0x03e07c1f; \
+ *dst++ = (Uint16)(d | d >> 16); \
+ } \
+ } while(0)
+
+/*
+ * The general slow catch-all function, for remaining depths and formats
+ */
+#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint8 *src = from; \
+ Uint8 *dst = to; \
+ for (i = 0; i < (int)(length); i++) { \
+ Uint32 s, d; \
+ unsigned rs, gs, bs, rd, gd, bd; \
+ switch (bpp) { \
+ case 2: \
+ s = *(Uint16 *)src; \
+ d = *(Uint16 *)dst; \
+ break; \
+ case 3: \
+ if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \
+ s = (src[0] << 16) | (src[1] << 8) | src[2]; \
+ d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \
+ } else { \
+ s = (src[2] << 16) | (src[1] << 8) | src[0]; \
+ d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \
+ } \
+ break; \
+ case 4: \
+ s = *(Uint32 *)src; \
+ d = *(Uint32 *)dst; \
+ break; \
+ } \
+ RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \
+ RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \
+ rd += (rs - rd) * alpha >> 8; \
+ gd += (gs - gd) * alpha >> 8; \
+ bd += (bs - bd) * alpha >> 8; \
+ PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \
+ switch (bpp) { \
+ case 2: \
+ *(Uint16 *)dst = (Uint16)d; \
+ break; \
+ case 3: \
+ if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \
+ dst[0] = (Uint8)(d >> 16); \
+ dst[1] = (Uint8)(d >> 8); \
+ dst[2] = (Uint8)(d); \
+ } else { \
+ dst[0] = (Uint8)d; \
+ dst[1] = (Uint8)(d >> 8); \
+ dst[2] = (Uint8)(d >> 16); \
+ } \
+ break; \
+ case 4: \
+ *(Uint32 *)dst = d; \
+ break; \
+ } \
+ src += bpp; \
+ dst += bpp; \
+ } \
+ } while(0)
+
+/*
+ * Special case: 50% alpha (alpha=128)
+ * This is treated specially because it can be optimized very well, and
+ * since it is good for many cases of semi-translucency.
+ * The theory is to do all three components at the same time:
+ * First zero the lowest bit of each component, which gives us room to
+ * add them. Then shift right and add the sum of the lowest bits.
+ */
+#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint32 *src = (Uint32 *)(from); \
+ Uint32 *dst = (Uint32 *)(to); \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \
+ + (s & d & 0x00010101); \
+ } \
+ } while(0)
+
+/*
+ * For 16bpp, we can actually blend two pixels in parallel, if we take
+ * care to shift before we add, not after.
+ */
+
+/* helper: blend a single 16 bit pixel at 50% */
+#define BLEND16_50(dst, src, mask) \
+ do { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ *dst++ = (Uint16)((((s & mask) + (d & mask)) >> 1) + \
+ (s & d & (~mask & 0xffff))); \
+ } while(0)
+
+/* basic 16bpp blender. mask is the pixels to keep when adding. */
+#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \
+ do { \
+ unsigned n = (length); \
+ Uint16 *src = (Uint16 *)(from); \
+ Uint16 *dst = (Uint16 *)(to); \
+ if (((uintptr_t)src ^ (uintptr_t)dst) & 3) { \
+ /* source and destination not in phase, blit one by one */ \
+ while (n--) \
+ BLEND16_50(dst, src, mask); \
+ } else { \
+ if ((uintptr_t)src & 3) { \
+ /* first odd pixel */ \
+ BLEND16_50(dst, src, mask); \
+ n--; \
+ } \
+ for (; n > 1; n -= 2) { \
+ Uint32 s = *(Uint32 *)src; \
+ Uint32 d = *(Uint32 *)dst; \
+ *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \
+ + ((d & (mask | mask << 16)) >> 1) \
+ + (s & d & (~(mask | mask << 16))); \
+ src += 2; \
+ dst += 2; \
+ } \
+ if (n) \
+ BLEND16_50(dst, src, mask); /* last odd pixel */ \
+ } \
+ } while(0)
+
+#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \
+ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de)
+
+#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \
+ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde)
+
+#define CHOOSE_BLIT(blitter, alpha, fmt) \
+ do { \
+ if (alpha == 255) { \
+ switch (fmt->BytesPerPixel) { \
+ case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \
+ case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \
+ case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \
+ case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \
+ } \
+ } else { \
+ switch (fmt->BytesPerPixel) { \
+ case 1: \
+ /* No 8bpp alpha blitting */ \
+ break; \
+ \
+ case 2: \
+ switch (fmt->Rmask | fmt->Gmask | fmt->Bmask) { \
+ case 0xffff: \
+ if (fmt->Gmask == 0x07e0 \
+ || fmt->Rmask == 0x07e0 \
+ || fmt->Bmask == 0x07e0) { \
+ if (alpha == 128) { \
+ blitter(2, Uint8, ALPHA_BLIT16_565_50); \
+ } else { \
+ blitter(2, Uint8, ALPHA_BLIT16_565); \
+ } \
+ } else \
+ goto general16; \
+ break; \
+ \
+ case 0x7fff: \
+ if (fmt->Gmask == 0x03e0 \
+ || fmt->Rmask == 0x03e0 \
+ || fmt->Bmask == 0x03e0) { \
+ if (alpha == 128) { \
+ blitter(2, Uint8, ALPHA_BLIT16_555_50); \
+ } else { \
+ blitter(2, Uint8, ALPHA_BLIT16_555); \
+ } \
+ break; \
+ } else \
+ goto general16; \
+ break; \
+ \
+ default: \
+ general16: \
+ blitter(2, Uint8, ALPHA_BLIT_ANY); \
+ } \
+ break; \
+ \
+ case 3: \
+ blitter(3, Uint8, ALPHA_BLIT_ANY); \
+ break; \
+ \
+ case 4: \
+ if ((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \
+ && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \
+ || fmt->Bmask == 0xff00)) { \
+ if (alpha == 128) { \
+ blitter(4, Uint16, ALPHA_BLIT32_888_50); \
+ } else { \
+ blitter(4, Uint16, ALPHA_BLIT32_888); \
+ } \
+ } else \
+ blitter(4, Uint16, ALPHA_BLIT_ANY); \
+ break; \
+ } \
+ } \
+ } while(0)
+
+/*
+ * Set a pixel value using the given format, except that the alpha value is
+ * placed in the top byte. This is the format used for RLE with alpha.
+ */
+#define RLEPIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift)| \
+ (a<<24); \
+}
+
+/*
+ * This takes care of the case when the surface is clipped on the left and/or
+ * right. Top clipping has already been taken care of.
+ */
+static void
+RLEClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst,
+ Uint8 * dstbuf, SDL_Rect * srcrect, unsigned alpha)
+{
+ SDL_PixelFormat *fmt = surf_dst->format;
+
+#define RLECLIPBLIT(bpp, Type, do_blit) \
+ do { \
+ int linecount = srcrect->h; \
+ int ofs = 0; \
+ int left = srcrect->x; \
+ int right = left + srcrect->w; \
+ dstbuf -= left * bpp; \
+ for (;;) { \
+ int run; \
+ ofs += *(Type *)srcbuf; \
+ run = ((Type *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Type); \
+ if (run) { \
+ /* clip to left and right borders */ \
+ if (ofs < right) { \
+ int start = 0; \
+ int len = run; \
+ int startcol; \
+ if (left - ofs > 0) { \
+ start = left - ofs; \
+ len -= start; \
+ if (len <= 0) \
+ goto nocopy ## bpp ## do_blit; \
+ } \
+ startcol = ofs + start; \
+ if (len > right - startcol) \
+ len = right - startcol; \
+ do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \
+ len, bpp, alpha); \
+ } \
+ nocopy ## bpp ## do_blit: \
+ srcbuf += run * bpp; \
+ ofs += run; \
+ } else if (!ofs) \
+ break; \
+ \
+ if (ofs == w) { \
+ ofs = 0; \
+ dstbuf += surf_dst->pitch; \
+ if (!--linecount) \
+ break; \
+ } \
+ } \
+ } while(0)
+
+ CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt);
+
+#undef RLECLIPBLIT
+
+}
+
+
+/* blit a colorkeyed RLE surface */
+int SDLCALL
+SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect,
+ SDL_Surface * surf_dst, SDL_Rect * dstrect)
+{
+ Uint8 *dstbuf;
+ Uint8 *srcbuf;
+ int x, y;
+ int w = surf_src->w;
+ unsigned alpha;
+
+ /* Lock the destination if necessary */
+ if (SDL_MUSTLOCK(surf_dst)) {
+ if (SDL_LockSurface(surf_dst) < 0) {
+ return (-1);
+ }
+ }
+
+ /* Set up the source and destination pointers */
+ x = dstrect->x;
+ y = dstrect->y;
+ dstbuf = (Uint8 *) surf_dst->pixels
+ + y * surf_dst->pitch + x * surf_src->format->BytesPerPixel;
+ srcbuf = (Uint8 *) surf_src->map->data;
+
+ {
+ /* skip lines at the top if necessary */
+ int vskip = srcrect->y;
+ int ofs = 0;
+ if (vskip) {
+
+#define RLESKIP(bpp, Type) \
+ for(;;) { \
+ int run; \
+ ofs += *(Type *)srcbuf; \
+ run = ((Type *)srcbuf)[1]; \
+ srcbuf += sizeof(Type) * 2; \
+ if(run) { \
+ srcbuf += run * bpp; \
+ ofs += run; \
+ } else if(!ofs) \
+ goto done; \
+ if(ofs == w) { \
+ ofs = 0; \
+ if(!--vskip) \
+ break; \
+ } \
+ }
+
+ switch (surf_src->format->BytesPerPixel) {
+ case 1:
+ RLESKIP(1, Uint8);
+ break;
+ case 2:
+ RLESKIP(2, Uint8);
+ break;
+ case 3:
+ RLESKIP(3, Uint8);
+ break;
+ case 4:
+ RLESKIP(4, Uint16);
+ break;
+ }
+
+#undef RLESKIP
+
+ }
+ }
+
+ alpha = surf_src->map->info.a;
+ /* if left or right edge clipping needed, call clip blit */
+ if (srcrect->x || srcrect->w != surf_src->w) {
+ RLEClipBlit(w, srcbuf, surf_dst, dstbuf, srcrect, alpha);
+ } else {
+ SDL_PixelFormat *fmt = surf_src->format;
+
+#define RLEBLIT(bpp, Type, do_blit) \
+ do { \
+ int linecount = srcrect->h; \
+ int ofs = 0; \
+ for(;;) { \
+ unsigned run; \
+ ofs += *(Type *)srcbuf; \
+ run = ((Type *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Type); \
+ if(run) { \
+ do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \
+ srcbuf += run * bpp; \
+ ofs += run; \
+ } else if(!ofs) \
+ break; \
+ if(ofs == w) { \
+ ofs = 0; \
+ dstbuf += surf_dst->pitch; \
+ if(!--linecount) \
+ break; \
+ } \
+ } \
+ } while(0)
+
+ CHOOSE_BLIT(RLEBLIT, alpha, fmt);
+
+#undef RLEBLIT
+ }
+
+ done:
+ /* Unlock the destination if necessary */
+ if (SDL_MUSTLOCK(surf_dst)) {
+ SDL_UnlockSurface(surf_dst);
+ }
+ return (0);
+}
+
+#undef OPAQUE_BLIT
+
+/*
+ * Per-pixel blitting macros for translucent pixels:
+ * These use the same techniques as the per-surface blitting macros
+ */
+
+/*
+ * For 32bpp pixels, we have made sure the alpha is stored in the top
+ * 8 bits, so proceed as usual
+ */
+#define BLIT_TRANSL_888(src, dst) \
+ do { \
+ Uint32 s = src; \
+ Uint32 d = dst; \
+ unsigned alpha = s >> 24; \
+ Uint32 s1 = s & 0xff00ff; \
+ Uint32 d1 = d & 0xff00ff; \
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \
+ s &= 0xff00; \
+ d &= 0xff00; \
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \
+ dst = d1 | d | 0xff000000; \
+ } while(0)
+
+/*
+ * For 16bpp pixels, we have stored the 5 most significant alpha bits in
+ * bits 5-10. As before, we can process all 3 RGB components at the same time.
+ */
+#define BLIT_TRANSL_565(src, dst) \
+ do { \
+ Uint32 s = src; \
+ Uint32 d = dst; \
+ unsigned alpha = (s & 0x3e0) >> 5; \
+ s &= 0x07e0f81f; \
+ d = (d | d << 16) & 0x07e0f81f; \
+ d += (s - d) * alpha >> 5; \
+ d &= 0x07e0f81f; \
+ dst = (Uint16)(d | d >> 16); \
+ } while(0)
+
+#define BLIT_TRANSL_555(src, dst) \
+ do { \
+ Uint32 s = src; \
+ Uint32 d = dst; \
+ unsigned alpha = (s & 0x3e0) >> 5; \
+ s &= 0x03e07c1f; \
+ d = (d | d << 16) & 0x03e07c1f; \
+ d += (s - d) * alpha >> 5; \
+ d &= 0x03e07c1f; \
+ dst = (Uint16)(d | d >> 16); \
+ } while(0)
+
+/* used to save the destination format in the encoding. Designed to be
+ macro-compatible with SDL_PixelFormat but without the unneeded fields */
+typedef struct
+{
+ Uint8 BytesPerPixel;
+ Uint8 padding[3];
+ Uint32 Rmask;
+ Uint32 Gmask;
+ Uint32 Bmask;
+ Uint32 Amask;
+ Uint8 Rloss;
+ Uint8 Gloss;
+ Uint8 Bloss;
+ Uint8 Aloss;
+ Uint8 Rshift;
+ Uint8 Gshift;
+ Uint8 Bshift;
+ Uint8 Ashift;
+} RLEDestFormat;
+
+/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */
+static void
+RLEAlphaClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst,
+ Uint8 * dstbuf, SDL_Rect * srcrect)
+{
+ SDL_PixelFormat *df = surf_dst->format;
+ /*
+ * clipped blitter: Ptype is the destination pixel type,
+ * Ctype the translucent count type, and do_blend the macro
+ * to blend one pixel.
+ */
+#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \
+ do { \
+ int linecount = srcrect->h; \
+ int left = srcrect->x; \
+ int right = left + srcrect->w; \
+ dstbuf -= left * sizeof(Ptype); \
+ do { \
+ int ofs = 0; \
+ /* blit opaque pixels on one line */ \
+ do { \
+ unsigned run; \
+ ofs += ((Ctype *)srcbuf)[0]; \
+ run = ((Ctype *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Ctype); \
+ if(run) { \
+ /* clip to left and right borders */ \
+ int cofs = ofs; \
+ int crun = run; \
+ if(left - cofs > 0) { \
+ crun -= left - cofs; \
+ cofs = left; \
+ } \
+ if(crun > right - cofs) \
+ crun = right - cofs; \
+ if(crun > 0) \
+ PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \
+ srcbuf + (cofs - ofs) * sizeof(Ptype), \
+ (unsigned)crun, sizeof(Ptype)); \
+ srcbuf += run * sizeof(Ptype); \
+ ofs += run; \
+ } else if(!ofs) \
+ return; \
+ } while(ofs < w); \
+ /* skip padding if necessary */ \
+ if(sizeof(Ptype) == 2) \
+ srcbuf += (uintptr_t)srcbuf & 2; \
+ /* blit translucent pixels on the same line */ \
+ ofs = 0; \
+ do { \
+ unsigned run; \
+ ofs += ((Uint16 *)srcbuf)[0]; \
+ run = ((Uint16 *)srcbuf)[1]; \
+ srcbuf += 4; \
+ if(run) { \
+ /* clip to left and right borders */ \
+ int cofs = ofs; \
+ int crun = run; \
+ if(left - cofs > 0) { \
+ crun -= left - cofs; \
+ cofs = left; \
+ } \
+ if(crun > right - cofs) \
+ crun = right - cofs; \
+ if(crun > 0) { \
+ Ptype *dst = (Ptype *)dstbuf + cofs; \
+ Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \
+ int i; \
+ for(i = 0; i < crun; i++) \
+ do_blend(src[i], dst[i]); \
+ } \
+ srcbuf += run * 4; \
+ ofs += run; \
+ } \
+ } while(ofs < w); \
+ dstbuf += surf_dst->pitch; \
+ } while(--linecount); \
+ } while(0)
+
+ switch (df->BytesPerPixel) {
+ case 2:
+ if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0)
+ RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565);
+ else
+ RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555);
+ break;
+ case 4:
+ RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888);
+ break;
+ }
+}
+
+/* blit a pixel-alpha RLE surface */
+int SDLCALL
+SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect,
+ SDL_Surface * surf_dst, SDL_Rect * dstrect)
+{
+ int x, y;
+ int w = surf_src->w;
+ Uint8 *srcbuf, *dstbuf;
+ SDL_PixelFormat *df = surf_dst->format;
+
+ /* Lock the destination if necessary */
+ if (SDL_MUSTLOCK(surf_dst)) {
+ if (SDL_LockSurface(surf_dst) < 0) {
+ return -1;
+ }
+ }
+
+ x = dstrect->x;
+ y = dstrect->y;
+ dstbuf = (Uint8 *) surf_dst->pixels + y * surf_dst->pitch + x * df->BytesPerPixel;
+ srcbuf = (Uint8 *) surf_src->map->data + sizeof(RLEDestFormat);
+
+ {
+ /* skip lines at the top if necessary */
+ int vskip = srcrect->y;
+ if (vskip) {
+ int ofs;
+ if (df->BytesPerPixel == 2) {
+ /* the 16/32 interleaved format */
+ do {
+ /* skip opaque line */
+ ofs = 0;
+ do {
+ int run;
+ ofs += srcbuf[0];
+ run = srcbuf[1];
+ srcbuf += 2;
+ if (run) {
+ srcbuf += 2 * run;
+ ofs += run;
+ } else if (!ofs)
+ goto done;
+ } while (ofs < w);
+
+ /* skip padding */
+ srcbuf += (uintptr_t) srcbuf & 2;
+
+ /* skip translucent line */
+ ofs = 0;
+ do {
+ int run;
+ ofs += ((Uint16 *) srcbuf)[0];
+ run = ((Uint16 *) srcbuf)[1];
+ srcbuf += 4 * (run + 1);
+ ofs += run;
+ } while (ofs < w);
+ } while (--vskip);
+ } else {
+ /* the 32/32 interleaved format */
+ vskip <<= 1; /* opaque and translucent have same format */
+ do {
+ ofs = 0;
+ do {
+ int run;
+ ofs += ((Uint16 *) srcbuf)[0];
+ run = ((Uint16 *) srcbuf)[1];
+ srcbuf += 4;
+ if (run) {
+ srcbuf += 4 * run;
+ ofs += run;
+ } else if (!ofs)
+ goto done;
+ } while (ofs < w);
+ } while (--vskip);
+ }
+ }
+ }
+
+ /* if left or right edge clipping needed, call clip blit */
+ if (srcrect->x || srcrect->w != surf_src->w) {
+ RLEAlphaClipBlit(w, srcbuf, surf_dst, dstbuf, srcrect);
+ } else {
+
+ /*
+ * non-clipped blitter. Ptype is the destination pixel type,
+ * Ctype the translucent count type, and do_blend the
+ * macro to blend one pixel.
+ */
+#define RLEALPHABLIT(Ptype, Ctype, do_blend) \
+ do { \
+ int linecount = srcrect->h; \
+ do { \
+ int ofs = 0; \
+ /* blit opaque pixels on one line */ \
+ do { \
+ unsigned run; \
+ ofs += ((Ctype *)srcbuf)[0]; \
+ run = ((Ctype *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Ctype); \
+ if(run) { \
+ PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \
+ run, sizeof(Ptype)); \
+ srcbuf += run * sizeof(Ptype); \
+ ofs += run; \
+ } else if(!ofs) \
+ goto done; \
+ } while(ofs < w); \
+ /* skip padding if necessary */ \
+ if(sizeof(Ptype) == 2) \
+ srcbuf += (uintptr_t)srcbuf & 2; \
+ /* blit translucent pixels on the same line */ \
+ ofs = 0; \
+ do { \
+ unsigned run; \
+ ofs += ((Uint16 *)srcbuf)[0]; \
+ run = ((Uint16 *)srcbuf)[1]; \
+ srcbuf += 4; \
+ if(run) { \
+ Ptype *dst = (Ptype *)dstbuf + ofs; \
+ unsigned i; \
+ for(i = 0; i < run; i++) { \
+ Uint32 src = *(Uint32 *)srcbuf; \
+ do_blend(src, *dst); \
+ srcbuf += 4; \
+ dst++; \
+ } \
+ ofs += run; \
+ } \
+ } while(ofs < w); \
+ dstbuf += surf_dst->pitch; \
+ } while(--linecount); \
+ } while(0)
+
+ switch (df->BytesPerPixel) {
+ case 2:
+ if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0
+ || df->Bmask == 0x07e0)
+ RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565);
+ else
+ RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555);
+ break;
+ case 4:
+ RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888);
+ break;
+ }
+ }
+
+ done:
+ /* Unlock the destination if necessary */
+ if (SDL_MUSTLOCK(surf_dst)) {
+ SDL_UnlockSurface(surf_dst);
+ }
+ return 0;
+}
+
+/*
+ * Auxiliary functions:
+ * The encoding functions take 32bpp rgb + a, and
+ * return the number of bytes copied to the destination.
+ * The decoding functions copy to 32bpp rgb + a, and
+ * return the number of bytes copied from the source.
+ * These are only used in the encoder and un-RLE code and are therefore not
+ * highly optimised.
+ */
+
+/* encode 32bpp rgb + a into 16bpp rgb, losing alpha */
+static int
+copy_opaque_16(void *dst, Uint32 * src, int n,
+ SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint16 *d = dst;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b;
+ RGB_FROM_PIXEL(*src, sfmt, r, g, b);
+ PIXEL_FROM_RGB(*d, dfmt, r, g, b);
+ src++;
+ d++;
+ }
+ return n * 2;
+}
+
+/* decode opaque pixels from 16bpp to 32bpp rgb + a */
+static int
+uncopy_opaque_16(Uint32 * dst, void *src, int n,
+ RLEDestFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint16 *s = src;
+ unsigned alpha = dfmt->Amask ? 255 : 0;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b;
+ RGB_FROM_PIXEL(*s, sfmt, r, g, b);
+ PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha);
+ s++;
+ dst++;
+ }
+ return n * 2;
+}
+
+
+
+/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */
+static int
+copy_transl_565(void *dst, Uint32 * src, int n,
+ SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint32 *d = dst;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint16 pix;
+ RGBA_FROM_8888(*src, sfmt, r, g, b, a);
+ PIXEL_FROM_RGB(pix, dfmt, r, g, b);
+ *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0);
+ src++;
+ d++;
+ }
+ return n * 4;
+}
+
+/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */
+static int
+copy_transl_555(void *dst, Uint32 * src, int n,
+ SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint32 *d = dst;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint16 pix;
+ RGBA_FROM_8888(*src, sfmt, r, g, b, a);
+ PIXEL_FROM_RGB(pix, dfmt, r, g, b);
+ *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0);
+ src++;
+ d++;
+ }
+ return n * 4;
+}
+
+/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */
+static int
+uncopy_transl_16(Uint32 * dst, void *src, int n,
+ RLEDestFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint32 *s = src;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint32 pix = *s++;
+ a = (pix & 0x3e0) >> 2;
+ pix = (pix & ~0x3e0) | pix >> 16;
+ RGB_FROM_PIXEL(pix, sfmt, r, g, b);
+ PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);
+ dst++;
+ }
+ return n * 4;
+}
+
+/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */
+static int
+copy_32(void *dst, Uint32 * src, int n,
+ SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint32 *d = dst;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ RGBA_FROM_8888(*src, sfmt, r, g, b, a);
+ RLEPIXEL_FROM_RGBA(*d, dfmt, r, g, b, a);
+ d++;
+ src++;
+ }
+ return n * 4;
+}
+
+/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */
+static int
+uncopy_32(Uint32 * dst, void *src, int n,
+ RLEDestFormat * sfmt, SDL_PixelFormat * dfmt)
+{
+ int i;
+ Uint32 *s = src;
+ for (i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint32 pixel = *s++;
+ RGB_FROM_PIXEL(pixel, sfmt, r, g, b);
+ a = pixel >> 24;
+ PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);
+ dst++;
+ }
+ return n * 4;
+}
+
+#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255)
+
+#define ISTRANSL(pixel, fmt) \
+ ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U)
+
+/* convert surface to be quickly alpha-blittable onto dest, if possible */
+static int
+RLEAlphaSurface(SDL_Surface * surface)
+{
+ SDL_Surface *dest;
+ SDL_PixelFormat *df;
+ int maxsize = 0;
+ int max_opaque_run;
+ int max_transl_run = 65535;
+ unsigned masksum;
+ Uint8 *rlebuf, *dst;
+ int (*copy_opaque) (void *, Uint32 *, int,
+ SDL_PixelFormat *, SDL_PixelFormat *);
+ int (*copy_transl) (void *, Uint32 *, int,
+ SDL_PixelFormat *, SDL_PixelFormat *);
+
+ dest = surface->map->dst;
+ if (!dest)
+ return -1;
+ df = dest->format;
+ if (surface->format->BitsPerPixel != 32)
+ return -1; /* only 32bpp source supported */
+
+ /* find out whether the destination is one we support,
+ and determine the max size of the encoded result */
+ masksum = df->Rmask | df->Gmask | df->Bmask;
+ switch (df->BytesPerPixel) {
+ case 2:
+ /* 16bpp: only support 565 and 555 formats */
+ switch (masksum) {
+ case 0xffff:
+ if (df->Gmask == 0x07e0
+ || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) {
+ copy_opaque = copy_opaque_16;
+ copy_transl = copy_transl_565;
+ } else
+ return -1;
+ break;
+ case 0x7fff:
+ if (df->Gmask == 0x03e0
+ || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) {
+ copy_opaque = copy_opaque_16;
+ copy_transl = copy_transl_555;
+ } else
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ max_opaque_run = 255; /* runs stored as bytes */
+
+ /* worst case is alternating opaque and translucent pixels,
+ with room for alignment padding between lines */
+ maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2;
+ break;
+ case 4:
+ if (masksum != 0x00ffffff)
+ return -1; /* requires unused high byte */
+ copy_opaque = copy_32;
+ copy_transl = copy_32;
+ max_opaque_run = 255; /* runs stored as short ints */
+
+ /* worst case is alternating opaque and translucent pixels */
+ maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4;
+ break;
+ default:
+ return -1; /* anything else unsupported right now */
+ }
+
+ maxsize += sizeof(RLEDestFormat);
+ rlebuf = (Uint8 *) SDL_malloc(maxsize);
+ if (!rlebuf) {
+ return SDL_OutOfMemory();
+ }
+ {
+ /* save the destination format so we can undo the encoding later */
+ RLEDestFormat *r = (RLEDestFormat *) rlebuf;
+ r->BytesPerPixel = df->BytesPerPixel;
+ r->Rmask = df->Rmask;
+ r->Gmask = df->Gmask;
+ r->Bmask = df->Bmask;
+ r->Amask = df->Amask;
+ r->Rloss = df->Rloss;
+ r->Gloss = df->Gloss;
+ r->Bloss = df->Bloss;
+ r->Aloss = df->Aloss;
+ r->Rshift = df->Rshift;
+ r->Gshift = df->Gshift;
+ r->Bshift = df->Bshift;
+ r->Ashift = df->Ashift;
+ }
+ dst = rlebuf + sizeof(RLEDestFormat);
+
+ /* Do the actual encoding */
+ {
+ int x, y;
+ int h = surface->h, w = surface->w;
+ SDL_PixelFormat *sf = surface->format;
+ Uint32 *src = (Uint32 *) surface->pixels;
+ Uint8 *lastline = dst; /* end of last non-blank line */
+
+ /* opaque counts are 8 or 16 bits, depending on target depth */
+#define ADD_OPAQUE_COUNTS(n, m) \
+ if(df->BytesPerPixel == 4) { \
+ ((Uint16 *)dst)[0] = n; \
+ ((Uint16 *)dst)[1] = m; \
+ dst += 4; \
+ } else { \
+ dst[0] = n; \
+ dst[1] = m; \
+ dst += 2; \
+ }
+
+ /* translucent counts are always 16 bit */
+#define ADD_TRANSL_COUNTS(n, m) \
+ (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4)
+
+ for (y = 0; y < h; y++) {
+ int runstart, skipstart;
+ int blankline = 0;
+ /* First encode all opaque pixels of a scan line */
+ x = 0;
+ do {
+ int run, skip, len;
+ skipstart = x;
+ while (x < w && !ISOPAQUE(src[x], sf))
+ x++;
+ runstart = x;
+ while (x < w && ISOPAQUE(src[x], sf))
+ x++;
+ skip = runstart - skipstart;
+ if (skip == w)
+ blankline = 1;
+ run = x - runstart;
+ while (skip > max_opaque_run) {
+ ADD_OPAQUE_COUNTS(max_opaque_run, 0);
+ skip -= max_opaque_run;
+ }
+ len = MIN(run, max_opaque_run);
+ ADD_OPAQUE_COUNTS(skip, len);
+ dst += copy_opaque(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ while (run) {
+ len = MIN(run, max_opaque_run);
+ ADD_OPAQUE_COUNTS(0, len);
+ dst += copy_opaque(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ }
+ } while (x < w);
+
+ /* Make sure the next output address is 32-bit aligned */
+ dst += (uintptr_t) dst & 2;
+
+ /* Next, encode all translucent pixels of the same scan line */
+ x = 0;
+ do {
+ int run, skip, len;
+ skipstart = x;
+ while (x < w && !ISTRANSL(src[x], sf))
+ x++;
+ runstart = x;
+ while (x < w && ISTRANSL(src[x], sf))
+ x++;
+ skip = runstart - skipstart;
+ blankline &= (skip == w);
+ run = x - runstart;
+ while (skip > max_transl_run) {
+ ADD_TRANSL_COUNTS(max_transl_run, 0);
+ skip -= max_transl_run;
+ }
+ len = MIN(run, max_transl_run);
+ ADD_TRANSL_COUNTS(skip, len);
+ dst += copy_transl(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ while (run) {
+ len = MIN(run, max_transl_run);
+ ADD_TRANSL_COUNTS(0, len);
+ dst += copy_transl(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ }
+ if (!blankline)
+ lastline = dst;
+ } while (x < w);
+
+ src += surface->pitch >> 2;
+ }
+ dst = lastline; /* back up past trailing blank lines */
+ ADD_OPAQUE_COUNTS(0, 0);
+ }
+
+#undef ADD_OPAQUE_COUNTS
+#undef ADD_TRANSL_COUNTS
+
+ /* Now that we have it encoded, release the original pixels */
+ if (!(surface->flags & SDL_PREALLOC)) {
+ SDL_free(surface->pixels);
+ surface->pixels = NULL;
+ }
+
+ /* realloc the buffer to release unused memory */
+ {
+ Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf);
+ if (!p)
+ p = rlebuf;
+ surface->map->data = p;
+ }
+
+ return 0;
+}
+
+static Uint32
+getpix_8(Uint8 * srcbuf)
+{
+ return *srcbuf;
+}
+
+static Uint32
+getpix_16(Uint8 * srcbuf)
+{
+ return *(Uint16 *) srcbuf;
+}
+
+static Uint32
+getpix_24(Uint8 * srcbuf)
+{
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16);
+#else
+ return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2];
+#endif
+}
+
+static Uint32
+getpix_32(Uint8 * srcbuf)
+{
+ return *(Uint32 *) srcbuf;
+}
+
+typedef Uint32(*getpix_func) (Uint8 *);
+
+static const getpix_func getpixes[4] = {
+ getpix_8, getpix_16, getpix_24, getpix_32
+};
+
+static int
+RLEColorkeySurface(SDL_Surface * surface)
+{
+ Uint8 *rlebuf, *dst;
+ int maxn;
+ int y;
+ Uint8 *srcbuf, *lastline;
+ int maxsize = 0;
+ const int bpp = surface->format->BytesPerPixel;
+ getpix_func getpix;
+ Uint32 ckey, rgbmask;
+ int w, h;
+
+ /* calculate the worst case size for the compressed surface */
+ switch (bpp) {
+ case 1:
+ /* worst case is alternating opaque and transparent pixels,
+ starting with an opaque pixel */
+ maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2;
+ break;
+ case 2:
+ case 3:
+ /* worst case is solid runs, at most 255 pixels wide */
+ maxsize = surface->h * (2 * (surface->w / 255 + 1)
+ + surface->w * bpp) + 2;
+ break;
+ case 4:
+ /* worst case is solid runs, at most 65535 pixels wide */
+ maxsize = surface->h * (4 * (surface->w / 65535 + 1)
+ + surface->w * 4) + 4;
+ break;
+
+ default:
+ return -1;
+ }
+
+ rlebuf = (Uint8 *) SDL_malloc(maxsize);
+ if (rlebuf == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Set up the conversion */
+ srcbuf = (Uint8 *) surface->pixels;
+ maxn = bpp == 4 ? 65535 : 255;
+ dst = rlebuf;
+ rgbmask = ~surface->format->Amask;
+ ckey = surface->map->info.colorkey & rgbmask;
+ lastline = dst;
+ getpix = getpixes[bpp - 1];
+ w = surface->w;
+ h = surface->h;
+
+#define ADD_COUNTS(n, m) \
+ if(bpp == 4) { \
+ ((Uint16 *)dst)[0] = n; \
+ ((Uint16 *)dst)[1] = m; \
+ dst += 4; \
+ } else { \
+ dst[0] = n; \
+ dst[1] = m; \
+ dst += 2; \
+ }
+
+ for (y = 0; y < h; y++) {
+ int x = 0;
+ int blankline = 0;
+ do {
+ int run, skip, len;
+ int runstart;
+ int skipstart = x;
+
+ /* find run of transparent, then opaque pixels */
+ while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey)
+ x++;
+ runstart = x;
+ while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey)
+ x++;
+ skip = runstart - skipstart;
+ if (skip == w)
+ blankline = 1;
+ run = x - runstart;
+
+ /* encode segment */
+ while (skip > maxn) {
+ ADD_COUNTS(maxn, 0);
+ skip -= maxn;
+ }
+ len = MIN(run, maxn);
+ ADD_COUNTS(skip, len);
+ SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp);
+ dst += len * bpp;
+ run -= len;
+ runstart += len;
+ while (run) {
+ len = MIN(run, maxn);
+ ADD_COUNTS(0, len);
+ SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp);
+ dst += len * bpp;
+ runstart += len;
+ run -= len;
+ }
+ if (!blankline)
+ lastline = dst;
+ } while (x < w);
+
+ srcbuf += surface->pitch;
+ }
+ dst = lastline; /* back up bast trailing blank lines */
+ ADD_COUNTS(0, 0);
+
+#undef ADD_COUNTS
+
+ /* Now that we have it encoded, release the original pixels */
+ if (!(surface->flags & SDL_PREALLOC)) {
+ SDL_free(surface->pixels);
+ surface->pixels = NULL;
+ }
+
+ /* realloc the buffer to release unused memory */
+ {
+ /* If realloc returns NULL, the original block is left intact */
+ Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf);
+ if (!p)
+ p = rlebuf;
+ surface->map->data = p;
+ }
+
+ return 0;
+}
+
+int
+SDL_RLESurface(SDL_Surface * surface)
+{
+ int flags;
+
+ /* Clear any previous RLE conversion */
+ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
+ SDL_UnRLESurface(surface, 1);
+ }
+
+ /* We don't support RLE encoding of bitmaps */
+ if (surface->format->BitsPerPixel < 8) {
+ return -1;
+ }
+
+ /* Make sure the pixels are available */
+ if (!surface->pixels) {
+ return -1;
+ }
+
+ /* If we don't have colorkey or blending, nothing to do... */
+ flags = surface->map->info.flags;
+ if (!(flags & (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) {
+ return -1;
+ }
+
+ /* Pass on combinations not supported */
+ if ((flags & SDL_COPY_MODULATE_COLOR) ||
+ ((flags & SDL_COPY_MODULATE_ALPHA) && surface->format->Amask) ||
+ (flags & (SDL_COPY_ADD | SDL_COPY_MOD)) ||
+ (flags & SDL_COPY_NEAREST)) {
+ return -1;
+ }
+
+ /* Encode and set up the blit */
+ if (!surface->format->Amask || !(flags & SDL_COPY_BLEND)) {
+ if (!surface->map->identity) {
+ return -1;
+ }
+ if (RLEColorkeySurface(surface) < 0) {
+ return -1;
+ }
+ surface->map->blit = SDL_RLEBlit;
+ surface->map->info.flags |= SDL_COPY_RLE_COLORKEY;
+ } else {
+ if (RLEAlphaSurface(surface) < 0) {
+ return -1;
+ }
+ surface->map->blit = SDL_RLEAlphaBlit;
+ surface->map->info.flags |= SDL_COPY_RLE_ALPHAKEY;
+ }
+
+ /* The surface is now accelerated */
+ surface->flags |= SDL_RLEACCEL;
+
+ return (0);
+}
+
+/*
+ * Un-RLE a surface with pixel alpha
+ * This may not give back exactly the image before RLE-encoding; all
+ * completely transparent pixels will be lost, and color and alpha depth
+ * may have been reduced (when encoding for 16bpp targets).
+ */
+static SDL_bool
+UnRLEAlpha(SDL_Surface * surface)
+{
+ Uint8 *srcbuf;
+ Uint32 *dst;
+ SDL_PixelFormat *sf = surface->format;
+ RLEDestFormat *df = surface->map->data;
+ int (*uncopy_opaque) (Uint32 *, void *, int,
+ RLEDestFormat *, SDL_PixelFormat *);
+ int (*uncopy_transl) (Uint32 *, void *, int,
+ RLEDestFormat *, SDL_PixelFormat *);
+ int w = surface->w;
+ int bpp = df->BytesPerPixel;
+
+ if (bpp == 2) {
+ uncopy_opaque = uncopy_opaque_16;
+ uncopy_transl = uncopy_transl_16;
+ } else {
+ uncopy_opaque = uncopy_transl = uncopy_32;
+ }
+
+ surface->pixels = SDL_malloc(surface->h * surface->pitch);
+ if (!surface->pixels) {
+ return (SDL_FALSE);
+ }
+ /* fill background with transparent pixels */
+ SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
+
+ dst = surface->pixels;
+ srcbuf = (Uint8 *) (df + 1);
+ for (;;) {
+ /* copy opaque pixels */
+ int ofs = 0;
+ do {
+ unsigned run;
+ if (bpp == 2) {
+ ofs += srcbuf[0];
+ run = srcbuf[1];
+ srcbuf += 2;
+ } else {
+ ofs += ((Uint16 *) srcbuf)[0];
+ run = ((Uint16 *) srcbuf)[1];
+ srcbuf += 4;
+ }
+ if (run) {
+ srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf);
+ ofs += run;
+ } else if (!ofs)
+ return (SDL_TRUE);
+ } while (ofs < w);
+
+ /* skip padding if needed */
+ if (bpp == 2)
+ srcbuf += (uintptr_t) srcbuf & 2;
+
+ /* copy translucent pixels */
+ ofs = 0;
+ do {
+ unsigned run;
+ ofs += ((Uint16 *) srcbuf)[0];
+ run = ((Uint16 *) srcbuf)[1];
+ srcbuf += 4;
+ if (run) {
+ srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf);
+ ofs += run;
+ }
+ } while (ofs < w);
+ dst += surface->pitch >> 2;
+ }
+ /* Make the compiler happy */
+ return (SDL_TRUE);
+}
+
+void
+SDL_UnRLESurface(SDL_Surface * surface, int recode)
+{
+ if (surface->flags & SDL_RLEACCEL) {
+ surface->flags &= ~SDL_RLEACCEL;
+
+ if (recode && !(surface->flags & SDL_PREALLOC)) {
+ if (surface->map->info.flags & SDL_COPY_RLE_COLORKEY) {
+ SDL_Rect full;
+
+ /* re-create the original surface */
+ surface->pixels = SDL_malloc(surface->h * surface->pitch);
+ if (!surface->pixels) {
+ /* Oh crap... */
+ surface->flags |= SDL_RLEACCEL;
+ return;
+ }
+
+ /* fill it with the background color */
+ SDL_FillRect(surface, NULL, surface->map->info.colorkey);
+
+ /* now render the encoded surface */
+ full.x = full.y = 0;
+ full.w = surface->w;
+ full.h = surface->h;
+ SDL_RLEBlit(surface, &full, surface, &full);
+ } else {
+ if (!UnRLEAlpha(surface)) {
+ /* Oh crap... */
+ surface->flags |= SDL_RLEACCEL;
+ return;
+ }
+ }
+ }
+ surface->map->info.flags &=
+ ~(SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY);
+
+ SDL_free(surface->map->data);
+ surface->map->data = NULL;
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_RLEaccel_c.h b/source/3rd-party/SDL2/src/video/SDL_RLEaccel_c.h
new file mode 100644
index 0000000..b6fa6a1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_RLEaccel_c.h
@@ -0,0 +1,38 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_RLEaccel_c_h_
+#define SDL_RLEaccel_c_h_
+
+#include "../SDL_internal.h"
+
+/* Useful functions and variables from SDL_RLEaccel.c */
+
+extern int SDL_RLESurface(SDL_Surface * surface);
+extern int SDLCALL SDL_RLEBlit (SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect);
+extern int SDLCALL SDL_RLEAlphaBlit(SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect);
+extern void SDL_UnRLESurface(SDL_Surface * surface, int recode);
+
+#endif /* SDL_RLEaccel_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit.c b/source/3rd-party/SDL2/src/video/SDL_blit.c
new file mode 100644
index 0000000..0d4e2fd
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit.c
@@ -0,0 +1,296 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_blit_auto.h"
+#include "SDL_blit_copy.h"
+#include "SDL_blit_slow.h"
+#include "SDL_RLEaccel_c.h"
+#include "SDL_pixels_c.h"
+
+/* The general purpose software blit routine */
+static int SDLCALL
+SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect)
+{
+ int okay;
+ int src_locked;
+ int dst_locked;
+
+ /* Everything is okay at the beginning... */
+ okay = 1;
+
+ /* Lock the destination if it's in hardware */
+ dst_locked = 0;
+ if (SDL_MUSTLOCK(dst)) {
+ if (SDL_LockSurface(dst) < 0) {
+ okay = 0;
+ } else {
+ dst_locked = 1;
+ }
+ }
+ /* Lock the source if it's in hardware */
+ src_locked = 0;
+ if (SDL_MUSTLOCK(src)) {
+ if (SDL_LockSurface(src) < 0) {
+ okay = 0;
+ } else {
+ src_locked = 1;
+ }
+ }
+
+ /* Set up source and destination buffer pointers, and BLIT! */
+ if (okay && !SDL_RectEmpty(srcrect)) {
+ SDL_BlitFunc RunBlit;
+ SDL_BlitInfo *info = &src->map->info;
+
+ /* Set up the blit information */
+ info->src = (Uint8 *) src->pixels +
+ (Uint16) srcrect->y * src->pitch +
+ (Uint16) srcrect->x * info->src_fmt->BytesPerPixel;
+ info->src_w = srcrect->w;
+ info->src_h = srcrect->h;
+ info->src_pitch = src->pitch;
+ info->src_skip =
+ info->src_pitch - info->src_w * info->src_fmt->BytesPerPixel;
+ info->dst =
+ (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch +
+ (Uint16) dstrect->x * info->dst_fmt->BytesPerPixel;
+ info->dst_w = dstrect->w;
+ info->dst_h = dstrect->h;
+ info->dst_pitch = dst->pitch;
+ info->dst_skip =
+ info->dst_pitch - info->dst_w * info->dst_fmt->BytesPerPixel;
+ RunBlit = (SDL_BlitFunc) src->map->data;
+
+ /* Run the actual software blit */
+ RunBlit(info);
+ }
+
+ /* We need to unlock the surfaces if they're locked */
+ if (dst_locked) {
+ SDL_UnlockSurface(dst);
+ }
+ if (src_locked) {
+ SDL_UnlockSurface(src);
+ }
+ /* Blit is done! */
+ return (okay ? 0 : -1);
+}
+
+#ifdef __MACOSX__
+#include <sys/sysctl.h>
+
+static SDL_bool
+SDL_UseAltivecPrefetch()
+{
+ const char key[] = "hw.l3cachesize";
+ u_int64_t result = 0;
+ size_t typeSize = sizeof(result);
+
+ if (sysctlbyname(key, &result, &typeSize, NULL, 0) == 0 && result > 0) {
+ return SDL_TRUE;
+ } else {
+ return SDL_FALSE;
+ }
+}
+#else
+static SDL_bool
+SDL_UseAltivecPrefetch()
+{
+ /* Just guess G4 */
+ return SDL_TRUE;
+}
+#endif /* __MACOSX__ */
+
+static SDL_BlitFunc
+SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
+ SDL_BlitFuncEntry * entries)
+{
+ int i, flagcheck;
+ static Uint32 features = 0xffffffff;
+
+ /* Get the available CPU features */
+ if (features == 0xffffffff) {
+ const char *override = SDL_getenv("SDL_BLIT_CPU_FEATURES");
+
+ features = SDL_CPU_ANY;
+
+ /* Allow an override for testing .. */
+ if (override) {
+ SDL_sscanf(override, "%u", &features);
+ } else {
+ if (SDL_HasMMX()) {
+ features |= SDL_CPU_MMX;
+ }
+ if (SDL_Has3DNow()) {
+ features |= SDL_CPU_3DNOW;
+ }
+ if (SDL_HasSSE()) {
+ features |= SDL_CPU_SSE;
+ }
+ if (SDL_HasSSE2()) {
+ features |= SDL_CPU_SSE2;
+ }
+ if (SDL_HasAltiVec()) {
+ if (SDL_UseAltivecPrefetch()) {
+ features |= SDL_CPU_ALTIVEC_PREFETCH;
+ } else {
+ features |= SDL_CPU_ALTIVEC_NOPREFETCH;
+ }
+ }
+ }
+ }
+
+ for (i = 0; entries[i].func; ++i) {
+ /* Check for matching pixel formats */
+ if (src_format != entries[i].src_format) {
+ continue;
+ }
+ if (dst_format != entries[i].dst_format) {
+ continue;
+ }
+
+ /* Check modulation flags */
+ flagcheck =
+ (flags & (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA));
+ if ((flagcheck & entries[i].flags) != flagcheck) {
+ continue;
+ }
+
+ /* Check blend flags */
+ flagcheck =
+ (flags &
+ (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD));
+ if ((flagcheck & entries[i].flags) != flagcheck) {
+ continue;
+ }
+
+ /* Check colorkey flag */
+ flagcheck = (flags & SDL_COPY_COLORKEY);
+ if ((flagcheck & entries[i].flags) != flagcheck) {
+ continue;
+ }
+
+ /* Check scaling flags */
+ flagcheck = (flags & SDL_COPY_NEAREST);
+ if ((flagcheck & entries[i].flags) != flagcheck) {
+ continue;
+ }
+
+ /* Check CPU features */
+ flagcheck = entries[i].cpu;
+ if ((flagcheck & features) != flagcheck) {
+ continue;
+ }
+
+ /* We found the best one! */
+ return entries[i].func;
+ }
+ return NULL;
+}
+
+/* Figure out which of many blit routines to set up on a surface */
+int
+SDL_CalculateBlit(SDL_Surface * surface)
+{
+ SDL_BlitFunc blit = NULL;
+ SDL_BlitMap *map = surface->map;
+ SDL_Surface *dst = map->dst;
+
+ /* We don't currently support blitting to < 8 bpp surfaces */
+ if (dst->format->BitsPerPixel < 8) {
+ SDL_InvalidateMap(map);
+ return SDL_SetError("Blit combination not supported");
+ }
+
+ /* Clean everything out to start */
+ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
+ SDL_UnRLESurface(surface, 1);
+ }
+ map->blit = SDL_SoftBlit;
+ map->info.src_fmt = surface->format;
+ map->info.src_pitch = surface->pitch;
+ map->info.dst_fmt = dst->format;
+ map->info.dst_pitch = dst->pitch;
+
+ /* See if we can do RLE acceleration */
+ if (map->info.flags & SDL_COPY_RLE_DESIRED) {
+ if (SDL_RLESurface(surface) == 0) {
+ return 0;
+ }
+ }
+
+ /* Choose a standard blit function */
+ if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) {
+ blit = SDL_BlitCopy;
+ } else if (surface->format->Rloss > 8 || dst->format->Rloss > 8) {
+ /* Greater than 8 bits per channel not supported yet */
+ SDL_InvalidateMap(map);
+ return SDL_SetError("Blit combination not supported");
+ } else if (surface->format->BitsPerPixel < 8 &&
+ SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
+ blit = SDL_CalculateBlit0(surface);
+ } else if (surface->format->BytesPerPixel == 1 &&
+ SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
+ blit = SDL_CalculateBlit1(surface);
+ } else if (map->info.flags & SDL_COPY_BLEND) {
+ blit = SDL_CalculateBlitA(surface);
+ } else {
+ blit = SDL_CalculateBlitN(surface);
+ }
+ if (blit == NULL) {
+ Uint32 src_format = surface->format->format;
+ Uint32 dst_format = dst->format->format;
+
+ blit =
+ SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
+ SDL_GeneratedBlitFuncTable);
+ }
+#ifndef TEST_SLOW_BLIT
+ if (blit == NULL)
+#endif
+ {
+ Uint32 src_format = surface->format->format;
+ Uint32 dst_format = dst->format->format;
+
+ if (!SDL_ISPIXELFORMAT_INDEXED(src_format) &&
+ !SDL_ISPIXELFORMAT_FOURCC(src_format) &&
+ !SDL_ISPIXELFORMAT_INDEXED(dst_format) &&
+ !SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
+ blit = SDL_Blit_Slow;
+ }
+ }
+ map->data = blit;
+
+ /* Make sure we have a blit function */
+ if (blit == NULL) {
+ SDL_InvalidateMap(map);
+ return SDL_SetError("Blit combination not supported");
+ }
+
+ return 0;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit.h b/source/3rd-party/SDL2/src/video/SDL_blit.h
new file mode 100644
index 0000000..6c95aaf
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit.h
@@ -0,0 +1,553 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#ifndef SDL_blit_h_
+#define SDL_blit_h_
+
+#include "SDL_cpuinfo.h"
+#include "SDL_endian.h"
+#include "SDL_surface.h"
+
+/* Table to do pixel byte expansion */
+extern Uint8* SDL_expand_byte[9];
+
+/* SDL blit copy flags */
+#define SDL_COPY_MODULATE_COLOR 0x00000001
+#define SDL_COPY_MODULATE_ALPHA 0x00000002
+#define SDL_COPY_BLEND 0x00000010
+#define SDL_COPY_ADD 0x00000020
+#define SDL_COPY_MOD 0x00000040
+#define SDL_COPY_COLORKEY 0x00000100
+#define SDL_COPY_NEAREST 0x00000200
+#define SDL_COPY_RLE_DESIRED 0x00001000
+#define SDL_COPY_RLE_COLORKEY 0x00002000
+#define SDL_COPY_RLE_ALPHAKEY 0x00004000
+#define SDL_COPY_RLE_MASK (SDL_COPY_RLE_DESIRED|SDL_COPY_RLE_COLORKEY|SDL_COPY_RLE_ALPHAKEY)
+
+/* SDL blit CPU flags */
+#define SDL_CPU_ANY 0x00000000
+#define SDL_CPU_MMX 0x00000001
+#define SDL_CPU_3DNOW 0x00000002
+#define SDL_CPU_SSE 0x00000004
+#define SDL_CPU_SSE2 0x00000008
+#define SDL_CPU_ALTIVEC_PREFETCH 0x00000010
+#define SDL_CPU_ALTIVEC_NOPREFETCH 0x00000020
+
+typedef struct
+{
+ Uint8 *src;
+ int src_w, src_h;
+ int src_pitch;
+ int src_skip;
+ Uint8 *dst;
+ int dst_w, dst_h;
+ int dst_pitch;
+ int dst_skip;
+ SDL_PixelFormat *src_fmt;
+ SDL_PixelFormat *dst_fmt;
+ Uint8 *table;
+ int flags;
+ Uint32 colorkey;
+ Uint8 r, g, b, a;
+} SDL_BlitInfo;
+
+typedef void (*SDL_BlitFunc) (SDL_BlitInfo *info);
+
+
+typedef struct
+{
+ Uint32 src_format;
+ Uint32 dst_format;
+ int flags;
+ int cpu;
+ SDL_BlitFunc func;
+} SDL_BlitFuncEntry;
+
+/* Blit mapping definition */
+typedef struct SDL_BlitMap
+{
+ SDL_Surface *dst;
+ int identity;
+ SDL_blit blit;
+ void *data;
+ SDL_BlitInfo info;
+
+ /* the version count matches the destination; mismatch indicates
+ an invalid mapping */
+ Uint32 dst_palette_version;
+ Uint32 src_palette_version;
+} SDL_BlitMap;
+
+/* Functions found in SDL_blit.c */
+extern int SDL_CalculateBlit(SDL_Surface * surface);
+
+/* Functions found in SDL_blit_*.c */
+extern SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface * surface);
+extern SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface * surface);
+extern SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface * surface);
+extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface * surface);
+
+/*
+ * Useful macros for blitting routines
+ */
+
+#if defined(__GNUC__)
+#define DECLARE_ALIGNED(t,v,a) t __attribute__((aligned(a))) v
+#elif defined(_MSC_VER)
+#define DECLARE_ALIGNED(t,v,a) __declspec(align(a)) t v
+#else
+#define DECLARE_ALIGNED(t,v,a) t v
+#endif
+
+/* Load pixel of the specified format from a buffer and get its R-G-B values */
+#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \
+{ \
+ r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
+ g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
+ b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
+}
+#define RGB_FROM_RGB565(Pixel, r, g, b) \
+{ \
+ r = SDL_expand_byte[3][((Pixel&0xF800)>>11)]; \
+ g = SDL_expand_byte[2][((Pixel&0x07E0)>>5)]; \
+ b = SDL_expand_byte[3][(Pixel&0x001F)]; \
+}
+#define RGB_FROM_RGB555(Pixel, r, g, b) \
+{ \
+ r = SDL_expand_byte[3][((Pixel&0x7C00)>>10)]; \
+ g = SDL_expand_byte[3][((Pixel&0x03E0)>>5)]; \
+ b = SDL_expand_byte[3][(Pixel&0x001F)]; \
+}
+#define RGB_FROM_RGB888(Pixel, r, g, b) \
+{ \
+ r = ((Pixel&0xFF0000)>>16); \
+ g = ((Pixel&0xFF00)>>8); \
+ b = (Pixel&0xFF); \
+}
+#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel) \
+do { \
+ switch (bpp) { \
+ case 1: \
+ Pixel = *((Uint8 *)(buf)); \
+ break; \
+ \
+ case 2: \
+ Pixel = *((Uint16 *)(buf)); \
+ break; \
+ \
+ case 3: { \
+ Uint8 *B = (Uint8 *)(buf); \
+ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
+ } else { \
+ Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
+ } \
+ } \
+ break; \
+ \
+ case 4: \
+ Pixel = *((Uint32 *)(buf)); \
+ break; \
+ \
+ default: \
+ Pixel = 0; /* stop gcc complaints */ \
+ break; \
+ } \
+} while (0)
+
+#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \
+do { \
+ switch (bpp) { \
+ case 1: \
+ Pixel = *((Uint8 *)(buf)); \
+ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
+ break; \
+ \
+ case 2: \
+ Pixel = *((Uint16 *)(buf)); \
+ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
+ break; \
+ \
+ case 3: { \
+ Pixel = 0; \
+ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ r = *((buf)+fmt->Rshift/8); \
+ g = *((buf)+fmt->Gshift/8); \
+ b = *((buf)+fmt->Bshift/8); \
+ } else { \
+ r = *((buf)+2-fmt->Rshift/8); \
+ g = *((buf)+2-fmt->Gshift/8); \
+ b = *((buf)+2-fmt->Bshift/8); \
+ } \
+ } \
+ break; \
+ \
+ case 4: \
+ Pixel = *((Uint32 *)(buf)); \
+ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
+ break; \
+ \
+ default: \
+ /* stop gcc complaints */ \
+ Pixel = 0; \
+ r = g = b = 0; \
+ break; \
+ } \
+} while (0)
+
+/* Assemble R-G-B values into a specified pixel format and store them */
+#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift)| \
+ fmt->Amask; \
+}
+#define RGB565_FROM_RGB(Pixel, r, g, b) \
+{ \
+ Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \
+}
+#define RGB555_FROM_RGB(Pixel, r, g, b) \
+{ \
+ Pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \
+}
+#define RGB888_FROM_RGB(Pixel, r, g, b) \
+{ \
+ Pixel = (r<<16)|(g<<8)|b; \
+}
+#define ARGB8888_FROM_RGBA(Pixel, r, g, b, a) \
+{ \
+ Pixel = (a<<24)|(r<<16)|(g<<8)|b; \
+}
+#define RGBA8888_FROM_RGBA(Pixel, r, g, b, a) \
+{ \
+ Pixel = (r<<24)|(g<<16)|(b<<8)|a; \
+}
+#define ABGR8888_FROM_RGBA(Pixel, r, g, b, a) \
+{ \
+ Pixel = (a<<24)|(b<<16)|(g<<8)|r; \
+}
+#define BGRA8888_FROM_RGBA(Pixel, r, g, b, a) \
+{ \
+ Pixel = (b<<24)|(g<<16)|(r<<8)|a; \
+}
+#define ARGB2101010_FROM_RGBA(Pixel, r, g, b, a) \
+{ \
+ r = r ? ((r << 2) | 0x3) : 0; \
+ g = g ? ((g << 2) | 0x3) : 0; \
+ b = b ? ((b << 2) | 0x3) : 0; \
+ a = (a * 3) / 255; \
+ Pixel = (a<<30)|(r<<20)|(g<<10)|b; \
+}
+#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \
+{ \
+ switch (bpp) { \
+ case 1: { \
+ Uint8 _Pixel; \
+ \
+ PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
+ *((Uint8 *)(buf)) = _Pixel; \
+ } \
+ break; \
+ \
+ case 2: { \
+ Uint16 _Pixel; \
+ \
+ PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
+ *((Uint16 *)(buf)) = _Pixel; \
+ } \
+ break; \
+ \
+ case 3: { \
+ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ *((buf)+fmt->Rshift/8) = r; \
+ *((buf)+fmt->Gshift/8) = g; \
+ *((buf)+fmt->Bshift/8) = b; \
+ } else { \
+ *((buf)+2-fmt->Rshift/8) = r; \
+ *((buf)+2-fmt->Gshift/8) = g; \
+ *((buf)+2-fmt->Bshift/8) = b; \
+ } \
+ } \
+ break; \
+ \
+ case 4: { \
+ Uint32 _Pixel; \
+ \
+ PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
+ *((Uint32 *)(buf)) = _Pixel; \
+ } \
+ break; \
+ } \
+}
+
+/* FIXME: Should we rescale alpha into 0..255 here? */
+#define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a) \
+{ \
+ r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
+ g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
+ b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
+ a = SDL_expand_byte[fmt->Aloss][((Pixel&fmt->Amask)>>fmt->Ashift)]; \
+}
+#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a) \
+{ \
+ r = (Pixel&fmt->Rmask)>>fmt->Rshift; \
+ g = (Pixel&fmt->Gmask)>>fmt->Gshift; \
+ b = (Pixel&fmt->Bmask)>>fmt->Bshift; \
+ a = (Pixel&fmt->Amask)>>fmt->Ashift; \
+}
+#define RGBA_FROM_RGBA8888(Pixel, r, g, b, a) \
+{ \
+ r = (Pixel>>24); \
+ g = ((Pixel>>16)&0xFF); \
+ b = ((Pixel>>8)&0xFF); \
+ a = (Pixel&0xFF); \
+}
+#define RGBA_FROM_ARGB8888(Pixel, r, g, b, a) \
+{ \
+ r = ((Pixel>>16)&0xFF); \
+ g = ((Pixel>>8)&0xFF); \
+ b = (Pixel&0xFF); \
+ a = (Pixel>>24); \
+}
+#define RGBA_FROM_ABGR8888(Pixel, r, g, b, a) \
+{ \
+ r = (Pixel&0xFF); \
+ g = ((Pixel>>8)&0xFF); \
+ b = ((Pixel>>16)&0xFF); \
+ a = (Pixel>>24); \
+}
+#define RGBA_FROM_BGRA8888(Pixel, r, g, b, a) \
+{ \
+ r = ((Pixel>>8)&0xFF); \
+ g = ((Pixel>>16)&0xFF); \
+ b = (Pixel>>24); \
+ a = (Pixel&0xFF); \
+}
+#define RGBA_FROM_ARGB2101010(Pixel, r, g, b, a) \
+{ \
+ r = ((Pixel>>22)&0xFF); \
+ g = ((Pixel>>12)&0xFF); \
+ b = ((Pixel>>2)&0xFF); \
+ a = SDL_expand_byte[6][(Pixel>>30)]; \
+}
+#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \
+do { \
+ switch (bpp) { \
+ case 1: \
+ Pixel = *((Uint8 *)(buf)); \
+ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
+ break; \
+ \
+ case 2: \
+ Pixel = *((Uint16 *)(buf)); \
+ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
+ break; \
+ \
+ case 3: { \
+ Pixel = 0; \
+ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ r = *((buf)+fmt->Rshift/8); \
+ g = *((buf)+fmt->Gshift/8); \
+ b = *((buf)+fmt->Bshift/8); \
+ } else { \
+ r = *((buf)+2-fmt->Rshift/8); \
+ g = *((buf)+2-fmt->Gshift/8); \
+ b = *((buf)+2-fmt->Bshift/8); \
+ } \
+ a = 0xFF; \
+ } \
+ break; \
+ \
+ case 4: \
+ Pixel = *((Uint32 *)(buf)); \
+ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
+ break; \
+ \
+ default: \
+ /* stop gcc complaints */ \
+ Pixel = 0; \
+ r = g = b = a = 0; \
+ break; \
+ } \
+} while (0)
+
+/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */
+#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift)| \
+ ((a>>fmt->Aloss)<<fmt->Ashift); \
+}
+#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
+{ \
+ switch (bpp) { \
+ case 1: { \
+ Uint8 _pixel; \
+ \
+ PIXEL_FROM_RGBA(_pixel, fmt, r, g, b, a); \
+ *((Uint8 *)(buf)) = _pixel; \
+ } \
+ break; \
+ \
+ case 2: { \
+ Uint16 _pixel; \
+ \
+ PIXEL_FROM_RGBA(_pixel, fmt, r, g, b, a); \
+ *((Uint16 *)(buf)) = _pixel; \
+ } \
+ break; \
+ \
+ case 3: { \
+ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ *((buf)+fmt->Rshift/8) = r; \
+ *((buf)+fmt->Gshift/8) = g; \
+ *((buf)+fmt->Bshift/8) = b; \
+ } else { \
+ *((buf)+2-fmt->Rshift/8) = r; \
+ *((buf)+2-fmt->Gshift/8) = g; \
+ *((buf)+2-fmt->Bshift/8) = b; \
+ } \
+ } \
+ break; \
+ \
+ case 4: { \
+ Uint32 _pixel; \
+ \
+ PIXEL_FROM_RGBA(_pixel, fmt, r, g, b, a); \
+ *((Uint32 *)(buf)) = _pixel; \
+ } \
+ break; \
+ } \
+}
+
+/* Blend the RGB values of two pixels with an alpha value */
+#define ALPHA_BLEND_RGB(sR, sG, sB, A, dR, dG, dB) \
+do { \
+ dR = (Uint8)((((int)(sR-dR)*(int)A)/255)+dR); \
+ dG = (Uint8)((((int)(sG-dG)*(int)A)/255)+dG); \
+ dB = (Uint8)((((int)(sB-dB)*(int)A)/255)+dB); \
+} while(0)
+
+
+/* Blend the RGBA values of two pixels */
+#define ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA) \
+do { \
+ dR = (Uint8)((((int)(sR-dR)*(int)sA)/255)+dR); \
+ dG = (Uint8)((((int)(sG-dG)*(int)sA)/255)+dG); \
+ dB = (Uint8)((((int)(sB-dB)*(int)sA)/255)+dB); \
+ dA = (Uint8)((int)sA+dA-((int)sA*dA)/255); \
+} while(0)
+
+
+/* This is a very useful loop for optimizing blitters */
+#if defined(_MSC_VER) && (_MSC_VER == 1300)
+/* There's a bug in the Visual C++ 7 optimizer when compiling this code */
+#else
+#define USE_DUFFS_LOOP
+#endif
+#ifdef USE_DUFFS_LOOP
+
+/* 8-times unrolled loop */
+#define DUFFS_LOOP8(pixel_copy_increment, width) \
+{ int n = (width+7)/8; \
+ switch (width & 7) { \
+ case 0: do { pixel_copy_increment; /* fallthrough */ \
+ case 7: pixel_copy_increment; /* fallthrough */ \
+ case 6: pixel_copy_increment; /* fallthrough */ \
+ case 5: pixel_copy_increment; /* fallthrough */ \
+ case 4: pixel_copy_increment; /* fallthrough */ \
+ case 3: pixel_copy_increment; /* fallthrough */ \
+ case 2: pixel_copy_increment; /* fallthrough */ \
+ case 1: pixel_copy_increment; /* fallthrough */ \
+ } while ( --n > 0 ); \
+ } \
+}
+
+/* 4-times unrolled loop */
+#define DUFFS_LOOP4(pixel_copy_increment, width) \
+{ int n = (width+3)/4; \
+ switch (width & 3) { \
+ case 0: do { pixel_copy_increment; /* fallthrough */ \
+ case 3: pixel_copy_increment; /* fallthrough */ \
+ case 2: pixel_copy_increment; /* fallthrough */ \
+ case 1: pixel_copy_increment; /* fallthrough */ \
+ } while (--n > 0); \
+ } \
+}
+
+/* Use the 8-times version of the loop by default */
+#define DUFFS_LOOP(pixel_copy_increment, width) \
+ DUFFS_LOOP8(pixel_copy_increment, width)
+
+/* Special version of Duff's device for even more optimization */
+#define DUFFS_LOOP_124(pixel_copy_increment1, \
+ pixel_copy_increment2, \
+ pixel_copy_increment4, width) \
+{ int n = width; \
+ if (n & 1) { \
+ pixel_copy_increment1; n -= 1; \
+ } \
+ if (n & 2) { \
+ pixel_copy_increment2; n -= 2; \
+ } \
+ if (n & 4) { \
+ pixel_copy_increment4; n -= 4; \
+ } \
+ if (n) { \
+ n /= 8; \
+ do { \
+ pixel_copy_increment4; \
+ pixel_copy_increment4; \
+ } while (--n > 0); \
+ } \
+}
+
+#else
+
+/* Don't use Duff's device to unroll loops */
+#define DUFFS_LOOP(pixel_copy_increment, width) \
+{ int n; \
+ for ( n=width; n > 0; --n ) { \
+ pixel_copy_increment; \
+ } \
+}
+#define DUFFS_LOOP8(pixel_copy_increment, width) \
+ DUFFS_LOOP(pixel_copy_increment, width)
+#define DUFFS_LOOP4(pixel_copy_increment, width) \
+ DUFFS_LOOP(pixel_copy_increment, width)
+#define DUFFS_LOOP_124(pixel_copy_increment1, \
+ pixel_copy_increment2, \
+ pixel_copy_increment4, width) \
+ DUFFS_LOOP(pixel_copy_increment1, width)
+
+#endif /* USE_DUFFS_LOOP */
+
+/* Prevent Visual C++ 6.0 from printing out stupid warnings */
+#if defined(_MSC_VER) && (_MSC_VER >= 600)
+#pragma warning(disable: 4550)
+#endif
+
+#endif /* SDL_blit_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_0.c b/source/3rd-party/SDL2/src/video/SDL_blit_0.c
new file mode 100644
index 0000000..b5c8efb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_0.c
@@ -0,0 +1,483 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/* Functions to blit from bitmaps to other surfaces */
+
+static void
+BlitBto1(SDL_BlitInfo * info)
+{
+ int c;
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+ srcskip += width - (width + 7) / 8;
+
+ if (map) {
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (1) {
+ *dst = map[bit];
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (1) {
+ *dst = bit;
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void
+BlitBto2(SDL_BlitInfo * info)
+{
+ int c;
+ int width, height;
+ Uint8 *src;
+ Uint16 *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = (Uint16 *) info->dst;
+ dstskip = info->dst_skip / 2;
+ map = (Uint16 *) info->table;
+ srcskip += width - (width + 7) / 8;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (1) {
+ *dst = map[bit];
+ }
+ byte <<= 1;
+ dst++;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitBto3(SDL_BlitInfo * info)
+{
+ int c, o;
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+ srcskip += width - (width + 7) / 8;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (1) {
+ o = bit * 4;
+ dst[0] = map[o++];
+ dst[1] = map[o++];
+ dst[2] = map[o++];
+ }
+ byte <<= 1;
+ dst += 3;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitBto4(SDL_BlitInfo * info)
+{
+ int width, height;
+ Uint8 *src;
+ Uint32 *map, *dst;
+ int srcskip, dstskip;
+ int c;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = (Uint32 *) info->dst;
+ dstskip = info->dst_skip / 4;
+ map = (Uint32 *) info->table;
+ srcskip += width - (width + 7) / 8;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (1) {
+ *dst = map[bit];
+ }
+ byte <<= 1;
+ dst++;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitBto1Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ Uint8 *dst = info->dst;
+ int srcskip = info->src_skip;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width - (width + 7) / 8;
+
+ if (palmap) {
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (bit != ckey) {
+ *dst = palmap[bit];
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (bit != ckey) {
+ *dst = bit;
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void
+BlitBto2Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int srcskip = info->src_skip;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width - (width + 7) / 8;
+ dstskip /= 2;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (bit != ckey) {
+ *dstp = ((Uint16 *) palmap)[bit];
+ }
+ byte <<= 1;
+ dstp++;
+ }
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void
+BlitBto3Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ Uint8 *dst = info->dst;
+ int srcskip = info->src_skip;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width - (width + 7) / 8;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (bit != ckey) {
+ SDL_memcpy(dst, &palmap[bit * 4], 3);
+ }
+ byte <<= 1;
+ dst += 3;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitBto4Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int srcskip = info->src_skip;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width - (width + 7) / 8;
+ dstskip /= 4;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (bit != ckey) {
+ *dstp = ((Uint32 *) palmap)[bit];
+ }
+ byte <<= 1;
+ dstp++;
+ }
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void
+BlitBtoNAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ Uint8 *dst = info->dst;
+ int srcskip = info->src_skip;
+ int dstskip = info->dst_skip;
+ const SDL_Color *srcpal = info->src_fmt->palette->colors;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int dstbpp;
+ int c;
+ Uint32 pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB, dA;
+ const unsigned A = info->a;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+ srcskip += width - (width + 7) / 8;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (1) {
+ sR = srcpal[bit].r;
+ sG = srcpal[bit].g;
+ sB = srcpal[bit].b;
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ byte <<= 1;
+ dst += dstbpp;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitBtoNAlphaKey(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ Uint8 *dst = info->dst;
+ int srcskip = info->src_skip;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ const SDL_Color *srcpal = srcfmt->palette->colors;
+ int dstbpp;
+ int c;
+ Uint32 pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB, dA;
+ const unsigned A = info->a;
+ Uint32 ckey = info->colorkey;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+ srcskip += width - (width + 7) / 8;
+
+ while (height--) {
+ Uint8 byte = 0, bit;
+ for (c = 0; c < width; ++c) {
+ if ((c & 7) == 0) {
+ byte = *src++;
+ }
+ bit = (byte & 0x80) >> 7;
+ if (bit != ckey) {
+ sR = srcpal[bit].r;
+ sG = srcpal[bit].g;
+ sB = srcpal[bit].b;
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ byte <<= 1;
+ dst += dstbpp;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static const SDL_BlitFunc bitmap_blit[] = {
+ (SDL_BlitFunc) NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
+};
+
+static const SDL_BlitFunc colorkey_blit[] = {
+ (SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
+};
+
+SDL_BlitFunc
+SDL_CalculateBlit0(SDL_Surface * surface)
+{
+ int which;
+
+ if (surface->format->BitsPerPixel != 1) {
+ /* We don't support sub 8-bit packed pixel modes */
+ return (SDL_BlitFunc) NULL;
+ }
+ if (surface->map->dst->format->BitsPerPixel < 8) {
+ which = 0;
+ } else {
+ which = surface->map->dst->format->BytesPerPixel;
+ }
+ switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
+ case 0:
+ return bitmap_blit[which];
+
+ case SDL_COPY_COLORKEY:
+ return colorkey_blit[which];
+
+ case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
+ return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc) NULL;
+
+ case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
+ return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc) NULL;
+ }
+ return (SDL_BlitFunc) NULL;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_1.c b/source/3rd-party/SDL2/src/video/SDL_blit_1.c
new file mode 100644
index 0000000..56ccf15
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_1.c
@@ -0,0 +1,552 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+#include "SDL_sysvideo.h"
+#include "SDL_endian.h"
+
+/* Functions to blit from 8-bit surfaces to other surfaces */
+
+static void
+Blit1to1(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ *dst = map[*src];
+ }
+ dst++;
+ src++;
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width; c; --c) {
+ *dst = map[*src];
+ dst++;
+ src++;
+ }
+#endif
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* This is now endian dependent */
+#ifndef USE_DUFFS_LOOP
+# if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
+# define HI 1
+# define LO 0
+# else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
+# define HI 0
+# define LO 1
+# endif
+#endif
+static void
+Blit1to2(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src, *dst;
+ Uint16 *map;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = (Uint16 *) info->table;
+
+#ifdef USE_DUFFS_LOOP
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ /* Memory align at 4-byte boundary, if necessary */
+ if ((long) dst & 0x03) {
+ /* Don't do anything if width is 0 */
+ if (width == 0) {
+ return;
+ }
+ --width;
+
+ while (height--) {
+ /* Perform copy alignment */
+ *(Uint16 *) dst = map[*src++];
+ dst += 2;
+
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
+ src += 2;
+ dst += 4;
+ *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
+ src += 2;
+ dst += 4;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ *(Uint16 *) dst = map[*src++];
+ dst += 2;
+ case 2:
+ *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
+ src += 2;
+ dst += 4;
+ break;
+ case 1:
+ *(Uint16 *) dst = map[*src++];
+ dst += 2;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
+ src += 2;
+ dst += 4;
+ *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
+ src += 2;
+ dst += 4;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ *(Uint16 *) dst = map[*src++];
+ dst += 2;
+ case 2:
+ *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
+ src += 2;
+ dst += 4;
+ break;
+ case 1:
+ *(Uint16 *) dst = map[*src++];
+ dst += 2;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+
+static void
+Blit1to3(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int o;
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ o = *src * 4;
+ dst[0] = map[o++];
+ dst[1] = map[o++];
+ dst[2] = map[o++];
+ }
+ src++;
+ dst += 3;
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width; c; --c) {
+ o = *src * 4;
+ dst[0] = map[o++];
+ dst[1] = map[o++];
+ dst[2] = map[o++];
+ src++;
+ dst += 3;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+Blit1to4(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src;
+ Uint32 *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = (Uint32 *) info->dst;
+ dstskip = info->dst_skip / 4;
+ map = (Uint32 *) info->table;
+
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ *dst++ = map[*src++];
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width / 4; c; --c) {
+ *dst++ = map[*src++];
+ *dst++ = map[*src++];
+ *dst++ = map[*src++];
+ *dst++ = map[*src++];
+ }
+ switch (width & 3) {
+ case 3:
+ *dst++ = map[*src++];
+ case 2:
+ *dst++ = map[*src++];
+ case 1:
+ *dst++ = map[*src++];
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+Blit1to1Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint8 *palmap = info->table;
+ Uint32 ckey = info->colorkey;
+
+ if (palmap) {
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dst = palmap[*src];
+ }
+ dst++;
+ src++;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dst = *src;
+ }
+ dst++;
+ src++;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void
+Blit1to2Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip;
+ Uint16 *palmap = (Uint16 *) info->table;
+ Uint32 ckey = info->colorkey;
+
+ /* Set up some basic variables */
+ dstskip /= 2;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dstp=palmap[*src];
+ }
+ src++;
+ dstp++;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void
+Blit1to3Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint8 *palmap = info->table;
+ Uint32 ckey = info->colorkey;
+ int o;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ o = *src * 4;
+ dst[0] = palmap[o++];
+ dst[1] = palmap[o++];
+ dst[2] = palmap[o++];
+ }
+ src++;
+ dst += 3;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+Blit1to4Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip;
+ Uint32 *palmap = (Uint32 *) info->table;
+ Uint32 ckey = info->colorkey;
+
+ /* Set up some basic variables */
+ dstskip /= 4;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dstp = palmap[*src];
+ }
+ src++;
+ dstp++;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void
+Blit1toNAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ const SDL_Color *srcpal = info->src_fmt->palette->colors;
+ int dstbpp;
+ Uint32 pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB, dA;
+ const unsigned A = info->a;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4(
+ {
+ sR = srcpal[*src].r;
+ sG = srcpal[*src].g;
+ sB = srcpal[*src].b;
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ src++;
+ dst += dstbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+Blit1toNAlphaKey(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ const SDL_Color *srcpal = info->src_fmt->palette->colors;
+ Uint32 ckey = info->colorkey;
+ int dstbpp;
+ Uint32 pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB, dA;
+ const unsigned A = info->a;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ sR = srcpal[*src].r;
+ sG = srcpal[*src].g;
+ sB = srcpal[*src].b;
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ src++;
+ dst += dstbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static const SDL_BlitFunc one_blit[] = {
+ (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
+};
+
+static const SDL_BlitFunc one_blitkey[] = {
+ (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
+};
+
+SDL_BlitFunc
+SDL_CalculateBlit1(SDL_Surface * surface)
+{
+ int which;
+ SDL_PixelFormat *dstfmt;
+
+ dstfmt = surface->map->dst->format;
+ if (dstfmt->BitsPerPixel < 8) {
+ which = 0;
+ } else {
+ which = dstfmt->BytesPerPixel;
+ }
+ switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
+ case 0:
+ return one_blit[which];
+
+ case SDL_COPY_COLORKEY:
+ return one_blitkey[which];
+
+ case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
+ /* Supporting 8bpp->8bpp alpha is doable but requires lots of
+ tables which consume space and takes time to precompute,
+ so is better left to the user */
+ return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL;
+
+ case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
+ return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
+ }
+ return (SDL_BlitFunc) NULL;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_A.c b/source/3rd-party/SDL2/src/video/SDL_blit_A.c
new file mode 100644
index 0000000..3507932
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_A.c
@@ -0,0 +1,1388 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/* Functions to perform alpha blended blitting */
+
+/* N->1 blending with per-surface alpha */
+static void
+BlitNto1SurfaceAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint8 *palmap = info->table;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ Uint32 Pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB;
+ const unsigned A = info->a;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ dR = dstfmt->palette->colors[*dst].r;
+ dG = dstfmt->palette->colors[*dst].g;
+ dB = dstfmt->palette->colors[*dst].b;
+ ALPHA_BLEND_RGB(sR, sG, sB, A, dR, dG, dB);
+ dR &= 0xff;
+ dG &= 0xff;
+ dB &= 0xff;
+ /* Pack RGB into 8bit pixel */
+ if ( palmap == NULL ) {
+ *dst =((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0));
+ } else {
+ *dst = palmap[((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0))];
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* N->1 blending with pixel alpha */
+static void
+BlitNto1PixelAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint8 *palmap = info->table;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+ unsigned dR, dG, dB;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4(
+ {
+ DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA);
+ dR = dstfmt->palette->colors[*dst].r;
+ dG = dstfmt->palette->colors[*dst].g;
+ dB = dstfmt->palette->colors[*dst].b;
+ ALPHA_BLEND_RGB(sR, sG, sB, sA, dR, dG, dB);
+ dR &= 0xff;
+ dG &= 0xff;
+ dB &= 0xff;
+ /* Pack RGB into 8bit pixel */
+ if ( palmap == NULL ) {
+ *dst =((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0));
+ } else {
+ *dst = palmap[((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0))];
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* colorkeyed N->1 blending with per-surface alpha */
+static void
+BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint8 *palmap = info->table;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ Uint32 ckey = info->colorkey;
+ Uint32 Pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB;
+ const unsigned A = info->a;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ if ( Pixel != ckey ) {
+ dR = dstfmt->palette->colors[*dst].r;
+ dG = dstfmt->palette->colors[*dst].g;
+ dB = dstfmt->palette->colors[*dst].b;
+ ALPHA_BLEND_RGB(sR, sG, sB, A, dR, dG, dB);
+ dR &= 0xff;
+ dG &= 0xff;
+ dB &= 0xff;
+ /* Pack RGB into 8bit pixel */
+ if ( palmap == NULL ) {
+ *dst =((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0));
+ } else {
+ *dst = palmap[((dR>>5)<<(3+2))|((dG>>5)<<(2))|((dB>>6)<<(0))];
+ }
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+#ifdef __MMX__
+
+/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
+static void
+BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+ Uint32 dalpha = info->dst_fmt->Amask;
+
+ __m64 src1, src2, dst1, dst2, lmask, hmask, dsta;
+
+ hmask = _mm_set_pi32(0x00fefefe, 0x00fefefe); /* alpha128 mask -> hmask */
+ lmask = _mm_set_pi32(0x00010101, 0x00010101); /* !alpha128 mask -> lmask */
+ dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */
+
+ while (height--) {
+ int n = width;
+ if (n & 1) {
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
+ + (s & d & 0x00010101)) | dalpha;
+ n--;
+ }
+
+ for (n >>= 1; n > 0; --n) {
+ dst1 = *(__m64 *) dstp; /* 2 x dst -> dst1(ARGBARGB) */
+ dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */
+
+ src1 = *(__m64 *) srcp; /* 2 x src -> src1(ARGBARGB) */
+ src2 = src1; /* 2 x src -> src2(ARGBARGB) */
+
+ dst2 = _mm_and_si64(dst2, hmask); /* dst & mask -> dst2 */
+ src2 = _mm_and_si64(src2, hmask); /* src & mask -> src2 */
+ src2 = _mm_add_pi32(src2, dst2); /* dst2 + src2 -> src2 */
+ src2 = _mm_srli_pi32(src2, 1); /* src2 >> 1 -> src2 */
+
+ dst1 = _mm_and_si64(dst1, src1); /* src & dst -> dst1 */
+ dst1 = _mm_and_si64(dst1, lmask); /* dst1 & !mask -> dst1 */
+ dst1 = _mm_add_pi32(dst1, src2); /* src2 + dst1 -> dst1 */
+ dst1 = _mm_or_si64(dst1, dsta); /* dsta(full alpha) | dst1 -> dst1 */
+
+ *(__m64 *) dstp = dst1; /* dst1 -> 2 x dst pixels */
+ dstp += 2;
+ srcp += 2;
+ }
+
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+}
+
+/* fast RGB888->(A)RGB888 blending with surface alpha */
+static void
+BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo * info)
+{
+ SDL_PixelFormat *df = info->dst_fmt;
+ Uint32 chanmask;
+ unsigned alpha = info->a;
+
+ if (alpha == 128 && (df->Rmask | df->Gmask | df->Bmask) == 0x00FFFFFF) {
+ /* only call a128 version when R,G,B occupy lower bits */
+ BlitRGBtoRGBSurfaceAlpha128MMX(info);
+ } else {
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+ Uint32 dalpha = df->Amask;
+ Uint32 amult;
+
+ __m64 src1, src2, dst1, dst2, mm_alpha, mm_zero, dsta;
+
+ mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */
+ /* form the alpha mult */
+ amult = alpha | (alpha << 8);
+ amult = amult | (amult << 16);
+ chanmask =
+ (0xff << df->Rshift) | (0xff << df->
+ Gshift) | (0xff << df->Bshift);
+ mm_alpha = _mm_set_pi32(0, amult & chanmask); /* 0000AAAA -> mm_alpha, minus 1 chan */
+ mm_alpha = _mm_unpacklo_pi8(mm_alpha, mm_zero); /* 0A0A0A0A -> mm_alpha, minus 1 chan */
+ /* at this point mm_alpha can be 000A0A0A or 0A0A0A00 or another combo */
+ dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */
+
+ while (height--) {
+ int n = width;
+ if (n & 1) {
+ /* One Pixel Blend */
+ src2 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src2 (0000ARGB) */
+ src2 = _mm_unpacklo_pi8(src2, mm_zero); /* 0A0R0G0B -> src2 */
+
+ dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */
+
+ src2 = _mm_sub_pi16(src2, dst1); /* src2 - dst2 -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */
+ dst1 = _mm_add_pi8(src2, dst1); /* src2 + dst1 -> dst1 */
+
+ dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */
+ dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */
+ *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */
+
+ ++srcp;
+ ++dstp;
+
+ n--;
+ }
+
+ for (n >>= 1; n > 0; --n) {
+ /* Two Pixels Blend */
+ src1 = *(__m64 *) srcp; /* 2 x src -> src1(ARGBARGB) */
+ src2 = src1; /* 2 x src -> src2(ARGBARGB) */
+ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* low - 0A0R0G0B -> src1 */
+ src2 = _mm_unpackhi_pi8(src2, mm_zero); /* high - 0A0R0G0B -> src2 */
+
+ dst1 = *(__m64 *) dstp; /* 2 x dst -> dst1(ARGBARGB) */
+ dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* low - 0A0R0G0B -> dst1 */
+ dst2 = _mm_unpackhi_pi8(dst2, mm_zero); /* high - 0A0R0G0B -> dst2 */
+
+ src1 = _mm_sub_pi16(src1, dst1); /* src1 - dst1 -> src1 */
+ src1 = _mm_mullo_pi16(src1, mm_alpha); /* src1 * alpha -> src1 */
+ src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1 */
+ dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst1) -> dst1 */
+
+ src2 = _mm_sub_pi16(src2, dst2); /* src2 - dst2 -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */
+ dst2 = _mm_add_pi8(src2, dst2); /* src2 + dst2(dst2) -> dst2 */
+
+ dst1 = _mm_packs_pu16(dst1, dst2); /* 0A0R0G0B(res1), 0A0R0G0B(res2) -> dst1(ARGBARGB) */
+ dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */
+
+ *(__m64 *) dstp = dst1; /* dst1 -> 2 x pixel */
+
+ srcp += 2;
+ dstp += 2;
+ }
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+ }
+}
+
+/* fast ARGB888->(A)RGB888 blending with pixel alpha */
+static void
+BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+ SDL_PixelFormat *sf = info->src_fmt;
+ Uint32 amask = sf->Amask;
+ Uint32 ashift = sf->Ashift;
+ Uint64 multmask, multmask2;
+
+ __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2;
+
+ mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */
+ multmask = 0x00FF;
+ multmask <<= (ashift * 2);
+ multmask2 = 0x00FF00FF00FF00FFULL;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 alpha = *srcp & amask;
+ if (alpha == 0) {
+ /* do nothing */
+ } else if (alpha == amask) {
+ *dstp = *srcp;
+ } else {
+ src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB) */
+ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */
+
+ dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */
+
+ mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */
+ mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha2 = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha2 */
+ mm_alpha = _mm_or_si64(mm_alpha2, *(__m64 *) & multmask); /* 0F0A0A0A -> mm_alpha */
+ mm_alpha2 = _mm_xor_si64(mm_alpha2, *(__m64 *) & multmask2); /* 255 - mm_alpha -> mm_alpha */
+
+ /* blend */
+ src1 = _mm_mullo_pi16(src1, mm_alpha);
+ src1 = _mm_srli_pi16(src1, 8);
+ dst1 = _mm_mullo_pi16(dst1, mm_alpha2);
+ dst1 = _mm_srli_pi16(dst1, 8);
+ dst1 = _mm_add_pi16(src1, dst1);
+ dst1 = _mm_packs_pu16(dst1, mm_zero);
+
+ *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+}
+
+#endif /* __MMX__ */
+
+/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
+static void
+BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
+ + (s & d & 0x00010101)) | 0xff000000;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+/* fast RGB888->(A)RGB888 blending with surface alpha */
+static void
+BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info)
+{
+ unsigned alpha = info->a;
+ if (alpha == 128) {
+ BlitRGBtoRGBSurfaceAlpha128(info);
+ } else {
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+ Uint32 s;
+ Uint32 d;
+ Uint32 s1;
+ Uint32 d1;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ s = *srcp;
+ d = *dstp;
+ s1 = s & 0xff00ff;
+ d1 = d & 0xff00ff;
+ d1 = (d1 + ((s1 - d1) * alpha >> 8))
+ & 0xff00ff;
+ s &= 0xff00;
+ d &= 0xff00;
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00;
+ *dstp = d1 | d | 0xff000000;
+ ++srcp;
+ ++dstp;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* fast ARGB888->(A)RGB888 blending with pixel alpha */
+static void
+BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 dalpha;
+ Uint32 d;
+ Uint32 s1;
+ Uint32 d1;
+ Uint32 s = *srcp;
+ Uint32 alpha = s >> 24;
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if (alpha) {
+ if (alpha == SDL_ALPHA_OPAQUE) {
+ *dstp = *srcp;
+ } else {
+ /*
+ * take out the middle component (green), and process
+ * the other two in parallel. One multiply less.
+ */
+ d = *dstp;
+ dalpha = d >> 24;
+ s1 = s & 0xff00ff;
+ d1 = d & 0xff00ff;
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
+ s &= 0xff00;
+ d &= 0xff00;
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00;
+ dalpha = alpha + (dalpha * (alpha ^ 0xFF) >> 8);
+ *dstp = d1 | d | (dalpha << 24);
+ }
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+#ifdef __3dNOW__
+/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */
+static void
+BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip >> 2;
+ SDL_PixelFormat *sf = info->src_fmt;
+ Uint32 amask = sf->Amask;
+ Uint32 ashift = sf->Ashift;
+ Uint64 multmask, multmask2;
+
+ __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2;
+
+ mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */
+ multmask = 0x00FF;
+ multmask <<= (ashift * 2);
+ multmask2 = 0x00FF00FF00FF00FFULL;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 alpha;
+
+ _m_prefetch(srcp + 16);
+ _m_prefetch(dstp + 16);
+
+ alpha = *srcp & amask;
+ if (alpha == 0) {
+ /* do nothing */
+ } else if (alpha == amask) {
+ *dstp = *srcp;
+ } else {
+ src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB) */
+ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */
+
+ dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */
+
+ mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */
+ mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha2 = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha2 */
+ mm_alpha = _mm_or_si64(mm_alpha2, *(__m64 *) & multmask); /* 0F0A0A0A -> mm_alpha */
+ mm_alpha2 = _mm_xor_si64(mm_alpha2, *(__m64 *) & multmask2); /* 255 - mm_alpha -> mm_alpha */
+
+
+ /* blend */
+ src1 = _mm_mullo_pi16(src1, mm_alpha);
+ src1 = _mm_srli_pi16(src1, 8);
+ dst1 = _mm_mullo_pi16(dst1, mm_alpha2);
+ dst1 = _mm_srli_pi16(dst1, 8);
+ dst1 = _mm_add_pi16(src1, dst1);
+ dst1 = _mm_packs_pu16(dst1, mm_zero);
+
+ *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+}
+
+#endif /* __3dNOW__ */
+
+/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */
+
+/* blend a single 16 bit pixel at 50% */
+#define BLEND16_50(d, s, mask) \
+ ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
+
+/* blend two 16 bit pixels at 50% */
+#define BLEND2x16_50(d, s, mask) \
+ (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \
+ + (s & d & (~(mask | mask << 16))))
+
+static void
+Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint16 *srcp = (Uint16 *) info->src;
+ int srcskip = info->src_skip >> 1;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+
+ while (height--) {
+ if (((uintptr_t) srcp ^ (uintptr_t) dstp) & 2) {
+ /*
+ * Source and destination not aligned, pipeline it.
+ * This is mostly a win for big blits but no loss for
+ * small ones
+ */
+ Uint32 prev_sw;
+ int w = width;
+
+ /* handle odd destination */
+ if ((uintptr_t) dstp & 2) {
+ Uint16 d = *dstp, s = *srcp;
+ *dstp = BLEND16_50(d, s, mask);
+ dstp++;
+ srcp++;
+ w--;
+ }
+ srcp++; /* srcp is now 32-bit aligned */
+
+ /* bootstrap pipeline with first halfword */
+ prev_sw = ((Uint32 *) srcp)[-1];
+
+ while (w > 1) {
+ Uint32 sw, dw, s;
+ sw = *(Uint32 *) srcp;
+ dw = *(Uint32 *) dstp;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ s = (prev_sw << 16) + (sw >> 16);
+#else
+ s = (prev_sw >> 16) + (sw << 16);
+#endif
+ prev_sw = sw;
+ *(Uint32 *) dstp = BLEND2x16_50(dw, s, mask);
+ dstp += 2;
+ srcp += 2;
+ w -= 2;
+ }
+
+ /* final pixel if any */
+ if (w) {
+ Uint16 d = *dstp, s;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ s = (Uint16) prev_sw;
+#else
+ s = (Uint16) (prev_sw >> 16);
+#endif
+ *dstp = BLEND16_50(d, s, mask);
+ srcp++;
+ dstp++;
+ }
+ srcp += srcskip - 1;
+ dstp += dstskip;
+ } else {
+ /* source and destination are aligned */
+ int w = width;
+
+ /* first odd pixel? */
+ if ((uintptr_t) srcp & 2) {
+ Uint16 d = *dstp, s = *srcp;
+ *dstp = BLEND16_50(d, s, mask);
+ srcp++;
+ dstp++;
+ w--;
+ }
+ /* srcp and dstp are now 32-bit aligned */
+
+ while (w > 1) {
+ Uint32 sw = *(Uint32 *) srcp;
+ Uint32 dw = *(Uint32 *) dstp;
+ *(Uint32 *) dstp = BLEND2x16_50(dw, sw, mask);
+ srcp += 2;
+ dstp += 2;
+ w -= 2;
+ }
+
+ /* last odd pixel? */
+ if (w) {
+ Uint16 d = *dstp, s = *srcp;
+ *dstp = BLEND16_50(d, s, mask);
+ srcp++;
+ dstp++;
+ }
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+#ifdef __MMX__
+
+/* fast RGB565->RGB565 blending with surface alpha */
+static void
+Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info)
+{
+ unsigned alpha = info->a;
+ if (alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xf7de);
+ } else {
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint16 *srcp = (Uint16 *) info->src;
+ int srcskip = info->src_skip >> 1;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+ Uint32 s, d;
+
+ __m64 src1, dst1, src2, dst2, gmask, bmask, mm_res, mm_alpha;
+
+ alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */
+ mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */
+ /* position alpha to allow for mullo and mulhi on diff channels
+ to reduce the number of operations */
+ mm_alpha = _mm_slli_si64(mm_alpha, 3);
+
+ /* Setup the 565 color channel masks */
+ gmask = _mm_set_pi32(0x07E007E0, 0x07E007E0); /* MASKGREEN -> gmask */
+ bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP_124(
+ {
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */
+ dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */
+
+ /* red */
+ src2 = src1;
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 [000r 000r 000r 000r] */
+
+ dst2 = dst1;
+ dst2 = _mm_srli_pi16(dst2, 11); /* dst2 >> 11 -> dst2 [000r 000r 000r 000r] */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_slli_pi16(dst2, 11); /* dst2 << 11 -> dst2 */
+
+ mm_res = dst2; /* RED -> mm_res */
+
+ /* green -- process the bits in place */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */
+
+ /* blue */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */
+
+ *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */
+
+ srcp += 4;
+ dstp += 4;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+ }
+}
+
+/* fast RGB555->RGB555 blending with surface alpha */
+static void
+Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info)
+{
+ unsigned alpha = info->a;
+ if (alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xfbde);
+ } else {
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint16 *srcp = (Uint16 *) info->src;
+ int srcskip = info->src_skip >> 1;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+ Uint32 s, d;
+
+ __m64 src1, dst1, src2, dst2, rmask, gmask, bmask, mm_res, mm_alpha;
+
+ alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */
+ mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */
+ /* position alpha to allow for mullo and mulhi on diff channels
+ to reduce the number of operations */
+ mm_alpha = _mm_slli_si64(mm_alpha, 3);
+
+ /* Setup the 555 color channel masks */
+ rmask = _mm_set_pi32(0x7C007C00, 0x7C007C00); /* MASKRED -> rmask */
+ gmask = _mm_set_pi32(0x03E003E0, 0x03E003E0); /* MASKGREEN -> gmask */
+ bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP_124(
+ {
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */
+ dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */
+
+ /* red -- process the bits in place */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, rmask); /* src & MASKRED -> src2 */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, rmask); /* dst & MASKRED -> dst2 */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_and_si64(dst2, rmask); /* dst2 & MASKRED -> dst2 */
+
+ mm_res = dst2; /* RED -> mm_res */
+
+ /* green -- process the bits in place */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */
+
+ /* blue */
+ src2 = src1; /* src -> src2 */
+ src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */
+
+ dst2 = dst1; /* dst -> dst2 */
+ dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */
+
+ *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */
+
+ srcp += 4;
+ dstp += 4;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+ }
+}
+
+#endif /* __MMX__ */
+
+/* fast RGB565->RGB565 blending with surface alpha */
+static void
+Blit565to565SurfaceAlpha(SDL_BlitInfo * info)
+{
+ unsigned alpha = info->a;
+ if (alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xf7de);
+ } else {
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint16 *srcp = (Uint16 *) info->src;
+ int srcskip = info->src_skip >> 1;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* fast RGB555->RGB555 blending with surface alpha */
+static void
+Blit555to555SurfaceAlpha(SDL_BlitInfo * info)
+{
+ unsigned alpha = info->a; /* downscale alpha to 5 bits */
+ if (alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xfbde);
+ } else {
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint16 *srcp = (Uint16 *) info->src;
+ int srcskip = info->src_skip >> 1;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* fast ARGB8888->RGB565 blending with pixel alpha */
+static void
+BlitARGBto565PixelAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ Uint32 s = *srcp;
+ unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha) {
+ if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
+ *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
+ } else {
+ Uint32 d = *dstp;
+ /*
+ * convert source and destination to G0RAB65565
+ * and blend all components at the same time
+ */
+ s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
+ + (s >> 3 & 0x1f);
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp = (Uint16)(d | d >> 16);
+ }
+ }
+ srcp++;
+ dstp++;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+/* fast ARGB8888->RGB555 blending with pixel alpha */
+static void
+BlitARGBto555PixelAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip >> 2;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip >> 1;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4({
+ unsigned alpha;
+ Uint32 s = *srcp;
+ alpha = s >> 27; /* downscale alpha to 5 bits */
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha) {
+ if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
+ *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f));
+ } else {
+ Uint32 d = *dstp;
+ /*
+ * convert source and destination to G0RAB65565
+ * and blend all components at the same time
+ */
+ s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00)
+ + (s >> 3 & 0x1f);
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp = (Uint16)(d | d >> 16);
+ }
+ }
+ srcp++;
+ dstp++;
+ }, width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+/* General (slow) N->N blending with per-surface alpha */
+static void
+BlitNtoNSurfaceAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
+ Uint32 Pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB, dA;
+ const unsigned sA = info->a;
+
+ if (sA) {
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ src += srcbpp;
+ dst += dstbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+/* General (slow) colorkeyed N->N blending with per-surface alpha */
+static void
+BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ Uint32 ckey = info->colorkey;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
+ Uint32 Pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB, dA;
+ const unsigned sA = info->a;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4(
+ {
+ RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
+ if(sA && Pixel != ckey) {
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ src += srcbpp;
+ dst += dstbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* General (slow) N->N blending with pixel alpha */
+static void
+BlitNtoNPixelAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int srcbpp;
+ int dstbpp;
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+ unsigned dR, dG, dB, dA;
+
+ /* Set up some basic variables */
+ srcbpp = srcfmt->BytesPerPixel;
+ dstbpp = dstfmt->BytesPerPixel;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP4(
+ {
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
+ if(sA) {
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA);
+ ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ src += srcbpp;
+ dst += dstbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+
+SDL_BlitFunc
+SDL_CalculateBlitA(SDL_Surface * surface)
+{
+ SDL_PixelFormat *sf = surface->format;
+ SDL_PixelFormat *df = surface->map->dst->format;
+
+ switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
+ case SDL_COPY_BLEND:
+ /* Per-pixel alpha blits */
+ switch (df->BytesPerPixel) {
+ case 1:
+ return BlitNto1PixelAlpha;
+
+ case 2:
+ if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000
+ && sf->Gmask == 0xff00
+ && ((sf->Rmask == 0xff && df->Rmask == 0x1f)
+ || (sf->Bmask == 0xff && df->Bmask == 0x1f))) {
+ if (df->Gmask == 0x7e0)
+ return BlitARGBto565PixelAlpha;
+ else if (df->Gmask == 0x3e0)
+ return BlitARGBto555PixelAlpha;
+ }
+ return BlitNtoNPixelAlpha;
+
+ case 4:
+ if (sf->Rmask == df->Rmask
+ && sf->Gmask == df->Gmask
+ && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) {
+#if defined(__MMX__) || defined(__3dNOW__)
+ if (sf->Rshift % 8 == 0
+ && sf->Gshift % 8 == 0
+ && sf->Bshift % 8 == 0
+ && sf->Ashift % 8 == 0 && sf->Aloss == 0) {
+#ifdef __3dNOW__
+ if (SDL_Has3DNow())
+ return BlitRGBtoRGBPixelAlphaMMX3DNOW;
+#endif
+#ifdef __MMX__
+ if (SDL_HasMMX())
+ return BlitRGBtoRGBPixelAlphaMMX;
+#endif
+ }
+#endif /* __MMX__ || __3dNOW__ */
+ if (sf->Amask == 0xff000000) {
+ return BlitRGBtoRGBPixelAlpha;
+ }
+ }
+ return BlitNtoNPixelAlpha;
+
+ case 3:
+ default:
+ break;
+ }
+ return BlitNtoNPixelAlpha;
+
+ case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
+ if (sf->Amask == 0) {
+ /* Per-surface alpha blits */
+ switch (df->BytesPerPixel) {
+ case 1:
+ return BlitNto1SurfaceAlpha;
+
+ case 2:
+ if (surface->map->identity) {
+ if (df->Gmask == 0x7e0) {
+#ifdef __MMX__
+ if (SDL_HasMMX())
+ return Blit565to565SurfaceAlphaMMX;
+ else
+#endif
+ return Blit565to565SurfaceAlpha;
+ } else if (df->Gmask == 0x3e0) {
+#ifdef __MMX__
+ if (SDL_HasMMX())
+ return Blit555to555SurfaceAlphaMMX;
+ else
+#endif
+ return Blit555to555SurfaceAlpha;
+ }
+ }
+ return BlitNtoNSurfaceAlpha;
+
+ case 4:
+ if (sf->Rmask == df->Rmask
+ && sf->Gmask == df->Gmask
+ && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) {
+#ifdef __MMX__
+ if (sf->Rshift % 8 == 0
+ && sf->Gshift % 8 == 0
+ && sf->Bshift % 8 == 0 && SDL_HasMMX())
+ return BlitRGBtoRGBSurfaceAlphaMMX;
+#endif
+ if ((sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff) {
+ return BlitRGBtoRGBSurfaceAlpha;
+ }
+ }
+ return BlitNtoNSurfaceAlpha;
+
+ case 3:
+ default:
+ return BlitNtoNSurfaceAlpha;
+ }
+ }
+ break;
+
+ case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
+ if (sf->Amask == 0) {
+ if (df->BytesPerPixel == 1) {
+ return BlitNto1SurfaceAlphaKey;
+ } else {
+ return BlitNtoNSurfaceAlphaKey;
+ }
+ }
+ break;
+ }
+
+ return NULL;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_N.c b/source/3rd-party/SDL2/src/video/SDL_blit_N.c
new file mode 100644
index 0000000..d6ec417
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_N.c
@@ -0,0 +1,2700 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_endian.h"
+#include "SDL_cpuinfo.h"
+#include "SDL_blit.h"
+
+#include "SDL_assert.h"
+
+/* Functions to blit from N-bit surfaces to other surfaces */
+
+#if SDL_ALTIVEC_BLITTERS
+#ifdef HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+#ifdef __MACOSX__
+#include <sys/sysctl.h>
+static size_t
+GetL3CacheSize(void)
+{
+ const char key[] = "hw.l3cachesize";
+ u_int64_t result = 0;
+ size_t typeSize = sizeof(result);
+
+
+ int err = sysctlbyname(key, &result, &typeSize, NULL, 0);
+ if (0 != err)
+ return 0;
+
+ return result;
+}
+#else
+static size_t
+GetL3CacheSize(void)
+{
+ /* XXX: Just guess G4 */
+ return 2097152;
+}
+#endif /* __MACOSX__ */
+
+#if (defined(__MACOSX__) && (__GNUC__ < 4))
+#define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
+ (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
+#define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
+ (vector unsigned short) ( a,b,c,d,e,f,g,h )
+#else
+#define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
+ (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
+#define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
+ (vector unsigned short) { a,b,c,d,e,f,g,h }
+#endif
+
+#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
+#define VSWIZZLE32(a,b,c,d) (vector unsigned char) \
+ ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \
+ 0x04+a, 0x04+b, 0x04+c, 0x04+d, \
+ 0x08+a, 0x08+b, 0x08+c, 0x08+d, \
+ 0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d )
+
+#define MAKE8888(dstfmt, r, g, b, a) \
+ ( ((r<<dstfmt->Rshift)&dstfmt->Rmask) | \
+ ((g<<dstfmt->Gshift)&dstfmt->Gmask) | \
+ ((b<<dstfmt->Bshift)&dstfmt->Bmask) | \
+ ((a<<dstfmt->Ashift)&dstfmt->Amask) )
+
+/*
+ * Data Stream Touch...Altivec cache prefetching.
+ *
+ * Don't use this on a G5...however, the speed boost is very significant
+ * on a G4.
+ */
+#define DST_CHAN_SRC 1
+#define DST_CHAN_DEST 2
+
+/* macro to set DST control word value... */
+#define DST_CTRL(size, count, stride) \
+ (((size) << 24) | ((count) << 16) | (stride))
+
+#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
+ ? vec_lvsl(0, src) \
+ : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
+
+/* Calculate the permute vector used for 32->32 swizzling */
+static vector unsigned char
+calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt)
+{
+ /*
+ * We have to assume that the bits that aren't used by other
+ * colors is alpha, and it's one complete byte, since some formats
+ * leave alpha with a zero mask, but we should still swizzle the bits.
+ */
+ /* ARGB */
+ const static const struct SDL_PixelFormat default_pixel_format = {
+ 0, NULL, 0, 0,
+ {0, 0},
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
+ 0, 0, 0, 0,
+ 16, 8, 0, 24,
+ 0, NULL
+ };
+ const vector unsigned char plus = VECUINT8_LITERAL(0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x04, 0x04, 0x04,
+ 0x08, 0x08, 0x08, 0x08,
+ 0x0C, 0x0C, 0x0C,
+ 0x0C);
+ vector unsigned char vswiz;
+ vector unsigned int srcvec;
+ Uint32 rmask, gmask, bmask, amask;
+
+ if (!srcfmt) {
+ srcfmt = &default_pixel_format;
+ }
+ if (!dstfmt) {
+ dstfmt = &default_pixel_format;
+ }
+
+#define RESHIFT(X) (3 - ((X) >> 3))
+ rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
+ gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
+ bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
+
+ /* Use zero for alpha if either surface doesn't have alpha */
+ if (dstfmt->Amask) {
+ amask =
+ ((srcfmt->Amask) ? RESHIFT(srcfmt->
+ Ashift) : 0x10) << (dstfmt->Ashift);
+ } else {
+ amask =
+ 0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^
+ 0xFFFFFFFF);
+ }
+#undef RESHIFT
+
+ ((unsigned int *) (char *) &srcvec)[0] = (rmask | gmask | bmask | amask);
+ vswiz = vec_add(plus, (vector unsigned char) vec_splat(srcvec, 0));
+ return (vswiz);
+}
+
+static void Blit_RGB888_RGB565(SDL_BlitInfo * info);
+static void
+Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info)
+{
+ int height = info->dst_h;
+ Uint8 *src = (Uint8 *) info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = (Uint8 *) info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ vector unsigned char valpha = vec_splat_u8(0);
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
+ vector unsigned char vgmerge = VECUINT8_LITERAL(0x00, 0x02, 0x00, 0x06,
+ 0x00, 0x0a, 0x00, 0x0e,
+ 0x00, 0x12, 0x00, 0x16,
+ 0x00, 0x1a, 0x00, 0x1e);
+ vector unsigned short v1 = vec_splat_u16(1);
+ vector unsigned short v3 = vec_splat_u16(3);
+ vector unsigned short v3f =
+ VECUINT16_LITERAL(0x003f, 0x003f, 0x003f, 0x003f,
+ 0x003f, 0x003f, 0x003f, 0x003f);
+ vector unsigned short vfc =
+ VECUINT16_LITERAL(0x00fc, 0x00fc, 0x00fc, 0x00fc,
+ 0x00fc, 0x00fc, 0x00fc, 0x00fc);
+ vector unsigned short vf800 = (vector unsigned short) vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned char voverflow;
+ vector unsigned char vsrc;
+
+ int width = info->dst_w;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, sA; \
+ DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \
+ sR, sG, sB, sA); \
+ *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \
+ ((sG << 3) & 0x000007E0) | \
+ ((sB >> 3) & 0x0000001F)); \
+ dst += 2; \
+ src += 4; \
+ widthvar--; \
+ }
+
+ ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 8); /* trailing unaligned stores */
+ width -= extrawidth;
+ vsrc = vec_ld(0, src);
+ valigner = VEC_ALIGNER(src);
+
+ while (width) {
+ vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
+ vector unsigned int vsrc1, vsrc2;
+ vector unsigned char vdst;
+
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+ vsrc1 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
+ src += 16;
+ vsrc = voverflow;
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+ vsrc2 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
+ /* 1555 */
+ vpixel = (vector unsigned short) vec_packpx(vsrc1, vsrc2);
+ vgpixel = (vector unsigned short) vec_perm(vsrc1, vsrc2, vgmerge);
+ vgpixel = vec_and(vgpixel, vfc);
+ vgpixel = vec_sl(vgpixel, v3);
+ vrpixel = vec_sl(vpixel, v1);
+ vrpixel = vec_and(vrpixel, vf800);
+ vbpixel = vec_and(vpixel, v3f);
+ vdst =
+ vec_or((vector unsigned char) vrpixel,
+ (vector unsigned char) vgpixel);
+ /* 565 */
+ vdst = vec_or(vdst, (vector unsigned char) vbpixel);
+ vec_st(vdst, 0, dst);
+
+ width -= 8;
+ src += 16;
+ dst += 16;
+ vsrc = voverflow;
+ }
+
+ SDL_assert(width == 0);
+
+ /* do scalar until we can align... */
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+
+ src += srcskip; /* move to next row, accounting for pitch. */
+ dst += dstskip;
+ }
+
+
+}
+
+static void
+Blit_RGB565_32Altivec(SDL_BlitInfo * info)
+{
+ int height = info->dst_h;
+ Uint8 *src = (Uint8 *) info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = (Uint8 *) info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ unsigned alpha;
+ vector unsigned char valpha;
+ vector unsigned char vpermute;
+ vector unsigned short vf800;
+ vector unsigned int v8 = vec_splat_u32(8);
+ vector unsigned int v16 = vec_add(v8, v8);
+ vector unsigned short v2 = vec_splat_u16(2);
+ vector unsigned short v3 = vec_splat_u16(3);
+ /*
+ 0x10 - 0x1f is the alpha
+ 0x00 - 0x0e evens are the red
+ 0x01 - 0x0f odds are zero
+ */
+ vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
+ 0x10, 0x02, 0x01, 0x01,
+ 0x10, 0x04, 0x01, 0x01,
+ 0x10, 0x06, 0x01,
+ 0x01);
+ vector unsigned char vredalpha2 =
+ (vector unsigned
+ char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
+ );
+ /*
+ 0x00 - 0x0f is ARxx ARxx ARxx ARxx
+ 0x11 - 0x0f odds are blue
+ */
+ vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
+ 0x04, 0x05, 0x06, 0x13,
+ 0x08, 0x09, 0x0a, 0x15,
+ 0x0c, 0x0d, 0x0e, 0x17);
+ vector unsigned char vblue2 =
+ (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
+ );
+ /*
+ 0x00 - 0x0f is ARxB ARxB ARxB ARxB
+ 0x10 - 0x0e evens are green
+ */
+ vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
+ 0x04, 0x05, 0x12, 0x07,
+ 0x08, 0x09, 0x14, 0x0b,
+ 0x0c, 0x0d, 0x16, 0x0f);
+ vector unsigned char vgreen2 =
+ (vector unsigned
+ char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
+ );
+
+ SDL_assert(srcfmt->BytesPerPixel == 2);
+ SDL_assert(dstfmt->BytesPerPixel == 4);
+
+ vf800 = (vector unsigned short) vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ if (dstfmt->Amask && info->a) {
+ ((unsigned char *) &valpha)[0] = alpha = info->a;
+ valpha = vec_splat(valpha, 0);
+ } else {
+ alpha = 0;
+ valpha = vec_splat_u8(0);
+ }
+
+ vpermute = calc_swizzle32(NULL, dstfmt);
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned char voverflow;
+ vector unsigned char vsrc;
+
+ int width = info->dst_w;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ unsigned sR, sG, sB; \
+ unsigned short Pixel = *((unsigned short *)src); \
+ sR = (Pixel >> 8) & 0xf8; \
+ sG = (Pixel >> 3) & 0xfc; \
+ sB = (Pixel << 3) & 0xf8; \
+ ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
+ src += 2; \
+ dst += 4; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 8); /* trailing unaligned stores */
+ width -= extrawidth;
+ vsrc = vec_ld(0, src);
+ valigner = VEC_ALIGNER(src);
+
+ while (width) {
+ vector unsigned short vR, vG, vB;
+ vector unsigned char vdst1, vdst2;
+
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+
+ vR = vec_and((vector unsigned short) vsrc, vf800);
+ vB = vec_sl((vector unsigned short) vsrc, v3);
+ vG = vec_sl(vB, v2);
+
+ vdst1 =
+ (vector unsigned char) vec_perm((vector unsigned char) vR,
+ valpha, vredalpha1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
+ vdst1 = vec_perm(vdst1, valpha, vpermute);
+ vec_st(vdst1, 0, dst);
+
+ vdst2 =
+ (vector unsigned char) vec_perm((vector unsigned char) vR,
+ valpha, vredalpha2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
+ vdst2 = vec_perm(vdst2, valpha, vpermute);
+ vec_st(vdst2, 16, dst);
+
+ width -= 8;
+ dst += 32;
+ src += 16;
+ vsrc = voverflow;
+ }
+
+ SDL_assert(width == 0);
+
+
+ /* do scalar until we can align... */
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+
+ src += srcskip; /* move to next row, accounting for pitch. */
+ dst += dstskip;
+ }
+
+}
+
+
+static void
+Blit_RGB555_32Altivec(SDL_BlitInfo * info)
+{
+ int height = info->dst_h;
+ Uint8 *src = (Uint8 *) info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = (Uint8 *) info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ unsigned alpha;
+ vector unsigned char valpha;
+ vector unsigned char vpermute;
+ vector unsigned short vf800;
+ vector unsigned int v8 = vec_splat_u32(8);
+ vector unsigned int v16 = vec_add(v8, v8);
+ vector unsigned short v1 = vec_splat_u16(1);
+ vector unsigned short v3 = vec_splat_u16(3);
+ /*
+ 0x10 - 0x1f is the alpha
+ 0x00 - 0x0e evens are the red
+ 0x01 - 0x0f odds are zero
+ */
+ vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
+ 0x10, 0x02, 0x01, 0x01,
+ 0x10, 0x04, 0x01, 0x01,
+ 0x10, 0x06, 0x01,
+ 0x01);
+ vector unsigned char vredalpha2 =
+ (vector unsigned
+ char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
+ );
+ /*
+ 0x00 - 0x0f is ARxx ARxx ARxx ARxx
+ 0x11 - 0x0f odds are blue
+ */
+ vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
+ 0x04, 0x05, 0x06, 0x13,
+ 0x08, 0x09, 0x0a, 0x15,
+ 0x0c, 0x0d, 0x0e, 0x17);
+ vector unsigned char vblue2 =
+ (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
+ );
+ /*
+ 0x00 - 0x0f is ARxB ARxB ARxB ARxB
+ 0x10 - 0x0e evens are green
+ */
+ vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
+ 0x04, 0x05, 0x12, 0x07,
+ 0x08, 0x09, 0x14, 0x0b,
+ 0x0c, 0x0d, 0x16, 0x0f);
+ vector unsigned char vgreen2 =
+ (vector unsigned
+ char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
+ );
+
+ SDL_assert(srcfmt->BytesPerPixel == 2);
+ SDL_assert(dstfmt->BytesPerPixel == 4);
+
+ vf800 = (vector unsigned short) vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ if (dstfmt->Amask && info->a) {
+ ((unsigned char *) &valpha)[0] = alpha = info->a;
+ valpha = vec_splat(valpha, 0);
+ } else {
+ alpha = 0;
+ valpha = vec_splat_u8(0);
+ }
+
+ vpermute = calc_swizzle32(NULL, dstfmt);
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned char voverflow;
+ vector unsigned char vsrc;
+
+ int width = info->dst_w;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ unsigned sR, sG, sB; \
+ unsigned short Pixel = *((unsigned short *)src); \
+ sR = (Pixel >> 7) & 0xf8; \
+ sG = (Pixel >> 2) & 0xf8; \
+ sB = (Pixel << 3) & 0xf8; \
+ ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
+ src += 2; \
+ dst += 4; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 8); /* trailing unaligned stores */
+ width -= extrawidth;
+ vsrc = vec_ld(0, src);
+ valigner = VEC_ALIGNER(src);
+
+ while (width) {
+ vector unsigned short vR, vG, vB;
+ vector unsigned char vdst1, vdst2;
+
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+
+ vR = vec_and(vec_sl((vector unsigned short) vsrc, v1), vf800);
+ vB = vec_sl((vector unsigned short) vsrc, v3);
+ vG = vec_sl(vB, v3);
+
+ vdst1 =
+ (vector unsigned char) vec_perm((vector unsigned char) vR,
+ valpha, vredalpha1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
+ vdst1 = vec_perm(vdst1, valpha, vpermute);
+ vec_st(vdst1, 0, dst);
+
+ vdst2 =
+ (vector unsigned char) vec_perm((vector unsigned char) vR,
+ valpha, vredalpha2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
+ vdst2 = vec_perm(vdst2, valpha, vpermute);
+ vec_st(vdst2, 16, dst);
+
+ width -= 8;
+ dst += 32;
+ src += 16;
+ vsrc = voverflow;
+ }
+
+ SDL_assert(width == 0);
+
+
+ /* do scalar until we can align... */
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+
+ src += srcskip; /* move to next row, accounting for pitch. */
+ dst += dstskip;
+ }
+
+}
+
+static void BlitNtoNKey(SDL_BlitInfo * info);
+static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info);
+static void
+Blit32to32KeyAltivec(SDL_BlitInfo * info)
+{
+ int height = info->dst_h;
+ Uint32 *srcp = (Uint32 *) info->src;
+ int srcskip = info->src_skip / 4;
+ Uint32 *dstp = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip / 4;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int dstbpp = dstfmt->BytesPerPixel;
+ int copy_alpha = (srcfmt->Amask && dstfmt->Amask);
+ unsigned alpha = dstfmt->Amask ? info->a : 0;
+ Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
+ Uint32 ckey = info->colorkey;
+ vector unsigned int valpha;
+ vector unsigned char vpermute;
+ vector unsigned char vzero;
+ vector unsigned int vckey;
+ vector unsigned int vrgbmask;
+ vpermute = calc_swizzle32(srcfmt, dstfmt);
+ if (info->dst_w < 16) {
+ if (copy_alpha) {
+ BlitNtoNKeyCopyAlpha(info);
+ } else {
+ BlitNtoNKey(info);
+ }
+ return;
+ }
+ vzero = vec_splat_u8(0);
+ if (alpha) {
+ ((unsigned char *) &valpha)[0] = (unsigned char) alpha;
+ valpha =
+ (vector unsigned int) vec_splat((vector unsigned char) valpha, 0);
+ } else {
+ valpha = (vector unsigned int) vzero;
+ }
+ ckey &= rgbmask;
+ ((unsigned int *) (char *) &vckey)[0] = ckey;
+ vckey = vec_splat(vckey, 0);
+ ((unsigned int *) (char *) &vrgbmask)[0] = rgbmask;
+ vrgbmask = vec_splat(vrgbmask, 0);
+
+ while (height--) {
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ if (copy_alpha) { \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, sA; \
+ DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \
+ sR, sG, sB, sA); \
+ if ( (Pixel & rgbmask) != ckey ) { \
+ ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
+ sR, sG, sB, sA); \
+ } \
+ dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \
+ srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \
+ widthvar--; \
+ } \
+ } else { \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB; \
+ RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \
+ if ( Pixel != ckey ) { \
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
+ ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
+ sR, sG, sB, alpha); \
+ } \
+ dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \
+ srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \
+ widthvar--; \
+ } \
+ }
+ int width = info->dst_w;
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ SDL_assert(width > 0);
+ if (width > 0) {
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned int vs = vec_ld(0, srcp);
+ width -= extrawidth;
+ SDL_assert(width >= 4);
+ while (width) {
+ vector unsigned char vsel;
+ vector unsigned int vd;
+ vector unsigned int voverflow = vec_ld(15, srcp);
+ /* load the source vec */
+ vs = vec_perm(vs, voverflow, valigner);
+ /* vsel is set for items that match the key */
+ vsel = (vector unsigned char) vec_and(vs, vrgbmask);
+ vsel = (vector unsigned char) vec_cmpeq(vs, vckey);
+ /* permute the src vec to the dest format */
+ vs = vec_perm(vs, valpha, vpermute);
+ /* load the destination vec */
+ vd = vec_ld(0, dstp);
+ /* select the source and dest into vs */
+ vd = (vector unsigned int) vec_sel((vector unsigned char) vs,
+ (vector unsigned char) vd,
+ vsel);
+
+ vec_st(vd, 0, dstp);
+ srcp += 4;
+ width -= 4;
+ dstp += 4;
+ vs = voverflow;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
+/* Use this on a G5 */
+static void
+ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info)
+{
+ int height = info->dst_h;
+ Uint32 *src = (Uint32 *) info->src;
+ int srcskip = info->src_skip / 4;
+ Uint32 *dst = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip / 4;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ vector unsigned int vzero = vec_splat_u32(0);
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
+ if (dstfmt->Amask && !srcfmt->Amask) {
+ if (info->a) {
+ vector unsigned char valpha;
+ ((unsigned char *) &valpha)[0] = info->a;
+ vzero = (vector unsigned int) vec_splat(valpha, 0);
+ }
+ }
+
+ SDL_assert(srcfmt->BytesPerPixel == 4);
+ SDL_assert(dstfmt->BytesPerPixel == 4);
+
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned int vbits;
+ vector unsigned int voverflow;
+ Uint32 bits;
+ Uint8 r, g, b, a;
+
+ int width = info->dst_w;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+ while ((UNALIGNED_PTR(dst)) && (width)) {
+ bits = *(src++);
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ if(!srcfmt->Amask)
+ a = info->a;
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ width--;
+ }
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 4);
+ width -= extrawidth;
+ valigner = VEC_ALIGNER(src);
+ vbits = vec_ld(0, src);
+
+ while (width) {
+ voverflow = vec_ld(15, src);
+ src += 4;
+ width -= 4;
+ vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
+ vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
+ vec_st(vbits, 0, dst); /* store it back out. */
+ dst += 4;
+ vbits = voverflow;
+ }
+
+ SDL_assert(width == 0);
+
+ /* cover pixels at the end of the row that didn't fit in 16 bytes. */
+ while (extrawidth) {
+ bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ if(!srcfmt->Amask)
+ a = info->a;
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ extrawidth--;
+ }
+
+ src += srcskip;
+ dst += dstskip;
+ }
+
+}
+
+/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
+/* Use this on a G4 */
+static void
+ConvertAltivec32to32_prefetch(SDL_BlitInfo * info)
+{
+ const int scalar_dst_lead = sizeof(Uint32) * 4;
+ const int vector_dst_lead = sizeof(Uint32) * 16;
+
+ int height = info->dst_h;
+ Uint32 *src = (Uint32 *) info->src;
+ int srcskip = info->src_skip / 4;
+ Uint32 *dst = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip / 4;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ vector unsigned int vzero = vec_splat_u32(0);
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
+ if (dstfmt->Amask && !srcfmt->Amask) {
+ if (info->a) {
+ vector unsigned char valpha;
+ ((unsigned char *) &valpha)[0] = info->a;
+ vzero = (vector unsigned int) vec_splat(valpha, 0);
+ }
+ }
+
+ SDL_assert(srcfmt->BytesPerPixel == 4);
+ SDL_assert(dstfmt->BytesPerPixel == 4);
+
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned int vbits;
+ vector unsigned int voverflow;
+ Uint32 bits;
+ Uint8 r, g, b, a;
+
+ int width = info->dst_w;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+ while ((UNALIGNED_PTR(dst)) && (width)) {
+ vec_dstt(src + scalar_dst_lead, DST_CTRL(2, 32, 1024),
+ DST_CHAN_SRC);
+ vec_dstst(dst + scalar_dst_lead, DST_CTRL(2, 32, 1024),
+ DST_CHAN_DEST);
+ bits = *(src++);
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ if(!srcfmt->Amask)
+ a = info->a;
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ width--;
+ }
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 4);
+ width -= extrawidth;
+ valigner = VEC_ALIGNER(src);
+ vbits = vec_ld(0, src);
+
+ while (width) {
+ vec_dstt(src + vector_dst_lead, DST_CTRL(2, 32, 1024),
+ DST_CHAN_SRC);
+ vec_dstst(dst + vector_dst_lead, DST_CTRL(2, 32, 1024),
+ DST_CHAN_DEST);
+ voverflow = vec_ld(15, src);
+ src += 4;
+ width -= 4;
+ vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
+ vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
+ vec_st(vbits, 0, dst); /* store it back out. */
+ dst += 4;
+ vbits = voverflow;
+ }
+
+ SDL_assert(width == 0);
+
+ /* cover pixels at the end of the row that didn't fit in 16 bytes. */
+ while (extrawidth) {
+ bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ if(!srcfmt->Amask)
+ a = info->a;
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ extrawidth--;
+ }
+
+ src += srcskip;
+ dst += dstskip;
+ }
+
+ vec_dss(DST_CHAN_SRC);
+ vec_dss(DST_CHAN_DEST);
+}
+
+static Uint32
+GetBlitFeatures(void)
+{
+ static Uint32 features = 0xffffffff;
+ if (features == 0xffffffff) {
+ /* Provide an override for testing .. */
+ char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES");
+ if (override) {
+ features = 0;
+ SDL_sscanf(override, "%u", &features);
+ } else {
+ features = (0
+ /* Feature 1 is has-MMX */
+ | ((SDL_HasMMX())? 1 : 0)
+ /* Feature 2 is has-AltiVec */
+ | ((SDL_HasAltiVec())? 2 : 0)
+ /* Feature 4 is dont-use-prefetch */
+ /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */
+ | ((GetL3CacheSize() == 0) ? 4 : 0)
+ );
+ }
+ }
+ return features;
+}
+
+#if __MWERKS__
+#pragma altivec_model off
+#endif
+#else
+/* Feature 1 is has-MMX */
+#define GetBlitFeatures() ((Uint32)(SDL_HasMMX() ? 1 : 0))
+#endif
+
+/* This is now endian dependent */
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define HI 1
+#define LO 0
+#else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
+#define HI 0
+#define LO 1
+#endif
+
+/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
+#define RGB888_RGB332(dst, src) { \
+ dst = (Uint8)((((src)&0x00E00000)>>16)| \
+ (((src)&0x0000E000)>>11)| \
+ (((src)&0x000000C0)>>6)); \
+}
+static void
+Blit_RGB888_index8(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ const Uint8 *map;
+ Uint8 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = (Uint32 *) info->src;
+ srcskip = info->src_skip / 4;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+
+ if (map == NULL) {
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ RGB888_RGB332(*dst++, *src);
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width / 4; c; --c) {
+ /* Pack RGB into 8bit pixel */
+ ++src;
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ }
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ case 2:
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ case 1:
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ int Pixel;
+
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width / 4; c; --c) {
+ /* Pack RGB into 8bit pixel */
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 2:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 1:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+/* Special optimized blit for RGB 10-10-10 --> RGB 3-3-2 */
+#define RGB101010_RGB332(dst, src) { \
+ dst = (Uint8)((((src)&0x38000000)>>22)| \
+ (((src)&0x000E0000)>>15)| \
+ (((src)&0x00000300)>>8)); \
+}
+static void
+Blit_RGB101010_index8(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ const Uint8 *map;
+ Uint8 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = (Uint32 *) info->src;
+ srcskip = info->src_skip / 4;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+
+ if (map == NULL) {
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ RGB101010_RGB332(*dst++, *src);
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width / 4; c; --c) {
+ /* Pack RGB into 8bit pixel */
+ ++src;
+ RGB101010_RGB332(*dst++, *src);
+ ++src;
+ RGB101010_RGB332(*dst++, *src);
+ ++src;
+ RGB101010_RGB332(*dst++, *src);
+ ++src;
+ }
+ switch (width & 3) {
+ case 3:
+ RGB101010_RGB332(*dst++, *src);
+ ++src;
+ case 2:
+ RGB101010_RGB332(*dst++, *src);
+ ++src;
+ case 1:
+ RGB101010_RGB332(*dst++, *src);
+ ++src;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ int Pixel;
+
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width / 4; c; --c) {
+ /* Pack RGB into 8bit pixel */
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+ switch (width & 3) {
+ case 3:
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 2:
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 1:
+ RGB101010_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+/* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
+#define RGB888_RGB555(dst, src) { \
+ *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \
+ (((*src)&0x0000F800)>>6)| \
+ (((*src)&0x000000F8)>>3)); \
+}
+#ifndef USE_DUFFS_LOOP
+#define RGB888_RGB555_TWO(dst, src) { \
+ *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
+ (((src[HI])&0x0000F800)>>6)| \
+ (((src[HI])&0x000000F8)>>3))<<16)| \
+ (((src[LO])&0x00F80000)>>9)| \
+ (((src[LO])&0x0000F800)>>6)| \
+ (((src[LO])&0x000000F8)>>3); \
+}
+#endif
+static void
+Blit_RGB888_RGB555(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ Uint16 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = (Uint32 *) info->src;
+ srcskip = info->src_skip / 4;
+ dst = (Uint16 *) info->dst;
+ dstskip = info->dst_skip / 2;
+
+#ifdef USE_DUFFS_LOOP
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ , width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ /* Memory align at 4-byte boundary, if necessary */
+ if ((long) dst & 0x03) {
+ /* Don't do anything if width is 0 */
+ if (width == 0) {
+ return;
+ }
+ --width;
+
+ while (height--) {
+ /* Perform copy alignment */
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+
+/* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
+#define RGB888_RGB565(dst, src) { \
+ *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \
+ (((*src)&0x0000FC00)>>5)| \
+ (((*src)&0x000000F8)>>3)); \
+}
+#ifndef USE_DUFFS_LOOP
+#define RGB888_RGB565_TWO(dst, src) { \
+ *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
+ (((src[HI])&0x0000FC00)>>5)| \
+ (((src[HI])&0x000000F8)>>3))<<16)| \
+ (((src[LO])&0x00F80000)>>8)| \
+ (((src[LO])&0x0000FC00)>>5)| \
+ (((src[LO])&0x000000F8)>>3); \
+}
+#endif
+static void
+Blit_RGB888_RGB565(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ Uint16 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = (Uint32 *) info->src;
+ srcskip = info->src_skip / 4;
+ dst = (Uint16 *) info->dst;
+ dstskip = info->dst_skip / 2;
+
+#ifdef USE_DUFFS_LOOP
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ , width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ /* Memory align at 4-byte boundary, if necessary */
+ if ((long) dst & 0x03) {
+ /* Don't do anything if width is 0 */
+ if (width == 0) {
+ return;
+ }
+ --width;
+
+ while (height--) {
+ /* Perform copy alignment */
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+
+
+/* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
+#define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
+static void
+Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src;
+ Uint32 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = (Uint8 *) info->src;
+ srcskip = info->src_skip;
+ dst = (Uint32 *) info->dst;
+ dstskip = info->dst_skip / 4;
+
+#ifdef USE_DUFFS_LOOP
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ while (height--) {
+ /* Copy in 4 pixel chunks */
+ for (c = width / 4; c; --c) {
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ case 2:
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ case 1:
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+
+/* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
+static const Uint32 RGB565_ARGB8888_LUT[512] = {
+ 0x00000000, 0xff000000, 0x00000008, 0xff002000,
+ 0x00000010, 0xff004000, 0x00000018, 0xff006100,
+ 0x00000020, 0xff008100, 0x00000029, 0xff00a100,
+ 0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
+ 0x00000041, 0xff080000, 0x0000004a, 0xff082000,
+ 0x00000052, 0xff084000, 0x0000005a, 0xff086100,
+ 0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
+ 0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
+ 0x00000083, 0xff100000, 0x0000008b, 0xff102000,
+ 0x00000094, 0xff104000, 0x0000009c, 0xff106100,
+ 0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
+ 0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
+ 0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
+ 0x000000d5, 0xff184000, 0x000000de, 0xff186100,
+ 0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
+ 0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
+ 0x00000400, 0xff200000, 0x00000408, 0xff202000,
+ 0x00000410, 0xff204000, 0x00000418, 0xff206100,
+ 0x00000420, 0xff208100, 0x00000429, 0xff20a100,
+ 0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
+ 0x00000441, 0xff290000, 0x0000044a, 0xff292000,
+ 0x00000452, 0xff294000, 0x0000045a, 0xff296100,
+ 0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
+ 0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
+ 0x00000483, 0xff310000, 0x0000048b, 0xff312000,
+ 0x00000494, 0xff314000, 0x0000049c, 0xff316100,
+ 0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
+ 0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
+ 0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
+ 0x000004d5, 0xff394000, 0x000004de, 0xff396100,
+ 0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
+ 0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
+ 0x00000800, 0xff410000, 0x00000808, 0xff412000,
+ 0x00000810, 0xff414000, 0x00000818, 0xff416100,
+ 0x00000820, 0xff418100, 0x00000829, 0xff41a100,
+ 0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
+ 0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
+ 0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
+ 0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
+ 0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
+ 0x00000883, 0xff520000, 0x0000088b, 0xff522000,
+ 0x00000894, 0xff524000, 0x0000089c, 0xff526100,
+ 0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
+ 0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
+ 0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
+ 0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
+ 0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
+ 0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
+ 0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
+ 0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
+ 0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
+ 0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
+ 0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
+ 0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
+ 0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
+ 0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
+ 0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
+ 0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
+ 0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
+ 0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
+ 0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
+ 0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
+ 0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
+ 0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
+ 0x00001000, 0xff830000, 0x00001008, 0xff832000,
+ 0x00001010, 0xff834000, 0x00001018, 0xff836100,
+ 0x00001020, 0xff838100, 0x00001029, 0xff83a100,
+ 0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
+ 0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
+ 0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
+ 0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
+ 0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
+ 0x00001083, 0xff940000, 0x0000108b, 0xff942000,
+ 0x00001094, 0xff944000, 0x0000109c, 0xff946100,
+ 0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
+ 0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
+ 0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
+ 0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
+ 0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
+ 0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
+ 0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
+ 0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
+ 0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
+ 0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
+ 0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
+ 0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
+ 0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
+ 0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
+ 0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
+ 0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
+ 0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
+ 0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
+ 0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
+ 0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
+ 0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
+ 0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
+ 0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
+ 0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
+ 0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
+ 0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
+ 0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
+ 0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
+ 0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
+ 0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
+ 0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
+ 0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
+ 0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
+ 0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
+ 0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
+ 0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
+ 0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
+ 0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
+ 0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
+ 0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
+ 0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
+ 0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
+ 0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
+ 0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
+ 0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
+ 0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
+ 0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
+ 0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
+ 0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
+ 0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
+ 0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
+ 0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
+ 0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
+ 0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
+};
+
+static void
+Blit_RGB565_ARGB8888(SDL_BlitInfo * info)
+{
+ Blit_RGB565_32(info, RGB565_ARGB8888_LUT);
+}
+
+/* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */
+static const Uint32 RGB565_ABGR8888_LUT[512] = {
+ 0xff000000, 0x00000000, 0xff080000, 0x00002000,
+ 0xff100000, 0x00004000, 0xff180000, 0x00006100,
+ 0xff200000, 0x00008100, 0xff290000, 0x0000a100,
+ 0xff310000, 0x0000c200, 0xff390000, 0x0000e200,
+ 0xff410000, 0x00000008, 0xff4a0000, 0x00002008,
+ 0xff520000, 0x00004008, 0xff5a0000, 0x00006108,
+ 0xff620000, 0x00008108, 0xff6a0000, 0x0000a108,
+ 0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208,
+ 0xff830000, 0x00000010, 0xff8b0000, 0x00002010,
+ 0xff940000, 0x00004010, 0xff9c0000, 0x00006110,
+ 0xffa40000, 0x00008110, 0xffac0000, 0x0000a110,
+ 0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210,
+ 0xffc50000, 0x00000018, 0xffcd0000, 0x00002018,
+ 0xffd50000, 0x00004018, 0xffde0000, 0x00006118,
+ 0xffe60000, 0x00008118, 0xffee0000, 0x0000a118,
+ 0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218,
+ 0xff000400, 0x00000020, 0xff080400, 0x00002020,
+ 0xff100400, 0x00004020, 0xff180400, 0x00006120,
+ 0xff200400, 0x00008120, 0xff290400, 0x0000a120,
+ 0xff310400, 0x0000c220, 0xff390400, 0x0000e220,
+ 0xff410400, 0x00000029, 0xff4a0400, 0x00002029,
+ 0xff520400, 0x00004029, 0xff5a0400, 0x00006129,
+ 0xff620400, 0x00008129, 0xff6a0400, 0x0000a129,
+ 0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229,
+ 0xff830400, 0x00000031, 0xff8b0400, 0x00002031,
+ 0xff940400, 0x00004031, 0xff9c0400, 0x00006131,
+ 0xffa40400, 0x00008131, 0xffac0400, 0x0000a131,
+ 0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231,
+ 0xffc50400, 0x00000039, 0xffcd0400, 0x00002039,
+ 0xffd50400, 0x00004039, 0xffde0400, 0x00006139,
+ 0xffe60400, 0x00008139, 0xffee0400, 0x0000a139,
+ 0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239,
+ 0xff000800, 0x00000041, 0xff080800, 0x00002041,
+ 0xff100800, 0x00004041, 0xff180800, 0x00006141,
+ 0xff200800, 0x00008141, 0xff290800, 0x0000a141,
+ 0xff310800, 0x0000c241, 0xff390800, 0x0000e241,
+ 0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a,
+ 0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a,
+ 0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a,
+ 0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a,
+ 0xff830800, 0x00000052, 0xff8b0800, 0x00002052,
+ 0xff940800, 0x00004052, 0xff9c0800, 0x00006152,
+ 0xffa40800, 0x00008152, 0xffac0800, 0x0000a152,
+ 0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252,
+ 0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a,
+ 0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a,
+ 0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a,
+ 0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a,
+ 0xff000c00, 0x00000062, 0xff080c00, 0x00002062,
+ 0xff100c00, 0x00004062, 0xff180c00, 0x00006162,
+ 0xff200c00, 0x00008162, 0xff290c00, 0x0000a162,
+ 0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262,
+ 0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a,
+ 0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a,
+ 0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a,
+ 0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a,
+ 0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073,
+ 0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173,
+ 0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173,
+ 0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273,
+ 0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b,
+ 0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b,
+ 0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b,
+ 0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b,
+ 0xff001000, 0x00000083, 0xff081000, 0x00002083,
+ 0xff101000, 0x00004083, 0xff181000, 0x00006183,
+ 0xff201000, 0x00008183, 0xff291000, 0x0000a183,
+ 0xff311000, 0x0000c283, 0xff391000, 0x0000e283,
+ 0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b,
+ 0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b,
+ 0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b,
+ 0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b,
+ 0xff831000, 0x00000094, 0xff8b1000, 0x00002094,
+ 0xff941000, 0x00004094, 0xff9c1000, 0x00006194,
+ 0xffa41000, 0x00008194, 0xffac1000, 0x0000a194,
+ 0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294,
+ 0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c,
+ 0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c,
+ 0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c,
+ 0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c,
+ 0xff001400, 0x000000a4, 0xff081400, 0x000020a4,
+ 0xff101400, 0x000040a4, 0xff181400, 0x000061a4,
+ 0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4,
+ 0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4,
+ 0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac,
+ 0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac,
+ 0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac,
+ 0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac,
+ 0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4,
+ 0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4,
+ 0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4,
+ 0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4,
+ 0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd,
+ 0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd,
+ 0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd,
+ 0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd,
+ 0xff001800, 0x000000c5, 0xff081800, 0x000020c5,
+ 0xff101800, 0x000040c5, 0xff181800, 0x000061c5,
+ 0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5,
+ 0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5,
+ 0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd,
+ 0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd,
+ 0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd,
+ 0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd,
+ 0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5,
+ 0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5,
+ 0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5,
+ 0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5,
+ 0xffc51800, 0x000000de, 0xffcd1800, 0x000020de,
+ 0xffd51800, 0x000040de, 0xffde1800, 0x000061de,
+ 0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de,
+ 0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de,
+ 0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6,
+ 0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6,
+ 0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6,
+ 0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6,
+ 0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee,
+ 0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee,
+ 0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee,
+ 0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee,
+ 0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6,
+ 0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6,
+ 0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6,
+ 0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6,
+ 0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff,
+ 0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff,
+ 0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff,
+ 0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff
+};
+
+static void
+Blit_RGB565_ABGR8888(SDL_BlitInfo * info)
+{
+ Blit_RGB565_32(info, RGB565_ABGR8888_LUT);
+}
+
+/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
+static const Uint32 RGB565_RGBA8888_LUT[512] = {
+ 0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
+ 0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
+ 0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
+ 0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
+ 0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
+ 0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
+ 0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
+ 0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
+ 0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
+ 0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
+ 0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
+ 0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
+ 0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
+ 0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
+ 0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
+ 0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
+ 0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
+ 0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
+ 0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
+ 0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
+ 0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
+ 0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
+ 0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
+ 0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
+ 0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
+ 0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
+ 0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
+ 0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
+ 0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
+ 0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
+ 0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
+ 0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
+ 0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
+ 0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
+ 0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
+ 0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
+ 0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
+ 0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
+ 0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
+ 0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
+ 0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
+ 0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
+ 0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
+ 0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
+ 0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
+ 0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
+ 0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
+ 0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
+ 0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
+ 0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
+ 0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
+ 0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
+ 0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
+ 0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
+ 0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
+ 0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
+ 0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
+ 0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
+ 0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
+ 0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
+ 0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
+ 0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
+ 0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
+ 0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
+ 0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
+ 0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
+ 0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
+ 0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
+ 0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
+ 0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
+ 0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
+ 0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
+ 0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
+ 0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
+ 0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
+ 0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
+ 0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
+ 0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
+ 0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
+ 0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
+ 0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
+ 0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
+ 0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
+ 0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
+ 0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
+ 0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
+ 0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
+ 0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
+ 0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
+ 0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
+ 0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
+ 0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
+ 0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
+ 0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
+ 0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
+ 0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
+ 0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
+ 0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
+ 0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
+ 0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
+ 0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
+ 0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
+ 0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
+ 0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
+ 0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
+ 0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
+ 0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
+ 0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
+ 0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
+ 0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
+ 0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
+ 0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
+ 0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
+ 0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
+ 0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
+ 0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
+ 0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
+ 0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
+ 0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
+ 0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
+ 0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
+ 0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
+ 0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
+ 0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
+ 0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
+ 0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
+ 0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
+ 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
+};
+
+static void
+Blit_RGB565_RGBA8888(SDL_BlitInfo * info)
+{
+ Blit_RGB565_32(info, RGB565_RGBA8888_LUT);
+}
+
+/* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */
+static const Uint32 RGB565_BGRA8888_LUT[512] = {
+ 0x00000000, 0x000000ff, 0x08000000, 0x002000ff,
+ 0x10000000, 0x004000ff, 0x18000000, 0x006100ff,
+ 0x20000000, 0x008100ff, 0x29000000, 0x00a100ff,
+ 0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff,
+ 0x41000000, 0x000008ff, 0x4a000000, 0x002008ff,
+ 0x52000000, 0x004008ff, 0x5a000000, 0x006108ff,
+ 0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff,
+ 0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff,
+ 0x83000000, 0x000010ff, 0x8b000000, 0x002010ff,
+ 0x94000000, 0x004010ff, 0x9c000000, 0x006110ff,
+ 0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff,
+ 0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff,
+ 0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff,
+ 0xd5000000, 0x004018ff, 0xde000000, 0x006118ff,
+ 0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff,
+ 0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff,
+ 0x00040000, 0x000020ff, 0x08040000, 0x002020ff,
+ 0x10040000, 0x004020ff, 0x18040000, 0x006120ff,
+ 0x20040000, 0x008120ff, 0x29040000, 0x00a120ff,
+ 0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff,
+ 0x41040000, 0x000029ff, 0x4a040000, 0x002029ff,
+ 0x52040000, 0x004029ff, 0x5a040000, 0x006129ff,
+ 0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff,
+ 0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff,
+ 0x83040000, 0x000031ff, 0x8b040000, 0x002031ff,
+ 0x94040000, 0x004031ff, 0x9c040000, 0x006131ff,
+ 0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff,
+ 0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff,
+ 0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff,
+ 0xd5040000, 0x004039ff, 0xde040000, 0x006139ff,
+ 0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff,
+ 0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff,
+ 0x00080000, 0x000041ff, 0x08080000, 0x002041ff,
+ 0x10080000, 0x004041ff, 0x18080000, 0x006141ff,
+ 0x20080000, 0x008141ff, 0x29080000, 0x00a141ff,
+ 0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff,
+ 0x41080000, 0x00004aff, 0x4a080000, 0x00204aff,
+ 0x52080000, 0x00404aff, 0x5a080000, 0x00614aff,
+ 0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff,
+ 0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff,
+ 0x83080000, 0x000052ff, 0x8b080000, 0x002052ff,
+ 0x94080000, 0x004052ff, 0x9c080000, 0x006152ff,
+ 0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff,
+ 0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff,
+ 0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff,
+ 0xd5080000, 0x00405aff, 0xde080000, 0x00615aff,
+ 0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff,
+ 0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff,
+ 0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff,
+ 0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff,
+ 0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff,
+ 0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff,
+ 0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff,
+ 0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff,
+ 0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff,
+ 0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff,
+ 0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff,
+ 0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff,
+ 0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff,
+ 0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff,
+ 0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff,
+ 0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff,
+ 0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff,
+ 0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff,
+ 0x00100000, 0x000083ff, 0x08100000, 0x002083ff,
+ 0x10100000, 0x004083ff, 0x18100000, 0x006183ff,
+ 0x20100000, 0x008183ff, 0x29100000, 0x00a183ff,
+ 0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff,
+ 0x41100000, 0x00008bff, 0x4a100000, 0x00208bff,
+ 0x52100000, 0x00408bff, 0x5a100000, 0x00618bff,
+ 0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff,
+ 0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff,
+ 0x83100000, 0x000094ff, 0x8b100000, 0x002094ff,
+ 0x94100000, 0x004094ff, 0x9c100000, 0x006194ff,
+ 0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff,
+ 0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff,
+ 0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff,
+ 0xd5100000, 0x00409cff, 0xde100000, 0x00619cff,
+ 0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff,
+ 0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff,
+ 0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff,
+ 0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff,
+ 0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff,
+ 0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff,
+ 0x41140000, 0x0000acff, 0x4a140000, 0x0020acff,
+ 0x52140000, 0x0040acff, 0x5a140000, 0x0061acff,
+ 0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff,
+ 0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff,
+ 0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff,
+ 0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff,
+ 0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff,
+ 0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff,
+ 0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff,
+ 0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff,
+ 0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff,
+ 0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff,
+ 0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff,
+ 0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff,
+ 0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff,
+ 0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff,
+ 0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff,
+ 0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff,
+ 0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff,
+ 0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff,
+ 0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff,
+ 0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff,
+ 0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff,
+ 0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff,
+ 0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff,
+ 0xd5180000, 0x0040deff, 0xde180000, 0x0061deff,
+ 0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff,
+ 0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff,
+ 0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff,
+ 0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff,
+ 0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff,
+ 0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff,
+ 0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff,
+ 0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff,
+ 0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff,
+ 0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff,
+ 0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff,
+ 0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff,
+ 0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff,
+ 0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff,
+ 0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff,
+ 0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff,
+ 0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff,
+ 0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff
+};
+
+static void
+Blit_RGB565_BGRA8888(SDL_BlitInfo * info)
+{
+ Blit_RGB565_32(info, RGB565_BGRA8888_LUT);
+}
+
+static void
+BlitNto1(SDL_BlitInfo * info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src;
+ const Uint8 *map;
+ Uint8 *dst;
+ int srcskip, dstskip;
+ int srcbpp;
+ Uint32 Pixel;
+ int sR, sG, sB;
+ SDL_PixelFormat *srcfmt;
+
+ /* Set up some basic variables */
+ width = info->dst_w;
+ height = info->dst_h;
+ src = info->src;
+ srcskip = info->src_skip;
+ dst = info->dst;
+ dstskip = info->dst_skip;
+ map = info->table;
+ srcfmt = info->src_fmt;
+ srcbpp = srcfmt->BytesPerPixel;
+
+ if (map == NULL) {
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( 1 ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = ((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ;
+ }
+ dst++;
+ src += srcbpp;
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width; c; --c) {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ if (1) {
+ /* Pack RGB into 8bit pixel */
+ *dst = ((sR >> 5) << (3 + 2)) |
+ ((sG >> 5) << (2)) | ((sB >> 6) << (0));
+ }
+ dst++;
+ src += srcbpp;
+ }
+#endif
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+#ifdef USE_DUFFS_LOOP
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( 1 ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = map[((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ];
+ }
+ dst++;
+ src += srcbpp;
+ , width);
+ /* *INDENT-ON* */
+#else
+ for (c = width; c; --c) {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ if (1) {
+ /* Pack RGB into 8bit pixel */
+ *dst = map[((sR >> 5) << (3 + 2)) |
+ ((sG >> 5) << (2)) | ((sB >> 6) << (0))];
+ }
+ dst++;
+ src += srcbpp;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+/* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
+static void
+Blit4to4MaskAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *src = (Uint32 *) info->src;
+ int srcskip = info->src_skip;
+ Uint32 *dst = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+
+ if (dstfmt->Amask) {
+ /* RGB->RGBA, SET_ALPHA */
+ Uint32 mask = (info->a >> dstfmt->Aloss) << dstfmt->Ashift;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ *dst = *src | mask;
+ ++dst;
+ ++src;
+ },
+ width);
+ /* *INDENT-ON* */
+ src = (Uint32 *) ((Uint8 *) src + srcskip);
+ dst = (Uint32 *) ((Uint8 *) dst + dstskip);
+ }
+ } else {
+ /* RGBA->RGB, NO_ALPHA */
+ Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ *dst = *src & mask;
+ ++dst;
+ ++src;
+ },
+ width);
+ /* *INDENT-ON* */
+ src = (Uint32 *) ((Uint8 *) src + srcskip);
+ dst = (Uint32 *) ((Uint8 *) dst + dstskip);
+ }
+ }
+}
+
+/* blits 32 bit RGBA<->RGBA with both surfaces having the same R,G,B,A fields */
+static void
+Blit4to4CopyAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint32 *src = (Uint32 *) info->src;
+ int srcskip = info->src_skip;
+ Uint32 *dst = (Uint32 *) info->dst;
+ int dstskip = info->dst_skip;
+
+ /* RGBA->RGBA, COPY_ALPHA */
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ *dst = *src;
+ ++dst;
+ ++src;
+ },
+ width);
+ /* *INDENT-ON* */
+ src = (Uint32 *) ((Uint8 *) src + srcskip);
+ dst = (Uint32 *) ((Uint8 *) dst + dstskip);
+ }
+}
+
+static void
+BlitNtoN(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int dstbpp = dstfmt->BytesPerPixel;
+ unsigned alpha = dstfmt->Amask ? info->a : 0;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
+ dst += dstbpp;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitNtoNCopyAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int dstbpp = dstfmt->BytesPerPixel;
+ int c;
+
+ while (height--) {
+ for (c = width; c; --c) {
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
+ dst += dstbpp;
+ src += srcbpp;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitNto1Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ const Uint8 *palmap = info->table;
+ Uint32 ckey = info->colorkey;
+ Uint32 rgbmask = ~srcfmt->Amask;
+ int srcbpp;
+ Uint32 Pixel;
+ unsigned sR, sG, sB;
+
+ /* Set up some basic variables */
+ srcbpp = srcfmt->BytesPerPixel;
+ ckey &= rgbmask;
+
+ if (palmap == NULL) {
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( (Pixel & rgbmask) != ckey ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = (Uint8)(((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)));
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( (Pixel & rgbmask) != ckey ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = (Uint8)palmap[((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ];
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void
+Blit2to2Key(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint16 *srcp = (Uint16 *) info->src;
+ int srcskip = info->src_skip;
+ Uint16 *dstp = (Uint16 *) info->dst;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ Uint32 rgbmask = ~info->src_fmt->Amask;
+
+ /* Set up some basic variables */
+ srcskip /= 2;
+ dstskip /= 2;
+ ckey &= rgbmask;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ( (*srcp & rgbmask) != ckey ) {
+ *dstp = *srcp;
+ }
+ dstp++;
+ srcp++;
+ },
+ width);
+ /* *INDENT-ON* */
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void
+BlitNtoNKey(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
+ unsigned alpha = dstfmt->Amask ? info->a : 0;
+ Uint32 rgbmask = ~srcfmt->Amask;
+
+ /* Set up some basic variables */
+ ckey &= rgbmask;
+
+ /* Fastpath: same source/destination format, no Amask, bpp 32, loop is vectorized. ~10x faster */
+ if (srcfmt->format == dstfmt->format &&
+ (srcfmt->format == SDL_PIXELFORMAT_RGB888 || srcfmt->format == SDL_PIXELFORMAT_BGR888)) {
+ Uint32 *src32 = (Uint32*)src;
+ Uint32 *dst32 = (Uint32*)dst;
+ srcskip /= sizeof(Uint32);
+ dstskip /= sizeof(Uint32);
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if (*src32 != ckey) {
+ *dst32 = *src32;
+ }
+ ++src32;
+ ++dst32;
+ },
+ width);
+ /* *INDENT-ON* */
+ src32 += srcskip;
+ dst32 += dstskip;
+ }
+ return;
+ }
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
+ if ( (Pixel & rgbmask) != ckey ) {
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
+ }
+ dst += dstbpp;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void
+BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ Uint32 ckey = info->colorkey;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ Uint32 rgbmask = ~srcfmt->Amask;
+
+ Uint8 srcbpp;
+ Uint8 dstbpp;
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+
+ /* Set up some basic variables */
+ srcbpp = srcfmt->BytesPerPixel;
+ dstbpp = dstfmt->BytesPerPixel;
+ ckey &= rgbmask;
+
+ /* Fastpath: same source/destination format, with Amask, bpp 32, loop is vectorized. ~10x faster */
+ if (srcfmt->format == dstfmt->format &&
+ (srcfmt->format == SDL_PIXELFORMAT_ARGB8888 ||
+ srcfmt->format == SDL_PIXELFORMAT_ABGR8888 ||
+ srcfmt->format == SDL_PIXELFORMAT_BGRA8888 ||
+ srcfmt->format == SDL_PIXELFORMAT_RGBA8888)) {
+ Uint32 *src32 = (Uint32*)src;
+ Uint32 *dst32 = (Uint32*)dst;
+ srcskip /= sizeof(Uint32);
+ dstskip /= sizeof(Uint32);
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ if ((*src32 & rgbmask) != ckey) {
+ *dst32 = *src32;
+ }
+ ++src32;
+ ++dst32;
+ },
+ width);
+ /* *INDENT-ON* */
+ src32 += srcskip;
+ dst32 += dstskip;
+ }
+ return;
+ }
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
+ if ( (Pixel & rgbmask) != ckey ) {
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
+ }
+ dst += dstbpp;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* Special optimized blit for ARGB 2-10-10-10 --> RGBA */
+static void
+Blit2101010toN(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *dstfmt = info->dst_fmt;
+ int dstbpp = dstfmt->BytesPerPixel;
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ Pixel = *(Uint32 *)src;
+ RGBA_FROM_ARGB2101010(Pixel, sR, sG, sB, sA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
+ dst += dstbpp;
+ src += 4;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* Special optimized blit for RGBA --> ARGB 2-10-10-10 */
+static void
+BlitNto2101010(SDL_BlitInfo * info)
+{
+ int width = info->dst_w;
+ int height = info->dst_h;
+ Uint8 *src = info->src;
+ int srcskip = info->src_skip;
+ Uint8 *dst = info->dst;
+ int dstskip = info->dst_skip;
+ SDL_PixelFormat *srcfmt = info->src_fmt;
+ int srcbpp = srcfmt->BytesPerPixel;
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+
+ while (height--) {
+ /* *INDENT-OFF* */
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
+ ARGB2101010_FROM_RGBA(Pixel, sR, sG, sB, sA);
+ *(Uint32 *)dst = Pixel;
+ dst += 4;
+ src += srcbpp;
+ },
+ width);
+ /* *INDENT-ON* */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* Normal N to N optimized blitters */
+#define NO_ALPHA 1
+#define SET_ALPHA 2
+#define COPY_ALPHA 4
+struct blit_table
+{
+ Uint32 srcR, srcG, srcB;
+ int dstbpp;
+ Uint32 dstR, dstG, dstB;
+ Uint32 blit_features;
+ SDL_BlitFunc blitfunc;
+ Uint32 alpha; /* bitwise NO_ALPHA, SET_ALPHA, COPY_ALPHA */
+};
+static const struct blit_table normal_blit_1[] = {
+ /* Default for 8-bit RGB source, never optimized */
+ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
+};
+
+static const struct blit_table normal_blit_2[] = {
+#if SDL_ALTIVEC_BLITTERS
+ /* has-altivec */
+ {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
+ 2, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+ {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
+ 2, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+#endif
+ {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
+ 0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+ {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
+ 0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+ {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00,
+ 0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+ {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000,
+ 0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+
+ /* Default for 16-bit RGB source, used if no other blitter matches */
+ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
+};
+
+static const struct blit_table normal_blit_3[] = {
+ /* Default for 24-bit RGB source, never optimized */
+ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
+};
+
+static const struct blit_table normal_blit_4[] = {
+#if SDL_ALTIVEC_BLITTERS
+ /* has-altivec | dont-use-prefetch */
+ {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
+ 6, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+ /* has-altivec */
+ {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
+ 2, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
+ /* has-altivec */
+ {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
+ 2, Blit_RGB888_RGB565Altivec, NO_ALPHA},
+#endif
+ {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
+ 0, Blit_RGB888_RGB565, NO_ALPHA},
+ {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
+ 0, Blit_RGB888_RGB555, NO_ALPHA},
+ /* Default for 32-bit RGB source, used if no other blitter matches */
+ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
+};
+
+static const struct blit_table *const normal_blit[] = {
+ normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
+};
+
+/* Mask matches table, or table entry is zero */
+#define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000))
+
+SDL_BlitFunc
+SDL_CalculateBlitN(SDL_Surface * surface)
+{
+ SDL_PixelFormat *srcfmt;
+ SDL_PixelFormat *dstfmt;
+ const struct blit_table *table;
+ int which;
+ SDL_BlitFunc blitfun;
+
+ /* Set up data for choosing the blit */
+ srcfmt = surface->format;
+ dstfmt = surface->map->dst->format;
+
+ /* We don't support destinations less than 8-bits */
+ if (dstfmt->BitsPerPixel < 8) {
+ return (NULL);
+ }
+
+ switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
+ case 0:
+ blitfun = NULL;
+ if (dstfmt->BitsPerPixel == 8) {
+ if ((srcfmt->BytesPerPixel == 4) &&
+ (srcfmt->Rmask == 0x00FF0000) &&
+ (srcfmt->Gmask == 0x0000FF00) &&
+ (srcfmt->Bmask == 0x000000FF)) {
+ blitfun = Blit_RGB888_index8;
+ } else if ((srcfmt->BytesPerPixel == 4) &&
+ (srcfmt->Rmask == 0x3FF00000) &&
+ (srcfmt->Gmask == 0x000FFC00) &&
+ (srcfmt->Bmask == 0x000003FF)) {
+ blitfun = Blit_RGB101010_index8;
+ } else {
+ blitfun = BlitNto1;
+ }
+ } else {
+ /* Now the meat, choose the blitter we want */
+ int a_need = NO_ALPHA;
+ if (dstfmt->Amask)
+ a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
+ table = normal_blit[srcfmt->BytesPerPixel - 1];
+ for (which = 0; table[which].dstbpp; ++which) {
+ if (MASKOK(srcfmt->Rmask, table[which].srcR) &&
+ MASKOK(srcfmt->Gmask, table[which].srcG) &&
+ MASKOK(srcfmt->Bmask, table[which].srcB) &&
+ MASKOK(dstfmt->Rmask, table[which].dstR) &&
+ MASKOK(dstfmt->Gmask, table[which].dstG) &&
+ MASKOK(dstfmt->Bmask, table[which].dstB) &&
+ dstfmt->BytesPerPixel == table[which].dstbpp &&
+ (a_need & table[which].alpha) == a_need &&
+ ((table[which].blit_features & GetBlitFeatures()) ==
+ table[which].blit_features))
+ break;
+ }
+ blitfun = table[which].blitfunc;
+
+ if (blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */
+ if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
+ blitfun = Blit2101010toN;
+ } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
+ blitfun = BlitNto2101010;
+ } else if (srcfmt->BytesPerPixel == 4 &&
+ dstfmt->BytesPerPixel == 4 &&
+ srcfmt->Rmask == dstfmt->Rmask &&
+ srcfmt->Gmask == dstfmt->Gmask &&
+ srcfmt->Bmask == dstfmt->Bmask) {
+ if (a_need == COPY_ALPHA) {
+ if (srcfmt->Amask == dstfmt->Amask) {
+ /* Fastpath C fallback: 32bit RGBA<->RGBA blit with matching RGBA */
+ blitfun = Blit4to4CopyAlpha;
+ } else {
+ blitfun = BlitNtoNCopyAlpha;
+ }
+ } else {
+ /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
+ blitfun = Blit4to4MaskAlpha;
+ }
+ } else if (a_need == COPY_ALPHA) {
+ blitfun = BlitNtoNCopyAlpha;
+ }
+ }
+ }
+ return (blitfun);
+
+ case SDL_COPY_COLORKEY:
+ /* colorkey blit: Here we don't have too many options, mostly
+ because RLE is the preferred fast way to deal with this.
+ If a particular case turns out to be useful we'll add it. */
+
+ if (srcfmt->BytesPerPixel == 2 && surface->map->identity)
+ return Blit2to2Key;
+ else if (dstfmt->BytesPerPixel == 1)
+ return BlitNto1Key;
+ else {
+#if SDL_ALTIVEC_BLITTERS
+ if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4)
+ && SDL_HasAltiVec()) {
+ return Blit32to32KeyAltivec;
+ } else
+#endif
+ if (srcfmt->Amask && dstfmt->Amask) {
+ return BlitNtoNKeyCopyAlpha;
+ } else {
+ return BlitNtoNKey;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_auto.c b/source/3rd-party/SDL2/src/video/SDL_blit_auto.c
new file mode 100644
index 0000000..d9d266f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_auto.c
@@ -0,0 +1,7419 @@
+/* DO NOT EDIT! This file is generated by sdlgenblit.pl */
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/* *INDENT-OFF* */
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+#include "SDL_blit_auto.h"
+
+static void SDL_Blit_RGB888_RGB888_Scale(SDL_BlitInfo *info)
+{
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ *dst = *src;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_RGB888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_RGB888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_RGB888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_RGB888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_RGB888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = 0xFF;
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = 0xFF;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = 0xFF;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGB888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Scale(SDL_BlitInfo *info)
+{
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ *dst = *src;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = 0xFF;
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = 0xFF;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = 0xFF;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = 0xFF;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Scale(SDL_BlitInfo *info)
+{
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ *dst = *src;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = (Uint8)(pixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = (Uint8)(pixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel;
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24);
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24);
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ Uint32 pixel;
+ Uint32 R, G, B;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ pixel = ((Uint32)B << 16) | ((Uint32)G << 8) | R;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstB = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstR = (Uint8)dstpixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstB << 16) | ((Uint32)dstG << 8) | dstR;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Scale(SDL_BlitInfo *info)
+{
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel;
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Modulate(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 pixel;
+ Uint32 R, G, B, A;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ pixel = *src;
+ B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ R = (R * modulateR) / 255;
+ G = (G * modulateG) / 255;
+ B = (B * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ A = (A * modulateA) / 255;
+ }
+ pixel = ((Uint32)A << 24) | ((Uint32)R << 16) | ((Uint32)G << 8) | B;
+ *dst = pixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+
+ while (info->dst_h--) {
+ Uint32 *src = (Uint32 *)info->src;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+}
+
+static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint32 *src = 0;
+ Uint32 *dst = (Uint32 *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
+ }
+ srcpixel = *src;
+ srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel;
+ dstpixel = *dst;
+ dstR = (Uint8)(dstpixel >> 16); dstG = (Uint8)(dstpixel >> 8); dstB = (Uint8)dstpixel; dstA = (Uint8)(dstpixel >> 24);
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR; if (dstR > 255) dstR = 255;
+ dstG = srcG + dstG; if (dstG > 255) dstG = 255;
+ dstB = srcB + dstB; if (dstB > 255) dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ dstpixel = ((Uint32)dstA << 24) | ((Uint32)dstR << 16) | ((Uint32)dstG << 8) | dstB;
+ *dst = dstpixel;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[] = {
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Blend },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Blend_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Modulate },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Modulate_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Modulate_Blend },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_RGB888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Blend },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Blend_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Modulate },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Modulate_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Modulate_Blend },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_BGR888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Blend },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Blend_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Modulate },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Modulate_Scale },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Modulate_Blend },
+ { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGB888_ARGB8888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Blend },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Blend_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Modulate },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Modulate_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Modulate_Blend },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_RGB888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Blend },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Blend_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Modulate },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Modulate_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Modulate_Blend },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_BGR888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Blend },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Blend_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Modulate },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Modulate_Scale },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Modulate_Blend },
+ { SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Blend },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Blend_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Modulate },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Modulate_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Modulate_Blend },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_RGB888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Blend },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Blend_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Modulate },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Modulate_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Modulate_Blend },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_BGR888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Blend },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Blend_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Modulate },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Modulate_Scale },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend },
+ { SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Blend },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Blend_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Modulate },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Modulate_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Modulate_Blend },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_RGB888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Blend },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Blend_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Modulate },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Modulate_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Modulate_Blend },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Blend },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Blend_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Modulate },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Modulate_Scale },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend },
+ { SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Blend },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Blend_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Modulate },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Modulate_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Modulate_Blend },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Blend },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Blend_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Modulate },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Modulate_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Modulate_Blend },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_BGR888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Blend },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Blend_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Modulate },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Modulate_Scale },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend },
+ { SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Blend },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Blend_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Modulate },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Modulate_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Modulate_Blend },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_RGB888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Blend },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Blend_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Modulate },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Modulate_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Modulate_Blend },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGR888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_BGR888_Modulate_Blend_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Blend },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Blend_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Modulate },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Modulate_Scale },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend },
+ { SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB8888, (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_NEAREST), SDL_CPU_ANY, SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend_Scale },
+ { 0, 0, 0, 0, NULL }
+};
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_auto.h b/source/3rd-party/SDL2/src/video/SDL_blit_auto.h
new file mode 100644
index 0000000..41a6a32
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_auto.h
@@ -0,0 +1,30 @@
+/* DO NOT EDIT! This file is generated by sdlgenblit.pl */
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/* *INDENT-OFF* */
+
+extern SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[];
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_copy.c b/source/3rd-party/SDL2/src/video/SDL_blit_copy.c
new file mode 100644
index 0000000..e862898
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_copy.c
@@ -0,0 +1,162 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+#include "SDL_blit_copy.h"
+
+
+#ifdef __SSE__
+/* This assumes 16-byte aligned src and dst */
+static SDL_INLINE void
+SDL_memcpySSE(Uint8 * dst, const Uint8 * src, int len)
+{
+ int i;
+
+ __m128 values[4];
+ for (i = len / 64; i--;) {
+ _mm_prefetch(src, _MM_HINT_NTA);
+ values[0] = *(__m128 *) (src + 0);
+ values[1] = *(__m128 *) (src + 16);
+ values[2] = *(__m128 *) (src + 32);
+ values[3] = *(__m128 *) (src + 48);
+ _mm_stream_ps((float *) (dst + 0), values[0]);
+ _mm_stream_ps((float *) (dst + 16), values[1]);
+ _mm_stream_ps((float *) (dst + 32), values[2]);
+ _mm_stream_ps((float *) (dst + 48), values[3]);
+ src += 64;
+ dst += 64;
+ }
+
+ if (len & 63)
+ SDL_memcpy(dst, src, len & 63);
+}
+#endif /* __SSE__ */
+
+#ifdef __MMX__
+#ifdef _MSC_VER
+#pragma warning(disable:4799)
+#endif
+static SDL_INLINE void
+SDL_memcpyMMX(Uint8 * dst, const Uint8 * src, int len)
+{
+ const int remain = (len & 63);
+ int i;
+
+ __m64* d64 = (__m64*)dst;
+ __m64* s64 = (__m64*)src;
+
+ for(i= len / 64; i--;) {
+ d64[0] = s64[0];
+ d64[1] = s64[1];
+ d64[2] = s64[2];
+ d64[3] = s64[3];
+ d64[4] = s64[4];
+ d64[5] = s64[5];
+ d64[6] = s64[6];
+ d64[7] = s64[7];
+
+ d64 += 8;
+ s64 += 8;
+ }
+
+ if (remain)
+ {
+ const int skip = len - remain;
+ SDL_memcpy(dst + skip, src + skip, remain);
+ }
+}
+#endif /* __MMX__ */
+
+void
+SDL_BlitCopy(SDL_BlitInfo * info)
+{
+ SDL_bool overlap;
+ Uint8 *src, *dst;
+ int w, h;
+ int srcskip, dstskip;
+
+ w = info->dst_w * info->dst_fmt->BytesPerPixel;
+ h = info->dst_h;
+ src = info->src;
+ dst = info->dst;
+ srcskip = info->src_pitch;
+ dstskip = info->dst_pitch;
+
+ /* Properly handle overlapping blits */
+ if (src < dst) {
+ overlap = (dst < (src + h*srcskip));
+ } else {
+ overlap = (src < (dst + h*dstskip));
+ }
+ if (overlap) {
+ if ( dst < src ) {
+ while ( h-- ) {
+ SDL_memmove(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ src += ((h-1) * srcskip);
+ dst += ((h-1) * dstskip);
+ while ( h-- ) {
+ SDL_memmove(dst, src, w);
+ src -= srcskip;
+ dst -= dstskip;
+ }
+ }
+ return;
+ }
+
+#ifdef __SSE__
+ if (SDL_HasSSE() &&
+ !((uintptr_t) src & 15) && !(srcskip & 15) &&
+ !((uintptr_t) dst & 15) && !(dstskip & 15)) {
+ while (h--) {
+ SDL_memcpySSE(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+ return;
+ }
+#endif
+
+#ifdef __MMX__
+ if (SDL_HasMMX() && !(srcskip & 7) && !(dstskip & 7)) {
+ while (h--) {
+ SDL_memcpyMMX(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+ _mm_empty();
+ return;
+ }
+#endif
+
+ while (h--) {
+ SDL_memcpy(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_copy.h b/source/3rd-party/SDL2/src/video/SDL_blit_copy.h
new file mode 100644
index 0000000..d569ae0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_copy.h
@@ -0,0 +1,29 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_blit_copy_h_
+#define SDL_blit_copy_h_
+
+void SDL_BlitCopy(SDL_BlitInfo * info);
+
+#endif /* SDL_blit_copy_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_slow.c b/source/3rd-party/SDL2/src/video/SDL_blit_slow.c
new file mode 100644
index 0000000..20ca8ab
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_slow.c
@@ -0,0 +1,164 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+#include "SDL_blit_slow.h"
+
+/* The ONE TRUE BLITTER
+ * This puppy has to handle all the unoptimized cases - yes, it's slow.
+ */
+void
+SDL_Blit_Slow(SDL_BlitInfo * info)
+{
+ const int flags = info->flags;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+ const Uint32 modulateA = info->a;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+ Uint32 dstR, dstG, dstB, dstA;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+ SDL_PixelFormat *src_fmt = info->src_fmt;
+ SDL_PixelFormat *dst_fmt = info->dst_fmt;
+ int srcbpp = src_fmt->BytesPerPixel;
+ int dstbpp = dst_fmt->BytesPerPixel;
+ Uint32 rgbmask = ~src_fmt->Amask;
+ Uint32 ckey = info->colorkey & rgbmask;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ Uint8 *src = 0;
+ Uint8 *dst = (Uint8 *) info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src =
+ (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
+ }
+ if (src_fmt->Amask) {
+ DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
+ srcB, srcA);
+ } else {
+ DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
+ srcB);
+ srcA = 0xFF;
+ }
+ if (flags & SDL_COPY_COLORKEY) {
+ /* srcpixel isn't set for 24 bpp */
+ if (srcbpp == 3) {
+ srcpixel = (srcR << src_fmt->Rshift) |
+ (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
+ }
+ if ((srcpixel & rgbmask) == ckey) {
+ posx += incx;
+ dst += dstbpp;
+ continue;
+ }
+ }
+ if (dst_fmt->Amask) {
+ DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
+ dstB, dstA);
+ } else {
+ DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
+ dstB);
+ dstA = 0xFF;
+ }
+
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ srcR = (srcR * modulateR) / 255;
+ srcG = (srcG * modulateG) / 255;
+ srcB = (srcB * modulateB) / 255;
+ }
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ srcA = (srcA * modulateA) / 255;
+ }
+ if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (srcA < 255) {
+ srcR = (srcR * srcA) / 255;
+ srcG = (srcG * srcA) / 255;
+ srcB = (srcB * srcA) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
+ case 0:
+ dstR = srcR;
+ dstG = srcG;
+ dstB = srcB;
+ dstA = srcA;
+ break;
+ case SDL_COPY_BLEND:
+ dstR = srcR + ((255 - srcA) * dstR) / 255;
+ dstG = srcG + ((255 - srcA) * dstG) / 255;
+ dstB = srcB + ((255 - srcA) * dstB) / 255;
+ dstA = srcA + ((255 - srcA) * dstA) / 255;
+ break;
+ case SDL_COPY_ADD:
+ dstR = srcR + dstR;
+ if (dstR > 255)
+ dstR = 255;
+ dstG = srcG + dstG;
+ if (dstG > 255)
+ dstG = 255;
+ dstB = srcB + dstB;
+ if (dstB > 255)
+ dstB = 255;
+ break;
+ case SDL_COPY_MOD:
+ dstR = (srcR * dstR) / 255;
+ dstG = (srcG * dstG) / 255;
+ dstB = (srcB * dstB) / 255;
+ break;
+ }
+ if (dst_fmt->Amask) {
+ ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
+ } else {
+ ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
+ }
+ posx += incx;
+ dst += dstbpp;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_blit_slow.h b/source/3rd-party/SDL2/src/video/SDL_blit_slow.h
new file mode 100644
index 0000000..d27fcd2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_blit_slow.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_blit_slow_h_
+#define SDL_blit_slow_h_
+
+#include "../SDL_internal.h"
+
+extern void SDL_Blit_Slow(SDL_BlitInfo * info);
+
+#endif /* SDL_blit_slow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_bmp.c b/source/3rd-party/SDL2/src/video/SDL_bmp.c
new file mode 100644
index 0000000..ba908a6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_bmp.c
@@ -0,0 +1,702 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/*
+ Code to load and save surfaces in Windows BMP format.
+
+ Why support BMP format? Well, it's a native format for Windows, and
+ most image processing programs can read and write it. It would be nice
+ to be able to have at least one image format that we can natively load
+ and save, and since PNG is so complex that it would bloat the library,
+ BMP is a good alternative.
+
+ This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp.
+*/
+
+#include "SDL_hints.h"
+#include "SDL_video.h"
+#include "SDL_assert.h"
+#include "SDL_endian.h"
+#include "SDL_pixels_c.h"
+
+#define SAVE_32BIT_BMP
+
+/* Compression encodings for BMP files */
+#ifndef BI_RGB
+#define BI_RGB 0
+#define BI_RLE8 1
+#define BI_RLE4 2
+#define BI_BITFIELDS 3
+#endif
+
+/* Logical color space values for BMP files */
+#ifndef LCS_WINDOWS_COLOR_SPACE
+/* 0x57696E20 == "Win " */
+#define LCS_WINDOWS_COLOR_SPACE 0x57696E20
+#endif
+
+static void CorrectAlphaChannel(SDL_Surface *surface)
+{
+ /* Check to see if there is any alpha channel data */
+ SDL_bool hasAlpha = SDL_FALSE;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ int alphaChannelOffset = 0;
+#else
+ int alphaChannelOffset = 3;
+#endif
+ Uint8 *alpha = ((Uint8*)surface->pixels) + alphaChannelOffset;
+ Uint8 *end = alpha + surface->h * surface->pitch;
+
+ while (alpha < end) {
+ if (*alpha != 0) {
+ hasAlpha = SDL_TRUE;
+ break;
+ }
+ alpha += 4;
+ }
+
+ if (!hasAlpha) {
+ alpha = ((Uint8*)surface->pixels) + alphaChannelOffset;
+ while (alpha < end) {
+ *alpha = SDL_ALPHA_OPAQUE;
+ alpha += 4;
+ }
+ }
+}
+
+SDL_Surface *
+SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
+{
+ SDL_bool was_error;
+ Sint64 fp_offset = 0;
+ int bmpPitch;
+ int i, pad;
+ SDL_Surface *surface;
+ Uint32 Rmask = 0;
+ Uint32 Gmask = 0;
+ Uint32 Bmask = 0;
+ Uint32 Amask = 0;
+ SDL_Palette *palette;
+ Uint8 *bits;
+ Uint8 *top, *end;
+ SDL_bool topDown;
+ int ExpandBMP;
+ SDL_bool haveRGBMasks = SDL_FALSE;
+ SDL_bool haveAlphaMask = SDL_FALSE;
+ SDL_bool correctAlpha = SDL_FALSE;
+
+ /* The Win32 BMP file header (14 bytes) */
+ char magic[2];
+ /* Uint32 bfSize = 0; */
+ /* Uint16 bfReserved1 = 0; */
+ /* Uint16 bfReserved2 = 0; */
+ Uint32 bfOffBits = 0;
+
+ /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
+ Uint32 biSize = 0;
+ Sint32 biWidth = 0;
+ Sint32 biHeight = 0;
+ /* Uint16 biPlanes = 0; */
+ Uint16 biBitCount = 0;
+ Uint32 biCompression = 0;
+ /* Uint32 biSizeImage = 0; */
+ /* Sint32 biXPelsPerMeter = 0; */
+ /* Sint32 biYPelsPerMeter = 0; */
+ Uint32 biClrUsed = 0;
+ /* Uint32 biClrImportant = 0; */
+
+ (void) haveRGBMasks;
+ (void) haveAlphaMask;
+
+ /* Make sure we are passed a valid data source */
+ surface = NULL;
+ was_error = SDL_FALSE;
+ if (src == NULL) {
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Read in the BMP file header */
+ fp_offset = SDL_RWtell(src);
+ SDL_ClearError();
+ if (SDL_RWread(src, magic, 1, 2) != 2) {
+ SDL_Error(SDL_EFREAD);
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ if (SDL_strncmp(magic, "BM", 2) != 0) {
+ SDL_SetError("File is not a Windows BMP file");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ /* bfSize = */ SDL_ReadLE32(src);
+ /* bfReserved1 = */ SDL_ReadLE16(src);
+ /* bfReserved2 = */ SDL_ReadLE16(src);
+ bfOffBits = SDL_ReadLE32(src);
+
+ /* Read the Win32 BITMAPINFOHEADER */
+ biSize = SDL_ReadLE32(src);
+ if (biSize == 12) { /* really old BITMAPCOREHEADER */
+ biWidth = (Uint32) SDL_ReadLE16(src);
+ biHeight = (Uint32) SDL_ReadLE16(src);
+ /* biPlanes = */ SDL_ReadLE16(src);
+ biBitCount = SDL_ReadLE16(src);
+ biCompression = BI_RGB;
+ } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */
+ Uint32 headerSize;
+ biWidth = SDL_ReadLE32(src);
+ biHeight = SDL_ReadLE32(src);
+ /* biPlanes = */ SDL_ReadLE16(src);
+ biBitCount = SDL_ReadLE16(src);
+ biCompression = SDL_ReadLE32(src);
+ /* biSizeImage = */ SDL_ReadLE32(src);
+ /* biXPelsPerMeter = */ SDL_ReadLE32(src);
+ /* biYPelsPerMeter = */ SDL_ReadLE32(src);
+ biClrUsed = SDL_ReadLE32(src);
+ /* biClrImportant = */ SDL_ReadLE32(src);
+
+ /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
+ if (biSize == 64) {
+ /* ignore these extra fields. */
+ if (biCompression == BI_BITFIELDS) {
+ /* this value is actually huffman compression in this variant. */
+ SDL_SetError("Compressed BMP files not supported");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ } else {
+ /* This is complicated. If compression is BI_BITFIELDS, then
+ we have 3 DWORDS that specify the RGB masks. This is either
+ stored here in an BITMAPV2INFOHEADER (which only differs in
+ that it adds these RGB masks) and biSize >= 52, or we've got
+ these masks stored in the exact same place, but strictly
+ speaking, this is the bmiColors field in BITMAPINFO immediately
+ following the legacy v1 info header, just past biSize. */
+ if (biCompression == BI_BITFIELDS) {
+ haveRGBMasks = SDL_TRUE;
+ Rmask = SDL_ReadLE32(src);
+ Gmask = SDL_ReadLE32(src);
+ Bmask = SDL_ReadLE32(src);
+
+ /* ...v3 adds an alpha mask. */
+ if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
+ haveAlphaMask = SDL_TRUE;
+ Amask = SDL_ReadLE32(src);
+ }
+ } else {
+ /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
+ if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */
+ /*Rmask = */ SDL_ReadLE32(src);
+ /*Gmask = */ SDL_ReadLE32(src);
+ /*Bmask = */ SDL_ReadLE32(src);
+ }
+ if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
+ /*Amask = */ SDL_ReadLE32(src);
+ }
+ }
+
+ /* Insert other fields here; Wikipedia and MSDN say we're up to
+ v5 of this header, but we ignore those for now (they add gamma,
+ color spaces, etc). Ignoring the weird OS/2 2.x format, we
+ currently parse up to v3 correctly (hopefully!). */
+ }
+
+ /* skip any header bytes we didn't handle... */
+ headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14));
+ if (biSize > headerSize) {
+ SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR);
+ }
+ }
+ if (biHeight < 0) {
+ topDown = SDL_TRUE;
+ biHeight = -biHeight;
+ } else {
+ topDown = SDL_FALSE;
+ }
+
+ /* Check for read error */
+ if (SDL_strcmp(SDL_GetError(), "") != 0) {
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
+ switch (biBitCount) {
+ case 1:
+ case 4:
+ ExpandBMP = biBitCount;
+ biBitCount = 8;
+ break;
+ default:
+ ExpandBMP = 0;
+ break;
+ }
+
+ /* We don't support any BMP compression right now */
+ switch (biCompression) {
+ case BI_RGB:
+ /* If there are no masks, use the defaults */
+ SDL_assert(!haveRGBMasks);
+ SDL_assert(!haveAlphaMask);
+ /* Default values for the BMP format */
+ switch (biBitCount) {
+ case 15:
+ case 16:
+ Rmask = 0x7C00;
+ Gmask = 0x03E0;
+ Bmask = 0x001F;
+ break;
+ case 24:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Rmask = 0x000000FF;
+ Gmask = 0x0000FF00;
+ Bmask = 0x00FF0000;
+#else
+ Rmask = 0x00FF0000;
+ Gmask = 0x0000FF00;
+ Bmask = 0x000000FF;
+#endif
+ break;
+ case 32:
+ /* We don't know if this has alpha channel or not */
+ correctAlpha = SDL_TRUE;
+ Amask = 0xFF000000;
+ Rmask = 0x00FF0000;
+ Gmask = 0x0000FF00;
+ Bmask = 0x000000FF;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case BI_BITFIELDS:
+ break; /* we handled this in the info header. */
+
+ default:
+ SDL_SetError("Compressed BMP files not supported");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Create a compatible surface, note that the colors are RGB ordered */
+ surface =
+ SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
+ Bmask, Amask);
+ if (surface == NULL) {
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Load the palette, if any */
+ palette = (surface->format)->palette;
+ if (palette) {
+ SDL_assert(biBitCount <= 8);
+ if (biClrUsed == 0) {
+ biClrUsed = 1 << biBitCount;
+ }
+ if ((int) biClrUsed > palette->ncolors) {
+ SDL_Color *colors;
+ int ncolors = biClrUsed;
+ colors =
+ (SDL_Color *) SDL_realloc(palette->colors,
+ ncolors *
+ sizeof(*palette->colors));
+ if (!colors) {
+ SDL_OutOfMemory();
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ palette->ncolors = ncolors;
+ palette->colors = colors;
+ } else if ((int) biClrUsed < palette->ncolors) {
+ palette->ncolors = biClrUsed;
+ }
+ if (biSize == 12) {
+ for (i = 0; i < (int) biClrUsed; ++i) {
+ SDL_RWread(src, &palette->colors[i].b, 1, 1);
+ SDL_RWread(src, &palette->colors[i].g, 1, 1);
+ SDL_RWread(src, &palette->colors[i].r, 1, 1);
+ palette->colors[i].a = SDL_ALPHA_OPAQUE;
+ }
+ } else {
+ for (i = 0; i < (int) biClrUsed; ++i) {
+ SDL_RWread(src, &palette->colors[i].b, 1, 1);
+ SDL_RWread(src, &palette->colors[i].g, 1, 1);
+ SDL_RWread(src, &palette->colors[i].r, 1, 1);
+ SDL_RWread(src, &palette->colors[i].a, 1, 1);
+
+ /* According to Microsoft documentation, the fourth element
+ is reserved and must be zero, so we shouldn't treat it as
+ alpha.
+ */
+ palette->colors[i].a = SDL_ALPHA_OPAQUE;
+ }
+ }
+ }
+
+ /* Read the surface pixels. Note that the bmp image is upside down */
+ if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
+ SDL_Error(SDL_EFSEEK);
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ top = (Uint8 *)surface->pixels;
+ end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
+ switch (ExpandBMP) {
+ case 1:
+ bmpPitch = (biWidth + 7) >> 3;
+ pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
+ break;
+ case 4:
+ bmpPitch = (biWidth + 1) >> 1;
+ pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0);
+ break;
+ default:
+ pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0);
+ break;
+ }
+ if (topDown) {
+ bits = top;
+ } else {
+ bits = end - surface->pitch;
+ }
+ while (bits >= top && bits < end) {
+ switch (ExpandBMP) {
+ case 1:
+ case 4:{
+ Uint8 pixel = 0;
+ int shift = (8 - ExpandBMP);
+ for (i = 0; i < surface->w; ++i) {
+ if (i % (8 / ExpandBMP) == 0) {
+ if (!SDL_RWread(src, &pixel, 1, 1)) {
+ SDL_SetError("Error reading from BMP");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ }
+ *(bits + i) = (pixel >> shift);
+ pixel <<= ExpandBMP;
+ }
+ }
+ break;
+
+ default:
+ if (SDL_RWread(src, bits, 1, surface->pitch)
+ != surface->pitch) {
+ SDL_Error(SDL_EFREAD);
+ was_error = SDL_TRUE;
+ goto done;
+ }
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ /* Byte-swap the pixels if needed. Note that the 24bpp
+ case has already been taken care of above. */
+ switch (biBitCount) {
+ case 15:
+ case 16:{
+ Uint16 *pix = (Uint16 *) bits;
+ for (i = 0; i < surface->w; i++)
+ pix[i] = SDL_Swap16(pix[i]);
+ break;
+ }
+
+ case 32:{
+ Uint32 *pix = (Uint32 *) bits;
+ for (i = 0; i < surface->w; i++)
+ pix[i] = SDL_Swap32(pix[i]);
+ break;
+ }
+ }
+#endif
+ break;
+ }
+ /* Skip padding bytes, ugh */
+ if (pad) {
+ Uint8 padbyte;
+ for (i = 0; i < pad; ++i) {
+ SDL_RWread(src, &padbyte, 1, 1);
+ }
+ }
+ if (topDown) {
+ bits += surface->pitch;
+ } else {
+ bits -= surface->pitch;
+ }
+ }
+ if (correctAlpha) {
+ CorrectAlphaChannel(surface);
+ }
+ done:
+ if (was_error) {
+ if (src) {
+ SDL_RWseek(src, fp_offset, RW_SEEK_SET);
+ }
+ SDL_FreeSurface(surface);
+ surface = NULL;
+ }
+ if (freesrc && src) {
+ SDL_RWclose(src);
+ }
+ return (surface);
+}
+
+int
+SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
+{
+ Sint64 fp_offset;
+ int i, pad;
+ SDL_Surface *surface;
+ Uint8 *bits;
+ SDL_bool save32bit = SDL_FALSE;
+ SDL_bool saveLegacyBMP = SDL_FALSE;
+
+ /* The Win32 BMP file header (14 bytes) */
+ char magic[2] = { 'B', 'M' };
+ Uint32 bfSize;
+ Uint16 bfReserved1;
+ Uint16 bfReserved2;
+ Uint32 bfOffBits;
+
+ /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
+ Uint32 biSize;
+ Sint32 biWidth;
+ Sint32 biHeight;
+ Uint16 biPlanes;
+ Uint16 biBitCount;
+ Uint32 biCompression;
+ Uint32 biSizeImage;
+ Sint32 biXPelsPerMeter;
+ Sint32 biYPelsPerMeter;
+ Uint32 biClrUsed;
+ Uint32 biClrImportant;
+
+ /* The additional header members from the Win32 BITMAPV4HEADER struct (108 bytes in total) */
+ Uint32 bV4RedMask = 0;
+ Uint32 bV4GreenMask = 0;
+ Uint32 bV4BlueMask = 0;
+ Uint32 bV4AlphaMask = 0;
+ Uint32 bV4CSType = 0;
+ Sint32 bV4Endpoints[3 * 3] = {0};
+ Uint32 bV4GammaRed = 0;
+ Uint32 bV4GammaGreen = 0;
+ Uint32 bV4GammaBlue = 0;
+
+ /* Make sure we have somewhere to save */
+ surface = NULL;
+ if (dst) {
+#ifdef SAVE_32BIT_BMP
+ /* We can save alpha information in a 32-bit BMP */
+ if (saveme->format->BitsPerPixel >= 8 && (saveme->format->Amask ||
+ saveme->map->info.flags & SDL_COPY_COLORKEY)) {
+ save32bit = SDL_TRUE;
+ }
+#endif /* SAVE_32BIT_BMP */
+
+ if (saveme->format->palette && !save32bit) {
+ if (saveme->format->BitsPerPixel == 8) {
+ surface = saveme;
+ } else {
+ SDL_SetError("%d bpp BMP files not supported",
+ saveme->format->BitsPerPixel);
+ }
+ } else if ((saveme->format->BitsPerPixel == 24) && !save32bit &&
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ (saveme->format->Rmask == 0x00FF0000) &&
+ (saveme->format->Gmask == 0x0000FF00) &&
+ (saveme->format->Bmask == 0x000000FF)
+#else
+ (saveme->format->Rmask == 0x000000FF) &&
+ (saveme->format->Gmask == 0x0000FF00) &&
+ (saveme->format->Bmask == 0x00FF0000)
+#endif
+ ) {
+ surface = saveme;
+ } else {
+ SDL_PixelFormat format;
+
+ /* If the surface has a colorkey or alpha channel we'll save a
+ 32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
+ if (save32bit) {
+ SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32);
+ } else {
+ SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
+ }
+ surface = SDL_ConvertSurface(saveme, &format, 0);
+ if (!surface) {
+ SDL_SetError("Couldn't convert image to %d bpp",
+ format.BitsPerPixel);
+ }
+ }
+ } else {
+ /* Set no error here because it may overwrite a more useful message from
+ SDL_RWFromFile() if SDL_SaveBMP_RW() is called from SDL_SaveBMP(). */
+ return -1;
+ }
+
+ if (save32bit) {
+ saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE);
+ }
+
+ if (surface && (SDL_LockSurface(surface) == 0)) {
+ const int bw = surface->w * surface->format->BytesPerPixel;
+
+ /* Set the BMP file header values */
+ bfSize = 0; /* We'll write this when we're done */
+ bfReserved1 = 0;
+ bfReserved2 = 0;
+ bfOffBits = 0; /* We'll write this when we're done */
+
+ /* Write the BMP file header values */
+ fp_offset = SDL_RWtell(dst);
+ SDL_ClearError();
+ SDL_RWwrite(dst, magic, 2, 1);
+ SDL_WriteLE32(dst, bfSize);
+ SDL_WriteLE16(dst, bfReserved1);
+ SDL_WriteLE16(dst, bfReserved2);
+ SDL_WriteLE32(dst, bfOffBits);
+
+ /* Set the BMP info values */
+ biSize = 40;
+ biWidth = surface->w;
+ biHeight = surface->h;
+ biPlanes = 1;
+ biBitCount = surface->format->BitsPerPixel;
+ biCompression = BI_RGB;
+ biSizeImage = surface->h * surface->pitch;
+ biXPelsPerMeter = 0;
+ biYPelsPerMeter = 0;
+ if (surface->format->palette) {
+ biClrUsed = surface->format->palette->ncolors;
+ } else {
+ biClrUsed = 0;
+ }
+ biClrImportant = 0;
+
+ /* Set the BMP info values for the version 4 header */
+ if (save32bit && !saveLegacyBMP) {
+ biSize = 108;
+ biCompression = BI_BITFIELDS;
+ /* The BMP format is always little endian, these masks stay the same */
+ bV4RedMask = 0x00ff0000;
+ bV4GreenMask = 0x0000ff00;
+ bV4BlueMask = 0x000000ff;
+ bV4AlphaMask = 0xff000000;
+ bV4CSType = LCS_WINDOWS_COLOR_SPACE;
+ bV4GammaRed = 0;
+ bV4GammaGreen = 0;
+ bV4GammaBlue = 0;
+ }
+
+ /* Write the BMP info values */
+ SDL_WriteLE32(dst, biSize);
+ SDL_WriteLE32(dst, biWidth);
+ SDL_WriteLE32(dst, biHeight);
+ SDL_WriteLE16(dst, biPlanes);
+ SDL_WriteLE16(dst, biBitCount);
+ SDL_WriteLE32(dst, biCompression);
+ SDL_WriteLE32(dst, biSizeImage);
+ SDL_WriteLE32(dst, biXPelsPerMeter);
+ SDL_WriteLE32(dst, biYPelsPerMeter);
+ SDL_WriteLE32(dst, biClrUsed);
+ SDL_WriteLE32(dst, biClrImportant);
+
+ /* Write the BMP info values for the version 4 header */
+ if (save32bit && !saveLegacyBMP) {
+ SDL_WriteLE32(dst, bV4RedMask);
+ SDL_WriteLE32(dst, bV4GreenMask);
+ SDL_WriteLE32(dst, bV4BlueMask);
+ SDL_WriteLE32(dst, bV4AlphaMask);
+ SDL_WriteLE32(dst, bV4CSType);
+ for (i = 0; i < 3 * 3; i++) {
+ SDL_WriteLE32(dst, bV4Endpoints[i]);
+ }
+ SDL_WriteLE32(dst, bV4GammaRed);
+ SDL_WriteLE32(dst, bV4GammaGreen);
+ SDL_WriteLE32(dst, bV4GammaBlue);
+ }
+
+ /* Write the palette (in BGR color order) */
+ if (surface->format->palette) {
+ SDL_Color *colors;
+ int ncolors;
+
+ colors = surface->format->palette->colors;
+ ncolors = surface->format->palette->ncolors;
+ for (i = 0; i < ncolors; ++i) {
+ SDL_RWwrite(dst, &colors[i].b, 1, 1);
+ SDL_RWwrite(dst, &colors[i].g, 1, 1);
+ SDL_RWwrite(dst, &colors[i].r, 1, 1);
+ SDL_RWwrite(dst, &colors[i].a, 1, 1);
+ }
+ }
+
+ /* Write the bitmap offset */
+ bfOffBits = (Uint32)(SDL_RWtell(dst) - fp_offset);
+ if (SDL_RWseek(dst, fp_offset + 10, RW_SEEK_SET) < 0) {
+ SDL_Error(SDL_EFSEEK);
+ }
+ SDL_WriteLE32(dst, bfOffBits);
+ if (SDL_RWseek(dst, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
+ SDL_Error(SDL_EFSEEK);
+ }
+
+ /* Write the bitmap image upside down */
+ bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch);
+ pad = ((bw % 4) ? (4 - (bw % 4)) : 0);
+ while (bits > (Uint8 *) surface->pixels) {
+ bits -= surface->pitch;
+ if (SDL_RWwrite(dst, bits, 1, bw) != bw) {
+ SDL_Error(SDL_EFWRITE);
+ break;
+ }
+ if (pad) {
+ const Uint8 padbyte = 0;
+ for (i = 0; i < pad; ++i) {
+ SDL_RWwrite(dst, &padbyte, 1, 1);
+ }
+ }
+ }
+
+ /* Write the BMP file size */
+ bfSize = (Uint32)(SDL_RWtell(dst) - fp_offset);
+ if (SDL_RWseek(dst, fp_offset + 2, RW_SEEK_SET) < 0) {
+ SDL_Error(SDL_EFSEEK);
+ }
+ SDL_WriteLE32(dst, bfSize);
+ if (SDL_RWseek(dst, fp_offset + bfSize, RW_SEEK_SET) < 0) {
+ SDL_Error(SDL_EFSEEK);
+ }
+
+ /* Close it up.. */
+ SDL_UnlockSurface(surface);
+ if (surface != saveme) {
+ SDL_FreeSurface(surface);
+ }
+ }
+
+ if (freedst && dst) {
+ SDL_RWclose(dst);
+ }
+ return ((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_clipboard.c b/source/3rd-party/SDL2/src/video/SDL_clipboard.c
new file mode 100644
index 0000000..0dd6a05
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_clipboard.c
@@ -0,0 +1,90 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_clipboard.h"
+#include "SDL_sysvideo.h"
+
+
+int
+SDL_SetClipboardText(const char *text)
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+ if (!_this) {
+ return SDL_SetError("Video subsystem must be initialized to set clipboard text");
+ }
+
+ if (!text) {
+ text = "";
+ }
+ if (_this->SetClipboardText) {
+ return _this->SetClipboardText(_this, text);
+ } else {
+ SDL_free(_this->clipboard_text);
+ _this->clipboard_text = SDL_strdup(text);
+ return 0;
+ }
+}
+
+char *
+SDL_GetClipboardText(void)
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+ if (!_this) {
+ SDL_SetError("Video subsystem must be initialized to get clipboard text");
+ return SDL_strdup("");
+ }
+
+ if (_this->GetClipboardText) {
+ return _this->GetClipboardText(_this);
+ } else {
+ const char *text = _this->clipboard_text;
+ if (!text) {
+ text = "";
+ }
+ return SDL_strdup(text);
+ }
+}
+
+SDL_bool
+SDL_HasClipboardText(void)
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+ if (!_this) {
+ SDL_SetError("Video subsystem must be initialized to check clipboard text");
+ return SDL_FALSE;
+ }
+
+ if (_this->HasClipboardText) {
+ return _this->HasClipboardText(_this);
+ } else {
+ if (_this->clipboard_text && _this->clipboard_text[0] != '\0') {
+ return SDL_TRUE;
+ } else {
+ return SDL_FALSE;
+ }
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_egl.c b/source/3rd-party/SDL2/src/video/SDL_egl.c
new file mode 100644
index 0000000..78abc03
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_egl.c
@@ -0,0 +1,920 @@
+/*
+ * Simple DirectMedia Layer
+ * Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+#include "../SDL_internal.h"
+
+#if SDL_VIDEO_OPENGL_EGL
+
+#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
+#include "../core/windows/SDL_windows.h"
+#endif
+#if SDL_VIDEO_DRIVER_ANDROID
+#include <android/native_window.h>
+#endif
+
+#include "SDL_sysvideo.h"
+#include "SDL_log.h"
+#include "SDL_egl_c.h"
+#include "SDL_loadso.h"
+#include "SDL_hints.h"
+
+#ifdef EGL_KHR_create_context
+/* EGL_OPENGL_ES3_BIT_KHR was added in version 13 of the extension. */
+#ifndef EGL_OPENGL_ES3_BIT_KHR
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#endif
+#endif /* EGL_KHR_create_context */
+
+#if SDL_VIDEO_DRIVER_RPI
+/* Raspbian places the OpenGL ES/EGL binaries in a non standard path */
+#define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" )
+#define DEFAULT_OGL_ES2 ( vc4 ? "libGLESv2.so.2" : "libbrcmGLESv2.so" )
+#define ALT_EGL "libEGL.so"
+#define ALT_OGL_ES2 "libGLESv2.so"
+#define DEFAULT_OGL_ES_PVR ( vc4 ? "libGLES_CM.so.1" : "libbrcmGLESv2.so" )
+#define DEFAULT_OGL_ES ( vc4 ? "libGLESv1_CM.so.1" : "libbrcmGLESv2.so" )
+
+#elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_VIVANTE
+/* Android */
+#define DEFAULT_EGL "libEGL.so"
+#define DEFAULT_OGL_ES2 "libGLESv2.so"
+#define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
+#define DEFAULT_OGL_ES "libGLESv1_CM.so"
+
+#elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
+/* EGL AND OpenGL ES support via ANGLE */
+#define DEFAULT_EGL "libEGL.dll"
+#define DEFAULT_OGL_ES2 "libGLESv2.dll"
+#define DEFAULT_OGL_ES_PVR "libGLES_CM.dll"
+#define DEFAULT_OGL_ES "libGLESv1_CM.dll"
+
+#elif SDL_VIDEO_DRIVER_COCOA
+/* EGL AND OpenGL ES support via ANGLE */
+#define DEFAULT_EGL "libEGL.dylib"
+#define DEFAULT_OGL_ES2 "libGLESv2.dylib"
+#define DEFAULT_OGL_ES_PVR "libGLES_CM.dylib" //???
+#define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //???
+
+#else
+/* Desktop Linux */
+#define DEFAULT_OGL "libGL.so.1"
+#define DEFAULT_EGL "libEGL.so.1"
+#define DEFAULT_OGL_ES2 "libGLESv2.so.2"
+#define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
+#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
+#endif /* SDL_VIDEO_DRIVER_RPI */
+
+#ifdef SDL_VIDEO_STATIC_ANGLE
+#define LOAD_FUNC(NAME) \
+_this->egl_data->NAME = (void *)NAME;
+#else
+#define LOAD_FUNC(NAME) \
+_this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
+if (!_this->egl_data->NAME) \
+{ \
+ return SDL_SetError("Could not retrieve EGL function " #NAME); \
+}
+#endif
+
+static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode)
+{
+#define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e;
+ switch (eglErrorCode) {
+ SDL_EGL_ERROR_TRANSLATE(EGL_SUCCESS);
+ SDL_EGL_ERROR_TRANSLATE(EGL_NOT_INITIALIZED);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ACCESS);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ALLOC);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ATTRIBUTE);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CONTEXT);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CONFIG);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CURRENT_SURFACE);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_DISPLAY);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_SURFACE);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_MATCH);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_PARAMETER);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_NATIVE_PIXMAP);
+ SDL_EGL_ERROR_TRANSLATE(EGL_BAD_NATIVE_WINDOW);
+ SDL_EGL_ERROR_TRANSLATE(EGL_CONTEXT_LOST);
+ }
+ return "";
+}
+
+int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode)
+{
+ const char * errorText = SDL_EGL_GetErrorName(eglErrorCode);
+ char altErrorText[32];
+ if (errorText[0] == '\0') {
+ /* An unknown-to-SDL error code was reported. Report its hexadecimal value, instead of its name. */
+ SDL_snprintf(altErrorText, SDL_arraysize(altErrorText), "0x%x", (unsigned int)eglErrorCode);
+ errorText = altErrorText;
+ }
+ return SDL_SetError("%s (call to %s failed, reporting an error of %s)", message, eglFunctionName, errorText);
+}
+
+/* EGL implementation of SDL OpenGL ES support */
+typedef enum {
+ SDL_EGL_DISPLAY_EXTENSION,
+ SDL_EGL_CLIENT_EXTENSION
+} SDL_EGL_ExtensionType;
+
+static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext)
+{
+ size_t ext_len;
+ const char *ext_override;
+ const char *egl_extstr;
+ const char *ext_start;
+
+ /* Invalid extensions can be rejected early */
+ if (ext == NULL || *ext == 0 || SDL_strchr(ext, ' ') != NULL) {
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid EGL extension"); */
+ return SDL_FALSE;
+ }
+
+ /* Extensions can be masked with an environment variable.
+ * Unlike the OpenGL override, this will use the set bits of an integer
+ * to disable the extension.
+ * Bit Action
+ * 0 If set, the display extension is masked and not present to SDL.
+ * 1 If set, the client extension is masked and not present to SDL.
+ */
+ ext_override = SDL_getenv(ext);
+ if (ext_override != NULL) {
+ int disable_ext = SDL_atoi(ext_override);
+ if (disable_ext & 0x01 && type == SDL_EGL_DISPLAY_EXTENSION) {
+ return SDL_FALSE;
+ } else if (disable_ext & 0x02 && type == SDL_EGL_CLIENT_EXTENSION) {
+ return SDL_FALSE;
+ }
+ }
+
+ ext_len = SDL_strlen(ext);
+ switch (type) {
+ case SDL_EGL_DISPLAY_EXTENSION:
+ egl_extstr = _this->egl_data->eglQueryString(_this->egl_data->egl_display, EGL_EXTENSIONS);
+ break;
+ case SDL_EGL_CLIENT_EXTENSION:
+ /* EGL_EXT_client_extensions modifies eglQueryString to return client extensions
+ * if EGL_NO_DISPLAY is passed. Implementations without it are required to return NULL.
+ * This behavior is included in EGL 1.5.
+ */
+ egl_extstr = _this->egl_data->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ break;
+ default:
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid extension type"); */
+ return SDL_FALSE;
+ }
+
+ if (egl_extstr != NULL) {
+ ext_start = egl_extstr;
+
+ while (*ext_start) {
+ ext_start = SDL_strstr(ext_start, ext);
+ if (ext_start == NULL) {
+ return SDL_FALSE;
+ }
+ /* Check if the match is not just a substring of one of the extensions */
+ if (ext_start == egl_extstr || *(ext_start - 1) == ' ') {
+ if (ext_start[ext_len] == ' ' || ext_start[ext_len] == 0) {
+ return SDL_TRUE;
+ }
+ }
+ /* If the search stopped in the middle of an extension, skip to the end of it */
+ ext_start += ext_len;
+ while (*ext_start != ' ' && *ext_start != 0) {
+ ext_start++;
+ }
+ }
+ }
+
+ return SDL_FALSE;
+}
+
+void *
+SDL_EGL_GetProcAddress(_THIS, const char *proc)
+{
+ static char procname[1024];
+ void *retval;
+
+ /* eglGetProcAddress is busted on Android http://code.google.com/p/android/issues/detail?id=7681 */
+#if !defined(SDL_VIDEO_DRIVER_ANDROID)
+ if (_this->egl_data->eglGetProcAddress) {
+ retval = _this->egl_data->eglGetProcAddress(proc);
+ if (retval) {
+ return retval;
+ }
+ }
+#endif
+
+ retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, proc);
+ if (!retval && SDL_strlen(proc) <= 1022) {
+ procname[0] = '_';
+ SDL_strlcpy(procname + 1, proc, 1022);
+ retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, procname);
+ }
+ return retval;
+}
+
+void
+SDL_EGL_UnloadLibrary(_THIS)
+{
+ if (_this->egl_data) {
+ if (_this->egl_data->egl_display) {
+ _this->egl_data->eglTerminate(_this->egl_data->egl_display);
+ _this->egl_data->egl_display = NULL;
+ }
+
+ if (_this->egl_data->dll_handle) {
+ SDL_UnloadObject(_this->egl_data->dll_handle);
+ _this->egl_data->dll_handle = NULL;
+ }
+ if (_this->egl_data->egl_dll_handle) {
+ SDL_UnloadObject(_this->egl_data->egl_dll_handle);
+ _this->egl_data->egl_dll_handle = NULL;
+ }
+
+ SDL_free(_this->egl_data);
+ _this->egl_data = NULL;
+ }
+}
+
+int
+SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display, EGLenum platform)
+{
+ void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */
+ const char *path = NULL;
+ int egl_version_major = 0, egl_version_minor = 0;
+#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
+ const char *d3dcompiler;
+#endif
+#if SDL_VIDEO_DRIVER_RPI
+ SDL_bool vc4 = (0 == access("/sys/module/vc4/", F_OK));
+#endif
+
+ if (_this->egl_data) {
+ return SDL_SetError("EGL context already created");
+ }
+
+ _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
+ if (!_this->egl_data) {
+ return SDL_OutOfMemory();
+ }
+
+#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
+ d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER);
+ if (!d3dcompiler) {
+ if (WIN_IsWindowsVistaOrGreater()) {
+ d3dcompiler = "d3dcompiler_46.dll";
+ } else {
+ d3dcompiler = "d3dcompiler_43.dll";
+ }
+ }
+ if (SDL_strcasecmp(d3dcompiler, "none") != 0) {
+ if (SDL_LoadObject(d3dcompiler) == NULL) {
+ SDL_ClearError();
+ }
+ }
+#endif
+
+#ifndef SDL_VIDEO_STATIC_ANGLE
+ /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */
+ path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
+ if (path != NULL) {
+ egl_dll_handle = SDL_LoadObject(path);
+ }
+
+ if (egl_dll_handle == NULL) {
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+ if (_this->gl_config.major_version > 1) {
+ path = DEFAULT_OGL_ES2;
+ egl_dll_handle = SDL_LoadObject(path);
+#ifdef ALT_OGL_ES2
+ if (egl_dll_handle == NULL && !vc4) {
+ path = ALT_OGL_ES2;
+ egl_dll_handle = SDL_LoadObject(path);
+ }
+#endif
+
+ } else {
+ path = DEFAULT_OGL_ES;
+ egl_dll_handle = SDL_LoadObject(path);
+ if (egl_dll_handle == NULL) {
+ path = DEFAULT_OGL_ES_PVR;
+ egl_dll_handle = SDL_LoadObject(path);
+ }
+#ifdef ALT_OGL_ES2
+ if (egl_dll_handle == NULL && !vc4) {
+ path = ALT_OGL_ES2;
+ egl_dll_handle = SDL_LoadObject(path);
+ }
+#endif
+ }
+ }
+#ifdef DEFAULT_OGL
+ else {
+ path = DEFAULT_OGL;
+ egl_dll_handle = SDL_LoadObject(path);
+ }
+#endif
+ }
+ _this->egl_data->egl_dll_handle = egl_dll_handle;
+
+ if (egl_dll_handle == NULL) {
+ return SDL_SetError("Could not initialize OpenGL / GLES library");
+ }
+
+ /* Loading libGL* in the previous step took care of loading libEGL.so, but we future proof by double checking */
+ if (egl_path != NULL) {
+ dll_handle = SDL_LoadObject(egl_path);
+ }
+ /* Try loading a EGL symbol, if it does not work try the default library paths */
+ if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
+ if (dll_handle != NULL) {
+ SDL_UnloadObject(dll_handle);
+ }
+ path = SDL_getenv("SDL_VIDEO_EGL_DRIVER");
+ if (path == NULL) {
+ path = DEFAULT_EGL;
+ }
+ dll_handle = SDL_LoadObject(path);
+
+#ifdef ALT_EGL
+ if (dll_handle == NULL && !vc4) {
+ path = ALT_EGL;
+ dll_handle = SDL_LoadObject(path);
+ }
+#endif
+
+ if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
+ if (dll_handle != NULL) {
+ SDL_UnloadObject(dll_handle);
+ }
+ return SDL_SetError("Could not load EGL library");
+ }
+ SDL_ClearError();
+ }
+#endif
+
+ _this->egl_data->dll_handle = dll_handle;
+
+ /* Load new function pointers */
+ LOAD_FUNC(eglGetDisplay);
+ LOAD_FUNC(eglInitialize);
+ LOAD_FUNC(eglTerminate);
+ LOAD_FUNC(eglGetProcAddress);
+ LOAD_FUNC(eglChooseConfig);
+ LOAD_FUNC(eglGetConfigAttrib);
+ LOAD_FUNC(eglCreateContext);
+ LOAD_FUNC(eglDestroyContext);
+ LOAD_FUNC(eglCreatePbufferSurface);
+ LOAD_FUNC(eglCreateWindowSurface);
+ LOAD_FUNC(eglDestroySurface);
+ LOAD_FUNC(eglMakeCurrent);
+ LOAD_FUNC(eglSwapBuffers);
+ LOAD_FUNC(eglSwapInterval);
+ LOAD_FUNC(eglWaitNative);
+ LOAD_FUNC(eglWaitGL);
+ LOAD_FUNC(eglBindAPI);
+ LOAD_FUNC(eglQueryString);
+ LOAD_FUNC(eglGetError);
+
+ if (_this->egl_data->eglQueryString) {
+ /* EGL 1.5 allows querying for client version */
+ const char *egl_version = _this->egl_data->eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
+ if (egl_version != NULL) {
+ if (SDL_sscanf(egl_version, "%d.%d", &egl_version_major, &egl_version_minor) != 2) {
+ egl_version_major = 0;
+ egl_version_minor = 0;
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not parse EGL version string: %s", egl_version);
+ }
+ }
+ }
+
+ _this->egl_data->egl_version_major = egl_version_major;
+ _this->egl_data->egl_version_minor = egl_version_minor;
+
+ if (egl_version_major == 1 && egl_version_minor == 5) {
+ LOAD_FUNC(eglGetPlatformDisplay);
+ }
+
+ _this->egl_data->egl_display = EGL_NO_DISPLAY;
+#if !defined(__WINRT__)
+ if (platform) {
+ if (egl_version_major == 1 && egl_version_minor == 5) {
+ _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(size_t)native_display, NULL);
+ } else {
+ if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) {
+ _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT");
+ if (_this->egl_data->eglGetPlatformDisplayEXT) {
+ _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(size_t)native_display, NULL);
+ }
+ }
+ }
+ }
+ /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */
+ if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
+ _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
+ }
+ if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
+ return SDL_SetError("Could not get EGL display");
+ }
+
+ if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
+ return SDL_SetError("Could not initialize EGL");
+ }
+#endif
+
+ if (path) {
+ SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1);
+ } else {
+ *_this->gl_config.driver_path = '\0';
+ }
+
+ return 0;
+}
+
+#ifdef DUMP_EGL_CONFIG
+
+#define ATTRIBUTE(_attr) { _attr, #_attr }
+
+typedef struct {
+ EGLint attribute;
+ char const* name;
+} Attribute;
+
+Attribute attributes[] = {
+ ATTRIBUTE( EGL_BUFFER_SIZE ),
+ ATTRIBUTE( EGL_ALPHA_SIZE ),
+ ATTRIBUTE( EGL_BLUE_SIZE ),
+ ATTRIBUTE( EGL_GREEN_SIZE ),
+ ATTRIBUTE( EGL_RED_SIZE ),
+ ATTRIBUTE( EGL_DEPTH_SIZE ),
+ ATTRIBUTE( EGL_STENCIL_SIZE ),
+ ATTRIBUTE( EGL_CONFIG_CAVEAT ),
+ ATTRIBUTE( EGL_CONFIG_ID ),
+ ATTRIBUTE( EGL_LEVEL ),
+ ATTRIBUTE( EGL_MAX_PBUFFER_HEIGHT ),
+ ATTRIBUTE( EGL_MAX_PBUFFER_WIDTH ),
+ ATTRIBUTE( EGL_MAX_PBUFFER_PIXELS ),
+ ATTRIBUTE( EGL_NATIVE_RENDERABLE ),
+ ATTRIBUTE( EGL_NATIVE_VISUAL_ID ),
+ ATTRIBUTE( EGL_NATIVE_VISUAL_TYPE ),
+ ATTRIBUTE( EGL_SAMPLES ),
+ ATTRIBUTE( EGL_SAMPLE_BUFFERS ),
+ ATTRIBUTE( EGL_SURFACE_TYPE ),
+ ATTRIBUTE( EGL_TRANSPARENT_TYPE ),
+ ATTRIBUTE( EGL_TRANSPARENT_BLUE_VALUE ),
+ ATTRIBUTE( EGL_TRANSPARENT_GREEN_VALUE ),
+ ATTRIBUTE( EGL_TRANSPARENT_RED_VALUE ),
+ ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGB ),
+ ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGBA ),
+ ATTRIBUTE( EGL_MIN_SWAP_INTERVAL ),
+ ATTRIBUTE( EGL_MAX_SWAP_INTERVAL ),
+ ATTRIBUTE( EGL_LUMINANCE_SIZE ),
+ ATTRIBUTE( EGL_ALPHA_MASK_SIZE ),
+ ATTRIBUTE( EGL_COLOR_BUFFER_TYPE ),
+ ATTRIBUTE( EGL_RENDERABLE_TYPE ),
+ ATTRIBUTE( EGL_MATCH_NATIVE_PIXMAP ),
+ ATTRIBUTE( EGL_CONFORMANT ),
+};
+
+
+static void dumpconfig(_THIS, EGLConfig config)
+{
+ int attr;
+ for (attr = 0 ; attr<sizeof(attributes)/sizeof(Attribute) ; attr++) {
+ EGLint value;
+ _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, attributes[attr].attribute, &value);
+ SDL_Log("\t%-32s: %10d (0x%08x)\n", attributes[attr].name, value, value);
+ }
+}
+
+#endif /* DUMP_EGL_CONFIG */
+
+int
+SDL_EGL_ChooseConfig(_THIS)
+{
+/* 64 seems nice. */
+ EGLint attribs[64];
+ EGLint found_configs = 0, value;
+#ifdef SDL_VIDEO_DRIVER_KMSDRM
+ /* Intel EGL on KMS/DRM (al least) returns invalid configs that confuse the bitdiff search used */
+ /* later in this function, so we simply use the first one when using the KMSDRM driver for now. */
+ EGLConfig configs[1];
+#else
+ /* 128 seems even nicer here */
+ EGLConfig configs[128];
+#endif
+ int i, j, best_bitdiff = -1, bitdiff;
+
+ if (!_this->egl_data) {
+ /* The EGL library wasn't loaded, SDL_GetError() should have info */
+ return -1;
+ }
+
+ /* Get a valid EGL configuration */
+ i = 0;
+ attribs[i++] = EGL_RED_SIZE;
+ attribs[i++] = _this->gl_config.red_size;
+ attribs[i++] = EGL_GREEN_SIZE;
+ attribs[i++] = _this->gl_config.green_size;
+ attribs[i++] = EGL_BLUE_SIZE;
+ attribs[i++] = _this->gl_config.blue_size;
+
+ if (_this->gl_config.alpha_size) {
+ attribs[i++] = EGL_ALPHA_SIZE;
+ attribs[i++] = _this->gl_config.alpha_size;
+ }
+
+ if (_this->gl_config.buffer_size) {
+ attribs[i++] = EGL_BUFFER_SIZE;
+ attribs[i++] = _this->gl_config.buffer_size;
+ }
+
+ attribs[i++] = EGL_DEPTH_SIZE;
+ attribs[i++] = _this->gl_config.depth_size;
+
+ if (_this->gl_config.stencil_size) {
+ attribs[i++] = EGL_STENCIL_SIZE;
+ attribs[i++] = _this->gl_config.stencil_size;
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ attribs[i++] = EGL_SAMPLE_BUFFERS;
+ attribs[i++] = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ attribs[i++] = EGL_SAMPLES;
+ attribs[i++] = _this->gl_config.multisamplesamples;
+ }
+
+ attribs[i++] = EGL_RENDERABLE_TYPE;
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+#ifdef EGL_KHR_create_context
+ if (_this->gl_config.major_version >= 3 &&
+ SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context")) {
+ attribs[i++] = EGL_OPENGL_ES3_BIT_KHR;
+ } else
+#endif
+ if (_this->gl_config.major_version >= 2) {
+ attribs[i++] = EGL_OPENGL_ES2_BIT;
+ } else {
+ attribs[i++] = EGL_OPENGL_ES_BIT;
+ }
+ _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
+ } else {
+ attribs[i++] = EGL_OPENGL_BIT;
+ _this->egl_data->eglBindAPI(EGL_OPENGL_API);
+ }
+
+ if (_this->egl_data->egl_surfacetype) {
+ attribs[i++] = EGL_SURFACE_TYPE;
+ attribs[i++] = _this->egl_data->egl_surfacetype;
+ }
+
+ attribs[i++] = EGL_NONE;
+
+ if (_this->egl_data->eglChooseConfig(_this->egl_data->egl_display,
+ attribs,
+ configs, SDL_arraysize(configs),
+ &found_configs) == EGL_FALSE ||
+ found_configs == 0) {
+ return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig");
+ }
+
+ /* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */
+ /* From those, we select the one that matches our requirements more closely via a makeshift algorithm */
+
+ for (i = 0; i < found_configs; i++ ) {
+ bitdiff = 0;
+ for (j = 0; j < SDL_arraysize(attribs) - 1; j += 2) {
+ if (attribs[j] == EGL_NONE) {
+ break;
+ }
+
+ if ( attribs[j+1] != EGL_DONT_CARE && (
+ attribs[j] == EGL_RED_SIZE ||
+ attribs[j] == EGL_GREEN_SIZE ||
+ attribs[j] == EGL_BLUE_SIZE ||
+ attribs[j] == EGL_ALPHA_SIZE ||
+ attribs[j] == EGL_DEPTH_SIZE ||
+ attribs[j] == EGL_STENCIL_SIZE)) {
+ _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], attribs[j], &value);
+ bitdiff += value - attribs[j + 1]; /* value is always >= attrib */
+ }
+ }
+
+ if (bitdiff < best_bitdiff || best_bitdiff == -1) {
+ _this->egl_data->egl_config = configs[i];
+
+ best_bitdiff = bitdiff;
+ }
+
+ if (bitdiff == 0) {
+ break; /* we found an exact match! */
+ }
+ }
+
+#ifdef DUMP_EGL_CONFIG
+ dumpconfig(_this, _this->egl_data->egl_config);
+#endif
+
+ return 0;
+}
+
+SDL_GLContext
+SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
+{
+ /* max 14 values plus terminator. */
+ EGLint attribs[15];
+ int attr = 0;
+
+ EGLContext egl_context, share_context = EGL_NO_CONTEXT;
+ EGLint profile_mask = _this->gl_config.profile_mask;
+ EGLint major_version = _this->gl_config.major_version;
+ EGLint minor_version = _this->gl_config.minor_version;
+ SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
+
+ if (!_this->egl_data) {
+ /* The EGL library wasn't loaded, SDL_GetError() should have info */
+ return NULL;
+ }
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (EGLContext)SDL_GL_GetCurrentContext();
+ }
+
+#if SDL_VIDEO_DRIVER_ANDROID
+ if ((_this->gl_config.flags & SDL_GL_CONTEXT_DEBUG_FLAG) != 0) {
+ /* If SDL_GL_CONTEXT_DEBUG_FLAG is set but EGL_KHR_debug unsupported, unset.
+ * This is required because some Android devices like to complain about it
+ * by "silently" failing, logging a hint which could be easily overlooked:
+ * E/libEGL (26984): validate_display:255 error 3008 (EGL_BAD_DISPLAY)
+ * The following explicitly checks for EGL_KHR_debug before EGL 1.5
+ */
+ int egl_version_major = _this->egl_data->egl_version_major;
+ int egl_version_minor = _this->egl_data->egl_version_minor;
+ if (((egl_version_major < 1) || (egl_version_major == 1 && egl_version_minor < 5)) &&
+ !SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_debug")) {
+ /* SDL profile bits match EGL profile bits. */
+ _this->gl_config.flags &= ~SDL_GL_CONTEXT_DEBUG_FLAG;
+ }
+ }
+#endif
+
+ /* Set the context version and other attributes. */
+ if ((major_version < 3 || (minor_version == 0 && profile_es)) &&
+ _this->gl_config.flags == 0 &&
+ (profile_mask == 0 || profile_es)) {
+ /* Create a context without using EGL_KHR_create_context attribs.
+ * When creating a GLES context without EGL_KHR_create_context we can
+ * only specify the major version. When creating a desktop GL context
+ * we can't specify any version, so we only try in that case when the
+ * version is less than 3.0 (matches SDL's GLX/WGL behavior.)
+ */
+ if (profile_es) {
+ attribs[attr++] = EGL_CONTEXT_CLIENT_VERSION;
+ attribs[attr++] = SDL_max(major_version, 1);
+ }
+ } else {
+#ifdef EGL_KHR_create_context
+ /* The Major/minor version, context profiles, and context flags can
+ * only be specified when this extension is available.
+ */
+ if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context")) {
+ attribs[attr++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
+ attribs[attr++] = major_version;
+ attribs[attr++] = EGL_CONTEXT_MINOR_VERSION_KHR;
+ attribs[attr++] = minor_version;
+
+ /* SDL profile bits match EGL profile bits. */
+ if (profile_mask != 0 && profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
+ attribs[attr++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
+ attribs[attr++] = profile_mask;
+ }
+
+ /* SDL flags match EGL flags. */
+ if (_this->gl_config.flags != 0) {
+ attribs[attr++] = EGL_CONTEXT_FLAGS_KHR;
+ attribs[attr++] = _this->gl_config.flags;
+ }
+ } else
+#endif /* EGL_KHR_create_context */
+ {
+ SDL_SetError("Could not create EGL context (context attributes are not supported)");
+ return NULL;
+ }
+ }
+
+ if (_this->gl_config.no_error) {
+#ifdef EGL_KHR_create_context_no_error
+ if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context_no_error")) {
+ attribs[attr++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
+ attribs[attr++] = _this->gl_config.no_error;
+ } else
+#endif
+ {
+ SDL_SetError("EGL implementation does not support no_error contexts");
+ return NULL;
+ }
+ }
+
+ attribs[attr++] = EGL_NONE;
+
+ /* Bind the API */
+ if (profile_es) {
+ _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
+ } else {
+ _this->egl_data->eglBindAPI(EGL_OPENGL_API);
+ }
+
+ egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
+ _this->egl_data->egl_config,
+ share_context, attribs);
+
+ if (egl_context == EGL_NO_CONTEXT) {
+ SDL_EGL_SetError("Could not create EGL context", "eglCreateContext");
+ return NULL;
+ }
+
+ _this->egl_data->egl_swapinterval = 0;
+
+ if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) {
+ /* Save the SDL error set by SDL_EGL_MakeCurrent */
+ char errorText[1024];
+ SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText));
+
+ /* Delete the context, which may alter the value returned by SDL_GetError() */
+ SDL_EGL_DeleteContext(_this, egl_context);
+
+ /* Restore the SDL error */
+ SDL_SetError("%s", errorText);
+
+ return NULL;
+ }
+
+ return (SDL_GLContext) egl_context;
+}
+
+int
+SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
+{
+ EGLContext egl_context = (EGLContext) context;
+
+ if (!_this->egl_data) {
+ return SDL_SetError("OpenGL not initialized");
+ }
+
+ /* The android emulator crashes badly if you try to eglMakeCurrent
+ * with a valid context and invalid surface, so we have to check for both here.
+ */
+ if (!egl_context || !egl_surface) {
+ _this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ } else {
+ if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
+ egl_surface, egl_surface, egl_context)) {
+ return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent");
+ }
+ }
+
+ return 0;
+}
+
+int
+SDL_EGL_SetSwapInterval(_THIS, int interval)
+{
+ EGLBoolean status;
+
+ if (!_this->egl_data) {
+ return SDL_SetError("EGL not initialized");
+ }
+
+ status = _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, interval);
+ if (status == EGL_TRUE) {
+ _this->egl_data->egl_swapinterval = interval;
+ return 0;
+ }
+
+ return SDL_EGL_SetError("Unable to set the EGL swap interval", "eglSwapInterval");
+}
+
+int
+SDL_EGL_GetSwapInterval(_THIS)
+{
+ if (!_this->egl_data) {
+ SDL_SetError("EGL not initialized");
+ return 0;
+ }
+
+ return _this->egl_data->egl_swapinterval;
+}
+
+int
+SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface)
+{
+ if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, egl_surface)) {
+ return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers");
+ }
+ return 0;
+}
+
+void
+SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ EGLContext egl_context = (EGLContext) context;
+
+ /* Clean up GLES and EGL */
+ if (!_this->egl_data) {
+ return;
+ }
+
+ if (egl_context != NULL && egl_context != EGL_NO_CONTEXT) {
+ _this->egl_data->eglDestroyContext(_this->egl_data->egl_display, egl_context);
+ }
+
+}
+
+EGLSurface *
+SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
+{
+ /* max 2 values plus terminator. */
+ EGLint attribs[3];
+ int attr = 0;
+
+ EGLSurface * surface;
+
+ if (SDL_EGL_ChooseConfig(_this) != 0) {
+ return EGL_NO_SURFACE;
+ }
+
+#if SDL_VIDEO_DRIVER_ANDROID
+ {
+ /* Android docs recommend doing this!
+ * Ref: http://developer.android.com/reference/android/app/NativeActivity.html
+ */
+ EGLint format;
+ _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
+ _this->egl_data->egl_config,
+ EGL_NATIVE_VISUAL_ID, &format);
+
+ ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
+ }
+#endif
+ if (_this->gl_config.framebuffer_srgb_capable) {
+#ifdef EGL_KHR_gl_colorspace
+ if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) {
+ attribs[attr++] = EGL_GL_COLORSPACE_KHR;
+ attribs[attr++] = EGL_GL_COLORSPACE_SRGB_KHR;
+ } else
+#endif
+ {
+ SDL_SetError("EGL implementation does not support sRGB system framebuffers");
+ return EGL_NO_SURFACE;
+ }
+ }
+
+ attribs[attr++] = EGL_NONE;
+
+ surface = _this->egl_data->eglCreateWindowSurface(
+ _this->egl_data->egl_display,
+ _this->egl_data->egl_config,
+ nw, &attribs[0]);
+ if (surface == EGL_NO_SURFACE) {
+ SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
+ }
+ return surface;
+}
+
+void
+SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface)
+{
+ if (!_this->egl_data) {
+ return;
+ }
+
+ if (egl_surface != EGL_NO_SURFACE) {
+ _this->egl_data->eglDestroySurface(_this->egl_data->egl_display, egl_surface);
+ }
+}
+
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/SDL_egl_c.h b/source/3rd-party/SDL2/src/video/SDL_egl_c.h
new file mode 100644
index 0000000..d1c4129
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_egl_c.h
@@ -0,0 +1,150 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#ifndef SDL_egl_h_
+#define SDL_egl_h_
+
+#if SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_egl.h"
+
+#include "SDL_sysvideo.h"
+
+typedef struct SDL_EGL_VideoData
+{
+ void *egl_dll_handle, *dll_handle;
+ EGLDisplay egl_display;
+ EGLConfig egl_config;
+ int egl_swapinterval;
+ int egl_surfacetype;
+ int egl_version_major, egl_version_minor;
+
+ EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display);
+ EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplay) (EGLenum platform,
+ void *native_display,
+ const EGLint *attrib_list);
+ EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplayEXT) (EGLenum platform,
+ void *native_display,
+ const EGLint *attrib_list);
+ EGLBoolean(EGLAPIENTRY *eglInitialize) (EGLDisplay dpy, EGLint * major,
+ EGLint * minor);
+ EGLBoolean(EGLAPIENTRY *eglTerminate) (EGLDisplay dpy);
+
+ void *(EGLAPIENTRY *eglGetProcAddress) (const char * procName);
+
+ EGLBoolean(EGLAPIENTRY *eglChooseConfig) (EGLDisplay dpy,
+ const EGLint * attrib_list,
+ EGLConfig * configs,
+ EGLint config_size, EGLint * num_config);
+
+ EGLContext(EGLAPIENTRY *eglCreateContext) (EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_list,
+ const EGLint * attrib_list);
+
+ EGLBoolean(EGLAPIENTRY *eglDestroyContext) (EGLDisplay dpy, EGLContext ctx);
+
+ EGLSurface(EGLAPIENTRY *eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
+ EGLint const* attrib_list);
+
+ EGLSurface(EGLAPIENTRY *eglCreateWindowSurface) (EGLDisplay dpy,
+ EGLConfig config,
+ NativeWindowType window,
+ const EGLint * attrib_list);
+ EGLBoolean(EGLAPIENTRY *eglDestroySurface) (EGLDisplay dpy, EGLSurface surface);
+
+ EGLBoolean(EGLAPIENTRY *eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx);
+
+ EGLBoolean(EGLAPIENTRY *eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw);
+
+ EGLBoolean(EGLAPIENTRY *eglSwapInterval) (EGLDisplay dpy, EGLint interval);
+
+ const char *(EGLAPIENTRY *eglQueryString) (EGLDisplay dpy, EGLint name);
+
+ EGLBoolean(EGLAPIENTRY *eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint * value);
+
+ EGLBoolean(EGLAPIENTRY *eglWaitNative) (EGLint engine);
+
+ EGLBoolean(EGLAPIENTRY *eglWaitGL)(void);
+
+ EGLBoolean(EGLAPIENTRY *eglBindAPI)(EGLenum);
+
+ EGLint(EGLAPIENTRY *eglGetError)(void);
+
+} SDL_EGL_VideoData;
+
+/* OpenGLES functions */
+extern int SDL_EGL_GetAttribute(_THIS, SDL_GLattr attrib, int *value);
+/* SDL_EGL_LoadLibrary can get a display for a specific platform (EGL_PLATFORM_*)
+ * or, if 0 is passed, let the implementation decide.
+ */
+extern int SDL_EGL_LoadLibrary(_THIS, const char *path, NativeDisplayType native_display, EGLenum platform);
+extern void *SDL_EGL_GetProcAddress(_THIS, const char *proc);
+extern void SDL_EGL_UnloadLibrary(_THIS);
+extern int SDL_EGL_ChooseConfig(_THIS);
+extern int SDL_EGL_SetSwapInterval(_THIS, int interval);
+extern int SDL_EGL_GetSwapInterval(_THIS);
+extern void SDL_EGL_DeleteContext(_THIS, SDL_GLContext context);
+extern EGLSurface *SDL_EGL_CreateSurface(_THIS, NativeWindowType nw);
+extern void SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface);
+
+/* These need to be wrapped to get the surface for the window by the platform GLES implementation */
+extern SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface);
+extern int SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context);
+extern int SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface);
+
+/* SDL Error-reporting */
+extern int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode);
+#define SDL_EGL_SetError(message, eglFunctionName) SDL_EGL_SetErrorEx(message, eglFunctionName, _this->egl_data->eglGetError())
+
+/* A few of useful macros */
+
+#define SDL_EGL_SwapWindow_impl(BACKEND) int \
+BACKEND ## _GLES_SwapWindow(_THIS, SDL_Window * window) \
+{\
+ return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);\
+}
+
+#define SDL_EGL_MakeCurrent_impl(BACKEND) int \
+BACKEND ## _GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) \
+{\
+ if (window && context) { \
+ return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); \
+ }\
+ else {\
+ return SDL_EGL_MakeCurrent(_this, NULL, NULL);\
+ }\
+}
+
+#define SDL_EGL_CreateContext_impl(BACKEND) SDL_GLContext \
+BACKEND ## _GLES_CreateContext(_THIS, SDL_Window * window) \
+{\
+ return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);\
+}
+
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_egl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_fillrect.c b/source/3rd-party/SDL2/src/video/SDL_fillrect.c
new file mode 100644
index 0000000..63f5fcb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_fillrect.c
@@ -0,0 +1,343 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+
+#ifdef __SSE__
+/* *INDENT-OFF* */
+
+#ifdef _MSC_VER
+#define SSE_BEGIN \
+ __m128 c128; \
+ c128.m128_u32[0] = color; \
+ c128.m128_u32[1] = color; \
+ c128.m128_u32[2] = color; \
+ c128.m128_u32[3] = color;
+#else
+#define SSE_BEGIN \
+ __m128 c128; \
+ DECLARE_ALIGNED(Uint32, cccc[4], 16); \
+ cccc[0] = color; \
+ cccc[1] = color; \
+ cccc[2] = color; \
+ cccc[3] = color; \
+ c128 = *(__m128 *)cccc;
+#endif
+
+#define SSE_WORK \
+ for (i = n / 64; i--;) { \
+ _mm_stream_ps((float *)(p+0), c128); \
+ _mm_stream_ps((float *)(p+16), c128); \
+ _mm_stream_ps((float *)(p+32), c128); \
+ _mm_stream_ps((float *)(p+48), c128); \
+ p += 64; \
+ }
+
+#define SSE_END
+
+#define DEFINE_SSE_FILLRECT(bpp, type) \
+static void \
+SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
+{ \
+ int i, n; \
+ Uint8 *p = NULL; \
+ \
+ SSE_BEGIN; \
+ \
+ while (h--) { \
+ n = w * bpp; \
+ p = pixels; \
+ \
+ if (n > 63) { \
+ int adjust = 16 - ((uintptr_t)p & 15); \
+ if (adjust < 16) { \
+ n -= adjust; \
+ adjust /= bpp; \
+ while (adjust--) { \
+ *((type *)p) = (type)color; \
+ p += bpp; \
+ } \
+ } \
+ SSE_WORK; \
+ } \
+ if (n & 63) { \
+ int remainder = (n & 63); \
+ remainder /= bpp; \
+ while (remainder--) { \
+ *((type *)p) = (type)color; \
+ p += bpp; \
+ } \
+ } \
+ pixels += pitch; \
+ } \
+ \
+ SSE_END; \
+}
+
+static void
+SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
+{
+ int i, n;
+
+ SSE_BEGIN;
+ while (h--) {
+ Uint8 *p = pixels;
+ n = w;
+
+ if (n > 63) {
+ int adjust = 16 - ((uintptr_t)p & 15);
+ if (adjust) {
+ n -= adjust;
+ SDL_memset(p, color, adjust);
+ p += adjust;
+ }
+ SSE_WORK;
+ }
+ if (n & 63) {
+ int remainder = (n & 63);
+ SDL_memset(p, color, remainder);
+ }
+ pixels += pitch;
+ }
+
+ SSE_END;
+}
+/* DEFINE_SSE_FILLRECT(1, Uint8) */
+DEFINE_SSE_FILLRECT(2, Uint16)
+DEFINE_SSE_FILLRECT(4, Uint32)
+
+/* *INDENT-ON* */
+#endif /* __SSE__ */
+
+static void
+SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+ int n;
+ Uint8 *p = NULL;
+
+ while (h--) {
+ n = w;
+ p = pixels;
+
+ if (n > 3) {
+ switch ((uintptr_t) p & 3) {
+ case 1:
+ *p++ = (Uint8) color;
+ --n; /* fallthrough */
+ case 2:
+ *p++ = (Uint8) color;
+ --n; /* fallthrough */
+ case 3:
+ *p++ = (Uint8) color;
+ --n; /* fallthrough */
+ }
+ SDL_memset4(p, color, (n >> 2));
+ }
+ if (n & 3) {
+ p += (n & ~3);
+ switch (n & 3) {
+ case 3:
+ *p++ = (Uint8) color; /* fallthrough */
+ case 2:
+ *p++ = (Uint8) color; /* fallthrough */
+ case 1:
+ *p++ = (Uint8) color; /* fallthrough */
+ }
+ }
+ pixels += pitch;
+ }
+}
+
+static void
+SDL_FillRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+ int n;
+ Uint16 *p = NULL;
+
+ while (h--) {
+ n = w;
+ p = (Uint16 *) pixels;
+
+ if (n > 1) {
+ if ((uintptr_t) p & 2) {
+ *p++ = (Uint16) color;
+ --n;
+ }
+ SDL_memset4(p, color, (n >> 1));
+ }
+ if (n & 1) {
+ p[n - 1] = (Uint16) color;
+ }
+ pixels += pitch;
+ }
+}
+
+static void
+SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ Uint8 b1 = (Uint8) (color & 0xFF);
+ Uint8 b2 = (Uint8) ((color >> 8) & 0xFF);
+ Uint8 b3 = (Uint8) ((color >> 16) & 0xFF);
+#elif SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Uint8 b1 = (Uint8) ((color >> 16) & 0xFF);
+ Uint8 b2 = (Uint8) ((color >> 8) & 0xFF);
+ Uint8 b3 = (Uint8) (color & 0xFF);
+#endif
+ int n;
+ Uint8 *p = NULL;
+
+ while (h--) {
+ n = w;
+ p = pixels;
+
+ while (n--) {
+ *p++ = b1;
+ *p++ = b2;
+ *p++ = b3;
+ }
+ pixels += pitch;
+ }
+}
+
+static void
+SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+ while (h--) {
+ SDL_memset4(pixels, color, w);
+ pixels += pitch;
+ }
+}
+
+/*
+ * This function performs a fast fill of the given rectangle with 'color'
+ */
+int
+SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
+{
+ SDL_Rect clipped;
+ Uint8 *pixels;
+
+ if (!dst) {
+ return SDL_SetError("Passed NULL destination surface");
+ }
+
+ /* This function doesn't work on surfaces < 8 bpp */
+ if (dst->format->BitsPerPixel < 8) {
+ return SDL_SetError("SDL_FillRect(): Unsupported surface format");
+ }
+
+ /* If 'rect' == NULL, then fill the whole surface */
+ if (rect) {
+ /* Perform clipping */
+ if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
+ return 0;
+ }
+ rect = &clipped;
+ } else {
+ rect = &dst->clip_rect;
+ /* Don't attempt to fill if the surface's clip_rect is empty */
+ if (SDL_RectEmpty(rect)) {
+ return 0;
+ }
+ }
+
+ /* Perform software fill */
+ if (!dst->pixels) {
+ return SDL_SetError("SDL_FillRect(): You must lock the surface");
+ }
+
+ pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
+ rect->x * dst->format->BytesPerPixel;
+
+ switch (dst->format->BytesPerPixel) {
+ case 1:
+ {
+ color |= (color << 8);
+ color |= (color << 16);
+#ifdef __SSE__
+ if (SDL_HasSSE()) {
+ SDL_FillRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+#endif
+ SDL_FillRect1(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+
+ case 2:
+ {
+ color |= (color << 16);
+#ifdef __SSE__
+ if (SDL_HasSSE()) {
+ SDL_FillRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+#endif
+ SDL_FillRect2(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+
+ case 3:
+ /* 24-bit RGB is a slow path, at least for now. */
+ {
+ SDL_FillRect3(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+
+ case 4:
+ {
+#ifdef __SSE__
+ if (SDL_HasSSE()) {
+ SDL_FillRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+#endif
+ SDL_FillRect4(pixels, dst->pitch, color, rect->w, rect->h);
+ break;
+ }
+ }
+
+ /* We're done! */
+ return 0;
+}
+
+int
+SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
+ Uint32 color)
+{
+ int i;
+ int status = 0;
+
+ if (!rects) {
+ return SDL_SetError("SDL_FillRects() passed NULL rects");
+ }
+
+ for (i = 0; i < count; ++i) {
+ status += SDL_FillRect(dst, &rects[i], color);
+ }
+ return status;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_pixels.c b/source/3rd-party/SDL2/src/video/SDL_pixels.c
new file mode 100644
index 0000000..c2e4163
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_pixels.c
@@ -0,0 +1,1125 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/* General (mostly internal) pixel/color manipulation routines for SDL */
+
+#include "SDL_endian.h"
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_pixels_c.h"
+#include "SDL_RLEaccel_c.h"
+
+
+/* Lookup tables to expand partial bytes to the full 0..255 range */
+
+static Uint8 lookup_0[] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+static Uint8 lookup_1[] = {
+0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
+};
+
+static Uint8 lookup_2[] = {
+0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255
+};
+
+static Uint8 lookup_3[] = {
+0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255
+};
+
+static Uint8 lookup_4[] = {
+0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
+};
+
+static Uint8 lookup_5[] = {
+0, 36, 72, 109, 145, 182, 218, 255
+};
+
+static Uint8 lookup_6[] = {
+0, 85, 170, 255
+};
+
+static Uint8 lookup_7[] = {
+0, 255
+};
+
+static Uint8 lookup_8[] = {
+255
+};
+
+Uint8* SDL_expand_byte[9] = {
+ lookup_0,
+ lookup_1,
+ lookup_2,
+ lookup_3,
+ lookup_4,
+ lookup_5,
+ lookup_6,
+ lookup_7,
+ lookup_8
+};
+
+/* Helper functions */
+
+const char*
+SDL_GetPixelFormatName(Uint32 format)
+{
+ switch (format) {
+#define CASE(X) case X: return #X;
+ CASE(SDL_PIXELFORMAT_INDEX1LSB)
+ CASE(SDL_PIXELFORMAT_INDEX1MSB)
+ CASE(SDL_PIXELFORMAT_INDEX4LSB)
+ CASE(SDL_PIXELFORMAT_INDEX4MSB)
+ CASE(SDL_PIXELFORMAT_INDEX8)
+ CASE(SDL_PIXELFORMAT_RGB332)
+ CASE(SDL_PIXELFORMAT_RGB444)
+ CASE(SDL_PIXELFORMAT_RGB555)
+ CASE(SDL_PIXELFORMAT_BGR555)
+ CASE(SDL_PIXELFORMAT_ARGB4444)
+ CASE(SDL_PIXELFORMAT_RGBA4444)
+ CASE(SDL_PIXELFORMAT_ABGR4444)
+ CASE(SDL_PIXELFORMAT_BGRA4444)
+ CASE(SDL_PIXELFORMAT_ARGB1555)
+ CASE(SDL_PIXELFORMAT_RGBA5551)
+ CASE(SDL_PIXELFORMAT_ABGR1555)
+ CASE(SDL_PIXELFORMAT_BGRA5551)
+ CASE(SDL_PIXELFORMAT_RGB565)
+ CASE(SDL_PIXELFORMAT_BGR565)
+ CASE(SDL_PIXELFORMAT_RGB24)
+ CASE(SDL_PIXELFORMAT_BGR24)
+ CASE(SDL_PIXELFORMAT_RGB888)
+ CASE(SDL_PIXELFORMAT_RGBX8888)
+ CASE(SDL_PIXELFORMAT_BGR888)
+ CASE(SDL_PIXELFORMAT_BGRX8888)
+ CASE(SDL_PIXELFORMAT_ARGB8888)
+ CASE(SDL_PIXELFORMAT_RGBA8888)
+ CASE(SDL_PIXELFORMAT_ABGR8888)
+ CASE(SDL_PIXELFORMAT_BGRA8888)
+ CASE(SDL_PIXELFORMAT_ARGB2101010)
+ CASE(SDL_PIXELFORMAT_YV12)
+ CASE(SDL_PIXELFORMAT_IYUV)
+ CASE(SDL_PIXELFORMAT_YUY2)
+ CASE(SDL_PIXELFORMAT_UYVY)
+ CASE(SDL_PIXELFORMAT_YVYU)
+ CASE(SDL_PIXELFORMAT_NV12)
+ CASE(SDL_PIXELFORMAT_NV21)
+#undef CASE
+ default:
+ return "SDL_PIXELFORMAT_UNKNOWN";
+ }
+}
+
+SDL_bool
+SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask,
+ Uint32 * Gmask, Uint32 * Bmask, Uint32 * Amask)
+{
+ Uint32 masks[4];
+
+ /* This function doesn't work with FourCC pixel formats */
+ if (SDL_ISPIXELFORMAT_FOURCC(format)) {
+ SDL_SetError("FOURCC pixel formats are not supported");
+ return SDL_FALSE;
+ }
+
+ /* Initialize the values here */
+ if (SDL_BYTESPERPIXEL(format) <= 2) {
+ *bpp = SDL_BITSPERPIXEL(format);
+ } else {
+ *bpp = SDL_BYTESPERPIXEL(format) * 8;
+ }
+ *Rmask = *Gmask = *Bmask = *Amask = 0;
+
+ if (format == SDL_PIXELFORMAT_RGB24) {
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ *Rmask = 0x00FF0000;
+ *Gmask = 0x0000FF00;
+ *Bmask = 0x000000FF;
+#else
+ *Rmask = 0x000000FF;
+ *Gmask = 0x0000FF00;
+ *Bmask = 0x00FF0000;
+#endif
+ return SDL_TRUE;
+ }
+
+ if (format == SDL_PIXELFORMAT_BGR24) {
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ *Rmask = 0x000000FF;
+ *Gmask = 0x0000FF00;
+ *Bmask = 0x00FF0000;
+#else
+ *Rmask = 0x00FF0000;
+ *Gmask = 0x0000FF00;
+ *Bmask = 0x000000FF;
+#endif
+ return SDL_TRUE;
+ }
+
+ if (SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED8 &&
+ SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED16 &&
+ SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED32) {
+ /* Not a format that uses masks */
+ return SDL_TRUE;
+ }
+
+ switch (SDL_PIXELLAYOUT(format)) {
+ case SDL_PACKEDLAYOUT_332:
+ masks[0] = 0x00000000;
+ masks[1] = 0x000000E0;
+ masks[2] = 0x0000001C;
+ masks[3] = 0x00000003;
+ break;
+ case SDL_PACKEDLAYOUT_4444:
+ masks[0] = 0x0000F000;
+ masks[1] = 0x00000F00;
+ masks[2] = 0x000000F0;
+ masks[3] = 0x0000000F;
+ break;
+ case SDL_PACKEDLAYOUT_1555:
+ masks[0] = 0x00008000;
+ masks[1] = 0x00007C00;
+ masks[2] = 0x000003E0;
+ masks[3] = 0x0000001F;
+ break;
+ case SDL_PACKEDLAYOUT_5551:
+ masks[0] = 0x0000F800;
+ masks[1] = 0x000007C0;
+ masks[2] = 0x0000003E;
+ masks[3] = 0x00000001;
+ break;
+ case SDL_PACKEDLAYOUT_565:
+ masks[0] = 0x00000000;
+ masks[1] = 0x0000F800;
+ masks[2] = 0x000007E0;
+ masks[3] = 0x0000001F;
+ break;
+ case SDL_PACKEDLAYOUT_8888:
+ masks[0] = 0xFF000000;
+ masks[1] = 0x00FF0000;
+ masks[2] = 0x0000FF00;
+ masks[3] = 0x000000FF;
+ break;
+ case SDL_PACKEDLAYOUT_2101010:
+ masks[0] = 0xC0000000;
+ masks[1] = 0x3FF00000;
+ masks[2] = 0x000FFC00;
+ masks[3] = 0x000003FF;
+ break;
+ case SDL_PACKEDLAYOUT_1010102:
+ masks[0] = 0xFFC00000;
+ masks[1] = 0x003FF000;
+ masks[2] = 0x00000FFC;
+ masks[3] = 0x00000003;
+ break;
+ default:
+ SDL_SetError("Unknown pixel format");
+ return SDL_FALSE;
+ }
+
+ switch (SDL_PIXELORDER(format)) {
+ case SDL_PACKEDORDER_XRGB:
+ *Rmask = masks[1];
+ *Gmask = masks[2];
+ *Bmask = masks[3];
+ break;
+ case SDL_PACKEDORDER_RGBX:
+ *Rmask = masks[0];
+ *Gmask = masks[1];
+ *Bmask = masks[2];
+ break;
+ case SDL_PACKEDORDER_ARGB:
+ *Amask = masks[0];
+ *Rmask = masks[1];
+ *Gmask = masks[2];
+ *Bmask = masks[3];
+ break;
+ case SDL_PACKEDORDER_RGBA:
+ *Rmask = masks[0];
+ *Gmask = masks[1];
+ *Bmask = masks[2];
+ *Amask = masks[3];
+ break;
+ case SDL_PACKEDORDER_XBGR:
+ *Bmask = masks[1];
+ *Gmask = masks[2];
+ *Rmask = masks[3];
+ break;
+ case SDL_PACKEDORDER_BGRX:
+ *Bmask = masks[0];
+ *Gmask = masks[1];
+ *Rmask = masks[2];
+ break;
+ case SDL_PACKEDORDER_BGRA:
+ *Bmask = masks[0];
+ *Gmask = masks[1];
+ *Rmask = masks[2];
+ *Amask = masks[3];
+ break;
+ case SDL_PACKEDORDER_ABGR:
+ *Amask = masks[0];
+ *Bmask = masks[1];
+ *Gmask = masks[2];
+ *Rmask = masks[3];
+ break;
+ default:
+ SDL_SetError("Unknown pixel format");
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+Uint32
+SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
+ Uint32 Amask)
+{
+ switch (bpp) {
+ case 1:
+ /* SDL defaults to MSB ordering */
+ return SDL_PIXELFORMAT_INDEX1MSB;
+ case 4:
+ /* SDL defaults to MSB ordering */
+ return SDL_PIXELFORMAT_INDEX4MSB;
+ case 8:
+ if (Rmask == 0) {
+ return SDL_PIXELFORMAT_INDEX8;
+ }
+ if (Rmask == 0xE0 &&
+ Gmask == 0x1C &&
+ Bmask == 0x03 &&
+ Amask == 0x00) {
+ return SDL_PIXELFORMAT_RGB332;
+ }
+ break;
+ case 12:
+ if (Rmask == 0) {
+ return SDL_PIXELFORMAT_RGB444;
+ }
+ if (Rmask == 0x0F00 &&
+ Gmask == 0x00F0 &&
+ Bmask == 0x000F &&
+ Amask == 0x0000) {
+ return SDL_PIXELFORMAT_RGB444;
+ }
+ break;
+ case 15:
+ if (Rmask == 0) {
+ return SDL_PIXELFORMAT_RGB555;
+ }
+ /* fallthrough */
+ case 16:
+ if (Rmask == 0) {
+ return SDL_PIXELFORMAT_RGB565;
+ }
+ if (Rmask == 0x7C00 &&
+ Gmask == 0x03E0 &&
+ Bmask == 0x001F &&
+ Amask == 0x0000) {
+ return SDL_PIXELFORMAT_RGB555;
+ }
+ if (Rmask == 0x001F &&
+ Gmask == 0x03E0 &&
+ Bmask == 0x7C00 &&
+ Amask == 0x0000) {
+ return SDL_PIXELFORMAT_BGR555;
+ }
+ if (Rmask == 0x0F00 &&
+ Gmask == 0x00F0 &&
+ Bmask == 0x000F &&
+ Amask == 0xF000) {
+ return SDL_PIXELFORMAT_ARGB4444;
+ }
+ if (Rmask == 0xF000 &&
+ Gmask == 0x0F00 &&
+ Bmask == 0x00F0 &&
+ Amask == 0x000F) {
+ return SDL_PIXELFORMAT_RGBA4444;
+ }
+ if (Rmask == 0x000F &&
+ Gmask == 0x00F0 &&
+ Bmask == 0x0F00 &&
+ Amask == 0xF000) {
+ return SDL_PIXELFORMAT_ABGR4444;
+ }
+ if (Rmask == 0x00F0 &&
+ Gmask == 0x0F00 &&
+ Bmask == 0xF000 &&
+ Amask == 0x000F) {
+ return SDL_PIXELFORMAT_BGRA4444;
+ }
+ if (Rmask == 0x7C00 &&
+ Gmask == 0x03E0 &&
+ Bmask == 0x001F &&
+ Amask == 0x8000) {
+ return SDL_PIXELFORMAT_ARGB1555;
+ }
+ if (Rmask == 0xF800 &&
+ Gmask == 0x07C0 &&
+ Bmask == 0x003E &&
+ Amask == 0x0001) {
+ return SDL_PIXELFORMAT_RGBA5551;
+ }
+ if (Rmask == 0x001F &&
+ Gmask == 0x03E0 &&
+ Bmask == 0x7C00 &&
+ Amask == 0x8000) {
+ return SDL_PIXELFORMAT_ABGR1555;
+ }
+ if (Rmask == 0x003E &&
+ Gmask == 0x07C0 &&
+ Bmask == 0xF800 &&
+ Amask == 0x0001) {
+ return SDL_PIXELFORMAT_BGRA5551;
+ }
+ if (Rmask == 0xF800 &&
+ Gmask == 0x07E0 &&
+ Bmask == 0x001F &&
+ Amask == 0x0000) {
+ return SDL_PIXELFORMAT_RGB565;
+ }
+ if (Rmask == 0x001F &&
+ Gmask == 0x07E0 &&
+ Bmask == 0xF800 &&
+ Amask == 0x0000) {
+ return SDL_PIXELFORMAT_BGR565;
+ }
+ if (Rmask == 0x003F &&
+ Gmask == 0x07C0 &&
+ Bmask == 0xF800 &&
+ Amask == 0x0000) {
+ /* Technically this would be BGR556, but Witek says this works in bug 3158 */
+ return SDL_PIXELFORMAT_RGB565;
+ }
+ break;
+ case 24:
+ switch (Rmask) {
+ case 0:
+ case 0x00FF0000:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ return SDL_PIXELFORMAT_RGB24;
+#else
+ return SDL_PIXELFORMAT_BGR24;
+#endif
+ case 0x000000FF:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ return SDL_PIXELFORMAT_BGR24;
+#else
+ return SDL_PIXELFORMAT_RGB24;
+#endif
+ }
+ case 32:
+ if (Rmask == 0) {
+ return SDL_PIXELFORMAT_RGB888;
+ }
+ if (Rmask == 0x00FF0000 &&
+ Gmask == 0x0000FF00 &&
+ Bmask == 0x000000FF &&
+ Amask == 0x00000000) {
+ return SDL_PIXELFORMAT_RGB888;
+ }
+ if (Rmask == 0xFF000000 &&
+ Gmask == 0x00FF0000 &&
+ Bmask == 0x0000FF00 &&
+ Amask == 0x00000000) {
+ return SDL_PIXELFORMAT_RGBX8888;
+ }
+ if (Rmask == 0x000000FF &&
+ Gmask == 0x0000FF00 &&
+ Bmask == 0x00FF0000 &&
+ Amask == 0x00000000) {
+ return SDL_PIXELFORMAT_BGR888;
+ }
+ if (Rmask == 0x0000FF00 &&
+ Gmask == 0x00FF0000 &&
+ Bmask == 0xFF000000 &&
+ Amask == 0x00000000) {
+ return SDL_PIXELFORMAT_BGRX8888;
+ }
+ if (Rmask == 0x00FF0000 &&
+ Gmask == 0x0000FF00 &&
+ Bmask == 0x000000FF &&
+ Amask == 0xFF000000) {
+ return SDL_PIXELFORMAT_ARGB8888;
+ }
+ if (Rmask == 0xFF000000 &&
+ Gmask == 0x00FF0000 &&
+ Bmask == 0x0000FF00 &&
+ Amask == 0x000000FF) {
+ return SDL_PIXELFORMAT_RGBA8888;
+ }
+ if (Rmask == 0x000000FF &&
+ Gmask == 0x0000FF00 &&
+ Bmask == 0x00FF0000 &&
+ Amask == 0xFF000000) {
+ return SDL_PIXELFORMAT_ABGR8888;
+ }
+ if (Rmask == 0x0000FF00 &&
+ Gmask == 0x00FF0000 &&
+ Bmask == 0xFF000000 &&
+ Amask == 0x000000FF) {
+ return SDL_PIXELFORMAT_BGRA8888;
+ }
+ if (Rmask == 0x3FF00000 &&
+ Gmask == 0x000FFC00 &&
+ Bmask == 0x000003FF &&
+ Amask == 0xC0000000) {
+ return SDL_PIXELFORMAT_ARGB2101010;
+ }
+ }
+ return SDL_PIXELFORMAT_UNKNOWN;
+}
+
+static SDL_PixelFormat *formats;
+static SDL_SpinLock formats_lock = 0;
+
+SDL_PixelFormat *
+SDL_AllocFormat(Uint32 pixel_format)
+{
+ SDL_PixelFormat *format;
+
+ SDL_AtomicLock(&formats_lock);
+
+ /* Look it up in our list of previously allocated formats */
+ for (format = formats; format; format = format->next) {
+ if (pixel_format == format->format) {
+ ++format->refcount;
+ SDL_AtomicUnlock(&formats_lock);
+ return format;
+ }
+ }
+
+ /* Allocate an empty pixel format structure, and initialize it */
+ format = SDL_malloc(sizeof(*format));
+ if (format == NULL) {
+ SDL_AtomicUnlock(&formats_lock);
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ if (SDL_InitFormat(format, pixel_format) < 0) {
+ SDL_AtomicUnlock(&formats_lock);
+ SDL_free(format);
+ SDL_InvalidParamError("format");
+ return NULL;
+ }
+
+ if (!SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
+ /* Cache the RGB formats */
+ format->next = formats;
+ formats = format;
+ }
+
+ SDL_AtomicUnlock(&formats_lock);
+
+ return format;
+}
+
+int
+SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format)
+{
+ int bpp;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+ Uint32 mask;
+
+ if (!SDL_PixelFormatEnumToMasks(pixel_format, &bpp,
+ &Rmask, &Gmask, &Bmask, &Amask)) {
+ return -1;
+ }
+
+ /* Set up the format */
+ SDL_zerop(format);
+ format->format = pixel_format;
+ format->BitsPerPixel = bpp;
+ format->BytesPerPixel = (bpp + 7) / 8;
+
+ format->Rmask = Rmask;
+ format->Rshift = 0;
+ format->Rloss = 8;
+ if (Rmask) {
+ for (mask = Rmask; !(mask & 0x01); mask >>= 1)
+ ++format->Rshift;
+ for (; (mask & 0x01); mask >>= 1)
+ --format->Rloss;
+ }
+
+ format->Gmask = Gmask;
+ format->Gshift = 0;
+ format->Gloss = 8;
+ if (Gmask) {
+ for (mask = Gmask; !(mask & 0x01); mask >>= 1)
+ ++format->Gshift;
+ for (; (mask & 0x01); mask >>= 1)
+ --format->Gloss;
+ }
+
+ format->Bmask = Bmask;
+ format->Bshift = 0;
+ format->Bloss = 8;
+ if (Bmask) {
+ for (mask = Bmask; !(mask & 0x01); mask >>= 1)
+ ++format->Bshift;
+ for (; (mask & 0x01); mask >>= 1)
+ --format->Bloss;
+ }
+
+ format->Amask = Amask;
+ format->Ashift = 0;
+ format->Aloss = 8;
+ if (Amask) {
+ for (mask = Amask; !(mask & 0x01); mask >>= 1)
+ ++format->Ashift;
+ for (; (mask & 0x01); mask >>= 1)
+ --format->Aloss;
+ }
+
+ format->palette = NULL;
+ format->refcount = 1;
+ format->next = NULL;
+
+ return 0;
+}
+
+void
+SDL_FreeFormat(SDL_PixelFormat *format)
+{
+ SDL_PixelFormat *prev;
+
+ if (!format) {
+ SDL_InvalidParamError("format");
+ return;
+ }
+
+ SDL_AtomicLock(&formats_lock);
+
+ if (--format->refcount > 0) {
+ SDL_AtomicUnlock(&formats_lock);
+ return;
+ }
+
+ /* Remove this format from our list */
+ if (format == formats) {
+ formats = format->next;
+ } else if (formats) {
+ for (prev = formats; prev->next; prev = prev->next) {
+ if (prev->next == format) {
+ prev->next = format->next;
+ break;
+ }
+ }
+ }
+
+ SDL_AtomicUnlock(&formats_lock);
+
+ if (format->palette) {
+ SDL_FreePalette(format->palette);
+ }
+ SDL_free(format);
+}
+
+SDL_Palette *
+SDL_AllocPalette(int ncolors)
+{
+ SDL_Palette *palette;
+
+ /* Input validation */
+ if (ncolors < 1) {
+ SDL_InvalidParamError("ncolors");
+ return NULL;
+ }
+
+ palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
+ if (!palette) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ palette->colors =
+ (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
+ if (!palette->colors) {
+ SDL_free(palette);
+ return NULL;
+ }
+ palette->ncolors = ncolors;
+ palette->version = 1;
+ palette->refcount = 1;
+
+ SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
+
+ return palette;
+}
+
+int
+SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette)
+{
+ if (!format) {
+ return SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format");
+ }
+
+ if (palette && palette->ncolors > (1 << format->BitsPerPixel)) {
+ return SDL_SetError("SDL_SetPixelFormatPalette() passed a palette that doesn't match the format");
+ }
+
+ if (format->palette == palette) {
+ return 0;
+ }
+
+ if (format->palette) {
+ SDL_FreePalette(format->palette);
+ }
+
+ format->palette = palette;
+
+ if (format->palette) {
+ ++format->palette->refcount;
+ }
+
+ return 0;
+}
+
+int
+SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
+ int firstcolor, int ncolors)
+{
+ int status = 0;
+
+ /* Verify the parameters */
+ if (!palette) {
+ return -1;
+ }
+ if (ncolors > (palette->ncolors - firstcolor)) {
+ ncolors = (palette->ncolors - firstcolor);
+ status = -1;
+ }
+
+ if (colors != (palette->colors + firstcolor)) {
+ SDL_memcpy(palette->colors + firstcolor, colors,
+ ncolors * sizeof(*colors));
+ }
+ ++palette->version;
+ if (!palette->version) {
+ palette->version = 1;
+ }
+
+ return status;
+}
+
+void
+SDL_FreePalette(SDL_Palette * palette)
+{
+ if (!palette) {
+ SDL_InvalidParamError("palette");
+ return;
+ }
+ if (--palette->refcount > 0) {
+ return;
+ }
+ SDL_free(palette->colors);
+ SDL_free(palette);
+}
+
+/*
+ * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors
+ */
+void
+SDL_DitherColors(SDL_Color * colors, int bpp)
+{
+ int i;
+ if (bpp != 8)
+ return; /* only 8bpp supported right now */
+
+ for (i = 0; i < 256; i++) {
+ int r, g, b;
+ /* map each bit field to the full [0, 255] interval,
+ so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */
+ r = i & 0xe0;
+ r |= r >> 3 | r >> 6;
+ colors[i].r = r;
+ g = (i << 3) & 0xe0;
+ g |= g >> 3 | g >> 6;
+ colors[i].g = g;
+ b = i & 0x3;
+ b |= b << 2;
+ b |= b << 4;
+ colors[i].b = b;
+ colors[i].a = SDL_ALPHA_OPAQUE;
+ }
+}
+
+/*
+ * Match an RGB value to a particular palette index
+ */
+Uint8
+SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+ /* Do colorspace distance matching */
+ unsigned int smallest;
+ unsigned int distance;
+ int rd, gd, bd, ad;
+ int i;
+ Uint8 pixel = 0;
+
+ smallest = ~0;
+ for (i = 0; i < pal->ncolors; ++i) {
+ rd = pal->colors[i].r - r;
+ gd = pal->colors[i].g - g;
+ bd = pal->colors[i].b - b;
+ ad = pal->colors[i].a - a;
+ distance = (rd * rd) + (gd * gd) + (bd * bd) + (ad * ad);
+ if (distance < smallest) {
+ pixel = i;
+ if (distance == 0) { /* Perfect match! */
+ break;
+ }
+ smallest = distance;
+ }
+ }
+ return (pixel);
+}
+
+/* Find the opaque pixel value corresponding to an RGB triple */
+Uint32
+SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b)
+{
+ if (format->palette == NULL) {
+ return (r >> format->Rloss) << format->Rshift
+ | (g >> format->Gloss) << format->Gshift
+ | (b >> format->Bloss) << format->Bshift | format->Amask;
+ } else {
+ return SDL_FindColor(format->palette, r, g, b, SDL_ALPHA_OPAQUE);
+ }
+}
+
+/* Find the pixel value corresponding to an RGBA quadruple */
+Uint32
+SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b,
+ Uint8 a)
+{
+ if (format->palette == NULL) {
+ return (r >> format->Rloss) << format->Rshift
+ | (g >> format->Gloss) << format->Gshift
+ | (b >> format->Bloss) << format->Bshift
+ | ((a >> format->Aloss) << format->Ashift & format->Amask);
+ } else {
+ return SDL_FindColor(format->palette, r, g, b, a);
+ }
+}
+
+void
+SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g,
+ Uint8 * b)
+{
+ if (format->palette == NULL) {
+ unsigned v;
+ v = (pixel & format->Rmask) >> format->Rshift;
+ *r = SDL_expand_byte[format->Rloss][v];
+ v = (pixel & format->Gmask) >> format->Gshift;
+ *g = SDL_expand_byte[format->Gloss][v];
+ v = (pixel & format->Bmask) >> format->Bshift;
+ *b = SDL_expand_byte[format->Bloss][v];
+ } else {
+ if (pixel < (unsigned)format->palette->ncolors) {
+ *r = format->palette->colors[pixel].r;
+ *g = format->palette->colors[pixel].g;
+ *b = format->palette->colors[pixel].b;
+ } else {
+ *r = *g = *b = 0;
+ }
+ }
+}
+
+void
+SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format,
+ Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
+{
+ if (format->palette == NULL) {
+ unsigned v;
+ v = (pixel & format->Rmask) >> format->Rshift;
+ *r = SDL_expand_byte[format->Rloss][v];
+ v = (pixel & format->Gmask) >> format->Gshift;
+ *g = SDL_expand_byte[format->Gloss][v];
+ v = (pixel & format->Bmask) >> format->Bshift;
+ *b = SDL_expand_byte[format->Bloss][v];
+ v = (pixel & format->Amask) >> format->Ashift;
+ *a = SDL_expand_byte[format->Aloss][v];
+ } else {
+ if (pixel < (unsigned)format->palette->ncolors) {
+ *r = format->palette->colors[pixel].r;
+ *g = format->palette->colors[pixel].g;
+ *b = format->palette->colors[pixel].b;
+ *a = format->palette->colors[pixel].a;
+ } else {
+ *r = *g = *b = *a = 0;
+ }
+ }
+}
+
+/* Map from Palette to Palette */
+static Uint8 *
+Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical)
+{
+ Uint8 *map;
+ int i;
+
+ if (identical) {
+ if (src->ncolors <= dst->ncolors) {
+ /* If an identical palette, no need to map */
+ if (src == dst
+ ||
+ (SDL_memcmp
+ (src->colors, dst->colors,
+ src->ncolors * sizeof(SDL_Color)) == 0)) {
+ *identical = 1;
+ return (NULL);
+ }
+ }
+ *identical = 0;
+ }
+ map = (Uint8 *) SDL_malloc(src->ncolors);
+ if (map == NULL) {
+ SDL_OutOfMemory();
+ return (NULL);
+ }
+ for (i = 0; i < src->ncolors; ++i) {
+ map[i] = SDL_FindColor(dst,
+ src->colors[i].r, src->colors[i].g,
+ src->colors[i].b, src->colors[i].a);
+ }
+ return (map);
+}
+
+/* Map from Palette to BitField */
+static Uint8 *
+Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
+ SDL_PixelFormat * dst)
+{
+ Uint8 *map;
+ int i;
+ int bpp;
+ SDL_Palette *pal = src->palette;
+
+ bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel);
+ map = (Uint8 *) SDL_malloc(pal->ncolors * bpp);
+ if (map == NULL) {
+ SDL_OutOfMemory();
+ return (NULL);
+ }
+
+ /* We memory copy to the pixel map so the endianness is preserved */
+ for (i = 0; i < pal->ncolors; ++i) {
+ Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255);
+ Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255);
+ Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255);
+ Uint8 A = (Uint8) ((pal->colors[i].a * Amod) / 255);
+ ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A);
+ }
+ return (map);
+}
+
+/* Map from BitField to Dithered-Palette to Palette */
+static Uint8 *
+MapNto1(SDL_PixelFormat * src, SDL_PixelFormat * dst, int *identical)
+{
+ /* Generate a 256 color dither palette */
+ SDL_Palette dithered;
+ SDL_Color colors[256];
+ SDL_Palette *pal = dst->palette;
+
+ dithered.ncolors = 256;
+ SDL_DitherColors(colors, 8);
+ dithered.colors = colors;
+ return (Map1to1(&dithered, pal, identical));
+}
+
+SDL_BlitMap *
+SDL_AllocBlitMap(void)
+{
+ SDL_BlitMap *map;
+
+ /* Allocate the empty map */
+ map = (SDL_BlitMap *) SDL_calloc(1, sizeof(*map));
+ if (map == NULL) {
+ SDL_OutOfMemory();
+ return (NULL);
+ }
+ map->info.r = 0xFF;
+ map->info.g = 0xFF;
+ map->info.b = 0xFF;
+ map->info.a = 0xFF;
+
+ /* It's ready to go */
+ return (map);
+}
+
+void
+SDL_InvalidateMap(SDL_BlitMap * map)
+{
+ if (!map) {
+ return;
+ }
+ if (map->dst) {
+ /* Release our reference to the surface - see the note below */
+ if (--map->dst->refcount <= 0) {
+ SDL_FreeSurface(map->dst);
+ }
+ }
+ map->dst = NULL;
+ map->src_palette_version = 0;
+ map->dst_palette_version = 0;
+ SDL_free(map->info.table);
+ map->info.table = NULL;
+}
+
+int
+SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst)
+{
+ SDL_PixelFormat *srcfmt;
+ SDL_PixelFormat *dstfmt;
+ SDL_BlitMap *map;
+
+ /* Clear out any previous mapping */
+ map = src->map;
+ if ((src->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
+ SDL_UnRLESurface(src, 1);
+ }
+ SDL_InvalidateMap(map);
+
+ /* Figure out what kind of mapping we're doing */
+ map->identity = 0;
+ srcfmt = src->format;
+ dstfmt = dst->format;
+ if (SDL_ISPIXELFORMAT_INDEXED(srcfmt->format)) {
+ if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
+ /* Palette --> Palette */
+ map->info.table =
+ Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
+ if (!map->identity) {
+ if (map->info.table == NULL) {
+ return (-1);
+ }
+ }
+ if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel)
+ map->identity = 0;
+ } else {
+ /* Palette --> BitField */
+ map->info.table =
+ Map1toN(srcfmt, src->map->info.r, src->map->info.g,
+ src->map->info.b, src->map->info.a, dstfmt);
+ if (map->info.table == NULL) {
+ return (-1);
+ }
+ }
+ } else {
+ if (SDL_ISPIXELFORMAT_INDEXED(dstfmt->format)) {
+ /* BitField --> Palette */
+ map->info.table = MapNto1(srcfmt, dstfmt, &map->identity);
+ if (!map->identity) {
+ if (map->info.table == NULL) {
+ return (-1);
+ }
+ }
+ map->identity = 0; /* Don't optimize to copy */
+ } else {
+ /* BitField --> BitField */
+ if (srcfmt == dstfmt) {
+ map->identity = 1;
+ }
+ }
+ }
+
+ map->dst = dst;
+
+ if (map->dst) {
+ /* Keep a reference to this surface so it doesn't get deleted
+ while we're still pointing at it.
+
+ A better method would be for the destination surface to keep
+ track of surfaces that are mapped to it and automatically
+ invalidate them when it is freed, but this will do for now.
+ */
+ ++map->dst->refcount;
+ }
+
+ if (dstfmt->palette) {
+ map->dst_palette_version = dstfmt->palette->version;
+ } else {
+ map->dst_palette_version = 0;
+ }
+
+ if (srcfmt->palette) {
+ map->src_palette_version = srcfmt->palette->version;
+ } else {
+ map->src_palette_version = 0;
+ }
+
+ /* Choose your blitters wisely */
+ return (SDL_CalculateBlit(src));
+}
+
+void
+SDL_FreeBlitMap(SDL_BlitMap * map)
+{
+ if (map) {
+ SDL_InvalidateMap(map);
+ SDL_free(map);
+ }
+}
+
+void
+SDL_CalculateGammaRamp(float gamma, Uint16 * ramp)
+{
+ int i;
+
+ /* Input validation */
+ if (gamma < 0.0f ) {
+ SDL_InvalidParamError("gamma");
+ return;
+ }
+ if (ramp == NULL) {
+ SDL_InvalidParamError("ramp");
+ return;
+ }
+
+ /* 0.0 gamma is all black */
+ if (gamma == 0.0f) {
+ SDL_memset(ramp, 0, 256 * sizeof(Uint16));
+ return;
+ } else if (gamma == 1.0f) {
+ /* 1.0 gamma is identity */
+ for (i = 0; i < 256; ++i) {
+ ramp[i] = (i << 8) | i;
+ }
+ return;
+ } else {
+ /* Calculate a real gamma ramp */
+ int value;
+ gamma = 1.0f / gamma;
+ for (i = 0; i < 256; ++i) {
+ value =
+ (int) (SDL_pow((double) i / 256.0, gamma) * 65535.0 + 0.5);
+ if (value > 65535) {
+ value = 65535;
+ }
+ ramp[i] = (Uint16) value;
+ }
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_pixels_c.h b/source/3rd-party/SDL2/src/video/SDL_pixels_c.h
new file mode 100644
index 0000000..c84e155
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_pixels_c.h
@@ -0,0 +1,46 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_pixels_c_h_
+#define SDL_pixels_c_h_
+
+#include "../SDL_internal.h"
+
+/* Useful functions and variables from SDL_pixel.c */
+
+#include "SDL_blit.h"
+
+/* Pixel format functions */
+extern int SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format);
+
+/* Blit mapping functions */
+extern SDL_BlitMap *SDL_AllocBlitMap(void);
+extern void SDL_InvalidateMap(SDL_BlitMap * map);
+extern int SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst);
+extern void SDL_FreeBlitMap(SDL_BlitMap * map);
+
+/* Miscellaneous functions */
+extern void SDL_DitherColors(SDL_Color * colors, int bpp);
+extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+
+#endif /* SDL_pixels_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_rect.c b/source/3rd-party/SDL2/src/video/SDL_rect.c
new file mode 100644
index 0000000..8c6ff2d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_rect.c
@@ -0,0 +1,531 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_rect.h"
+#include "SDL_rect_c.h"
+#include "SDL_assert.h"
+
+SDL_bool
+SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ if (!A) {
+ SDL_InvalidParamError("A");
+ return SDL_FALSE;
+ }
+
+ if (!B) {
+ SDL_InvalidParamError("B");
+ return SDL_FALSE;
+ }
+
+ /* Special cases for empty rects */
+ if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
+ return SDL_FALSE;
+ }
+
+ /* Horizontal intersection */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ if (Amax <= Amin)
+ return SDL_FALSE;
+
+ /* Vertical intersection */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ if (Amax <= Amin)
+ return SDL_FALSE;
+
+ return SDL_TRUE;
+}
+
+SDL_bool
+SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ if (!A) {
+ SDL_InvalidParamError("A");
+ return SDL_FALSE;
+ }
+
+ if (!B) {
+ SDL_InvalidParamError("B");
+ return SDL_FALSE;
+ }
+
+ if (!result) {
+ SDL_InvalidParamError("result");
+ return SDL_FALSE;
+ }
+
+ /* Special cases for empty rects */
+ if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
+ result->w = 0;
+ result->h = 0;
+ return SDL_FALSE;
+ }
+
+ /* Horizontal intersection */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ result->x = Amin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ result->w = Amax - Amin;
+
+ /* Vertical intersection */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ result->y = Amin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ result->h = Amax - Amin;
+
+ return !SDL_RectEmpty(result);
+}
+
+void
+SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ if (!A) {
+ SDL_InvalidParamError("A");
+ return;
+ }
+
+ if (!B) {
+ SDL_InvalidParamError("B");
+ return;
+ }
+
+ if (!result) {
+ SDL_InvalidParamError("result");
+ return;
+ }
+
+ /* Special cases for empty Rects */
+ if (SDL_RectEmpty(A)) {
+ if (SDL_RectEmpty(B)) {
+ /* A and B empty */
+ return;
+ } else {
+ /* A empty, B not empty */
+ *result = *B;
+ return;
+ }
+ } else {
+ if (SDL_RectEmpty(B)) {
+ /* A not empty, B empty */
+ *result = *A;
+ return;
+ }
+ }
+
+ /* Horizontal union */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if (Bmin < Amin)
+ Amin = Bmin;
+ result->x = Amin;
+ if (Bmax > Amax)
+ Amax = Bmax;
+ result->w = Amax - Amin;
+
+ /* Vertical union */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if (Bmin < Amin)
+ Amin = Bmin;
+ result->y = Amin;
+ if (Bmax > Amax)
+ Amax = Bmax;
+ result->h = Amax - Amin;
+}
+
+SDL_bool
+SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip,
+ SDL_Rect * result)
+{
+ int minx = 0;
+ int miny = 0;
+ int maxx = 0;
+ int maxy = 0;
+ int x, y, i;
+
+ if (!points) {
+ SDL_InvalidParamError("points");
+ return SDL_FALSE;
+ }
+
+ if (count < 1) {
+ SDL_InvalidParamError("count");
+ return SDL_FALSE;
+ }
+
+ if (clip) {
+ SDL_bool added = SDL_FALSE;
+ const int clip_minx = clip->x;
+ const int clip_miny = clip->y;
+ const int clip_maxx = clip->x+clip->w-1;
+ const int clip_maxy = clip->y+clip->h-1;
+
+ /* Special case for empty rectangle */
+ if (SDL_RectEmpty(clip)) {
+ return SDL_FALSE;
+ }
+
+ for (i = 0; i < count; ++i) {
+ x = points[i].x;
+ y = points[i].y;
+
+ if (x < clip_minx || x > clip_maxx ||
+ y < clip_miny || y > clip_maxy) {
+ continue;
+ }
+ if (!added) {
+ /* Special case: if no result was requested, we are done */
+ if (result == NULL) {
+ return SDL_TRUE;
+ }
+
+ /* First point added */
+ minx = maxx = x;
+ miny = maxy = y;
+ added = SDL_TRUE;
+ continue;
+ }
+ if (x < minx) {
+ minx = x;
+ } else if (x > maxx) {
+ maxx = x;
+ }
+ if (y < miny) {
+ miny = y;
+ } else if (y > maxy) {
+ maxy = y;
+ }
+ }
+ if (!added) {
+ return SDL_FALSE;
+ }
+ } else {
+ /* Special case: if no result was requested, we are done */
+ if (result == NULL) {
+ return SDL_TRUE;
+ }
+
+ /* No clipping, always add the first point */
+ minx = maxx = points[0].x;
+ miny = maxy = points[0].y;
+
+ for (i = 1; i < count; ++i) {
+ x = points[i].x;
+ y = points[i].y;
+
+ if (x < minx) {
+ minx = x;
+ } else if (x > maxx) {
+ maxx = x;
+ }
+ if (y < miny) {
+ miny = y;
+ } else if (y > maxy) {
+ maxy = y;
+ }
+ }
+ }
+
+ if (result) {
+ result->x = minx;
+ result->y = miny;
+ result->w = (maxx-minx)+1;
+ result->h = (maxy-miny)+1;
+ }
+ return SDL_TRUE;
+}
+
+/* Use the Cohen-Sutherland algorithm for line clipping */
+#define CODE_BOTTOM 1
+#define CODE_TOP 2
+#define CODE_LEFT 4
+#define CODE_RIGHT 8
+
+static int
+ComputeOutCode(const SDL_Rect * rect, int x, int y)
+{
+ int code = 0;
+ if (y < rect->y) {
+ code |= CODE_TOP;
+ } else if (y >= rect->y + rect->h) {
+ code |= CODE_BOTTOM;
+ }
+ if (x < rect->x) {
+ code |= CODE_LEFT;
+ } else if (x >= rect->x + rect->w) {
+ code |= CODE_RIGHT;
+ }
+ return code;
+}
+
+SDL_bool
+SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
+ int *Y2)
+{
+ int x = 0;
+ int y = 0;
+ int x1, y1;
+ int x2, y2;
+ int rectx1;
+ int recty1;
+ int rectx2;
+ int recty2;
+ int outcode1, outcode2;
+
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return SDL_FALSE;
+ }
+
+ if (!X1) {
+ SDL_InvalidParamError("X1");
+ return SDL_FALSE;
+ }
+
+ if (!Y1) {
+ SDL_InvalidParamError("Y1");
+ return SDL_FALSE;
+ }
+
+ if (!X2) {
+ SDL_InvalidParamError("X2");
+ return SDL_FALSE;
+ }
+
+ if (!Y2) {
+ SDL_InvalidParamError("Y2");
+ return SDL_FALSE;
+ }
+
+ /* Special case for empty rect */
+ if (SDL_RectEmpty(rect)) {
+ return SDL_FALSE;
+ }
+
+ x1 = *X1;
+ y1 = *Y1;
+ x2 = *X2;
+ y2 = *Y2;
+ rectx1 = rect->x;
+ recty1 = rect->y;
+ rectx2 = rect->x + rect->w - 1;
+ recty2 = rect->y + rect->h - 1;
+
+ /* Check to see if entire line is inside rect */
+ if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
+ y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
+ return SDL_TRUE;
+ }
+
+ /* Check to see if entire line is to one side of rect */
+ if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
+ (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
+ return SDL_FALSE;
+ }
+
+ if (y1 == y2) {
+ /* Horizontal line, easy to clip */
+ if (x1 < rectx1) {
+ *X1 = rectx1;
+ } else if (x1 > rectx2) {
+ *X1 = rectx2;
+ }
+ if (x2 < rectx1) {
+ *X2 = rectx1;
+ } else if (x2 > rectx2) {
+ *X2 = rectx2;
+ }
+ return SDL_TRUE;
+ }
+
+ if (x1 == x2) {
+ /* Vertical line, easy to clip */
+ if (y1 < recty1) {
+ *Y1 = recty1;
+ } else if (y1 > recty2) {
+ *Y1 = recty2;
+ }
+ if (y2 < recty1) {
+ *Y2 = recty1;
+ } else if (y2 > recty2) {
+ *Y2 = recty2;
+ }
+ return SDL_TRUE;
+ }
+
+ /* More complicated Cohen-Sutherland algorithm */
+ outcode1 = ComputeOutCode(rect, x1, y1);
+ outcode2 = ComputeOutCode(rect, x2, y2);
+ while (outcode1 || outcode2) {
+ if (outcode1 & outcode2) {
+ return SDL_FALSE;
+ }
+
+ if (outcode1) {
+ if (outcode1 & CODE_TOP) {
+ y = recty1;
+ x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
+ } else if (outcode1 & CODE_BOTTOM) {
+ y = recty2;
+ x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
+ } else if (outcode1 & CODE_LEFT) {
+ x = rectx1;
+ y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
+ } else if (outcode1 & CODE_RIGHT) {
+ x = rectx2;
+ y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
+ }
+ x1 = x;
+ y1 = y;
+ outcode1 = ComputeOutCode(rect, x, y);
+ } else {
+ if (outcode2 & CODE_TOP) {
+ y = recty1;
+ x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
+ } else if (outcode2 & CODE_BOTTOM) {
+ y = recty2;
+ x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
+ } else if (outcode2 & CODE_LEFT) {
+ /* If this assertion ever fires, here's the static analysis that warned about it:
+ http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */
+ SDL_assert(x2 != x1); /* if equal: division by zero. */
+ x = rectx1;
+ y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
+ } else if (outcode2 & CODE_RIGHT) {
+ /* If this assertion ever fires, here's the static analysis that warned about it:
+ http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */
+ SDL_assert(x2 != x1); /* if equal: division by zero. */
+ x = rectx2;
+ y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
+ }
+ x2 = x;
+ y2 = y;
+ outcode2 = ComputeOutCode(rect, x, y);
+ }
+ }
+ *X1 = x1;
+ *Y1 = y1;
+ *X2 = x2;
+ *Y2 = y2;
+ return SDL_TRUE;
+}
+
+SDL_bool
+SDL_GetSpanEnclosingRect(int width, int height,
+ int numrects, const SDL_Rect * rects, SDL_Rect *span)
+{
+ int i;
+ int span_y1, span_y2;
+ int rect_y1, rect_y2;
+
+ if (width < 1) {
+ SDL_InvalidParamError("width");
+ return SDL_FALSE;
+ }
+
+ if (height < 1) {
+ SDL_InvalidParamError("height");
+ return SDL_FALSE;
+ }
+
+ if (!rects) {
+ SDL_InvalidParamError("rects");
+ return SDL_FALSE;
+ }
+
+ if (!span) {
+ SDL_InvalidParamError("span");
+ return SDL_FALSE;
+ }
+
+ if (numrects < 1) {
+ SDL_InvalidParamError("numrects");
+ return SDL_FALSE;
+ }
+
+ /* Initialize to empty rect */
+ span_y1 = height;
+ span_y2 = 0;
+
+ for (i = 0; i < numrects; ++i) {
+ rect_y1 = rects[i].y;
+ rect_y2 = rect_y1 + rects[i].h;
+
+ /* Clip out of bounds rectangles, and expand span rect */
+ if (rect_y1 < 0) {
+ span_y1 = 0;
+ } else if (rect_y1 < span_y1) {
+ span_y1 = rect_y1;
+ }
+ if (rect_y2 > height) {
+ span_y2 = height;
+ } else if (rect_y2 > span_y2) {
+ span_y2 = rect_y2;
+ }
+ }
+ if (span_y2 > span_y1) {
+ span->x = 0;
+ span->y = span_y1;
+ span->w = width;
+ span->h = (span_y2 - span_y1);
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_rect_c.h b/source/3rd-party/SDL2/src/video/SDL_rect_c.h
new file mode 100644
index 0000000..56d6f2e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_rect_c.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_rect_c_h_
+#define SDL_rect_c_h_
+
+#include "../SDL_internal.h"
+
+extern SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect * rects, SDL_Rect *span);
+
+#endif /* SDL_rect_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_shape.c b/source/3rd-party/SDL2/src/video/SDL_shape.c
new file mode 100644
index 0000000..6f029bc
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_shape.c
@@ -0,0 +1,309 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL.h"
+#include "SDL_assert.h"
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_pixels.h"
+#include "SDL_surface.h"
+#include "SDL_shape.h"
+#include "SDL_shape_internals.h"
+
+SDL_Window*
+SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags)
+{
+ SDL_Window *result = NULL;
+ result = SDL_CreateWindow(title,-1000,-1000,w,h,(flags | SDL_WINDOW_BORDERLESS) & (~SDL_WINDOW_FULLSCREEN) & (~SDL_WINDOW_RESIZABLE) /* & (~SDL_WINDOW_SHOWN) */);
+ if(result != NULL) {
+ if (SDL_GetVideoDevice()->shape_driver.CreateShaper == NULL) {
+ SDL_DestroyWindow(result);
+ return NULL;
+ }
+ result->shaper = SDL_GetVideoDevice()->shape_driver.CreateShaper(result);
+ if(result->shaper != NULL) {
+ result->shaper->userx = x;
+ result->shaper->usery = y;
+ result->shaper->mode.mode = ShapeModeDefault;
+ result->shaper->mode.parameters.binarizationCutoff = 1;
+ result->shaper->hasshape = SDL_FALSE;
+ return result;
+ }
+ else {
+ SDL_DestroyWindow(result);
+ return NULL;
+ }
+ }
+ else
+ return NULL;
+}
+
+SDL_bool
+SDL_IsShapedWindow(const SDL_Window *window)
+{
+ if(window == NULL)
+ return SDL_FALSE;
+ else
+ return (SDL_bool)(window->shaper != NULL);
+}
+
+/* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */
+void
+SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb)
+{
+ int x = 0;
+ int y = 0;
+ Uint8 r = 0,g = 0,b = 0,alpha = 0;
+ Uint8* pixel = NULL;
+ Uint32 pixel_value = 0,mask_value = 0;
+ int bytes_per_scanline = (shape->w + (ppb - 1)) / ppb;
+ Uint8 *bitmap_scanline;
+ SDL_Color key;
+ if(SDL_MUSTLOCK(shape))
+ SDL_LockSurface(shape);
+ for(y = 0;y<shape->h;y++) {
+ bitmap_scanline = bitmap + y * bytes_per_scanline;
+ for(x=0;x<shape->w;x++) {
+ alpha = 0;
+ pixel_value = 0;
+ pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
+ switch(shape->format->BytesPerPixel) {
+ case(1):
+ pixel_value = *(Uint8*)pixel;
+ break;
+ case(2):
+ pixel_value = *(Uint16*)pixel;
+ break;
+ case(3):
+ pixel_value = *(Uint32*)pixel & (~shape->format->Amask);
+ break;
+ case(4):
+ pixel_value = *(Uint32*)pixel;
+ break;
+ }
+ SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha);
+ switch(mode.mode) {
+ case(ShapeModeDefault):
+ mask_value = (alpha >= 1 ? 1 : 0);
+ break;
+ case(ShapeModeBinarizeAlpha):
+ mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0);
+ break;
+ case(ShapeModeReverseBinarizeAlpha):
+ mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0);
+ break;
+ case(ShapeModeColorKey):
+ key = mode.parameters.colorKey;
+ mask_value = ((key.r != r || key.g != g || key.b != b) ? 1 : 0);
+ break;
+ }
+ bitmap_scanline[x / ppb] |= mask_value << (x % ppb);
+ }
+ }
+ if(SDL_MUSTLOCK(shape))
+ SDL_UnlockSurface(shape);
+}
+
+static SDL_ShapeTree*
+RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* mask,SDL_Rect dimensions) {
+ int x = 0,y = 0;
+ Uint8* pixel = NULL;
+ Uint32 pixel_value = 0;
+ Uint8 r = 0,g = 0,b = 0,a = 0;
+ SDL_bool pixel_opaque = SDL_FALSE;
+ int last_opaque = -1;
+ SDL_Color key;
+ SDL_ShapeTree* result = (SDL_ShapeTree*)SDL_malloc(sizeof(SDL_ShapeTree));
+ SDL_Rect next = {0,0,0,0};
+
+ for(y=dimensions.y;y<dimensions.y + dimensions.h;y++) {
+ for(x=dimensions.x;x<dimensions.x + dimensions.w;x++) {
+ pixel_value = 0;
+ pixel = (Uint8 *)(mask->pixels) + (y*mask->pitch) + (x*mask->format->BytesPerPixel);
+ switch(mask->format->BytesPerPixel) {
+ case(1):
+ pixel_value = *(Uint8*)pixel;
+ break;
+ case(2):
+ pixel_value = *(Uint16*)pixel;
+ break;
+ case(3):
+ pixel_value = *(Uint32*)pixel & (~mask->format->Amask);
+ break;
+ case(4):
+ pixel_value = *(Uint32*)pixel;
+ break;
+ }
+ SDL_GetRGBA(pixel_value,mask->format,&r,&g,&b,&a);
+ switch(mode.mode) {
+ case(ShapeModeDefault):
+ pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE);
+ break;
+ case(ShapeModeBinarizeAlpha):
+ pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
+ break;
+ case(ShapeModeReverseBinarizeAlpha):
+ pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
+ break;
+ case(ShapeModeColorKey):
+ key = mode.parameters.colorKey;
+ pixel_opaque = ((key.r != r || key.g != g || key.b != b) ? SDL_TRUE : SDL_FALSE);
+ break;
+ }
+ if(last_opaque == -1)
+ last_opaque = pixel_opaque;
+ if(last_opaque != pixel_opaque) {
+ const int halfwidth = dimensions.w / 2;
+ const int halfheight = dimensions.h / 2;
+
+ result->kind = QuadShape;
+
+ next.x = dimensions.x;
+ next.y = dimensions.y;
+ next.w = halfwidth;
+ next.h = halfheight;
+ result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
+
+ next.x = dimensions.x + halfwidth;
+ next.w = dimensions.w - halfwidth;
+ result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
+
+ next.x = dimensions.x;
+ next.w = halfwidth;
+ next.y = dimensions.y + halfheight;
+ next.h = dimensions.h - halfheight;
+ result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
+
+ next.x = dimensions.x + halfwidth;
+ next.w = dimensions.w - halfwidth;
+ result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
+
+ return result;
+ }
+ }
+ }
+
+
+ /* If we never recursed, all the pixels in this quadrant have the same "value". */
+ result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape);
+ result->data.shape = dimensions;
+ return result;
+}
+
+SDL_ShapeTree*
+SDL_CalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* shape)
+{
+ SDL_Rect dimensions;
+ SDL_ShapeTree* result = NULL;
+
+ dimensions.x = 0;
+ dimensions.y = 0;
+ dimensions.w = shape->w;
+ dimensions.h = shape->h;
+
+ if(SDL_MUSTLOCK(shape))
+ SDL_LockSurface(shape);
+ result = RecursivelyCalculateShapeTree(mode,shape,dimensions);
+ if(SDL_MUSTLOCK(shape))
+ SDL_UnlockSurface(shape);
+ return result;
+}
+
+void
+SDL_TraverseShapeTree(SDL_ShapeTree *tree,SDL_TraversalFunction function,void* closure)
+{
+ SDL_assert(tree != NULL);
+ if(tree->kind == QuadShape) {
+ SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft,function,closure);
+ SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright,function,closure);
+ SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft,function,closure);
+ SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright,function,closure);
+ }
+ else
+ function(tree,closure);
+}
+
+void
+SDL_FreeShapeTree(SDL_ShapeTree** shape_tree)
+{
+ if((*shape_tree)->kind == QuadShape) {
+ SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.upleft);
+ SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.upright);
+ SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.downleft);
+ SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.downright);
+ }
+ SDL_free(*shape_tree);
+ *shape_tree = NULL;
+}
+
+int
+SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode)
+{
+ int result;
+ if(window == NULL || !SDL_IsShapedWindow(window))
+ /* The window given was not a shapeable window. */
+ return SDL_NONSHAPEABLE_WINDOW;
+ if(shape == NULL)
+ /* Invalid shape argument. */
+ return SDL_INVALID_SHAPE_ARGUMENT;
+
+ if(shape_mode != NULL)
+ window->shaper->mode = *shape_mode;
+ result = SDL_GetVideoDevice()->shape_driver.SetWindowShape(window->shaper,shape,shape_mode);
+ window->shaper->hasshape = SDL_TRUE;
+ if(window->shaper->userx != 0 && window->shaper->usery != 0) {
+ SDL_SetWindowPosition(window,window->shaper->userx,window->shaper->usery);
+ window->shaper->userx = 0;
+ window->shaper->usery = 0;
+ }
+ return result;
+}
+
+static SDL_bool
+SDL_WindowHasAShape(SDL_Window *window)
+{
+ if (window == NULL || !SDL_IsShapedWindow(window))
+ return SDL_FALSE;
+ return window->shaper->hasshape;
+}
+
+int
+SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode)
+{
+ if(window != NULL && SDL_IsShapedWindow(window)) {
+ if(shape_mode == NULL) {
+ if(SDL_WindowHasAShape(window))
+ /* The window given has a shape. */
+ return 0;
+ else
+ /* The window given is shapeable but lacks a shape. */
+ return SDL_WINDOW_LACKS_SHAPE;
+ }
+ else {
+ *shape_mode = window->shaper->mode;
+ return 0;
+ }
+ }
+ else
+ /* The window given is not a valid shapeable window. */
+ return SDL_NONSHAPEABLE_WINDOW;
+}
diff --git a/source/3rd-party/SDL2/src/video/SDL_shape_internals.h b/source/3rd-party/SDL2/src/video/SDL_shape_internals.h
new file mode 100644
index 0000000..49a8786
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_shape_internals.h
@@ -0,0 +1,69 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#ifndef SDL_shape_internals_h_
+#define SDL_shape_internals_h_
+
+#include "SDL_rect.h"
+#include "SDL_shape.h"
+#include "SDL_surface.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+typedef struct {
+ struct SDL_ShapeTree *upleft,*upright,*downleft,*downright;
+} SDL_QuadTreeChildren;
+
+typedef union {
+ SDL_QuadTreeChildren children;
+ SDL_Rect shape;
+} SDL_ShapeUnion;
+
+typedef enum { QuadShape,TransparentShape,OpaqueShape } SDL_ShapeKind;
+
+typedef struct {
+ SDL_ShapeKind kind;
+ SDL_ShapeUnion data;
+} SDL_ShapeTree;
+
+typedef void(*SDL_TraversalFunction)(SDL_ShapeTree*,void*);
+
+extern void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb);
+extern SDL_ShapeTree* SDL_CalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* shape);
+extern void SDL_TraverseShapeTree(SDL_ShapeTree *tree,SDL_TraversalFunction function,void* closure);
+extern void SDL_FreeShapeTree(SDL_ShapeTree** shape_tree);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/SDL_stretch.c b/source/3rd-party/SDL2/src/video/SDL_stretch.c
new file mode 100644
index 0000000..8cc6bf3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_stretch.c
@@ -0,0 +1,353 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/* This a stretch blit implementation based on ideas given to me by
+ Tomasz Cejner - thanks! :)
+
+ April 27, 2000 - Sam Lantinga
+*/
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/* This isn't ready for general consumption yet - it should be folded
+ into the general blitting mechanism.
+*/
+
+#if ((defined(_MSC_VER) && defined(_M_IX86)) || \
+ (defined(__WATCOMC__) && defined(__386__)) || \
+ (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES
+/* There's a bug with gcc 4.4.1 and -O2 where srcp doesn't get the correct
+ * value after the first scanline. FIXME? */
+/* #define USE_ASM_STRETCH */
+#endif
+
+#ifdef USE_ASM_STRETCH
+
+#ifdef HAVE_MPROTECT
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+#ifdef __GNUC__
+#define PAGE_ALIGNED __attribute__((__aligned__(4096)))
+#else
+#define PAGE_ALIGNED
+#endif
+
+#if defined(_M_IX86) || defined(__i386__) || defined(__386__)
+#define PREFIX16 0x66
+#define STORE_BYTE 0xAA
+#define STORE_WORD 0xAB
+#define LOAD_BYTE 0xAC
+#define LOAD_WORD 0xAD
+#define RETURN 0xC3
+#else
+#error Need assembly opcodes for this architecture
+#endif
+
+static unsigned char copy_row[4096] PAGE_ALIGNED;
+
+static int
+generate_rowbytes(int src_w, int dst_w, int bpp)
+{
+ static struct
+ {
+ int bpp;
+ int src_w;
+ int dst_w;
+ int status;
+ } last;
+
+ int i;
+ int pos, inc;
+ unsigned char *eip, *fence;
+ unsigned char load, store;
+
+ /* See if we need to regenerate the copy buffer */
+ if ((src_w == last.src_w) && (dst_w == last.dst_w) && (bpp == last.bpp)) {
+ return (last.status);
+ }
+ last.bpp = bpp;
+ last.src_w = src_w;
+ last.dst_w = dst_w;
+ last.status = -1;
+
+ switch (bpp) {
+ case 1:
+ load = LOAD_BYTE;
+ store = STORE_BYTE;
+ break;
+ case 2:
+ case 4:
+ load = LOAD_WORD;
+ store = STORE_WORD;
+ break;
+ default:
+ return SDL_SetError("ASM stretch of %d bytes isn't supported", bpp);
+ }
+#ifdef HAVE_MPROTECT
+ /* Make the code writeable */
+ if (mprotect(copy_row, sizeof(copy_row), PROT_READ | PROT_WRITE) < 0) {
+ return SDL_SetError("Couldn't make copy buffer writeable");
+ }
+#endif
+ pos = 0x10000;
+ inc = (src_w << 16) / dst_w;
+ eip = copy_row;
+ fence = copy_row + sizeof(copy_row)-2;
+ for (i = 0; i < dst_w; ++i) {
+ while (pos >= 0x10000L) {
+ if (eip == fence) {
+ return -1;
+ }
+ if (bpp == 2) {
+ *eip++ = PREFIX16;
+ }
+ *eip++ = load;
+ pos -= 0x10000L;
+ }
+ if (eip == fence) {
+ return -1;
+ }
+ if (bpp == 2) {
+ *eip++ = PREFIX16;
+ }
+ *eip++ = store;
+ pos += inc;
+ }
+ *eip++ = RETURN;
+
+#ifdef HAVE_MPROTECT
+ /* Make the code executable but not writeable */
+ if (mprotect(copy_row, sizeof(copy_row), PROT_READ | PROT_EXEC) < 0) {
+ return SDL_SetError("Couldn't make copy buffer executable");
+ }
+#endif
+ last.status = 0;
+ return (0);
+}
+
+#endif /* USE_ASM_STRETCH */
+
+#define DEFINE_COPY_ROW(name, type) \
+static void name(type *src, int src_w, type *dst, int dst_w) \
+{ \
+ int i; \
+ int pos, inc; \
+ type pixel = 0; \
+ \
+ pos = 0x10000; \
+ inc = (src_w << 16) / dst_w; \
+ for ( i=dst_w; i>0; --i ) { \
+ while ( pos >= 0x10000L ) { \
+ pixel = *src++; \
+ pos -= 0x10000L; \
+ } \
+ *dst++ = pixel; \
+ pos += inc; \
+ } \
+}
+/* *INDENT-OFF* */
+DEFINE_COPY_ROW(copy_row1, Uint8)
+DEFINE_COPY_ROW(copy_row2, Uint16)
+DEFINE_COPY_ROW(copy_row4, Uint32)
+/* *INDENT-ON* */
+
+/* The ASM code doesn't handle 24-bpp stretch blits */
+static void
+copy_row3(Uint8 * src, int src_w, Uint8 * dst, int dst_w)
+{
+ int i;
+ int pos, inc;
+ Uint8 pixel[3] = { 0, 0, 0 };
+
+ pos = 0x10000;
+ inc = (src_w << 16) / dst_w;
+ for (i = dst_w; i > 0; --i) {
+ while (pos >= 0x10000L) {
+ pixel[0] = *src++;
+ pixel[1] = *src++;
+ pixel[2] = *src++;
+ pos -= 0x10000L;
+ }
+ *dst++ = pixel[0];
+ *dst++ = pixel[1];
+ *dst++ = pixel[2];
+ pos += inc;
+ }
+}
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+int
+SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect,
+ SDL_Surface * dst, const SDL_Rect * dstrect)
+{
+ int src_locked;
+ int dst_locked;
+ int pos, inc;
+ int dst_maxrow;
+ int src_row, dst_row;
+ Uint8 *srcp = NULL;
+ Uint8 *dstp;
+ SDL_Rect full_src;
+ SDL_Rect full_dst;
+#ifdef USE_ASM_STRETCH
+ SDL_bool use_asm = SDL_TRUE;
+#ifdef __GNUC__
+ int u1, u2;
+#endif
+#endif /* USE_ASM_STRETCH */
+ const int bpp = dst->format->BytesPerPixel;
+
+ if (src->format->format != dst->format->format) {
+ return SDL_SetError("Only works with same format surfaces");
+ }
+
+ /* Verify the blit rectangles */
+ if (srcrect) {
+ if ((srcrect->x < 0) || (srcrect->y < 0) ||
+ ((srcrect->x + srcrect->w) > src->w) ||
+ ((srcrect->y + srcrect->h) > src->h)) {
+ return SDL_SetError("Invalid source blit rectangle");
+ }
+ } else {
+ full_src.x = 0;
+ full_src.y = 0;
+ full_src.w = src->w;
+ full_src.h = src->h;
+ srcrect = &full_src;
+ }
+ if (dstrect) {
+ if ((dstrect->x < 0) || (dstrect->y < 0) ||
+ ((dstrect->x + dstrect->w) > dst->w) ||
+ ((dstrect->y + dstrect->h) > dst->h)) {
+ return SDL_SetError("Invalid destination blit rectangle");
+ }
+ } else {
+ full_dst.x = 0;
+ full_dst.y = 0;
+ full_dst.w = dst->w;
+ full_dst.h = dst->h;
+ dstrect = &full_dst;
+ }
+
+ /* Lock the destination if it's in hardware */
+ dst_locked = 0;
+ if (SDL_MUSTLOCK(dst)) {
+ if (SDL_LockSurface(dst) < 0) {
+ return SDL_SetError("Unable to lock destination surface");
+ }
+ dst_locked = 1;
+ }
+ /* Lock the source if it's in hardware */
+ src_locked = 0;
+ if (SDL_MUSTLOCK(src)) {
+ if (SDL_LockSurface(src) < 0) {
+ if (dst_locked) {
+ SDL_UnlockSurface(dst);
+ }
+ return SDL_SetError("Unable to lock source surface");
+ }
+ src_locked = 1;
+ }
+
+ /* Set up the data... */
+ pos = 0x10000;
+ inc = (srcrect->h << 16) / dstrect->h;
+ src_row = srcrect->y;
+ dst_row = dstrect->y;
+
+#ifdef USE_ASM_STRETCH
+ /* Write the opcodes for this stretch */
+ if ((bpp == 3) || (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0)) {
+ use_asm = SDL_FALSE;
+ }
+#endif
+
+ /* Perform the stretch blit */
+ for (dst_maxrow = dst_row + dstrect->h; dst_row < dst_maxrow; ++dst_row) {
+ dstp = (Uint8 *) dst->pixels + (dst_row * dst->pitch)
+ + (dstrect->x * bpp);
+ while (pos >= 0x10000L) {
+ srcp = (Uint8 *) src->pixels + (src_row * src->pitch)
+ + (srcrect->x * bpp);
+ ++src_row;
+ pos -= 0x10000L;
+ }
+#ifdef USE_ASM_STRETCH
+ if (use_asm) {
+#ifdef __GNUC__
+ __asm__ __volatile__("call *%4":"=&D"(u1), "=&S"(u2)
+ :"0"(dstp), "1"(srcp), "r"(copy_row)
+ :"memory");
+#elif defined(_MSC_VER) || defined(__WATCOMC__)
+ /* *INDENT-OFF* */
+ {
+ void *code = copy_row;
+ __asm {
+ push edi
+ push esi
+ mov edi, dstp
+ mov esi, srcp
+ call dword ptr code
+ pop esi
+ pop edi
+ }
+ }
+ /* *INDENT-ON* */
+#else
+#error Need inline assembly for this compiler
+#endif
+ } else
+#endif
+ switch (bpp) {
+ case 1:
+ copy_row1(srcp, srcrect->w, dstp, dstrect->w);
+ break;
+ case 2:
+ copy_row2((Uint16 *) srcp, srcrect->w,
+ (Uint16 *) dstp, dstrect->w);
+ break;
+ case 3:
+ copy_row3(srcp, srcrect->w, dstp, dstrect->w);
+ break;
+ case 4:
+ copy_row4((Uint32 *) srcp, srcrect->w,
+ (Uint32 *) dstp, dstrect->w);
+ break;
+ }
+ pos += inc;
+ }
+
+ /* We need to unlock the surfaces if they're locked */
+ if (dst_locked) {
+ SDL_UnlockSurface(dst);
+ }
+ if (src_locked) {
+ SDL_UnlockSurface(src);
+ }
+ return (0);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_surface.c b/source/3rd-party/SDL2/src/video/SDL_surface.c
new file mode 100644
index 0000000..1b2ee6c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_surface.c
@@ -0,0 +1,1246 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_RLEaccel_c.h"
+#include "SDL_pixels_c.h"
+#include "SDL_yuv_c.h"
+
+
+/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */
+SDL_COMPILE_TIME_ASSERT(surface_size_assumptions,
+ sizeof(int) == sizeof(Sint32) && sizeof(size_t) >= sizeof(Sint32));
+
+/* Public routines */
+
+/*
+ * Calculate the pad-aligned scanline width of a surface
+ */
+static int
+SDL_CalculatePitch(Uint32 format, int width)
+{
+ int pitch;
+
+ /* Surface should be 4-byte aligned for speed */
+ pitch = width * SDL_BYTESPERPIXEL(format);
+ switch (SDL_BITSPERPIXEL(format)) {
+ case 1:
+ pitch = (pitch + 7) / 8;
+ break;
+ case 4:
+ pitch = (pitch + 1) / 2;
+ break;
+ default:
+ break;
+ }
+ pitch = (pitch + 3) & ~3; /* 4-byte aligning */
+ return pitch;
+}
+
+/*
+ * Create an empty RGB surface of the appropriate depth using the given
+ * enum SDL_PIXELFORMAT_* format
+ */
+SDL_Surface *
+SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth,
+ Uint32 format)
+{
+ SDL_Surface *surface;
+
+ /* The flags are no longer used, make the compiler happy */
+ (void)flags;
+
+ /* Allocate the surface */
+ surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
+ if (surface == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ surface->format = SDL_AllocFormat(format);
+ if (!surface->format) {
+ SDL_FreeSurface(surface);
+ return NULL;
+ }
+ surface->w = width;
+ surface->h = height;
+ surface->pitch = SDL_CalculatePitch(format, width);
+ SDL_SetClipRect(surface, NULL);
+
+ if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
+ SDL_Palette *palette =
+ SDL_AllocPalette((1 << surface->format->BitsPerPixel));
+ if (!palette) {
+ SDL_FreeSurface(surface);
+ return NULL;
+ }
+ if (palette->ncolors == 2) {
+ /* Create a black and white bitmap palette */
+ palette->colors[0].r = 0xFF;
+ palette->colors[0].g = 0xFF;
+ palette->colors[0].b = 0xFF;
+ palette->colors[1].r = 0x00;
+ palette->colors[1].g = 0x00;
+ palette->colors[1].b = 0x00;
+ }
+ SDL_SetSurfacePalette(surface, palette);
+ SDL_FreePalette(palette);
+ }
+
+ /* Get the pixels */
+ if (surface->w && surface->h) {
+ /* Assumptions checked in surface_size_assumptions assert above */
+ Sint64 size = ((Sint64)surface->h * surface->pitch);
+ if (size < 0 || size > SDL_MAX_SINT32) {
+ /* Overflow... */
+ SDL_FreeSurface(surface);
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ surface->pixels = SDL_malloc((size_t)size);
+ if (!surface->pixels) {
+ SDL_FreeSurface(surface);
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ /* This is important for bitmaps */
+ SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
+ }
+
+ /* Allocate an empty mapping */
+ surface->map = SDL_AllocBlitMap();
+ if (!surface->map) {
+ SDL_FreeSurface(surface);
+ return NULL;
+ }
+
+ /* By default surface with an alpha mask are set up for blending */
+ if (surface->format->Amask) {
+ SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
+ }
+
+ /* The surface is ready to go */
+ surface->refcount = 1;
+ return surface;
+}
+
+/*
+ * Create an empty RGB surface of the appropriate depth
+ */
+SDL_Surface *
+SDL_CreateRGBSurface(Uint32 flags,
+ int width, int height, int depth,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ Uint32 format;
+
+ /* Get the pixel format */
+ format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
+ if (format == SDL_PIXELFORMAT_UNKNOWN) {
+ SDL_SetError("Unknown pixel format");
+ return NULL;
+ }
+
+ return SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format);
+}
+
+/*
+ * Create an RGB surface from an existing memory buffer
+ */
+SDL_Surface *
+SDL_CreateRGBSurfaceFrom(void *pixels,
+ int width, int height, int depth, int pitch,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
+ Uint32 Amask)
+{
+ SDL_Surface *surface;
+
+ surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
+ if (surface != NULL) {
+ surface->flags |= SDL_PREALLOC;
+ surface->pixels = pixels;
+ surface->w = width;
+ surface->h = height;
+ surface->pitch = pitch;
+ SDL_SetClipRect(surface, NULL);
+ }
+ return surface;
+}
+
+/*
+ * Create an RGB surface from an existing memory buffer using the given given
+ * enum SDL_PIXELFORMAT_* format
+ */
+SDL_Surface *
+SDL_CreateRGBSurfaceWithFormatFrom(void *pixels,
+ int width, int height, int depth, int pitch,
+ Uint32 format)
+{
+ SDL_Surface *surface;
+
+ surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format);
+ if (surface != NULL) {
+ surface->flags |= SDL_PREALLOC;
+ surface->pixels = pixels;
+ surface->w = width;
+ surface->h = height;
+ surface->pitch = pitch;
+ SDL_SetClipRect(surface, NULL);
+ }
+ return surface;
+}
+
+int
+SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
+{
+ if (!surface) {
+ return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
+ }
+ if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) {
+ return -1;
+ }
+ SDL_InvalidateMap(surface->map);
+
+ return 0;
+}
+
+int
+SDL_SetSurfaceRLE(SDL_Surface * surface, int flag)
+{
+ int flags;
+
+ if (!surface) {
+ return -1;
+ }
+
+ flags = surface->map->info.flags;
+ if (flag) {
+ surface->map->info.flags |= SDL_COPY_RLE_DESIRED;
+ } else {
+ surface->map->info.flags &= ~SDL_COPY_RLE_DESIRED;
+ }
+ if (surface->map->info.flags != flags) {
+ SDL_InvalidateMap(surface->map);
+ }
+ return 0;
+}
+
+int
+SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key)
+{
+ int flags;
+
+ if (!surface) {
+ return SDL_InvalidParamError("surface");
+ }
+
+ if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) {
+ return SDL_InvalidParamError("key");
+ }
+
+ if (flag & SDL_RLEACCEL) {
+ SDL_SetSurfaceRLE(surface, 1);
+ }
+
+ flags = surface->map->info.flags;
+ if (flag) {
+ surface->map->info.flags |= SDL_COPY_COLORKEY;
+ surface->map->info.colorkey = key;
+ if (surface->format->palette) {
+ surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT;
+ ++surface->format->palette->version;
+ if (!surface->format->palette->version) {
+ surface->format->palette->version = 1;
+ }
+ }
+ } else {
+ if (surface->format->palette) {
+ surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_OPAQUE;
+ ++surface->format->palette->version;
+ if (!surface->format->palette->version) {
+ surface->format->palette->version = 1;
+ }
+ }
+ surface->map->info.flags &= ~SDL_COPY_COLORKEY;
+ }
+ if (surface->map->info.flags != flags) {
+ SDL_InvalidateMap(surface->map);
+ }
+
+ return 0;
+}
+
+SDL_bool
+SDL_HasColorKey(SDL_Surface * surface)
+{
+ if (!surface) {
+ return SDL_FALSE;
+ }
+
+ if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
+ return SDL_FALSE;
+ }
+
+ return SDL_TRUE;
+}
+
+int
+SDL_GetColorKey(SDL_Surface * surface, Uint32 * key)
+{
+ if (!surface) {
+ return SDL_InvalidParamError("surface");
+ }
+
+ if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
+ return SDL_SetError("Surface doesn't have a colorkey");
+ }
+
+ if (key) {
+ *key = surface->map->info.colorkey;
+ }
+ return 0;
+}
+
+/* This is a fairly slow function to switch from colorkey to alpha */
+static void
+SDL_ConvertColorkeyToAlpha(SDL_Surface * surface)
+{
+ int x, y;
+
+ if (!surface) {
+ return;
+ }
+
+ if (!(surface->map->info.flags & SDL_COPY_COLORKEY) ||
+ !surface->format->Amask) {
+ return;
+ }
+
+ SDL_LockSurface(surface);
+
+ switch (surface->format->BytesPerPixel) {
+ case 2:
+ {
+ Uint16 *row, *spot;
+ Uint16 ckey = (Uint16) surface->map->info.colorkey;
+ Uint16 mask = (Uint16) (~surface->format->Amask);
+
+ /* Ignore alpha in colorkey comparison */
+ ckey &= mask;
+ row = (Uint16 *) surface->pixels;
+ for (y = surface->h; y--;) {
+ spot = row;
+ for (x = surface->w; x--;) {
+ if ((*spot & mask) == ckey) {
+ *spot &= mask;
+ }
+ ++spot;
+ }
+ row += surface->pitch / 2;
+ }
+ }
+ break;
+ case 3:
+ /* FIXME */
+ break;
+ case 4:
+ {
+ Uint32 *row, *spot;
+ Uint32 ckey = surface->map->info.colorkey;
+ Uint32 mask = ~surface->format->Amask;
+
+ /* Ignore alpha in colorkey comparison */
+ ckey &= mask;
+ row = (Uint32 *) surface->pixels;
+ for (y = surface->h; y--;) {
+ spot = row;
+ for (x = surface->w; x--;) {
+ if ((*spot & mask) == ckey) {
+ *spot &= mask;
+ }
+ ++spot;
+ }
+ row += surface->pitch / 4;
+ }
+ }
+ break;
+ }
+
+ SDL_UnlockSurface(surface);
+
+ SDL_SetColorKey(surface, 0, 0);
+ SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
+}
+
+int
+SDL_SetSurfaceColorMod(SDL_Surface * surface, Uint8 r, Uint8 g, Uint8 b)
+{
+ int flags;
+
+ if (!surface) {
+ return -1;
+ }
+
+ surface->map->info.r = r;
+ surface->map->info.g = g;
+ surface->map->info.b = b;
+
+ flags = surface->map->info.flags;
+ if (r != 0xFF || g != 0xFF || b != 0xFF) {
+ surface->map->info.flags |= SDL_COPY_MODULATE_COLOR;
+ } else {
+ surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR;
+ }
+ if (surface->map->info.flags != flags) {
+ SDL_InvalidateMap(surface->map);
+ }
+ return 0;
+}
+
+
+int
+SDL_GetSurfaceColorMod(SDL_Surface * surface, Uint8 * r, Uint8 * g, Uint8 * b)
+{
+ if (!surface) {
+ return -1;
+ }
+
+ if (r) {
+ *r = surface->map->info.r;
+ }
+ if (g) {
+ *g = surface->map->info.g;
+ }
+ if (b) {
+ *b = surface->map->info.b;
+ }
+ return 0;
+}
+
+int
+SDL_SetSurfaceAlphaMod(SDL_Surface * surface, Uint8 alpha)
+{
+ int flags;
+
+ if (!surface) {
+ return -1;
+ }
+
+ surface->map->info.a = alpha;
+
+ flags = surface->map->info.flags;
+ if (alpha != 0xFF) {
+ surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA;
+ } else {
+ surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA;
+ }
+ if (surface->map->info.flags != flags) {
+ SDL_InvalidateMap(surface->map);
+ }
+ return 0;
+}
+
+int
+SDL_GetSurfaceAlphaMod(SDL_Surface * surface, Uint8 * alpha)
+{
+ if (!surface) {
+ return -1;
+ }
+
+ if (alpha) {
+ *alpha = surface->map->info.a;
+ }
+ return 0;
+}
+
+int
+SDL_SetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode blendMode)
+{
+ int flags, status;
+
+ if (!surface) {
+ return -1;
+ }
+
+ status = 0;
+ flags = surface->map->info.flags;
+ surface->map->info.flags &=
+ ~(SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD);
+ switch (blendMode) {
+ case SDL_BLENDMODE_NONE:
+ break;
+ case SDL_BLENDMODE_BLEND:
+ surface->map->info.flags |= SDL_COPY_BLEND;
+ break;
+ case SDL_BLENDMODE_ADD:
+ surface->map->info.flags |= SDL_COPY_ADD;
+ break;
+ case SDL_BLENDMODE_MOD:
+ surface->map->info.flags |= SDL_COPY_MOD;
+ break;
+ default:
+ status = SDL_Unsupported();
+ break;
+ }
+
+ if (surface->map->info.flags != flags) {
+ SDL_InvalidateMap(surface->map);
+ }
+
+ return status;
+}
+
+int
+SDL_GetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode *blendMode)
+{
+ if (!surface) {
+ return -1;
+ }
+
+ if (!blendMode) {
+ return 0;
+ }
+
+ switch (surface->map->
+ info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ *blendMode = SDL_BLENDMODE_BLEND;
+ break;
+ case SDL_COPY_ADD:
+ *blendMode = SDL_BLENDMODE_ADD;
+ break;
+ case SDL_COPY_MOD:
+ *blendMode = SDL_BLENDMODE_MOD;
+ break;
+ default:
+ *blendMode = SDL_BLENDMODE_NONE;
+ break;
+ }
+ return 0;
+}
+
+SDL_bool
+SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect)
+{
+ SDL_Rect full_rect;
+
+ /* Don't do anything if there's no surface to act on */
+ if (!surface) {
+ return SDL_FALSE;
+ }
+
+ /* Set up the full surface rectangle */
+ full_rect.x = 0;
+ full_rect.y = 0;
+ full_rect.w = surface->w;
+ full_rect.h = surface->h;
+
+ /* Set the clipping rectangle */
+ if (!rect) {
+ surface->clip_rect = full_rect;
+ return SDL_TRUE;
+ }
+ return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
+}
+
+void
+SDL_GetClipRect(SDL_Surface * surface, SDL_Rect * rect)
+{
+ if (surface && rect) {
+ *rect = surface->clip_rect;
+ }
+}
+
+/*
+ * Set up a blit between two surfaces -- split into three parts:
+ * The upper part, SDL_UpperBlit(), performs clipping and rectangle
+ * verification. The lower part is a pointer to a low level
+ * accelerated blitting function.
+ *
+ * These parts are separated out and each used internally by this
+ * library in the optimimum places. They are exported so that if
+ * you know exactly what you are doing, you can optimize your code
+ * by calling the one(s) you need.
+ */
+int
+SDL_LowerBlit(SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect)
+{
+ /* Check to make sure the blit mapping is valid */
+ if ((src->map->dst != dst) ||
+ (dst->format->palette &&
+ src->map->dst_palette_version != dst->format->palette->version) ||
+ (src->format->palette &&
+ src->map->src_palette_version != src->format->palette->version)) {
+ if (SDL_MapSurface(src, dst) < 0) {
+ return (-1);
+ }
+ /* just here for debugging */
+/* printf */
+/* ("src = 0x%08X src->flags = %08X src->map->info.flags = %08x\ndst = 0x%08X dst->flags = %08X dst->map->info.flags = %08X\nsrc->map->blit = 0x%08x\n", */
+/* src, dst->flags, src->map->info.flags, dst, dst->flags, */
+/* dst->map->info.flags, src->map->blit); */
+ }
+ return (src->map->blit(src, srcrect, dst, dstrect));
+}
+
+
+int
+SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect)
+{
+ SDL_Rect fulldst;
+ int srcx, srcy, w, h;
+
+ /* Make sure the surfaces aren't locked */
+ if (!src || !dst) {
+ return SDL_SetError("SDL_UpperBlit: passed a NULL surface");
+ }
+ if (src->locked || dst->locked) {
+ return SDL_SetError("Surfaces must not be locked during blit");
+ }
+
+ /* If the destination rectangle is NULL, use the entire dest surface */
+ if (dstrect == NULL) {
+ fulldst.x = fulldst.y = 0;
+ fulldst.w = dst->w;
+ fulldst.h = dst->h;
+ dstrect = &fulldst;
+ }
+
+ /* clip the source rectangle to the source surface */
+ if (srcrect) {
+ int maxw, maxh;
+
+ srcx = srcrect->x;
+ w = srcrect->w;
+ if (srcx < 0) {
+ w += srcx;
+ dstrect->x -= srcx;
+ srcx = 0;
+ }
+ maxw = src->w - srcx;
+ if (maxw < w)
+ w = maxw;
+
+ srcy = srcrect->y;
+ h = srcrect->h;
+ if (srcy < 0) {
+ h += srcy;
+ dstrect->y -= srcy;
+ srcy = 0;
+ }
+ maxh = src->h - srcy;
+ if (maxh < h)
+ h = maxh;
+
+ } else {
+ srcx = srcy = 0;
+ w = src->w;
+ h = src->h;
+ }
+
+ /* clip the destination rectangle against the clip rectangle */
+ {
+ SDL_Rect *clip = &dst->clip_rect;
+ int dx, dy;
+
+ dx = clip->x - dstrect->x;
+ if (dx > 0) {
+ w -= dx;
+ dstrect->x += dx;
+ srcx += dx;
+ }
+ dx = dstrect->x + w - clip->x - clip->w;
+ if (dx > 0)
+ w -= dx;
+
+ dy = clip->y - dstrect->y;
+ if (dy > 0) {
+ h -= dy;
+ dstrect->y += dy;
+ srcy += dy;
+ }
+ dy = dstrect->y + h - clip->y - clip->h;
+ if (dy > 0)
+ h -= dy;
+ }
+
+ /* Switch back to a fast blit if we were previously stretching */
+ if (src->map->info.flags & SDL_COPY_NEAREST) {
+ src->map->info.flags &= ~SDL_COPY_NEAREST;
+ SDL_InvalidateMap(src->map);
+ }
+
+ if (w > 0 && h > 0) {
+ SDL_Rect sr;
+ sr.x = srcx;
+ sr.y = srcy;
+ sr.w = dstrect->w = w;
+ sr.h = dstrect->h = h;
+ return SDL_LowerBlit(src, &sr, dst, dstrect);
+ }
+ dstrect->w = dstrect->h = 0;
+ return 0;
+}
+
+int
+SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect)
+{
+ double src_x0, src_y0, src_x1, src_y1;
+ double dst_x0, dst_y0, dst_x1, dst_y1;
+ SDL_Rect final_src, final_dst;
+ double scaling_w, scaling_h;
+ int src_w, src_h;
+ int dst_w, dst_h;
+
+ /* Make sure the surfaces aren't locked */
+ if (!src || !dst) {
+ return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface");
+ }
+ if (src->locked || dst->locked) {
+ return SDL_SetError("Surfaces must not be locked during blit");
+ }
+
+ if (NULL == srcrect) {
+ src_w = src->w;
+ src_h = src->h;
+ } else {
+ src_w = srcrect->w;
+ src_h = srcrect->h;
+ }
+
+ if (NULL == dstrect) {
+ dst_w = dst->w;
+ dst_h = dst->h;
+ } else {
+ dst_w = dstrect->w;
+ dst_h = dstrect->h;
+ }
+
+ if (dst_w == src_w && dst_h == src_h) {
+ /* No scaling, defer to regular blit */
+ return SDL_BlitSurface(src, srcrect, dst, dstrect);
+ }
+
+ scaling_w = (double)dst_w / src_w;
+ scaling_h = (double)dst_h / src_h;
+
+ if (NULL == dstrect) {
+ dst_x0 = 0;
+ dst_y0 = 0;
+ dst_x1 = dst_w - 1;
+ dst_y1 = dst_h - 1;
+ } else {
+ dst_x0 = dstrect->x;
+ dst_y0 = dstrect->y;
+ dst_x1 = dst_x0 + dst_w - 1;
+ dst_y1 = dst_y0 + dst_h - 1;
+ }
+
+ if (NULL == srcrect) {
+ src_x0 = 0;
+ src_y0 = 0;
+ src_x1 = src_w - 1;
+ src_y1 = src_h - 1;
+ } else {
+ src_x0 = srcrect->x;
+ src_y0 = srcrect->y;
+ src_x1 = src_x0 + src_w - 1;
+ src_y1 = src_y0 + src_h - 1;
+
+ /* Clip source rectangle to the source surface */
+
+ if (src_x0 < 0) {
+ dst_x0 -= src_x0 * scaling_w;
+ src_x0 = 0;
+ }
+
+ if (src_x1 >= src->w) {
+ dst_x1 -= (src_x1 - src->w + 1) * scaling_w;
+ src_x1 = src->w - 1;
+ }
+
+ if (src_y0 < 0) {
+ dst_y0 -= src_y0 * scaling_h;
+ src_y0 = 0;
+ }
+
+ if (src_y1 >= src->h) {
+ dst_y1 -= (src_y1 - src->h + 1) * scaling_h;
+ src_y1 = src->h - 1;
+ }
+ }
+
+ /* Clip destination rectangle to the clip rectangle */
+
+ /* Translate to clip space for easier calculations */
+ dst_x0 -= dst->clip_rect.x;
+ dst_x1 -= dst->clip_rect.x;
+ dst_y0 -= dst->clip_rect.y;
+ dst_y1 -= dst->clip_rect.y;
+
+ if (dst_x0 < 0) {
+ src_x0 -= dst_x0 / scaling_w;
+ dst_x0 = 0;
+ }
+
+ if (dst_x1 >= dst->clip_rect.w) {
+ src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w;
+ dst_x1 = dst->clip_rect.w - 1;
+ }
+
+ if (dst_y0 < 0) {
+ src_y0 -= dst_y0 / scaling_h;
+ dst_y0 = 0;
+ }
+
+ if (dst_y1 >= dst->clip_rect.h) {
+ src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h;
+ dst_y1 = dst->clip_rect.h - 1;
+ }
+
+ /* Translate back to surface coordinates */
+ dst_x0 += dst->clip_rect.x;
+ dst_x1 += dst->clip_rect.x;
+ dst_y0 += dst->clip_rect.y;
+ dst_y1 += dst->clip_rect.y;
+
+ final_src.x = (int)SDL_floor(src_x0 + 0.5);
+ final_src.y = (int)SDL_floor(src_y0 + 0.5);
+ final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
+ final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
+
+ final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
+ final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
+ final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5);
+ final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5);
+
+ if (final_dst.w < 0)
+ final_dst.w = 0;
+ if (final_dst.h < 0)
+ final_dst.h = 0;
+
+ if (dstrect)
+ *dstrect = final_dst;
+
+ if (final_dst.w == 0 || final_dst.h == 0 ||
+ final_src.w <= 0 || final_src.h <= 0) {
+ /* No-op. */
+ return 0;
+ }
+
+ return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
+}
+
+/**
+ * This is a semi-private blit function and it performs low-level surface
+ * scaled blitting only.
+ */
+int
+SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect)
+{
+ static const Uint32 complex_copy_flags = (
+ SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA |
+ SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD |
+ SDL_COPY_COLORKEY
+ );
+
+ if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
+ src->map->info.flags |= SDL_COPY_NEAREST;
+ SDL_InvalidateMap(src->map);
+ }
+
+ if ( !(src->map->info.flags & complex_copy_flags) &&
+ src->format->format == dst->format->format &&
+ !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
+ return SDL_SoftStretch( src, srcrect, dst, dstrect );
+ } else {
+ return SDL_LowerBlit( src, srcrect, dst, dstrect );
+ }
+}
+
+/*
+ * Lock a surface to directly access the pixels
+ */
+int
+SDL_LockSurface(SDL_Surface * surface)
+{
+ if (!surface->locked) {
+ /* Perform the lock */
+ if (surface->flags & SDL_RLEACCEL) {
+ SDL_UnRLESurface(surface, 1);
+ surface->flags |= SDL_RLEACCEL; /* save accel'd state */
+ }
+ }
+
+ /* Increment the surface lock count, for recursive locks */
+ ++surface->locked;
+
+ /* Ready to go.. */
+ return (0);
+}
+
+/*
+ * Unlock a previously locked surface
+ */
+void
+SDL_UnlockSurface(SDL_Surface * surface)
+{
+ /* Only perform an unlock if we are locked */
+ if (!surface->locked || (--surface->locked > 0)) {
+ return;
+ }
+
+ /* Update RLE encoded surface with new data */
+ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
+ surface->flags &= ~SDL_RLEACCEL; /* stop lying */
+ SDL_RLESurface(surface);
+ }
+}
+
+/*
+ * Creates a new surface identical to the existing surface
+ */
+SDL_Surface *
+SDL_DuplicateSurface(SDL_Surface * surface)
+{
+ return SDL_ConvertSurface(surface, surface->format, surface->flags);
+}
+
+/*
+ * Convert a surface into the specified pixel format.
+ */
+SDL_Surface *
+SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
+ Uint32 flags)
+{
+ SDL_Surface *convert;
+ Uint32 copy_flags;
+ SDL_Color copy_color;
+ SDL_Rect bounds;
+
+ if (!surface) {
+ SDL_InvalidParamError("surface");
+ return NULL;
+ }
+ if (!format) {
+ SDL_InvalidParamError("format");
+ return NULL;
+ }
+
+ /* Check for empty destination palette! (results in empty image) */
+ if (format->palette != NULL) {
+ int i;
+ for (i = 0; i < format->palette->ncolors; ++i) {
+ if ((format->palette->colors[i].r != 0xFF) ||
+ (format->palette->colors[i].g != 0xFF) ||
+ (format->palette->colors[i].b != 0xFF))
+ break;
+ }
+ if (i == format->palette->ncolors) {
+ SDL_SetError("Empty destination palette");
+ return (NULL);
+ }
+ }
+
+ /* Create a new surface with the desired format */
+ convert = SDL_CreateRGBSurface(flags, surface->w, surface->h,
+ format->BitsPerPixel, format->Rmask,
+ format->Gmask, format->Bmask,
+ format->Amask);
+ if (convert == NULL) {
+ return (NULL);
+ }
+
+ /* Copy the palette if any */
+ if (format->palette && convert->format->palette) {
+ SDL_memcpy(convert->format->palette->colors,
+ format->palette->colors,
+ format->palette->ncolors * sizeof(SDL_Color));
+ convert->format->palette->ncolors = format->palette->ncolors;
+ }
+
+ /* Save the original copy flags */
+ copy_flags = surface->map->info.flags;
+ copy_color.r = surface->map->info.r;
+ copy_color.g = surface->map->info.g;
+ copy_color.b = surface->map->info.b;
+ copy_color.a = surface->map->info.a;
+ surface->map->info.r = 0xFF;
+ surface->map->info.g = 0xFF;
+ surface->map->info.b = 0xFF;
+ surface->map->info.a = 0xFF;
+ surface->map->info.flags = 0;
+ SDL_InvalidateMap(surface->map);
+
+ /* Copy over the image data */
+ bounds.x = 0;
+ bounds.y = 0;
+ bounds.w = surface->w;
+ bounds.h = surface->h;
+ SDL_LowerBlit(surface, &bounds, convert, &bounds);
+
+ /* Clean up the original surface, and update converted surface */
+ convert->map->info.r = copy_color.r;
+ convert->map->info.g = copy_color.g;
+ convert->map->info.b = copy_color.b;
+ convert->map->info.a = copy_color.a;
+ convert->map->info.flags =
+ (copy_flags &
+ ~(SDL_COPY_COLORKEY | SDL_COPY_BLEND
+ | SDL_COPY_RLE_DESIRED | SDL_COPY_RLE_COLORKEY |
+ SDL_COPY_RLE_ALPHAKEY));
+ surface->map->info.r = copy_color.r;
+ surface->map->info.g = copy_color.g;
+ surface->map->info.b = copy_color.b;
+ surface->map->info.a = copy_color.a;
+ surface->map->info.flags = copy_flags;
+ SDL_InvalidateMap(surface->map);
+ if (copy_flags & SDL_COPY_COLORKEY) {
+ SDL_bool set_colorkey_by_color = SDL_FALSE;
+
+ if (surface->format->palette) {
+ if (format->palette &&
+ surface->format->palette->ncolors <= format->palette->ncolors &&
+ (SDL_memcmp(surface->format->palette->colors, format->palette->colors,
+ surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) {
+ /* The palette is identical, just set the same colorkey */
+ SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
+ } else if (format->Amask) {
+ /* The alpha was set in the destination from the palette */
+ } else {
+ set_colorkey_by_color = SDL_TRUE;
+ }
+ } else {
+ set_colorkey_by_color = SDL_TRUE;
+ }
+
+ if (set_colorkey_by_color) {
+ SDL_Surface *tmp;
+ SDL_Surface *tmp2;
+ int converted_colorkey = 0;
+
+ /* Create a dummy surface to get the colorkey converted */
+ tmp = SDL_CreateRGBSurface(0, 1, 1,
+ surface->format->BitsPerPixel, surface->format->Rmask,
+ surface->format->Gmask, surface->format->Bmask,
+ surface->format->Amask);
+
+ /* Share the palette, if any */
+ if (surface->format->palette) {
+ SDL_SetSurfacePalette(tmp, surface->format->palette);
+ }
+
+ SDL_FillRect(tmp, NULL, surface->map->info.colorkey);
+
+ tmp->map->info.flags &= ~SDL_COPY_COLORKEY;
+
+ /* Convertion of the colorkey */
+ tmp2 = SDL_ConvertSurface(tmp, format, 0);
+
+ /* Get the converted colorkey */
+ SDL_memcpy(&converted_colorkey, tmp2->pixels, tmp2->format->BytesPerPixel);
+
+ SDL_FreeSurface(tmp);
+ SDL_FreeSurface(tmp2);
+
+ /* Set the converted colorkey on the new surface */
+ SDL_SetColorKey(convert, 1, converted_colorkey);
+
+ /* This is needed when converting for 3D texture upload */
+ SDL_ConvertColorkeyToAlpha(convert);
+ }
+ }
+ SDL_SetClipRect(convert, &surface->clip_rect);
+
+ /* Enable alpha blending by default if the new surface has an
+ * alpha channel or alpha modulation */
+ if ((surface->format->Amask && format->Amask) ||
+ (copy_flags & SDL_COPY_MODULATE_ALPHA)) {
+ SDL_SetSurfaceBlendMode(convert, SDL_BLENDMODE_BLEND);
+ }
+ if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) {
+ SDL_SetSurfaceRLE(convert, SDL_RLEACCEL);
+ }
+
+ /* We're ready to go! */
+ return (convert);
+}
+
+SDL_Surface *
+SDL_ConvertSurfaceFormat(SDL_Surface * surface, Uint32 pixel_format,
+ Uint32 flags)
+{
+ SDL_PixelFormat *fmt;
+ SDL_Surface *convert = NULL;
+
+ fmt = SDL_AllocFormat(pixel_format);
+ if (fmt) {
+ convert = SDL_ConvertSurface(surface, fmt, flags);
+ SDL_FreeFormat(fmt);
+ }
+ return convert;
+}
+
+/*
+ * Create a surface on the stack for quick blit operations
+ */
+static SDL_INLINE SDL_bool
+SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format,
+ void * pixels, int pitch, SDL_Surface * surface,
+ SDL_PixelFormat * format, SDL_BlitMap * blitmap)
+{
+ if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
+ SDL_SetError("Indexed pixel formats not supported");
+ return SDL_FALSE;
+ }
+ if (SDL_InitFormat(format, pixel_format) < 0) {
+ return SDL_FALSE;
+ }
+
+ SDL_zerop(surface);
+ surface->flags = SDL_PREALLOC;
+ surface->format = format;
+ surface->pixels = pixels;
+ surface->w = width;
+ surface->h = height;
+ surface->pitch = pitch;
+ /* We don't actually need to set up the clip rect for our purposes */
+ /* SDL_SetClipRect(surface, NULL); */
+
+ /* Allocate an empty mapping */
+ SDL_zerop(blitmap);
+ blitmap->info.r = 0xFF;
+ blitmap->info.g = 0xFF;
+ blitmap->info.b = 0xFF;
+ blitmap->info.a = 0xFF;
+ surface->map = blitmap;
+
+ /* The surface is ready to go */
+ surface->refcount = 1;
+ return SDL_TRUE;
+}
+
+/*
+ * Copy a block of pixels of one format to another format
+ */
+int SDL_ConvertPixels(int width, int height,
+ Uint32 src_format, const void * src, int src_pitch,
+ Uint32 dst_format, void * dst, int dst_pitch)
+{
+ SDL_Surface src_surface, dst_surface;
+ SDL_PixelFormat src_fmt, dst_fmt;
+ SDL_BlitMap src_blitmap, dst_blitmap;
+ SDL_Rect rect;
+ void *nonconst_src = (void *) src;
+
+ /* Check to make sure we are blitting somewhere, so we don't crash */
+ if (!dst) {
+ return SDL_InvalidParamError("dst");
+ }
+ if (!dst_pitch) {
+ return SDL_InvalidParamError("dst_pitch");
+ }
+
+ if (SDL_ISPIXELFORMAT_FOURCC(src_format) && SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
+ return SDL_ConvertPixels_YUV_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ } else if (SDL_ISPIXELFORMAT_FOURCC(src_format)) {
+ return SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ } else if (SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
+ return SDL_ConvertPixels_RGB_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ }
+
+ /* Fast path for same format copy */
+ if (src_format == dst_format) {
+ int i;
+ const int bpp = SDL_BYTESPERPIXEL(src_format);
+ width *= bpp;
+ for (i = height; i--;) {
+ SDL_memcpy(dst, src, width);
+ src = (const Uint8*)src + src_pitch;
+ dst = (Uint8*)dst + dst_pitch;
+ }
+ return 0;
+ }
+
+ if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src,
+ src_pitch,
+ &src_surface, &src_fmt, &src_blitmap)) {
+ return -1;
+ }
+ if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch,
+ &dst_surface, &dst_fmt, &dst_blitmap)) {
+ return -1;
+ }
+
+ /* Set up the rect and go! */
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = width;
+ rect.h = height;
+ return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect);
+}
+
+/*
+ * Free a surface created by the above function.
+ */
+void
+SDL_FreeSurface(SDL_Surface * surface)
+{
+ if (surface == NULL) {
+ return;
+ }
+ if (surface->flags & SDL_DONTFREE) {
+ return;
+ }
+ SDL_InvalidateMap(surface->map);
+
+ if (--surface->refcount > 0) {
+ return;
+ }
+ while (surface->locked > 0) {
+ SDL_UnlockSurface(surface);
+ }
+ if (surface->flags & SDL_RLEACCEL) {
+ SDL_UnRLESurface(surface, 0);
+ }
+ if (surface->format) {
+ SDL_SetSurfacePalette(surface, NULL);
+ SDL_FreeFormat(surface->format);
+ surface->format = NULL;
+ }
+ if (!(surface->flags & SDL_PREALLOC)) {
+ SDL_free(surface->pixels);
+ }
+ if (surface->map) {
+ SDL_FreeBlitMap(surface->map);
+ }
+ SDL_free(surface);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_sysvideo.h b/source/3rd-party/SDL2/src/video/SDL_sysvideo.h
new file mode 100644
index 0000000..25862ca
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_sysvideo.h
@@ -0,0 +1,467 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#ifndef SDL_sysvideo_h_
+#define SDL_sysvideo_h_
+
+#include "SDL_messagebox.h"
+#include "SDL_shape.h"
+#include "SDL_thread.h"
+
+#include "SDL_vulkan_internal.h"
+
+/* The SDL video driver */
+
+typedef struct SDL_WindowShaper SDL_WindowShaper;
+typedef struct SDL_ShapeDriver SDL_ShapeDriver;
+typedef struct SDL_VideoDisplay SDL_VideoDisplay;
+typedef struct SDL_VideoDevice SDL_VideoDevice;
+
+/* Define the SDL window-shaper structure */
+struct SDL_WindowShaper
+{
+ /* The window associated with the shaper */
+ SDL_Window *window;
+
+ /* The user's specified coordinates for the window, for once we give it a shape. */
+ Uint32 userx,usery;
+
+ /* The parameters for shape calculation. */
+ SDL_WindowShapeMode mode;
+
+ /* Has this window been assigned a shape? */
+ SDL_bool hasshape;
+
+ void *driverdata;
+};
+
+/* Define the SDL shape driver structure */
+struct SDL_ShapeDriver
+{
+ SDL_WindowShaper *(*CreateShaper)(SDL_Window * window);
+ int (*SetWindowShape)(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode);
+ int (*ResizeWindowShape)(SDL_Window *window);
+};
+
+typedef struct SDL_WindowUserData
+{
+ char *name;
+ void *data;
+ struct SDL_WindowUserData *next;
+} SDL_WindowUserData;
+
+/* Define the SDL window structure, corresponding to toplevel windows */
+struct SDL_Window
+{
+ const void *magic;
+ Uint32 id;
+ char *title;
+ SDL_Surface *icon;
+ int x, y;
+ int w, h;
+ int min_w, min_h;
+ int max_w, max_h;
+ Uint32 flags;
+ Uint32 last_fullscreen_flags;
+
+ /* Stored position and size for windowed mode */
+ SDL_Rect windowed;
+
+ SDL_DisplayMode fullscreen_mode;
+
+ float opacity;
+
+ float brightness;
+ Uint16 *gamma;
+ Uint16 *saved_gamma; /* (just offset into gamma) */
+
+ SDL_Surface *surface;
+ SDL_bool surface_valid;
+
+ SDL_bool is_hiding;
+ SDL_bool is_destroying;
+ SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */
+
+ SDL_WindowShaper *shaper;
+
+ SDL_HitTest hit_test;
+ void *hit_test_data;
+
+ SDL_WindowUserData *data;
+
+ void *driverdata;
+
+ SDL_Window *prev;
+ SDL_Window *next;
+};
+#define FULLSCREEN_VISIBLE(W) \
+ (((W)->flags & SDL_WINDOW_FULLSCREEN) && \
+ ((W)->flags & SDL_WINDOW_SHOWN) && \
+ !((W)->flags & SDL_WINDOW_MINIMIZED))
+
+/*
+ * Define the SDL display structure.
+ * This corresponds to physical monitors attached to the system.
+ */
+struct SDL_VideoDisplay
+{
+ char *name;
+ int max_display_modes;
+ int num_display_modes;
+ SDL_DisplayMode *display_modes;
+ SDL_DisplayMode desktop_mode;
+ SDL_DisplayMode current_mode;
+ SDL_DisplayOrientation orientation;
+
+ SDL_Window *fullscreen_window;
+
+ SDL_VideoDevice *device;
+
+ void *driverdata;
+};
+
+/* Forward declaration */
+struct SDL_SysWMinfo;
+
+/* Define the SDL video driver structure */
+#define _THIS SDL_VideoDevice *_this
+
+struct SDL_VideoDevice
+{
+ /* * * */
+ /* The name of this video driver */
+ const char *name;
+
+ /* * * */
+ /* Initialization/Query functions */
+
+ /*
+ * Initialize the native video subsystem, filling in the list of
+ * displays for this driver, returning 0 or -1 if there's an error.
+ */
+ int (*VideoInit) (_THIS);
+
+ /*
+ * Reverse the effects VideoInit() -- called if VideoInit() fails or
+ * if the application is shutting down the video subsystem.
+ */
+ void (*VideoQuit) (_THIS);
+
+ /*
+ * Reinitialize the touch devices -- called if an unknown touch ID occurs.
+ */
+ void (*ResetTouch) (_THIS);
+
+ /* * * */
+ /*
+ * Display functions
+ */
+
+ /*
+ * Get the bounds of a display
+ */
+ int (*GetDisplayBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+
+ /*
+ * Get the usable bounds of a display (bounds minus menubar or whatever)
+ */
+ int (*GetDisplayUsableBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+
+ /*
+ * Get the dots/pixels-per-inch of a display
+ */
+ int (*GetDisplayDPI) (_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
+
+ /*
+ * Get a list of the available display modes for a display.
+ */
+ void (*GetDisplayModes) (_THIS, SDL_VideoDisplay * display);
+
+ /*
+ * Setting the display mode is independent of creating windows, so
+ * when the display mode is changed, all existing windows should have
+ * their data updated accordingly, including the display surfaces
+ * associated with them.
+ */
+ int (*SetDisplayMode) (_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+
+ /* * * */
+ /*
+ * Window functions
+ */
+ int (*CreateSDLWindow) (_THIS, SDL_Window * window);
+ int (*CreateSDLWindowFrom) (_THIS, SDL_Window * window, const void *data);
+ void (*SetWindowTitle) (_THIS, SDL_Window * window);
+ void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon);
+ void (*SetWindowPosition) (_THIS, SDL_Window * window);
+ void (*SetWindowSize) (_THIS, SDL_Window * window);
+ void (*SetWindowMinimumSize) (_THIS, SDL_Window * window);
+ void (*SetWindowMaximumSize) (_THIS, SDL_Window * window);
+ int (*GetWindowBordersSize) (_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
+ int (*SetWindowOpacity) (_THIS, SDL_Window * window, float opacity);
+ int (*SetWindowModalFor) (_THIS, SDL_Window * modal_window, SDL_Window * parent_window);
+ int (*SetWindowInputFocus) (_THIS, SDL_Window * window);
+ void (*ShowWindow) (_THIS, SDL_Window * window);
+ void (*HideWindow) (_THIS, SDL_Window * window);
+ void (*RaiseWindow) (_THIS, SDL_Window * window);
+ void (*MaximizeWindow) (_THIS, SDL_Window * window);
+ void (*MinimizeWindow) (_THIS, SDL_Window * window);
+ void (*RestoreWindow) (_THIS, SDL_Window * window);
+ void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered);
+ void (*SetWindowResizable) (_THIS, SDL_Window * window, SDL_bool resizable);
+ void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+ int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp);
+ int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp);
+ void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
+ void (*DestroyWindow) (_THIS, SDL_Window * window);
+ int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
+ int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
+ void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
+ void (*OnWindowEnter) (_THIS, SDL_Window * window);
+
+ /* * * */
+ /*
+ * Shaped-window functions
+ */
+ SDL_ShapeDriver shape_driver;
+
+ /* Get some platform dependent window information */
+ SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo * info);
+
+ /* * * */
+ /*
+ * OpenGL support
+ */
+ int (*GL_LoadLibrary) (_THIS, const char *path);
+ void *(*GL_GetProcAddress) (_THIS, const char *proc);
+ void (*GL_UnloadLibrary) (_THIS);
+ SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window);
+ int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context);
+ void (*GL_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h);
+ int (*GL_SetSwapInterval) (_THIS, int interval);
+ int (*GL_GetSwapInterval) (_THIS);
+ int (*GL_SwapWindow) (_THIS, SDL_Window * window);
+ void (*GL_DeleteContext) (_THIS, SDL_GLContext context);
+ void (*GL_DefaultProfileConfig) (_THIS, int *mask, int *major, int *minor);
+
+ /* * * */
+ /*
+ * Vulkan support
+ */
+ int (*Vulkan_LoadLibrary) (_THIS, const char *path);
+ void (*Vulkan_UnloadLibrary) (_THIS);
+ SDL_bool (*Vulkan_GetInstanceExtensions) (_THIS, SDL_Window *window, unsigned *count, const char **names);
+ SDL_bool (*Vulkan_CreateSurface) (_THIS, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface);
+ void (*Vulkan_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h);
+
+ /* * * */
+ /*
+ * Event manager functions
+ */
+ void (*PumpEvents) (_THIS);
+
+ /* Suspend the screensaver */
+ void (*SuspendScreenSaver) (_THIS);
+
+ /* Text input */
+ void (*StartTextInput) (_THIS);
+ void (*StopTextInput) (_THIS);
+ void (*SetTextInputRect) (_THIS, SDL_Rect *rect);
+
+ /* Screen keyboard */
+ SDL_bool (*HasScreenKeyboardSupport) (_THIS);
+ void (*ShowScreenKeyboard) (_THIS, SDL_Window *window);
+ void (*HideScreenKeyboard) (_THIS, SDL_Window *window);
+ SDL_bool (*IsScreenKeyboardShown) (_THIS, SDL_Window *window);
+
+ /* Clipboard */
+ int (*SetClipboardText) (_THIS, const char *text);
+ char * (*GetClipboardText) (_THIS);
+ SDL_bool (*HasClipboardText) (_THIS);
+
+ /* MessageBox */
+ int (*ShowMessageBox) (_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+ /* Hit-testing */
+ int (*SetWindowHitTest)(SDL_Window * window, SDL_bool enabled);
+
+ /* Tell window that app enabled drag'n'drop events */
+ void (*AcceptDragAndDrop)(SDL_Window * window, SDL_bool accept);
+
+ /* * * */
+ /* Data common to all drivers */
+ SDL_bool is_dummy;
+ SDL_bool suspend_screensaver;
+ int num_displays;
+ SDL_VideoDisplay *displays;
+ SDL_Window *windows;
+ SDL_Window *grabbed_window;
+ Uint8 window_magic;
+ Uint32 next_object_id;
+ char *clipboard_text;
+
+ /* * * */
+ /* Data used by the GL drivers */
+ struct
+ {
+ int red_size;
+ int green_size;
+ int blue_size;
+ int alpha_size;
+ int depth_size;
+ int buffer_size;
+ int stencil_size;
+ int double_buffer;
+ int accum_red_size;
+ int accum_green_size;
+ int accum_blue_size;
+ int accum_alpha_size;
+ int stereo;
+ int multisamplebuffers;
+ int multisamplesamples;
+ int accelerated;
+ int major_version;
+ int minor_version;
+ int flags;
+ int profile_mask;
+ int share_with_current_context;
+ int release_behavior;
+ int reset_notification;
+ int framebuffer_srgb_capable;
+ int no_error;
+ int retained_backing;
+ int driver_loaded;
+ char driver_path[256];
+ void *dll_handle;
+ } gl_config;
+
+ /* * * */
+ /* Cache current GL context; don't call the OS when it hasn't changed. */
+ /* We have the global pointers here so Cocoa continues to work the way
+ it always has, and the thread-local storage for the general case.
+ */
+ SDL_Window *current_glwin;
+ SDL_GLContext current_glctx;
+ SDL_TLSID current_glwin_tls;
+ SDL_TLSID current_glctx_tls;
+
+ /* * * */
+ /* Data used by the Vulkan drivers */
+ struct
+ {
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
+ int loader_loaded;
+ char loader_path[256];
+ void *loader_handle;
+ } vulkan_config;
+
+ /* * * */
+ /* Data private to this driver */
+ void *driverdata;
+ struct SDL_GLDriverData *gl_data;
+
+#if SDL_VIDEO_OPENGL_EGL
+ struct SDL_EGL_VideoData *egl_data;
+#endif
+
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ struct SDL_PrivateGLESData *gles_data;
+#endif
+
+ /* * * */
+ /* The function used to dispose of this structure */
+ void (*free) (_THIS);
+};
+
+typedef struct VideoBootStrap
+{
+ const char *name;
+ const char *desc;
+ int (*available) (void);
+ SDL_VideoDevice *(*create) (int devindex);
+} VideoBootStrap;
+
+/* Not all of these are available in a given build. Use #ifdefs, etc. */
+extern VideoBootStrap COCOA_bootstrap;
+extern VideoBootStrap X11_bootstrap;
+extern VideoBootStrap MIR_bootstrap;
+extern VideoBootStrap DirectFB_bootstrap;
+extern VideoBootStrap WINDOWS_bootstrap;
+extern VideoBootStrap WINRT_bootstrap;
+extern VideoBootStrap HAIKU_bootstrap;
+extern VideoBootStrap PND_bootstrap;
+extern VideoBootStrap UIKIT_bootstrap;
+extern VideoBootStrap Android_bootstrap;
+extern VideoBootStrap PSP_bootstrap;
+extern VideoBootStrap RPI_bootstrap;
+extern VideoBootStrap KMSDRM_bootstrap;
+extern VideoBootStrap DUMMY_bootstrap;
+extern VideoBootStrap Wayland_bootstrap;
+extern VideoBootStrap NACL_bootstrap;
+extern VideoBootStrap VIVANTE_bootstrap;
+extern VideoBootStrap Emscripten_bootstrap;
+extern VideoBootStrap QNX_bootstrap;
+
+extern SDL_VideoDevice *SDL_GetVideoDevice(void);
+extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
+extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display);
+extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode);
+extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display);
+extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex);
+extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window);
+extern void *SDL_GetDisplayDriverData( int displayIndex );
+
+extern void SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor);
+
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+extern SDL_bool SDL_HasWindows(void);
+
+extern void SDL_OnWindowShown(SDL_Window * window);
+extern void SDL_OnWindowHidden(SDL_Window * window);
+extern void SDL_OnWindowResized(SDL_Window * window);
+extern void SDL_OnWindowMinimized(SDL_Window * window);
+extern void SDL_OnWindowRestored(SDL_Window * window);
+extern void SDL_OnWindowEnter(SDL_Window * window);
+extern void SDL_OnWindowLeave(SDL_Window * window);
+extern void SDL_OnWindowFocusGained(SDL_Window * window);
+extern void SDL_OnWindowFocusLost(SDL_Window * window);
+extern void SDL_UpdateWindowGrab(SDL_Window * window);
+extern SDL_Window * SDL_GetFocusWindow(void);
+
+extern SDL_bool SDL_ShouldAllowTopmost(void);
+
+extern float SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches);
+
+extern void SDL_OnApplicationWillTerminate(void);
+extern void SDL_OnApplicationDidReceiveMemoryWarning(void);
+extern void SDL_OnApplicationWillResignActive(void);
+extern void SDL_OnApplicationDidEnterBackground(void);
+extern void SDL_OnApplicationWillEnterForeground(void);
+extern void SDL_OnApplicationDidBecomeActive(void);
+
+extern void SDL_ToggleDragAndDropSupport(void);
+
+#endif /* SDL_sysvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_video.c b/source/3rd-party/SDL2/src/video/SDL_video.c
new file mode 100644
index 0000000..336fdaa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_video.c
@@ -0,0 +1,4161 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/* The high-level video driver subsystem */
+
+#include "SDL.h"
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_pixels_c.h"
+#include "SDL_rect_c.h"
+#include "../events/SDL_events_c.h"
+#include "../timer/SDL_timer_c.h"
+
+#include "SDL_syswm.h"
+
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#endif /* SDL_VIDEO_OPENGL */
+
+#if SDL_VIDEO_OPENGL_ES
+#include "SDL_opengles.h"
+#endif /* SDL_VIDEO_OPENGL_ES */
+
+/* GL and GLES2 headers conflict on Linux 32 bits */
+#if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL
+#include "SDL_opengles2.h"
+#endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
+
+#if !SDL_VIDEO_OPENGL
+#ifndef GL_CONTEXT_RELEASE_BEHAVIOR_KHR
+#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
+#endif
+#endif
+
+#ifdef __EMSCRIPTEN__
+#include <emscripten.h>
+#endif
+
+/* Available video drivers */
+static VideoBootStrap *bootstrap[] = {
+#if SDL_VIDEO_DRIVER_COCOA
+ &COCOA_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_X11
+ &X11_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_MIR
+ &MIR_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_WAYLAND
+ &Wayland_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_VIVANTE
+ &VIVANTE_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DIRECTFB
+ &DirectFB_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_WINDOWS
+ &WINDOWS_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_WINRT
+ &WINRT_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_HAIKU
+ &HAIKU_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_PANDORA
+ &PND_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_UIKIT
+ &UIKIT_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_ANDROID
+ &Android_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_PSP
+ &PSP_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_KMSDRM
+ &KMSDRM_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_RPI
+ &RPI_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_NACL
+ &NACL_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN
+ &Emscripten_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_QNX
+ &QNX_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DUMMY
+ &DUMMY_bootstrap,
+#endif
+ NULL
+};
+
+static SDL_VideoDevice *_this = NULL;
+
+#define CHECK_WINDOW_MAGIC(window, retval) \
+ if (!_this) { \
+ SDL_UninitializedVideo(); \
+ return retval; \
+ } \
+ SDL_assert(window && window->magic == &_this->window_magic); \
+ if (!window || window->magic != &_this->window_magic) { \
+ SDL_SetError("Invalid window"); \
+ return retval; \
+ }
+
+#define CHECK_DISPLAY_INDEX(displayIndex, retval) \
+ if (!_this) { \
+ SDL_UninitializedVideo(); \
+ return retval; \
+ } \
+ SDL_assert(_this->displays != NULL); \
+ SDL_assert(displayIndex >= 0 && displayIndex < _this->num_displays); \
+ if (displayIndex < 0 || displayIndex >= _this->num_displays) { \
+ SDL_SetError("displayIndex must be in the range 0 - %d", \
+ _this->num_displays - 1); \
+ return retval; \
+ }
+
+#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
+
+#ifdef __MACOSX__
+/* Support for Mac OS X fullscreen spaces */
+extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window);
+extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state);
+#endif
+
+
+/* Support for framebuffer emulation using an accelerated renderer */
+
+#define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData"
+
+typedef struct {
+ SDL_Renderer *renderer;
+ SDL_Texture *texture;
+ void *pixels;
+ int pitch;
+ int bytes_per_pixel;
+} SDL_WindowTextureData;
+
+static SDL_bool
+ShouldUseTextureFramebuffer()
+{
+ const char *hint;
+
+ /* If there's no native framebuffer support then there's no option */
+ if (!_this->CreateWindowFramebuffer) {
+ return SDL_TRUE;
+ }
+
+ /* If this is the dummy driver there is no texture support */
+ if (_this->is_dummy) {
+ return SDL_FALSE;
+ }
+
+ /* If the user has specified a software renderer we can't use a
+ texture framebuffer, or renderer creation will go recursive.
+ */
+ hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
+ if (hint && SDL_strcasecmp(hint, "software") == 0) {
+ return SDL_FALSE;
+ }
+
+ /* See if the user or application wants a specific behavior */
+ hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
+ if (hint) {
+ if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) {
+ return SDL_FALSE;
+ } else {
+ return SDL_TRUE;
+ }
+ }
+
+ /* Each platform has different performance characteristics */
+#if defined(__WIN32__)
+ /* GDI BitBlt() is way faster than Direct3D dynamic textures right now.
+ */
+ return SDL_FALSE;
+
+#elif defined(__MACOSX__)
+ /* Mac OS X uses OpenGL as the native fast path (for cocoa and X11) */
+ return SDL_TRUE;
+
+#elif defined(__LINUX__)
+ /* Properly configured OpenGL drivers are faster than MIT-SHM */
+#if SDL_VIDEO_OPENGL
+ /* Ugh, find a way to cache this value! */
+ {
+ SDL_Window *window;
+ SDL_GLContext context;
+ SDL_bool hasAcceleratedOpenGL = SDL_FALSE;
+
+ window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN);
+ if (window) {
+ context = SDL_GL_CreateContext(window);
+ if (context) {
+ const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
+ const char *vendor = NULL;
+
+ glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
+ if (glGetStringFunc) {
+ vendor = (const char *) glGetStringFunc(GL_VENDOR);
+ }
+ /* Add more vendors here at will... */
+ if (vendor &&
+ (SDL_strstr(vendor, "ATI Technologies") ||
+ SDL_strstr(vendor, "NVIDIA"))) {
+ hasAcceleratedOpenGL = SDL_TRUE;
+ }
+ SDL_GL_DeleteContext(context);
+ }
+ SDL_DestroyWindow(window);
+ }
+ return hasAcceleratedOpenGL;
+ }
+#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ /* Let's be optimistic about this! */
+ return SDL_TRUE;
+#else
+ return SDL_FALSE;
+#endif
+
+#else
+ /* Play it safe, assume that if there is a framebuffer driver that it's
+ optimized for the current platform.
+ */
+ return SDL_FALSE;
+#endif
+}
+
+static int
+SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
+{
+ SDL_WindowTextureData *data;
+
+ data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
+ if (!data) {
+ SDL_Renderer *renderer = NULL;
+ int i;
+ const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
+
+ /* Check to see if there's a specific driver requested */
+ if (hint && *hint != '0' && *hint != '1' &&
+ SDL_strcasecmp(hint, "true") != 0 &&
+ SDL_strcasecmp(hint, "false") != 0 &&
+ SDL_strcasecmp(hint, "software") != 0) {
+ for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
+ SDL_RendererInfo info;
+ SDL_GetRenderDriverInfo(i, &info);
+ if (SDL_strcasecmp(info.name, hint) == 0) {
+ renderer = SDL_CreateRenderer(window, i, 0);
+ break;
+ }
+ }
+ }
+
+ if (!renderer) {
+ for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
+ SDL_RendererInfo info;
+ SDL_GetRenderDriverInfo(i, &info);
+ if (SDL_strcmp(info.name, "software") != 0) {
+ renderer = SDL_CreateRenderer(window, i, 0);
+ if (renderer) {
+ break;
+ }
+ }
+ }
+ }
+ if (!renderer) {
+ return SDL_SetError("No hardware accelerated renderers available");
+ }
+
+ /* Create the data after we successfully create the renderer (bug #1116) */
+ data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ SDL_DestroyRenderer(renderer);
+ return SDL_OutOfMemory();
+ }
+ SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data);
+
+ data->renderer = renderer;
+ }
+
+ /* Free any old texture and pixel data */
+ if (data->texture) {
+ SDL_DestroyTexture(data->texture);
+ data->texture = NULL;
+ }
+ SDL_free(data->pixels);
+ data->pixels = NULL;
+
+ {
+ SDL_RendererInfo info;
+ Uint32 i;
+
+ if (SDL_GetRendererInfo(data->renderer, &info) < 0) {
+ return -1;
+ }
+
+ /* Find the first format without an alpha channel */
+ *format = info.texture_formats[0];
+
+ for (i = 0; i < info.num_texture_formats; ++i) {
+ if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) &&
+ !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) {
+ *format = info.texture_formats[i];
+ break;
+ }
+ }
+ }
+
+ data->texture = SDL_CreateTexture(data->renderer, *format,
+ SDL_TEXTUREACCESS_STREAMING,
+ window->w, window->h);
+ if (!data->texture) {
+ return -1;
+ }
+
+ /* Create framebuffer data */
+ data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format);
+ data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
+
+ {
+ /* Make static analysis happy about potential malloc(0) calls. */
+ const size_t allocsize = window->h * data->pitch;
+ data->pixels = SDL_malloc((allocsize > 0) ? allocsize : 1);
+ if (!data->pixels) {
+ return SDL_OutOfMemory();
+ }
+ }
+
+ *pixels = data->pixels;
+ *pitch = data->pitch;
+
+ /* Make sure we're not double-scaling the viewport */
+ SDL_RenderSetViewport(data->renderer, NULL);
+
+ return 0;
+}
+
+static int
+SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_Rect * rects, int numrects)
+{
+ SDL_WindowTextureData *data;
+ SDL_Rect rect;
+ void *src;
+
+ data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
+ if (!data || !data->texture) {
+ return SDL_SetError("No window texture data");
+ }
+
+ /* Update a single rect that contains subrects for best DMA performance */
+ if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
+ src = (void *)((Uint8 *)data->pixels +
+ rect.y * data->pitch +
+ rect.x * data->bytes_per_pixel);
+ if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
+ return -1;
+ }
+
+ if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ SDL_RenderPresent(data->renderer);
+ }
+ return 0;
+}
+
+static void
+SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window)
+{
+ SDL_WindowTextureData *data;
+
+ data = SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, NULL);
+ if (!data) {
+ return;
+ }
+ if (data->texture) {
+ SDL_DestroyTexture(data->texture);
+ }
+ if (data->renderer) {
+ SDL_DestroyRenderer(data->renderer);
+ }
+ SDL_free(data->pixels);
+ SDL_free(data);
+}
+
+
+static int
+cmpmodes(const void *A, const void *B)
+{
+ const SDL_DisplayMode *a = (const SDL_DisplayMode *) A;
+ const SDL_DisplayMode *b = (const SDL_DisplayMode *) B;
+ if (a == b) {
+ return 0;
+ } else if (a->w != b->w) {
+ return b->w - a->w;
+ } else if (a->h != b->h) {
+ return b->h - a->h;
+ } else if (SDL_BITSPERPIXEL(a->format) != SDL_BITSPERPIXEL(b->format)) {
+ return SDL_BITSPERPIXEL(b->format) - SDL_BITSPERPIXEL(a->format);
+ } else if (SDL_PIXELLAYOUT(a->format) != SDL_PIXELLAYOUT(b->format)) {
+ return SDL_PIXELLAYOUT(b->format) - SDL_PIXELLAYOUT(a->format);
+ } else if (a->refresh_rate != b->refresh_rate) {
+ return b->refresh_rate - a->refresh_rate;
+ }
+ return 0;
+}
+
+static int
+SDL_UninitializedVideo()
+{
+ return SDL_SetError("Video subsystem has not been initialized");
+}
+
+int
+SDL_GetNumVideoDrivers(void)
+{
+ return SDL_arraysize(bootstrap) - 1;
+}
+
+const char *
+SDL_GetVideoDriver(int index)
+{
+ if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
+ return bootstrap[index]->name;
+ }
+ return NULL;
+}
+
+/*
+ * Initialize the video and event subsystems -- determine native pixel format
+ */
+int
+SDL_VideoInit(const char *driver_name)
+{
+ SDL_VideoDevice *video;
+ int index;
+ int i;
+
+ /* Check to make sure we don't overwrite '_this' */
+ if (_this != NULL) {
+ SDL_VideoQuit();
+ }
+
+#if !SDL_TIMERS_DISABLED
+ SDL_TicksInit();
+#endif
+
+ /* Start the event loop */
+ if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 ||
+ SDL_KeyboardInit() < 0 ||
+ SDL_MouseInit() < 0 ||
+ SDL_TouchInit() < 0) {
+ return -1;
+ }
+
+ /* Select the proper video driver */
+ index = 0;
+ video = NULL;
+ if (driver_name == NULL) {
+ driver_name = SDL_getenv("SDL_VIDEODRIVER");
+ }
+ if (driver_name != NULL) {
+ for (i = 0; bootstrap[i]; ++i) {
+ if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) {
+ if (bootstrap[i]->available()) {
+ video = bootstrap[i]->create(index);
+ break;
+ }
+ }
+ }
+ } else {
+ for (i = 0; bootstrap[i]; ++i) {
+ if (bootstrap[i]->available()) {
+ video = bootstrap[i]->create(index);
+ if (video != NULL) {
+ break;
+ }
+ }
+ }
+ }
+ if (video == NULL) {
+ if (driver_name) {
+ return SDL_SetError("%s not available", driver_name);
+ }
+ return SDL_SetError("No available video device");
+ }
+ _this = video;
+ _this->name = bootstrap[i]->name;
+ _this->next_object_id = 1;
+
+
+ /* Set some very sane GL defaults */
+ _this->gl_config.driver_loaded = 0;
+ _this->gl_config.dll_handle = NULL;
+ SDL_GL_ResetAttributes();
+
+ _this->current_glwin_tls = SDL_TLSCreate();
+ _this->current_glctx_tls = SDL_TLSCreate();
+
+ /* Initialize the video subsystem */
+ if (_this->VideoInit(_this) < 0) {
+ SDL_VideoQuit();
+ return -1;
+ }
+
+ /* Make sure some displays were added */
+ if (_this->num_displays == 0) {
+ SDL_VideoQuit();
+ return SDL_SetError("The video driver did not add any displays");
+ }
+
+ /* Add the renderer framebuffer emulation if desired */
+ if (ShouldUseTextureFramebuffer()) {
+ _this->CreateWindowFramebuffer = SDL_CreateWindowTexture;
+ _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture;
+ _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture;
+ }
+
+ /* Disable the screen saver by default. This is a change from <= 2.0.1,
+ but most things using SDL are games or media players; you wouldn't
+ want a screensaver to trigger if you're playing exclusively with a
+ joystick, or passively watching a movie. Things that use SDL but
+ function more like a normal desktop app should explicitly reenable the
+ screensaver. */
+ if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, SDL_FALSE)) {
+ SDL_DisableScreenSaver();
+ }
+
+ /* If we don't use a screen keyboard, turn on text input by default,
+ otherwise programs that expect to get text events without enabling
+ UNICODE input won't get any events.
+
+ Actually, come to think of it, you needed to call SDL_EnableUNICODE(1)
+ in SDL 1.2 before you got text input events. Hmm...
+ */
+ if (!SDL_HasScreenKeyboardSupport()) {
+ SDL_StartTextInput();
+ }
+
+ /* We're ready to go! */
+ return 0;
+}
+
+const char *
+SDL_GetCurrentVideoDriver()
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return NULL;
+ }
+ return _this->name;
+}
+
+SDL_VideoDevice *
+SDL_GetVideoDevice(void)
+{
+ return _this;
+}
+
+int
+SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
+{
+ SDL_VideoDisplay display;
+
+ SDL_zero(display);
+ if (desktop_mode) {
+ display.desktop_mode = *desktop_mode;
+ }
+ display.current_mode = display.desktop_mode;
+
+ return SDL_AddVideoDisplay(&display);
+}
+
+int
+SDL_AddVideoDisplay(const SDL_VideoDisplay * display)
+{
+ SDL_VideoDisplay *displays;
+ int index = -1;
+
+ displays =
+ SDL_realloc(_this->displays,
+ (_this->num_displays + 1) * sizeof(*displays));
+ if (displays) {
+ index = _this->num_displays++;
+ displays[index] = *display;
+ displays[index].device = _this;
+ _this->displays = displays;
+
+ if (display->name) {
+ displays[index].name = SDL_strdup(display->name);
+ } else {
+ char name[32];
+
+ SDL_itoa(index, name, 10);
+ displays[index].name = SDL_strdup(name);
+ }
+ } else {
+ SDL_OutOfMemory();
+ }
+ return index;
+}
+
+int
+SDL_GetNumVideoDisplays(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return 0;
+ }
+ return _this->num_displays;
+}
+
+int
+SDL_GetIndexOfDisplay(SDL_VideoDisplay *display)
+{
+ int displayIndex;
+
+ for (displayIndex = 0; displayIndex < _this->num_displays; ++displayIndex) {
+ if (display == &_this->displays[displayIndex]) {
+ return displayIndex;
+ }
+ }
+
+ /* Couldn't find the display, just use index 0 */
+ return 0;
+}
+
+void *
+SDL_GetDisplayDriverData(int displayIndex)
+{
+ CHECK_DISPLAY_INDEX(displayIndex, NULL);
+
+ return _this->displays[displayIndex].driverdata;
+}
+
+const char *
+SDL_GetDisplayName(int displayIndex)
+{
+ CHECK_DISPLAY_INDEX(displayIndex, NULL);
+
+ return _this->displays[displayIndex].name;
+}
+
+int
+SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
+{
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ if (rect) {
+ SDL_VideoDisplay *display = &_this->displays[displayIndex];
+
+ if (_this->GetDisplayBounds) {
+ if (_this->GetDisplayBounds(_this, display, rect) == 0) {
+ return 0;
+ }
+ }
+
+ /* Assume that the displays are left to right */
+ if (displayIndex == 0) {
+ rect->x = 0;
+ rect->y = 0;
+ } else {
+ SDL_GetDisplayBounds(displayIndex-1, rect);
+ rect->x += rect->w;
+ }
+ rect->w = display->current_mode.w;
+ rect->h = display->current_mode.h;
+ }
+ return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
+}
+
+int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect)
+{
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ if (rect) {
+ SDL_VideoDisplay *display = &_this->displays[displayIndex];
+
+ if (_this->GetDisplayUsableBounds) {
+ if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) {
+ return 0;
+ }
+ }
+
+ /* Oh well, just give the entire display bounds. */
+ return SDL_GetDisplayBounds(displayIndex, rect);
+ }
+ return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
+}
+
+int
+SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ display = &_this->displays[displayIndex];
+
+ if (_this->GetDisplayDPI) {
+ if (_this->GetDisplayDPI(_this, display, ddpi, hdpi, vdpi) == 0) {
+ return 0;
+ }
+ } else {
+ return SDL_Unsupported();
+ }
+
+ return -1;
+}
+
+SDL_DisplayOrientation
+SDL_GetDisplayOrientation(int displayIndex)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_DISPLAY_INDEX(displayIndex, SDL_ORIENTATION_UNKNOWN);
+
+ display = &_this->displays[displayIndex];
+ return display->orientation;
+}
+
+SDL_bool
+SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
+{
+ SDL_DisplayMode *modes;
+ int i, nmodes;
+
+ /* Make sure we don't already have the mode in the list */
+ modes = display->display_modes;
+ nmodes = display->num_display_modes;
+ for (i = 0; i < nmodes; ++i) {
+ if (cmpmodes(mode, &modes[i]) == 0) {
+ return SDL_FALSE;
+ }
+ }
+
+ /* Go ahead and add the new mode */
+ if (nmodes == display->max_display_modes) {
+ modes =
+ SDL_realloc(modes,
+ (display->max_display_modes + 32) * sizeof(*modes));
+ if (!modes) {
+ return SDL_FALSE;
+ }
+ display->display_modes = modes;
+ display->max_display_modes += 32;
+ }
+ modes[nmodes] = *mode;
+ display->num_display_modes++;
+
+ /* Re-sort video modes */
+ SDL_qsort(display->display_modes, display->num_display_modes,
+ sizeof(SDL_DisplayMode), cmpmodes);
+
+ return SDL_TRUE;
+}
+
+static int
+SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display)
+{
+ if (!display->num_display_modes && _this->GetDisplayModes) {
+ _this->GetDisplayModes(_this, display);
+ SDL_qsort(display->display_modes, display->num_display_modes,
+ sizeof(SDL_DisplayMode), cmpmodes);
+ }
+ return display->num_display_modes;
+}
+
+int
+SDL_GetNumDisplayModes(int displayIndex)
+{
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]);
+}
+
+int
+SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ display = &_this->displays[displayIndex];
+ if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) {
+ return SDL_SetError("index must be in the range of 0 - %d",
+ SDL_GetNumDisplayModesForDisplay(display) - 1);
+ }
+ if (mode) {
+ *mode = display->display_modes[index];
+ }
+ return 0;
+}
+
+int
+SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ display = &_this->displays[displayIndex];
+ if (mode) {
+ *mode = display->desktop_mode;
+ }
+ return 0;
+}
+
+int
+SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_DISPLAY_INDEX(displayIndex, -1);
+
+ display = &_this->displays[displayIndex];
+ if (mode) {
+ *mode = display->current_mode;
+ }
+ return 0;
+}
+
+static SDL_DisplayMode *
+SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display,
+ const SDL_DisplayMode * mode,
+ SDL_DisplayMode * closest)
+{
+ Uint32 target_format;
+ int target_refresh_rate;
+ int i;
+ SDL_DisplayMode *current, *match;
+
+ if (!mode || !closest) {
+ SDL_SetError("Missing desired mode or closest mode parameter");
+ return NULL;
+ }
+
+ /* Default to the desktop format */
+ if (mode->format) {
+ target_format = mode->format;
+ } else {
+ target_format = display->desktop_mode.format;
+ }
+
+ /* Default to the desktop refresh rate */
+ if (mode->refresh_rate) {
+ target_refresh_rate = mode->refresh_rate;
+ } else {
+ target_refresh_rate = display->desktop_mode.refresh_rate;
+ }
+
+ match = NULL;
+ for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) {
+ current = &display->display_modes[i];
+
+ if (current->w && (current->w < mode->w)) {
+ /* Out of sorted modes large enough here */
+ break;
+ }
+ if (current->h && (current->h < mode->h)) {
+ if (current->w && (current->w == mode->w)) {
+ /* Out of sorted modes large enough here */
+ break;
+ }
+ /* Wider, but not tall enough, due to a different
+ aspect ratio. This mode must be skipped, but closer
+ modes may still follow. */
+ continue;
+ }
+ if (!match || current->w < match->w || current->h < match->h) {
+ match = current;
+ continue;
+ }
+ if (current->format != match->format) {
+ /* Sorted highest depth to lowest */
+ if (current->format == target_format ||
+ (SDL_BITSPERPIXEL(current->format) >=
+ SDL_BITSPERPIXEL(target_format)
+ && SDL_PIXELTYPE(current->format) ==
+ SDL_PIXELTYPE(target_format))) {
+ match = current;
+ }
+ continue;
+ }
+ if (current->refresh_rate != match->refresh_rate) {
+ /* Sorted highest refresh to lowest */
+ if (current->refresh_rate >= target_refresh_rate) {
+ match = current;
+ }
+ }
+ }
+ if (match) {
+ if (match->format) {
+ closest->format = match->format;
+ } else {
+ closest->format = mode->format;
+ }
+ if (match->w && match->h) {
+ closest->w = match->w;
+ closest->h = match->h;
+ } else {
+ closest->w = mode->w;
+ closest->h = mode->h;
+ }
+ if (match->refresh_rate) {
+ closest->refresh_rate = match->refresh_rate;
+ } else {
+ closest->refresh_rate = mode->refresh_rate;
+ }
+ closest->driverdata = match->driverdata;
+
+ /*
+ * Pick some reasonable defaults if the app and driver don't
+ * care
+ */
+ if (!closest->format) {
+ closest->format = SDL_PIXELFORMAT_RGB888;
+ }
+ if (!closest->w) {
+ closest->w = 640;
+ }
+ if (!closest->h) {
+ closest->h = 480;
+ }
+ return closest;
+ }
+ return NULL;
+}
+
+SDL_DisplayMode *
+SDL_GetClosestDisplayMode(int displayIndex,
+ const SDL_DisplayMode * mode,
+ SDL_DisplayMode * closest)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_DISPLAY_INDEX(displayIndex, NULL);
+
+ display = &_this->displays[displayIndex];
+ return SDL_GetClosestDisplayModeForDisplay(display, mode, closest);
+}
+
+static int
+SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
+{
+ SDL_DisplayMode display_mode;
+ SDL_DisplayMode current_mode;
+
+ if (mode) {
+ display_mode = *mode;
+
+ /* Default to the current mode */
+ if (!display_mode.format) {
+ display_mode.format = display->current_mode.format;
+ }
+ if (!display_mode.w) {
+ display_mode.w = display->current_mode.w;
+ }
+ if (!display_mode.h) {
+ display_mode.h = display->current_mode.h;
+ }
+ if (!display_mode.refresh_rate) {
+ display_mode.refresh_rate = display->current_mode.refresh_rate;
+ }
+
+ /* Get a good video mode, the closest one possible */
+ if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
+ return SDL_SetError("No video mode large enough for %dx%d",
+ display_mode.w, display_mode.h);
+ }
+ } else {
+ display_mode = display->desktop_mode;
+ }
+
+ /* See if there's anything left to do */
+ current_mode = display->current_mode;
+ if (SDL_memcmp(&display_mode, &current_mode, sizeof(display_mode)) == 0) {
+ return 0;
+ }
+
+ /* Actually change the display mode */
+ if (!_this->SetDisplayMode) {
+ return SDL_SetError("SDL video driver doesn't support changing display mode");
+ }
+ if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
+ return -1;
+ }
+ display->current_mode = display_mode;
+ return 0;
+}
+
+SDL_VideoDisplay *
+SDL_GetDisplay(int displayIndex)
+{
+ CHECK_DISPLAY_INDEX(displayIndex, NULL);
+
+ return &_this->displays[displayIndex];
+}
+
+int
+SDL_GetWindowDisplayIndex(SDL_Window * window)
+{
+ int displayIndex;
+ int i, dist;
+ int closest = -1;
+ int closest_dist = 0x7FFFFFFF;
+ SDL_Point center;
+ SDL_Point delta;
+ SDL_Rect rect;
+
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (SDL_WINDOWPOS_ISUNDEFINED(window->x) ||
+ SDL_WINDOWPOS_ISCENTERED(window->x)) {
+ displayIndex = (window->x & 0xFFFF);
+ if (displayIndex >= _this->num_displays) {
+ displayIndex = 0;
+ }
+ return displayIndex;
+ }
+ if (SDL_WINDOWPOS_ISUNDEFINED(window->y) ||
+ SDL_WINDOWPOS_ISCENTERED(window->y)) {
+ displayIndex = (window->y & 0xFFFF);
+ if (displayIndex >= _this->num_displays) {
+ displayIndex = 0;
+ }
+ return displayIndex;
+ }
+
+ /* Find the display containing the window */
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+
+ if (display->fullscreen_window == window) {
+ return i;
+ }
+ }
+ center.x = window->x + window->w / 2;
+ center.y = window->y + window->h / 2;
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_GetDisplayBounds(i, &rect);
+ if (SDL_EnclosePoints(&center, 1, &rect, NULL)) {
+ return i;
+ }
+
+ delta.x = center.x - (rect.x + rect.w / 2);
+ delta.y = center.y - (rect.y + rect.h / 2);
+ dist = (delta.x*delta.x + delta.y*delta.y);
+ if (dist < closest_dist) {
+ closest = i;
+ closest_dist = dist;
+ }
+ }
+ if (closest < 0) {
+ SDL_SetError("Couldn't find any displays");
+ }
+ return closest;
+}
+
+SDL_VideoDisplay *
+SDL_GetDisplayForWindow(SDL_Window *window)
+{
+ int displayIndex = SDL_GetWindowDisplayIndex(window);
+ if (displayIndex >= 0) {
+ return &_this->displays[displayIndex];
+ } else {
+ return NULL;
+ }
+}
+
+int
+SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (mode) {
+ window->fullscreen_mode = *mode;
+ } else {
+ SDL_zero(window->fullscreen_mode);
+ }
+
+ if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ SDL_DisplayMode fullscreen_mode;
+ if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
+ SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode);
+ }
+ }
+ return 0;
+}
+
+int
+SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
+{
+ SDL_DisplayMode fullscreen_mode;
+ SDL_VideoDisplay *display;
+
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!mode) {
+ return SDL_InvalidParamError("mode");
+ }
+
+ fullscreen_mode = window->fullscreen_mode;
+ if (!fullscreen_mode.w) {
+ fullscreen_mode.w = window->windowed.w;
+ }
+ if (!fullscreen_mode.h) {
+ fullscreen_mode.h = window->windowed.h;
+ }
+
+ display = SDL_GetDisplayForWindow(window);
+
+ /* if in desktop size mode, just return the size of the desktop */
+ if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ fullscreen_mode = display->desktop_mode;
+ } else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window),
+ &fullscreen_mode,
+ &fullscreen_mode)) {
+ return SDL_SetError("Couldn't find display mode match");
+ }
+
+ if (mode) {
+ *mode = fullscreen_mode;
+ }
+ return 0;
+}
+
+Uint32
+SDL_GetWindowPixelFormat(SDL_Window * window)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN);
+
+ display = SDL_GetDisplayForWindow(window);
+ return display->current_mode.format;
+}
+
+static void
+SDL_RestoreMousePosition(SDL_Window *window)
+{
+ int x, y;
+
+ if (window == SDL_GetMouseFocus()) {
+ SDL_GetMouseState(&x, &y);
+ SDL_WarpMouseInWindow(window, x, y);
+ }
+}
+
+#if __WINRT__
+extern Uint32 WINRT_DetectWindowFlags(SDL_Window * window);
+#endif
+
+static int
+SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
+{
+ SDL_VideoDisplay *display;
+ SDL_Window *other;
+
+ CHECK_WINDOW_MAGIC(window,-1);
+
+ /* if we are in the process of hiding don't go back to fullscreen */
+ if (window->is_hiding && fullscreen) {
+ return 0;
+ }
+
+#ifdef __MACOSX__
+ /* if the window is going away and no resolution change is necessary,
+ do nothing, or else we may trigger an ugly double-transition
+ */
+ if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */
+ if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)
+ return 0;
+
+ /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
+ if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
+ if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
+ return -1;
+ }
+ } else if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
+ display = SDL_GetDisplayForWindow(window);
+ SDL_SetDisplayModeForDisplay(display, NULL);
+ if (_this->SetWindowFullscreen) {
+ _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
+ }
+ }
+
+ if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
+ if (Cocoa_IsWindowInFullscreenSpace(window) != fullscreen) {
+ return -1;
+ }
+ window->last_fullscreen_flags = window->flags;
+ return 0;
+ }
+ }
+#elif __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
+ /* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen
+ or not. The user can choose this, via OS-provided UI, but this can't
+ be set programmatically.
+
+ Just look at what SDL's WinRT video backend code detected with regards
+ to fullscreen (being active, or not), and figure out a return/error code
+ from that.
+ */
+ if (fullscreen == !(WINRT_DetectWindowFlags(window) & FULLSCREEN_MASK)) {
+ /* Uh oh, either:
+ 1. fullscreen was requested, and we're already windowed
+ 2. windowed-mode was requested, and we're already fullscreen
+
+ WinRT 8.x can't resolve either programmatically, so we're
+ giving up.
+ */
+ return -1;
+ } else {
+ /* Whatever was requested, fullscreen or windowed mode, is already
+ in-place.
+ */
+ return 0;
+ }
+#endif
+
+ display = SDL_GetDisplayForWindow(window);
+
+ if (fullscreen) {
+ /* Hide any other fullscreen windows */
+ if (display->fullscreen_window &&
+ display->fullscreen_window != window) {
+ SDL_MinimizeWindow(display->fullscreen_window);
+ }
+ }
+
+ /* See if anything needs to be done now */
+ if ((display->fullscreen_window == window) == fullscreen) {
+ if ((window->last_fullscreen_flags & FULLSCREEN_MASK) == (window->flags & FULLSCREEN_MASK)) {
+ return 0;
+ }
+ }
+
+ /* See if there are any fullscreen windows */
+ for (other = _this->windows; other; other = other->next) {
+ SDL_bool setDisplayMode = SDL_FALSE;
+
+ if (other == window) {
+ setDisplayMode = fullscreen;
+ } else if (FULLSCREEN_VISIBLE(other) &&
+ SDL_GetDisplayForWindow(other) == display) {
+ setDisplayMode = SDL_TRUE;
+ }
+
+ if (setDisplayMode) {
+ SDL_DisplayMode fullscreen_mode;
+
+ SDL_zero(fullscreen_mode);
+
+ if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) {
+ SDL_bool resized = SDL_TRUE;
+
+ if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) {
+ resized = SDL_FALSE;
+ }
+
+ /* only do the mode change if we want exclusive fullscreen */
+ if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
+ return -1;
+ }
+ } else {
+ if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
+ return -1;
+ }
+ }
+
+ if (_this->SetWindowFullscreen) {
+ _this->SetWindowFullscreen(_this, other, display, SDL_TRUE);
+ }
+ display->fullscreen_window = other;
+
+ /* Generate a mode change event here */
+ if (resized) {
+#ifndef ANDROID
+ // Android may not resize the window to exactly what our fullscreen mode is, especially on
+ // windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't
+ // use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such,
+ // Android's SetWindowFullscreen will generate the window event for us with the proper final size.
+
+ SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED,
+ fullscreen_mode.w, fullscreen_mode.h);
+#endif
+ } else {
+ SDL_OnWindowResized(other);
+ }
+
+ SDL_RestoreMousePosition(other);
+
+ window->last_fullscreen_flags = window->flags;
+ return 0;
+ }
+ }
+ }
+
+ /* Nope, restore the desktop mode */
+ SDL_SetDisplayModeForDisplay(display, NULL);
+
+ if (_this->SetWindowFullscreen) {
+ _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
+ }
+ display->fullscreen_window = NULL;
+
+ /* Generate a mode change event here */
+ SDL_OnWindowResized(window);
+
+ /* Restore the cursor position */
+ SDL_RestoreMousePosition(window);
+
+ window->last_fullscreen_flags = window->flags;
+ return 0;
+}
+
+#define CREATE_FLAGS \
+ (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN | SDL_WINDOW_MINIMIZED)
+
+static SDL_INLINE SDL_bool
+IsAcceptingDragAndDrop(void)
+{
+ if ((SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) ||
+ (SDL_GetEventState(SDL_DROPTEXT) == SDL_ENABLE)) {
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
+}
+
+/* prepare a newly-created window */
+static SDL_INLINE void
+PrepareDragAndDropSupport(SDL_Window *window)
+{
+ if (_this->AcceptDragAndDrop) {
+ _this->AcceptDragAndDrop(window, IsAcceptingDragAndDrop());
+ }
+}
+
+/* toggle d'n'd for all existing windows. */
+void
+SDL_ToggleDragAndDropSupport(void)
+{
+ if (_this && _this->AcceptDragAndDrop) {
+ const SDL_bool enable = IsAcceptingDragAndDrop();
+ SDL_Window *window;
+ for (window = _this->windows; window; window = window->next) {
+ _this->AcceptDragAndDrop(window, enable);
+ }
+ }
+}
+
+static void
+SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
+{
+ PrepareDragAndDropSupport(window);
+
+ if (flags & SDL_WINDOW_MAXIMIZED) {
+ SDL_MaximizeWindow(window);
+ }
+ if (flags & SDL_WINDOW_MINIMIZED) {
+ SDL_MinimizeWindow(window);
+ }
+ if (flags & SDL_WINDOW_FULLSCREEN) {
+ SDL_SetWindowFullscreen(window, flags);
+ }
+ if (flags & SDL_WINDOW_INPUT_GRABBED) {
+ SDL_SetWindowGrab(window, SDL_TRUE);
+ }
+ if (!(flags & SDL_WINDOW_HIDDEN)) {
+ SDL_ShowWindow(window);
+ }
+}
+
+SDL_Window *
+SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
+{
+ SDL_Window *window;
+
+ if (!_this) {
+ /* Initialize the video system if needed */
+ if (SDL_VideoInit(NULL) < 0) {
+ return NULL;
+ }
+ }
+
+ if ((((flags & SDL_WINDOW_UTILITY) != 0) + ((flags & SDL_WINDOW_TOOLTIP) != 0) + ((flags & SDL_WINDOW_POPUP_MENU) != 0)) > 1) {
+ SDL_SetError("Conflicting window flags specified");
+ return NULL;
+ }
+
+ /* Some platforms can't create zero-sized windows */
+ if (w < 1) {
+ w = 1;
+ }
+ if (h < 1) {
+ h = 1;
+ }
+
+ /* Some platforms blow up if the windows are too large. Raise it later? */
+ if ((w > 16384) || (h > 16384)) {
+ SDL_SetError("Window is too large.");
+ return NULL;
+ }
+
+ /* Some platforms have OpenGL enabled by default */
+#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
+ if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN)) {
+ flags |= SDL_WINDOW_OPENGL;
+ }
+#endif
+ if (flags & SDL_WINDOW_OPENGL) {
+ if (!_this->GL_CreateContext) {
+ SDL_SetError("OpenGL support is either not configured in SDL "
+ "or not available in current SDL video driver "
+ "(%s) or platform", _this->name);
+ return NULL;
+ }
+ if (SDL_GL_LoadLibrary(NULL) < 0) {
+ return NULL;
+ }
+ }
+
+ if (flags & SDL_WINDOW_VULKAN) {
+ if (!_this->Vulkan_CreateSurface) {
+ SDL_SetError("Vulkan support is either not configured in SDL "
+ "or not available in current SDL video driver "
+ "(%s) or platform", _this->name);
+ return NULL;
+ }
+ if (flags & SDL_WINDOW_OPENGL) {
+ SDL_SetError("Vulkan and OpenGL not supported on same window");
+ return NULL;
+ }
+ if (SDL_Vulkan_LoadLibrary(NULL) < 0) {
+ return NULL;
+ }
+ }
+
+ /* Unless the user has specified the high-DPI disabling hint, respect the
+ * SDL_WINDOW_ALLOW_HIGHDPI flag.
+ */
+ if (flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_HIGHDPI_DISABLED, SDL_FALSE)) {
+ flags &= ~SDL_WINDOW_ALLOW_HIGHDPI;
+ }
+ }
+
+ window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
+ if (!window) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ window->magic = &_this->window_magic;
+ window->id = _this->next_object_id++;
+ window->x = x;
+ window->y = y;
+ window->w = w;
+ window->h = h;
+ if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) ||
+ SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ int displayIndex;
+ SDL_Rect bounds;
+
+ displayIndex = SDL_GetIndexOfDisplay(display);
+ SDL_GetDisplayBounds(displayIndex, &bounds);
+ if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) {
+ window->x = bounds.x + (bounds.w - w) / 2;
+ }
+ if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) {
+ window->y = bounds.y + (bounds.h - h) / 2;
+ }
+ }
+ window->windowed.x = window->x;
+ window->windowed.y = window->y;
+ window->windowed.w = window->w;
+ window->windowed.h = window->h;
+
+ if (flags & SDL_WINDOW_FULLSCREEN) {
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ int displayIndex;
+ SDL_Rect bounds;
+
+ displayIndex = SDL_GetIndexOfDisplay(display);
+ SDL_GetDisplayBounds(displayIndex, &bounds);
+
+ window->x = bounds.x;
+ window->y = bounds.y;
+ window->w = bounds.w;
+ window->h = bounds.h;
+ }
+
+ window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
+ window->last_fullscreen_flags = window->flags;
+ window->opacity = 1.0f;
+ window->brightness = 1.0f;
+ window->next = _this->windows;
+ window->is_destroying = SDL_FALSE;
+
+ if (_this->windows) {
+ _this->windows->prev = window;
+ }
+ _this->windows = window;
+
+ if (_this->CreateSDLWindow && _this->CreateSDLWindow(_this, window) < 0) {
+ SDL_DestroyWindow(window);
+ return NULL;
+ }
+
+ /* Clear minimized if not on windows, only windows handles it at create rather than FinishWindowCreation,
+ * but it's important or window focus will get broken on windows!
+ */
+#if !defined(__WIN32__)
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ window->flags &= ~SDL_WINDOW_MINIMIZED;
+ }
+#endif
+
+#if __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
+ /* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen
+ or not. The user can choose this, via OS-provided UI, but this can't
+ be set programmatically.
+
+ Just look at what SDL's WinRT video backend code detected with regards
+ to fullscreen (being active, or not), and figure out a return/error code
+ from that.
+ */
+ flags = window->flags;
+#endif
+
+ if (title) {
+ SDL_SetWindowTitle(window, title);
+ }
+ SDL_FinishWindowCreation(window, flags);
+
+ /* If the window was created fullscreen, make sure the mode code matches */
+ SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window));
+
+ return window;
+}
+
+SDL_Window *
+SDL_CreateWindowFrom(const void *data)
+{
+ SDL_Window *window;
+
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return NULL;
+ }
+ if (!_this->CreateSDLWindowFrom) {
+ SDL_Unsupported();
+ return NULL;
+ }
+ window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
+ if (!window) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ window->magic = &_this->window_magic;
+ window->id = _this->next_object_id++;
+ window->flags = SDL_WINDOW_FOREIGN;
+ window->last_fullscreen_flags = window->flags;
+ window->is_destroying = SDL_FALSE;
+ window->opacity = 1.0f;
+ window->brightness = 1.0f;
+ window->next = _this->windows;
+ if (_this->windows) {
+ _this->windows->prev = window;
+ }
+ _this->windows = window;
+
+ if (_this->CreateSDLWindowFrom(_this, window, data) < 0) {
+ SDL_DestroyWindow(window);
+ return NULL;
+ }
+
+ PrepareDragAndDropSupport(window);
+
+ return window;
+}
+
+int
+SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
+{
+ SDL_bool loaded_opengl = SDL_FALSE;
+
+ if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
+ return SDL_SetError("OpenGL support is either not configured in SDL "
+ "or not available in current SDL video driver "
+ "(%s) or platform", _this->name);
+ }
+
+ if (window->flags & SDL_WINDOW_FOREIGN) {
+ /* Can't destroy and re-create foreign windows, hrm */
+ flags |= SDL_WINDOW_FOREIGN;
+ } else {
+ flags &= ~SDL_WINDOW_FOREIGN;
+ }
+
+ /* Restore video mode, etc. */
+ SDL_HideWindow(window);
+
+ /* Tear down the old native window */
+ if (window->surface) {
+ window->surface->flags &= ~SDL_DONTFREE;
+ SDL_FreeSurface(window->surface);
+ window->surface = NULL;
+ }
+ if (_this->DestroyWindowFramebuffer) {
+ _this->DestroyWindowFramebuffer(_this, window);
+ }
+ if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
+ _this->DestroyWindow(_this, window);
+ }
+
+ if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
+ if (flags & SDL_WINDOW_OPENGL) {
+ if (SDL_GL_LoadLibrary(NULL) < 0) {
+ return -1;
+ }
+ loaded_opengl = SDL_TRUE;
+ } else {
+ SDL_GL_UnloadLibrary();
+ }
+ }
+
+ if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) {
+ SDL_SetError("Can't change SDL_WINDOW_VULKAN window flag");
+ return -1;
+ }
+
+ if ((window->flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) {
+ SDL_SetError("Vulkan and OpenGL not supported on same window");
+ return -1;
+ }
+
+ window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
+ window->last_fullscreen_flags = window->flags;
+ window->is_destroying = SDL_FALSE;
+
+ if (_this->CreateSDLWindow && !(flags & SDL_WINDOW_FOREIGN)) {
+ if (_this->CreateSDLWindow(_this, window) < 0) {
+ if (loaded_opengl) {
+ SDL_GL_UnloadLibrary();
+ window->flags &= ~SDL_WINDOW_OPENGL;
+ }
+ return -1;
+ }
+ }
+
+ if (flags & SDL_WINDOW_FOREIGN) {
+ window->flags |= SDL_WINDOW_FOREIGN;
+ }
+
+ if (_this->SetWindowTitle && window->title) {
+ _this->SetWindowTitle(_this, window);
+ }
+
+ if (_this->SetWindowIcon && window->icon) {
+ _this->SetWindowIcon(_this, window, window->icon);
+ }
+
+ if (window->hit_test) {
+ _this->SetWindowHitTest(window, SDL_TRUE);
+ }
+
+ SDL_FinishWindowCreation(window, flags);
+
+ return 0;
+}
+
+SDL_bool
+SDL_HasWindows(void)
+{
+ return (_this && _this->windows != NULL);
+}
+
+Uint32
+SDL_GetWindowID(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, 0);
+
+ return window->id;
+}
+
+SDL_Window *
+SDL_GetWindowFromID(Uint32 id)
+{
+ SDL_Window *window;
+
+ if (!_this) {
+ return NULL;
+ }
+ for (window = _this->windows; window; window = window->next) {
+ if (window->id == id) {
+ return window;
+ }
+ }
+ return NULL;
+}
+
+Uint32
+SDL_GetWindowFlags(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, 0);
+
+ return window->flags;
+}
+
+void
+SDL_SetWindowTitle(SDL_Window * window, const char *title)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (title == window->title) {
+ return;
+ }
+ SDL_free(window->title);
+
+ window->title = SDL_strdup(title ? title : "");
+
+ if (_this->SetWindowTitle) {
+ _this->SetWindowTitle(_this, window);
+ }
+}
+
+const char *
+SDL_GetWindowTitle(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, "");
+
+ return window->title ? window->title : "";
+}
+
+void
+SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (!icon) {
+ return;
+ }
+
+ SDL_FreeSurface(window->icon);
+
+ /* Convert the icon into ARGB8888 */
+ window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
+ if (!window->icon) {
+ return;
+ }
+
+ if (_this->SetWindowIcon) {
+ _this->SetWindowIcon(_this, window, window->icon);
+ }
+}
+
+void*
+SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata)
+{
+ SDL_WindowUserData *prev, *data;
+
+ CHECK_WINDOW_MAGIC(window, NULL);
+
+ /* Input validation */
+ if (name == NULL || name[0] == '\0') {
+ SDL_InvalidParamError("name");
+ return NULL;
+ }
+
+ /* See if the named data already exists */
+ prev = NULL;
+ for (data = window->data; data; prev = data, data = data->next) {
+ if (data->name && SDL_strcmp(data->name, name) == 0) {
+ void *last_value = data->data;
+
+ if (userdata) {
+ /* Set the new value */
+ data->data = userdata;
+ } else {
+ /* Delete this value */
+ if (prev) {
+ prev->next = data->next;
+ } else {
+ window->data = data->next;
+ }
+ SDL_free(data->name);
+ SDL_free(data);
+ }
+ return last_value;
+ }
+ }
+
+ /* Add new data to the window */
+ if (userdata) {
+ data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data));
+ data->name = SDL_strdup(name);
+ data->data = userdata;
+ data->next = window->data;
+ window->data = data;
+ }
+ return NULL;
+}
+
+void *
+SDL_GetWindowData(SDL_Window * window, const char *name)
+{
+ SDL_WindowUserData *data;
+
+ CHECK_WINDOW_MAGIC(window, NULL);
+
+ /* Input validation */
+ if (name == NULL || name[0] == '\0') {
+ SDL_InvalidParamError("name");
+ return NULL;
+ }
+
+ for (data = window->data; data; data = data->next) {
+ if (data->name && SDL_strcmp(data->name, name) == 0) {
+ return data->data;
+ }
+ }
+ return NULL;
+}
+
+void
+SDL_SetWindowPosition(SDL_Window * window, int x, int y)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
+ int displayIndex = (x & 0xFFFF);
+ SDL_Rect bounds;
+ if (displayIndex >= _this->num_displays) {
+ displayIndex = 0;
+ }
+
+ SDL_zero(bounds);
+
+ SDL_GetDisplayBounds(displayIndex, &bounds);
+ if (SDL_WINDOWPOS_ISCENTERED(x)) {
+ x = bounds.x + (bounds.w - window->w) / 2;
+ }
+ if (SDL_WINDOWPOS_ISCENTERED(y)) {
+ y = bounds.y + (bounds.h - window->h) / 2;
+ }
+ }
+
+ if ((window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
+ window->windowed.x = x;
+ }
+ if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
+ window->windowed.y = y;
+ }
+ } else {
+ if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
+ window->x = x;
+ }
+ if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
+ window->y = y;
+ }
+
+ if (_this->SetWindowPosition) {
+ _this->SetWindowPosition(_this, window);
+ }
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
+ }
+}
+
+void
+SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ /* Fullscreen windows are always at their display's origin */
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ int displayIndex;
+
+ if (x) {
+ *x = 0;
+ }
+ if (y) {
+ *y = 0;
+ }
+
+ /* Find the window's monitor and update to the
+ monitor offset. */
+ displayIndex = SDL_GetWindowDisplayIndex(window);
+ if (displayIndex >= 0) {
+ SDL_Rect bounds;
+
+ SDL_zero(bounds);
+
+ SDL_GetDisplayBounds(displayIndex, &bounds);
+ if (x) {
+ *x = bounds.x;
+ }
+ if (y) {
+ *y = bounds.y;
+ }
+ }
+ } else {
+ if (x) {
+ *x = window->x;
+ }
+ if (y) {
+ *y = window->y;
+ }
+ }
+}
+
+void
+SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ const int want = (bordered != SDL_FALSE); /* normalize the flag. */
+ const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0);
+ if ((want != have) && (_this->SetWindowBordered)) {
+ if (want) {
+ window->flags &= ~SDL_WINDOW_BORDERLESS;
+ } else {
+ window->flags |= SDL_WINDOW_BORDERLESS;
+ }
+ _this->SetWindowBordered(_this, window, (SDL_bool) want);
+ }
+ }
+}
+
+void
+SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ const int want = (resizable != SDL_FALSE); /* normalize the flag. */
+ const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0);
+ if ((want != have) && (_this->SetWindowResizable)) {
+ if (want) {
+ window->flags |= SDL_WINDOW_RESIZABLE;
+ } else {
+ window->flags &= ~SDL_WINDOW_RESIZABLE;
+ }
+ _this->SetWindowResizable(_this, window, (SDL_bool) want);
+ }
+ }
+}
+
+void
+SDL_SetWindowSize(SDL_Window * window, int w, int h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (w <= 0) {
+ SDL_InvalidParamError("w");
+ return;
+ }
+ if (h <= 0) {
+ SDL_InvalidParamError("h");
+ return;
+ }
+
+ /* Make sure we don't exceed any window size limits */
+ if (window->min_w && w < window->min_w) {
+ w = window->min_w;
+ }
+ if (window->max_w && w > window->max_w) {
+ w = window->max_w;
+ }
+ if (window->min_h && h < window->min_h) {
+ h = window->min_h;
+ }
+ if (window->max_h && h > window->max_h) {
+ h = window->max_h;
+ }
+
+ window->windowed.w = w;
+ window->windowed.h = h;
+
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ window->last_fullscreen_flags = 0;
+ SDL_UpdateFullscreenMode(window, SDL_TRUE);
+ }
+ } else {
+ window->w = w;
+ window->h = h;
+ if (_this->SetWindowSize) {
+ _this->SetWindowSize(_this, window);
+ }
+ if (window->w == w && window->h == h) {
+ /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */
+ SDL_OnWindowResized(window);
+ }
+ }
+}
+
+void
+SDL_GetWindowSize(SDL_Window * window, int *w, int *h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (w) {
+ *w = window->w;
+ }
+ if (h) {
+ *h = window->h;
+ }
+}
+
+int
+SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, int *right)
+{
+ int dummy = 0;
+
+ if (!top) { top = &dummy; }
+ if (!left) { left = &dummy; }
+ if (!right) { right = &dummy; }
+ if (!bottom) { bottom = &dummy; }
+
+ /* Always initialize, so applications don't have to care */
+ *top = *left = *bottom = *right = 0;
+
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!_this->GetWindowBordersSize) {
+ return SDL_Unsupported();
+ }
+
+ return _this->GetWindowBordersSize(_this, window, top, left, bottom, right);
+}
+
+void
+SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (min_w <= 0) {
+ SDL_InvalidParamError("min_w");
+ return;
+ }
+ if (min_h <= 0) {
+ SDL_InvalidParamError("min_h");
+ return;
+ }
+
+ if ((window->max_w && min_w >= window->max_w) ||
+ (window->max_h && min_h >= window->max_h)) {
+ SDL_SetError("SDL_SetWindowMinimumSize(): Tried to set minimum size larger than maximum size");
+ return;
+ }
+
+ window->min_w = min_w;
+ window->min_h = min_h;
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if (_this->SetWindowMinimumSize) {
+ _this->SetWindowMinimumSize(_this, window);
+ }
+ /* Ensure that window is not smaller than minimal size */
+ SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h));
+ }
+}
+
+void
+SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (min_w) {
+ *min_w = window->min_w;
+ }
+ if (min_h) {
+ *min_h = window->min_h;
+ }
+}
+
+void
+SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (max_w <= 0) {
+ SDL_InvalidParamError("max_w");
+ return;
+ }
+ if (max_h <= 0) {
+ SDL_InvalidParamError("max_h");
+ return;
+ }
+
+ if (max_w <= window->min_w || max_h <= window->min_h) {
+ SDL_SetError("SDL_SetWindowMaximumSize(): Tried to set maximum size smaller than minimum size");
+ return;
+ }
+
+ window->max_w = max_w;
+ window->max_h = max_h;
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if (_this->SetWindowMaximumSize) {
+ _this->SetWindowMaximumSize(_this, window);
+ }
+ /* Ensure that window is not larger than maximal size */
+ SDL_SetWindowSize(window, SDL_min(window->w, window->max_w), SDL_min(window->h, window->max_h));
+ }
+}
+
+void
+SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+ if (max_w) {
+ *max_w = window->max_w;
+ }
+ if (max_h) {
+ *max_h = window->max_h;
+ }
+}
+
+void
+SDL_ShowWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (window->flags & SDL_WINDOW_SHOWN) {
+ return;
+ }
+
+ if (_this->ShowWindow) {
+ _this->ShowWindow(_this, window);
+ }
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+}
+
+void
+SDL_HideWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (!(window->flags & SDL_WINDOW_SHOWN)) {
+ return;
+ }
+
+ window->is_hiding = SDL_TRUE;
+ SDL_UpdateFullscreenMode(window, SDL_FALSE);
+
+ if (_this->HideWindow) {
+ _this->HideWindow(_this, window);
+ }
+ window->is_hiding = SDL_FALSE;
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+}
+
+void
+SDL_RaiseWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (!(window->flags & SDL_WINDOW_SHOWN)) {
+ return;
+ }
+ if (_this->RaiseWindow) {
+ _this->RaiseWindow(_this, window);
+ }
+}
+
+void
+SDL_MaximizeWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (window->flags & SDL_WINDOW_MAXIMIZED) {
+ return;
+ }
+
+ /* !!! FIXME: should this check if the window is resizable? */
+
+ if (_this->MaximizeWindow) {
+ _this->MaximizeWindow(_this, window);
+ }
+}
+
+void
+SDL_MinimizeWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ return;
+ }
+
+ SDL_UpdateFullscreenMode(window, SDL_FALSE);
+
+ if (_this->MinimizeWindow) {
+ _this->MinimizeWindow(_this, window);
+ }
+}
+
+void
+SDL_RestoreWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
+ return;
+ }
+
+ if (_this->RestoreWindow) {
+ _this->RestoreWindow(_this, window);
+ }
+}
+
+int
+SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags)
+{
+ Uint32 oldflags;
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ flags &= FULLSCREEN_MASK;
+
+ if (flags == (window->flags & FULLSCREEN_MASK)) {
+ return 0;
+ }
+
+ /* clear the previous flags and OR in the new ones */
+ oldflags = window->flags & FULLSCREEN_MASK;
+ window->flags &= ~FULLSCREEN_MASK;
+ window->flags |= flags;
+
+ if (SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)) == 0) {
+ return 0;
+ }
+
+ window->flags &= ~FULLSCREEN_MASK;
+ window->flags |= oldflags;
+ return -1;
+}
+
+static SDL_Surface *
+SDL_CreateWindowFramebuffer(SDL_Window * window)
+{
+ Uint32 format;
+ void *pixels;
+ int pitch;
+ int bpp;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
+ if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
+ return NULL;
+ }
+
+ if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
+ return NULL;
+ }
+
+ if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+ return NULL;
+ }
+
+ return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
+}
+
+SDL_Surface *
+SDL_GetWindowSurface(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, NULL);
+
+ if (!window->surface_valid) {
+ if (window->surface) {
+ window->surface->flags &= ~SDL_DONTFREE;
+ SDL_FreeSurface(window->surface);
+ }
+ window->surface = SDL_CreateWindowFramebuffer(window);
+ if (window->surface) {
+ window->surface_valid = SDL_TRUE;
+ window->surface->flags |= SDL_DONTFREE;
+ }
+ }
+ return window->surface;
+}
+
+int
+SDL_UpdateWindowSurface(SDL_Window * window)
+{
+ SDL_Rect full_rect;
+
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ full_rect.x = 0;
+ full_rect.y = 0;
+ full_rect.w = window->w;
+ full_rect.h = window->h;
+ return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1);
+}
+
+int
+SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects,
+ int numrects)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!window->surface_valid) {
+ return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
+ }
+
+ return _this->UpdateWindowFramebuffer(_this, window, rects, numrects);
+}
+
+int
+SDL_SetWindowBrightness(SDL_Window * window, float brightness)
+{
+ Uint16 ramp[256];
+ int status;
+
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ SDL_CalculateGammaRamp(brightness, ramp);
+ status = SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
+ if (status == 0) {
+ window->brightness = brightness;
+ }
+ return status;
+}
+
+float
+SDL_GetWindowBrightness(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, 1.0f);
+
+ return window->brightness;
+}
+
+int
+SDL_SetWindowOpacity(SDL_Window * window, float opacity)
+{
+ int retval;
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!_this->SetWindowOpacity) {
+ return SDL_Unsupported();
+ }
+
+ if (opacity < 0.0f) {
+ opacity = 0.0f;
+ } else if (opacity > 1.0f) {
+ opacity = 1.0f;
+ }
+
+ retval = _this->SetWindowOpacity(_this, window, opacity);
+ if (retval == 0) {
+ window->opacity = opacity;
+ }
+
+ return retval;
+}
+
+int
+SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (out_opacity) {
+ *out_opacity = window->opacity;
+ }
+
+ return 0;
+}
+
+int
+SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window)
+{
+ CHECK_WINDOW_MAGIC(modal_window, -1);
+ CHECK_WINDOW_MAGIC(parent_window, -1);
+
+ if (!_this->SetWindowModalFor) {
+ return SDL_Unsupported();
+ }
+
+ return _this->SetWindowModalFor(_this, modal_window, parent_window);
+}
+
+int
+SDL_SetWindowInputFocus(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!_this->SetWindowInputFocus) {
+ return SDL_Unsupported();
+ }
+
+ return _this->SetWindowInputFocus(_this, window);
+}
+
+
+int
+SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red,
+ const Uint16 * green,
+ const Uint16 * blue)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!_this->SetWindowGammaRamp) {
+ return SDL_Unsupported();
+ }
+
+ if (!window->gamma) {
+ if (SDL_GetWindowGammaRamp(window, NULL, NULL, NULL) < 0) {
+ return -1;
+ }
+ SDL_assert(window->gamma != NULL);
+ }
+
+ if (red) {
+ SDL_memcpy(&window->gamma[0*256], red, 256*sizeof(Uint16));
+ }
+ if (green) {
+ SDL_memcpy(&window->gamma[1*256], green, 256*sizeof(Uint16));
+ }
+ if (blue) {
+ SDL_memcpy(&window->gamma[2*256], blue, 256*sizeof(Uint16));
+ }
+ if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
+ return _this->SetWindowGammaRamp(_this, window, window->gamma);
+ } else {
+ return 0;
+ }
+}
+
+int
+SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red,
+ Uint16 * green,
+ Uint16 * blue)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!window->gamma) {
+ int i;
+
+ window->gamma = (Uint16 *)SDL_malloc(256*6*sizeof(Uint16));
+ if (!window->gamma) {
+ return SDL_OutOfMemory();
+ }
+ window->saved_gamma = window->gamma + 3*256;
+
+ if (_this->GetWindowGammaRamp) {
+ if (_this->GetWindowGammaRamp(_this, window, window->gamma) < 0) {
+ return -1;
+ }
+ } else {
+ /* Create an identity gamma ramp */
+ for (i = 0; i < 256; ++i) {
+ Uint16 value = (Uint16)((i << 8) | i);
+
+ window->gamma[0*256+i] = value;
+ window->gamma[1*256+i] = value;
+ window->gamma[2*256+i] = value;
+ }
+ }
+ SDL_memcpy(window->saved_gamma, window->gamma, 3*256*sizeof(Uint16));
+ }
+
+ if (red) {
+ SDL_memcpy(red, &window->gamma[0*256], 256*sizeof(Uint16));
+ }
+ if (green) {
+ SDL_memcpy(green, &window->gamma[1*256], 256*sizeof(Uint16));
+ }
+ if (blue) {
+ SDL_memcpy(blue, &window->gamma[2*256], 256*sizeof(Uint16));
+ }
+ return 0;
+}
+
+void
+SDL_UpdateWindowGrab(SDL_Window * window)
+{
+ SDL_Window *grabbed_window;
+ SDL_bool grabbed;
+ if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
+ (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
+ grabbed = SDL_TRUE;
+ } else {
+ grabbed = SDL_FALSE;
+ }
+
+ grabbed_window = _this->grabbed_window;
+ if (grabbed) {
+ if (grabbed_window && (grabbed_window != window)) {
+ /* stealing a grab from another window! */
+ grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
+ if (_this->SetWindowGrab) {
+ _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE);
+ }
+ }
+ _this->grabbed_window = window;
+ } else if (grabbed_window == window) {
+ _this->grabbed_window = NULL; /* ungrabbing. */
+ }
+
+ if (_this->SetWindowGrab) {
+ _this->SetWindowGrab(_this, window, grabbed);
+ }
+}
+
+void
+SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
+ return;
+ }
+ if (grabbed) {
+ window->flags |= SDL_WINDOW_INPUT_GRABBED;
+ } else {
+ window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
+ }
+ SDL_UpdateWindowGrab(window);
+}
+
+SDL_bool
+SDL_GetWindowGrab(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+ SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
+ return window == _this->grabbed_window;
+}
+
+SDL_Window *
+SDL_GetGrabbedWindow(void)
+{
+ SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
+ return _this->grabbed_window;
+}
+
+void
+SDL_OnWindowShown(SDL_Window * window)
+{
+ SDL_OnWindowRestored(window);
+}
+
+void
+SDL_OnWindowHidden(SDL_Window * window)
+{
+ SDL_UpdateFullscreenMode(window, SDL_FALSE);
+}
+
+void
+SDL_OnWindowResized(SDL_Window * window)
+{
+ window->surface_valid = SDL_FALSE;
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
+}
+
+void
+SDL_OnWindowMinimized(SDL_Window * window)
+{
+ SDL_UpdateFullscreenMode(window, SDL_FALSE);
+}
+
+void
+SDL_OnWindowRestored(SDL_Window * window)
+{
+ /*
+ * FIXME: Is this fine to just remove this, or should it be preserved just
+ * for the fullscreen case? In principle it seems like just hiding/showing
+ * windows shouldn't affect the stacking order; maybe the right fix is to
+ * re-decouple OnWindowShown and OnWindowRestored.
+ */
+ /*SDL_RaiseWindow(window);*/
+
+ if (FULLSCREEN_VISIBLE(window)) {
+ SDL_UpdateFullscreenMode(window, SDL_TRUE);
+ }
+}
+
+void
+SDL_OnWindowEnter(SDL_Window * window)
+{
+ if (_this->OnWindowEnter) {
+ _this->OnWindowEnter(_this, window);
+ }
+}
+
+void
+SDL_OnWindowLeave(SDL_Window * window)
+{
+}
+
+void
+SDL_OnWindowFocusGained(SDL_Window * window)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (window->gamma && _this->SetWindowGammaRamp) {
+ _this->SetWindowGammaRamp(_this, window, window->gamma);
+ }
+
+ if (mouse && mouse->relative_mode) {
+ SDL_SetMouseFocus(window);
+ SDL_WarpMouseInWindow(window, window->w/2, window->h/2);
+ }
+
+ SDL_UpdateWindowGrab(window);
+}
+
+static SDL_bool
+ShouldMinimizeOnFocusLoss(SDL_Window * window)
+{
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) {
+ return SDL_FALSE;
+ }
+
+#ifdef __MACOSX__
+ if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */
+ if (Cocoa_IsWindowInFullscreenSpace(window)) {
+ return SDL_FALSE;
+ }
+ }
+#endif
+
+ return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_TRUE);
+}
+
+void
+SDL_OnWindowFocusLost(SDL_Window * window)
+{
+ if (window->gamma && _this->SetWindowGammaRamp) {
+ _this->SetWindowGammaRamp(_this, window, window->saved_gamma);
+ }
+
+ SDL_UpdateWindowGrab(window);
+
+ if (ShouldMinimizeOnFocusLoss(window)) {
+ SDL_MinimizeWindow(window);
+ }
+}
+
+/* !!! FIXME: is this different than SDL_GetKeyboardFocus()?
+ !!! FIXME: Also, SDL_GetKeyboardFocus() is O(1), this isn't. */
+SDL_Window *
+SDL_GetFocusWindow(void)
+{
+ SDL_Window *window;
+
+ if (!_this) {
+ return NULL;
+ }
+ for (window = _this->windows; window; window = window->next) {
+ if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
+ return window;
+ }
+ }
+ return NULL;
+}
+
+void
+SDL_DestroyWindow(SDL_Window * window)
+{
+ SDL_VideoDisplay *display;
+
+ CHECK_WINDOW_MAGIC(window,);
+
+ window->is_destroying = SDL_TRUE;
+
+ /* Restore video mode, etc. */
+ SDL_HideWindow(window);
+
+ /* Make sure this window no longer has focus */
+ if (SDL_GetKeyboardFocus() == window) {
+ SDL_SetKeyboardFocus(NULL);
+ }
+ if (SDL_GetMouseFocus() == window) {
+ SDL_SetMouseFocus(NULL);
+ }
+
+ /* make no context current if this is the current context window. */
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ if (_this->current_glwin == window) {
+ SDL_GL_MakeCurrent(window, NULL);
+ }
+ }
+
+ if (window->surface) {
+ window->surface->flags &= ~SDL_DONTFREE;
+ SDL_FreeSurface(window->surface);
+ }
+ if (_this->DestroyWindowFramebuffer) {
+ _this->DestroyWindowFramebuffer(_this, window);
+ }
+ if (_this->DestroyWindow) {
+ _this->DestroyWindow(_this, window);
+ }
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ SDL_GL_UnloadLibrary();
+ }
+ if (window->flags & SDL_WINDOW_VULKAN) {
+ SDL_Vulkan_UnloadLibrary();
+ }
+
+ display = SDL_GetDisplayForWindow(window);
+ if (display->fullscreen_window == window) {
+ display->fullscreen_window = NULL;
+ }
+
+ /* Now invalidate magic */
+ window->magic = NULL;
+
+ /* Free memory associated with the window */
+ SDL_free(window->title);
+ SDL_FreeSurface(window->icon);
+ SDL_free(window->gamma);
+ while (window->data) {
+ SDL_WindowUserData *data = window->data;
+
+ window->data = data->next;
+ SDL_free(data->name);
+ SDL_free(data);
+ }
+
+ /* Unlink the window from the list */
+ if (window->next) {
+ window->next->prev = window->prev;
+ }
+ if (window->prev) {
+ window->prev->next = window->next;
+ } else {
+ _this->windows = window->next;
+ }
+
+ SDL_free(window);
+}
+
+SDL_bool
+SDL_IsScreenSaverEnabled()
+{
+ if (!_this) {
+ return SDL_TRUE;
+ }
+ return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE;
+}
+
+void
+SDL_EnableScreenSaver()
+{
+ if (!_this) {
+ return;
+ }
+ if (!_this->suspend_screensaver) {
+ return;
+ }
+ _this->suspend_screensaver = SDL_FALSE;
+ if (_this->SuspendScreenSaver) {
+ _this->SuspendScreenSaver(_this);
+ }
+}
+
+void
+SDL_DisableScreenSaver()
+{
+ if (!_this) {
+ return;
+ }
+ if (_this->suspend_screensaver) {
+ return;
+ }
+ _this->suspend_screensaver = SDL_TRUE;
+ if (_this->SuspendScreenSaver) {
+ _this->SuspendScreenSaver(_this);
+ }
+}
+
+void
+SDL_VideoQuit(void)
+{
+ int i, j;
+
+ if (!_this) {
+ return;
+ }
+
+ /* Halt event processing before doing anything else */
+ SDL_TouchQuit();
+ SDL_MouseQuit();
+ SDL_KeyboardQuit();
+ SDL_QuitSubSystem(SDL_INIT_EVENTS);
+
+ SDL_EnableScreenSaver();
+
+ /* Clean up the system video */
+ while (_this->windows) {
+ SDL_DestroyWindow(_this->windows);
+ }
+ _this->VideoQuit(_this);
+
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+ for (j = display->num_display_modes; j--;) {
+ SDL_free(display->display_modes[j].driverdata);
+ display->display_modes[j].driverdata = NULL;
+ }
+ SDL_free(display->display_modes);
+ display->display_modes = NULL;
+ SDL_free(display->desktop_mode.driverdata);
+ display->desktop_mode.driverdata = NULL;
+ SDL_free(display->driverdata);
+ display->driverdata = NULL;
+ }
+ if (_this->displays) {
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_free(_this->displays[i].name);
+ }
+ SDL_free(_this->displays);
+ _this->displays = NULL;
+ _this->num_displays = 0;
+ }
+ SDL_free(_this->clipboard_text);
+ _this->clipboard_text = NULL;
+ _this->free(_this);
+ _this = NULL;
+}
+
+int
+SDL_GL_LoadLibrary(const char *path)
+{
+ int retval;
+
+ if (!_this) {
+ return SDL_UninitializedVideo();
+ }
+ if (_this->gl_config.driver_loaded) {
+ if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
+ return SDL_SetError("OpenGL library already loaded");
+ }
+ retval = 0;
+ } else {
+ if (!_this->GL_LoadLibrary) {
+ return SDL_SetError("No dynamic GL support in current SDL video driver (%s)", _this->name);
+ }
+ retval = _this->GL_LoadLibrary(_this, path);
+ }
+ if (retval == 0) {
+ ++_this->gl_config.driver_loaded;
+ } else {
+ if (_this->GL_UnloadLibrary) {
+ _this->GL_UnloadLibrary(_this);
+ }
+ }
+ return (retval);
+}
+
+void *
+SDL_GL_GetProcAddress(const char *proc)
+{
+ void *func;
+
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return NULL;
+ }
+ func = NULL;
+ if (_this->GL_GetProcAddress) {
+ if (_this->gl_config.driver_loaded) {
+ func = _this->GL_GetProcAddress(_this, proc);
+ } else {
+ SDL_SetError("No GL driver has been loaded");
+ }
+ } else {
+ SDL_SetError("No dynamic GL support in current SDL video driver (%s)", _this->name);
+ }
+ return func;
+}
+
+void
+SDL_GL_UnloadLibrary(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return;
+ }
+ if (_this->gl_config.driver_loaded > 0) {
+ if (--_this->gl_config.driver_loaded > 0) {
+ return;
+ }
+ if (_this->GL_UnloadLibrary) {
+ _this->GL_UnloadLibrary(_this);
+ }
+ }
+}
+
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+static SDL_INLINE SDL_bool
+isAtLeastGL3(const char *verstr)
+{
+ return (verstr && (SDL_atoi(verstr) >= 3));
+}
+#endif
+
+SDL_bool
+SDL_GL_ExtensionSupported(const char *extension)
+{
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
+ const char *extensions;
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = SDL_strchr(extension, ' ');
+ if (where || *extension == '\0') {
+ return SDL_FALSE;
+ }
+ /* See if there's an environment variable override */
+ start = SDL_getenv(extension);
+ if (start && *start == '0') {
+ return SDL_FALSE;
+ }
+
+ /* Lookup the available extensions */
+
+ glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
+ if (!glGetStringFunc) {
+ return SDL_FALSE;
+ }
+
+ if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {
+ const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint);
+ void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
+ GLint num_exts = 0;
+ GLint i;
+
+ glGetStringiFunc = SDL_GL_GetProcAddress("glGetStringi");
+ glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
+ if ((!glGetStringiFunc) || (!glGetIntegervFunc)) {
+ return SDL_FALSE;
+ }
+
+ #ifndef GL_NUM_EXTENSIONS
+ #define GL_NUM_EXTENSIONS 0x821D
+ #endif
+ glGetIntegervFunc(GL_NUM_EXTENSIONS, &num_exts);
+ for (i = 0; i < num_exts; i++) {
+ const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS, i);
+ if (SDL_strcmp(thisext, extension) == 0) {
+ return SDL_TRUE;
+ }
+ }
+
+ return SDL_FALSE;
+ }
+
+ /* Try the old way with glGetString(GL_EXTENSIONS) ... */
+
+ extensions = (const char *) glGetStringFunc(GL_EXTENSIONS);
+ if (!extensions) {
+ return SDL_FALSE;
+ }
+ /*
+ * It takes a bit of care to be fool-proof about parsing the OpenGL
+ * extensions string. Don't be fooled by sub-strings, etc.
+ */
+
+ start = extensions;
+
+ for (;;) {
+ where = SDL_strstr(start, extension);
+ if (!where)
+ break;
+
+ terminator = where + SDL_strlen(extension);
+ if (where == extensions || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0')
+ return SDL_TRUE;
+
+ start = terminator;
+ }
+ return SDL_FALSE;
+#else
+ return SDL_FALSE;
+#endif
+}
+
+/* Deduce supported ES profile versions from the supported
+ ARB_ES*_compatibility extensions. There is no direct query.
+
+ This is normally only called when the OpenGL driver supports
+ {GLX,WGL}_EXT_create_context_es2_profile.
+ */
+void
+SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor)
+{
+/* THIS REQUIRES AN EXISTING GL CONTEXT THAT HAS BEEN MADE CURRENT. */
+/* Please refer to https://bugzilla.libsdl.org/show_bug.cgi?id=3725 for discussion. */
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ /* XXX This is fragile; it will break in the event of release of
+ * new versions of OpenGL ES.
+ */
+ if (SDL_GL_ExtensionSupported("GL_ARB_ES3_2_compatibility")) {
+ *major = 3;
+ *minor = 2;
+ } else if (SDL_GL_ExtensionSupported("GL_ARB_ES3_1_compatibility")) {
+ *major = 3;
+ *minor = 1;
+ } else if (SDL_GL_ExtensionSupported("GL_ARB_ES3_compatibility")) {
+ *major = 3;
+ *minor = 0;
+ } else {
+ *major = 2;
+ *minor = 0;
+ }
+#endif
+}
+
+void
+SDL_GL_ResetAttributes()
+{
+ if (!_this) {
+ return;
+ }
+
+ _this->gl_config.red_size = 3;
+ _this->gl_config.green_size = 3;
+ _this->gl_config.blue_size = 2;
+ _this->gl_config.alpha_size = 0;
+ _this->gl_config.buffer_size = 0;
+ _this->gl_config.depth_size = 16;
+ _this->gl_config.stencil_size = 0;
+ _this->gl_config.double_buffer = 1;
+ _this->gl_config.accum_red_size = 0;
+ _this->gl_config.accum_green_size = 0;
+ _this->gl_config.accum_blue_size = 0;
+ _this->gl_config.accum_alpha_size = 0;
+ _this->gl_config.stereo = 0;
+ _this->gl_config.multisamplebuffers = 0;
+ _this->gl_config.multisamplesamples = 0;
+ _this->gl_config.retained_backing = 1;
+ _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */
+
+ if (_this->GL_DefaultProfileConfig) {
+ _this->GL_DefaultProfileConfig(_this, &_this->gl_config.profile_mask,
+ &_this->gl_config.major_version,
+ &_this->gl_config.minor_version);
+ } else {
+#if SDL_VIDEO_OPENGL
+ _this->gl_config.major_version = 2;
+ _this->gl_config.minor_version = 1;
+ _this->gl_config.profile_mask = 0;
+#elif SDL_VIDEO_OPENGL_ES2
+ _this->gl_config.major_version = 2;
+ _this->gl_config.minor_version = 0;
+ _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
+#elif SDL_VIDEO_OPENGL_ES
+ _this->gl_config.major_version = 1;
+ _this->gl_config.minor_version = 1;
+ _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
+#endif
+ }
+
+ _this->gl_config.flags = 0;
+ _this->gl_config.framebuffer_srgb_capable = 0;
+ _this->gl_config.no_error = 0;
+ _this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
+ _this->gl_config.reset_notification = SDL_GL_CONTEXT_RESET_NO_NOTIFICATION;
+
+ _this->gl_config.share_with_current_context = 0;
+}
+
+int
+SDL_GL_SetAttribute(SDL_GLattr attr, int value)
+{
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ int retval;
+
+ if (!_this) {
+ return SDL_UninitializedVideo();
+ }
+ retval = 0;
+ switch (attr) {
+ case SDL_GL_RED_SIZE:
+ _this->gl_config.red_size = value;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ _this->gl_config.green_size = value;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ _this->gl_config.blue_size = value;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ _this->gl_config.alpha_size = value;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ _this->gl_config.double_buffer = value;
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ _this->gl_config.buffer_size = value;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ _this->gl_config.depth_size = value;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ _this->gl_config.stencil_size = value;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ _this->gl_config.accum_red_size = value;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ _this->gl_config.accum_green_size = value;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ _this->gl_config.accum_blue_size = value;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ _this->gl_config.accum_alpha_size = value;
+ break;
+ case SDL_GL_STEREO:
+ _this->gl_config.stereo = value;
+ break;
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ _this->gl_config.multisamplebuffers = value;
+ break;
+ case SDL_GL_MULTISAMPLESAMPLES:
+ _this->gl_config.multisamplesamples = value;
+ break;
+ case SDL_GL_ACCELERATED_VISUAL:
+ _this->gl_config.accelerated = value;
+ break;
+ case SDL_GL_RETAINED_BACKING:
+ _this->gl_config.retained_backing = value;
+ break;
+ case SDL_GL_CONTEXT_MAJOR_VERSION:
+ _this->gl_config.major_version = value;
+ break;
+ case SDL_GL_CONTEXT_MINOR_VERSION:
+ _this->gl_config.minor_version = value;
+ break;
+ case SDL_GL_CONTEXT_EGL:
+ /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
+ if (value != 0) {
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
+ } else {
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
+ };
+ break;
+ case SDL_GL_CONTEXT_FLAGS:
+ if (value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
+ SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG |
+ SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG |
+ SDL_GL_CONTEXT_RESET_ISOLATION_FLAG)) {
+ retval = SDL_SetError("Unknown OpenGL context flag %d", value);
+ break;
+ }
+ _this->gl_config.flags = value;
+ break;
+ case SDL_GL_CONTEXT_PROFILE_MASK:
+ if (value != 0 &&
+ value != SDL_GL_CONTEXT_PROFILE_CORE &&
+ value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY &&
+ value != SDL_GL_CONTEXT_PROFILE_ES) {
+ retval = SDL_SetError("Unknown OpenGL context profile %d", value);
+ break;
+ }
+ _this->gl_config.profile_mask = value;
+ break;
+ case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
+ _this->gl_config.share_with_current_context = value;
+ break;
+ case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE:
+ _this->gl_config.framebuffer_srgb_capable = value;
+ break;
+ case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
+ _this->gl_config.release_behavior = value;
+ break;
+ case SDL_GL_CONTEXT_RESET_NOTIFICATION:
+ _this->gl_config.reset_notification = value;
+ break;
+ case SDL_GL_CONTEXT_NO_ERROR:
+ _this->gl_config.no_error = value;
+ break;
+ default:
+ retval = SDL_SetError("Unknown OpenGL attribute");
+ break;
+ }
+ return retval;
+#else
+ return SDL_Unsupported();
+#endif /* SDL_VIDEO_OPENGL */
+}
+
+int
+SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
+{
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ GLenum (APIENTRY *glGetErrorFunc) (void);
+ GLenum attrib = 0;
+ GLenum error = 0;
+
+ /*
+ * Some queries in Core Profile desktop OpenGL 3+ contexts require
+ * glGetFramebufferAttachmentParameteriv instead of glGetIntegerv. Note that
+ * the enums we use for the former function don't exist in OpenGL ES 2, and
+ * the function itself doesn't exist prior to OpenGL 3 and OpenGL ES 2.
+ */
+#if SDL_VIDEO_OPENGL
+ const GLubyte *(APIENTRY *glGetStringFunc) (GLenum name);
+ void (APIENTRY *glGetFramebufferAttachmentParameterivFunc) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ GLenum attachment = GL_BACK_LEFT;
+ GLenum attachmentattrib = 0;
+#endif
+
+ if (!value) {
+ return SDL_InvalidParamError("value");
+ }
+
+ /* Clear value in any case */
+ *value = 0;
+
+ if (!_this) {
+ return SDL_UninitializedVideo();
+ }
+
+ switch (attr) {
+ case SDL_GL_RED_SIZE:
+#if SDL_VIDEO_OPENGL
+ attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
+#endif
+ attrib = GL_RED_BITS;
+ break;
+ case SDL_GL_BLUE_SIZE:
+#if SDL_VIDEO_OPENGL
+ attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
+#endif
+ attrib = GL_BLUE_BITS;
+ break;
+ case SDL_GL_GREEN_SIZE:
+#if SDL_VIDEO_OPENGL
+ attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
+#endif
+ attrib = GL_GREEN_BITS;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+#if SDL_VIDEO_OPENGL
+ attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
+#endif
+ attrib = GL_ALPHA_BITS;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+#if SDL_VIDEO_OPENGL
+ attrib = GL_DOUBLEBUFFER;
+ break;
+#else
+ /* OpenGL ES 1.0 and above specifications have EGL_SINGLE_BUFFER */
+ /* parameter which switches double buffer to single buffer. OpenGL ES */
+ /* SDL driver must set proper value after initialization */
+ *value = _this->gl_config.double_buffer;
+ return 0;
+#endif
+ case SDL_GL_DEPTH_SIZE:
+#if SDL_VIDEO_OPENGL
+ attachment = GL_DEPTH;
+ attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
+#endif
+ attrib = GL_DEPTH_BITS;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+#if SDL_VIDEO_OPENGL
+ attachment = GL_STENCIL;
+ attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE;
+#endif
+ attrib = GL_STENCIL_BITS;
+ break;
+#if SDL_VIDEO_OPENGL
+ case SDL_GL_ACCUM_RED_SIZE:
+ attrib = GL_ACCUM_RED_BITS;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ attrib = GL_ACCUM_GREEN_BITS;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ attrib = GL_ACCUM_BLUE_BITS;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ attrib = GL_ACCUM_ALPHA_BITS;
+ break;
+ case SDL_GL_STEREO:
+ attrib = GL_STEREO;
+ break;
+#else
+ case SDL_GL_ACCUM_RED_SIZE:
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ case SDL_GL_STEREO:
+ /* none of these are supported in OpenGL ES */
+ *value = 0;
+ return 0;
+#endif
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ attrib = GL_SAMPLE_BUFFERS;
+ break;
+ case SDL_GL_MULTISAMPLESAMPLES:
+ attrib = GL_SAMPLES;
+ break;
+ case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
+#if SDL_VIDEO_OPENGL
+ attrib = GL_CONTEXT_RELEASE_BEHAVIOR;
+#else
+ attrib = GL_CONTEXT_RELEASE_BEHAVIOR_KHR;
+#endif
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ {
+ int rsize = 0, gsize = 0, bsize = 0, asize = 0;
+
+ /* There doesn't seem to be a single flag in OpenGL for this! */
+ if (SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &rsize) < 0) {
+ return -1;
+ }
+ if (SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gsize) < 0) {
+ return -1;
+ }
+ if (SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &bsize) < 0) {
+ return -1;
+ }
+ if (SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &asize) < 0) {
+ return -1;
+ }
+
+ *value = rsize + gsize + bsize + asize;
+ return 0;
+ }
+ case SDL_GL_ACCELERATED_VISUAL:
+ {
+ /* FIXME: How do we get this information? */
+ *value = (_this->gl_config.accelerated != 0);
+ return 0;
+ }
+ case SDL_GL_RETAINED_BACKING:
+ {
+ *value = _this->gl_config.retained_backing;
+ return 0;
+ }
+ case SDL_GL_CONTEXT_MAJOR_VERSION:
+ {
+ *value = _this->gl_config.major_version;
+ return 0;
+ }
+ case SDL_GL_CONTEXT_MINOR_VERSION:
+ {
+ *value = _this->gl_config.minor_version;
+ return 0;
+ }
+ case SDL_GL_CONTEXT_EGL:
+ /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
+ {
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+ *value = 1;
+ }
+ else {
+ *value = 0;
+ }
+ return 0;
+ }
+ case SDL_GL_CONTEXT_FLAGS:
+ {
+ *value = _this->gl_config.flags;
+ return 0;
+ }
+ case SDL_GL_CONTEXT_PROFILE_MASK:
+ {
+ *value = _this->gl_config.profile_mask;
+ return 0;
+ }
+ case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
+ {
+ *value = _this->gl_config.share_with_current_context;
+ return 0;
+ }
+ case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE:
+ {
+ *value = _this->gl_config.framebuffer_srgb_capable;
+ return 0;
+ }
+ case SDL_GL_CONTEXT_NO_ERROR:
+ {
+ *value = _this->gl_config.no_error;
+ return 0;
+ }
+ default:
+ return SDL_SetError("Unknown OpenGL attribute");
+ }
+
+#if SDL_VIDEO_OPENGL
+ glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
+ if (!glGetStringFunc) {
+ return -1;
+ }
+
+ if (attachmentattrib && isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {
+ glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv");
+
+ if (glGetFramebufferAttachmentParameterivFunc) {
+ glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *) value);
+ } else {
+ return -1;
+ }
+ } else
+#endif
+ {
+ void (APIENTRY *glGetIntegervFunc) (GLenum pname, GLint * params);
+ glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
+ if (glGetIntegervFunc) {
+ glGetIntegervFunc(attrib, (GLint *) value);
+ } else {
+ return -1;
+ }
+ }
+
+ glGetErrorFunc = SDL_GL_GetProcAddress("glGetError");
+ if (!glGetErrorFunc) {
+ return -1;
+ }
+
+ error = glGetErrorFunc();
+ if (error != GL_NO_ERROR) {
+ if (error == GL_INVALID_ENUM) {
+ return SDL_SetError("OpenGL error: GL_INVALID_ENUM");
+ } else if (error == GL_INVALID_VALUE) {
+ return SDL_SetError("OpenGL error: GL_INVALID_VALUE");
+ }
+ return SDL_SetError("OpenGL error: %08X", error);
+ }
+ return 0;
+#else
+ return SDL_Unsupported();
+#endif /* SDL_VIDEO_OPENGL */
+}
+
+SDL_GLContext
+SDL_GL_CreateContext(SDL_Window * window)
+{
+ SDL_GLContext ctx = NULL;
+ CHECK_WINDOW_MAGIC(window, NULL);
+
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ SDL_SetError("The specified window isn't an OpenGL window");
+ return NULL;
+ }
+
+ ctx = _this->GL_CreateContext(_this, window);
+
+ /* Creating a context is assumed to make it current in the SDL driver. */
+ if (ctx) {
+ _this->current_glwin = window;
+ _this->current_glctx = ctx;
+ SDL_TLSSet(_this->current_glwin_tls, window, NULL);
+ SDL_TLSSet(_this->current_glctx_tls, ctx, NULL);
+ }
+ return ctx;
+}
+
+int
+SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
+{
+ int retval;
+
+ if (window == SDL_GL_GetCurrentWindow() &&
+ ctx == SDL_GL_GetCurrentContext()) {
+ /* We're already current. */
+ return 0;
+ }
+
+ if (!ctx) {
+ window = NULL;
+ } else {
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ return SDL_SetError("The specified window isn't an OpenGL window");
+ }
+ }
+
+ retval = _this->GL_MakeCurrent(_this, window, ctx);
+ if (retval == 0) {
+ _this->current_glwin = window;
+ _this->current_glctx = ctx;
+ SDL_TLSSet(_this->current_glwin_tls, window, NULL);
+ SDL_TLSSet(_this->current_glctx_tls, ctx, NULL);
+ }
+ return retval;
+}
+
+SDL_Window *
+SDL_GL_GetCurrentWindow(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return NULL;
+ }
+ return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls);
+}
+
+SDL_GLContext
+SDL_GL_GetCurrentContext(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return NULL;
+ }
+ return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls);
+}
+
+void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (_this->GL_GetDrawableSize) {
+ _this->GL_GetDrawableSize(_this, window, w, h);
+ } else {
+ SDL_GetWindowSize(window, w, h);
+ }
+}
+
+int
+SDL_GL_SetSwapInterval(int interval)
+{
+ if (!_this) {
+ return SDL_UninitializedVideo();
+ } else if (SDL_GL_GetCurrentContext() == NULL) {
+ return SDL_SetError("No OpenGL context has been made current");
+ } else if (_this->GL_SetSwapInterval) {
+ return _this->GL_SetSwapInterval(_this, interval);
+ } else {
+ return SDL_SetError("Setting the swap interval is not supported");
+ }
+}
+
+int
+SDL_GL_GetSwapInterval(void)
+{
+ if (!_this) {
+ return 0;
+ } else if (SDL_GL_GetCurrentContext() == NULL) {
+ return 0;
+ } else if (_this->GL_GetSwapInterval) {
+ return _this->GL_GetSwapInterval(_this);
+ } else {
+ return 0;
+ }
+}
+
+void
+SDL_GL_SwapWindow(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ SDL_SetError("The specified window isn't an OpenGL window");
+ return;
+ }
+
+ if (SDL_GL_GetCurrentWindow() != window) {
+ SDL_SetError("The specified window has not been made current");
+ return;
+ }
+
+ _this->GL_SwapWindow(_this, window);
+}
+
+void
+SDL_GL_DeleteContext(SDL_GLContext context)
+{
+ if (!_this || !context) {
+ return;
+ }
+
+ if (SDL_GL_GetCurrentContext() == context) {
+ SDL_GL_MakeCurrent(NULL, NULL);
+ }
+
+ _this->GL_DeleteContext(_this, context);
+}
+
+#if 0 /* FIXME */
+/*
+ * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags
+ * & 2 for alpha channel.
+ */
+static void
+CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags)
+{
+ int x, y;
+ Uint32 colorkey;
+#define SET_MASKBIT(icon, x, y, mask) \
+ mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
+
+ colorkey = icon->format->colorkey;
+ switch (icon->format->BytesPerPixel) {
+ case 1:
+ {
+ Uint8 *pixels;
+ for (y = 0; y < icon->h; ++y) {
+ pixels = (Uint8 *) icon->pixels + y * icon->pitch;
+ for (x = 0; x < icon->w; ++x) {
+ if (*pixels++ == colorkey) {
+ SET_MASKBIT(icon, x, y, mask);
+ }
+ }
+ }
+ }
+ break;
+
+ case 2:
+ {
+ Uint16 *pixels;
+ for (y = 0; y < icon->h; ++y) {
+ pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2;
+ for (x = 0; x < icon->w; ++x) {
+ if ((flags & 1) && *pixels == colorkey) {
+ SET_MASKBIT(icon, x, y, mask);
+ } else if ((flags & 2)
+ && (*pixels & icon->format->Amask) == 0) {
+ SET_MASKBIT(icon, x, y, mask);
+ }
+ pixels++;
+ }
+ }
+ }
+ break;
+
+ case 4:
+ {
+ Uint32 *pixels;
+ for (y = 0; y < icon->h; ++y) {
+ pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4;
+ for (x = 0; x < icon->w; ++x) {
+ if ((flags & 1) && *pixels == colorkey) {
+ SET_MASKBIT(icon, x, y, mask);
+ } else if ((flags & 2)
+ && (*pixels & icon->format->Amask) == 0) {
+ SET_MASKBIT(icon, x, y, mask);
+ }
+ pixels++;
+ }
+ }
+ }
+ break;
+ }
+}
+
+/*
+ * Sets the window manager icon for the display window.
+ */
+void
+SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
+{
+ if (icon && _this->SetIcon) {
+ /* Generate a mask if necessary, and create the icon! */
+ if (mask == NULL) {
+ int mask_len = icon->h * (icon->w + 7) / 8;
+ int flags = 0;
+ mask = (Uint8 *) SDL_malloc(mask_len);
+ if (mask == NULL) {
+ return;
+ }
+ SDL_memset(mask, ~0, mask_len);
+ if (icon->flags & SDL_SRCCOLORKEY)
+ flags |= 1;
+ if (icon->flags & SDL_SRCALPHA)
+ flags |= 2;
+ if (flags) {
+ CreateMaskFromColorKeyOrAlpha(icon, mask, flags);
+ }
+ _this->SetIcon(_this, icon, mask);
+ SDL_free(mask);
+ } else {
+ _this->SetIcon(_this, icon, mask);
+ }
+ }
+}
+#endif
+
+SDL_bool
+SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+
+ if (!info) {
+ SDL_InvalidParamError("info");
+ return SDL_FALSE;
+ }
+ info->subsystem = SDL_SYSWM_UNKNOWN;
+
+ if (!_this->GetWindowWMInfo) {
+ SDL_Unsupported();
+ return SDL_FALSE;
+ }
+ return (_this->GetWindowWMInfo(_this, window, info));
+}
+
+void
+SDL_StartTextInput(void)
+{
+ SDL_Window *window;
+
+ /* First, enable text events */
+ SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE);
+ SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE);
+
+ /* Then show the on-screen keyboard, if any */
+ window = SDL_GetFocusWindow();
+ if (window && _this && _this->ShowScreenKeyboard) {
+ _this->ShowScreenKeyboard(_this, window);
+ }
+
+ /* Finally start the text input system */
+ if (_this && _this->StartTextInput) {
+ _this->StartTextInput(_this);
+ }
+}
+
+SDL_bool
+SDL_IsTextInputActive(void)
+{
+ return (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE);
+}
+
+void
+SDL_StopTextInput(void)
+{
+ SDL_Window *window;
+
+ /* Stop the text input system */
+ if (_this && _this->StopTextInput) {
+ _this->StopTextInput(_this);
+ }
+
+ /* Hide the on-screen keyboard, if any */
+ window = SDL_GetFocusWindow();
+ if (window && _this && _this->HideScreenKeyboard) {
+ _this->HideScreenKeyboard(_this, window);
+ }
+
+ /* Finally disable text events */
+ SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
+ SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
+}
+
+void
+SDL_SetTextInputRect(SDL_Rect *rect)
+{
+ if (_this && _this->SetTextInputRect) {
+ _this->SetTextInputRect(_this, rect);
+ }
+}
+
+SDL_bool
+SDL_HasScreenKeyboardSupport(void)
+{
+ if (_this && _this->HasScreenKeyboardSupport) {
+ return _this->HasScreenKeyboardSupport(_this);
+ }
+ return SDL_FALSE;
+}
+
+SDL_bool
+SDL_IsScreenKeyboardShown(SDL_Window *window)
+{
+ if (window && _this && _this->IsScreenKeyboardShown) {
+ return _this->IsScreenKeyboardShown(_this, window);
+ }
+ return SDL_FALSE;
+}
+
+#if SDL_VIDEO_DRIVER_ANDROID
+#include "android/SDL_androidmessagebox.h"
+#endif
+#if SDL_VIDEO_DRIVER_WINDOWS
+#include "windows/SDL_windowsmessagebox.h"
+#endif
+#if SDL_VIDEO_DRIVER_WINRT
+#include "winrt/SDL_winrtmessagebox.h"
+#endif
+#if SDL_VIDEO_DRIVER_COCOA
+#include "cocoa/SDL_cocoamessagebox.h"
+#endif
+#if SDL_VIDEO_DRIVER_UIKIT
+#include "uikit/SDL_uikitmessagebox.h"
+#endif
+#if SDL_VIDEO_DRIVER_X11
+#include "x11/SDL_x11messagebox.h"
+#endif
+
+
+#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11
+static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
+{
+ SDL_SysWMinfo info;
+ SDL_Window *window = messageboxdata->window;
+
+ if (!window) {
+ return SDL_TRUE;
+ }
+
+ SDL_VERSION(&info.version);
+ if (!SDL_GetWindowWMInfo(window, &info)) {
+ return SDL_TRUE;
+ } else {
+ return (info.subsystem == drivertype);
+ }
+}
+#endif
+
+int
+SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ int dummybutton;
+ int retval = -1;
+ SDL_bool relative_mode;
+ int show_cursor_prev;
+ SDL_bool mouse_captured;
+ SDL_Window *current_window;
+
+ if (!messageboxdata) {
+ return SDL_InvalidParamError("messageboxdata");
+ } else if (messageboxdata->numbuttons < 0) {
+ return SDL_SetError("Invalid number of buttons");
+ }
+
+ current_window = SDL_GetKeyboardFocus();
+ mouse_captured = current_window && ((SDL_GetWindowFlags(current_window) & SDL_WINDOW_MOUSE_CAPTURE) != 0);
+ relative_mode = SDL_GetRelativeMouseMode();
+ SDL_CaptureMouse(SDL_FALSE);
+ SDL_SetRelativeMouseMode(SDL_FALSE);
+ show_cursor_prev = SDL_ShowCursor(1);
+ SDL_ResetKeyboard();
+
+ if (!buttonid) {
+ buttonid = &dummybutton;
+ }
+
+ if (_this && _this->ShowMessageBox) {
+ retval = _this->ShowMessageBox(_this, messageboxdata, buttonid);
+ }
+
+ /* It's completely fine to call this function before video is initialized */
+#if SDL_VIDEO_DRIVER_ANDROID
+ if (retval == -1 &&
+ Android_ShowMessageBox(messageboxdata, buttonid) == 0) {
+ retval = 0;
+ }
+#endif
+#if SDL_VIDEO_DRIVER_WINDOWS
+ if (retval == -1 &&
+ SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINDOWS) &&
+ WIN_ShowMessageBox(messageboxdata, buttonid) == 0) {
+ retval = 0;
+ }
+#endif
+#if SDL_VIDEO_DRIVER_WINRT
+ if (retval == -1 &&
+ SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINRT) &&
+ WINRT_ShowMessageBox(messageboxdata, buttonid) == 0) {
+ retval = 0;
+ }
+#endif
+#if SDL_VIDEO_DRIVER_COCOA
+ if (retval == -1 &&
+ SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) &&
+ Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) {
+ retval = 0;
+ }
+#endif
+#if SDL_VIDEO_DRIVER_UIKIT
+ if (retval == -1 &&
+ SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_UIKIT) &&
+ UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) {
+ retval = 0;
+ }
+#endif
+#if SDL_VIDEO_DRIVER_X11
+ if (retval == -1 &&
+ SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) &&
+ X11_ShowMessageBox(messageboxdata, buttonid) == 0) {
+ retval = 0;
+ }
+#endif
+ if (retval == -1) {
+ SDL_SetError("No message system available");
+ }
+
+ if (current_window) {
+ SDL_RaiseWindow(current_window);
+ if (mouse_captured) {
+ SDL_CaptureMouse(SDL_TRUE);
+ }
+ }
+
+ SDL_ShowCursor(show_cursor_prev);
+ SDL_SetRelativeMouseMode(relative_mode);
+
+ return retval;
+}
+
+int
+SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window)
+{
+#ifdef __EMSCRIPTEN__
+ /* !!! FIXME: propose a browser API for this, get this #ifdef out of here? */
+ /* Web browsers don't (currently) have an API for a custom message box
+ that can block, but for the most common case (SDL_ShowSimpleMessageBox),
+ we can use the standard Javascript alert() function. */
+ EM_ASM_({
+ alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1));
+ }, title, message);
+ return 0;
+#else
+ SDL_MessageBoxData data;
+ SDL_MessageBoxButtonData button;
+
+ SDL_zero(data);
+ data.flags = flags;
+ data.title = title;
+ data.message = message;
+ data.numbuttons = 1;
+ data.buttons = &button;
+ data.window = window;
+
+ SDL_zero(button);
+ button.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
+ button.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ button.text = "OK";
+
+ return SDL_ShowMessageBox(&data, NULL);
+#endif
+}
+
+SDL_bool
+SDL_ShouldAllowTopmost(void)
+{
+ return SDL_GetHintBoolean(SDL_HINT_ALLOW_TOPMOST, SDL_TRUE);
+}
+
+int
+SDL_SetWindowHitTest(SDL_Window * window, SDL_HitTest callback, void *userdata)
+{
+ CHECK_WINDOW_MAGIC(window, -1);
+
+ if (!_this->SetWindowHitTest) {
+ return SDL_Unsupported();
+ } else if (_this->SetWindowHitTest(window, callback != NULL) == -1) {
+ return -1;
+ }
+
+ window->hit_test = callback;
+ window->hit_test_data = userdata;
+
+ return 0;
+}
+
+float
+SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches)
+{
+ float den2 = hinches * hinches + vinches * vinches;
+ if (den2 <= 0.0f) {
+ return 0.0f;
+ }
+
+ return (float)(SDL_sqrt((double)hpix * (double)hpix + (double)vpix * (double)vpix) /
+ SDL_sqrt((double)den2));
+}
+
+/*
+ * Functions used by iOS application delegates
+ */
+void SDL_OnApplicationWillTerminate(void)
+{
+ SDL_SendAppEvent(SDL_APP_TERMINATING);
+}
+
+void SDL_OnApplicationDidReceiveMemoryWarning(void)
+{
+ SDL_SendAppEvent(SDL_APP_LOWMEMORY);
+}
+
+void SDL_OnApplicationWillResignActive(void)
+{
+ if (_this) {
+ SDL_Window *window;
+ for (window = _this->windows; window != NULL; window = window->next) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+ }
+ }
+ SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
+}
+
+void SDL_OnApplicationDidEnterBackground(void)
+{
+ SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
+}
+
+void SDL_OnApplicationWillEnterForeground(void)
+{
+ SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
+}
+
+void SDL_OnApplicationDidBecomeActive(void)
+{
+ SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
+
+ if (_this) {
+ SDL_Window *window;
+ for (window = _this->windows; window != NULL; window = window->next) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+ }
+ }
+}
+
+#define NOT_A_VULKAN_WINDOW "The specified window isn't a Vulkan window"
+
+int SDL_Vulkan_LoadLibrary(const char *path)
+{
+ int retval;
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return -1;
+ }
+ if (_this->vulkan_config.loader_loaded) {
+ if (path && SDL_strcmp(path, _this->vulkan_config.loader_path) != 0) {
+ return SDL_SetError("Vulkan loader library already loaded");
+ }
+ retval = 0;
+ } else {
+ if (!_this->Vulkan_LoadLibrary) {
+ return SDL_SetError("Vulkan support is either not configured in SDL "
+ "or not available in current SDL video driver "
+ "(%s) or platform", _this->name);
+ }
+ retval = _this->Vulkan_LoadLibrary(_this, path);
+ }
+ if (retval == 0) {
+ _this->vulkan_config.loader_loaded++;
+ }
+ return retval;
+}
+
+void *SDL_Vulkan_GetVkGetInstanceProcAddr(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return NULL;
+ }
+ if (!_this->vulkan_config.loader_loaded) {
+ SDL_SetError("No Vulkan loader has been loaded");
+ return NULL;
+ }
+ return _this->vulkan_config.vkGetInstanceProcAddr;
+}
+
+void SDL_Vulkan_UnloadLibrary(void)
+{
+ if (!_this) {
+ SDL_UninitializedVideo();
+ return;
+ }
+ if (_this->vulkan_config.loader_loaded > 0) {
+ if (--_this->vulkan_config.loader_loaded > 0) {
+ return;
+ }
+ if (_this->Vulkan_UnloadLibrary) {
+ _this->Vulkan_UnloadLibrary(_this);
+ }
+ }
+}
+
+SDL_bool SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, unsigned *count, const char **names)
+{
+ if (window) {
+ CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+
+ if (!(window->flags & SDL_WINDOW_VULKAN))
+ {
+ SDL_SetError(NOT_A_VULKAN_WINDOW);
+ return SDL_FALSE;
+ }
+ }
+
+ if (!count) {
+ SDL_InvalidParamError("count");
+ return SDL_FALSE;
+ }
+
+ return _this->Vulkan_GetInstanceExtensions(_this, window, count, names);
+}
+
+SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+
+ if (!(window->flags & SDL_WINDOW_VULKAN)) {
+ SDL_SetError(NOT_A_VULKAN_WINDOW);
+ return SDL_FALSE;
+ }
+
+ if (!instance) {
+ SDL_InvalidParamError("instance");
+ return SDL_FALSE;
+ }
+
+ if (!surface) {
+ SDL_InvalidParamError("surface");
+ return SDL_FALSE;
+ }
+
+ return _this->Vulkan_CreateSurface(_this, window, instance, surface);
+}
+
+void SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h)
+{
+ CHECK_WINDOW_MAGIC(window,);
+
+ if (_this->Vulkan_GetDrawableSize) {
+ _this->Vulkan_GetDrawableSize(_this, window, w, h);
+ } else {
+ SDL_GetWindowSize(window, w, h);
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_vulkan_internal.h b/source/3rd-party/SDL2/src/video/SDL_vulkan_internal.h
new file mode 100644
index 0000000..cdf464e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_vulkan_internal.h
@@ -0,0 +1,91 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_vulkan_internal_h_
+#define SDL_vulkan_internal_h_
+
+#include "../SDL_internal.h"
+
+#include "SDL_stdinc.h"
+
+#if defined(SDL_LOADSO_DISABLED)
+#undef SDL_VIDEO_VULKAN
+#define SDL_VIDEO_VULKAN 0
+#endif
+
+#if SDL_VIDEO_VULKAN
+
+#if SDL_VIDEO_DRIVER_ANDROID
+#define VK_USE_PLATFORM_ANDROID_KHR
+#endif
+#if SDL_VIDEO_DRIVER_COCOA
+#define VK_USE_PLATFORM_MACOS_MVK
+#endif
+#if SDL_VIDEO_DRIVER_MIR
+#define VK_USE_PLATFORM_MIR_KHR
+#endif
+#if SDL_VIDEO_DRIVER_UIKIT
+#define VK_USE_PLATFORM_IOS_MVK
+#endif
+#if SDL_VIDEO_DRIVER_WAYLAND
+#define VK_USE_PLATFORM_WAYLAND_KHR
+#include "wayland/SDL_waylanddyn.h"
+#endif
+#if SDL_VIDEO_DRIVER_WINDOWS
+#define VK_USE_PLATFORM_WIN32_KHR
+#include "../core/windows/SDL_windows.h"
+#endif
+#if SDL_VIDEO_DRIVER_X11
+#define VK_USE_PLATFORM_XLIB_KHR
+#define VK_USE_PLATFORM_XCB_KHR
+#endif
+
+#define VK_NO_PROTOTYPES
+#include "./khronos/vulkan/vulkan.h"
+
+#include "SDL_vulkan.h"
+
+
+extern const char *SDL_Vulkan_GetResultString(VkResult result);
+
+extern VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
+ Uint32 *extensionCount); /* free returned list with SDL_free */
+
+/* Implements functionality of SDL_Vulkan_GetInstanceExtensions for a list of
+ * names passed in nameCount and names. */
+extern SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
+ const char **userNames,
+ unsigned nameCount,
+ const char *const *names);
+
+#else
+
+/* No SDL Vulkan support, just include the header for typedefs */
+#include "SDL_vulkan.h"
+
+typedef void (*PFN_vkGetInstanceProcAddr) (void);
+typedef int (*PFN_vkEnumerateInstanceExtensionProperties) (void);
+
+#endif /* SDL_VIDEO_VULKAN */
+
+#endif /* SDL_vulkan_internal_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_vulkan_utils.c b/source/3rd-party/SDL2/src/video/SDL_vulkan_utils.c
new file mode 100644
index 0000000..1b242f1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_vulkan_utils.c
@@ -0,0 +1,172 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_vulkan_internal.h"
+#include "SDL_error.h"
+
+#if SDL_VIDEO_VULKAN
+
+const char *SDL_Vulkan_GetResultString(VkResult result)
+{
+ switch((int)result)
+ {
+ case VK_SUCCESS:
+ return "VK_SUCCESS";
+ case VK_NOT_READY:
+ return "VK_NOT_READY";
+ case VK_TIMEOUT:
+ return "VK_TIMEOUT";
+ case VK_EVENT_SET:
+ return "VK_EVENT_SET";
+ case VK_EVENT_RESET:
+ return "VK_EVENT_RESET";
+ case VK_INCOMPLETE:
+ return "VK_INCOMPLETE";
+ case VK_ERROR_OUT_OF_HOST_MEMORY:
+ return "VK_ERROR_OUT_OF_HOST_MEMORY";
+ case VK_ERROR_OUT_OF_DEVICE_MEMORY:
+ return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
+ case VK_ERROR_INITIALIZATION_FAILED:
+ return "VK_ERROR_INITIALIZATION_FAILED";
+ case VK_ERROR_DEVICE_LOST:
+ return "VK_ERROR_DEVICE_LOST";
+ case VK_ERROR_MEMORY_MAP_FAILED:
+ return "VK_ERROR_MEMORY_MAP_FAILED";
+ case VK_ERROR_LAYER_NOT_PRESENT:
+ return "VK_ERROR_LAYER_NOT_PRESENT";
+ case VK_ERROR_EXTENSION_NOT_PRESENT:
+ return "VK_ERROR_EXTENSION_NOT_PRESENT";
+ case VK_ERROR_FEATURE_NOT_PRESENT:
+ return "VK_ERROR_FEATURE_NOT_PRESENT";
+ case VK_ERROR_INCOMPATIBLE_DRIVER:
+ return "VK_ERROR_INCOMPATIBLE_DRIVER";
+ case VK_ERROR_TOO_MANY_OBJECTS:
+ return "VK_ERROR_TOO_MANY_OBJECTS";
+ case VK_ERROR_FORMAT_NOT_SUPPORTED:
+ return "VK_ERROR_FORMAT_NOT_SUPPORTED";
+ case VK_ERROR_FRAGMENTED_POOL:
+ return "VK_ERROR_FRAGMENTED_POOL";
+ case VK_ERROR_SURFACE_LOST_KHR:
+ return "VK_ERROR_SURFACE_LOST_KHR";
+ case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
+ return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
+ case VK_SUBOPTIMAL_KHR:
+ return "VK_SUBOPTIMAL_KHR";
+ case VK_ERROR_OUT_OF_DATE_KHR:
+ return "VK_ERROR_OUT_OF_DATE_KHR";
+ case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
+ return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
+ case VK_ERROR_VALIDATION_FAILED_EXT:
+ return "VK_ERROR_VALIDATION_FAILED_EXT";
+ case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
+ return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR";
+ case VK_ERROR_INVALID_SHADER_NV:
+ return "VK_ERROR_INVALID_SHADER_NV";
+ case VK_RESULT_MAX_ENUM:
+ case VK_RESULT_RANGE_SIZE:
+ break;
+ }
+ if(result < 0)
+ return "VK_ERROR_<Unknown>";
+ return "VK_<Unknown>";
+}
+
+VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
+ Uint32 *extensionCount)
+{
+ Uint32 count = 0;
+ VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
+ VkExtensionProperties *retval;
+ if(result == VK_ERROR_INCOMPATIBLE_DRIVER)
+ {
+ /* Avoid the ERR_MAX_STRLEN limit by passing part of the message
+ * as a string argument.
+ */
+ SDL_SetError(
+ "You probably don't have a working Vulkan driver installed. %s %s %s(%d)",
+ "Getting Vulkan extensions failed:",
+ "vkEnumerateInstanceExtensionProperties returned",
+ SDL_Vulkan_GetResultString(result),
+ (int)result);
+ return NULL;
+ }
+ else if(result != VK_SUCCESS)
+ {
+ SDL_SetError(
+ "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
+ "%s(%d)",
+ SDL_Vulkan_GetResultString(result),
+ (int)result);
+ return NULL;
+ }
+ if(count == 0)
+ {
+ retval = SDL_calloc(1, sizeof(VkExtensionProperties)); // so we can return non-null
+ }
+ else
+ {
+ retval = SDL_calloc(count, sizeof(VkExtensionProperties));
+ }
+ if(!retval)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ result = vkEnumerateInstanceExtensionProperties(NULL, &count, retval);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError(
+ "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
+ "%s(%d)",
+ SDL_Vulkan_GetResultString(result),
+ (int)result);
+ SDL_free(retval);
+ return NULL;
+ }
+ *extensionCount = count;
+ return retval;
+}
+
+SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
+ const char **userNames,
+ unsigned nameCount,
+ const char *const *names)
+{
+ if (userNames) {
+ unsigned i;
+
+ if (*userCount < nameCount) {
+ SDL_SetError("Output array for SDL_Vulkan_GetInstanceExtensions needs to be at least %d big", nameCount);
+ return SDL_FALSE;
+ }
+ for (i = 0; i < nameCount; i++) {
+ userNames[i] = names[i];
+ }
+ }
+ *userCount = nameCount;
+ return SDL_TRUE;
+}
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_yuv.c b/source/3rd-party/SDL2/src/video/SDL_yuv.c
new file mode 100644
index 0000000..03b04dc
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_yuv.c
@@ -0,0 +1,1835 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+#include "SDL_endian.h"
+#include "SDL_video.h"
+#include "SDL_pixels_c.h"
+#include "SDL_yuv_c.h"
+
+#include "yuv2rgb/yuv_rgb.h"
+
+#define SDL_YUV_SD_THRESHOLD 576
+
+
+static SDL_YUV_CONVERSION_MODE SDL_YUV_ConversionMode = SDL_YUV_CONVERSION_BT601;
+
+
+void SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode)
+{
+ SDL_YUV_ConversionMode = mode;
+}
+
+SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionMode()
+{
+ return SDL_YUV_ConversionMode;
+}
+
+SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionModeForResolution(int width, int height)
+{
+ SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionMode();
+ if (mode == SDL_YUV_CONVERSION_AUTOMATIC) {
+ if (height <= SDL_YUV_SD_THRESHOLD) {
+ mode = SDL_YUV_CONVERSION_BT601;
+ } else {
+ mode = SDL_YUV_CONVERSION_BT709;
+ }
+ }
+ return mode;
+}
+
+static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type)
+{
+ switch (SDL_GetYUVConversionModeForResolution(width, height)) {
+ case SDL_YUV_CONVERSION_JPEG:
+ *yuv_type = YCBCR_JPEG;
+ break;
+ case SDL_YUV_CONVERSION_BT601:
+ *yuv_type = YCBCR_601;
+ break;
+ case SDL_YUV_CONVERSION_BT709:
+ *yuv_type = YCBCR_709;
+ break;
+ default:
+ return SDL_SetError("Unexpected YUV conversion mode");
+ }
+ return 0;
+}
+
+static SDL_bool IsPlanar2x2Format(Uint32 format)
+{
+ return (format == SDL_PIXELFORMAT_YV12 ||
+ format == SDL_PIXELFORMAT_IYUV ||
+ format == SDL_PIXELFORMAT_NV12 ||
+ format == SDL_PIXELFORMAT_NV21);
+}
+
+static SDL_bool IsPacked4Format(Uint32 format)
+{
+ return (format == SDL_PIXELFORMAT_YUY2 ||
+ format == SDL_PIXELFORMAT_UYVY ||
+ format == SDL_PIXELFORMAT_YVYU);
+}
+
+static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, int yuv_pitch,
+ const Uint8 **y, const Uint8 **u, const Uint8 **v, Uint32 *y_stride, Uint32 *uv_stride)
+{
+ const Uint8 *planes[3] = { NULL, NULL, NULL };
+ int pitches[3] = { 0, 0, 0 };
+
+ switch (format) {
+ case SDL_PIXELFORMAT_YV12:
+ case SDL_PIXELFORMAT_IYUV:
+ pitches[0] = yuv_pitch;
+ pitches[1] = (pitches[0] + 1) / 2;
+ pitches[2] = (pitches[0] + 1) / 2;
+ planes[0] = (const Uint8 *)yuv;
+ planes[1] = planes[0] + pitches[0] * height;
+ planes[2] = planes[1] + pitches[1] * ((height + 1) / 2);
+ break;
+ case SDL_PIXELFORMAT_YUY2:
+ case SDL_PIXELFORMAT_UYVY:
+ case SDL_PIXELFORMAT_YVYU:
+ pitches[0] = yuv_pitch;
+ planes[0] = (const Uint8 *)yuv;
+ break;
+ case SDL_PIXELFORMAT_NV12:
+ case SDL_PIXELFORMAT_NV21:
+ pitches[0] = yuv_pitch;
+ pitches[1] = 2 * ((pitches[0] + 1) / 2);
+ planes[0] = (const Uint8 *)yuv;
+ planes[1] = planes[0] + pitches[0] * height;
+ break;
+ default:
+ return SDL_SetError("GetYUVPlanes(): Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
+ }
+
+ switch (format) {
+ case SDL_PIXELFORMAT_YV12:
+ *y = planes[0];
+ *y_stride = pitches[0];
+ *v = planes[1];
+ *u = planes[2];
+ *uv_stride = pitches[1];
+ break;
+ case SDL_PIXELFORMAT_IYUV:
+ *y = planes[0];
+ *y_stride = pitches[0];
+ *v = planes[2];
+ *u = planes[1];
+ *uv_stride = pitches[1];
+ break;
+ case SDL_PIXELFORMAT_YUY2:
+ *y = planes[0];
+ *y_stride = pitches[0];
+ *v = *y + 3;
+ *u = *y + 1;
+ *uv_stride = pitches[0];
+ break;
+ case SDL_PIXELFORMAT_UYVY:
+ *y = planes[0] + 1;
+ *y_stride = pitches[0];
+ *v = *y + 1;
+ *u = *y - 1;
+ *uv_stride = pitches[0];
+ break;
+ case SDL_PIXELFORMAT_YVYU:
+ *y = planes[0];
+ *y_stride = pitches[0];
+ *v = *y + 1;
+ *u = *y + 3;
+ *uv_stride = pitches[0];
+ break;
+ case SDL_PIXELFORMAT_NV12:
+ *y = planes[0];
+ *y_stride = pitches[0];
+ *u = planes[1];
+ *v = *u + 1;
+ *uv_stride = pitches[1];
+ break;
+ case SDL_PIXELFORMAT_NV21:
+ *y = planes[0];
+ *y_stride = pitches[0];
+ *v = planes[1];
+ *u = *v + 1;
+ *uv_stride = pitches[1];
+ break;
+ default:
+ /* Should have caught this above */
+ return SDL_SetError("GetYUVPlanes[2]: Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
+ }
+ return 0;
+}
+
+static SDL_bool yuv_rgb_sse(
+ Uint32 src_format, Uint32 dst_format,
+ Uint32 width, Uint32 height,
+ const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
+ Uint8 *rgb, Uint32 rgb_stride,
+ YCbCrType yuv_type)
+{
+#ifdef __SSE2__
+ if (!SDL_HasSSE2()) {
+ return SDL_FALSE;
+ }
+
+ if (src_format == SDL_PIXELFORMAT_YV12 ||
+ src_format == SDL_PIXELFORMAT_IYUV) {
+
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_RGB565:
+ yuv420_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB24:
+ yuv420_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGBX8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ yuv420_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGRX8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ yuv420_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ yuv420_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ yuv420_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ default:
+ break;
+ }
+ }
+
+ if (src_format == SDL_PIXELFORMAT_YUY2 ||
+ src_format == SDL_PIXELFORMAT_UYVY ||
+ src_format == SDL_PIXELFORMAT_YVYU) {
+
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_RGB565:
+ yuv422_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB24:
+ yuv422_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGBX8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ yuv422_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGRX8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ yuv422_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ yuv422_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ yuv422_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ default:
+ break;
+ }
+ }
+
+ if (src_format == SDL_PIXELFORMAT_NV12 ||
+ src_format == SDL_PIXELFORMAT_NV21) {
+
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_RGB565:
+ yuvnv12_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB24:
+ yuvnv12_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGBX8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ yuvnv12_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGRX8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ yuvnv12_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ yuvnv12_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ yuvnv12_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ default:
+ break;
+ }
+ }
+#endif
+ return SDL_FALSE;
+}
+
+static SDL_bool yuv_rgb_std(
+ Uint32 src_format, Uint32 dst_format,
+ Uint32 width, Uint32 height,
+ const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
+ Uint8 *rgb, Uint32 rgb_stride,
+ YCbCrType yuv_type)
+{
+ if (src_format == SDL_PIXELFORMAT_YV12 ||
+ src_format == SDL_PIXELFORMAT_IYUV) {
+
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_RGB565:
+ yuv420_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB24:
+ yuv420_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGBX8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ yuv420_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGRX8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ yuv420_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ yuv420_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ yuv420_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ default:
+ break;
+ }
+ }
+
+ if (src_format == SDL_PIXELFORMAT_YUY2 ||
+ src_format == SDL_PIXELFORMAT_UYVY ||
+ src_format == SDL_PIXELFORMAT_YVYU) {
+
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_RGB565:
+ yuv422_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB24:
+ yuv422_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGBX8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ yuv422_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGRX8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ yuv422_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ yuv422_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ yuv422_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ default:
+ break;
+ }
+ }
+
+ if (src_format == SDL_PIXELFORMAT_NV12 ||
+ src_format == SDL_PIXELFORMAT_NV21) {
+
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_RGB565:
+ yuvnv12_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB24:
+ yuvnv12_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGBX8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ yuvnv12_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGRX8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ yuvnv12_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_ARGB8888:
+ yuvnv12_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ yuvnv12_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
+ return SDL_TRUE;
+ default:
+ break;
+ }
+ }
+ return SDL_FALSE;
+}
+
+int
+SDL_ConvertPixels_YUV_to_RGB(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+ const Uint8 *y = NULL;
+ const Uint8 *u = NULL;
+ const Uint8 *v = NULL;
+ Uint32 y_stride = 0;
+ Uint32 uv_stride = 0;
+ YCbCrType yuv_type = YCBCR_601;
+
+ if (GetYUVPlanes(width, height, src_format, src, src_pitch, &y, &u, &v, &y_stride, &uv_stride) < 0) {
+ return -1;
+ }
+
+ if (GetYUVConversionType(width, height, &yuv_type) < 0) {
+ return -1;
+ }
+
+ if (yuv_rgb_sse(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
+ return 0;
+ }
+
+ if (yuv_rgb_std(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
+ return 0;
+ }
+
+ /* No fast path for the RGB format, instead convert using an intermediate buffer */
+ if (dst_format != SDL_PIXELFORMAT_ARGB8888) {
+ int ret;
+ void *tmp;
+ int tmp_pitch = (width * sizeof(Uint32));
+
+ tmp = SDL_malloc(tmp_pitch * height);
+ if (tmp == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ /* convert src/src_format to tmp/ARGB8888 */
+ ret = SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch);
+ if (ret < 0) {
+ SDL_free(tmp);
+ return ret;
+ }
+
+ /* convert tmp/ARGB8888 to dst/RGB */
+ ret = SDL_ConvertPixels(width, height, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch, dst_format, dst, dst_pitch);
+ SDL_free(tmp);
+ return ret;
+ }
+
+ return SDL_SetError("Unsupported YUV conversion");
+}
+
+struct RGB2YUVFactors
+{
+ int y_offset;
+ float y[3]; /* Rfactor, Gfactor, Bfactor */
+ float u[3]; /* Rfactor, Gfactor, Bfactor */
+ float v[3]; /* Rfactor, Gfactor, Bfactor */
+};
+
+static int
+SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
+{
+ const int src_pitch_x_2 = src_pitch * 2;
+ const int height_half = height / 2;
+ const int height_remainder = (height & 0x1);
+ const int width_half = width / 2;
+ const int width_remainder = (width & 0x1);
+ int i, j;
+
+ static struct RGB2YUVFactors RGB2YUVFactorTables[SDL_YUV_CONVERSION_BT709 + 1] =
+ {
+ /* ITU-T T.871 (JPEG) */
+ {
+ 0,
+ { 0.2990f, 0.5870f, 0.1140f },
+ { -0.1687f, -0.3313f, 0.5000f },
+ { 0.5000f, -0.4187f, -0.0813f },
+ },
+ /* ITU-R BT.601-7 */
+ {
+ 16,
+ { 0.2568f, 0.5041f, 0.0979f },
+ { -0.1482f, -0.2910f, 0.4392f },
+ { 0.4392f, -0.3678f, -0.0714f },
+ },
+ /* ITU-R BT.709-6 */
+ {
+ 16,
+ { 0.1826f, 0.6142f, 0.0620f },
+ {-0.1006f, -0.3386f, 0.4392f },
+ { 0.4392f, -0.3989f, -0.0403f },
+ },
+ };
+ const struct RGB2YUVFactors *cvt = &RGB2YUVFactorTables[SDL_GetYUVConversionModeForResolution(width, height)];
+
+#define MAKE_Y(r, g, b) (Uint8)((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset)
+#define MAKE_U(r, g, b) (Uint8)((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128)
+#define MAKE_V(r, g, b) (Uint8)((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128)
+
+#define READ_2x2_PIXELS \
+ const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
+ const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \
+ const Uint32 p3 = ((const Uint32 *)next_row)[2 * i]; \
+ const Uint32 p4 = ((const Uint32 *)next_row)[2 * i + 1]; \
+ const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \
+ const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \
+ const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; \
+
+#define READ_2x1_PIXELS \
+ const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
+ const Uint32 p2 = ((const Uint32 *)next_row)[2 * i]; \
+ const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \
+ const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \
+ const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \
+
+#define READ_1x2_PIXELS \
+ const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
+ const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \
+ const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \
+ const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \
+ const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \
+
+#define READ_1x1_PIXEL \
+ const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \
+ const Uint32 r = (p & 0x00ff0000) >> 16; \
+ const Uint32 g = (p & 0x0000ff00) >> 8; \
+ const Uint32 b = (p & 0x000000ff); \
+
+#define READ_TWO_RGB_PIXELS \
+ const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \
+ const Uint32 r = (p & 0x00ff0000) >> 16; \
+ const Uint32 g = (p & 0x0000ff00) >> 8; \
+ const Uint32 b = (p & 0x000000ff); \
+ const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i + 1]; \
+ const Uint32 r1 = (p1 & 0x00ff0000) >> 16; \
+ const Uint32 g1 = (p1 & 0x0000ff00) >> 8; \
+ const Uint32 b1 = (p1 & 0x000000ff); \
+ const Uint32 R = (r + r1)/2; \
+ const Uint32 G = (g + g1)/2; \
+ const Uint32 B = (b + b1)/2; \
+
+#define READ_ONE_RGB_PIXEL READ_1x1_PIXEL
+
+ switch (dst_format)
+ {
+ case SDL_PIXELFORMAT_YV12:
+ case SDL_PIXELFORMAT_IYUV:
+ case SDL_PIXELFORMAT_NV12:
+ case SDL_PIXELFORMAT_NV21:
+ {
+ const Uint8 *curr_row, *next_row;
+
+ Uint8 *plane_y;
+ Uint8 *plane_u;
+ Uint8 *plane_v;
+ Uint8 *plane_interleaved_uv;
+ Uint32 y_stride, uv_stride, y_skip, uv_skip;
+
+ GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
+ (const Uint8 **)&plane_y, (const Uint8 **)&plane_u, (const Uint8 **)&plane_v,
+ &y_stride, &uv_stride);
+ plane_interleaved_uv = (plane_y + height * y_stride);
+ y_skip = (y_stride - width);
+
+ curr_row = (const Uint8*)src;
+
+ /* Write Y plane */
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ const Uint32 p1 = ((const Uint32 *)curr_row)[i];
+ const Uint32 r = (p1 & 0x00ff0000) >> 16;
+ const Uint32 g = (p1 & 0x0000ff00) >> 8;
+ const Uint32 b = (p1 & 0x000000ff);
+ *plane_y++ = MAKE_Y(r, g, b);
+ }
+ plane_y += y_skip;
+ curr_row += src_pitch;
+ }
+
+ curr_row = (const Uint8*)src;
+ next_row = (const Uint8*)src;
+ next_row += src_pitch;
+
+ if (dst_format == SDL_PIXELFORMAT_YV12 || dst_format == SDL_PIXELFORMAT_IYUV)
+ {
+ /* Write UV planes, not interleaved */
+ uv_skip = (uv_stride - (width + 1)/2);
+ for (j = 0; j < height_half; j++) {
+ for (i = 0; i < width_half; i++) {
+ READ_2x2_PIXELS;
+ *plane_u++ = MAKE_U(r, g, b);
+ *plane_v++ = MAKE_V(r, g, b);
+ }
+ if (width_remainder) {
+ READ_2x1_PIXELS;
+ *plane_u++ = MAKE_U(r, g, b);
+ *plane_v++ = MAKE_V(r, g, b);
+ }
+ plane_u += uv_skip;
+ plane_v += uv_skip;
+ curr_row += src_pitch_x_2;
+ next_row += src_pitch_x_2;
+ }
+ if (height_remainder) {
+ for (i = 0; i < width_half; i++) {
+ READ_1x2_PIXELS;
+ *plane_u++ = MAKE_U(r, g, b);
+ *plane_v++ = MAKE_V(r, g, b);
+ }
+ if (width_remainder) {
+ READ_1x1_PIXEL;
+ *plane_u++ = MAKE_U(r, g, b);
+ *plane_v++ = MAKE_V(r, g, b);
+ }
+ plane_u += uv_skip;
+ plane_v += uv_skip;
+ }
+ }
+ else if (dst_format == SDL_PIXELFORMAT_NV12)
+ {
+ uv_skip = (uv_stride - ((width + 1)/2)*2);
+ for (j = 0; j < height_half; j++) {
+ for (i = 0; i < width_half; i++) {
+ READ_2x2_PIXELS;
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ }
+ if (width_remainder) {
+ READ_2x1_PIXELS;
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ }
+ plane_interleaved_uv += uv_skip;
+ curr_row += src_pitch_x_2;
+ next_row += src_pitch_x_2;
+ }
+ if (height_remainder) {
+ for (i = 0; i < width_half; i++) {
+ READ_1x2_PIXELS;
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ }
+ if (width_remainder) {
+ READ_1x1_PIXEL;
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ }
+ }
+ }
+ else /* dst_format == SDL_PIXELFORMAT_NV21 */
+ {
+ uv_skip = (uv_stride - ((width + 1)/2)*2);
+ for (j = 0; j < height_half; j++) {
+ for (i = 0; i < width_half; i++) {
+ READ_2x2_PIXELS;
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ }
+ if (width_remainder) {
+ READ_2x1_PIXELS;
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ }
+ plane_interleaved_uv += uv_skip;
+ curr_row += src_pitch_x_2;
+ next_row += src_pitch_x_2;
+ }
+ if (height_remainder) {
+ for (i = 0; i < width_half; i++) {
+ READ_1x2_PIXELS;
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ }
+ if (width_remainder) {
+ READ_1x1_PIXEL;
+ *plane_interleaved_uv++ = MAKE_V(r, g, b);
+ *plane_interleaved_uv++ = MAKE_U(r, g, b);
+ }
+ }
+ }
+ }
+ break;
+
+ case SDL_PIXELFORMAT_YUY2:
+ case SDL_PIXELFORMAT_UYVY:
+ case SDL_PIXELFORMAT_YVYU:
+ {
+ const Uint8 *curr_row = (const Uint8*) src;
+ Uint8 *plane = (Uint8*) dst;
+ const int row_size = (4 * ((width + 1) / 2));
+ int plane_skip;
+
+ if (dst_pitch < row_size) {
+ return SDL_SetError("Destination pitch is too small, expected at least %d\n", row_size);
+ }
+ plane_skip = (dst_pitch - row_size);
+
+ /* Write YUV plane, packed */
+ if (dst_format == SDL_PIXELFORMAT_YUY2)
+ {
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width_half; i++) {
+ READ_TWO_RGB_PIXELS;
+ /* Y U Y1 V */
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_U(R, G, B);
+ *plane++ = MAKE_Y(r1, g1, b1);
+ *plane++ = MAKE_V(R, G, B);
+ }
+ if (width_remainder) {
+ READ_ONE_RGB_PIXEL;
+ /* Y U Y V */
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_U(r, g, b);
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_V(r, g, b);
+ }
+ plane += plane_skip;
+ curr_row += src_pitch;
+ }
+ }
+ else if (dst_format == SDL_PIXELFORMAT_UYVY)
+ {
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width_half; i++) {
+ READ_TWO_RGB_PIXELS;
+ /* U Y V Y1 */
+ *plane++ = MAKE_U(R, G, B);
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_V(R, G, B);
+ *plane++ = MAKE_Y(r1, g1, b1);
+ }
+ if (width_remainder) {
+ READ_ONE_RGB_PIXEL;
+ /* U Y V Y */
+ *plane++ = MAKE_U(r, g, b);
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_V(r, g, b);
+ *plane++ = MAKE_Y(r, g, b);
+ }
+ plane += plane_skip;
+ curr_row += src_pitch;
+ }
+ }
+ else if (dst_format == SDL_PIXELFORMAT_YVYU)
+ {
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width_half; i++) {
+ READ_TWO_RGB_PIXELS;
+ /* Y V Y1 U */
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_V(R, G, B);
+ *plane++ = MAKE_Y(r1, g1, b1);
+ *plane++ = MAKE_U(R, G, B);
+ }
+ if (width_remainder) {
+ READ_ONE_RGB_PIXEL;
+ /* Y V Y U */
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_V(r, g, b);
+ *plane++ = MAKE_Y(r, g, b);
+ *plane++ = MAKE_U(r, g, b);
+ }
+ plane += plane_skip;
+ curr_row += src_pitch;
+ }
+ }
+ }
+ break;
+
+ default:
+ return SDL_SetError("Unsupported YUV destination format: %s", SDL_GetPixelFormatName(dst_format));
+ }
+#undef MAKE_Y
+#undef MAKE_U
+#undef MAKE_V
+#undef READ_2x2_PIXELS
+#undef READ_2x1_PIXELS
+#undef READ_1x2_PIXELS
+#undef READ_1x1_PIXEL
+#undef READ_TWO_RGB_PIXELS
+#undef READ_ONE_RGB_PIXEL
+ return 0;
+}
+
+int
+SDL_ConvertPixels_RGB_to_YUV(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+#if 0 /* Doesn't handle odd widths */
+ /* RGB24 to FOURCC */
+ if (src_format == SDL_PIXELFORMAT_RGB24) {
+ Uint8 *y;
+ Uint8 *u;
+ Uint8 *v;
+ Uint32 y_stride;
+ Uint32 uv_stride;
+ YCbCrType yuv_type;
+
+ if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch, (const Uint8 **)&y, (const Uint8 **)&u, (const Uint8 **)&v, &y_stride, &uv_stride) < 0) {
+ return -1;
+ }
+
+ if (GetYUVConversionType(width, height, &yuv_type) < 0) {
+ return -1;
+ }
+
+ rgb24_yuv420_std(width, height, src, src_pitch, y, u, v, y_stride, uv_stride, yuv_type);
+ return 0;
+ }
+#endif
+
+ /* ARGB8888 to FOURCC */
+ if (src_format == SDL_PIXELFORMAT_ARGB8888) {
+ return SDL_ConvertPixels_ARGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch);
+ }
+
+ /* not ARGB8888 to FOURCC : need an intermediate conversion */
+ {
+ int ret;
+ void *tmp;
+ int tmp_pitch = (width * sizeof(Uint32));
+
+ tmp = SDL_malloc(tmp_pitch * height);
+ if (tmp == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ /* convert src/src_format to tmp/ARGB8888 */
+ ret = SDL_ConvertPixels(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch);
+ if (ret == -1) {
+ SDL_free(tmp);
+ return ret;
+ }
+
+ /* convert tmp/ARGB8888 to dst/FOURCC */
+ ret = SDL_ConvertPixels_ARGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch);
+ SDL_free(tmp);
+ return ret;
+ }
+}
+
+static int
+SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format,
+ const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int i;
+
+ if (IsPlanar2x2Format(format)) {
+ /* Y plane */
+ for (i = height; i--;) {
+ SDL_memcpy(dst, src, width);
+ src = (const Uint8*)src + src_pitch;
+ dst = (Uint8*)dst + dst_pitch;
+ }
+
+ if (format == SDL_PIXELFORMAT_YV12 || format == SDL_PIXELFORMAT_IYUV) {
+ /* U and V planes are a quarter the size of the Y plane, rounded up */
+ width = (width + 1) / 2;
+ height = (height + 1) / 2;
+ src_pitch = (src_pitch + 1) / 2;
+ dst_pitch = (dst_pitch + 1) / 2;
+ for (i = height * 2; i--;) {
+ SDL_memcpy(dst, src, width);
+ src = (const Uint8*)src + src_pitch;
+ dst = (Uint8*)dst + dst_pitch;
+ }
+ } else if (format == SDL_PIXELFORMAT_NV12 || format == SDL_PIXELFORMAT_NV21) {
+ /* U/V plane is half the height of the Y plane, rounded up */
+ height = (height + 1) / 2;
+ width = ((width + 1) / 2)*2;
+ src_pitch = ((src_pitch + 1) / 2)*2;
+ dst_pitch = ((dst_pitch + 1) / 2)*2;
+ for (i = height; i--;) {
+ SDL_memcpy(dst, src, width);
+ src = (const Uint8*)src + src_pitch;
+ dst = (Uint8*)dst + dst_pitch;
+ }
+ }
+ return 0;
+ }
+
+ if (IsPacked4Format(format)) {
+ /* Packed planes */
+ width = 4 * ((width + 1) / 2);
+ for (i = height; i--;) {
+ SDL_memcpy(dst, src, width);
+ src = (const Uint8*)src + src_pitch;
+ dst = (Uint8*)dst + dst_pitch;
+ }
+ return 0;
+ }
+
+ return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV_Copy: Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
+}
+
+static int
+SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int y;
+ const int UVwidth = (width + 1)/2;
+ const int UVheight = (height + 1)/2;
+
+ /* Skip the Y plane */
+ src = (const Uint8 *)src + height * src_pitch;
+ dst = (Uint8 *)dst + height * dst_pitch;
+
+ if (src == dst) {
+ int UVpitch = (dst_pitch + 1)/2;
+ Uint8 *tmp;
+ Uint8 *row1 = dst;
+ Uint8 *row2 = (Uint8 *)dst + UVheight * UVpitch;
+
+ /* Allocate a temporary row for the swap */
+ tmp = (Uint8 *)SDL_malloc(UVwidth);
+ if (!tmp) {
+ return SDL_OutOfMemory();
+ }
+ for (y = 0; y < UVheight; ++y) {
+ SDL_memcpy(tmp, row1, UVwidth);
+ SDL_memcpy(row1, row2, UVwidth);
+ SDL_memcpy(row2, tmp, UVwidth);
+ row1 += UVpitch;
+ row2 += UVpitch;
+ }
+ SDL_free(tmp);
+ } else {
+ const Uint8 *srcUV;
+ Uint8 *dstUV;
+ int srcUVPitch = ((src_pitch + 1)/2);
+ int dstUVPitch = ((dst_pitch + 1)/2);
+
+ /* Copy the first plane */
+ srcUV = (const Uint8 *)src;
+ dstUV = (Uint8 *)dst + UVheight * dstUVPitch;
+ for (y = 0; y < UVheight; ++y) {
+ SDL_memcpy(dstUV, srcUV, UVwidth);
+ srcUV += srcUVPitch;
+ dstUV += dstUVPitch;
+ }
+
+ /* Copy the second plane */
+ dstUV = (Uint8 *)dst;
+ for (y = 0; y < UVheight; ++y) {
+ SDL_memcpy(dstUV, srcUV, UVwidth);
+ srcUV += srcUVPitch;
+ dstUV += dstUVPitch;
+ }
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
+{
+ int x, y;
+ const int UVwidth = (width + 1)/2;
+ const int UVheight = (height + 1)/2;
+ const int srcUVPitch = ((src_pitch + 1)/2);
+ const int srcUVPitchLeft = srcUVPitch - UVwidth;
+ const int dstUVPitch = ((dst_pitch + 1)/2)*2;
+ const int dstUVPitchLeft = dstUVPitch - UVwidth*2;
+ const Uint8 *src1, *src2;
+ Uint8 *dstUV;
+ Uint8 *tmp = NULL;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ /* Skip the Y plane */
+ src = (const Uint8 *)src + height * src_pitch;
+ dst = (Uint8 *)dst + height * dst_pitch;
+
+ if (src == dst) {
+ /* Need to make a copy of the buffer so we don't clobber it while converting */
+ tmp = (Uint8 *)SDL_malloc(2*UVheight*srcUVPitch);
+ if (!tmp) {
+ return SDL_OutOfMemory();
+ }
+ SDL_memcpy(tmp, src, 2*UVheight*srcUVPitch);
+ src = tmp;
+ }
+
+ if (reverseUV) {
+ src2 = (const Uint8 *)src;
+ src1 = src2 + UVheight * srcUVPitch;
+ } else {
+ src1 = (const Uint8 *)src;
+ src2 = src1 + UVheight * srcUVPitch;
+ }
+ dstUV = (Uint8 *)dst;
+
+ y = UVheight;
+ while (y--) {
+ x = UVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ while (x >= 16) {
+ __m128i u = _mm_loadu_si128((__m128i *)src1);
+ __m128i v = _mm_loadu_si128((__m128i *)src2);
+ __m128i uv1 = _mm_unpacklo_epi8(u, v);
+ __m128i uv2 = _mm_unpackhi_epi8(u, v);
+ _mm_storeu_si128((__m128i*)dstUV, uv1);
+ _mm_storeu_si128((__m128i*)(dstUV + 16), uv2);
+ src1 += 16;
+ src2 += 16;
+ dstUV += 32;
+ x -= 16;
+ }
+ }
+#endif
+ while (x--) {
+ *dstUV++ = *src1++;
+ *dstUV++ = *src2++;
+ }
+ src1 += srcUVPitchLeft;
+ src2 += srcUVPitchLeft;
+ dstUV += dstUVPitchLeft;
+ }
+
+ if (tmp) {
+ SDL_free(tmp);
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
+{
+ int x, y;
+ const int UVwidth = (width + 1)/2;
+ const int UVheight = (height + 1)/2;
+ const int srcUVPitch = ((src_pitch + 1)/2)*2;
+ const int srcUVPitchLeft = srcUVPitch - UVwidth*2;
+ const int dstUVPitch = ((dst_pitch + 1)/2);
+ const int dstUVPitchLeft = dstUVPitch - UVwidth;
+ const Uint8 *srcUV;
+ Uint8 *dst1, *dst2;
+ Uint8 *tmp = NULL;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ /* Skip the Y plane */
+ src = (const Uint8 *)src + height * src_pitch;
+ dst = (Uint8 *)dst + height * dst_pitch;
+
+ if (src == dst) {
+ /* Need to make a copy of the buffer so we don't clobber it while converting */
+ tmp = (Uint8 *)SDL_malloc(UVheight*srcUVPitch);
+ if (!tmp) {
+ return SDL_OutOfMemory();
+ }
+ SDL_memcpy(tmp, src, UVheight*srcUVPitch);
+ src = tmp;
+ }
+
+ if (reverseUV) {
+ dst2 = (Uint8 *)dst;
+ dst1 = dst2 + UVheight * dstUVPitch;
+ } else {
+ dst1 = (Uint8 *)dst;
+ dst2 = dst1 + UVheight * dstUVPitch;
+ }
+ srcUV = (const Uint8 *)src;
+
+ y = UVheight;
+ while (y--) {
+ x = UVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ __m128i mask = _mm_set1_epi16(0x00FF);
+ while (x >= 16) {
+ __m128i uv1 = _mm_loadu_si128((__m128i*)srcUV);
+ __m128i uv2 = _mm_loadu_si128((__m128i*)(srcUV+16));
+ __m128i u1 = _mm_and_si128(uv1, mask);
+ __m128i u2 = _mm_and_si128(uv2, mask);
+ __m128i u = _mm_packus_epi16(u1, u2);
+ __m128i v1 = _mm_srli_epi16(uv1, 8);
+ __m128i v2 = _mm_srli_epi16(uv2, 8);
+ __m128i v = _mm_packus_epi16(v1, v2);
+ _mm_storeu_si128((__m128i*)dst1, u);
+ _mm_storeu_si128((__m128i*)dst2, v);
+ srcUV += 32;
+ dst1 += 16;
+ dst2 += 16;
+ x -= 16;
+ }
+ }
+#endif
+ while (x--) {
+ *dst1++ = *srcUV++;
+ *dst2++ = *srcUV++;
+ }
+ srcUV += srcUVPitchLeft;
+ dst1 += dstUVPitchLeft;
+ dst2 += dstUVPitchLeft;
+ }
+
+ if (tmp) {
+ SDL_free(tmp);
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int UVwidth = (width + 1)/2;
+ const int UVheight = (height + 1)/2;
+ const int srcUVPitch = ((src_pitch + 1)/2)*2;
+ const int srcUVPitchLeft = (srcUVPitch - UVwidth*2)/sizeof(Uint16);
+ const int dstUVPitch = ((dst_pitch + 1)/2)*2;
+ const int dstUVPitchLeft = (dstUVPitch - UVwidth*2)/sizeof(Uint16);
+ const Uint16 *srcUV;
+ Uint16 *dstUV;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ /* Skip the Y plane */
+ src = (const Uint8 *)src + height * src_pitch;
+ dst = (Uint8 *)dst + height * dst_pitch;
+
+ srcUV = (const Uint16 *)src;
+ dstUV = (Uint16 *)dst;
+ y = UVheight;
+ while (y--) {
+ x = UVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ while (x >= 8) {
+ __m128i uv = _mm_loadu_si128((__m128i*)srcUV);
+ __m128i v = _mm_slli_epi16(uv, 8);
+ __m128i u = _mm_srli_epi16(uv, 8);
+ __m128i vu = _mm_or_si128(v, u);
+ _mm_storeu_si128((__m128i*)dstUV, vu);
+ srcUV += 8;
+ dstUV += 8;
+ x -= 8;
+ }
+ }
+#endif
+ while (x--) {
+ *dstUV++ = SDL_Swap16(*srcUV++);
+ }
+ srcUV += srcUVPitchLeft;
+ dstUV += dstUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_Planar2x2_to_Planar2x2(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+ if (src != dst) {
+ /* Copy Y plane */
+ int i;
+ const Uint8 *srcY = (const Uint8 *)src;
+ Uint8 *dstY = (Uint8 *)dst;
+ for (i = height; i--; ) {
+ SDL_memcpy(dstY, srcY, width);
+ srcY += src_pitch;
+ dstY += dst_pitch;
+ }
+ }
+
+ switch (src_format) {
+ case SDL_PIXELFORMAT_YV12:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_IYUV:
+ return SDL_ConvertPixels_SwapUVPlanes(width, height, src, src_pitch, dst, dst_pitch);
+ case SDL_PIXELFORMAT_NV12:
+ return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
+ case SDL_PIXELFORMAT_NV21:
+ return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
+ default:
+ break;
+ }
+ break;
+ case SDL_PIXELFORMAT_IYUV:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_YV12:
+ return SDL_ConvertPixels_SwapUVPlanes(width, height, src, src_pitch, dst, dst_pitch);
+ case SDL_PIXELFORMAT_NV12:
+ return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
+ case SDL_PIXELFORMAT_NV21:
+ return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
+ default:
+ break;
+ }
+ break;
+ case SDL_PIXELFORMAT_NV12:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_YV12:
+ return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
+ case SDL_PIXELFORMAT_IYUV:
+ return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
+ case SDL_PIXELFORMAT_NV21:
+ return SDL_ConvertPixels_SwapNV(width, height, src, src_pitch, dst, dst_pitch);
+ default:
+ break;
+ }
+ break;
+ case SDL_PIXELFORMAT_NV21:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_YV12:
+ return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
+ case SDL_PIXELFORMAT_IYUV:
+ return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
+ case SDL_PIXELFORMAT_NV12:
+ return SDL_ConvertPixels_SwapNV(width, height, src, src_pitch, dst, dst_pitch);
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return SDL_SetError("SDL_ConvertPixels_Planar2x2_to_Planar2x2: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
+}
+
+#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle) \
+ while (x >= 4) { \
+ __m128i yuv = _mm_loadu_si128((__m128i*)srcYUV); \
+ __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \
+ __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \
+ lo = _mm_shufflelo_epi16(lo, shuffle); \
+ lo = _mm_shufflehi_epi16(lo, shuffle); \
+ hi = _mm_shufflelo_epi16(hi, shuffle); \
+ hi = _mm_shufflehi_epi16(hi, shuffle); \
+ yuv = _mm_packus_epi16(lo, hi); \
+ _mm_storeu_si128((__m128i*)dstYUV, yuv); \
+ srcYUV += 16; \
+ dstYUV += 16; \
+ x -= 4; \
+ } \
+
+static int
+SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int YUVwidth = (width + 1)/2;
+ const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
+ const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
+ const Uint8 *srcYUV = (const Uint8 *)src;
+ Uint8 *dstYUV = (Uint8 *)dst;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ y = height;
+ while (y--) {
+ x = YUVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1));
+ }
+#endif
+ while (x--) {
+ Uint8 Y1, U, Y2, V;
+
+ Y1 = srcYUV[0];
+ U = srcYUV[1];
+ Y2 = srcYUV[2];
+ V = srcYUV[3];
+ srcYUV += 4;
+
+ dstYUV[0] = U;
+ dstYUV[1] = Y1;
+ dstYUV[2] = V;
+ dstYUV[3] = Y2;
+ dstYUV += 4;
+ }
+ srcYUV += srcYUVPitchLeft;
+ dstYUV += dstYUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int YUVwidth = (width + 1)/2;
+ const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
+ const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
+ const Uint8 *srcYUV = (const Uint8 *)src;
+ Uint8 *dstYUV = (Uint8 *)dst;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ y = height;
+ while (y--) {
+ x = YUVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0));
+ }
+#endif
+ while (x--) {
+ Uint8 Y1, U, Y2, V;
+
+ Y1 = srcYUV[0];
+ U = srcYUV[1];
+ Y2 = srcYUV[2];
+ V = srcYUV[3];
+ srcYUV += 4;
+
+ dstYUV[0] = Y1;
+ dstYUV[1] = V;
+ dstYUV[2] = Y2;
+ dstYUV[3] = U;
+ dstYUV += 4;
+ }
+ srcYUV += srcYUVPitchLeft;
+ dstYUV += dstYUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int YUVwidth = (width + 1)/2;
+ const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
+ const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
+ const Uint8 *srcYUV = (const Uint8 *)src;
+ Uint8 *dstYUV = (Uint8 *)dst;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ y = height;
+ while (y--) {
+ x = YUVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1));
+ }
+#endif
+ while (x--) {
+ Uint8 Y1, U, Y2, V;
+
+ U = srcYUV[0];
+ Y1 = srcYUV[1];
+ V = srcYUV[2];
+ Y2 = srcYUV[3];
+ srcYUV += 4;
+
+ dstYUV[0] = Y1;
+ dstYUV[1] = U;
+ dstYUV[2] = Y2;
+ dstYUV[3] = V;
+ dstYUV += 4;
+ }
+ srcYUV += srcYUVPitchLeft;
+ dstYUV += dstYUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int YUVwidth = (width + 1)/2;
+ const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
+ const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
+ const Uint8 *srcYUV = (const Uint8 *)src;
+ Uint8 *dstYUV = (Uint8 *)dst;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ y = height;
+ while (y--) {
+ x = YUVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(0, 3, 2, 1));
+ }
+#endif
+ while (x--) {
+ Uint8 Y1, U, Y2, V;
+
+ U = srcYUV[0];
+ Y1 = srcYUV[1];
+ V = srcYUV[2];
+ Y2 = srcYUV[3];
+ srcYUV += 4;
+
+ dstYUV[0] = Y1;
+ dstYUV[1] = V;
+ dstYUV[2] = Y2;
+ dstYUV[3] = U;
+ dstYUV += 4;
+ }
+ srcYUV += srcYUVPitchLeft;
+ dstYUV += dstYUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int YUVwidth = (width + 1)/2;
+ const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
+ const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
+ const Uint8 *srcYUV = (const Uint8 *)src;
+ Uint8 *dstYUV = (Uint8 *)dst;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ y = height;
+ while (y--) {
+ x = YUVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0));
+ }
+#endif
+ while (x--) {
+ Uint8 Y1, U, Y2, V;
+
+ Y1 = srcYUV[0];
+ V = srcYUV[1];
+ Y2 = srcYUV[2];
+ U = srcYUV[3];
+ srcYUV += 4;
+
+ dstYUV[0] = Y1;
+ dstYUV[1] = U;
+ dstYUV[2] = Y2;
+ dstYUV[3] = V;
+ dstYUV += 4;
+ }
+ srcYUV += srcYUVPitchLeft;
+ dstYUV += dstYUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
+{
+ int x, y;
+ const int YUVwidth = (width + 1)/2;
+ const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
+ const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
+ const Uint8 *srcYUV = (const Uint8 *)src;
+ Uint8 *dstYUV = (Uint8 *)dst;
+#ifdef __SSE2__
+ const SDL_bool use_SSE2 = SDL_HasSSE2();
+#endif
+
+ y = height;
+ while (y--) {
+ x = YUVwidth;
+#ifdef __SSE2__
+ if (use_SSE2) {
+ PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 1, 0, 3));
+ }
+#endif
+ while (x--) {
+ Uint8 Y1, U, Y2, V;
+
+ Y1 = srcYUV[0];
+ V = srcYUV[1];
+ Y2 = srcYUV[2];
+ U = srcYUV[3];
+ srcYUV += 4;
+
+ dstYUV[0] = U;
+ dstYUV[1] = Y1;
+ dstYUV[2] = V;
+ dstYUV[3] = Y2;
+ dstYUV += 4;
+ }
+ srcYUV += srcYUVPitchLeft;
+ dstYUV += dstYUVPitchLeft;
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_Packed4_to_Packed4(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+ switch (src_format) {
+ case SDL_PIXELFORMAT_YUY2:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_UYVY:
+ return SDL_ConvertPixels_YUY2_to_UYVY(width, height, src, src_pitch, dst, dst_pitch);
+ case SDL_PIXELFORMAT_YVYU:
+ return SDL_ConvertPixels_YUY2_to_YVYU(width, height, src, src_pitch, dst, dst_pitch);
+ default:
+ break;
+ }
+ break;
+ case SDL_PIXELFORMAT_UYVY:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_YUY2:
+ return SDL_ConvertPixels_UYVY_to_YUY2(width, height, src, src_pitch, dst, dst_pitch);
+ case SDL_PIXELFORMAT_YVYU:
+ return SDL_ConvertPixels_UYVY_to_YVYU(width, height, src, src_pitch, dst, dst_pitch);
+ default:
+ break;
+ }
+ break;
+ case SDL_PIXELFORMAT_YVYU:
+ switch (dst_format) {
+ case SDL_PIXELFORMAT_YUY2:
+ return SDL_ConvertPixels_YVYU_to_YUY2(width, height, src, src_pitch, dst, dst_pitch);
+ case SDL_PIXELFORMAT_UYVY:
+ return SDL_ConvertPixels_YVYU_to_UYVY(width, height, src, src_pitch, dst, dst_pitch);
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return SDL_SetError("SDL_ConvertPixels_Packed4_to_Packed4: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
+}
+
+static int
+SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+ int x, y;
+ const Uint8 *srcY1, *srcY2, *srcU, *srcV;
+ Uint32 srcY_pitch, srcUV_pitch;
+ Uint32 srcY_pitch_left, srcUV_pitch_left, srcUV_pixel_stride;
+ Uint8 *dstY1, *dstY2, *dstU1, *dstU2, *dstV1, *dstV2;
+ Uint32 dstY_pitch, dstUV_pitch;
+ Uint32 dst_pitch_left;
+
+ if (src == dst) {
+ return SDL_SetError("Can't change YUV plane types in-place");
+ }
+
+ if (GetYUVPlanes(width, height, src_format, src, src_pitch,
+ &srcY1, &srcU, &srcV, &srcY_pitch, &srcUV_pitch) < 0) {
+ return -1;
+ }
+ srcY2 = srcY1 + srcY_pitch;
+ srcY_pitch_left = (srcY_pitch - width);
+
+ if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) {
+ srcUV_pixel_stride = 2;
+ srcUV_pitch_left = (srcUV_pitch - 2*((width + 1)/2));
+ } else {
+ srcUV_pixel_stride = 1;
+ srcUV_pitch_left = (srcUV_pitch - ((width + 1)/2));
+ }
+
+ if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
+ (const Uint8 **)&dstY1, (const Uint8 **)&dstU1, (const Uint8 **)&dstV1,
+ &dstY_pitch, &dstUV_pitch) < 0) {
+ return -1;
+ }
+ dstY2 = dstY1 + dstY_pitch;
+ dstU2 = dstU1 + dstUV_pitch;
+ dstV2 = dstV1 + dstUV_pitch;
+ dst_pitch_left = (dstY_pitch - 4*((width + 1)/2));
+
+ /* Copy 2x2 blocks of pixels at a time */
+ for (y = 0; y < (height - 1); y += 2) {
+ for (x = 0; x < (width - 1); x += 2) {
+ /* Row 1 */
+ *dstY1 = *srcY1++;
+ dstY1 += 2;
+ *dstY1 = *srcY1++;
+ dstY1 += 2;
+ *dstU1 = *srcU;
+ *dstV1 = *srcV;
+
+ /* Row 2 */
+ *dstY2 = *srcY2++;
+ dstY2 += 2;
+ *dstY2 = *srcY2++;
+ dstY2 += 2;
+ *dstU2 = *srcU;
+ *dstV2 = *srcV;
+
+ srcU += srcUV_pixel_stride;
+ srcV += srcUV_pixel_stride;
+ dstU1 += 4;
+ dstU2 += 4;
+ dstV1 += 4;
+ dstV2 += 4;
+ }
+
+ /* Last column */
+ if (x == (width - 1)) {
+ /* Row 1 */
+ *dstY1 = *srcY1;
+ dstY1 += 2;
+ *dstY1 = *srcY1++;
+ dstY1 += 2;
+ *dstU1 = *srcU;
+ *dstV1 = *srcV;
+
+ /* Row 2 */
+ *dstY2 = *srcY2;
+ dstY2 += 2;
+ *dstY2 = *srcY2++;
+ dstY2 += 2;
+ *dstU2 = *srcU;
+ *dstV2 = *srcV;
+
+ srcU += srcUV_pixel_stride;
+ srcV += srcUV_pixel_stride;
+ dstU1 += 4;
+ dstU2 += 4;
+ dstV1 += 4;
+ dstV2 += 4;
+ }
+
+ srcY1 += srcY_pitch_left + srcY_pitch;
+ srcY2 += srcY_pitch_left + srcY_pitch;
+ srcU += srcUV_pitch_left;
+ srcV += srcUV_pitch_left;
+ dstY1 += dst_pitch_left + dstY_pitch;
+ dstY2 += dst_pitch_left + dstY_pitch;
+ dstU1 += dst_pitch_left + dstUV_pitch;
+ dstU2 += dst_pitch_left + dstUV_pitch;
+ dstV1 += dst_pitch_left + dstUV_pitch;
+ dstV2 += dst_pitch_left + dstUV_pitch;
+ }
+
+ /* Last row */
+ if (y == (height - 1)) {
+ for (x = 0; x < (width - 1); x += 2) {
+ /* Row 1 */
+ *dstY1 = *srcY1++;
+ dstY1 += 2;
+ *dstY1 = *srcY1++;
+ dstY1 += 2;
+ *dstU1 = *srcU;
+ *dstV1 = *srcV;
+
+ srcU += srcUV_pixel_stride;
+ srcV += srcUV_pixel_stride;
+ dstU1 += 4;
+ dstV1 += 4;
+ }
+
+ /* Last column */
+ if (x == (width - 1)) {
+ /* Row 1 */
+ *dstY1 = *srcY1;
+ dstY1 += 2;
+ *dstY1 = *srcY1++;
+ dstY1 += 2;
+ *dstU1 = *srcU;
+ *dstV1 = *srcV;
+
+ srcU += srcUV_pixel_stride;
+ srcV += srcUV_pixel_stride;
+ dstU1 += 4;
+ dstV1 += 4;
+ }
+ }
+ return 0;
+}
+
+static int
+SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+ int x, y;
+ const Uint8 *srcY1, *srcY2, *srcU1, *srcU2, *srcV1, *srcV2;
+ Uint32 srcY_pitch, srcUV_pitch;
+ Uint32 src_pitch_left;
+ Uint8 *dstY1, *dstY2, *dstU, *dstV;
+ Uint32 dstY_pitch, dstUV_pitch;
+ Uint32 dstY_pitch_left, dstUV_pitch_left, dstUV_pixel_stride;
+
+ if (src == dst) {
+ return SDL_SetError("Can't change YUV plane types in-place");
+ }
+
+ if (GetYUVPlanes(width, height, src_format, src, src_pitch,
+ &srcY1, &srcU1, &srcV1, &srcY_pitch, &srcUV_pitch) < 0) {
+ return -1;
+ }
+ srcY2 = srcY1 + srcY_pitch;
+ srcU2 = srcU1 + srcUV_pitch;
+ srcV2 = srcV1 + srcUV_pitch;
+ src_pitch_left = (srcY_pitch - 4*((width + 1)/2));
+
+ if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
+ (const Uint8 **)&dstY1, (const Uint8 **)&dstU, (const Uint8 **)&dstV,
+ &dstY_pitch, &dstUV_pitch) < 0) {
+ return -1;
+ }
+ dstY2 = dstY1 + dstY_pitch;
+ dstY_pitch_left = (dstY_pitch - width);
+
+ if (dst_format == SDL_PIXELFORMAT_NV12 || dst_format == SDL_PIXELFORMAT_NV21) {
+ dstUV_pixel_stride = 2;
+ dstUV_pitch_left = (dstUV_pitch - 2*((width + 1)/2));
+ } else {
+ dstUV_pixel_stride = 1;
+ dstUV_pitch_left = (dstUV_pitch - ((width + 1)/2));
+ }
+
+ /* Copy 2x2 blocks of pixels at a time */
+ for (y = 0; y < (height - 1); y += 2) {
+ for (x = 0; x < (width - 1); x += 2) {
+ /* Row 1 */
+ *dstY1++ = *srcY1;
+ srcY1 += 2;
+ *dstY1++ = *srcY1;
+ srcY1 += 2;
+
+ /* Row 2 */
+ *dstY2++ = *srcY2;
+ srcY2 += 2;
+ *dstY2++ = *srcY2;
+ srcY2 += 2;
+
+ *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2);
+ *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2);
+
+ srcU1 += 4;
+ srcU2 += 4;
+ srcV1 += 4;
+ srcV2 += 4;
+ dstU += dstUV_pixel_stride;
+ dstV += dstUV_pixel_stride;
+ }
+
+ /* Last column */
+ if (x == (width - 1)) {
+ /* Row 1 */
+ *dstY1 = *srcY1;
+ srcY1 += 2;
+ *dstY1++ = *srcY1;
+ srcY1 += 2;
+
+ /* Row 2 */
+ *dstY2 = *srcY2;
+ srcY2 += 2;
+ *dstY2++ = *srcY2;
+ srcY2 += 2;
+
+ *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2);
+ *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2);
+
+ srcU1 += 4;
+ srcU2 += 4;
+ srcV1 += 4;
+ srcV2 += 4;
+ dstU += dstUV_pixel_stride;
+ dstV += dstUV_pixel_stride;
+ }
+
+ srcY1 += src_pitch_left + srcY_pitch;
+ srcY2 += src_pitch_left + srcY_pitch;
+ srcU1 += src_pitch_left + srcUV_pitch;
+ srcU2 += src_pitch_left + srcUV_pitch;
+ srcV1 += src_pitch_left + srcUV_pitch;
+ srcV2 += src_pitch_left + srcUV_pitch;
+ dstY1 += dstY_pitch_left + dstY_pitch;
+ dstY2 += dstY_pitch_left + dstY_pitch;
+ dstU += dstUV_pitch_left;
+ dstV += dstUV_pitch_left;
+ }
+
+ /* Last row */
+ if (y == (height - 1)) {
+ for (x = 0; x < (width - 1); x += 2) {
+ *dstY1++ = *srcY1;
+ srcY1 += 2;
+ *dstY1++ = *srcY1;
+ srcY1 += 2;
+
+ *dstU = *srcU1;
+ *dstV = *srcV1;
+
+ srcU1 += 4;
+ srcV1 += 4;
+ dstU += dstUV_pixel_stride;
+ dstV += dstUV_pixel_stride;
+ }
+
+ /* Last column */
+ if (x == (width - 1)) {
+ *dstY1 = *srcY1;
+ *dstU = *srcU1;
+ *dstV = *srcV1;
+ }
+ }
+ return 0;
+}
+
+int
+SDL_ConvertPixels_YUV_to_YUV(int width, int height,
+ Uint32 src_format, const void *src, int src_pitch,
+ Uint32 dst_format, void *dst, int dst_pitch)
+{
+ if (src_format == dst_format) {
+ if (src == dst) {
+ /* Nothing to do */
+ return 0;
+ }
+ return SDL_ConvertPixels_YUV_to_YUV_Copy(width, height, src_format, src, src_pitch, dst, dst_pitch);
+ }
+
+ if (IsPlanar2x2Format(src_format) && IsPlanar2x2Format(dst_format)) {
+ return SDL_ConvertPixels_Planar2x2_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ } else if (IsPacked4Format(src_format) && IsPacked4Format(dst_format)) {
+ return SDL_ConvertPixels_Packed4_to_Packed4(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ } else if (IsPlanar2x2Format(src_format) && IsPacked4Format(dst_format)) {
+ return SDL_ConvertPixels_Planar2x2_to_Packed4(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ } else if (IsPacked4Format(src_format) && IsPlanar2x2Format(dst_format)) {
+ return SDL_ConvertPixels_Packed4_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
+ } else {
+ return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/SDL_yuv_c.h b/source/3rd-party/SDL2/src/video/SDL_yuv_c.h
new file mode 100644
index 0000000..192bd2c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/SDL_yuv_c.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_yuv_c_h_
+#define SDL_yuv_c_h_
+
+#include "../SDL_internal.h"
+
+
+/* YUV conversion functions */
+
+extern int SDL_ConvertPixels_YUV_to_RGB(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch);
+extern int SDL_ConvertPixels_RGB_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch);
+extern int SDL_ConvertPixels_YUV_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch);
+
+#endif /* SDL_yuv_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.c b/source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.c
new file mode 100644
index 0000000..c913af5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.c
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidclipboard.h"
+#include "../../core/android/SDL_android.h"
+
+int
+Android_SetClipboardText(_THIS, const char *text)
+{
+ return Android_JNI_SetClipboardText(text);
+}
+
+char *
+Android_GetClipboardText(_THIS)
+{
+ return Android_JNI_GetClipboardText();
+}
+
+SDL_bool Android_HasClipboardText(_THIS)
+{
+ return Android_JNI_HasClipboardText();
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.h b/source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.h
new file mode 100644
index 0000000..7f48b0e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidclipboard.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_androidclipboard_h_
+#define SDL_androidclipboard_h_
+
+extern int Android_SetClipboardText(_THIS, const char *text);
+extern char *Android_GetClipboardText(_THIS);
+extern SDL_bool Android_HasClipboardText(_THIS);
+
+#endif /* SDL_androidclipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidevents.c b/source/3rd-party/SDL2/src/video/android/SDL_androidevents.c
new file mode 100644
index 0000000..6cf9af2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidevents.c
@@ -0,0 +1,123 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+/* We're going to do this by default */
+#define SDL_ANDROID_BLOCK_ON_PAUSE 1
+
+#include "SDL_androidevents.h"
+#include "SDL_events.h"
+#include "SDL_androidwindow.h"
+
+#if !SDL_AUDIO_DISABLED
+/* Can't include sysaudio "../../audio/android/SDL_androidaudio.h"
+ * because of THIS redefinition */
+extern void ANDROIDAUDIO_ResumeDevices(void);
+extern void ANDROIDAUDIO_PauseDevices(void);
+#else
+static void ANDROIDAUDIO_ResumeDevices(void) {}
+static void ANDROIDAUDIO_PauseDevices(void) {}
+#endif
+
+static void
+android_egl_context_restore()
+{
+ SDL_Event event;
+ SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata;
+ if (SDL_GL_MakeCurrent(Android_Window, (SDL_GLContext) data->egl_context) < 0) {
+ /* The context is no longer valid, create a new one */
+ data->egl_context = (EGLContext) SDL_GL_CreateContext(Android_Window);
+ SDL_GL_MakeCurrent(Android_Window, (SDL_GLContext) data->egl_context);
+ event.type = SDL_RENDER_DEVICE_RESET;
+ SDL_PushEvent(&event);
+ }
+}
+
+static void
+android_egl_context_backup()
+{
+ /* Keep a copy of the EGL Context so we can try to restore it when we resume */
+ SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata;
+ data->egl_context = SDL_GL_GetCurrentContext();
+ /* We need to do this so the EGLSurface can be freed */
+ SDL_GL_MakeCurrent(Android_Window, NULL);
+}
+
+void
+Android_PumpEvents(_THIS)
+{
+ static int isPaused = 0;
+#if SDL_ANDROID_BLOCK_ON_PAUSE
+ static int isPausing = 0;
+#endif
+ /* No polling necessary */
+
+ /*
+ * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
+ * When the pause semaphore is signaled, if SDL_ANDROID_BLOCK_ON_PAUSE is defined the event loop will block until the resume signal is emitted.
+ */
+
+#if SDL_ANDROID_BLOCK_ON_PAUSE
+ if (isPaused && !isPausing) {
+ /* Make sure this is the last thing we do before pausing */
+ android_egl_context_backup();
+ ANDROIDAUDIO_PauseDevices();
+ if(SDL_SemWait(Android_ResumeSem) == 0) {
+#else
+ if (isPaused) {
+ if(SDL_SemTryWait(Android_ResumeSem) == 0) {
+#endif
+ isPaused = 0;
+ ANDROIDAUDIO_ResumeDevices();
+ /* Restore the GL Context from here, as this operation is thread dependent */
+ if (!SDL_HasEvent(SDL_QUIT)) {
+ android_egl_context_restore();
+ }
+ }
+ }
+ else {
+#if SDL_ANDROID_BLOCK_ON_PAUSE
+ if( isPausing || SDL_SemTryWait(Android_PauseSem) == 0 ) {
+ /* We've been signaled to pause, but before we block ourselves,
+ we need to make sure that certain key events have reached the app */
+ if (SDL_HasEvent(SDL_WINDOWEVENT) || SDL_HasEvent(SDL_APP_WILLENTERBACKGROUND) || SDL_HasEvent(SDL_APP_DIDENTERBACKGROUND) ) {
+ isPausing = 1;
+ }
+ else {
+ isPausing = 0;
+ isPaused = 1;
+ }
+ }
+#else
+ if(SDL_SemTryWait(Android_PauseSem) == 0) {
+ android_egl_context_backup();
+ ANDROIDAUDIO_PauseDevices();
+ isPaused = 1;
+ }
+#endif
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidevents.h b/source/3rd-party/SDL2/src/video/android/SDL_androidevents.h
new file mode 100644
index 0000000..00e7427
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidevents.h
@@ -0,0 +1,27 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include "SDL_androidvideo.h"
+
+extern void Android_PumpEvents(_THIS);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidgl.c b/source/3rd-party/SDL2/src/video/android/SDL_androidgl.c
new file mode 100644
index 0000000..859b46e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidgl.c
@@ -0,0 +1,62 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+/* Android SDL video driver implementation */
+
+#include "SDL_video.h"
+#include "../SDL_egl_c.h"
+#include "SDL_androidwindow.h"
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidgl.h"
+#include "../../core/android/SDL_android.h"
+
+#include <android/log.h>
+
+#include <dlfcn.h>
+
+SDL_EGL_CreateContext_impl(Android)
+SDL_EGL_MakeCurrent_impl(Android)
+
+int
+Android_GLES_SwapWindow(_THIS, SDL_Window * window)
+{
+ /* The following two calls existed in the original Java code
+ * If you happen to have a device that's affected by their removal,
+ * please report to Bugzilla. -- Gabriel
+ */
+
+ /*_this->egl_data->eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+ _this->egl_data->eglWaitGL();*/
+ return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+}
+
+int
+Android_GLES_LoadLibrary(_THIS, const char *path) {
+ return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0);
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidgl.h b/source/3rd-party/SDL2/src/video/android/SDL_androidgl.h
new file mode 100644
index 0000000..1dab5a6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidgl.h
@@ -0,0 +1,34 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_androidgl_h_
+#define SDL_androidgl_h_
+
+SDL_GLContext Android_GLES_CreateContext(_THIS, SDL_Window * window);
+int Android_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int Android_GLES_SwapWindow(_THIS, SDL_Window * window);
+int Android_GLES_LoadLibrary(_THIS, const char *path);
+
+
+#endif /* SDL_androidgl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.c b/source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.c
new file mode 100644
index 0000000..6c94cac
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.c
@@ -0,0 +1,391 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+#include <android/log.h>
+
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_androidkeyboard.h"
+
+#include "../../core/android/SDL_android.h"
+
+void Android_InitKeyboard(void)
+{
+ SDL_Keycode keymap[SDL_NUM_SCANCODES];
+
+ /* Add default scancode to key mapping */
+ SDL_GetDefaultKeymap(keymap);
+ SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
+}
+
+static SDL_Scancode Android_Keycodes[] = {
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_UNKNOWN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_LEFT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_RIGHT */
+ SDL_SCANCODE_AC_HOME, /* AKEYCODE_HOME */
+ SDL_SCANCODE_AC_BACK, /* AKEYCODE_BACK */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALL */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ENDCALL */
+ SDL_SCANCODE_0, /* AKEYCODE_0 */
+ SDL_SCANCODE_1, /* AKEYCODE_1 */
+ SDL_SCANCODE_2, /* AKEYCODE_2 */
+ SDL_SCANCODE_3, /* AKEYCODE_3 */
+ SDL_SCANCODE_4, /* AKEYCODE_4 */
+ SDL_SCANCODE_5, /* AKEYCODE_5 */
+ SDL_SCANCODE_6, /* AKEYCODE_6 */
+ SDL_SCANCODE_7, /* AKEYCODE_7 */
+ SDL_SCANCODE_8, /* AKEYCODE_8 */
+ SDL_SCANCODE_9, /* AKEYCODE_9 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STAR */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_POUND */
+ SDL_SCANCODE_UP, /* AKEYCODE_DPAD_UP */
+ SDL_SCANCODE_DOWN, /* AKEYCODE_DPAD_DOWN */
+ SDL_SCANCODE_LEFT, /* AKEYCODE_DPAD_LEFT */
+ SDL_SCANCODE_RIGHT, /* AKEYCODE_DPAD_RIGHT */
+ SDL_SCANCODE_SELECT, /* AKEYCODE_DPAD_CENTER */
+ SDL_SCANCODE_VOLUMEUP, /* AKEYCODE_VOLUME_UP */
+ SDL_SCANCODE_VOLUMEDOWN, /* AKEYCODE_VOLUME_DOWN */
+ SDL_SCANCODE_POWER, /* AKEYCODE_POWER */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAMERA */
+ SDL_SCANCODE_CLEAR, /* AKEYCODE_CLEAR */
+ SDL_SCANCODE_A, /* AKEYCODE_A */
+ SDL_SCANCODE_B, /* AKEYCODE_B */
+ SDL_SCANCODE_C, /* AKEYCODE_C */
+ SDL_SCANCODE_D, /* AKEYCODE_D */
+ SDL_SCANCODE_E, /* AKEYCODE_E */
+ SDL_SCANCODE_F, /* AKEYCODE_F */
+ SDL_SCANCODE_G, /* AKEYCODE_G */
+ SDL_SCANCODE_H, /* AKEYCODE_H */
+ SDL_SCANCODE_I, /* AKEYCODE_I */
+ SDL_SCANCODE_J, /* AKEYCODE_J */
+ SDL_SCANCODE_K, /* AKEYCODE_K */
+ SDL_SCANCODE_L, /* AKEYCODE_L */
+ SDL_SCANCODE_M, /* AKEYCODE_M */
+ SDL_SCANCODE_N, /* AKEYCODE_N */
+ SDL_SCANCODE_O, /* AKEYCODE_O */
+ SDL_SCANCODE_P, /* AKEYCODE_P */
+ SDL_SCANCODE_Q, /* AKEYCODE_Q */
+ SDL_SCANCODE_R, /* AKEYCODE_R */
+ SDL_SCANCODE_S, /* AKEYCODE_S */
+ SDL_SCANCODE_T, /* AKEYCODE_T */
+ SDL_SCANCODE_U, /* AKEYCODE_U */
+ SDL_SCANCODE_V, /* AKEYCODE_V */
+ SDL_SCANCODE_W, /* AKEYCODE_W */
+ SDL_SCANCODE_X, /* AKEYCODE_X */
+ SDL_SCANCODE_Y, /* AKEYCODE_Y */
+ SDL_SCANCODE_Z, /* AKEYCODE_Z */
+ SDL_SCANCODE_COMMA, /* AKEYCODE_COMMA */
+ SDL_SCANCODE_PERIOD, /* AKEYCODE_PERIOD */
+ SDL_SCANCODE_LALT, /* AKEYCODE_ALT_LEFT */
+ SDL_SCANCODE_RALT, /* AKEYCODE_ALT_RIGHT */
+ SDL_SCANCODE_LSHIFT, /* AKEYCODE_SHIFT_LEFT */
+ SDL_SCANCODE_RSHIFT, /* AKEYCODE_SHIFT_RIGHT */
+ SDL_SCANCODE_TAB, /* AKEYCODE_TAB */
+ SDL_SCANCODE_SPACE, /* AKEYCODE_SPACE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SYM */
+ SDL_SCANCODE_WWW, /* AKEYCODE_EXPLORER */
+ SDL_SCANCODE_MAIL, /* AKEYCODE_ENVELOPE */
+ SDL_SCANCODE_RETURN, /* AKEYCODE_ENTER */
+ SDL_SCANCODE_BACKSPACE, /* AKEYCODE_DEL */
+ SDL_SCANCODE_GRAVE, /* AKEYCODE_GRAVE */
+ SDL_SCANCODE_MINUS, /* AKEYCODE_MINUS */
+ SDL_SCANCODE_EQUALS, /* AKEYCODE_EQUALS */
+ SDL_SCANCODE_LEFTBRACKET, /* AKEYCODE_LEFT_BRACKET */
+ SDL_SCANCODE_RIGHTBRACKET, /* AKEYCODE_RIGHT_BRACKET */
+ SDL_SCANCODE_BACKSLASH, /* AKEYCODE_BACKSLASH */
+ SDL_SCANCODE_SEMICOLON, /* AKEYCODE_SEMICOLON */
+ SDL_SCANCODE_APOSTROPHE, /* AKEYCODE_APOSTROPHE */
+ SDL_SCANCODE_SLASH, /* AKEYCODE_SLASH */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HEADSETHOOK */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FOCUS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PLUS */
+ SDL_SCANCODE_MENU, /* AKEYCODE_MENU */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NOTIFICATION */
+ SDL_SCANCODE_AC_SEARCH, /* AKEYCODE_SEARCH */
+ SDL_SCANCODE_AUDIOPLAY, /* AKEYCODE_MEDIA_PLAY_PAUSE */
+ SDL_SCANCODE_AUDIOSTOP, /* AKEYCODE_MEDIA_STOP */
+ SDL_SCANCODE_AUDIONEXT, /* AKEYCODE_MEDIA_NEXT */
+ SDL_SCANCODE_AUDIOPREV, /* AKEYCODE_MEDIA_PREVIOUS */
+ SDL_SCANCODE_AUDIOREWIND, /* AKEYCODE_MEDIA_REWIND */
+ SDL_SCANCODE_AUDIOFASTFORWARD, /* AKEYCODE_MEDIA_FAST_FORWARD */
+ SDL_SCANCODE_MUTE, /* AKEYCODE_MUTE */
+ SDL_SCANCODE_PAGEUP, /* AKEYCODE_PAGE_UP */
+ SDL_SCANCODE_PAGEDOWN, /* AKEYCODE_PAGE_DOWN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PICTSYMBOLS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SWITCH_CHARSET */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_A */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_B */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_C */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_X */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Y */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Z */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBL */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBR */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_START */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_SELECT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_MODE */
+ SDL_SCANCODE_ESCAPE, /* AKEYCODE_ESCAPE */
+ SDL_SCANCODE_DELETE, /* AKEYCODE_FORWARD_DEL */
+ SDL_SCANCODE_LCTRL, /* AKEYCODE_CTRL_LEFT */
+ SDL_SCANCODE_RCTRL, /* AKEYCODE_CTRL_RIGHT */
+ SDL_SCANCODE_CAPSLOCK, /* AKEYCODE_CAPS_LOCK */
+ SDL_SCANCODE_SCROLLLOCK, /* AKEYCODE_SCROLL_LOCK */
+ SDL_SCANCODE_LGUI, /* AKEYCODE_META_LEFT */
+ SDL_SCANCODE_RGUI, /* AKEYCODE_META_RIGHT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FUNCTION */
+ SDL_SCANCODE_PRINTSCREEN, /* AKEYCODE_SYSRQ */
+ SDL_SCANCODE_PAUSE, /* AKEYCODE_BREAK */
+ SDL_SCANCODE_HOME, /* AKEYCODE_MOVE_HOME */
+ SDL_SCANCODE_END, /* AKEYCODE_MOVE_END */
+ SDL_SCANCODE_INSERT, /* AKEYCODE_INSERT */
+ SDL_SCANCODE_AC_FORWARD, /* AKEYCODE_FORWARD */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PLAY */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PAUSE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_CLOSE */
+ SDL_SCANCODE_EJECT, /* AKEYCODE_MEDIA_EJECT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_RECORD */
+ SDL_SCANCODE_F1, /* AKEYCODE_F1 */
+ SDL_SCANCODE_F2, /* AKEYCODE_F2 */
+ SDL_SCANCODE_F3, /* AKEYCODE_F3 */
+ SDL_SCANCODE_F4, /* AKEYCODE_F4 */
+ SDL_SCANCODE_F5, /* AKEYCODE_F5 */
+ SDL_SCANCODE_F6, /* AKEYCODE_F6 */
+ SDL_SCANCODE_F7, /* AKEYCODE_F7 */
+ SDL_SCANCODE_F8, /* AKEYCODE_F8 */
+ SDL_SCANCODE_F9, /* AKEYCODE_F9 */
+ SDL_SCANCODE_F10, /* AKEYCODE_F10 */
+ SDL_SCANCODE_F11, /* AKEYCODE_F11 */
+ SDL_SCANCODE_F12, /* AKEYCODE_F12 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM_LOCK */
+ SDL_SCANCODE_KP_0, /* AKEYCODE_NUMPAD_0 */
+ SDL_SCANCODE_KP_1, /* AKEYCODE_NUMPAD_1 */
+ SDL_SCANCODE_KP_2, /* AKEYCODE_NUMPAD_2 */
+ SDL_SCANCODE_KP_3, /* AKEYCODE_NUMPAD_3 */
+ SDL_SCANCODE_KP_4, /* AKEYCODE_NUMPAD_4 */
+ SDL_SCANCODE_KP_5, /* AKEYCODE_NUMPAD_5 */
+ SDL_SCANCODE_KP_6, /* AKEYCODE_NUMPAD_6 */
+ SDL_SCANCODE_KP_7, /* AKEYCODE_NUMPAD_7 */
+ SDL_SCANCODE_KP_8, /* AKEYCODE_NUMPAD_8 */
+ SDL_SCANCODE_KP_9, /* AKEYCODE_NUMPAD_9 */
+ SDL_SCANCODE_KP_DIVIDE, /* AKEYCODE_NUMPAD_DIVIDE */
+ SDL_SCANCODE_KP_MULTIPLY, /* AKEYCODE_NUMPAD_MULTIPLY */
+ SDL_SCANCODE_KP_MINUS, /* AKEYCODE_NUMPAD_SUBTRACT */
+ SDL_SCANCODE_KP_PLUS, /* AKEYCODE_NUMPAD_ADD */
+ SDL_SCANCODE_KP_PERIOD, /* AKEYCODE_NUMPAD_DOT */
+ SDL_SCANCODE_KP_COMMA, /* AKEYCODE_NUMPAD_COMMA */
+ SDL_SCANCODE_KP_ENTER, /* AKEYCODE_NUMPAD_ENTER */
+ SDL_SCANCODE_KP_EQUALS, /* AKEYCODE_NUMPAD_EQUALS */
+ SDL_SCANCODE_KP_LEFTPAREN, /* AKEYCODE_NUMPAD_LEFT_PAREN */
+ SDL_SCANCODE_KP_RIGHTPAREN, /* AKEYCODE_NUMPAD_RIGHT_PAREN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOLUME_MUTE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_INFO */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_UP */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_DOWN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_IN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_OUT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WINDOW */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_GUIDE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DVR */
+ SDL_SCANCODE_AC_BOOKMARKS, /* AKEYCODE_BOOKMARK */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAPTIONS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SETTINGS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_POWER */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_POWER */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_INPUT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_POWER */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_INPUT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_RED */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_GREEN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_YELLOW */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_BLUE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_APP_SWITCH */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_3 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_4 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_5 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_6 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_7 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_8 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_9 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_10 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_11 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_12 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_13 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_14 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_15 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_16 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LANGUAGE_SWITCH */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MANNER_MODE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_3D_MODE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CONTACTS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALENDAR */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUSIC */
+ SDL_SCANCODE_CALCULATOR, /* AKEYCODE_CALCULATOR */
+ SDL_SCANCODE_LANG5, /* AKEYCODE_ZENKAKU_HANKAKU */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EISU */
+ SDL_SCANCODE_INTERNATIONAL5, /* AKEYCODE_MUHENKAN */
+ SDL_SCANCODE_INTERNATIONAL4, /* AKEYCODE_HENKAN */
+ SDL_SCANCODE_LANG3, /* AKEYCODE_KATAKANA_HIRAGANA */
+ SDL_SCANCODE_INTERNATIONAL3, /* AKEYCODE_YEN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_RO */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_KANA */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ASSIST */
+ SDL_SCANCODE_BRIGHTNESSDOWN, /* AKEYCODE_BRIGHTNESS_DOWN */
+ SDL_SCANCODE_BRIGHTNESSUP, /* AKEYCODE_BRIGHTNESS_UP */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_AUDIO_TRACK */
+ SDL_SCANCODE_SLEEP, /* AKEYCODE_SLEEP */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WAKEUP */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PAIRING */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_TOP_MENU */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_11 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_12 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LAST_CHANNEL */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_DATA_SERVICE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOICE_ASSIST */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_RADIO_SERVICE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TELETEXT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_NUMBER_ENTRY */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TERRESTRIAL_ANALOG */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TERRESTRIAL_DIGITAL */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_BS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_CS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_SERVICE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_NETWORK */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_ANTENNA_CABLE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_3 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_4 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPOSITE_1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPOSITE_2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPONENT_1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPONENT_2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_VGA_1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_ZOOM_MODE */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_CONTENTS_MENU */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_MEDIA_CONTEXT_MENU */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TIMER_PROGRAMMING */
+ SDL_SCANCODE_HELP, /* AKEYCODE_HELP */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_PREVIOUS */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_NEXT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_IN */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_OUT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_PRIMARY */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_1 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_2 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_3 */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_LEFT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_LEFT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_RIGHT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_RIGHT */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_FORWARD */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_BACKWARD */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_FORWARD */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_BACKWARD */
+ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_SLEEP */
+ SDL_SCANCODE_CUT, /* AKEYCODE_CUT */
+ SDL_SCANCODE_COPY, /* AKEYCODE_COPY */
+ SDL_SCANCODE_PASTE, /* AKEYCODE_PASTE */
+};
+
+static SDL_Scancode
+TranslateKeycode(int keycode)
+{
+ SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
+
+ if (keycode < SDL_arraysize(Android_Keycodes)) {
+ scancode = Android_Keycodes[keycode];
+ }
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode);
+ }
+ return scancode;
+}
+
+int
+Android_OnKeyDown(int keycode)
+{
+ return SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode(keycode));
+}
+
+int
+Android_OnKeyUp(int keycode)
+{
+ return SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode(keycode));
+}
+
+SDL_bool
+Android_HasScreenKeyboardSupport(_THIS)
+{
+ return SDL_TRUE;
+}
+
+SDL_bool
+Android_IsScreenKeyboardShown(_THIS, SDL_Window * window)
+{
+ return Android_JNI_IsScreenKeyboardShown();
+}
+
+void
+Android_StartTextInput(_THIS)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ Android_JNI_ShowTextInput(&videodata->textRect);
+}
+
+void
+Android_StopTextInput(_THIS)
+{
+ Android_JNI_HideTextInput();
+}
+
+void
+Android_SetTextInputRect(_THIS, SDL_Rect *rect)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return;
+ }
+
+ videodata->textRect = *rect;
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.h b/source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.h
new file mode 100644
index 0000000..a1a10f5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidkeyboard.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include "SDL_androidvideo.h"
+
+extern void Android_InitKeyboard(void);
+extern int Android_OnKeyDown(int keycode);
+extern int Android_OnKeyUp(int keycode);
+
+extern SDL_bool Android_HasScreenKeyboardSupport(_THIS);
+extern SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window * window);
+
+extern void Android_StartTextInput(_THIS);
+extern void Android_StopTextInput(_THIS);
+extern void Android_SetTextInputRect(_THIS, SDL_Rect *rect);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.c b/source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.c
new file mode 100644
index 0000000..1716024
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.c
@@ -0,0 +1,37 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+#include "SDL_messagebox.h"
+#include "SDL_androidmessagebox.h"
+#include "../../core/android/SDL_android.h"
+
+int
+Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ return Android_JNI_ShowMessageBox(messageboxdata, buttonid);
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.h b/source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.h
new file mode 100644
index 0000000..2c3a44f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidmessagebox.h
@@ -0,0 +1,29 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+extern int Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidmouse.c b/source/3rd-party/SDL2/src/video/android/SDL_androidmouse.c
new file mode 100644
index 0000000..037b453
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidmouse.c
@@ -0,0 +1,266 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+#include "SDL_androidmouse.h"
+
+#include "SDL_events.h"
+#include "../../events/SDL_mouse_c.h"
+
+#include "../../core/android/SDL_android.h"
+
+/* See Android's MotionEvent class for constants */
+#define ACTION_DOWN 0
+#define ACTION_UP 1
+#define ACTION_MOVE 2
+#define ACTION_HOVER_MOVE 7
+#define ACTION_SCROLL 8
+#define BUTTON_PRIMARY 1
+#define BUTTON_SECONDARY 2
+#define BUTTON_TERTIARY 4
+#define BUTTON_BACK 8
+#define BUTTON_FORWARD 16
+
+typedef struct
+{
+ int custom_cursor;
+ int system_cursor;
+
+} SDL_AndroidCursorData;
+
+/* Last known Android mouse button state (includes all buttons) */
+static int last_state;
+
+/* Blank cursor */
+static SDL_Cursor *empty_cursor;
+
+static SDL_Cursor *
+Android_WrapCursor(int custom_cursor, int system_cursor)
+{
+ SDL_Cursor *cursor;
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ SDL_AndroidCursorData *data = (SDL_AndroidCursorData*)SDL_calloc(1, sizeof(*data));
+ if (data) {
+ data->custom_cursor = custom_cursor;
+ data->system_cursor = system_cursor;
+ cursor->driverdata = data;
+ } else {
+ SDL_free(cursor);
+ cursor = NULL;
+ SDL_OutOfMemory();
+ }
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+Android_CreateDefaultCursor()
+{
+ return Android_WrapCursor(0, SDL_SYSTEM_CURSOR_ARROW);
+}
+
+static SDL_Cursor *
+Android_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ int custom_cursor;
+ SDL_Surface *converted;
+
+ converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
+ if (!converted) {
+ return NULL;
+ }
+ custom_cursor = Android_JNI_CreateCustomCursor(converted, hot_x, hot_y);
+ SDL_FreeSurface(converted);
+ if (!custom_cursor) {
+ SDL_Unsupported();
+ return NULL;
+ }
+ return Android_WrapCursor(custom_cursor, 0);
+}
+
+static SDL_Cursor *
+Android_CreateSystemCursor(SDL_SystemCursor id)
+{
+ return Android_WrapCursor(0, id);
+}
+
+static void
+Android_FreeCursor(SDL_Cursor * cursor)
+{
+ SDL_free(cursor->driverdata);
+ SDL_free(cursor);
+}
+
+static SDL_Cursor *
+Android_CreateEmptyCursor()
+{
+ if (!empty_cursor) {
+ SDL_Surface *empty_surface = SDL_CreateRGBSurfaceWithFormat(0, 1, 1, 32, SDL_PIXELFORMAT_ARGB8888);
+ if (empty_surface) {
+ SDL_memset(empty_surface->pixels, 0, empty_surface->h * empty_surface->pitch);
+ empty_cursor = Android_CreateCursor(empty_surface, 0, 0);
+ SDL_FreeSurface(empty_surface);
+ }
+ }
+ return empty_cursor;
+}
+
+static void
+Android_DestroyEmptyCursor()
+{
+ if (empty_cursor) {
+ Android_FreeCursor(empty_cursor);
+ empty_cursor = NULL;
+ }
+}
+
+static int
+Android_ShowCursor(SDL_Cursor * cursor)
+{
+ if (!cursor) {
+ cursor = Android_CreateEmptyCursor();
+ }
+ if (cursor) {
+ SDL_AndroidCursorData *data = (SDL_AndroidCursorData*)cursor->driverdata;
+ if (data->custom_cursor) {
+ if (!Android_JNI_SetCustomCursor(data->custom_cursor)) {
+ return SDL_Unsupported();
+ }
+ } else {
+ if (!Android_JNI_SetSystemCursor(data->system_cursor)) {
+ return SDL_Unsupported();
+ }
+ }
+ return 0;
+ } else {
+ /* SDL error set inside Android_CreateEmptyCursor() */
+ return -1;
+ }
+}
+
+static int
+Android_SetRelativeMouseMode(SDL_bool enabled)
+{
+ if (!Android_JNI_SupportsRelativeMouse()) {
+ return SDL_Unsupported();
+ }
+
+ if (!Android_JNI_SetRelativeMouseEnabled(enabled)) {
+ return SDL_Unsupported();
+ }
+
+ return 0;
+}
+
+void
+Android_InitMouse(void)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = Android_CreateCursor;
+ mouse->CreateSystemCursor = Android_CreateSystemCursor;
+ mouse->ShowCursor = Android_ShowCursor;
+ mouse->FreeCursor = Android_FreeCursor;
+ mouse->SetRelativeMouseMode = Android_SetRelativeMouseMode;
+
+ SDL_SetDefaultCursor(Android_CreateDefaultCursor());
+
+ last_state = 0;
+}
+
+void
+Android_QuitMouse(void)
+{
+ Android_DestroyEmptyCursor();
+}
+
+/* Translate Android mouse button state to SDL mouse button */
+static Uint8
+TranslateButton(int state)
+{
+ if (state & BUTTON_PRIMARY) {
+ return SDL_BUTTON_LEFT;
+ } else if (state & BUTTON_SECONDARY) {
+ return SDL_BUTTON_RIGHT;
+ } else if (state & BUTTON_TERTIARY) {
+ return SDL_BUTTON_MIDDLE;
+ } else if (state & BUTTON_FORWARD) {
+ return SDL_BUTTON_X1;
+ } else if (state & BUTTON_BACK) {
+ return SDL_BUTTON_X2;
+ } else {
+ return 0;
+ }
+}
+
+void
+Android_OnMouse(int state, int action, float x, float y, SDL_bool relative)
+{
+ int changes;
+ Uint8 button;
+
+ if (!Android_Window) {
+ return;
+ }
+
+ switch(action) {
+ case ACTION_DOWN:
+ changes = state & ~last_state;
+ button = TranslateButton(changes);
+ last_state = state;
+ SDL_SendMouseMotion(Android_Window, 0, relative, x, y);
+ SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, button);
+ break;
+
+ case ACTION_UP:
+ changes = last_state & ~state;
+ button = TranslateButton(changes);
+ last_state = state;
+ SDL_SendMouseMotion(Android_Window, 0, relative, x, y);
+ SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, button);
+ break;
+
+ case ACTION_MOVE:
+ case ACTION_HOVER_MOVE:
+ SDL_SendMouseMotion(Android_Window, 0, relative, x, y);
+ break;
+
+ case ACTION_SCROLL:
+ SDL_SendMouseWheel(Android_Window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidmouse.h b/source/3rd-party/SDL2/src/video/android/SDL_androidmouse.h
new file mode 100644
index 0000000..eca9e47
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidmouse.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_androidmouse_h_
+#define SDL_androidmouse_h_
+
+#include "SDL_androidvideo.h"
+
+extern void Android_InitMouse(void);
+extern void Android_OnMouse(int button, int action, float x, float y, SDL_bool relative);
+extern void Android_QuitMouse(void);
+
+#endif /* SDL_androidmouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidtouch.c b/source/3rd-party/SDL2/src/video/android/SDL_androidtouch.c
new file mode 100644
index 0000000..5c3e4aa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidtouch.c
@@ -0,0 +1,151 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+#include <android/log.h>
+
+#include "SDL_hints.h"
+#include "SDL_events.h"
+#include "SDL_log.h"
+#include "SDL_androidtouch.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../../core/android/SDL_android.h"
+
+#define ACTION_DOWN 0
+#define ACTION_UP 1
+#define ACTION_MOVE 2
+#define ACTION_CANCEL 3
+#define ACTION_OUTSIDE 4
+#define ACTION_POINTER_DOWN 5
+#define ACTION_POINTER_UP 6
+
+static void Android_GetWindowCoordinates(float x, float y,
+ int *window_x, int *window_y)
+{
+ int window_w, window_h;
+
+ SDL_GetWindowSize(Android_Window, &window_w, &window_h);
+ *window_x = (int)(x * window_w);
+ *window_y = (int)(y * window_h);
+}
+
+static SDL_bool separate_mouse_and_touch = SDL_FALSE;
+
+static void SDLCALL
+SeparateEventsHintWatcher(void *userdata, const char *name,
+ const char *oldValue, const char *newValue)
+{
+ separate_mouse_and_touch = (newValue && (SDL_strcmp(newValue, "1") == 0));
+
+ Android_JNI_SetSeparateMouseAndTouch(separate_mouse_and_touch);
+}
+
+void Android_InitTouch(void)
+{
+ int i;
+ int* ids;
+ const int number = Android_JNI_GetTouchDeviceIds(&ids);
+
+ SDL_AddHintCallback(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH,
+ SeparateEventsHintWatcher, NULL);
+
+ if (0 < number) {
+ for (i = 0; i < number; ++i) {
+ SDL_AddTouch((SDL_TouchID) ids[i], ""); /* no error handling */
+ }
+ SDL_free(ids);
+ }
+}
+
+void Android_QuitTouch(void)
+{
+ SDL_DelHintCallback(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH,
+ SeparateEventsHintWatcher, NULL);
+ separate_mouse_and_touch = SDL_FALSE;
+}
+
+void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
+{
+ SDL_TouchID touchDeviceId = 0;
+ SDL_FingerID fingerId = 0;
+ int window_x, window_y;
+ static SDL_FingerID pointerFingerID = 0;
+
+ if (!Android_Window) {
+ return;
+ }
+
+ touchDeviceId = (SDL_TouchID)touch_device_id_in;
+ if (SDL_AddTouch(touchDeviceId, "") < 0) {
+ SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
+ }
+
+ fingerId = (SDL_FingerID)pointer_finger_id_in;
+ switch (action) {
+ case ACTION_DOWN:
+ /* Primary pointer down */
+ if (!separate_mouse_and_touch) {
+ Android_GetWindowCoordinates(x, y, &window_x, &window_y);
+ /* send moved event */
+ SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y);
+ /* send mouse down event */
+ SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+ }
+ pointerFingerID = fingerId;
+ case ACTION_POINTER_DOWN:
+ /* Non primary pointer down */
+ SDL_SendTouch(touchDeviceId, fingerId, SDL_TRUE, x, y, p);
+ break;
+
+ case ACTION_MOVE:
+ if (!pointerFingerID) {
+ if (!separate_mouse_and_touch) {
+ Android_GetWindowCoordinates(x, y, &window_x, &window_y);
+ /* send moved event */
+ SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y);
+ }
+ }
+ SDL_SendTouchMotion(touchDeviceId, fingerId, x, y, p);
+ break;
+
+ case ACTION_UP:
+ /* Primary pointer up */
+ if (!separate_mouse_and_touch) {
+ /* send mouse up */
+ SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+ }
+ pointerFingerID = (SDL_FingerID) 0;
+ case ACTION_POINTER_UP:
+ /* Non primary pointer up */
+ SDL_SendTouch(touchDeviceId, fingerId, SDL_FALSE, x, y, p);
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidtouch.h b/source/3rd-party/SDL2/src/video/android/SDL_androidtouch.h
new file mode 100644
index 0000000..e10be4f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidtouch.h
@@ -0,0 +1,29 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include "SDL_androidvideo.h"
+
+extern void Android_InitTouch(void);
+extern void Android_QuitTouch(void);
+extern void Android_OnTouch( int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidvideo.c b/source/3rd-party/SDL2/src/video/android/SDL_androidvideo.c
new file mode 100644
index 0000000..589461a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidvideo.c
@@ -0,0 +1,259 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+/* Android SDL video driver implementation
+*/
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_windowevents_c.h"
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidgl.h"
+#include "SDL_androidclipboard.h"
+#include "SDL_androidevents.h"
+#include "SDL_androidkeyboard.h"
+#include "SDL_androidmouse.h"
+#include "SDL_androidtouch.h"
+#include "SDL_androidwindow.h"
+#include "SDL_androidvulkan.h"
+
+#define ANDROID_VID_DRIVER_NAME "Android"
+
+/* Initialization/Query functions */
+static int Android_VideoInit(_THIS);
+static void Android_VideoQuit(_THIS);
+int Android_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
+
+#include "../SDL_egl_c.h"
+#define Android_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define Android_GLES_DeleteContext SDL_EGL_DeleteContext
+
+/* Android driver bootstrap functions */
+
+
+/* These are filled in with real values in Android_SetScreenResolution on init (before SDL_main()) */
+int Android_SurfaceWidth = 0;
+int Android_SurfaceHeight = 0;
+int Android_DeviceWidth = 0;
+int Android_DeviceHeight = 0;
+Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN;
+static int Android_ScreenRate = 0;
+
+SDL_sem *Android_PauseSem = NULL, *Android_ResumeSem = NULL;
+
+/* Currently only one window */
+SDL_Window *Android_Window = NULL;
+
+static int
+Android_Available(void)
+{
+ return 1;
+}
+
+static void
+Android_SuspendScreenSaver(_THIS)
+{
+ Android_JNI_SuspendScreenSaver(_this->suspend_screensaver);
+}
+
+static void
+Android_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_free(device->driverdata);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+Android_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ data = (SDL_VideoData*) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (!data) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return NULL;
+ }
+
+ device->driverdata = data;
+
+ /* Set the function pointers */
+ device->VideoInit = Android_VideoInit;
+ device->VideoQuit = Android_VideoQuit;
+ device->PumpEvents = Android_PumpEvents;
+
+ device->GetDisplayDPI = Android_GetDisplayDPI;
+
+ device->CreateSDLWindow = Android_CreateWindow;
+ device->SetWindowTitle = Android_SetWindowTitle;
+ device->SetWindowFullscreen = Android_SetWindowFullscreen;
+ device->DestroyWindow = Android_DestroyWindow;
+ device->GetWindowWMInfo = Android_GetWindowWMInfo;
+
+ device->free = Android_DeleteDevice;
+
+ /* GL pointers */
+ device->GL_LoadLibrary = Android_GLES_LoadLibrary;
+ device->GL_GetProcAddress = Android_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = Android_GLES_UnloadLibrary;
+ device->GL_CreateContext = Android_GLES_CreateContext;
+ device->GL_MakeCurrent = Android_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = Android_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = Android_GLES_GetSwapInterval;
+ device->GL_SwapWindow = Android_GLES_SwapWindow;
+ device->GL_DeleteContext = Android_GLES_DeleteContext;
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = Android_Vulkan_CreateSurface;
+#endif
+
+ /* Screensaver */
+ device->SuspendScreenSaver = Android_SuspendScreenSaver;
+
+ /* Text input */
+ device->StartTextInput = Android_StartTextInput;
+ device->StopTextInput = Android_StopTextInput;
+ device->SetTextInputRect = Android_SetTextInputRect;
+
+ /* Screen keyboard */
+ device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport;
+ device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
+
+ /* Clipboard */
+ device->SetClipboardText = Android_SetClipboardText;
+ device->GetClipboardText = Android_GetClipboardText;
+ device->HasClipboardText = Android_HasClipboardText;
+
+ return device;
+}
+
+VideoBootStrap Android_bootstrap = {
+ ANDROID_VID_DRIVER_NAME, "SDL Android video driver",
+ Android_Available, Android_CreateDevice
+};
+
+
+int
+Android_VideoInit(_THIS)
+{
+ SDL_DisplayMode mode;
+
+ mode.format = Android_ScreenFormat;
+ mode.w = Android_DeviceWidth;
+ mode.h = Android_DeviceHeight;
+ mode.refresh_rate = Android_ScreenRate;
+ mode.driverdata = NULL;
+ if (SDL_AddBasicVideoDisplay(&mode) < 0) {
+ return -1;
+ }
+
+ SDL_AddDisplayMode(&_this->displays[0], &mode);
+
+ Android_InitKeyboard();
+
+ Android_InitTouch();
+
+ Android_InitMouse();
+
+ /* We're done! */
+ return 0;
+}
+
+void
+Android_VideoQuit(_THIS)
+{
+ Android_QuitMouse();
+ Android_QuitTouch();
+}
+
+int
+Android_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
+{
+ return Android_JNI_GetDisplayDPI(ddpi, hdpi, vdpi);
+}
+
+void
+Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate)
+{
+ SDL_VideoDevice* device;
+ SDL_VideoDisplay *display;
+ Android_SurfaceWidth = surfaceWidth;
+ Android_SurfaceHeight = surfaceHeight;
+ Android_DeviceWidth = deviceWidth;
+ Android_DeviceHeight = deviceHeight;
+ Android_ScreenFormat = format;
+ Android_ScreenRate = rate;
+
+ /*
+ Update the resolution of the desktop mode, so that the window
+ can be properly resized. The screen resolution change can for
+ example happen when the Activity enters or exits immersive mode,
+ which can happen after VideoInit().
+ */
+ device = SDL_GetVideoDevice();
+ if (device && device->num_displays > 0)
+ {
+ display = &device->displays[0];
+ display->desktop_mode.format = Android_ScreenFormat;
+ display->desktop_mode.w = Android_DeviceWidth;
+ display->desktop_mode.h = Android_DeviceHeight;
+ display->desktop_mode.refresh_rate = Android_ScreenRate;
+ }
+
+ if (Android_Window) {
+ /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event
+ * will fall back to the old mode */
+ display = SDL_GetDisplayForWindow(Android_Window);
+
+ display->display_modes[0].format = format;
+ display->display_modes[0].w = Android_DeviceWidth;
+ display->display_modes[0].h = Android_DeviceHeight;
+ display->display_modes[0].refresh_rate = rate;
+ display->current_mode = display->display_modes[0];
+
+ SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, surfaceWidth, surfaceHeight);
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidvideo.h b/source/3rd-party/SDL2/src/video/android/SDL_androidvideo.h
new file mode 100644
index 0000000..6dce7ed
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidvideo.h
@@ -0,0 +1,51 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_androidvideo_h_
+#define SDL_androidvideo_h_
+
+#include "SDL_mutex.h"
+#include "SDL_rect.h"
+#include "../SDL_sysvideo.h"
+
+/* Called by the JNI layer when the screen changes size or format */
+extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate);
+
+/* Private display data */
+
+typedef struct SDL_VideoData
+{
+ SDL_Rect textRect;
+} SDL_VideoData;
+
+extern int Android_SurfaceWidth;
+extern int Android_SurfaceHeight;
+extern int Android_DeviceWidth;
+extern int Android_DeviceHeight;
+extern Uint32 Android_ScreenFormat;
+extern SDL_sem *Android_PauseSem, *Android_ResumeSem;
+extern SDL_Window *Android_Window;
+
+
+#endif /* SDL_androidvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.c b/source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.c
new file mode 100644
index 0000000..e013034
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.c
@@ -0,0 +1,175 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidwindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_androidvulkan.h"
+#include "SDL_syswm.h"
+
+int Android_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 i, extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasAndroidSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+ if(_this->vulkan_config.loader_handle)
+ return SDL_SetError("Vulkan already loaded");
+
+ /* Load the Vulkan loader library */
+ if(!path)
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ if(!path)
+ path = "libvulkan.so";
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if(!_this->vulkan_config.loader_handle)
+ return -1;
+ SDL_strlcpy(_this->vulkan_config.loader_path, path,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+ if(!vkGetInstanceProcAddr)
+ goto fail;
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+ if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
+ goto fail;
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+ if(!extensions)
+ goto fail;
+ for(i = 0; i < extensionCount; i++)
+ {
+ if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasSurfaceExtension = SDL_TRUE;
+ else if(SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasAndroidSurfaceExtension = SDL_TRUE;
+ }
+ SDL_free(extensions);
+ if(!hasSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ }
+ else if(!hasAndroidSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+ return 0;
+
+fail:
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void Android_Vulkan_UnloadLibrary(_THIS)
+{
+ if(_this->vulkan_config.loader_handle)
+ {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForAndroid[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
+ };
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForAndroid),
+ extensionsForAndroid);
+}
+
+SDL_bool Android_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR =
+ (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateAndroidSurfaceKHR");
+ VkAndroidSurfaceCreateInfoKHR createInfo;
+ VkResult result;
+
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if(!vkCreateAndroidSurfaceKHR)
+ {
+ SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ SDL_zero(createInfo);
+ createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.window = windowData->native_window;
+ result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
+ NULL, surface);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.h b/source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.h
new file mode 100644
index 0000000..2634c61
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidvulkan.h
@@ -0,0 +1,52 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_androidvulkan_h_
+#define SDL_androidvulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID
+
+int Android_Vulkan_LoadLibrary(_THIS, const char *path);
+void Android_Vulkan_UnloadLibrary(_THIS);
+SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool Android_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+#endif
+
+#endif /* SDL_androidvulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidwindow.c b/source/3rd-party/SDL2/src/video/android/SDL_androidwindow.c
new file mode 100644
index 0000000..cf18e67
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidwindow.c
@@ -0,0 +1,183 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_ANDROID
+
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_windowevents_c.h"
+#include "../../core/android/SDL_android.h"
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidwindow.h"
+#include "SDL_hints.h"
+
+int
+Android_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data;
+
+ if (Android_Window) {
+ return SDL_SetError("Android only supports one window");
+ }
+
+ Android_PauseSem = SDL_CreateSemaphore(0);
+ Android_ResumeSem = SDL_CreateSemaphore(0);
+
+ /* Set orientation */
+ Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
+
+ /* Adjust the window data to match the screen */
+ window->x = 0;
+ window->y = 0;
+ window->w = Android_SurfaceWidth;
+ window->h = Android_SurfaceHeight;
+
+ window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */
+ window->flags &= ~SDL_WINDOW_HIDDEN;
+ window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */
+ window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
+
+ /* One window, it always has focus */
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+
+ data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+
+ data->native_window = Android_JNI_GetNativeWindow();
+
+ if (!data->native_window) {
+ SDL_free(data);
+ return SDL_SetError("Could not fetch native window");
+ }
+
+ /* Do not create EGLSurface for Vulkan window since it will then make the window
+ incompatible with vkCreateAndroidSurfaceKHR */
+ if ((window->flags & SDL_WINDOW_VULKAN) == 0) {
+ data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
+
+ if (data->egl_surface == EGL_NO_SURFACE) {
+ ANativeWindow_release(data->native_window);
+ SDL_free(data);
+ return SDL_SetError("Could not create GLES window surface");
+ }
+ }
+
+ window->driverdata = data;
+ Android_Window = window;
+
+ return 0;
+}
+
+void
+Android_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ Android_JNI_SetActivityTitle(window->title);
+}
+
+void
+Android_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+ /* If the window is being destroyed don't change visible state */
+ if (!window->is_destroying) {
+ Android_JNI_SetWindowStyle(fullscreen);
+ }
+
+ /* Ensure our size matches reality after we've executed the window style change.
+ *
+ * It is possible that we've set width and height to the full-size display, but on
+ * Samsung DeX or Chromebooks or other windowed Android environemtns, our window may
+ * still not be the full display size.
+ */
+ if (!SDL_IsDeXMode() && !SDL_IsChromebook()) {
+ return;
+ }
+
+ SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
+
+ if (!data || !data->native_window) {
+ return;
+ }
+
+ int old_w = window->w;
+ int old_h = window->h;
+
+ int new_w = ANativeWindow_getWidth(data->native_window);
+ int new_h = ANativeWindow_getHeight(data->native_window);
+
+ if (old_w != new_w || old_h != new_h) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
+ }
+}
+
+void
+Android_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data;
+
+ if (window == Android_Window) {
+ Android_Window = NULL;
+ if (Android_PauseSem) SDL_DestroySemaphore(Android_PauseSem);
+ if (Android_ResumeSem) SDL_DestroySemaphore(Android_ResumeSem);
+ Android_PauseSem = NULL;
+ Android_ResumeSem = NULL;
+
+ if(window->driverdata) {
+ data = (SDL_WindowData *) window->driverdata;
+ if (data->egl_surface != EGL_NO_SURFACE) {
+ SDL_EGL_DestroySurface(_this, data->egl_surface);
+ }
+ if (data->native_window) {
+ ANativeWindow_release(data->native_window);
+ }
+ SDL_free(window->driverdata);
+ window->driverdata = NULL;
+ }
+ }
+}
+
+SDL_bool
+Android_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (info->version.major == SDL_MAJOR_VERSION &&
+ info->version.minor == SDL_MINOR_VERSION) {
+ info->subsystem = SDL_SYSWM_ANDROID;
+ info->info.android.window = data->native_window;
+ info->info.android.surface = data->egl_surface;
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/android/SDL_androidwindow.h b/source/3rd-party/SDL2/src/video/android/SDL_androidwindow.h
new file mode 100644
index 0000000..df99567
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/android/SDL_androidwindow.h
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_androidwindow_h_
+#define SDL_androidwindow_h_
+
+#include "../../core/android/SDL_android.h"
+#include "../SDL_egl_c.h"
+
+extern int Android_CreateWindow(_THIS, SDL_Window * window);
+extern void Android_SetWindowTitle(_THIS, SDL_Window * window);
+extern void Android_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern void Android_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info);
+
+typedef struct
+{
+ EGLSurface egl_surface;
+ EGLContext egl_context; /* We use this to preserve the context when losing focus */
+ ANativeWindow* native_window;
+
+} SDL_WindowData;
+
+#endif /* SDL_androidwindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.h
new file mode 100644
index 0000000..54e4c88
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoaclipboard_h_
+#define SDL_cocoaclipboard_h_
+
+/* Forward declaration */
+struct SDL_VideoData;
+
+extern int Cocoa_SetClipboardText(_THIS, const char *text);
+extern char *Cocoa_GetClipboardText(_THIS);
+extern SDL_bool Cocoa_HasClipboardText(_THIS);
+extern void Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data);
+
+#endif /* SDL_cocoaclipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.m
new file mode 100644
index 0000000..9c96634
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaclipboard.m
@@ -0,0 +1,103 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_cocoavideo.h"
+#include "../../events/SDL_clipboardevents_c.h"
+
+int
+Cocoa_SetClipboardText(_THIS, const char *text)
+{ @autoreleasepool
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ NSPasteboard *pasteboard;
+ NSString *format = NSPasteboardTypeString;
+
+ pasteboard = [NSPasteboard generalPasteboard];
+ data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
+ [pasteboard setString:[NSString stringWithUTF8String:text] forType:format];
+
+ return 0;
+}}
+
+char *
+Cocoa_GetClipboardText(_THIS)
+{ @autoreleasepool
+{
+ NSPasteboard *pasteboard;
+ NSString *format = NSPasteboardTypeString;
+ NSString *available;
+ char *text;
+
+ pasteboard = [NSPasteboard generalPasteboard];
+ available = [pasteboard availableTypeFromArray:[NSArray arrayWithObject:format]];
+ if ([available isEqualToString:format]) {
+ NSString* string;
+ const char *utf8;
+
+ string = [pasteboard stringForType:format];
+ if (string == nil) {
+ utf8 = "";
+ } else {
+ utf8 = [string UTF8String];
+ }
+ text = SDL_strdup(utf8);
+ } else {
+ text = SDL_strdup("");
+ }
+
+ return text;
+}}
+
+SDL_bool
+Cocoa_HasClipboardText(_THIS)
+{
+ SDL_bool result = SDL_FALSE;
+ char *text = Cocoa_GetClipboardText(_this);
+ if (text) {
+ result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
+ SDL_free(text);
+ }
+ return result;
+}
+
+void
+Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data)
+{ @autoreleasepool
+{
+ NSPasteboard *pasteboard;
+ NSInteger count;
+
+ pasteboard = [NSPasteboard generalPasteboard];
+ count = [pasteboard changeCount];
+ if (count != data->clipboard_count) {
+ if (data->clipboard_count) {
+ SDL_SendClipboardUpdate();
+ }
+ data->clipboard_count = count;
+ }
+}}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.h
new file mode 100644
index 0000000..986168e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoaevents_h_
+#define SDL_cocoaevents_h_
+
+extern void Cocoa_RegisterApp(void);
+extern void Cocoa_PumpEvents(_THIS);
+extern void Cocoa_SuspendScreenSaver(_THIS);
+
+#endif /* SDL_cocoaevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.m
new file mode 100644
index 0000000..76d235e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaevents.m
@@ -0,0 +1,483 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+#include "SDL_timer.h"
+
+#include "SDL_cocoavideo.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+
+/* This define was added in the 10.9 SDK. */
+#ifndef kIOPMAssertPreventUserIdleDisplaySleep
+#define kIOPMAssertPreventUserIdleDisplaySleep kIOPMAssertionTypePreventUserIdleDisplaySleep
+#endif
+
+@interface SDLApplication : NSApplication
+
+- (void)terminate:(id)sender;
+- (void)sendEvent:(NSEvent *)theEvent;
+
++ (void)registerUserDefaults;
+
+@end
+
+@implementation SDLApplication
+
+// Override terminate to handle Quit and System Shutdown smoothly.
+- (void)terminate:(id)sender
+{
+ SDL_SendQuit();
+}
+
+static SDL_bool s_bShouldHandleEventsInSDLApplication = SDL_FALSE;
+
+static void Cocoa_DispatchEvent(NSEvent *theEvent)
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+ switch ([theEvent type]) {
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeOtherMouseDown:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeLeftMouseUp:
+ case NSEventTypeOtherMouseUp:
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
+ case NSEventTypeOtherMouseDragged: /* usually middle mouse dragged */
+ case NSEventTypeMouseMoved:
+ case NSEventTypeScrollWheel:
+ Cocoa_HandleMouseEvent(_this, theEvent);
+ break;
+ case NSEventTypeKeyDown:
+ case NSEventTypeKeyUp:
+ case NSEventTypeFlagsChanged:
+ Cocoa_HandleKeyEvent(_this, theEvent);
+ break;
+ default:
+ break;
+ }
+}
+
+// Dispatch events here so that we can handle events caught by
+// nextEventMatchingMask in SDL, as well as events caught by other
+// processes (such as CEF) that are passed down to NSApp.
+- (void)sendEvent:(NSEvent *)theEvent
+{
+ if (s_bShouldHandleEventsInSDLApplication) {
+ Cocoa_DispatchEvent(theEvent);
+ }
+
+ [super sendEvent:theEvent];
+}
+
++ (void)registerUserDefaults
+{
+ NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithBool:NO], @"AppleMomentumScrollSupported",
+ [NSNumber numberWithBool:NO], @"ApplePressAndHoldEnabled",
+ [NSNumber numberWithBool:YES], @"ApplePersistenceIgnoreState",
+ nil];
+ [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
+ [appDefaults release];
+}
+
+@end // SDLApplication
+
+/* setAppleMenu disappeared from the headers in 10.4 */
+@interface NSApplication(NSAppleMenu)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+
+@interface SDLAppDelegate : NSObject <NSApplicationDelegate> {
+@public
+ BOOL seenFirstActivate;
+}
+
+- (id)init;
+@end
+
+@implementation SDLAppDelegate : NSObject
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ seenFirstActivate = NO;
+
+ [center addObserver:self
+ selector:@selector(windowWillClose:)
+ name:NSWindowWillCloseNotification
+ object:nil];
+
+ [center addObserver:self
+ selector:@selector(focusSomeWindow:)
+ name:NSApplicationDidBecomeActiveNotification
+ object:nil];
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
+ [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
+
+ [super dealloc];
+}
+
+- (void)windowWillClose:(NSNotification *)notification;
+{
+ NSWindow *win = (NSWindow*)[notification object];
+
+ if (![win isKeyWindow]) {
+ return;
+ }
+
+ /* HACK: Make the next window in the z-order key when the key window is
+ * closed. The custom event loop and/or windowing code we have seems to
+ * prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825
+ */
+
+ /* +[NSApp orderedWindows] never includes the 'About' window, but we still
+ * want to try its list first since the behavior in other apps is to only
+ * make the 'About' window key if no other windows are on-screen.
+ */
+ for (NSWindow *window in [NSApp orderedWindows]) {
+ if (window != win && [window canBecomeKeyWindow]) {
+ if (![window isOnActiveSpace]) {
+ continue;
+ }
+ [window makeKeyAndOrderFront:self];
+ return;
+ }
+ }
+
+ /* If a window wasn't found above, iterate through all visible windows in
+ * the active Space in z-order (including the 'About' window, if it's shown)
+ * and make the first one key.
+ */
+ for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
+ NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
+ if (window && window != win && [window canBecomeKeyWindow]) {
+ [window makeKeyAndOrderFront:self];
+ return;
+ }
+ }
+}
+
+- (void)focusSomeWindow:(NSNotification *)aNotification
+{
+ /* HACK: Ignore the first call. The application gets a
+ * applicationDidBecomeActive: a little bit after the first window is
+ * created, and if we don't ignore it, a window that has been created with
+ * SDL_WINDOW_MINIMIZED will ~immediately be restored.
+ */
+ if (!seenFirstActivate) {
+ seenFirstActivate = YES;
+ return;
+ }
+
+ SDL_VideoDevice *device = SDL_GetVideoDevice();
+ if (device && device->windows) {
+ SDL_Window *window = device->windows;
+ int i;
+ for (i = 0; i < device->num_displays; ++i) {
+ SDL_Window *fullscreen_window = device->displays[i].fullscreen_window;
+ if (fullscreen_window) {
+ if (fullscreen_window->flags & SDL_WINDOW_MINIMIZED) {
+ SDL_RestoreWindow(fullscreen_window);
+ }
+ return;
+ }
+ }
+
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ SDL_RestoreWindow(window);
+ } else {
+ SDL_RaiseWindow(window);
+ }
+ }
+}
+
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL);
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+ /* The menu bar of SDL apps which don't have the typical .app bundle
+ * structure fails to work the first time a window is created (until it's
+ * de-focused and re-focused), if this call is in Cocoa_RegisterApp instead
+ * of here. https://bugzilla.libsdl.org/show_bug.cgi?id=3051
+ */
+ if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) {
+ [NSApp activateIgnoringOtherApps:YES];
+ }
+
+ /* If we call this before NSApp activation, macOS might print a complaint
+ * about ApplePersistenceIgnoreState. */
+ [SDLApplication registerUserDefaults];
+}
+@end
+
+static SDLAppDelegate *appDelegate = nil;
+
+static NSString *
+GetApplicationName(void)
+{
+ NSString *appName;
+
+ /* Determine the application name */
+ appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
+ if (!appName) {
+ appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
+ }
+
+ if (![appName length]) {
+ appName = [[NSProcessInfo processInfo] processName];
+ }
+
+ return appName;
+}
+
+static void
+CreateApplicationMenus(void)
+{
+ NSString *appName;
+ NSString *title;
+ NSMenu *appleMenu;
+ NSMenu *serviceMenu;
+ NSMenu *windowMenu;
+ NSMenu *viewMenu;
+ NSMenuItem *menuItem;
+ NSMenu *mainMenu;
+
+ if (NSApp == nil) {
+ return;
+ }
+
+ mainMenu = [[NSMenu alloc] init];
+
+ /* Create the main menu bar */
+ [NSApp setMainMenu:mainMenu];
+
+ [mainMenu release]; /* we're done with it, let NSApp own it. */
+ mainMenu = nil;
+
+ /* Create the application menu */
+ appName = GetApplicationName();
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
+
+ /* Add menu items */
+ title = [@"About " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ [appleMenu addItemWithTitle:@"Preferences…" action:nil keyEquivalent:@","];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ serviceMenu = [[NSMenu alloc] initWithTitle:@""];
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:serviceMenu];
+
+ [NSApp setServicesMenu:serviceMenu];
+ [serviceMenu release];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Hide " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSEventModifierFlagOption|NSEventModifierFlagCommand)];
+
+ [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Quit " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+ [menuItem release];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+ [appleMenu release];
+
+
+ /* Create the window menu */
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ /* Add menu items */
+ [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+
+ [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:windowMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+ [menuItem release];
+
+ /* Tell the application object that this is now the window menu */
+ [NSApp setWindowsMenu:windowMenu];
+ [windowMenu release];
+
+
+ /* Add the fullscreen view toggle menu option, if supported */
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) {
+ /* Create the view menu */
+ viewMenu = [[NSMenu alloc] initWithTitle:@"View"];
+
+ /* Add menu items */
+ menuItem = [viewMenu addItemWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"];
+ [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:viewMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+ [menuItem release];
+
+ [viewMenu release];
+ }
+}
+
+void
+Cocoa_RegisterApp(void)
+{ @autoreleasepool
+{
+ /* This can get called more than once! Be careful what you initialize! */
+
+ if (NSApp == nil) {
+ [SDLApplication sharedApplication];
+ SDL_assert(NSApp != nil);
+
+ s_bShouldHandleEventsInSDLApplication = SDL_TRUE;
+
+ if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) {
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+ }
+
+ if ([NSApp mainMenu] == nil) {
+ CreateApplicationMenus();
+ }
+ [NSApp finishLaunching];
+ if ([NSApp delegate]) {
+ /* The SDL app delegate calls this in didFinishLaunching if it's
+ * attached to the NSApp, otherwise we need to call it manually.
+ */
+ [SDLApplication registerUserDefaults];
+ }
+ }
+ if (NSApp && !appDelegate) {
+ appDelegate = [[SDLAppDelegate alloc] init];
+
+ /* If someone else has an app delegate, it means we can't turn a
+ * termination into SDL_Quit, and we can't handle application:openFile:
+ */
+ if (![NSApp delegate]) {
+ [(NSApplication *)NSApp setDelegate:appDelegate];
+ } else {
+ appDelegate->seenFirstActivate = YES;
+ }
+ }
+}}
+
+void
+Cocoa_PumpEvents(_THIS)
+{ @autoreleasepool
+{
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+ /* Update activity every 30 seconds to prevent screensaver */
+ SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
+ if (_this->suspend_screensaver && !data->screensaver_use_iopm) {
+ Uint32 now = SDL_GetTicks();
+ if (!data->screensaver_activity ||
+ SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
+ UpdateSystemActivity(UsrActivity);
+ data->screensaver_activity = now;
+ }
+ }
+#endif
+
+ for ( ; ; ) {
+ NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
+ if ( event == nil ) {
+ break;
+ }
+
+ if (!s_bShouldHandleEventsInSDLApplication) {
+ Cocoa_DispatchEvent(event);
+ }
+
+ // Pass events down to SDLApplication to be handled in sendEvent:
+ [NSApp sendEvent:event];
+ }
+}}
+
+void
+Cocoa_SuspendScreenSaver(_THIS)
+{ @autoreleasepool
+{
+ SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
+
+ if (!data->screensaver_use_iopm) {
+ return;
+ }
+
+ if (data->screensaver_assertion) {
+ IOPMAssertionRelease(data->screensaver_assertion);
+ data->screensaver_assertion = 0;
+ }
+
+ if (_this->suspend_screensaver) {
+ /* FIXME: this should ideally describe the real reason why the game
+ * called SDL_DisableScreenSaver. Note that the name is only meant to be
+ * seen by OS X power users. there's an additional optional human-readable
+ * (localized) reason parameter which we don't set.
+ */
+ NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"];
+ IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep,
+ (CFStringRef) name,
+ NULL, NULL, NULL, 0, NULL,
+ &data->screensaver_assertion);
+ }
+}}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.h
new file mode 100644
index 0000000..7d89523
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoakeyboard_h_
+#define SDL_cocoakeyboard_h_
+
+extern void Cocoa_InitKeyboard(_THIS);
+extern void Cocoa_HandleKeyEvent(_THIS, NSEvent * event);
+extern void Cocoa_QuitKeyboard(_THIS);
+
+extern void Cocoa_StartTextInput(_THIS);
+extern void Cocoa_StopTextInput(_THIS);
+extern void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect);
+
+#endif /* SDL_cocoakeyboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.m
new file mode 100644
index 0000000..8436047
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoakeyboard.m
@@ -0,0 +1,720 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_cocoavideo.h"
+
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/scancodes_darwin.h"
+
+#include <Carbon/Carbon.h>
+#include <IOKit/hid/IOHIDLib.h>
+
+/*#define DEBUG_IME NSLog */
+#define DEBUG_IME(...)
+
+@interface SDLTranslatorResponder : NSView <NSTextInputClient> {
+ NSString *_markedText;
+ NSRange _markedRange;
+ NSRange _selectedRange;
+ SDL_Rect _inputRect;
+}
+- (void)doCommandBySelector:(SEL)myselector;
+- (void)setInputRect:(SDL_Rect *)rect;
+@end
+
+@implementation SDLTranslatorResponder
+
+- (void)setInputRect:(SDL_Rect *)rect
+{
+ _inputRect = *rect;
+}
+
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
+{
+ /* TODO: Make use of replacementRange? */
+
+ const char *str;
+
+ DEBUG_IME(@"insertText: %@", aString);
+
+ /* Could be NSString or NSAttributedString, so we have
+ * to test and convert it before return as SDL event */
+ if ([aString isKindOfClass: [NSAttributedString class]]) {
+ str = [[aString string] UTF8String];
+ } else {
+ str = [aString UTF8String];
+ }
+
+ SDL_SendKeyboardText(str);
+}
+
+- (void)doCommandBySelector:(SEL)myselector
+{
+ /* No need to do anything since we are not using Cocoa
+ selectors to handle special keys, instead we use SDL
+ key events to do the same job.
+ */
+}
+
+- (BOOL)hasMarkedText
+{
+ return _markedText != nil;
+}
+
+- (NSRange)markedRange
+{
+ return _markedRange;
+}
+
+- (NSRange)selectedRange
+{
+ return _selectedRange;
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ aString = [aString string];
+ }
+
+ if ([aString length] == 0) {
+ [self unmarkText];
+ return;
+ }
+
+ if (_markedText != aString) {
+ [_markedText release];
+ _markedText = [aString retain];
+ }
+
+ _selectedRange = selectedRange;
+ _markedRange = NSMakeRange(0, [aString length]);
+
+ SDL_SendEditingText([aString UTF8String],
+ (int) selectedRange.location, (int) selectedRange.length);
+
+ DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText,
+ selRange.location, selRange.length);
+}
+
+- (void)unmarkText
+{
+ [_markedText release];
+ _markedText = nil;
+
+ SDL_SendEditingText("", 0, 0);
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+ NSWindow *window = [self window];
+ NSRect contentRect = [window contentRectForFrameRect:[window frame]];
+ float windowHeight = contentRect.size.height;
+ NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h,
+ _inputRect.w, _inputRect.h);
+
+ if (actualRange) {
+ *actualRange = aRange;
+ }
+
+ DEBUG_IME(@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@",
+ aRange.location, aRange.length, windowHeight,
+ NSStringFromRect(rect));
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+ if (![window respondsToSelector:@selector(convertRectToScreen:)]) {
+ rect.origin = [window convertBaseToScreen:rect.origin];
+ } else
+#endif
+ {
+ rect = [window convertRectToScreen:rect];
+ }
+
+ return rect;
+}
+
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+ DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length);
+ return nil;
+}
+
+- (NSInteger)conversationIdentifier
+{
+ return (NSInteger) self;
+}
+
+/* This method returns the index for character that is
+ * nearest to thePoint. thPoint is in screen coordinate system.
+ */
+- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
+{
+ DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y);
+ return 0;
+}
+
+/* This method is the key to attribute extension.
+ * We could add new attributes through this method.
+ * NSInputServer examines the return value of this
+ * method & constructs appropriate attributed string.
+ */
+- (NSArray *)validAttributesForMarkedText
+{
+ return [NSArray array];
+}
+
+@end
+
+/*------------------------------------------------------------------------------
+Set up a HID callback to properly detect Caps Lock up/down events.
+Derived from:
+http://stackoverflow.com/questions/7190852/using-iohidmanager-to-get-modifier-key-events
+*/
+
+static IOHIDManagerRef s_hidManager = NULL;
+
+static void
+HIDCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
+{
+ if (context != s_hidManager) {
+ /* An old callback, ignore it (related to bug 2157 below) */
+ return;
+ }
+
+ IOHIDElementRef elem = IOHIDValueGetElement(value);
+ if (IOHIDElementGetUsagePage(elem) != kHIDPage_KeyboardOrKeypad
+ || IOHIDElementGetUsage(elem) != kHIDUsage_KeyboardCapsLock) {
+ return;
+ }
+ CFIndex pressed = IOHIDValueGetIntegerValue(value);
+ SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
+}
+
+static CFDictionaryRef
+CreateHIDDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage)
+{
+ CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (dict) {
+ CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage);
+ if (number) {
+ CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number);
+ CFRelease(number);
+ number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
+ if (number) {
+ CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number);
+ CFRelease(number);
+ return dict;
+ }
+ }
+ CFRelease(dict);
+ }
+ return NULL;
+}
+
+static void
+QuitHIDCallback()
+{
+ if (!s_hidManager) {
+ return;
+ }
+
+#if 0 /* Releasing here causes a crash on Mac OS X 10.10 and earlier,
+ * so just leak it for now. See bug 2157 for details.
+ */
+ IOHIDManagerUnscheduleFromRunLoop(s_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);
+ IOHIDManagerClose(s_hidManager, 0);
+
+ CFRelease(s_hidManager);
+#endif
+ s_hidManager = NULL;
+}
+
+static void
+InitHIDCallback()
+{
+ s_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
+ if (!s_hidManager) {
+ return;
+ }
+ CFDictionaryRef keyboard = NULL, keypad = NULL;
+ CFArrayRef matches = NULL;
+ keyboard = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
+ if (!keyboard) {
+ goto fail;
+ }
+ keypad = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad);
+ if (!keypad) {
+ goto fail;
+ }
+ CFDictionaryRef matchesList[] = { keyboard, keypad };
+ matches = CFArrayCreate(kCFAllocatorDefault, (const void **)matchesList, 2, NULL);
+ if (!matches) {
+ goto fail;
+ }
+ IOHIDManagerSetDeviceMatchingMultiple(s_hidManager, matches);
+ IOHIDManagerRegisterInputValueCallback(s_hidManager, HIDCallback, s_hidManager);
+ IOHIDManagerScheduleWithRunLoop(s_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+ if (IOHIDManagerOpen(s_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess) {
+ goto cleanup;
+ }
+
+fail:
+ QuitHIDCallback();
+
+cleanup:
+ if (matches) {
+ CFRelease(matches);
+ }
+ if (keypad) {
+ CFRelease(keypad);
+ }
+ if (keyboard) {
+ CFRelease(keyboard);
+ }
+}
+
+/* This is a helper function for HandleModifierSide. This
+ * function reverts back to behavior before the distinction between
+ * sides was made.
+ */
+static void
+HandleNonDeviceModifier(unsigned int device_independent_mask,
+ unsigned int oldMods,
+ unsigned int newMods,
+ SDL_Scancode scancode)
+{
+ unsigned int oldMask, newMask;
+
+ /* Isolate just the bits we care about in the depedent bits so we can
+ * figure out what changed
+ */
+ oldMask = oldMods & device_independent_mask;
+ newMask = newMods & device_independent_mask;
+
+ if (oldMask && oldMask != newMask) {
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ } else if (newMask && oldMask != newMask) {
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ }
+}
+
+/* This is a helper function for HandleModifierSide.
+ * This function sets the actual SDL_PrivateKeyboard event.
+ */
+static void
+HandleModifierOneSide(unsigned int oldMods, unsigned int newMods,
+ SDL_Scancode scancode,
+ unsigned int sided_device_dependent_mask)
+{
+ unsigned int old_dep_mask, new_dep_mask;
+
+ /* Isolate just the bits we care about in the depedent bits so we can
+ * figure out what changed
+ */
+ old_dep_mask = oldMods & sided_device_dependent_mask;
+ new_dep_mask = newMods & sided_device_dependent_mask;
+
+ /* We now know that this side bit flipped. But we don't know if
+ * it went pressed to released or released to pressed, so we must
+ * find out which it is.
+ */
+ if (new_dep_mask && old_dep_mask != new_dep_mask) {
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ } else {
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+}
+
+/* This is a helper function for DoSidedModifiers.
+ * This function will figure out if the modifier key is the left or right side,
+ * e.g. left-shift vs right-shift.
+ */
+static void
+HandleModifierSide(int device_independent_mask,
+ unsigned int oldMods, unsigned int newMods,
+ SDL_Scancode left_scancode,
+ SDL_Scancode right_scancode,
+ unsigned int left_device_dependent_mask,
+ unsigned int right_device_dependent_mask)
+{
+ unsigned int device_dependent_mask = (left_device_dependent_mask |
+ right_device_dependent_mask);
+ unsigned int diff_mod;
+
+ /* On the basis that the device independent mask is set, but there are
+ * no device dependent flags set, we'll assume that we can't detect this
+ * keyboard and revert to the unsided behavior.
+ */
+ if ((device_dependent_mask & newMods) == 0) {
+ /* Revert to the old behavior */
+ HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
+ return;
+ }
+
+ /* XOR the previous state against the new state to see if there's a change */
+ diff_mod = (device_dependent_mask & oldMods) ^
+ (device_dependent_mask & newMods);
+ if (diff_mod) {
+ /* A change in state was found. Isolate the left and right bits
+ * to handle them separately just in case the values can simulataneously
+ * change or if the bits don't both exist.
+ */
+ if (left_device_dependent_mask & diff_mod) {
+ HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
+ }
+ if (right_device_dependent_mask & diff_mod) {
+ HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
+ }
+ }
+}
+
+/* This is a helper function for DoSidedModifiers.
+ * This function will release a key press in the case that
+ * it is clear that the modifier has been released (i.e. one side
+ * can't still be down).
+ */
+static void
+ReleaseModifierSide(unsigned int device_independent_mask,
+ unsigned int oldMods, unsigned int newMods,
+ SDL_Scancode left_scancode,
+ SDL_Scancode right_scancode,
+ unsigned int left_device_dependent_mask,
+ unsigned int right_device_dependent_mask)
+{
+ unsigned int device_dependent_mask = (left_device_dependent_mask |
+ right_device_dependent_mask);
+
+ /* On the basis that the device independent mask is set, but there are
+ * no device dependent flags set, we'll assume that we can't detect this
+ * keyboard and revert to the unsided behavior.
+ */
+ if ((device_dependent_mask & oldMods) == 0) {
+ /* In this case, we can't detect the keyboard, so use the left side
+ * to represent both, and release it.
+ */
+ SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
+ return;
+ }
+
+ /*
+ * This could have been done in an if-else case because at this point,
+ * we know that all keys have been released when calling this function.
+ * But I'm being paranoid so I want to handle each separately,
+ * so I hope this doesn't cause other problems.
+ */
+ if ( left_device_dependent_mask & oldMods ) {
+ SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
+ }
+ if ( right_device_dependent_mask & oldMods ) {
+ SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
+ }
+}
+
+/* This function will handle the modifier keys and also determine the
+ * correct side of the key.
+ */
+static void
+DoSidedModifiers(unsigned short scancode,
+ unsigned int oldMods, unsigned int newMods)
+{
+ /* Set up arrays for the key syms for the left and right side. */
+ const SDL_Scancode left_mapping[] = {
+ SDL_SCANCODE_LSHIFT,
+ SDL_SCANCODE_LCTRL,
+ SDL_SCANCODE_LALT,
+ SDL_SCANCODE_LGUI
+ };
+ const SDL_Scancode right_mapping[] = {
+ SDL_SCANCODE_RSHIFT,
+ SDL_SCANCODE_RCTRL,
+ SDL_SCANCODE_RALT,
+ SDL_SCANCODE_RGUI
+ };
+ /* Set up arrays for the device dependent masks with indices that
+ * correspond to the _mapping arrays
+ */
+ const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
+ const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
+
+ unsigned int i, bit;
+
+ /* Iterate through the bits, testing each against the old modifiers */
+ for (i = 0, bit = NSEventModifierFlagShift; bit <= NSEventModifierFlagCommand; bit <<= 1, ++i) {
+ unsigned int oldMask, newMask;
+
+ oldMask = oldMods & bit;
+ newMask = newMods & bit;
+
+ /* If the bit is set, we must always examine it because the left
+ * and right side keys may alternate or both may be pressed.
+ */
+ if (newMask) {
+ HandleModifierSide(bit, oldMods, newMods,
+ left_mapping[i], right_mapping[i],
+ left_device_mapping[i], right_device_mapping[i]);
+ }
+ /* If the state changed from pressed to unpressed, we must examine
+ * the device dependent bits to release the correct keys.
+ */
+ else if (oldMask && oldMask != newMask) {
+ ReleaseModifierSide(bit, oldMods, newMods,
+ left_mapping[i], right_mapping[i],
+ left_device_mapping[i], right_device_mapping[i]);
+ }
+ }
+}
+
+static void
+HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (modifierFlags == data->modifierFlags) {
+ return;
+ }
+
+ DoSidedModifiers(scancode, data->modifierFlags, modifierFlags);
+ data->modifierFlags = modifierFlags;
+}
+
+static void
+UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
+{
+ TISInputSourceRef key_layout;
+ const void *chr_data;
+ int i;
+ SDL_Scancode scancode;
+ SDL_Keycode keymap[SDL_NUM_SCANCODES];
+
+ /* See if the keymap needs to be updated */
+ key_layout = TISCopyCurrentKeyboardLayoutInputSource();
+ if (key_layout == data->key_layout) {
+ return;
+ }
+ data->key_layout = key_layout;
+
+ SDL_GetDefaultKeymap(keymap);
+
+ /* Try Unicode data first */
+ CFDataRef uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData);
+ if (uchrDataRef) {
+ chr_data = CFDataGetBytePtr(uchrDataRef);
+ } else {
+ goto cleanup;
+ }
+
+ if (chr_data) {
+ UInt32 keyboard_type = LMGetKbdType();
+ OSStatus err;
+
+ for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) {
+ UniChar s[8];
+ UniCharCount len;
+ UInt32 dead_key_state;
+
+ /* Make sure this scancode is a valid character scancode */
+ scancode = darwin_scancode_table[i];
+ if (scancode == SDL_SCANCODE_UNKNOWN ||
+ (keymap[scancode] & SDLK_SCANCODE_MASK)) {
+ continue;
+ }
+
+ dead_key_state = 0;
+ err = UCKeyTranslate ((UCKeyboardLayout *) chr_data,
+ i, kUCKeyActionDown,
+ 0, keyboard_type,
+ kUCKeyTranslateNoDeadKeysMask,
+ &dead_key_state, 8, &len, s);
+ if (err != noErr) {
+ continue;
+ }
+
+ if (len > 0 && s[0] != 0x10) {
+ keymap[scancode] = s[0];
+ }
+ }
+ SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
+ if (send_event) {
+ SDL_SendKeymapChangedEvent();
+ }
+ return;
+ }
+
+cleanup:
+ CFRelease(key_layout);
+}
+
+void
+Cocoa_InitKeyboard(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ UpdateKeymap(data, SDL_FALSE);
+
+ /* Set our own names for the platform-dependent but layout-independent keys */
+ /* This key is NumLock on the MacBook keyboard. :) */
+ /*SDL_SetScancodeName(SDL_SCANCODE_NUMLOCKCLEAR, "Clear");*/
+ SDL_SetScancodeName(SDL_SCANCODE_LALT, "Left Option");
+ SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Command");
+ SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
+ SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
+
+ data->modifierFlags = [NSEvent modifierFlags];
+ SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSEventModifierFlagCapsLock) != 0);
+
+ InitHIDCallback();
+}
+
+void
+Cocoa_StartTextInput(_THIS)
+{ @autoreleasepool
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ SDL_Window *window = SDL_GetKeyboardFocus();
+ NSWindow *nswindow = nil;
+ if (window) {
+ nswindow = ((SDL_WindowData*)window->driverdata)->nswindow;
+ }
+
+ NSView *parentView = [nswindow contentView];
+
+ /* We only keep one field editor per process, since only the front most
+ * window can receive text input events, so it make no sense to keep more
+ * than one copy. When we switched to another window and requesting for
+ * text input, simply remove the field editor from its superview then add
+ * it to the front most window's content view */
+ if (!data->fieldEdit) {
+ data->fieldEdit =
+ [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)];
+ }
+
+ if (![[data->fieldEdit superview] isEqual:parentView]) {
+ /* DEBUG_IME(@"add fieldEdit to window contentView"); */
+ [data->fieldEdit removeFromSuperview];
+ [parentView addSubview: data->fieldEdit];
+ [nswindow makeFirstResponder: data->fieldEdit];
+ }
+}}
+
+void
+Cocoa_StopTextInput(_THIS)
+{ @autoreleasepool
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (data && data->fieldEdit) {
+ [data->fieldEdit removeFromSuperview];
+ [data->fieldEdit release];
+ data->fieldEdit = nil;
+ }
+}}
+
+void
+Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return;
+ }
+
+ [data->fieldEdit setInputRect:rect];
+}
+
+void
+Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
+{
+ SDL_VideoData *data = _this ? ((SDL_VideoData *) _this->driverdata) : NULL;
+ if (!data) {
+ return; /* can happen when returning from fullscreen Space on shutdown */
+ }
+
+ unsigned short scancode = [event keyCode];
+ SDL_Scancode code;
+#if 0
+ const char *text;
+#endif
+
+ if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
+ /* see comments in SDL_cocoakeys.h */
+ scancode = 60 - scancode;
+ }
+
+ if (scancode < SDL_arraysize(darwin_scancode_table)) {
+ code = darwin_scancode_table[scancode];
+ } else {
+ /* Hmm, does this ever happen? If so, need to extend the keymap... */
+ code = SDL_SCANCODE_UNKNOWN;
+ }
+
+ switch ([event type]) {
+ case NSEventTypeKeyDown:
+ if (![event isARepeat]) {
+ /* See if we need to rebuild the keyboard layout */
+ UpdateKeymap(data, SDL_TRUE);
+ }
+
+ SDL_SendKeyboardKey(SDL_PRESSED, code);
+#if 1
+ if (code == SDL_SCANCODE_UNKNOWN) {
+ fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
+ }
+#endif
+ if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
+ /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */
+ [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
+#if 0
+ text = [[event characters] UTF8String];
+ if(text && *text) {
+ SDL_SendKeyboardText(text);
+ [data->fieldEdit setString:@""];
+ }
+#endif
+ }
+ break;
+ case NSEventTypeKeyUp:
+ SDL_SendKeyboardKey(SDL_RELEASED, code);
+ break;
+ case NSEventTypeFlagsChanged:
+ /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
+ HandleModifiers(_this, scancode, [event modifierFlags]);
+ break;
+ default: /* just to avoid compiler warnings */
+ break;
+ }
+}
+
+void
+Cocoa_QuitKeyboard(_THIS)
+{
+ QuitHIDCallback();
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.h
new file mode 100644
index 0000000..74a815a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.h
@@ -0,0 +1,29 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+extern int Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.m
new file mode 100644
index 0000000..a98237f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamessagebox.m
@@ -0,0 +1,145 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_events.h"
+#include "SDL_timer.h"
+#include "SDL_messagebox.h"
+#include "SDL_cocoavideo.h"
+
+@interface SDLMessageBoxPresenter : NSObject {
+@public
+ NSInteger clicked;
+ NSWindow *nswindow;
+}
+- (id) initWithParentWindow:(SDL_Window *)window;
+- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
+@end
+
+@implementation SDLMessageBoxPresenter
+- (id) initWithParentWindow:(SDL_Window *)window
+{
+ self = [super init];
+ if (self) {
+ clicked = -1;
+
+ /* Retain the NSWindow because we'll show the alert later on the main thread */
+ if (window) {
+ nswindow = [((SDL_WindowData *) window->driverdata)->nswindow retain];
+ } else {
+ nswindow = NULL;
+ }
+ }
+
+ return self;
+}
+
+- (void)showAlert:(NSAlert*)alert
+{
+ if (nswindow) {
+#ifdef MAC_OS_X_VERSION_10_9
+ if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
+ [alert beginSheetModalForWindow:nswindow completionHandler:^(NSModalResponse returnCode) {
+ clicked = returnCode;
+ }];
+ } else
+#endif
+ {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+ [alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
+#endif
+ }
+
+ while (clicked < 0) {
+ SDL_PumpEvents();
+ SDL_Delay(100);
+ }
+
+ [nswindow release];
+ } else {
+ clicked = [alert runModal];
+ }
+}
+
+- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
+{
+ clicked = returnCode;
+}
+
+@end
+
+
+/* Display a Cocoa message box */
+int
+Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{ @autoreleasepool
+{
+ Cocoa_RegisterApp();
+
+ NSAlert* alert = [[[NSAlert alloc] init] autorelease];
+
+ if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
+ [alert setAlertStyle:NSAlertStyleCritical];
+ } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
+ [alert setAlertStyle:NSAlertStyleWarning];
+ } else {
+ [alert setAlertStyle:NSAlertStyleInformational];
+ }
+
+ [alert setMessageText:[NSString stringWithUTF8String:messageboxdata->title]];
+ [alert setInformativeText:[NSString stringWithUTF8String:messageboxdata->message]];
+
+ const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+ int i;
+ for (i = 0; i < messageboxdata->numbuttons; ++i) {
+ NSButton *button = [alert addButtonWithTitle:[NSString stringWithUTF8String:buttons[i].text]];
+ if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
+ [button setKeyEquivalent:@"\r"];
+ } else if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+ [button setKeyEquivalent:@"\033"];
+ } else {
+ [button setKeyEquivalent:@""];
+ }
+ }
+
+ SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
+
+ [presenter performSelectorOnMainThread:@selector(showAlert:)
+ withObject:alert
+ waitUntilDone:YES];
+
+ int returnValue = 0;
+ NSInteger clicked = presenter->clicked;
+ if (clicked >= NSAlertFirstButtonReturn) {
+ clicked -= NSAlertFirstButtonReturn;
+ *buttonid = buttons[clicked].buttonid;
+ } else {
+ returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
+ }
+
+ return returnValue;
+}}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.h
new file mode 100644
index 0000000..185d45d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.h
@@ -0,0 +1,63 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+/*
+ * @author Mark Callow, www.edgewise-consulting.com.
+ *
+ * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
+ * how to add a CAMetalLayer backed view.
+ */
+
+#ifndef SDL_cocoametalview_h_
+#define SDL_cocoametalview_h_
+
+#import "../SDL_sysvideo.h"
+#import "SDL_cocoawindow.h"
+
+#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL)
+
+#import <Cocoa/Cocoa.h>
+#import <Metal/Metal.h>
+#import <QuartzCore/CAMetalLayer.h>
+
+#define METALVIEW_TAG 255
+
+@interface SDL_cocoametalview : NSView
+
+- (instancetype)initWithFrame:(NSRect)frame
+ highDPI:(BOOL)highDPI;
+
+/* Override superclass tag so this class can set it. */
+@property (assign, readonly) NSInteger tag;
+
+@property (nonatomic) BOOL highDPI;
+
+@end
+
+SDL_cocoametalview* Cocoa_Mtl_AddMetalView(SDL_Window* window);
+
+void Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
+
+#endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL) */
+
+#endif /* SDL_cocoametalview_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.m
new file mode 100644
index 0000000..9447fb8
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoametalview.m
@@ -0,0 +1,138 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+/*
+ * @author Mark Callow, www.edgewise-consulting.com.
+ *
+ * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
+ * how to add a CAMetalLayer backed view.
+ */
+
+#import "SDL_cocoametalview.h"
+
+#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL)
+
+#include "SDL_assert.h"
+
+@implementation SDL_cocoametalview
+
+/* Return a Metal-compatible layer. */
++ (Class)layerClass
+{
+ return NSClassFromString(@"CAMetalLayer");
+}
+
+/* Indicate the view wants to draw using a backing layer instead of drawRect. */
+- (BOOL)wantsUpdateLayer
+{
+ return YES;
+}
+
+/* When the wantsLayer property is set to YES, this method will be invoked to
+ * return a layer instance.
+ */
+- (CALayer*)makeBackingLayer
+{
+ return [self.class.layerClass layer];
+}
+
+- (instancetype)initWithFrame:(NSRect)frame
+ highDPI:(BOOL)highDPI
+{
+ if ((self = [super initWithFrame:frame])) {
+ self.highDPI = highDPI;
+ self.wantsLayer = YES;
+
+ /* Allow resize. */
+ self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
+
+ [self updateDrawableSize];
+ }
+
+ return self;
+}
+
+- (NSInteger)tag
+{
+ return METALVIEW_TAG;
+}
+
+- (void)updateDrawableSize
+{
+ CAMetalLayer *metalLayer = (CAMetalLayer *)self.layer;
+ CGSize size = self.bounds.size;
+ CGSize backingSize = size;
+
+ if (self.highDPI) {
+ /* Note: NSHighResolutionCapable must be set to true in the app's
+ * Info.plist in order for the backing size to be high res.
+ */
+ backingSize = [self convertSizeToBacking:size];
+ }
+
+ metalLayer.contentsScale = backingSize.height / size.height;
+ metalLayer.drawableSize = backingSize;
+}
+
+/* Set the size of the metal drawables when the view is resized. */
+- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
+{
+ [super resizeWithOldSuperviewSize:oldSize];
+ [self updateDrawableSize];
+}
+
+@end
+
+SDL_cocoametalview*
+Cocoa_Mtl_AddMetalView(SDL_Window* window)
+{
+ SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata;
+ NSView *view = data->nswindow.contentView;
+ BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
+ SDL_cocoametalview *metalview;
+
+ metalview = [[SDL_cocoametalview alloc] initWithFrame:view.frame highDPI:highDPI];
+ [view addSubview:metalview];
+ return metalview;
+}
+
+void
+Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
+{
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ NSView *view = data->nswindow.contentView;
+ SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
+ if (metalview) {
+ CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
+ assert(layer != NULL);
+ if (w) {
+ *w = layer.drawableSize.width;
+ }
+ if (h) {
+ *h = layer.drawableSize.height;
+ }
+ } else {
+ SDL_GetWindowSize(window, w, h);
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL) */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.h
new file mode 100644
index 0000000..05482e8
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.h
@@ -0,0 +1,46 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoamodes_h_
+#define SDL_cocoamodes_h_
+
+typedef struct
+{
+ CGDirectDisplayID display;
+} SDL_DisplayData;
+
+typedef struct
+{
+ CGDisplayModeRef moderef;
+} SDL_DisplayModeData;
+
+extern void Cocoa_InitModes(_THIS);
+extern int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+extern int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+extern void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hpdi, float * vdpi);
+extern int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void Cocoa_QuitModes(_THIS);
+
+#endif /* SDL_cocoamodes_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.m
new file mode 100644
index 0000000..97ccd94
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamodes.m
@@ -0,0 +1,490 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+#include "SDL_assert.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_cocoavideo.h"
+
+/* We need this for IODisplayCreateInfoDictionary and kIODisplayOnlyPreferredName */
+#include <IOKit/graphics/IOGraphicsLib.h>
+
+/* We need this for CVDisplayLinkGetNominalOutputVideoRefreshPeriod */
+#include <CoreVideo/CVBase.h>
+#include <CoreVideo/CVDisplayLink.h>
+
+/* we need this for ShowMenuBar() and HideMenuBar(). */
+#include <Carbon/Carbon.h>
+
+/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */
+#include <AvailabilityMacros.h>
+
+
+static void
+Cocoa_ToggleMenuBar(const BOOL show)
+{
+ /* !!! FIXME: keep an eye on this.
+ * ShowMenuBar/HideMenuBar is officially unavailable for 64-bit binaries.
+ * It happens to work, as of 10.7, but we're going to see if
+ * we can just simply do without it on newer OSes...
+ */
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__)
+ if (show) {
+ ShowMenuBar();
+ } else {
+ HideMenuBar();
+ }
+#endif
+}
+
+static int
+CG_SetError(const char *prefix, CGDisplayErr result)
+{
+ const char *error;
+
+ switch (result) {
+ case kCGErrorFailure:
+ error = "kCGErrorFailure";
+ break;
+ case kCGErrorIllegalArgument:
+ error = "kCGErrorIllegalArgument";
+ break;
+ case kCGErrorInvalidConnection:
+ error = "kCGErrorInvalidConnection";
+ break;
+ case kCGErrorInvalidContext:
+ error = "kCGErrorInvalidContext";
+ break;
+ case kCGErrorCannotComplete:
+ error = "kCGErrorCannotComplete";
+ break;
+ case kCGErrorNotImplemented:
+ error = "kCGErrorNotImplemented";
+ break;
+ case kCGErrorRangeCheck:
+ error = "kCGErrorRangeCheck";
+ break;
+ case kCGErrorTypeCheck:
+ error = "kCGErrorTypeCheck";
+ break;
+ case kCGErrorInvalidOperation:
+ error = "kCGErrorInvalidOperation";
+ break;
+ case kCGErrorNoneAvailable:
+ error = "kCGErrorNoneAvailable";
+ break;
+ default:
+ error = "Unknown Error";
+ break;
+ }
+ return SDL_SetError("%s: %s", prefix, error);
+}
+
+static SDL_bool
+GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CVDisplayLinkRef link, SDL_DisplayMode *mode)
+{
+ SDL_DisplayModeData *data;
+ int width = 0;
+ int height = 0;
+ int bpp = 0;
+ int refreshRate = 0;
+ CFStringRef fmt;
+
+ data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
+ if (!data) {
+ return SDL_FALSE;
+ }
+ data->moderef = vidmode;
+
+ fmt = CGDisplayModeCopyPixelEncoding(vidmode);
+ width = (int) CGDisplayModeGetWidth(vidmode);
+ height = (int) CGDisplayModeGetHeight(vidmode);
+ refreshRate = (int) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
+
+ if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
+ kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ bpp = 32;
+ } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
+ kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ bpp = 16;
+ } else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
+ kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ bpp = 30;
+ } else {
+ bpp = 0; /* ignore 8-bit and such for now. */
+ }
+
+ CFRelease(fmt);
+
+ /* CGDisplayModeGetRefreshRate returns 0 for many non-CRT displays. */
+ if (refreshRate == 0 && link != NULL) {
+ CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
+ if ((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0) {
+ refreshRate = (int) ((time.timeScale / (double) time.timeValue) + 0.5);
+ }
+ }
+
+ mode->format = SDL_PIXELFORMAT_UNKNOWN;
+ switch (bpp) {
+ case 16:
+ mode->format = SDL_PIXELFORMAT_ARGB1555;
+ break;
+ case 30:
+ mode->format = SDL_PIXELFORMAT_ARGB2101010;
+ break;
+ case 32:
+ mode->format = SDL_PIXELFORMAT_ARGB8888;
+ break;
+ case 8: /* We don't support palettized modes now */
+ default: /* Totally unrecognizable bit depth. */
+ SDL_free(data);
+ return SDL_FALSE;
+ }
+ mode->w = width;
+ mode->h = height;
+ mode->refresh_rate = refreshRate;
+ mode->driverdata = data;
+ return SDL_TRUE;
+}
+
+static const char *
+Cocoa_GetDisplayName(CGDirectDisplayID displayID)
+{
+ CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
+ NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
+ const char* displayName = NULL;
+
+ if ([localizedNames count] > 0) {
+ displayName = SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
+ }
+ CFRelease(deviceInfo);
+ return displayName;
+}
+
+void
+Cocoa_InitModes(_THIS)
+{ @autoreleasepool
+{
+ CGDisplayErr result;
+ CGDirectDisplayID *displays;
+ CGDisplayCount numDisplays;
+ int pass, i;
+
+ result = CGGetOnlineDisplayList(0, NULL, &numDisplays);
+ if (result != kCGErrorSuccess) {
+ CG_SetError("CGGetOnlineDisplayList()", result);
+ return;
+ }
+ displays = SDL_stack_alloc(CGDirectDisplayID, numDisplays);
+ result = CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
+ if (result != kCGErrorSuccess) {
+ CG_SetError("CGGetOnlineDisplayList()", result);
+ SDL_stack_free(displays);
+ return;
+ }
+
+ /* Pick up the primary display in the first pass, then get the rest */
+ for (pass = 0; pass < 2; ++pass) {
+ for (i = 0; i < numDisplays; ++i) {
+ SDL_VideoDisplay display;
+ SDL_DisplayData *displaydata;
+ SDL_DisplayMode mode;
+ CGDisplayModeRef moderef = NULL;
+ CVDisplayLinkRef link = NULL;
+
+ if (pass == 0) {
+ if (!CGDisplayIsMain(displays[i])) {
+ continue;
+ }
+ } else {
+ if (CGDisplayIsMain(displays[i])) {
+ continue;
+ }
+ }
+
+ if (CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay) {
+ continue;
+ }
+
+ moderef = CGDisplayCopyDisplayMode(displays[i]);
+
+ if (!moderef) {
+ continue;
+ }
+
+ displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
+ if (!displaydata) {
+ CGDisplayModeRelease(moderef);
+ continue;
+ }
+ displaydata->display = displays[i];
+
+ CVDisplayLinkCreateWithCGDisplay(displays[i], &link);
+
+ SDL_zero(display);
+ /* this returns a stddup'ed string */
+ display.name = (char *)Cocoa_GetDisplayName(displays[i]);
+ if (!GetDisplayMode(_this, moderef, link, &mode)) {
+ CVDisplayLinkRelease(link);
+ CGDisplayModeRelease(moderef);
+ SDL_free(display.name);
+ SDL_free(displaydata);
+ continue;
+ }
+
+ CVDisplayLinkRelease(link);
+
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ display.driverdata = displaydata;
+ SDL_AddVideoDisplay(&display);
+ SDL_free(display.name);
+ }
+ }
+ SDL_stack_free(displays);
+}}
+
+int
+Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
+{
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
+ CGRect cgrect;
+
+ cgrect = CGDisplayBounds(displaydata->display);
+ rect->x = (int)cgrect.origin.x;
+ rect->y = (int)cgrect.origin.y;
+ rect->w = (int)cgrect.size.width;
+ rect->h = (int)cgrect.size.height;
+ return 0;
+}
+
+int
+Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
+{
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
+ const CGDirectDisplayID cgdisplay = displaydata->display;
+ NSArray *screens = [NSScreen screens];
+ NSScreen *screen = nil;
+
+ /* !!! FIXME: maybe track the NSScreen in SDL_DisplayData? */
+ for (NSScreen *i in screens) {
+ const CGDirectDisplayID thisDisplay = (CGDirectDisplayID) [[[i deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
+ if (thisDisplay == cgdisplay) {
+ screen = i;
+ break;
+ }
+ }
+
+ SDL_assert(screen != nil); /* didn't find it?! */
+ if (screen == nil) {
+ return -1;
+ }
+
+ const CGRect cgrect = CGDisplayBounds(cgdisplay);
+ const NSRect frame = [screen visibleFrame];
+
+ // !!! FIXME: I assume -[NSScreen visibleFrame] is relative to the origin of the screen in question and not the whole desktop.
+ // !!! FIXME: The math vs CGDisplayBounds might be incorrect if that's not the case, though. Check this.
+ rect->x = (int)(cgrect.origin.x + frame.origin.x);
+ rect->y = (int)(cgrect.origin.y + frame.origin.y);
+ rect->w = (int)frame.size.width;
+ rect->h = (int)frame.size.height;
+
+ return 0;
+}
+
+int
+Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
+{
+ const float MM_IN_INCH = 25.4f;
+
+ SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+
+ CGSize displaySize = CGDisplayScreenSize(data->display);
+ int pixelWidth = (int) CGDisplayPixelsWide(data->display);
+ int pixelHeight = (int) CGDisplayPixelsHigh(data->display);
+
+ if (ddpi) {
+ *ddpi = SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH);
+ }
+ if (hdpi) {
+ *hdpi = pixelWidth * MM_IN_INCH / displaySize.width;
+ }
+ if (vdpi) {
+ *vdpi = pixelHeight * MM_IN_INCH / displaySize.height;
+ }
+
+ return 0;
+}
+
+void
+Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+ CVDisplayLinkRef link = NULL;
+ CGDisplayModeRef desktopmoderef;
+ SDL_DisplayMode desktopmode;
+ CFArrayRef modes;
+
+ CVDisplayLinkCreateWithCGDisplay(data->display, &link);
+
+ desktopmoderef = CGDisplayCopyDisplayMode(data->display);
+
+ /* CopyAllDisplayModes won't always contain the desktop display mode (if
+ * NULL is passed in) - for example on a retina 15" MBP, System Preferences
+ * allows choosing 1920x1200 but it's not in the list. AddDisplayMode makes
+ * sure there are no duplicates so it's safe to always add the desktop mode
+ * even in cases where it is in the CopyAllDisplayModes list.
+ */
+ if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, link, &desktopmode)) {
+ if (!SDL_AddDisplayMode(display, &desktopmode)) {
+ CGDisplayModeRelease(desktopmoderef);
+ SDL_free(desktopmode.driverdata);
+ }
+ } else {
+ CGDisplayModeRelease(desktopmoderef);
+ }
+
+ modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
+
+ if (modes) {
+ CFIndex i;
+ const CFIndex count = CFArrayGetCount(modes);
+
+ for (i = 0; i < count; i++) {
+ CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+ SDL_DisplayMode mode;
+
+ if (GetDisplayMode(_this, moderef, link, &mode)) {
+ if (SDL_AddDisplayMode(display, &mode)) {
+ CGDisplayModeRetain(moderef);
+ } else {
+ SDL_free(mode.driverdata);
+ }
+ }
+ }
+
+ CFRelease(modes);
+ }
+
+ CVDisplayLinkRelease(link);
+}
+
+int
+Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
+ SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
+ CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
+ CGError result;
+
+ /* Fade to black to hide resolution-switching flicker */
+ if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
+ CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
+ }
+
+ if (data == display->desktop_mode.driverdata) {
+ /* Restoring desktop mode */
+ CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL);
+
+ if (CGDisplayIsMain(displaydata->display)) {
+ CGReleaseAllDisplays();
+ } else {
+ CGDisplayRelease(displaydata->display);
+ }
+
+ if (CGDisplayIsMain(displaydata->display)) {
+ Cocoa_ToggleMenuBar(YES);
+ }
+ } else {
+ /* Put up the blanking window (a window above all other windows) */
+ if (CGDisplayIsMain(displaydata->display)) {
+ /* If we don't capture all displays, Cocoa tries to rearrange windows... *sigh* */
+ result = CGCaptureAllDisplays();
+ } else {
+ result = CGDisplayCapture(displaydata->display);
+ }
+ if (result != kCGErrorSuccess) {
+ CG_SetError("CGDisplayCapture()", result);
+ goto ERR_NO_CAPTURE;
+ }
+
+ /* Do the physical switch */
+ result = CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL);
+ if (result != kCGErrorSuccess) {
+ CG_SetError("CGDisplaySwitchToMode()", result);
+ goto ERR_NO_SWITCH;
+ }
+
+ /* Hide the menu bar so it doesn't intercept events */
+ if (CGDisplayIsMain(displaydata->display)) {
+ Cocoa_ToggleMenuBar(NO);
+ }
+ }
+
+ /* Fade in again (asynchronously) */
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation(fade_token);
+ }
+
+ return 0;
+
+ /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
+ERR_NO_SWITCH:
+ CGDisplayRelease(displaydata->display);
+ERR_NO_CAPTURE:
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation(fade_token);
+ }
+ return -1;
+}
+
+void
+Cocoa_QuitModes(_THIS)
+{
+ int i, j;
+
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+ SDL_DisplayModeData *mode;
+
+ if (display->current_mode.driverdata != display->desktop_mode.driverdata) {
+ Cocoa_SetDisplayMode(_this, display, &display->desktop_mode);
+ }
+
+ mode = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
+ CGDisplayModeRelease(mode->moderef);
+
+ for (j = 0; j < display->num_display_modes; j++) {
+ mode = (SDL_DisplayModeData*) display->display_modes[j].driverdata;
+ CGDisplayModeRelease(mode->moderef);
+ }
+
+ }
+ Cocoa_ToggleMenuBar(YES);
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.h
new file mode 100644
index 0000000..b79a3cf
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.h
@@ -0,0 +1,52 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoamouse_h_
+#define SDL_cocoamouse_h_
+
+#include "SDL_cocoavideo.h"
+
+extern void Cocoa_InitMouse(_THIS);
+extern void Cocoa_HandleMouseEvent(_THIS, NSEvent * event);
+extern void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent * event);
+extern void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y);
+extern void Cocoa_QuitMouse(_THIS);
+
+typedef struct {
+ /* Wether we've seen a cursor warp since the last move event. */
+ SDL_bool seenWarp;
+ /* What location our last cursor warp was to. */
+ CGFloat lastWarpX;
+ CGFloat lastWarpY;
+ /* What location we last saw the cursor move to. */
+ CGFloat lastMoveX;
+ CGFloat lastMoveY;
+ void *tapdata;
+} SDL_MouseData;
+
+@interface NSCursor (InvisibleCursor)
++ (NSCursor *)invisibleCursor;
+@end
+
+#endif /* SDL_cocoamouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.m
new file mode 100644
index 0000000..c9db253
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamouse.m
@@ -0,0 +1,477 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_assert.h"
+#include "SDL_events.h"
+#include "SDL_cocoamouse.h"
+#include "SDL_cocoamousetap.h"
+#include "SDL_cocoavideo.h"
+
+#include "../../events/SDL_mouse_c.h"
+
+/* #define DEBUG_COCOAMOUSE */
+
+#ifdef DEBUG_COCOAMOUSE
+#define DLog(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
+#else
+#define DLog(...) do { } while (0)
+#endif
+
+@implementation NSCursor (InvisibleCursor)
++ (NSCursor *)invisibleCursor
+{
+ static NSCursor *invisibleCursor = NULL;
+ if (!invisibleCursor) {
+ /* RAW 16x16 transparent GIF */
+ static unsigned char cursorBytes[] = {
+ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
+ 0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED,
+ 0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B
+ };
+
+ NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
+ length:sizeof(cursorBytes)
+ freeWhenDone:NO];
+ NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
+ invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
+ hotSpot:NSZeroPoint];
+ }
+
+ return invisibleCursor;
+}
+@end
+
+
+static SDL_Cursor *
+Cocoa_CreateDefaultCursor()
+{ @autoreleasepool
+{
+ NSCursor *nscursor;
+ SDL_Cursor *cursor = NULL;
+
+ nscursor = [NSCursor arrowCursor];
+
+ if (nscursor) {
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ cursor->driverdata = nscursor;
+ [nscursor retain];
+ }
+ }
+
+ return cursor;
+}}
+
+static SDL_Cursor *
+Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{ @autoreleasepool
+{
+ NSImage *nsimage;
+ NSCursor *nscursor = NULL;
+ SDL_Cursor *cursor = NULL;
+
+ nsimage = Cocoa_CreateImage(surface);
+ if (nsimage) {
+ nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
+ }
+
+ if (nscursor) {
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ cursor->driverdata = nscursor;
+ } else {
+ [nscursor release];
+ }
+ }
+
+ return cursor;
+}}
+
+static SDL_Cursor *
+Cocoa_CreateSystemCursor(SDL_SystemCursor id)
+{ @autoreleasepool
+{
+ NSCursor *nscursor = NULL;
+ SDL_Cursor *cursor = NULL;
+
+ switch(id) {
+ case SDL_SYSTEM_CURSOR_ARROW:
+ nscursor = [NSCursor arrowCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_IBEAM:
+ nscursor = [NSCursor IBeamCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_WAIT:
+ nscursor = [NSCursor arrowCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR:
+ nscursor = [NSCursor crosshairCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_WAITARROW:
+ nscursor = [NSCursor arrowCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE:
+ case SDL_SYSTEM_CURSOR_SIZENESW:
+ nscursor = [NSCursor closedHandCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEWE:
+ nscursor = [NSCursor resizeLeftRightCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENS:
+ nscursor = [NSCursor resizeUpDownCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEALL:
+ nscursor = [NSCursor closedHandCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_NO:
+ nscursor = [NSCursor operationNotAllowedCursor];
+ break;
+ case SDL_SYSTEM_CURSOR_HAND:
+ nscursor = [NSCursor pointingHandCursor];
+ break;
+ default:
+ SDL_assert(!"Unknown system cursor");
+ return NULL;
+ }
+
+ if (nscursor) {
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ /* We'll free it later, so retain it here */
+ [nscursor retain];
+ cursor->driverdata = nscursor;
+ }
+ }
+
+ return cursor;
+}}
+
+static void
+Cocoa_FreeCursor(SDL_Cursor * cursor)
+{ @autoreleasepool
+{
+ NSCursor *nscursor = (NSCursor *)cursor->driverdata;
+
+ [nscursor release];
+ SDL_free(cursor);
+}}
+
+static int
+Cocoa_ShowCursor(SDL_Cursor * cursor)
+{ @autoreleasepool
+{
+ SDL_VideoDevice *device = SDL_GetVideoDevice();
+ SDL_Window *window = (device ? device->windows : NULL);
+ for (; window != NULL; window = window->next) {
+ SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata;
+ if (driverdata) {
+ [driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
+ withObject:[driverdata->nswindow contentView]
+ waitUntilDone:NO];
+ }
+ }
+ return 0;
+}}
+
+static SDL_Window *
+SDL_FindWindowAtPoint(const int x, const int y)
+{
+ const SDL_Point pt = { x, y };
+ SDL_Window *i;
+ for (i = SDL_GetVideoDevice()->windows; i; i = i->next) {
+ const SDL_Rect r = { i->x, i->y, i->w, i->h };
+ if (SDL_PointInRect(&pt, &r)) {
+ return i;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+Cocoa_WarpMouseGlobal(int x, int y)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if (mouse->focus) {
+ SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata;
+ if ([data->listener isMoving]) {
+ DLog("Postponing warp, window being moved.");
+ [data->listener setPendingMoveX:x Y:y];
+ return 0;
+ }
+ }
+ const CGPoint point = CGPointMake((float)x, (float)y);
+
+ Cocoa_HandleMouseWarp(point.x, point.y);
+
+ CGWarpMouseCursorPosition(point);
+
+ /* CGWarpMouse causes a short delay by default, which is preventable by
+ * Calling this directly after. CGSetLocalEventsSuppressionInterval can also
+ * prevent it, but it's deprecated as of OS X 10.6.
+ */
+ if (!mouse->relative_mode) {
+ CGAssociateMouseAndMouseCursorPosition(YES);
+ }
+
+ /* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
+ * other implementations' APIs. Send what's appropriate.
+ */
+ if (!mouse->relative_mode) {
+ SDL_Window *win = SDL_FindWindowAtPoint(x, y);
+ SDL_SetMouseFocus(win);
+ if (win) {
+ SDL_assert(win == mouse->focus);
+ SDL_SendMouseMotion(win, mouse->mouseID, 0, x - win->x, y - win->y);
+ }
+ }
+
+ return 0;
+}
+
+static void
+Cocoa_WarpMouse(SDL_Window * window, int x, int y)
+{
+ Cocoa_WarpMouseGlobal(x + window->x, y + window->y);
+}
+
+static int
+Cocoa_SetRelativeMouseMode(SDL_bool enabled)
+{
+ /* We will re-apply the relative mode when the window gets focus, if it
+ * doesn't have focus right now.
+ */
+ SDL_Window *window = SDL_GetMouseFocus();
+ if (!window) {
+ return 0;
+ }
+
+ /* We will re-apply the relative mode when the window finishes being moved,
+ * if it is being moved right now.
+ */
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ if ([data->listener isMoving]) {
+ return 0;
+ }
+
+ CGError result;
+ if (enabled) {
+ DLog("Turning on.");
+ result = CGAssociateMouseAndMouseCursorPosition(NO);
+ } else {
+ DLog("Turning off.");
+ result = CGAssociateMouseAndMouseCursorPosition(YES);
+ }
+ if (result != kCGErrorSuccess) {
+ return SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
+ }
+
+ /* The hide/unhide calls are redundant most of the time, but they fix
+ * https://bugzilla.libsdl.org/show_bug.cgi?id=2550
+ */
+ if (enabled) {
+ [NSCursor hide];
+ } else {
+ [NSCursor unhide];
+ }
+ return 0;
+}
+
+static int
+Cocoa_CaptureMouse(SDL_Window *window)
+{
+ /* our Cocoa event code already tracks the mouse outside the window,
+ so all we have to do here is say "okay" and do what we always do. */
+ return 0;
+}
+
+static Uint32
+Cocoa_GetGlobalMouseState(int *x, int *y)
+{
+ const NSUInteger cocoaButtons = [NSEvent pressedMouseButtons];
+ const NSPoint cocoaLocation = [NSEvent mouseLocation];
+ Uint32 retval = 0;
+
+ for (NSScreen *screen in [NSScreen screens]) {
+ NSRect frame = [screen frame];
+ if (NSMouseInRect(cocoaLocation, frame, NO)) {
+ *x = (int) cocoaLocation.x;
+ *y = (int) ((frame.origin.y + frame.size.height) - cocoaLocation.y);
+ break;
+ }
+ }
+
+ retval |= (cocoaButtons & (1 << 0)) ? SDL_BUTTON_LMASK : 0;
+ retval |= (cocoaButtons & (1 << 1)) ? SDL_BUTTON_RMASK : 0;
+ retval |= (cocoaButtons & (1 << 2)) ? SDL_BUTTON_MMASK : 0;
+ retval |= (cocoaButtons & (1 << 3)) ? SDL_BUTTON_X1MASK : 0;
+ retval |= (cocoaButtons & (1 << 4)) ? SDL_BUTTON_X2MASK : 0;
+
+ return retval;
+}
+
+void
+Cocoa_InitMouse(_THIS)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->driverdata = SDL_calloc(1, sizeof(SDL_MouseData));
+
+ mouse->CreateCursor = Cocoa_CreateCursor;
+ mouse->CreateSystemCursor = Cocoa_CreateSystemCursor;
+ mouse->ShowCursor = Cocoa_ShowCursor;
+ mouse->FreeCursor = Cocoa_FreeCursor;
+ mouse->WarpMouse = Cocoa_WarpMouse;
+ mouse->WarpMouseGlobal = Cocoa_WarpMouseGlobal;
+ mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
+ mouse->CaptureMouse = Cocoa_CaptureMouse;
+ mouse->GetGlobalMouseState = Cocoa_GetGlobalMouseState;
+
+ SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
+
+ Cocoa_InitMouseEventTap(mouse->driverdata);
+
+ SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
+ const NSPoint location = [NSEvent mouseLocation];
+ driverdata->lastMoveX = location.x;
+ driverdata->lastMoveY = location.y;
+}
+
+void
+Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
+{
+ switch ([event type]) {
+ case NSEventTypeMouseMoved:
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
+ case NSEventTypeOtherMouseDragged:
+ break;
+
+ default:
+ /* Ignore any other events. */
+ return;
+ }
+
+ SDL_Mouse *mouse = SDL_GetMouse();
+ SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
+ if (!driverdata) {
+ return; /* can happen when returning from fullscreen Space on shutdown */
+ }
+
+ const SDL_bool seenWarp = driverdata->seenWarp;
+ driverdata->seenWarp = NO;
+
+ const NSPoint location = [NSEvent mouseLocation];
+ const CGFloat lastMoveX = driverdata->lastMoveX;
+ const CGFloat lastMoveY = driverdata->lastMoveY;
+ driverdata->lastMoveX = location.x;
+ driverdata->lastMoveY = location.y;
+ DLog("Last seen mouse: (%g, %g)", location.x, location.y);
+
+ /* Non-relative movement is handled in -[Cocoa_WindowListener mouseMoved:] */
+ if (!mouse->relative_mode) {
+ return;
+ }
+
+ /* Ignore events that aren't inside the client area (i.e. title bar.) */
+ if ([event window]) {
+ NSRect windowRect = [[[event window] contentView] frame];
+ if (!NSMouseInRect([event locationInWindow], windowRect, NO)) {
+ return;
+ }
+ }
+
+ float deltaX = [event deltaX];
+ float deltaY = [event deltaY];
+
+ if (seenWarp) {
+ deltaX += (lastMoveX - driverdata->lastWarpX);
+ deltaY += ((CGDisplayPixelsHigh(kCGDirectMainDisplay) - lastMoveY) - driverdata->lastWarpY);
+
+ DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
+ }
+
+ SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)deltaX, (int)deltaY);
+}
+
+void
+Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ CGFloat x = -[event deltaX];
+ CGFloat y = [event deltaY];
+ SDL_MouseWheelDirection direction = SDL_MOUSEWHEEL_NORMAL;
+
+ if ([event respondsToSelector:@selector(isDirectionInvertedFromDevice)]) {
+ if ([event isDirectionInvertedFromDevice] == YES) {
+ direction = SDL_MOUSEWHEEL_FLIPPED;
+ }
+ }
+
+ if (x > 0) {
+ x = SDL_ceil(x);
+ } else if (x < 0) {
+ x = SDL_floor(x);
+ }
+ if (y > 0) {
+ y = SDL_ceil(y);
+ } else if (y < 0) {
+ y = SDL_floor(y);
+ }
+ SDL_SendMouseWheel(window, mouse->mouseID, x, y, direction);
+}
+
+void
+Cocoa_HandleMouseWarp(CGFloat x, CGFloat y)
+{
+ /* This makes Cocoa_HandleMouseEvent ignore the delta caused by the warp,
+ * since it gets included in the next movement event.
+ */
+ SDL_MouseData *driverdata = (SDL_MouseData*)SDL_GetMouse()->driverdata;
+ driverdata->lastWarpX = x;
+ driverdata->lastWarpY = y;
+ driverdata->seenWarp = SDL_TRUE;
+
+ DLog("(%g, %g)", x, y);
+}
+
+void
+Cocoa_QuitMouse(_THIS)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if (mouse) {
+ if (mouse->driverdata) {
+ Cocoa_QuitMouseEventTap(((SDL_MouseData*)mouse->driverdata));
+ }
+
+ SDL_free(mouse->driverdata);
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.h
new file mode 100644
index 0000000..40ce386
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.h
@@ -0,0 +1,34 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoamousetap_h_
+#define SDL_cocoamousetap_h_
+
+#include "SDL_cocoamouse.h"
+
+extern void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata);
+extern void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled);
+extern void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata);
+
+#endif /* SDL_cocoamousetap_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.m
new file mode 100644
index 0000000..aa4f152
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoamousetap.m
@@ -0,0 +1,286 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_cocoamousetap.h"
+
+/* Event taps are forbidden in the Mac App Store, so we can only enable this
+ * code if your app doesn't need to ship through the app store.
+ * This code makes it so that a grabbed cursor cannot "leak" a mouse click
+ * past the edge of the window if moving the cursor too fast.
+ */
+#if SDL_MAC_NO_SANDBOX
+
+#include "SDL_keyboard.h"
+#include "SDL_cocoavideo.h"
+#include "../../thread/SDL_systhread.h"
+
+#include "../../events/SDL_mouse_c.h"
+
+typedef struct {
+ CFMachPortRef tap;
+ CFRunLoopRef runloop;
+ CFRunLoopSourceRef runloopSource;
+ SDL_Thread *thread;
+ SDL_sem *runloopStartedSemaphore;
+} SDL_MouseEventTapData;
+
+static const CGEventMask movementEventsMask =
+ CGEventMaskBit(kCGEventLeftMouseDragged)
+ | CGEventMaskBit(kCGEventRightMouseDragged)
+ | CGEventMaskBit(kCGEventMouseMoved);
+
+static const CGEventMask allGrabbedEventsMask =
+ CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp)
+ | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp)
+ | CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp)
+ | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged)
+ | CGEventMaskBit(kCGEventMouseMoved);
+
+static CGEventRef
+Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
+{
+ SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)refcon;
+ SDL_Mouse *mouse = SDL_GetMouse();
+ SDL_Window *window = SDL_GetKeyboardFocus();
+ NSWindow *nswindow;
+ NSRect windowRect;
+ CGPoint eventLocation;
+
+ switch (type) {
+ case kCGEventTapDisabledByTimeout:
+ {
+ CGEventTapEnable(tapdata->tap, true);
+ return NULL;
+ }
+ case kCGEventTapDisabledByUserInput:
+ {
+ return NULL;
+ }
+ default:
+ break;
+ }
+
+
+ if (!window || !mouse) {
+ return event;
+ }
+
+ if (mouse->relative_mode) {
+ return event;
+ }
+
+ if (!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
+ return event;
+ }
+
+ /* This is the same coordinate system as Cocoa uses. */
+ nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+ eventLocation = CGEventGetUnflippedLocation(event);
+ windowRect = [nswindow contentRectForFrameRect:[nswindow frame]];
+
+ if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) {
+
+ /* This is in CGs global screenspace coordinate system, which has a
+ * flipped Y.
+ */
+ CGPoint newLocation = CGEventGetLocation(event);
+
+ if (eventLocation.x < NSMinX(windowRect)) {
+ newLocation.x = NSMinX(windowRect);
+ } else if (eventLocation.x >= NSMaxX(windowRect)) {
+ newLocation.x = NSMaxX(windowRect) - 1.0;
+ }
+
+ if (eventLocation.y <= NSMinY(windowRect)) {
+ newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1);
+ } else if (eventLocation.y > NSMaxY(windowRect)) {
+ newLocation.y += (eventLocation.y - NSMaxY(windowRect));
+ }
+
+ CGWarpMouseCursorPosition(newLocation);
+ CGAssociateMouseAndMouseCursorPosition(YES);
+
+ if ((CGEventMaskBit(type) & movementEventsMask) == 0) {
+ /* For click events, we just constrain the event to the window, so
+ * no other app receives the click event. We can't due the same to
+ * movement events, since they mean that our warp cursor above
+ * behaves strangely.
+ */
+ CGEventSetLocation(event, newLocation);
+ }
+ }
+
+ return event;
+}
+
+static void
+SemaphorePostCallback(CFRunLoopTimerRef timer, void *info)
+{
+ SDL_SemPost((SDL_sem*)info);
+}
+
+static int
+Cocoa_MouseTapThread(void *data)
+{
+ SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)data;
+
+ /* Tap was created on main thread but we own it now. */
+ CFMachPortRef eventTap = tapdata->tap;
+ if (eventTap) {
+ /* Try to create a runloop source we can schedule. */
+ CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
+ if (runloopSource) {
+ tapdata->runloopSource = runloopSource;
+ } else {
+ CFRelease(eventTap);
+ SDL_SemPost(tapdata->runloopStartedSemaphore);
+ /* TODO: Both here and in the return below, set some state in
+ * tapdata to indicate that initialization failed, which we should
+ * check in InitMouseEventTap, after we move the semaphore check
+ * from Quit to Init.
+ */
+ return 1;
+ }
+ } else {
+ SDL_SemPost(tapdata->runloopStartedSemaphore);
+ return 1;
+ }
+
+ tapdata->runloop = CFRunLoopGetCurrent();
+ CFRunLoopAddSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
+ CFRunLoopTimerContext context = {.info = tapdata->runloopStartedSemaphore};
+ /* We signal the runloop started semaphore *after* the run loop has started, indicating it's safe to CFRunLoopStop it. */
+ CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, &SemaphorePostCallback, &context);
+ CFRunLoopAddTimer(tapdata->runloop, timer, kCFRunLoopCommonModes);
+ CFRelease(timer);
+
+ /* Run the event loop to handle events in the event tap. */
+ CFRunLoopRun();
+ /* Make sure this is signaled so that SDL_QuitMouseEventTap knows it can safely SDL_WaitThread for us. */
+ if (SDL_SemValue(tapdata->runloopStartedSemaphore) < 1) {
+ SDL_SemPost(tapdata->runloopStartedSemaphore);
+ }
+ CFRunLoopRemoveSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
+
+ /* Clean up. */
+ CGEventTapEnable(tapdata->tap, false);
+ CFRelease(tapdata->runloopSource);
+ CFRelease(tapdata->tap);
+ tapdata->runloopSource = NULL;
+ tapdata->tap = NULL;
+
+ return 0;
+}
+
+void
+Cocoa_InitMouseEventTap(SDL_MouseData* driverdata)
+{
+ SDL_MouseEventTapData *tapdata;
+ driverdata->tapdata = SDL_calloc(1, sizeof(SDL_MouseEventTapData));
+ tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
+
+ tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
+ if (tapdata->runloopStartedSemaphore) {
+ tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
+ kCGEventTapOptionDefault, allGrabbedEventsMask,
+ &Cocoa_MouseTapCallback, tapdata);
+ if (tapdata->tap) {
+ /* Tap starts disabled, until app requests mouse grab */
+ CGEventTapEnable(tapdata->tap, false);
+ tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
+ if (tapdata->thread) {
+ /* Success - early out. Ownership transferred to thread. */
+ return;
+ }
+ CFRelease(tapdata->tap);
+ }
+ SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
+ }
+ SDL_free(driverdata->tapdata);
+ driverdata->tapdata = NULL;
+}
+
+void
+Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
+{
+ SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
+ if (tapdata && tapdata->tap)
+ {
+ CGEventTapEnable(tapdata->tap, !!enabled);
+ }
+}
+
+void
+Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
+{
+ SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
+ int status;
+
+ if (tapdata == NULL) {
+ /* event tap was already cleaned up (possibly due to CGEventTapCreate
+ * returning null.)
+ */
+ return;
+ }
+
+ /* Ensure that the runloop has been started first.
+ * TODO: Move this to InitMouseEventTap, check for error conditions that can
+ * happen in Cocoa_MouseTapThread, and fall back to the non-EventTap way of
+ * grabbing the mouse if it fails to Init.
+ */
+ status = SDL_SemWaitTimeout(tapdata->runloopStartedSemaphore, 5000);
+ if (status > -1) {
+ /* Then stop it, which will cause Cocoa_MouseTapThread to return. */
+ CFRunLoopStop(tapdata->runloop);
+ /* And then wait for Cocoa_MouseTapThread to finish cleaning up. It
+ * releases some of the pointers in tapdata. */
+ SDL_WaitThread(tapdata->thread, &status);
+ }
+
+ SDL_free(driverdata->tapdata);
+ driverdata->tapdata = NULL;
+}
+
+#else /* SDL_MAC_NO_SANDBOX */
+
+void
+Cocoa_InitMouseEventTap(SDL_MouseData *unused)
+{
+}
+
+void
+Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
+{
+}
+
+void
+Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
+{
+}
+
+#endif /* !SDL_MAC_NO_SANDBOX */
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.h
new file mode 100644
index 0000000..81ca5ed
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.h
@@ -0,0 +1,68 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoaopengl_h_
+#define SDL_cocoaopengl_h_
+
+#if SDL_VIDEO_OPENGL_CGL
+
+#include "SDL_atomic.h"
+#import <Cocoa/Cocoa.h>
+
+struct SDL_GLDriverData
+{
+ int initialized;
+};
+
+@interface SDLOpenGLContext : NSOpenGLContext {
+ SDL_atomic_t dirty;
+ SDL_Window *window;
+}
+
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format
+ shareContext:(NSOpenGLContext *)share;
+- (void)scheduleUpdate;
+- (void)updateIfNeeded;
+- (void)setWindow:(SDL_Window *)window;
+
+@end
+
+
+/* OpenGL functions */
+extern int Cocoa_GL_LoadLibrary(_THIS, const char *path);
+extern void *Cocoa_GL_GetProcAddress(_THIS, const char *proc);
+extern void Cocoa_GL_UnloadLibrary(_THIS);
+extern SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window);
+extern int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern void Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window,
+ int * w, int * h);
+extern int Cocoa_GL_SetSwapInterval(_THIS, int interval);
+extern int Cocoa_GL_GetSwapInterval(_THIS);
+extern int Cocoa_GL_SwapWindow(_THIS, SDL_Window * window);
+extern void Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_OPENGL_CGL */
+
+#endif /* SDL_cocoaopengl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.m
new file mode 100644
index 0000000..9539c17
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengl.m
@@ -0,0 +1,436 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+/* NSOpenGL implementation of SDL OpenGL support */
+
+#if SDL_VIDEO_OPENGL_CGL
+#include "SDL_cocoavideo.h"
+#include "SDL_cocoaopengl.h"
+#include "SDL_cocoaopengles.h"
+
+#include <OpenGL/CGLTypes.h>
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/CGLRenderers.h>
+
+#include "SDL_loadso.h"
+#include "SDL_opengl.h"
+
+#define DEFAULT_OPENGL "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
+
+@implementation SDLOpenGLContext : NSOpenGLContext
+
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format
+ shareContext:(NSOpenGLContext *)share
+{
+ self = [super initWithFormat:format shareContext:share];
+ if (self) {
+ SDL_AtomicSet(&self->dirty, 0);
+ self->window = NULL;
+ }
+ return self;
+}
+
+- (void)scheduleUpdate
+{
+ SDL_AtomicAdd(&self->dirty, 1);
+}
+
+/* This should only be called on the thread on which a user is using the context. */
+- (void)updateIfNeeded
+{
+ int value = SDL_AtomicSet(&self->dirty, 0);
+ if (value > 0) {
+ /* We call the real underlying update here, since -[SDLOpenGLContext update] just calls us. */
+ [super update];
+ }
+}
+
+/* This should only be called on the thread on which a user is using the context. */
+- (void)update
+{
+ /* This ensures that regular 'update' calls clear the atomic dirty flag. */
+ [self scheduleUpdate];
+ [self updateIfNeeded];
+}
+
+/* Updates the drawable for the contexts and manages related state. */
+- (void)setWindow:(SDL_Window *)newWindow
+{
+ if (self->window) {
+ SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata;
+
+ /* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */
+ NSMutableArray *contexts = oldwindowdata->nscontexts;
+ @synchronized (contexts) {
+ [contexts removeObject:self];
+ }
+ }
+
+ self->window = newWindow;
+
+ if (newWindow) {
+ SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata;
+
+ /* Now sign up for scheduled updates for the new window. */
+ NSMutableArray *contexts = windowdata->nscontexts;
+ @synchronized (contexts) {
+ [contexts addObject:self];
+ }
+
+ if ([self view] != [windowdata->nswindow contentView]) {
+ [self setView:[windowdata->nswindow contentView]];
+ if (self == [NSOpenGLContext currentContext]) {
+ [self update];
+ } else {
+ [self scheduleUpdate];
+ }
+ }
+ } else {
+ [self clearDrawable];
+ if (self == [NSOpenGLContext currentContext]) {
+ [self update];
+ } else {
+ [self scheduleUpdate];
+ }
+ }
+}
+
+@end
+
+
+int
+Cocoa_GL_LoadLibrary(_THIS, const char *path)
+{
+ /* Load the OpenGL library */
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ }
+ if (path == NULL) {
+ path = DEFAULT_OPENGL;
+ }
+ _this->gl_config.dll_handle = SDL_LoadObject(path);
+ if (!_this->gl_config.dll_handle) {
+ return -1;
+ }
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+ return 0;
+}
+
+void *
+Cocoa_GL_GetProcAddress(_THIS, const char *proc)
+{
+ return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
+}
+
+void
+Cocoa_GL_UnloadLibrary(_THIS)
+{
+ SDL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+}
+
+SDL_GLContext
+Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
+ SDL_bool lion_or_later = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
+ NSOpenGLPixelFormatAttribute attr[32];
+ NSOpenGLPixelFormat *fmt;
+ SDLOpenGLContext *context;
+ NSOpenGLContext *share_context = nil;
+ int i = 0;
+ const char *glversion;
+ int glversion_major;
+ int glversion_minor;
+
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+#if SDL_VIDEO_OPENGL_EGL
+ /* Switch to EGL based functions */
+ Cocoa_GL_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = Cocoa_GLES_LoadLibrary;
+ _this->GL_GetProcAddress = Cocoa_GLES_GetProcAddress;
+ _this->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary;
+ _this->GL_CreateContext = Cocoa_GLES_CreateContext;
+ _this->GL_MakeCurrent = Cocoa_GLES_MakeCurrent;
+ _this->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval;
+ _this->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval;
+ _this->GL_SwapWindow = Cocoa_GLES_SwapWindow;
+ _this->GL_DeleteContext = Cocoa_GLES_DeleteContext;
+
+ if (Cocoa_GLES_LoadLibrary(_this, NULL) != 0) {
+ return NULL;
+ }
+ return Cocoa_GLES_CreateContext(_this, window);
+#else
+ SDL_SetError("SDL not configured with EGL support");
+ return NULL;
+#endif
+ }
+ if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) && !lion_or_later) {
+ SDL_SetError ("OpenGL Core Profile is not supported on this platform version");
+ return NULL;
+ }
+
+ attr[i++] = NSOpenGLPFAAllowOfflineRenderers;
+
+ /* specify a profile if we're on Lion (10.7) or later. */
+ if (lion_or_later) {
+ NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy;
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) {
+ profile = NSOpenGLProfileVersion3_2Core;
+ }
+ attr[i++] = NSOpenGLPFAOpenGLProfile;
+ attr[i++] = profile;
+ }
+
+ attr[i++] = NSOpenGLPFAColorSize;
+ attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;
+
+ attr[i++] = NSOpenGLPFADepthSize;
+ attr[i++] = _this->gl_config.depth_size;
+
+ if (_this->gl_config.double_buffer) {
+ attr[i++] = NSOpenGLPFADoubleBuffer;
+ }
+
+ if (_this->gl_config.stereo) {
+ attr[i++] = NSOpenGLPFAStereo;
+ }
+
+ if (_this->gl_config.stencil_size) {
+ attr[i++] = NSOpenGLPFAStencilSize;
+ attr[i++] = _this->gl_config.stencil_size;
+ }
+
+ if ((_this->gl_config.accum_red_size +
+ _this->gl_config.accum_green_size +
+ _this->gl_config.accum_blue_size +
+ _this->gl_config.accum_alpha_size) > 0) {
+ attr[i++] = NSOpenGLPFAAccumSize;
+ attr[i++] = _this->gl_config.accum_red_size + _this->gl_config.accum_green_size + _this->gl_config.accum_blue_size + _this->gl_config.accum_alpha_size;
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ attr[i++] = NSOpenGLPFASampleBuffers;
+ attr[i++] = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ attr[i++] = NSOpenGLPFASamples;
+ attr[i++] = _this->gl_config.multisamplesamples;
+ attr[i++] = NSOpenGLPFANoRecovery;
+ }
+
+ if (_this->gl_config.accelerated >= 0) {
+ if (_this->gl_config.accelerated) {
+ attr[i++] = NSOpenGLPFAAccelerated;
+ } else {
+ attr[i++] = NSOpenGLPFARendererID;
+ attr[i++] = kCGLRendererGenericFloatID;
+ }
+ }
+
+ attr[i++] = NSOpenGLPFAScreenMask;
+ attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
+ attr[i] = 0;
+
+ fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
+ if (fmt == nil) {
+ SDL_SetError("Failed creating OpenGL pixel format");
+ return NULL;
+ }
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+ }
+
+ context = [[SDLOpenGLContext alloc] initWithFormat:fmt shareContext:share_context];
+
+ [fmt release];
+
+ if (context == nil) {
+ SDL_SetError("Failed creating OpenGL context");
+ return NULL;
+ }
+
+ if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
+ Cocoa_GL_DeleteContext(_this, context);
+ SDL_SetError("Failed making OpenGL context current");
+ return NULL;
+ }
+
+ if (_this->gl_config.major_version < 3 &&
+ _this->gl_config.profile_mask == 0 &&
+ _this->gl_config.flags == 0) {
+ /* This is a legacy profile, so to match other backends, we're done. */
+ } else {
+ const GLubyte *(APIENTRY * glGetStringFunc)(GLenum);
+
+ glGetStringFunc = (const GLubyte *(APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glGetString");
+ if (!glGetStringFunc) {
+ Cocoa_GL_DeleteContext(_this, context);
+ SDL_SetError ("Failed getting OpenGL glGetString entry point");
+ return NULL;
+ }
+
+ glversion = (const char *)glGetStringFunc(GL_VERSION);
+ if (glversion == NULL) {
+ Cocoa_GL_DeleteContext(_this, context);
+ SDL_SetError ("Failed getting OpenGL context version");
+ return NULL;
+ }
+
+ if (SDL_sscanf(glversion, "%d.%d", &glversion_major, &glversion_minor) != 2) {
+ Cocoa_GL_DeleteContext(_this, context);
+ SDL_SetError ("Failed parsing OpenGL context version");
+ return NULL;
+ }
+
+ if ((glversion_major < _this->gl_config.major_version) ||
+ ((glversion_major == _this->gl_config.major_version) && (glversion_minor < _this->gl_config.minor_version))) {
+ Cocoa_GL_DeleteContext(_this, context);
+ SDL_SetError ("Failed creating OpenGL context at version requested");
+ return NULL;
+ }
+
+ /* In the future we'll want to do this, but to match other platforms
+ we'll leave the OpenGL version the way it is for now
+ */
+ /*_this->gl_config.major_version = glversion_major;*/
+ /*_this->gl_config.minor_version = glversion_minor;*/
+ }
+ return context;
+}}
+
+int
+Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{ @autoreleasepool
+{
+ if (context) {
+ SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
+ [nscontext setWindow:window];
+ [nscontext updateIfNeeded];
+ [nscontext makeCurrentContext];
+ } else {
+ [NSOpenGLContext clearCurrentContext];
+ }
+
+ return 0;
+}}
+
+void
+Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
+{
+ SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+ NSView *contentView = [windata->nswindow contentView];
+ NSRect viewport = [contentView bounds];
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ /* This gives us the correct viewport for a Retina-enabled view, only
+ * supported on 10.7+. */
+ if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
+ viewport = [contentView convertRectToBacking:viewport];
+ }
+ }
+
+ if (w) {
+ *w = viewport.size.width;
+ }
+
+ if (h) {
+ *h = viewport.size.height;
+ }
+}
+
+int
+Cocoa_GL_SetSwapInterval(_THIS, int interval)
+{ @autoreleasepool
+{
+ NSOpenGLContext *nscontext;
+ GLint value;
+ int status;
+
+ if (interval < 0) { /* no extension for this on Mac OS X at the moment. */
+ return SDL_SetError("Late swap tearing currently unsupported");
+ }
+
+ nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+ if (nscontext != nil) {
+ value = interval;
+ [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
+ status = 0;
+ } else {
+ status = SDL_SetError("No current OpenGL context");
+ }
+
+ return status;
+}}
+
+int
+Cocoa_GL_GetSwapInterval(_THIS)
+{ @autoreleasepool
+{
+ NSOpenGLContext *nscontext;
+ GLint value;
+ int status = 0;
+
+ nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+ if (nscontext != nil) {
+ [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
+ status = (int)value;
+ }
+
+ return status;
+}}
+
+int
+Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+
+ /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
+ threads try to swap at the same time, so put a mutex around it. */
+ SDL_LockMutex(videodata->swaplock);
+ [nscontext flushBuffer];
+ [nscontext updateIfNeeded];
+ SDL_UnlockMutex(videodata->swaplock);
+ return 0;
+}}
+
+void
+Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
+{ @autoreleasepool
+{
+ SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
+
+ [nscontext setWindow:NULL];
+ [nscontext release];
+}}
+
+#endif /* SDL_VIDEO_OPENGL_CGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.h
new file mode 100644
index 0000000..fc7f5c0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.h
@@ -0,0 +1,49 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoaopengles_h_
+#define SDL_cocoaopengles_h_
+
+#if SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define Cocoa_GLES_GetAttribute SDL_EGL_GetAttribute
+#define Cocoa_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define Cocoa_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define Cocoa_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define Cocoa_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+
+extern int Cocoa_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext Cocoa_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int Cocoa_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int Cocoa_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern void Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context);
+extern int Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window);
+
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_cocoaopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.m
new file mode 100644
index 0000000..e0a05a1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoaopengles.m
@@ -0,0 +1,132 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_cocoavideo.h"
+#include "SDL_cocoaopengles.h"
+#include "SDL_cocoaopengl.h"
+#include "SDL_log.h"
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+Cocoa_GLES_LoadLibrary(_THIS, const char *path) {
+
+ /* If the profile requested is not GL ES, switch over to WIN_GL functions */
+ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
+#if SDL_VIDEO_OPENGL_CGL
+ Cocoa_GLES_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
+ _this->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
+ _this->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
+ _this->GL_CreateContext = Cocoa_GL_CreateContext;
+ _this->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
+ _this->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
+ _this->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
+ _this->GL_SwapWindow = Cocoa_GL_SwapWindow;
+ _this->GL_DeleteContext = Cocoa_GL_DeleteContext;
+ return Cocoa_GL_LoadLibrary(_this, path);
+#else
+ return SDL_SetError("SDL not configured with OpenGL/CGL support");
+#endif
+ }
+
+ if (_this->egl_data == NULL) {
+ return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0);
+ }
+
+ return 0;
+}
+
+SDL_GLContext
+Cocoa_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_GLContext context;
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+
+#if SDL_VIDEO_OPENGL_CGL
+ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
+ /* Switch to CGL based functions */
+ Cocoa_GLES_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
+ _this->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
+ _this->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
+ _this->GL_CreateContext = Cocoa_GL_CreateContext;
+ _this->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
+ _this->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
+ _this->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
+ _this->GL_SwapWindow = Cocoa_GL_SwapWindow;
+ _this->GL_DeleteContext = Cocoa_GL_DeleteContext;
+
+ if (Cocoa_GL_LoadLibrary(_this, NULL) != 0) {
+ return NULL;
+ }
+
+ return Cocoa_GL_CreateContext(_this, window);
+ }
+#endif
+
+ context = SDL_EGL_CreateContext(_this, data->egl_surface);
+ return context;
+}
+
+void
+Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context)
+{
+ SDL_EGL_DeleteContext(_this, context);
+ Cocoa_GLES_UnloadLibrary(_this);
+}
+
+SDL_EGL_SwapWindow_impl(Cocoa)
+SDL_EGL_MakeCurrent_impl(Cocoa)
+
+int
+Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window)
+{
+ /* The current context is lost in here; save it and reset it. */
+ SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
+ SDL_Window *current_win = SDL_GL_GetCurrentWindow();
+ SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
+
+
+ if (_this->egl_data == NULL) {
+ if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) {
+ SDL_EGL_UnloadLibrary(_this);
+ return -1;
+ }
+ }
+
+ /* Create the GLES window surface */
+ NSView* v = windowdata->nswindow.contentView;
+ windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)[v layer]);
+
+ if (windowdata->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("Could not create GLES window surface");
+ }
+
+ return Cocoa_GLES_MakeCurrent(_this, current_win, current_ctx);
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.h
new file mode 100644
index 0000000..da1b5eb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.h
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoashape_h_
+#define SDL_cocoashape_h_
+
+#include "SDL_stdinc.h"
+#include "SDL_video.h"
+#include "SDL_shape.h"
+#include "../SDL_shape_internals.h"
+
+typedef struct {
+ NSGraphicsContext* context;
+ SDL_bool saved;
+
+ SDL_ShapeTree* shape;
+} SDL_ShapeData;
+
+extern SDL_WindowShaper* Cocoa_CreateShaper(SDL_Window* window);
+extern int Cocoa_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode);
+extern int Cocoa_ResizeWindowShape(SDL_Window *window);
+
+#endif /* SDL_cocoashape_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.m
new file mode 100644
index 0000000..7a2f04f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoashape.m
@@ -0,0 +1,113 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_cocoavideo.h"
+#include "SDL_shape.h"
+#include "SDL_cocoashape.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_assert.h"
+
+SDL_WindowShaper*
+Cocoa_CreateShaper(SDL_Window* window)
+{
+ SDL_WindowData* windata = (SDL_WindowData*)window->driverdata;
+ [windata->nswindow setOpaque:NO];
+
+ [windata->nswindow setStyleMask:NSWindowStyleMaskBorderless];
+
+ SDL_WindowShaper* result = result = malloc(sizeof(SDL_WindowShaper));
+ result->window = window;
+ result->mode.mode = ShapeModeDefault;
+ result->mode.parameters.binarizationCutoff = 1;
+ result->userx = result->usery = 0;
+ window->shaper = result;
+
+ SDL_ShapeData* data = malloc(sizeof(SDL_ShapeData));
+ result->driverdata = data;
+ data->context = [windata->nswindow graphicsContext];
+ data->saved = SDL_FALSE;
+ data->shape = NULL;
+
+ int resized_properly = Cocoa_ResizeWindowShape(window);
+ SDL_assert(resized_properly == 0);
+ return result;
+}
+
+typedef struct {
+ NSView* view;
+ NSBezierPath* path;
+ SDL_Window* window;
+} SDL_CocoaClosure;
+
+void
+ConvertRects(SDL_ShapeTree* tree, void* closure)
+{
+ SDL_CocoaClosure* data = (SDL_CocoaClosure*)closure;
+ if(tree->kind == OpaqueShape) {
+ NSRect rect = NSMakeRect(tree->data.shape.x,data->window->h - tree->data.shape.y,tree->data.shape.w,tree->data.shape.h);
+ [data->path appendBezierPathWithRect:[data->view convertRect:rect toView:nil]];
+ }
+}
+
+int
+Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode)
+{ @autoreleasepool
+{
+ SDL_ShapeData* data = (SDL_ShapeData*)shaper->driverdata;
+ SDL_WindowData* windata = (SDL_WindowData*)shaper->window->driverdata;
+ SDL_CocoaClosure closure;
+ if(data->saved == SDL_TRUE) {
+ [data->context restoreGraphicsState];
+ data->saved = SDL_FALSE;
+ }
+
+ /*[data->context saveGraphicsState];*/
+ /*data->saved = SDL_TRUE;*/
+ [NSGraphicsContext setCurrentContext:data->context];
+
+ [[NSColor clearColor] set];
+ NSRectFill([[windata->nswindow contentView] frame]);
+ data->shape = SDL_CalculateShapeTree(*shape_mode,shape);
+
+ closure.view = [windata->nswindow contentView];
+ closure.path = [NSBezierPath bezierPath];
+ closure.window = shaper->window;
+ SDL_TraverseShapeTree(data->shape,&ConvertRects,&closure);
+ [closure.path addClip];
+
+ return 0;
+}}
+
+int
+Cocoa_ResizeWindowShape(SDL_Window *window)
+{
+ SDL_ShapeData* data = window->shaper->driverdata;
+ SDL_assert(data != NULL);
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.h
new file mode 100644
index 0000000..b1c26fa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.h
@@ -0,0 +1,118 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoavideo_h_
+#define SDL_cocoavideo_h_
+
+#include "SDL_opengl.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <Cocoa/Cocoa.h>
+
+#include "SDL_keycode.h"
+#include "../SDL_sysvideo.h"
+
+#include "SDL_cocoaclipboard.h"
+#include "SDL_cocoaevents.h"
+#include "SDL_cocoakeyboard.h"
+#include "SDL_cocoamodes.h"
+#include "SDL_cocoamouse.h"
+#include "SDL_cocoaopengl.h"
+#include "SDL_cocoawindow.h"
+
+#ifndef MAC_OS_X_VERSION_10_12
+#define DECLARE_EVENT(name) static const NSEventType NSEventType##name = NS##name
+DECLARE_EVENT(LeftMouseDown);
+DECLARE_EVENT(LeftMouseUp);
+DECLARE_EVENT(RightMouseDown);
+DECLARE_EVENT(RightMouseUp);
+DECLARE_EVENT(OtherMouseDown);
+DECLARE_EVENT(OtherMouseUp);
+DECLARE_EVENT(MouseMoved);
+DECLARE_EVENT(LeftMouseDragged);
+DECLARE_EVENT(RightMouseDragged);
+DECLARE_EVENT(OtherMouseDragged);
+DECLARE_EVENT(ScrollWheel);
+DECLARE_EVENT(KeyDown);
+DECLARE_EVENT(KeyUp);
+DECLARE_EVENT(FlagsChanged);
+#undef DECLARE_EVENT
+
+static const NSEventMask NSEventMaskAny = NSAnyEventMask;
+
+#define DECLARE_MODIFIER_FLAG(name) static const NSUInteger NSEventModifierFlag##name = NS##name##KeyMask
+DECLARE_MODIFIER_FLAG(Shift);
+DECLARE_MODIFIER_FLAG(Control);
+DECLARE_MODIFIER_FLAG(Command);
+DECLARE_MODIFIER_FLAG(NumericPad);
+DECLARE_MODIFIER_FLAG(Help);
+DECLARE_MODIFIER_FLAG(Function);
+#undef DECLARE_MODIFIER_FLAG
+static const NSUInteger NSEventModifierFlagCapsLock = NSAlphaShiftKeyMask;
+static const NSUInteger NSEventModifierFlagOption = NSAlternateKeyMask;
+
+#define DECLARE_WINDOW_MASK(name) static const unsigned int NSWindowStyleMask##name = NS##name##WindowMask
+DECLARE_WINDOW_MASK(Borderless);
+DECLARE_WINDOW_MASK(Titled);
+DECLARE_WINDOW_MASK(Closable);
+DECLARE_WINDOW_MASK(Miniaturizable);
+DECLARE_WINDOW_MASK(Resizable);
+DECLARE_WINDOW_MASK(TexturedBackground);
+DECLARE_WINDOW_MASK(UnifiedTitleAndToolbar);
+DECLARE_WINDOW_MASK(FullScreen);
+/*DECLARE_WINDOW_MASK(FullSizeContentView);*/ /* Not used, fails compile on older SDKs */
+static const unsigned int NSWindowStyleMaskUtilityWindow = NSUtilityWindowMask;
+static const unsigned int NSWindowStyleMaskDocModalWindow = NSDocModalWindowMask;
+static const unsigned int NSWindowStyleMaskHUDWindow = NSHUDWindowMask;
+#undef DECLARE_WINDOW_MASK
+
+#define DECLARE_ALERT_STYLE(name) static const NSUInteger NSAlertStyle##name = NS##name##AlertStyle
+DECLARE_ALERT_STYLE(Warning);
+DECLARE_ALERT_STYLE(Informational);
+DECLARE_ALERT_STYLE(Critical);
+#undef DECLARE_ALERT_STYLE
+#endif
+
+/* Private display data */
+
+@class SDLTranslatorResponder;
+
+typedef struct SDL_VideoData
+{
+ int allow_spaces;
+ unsigned int modifierFlags;
+ void *key_layout;
+ SDLTranslatorResponder *fieldEdit;
+ NSInteger clipboard_count;
+ Uint32 screensaver_activity;
+ BOOL screensaver_use_iopm;
+ IOPMAssertionID screensaver_assertion;
+ SDL_mutex *swaplock;
+} SDL_VideoData;
+
+/* Utility functions */
+extern NSImage * Cocoa_CreateImage(SDL_Surface * surface);
+
+#endif /* SDL_cocoavideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.m
new file mode 100644
index 0000000..20bdfa7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavideo.m
@@ -0,0 +1,262 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL.h"
+#include "SDL_endian.h"
+#include "SDL_cocoavideo.h"
+#include "SDL_cocoashape.h"
+#include "SDL_cocoavulkan.h"
+#include "SDL_assert.h"
+
+/* Initialization/Query functions */
+static int Cocoa_VideoInit(_THIS);
+static void Cocoa_VideoQuit(_THIS);
+
+/* Cocoa driver bootstrap functions */
+
+static int
+Cocoa_Available(void)
+{
+ return (1);
+}
+
+static void
+Cocoa_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_free(device->driverdata);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+Cocoa_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ Cocoa_RegisterApp();
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device) {
+ data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ } else {
+ data = NULL;
+ }
+ if (!data) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return NULL;
+ }
+ device->driverdata = data;
+
+ /* Set the function pointers */
+ device->VideoInit = Cocoa_VideoInit;
+ device->VideoQuit = Cocoa_VideoQuit;
+ device->GetDisplayBounds = Cocoa_GetDisplayBounds;
+ device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds;
+ device->GetDisplayDPI = Cocoa_GetDisplayDPI;
+ device->GetDisplayModes = Cocoa_GetDisplayModes;
+ device->SetDisplayMode = Cocoa_SetDisplayMode;
+ device->PumpEvents = Cocoa_PumpEvents;
+ device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
+
+ device->CreateSDLWindow = Cocoa_CreateWindow;
+ device->CreateSDLWindowFrom = Cocoa_CreateWindowFrom;
+ device->SetWindowTitle = Cocoa_SetWindowTitle;
+ device->SetWindowIcon = Cocoa_SetWindowIcon;
+ device->SetWindowPosition = Cocoa_SetWindowPosition;
+ device->SetWindowSize = Cocoa_SetWindowSize;
+ device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
+ device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
+ device->SetWindowOpacity = Cocoa_SetWindowOpacity;
+ device->ShowWindow = Cocoa_ShowWindow;
+ device->HideWindow = Cocoa_HideWindow;
+ device->RaiseWindow = Cocoa_RaiseWindow;
+ device->MaximizeWindow = Cocoa_MaximizeWindow;
+ device->MinimizeWindow = Cocoa_MinimizeWindow;
+ device->RestoreWindow = Cocoa_RestoreWindow;
+ device->SetWindowBordered = Cocoa_SetWindowBordered;
+ device->SetWindowResizable = Cocoa_SetWindowResizable;
+ device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
+ device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
+ device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
+ device->SetWindowGrab = Cocoa_SetWindowGrab;
+ device->DestroyWindow = Cocoa_DestroyWindow;
+ device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
+ device->SetWindowHitTest = Cocoa_SetWindowHitTest;
+ device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop;
+
+ device->shape_driver.CreateShaper = Cocoa_CreateShaper;
+ device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
+ device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape;
+
+#if SDL_VIDEO_OPENGL_CGL
+ device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
+ device->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
+ device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
+ device->GL_CreateContext = Cocoa_GL_CreateContext;
+ device->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
+ device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize;
+ device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
+ device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
+ device->GL_SwapWindow = Cocoa_GL_SwapWindow;
+ device->GL_DeleteContext = Cocoa_GL_DeleteContext;
+#elif SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = Cocoa_GLES_LoadLibrary;
+ device->GL_GetProcAddress = Cocoa_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary;
+ device->GL_CreateContext = Cocoa_GLES_CreateContext;
+ device->GL_MakeCurrent = Cocoa_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval;
+ device->GL_SwapWindow = Cocoa_GLES_SwapWindow;
+ device->GL_DeleteContext = Cocoa_GLES_DeleteContext;
+#endif
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = Cocoa_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = Cocoa_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions = Cocoa_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = Cocoa_Vulkan_CreateSurface;
+ device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize;
+#endif
+
+ device->StartTextInput = Cocoa_StartTextInput;
+ device->StopTextInput = Cocoa_StopTextInput;
+ device->SetTextInputRect = Cocoa_SetTextInputRect;
+
+ device->SetClipboardText = Cocoa_SetClipboardText;
+ device->GetClipboardText = Cocoa_GetClipboardText;
+ device->HasClipboardText = Cocoa_HasClipboardText;
+
+ device->free = Cocoa_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap COCOA_bootstrap = {
+ "cocoa", "SDL Cocoa video driver",
+ Cocoa_Available, Cocoa_CreateDevice
+};
+
+
+int
+Cocoa_VideoInit(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ Cocoa_InitModes(_this);
+ Cocoa_InitKeyboard(_this);
+ Cocoa_InitMouse(_this);
+
+ data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE));
+
+ /* The IOPM assertion API can disable the screensaver as of 10.7. */
+ data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
+
+ data->swaplock = SDL_CreateMutex();
+ if (!data->swaplock) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+Cocoa_VideoQuit(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ Cocoa_QuitModes(_this);
+ Cocoa_QuitKeyboard(_this);
+ Cocoa_QuitMouse(_this);
+ SDL_DestroyMutex(data->swaplock);
+ data->swaplock = NULL;
+}
+
+/* This function assumes that it's called from within an autorelease pool */
+NSImage *
+Cocoa_CreateImage(SDL_Surface * surface)
+{
+ SDL_Surface *converted;
+ NSBitmapImageRep *imgrep;
+ Uint8 *pixels;
+ int i;
+ NSImage *img;
+
+ converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
+ if (!converted) {
+ return nil;
+ }
+
+ imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
+ pixelsWide: converted->w
+ pixelsHigh: converted->h
+ bitsPerSample: 8
+ samplesPerPixel: 4
+ hasAlpha: YES
+ isPlanar: NO
+ colorSpaceName: NSDeviceRGBColorSpace
+ bytesPerRow: converted->pitch
+ bitsPerPixel: converted->format->BitsPerPixel] autorelease];
+ if (imgrep == nil) {
+ SDL_FreeSurface(converted);
+ return nil;
+ }
+
+ /* Copy the pixels */
+ pixels = [imgrep bitmapData];
+ SDL_memcpy(pixels, converted->pixels, converted->h * converted->pitch);
+ SDL_FreeSurface(converted);
+
+ /* Premultiply the alpha channel */
+ for (i = (surface->h * surface->w); i--; ) {
+ Uint8 alpha = pixels[3];
+ pixels[0] = (Uint8)(((Uint16)pixels[0] * alpha) / 255);
+ pixels[1] = (Uint8)(((Uint16)pixels[1] * alpha) / 255);
+ pixels[2] = (Uint8)(((Uint16)pixels[2] * alpha) / 255);
+ pixels += 4;
+ }
+
+ img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
+ if (img != nil) {
+ [img addRepresentation: imgrep];
+ }
+ return img;
+}
+
+/*
+ * Mac OS X log support.
+ *
+ * This doesn't really have aything to do with the interfaces of the SDL video
+ * subsystem, but we need to stuff this into an Objective-C source code file.
+ */
+
+void SDL_NSLog(const char *text)
+{
+ NSLog(@"%s", text);
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.h
new file mode 100644
index 0000000..a49c148
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.h
@@ -0,0 +1,55 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoavulkan_h_
+#define SDL_cocoavulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_COCOA
+
+int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path);
+void Cocoa_Vulkan_UnloadLibrary(_THIS);
+SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
+
+#endif
+
+#endif /* SDL_cocoavulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.m
new file mode 100644
index 0000000..0e53d21
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoavulkan.m
@@ -0,0 +1,230 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_cocoavideo.h"
+#include "SDL_cocoawindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_cocoametalview.h"
+#include "SDL_cocoavulkan.h"
+#include "SDL_syswm.h"
+
+#include <dlfcn.h>
+
+const char* defaultPaths[] = {
+ "vulkan.framework/vulkan",
+ "libvulkan.1.dylib",
+ "MoltenVK.framework/MoltenVK",
+ "libMoltenVK.dylib"
+};
+
+/* Since libSDL is most likely a .dylib, need RTLD_DEFAULT not RTLD_SELF. */
+#define DEFAULT_HANDLE RTLD_DEFAULT
+
+int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasMacOSSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+
+ if (_this->vulkan_config.loader_handle) {
+ return SDL_SetError("Vulkan/MoltenVK already loaded");
+ }
+
+ /* Load the Vulkan loader library */
+ if (!path) {
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ }
+
+ if (!path) {
+ /* MoltenVK framework, currently, v0.17.0, has a static library and is
+ * the recommended way to use the package. There is likely no object to
+ * load. */
+ vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
+ "vkGetInstanceProcAddr");
+ }
+
+ if (vkGetInstanceProcAddr) {
+ _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
+ } else {
+ const char** paths;
+ const char *foundPath = NULL;
+ int numPaths;
+ int i;
+
+ if (path) {
+ paths = &path;
+ numPaths = 1;
+ } else {
+ /* Look for framework or .dylib packaged with the application
+ * instead. */
+ paths = defaultPaths;
+ numPaths = SDL_arraysize(defaultPaths);
+ }
+
+ for (i = 0; i < numPaths && _this->vulkan_config.loader_handle == NULL; i++) {
+ foundPath = paths[i];
+ _this->vulkan_config.loader_handle = SDL_LoadObject(foundPath);
+ }
+
+ if (_this->vulkan_config.loader_handle == NULL) {
+ return SDL_SetError("Failed to load Vulkan/MoltenVK library");
+ }
+
+ SDL_strlcpy(_this->vulkan_config.loader_path, foundPath,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+ }
+
+ if (!vkGetInstanceProcAddr) {
+ SDL_SetError("Failed to find %s in either executable or %s: %s",
+ "vkGetInstanceProcAddr",
+ _this->vulkan_config.loader_path,
+ (const char *) dlerror());
+ goto fail;
+ }
+
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+ if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
+ goto fail;
+ }
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+ if (!extensions) {
+ goto fail;
+ }
+ for (Uint32 i = 0; i < extensionCount; i++) {
+ if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
+ hasSurfaceExtension = SDL_TRUE;
+ } else if (SDL_strcmp(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
+ hasMacOSSurfaceExtension = SDL_TRUE;
+ }
+ }
+ SDL_free(extensions);
+ if (!hasSurfaceExtension) {
+ SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ } else if (!hasMacOSSurfaceExtension) {
+ SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
+ VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+ return 0;
+
+fail:
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void Cocoa_Vulkan_UnloadLibrary(_THIS)
+{
+ if (_this->vulkan_config.loader_handle) {
+ if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE) {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ }
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForCocoa[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_EXTENSION_NAME
+ };
+ if (!_this->vulkan_config.loader_handle) {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForCocoa),
+ extensionsForCocoa);
+}
+
+SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK =
+ (PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateMacOSSurfaceMVK");
+ VkMacOSSurfaceCreateInfoMVK createInfo = {};
+ VkResult result;
+
+ if (!_this->vulkan_config.loader_handle) {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if (!vkCreateMacOSSurfaceMVK) {
+ SDL_SetError(VK_MVK_MACOS_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.pView = Cocoa_Mtl_AddMetalView(window);
+ result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
+ NULL, surface);
+ if (result != VK_SUCCESS) {
+ SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
+{
+ Cocoa_Mtl_GetDrawableSize(window, w, h);
+}
+
+#endif
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.h b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.h
new file mode 100644
index 0000000..2311e3d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.h
@@ -0,0 +1,155 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_cocoawindow_h_
+#define SDL_cocoawindow_h_
+
+#import <Cocoa/Cocoa.h>
+
+#if SDL_VIDEO_OPENGL_EGL
+#include "../SDL_egl_c.h"
+#endif
+
+typedef struct SDL_WindowData SDL_WindowData;
+
+typedef enum
+{
+ PENDING_OPERATION_NONE,
+ PENDING_OPERATION_ENTER_FULLSCREEN,
+ PENDING_OPERATION_LEAVE_FULLSCREEN,
+ PENDING_OPERATION_MINIMIZE
+} PendingWindowOperation;
+
+@interface Cocoa_WindowListener : NSResponder <NSWindowDelegate> {
+ SDL_WindowData *_data;
+ BOOL observingVisible;
+ BOOL wasCtrlLeft;
+ BOOL wasVisible;
+ BOOL isFullscreenSpace;
+ BOOL inFullscreenTransition;
+ PendingWindowOperation pendingWindowOperation;
+ BOOL isMoving;
+ int pendingWindowWarpX, pendingWindowWarpY;
+ BOOL isDragAreaRunning;
+}
+
+-(void) listen:(SDL_WindowData *) data;
+-(void) pauseVisibleObservation;
+-(void) resumeVisibleObservation;
+-(BOOL) setFullscreenSpace:(BOOL) state;
+-(BOOL) isInFullscreenSpace;
+-(BOOL) isInFullscreenSpaceTransition;
+-(void) addPendingWindowOperation:(PendingWindowOperation) operation;
+-(void) close;
+
+-(BOOL) isMoving;
+-(void) setPendingMoveX:(int)x Y:(int)y;
+-(void) windowDidFinishMoving;
+
+/* Window delegate functionality */
+-(BOOL) windowShouldClose:(id) sender;
+-(void) windowDidExpose:(NSNotification *) aNotification;
+-(void) windowDidMove:(NSNotification *) aNotification;
+-(void) windowDidResize:(NSNotification *) aNotification;
+-(void) windowDidMiniaturize:(NSNotification *) aNotification;
+-(void) windowDidDeminiaturize:(NSNotification *) aNotification;
+-(void) windowDidBecomeKey:(NSNotification *) aNotification;
+-(void) windowDidResignKey:(NSNotification *) aNotification;
+-(void) windowDidChangeBackingProperties:(NSNotification *) aNotification;
+-(void) windowWillEnterFullScreen:(NSNotification *) aNotification;
+-(void) windowDidEnterFullScreen:(NSNotification *) aNotification;
+-(void) windowWillExitFullScreen:(NSNotification *) aNotification;
+-(void) windowDidExitFullScreen:(NSNotification *) aNotification;
+-(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions;
+
+/* See if event is in a drag area, toggle on window dragging. */
+-(BOOL) processHitTest:(NSEvent *)theEvent;
+
+/* Window event handling */
+-(void) mouseDown:(NSEvent *) theEvent;
+-(void) rightMouseDown:(NSEvent *) theEvent;
+-(void) otherMouseDown:(NSEvent *) theEvent;
+-(void) mouseUp:(NSEvent *) theEvent;
+-(void) rightMouseUp:(NSEvent *) theEvent;
+-(void) otherMouseUp:(NSEvent *) theEvent;
+-(void) mouseMoved:(NSEvent *) theEvent;
+-(void) mouseDragged:(NSEvent *) theEvent;
+-(void) rightMouseDragged:(NSEvent *) theEvent;
+-(void) otherMouseDragged:(NSEvent *) theEvent;
+-(void) scrollWheel:(NSEvent *) theEvent;
+-(void) touchesBeganWithEvent:(NSEvent *) theEvent;
+-(void) touchesMovedWithEvent:(NSEvent *) theEvent;
+-(void) touchesEndedWithEvent:(NSEvent *) theEvent;
+-(void) touchesCancelledWithEvent:(NSEvent *) theEvent;
+
+/* Touch event handling */
+-(void) handleTouches:(NSTouchPhase) phase withEvent:(NSEvent*) theEvent;
+
+@end
+/* *INDENT-ON* */
+
+@class SDLOpenGLContext;
+
+struct SDL_WindowData
+{
+ SDL_Window *window;
+ NSWindow *nswindow;
+ NSMutableArray *nscontexts;
+ SDL_bool created;
+ SDL_bool inWindowMove;
+ Cocoa_WindowListener *listener;
+ struct SDL_VideoData *videodata;
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+};
+
+extern int Cocoa_CreateWindow(_THIS, SDL_Window * window);
+extern int Cocoa_CreateWindowFrom(_THIS, SDL_Window * window,
+ const void *data);
+extern void Cocoa_SetWindowTitle(_THIS, SDL_Window * window);
+extern void Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window);
+extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window);
+extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window);
+extern void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window);
+extern int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
+extern void Cocoa_ShowWindow(_THIS, SDL_Window * window);
+extern void Cocoa_HideWindow(_THIS, SDL_Window * window);
+extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window);
+extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window);
+extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window);
+extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window);
+extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
+extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
+extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
+extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
+extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);
+extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
+extern void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
+
+#endif /* SDL_cocoawindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.m b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.m
new file mode 100644
index 0000000..a8e95cc
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/cocoa/SDL_cocoawindow.m
@@ -0,0 +1,1905 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+# error SDL for Mac OS X must be built with a 10.7 SDK or above.
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1070 */
+
+#include "SDL_syswm.h"
+#include "SDL_timer.h" /* For SDL_GetTicks() */
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../../events/SDL_windowevents_c.h"
+#include "../../events/SDL_dropevents_c.h"
+#include "SDL_cocoavideo.h"
+#include "SDL_cocoashape.h"
+#include "SDL_cocoamouse.h"
+#include "SDL_cocoamousetap.h"
+#include "SDL_cocoaopengl.h"
+#include "SDL_cocoaopengles.h"
+#include "SDL_assert.h"
+
+/* #define DEBUG_COCOAWINDOW */
+
+#ifdef DEBUG_COCOAWINDOW
+#define DLog(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
+#else
+#define DLog(...) do { } while (0)
+#endif
+
+
+#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
+
+
+@interface SDLWindow : NSWindow <NSDraggingDestination>
+/* These are needed for borderless/fullscreen windows */
+- (BOOL)canBecomeKeyWindow;
+- (BOOL)canBecomeMainWindow;
+- (void)sendEvent:(NSEvent *)event;
+- (void)doCommandBySelector:(SEL)aSelector;
+
+/* Handle drag-and-drop of files onto the SDL window. */
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
+- (BOOL)wantsPeriodicDraggingUpdates;
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
+
+- (SDL_Window*)findSDLWindow;
+@end
+
+@implementation SDLWindow
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+ /* Only allow using the macOS native fullscreen toggle menubar item if the
+ * window is resizable and not in a SDL fullscreen mode.
+ */
+ if ([menuItem action] == @selector(toggleFullScreen:)) {
+ SDL_Window *window = [self findSDLWindow];
+ if (window == NULL) {
+ return NO;
+ } else if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) {
+ return NO;
+ } else if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) {
+ return NO;
+ }
+ }
+ return [super validateMenuItem:menuItem];
+}
+
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+- (BOOL)canBecomeMainWindow
+{
+ return YES;
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ [super sendEvent:event];
+
+ if ([event type] != NSEventTypeLeftMouseUp) {
+ return;
+ }
+
+ id delegate = [self delegate];
+ if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
+ return;
+ }
+
+ if ([delegate isMoving]) {
+ [delegate windowDidFinishMoving];
+ }
+}
+
+/* We'll respond to selectors by doing nothing so we don't beep.
+ * The escape key gets converted to a "cancel" selector, etc.
+ */
+- (void)doCommandBySelector:(SEL)aSelector
+{
+ /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ if (([sender draggingSourceOperationMask] & NSDragOperationGeneric) == NSDragOperationGeneric) {
+ return NSDragOperationGeneric;
+ }
+
+ return NSDragOperationNone; /* no idea what to do with this, reject it. */
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{ @autoreleasepool
+{
+ NSPasteboard *pasteboard = [sender draggingPasteboard];
+ NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
+ NSString *desiredType = [pasteboard availableTypeFromArray:types];
+ SDL_Window *sdlwindow = [self findSDLWindow];
+
+ if (desiredType == nil) {
+ return NO; /* can't accept anything that's being dropped here. */
+ }
+
+ NSData *data = [pasteboard dataForType:desiredType];
+ if (data == nil) {
+ return NO;
+ }
+
+ SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]);
+ NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];
+
+ for (NSString *path in array) {
+ NSURL *fileURL = [NSURL fileURLWithPath:path];
+ NSNumber *isAlias = nil;
+
+ [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
+
+ /* If the URL is an alias, resolve it. */
+ if ([isAlias boolValue]) {
+ NSURLBookmarkResolutionOptions opts = NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI;
+ NSData *bookmark = [NSURL bookmarkDataWithContentsOfURL:fileURL error:nil];
+ if (bookmark != nil) {
+ NSURL *resolvedURL = [NSURL URLByResolvingBookmarkData:bookmark
+ options:opts
+ relativeToURL:nil
+ bookmarkDataIsStale:nil
+ error:nil];
+
+ if (resolvedURL != nil) {
+ fileURL = resolvedURL;
+ }
+ }
+ }
+
+ if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) {
+ return NO;
+ }
+ }
+
+ SDL_SendDropComplete(sdlwindow);
+ return YES;
+}}
+
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+ return NO;
+}
+
+- (SDL_Window*)findSDLWindow
+{
+ SDL_Window *sdlwindow = NULL;
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+ /* !!! FIXME: is there a better way to do this? */
+ if (_this) {
+ for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) {
+ NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
+ if (nswindow == self) {
+ break;
+ }
+ }
+ }
+
+ return sdlwindow;
+}
+
+@end
+
+
+static Uint32 s_moveHack;
+
+static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r)
+{
+ r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
+}
+
+static void
+ScheduleContextUpdates(SDL_WindowData *data)
+{
+ NSOpenGLContext *currentContext = [NSOpenGLContext currentContext];
+ NSMutableArray *contexts = data->nscontexts;
+ @synchronized (contexts) {
+ for (SDLOpenGLContext *context in contexts) {
+ if (context == currentContext) {
+ [context update];
+ } else {
+ [context scheduleUpdate];
+ }
+ }
+ }
+}
+
+/* !!! FIXME: this should use a hint callback. */
+static int
+GetHintCtrlClickEmulateRightClick()
+{
+ return SDL_GetHintBoolean(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, SDL_FALSE);
+}
+
+static NSUInteger
+GetWindowStyle(SDL_Window * window)
+{
+ NSUInteger style = 0;
+
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ style = NSWindowStyleMaskBorderless;
+ } else {
+ if (window->flags & SDL_WINDOW_BORDERLESS) {
+ style = NSWindowStyleMaskBorderless;
+ } else {
+ style = (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable);
+ }
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ style |= NSWindowStyleMaskResizable;
+ }
+ }
+ return style;
+}
+
+static SDL_bool
+SetWindowStyle(SDL_Window * window, NSUInteger style)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = data->nswindow;
+
+ /* The view responder chain gets messed with during setStyleMask */
+ if ([[nswindow contentView] nextResponder] == data->listener) {
+ [[nswindow contentView] setNextResponder:nil];
+ }
+
+ [nswindow setStyleMask:style];
+
+ /* The view responder chain gets messed with during setStyleMask */
+ if ([[nswindow contentView] nextResponder] != data->listener) {
+ [[nswindow contentView] setNextResponder:data->listener];
+ }
+
+ return SDL_TRUE;
+}
+
+
+@implementation Cocoa_WindowListener
+
+- (void)listen:(SDL_WindowData *)data
+{
+ NSNotificationCenter *center;
+ NSWindow *window = data->nswindow;
+ NSView *view = [window contentView];
+
+ _data = data;
+ observingVisible = YES;
+ wasCtrlLeft = NO;
+ wasVisible = [window isVisible];
+ isFullscreenSpace = NO;
+ inFullscreenTransition = NO;
+ pendingWindowOperation = PENDING_OPERATION_NONE;
+ isMoving = NO;
+ isDragAreaRunning = NO;
+
+ center = [NSNotificationCenter defaultCenter];
+
+ if ([window delegate] != nil) {
+ [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window];
+ [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window];
+ [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window];
+ [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window];
+ [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
+ [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
+ [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
+ [center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
+ [center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
+ [center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
+ [center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
+ [center addObserver:self selector:@selector(windowDidExitFullScreen:) name:NSWindowDidExitFullScreenNotification object:window];
+ [center addObserver:self selector:@selector(windowDidFailToEnterFullScreen:) name:@"NSWindowDidFailToEnterFullScreenNotification" object:window];
+ [center addObserver:self selector:@selector(windowDidFailToExitFullScreen:) name:@"NSWindowDidFailToExitFullScreenNotification" object:window];
+ } else {
+ [window setDelegate:self];
+ }
+
+ /* Haven't found a delegate / notification that triggers when the window is
+ * ordered out (is not visible any more). You can be ordered out without
+ * minimizing, so DidMiniaturize doesn't work. (e.g. -[NSWindow orderOut:])
+ */
+ [window addObserver:self
+ forKeyPath:@"visible"
+ options:NSKeyValueObservingOptionNew
+ context:NULL];
+
+ [window setNextResponder:self];
+ [window setAcceptsMouseMovedEvents:YES];
+
+ [view setNextResponder:self];
+
+ [view setAcceptsTouchEvents:YES];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
+ context:(void *)context
+{
+ if (!observingVisible) {
+ return;
+ }
+
+ if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) {
+ int newVisibility = [[change objectForKey:@"new"] intValue];
+ if (newVisibility) {
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+ } else {
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+ }
+ }
+}
+
+-(void) pauseVisibleObservation
+{
+ observingVisible = NO;
+ wasVisible = [_data->nswindow isVisible];
+}
+
+-(void) resumeVisibleObservation
+{
+ BOOL isVisible = [_data->nswindow isVisible];
+ observingVisible = YES;
+ if (wasVisible != isVisible) {
+ if (isVisible) {
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+ } else {
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+ }
+
+ wasVisible = isVisible;
+ }
+}
+
+-(BOOL) setFullscreenSpace:(BOOL) state
+{
+ SDL_Window *window = _data->window;
+ NSWindow *nswindow = _data->nswindow;
+ SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
+
+ if (!videodata->allow_spaces) {
+ return NO; /* Spaces are forcibly disabled. */
+ } else if (state && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) {
+ return NO; /* we only allow you to make a Space on FULLSCREEN_DESKTOP windows. */
+ } else if (!state && ((window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) {
+ return NO; /* we only handle leaving the Space on windows that were previously FULLSCREEN_DESKTOP. */
+ } else if (state == isFullscreenSpace) {
+ return YES; /* already there. */
+ }
+
+ if (inFullscreenTransition) {
+ if (state) {
+ [self addPendingWindowOperation:PENDING_OPERATION_ENTER_FULLSCREEN];
+ } else {
+ [self addPendingWindowOperation:PENDING_OPERATION_LEAVE_FULLSCREEN];
+ }
+ return YES;
+ }
+ inFullscreenTransition = YES;
+
+ /* you need to be FullScreenPrimary, or toggleFullScreen doesn't work. Unset it again in windowDidExitFullScreen. */
+ [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+ [nswindow performSelectorOnMainThread: @selector(toggleFullScreen:) withObject:nswindow waitUntilDone:NO];
+ return YES;
+}
+
+-(BOOL) isInFullscreenSpace
+{
+ return isFullscreenSpace;
+}
+
+-(BOOL) isInFullscreenSpaceTransition
+{
+ return inFullscreenTransition;
+}
+
+-(void) addPendingWindowOperation:(PendingWindowOperation) operation
+{
+ pendingWindowOperation = operation;
+}
+
+- (void)close
+{
+ NSNotificationCenter *center;
+ NSWindow *window = _data->nswindow;
+ NSView *view = [window contentView];
+
+ center = [NSNotificationCenter defaultCenter];
+
+ if ([window delegate] != self) {
+ [center removeObserver:self name:NSWindowDidExposeNotification object:window];
+ [center removeObserver:self name:NSWindowDidMoveNotification object:window];
+ [center removeObserver:self name:NSWindowDidResizeNotification object:window];
+ [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window];
+ [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
+ [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
+ [center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
+ [center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
+ [center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
+ [center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
+ [center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
+ [center removeObserver:self name:NSWindowDidExitFullScreenNotification object:window];
+ [center removeObserver:self name:@"NSWindowDidFailToEnterFullScreenNotification" object:window];
+ [center removeObserver:self name:@"NSWindowDidFailToExitFullScreenNotification" object:window];
+ } else {
+ [window setDelegate:nil];
+ }
+
+ [window removeObserver:self forKeyPath:@"visible"];
+
+ if ([window nextResponder] == self) {
+ [window setNextResponder:nil];
+ }
+ if ([view nextResponder] == self) {
+ [view setNextResponder:nil];
+ }
+}
+
+- (BOOL)isMoving
+{
+ return isMoving;
+}
+
+-(void) setPendingMoveX:(int)x Y:(int)y
+{
+ pendingWindowWarpX = x;
+ pendingWindowWarpY = y;
+}
+
+- (void)windowDidFinishMoving
+{
+ if ([self isMoving]) {
+ isMoving = NO;
+
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if (pendingWindowWarpX != INT_MAX && pendingWindowWarpY != INT_MAX) {
+ mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY);
+ pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
+ }
+ if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) {
+ mouse->SetRelativeMouseMode(SDL_TRUE);
+ }
+ }
+}
+
+- (BOOL)windowShouldClose:(id)sender
+{
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
+ return NO;
+}
+
+- (void)windowDidExpose:(NSNotification *)aNotification
+{
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
+}
+
+- (void)windowWillMove:(NSNotification *)aNotification
+{
+ if ([_data->nswindow isKindOfClass:[SDLWindow class]]) {
+ pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
+ isMoving = YES;
+ }
+}
+
+- (void)windowDidMove:(NSNotification *)aNotification
+{
+ int x, y;
+ SDL_Window *window = _data->window;
+ NSWindow *nswindow = _data->nswindow;
+ BOOL fullscreen = window->flags & FULLSCREEN_MASK;
+ NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
+ ConvertNSRect([nswindow screen], fullscreen, &rect);
+
+ if (inFullscreenTransition) {
+ /* We'll take care of this at the end of the transition */
+ return;
+ }
+
+ if (s_moveHack) {
+ SDL_bool blockMove = ((SDL_GetTicks() - s_moveHack) < 500);
+
+ s_moveHack = 0;
+
+ if (blockMove) {
+ /* Cocoa is adjusting the window in response to a mode change */
+ rect.origin.x = window->x;
+ rect.origin.y = window->y;
+ ConvertNSRect([nswindow screen], fullscreen, &rect);
+ [nswindow setFrameOrigin:rect.origin];
+ return;
+ }
+ }
+
+ x = (int)rect.origin.x;
+ y = (int)rect.origin.y;
+
+ ScheduleContextUpdates(_data);
+
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
+}
+
+- (void)windowDidResize:(NSNotification *)aNotification
+{
+ if (inFullscreenTransition) {
+ /* We'll take care of this at the end of the transition */
+ return;
+ }
+
+ SDL_Window *window = _data->window;
+ NSWindow *nswindow = _data->nswindow;
+ int x, y, w, h;
+ NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
+ ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
+ x = (int)rect.origin.x;
+ y = (int)rect.origin.y;
+ w = (int)rect.size.width;
+ h = (int)rect.size.height;
+
+ if (SDL_IsShapedWindow(window)) {
+ Cocoa_ResizeWindowShape(window);
+ }
+
+ ScheduleContextUpdates(_data);
+
+ /* The window can move during a resize event, such as when maximizing
+ or resizing from a corner */
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
+
+ const BOOL zoomed = [nswindow isZoomed];
+ if (!zoomed) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+ } else if (zoomed) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
+ }
+}
+
+- (void)windowDidMiniaturize:(NSNotification *)aNotification
+{
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+}
+
+- (void)windowDidDeminiaturize:(NSNotification *)aNotification
+{
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+}
+
+- (void)windowDidBecomeKey:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ /* We're going to get keyboard events, since we're key. */
+ /* This needs to be done before restoring the relative mouse mode. */
+ SDL_SetKeyboardFocus(window);
+
+ if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) {
+ mouse->SetRelativeMouseMode(SDL_TRUE);
+ }
+
+ /* If we just gained focus we need the updated mouse position */
+ if (!mouse->relative_mode) {
+ NSPoint point;
+ int x, y;
+
+ point = [_data->nswindow mouseLocationOutsideOfEventStream];
+ x = (int)point.x;
+ y = (int)(window->h - point.y);
+
+ if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
+ SDL_SendMouseMotion(window, 0, 0, x, y);
+ }
+ }
+
+ /* Check to see if someone updated the clipboard */
+ Cocoa_CheckClipboardUpdate(_data->videodata);
+
+ if ((isFullscreenSpace) && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
+ [NSMenu setMenuBarVisible:NO];
+ }
+
+ const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock;
+ _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSEventModifierFlagCapsLock) | newflags;
+ SDL_ToggleModState(KMOD_CAPS, newflags != 0);
+}
+
+- (void)windowDidResignKey:(NSNotification *)aNotification
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if (mouse->relative_mode && !mouse->relative_mode_warp) {
+ mouse->SetRelativeMouseMode(SDL_FALSE);
+ }
+
+ /* Some other window will get mouse events, since we're not key. */
+ if (SDL_GetMouseFocus() == _data->window) {
+ SDL_SetMouseFocus(NULL);
+ }
+
+ /* Some other window will get keyboard events, since we're not key. */
+ if (SDL_GetKeyboardFocus() == _data->window) {
+ SDL_SetKeyboardFocus(NULL);
+ }
+
+ if (isFullscreenSpace) {
+ [NSMenu setMenuBarVisible:YES];
+ }
+}
+
+- (void)windowDidChangeBackingProperties:(NSNotification *)aNotification
+{
+ NSNumber *oldscale = [[aNotification userInfo] objectForKey:NSBackingPropertyOldScaleFactorKey];
+
+ if (inFullscreenTransition) {
+ return;
+ }
+
+ if ([oldscale doubleValue] != [_data->nswindow backingScaleFactor]) {
+ /* Force a resize event when the backing scale factor changes. */
+ _data->window->w = 0;
+ _data->window->h = 0;
+ [self windowDidResize:aNotification];
+ }
+}
+
+- (void)windowWillEnterFullScreen:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+
+ SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
+
+ isFullscreenSpace = YES;
+ inFullscreenTransition = YES;
+}
+
+- (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+
+ if (window->is_destroying) {
+ return;
+ }
+
+ SetWindowStyle(window, GetWindowStyle(window));
+
+ isFullscreenSpace = NO;
+ inFullscreenTransition = NO;
+
+ [self windowDidExitFullScreen:nil];
+}
+
+- (void)windowDidEnterFullScreen:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = data->nswindow;
+
+ inFullscreenTransition = NO;
+
+ if (pendingWindowOperation == PENDING_OPERATION_LEAVE_FULLSCREEN) {
+ pendingWindowOperation = PENDING_OPERATION_NONE;
+ [self setFullscreenSpace:NO];
+ } else {
+ /* Unset the resizable flag.
+ This is a workaround for https://bugzilla.libsdl.org/show_bug.cgi?id=3697
+ */
+ SetWindowStyle(window, [nswindow styleMask] & (~NSWindowStyleMaskResizable));
+
+ if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ [NSMenu setMenuBarVisible:NO];
+ }
+
+ pendingWindowOperation = PENDING_OPERATION_NONE;
+ /* Force the size change event in case it was delivered earlier
+ while the window was still animating into place.
+ */
+ window->w = 0;
+ window->h = 0;
+ [self windowDidMove:aNotification];
+ [self windowDidResize:aNotification];
+ }
+}
+
+- (void)windowWillExitFullScreen:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+
+ isFullscreenSpace = NO;
+ inFullscreenTransition = YES;
+
+ /* As of OS X 10.11, the window seems to need to be resizable when exiting
+ a Space, in order for it to resize back to its windowed-mode size.
+ */
+ SetWindowStyle(window, GetWindowStyle(window) | NSWindowStyleMaskResizable);
+}
+
+- (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+
+ if (window->is_destroying) {
+ return;
+ }
+
+ SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
+
+ isFullscreenSpace = YES;
+ inFullscreenTransition = NO;
+
+ [self windowDidEnterFullScreen:nil];
+}
+
+- (void)windowDidExitFullScreen:(NSNotification *)aNotification
+{
+ SDL_Window *window = _data->window;
+ NSWindow *nswindow = _data->nswindow;
+
+ inFullscreenTransition = NO;
+
+ SetWindowStyle(window, GetWindowStyle(window));
+
+ [nswindow setLevel:kCGNormalWindowLevel];
+
+ if (pendingWindowOperation == PENDING_OPERATION_ENTER_FULLSCREEN) {
+ pendingWindowOperation = PENDING_OPERATION_NONE;
+ [self setFullscreenSpace:YES];
+ } else if (pendingWindowOperation == PENDING_OPERATION_MINIMIZE) {
+ pendingWindowOperation = PENDING_OPERATION_NONE;
+ [nswindow miniaturize:nil];
+ } else {
+ /* Adjust the fullscreen toggle button and readd menu now that we're here. */
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
+ [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+ } else {
+ [nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged];
+ }
+ [NSMenu setMenuBarVisible:YES];
+
+ pendingWindowOperation = PENDING_OPERATION_NONE;
+
+#if 0
+/* This fixed bug 3719, which is that changing window size while fullscreen
+ doesn't take effect when leaving fullscreen, but introduces bug 3809,
+ which is that a maximized window doesn't go back to normal size when
+ restored, so this code is disabled until we can properly handle the
+ beginning and end of maximize and restore.
+ */
+ /* Restore windowed size and position in case it changed while fullscreen */
+ {
+ NSRect rect;
+ rect.origin.x = window->windowed.x;
+ rect.origin.y = window->windowed.y;
+ rect.size.width = window->windowed.w;
+ rect.size.height = window->windowed.h;
+ ConvertNSRect([nswindow screen], NO, &rect);
+
+ s_moveHack = 0;
+ [nswindow setContentSize:rect.size];
+ [nswindow setFrameOrigin:rect.origin];
+ s_moveHack = SDL_GetTicks();
+ }
+#endif /* 0 */
+
+ /* Force the size change event in case it was delivered earlier
+ while the window was still animating into place.
+ */
+ window->w = 0;
+ window->h = 0;
+ [self windowDidMove:aNotification];
+ [self windowDidResize:aNotification];
+
+ /* FIXME: Why does the window get hidden? */
+ if (window->flags & SDL_WINDOW_SHOWN) {
+ Cocoa_ShowWindow(SDL_GetVideoDevice(), window);
+ }
+ }
+}
+
+-(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
+{
+ if ((_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ return NSApplicationPresentationFullScreen | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar;
+ } else {
+ return proposedOptions;
+ }
+}
+
+
+/* We'll respond to key events by doing nothing so we don't beep.
+ * We could handle key messages here, but we lose some in the NSApp dispatch,
+ * where they get converted to action messages, etc.
+ */
+- (void)flagsChanged:(NSEvent *)theEvent
+{
+ /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
+}
+- (void)keyDown:(NSEvent *)theEvent
+{
+ /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
+}
+- (void)keyUp:(NSEvent *)theEvent
+{
+ /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
+}
+
+/* We'll respond to selectors by doing nothing so we don't beep.
+ * The escape key gets converted to a "cancel" selector, etc.
+ */
+- (void)doCommandBySelector:(SEL)aSelector
+{
+ /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
+}
+
+- (BOOL)processHitTest:(NSEvent *)theEvent
+{
+ SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]);
+
+ if (_data->window->hit_test) { /* if no hit-test, skip this. */
+ const NSPoint location = [theEvent locationInWindow];
+ const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) };
+ const SDL_HitTestResult rc = _data->window->hit_test(_data->window, &point, _data->window->hit_test_data);
+ if (rc == SDL_HITTEST_DRAGGABLE) {
+ if (!isDragAreaRunning) {
+ isDragAreaRunning = YES;
+ [_data->nswindow setMovableByWindowBackground:YES];
+ }
+ return YES; /* dragging! */
+ }
+ }
+
+ if (isDragAreaRunning) {
+ isDragAreaRunning = NO;
+ [_data->nswindow setMovableByWindowBackground:NO];
+ return YES; /* was dragging, drop event. */
+ }
+
+ return NO; /* not a special area, carry on. */
+}
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ int button;
+ int clicks;
+
+ /* Ignore events that aren't inside the client area (i.e. title bar.) */
+ if ([theEvent window]) {
+ NSRect windowRect = [[[theEvent window] contentView] frame];
+ if (!NSMouseInRect([theEvent locationInWindow], windowRect, NO)) {
+ return;
+ }
+ }
+
+ if ([self processHitTest:theEvent]) {
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
+ return; /* dragging, drop event. */
+ }
+
+ switch ([theEvent buttonNumber]) {
+ case 0:
+ if (([theEvent modifierFlags] & NSEventModifierFlagControl) &&
+ GetHintCtrlClickEmulateRightClick()) {
+ wasCtrlLeft = YES;
+ button = SDL_BUTTON_RIGHT;
+ } else {
+ wasCtrlLeft = NO;
+ button = SDL_BUTTON_LEFT;
+ }
+ break;
+ case 1:
+ button = SDL_BUTTON_RIGHT;
+ break;
+ case 2:
+ button = SDL_BUTTON_MIDDLE;
+ break;
+ default:
+ button = (int) [theEvent buttonNumber] + 1;
+ break;
+ }
+
+ clicks = (int) [theEvent clickCount];
+ SDL_SendMouseButtonClicks(_data->window, 0, SDL_PRESSED, button, clicks);
+}
+
+- (void)rightMouseDown:(NSEvent *)theEvent
+{
+ [self mouseDown:theEvent];
+}
+
+- (void)otherMouseDown:(NSEvent *)theEvent
+{
+ [self mouseDown:theEvent];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ int button;
+ int clicks;
+
+ if ([self processHitTest:theEvent]) {
+ SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
+ return; /* stopped dragging, drop event. */
+ }
+
+ switch ([theEvent buttonNumber]) {
+ case 0:
+ if (wasCtrlLeft) {
+ button = SDL_BUTTON_RIGHT;
+ wasCtrlLeft = NO;
+ } else {
+ button = SDL_BUTTON_LEFT;
+ }
+ break;
+ case 1:
+ button = SDL_BUTTON_RIGHT;
+ break;
+ case 2:
+ button = SDL_BUTTON_MIDDLE;
+ break;
+ default:
+ button = (int) [theEvent buttonNumber] + 1;
+ break;
+ }
+
+ clicks = (int) [theEvent clickCount];
+ SDL_SendMouseButtonClicks(_data->window, 0, SDL_RELEASED, button, clicks);
+}
+
+- (void)rightMouseUp:(NSEvent *)theEvent
+{
+ [self mouseUp:theEvent];
+}
+
+- (void)otherMouseUp:(NSEvent *)theEvent
+{
+ [self mouseUp:theEvent];
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ SDL_Window *window = _data->window;
+ NSPoint point;
+ int x, y;
+
+ if ([self processHitTest:theEvent]) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
+ return; /* dragging, drop event. */
+ }
+
+ if (mouse->relative_mode) {
+ return;
+ }
+
+ point = [theEvent locationInWindow];
+ x = (int)point.x;
+ y = (int)(window->h - point.y);
+
+ if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
+ if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
+ if (x < 0) {
+ x = 0;
+ } else if (x >= window->w) {
+ x = window->w - 1;
+ }
+ if (y < 0) {
+ y = 0;
+ } else if (y >= window->h) {
+ y = window->h - 1;
+ }
+
+#if !SDL_MAC_NO_SANDBOX
+ CGPoint cgpoint;
+
+ /* When SDL_MAC_NO_SANDBOX is set, this is handled by
+ * SDL_cocoamousetap.m.
+ */
+
+ cgpoint.x = window->x + x;
+ cgpoint.y = window->y + y;
+
+ CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
+ CGAssociateMouseAndMouseCursorPosition(YES);
+
+ Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
+#endif
+ }
+ }
+ SDL_SendMouseMotion(window, 0, 0, x, y);
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ [self mouseMoved:theEvent];
+}
+
+- (void)rightMouseDragged:(NSEvent *)theEvent
+{
+ [self mouseMoved:theEvent];
+}
+
+- (void)otherMouseDragged:(NSEvent *)theEvent
+{
+ [self mouseMoved:theEvent];
+}
+
+- (void)scrollWheel:(NSEvent *)theEvent
+{
+ Cocoa_HandleMouseWheel(_data->window, theEvent);
+}
+
+- (void)touchesBeganWithEvent:(NSEvent *) theEvent
+{
+ NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
+ int existingTouchCount = 0;
+
+ for (NSTouch* touch in touches) {
+ if ([touch phase] != NSTouchPhaseBegan) {
+ existingTouchCount++;
+ }
+ }
+ if (existingTouchCount == 0) {
+ SDL_TouchID touchID = (SDL_TouchID)(intptr_t)[[touches anyObject] device];
+ int numFingers = SDL_GetNumTouchFingers(touchID);
+ DLog("Reset Lost Fingers: %d", numFingers);
+ for (--numFingers; numFingers >= 0; --numFingers) {
+ SDL_Finger* finger = SDL_GetTouchFinger(touchID, numFingers);
+ SDL_SendTouch(touchID, finger->id, SDL_FALSE, 0, 0, 0);
+ }
+ }
+
+ DLog("Began Fingers: %lu .. existing: %d", (unsigned long)[touches count], existingTouchCount);
+ [self handleTouches:NSTouchPhaseBegan withEvent:theEvent];
+}
+
+- (void)touchesMovedWithEvent:(NSEvent *) theEvent
+{
+ [self handleTouches:NSTouchPhaseMoved withEvent:theEvent];
+}
+
+- (void)touchesEndedWithEvent:(NSEvent *) theEvent
+{
+ [self handleTouches:NSTouchPhaseEnded withEvent:theEvent];
+}
+
+- (void)touchesCancelledWithEvent:(NSEvent *) theEvent
+{
+ [self handleTouches:NSTouchPhaseCancelled withEvent:theEvent];
+}
+
+- (void)handleTouches:(NSTouchPhase) phase withEvent:(NSEvent *) theEvent
+{
+ NSSet *touches = [theEvent touchesMatchingPhase:phase inView:nil];
+
+ for (NSTouch *touch in touches) {
+ const SDL_TouchID touchId = (SDL_TouchID)(intptr_t)[touch device];
+ if (SDL_AddTouch(touchId, "") < 0) {
+ return;
+ }
+
+ const SDL_FingerID fingerId = (SDL_FingerID)(intptr_t)[touch identity];
+ float x = [touch normalizedPosition].x;
+ float y = [touch normalizedPosition].y;
+ /* Make the origin the upper left instead of the lower left */
+ y = 1.0f - y;
+
+ switch (phase) {
+ case NSTouchPhaseBegan:
+ SDL_SendTouch(touchId, fingerId, SDL_TRUE, x, y, 1.0f);
+ break;
+ case NSTouchPhaseEnded:
+ case NSTouchPhaseCancelled:
+ SDL_SendTouch(touchId, fingerId, SDL_FALSE, x, y, 1.0f);
+ break;
+ case NSTouchPhaseMoved:
+ SDL_SendTouchMotion(touchId, fingerId, x, y, 1.0f);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+@end
+
+@interface SDLView : NSView {
+ SDL_Window *_sdlWindow;
+}
+
+- (void)setSDLWindow:(SDL_Window*)window;
+
+/* The default implementation doesn't pass rightMouseDown to responder chain */
+- (void)rightMouseDown:(NSEvent *)theEvent;
+- (BOOL)mouseDownCanMoveWindow;
+- (void)drawRect:(NSRect)dirtyRect;
+- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
+- (BOOL)wantsUpdateLayer;
+- (void)updateLayer;
+@end
+
+@implementation SDLView
+
+- (void)setSDLWindow:(SDL_Window*)window
+{
+ _sdlWindow = window;
+}
+
+/* this is used on older macOS revisions. 10.8 and later use updateLayer. */
+- (void)drawRect:(NSRect)dirtyRect
+{
+ /* Force the graphics context to clear to black so we don't get a flash of
+ white until the app is ready to draw. In practice on modern macOS, this
+ only gets called for window creation and other extraordinary events. */
+ [[NSColor blackColor] setFill];
+ NSRectFill(dirtyRect);
+ SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
+}
+
+-(BOOL) wantsUpdateLayer
+{
+ return YES;
+}
+
+-(void) updateLayer
+{
+ /* Force the graphics context to clear to black so we don't get a flash of
+ white until the app is ready to draw. In practice on modern macOS, this
+ only gets called for window creation and other extraordinary events. */
+ self.layer.backgroundColor = NSColor.blackColor.CGColor;
+ ScheduleContextUpdates((SDL_WindowData *) _sdlWindow->driverdata);
+ SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
+}
+
+- (void)rightMouseDown:(NSEvent *)theEvent
+{
+ [[self nextResponder] rightMouseDown:theEvent];
+}
+
+- (BOOL)mouseDownCanMoveWindow
+{
+ /* Always say YES, but this doesn't do anything until we call
+ -[NSWindow setMovableByWindowBackground:YES], which we ninja-toggle
+ during mouse events when we're using a drag area. */
+ return YES;
+}
+
+- (void)resetCursorRects
+{
+ [super resetCursorRects];
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) {
+ [self addCursorRect:[self bounds]
+ cursor:mouse->cur_cursor->driverdata];
+ } else {
+ [self addCursorRect:[self bounds]
+ cursor:[NSCursor invisibleCursor]];
+ }
+}
+
+- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
+{
+ if (SDL_GetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH)) {
+ return SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE);
+ } else {
+ return SDL_GetHintBoolean("SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH", SDL_FALSE);
+ }
+}
+@end
+
+static int
+SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
+{ @autoreleasepool
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *data;
+
+ /* Allocate the window data */
+ window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+ data->window = window;
+ data->nswindow = nswindow;
+ data->created = created;
+ data->videodata = videodata;
+ data->nscontexts = [[NSMutableArray alloc] init];
+
+ /* Create an event listener for the window */
+ data->listener = [[Cocoa_WindowListener alloc] init];
+
+ /* Fill in the SDL window with the window data */
+ {
+ NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
+ ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
+ window->x = (int)rect.origin.x;
+ window->y = (int)rect.origin.y;
+ window->w = (int)rect.size.width;
+ window->h = (int)rect.size.height;
+ }
+
+ /* Set up the listener after we create the view */
+ [data->listener listen:data];
+
+ if ([nswindow isVisible]) {
+ window->flags |= SDL_WINDOW_SHOWN;
+ } else {
+ window->flags &= ~SDL_WINDOW_SHOWN;
+ }
+
+ {
+ unsigned long style = [nswindow styleMask];
+
+ if (style == NSWindowStyleMaskBorderless) {
+ window->flags |= SDL_WINDOW_BORDERLESS;
+ } else {
+ window->flags &= ~SDL_WINDOW_BORDERLESS;
+ }
+ if (style & NSWindowStyleMaskResizable) {
+ window->flags |= SDL_WINDOW_RESIZABLE;
+ } else {
+ window->flags &= ~SDL_WINDOW_RESIZABLE;
+ }
+ }
+
+ /* isZoomed always returns true if the window is not resizable */
+ if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
+ window->flags |= SDL_WINDOW_MAXIMIZED;
+ } else {
+ window->flags &= ~SDL_WINDOW_MAXIMIZED;
+ }
+
+ if ([nswindow isMiniaturized]) {
+ window->flags |= SDL_WINDOW_MINIMIZED;
+ } else {
+ window->flags &= ~SDL_WINDOW_MINIMIZED;
+ }
+
+ if ([nswindow isKeyWindow]) {
+ window->flags |= SDL_WINDOW_INPUT_FOCUS;
+ SDL_SetKeyboardFocus(data->window);
+ }
+
+ /* Prevents the window's "window device" from being destroyed when it is
+ * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
+ */
+ [nswindow setOneShot:NO];
+
+ /* All done! */
+ window->driverdata = data;
+ return 0;
+}}
+
+int
+Cocoa_CreateWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ NSWindow *nswindow;
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ NSRect rect;
+ SDL_Rect bounds;
+ NSUInteger style;
+ NSArray *screens = [NSScreen screens];
+
+ Cocoa_GetDisplayBounds(_this, display, &bounds);
+ rect.origin.x = window->x;
+ rect.origin.y = window->y;
+ rect.size.width = window->w;
+ rect.size.height = window->h;
+ ConvertNSRect([screens objectAtIndex:0], (window->flags & FULLSCREEN_MASK), &rect);
+
+ style = GetWindowStyle(window);
+
+ /* Figure out which screen to place this window */
+ NSScreen *screen = nil;
+ for (NSScreen *candidate in screens) {
+ NSRect screenRect = [candidate frame];
+ if (rect.origin.x >= screenRect.origin.x &&
+ rect.origin.x < screenRect.origin.x + screenRect.size.width &&
+ rect.origin.y >= screenRect.origin.y &&
+ rect.origin.y < screenRect.origin.y + screenRect.size.height) {
+ screen = candidate;
+ rect.origin.x -= screenRect.origin.x;
+ rect.origin.y -= screenRect.origin.y;
+ }
+ }
+
+ @try {
+ nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO screen:screen];
+ }
+ @catch (NSException *e) {
+ return SDL_SetError("%s", [[e reason] UTF8String]);
+ }
+
+ if (videodata->allow_spaces) {
+ SDL_assert(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6);
+ SDL_assert([nswindow respondsToSelector:@selector(toggleFullScreen:)]);
+ /* we put FULLSCREEN_DESKTOP windows in their own Space, without a toggle button or menubar, later */
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
+ [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+ }
+ }
+
+ /* Create a default view for this window */
+ rect = [nswindow contentRectForFrameRect:[nswindow frame]];
+ SDLView *contentView = [[SDLView alloc] initWithFrame:rect];
+ [contentView setSDLWindow:window];
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [contentView setWantsBestResolutionOpenGLSurface:YES];
+ }
+ }
+
+#if SDL_VIDEO_OPENGL_ES2
+#if SDL_VIDEO_OPENGL_EGL
+ if ((window->flags & SDL_WINDOW_OPENGL) &&
+ _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+ [contentView setWantsLayer:TRUE];
+ }
+#endif /* SDL_VIDEO_OPENGL_EGL */
+#endif /* SDL_VIDEO_OPENGL_ES2 */
+ [nswindow setContentView:contentView];
+ [contentView release];
+
+ if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
+ [nswindow release];
+ return -1;
+ }
+
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ return 0;
+ }
+
+ /* The rest of this macro mess is for OpenGL or OpenGL ES windows */
+#if SDL_VIDEO_OPENGL_ES2
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
+#if SDL_VIDEO_OPENGL_EGL
+ if (Cocoa_GLES_SetupWindow(_this, window) < 0) {
+ Cocoa_DestroyWindow(_this, window);
+ return -1;
+ }
+ return 0;
+#else
+ return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ }
+#endif /* SDL_VIDEO_OPENGL_ES2 */
+ return 0;
+}}
+
+int
+Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{ @autoreleasepool
+{
+ NSWindow *nswindow = (NSWindow *) data;
+ NSString *title;
+
+ /* Query the title from the existing window */
+ title = [nswindow title];
+ if (title) {
+ window->title = SDL_strdup([title UTF8String]);
+ }
+
+ return SetupWindowData(_this, window, nswindow, SDL_FALSE);
+}}
+
+void
+Cocoa_SetWindowTitle(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ const char *title = window->title ? window->title : "";
+ NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+ NSString *string = [[NSString alloc] initWithUTF8String:title];
+ [nswindow setTitle:string];
+ [string release];
+}}
+
+void
+Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{ @autoreleasepool
+{
+ NSImage *nsimage = Cocoa_CreateImage(icon);
+
+ if (nsimage) {
+ [NSApp setApplicationIconImage:nsimage];
+ }
+}}
+
+void
+Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = windata->nswindow;
+ NSRect rect;
+ Uint32 moveHack;
+
+ rect.origin.x = window->x;
+ rect.origin.y = window->y;
+ rect.size.width = window->w;
+ rect.size.height = window->h;
+ ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
+
+ moveHack = s_moveHack;
+ s_moveHack = 0;
+ [nswindow setFrameOrigin:rect.origin];
+ s_moveHack = moveHack;
+
+ ScheduleContextUpdates(windata);
+}}
+
+void
+Cocoa_SetWindowSize(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = windata->nswindow;
+ NSRect rect;
+ Uint32 moveHack;
+
+ /* Cocoa will resize the window from the bottom-left rather than the
+ * top-left when -[nswindow setContentSize:] is used, so we must set the
+ * entire frame based on the new size, in order to preserve the position.
+ */
+ rect.origin.x = window->x;
+ rect.origin.y = window->y;
+ rect.size.width = window->w;
+ rect.size.height = window->h;
+ ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
+
+ moveHack = s_moveHack;
+ s_moveHack = 0;
+ [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
+ s_moveHack = moveHack;
+
+ ScheduleContextUpdates(windata);
+}}
+
+void
+Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+
+ NSSize minSize;
+ minSize.width = window->min_w;
+ minSize.height = window->min_h;
+
+ [windata->nswindow setContentMinSize:minSize];
+}}
+
+void
+Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+
+ NSSize maxSize;
+ maxSize.width = window->max_w;
+ maxSize.height = window->max_h;
+
+ [windata->nswindow setContentMaxSize:maxSize];
+}}
+
+void
+Cocoa_ShowWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
+ NSWindow *nswindow = windowData->nswindow;
+
+ if (![nswindow isMiniaturized]) {
+ [windowData->listener pauseVisibleObservation];
+ [nswindow makeKeyAndOrderFront:nil];
+ [windowData->listener resumeVisibleObservation];
+ }
+}}
+
+void
+Cocoa_HideWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+
+ [nswindow orderOut:nil];
+}}
+
+void
+Cocoa_RaiseWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
+ NSWindow *nswindow = windowData->nswindow;
+
+ /* makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing
+ a minimized or hidden window, so check for that before showing it.
+ */
+ [windowData->listener pauseVisibleObservation];
+ if (![nswindow isMiniaturized] && [nswindow isVisible]) {
+ [NSApp activateIgnoringOtherApps:YES];
+ [nswindow makeKeyAndOrderFront:nil];
+ }
+ [windowData->listener resumeVisibleObservation];
+}}
+
+void
+Cocoa_MaximizeWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = windata->nswindow;
+
+ [nswindow zoom:nil];
+
+ ScheduleContextUpdates(windata);
+}}
+
+void
+Cocoa_MinimizeWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = data->nswindow;
+
+ if ([data->listener isInFullscreenSpaceTransition]) {
+ [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE];
+ } else {
+ [nswindow miniaturize:nil];
+ }
+}}
+
+void
+Cocoa_RestoreWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+
+ if ([nswindow isMiniaturized]) {
+ [nswindow deminiaturize:nil];
+ } else if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
+ [nswindow zoom:nil];
+ }
+}}
+
+void
+Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
+{ @autoreleasepool
+{
+ if (SetWindowStyle(window, GetWindowStyle(window))) {
+ if (bordered) {
+ Cocoa_SetWindowTitle(_this, window); /* this got blanked out. */
+ }
+ }
+}}
+
+void
+Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
+{ @autoreleasepool
+{
+ /* Don't set this if we're in a space!
+ * The window will get permanently stuck if resizable is false.
+ * -flibit
+ */
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Cocoa_WindowListener *listener = data->listener;
+ if (![listener isInFullscreenSpace]) {
+ SetWindowStyle(window, GetWindowStyle(window));
+ }
+}}
+
+void
+Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{ @autoreleasepool
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ NSWindow *nswindow = data->nswindow;
+ NSRect rect;
+
+ /* The view responder chain gets messed with during setStyleMask */
+ if ([[nswindow contentView] nextResponder] == data->listener) {
+ [[nswindow contentView] setNextResponder:nil];
+ }
+
+ if (fullscreen) {
+ SDL_Rect bounds;
+
+ Cocoa_GetDisplayBounds(_this, display, &bounds);
+ rect.origin.x = bounds.x;
+ rect.origin.y = bounds.y;
+ rect.size.width = bounds.w;
+ rect.size.height = bounds.h;
+ ConvertNSRect([nswindow screen], fullscreen, &rect);
+
+ /* Hack to fix origin on Mac OS X 10.4 */
+ NSRect screenRect = [[nswindow screen] frame];
+ if (screenRect.size.height >= 1.0f) {
+ rect.origin.y += (screenRect.size.height - rect.size.height);
+ }
+
+ [nswindow setStyleMask:NSWindowStyleMaskBorderless];
+ } else {
+ rect.origin.x = window->windowed.x;
+ rect.origin.y = window->windowed.y;
+ rect.size.width = window->windowed.w;
+ rect.size.height = window->windowed.h;
+ ConvertNSRect([nswindow screen], fullscreen, &rect);
+
+ [nswindow setStyleMask:GetWindowStyle(window)];
+
+ /* Hack to restore window decorations on Mac OS X 10.10 */
+ NSRect frameRect = [nswindow frame];
+ [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
+ [nswindow setFrame:frameRect display:NO];
+ }
+
+ /* The view responder chain gets messed with during setStyleMask */
+ if ([[nswindow contentView] nextResponder] != data->listener) {
+ [[nswindow contentView] setNextResponder:data->listener];
+ }
+
+ s_moveHack = 0;
+ [nswindow setContentSize:rect.size];
+ [nswindow setFrameOrigin:rect.origin];
+ s_moveHack = SDL_GetTicks();
+
+ /* When the window style changes the title is cleared */
+ if (!fullscreen) {
+ Cocoa_SetWindowTitle(_this, window);
+ }
+
+ if (SDL_ShouldAllowTopmost() && fullscreen) {
+ /* OpenGL is rendering to the window, so make it visible! */
+ [nswindow setLevel:CGShieldingWindowLevel()];
+ } else {
+ [nswindow setLevel:kCGNormalWindowLevel];
+ }
+
+ if ([nswindow isVisible] || fullscreen) {
+ [data->listener pauseVisibleObservation];
+ [nswindow makeKeyAndOrderFront:nil];
+ [data->listener resumeVisibleObservation];
+ }
+
+ ScheduleContextUpdates(data);
+}}
+
+int
+Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
+ const uint32_t tableSize = 256;
+ CGGammaValue redTable[tableSize];
+ CGGammaValue greenTable[tableSize];
+ CGGammaValue blueTable[tableSize];
+ uint32_t i;
+ float inv65535 = 1.0f / 65535.0f;
+
+ /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
+ for (i = 0; i < 256; i++) {
+ redTable[i] = ramp[0*256+i] * inv65535;
+ greenTable[i] = ramp[1*256+i] * inv65535;
+ blueTable[i] = ramp[2*256+i] * inv65535;
+ }
+
+ if (CGSetDisplayTransferByTable(display_id, tableSize,
+ redTable, greenTable, blueTable) != CGDisplayNoErr) {
+ return SDL_SetError("CGSetDisplayTransferByTable()");
+ }
+ return 0;
+}
+
+int
+Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
+ const uint32_t tableSize = 256;
+ CGGammaValue redTable[tableSize];
+ CGGammaValue greenTable[tableSize];
+ CGGammaValue blueTable[tableSize];
+ uint32_t i, tableCopied;
+
+ if (CGGetDisplayTransferByTable(display_id, tableSize,
+ redTable, greenTable, blueTable, &tableCopied) != CGDisplayNoErr) {
+ return SDL_SetError("CGGetDisplayTransferByTable()");
+ }
+
+ for (i = 0; i < tableCopied; i++) {
+ ramp[0*256+i] = (Uint16)(redTable[i] * 65535.0f);
+ ramp[1*256+i] = (Uint16)(greenTable[i] * 65535.0f);
+ ramp[2*256+i] = (Uint16)(blueTable[i] * 65535.0f);
+ }
+ return 0;
+}
+
+void
+Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ /* Enable or disable the event tap as necessary */
+ Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed);
+
+ /* Move the cursor to the nearest point in the window */
+ if (grabbed && data && ![data->listener isMoving]) {
+ int x, y;
+ CGPoint cgpoint;
+
+ SDL_GetMouseState(&x, &y);
+ cgpoint.x = window->x + x;
+ cgpoint.y = window->y + y;
+
+ Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
+
+ DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y);
+ CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
+ }
+
+ if ( data && (window->flags & SDL_WINDOW_FULLSCREEN) ) {
+ if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS)
+ && ![data->listener isInFullscreenSpace]) {
+ /* OpenGL is rendering to the window, so make it visible! */
+ /* Doing this in 10.11 while in a Space breaks things (bug #3152) */
+ [data->nswindow setLevel:CGShieldingWindowLevel()];
+ } else {
+ [data->nswindow setLevel:kCGNormalWindowLevel];
+ }
+ }
+}
+
+void
+Cocoa_DestroyWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (data) {
+ if ([data->listener isInFullscreenSpace]) {
+ [NSMenu setMenuBarVisible:YES];
+ }
+ [data->listener close];
+ [data->listener release];
+ if (data->created) {
+ [data->nswindow close];
+ }
+
+ NSArray *contexts = [[data->nscontexts copy] autorelease];
+ for (SDLOpenGLContext *context in contexts) {
+ /* Calling setWindow:NULL causes the context to remove itself from the context list. */
+ [context setWindow:NULL];
+ }
+ [data->nscontexts release];
+
+ SDL_free(data);
+ }
+ window->driverdata = NULL;
+}}
+
+SDL_bool
+Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ info->subsystem = SDL_SYSWM_COCOA;
+ info->info.cocoa.window = nswindow;
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+}
+
+SDL_bool
+Cocoa_IsWindowInFullscreenSpace(SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if ([data->listener isInFullscreenSpace]) {
+ return SDL_TRUE;
+ } else {
+ return SDL_FALSE;
+ }
+}
+
+SDL_bool
+Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state)
+{ @autoreleasepool
+{
+ SDL_bool succeeded = SDL_FALSE;
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if ([data->listener setFullscreenSpace:(state ? YES : NO)]) {
+ const int maxattempts = 3;
+ int attempt = 0;
+ while (++attempt <= maxattempts) {
+ /* Wait for the transition to complete, so application changes
+ take effect properly (e.g. setting the window size, etc.)
+ */
+ const int limit = 10000;
+ int count = 0;
+ while ([data->listener isInFullscreenSpaceTransition]) {
+ if ( ++count == limit ) {
+ /* Uh oh, transition isn't completing. Should we assert? */
+ break;
+ }
+ SDL_Delay(1);
+ SDL_PumpEvents();
+ }
+ if ([data->listener isInFullscreenSpace] == (state ? YES : NO))
+ break;
+ /* Try again, the last attempt was interrupted by user gestures */
+ if (![data->listener setFullscreenSpace:(state ? YES : NO)])
+ break; /* ??? */
+ }
+ /* Return TRUE to prevent non-space fullscreen logic from running */
+ succeeded = SDL_TRUE;
+ }
+
+ return succeeded;
+}}
+
+int
+Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled)
+{
+ return 0; /* just succeed, the real work is done elsewhere. */
+}
+
+void
+Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ if (accept) {
+ [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
+ } else {
+ [data->nswindow unregisterDraggedTypes];
+ }
+}
+
+int
+Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ [data->nswindow setAlphaValue:opacity];
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.c
new file mode 100644
index 0000000..d9d0c3a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.c
@@ -0,0 +1,413 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_window.h"
+
+#include "../../events/SDL_windowevents_c.h"
+
+#define COLOR_EXPAND(col) col.r, col.g, col.b, col.a
+
+static DFB_Theme theme_std = {
+ 4, 4, 8, 8,
+ {255, 200, 200, 200},
+ 24,
+ {255, 0, 0, 255},
+ 16,
+ {255, 255, 255, 255},
+ "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
+ {255, 255, 0, 0},
+ {255, 255, 255, 0},
+};
+
+static DFB_Theme theme_none = {
+ 0, 0, 0, 0,
+ {0, 0, 0, 0},
+ 0,
+ {0, 0, 0, 0},
+ 0,
+ {0, 0, 0, 0},
+ NULL
+};
+
+static void
+DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w)
+{
+ int x1, x2, x3;
+ int y1, y2, y3;
+
+ if (down) {
+ x1 = x + w / 2;
+ x2 = x;
+ x3 = x + w;
+ y1 = y + w;
+ y2 = y;
+ y3 = y;
+ } else {
+ x1 = x + w / 2;
+ x2 = x;
+ x3 = x + w;
+ y1 = y;
+ y2 = y + w;
+ y3 = y + w;
+ }
+ s->FillTriangle(s, x1, y1, x2, y2, x3, y3);
+}
+
+static void
+LoadFont(_THIS, SDL_Window * window)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(window);
+
+ if (windata->font != NULL) {
+ SDL_DFB_RELEASE(windata->font);
+ windata->font = NULL;
+ SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
+ }
+
+ if (windata->theme.font != NULL)
+ {
+ DFBFontDescription fdesc;
+
+ SDL_zero(fdesc);
+ fdesc.flags = DFDESC_HEIGHT;
+ fdesc.height = windata->theme.font_size;
+ SDL_DFB_CHECK(devdata->
+ dfb->CreateFont(devdata->dfb, windata->theme.font,
+ &fdesc, &windata->font));
+ SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
+ }
+}
+
+static void
+DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text)
+{
+ DFBSurfaceTextFlags flags;
+
+ flags = DSTF_CENTER | DSTF_TOP;
+
+ s->DrawString(s, text, -1, x, y, flags);
+}
+
+void
+DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ IDirectFBSurface *s = windata->window_surface;
+ DFB_Theme *t = &windata->theme;
+ int i;
+ int d = (t->caption_size - t->font_size) / 2;
+ int x, y, w;
+
+
+ if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN))
+ return;
+
+ SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE));
+ SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO));
+ SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX));
+ SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX));
+
+ LoadFont(_this, window);
+ /* s->SetDrawingFlags(s, DSDRAW_BLEND); */
+ s->SetColor(s, COLOR_EXPAND(t->frame_color));
+ /* top */
+ for (i = 0; i < t->top_size; i++)
+ s->DrawLine(s, 0, i, windata->size.w, i);
+ /* bottom */
+ for (i = windata->size.h - t->bottom_size; i < windata->size.h; i++)
+ s->DrawLine(s, 0, i, windata->size.w, i);
+ /* left */
+ for (i = 0; i < t->left_size; i++)
+ s->DrawLine(s, i, 0, i, windata->size.h);
+ /* right */
+ for (i = windata->size.w - t->right_size; i < windata->size.w; i++)
+ s->DrawLine(s, i, 0, i, windata->size.h);
+ /* Caption */
+ s->SetColor(s, COLOR_EXPAND(t->caption_color));
+ s->FillRectangle(s, t->left_size, t->top_size, windata->client.w,
+ t->caption_size);
+ /* Close Button */
+ w = t->caption_size;
+ x = windata->size.w - t->right_size - w + d;
+ y = t->top_size + d;
+ s->SetColor(s, COLOR_EXPAND(t->close_color));
+ DrawTriangle(s, 1, x, y, w - 2 * d);
+ /* Max Button */
+ s->SetColor(s, COLOR_EXPAND(t->max_color));
+ DrawTriangle(s, window->flags & SDL_WINDOW_MAXIMIZED ? 1 : 0, x - w,
+ y, w - 2 * d);
+
+ /* Caption */
+ if (*window->title) {
+ s->SetColor(s, COLOR_EXPAND(t->font_color));
+ DrawCraption(_this, s, (x - w) / 2, t->top_size + d, window->title);
+ }
+ /* Icon */
+ if (windata->icon) {
+ DFBRectangle dr;
+
+ dr.x = t->left_size + d;
+ dr.y = t->top_size + d;
+ dr.w = w - 2 * d;
+ dr.h = w - 2 * d;
+ s->SetBlittingFlags(s, DSBLIT_BLEND_ALPHACHANNEL);
+
+ s->StretchBlit(s, windata->icon, NULL, &dr);
+ }
+ windata->wm_needs_redraw = 0;
+}
+
+DFBResult
+DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
+{
+ SDL_DFB_WINDOWDATA(window);
+ IDirectFBWindow *dfbwin = windata->dfbwin;
+
+ SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch));
+ dfbwin->GetSize(dfbwin, cw, ch);
+ *cw -= windata->theme.left_size + windata->theme.right_size;
+ *ch -=
+ windata->theme.top_size + windata->theme.caption_size +
+ windata->theme.bottom_size;
+ return DFB_OK;
+}
+
+void
+DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h)
+{
+ SDL_DFB_WINDOWDATA(window);
+
+ if (!windata->is_managed)
+ windata->theme = theme_none;
+ else if (flags & SDL_WINDOW_BORDERLESS)
+ /* desc.caps |= DWCAPS_NODECORATION;) */
+ windata->theme = theme_none;
+ else if (flags & SDL_WINDOW_FULLSCREEN) {
+ windata->theme = theme_none;
+ } else if (flags & SDL_WINDOW_MAXIMIZED) {
+ windata->theme = theme_std;
+ windata->theme.left_size = 0;
+ windata->theme.right_size = 0;
+ windata->theme.top_size = 0;
+ windata->theme.bottom_size = 0;
+ } else {
+ windata->theme = theme_std;
+ }
+
+ windata->client.x = windata->theme.left_size;
+ windata->client.y = windata->theme.top_size + windata->theme.caption_size;
+ windata->client.w = w;
+ windata->client.h = h;
+ windata->size.w =
+ w + windata->theme.left_size + windata->theme.right_size;
+ windata->size.h =
+ h + windata->theme.top_size +
+ windata->theme.caption_size + windata->theme.bottom_size;
+}
+
+
+enum
+{
+ WM_POS_NONE = 0x00,
+ WM_POS_CAPTION = 0x01,
+ WM_POS_CLOSE = 0x02,
+ WM_POS_MAX = 0x04,
+ WM_POS_LEFT = 0x08,
+ WM_POS_RIGHT = 0x10,
+ WM_POS_TOP = 0x20,
+ WM_POS_BOTTOM = 0x40,
+};
+
+static int
+WMIsClient(DFB_WindowData * p, int x, int y)
+{
+ x -= p->client.x;
+ y -= p->client.y;
+ if (x < 0 || y < 0)
+ return 0;
+ if (x >= p->client.w || y >= p->client.h)
+ return 0;
+ return 1;
+}
+
+static int
+WMPos(DFB_WindowData * p, int x, int y)
+{
+ int pos = WM_POS_NONE;
+
+ if (!WMIsClient(p, x, y)) {
+ if (y < p->theme.top_size) {
+ pos |= WM_POS_TOP;
+ } else if (y < p->client.y) {
+ if (x <
+ p->size.w - p->theme.right_size - 2 * p->theme.caption_size) {
+ pos |= WM_POS_CAPTION;
+ } else if (x <
+ p->size.w - p->theme.right_size -
+ p->theme.caption_size) {
+ pos |= WM_POS_MAX;
+ } else {
+ pos |= WM_POS_CLOSE;
+ }
+ } else if (y >= p->size.h - p->theme.bottom_size) {
+ pos |= WM_POS_BOTTOM;
+ }
+ if (x < p->theme.left_size) {
+ pos |= WM_POS_LEFT;
+ } else if (x >= p->size.w - p->theme.right_size) {
+ pos |= WM_POS_RIGHT;
+ }
+ }
+ return pos;
+}
+
+int
+DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(window);
+ DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
+ IDirectFBWindow *dfbwin = windata->dfbwin;
+ DFBWindowOptions wopts;
+
+ if (!windata->is_managed)
+ return 0;
+
+ SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts));
+
+ switch (evt->type) {
+ case DWET_BUTTONDOWN:
+ if (evt->buttons & DIBM_LEFT) {
+ int pos = WMPos(windata, evt->x, evt->y);
+ switch (pos) {
+ case WM_POS_NONE:
+ return 0;
+ case WM_POS_CLOSE:
+ windata->wm_grab = WM_POS_NONE;
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0,
+ 0);
+ return 1;
+ case WM_POS_MAX:
+ windata->wm_grab = WM_POS_NONE;
+ if (window->flags & SDL_WINDOW_MAXIMIZED) {
+ SDL_RestoreWindow(window);
+ } else {
+ SDL_MaximizeWindow(window);
+ }
+ return 1;
+ case WM_POS_CAPTION:
+ if (!(wopts & DWOP_KEEP_STACKING)) {
+ DirectFB_RaiseWindow(_this, window);
+ }
+ if (window->flags & SDL_WINDOW_MAXIMIZED)
+ return 1;
+ /* fall through */
+ default:
+ windata->wm_grab = pos;
+ if (gwindata != NULL)
+ SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
+ SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin));
+ windata->wm_lastx = evt->cx;
+ windata->wm_lasty = evt->cy;
+ }
+ }
+ return 1;
+ case DWET_BUTTONUP:
+ if (!windata->wm_grab)
+ return 0;
+ if (!(evt->buttons & DIBM_LEFT)) {
+ if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
+ int dx = evt->cx - windata->wm_lastx;
+ int dy = evt->cy - windata->wm_lasty;
+
+ if (!(wopts & DWOP_KEEP_SIZE)) {
+ int cw, ch;
+ if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
+ dx = 0;
+ else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
+ dy = 0;
+ SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
+
+ /* necessary to trigger an event - ugly */
+ SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
+ SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy));
+ SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
+
+ SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
+ }
+ }
+ SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin));
+ if (gwindata != NULL)
+ SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin));
+ windata->wm_grab = WM_POS_NONE;
+ return 1;
+ }
+ break;
+ case DWET_MOTION:
+ if (!windata->wm_grab)
+ return 0;
+ if (evt->buttons & DIBM_LEFT) {
+ int dx = evt->cx - windata->wm_lastx;
+ int dy = evt->cy - windata->wm_lasty;
+
+ if (windata->wm_grab & WM_POS_CAPTION) {
+ if (!(wopts & DWOP_KEEP_POSITION))
+ SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy));
+ }
+ if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
+ if (!(wopts & DWOP_KEEP_SIZE)) {
+ int cw, ch;
+
+ /* Make sure all events are disabled for this operation ! */
+ SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
+
+ if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
+ dx = 0;
+ else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
+ dy = 0;
+
+ SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
+ SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
+
+ SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
+ }
+ }
+ windata->wm_lastx = evt->cx;
+ windata->wm_lasty = evt->cy;
+ return 1;
+ }
+ break;
+ case DWET_KEYDOWN:
+ break;
+ case DWET_KEYUP:
+ break;
+ default:
+ ;
+ }
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.h
new file mode 100644
index 0000000..98d943f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_WM.h
@@ -0,0 +1,56 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_directfb_wm_h_
+#define SDL_directfb_wm_h_
+
+#include "SDL_DirectFB_video.h"
+
+typedef struct _DFB_Theme DFB_Theme;
+struct _DFB_Theme
+{
+ int left_size;
+ int right_size;
+ int top_size;
+ int bottom_size;
+ DFBColor frame_color;
+ int caption_size;
+ DFBColor caption_color;
+ int font_size;
+ DFBColor font_color;
+ char *font;
+ DFBColor close_color;
+ DFBColor max_color;
+};
+
+extern void DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h);
+extern void DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window);
+
+extern int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window,
+ DFBWindowEvent * evt);
+
+extern DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window * window,
+ int *cw, int *ch);
+
+
+#endif /* SDL_directfb_wm_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.c
new file mode 100644
index 0000000..12cf21a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.c
@@ -0,0 +1,117 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_dyn.h"
+
+#ifdef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+#define DFB_SYM(ret, name, args, al, func) ret (*name) args;
+static struct _SDL_DirectFB_Symbols
+{
+ DFB_SYMS
+ const unsigned int *directfb_major_version;
+ const unsigned int *directfb_minor_version;
+ const unsigned int *directfb_micro_version;
+} SDL_DirectFB_Symbols;
+#undef DFB_SYM
+
+#define DFB_SYM(ret, name, args, al, func) ret name args { func SDL_DirectFB_Symbols.name al ; }
+DFB_SYMS
+#undef DFB_SYM
+
+static void *handle = NULL;
+
+int
+SDL_DirectFB_LoadLibrary(void)
+{
+ int retval = 0;
+
+ if (handle == NULL) {
+ handle = SDL_LoadObject(SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC);
+ if (handle != NULL) {
+ retval = 1;
+#define DFB_SYM(ret, name, args, al, func) if (!(SDL_DirectFB_Symbols.name = SDL_LoadFunction(handle, # name))) retval = 0;
+ DFB_SYMS
+#undef DFB_SYM
+ if (!
+ (SDL_DirectFB_Symbols.directfb_major_version =
+ SDL_LoadFunction(handle, "directfb_major_version")))
+ retval = 0;
+ if (!
+ (SDL_DirectFB_Symbols.directfb_minor_version =
+ SDL_LoadFunction(handle, "directfb_minor_version")))
+ retval = 0;
+ if (!
+ (SDL_DirectFB_Symbols.directfb_micro_version =
+ SDL_LoadFunction(handle, "directfb_micro_version")))
+ retval = 0;
+ }
+ }
+ if (retval) {
+ const char *stemp = DirectFBCheckVersion(DIRECTFB_MAJOR_VERSION,
+ DIRECTFB_MINOR_VERSION,
+ DIRECTFB_MICRO_VERSION);
+ /* Version Check */
+ if (stemp != NULL) {
+ fprintf(stderr,
+ "DirectFB Lib: Version mismatch. Compiled: %d.%d.%d Library %d.%d.%d\n",
+ DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION,
+ DIRECTFB_MICRO_VERSION,
+ *SDL_DirectFB_Symbols.directfb_major_version,
+ *SDL_DirectFB_Symbols.directfb_minor_version,
+ *SDL_DirectFB_Symbols.directfb_micro_version);
+ retval = 0;
+ }
+ }
+ if (!retval)
+ SDL_DirectFB_UnLoadLibrary();
+ return retval;
+}
+
+void
+SDL_DirectFB_UnLoadLibrary(void)
+{
+ if (handle != NULL) {
+ SDL_UnloadObject(handle);
+ handle = NULL;
+ }
+}
+
+#else
+int
+SDL_DirectFB_LoadLibrary(void)
+{
+ return 1;
+}
+
+void
+SDL_DirectFB_UnLoadLibrary(void)
+{
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.h
new file mode 100644
index 0000000..1a370c6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_dyn.h
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_DirectFB_dyn_h_
+#define SDL_DirectFB_dyn_h_
+
+#define DFB_SYMS \
+ DFB_SYM(DFBResult, DirectFBError, (const char *msg, DFBResult result), (msg, result), return) \
+ DFB_SYM(DFBResult, DirectFBErrorFatal, (const char *msg, DFBResult result), (msg, result), return) \
+ DFB_SYM(const char *, DirectFBErrorString, (DFBResult result), (result), return) \
+ DFB_SYM(const char *, DirectFBUsageString, ( void ), (), return) \
+ DFB_SYM(DFBResult, DirectFBInit, (int *argc, char *(*argv[]) ), (argc, argv), return) \
+ DFB_SYM(DFBResult, DirectFBSetOption, (const char *name, const char *value), (name, value), return) \
+ DFB_SYM(DFBResult, DirectFBCreate, (IDirectFB **interface), (interface), return) \
+ DFB_SYM(const char *, DirectFBCheckVersion, (unsigned int required_major, unsigned int required_minor, unsigned int required_micro), \
+ (required_major, required_minor, required_micro), return)
+
+int SDL_DirectFB_LoadLibrary(void);
+void SDL_DirectFB_UnLoadLibrary(void);
+
+#endif /* SDL_DirectFB_dyn_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c
new file mode 100644
index 0000000..27cf19f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c
@@ -0,0 +1,748 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+/* Handle the event stream, converting DirectFB input events into SDL events */
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_window.h"
+#include "SDL_DirectFB_modes.h"
+
+#include "SDL_syswm.h"
+
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_windowevents_c.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/scancodes_linux.h"
+#include "../../events/scancodes_xfree86.h"
+
+#include "SDL_DirectFB_events.h"
+
+#if USE_MULTI_API
+#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y, p)
+#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
+#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(id, state, scancode)
+#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(id, text)
+#else
+#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y)
+#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
+#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(state, scancode)
+#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(text)
+#endif
+
+typedef struct _cb_data cb_data;
+struct _cb_data
+{
+ DFB_DeviceData *devdata;
+ int sys_ids;
+ int sys_kbd;
+};
+
+/* The translation tables from a DirectFB keycode to a SDL keysym */
+static SDL_Scancode oskeymap[256];
+
+
+static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
+ SDL_Keysym * keysym, Uint32 *unicode);
+static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
+ SDL_Keysym * keysym, Uint32 *unicode);
+
+static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys);
+static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
+
+static void UnicodeToUtf8( Uint16 w , char *utf8buf)
+{
+ unsigned char *utf8s = (unsigned char *) utf8buf;
+
+ if ( w < 0x0080 ) {
+ utf8s[0] = ( unsigned char ) w;
+ utf8s[1] = 0;
+ }
+ else if ( w < 0x0800 ) {
+ utf8s[0] = 0xc0 | (( w ) >> 6 );
+ utf8s[1] = 0x80 | (( w ) & 0x3f );
+ utf8s[2] = 0;
+ }
+ else {
+ utf8s[0] = 0xe0 | (( w ) >> 12 );
+ utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f );
+ utf8s[2] = 0x80 | (( w ) & 0x3f );
+ utf8s[3] = 0;
+ }
+}
+
+static void
+FocusAllMice(_THIS, SDL_Window *window)
+{
+#if USE_MULTI_API
+ SDL_DFB_DEVICEDATA(_this);
+ int index;
+
+ for (index = 0; index < devdata->num_mice; index++)
+ SDL_SetMouseFocus(devdata->mouse_id[index], id);
+#else
+ SDL_SetMouseFocus(window);
+#endif
+}
+
+
+static void
+FocusAllKeyboards(_THIS, SDL_Window *window)
+{
+#if USE_MULTI_API
+ SDL_DFB_DEVICEDATA(_this);
+ int index;
+
+ for (index = 0; index < devdata->num_keyboard; index++)
+ SDL_SetKeyboardFocus(index, id);
+#else
+ SDL_SetKeyboardFocus(window);
+#endif
+}
+
+static void
+MotionAllMice(_THIS, int x, int y)
+{
+#if USE_MULTI_API
+ SDL_DFB_DEVICEDATA(_this);
+ int index;
+
+ for (index = 0; index < devdata->num_mice; index++) {
+ SDL_Mouse *mouse = SDL_GetMouse(index);
+ mouse->x = mouse->last_x = x;
+ mouse->y = mouse->last_y = y;
+ /* SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0); */
+ }
+#endif
+}
+
+static int
+KbdIndex(_THIS, int id)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ int index;
+
+ for (index = 0; index < devdata->num_keyboard; index++) {
+ if (devdata->keyboard[index].id == id)
+ return index;
+ }
+ return -1;
+}
+
+static int
+ClientXY(DFB_WindowData * p, int *x, int *y)
+{
+ int cx, cy;
+
+ cx = *x;
+ cy = *y;
+
+ cx -= p->client.x;
+ cy -= p->client.y;
+
+ if (cx < 0 || cy < 0)
+ return 0;
+ if (cx >= p->client.w || cy >= p->client.h)
+ return 0;
+ *x = cx;
+ *y = cy;
+ return 1;
+}
+
+static void
+ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(sdlwin);
+ SDL_Keysym keysym;
+ Uint32 unicode;
+ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
+
+ if (evt->clazz == DFEC_WINDOW) {
+ switch (evt->type) {
+ case DWET_BUTTONDOWN:
+ if (ClientXY(windata, &evt->x, &evt->y)) {
+ if (!devdata->use_linux_input) {
+ SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
+ evt->y, 0);
+ SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
+ SDL_PRESSED,
+ DirectFB_TranslateButton
+ (evt->button));
+ } else {
+ MotionAllMice(_this, evt->x, evt->y);
+ }
+ }
+ break;
+ case DWET_BUTTONUP:
+ if (ClientXY(windata, &evt->x, &evt->y)) {
+ if (!devdata->use_linux_input) {
+ SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
+ evt->y, 0);
+ SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
+ SDL_RELEASED,
+ DirectFB_TranslateButton
+ (evt->button));
+ } else {
+ MotionAllMice(_this, evt->x, evt->y);
+ }
+ }
+ break;
+ case DWET_MOTION:
+ if (ClientXY(windata, &evt->x, &evt->y)) {
+ if (!devdata->use_linux_input) {
+ if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED))
+ SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
+ evt->x, evt->y, 0);
+ } else {
+ /* relative movements are not exact!
+ * This code should limit the number of events sent.
+ * However it kills MAME axis recognition ... */
+ static int cnt = 0;
+ if (1 && ++cnt > 20) {
+ MotionAllMice(_this, evt->x, evt->y);
+ cnt = 0;
+ }
+ }
+ if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS))
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0,
+ 0);
+ }
+ break;
+ case DWET_KEYDOWN:
+ if (!devdata->use_linux_input) {
+ DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
+ /* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
+ SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode);
+ if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
+ SDL_zero(text);
+ UnicodeToUtf8(unicode, text);
+ if (*text) {
+ SDL_SendKeyboardText_ex(0, text);
+ }
+ }
+ }
+ break;
+ case DWET_KEYUP:
+ if (!devdata->use_linux_input) {
+ DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
+ SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode);
+ }
+ break;
+ case DWET_POSITION:
+ if (ClientXY(windata, &evt->x, &evt->y)) {
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
+ evt->x, evt->y);
+ }
+ break;
+ case DWET_POSITION_SIZE:
+ if (ClientXY(windata, &evt->x, &evt->y)) {
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
+ evt->x, evt->y);
+ }
+ /* fall throught */
+ case DWET_SIZE:
+ /* FIXME: what about < 0 */
+ evt->w -= (windata->theme.right_size + windata->theme.left_size);
+ evt->h -=
+ (windata->theme.top_size + windata->theme.bottom_size +
+ windata->theme.caption_size);
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED,
+ evt->w, evt->h);
+ break;
+ case DWET_CLOSE:
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0);
+ break;
+ case DWET_GOTFOCUS:
+ DirectFB_SetContext(_this, sdlwin);
+ FocusAllKeyboards(_this, sdlwin);
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED,
+ 0, 0);
+ break;
+ case DWET_LOSTFOCUS:
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+ FocusAllKeyboards(_this, 0);
+ break;
+ case DWET_ENTER:
+ /* SDL_DirectFB_ReshowCursor(_this, 0); */
+ FocusAllMice(_this, sdlwin);
+ /* FIXME: when do we really enter ? */
+ if (ClientXY(windata, &evt->x, &evt->y))
+ MotionAllMice(_this, evt->x, evt->y);
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0);
+ break;
+ case DWET_LEAVE:
+ SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0);
+ FocusAllMice(_this, 0);
+ /* SDL_DirectFB_ReshowCursor(_this, 1); */
+ break;
+ default:
+ ;
+ }
+ } else
+ printf("Event Clazz %d\n", evt->clazz);
+}
+
+static void
+ProcessInputEvent(_THIS, DFBInputEvent * ievt)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_Keysym keysym;
+ int kbd_idx;
+ Uint32 unicode;
+ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
+
+ if (!devdata->use_linux_input) {
+ if (ievt->type == DIET_AXISMOTION) {
+ if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
+ if (ievt->axis == DIAI_X)
+ SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
+ ievt->axisrel, 0, 0);
+ else if (ievt->axis == DIAI_Y)
+ SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
+ ievt->axisrel, 0);
+ }
+ }
+ } else {
+ static int last_x, last_y;
+
+ switch (ievt->type) {
+ case DIET_AXISMOTION:
+ if (ievt->flags & DIEF_AXISABS) {
+ if (ievt->axis == DIAI_X)
+ last_x = ievt->axisabs;
+ else if (ievt->axis == DIAI_Y)
+ last_y = ievt->axisabs;
+ if (!(ievt->flags & DIEF_FOLLOW)) {
+#if USE_MULTI_API
+ SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
+ SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
+#else
+ SDL_Window *window = devdata->grabbed_window;
+#endif
+ if (window) {
+ DFB_WindowData *windata =
+ (DFB_WindowData *) window->driverdata;
+ int x, y;
+
+ windata->dfbwin->GetPosition(windata->dfbwin, &x, &y);
+ SDL_SendMouseMotion_ex(window, ievt->device_id, 0,
+ last_x - (x +
+ windata->client.x),
+ last_y - (y +
+ windata->client.y), 0);
+ } else {
+ SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x,
+ last_y, 0);
+ }
+ }
+ } else if (ievt->flags & DIEF_AXISREL) {
+ if (ievt->axis == DIAI_X)
+ SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
+ ievt->axisrel, 0, 0);
+ else if (ievt->axis == DIAI_Y)
+ SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
+ ievt->axisrel, 0);
+ }
+ break;
+ case DIET_KEYPRESS:
+ kbd_idx = KbdIndex(_this, ievt->device_id);
+ DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
+ /* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
+ SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode);
+ if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
+ SDL_zero(text);
+ UnicodeToUtf8(unicode, text);
+ if (*text) {
+ SDL_SendKeyboardText_ex(kbd_idx, text);
+ }
+ }
+ break;
+ case DIET_KEYRELEASE:
+ kbd_idx = KbdIndex(_this, ievt->device_id);
+ DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
+ SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode);
+ break;
+ case DIET_BUTTONPRESS:
+ if (ievt->buttons & DIBM_LEFT)
+ SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1);
+ if (ievt->buttons & DIBM_MIDDLE)
+ SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2);
+ if (ievt->buttons & DIBM_RIGHT)
+ SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3);
+ break;
+ case DIET_BUTTONRELEASE:
+ if (!(ievt->buttons & DIBM_LEFT))
+ SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1);
+ if (!(ievt->buttons & DIBM_MIDDLE))
+ SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2);
+ if (!(ievt->buttons & DIBM_RIGHT))
+ SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3);
+ break;
+ default:
+ break; /* please gcc */
+ }
+ }
+}
+
+void
+DirectFB_PumpEventsWindow(_THIS)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ DFBInputEvent ievt;
+ SDL_Window *w;
+
+ for (w = devdata->firstwin; w != NULL; w = w->next) {
+ SDL_DFB_WINDOWDATA(w);
+ DFBWindowEvent evt;
+
+ while (windata->eventbuffer->GetEvent(windata->eventbuffer,
+ DFB_EVENT(&evt)) == DFB_OK) {
+ if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) {
+ /* Send a SDL_SYSWMEVENT if the application wants them */
+ if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
+ SDL_SysWMmsg wmmsg;
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
+ wmmsg.msg.dfb.event.window = evt;
+ SDL_SendSysWMEvent(&wmmsg);
+ }
+ ProcessWindowEvent(_this, w, &evt);
+ }
+ }
+ }
+
+ /* Now get relative events in case we need them */
+ while (devdata->events->GetEvent(devdata->events,
+ DFB_EVENT(&ievt)) == DFB_OK) {
+
+ if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
+ SDL_SysWMmsg wmmsg;
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
+ wmmsg.msg.dfb.event.input = ievt;
+ SDL_SendSysWMEvent(&wmmsg);
+ }
+ ProcessInputEvent(_this, &ievt);
+ }
+}
+
+void
+DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys)
+{
+ int i;
+
+ /* Initialize the DirectFB key translation table */
+ for (i = 0; i < numkeys; ++i)
+ keymap[i] = SDL_SCANCODE_UNKNOWN;
+
+ keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
+ keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
+ keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
+ keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
+ keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
+ keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
+ keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
+ keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
+ keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
+ keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
+ keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
+ keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
+ keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
+ keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
+ keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
+ keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
+ keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
+ keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
+ keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
+ keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
+ keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
+ keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
+ keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
+ keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
+ keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
+ keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
+
+ keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
+ keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
+ keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
+ keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
+ keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
+ keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
+ keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
+ keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
+ keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
+ keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
+
+ keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
+ keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
+ keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
+ keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
+ keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
+ keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
+ keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
+ keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
+ keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
+ keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
+ keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
+ keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
+
+ keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
+ keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
+ keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
+ keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
+ keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
+ keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
+ keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
+ keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
+ keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
+ keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
+ keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
+ keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
+ keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
+ keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
+ keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
+ /* FIXME:Do we read hyper keys ?
+ * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
+ * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
+ */
+ keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
+ keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
+ keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
+ keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
+ keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
+ keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
+ keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
+ keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
+ keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
+ keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
+ keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
+ keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
+ keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
+ keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
+ keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
+
+ keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
+ keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
+ keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
+ keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
+ keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
+ keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
+ keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
+ keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
+ keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
+ keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
+ keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
+ keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
+ keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
+ keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
+ keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
+ keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
+ keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
+
+ keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE; /* TLDE */
+ keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS; /* AE11 */
+ keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS; /* AE12 */
+ keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET; /* AD11 */
+ keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET; /* AD12 */
+ keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH; /* BKSL */
+ keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON; /* AC10 */
+ keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE; /* AC11 */
+ keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA; /* AB08 */
+ keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD; /* AB09 */
+ keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH; /* AB10 */
+ keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH; /* 103rd */
+
+}
+
+static SDL_Keysym *
+DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */
+ DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
+
+ keysym->scancode = SDL_SCANCODE_UNKNOWN;
+
+ if (kbd->map && evt->key_code >= kbd->map_adjust &&
+ evt->key_code < kbd->map_size + kbd->map_adjust)
+ keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
+
+ if (keysym->scancode == SDL_SCANCODE_UNKNOWN ||
+ devdata->keyboard[kbd_idx].is_generic) {
+ if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
+ keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
+ else
+ keysym->scancode = SDL_SCANCODE_UNKNOWN;
+ }
+
+ *unicode =
+ (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
+ if (*unicode == 0 &&
+ (evt->key_symbol > 0 && evt->key_symbol < 255))
+ *unicode = evt->key_symbol;
+
+ return keysym;
+}
+
+static SDL_Keysym *
+DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
+ SDL_Keysym * keysym, Uint32 *unicode)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ int kbd_idx = KbdIndex(_this, evt->device_id);
+ DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
+
+ keysym->scancode = SDL_SCANCODE_UNKNOWN;
+
+ if (kbd->map && evt->key_code >= kbd->map_adjust &&
+ evt->key_code < kbd->map_size + kbd->map_adjust)
+ keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
+
+ if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) {
+ if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
+ keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
+ else
+ keysym->scancode = SDL_SCANCODE_UNKNOWN;
+ }
+
+ *unicode =
+ (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
+ if (*unicode == 0 &&
+ (evt->key_symbol > 0 && evt->key_symbol < 255))
+ *unicode = evt->key_symbol;
+
+ return keysym;
+}
+
+static int
+DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
+{
+ switch (button) {
+ case DIBI_LEFT:
+ return 1;
+ case DIBI_MIDDLE:
+ return 2;
+ case DIBI_RIGHT:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
+static DFBEnumerationResult
+EnumKeyboards(DFBInputDeviceID device_id,
+ DFBInputDeviceDescription desc, void *callbackdata)
+{
+ cb_data *cb = callbackdata;
+ DFB_DeviceData *devdata = cb->devdata;
+#if USE_MULTI_API
+ SDL_Keyboard keyboard;
+#endif
+ SDL_Keycode keymap[SDL_NUM_SCANCODES];
+
+ if (!cb->sys_kbd) {
+ if (cb->sys_ids) {
+ if (device_id >= 0x10)
+ return DFENUM_OK;
+ } else {
+ if (device_id < 0x10)
+ return DFENUM_OK;
+ }
+ } else {
+ if (device_id != DIDID_KEYBOARD)
+ return DFENUM_OK;
+ }
+
+ if ((desc.caps & DIDTF_KEYBOARD)) {
+#if USE_MULTI_API
+ SDL_zero(keyboard);
+ SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
+#endif
+ devdata->keyboard[devdata->num_keyboard].id = device_id;
+ devdata->keyboard[devdata->num_keyboard].is_generic = 0;
+ if (!strncmp("X11", desc.name, 3))
+ {
+ devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
+ devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);
+ devdata->keyboard[devdata->num_keyboard].map_adjust = 8;
+ } else {
+ devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table;
+ devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table);
+ devdata->keyboard[devdata->num_keyboard].map_adjust = 0;
+ }
+
+ SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name);
+
+ SDL_GetDefaultKeymap(keymap);
+#if USE_MULTI_API
+ SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
+#else
+ SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
+#endif
+ devdata->num_keyboard++;
+
+ if (cb->sys_kbd)
+ return DFENUM_CANCEL;
+ }
+ return DFENUM_OK;
+}
+
+void
+DirectFB_InitKeyboard(_THIS)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ cb_data cb;
+
+ DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
+
+ devdata->num_keyboard = 0;
+ cb.devdata = devdata;
+
+ if (devdata->use_linux_input) {
+ cb.sys_kbd = 0;
+ cb.sys_ids = 0;
+ SDL_DFB_CHECK(devdata->dfb->
+ EnumInputDevices(devdata->dfb, EnumKeyboards, &cb));
+ if (devdata->num_keyboard == 0) {
+ cb.sys_ids = 1;
+ SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
+ EnumKeyboards,
+ &cb));
+ }
+ } else {
+ cb.sys_kbd = 1;
+ SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
+ EnumKeyboards,
+ &cb));
+ }
+}
+
+void
+DirectFB_QuitKeyboard(_THIS)
+{
+ /* SDL_DFB_DEVICEDATA(_this); */
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.h
new file mode 100644
index 0000000..ccbdb0a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.h
@@ -0,0 +1,34 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_DirectFB_events_h_
+#define SDL_DirectFB_events_h_
+
+#include "../SDL_sysvideo.h"
+
+/* Functions to be exported */
+extern void DirectFB_InitKeyboard(_THIS);
+extern void DirectFB_QuitKeyboard(_THIS);
+extern void DirectFB_PumpEventsWindow(_THIS);
+
+#endif /* SDL_DirectFB_events_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.c
new file mode 100644
index 0000000..a3b8b45
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.c
@@ -0,0 +1,414 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_modes.h"
+
+#define DFB_MAX_MODES 200
+
+struct screen_callback_t
+{
+ int numscreens;
+ DFBScreenID screenid[DFB_MAX_SCREENS];
+ DFBDisplayLayerID gralayer[DFB_MAX_SCREENS];
+ DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS];
+ int aux; /* auxiliary integer for callbacks */
+};
+
+struct modes_callback_t
+{
+ int nummodes;
+ SDL_DisplayMode *modelist;
+};
+
+static DFBEnumerationResult
+EnumModesCallback(int width, int height, int bpp, void *data)
+{
+ struct modes_callback_t *modedata = (struct modes_callback_t *) data;
+ SDL_DisplayMode mode;
+
+ mode.w = width;
+ mode.h = height;
+ mode.refresh_rate = 0;
+ mode.driverdata = NULL;
+ mode.format = SDL_PIXELFORMAT_UNKNOWN;
+
+ if (modedata->nummodes < DFB_MAX_MODES) {
+ modedata->modelist[modedata->nummodes++] = mode;
+ }
+
+ return DFENUM_OK;
+}
+
+static DFBEnumerationResult
+EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc,
+ void *callbackdata)
+{
+ struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
+
+ devdata->screenid[devdata->numscreens++] = screen_id;
+ return DFENUM_OK;
+}
+
+static DFBEnumerationResult
+EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc,
+ void *callbackdata)
+{
+ struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
+
+ if (desc.caps & DLCAPS_SURFACE) {
+ if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) {
+ if (devdata->vidlayer[devdata->aux] == -1)
+ devdata->vidlayer[devdata->aux] = layer_id;
+ } else if (desc.type & DLTF_GRAPHICS) {
+ if (devdata->gralayer[devdata->aux] == -1)
+ devdata->gralayer[devdata->aux] = layer_id;
+ }
+ }
+ return DFENUM_OK;
+}
+
+static void
+CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ DFBDisplayLayerConfig config;
+ DFBDisplayLayerConfigFlags failed;
+
+ SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
+ DLSCL_ADMINISTRATIVE));
+ config.width = mode->w;
+ config.height = mode->h;
+ config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
+ config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
+ if (devdata->use_yuv_underlays) {
+ config.flags |= DLCONF_OPTIONS;
+ config.options = DLOP_ALPHACHANNEL;
+ }
+ failed = 0;
+ data->layer->TestConfiguration(data->layer, &config, &failed);
+ SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
+ DLSCL_SHARED));
+ if (failed == 0)
+ {
+ SDL_AddDisplayMode(display, mode);
+ SDL_DFB_LOG("Mode %d x %d Added\n", mode->w, mode->h);
+ }
+ else
+ SDL_DFB_ERR("Mode %d x %d not available: %x\n", mode->w,
+ mode->h, failed);
+
+ return;
+ error:
+ return;
+}
+
+
+void
+DirectFB_SetContext(_THIS, SDL_Window *window)
+{
+#if (DFB_VERSION_ATLEAST(1,0,0))
+ /* FIXME: does not work on 1.0/1.2 with radeon driver
+ * the approach did work with the matrox driver
+ * This has simply no effect.
+ */
+
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+
+ /* FIXME: should we handle the error */
+ if (dispdata->vidIDinuse)
+ SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer,
+ DFB_TRUE));
+#endif
+}
+
+void
+DirectFB_InitModes(_THIS)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ IDirectFBDisplayLayer *layer = NULL;
+ SDL_VideoDisplay display;
+ DFB_DisplayData *dispdata = NULL;
+ SDL_DisplayMode mode;
+ DFBGraphicsDeviceDescription caps;
+ DFBDisplayLayerConfig dlc;
+ struct screen_callback_t *screencbdata;
+
+ int tcw[DFB_MAX_SCREENS];
+ int tch[DFB_MAX_SCREENS];
+ int i;
+ DFBResult ret;
+
+ SDL_DFB_ALLOC_CLEAR(screencbdata, sizeof(*screencbdata));
+
+ screencbdata->numscreens = 0;
+
+ for (i = 0; i < DFB_MAX_SCREENS; i++) {
+ screencbdata->gralayer[i] = -1;
+ screencbdata->vidlayer[i] = -1;
+ }
+
+ SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &EnumScreensCallback,
+ screencbdata));
+
+ for (i = 0; i < screencbdata->numscreens; i++) {
+ IDirectFBScreen *screen;
+
+ SDL_DFB_CHECKERR(devdata->dfb->GetScreen(devdata->dfb,
+ screencbdata->screenid
+ [i], &screen));
+
+ screencbdata->aux = i;
+ SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &EnumLayersCallback,
+ screencbdata));
+ screen->GetSize(screen, &tcw[i], &tch[i]);
+
+ screen->Release(screen);
+ }
+
+ /* Query card capabilities */
+
+ devdata->dfb->GetDeviceDescription(devdata->dfb, &caps);
+
+ for (i = 0; i < screencbdata->numscreens; i++) {
+ SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
+ screencbdata->gralayer
+ [i], &layer));
+
+ SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer,
+ DLSCL_ADMINISTRATIVE));
+ layer->EnableCursor(layer, 1);
+ SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0));
+
+ if (devdata->use_yuv_underlays) {
+ dlc.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS;
+ dlc.pixelformat = DSPF_ARGB;
+ dlc.options = DLOP_ALPHACHANNEL;
+
+ ret = layer->SetConfiguration(layer, &dlc);
+ if (ret != DFB_OK) {
+ /* try AiRGB if the previous failed */
+ dlc.pixelformat = DSPF_AiRGB;
+ SDL_DFB_CHECKERR(layer->SetConfiguration(layer, &dlc));
+ }
+ }
+
+ /* Query layer configuration to determine the current mode and pixelformat */
+ dlc.flags = DLCONF_ALL;
+ SDL_DFB_CHECKERR(layer->GetConfiguration(layer, &dlc));
+
+ mode.format = DirectFB_DFBToSDLPixelFormat(dlc.pixelformat);
+
+ if (mode.format == SDL_PIXELFORMAT_UNKNOWN) {
+ SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat);
+ goto error;
+ }
+
+ mode.w = dlc.width;
+ mode.h = dlc.height;
+ mode.refresh_rate = 0;
+ mode.driverdata = NULL;
+
+ SDL_DFB_ALLOC_CLEAR(dispdata, sizeof(*dispdata));
+
+ dispdata->layer = layer;
+ dispdata->pixelformat = dlc.pixelformat;
+ dispdata->cw = tcw[i];
+ dispdata->ch = tch[i];
+
+ /* YUV - Video layer */
+
+ dispdata->vidID = screencbdata->vidlayer[i];
+ dispdata->vidIDinuse = 0;
+
+ SDL_zero(display);
+
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ display.driverdata = dispdata;
+
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ dlc.flags =
+ DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
+ DLCONF_OPTIONS;
+ ret = layer->SetConfiguration(layer, &dlc);
+#endif
+
+ SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
+
+ SDL_AddVideoDisplay(&display);
+ }
+ SDL_DFB_FREE(screencbdata);
+ return;
+ error:
+ /* FIXME: Cleanup not complete, Free existing displays */
+ SDL_DFB_FREE(dispdata);
+ SDL_DFB_RELEASE(layer);
+ return;
+}
+
+void
+DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+ SDL_DisplayMode mode;
+ struct modes_callback_t data;
+ int i;
+
+ data.nummodes = 0;
+ /* Enumerate the available fullscreen modes */
+ SDL_DFB_CALLOC(data.modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode));
+ SDL_DFB_CHECKERR(devdata->dfb->EnumVideoModes(devdata->dfb,
+ EnumModesCallback, &data));
+
+ for (i = 0; i < data.nummodes; ++i) {
+ mode = data.modelist[i];
+
+ mode.format = SDL_PIXELFORMAT_ARGB8888;
+ CheckSetDisplayMode(_this, display, dispdata, &mode);
+ mode.format = SDL_PIXELFORMAT_RGB888;
+ CheckSetDisplayMode(_this, display, dispdata, &mode);
+ mode.format = SDL_PIXELFORMAT_RGB24;
+ CheckSetDisplayMode(_this, display, dispdata, &mode);
+ mode.format = SDL_PIXELFORMAT_RGB565;
+ CheckSetDisplayMode(_this, display, dispdata, &mode);
+ mode.format = SDL_PIXELFORMAT_INDEX8;
+ CheckSetDisplayMode(_this, display, dispdata, &mode);
+ }
+
+ SDL_DFB_FREE(data.modelist);
+error:
+ return;
+}
+
+int
+DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ /*
+ * FIXME: video mode switch is currently broken for 1.2.0
+ *
+ */
+
+ SDL_DFB_DEVICEDATA(_this);
+ DFB_DisplayData *data = (DFB_DisplayData *) display->driverdata;
+ DFBDisplayLayerConfig config, rconfig;
+ DFBDisplayLayerConfigFlags fail = 0;
+
+ SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
+ DLSCL_ADMINISTRATIVE));
+
+ SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config));
+ config.flags = DLCONF_WIDTH | DLCONF_HEIGHT;
+ if (mode->format != SDL_PIXELFORMAT_UNKNOWN) {
+ config.flags |= DLCONF_PIXELFORMAT;
+ config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
+ data->pixelformat = config.pixelformat;
+ }
+ config.width = mode->w;
+ config.height = mode->h;
+
+ if (devdata->use_yuv_underlays) {
+ config.flags |= DLCONF_OPTIONS;
+ config.options = DLOP_ALPHACHANNEL;
+ }
+
+ data->layer->TestConfiguration(data->layer, &config, &fail);
+
+ if (fail &
+ (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
+ DLCONF_OPTIONS)) {
+ SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
+ mode->format);
+ return -1;
+ }
+
+ config.flags &= ~fail;
+ SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ /* Need to call this twice ! */
+ SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
+#endif
+
+ /* Double check */
+ SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig));
+ SDL_DFB_CHECKERR(data->
+ layer->SetCooperativeLevel(data->layer, DLSCL_SHARED));
+
+ if ((config.width != rconfig.width) || (config.height != rconfig.height)
+ || ((mode->format != SDL_PIXELFORMAT_UNKNOWN)
+ && (config.pixelformat != rconfig.pixelformat))) {
+ SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
+ mode->format);
+ return -1;
+ }
+
+ data->pixelformat = rconfig.pixelformat;
+ data->cw = config.width;
+ data->ch = config.height;
+ display->current_mode = *mode;
+
+ return 0;
+ error:
+ return -1;
+}
+
+void
+DirectFB_QuitModes(_THIS)
+{
+ SDL_DisplayMode tmode;
+ int i;
+
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+
+ SDL_GetDesktopDisplayMode(i, &tmode);
+ tmode.format = SDL_PIXELFORMAT_UNKNOWN;
+ DirectFB_SetDisplayMode(_this, display, &tmode);
+
+ SDL_GetDesktopDisplayMode(i, &tmode);
+ DirectFB_SetDisplayMode(_this, display, &tmode);
+
+ if (dispdata->layer) {
+ SDL_DFB_CHECK(dispdata->
+ layer->SetCooperativeLevel(dispdata->layer,
+ DLSCL_ADMINISTRATIVE));
+ SDL_DFB_CHECK(dispdata->
+ layer->SetCursorOpacity(dispdata->layer, 0x00));
+ SDL_DFB_CHECK(dispdata->
+ layer->SetCooperativeLevel(dispdata->layer,
+ DLSCL_SHARED));
+ }
+
+ SDL_DFB_RELEASE(dispdata->layer);
+ SDL_DFB_RELEASE(dispdata->vidlayer);
+
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.h
new file mode 100644
index 0000000..75d8bbf
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_modes.h
@@ -0,0 +1,59 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_directfb_modes_h_
+#define SDL_directfb_modes_h_
+
+#include <directfb.h>
+
+#include "../SDL_sysvideo.h"
+
+#define SDL_DFB_DISPLAYDATA(win) DFB_DisplayData *dispdata = ((win) ? (DFB_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata : NULL)
+
+typedef struct _DFB_DisplayData DFB_DisplayData;
+struct _DFB_DisplayData
+{
+ IDirectFBDisplayLayer *layer;
+ DFBSurfacePixelFormat pixelformat;
+ /* FIXME: support for multiple video layer.
+ * However, I do not know any card supporting
+ * more than one
+ */
+ DFBDisplayLayerID vidID;
+ IDirectFBDisplayLayer *vidlayer;
+
+ int vidIDinuse;
+
+ int cw;
+ int ch;
+};
+
+
+extern void DirectFB_InitModes(_THIS);
+extern void DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void DirectFB_QuitModes(_THIS);
+
+extern void DirectFB_SetContext(_THIS, SDL_Window *window);
+
+#endif /* SDL_directfb_modes_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.c
new file mode 100644
index 0000000..a2b3e41
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.c
@@ -0,0 +1,389 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_assert.h"
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_mouse.h"
+#include "SDL_DirectFB_modes.h"
+#include "SDL_DirectFB_window.h"
+
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_mouse_c.h"
+
+static SDL_Cursor *DirectFB_CreateDefaultCursor(void);
+static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface,
+ int hot_x, int hot_y);
+static int DirectFB_ShowCursor(SDL_Cursor * cursor);
+static void DirectFB_FreeCursor(SDL_Cursor * cursor);
+static void DirectFB_WarpMouse(SDL_Window * window, int x, int y);
+
+static const char *arrow[] = {
+ /* pixels */
+ "X ",
+ "XX ",
+ "X.X ",
+ "X..X ",
+ "X...X ",
+ "X....X ",
+ "X.....X ",
+ "X......X ",
+ "X.......X ",
+ "X........X ",
+ "X.....XXXXX ",
+ "X..X..X ",
+ "X.X X..X ",
+ "XX X..X ",
+ "X X..X ",
+ " X..X ",
+ " X..X ",
+ " X..X ",
+ " XX ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+};
+
+static SDL_Cursor *
+DirectFB_CreateDefaultCursor(void)
+{
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+
+ SDL_DFB_DEVICEDATA(dev);
+ DFB_CursorData *curdata;
+ DFBSurfaceDescription dsc;
+ SDL_Cursor *cursor;
+ Uint32 *dest;
+ int pitch, i, j;
+
+ SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
+ SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
+
+ dsc.flags =
+ DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
+ dsc.caps = DSCAPS_VIDEOONLY;
+ dsc.width = 32;
+ dsc.height = 32;
+ dsc.pixelformat = DSPF_ARGB;
+
+ SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
+ &curdata->surf));
+ curdata->hotx = 0;
+ curdata->hoty = 0;
+ cursor->driverdata = curdata;
+
+ SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
+ (void *) &dest, &pitch));
+
+ /* Relies on the fact that this is only called with ARGB surface. */
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 32; j++)
+ {
+ switch (arrow[i][j])
+ {
+ case ' ': dest[j] = 0x00000000; break;
+ case '.': dest[j] = 0xffffffff; break;
+ case 'X': dest[j] = 0xff000000; break;
+ }
+ }
+ dest += (pitch >> 2);
+ }
+
+ curdata->surf->Unlock(curdata->surf);
+ return cursor;
+ error:
+ return NULL;
+}
+
+/* Create a cursor from a surface */
+static SDL_Cursor *
+DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+
+ SDL_DFB_DEVICEDATA(dev);
+ DFB_CursorData *curdata;
+ DFBSurfaceDescription dsc;
+ SDL_Cursor *cursor;
+ Uint32 *dest;
+ Uint32 *p;
+ int pitch, i;
+
+ SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
+ SDL_assert(surface->pitch == surface->w * 4);
+
+ SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
+ SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
+
+ dsc.flags =
+ DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
+ dsc.caps = DSCAPS_VIDEOONLY;
+ dsc.width = surface->w;
+ dsc.height = surface->h;
+ dsc.pixelformat = DSPF_ARGB;
+
+ SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
+ &curdata->surf));
+ curdata->hotx = hot_x;
+ curdata->hoty = hot_y;
+ cursor->driverdata = curdata;
+
+ SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
+ (void *) &dest, &pitch));
+
+ p = surface->pixels;
+ for (i = 0; i < surface->h; i++)
+ memcpy((char *) dest + i * pitch,
+ (char *) p + i * surface->pitch, 4 * surface->w);
+
+ curdata->surf->Unlock(curdata->surf);
+ return cursor;
+ error:
+ return NULL;
+}
+
+/* Show the specified cursor, or hide if cursor is NULL */
+static int
+DirectFB_ShowCursor(SDL_Cursor * cursor)
+{
+ SDL_DFB_CURSORDATA(cursor);
+ SDL_Window *window;
+
+ window = SDL_GetFocusWindow();
+ if (!window)
+ return -1;
+ else {
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+
+ if (display) {
+ DFB_DisplayData *dispdata =
+ (DFB_DisplayData *) display->driverdata;
+ DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
+
+ if (cursor)
+ SDL_DFB_CHECKERR(windata->dfbwin->
+ SetCursorShape(windata->dfbwin,
+ curdata->surf, curdata->hotx,
+ curdata->hoty));
+
+ SDL_DFB_CHECKERR(dispdata->layer->
+ SetCooperativeLevel(dispdata->layer,
+ DLSCL_ADMINISTRATIVE));
+ SDL_DFB_CHECKERR(dispdata->layer->
+ SetCursorOpacity(dispdata->layer,
+ cursor ? 0xC0 : 0x00));
+ SDL_DFB_CHECKERR(dispdata->layer->
+ SetCooperativeLevel(dispdata->layer,
+ DLSCL_SHARED));
+ }
+ }
+
+ return 0;
+ error:
+ return -1;
+}
+
+/* Free a window manager cursor */
+static void
+DirectFB_FreeCursor(SDL_Cursor * cursor)
+{
+ SDL_DFB_CURSORDATA(cursor);
+
+ SDL_DFB_RELEASE(curdata->surf);
+ SDL_DFB_FREE(cursor->driverdata);
+ SDL_DFB_FREE(cursor);
+}
+
+/* Warp the mouse to (x,y) */
+static void
+DirectFB_WarpMouse(SDL_Window * window, int x, int y)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+ DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
+ int cx, cy;
+
+ SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
+ SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
+ cx + x + windata->client.x,
+ cy + y + windata->client.y));
+
+ error:
+ return;
+}
+
+#if USE_MULTI_API
+
+static void DirectFB_MoveCursor(SDL_Cursor * cursor);
+static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window,
+ int x, int y);
+static void DirectFB_FreeMouse(SDL_Mouse * mouse);
+
+static int id_mask;
+
+static DFBEnumerationResult
+EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
+ void *callbackdata)
+{
+ DFB_DeviceData *devdata = callbackdata;
+
+ if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
+ SDL_Mouse mouse;
+
+ SDL_zero(mouse);
+ mouse.id = device_id;
+ mouse.CreateCursor = DirectFB_CreateCursor;
+ mouse.ShowCursor = DirectFB_ShowCursor;
+ mouse.MoveCursor = DirectFB_MoveCursor;
+ mouse.FreeCursor = DirectFB_FreeCursor;
+ mouse.WarpMouse = DirectFB_WarpMouse;
+ mouse.FreeMouse = DirectFB_FreeMouse;
+ mouse.cursor_shown = 1;
+
+ SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
+ devdata->mouse_id[devdata->num_mice++] = device_id;
+ }
+ return DFENUM_OK;
+}
+
+void
+DirectFB_InitMouse(_THIS)
+{
+ SDL_DFB_DEVICEDATA(_this);
+
+ devdata->num_mice = 0;
+ if (devdata->use_linux_input) {
+ /* try non-core devices first */
+ id_mask = 0xF0;
+ devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
+ if (devdata->num_mice == 0) {
+ /* try core devices */
+ id_mask = 0x0F;
+ devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
+ }
+ }
+ if (devdata->num_mice == 0) {
+ SDL_Mouse mouse;
+
+ SDL_zero(mouse);
+ mouse.CreateCursor = DirectFB_CreateCursor;
+ mouse.ShowCursor = DirectFB_ShowCursor;
+ mouse.MoveCursor = DirectFB_MoveCursor;
+ mouse.FreeCursor = DirectFB_FreeCursor;
+ mouse.WarpMouse = DirectFB_WarpMouse;
+ mouse.FreeMouse = DirectFB_FreeMouse;
+ mouse.cursor_shown = 1;
+
+ SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
+ devdata->num_mice = 1;
+ }
+}
+
+void
+DirectFB_QuitMouse(_THIS)
+{
+ SDL_DFB_DEVICEDATA(_this);
+
+ if (devdata->use_linux_input) {
+ SDL_MouseQuit();
+ } else {
+ SDL_DelMouse(0);
+ }
+}
+
+
+/* This is called when a mouse motion event occurs */
+static void
+DirectFB_MoveCursor(SDL_Cursor * cursor)
+{
+
+}
+
+/* Warp the mouse to (x,y) */
+static void
+DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+ DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
+ DFBResult ret;
+ int cx, cy;
+
+ SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
+ SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
+ cx + x + windata->client.x,
+ cy + y + windata->client.y));
+
+ error:
+ return;
+}
+
+/* Free the mouse when it's time */
+static void
+DirectFB_FreeMouse(SDL_Mouse * mouse)
+{
+ /* nothing yet */
+}
+
+#else /* USE_MULTI_API */
+
+void
+DirectFB_InitMouse(_THIS)
+{
+ SDL_DFB_DEVICEDATA(_this);
+
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = DirectFB_CreateCursor;
+ mouse->ShowCursor = DirectFB_ShowCursor;
+ mouse->WarpMouse = DirectFB_WarpMouse;
+ mouse->FreeCursor = DirectFB_FreeCursor;
+
+ SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor());
+
+ devdata->num_mice = 1;
+}
+
+void
+DirectFB_QuitMouse(_THIS)
+{
+}
+
+
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.h
new file mode 100644
index 0000000..e1236a0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_mouse.h
@@ -0,0 +1,44 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_DirectFB_mouse_h_
+#define SDL_DirectFB_mouse_h_
+
+#include <directfb.h>
+
+#include "../SDL_sysvideo.h"
+
+typedef struct _DFB_CursorData DFB_CursorData;
+struct _DFB_CursorData
+{
+ IDirectFBSurface *surf;
+ int hotx;
+ int hoty;
+};
+
+#define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs) ? (curs)->driverdata : NULL)
+
+extern void DirectFB_InitMouse(_THIS);
+extern void DirectFB_QuitMouse(_THIS);
+
+#endif /* SDL_DirectFB_mouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.c
new file mode 100644
index 0000000..93d2fde
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.c
@@ -0,0 +1,332 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_DirectFB_video.h"
+
+#if SDL_DIRECTFB_OPENGL
+
+#include "SDL_DirectFB_opengl.h"
+#include "SDL_DirectFB_window.h"
+
+#include <directfbgl.h>
+#include "SDL_loadso.h"
+#endif
+
+#if SDL_DIRECTFB_OPENGL
+
+struct SDL_GLDriverData
+{
+ int gl_active; /* to stop switching drivers while we have a valid context */
+ int initialized;
+ DirectFB_GLContext *firstgl; /* linked list */
+
+ /* OpenGL */
+ void (*glFinish) (void);
+ void (*glFlush) (void);
+};
+
+#define OPENGL_REQUIRS_DLOPEN
+#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
+#include <dlfcn.h>
+#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
+#define GL_LoadFunction dlsym
+#define GL_UnloadObject dlclose
+#else
+#define GL_LoadObject SDL_LoadObject
+#define GL_LoadFunction SDL_LoadFunction
+#define GL_UnloadObject SDL_UnloadObject
+#endif
+
+static void DirectFB_GL_UnloadLibrary(_THIS);
+
+int
+DirectFB_GL_Initialize(_THIS)
+{
+ if (_this->gl_data) {
+ return 0;
+ }
+
+ _this->gl_data =
+ (struct SDL_GLDriverData *) SDL_calloc(1,
+ sizeof(struct
+ SDL_GLDriverData));
+ if (!_this->gl_data) {
+ return SDL_OutOfMemory();
+ }
+ _this->gl_data->initialized = 0;
+
+ ++_this->gl_data->initialized;
+ _this->gl_data->firstgl = NULL;
+
+ if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
+ return -1;
+ }
+
+ /* Initialize extensions */
+ /* FIXME needed?
+ * X11_GL_InitExtensions(_this);
+ */
+
+ return 0;
+}
+
+void
+DirectFB_GL_Shutdown(_THIS)
+{
+ if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
+ return;
+ }
+
+ DirectFB_GL_UnloadLibrary(_this);
+
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
+}
+
+int
+DirectFB_GL_LoadLibrary(_THIS, const char *path)
+{
+ void *handle = NULL;
+
+ SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
+
+ if (_this->gl_data->gl_active) {
+ return SDL_SetError("OpenGL context already created");
+ }
+
+
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ if (path == NULL) {
+ path = "libGL.so.1";
+ }
+ }
+
+ handle = GL_LoadObject(path);
+ if (handle == NULL) {
+ SDL_DFB_ERR("Library not found: %s\n", path);
+ /* SDL_LoadObject() will call SDL_SetError() for us. */
+ return -1;
+ }
+
+ SDL_DFB_DEBUG("Loaded library: %s\n", path);
+
+ _this->gl_config.dll_handle = handle;
+ if (path) {
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+ } else {
+ *_this->gl_config.driver_path = '\0';
+ }
+
+ _this->gl_data->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
+ _this->gl_data->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
+
+ return 0;
+}
+
+static void
+DirectFB_GL_UnloadLibrary(_THIS)
+{
+ #if 0
+ int ret = GL_UnloadObject(_this->gl_config.dll_handle);
+ if (ret)
+ SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
+ _this->gl_config.dll_handle = NULL;
+#endif
+ /* Free OpenGL memory */
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
+}
+
+void *
+DirectFB_GL_GetProcAddress(_THIS, const char *proc)
+{
+ void *handle;
+
+ handle = _this->gl_config.dll_handle;
+ return GL_LoadFunction(handle, proc);
+}
+
+SDL_GLContext
+DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ DirectFB_GLContext *context;
+
+ SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext));
+
+ SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
+ &context->context));
+
+ if (!context->context)
+ return NULL;
+
+ context->is_locked = 0;
+ context->sdl_window = window;
+
+ context->next = _this->gl_data->firstgl;
+ _this->gl_data->firstgl = context;
+
+ SDL_DFB_CHECK(context->context->Unlock(context->context));
+
+ if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
+ DirectFB_GL_DeleteContext(_this, context);
+ return NULL;
+ }
+
+ return context;
+
+ error:
+ return NULL;
+}
+
+int
+DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
+ DirectFB_GLContext *p;
+
+ for (p = _this->gl_data->firstgl; p; p = p->next)
+ {
+ if (p->is_locked) {
+ SDL_DFB_CHECKERR(p->context->Unlock(p->context));
+ p->is_locked = 0;
+ }
+
+ }
+
+ if (ctx != NULL) {
+ SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
+ ctx->is_locked = 1;
+ }
+
+ return 0;
+ error:
+ return -1;
+}
+
+int
+DirectFB_GL_SetSwapInterval(_THIS, int interval)
+{
+ return SDL_Unsupported();
+}
+
+int
+DirectFB_GL_GetSwapInterval(_THIS)
+{
+ return 0;
+}
+
+int
+DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ DirectFB_GLContext *p;
+
+#if 0
+ if (devdata->glFinish)
+ devdata->glFinish();
+ else if (devdata->glFlush)
+ devdata->glFlush();
+#endif
+
+ for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
+ if (p->sdl_window == window && p->is_locked)
+ {
+ SDL_DFB_CHECKERR(p->context->Unlock(p->context));
+ p->is_locked = 0;
+ }
+
+ SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL, DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
+ return 0;
+ error:
+ return -1;
+}
+
+void
+DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
+ DirectFB_GLContext *p;
+
+ if (ctx->is_locked)
+ SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
+ SDL_DFB_RELEASE(ctx->context);
+
+ for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
+ ;
+ if (p)
+ p->next = ctx->next;
+ else
+ _this->gl_data->firstgl = ctx->next;
+
+ SDL_DFB_FREE(ctx);
+}
+
+void
+DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
+{
+ DirectFB_GLContext *p;
+
+ for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
+ if (p->sdl_window == window)
+ {
+ if (p->is_locked)
+ SDL_DFB_CHECK(p->context->Unlock(p->context));
+ SDL_DFB_RELEASE(p->context);
+ }
+}
+
+void
+DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
+{
+ DirectFB_GLContext *p;
+
+ for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
+ if (p->sdl_window == window)
+ {
+ SDL_DFB_WINDOWDATA(window);
+ SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
+ &p->context));
+ if (p->is_locked)
+ SDL_DFB_CHECK(p->context->Lock(p->context));
+ }
+}
+
+void
+DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
+{
+ DirectFB_GLContext *p;
+
+ for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
+ if (p->sdl_window == window)
+ DirectFB_GL_DeleteContext(_this, p);
+}
+
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.h
new file mode 100644
index 0000000..9463e1b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_opengl.h
@@ -0,0 +1,64 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef SDL_directfb_opengl_h_
+#define SDL_directfb_opengl_h_
+
+#include "SDL_DirectFB_video.h"
+
+#if SDL_DIRECTFB_OPENGL
+
+#include "SDL_opengl.h"
+
+typedef struct _DirectFB_GLContext DirectFB_GLContext;
+struct _DirectFB_GLContext
+{
+ IDirectFBGL *context;
+ DirectFB_GLContext *next;
+
+ SDL_Window *sdl_window;
+ int is_locked;
+};
+
+/* OpenGL functions */
+extern int DirectFB_GL_Initialize(_THIS);
+extern void DirectFB_GL_Shutdown(_THIS);
+
+extern int DirectFB_GL_LoadLibrary(_THIS, const char *path);
+extern void *DirectFB_GL_GetProcAddress(_THIS, const char *proc);
+extern SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window);
+extern int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern int DirectFB_GL_SetSwapInterval(_THIS, int interval);
+extern int DirectFB_GL_GetSwapInterval(_THIS);
+extern int DirectFB_GL_SwapWindow(_THIS, SDL_Window * window);
+extern void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context);
+
+extern void DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window);
+extern void DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window);
+extern void DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window);
+
+#endif /* SDL_DIRECTFB_OPENGL */
+
+#endif /* SDL_directfb_opengl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.c
new file mode 100644
index 0000000..4054f73
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.c
@@ -0,0 +1,1335 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+#include "SDL_DirectFB_window.h"
+#include "SDL_DirectFB_modes.h"
+
+#include "SDL_syswm.h"
+#include "SDL_DirectFB_shape.h"
+
+#include "../SDL_sysvideo.h"
+#include "../../render/SDL_sysrender.h"
+
+#ifndef DFB_VERSION_ATLEAST
+
+#define DFB_VERSIONNUM(X, Y, Z) \
+ ((X)*1000 + (Y)*100 + (Z))
+
+#define DFB_COMPILEDVERSION \
+ DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
+
+#define DFB_VERSION_ATLEAST(X, Y, Z) \
+ (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
+
+#define SDL_DFB_CHECK(x) x
+
+#endif
+
+/* the following is not yet tested ... */
+#define USE_DISPLAY_PALETTE (0)
+
+
+#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
+
+
+/* DirectFB renderer implementation */
+
+static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
+ Uint32 flags);
+static void DirectFB_ActivateRenderer(SDL_Renderer * renderer);
+static int DirectFB_CreateTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ void **pixels, int *pitch);
+static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Color * colors,
+ int firstcolor, int ncolors);
+static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ SDL_Color * colors,
+ int firstcolor, int ncolors);
+static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * rect,
+ const void *pixels, int pitch);
+static int DirectFB_LockTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * rect,
+ void **pixels, int *pitch);
+static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture, int numrects,
+ const SDL_Rect * rects);
+static int DirectFB_SetDrawBlendMode(SDL_Renderer * renderer);
+static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count);
+static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count);
+static int DirectFB_RenderDrawRects(SDL_Renderer * renderer,
+ const SDL_Rect ** rects, int count);
+static int DirectFB_RenderFillRects(SDL_Renderer * renderer,
+ const SDL_FRect * rects, int count);
+static int DirectFB_RenderCopy(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * srcrect,
+ const SDL_FRect * dstrect);
+static void DirectFB_RenderPresent(SDL_Renderer * renderer);
+static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture);
+static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
+static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 format, void * pixels, int pitch);
+static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 format, const void * pixels, int pitch);
+static int DirectFB_UpdateViewport(SDL_Renderer * renderer);
+static int DirectFB_UpdateClipRect(SDL_Renderer * renderer);
+static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
+
+static int PrepareDraw(SDL_Renderer * renderer);
+
+
+#define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
+
+SDL_RenderDriver DirectFB_RenderDriver = {
+ DirectFB_CreateRenderer,
+ {
+ "directfb",
+ (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
+ /* (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
+ SDL_TEXTUREMODULATE_ALPHA),
+ (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND |
+ SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
+ (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST |
+ SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST), */
+ 0,
+ {
+ /* formats filled in later */
+ },
+ 0,
+ 0}
+};
+
+typedef struct
+{
+ SDL_Window *window;
+ DFBSurfaceFlipFlags flipflags;
+ int size_changed;
+ int lastBlendMode;
+ DFBSurfaceBlittingFlags blitFlags;
+ DFBSurfaceDrawingFlags drawFlags;
+ IDirectFBSurface* target;
+} DirectFB_RenderData;
+
+typedef struct
+{
+ IDirectFBSurface *surface;
+ Uint32 format;
+ void *pixels;
+ int pitch;
+ IDirectFBPalette *palette;
+ int isDirty;
+
+ SDL_VideoDisplay *display; /* only for yuv textures */
+
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ DFBSurfaceRenderOptions render_options;
+#endif
+} DirectFB_TextureData;
+
+static SDL_INLINE void
+SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr)
+{
+ dr->x = sr->x;
+ dr->y = sr->y;
+ dr->h = sr->h;
+ dr->w = sr->w;
+}
+static SDL_INLINE void
+SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr)
+{
+ dr->x = sr->x;
+ dr->y = sr->y;
+ dr->h = sr->h;
+ dr->w = sr->w;
+}
+
+
+static int
+TextureHasAlpha(DirectFB_TextureData * data)
+{
+ /* Drawing primitive ? */
+ if (!data)
+ return 0;
+
+ return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0);
+#if 0
+ switch (data->format) {
+ case SDL_PIXELFORMAT_INDEX4LSB:
+ case SDL_PIXELFORMAT_INDEX4MSB:
+ case SDL_PIXELFORMAT_ARGB4444:
+ case SDL_PIXELFORMAT_ARGB1555:
+ case SDL_PIXELFORMAT_ARGB8888:
+ case SDL_PIXELFORMAT_RGBA8888:
+ case SDL_PIXELFORMAT_ABGR8888:
+ case SDL_PIXELFORMAT_BGRA8888:
+ case SDL_PIXELFORMAT_ARGB2101010:
+ return 1;
+ default:
+ return 0;
+ }
+#endif
+}
+
+static SDL_INLINE IDirectFBSurface *get_dfb_surface(SDL_Window *window)
+{
+ SDL_SysWMinfo wm_info;
+ SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
+
+ SDL_VERSION(&wm_info.version);
+ if (!SDL_GetWindowWMInfo(window, &wm_info)) {
+ return NULL;
+ }
+
+ return wm_info.info.dfb.surface;
+}
+
+static SDL_INLINE IDirectFBWindow *get_dfb_window(SDL_Window *window)
+{
+ SDL_SysWMinfo wm_info;
+ SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
+
+ SDL_VERSION(&wm_info.version);
+ if (!SDL_GetWindowWMInfo(window, &wm_info)) {
+ return NULL;
+ }
+
+ return wm_info.info.dfb.window;
+}
+
+static void
+SetBlendMode(DirectFB_RenderData * data, int blendMode,
+ DirectFB_TextureData * source)
+{
+ IDirectFBSurface *destsurf = data->target;
+
+ /* FIXME: check for format change */
+ if (1 || data->lastBlendMode != blendMode) {
+ switch (blendMode) {
+ case SDL_BLENDMODE_NONE:
+ /**< No blending */
+ data->blitFlags = DSBLIT_NOFX;
+ data->drawFlags = DSDRAW_NOFX;
+ SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
+ SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
+ break;
+#if 0
+ case SDL_BLENDMODE_MASK:
+ data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
+ data->drawFlags = DSDRAW_BLEND;
+ SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
+ SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
+ break;
+#endif
+ case SDL_BLENDMODE_BLEND:
+ data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
+ data->drawFlags = DSDRAW_BLEND;
+ SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
+ SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
+ break;
+ case SDL_BLENDMODE_ADD:
+ data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
+ data->drawFlags = DSDRAW_BLEND;
+ /* FIXME: SRCALPHA kills performance on radeon ...
+ * It will be cheaper to copy the surface to a temporary surface and premultiply
+ */
+ if (source && TextureHasAlpha(source))
+ SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
+ else
+ SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
+ SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
+ break;
+ case SDL_BLENDMODE_MOD:
+ data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
+ data->drawFlags = DSDRAW_BLEND;
+ SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO));
+ SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR));
+
+ break;
+ }
+ data->lastBlendMode = blendMode;
+ }
+}
+
+static int
+DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
+{
+#if USE_DISPLAY_PALETTE
+ DirectFB_RenderData *data = (DirectFB_RenderData *) userdata;
+ SDL_DFB_WINDOWSURFACE(data->window);
+ IDirectFBPalette *surfpal;
+
+ int i;
+ int ncolors;
+ DFBColor entries[256];
+
+ SDL_DFB_CHECKERR(destsurf->GetPalette(destsurf, &surfpal));
+
+ /* FIXME: number of colors */
+ ncolors = (palette->ncolors < 256 ? palette->ncolors : 256);
+
+ for (i = 0; i < ncolors; ++i) {
+ entries[i].r = palette->colors[i].r;
+ entries[i].g = palette->colors[i].g;
+ entries[i].b = palette->colors[i].b;
+ entries[i].a = palette->colors[i].a;
+ }
+ SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0));
+ return 0;
+ error:
+#else
+ SDL_Unsupported();
+#endif
+ return -1;
+}
+
+static void
+DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+ SDL_DFB_RENDERERDATA(renderer);
+
+ if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+ /* Rebind the context to the window area and update matrices */
+ /* SDL_CurrentContext = NULL; */
+ /* data->updateSize = SDL_TRUE; */
+ renddata->size_changed = SDL_TRUE;
+ }
+}
+
+static int
+DirectFB_RenderClear(SDL_Renderer * renderer)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ PrepareDraw(renderer);
+
+ destsurf->Clear(destsurf, renderer->r, renderer->g, renderer->b, renderer->a);
+
+ return 0;
+}
+
+SDL_Renderer *
+DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+ IDirectFBSurface *winsurf = get_dfb_surface(window);
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_Renderer *renderer = NULL;
+ DirectFB_RenderData *data = NULL;
+ DFBSurfaceCapabilities scaps;
+
+ if (!winsurf) {
+ return NULL;
+ }
+
+ SDL_DFB_ALLOC_CLEAR(renderer, sizeof(*renderer));
+ SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
+
+ renderer->WindowEvent = DirectFB_WindowEvent;
+ renderer->CreateTexture = DirectFB_CreateTexture;
+ renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
+ renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
+ renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
+ renderer->UpdateTexture = DirectFB_UpdateTexture;
+ renderer->LockTexture = DirectFB_LockTexture;
+ renderer->RenderClear = DirectFB_RenderClear;
+ renderer->UnlockTexture = DirectFB_UnlockTexture;
+ renderer->RenderDrawPoints = DirectFB_RenderDrawPoints;
+ renderer->RenderDrawLines = DirectFB_RenderDrawLines;
+ /* SetDrawColor - no needed */
+ renderer->RenderFillRects = DirectFB_RenderFillRects;
+
+ renderer->RenderCopy = DirectFB_RenderCopy;
+ renderer->RenderPresent = DirectFB_RenderPresent;
+
+ /* FIXME: Yet to be tested */
+ renderer->RenderReadPixels = DirectFB_RenderReadPixels;
+ /* renderer->RenderWritePixels = DirectFB_RenderWritePixels; */
+
+ renderer->DestroyTexture = DirectFB_DestroyTexture;
+ renderer->DestroyRenderer = DirectFB_DestroyRenderer;
+ renderer->UpdateViewport = DirectFB_UpdateViewport;
+ renderer->UpdateClipRect = DirectFB_UpdateClipRect;
+ renderer->SetRenderTarget = DirectFB_SetRenderTarget;
+
+#if 0
+ renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
+ renderer->SetTexturePalette = DirectFB_SetTexturePalette;
+ renderer->GetTexturePalette = DirectFB_GetTexturePalette;
+ renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
+ renderer->DirtyTexture = DirectFB_DirtyTexture;
+ renderer->SetDrawBlendMode = DirectFB_SetDrawBlendMode;
+ renderer->RenderDrawRects = DirectFB_RenderDrawRects;
+#endif
+
+ renderer->info = DirectFB_RenderDriver.info;
+ renderer->window = window; /* SDL window */
+ renderer->driverdata = data;
+
+ renderer->info.flags =
+ SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
+
+ data->window = window;
+ data->target = winsurf;
+
+ data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
+
+ if (flags & SDL_RENDERER_PRESENTVSYNC) {
+ data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
+ renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+ } else
+ data->flipflags |= DSFLIP_ONSYNC;
+
+ SDL_DFB_CHECKERR(winsurf->GetCapabilities(winsurf, &scaps));
+
+#if 0
+ if (scaps & DSCAPS_DOUBLE)
+ renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
+ else if (scaps & DSCAPS_TRIPLE)
+ renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
+ else
+ renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
+#endif
+
+ DirectFB_SetSupportedPixelFormats(&renderer->info);
+
+#if 0
+ /* Set up a palette watch on the display palette */
+ if (display-> palette) {
+ SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
+ }
+#endif
+
+ return renderer;
+
+ error:
+ SDL_DFB_FREE(renderer);
+ SDL_DFB_FREE(data);
+ return NULL;
+}
+
+static void
+DirectFB_ActivateRenderer(SDL_Renderer * renderer)
+{
+ SDL_DFB_RENDERERDATA(renderer);
+ SDL_Window *window = renderer->window;
+ SDL_DFB_WINDOWDATA(window);
+
+ if (renddata->size_changed /* || windata->wm_needs_redraw */) {
+ renddata->size_changed = SDL_FALSE;
+ }
+}
+
+
+static int
+DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ SDL_Window *window = renderer->window;
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DFB_DEVICEDATA(display->device);
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+ DirectFB_TextureData *data = texture->driverdata;
+ DFBDisplayLayerConfig layconf;
+ DFBResult ret;
+
+ if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
+ && (!dispdata->vidIDinuse)
+ && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+ layconf.flags =
+ DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
+ DLCONF_SURFACE_CAPS;
+ layconf.width = texture->w;
+ layconf.height = texture->h;
+ layconf.pixelformat = DirectFB_SDLToDFBPixelFormat(data->format);
+ layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
+
+ SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
+ dispdata->vidID,
+ &dispdata->vidlayer));
+ SDL_DFB_CHECKERR(dispdata->
+ vidlayer->SetCooperativeLevel(dispdata->vidlayer,
+ DLSCL_EXCLUSIVE));
+
+ if (devdata->use_yuv_underlays) {
+ ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
+ if (ret != DFB_OK)
+ SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
+ }
+ SDL_DFB_CHECKERR(dispdata->
+ vidlayer->SetConfiguration(dispdata->vidlayer,
+ &layconf));
+ SDL_DFB_CHECKERR(dispdata->
+ vidlayer->GetSurface(dispdata->vidlayer,
+ &data->surface));
+ dispdata->vidIDinuse = 1;
+ data->display = display;
+ return 0;
+ }
+ return 1;
+ error:
+ if (dispdata->vidlayer) {
+ SDL_DFB_RELEASE(data->surface);
+ SDL_DFB_CHECKERR(dispdata->
+ vidlayer->SetCooperativeLevel(dispdata->vidlayer,
+ DLSCL_ADMINISTRATIVE));
+ SDL_DFB_RELEASE(dispdata->vidlayer);
+ }
+ return 1;
+}
+
+static int
+DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ SDL_Window *window = renderer->window;
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DFB_DEVICEDATA(display->device);
+ DirectFB_TextureData *data;
+ DFBSurfaceDescription dsc;
+ DFBSurfacePixelFormat pixelformat;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
+ texture->driverdata = data;
+
+ /* find the right pixelformat */
+ pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format);
+ if (pixelformat == DSPF_UNKNOWN) {
+ SDL_SetError("Unknown pixel format %d", data->format);
+ goto error;
+ }
+
+ data->format = texture->format;
+ data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
+
+ if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
+ /* fill surface description */
+ dsc.flags =
+ DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
+ dsc.width = texture->w;
+ dsc.height = texture->h;
+ if(texture->format == SDL_PIXELFORMAT_YV12 ||
+ texture->format == SDL_PIXELFORMAT_IYUV) {
+ /* dfb has problems with odd sizes -make them even internally */
+ dsc.width += (dsc.width % 2);
+ dsc.height += (dsc.height % 2);
+ }
+ /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
+ * No DSCAPS_SYSTEMONLY either - let dfb decide
+ * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
+ * Depends on other settings as well. Let dfb decide.
+ */
+ dsc.caps = DSCAPS_PREMULTIPLIED;
+#if 0
+ if (texture->access == SDL_TEXTUREACCESS_STREAMING)
+ dsc.caps |= DSCAPS_SYSTEMONLY;
+ else
+ dsc.caps |= DSCAPS_VIDEOONLY;
+#endif
+
+ dsc.pixelformat = pixelformat;
+ data->pixels = NULL;
+
+ /* Create the surface */
+ SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
+ &data->surface));
+ if (SDL_ISPIXELFORMAT_INDEXED(data->format)
+ && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+#if 1
+ SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette));
+#else
+ /* DFB has issues with blitting LUT8 surfaces.
+ * Creating a new palette does not help.
+ */
+ DFBPaletteDescription pal_desc;
+ pal_desc.flags = DPDESC_SIZE; /* | DPDESC_ENTRIES */
+ pal_desc.size = 256;
+ SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette));
+ SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette));
+#endif
+ }
+
+ }
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ data->render_options = DSRO_NONE;
+#endif
+ if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+ /* 3 plane YUVs return 1 bpp, but we need more space for other planes */
+ if(texture->format == SDL_PIXELFORMAT_YV12 ||
+ texture->format == SDL_PIXELFORMAT_IYUV) {
+ SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4));
+ } else {
+ SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch);
+ }
+ }
+
+ return 0;
+
+ error:
+ SDL_DFB_RELEASE(data->palette);
+ SDL_DFB_RELEASE(data->surface);
+ SDL_DFB_FREE(texture->driverdata);
+ return -1;
+}
+
+static int
+DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
+ SDL_Texture * texture, void **pixels, int *pitch)
+{
+ DirectFB_TextureData *texturedata =
+ (DirectFB_TextureData *) texture->driverdata;
+
+ if (texturedata->display) {
+ return -1;
+ } else {
+ *pixels = texturedata->pixels;
+ *pitch = texturedata->pitch;
+ }
+ return 0;
+}
+
+static int
+DirectFB_SetTexturePalette(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Color * colors, int firstcolor,
+ int ncolors)
+{
+ DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+ if (SDL_ISPIXELFORMAT_INDEXED(data->format)
+ && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+ DFBColor entries[256];
+ int i;
+
+ if (ncolors > 256)
+ ncolors = 256;
+
+ for (i = 0; i < ncolors; ++i) {
+ entries[i].r = colors[i].r;
+ entries[i].g = colors[i].g;
+ entries[i].b = colors[i].b;
+ entries[i].a = 0xff;
+ }
+ SDL_DFB_CHECKERR(data->
+ palette->SetEntries(data->palette, entries, ncolors, firstcolor));
+ return 0;
+ } else {
+ return SDL_SetError("YUV textures don't have a palette");
+ }
+ error:
+ return -1;
+}
+
+static int
+DirectFB_GetTexturePalette(SDL_Renderer * renderer,
+ SDL_Texture * texture, SDL_Color * colors,
+ int firstcolor, int ncolors)
+{
+ DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+
+ if (SDL_ISPIXELFORMAT_INDEXED(data->format)
+ && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+ DFBColor entries[256];
+ int i;
+
+ SDL_DFB_CHECKERR(data->
+ palette->GetEntries(data->palette, entries, ncolors,
+ firstcolor));
+
+ for (i = 0; i < ncolors; ++i) {
+ colors[i].r = entries[i].r;
+ colors[i].g = entries[i].g;
+ colors[i].b = entries[i].b;
+ colors[i].a = SDL_ALPHA_OPAQUE;
+ }
+ return 0;
+ } else {
+ return SDL_SetError("YUV textures don't have a palette");
+ }
+ error:
+ return -1;
+}
+
+static int
+DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ return 0;
+}
+
+static int
+DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ return 0;
+}
+
+static int
+DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ switch (texture->blendMode) {
+ case SDL_BLENDMODE_NONE:
+ /* case SDL_BLENDMODE_MASK: */
+ case SDL_BLENDMODE_BLEND:
+ case SDL_BLENDMODE_ADD:
+ case SDL_BLENDMODE_MOD:
+ return 0;
+ default:
+ texture->blendMode = SDL_BLENDMODE_NONE;
+ return SDL_Unsupported();
+ }
+}
+
+static int
+DirectFB_SetDrawBlendMode(SDL_Renderer * renderer)
+{
+ switch (renderer->blendMode) {
+ case SDL_BLENDMODE_NONE:
+ /* case SDL_BLENDMODE_MASK: */
+ case SDL_BLENDMODE_BLEND:
+ case SDL_BLENDMODE_ADD:
+ case SDL_BLENDMODE_MOD:
+ return 0;
+ default:
+ renderer->blendMode = SDL_BLENDMODE_NONE;
+ return SDL_Unsupported();
+ }
+}
+
+#if 0
+static int
+DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+#if (DFB_VERSION_ATLEAST(1,2,0))
+
+ DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+
+ switch (texture->scaleMode) {
+ case SDL_SCALEMODE_NONE:
+ case SDL_SCALEMODE_FAST:
+ data->render_options = DSRO_NONE;
+ break;
+ case SDL_SCALEMODE_SLOW:
+ data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
+ break;
+ case SDL_SCALEMODE_BEST:
+ data->render_options =
+ DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
+ break;
+ default:
+ data->render_options = DSRO_NONE;
+ texture->scaleMode = SDL_SCALEMODE_NONE;
+ return SDL_Unsupported();
+ }
+#endif
+ return 0;
+}
+#endif
+
+static int
+DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect, const void *pixels, int pitch)
+{
+ DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+ Uint8 *dpixels;
+ int dpitch;
+ Uint8 *src, *dst;
+ int row;
+ size_t length;
+ int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
+ /* FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes */
+
+ DirectFB_ActivateRenderer(renderer);
+
+ if ((texture->format == SDL_PIXELFORMAT_YV12) ||
+ (texture->format == SDL_PIXELFORMAT_IYUV)) {
+ bpp = 1;
+ }
+
+ SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
+ DSLF_WRITE | DSLF_READ,
+ ((void **) &dpixels), &dpitch));
+ src = (Uint8 *) pixels;
+ dst = (Uint8 *) dpixels + rect->y * dpitch + rect->x * bpp;
+ length = rect->w * bpp;
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += dpitch;
+ }
+ /* copy other planes for 3 plane formats */
+ if ((texture->format == SDL_PIXELFORMAT_YV12) ||
+ (texture->format == SDL_PIXELFORMAT_IYUV)) {
+ src = (Uint8 *) pixels + texture->h * pitch;
+ dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
+ for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
+ SDL_memcpy(dst, src, length / 2);
+ src += pitch / 2;
+ dst += dpitch / 2;
+ }
+ src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
+ dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
+ for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
+ SDL_memcpy(dst, src, length / 2);
+ src += pitch / 2;
+ dst += dpitch / 2;
+ }
+ }
+ SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
+ data->isDirty = 0;
+ return 0;
+ error:
+ return 1;
+
+}
+
+static int
+DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect, void **pixels, int *pitch)
+{
+ DirectFB_TextureData *texturedata =
+ (DirectFB_TextureData *) texture->driverdata;
+
+ DirectFB_ActivateRenderer(renderer);
+
+#if 0
+ if (markDirty) {
+ SDL_AddDirtyRect(&texturedata->dirty, rect);
+ }
+#endif
+
+ if (texturedata->display) {
+ void *fdata;
+ int fpitch;
+
+ SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface,
+ DSLF_WRITE | DSLF_READ,
+ &fdata, &fpitch));
+ *pitch = fpitch;
+ *pixels = fdata;
+ } else {
+ *pixels =
+ (void *) ((Uint8 *) texturedata->pixels +
+ rect->y * texturedata->pitch +
+ rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)));
+ *pitch = texturedata->pitch;
+ texturedata->isDirty = 1;
+ }
+ return 0;
+
+ error:
+ return -1;
+}
+
+static void
+DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ DirectFB_TextureData *texturedata =
+ (DirectFB_TextureData *) texture->driverdata;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ if (texturedata->display) {
+ SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
+ texturedata->pixels = NULL;
+ }
+}
+
+#if 0
+static void
+DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ int numrects, const SDL_Rect * rects)
+{
+ DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+ int i;
+
+ for (i = 0; i < numrects; ++i) {
+ SDL_AddDirtyRect(&data->dirty, &rects[i]);
+ }
+}
+#endif
+
+static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ DirectFB_TextureData *tex_data = NULL;
+
+ DirectFB_ActivateRenderer(renderer);
+ if (texture) {
+ tex_data = (DirectFB_TextureData *) texture->driverdata;
+ data->target = tex_data->surface;
+ } else {
+ data->target = get_dfb_surface(data->window);
+ }
+ data->lastBlendMode = 0;
+ return 0;
+}
+
+
+static int
+PrepareDraw(SDL_Renderer * renderer)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+
+ Uint8 r, g, b, a;
+
+ r = renderer->r;
+ g = renderer->g;
+ b = renderer->b;
+ a = renderer->a;
+
+ SetBlendMode(data, renderer->blendMode, NULL);
+ SDL_DFB_CHECKERR(destsurf->SetDrawingFlags(destsurf, data->drawFlags));
+
+ switch (renderer->blendMode) {
+ case SDL_BLENDMODE_NONE:
+ /* case SDL_BLENDMODE_MASK: */
+ case SDL_BLENDMODE_BLEND:
+ break;
+ case SDL_BLENDMODE_ADD:
+ case SDL_BLENDMODE_MOD:
+ r = ((int) r * (int) a) / 255;
+ g = ((int) g * (int) a) / 255;
+ b = ((int) b * (int) a) / 255;
+ a = 255;
+ break;
+ }
+
+ SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, r, g, b, a));
+ return 0;
+ error:
+ return -1;
+}
+
+static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+ DFBRegion clip_region;
+ int i;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ PrepareDraw(renderer);
+ destsurf->GetClip(destsurf, &clip_region);
+ for (i=0; i < count; i++) {
+ int x = points[i].x + clip_region.x1;
+ int y = points[i].y + clip_region.y1;
+ SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x, y, x, y));
+ }
+ return 0;
+ error:
+ return -1;
+}
+
+static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+ DFBRegion clip_region;
+ int i;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ PrepareDraw(renderer);
+ /* Use antialiasing when available */
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS));
+#endif
+
+ destsurf->GetClip(destsurf, &clip_region);
+ for (i=0; i < count - 1; i++) {
+ int x1 = points[i].x + clip_region.x1;
+ int y1 = points[i].y + clip_region.y1;
+ int x2 = points[i + 1].x + clip_region.x1;
+ int y2 = points[i + 1].y + clip_region.y1;
+ SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x1, y1, x2, y2));
+ }
+
+ return 0;
+ error:
+ return -1;
+}
+
+static int
+DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+ DFBRegion clip_region;
+ int i;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ PrepareDraw(renderer);
+
+ destsurf->GetClip(destsurf, &clip_region);
+ for (i=0; i<count; i++) {
+ SDL_Rect dst = {rects[i]->x, rects[i]->y, rects[i]->w, rects[i]->h};
+ dst.x += clip_region.x1;
+ dst.y += clip_region.y1;
+ SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, dst.x, dst.y,
+ dst.w, dst.h));
+ }
+
+ return 0;
+ error:
+ return -1;
+}
+
+static int
+DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+ DFBRegion clip_region;
+ int i;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ PrepareDraw(renderer);
+
+ destsurf->GetClip(destsurf, &clip_region);
+ for (i=0; i<count; i++) {
+ SDL_Rect dst = {rects[i].x, rects[i].y, rects[i].w, rects[i].h};
+ dst.x += clip_region.x1;
+ dst.y += clip_region.y1;
+ SDL_DFB_CHECKERR(destsurf->FillRectangle(destsurf, dst.x, dst.y,
+ dst.w, dst.h));
+ }
+
+ return 0;
+ error:
+ return -1;
+}
+
+static int
+DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = data->target;
+ DirectFB_TextureData *texturedata =
+ (DirectFB_TextureData *) texture->driverdata;
+ Uint8 alpha, r, g, b;
+ DFBRegion clip_region;
+ DFBRectangle sr, dr;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ SDLtoDFBRect(srcrect, &sr);
+ SDLtoDFBRect_Float(dstrect, &dr);
+
+ destsurf->GetClip(destsurf, &clip_region);
+ dr.x += clip_region.x1;
+ dr.y += clip_region.y1;
+
+ if (texturedata->display) {
+ int px, py;
+ SDL_Window *window = renderer->window;
+ IDirectFBWindow *dfbwin = get_dfb_window(window);
+ SDL_DFB_WINDOWDATA(window);
+ SDL_VideoDisplay *display = texturedata->display;
+ DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
+
+ SDL_DFB_CHECKERR(dispdata->
+ vidlayer->SetSourceRectangle(dispdata->vidlayer,
+ sr.x, sr.y, sr.w, sr.h));
+ dfbwin->GetPosition(dfbwin, &px, &py);
+ px += windata->client.x;
+ py += windata->client.y;
+ SDL_DFB_CHECKERR(dispdata->
+ vidlayer->SetScreenRectangle(dispdata->vidlayer,
+ px + dr.x,
+ py + dr.y,
+ dr.w,
+ dr.h));
+ } else {
+ DFBSurfaceBlittingFlags flags = 0;
+
+#if 0
+ if (texturedata->dirty.list) {
+ SDL_DirtyRect *dirty;
+ void *pixels;
+ int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
+ int pitch = texturedata->pitch;
+
+ for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
+ SDL_Rect *rect = &dirty->rect;
+ pixels =
+ (void *) ((Uint8 *) texturedata->pixels +
+ rect->y * pitch + rect->x * bpp);
+ DirectFB_UpdateTexture(renderer, texture, rect,
+ pixels,
+ texturedata->pitch);
+ }
+ SDL_ClearDirtyRects(&texturedata->dirty);
+ }
+#endif
+ if (texturedata->isDirty)
+ {
+ SDL_Rect rect;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = texture->w;
+ rect.h = texture->h;
+
+ DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
+ }
+
+ alpha = r = g = b = 0xff;
+ if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){
+ alpha = texture->a;
+ flags |= DSBLIT_BLEND_COLORALPHA;
+ }
+
+ if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
+ r = texture->r;
+ g = texture->g;
+ b = texture->b;
+ flags |= DSBLIT_COLORIZE;
+ }
+ SDL_DFB_CHECKERR(destsurf->
+ SetColor(destsurf, r, g, b, alpha));
+
+ /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
+
+ SetBlendMode(data, texture->blendMode, texturedata);
+
+ SDL_DFB_CHECKERR(destsurf->SetBlittingFlags(destsurf,
+ data->blitFlags | flags));
+
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf,
+ texturedata->
+ render_options));
+#endif
+
+ if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
+ SDL_DFB_CHECKERR(destsurf->Blit(destsurf,
+ texturedata->surface,
+ &sr, dr.x, dr.y));
+ } else {
+ SDL_DFB_CHECKERR(destsurf->StretchBlit(destsurf,
+ texturedata->surface,
+ &sr, &dr));
+ }
+ }
+ return 0;
+ error:
+ return -1;
+}
+
+static void
+DirectFB_RenderPresent(SDL_Renderer * renderer)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ SDL_Window *window = renderer->window;
+ SDL_DFB_WINDOWDATA(window);
+ SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL);
+
+ DirectFB_ActivateRenderer(renderer);
+
+ if (shape_data && shape_data->surface) {
+ /* saturate the window surface alpha channel */
+ SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
+ SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
+ SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
+ SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
+ SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
+
+ /* blit the mask */
+ SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
+ SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
+ SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
+#endif
+ SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0));
+ }
+
+ /* Send the data to the display */
+ SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL,
+ data->flipflags));
+}
+
+static void
+DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ if (!data) {
+ return;
+ }
+ SDL_DFB_RELEASE(data->palette);
+ SDL_DFB_RELEASE(data->surface);
+ if (data->display) {
+ DFB_DisplayData *dispdata =
+ (DFB_DisplayData *) data->display->driverdata;
+ dispdata->vidIDinuse = 0;
+ /* FIXME: Shouldn't we reset the cooperative level */
+ SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
+ DLSCL_ADMINISTRATIVE));
+ SDL_DFB_RELEASE(dispdata->vidlayer);
+ }
+ SDL_DFB_FREE(data->pixels);
+ SDL_free(data);
+ texture->driverdata = NULL;
+}
+
+static void
+DirectFB_DestroyRenderer(SDL_Renderer * renderer)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(data->window);
+#if 0
+ if (display->palette) {
+ SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data);
+ }
+#endif
+
+ SDL_free(data);
+ SDL_free(renderer);
+}
+
+static int
+DirectFB_UpdateViewport(SDL_Renderer * renderer)
+{
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *winsurf = data->target;
+ DFBRegion dreg;
+
+ dreg.x1 = renderer->viewport.x;
+ dreg.y1 = renderer->viewport.y;
+ dreg.x2 = dreg.x1 + renderer->viewport.w - 1;
+ dreg.y2 = dreg.y1 + renderer->viewport.h - 1;
+
+ winsurf->SetClip(winsurf, &dreg);
+ return 0;
+}
+
+static int
+DirectFB_UpdateClipRect(SDL_Renderer * renderer)
+{
+ const SDL_Rect *rect = &renderer->clip_rect;
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *destsurf = get_dfb_surface(data->window);
+ DFBRegion region;
+
+ if (!SDL_RectEmpty(rect)) {
+ region.x1 = rect->x;
+ region.x2 = rect->x + rect->w;
+ region.y1 = rect->y;
+ region.y2 = rect->y + rect->h;
+ SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, &region));
+ } else {
+ SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, NULL));
+ }
+ return 0;
+ error:
+ return -1;
+}
+
+static int
+DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 format, void * pixels, int pitch)
+{
+ Uint32 sdl_format;
+ unsigned char* laypixels;
+ int laypitch;
+ DFBSurfacePixelFormat dfb_format;
+ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+ IDirectFBSurface *winsurf = data->target;
+
+ DirectFB_ActivateRenderer(renderer);
+
+ winsurf->GetPixelFormat(winsurf, &dfb_format);
+ sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
+ winsurf->Lock(winsurf, DSLF_READ, (void **) &laypixels, &laypitch);
+
+ laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
+ SDL_ConvertPixels(rect->w, rect->h,
+ sdl_format, laypixels, laypitch,
+ format, pixels, pitch);
+
+ winsurf->Unlock(winsurf);
+
+ return 0;
+}
+
+#if 0
+static int
+DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 format, const void * pixels, int pitch)
+{
+ SDL_Window *window = renderer->window;
+ SDL_DFB_WINDOWDATA(window);
+ Uint32 sdl_format;
+ unsigned char* laypixels;
+ int laypitch;
+ DFBSurfacePixelFormat dfb_format;
+
+ SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
+ sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
+
+ SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (void **) &laypixels, &laypitch));
+
+ laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
+ SDL_ConvertPixels(rect->w, rect->h,
+ format, pixels, pitch,
+ sdl_format, laypixels, laypitch);
+
+ SDL_DFB_CHECK(windata->surface->Unlock(windata->surface));
+
+ return 0;
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.h
new file mode 100644
index 0000000..bc3c075
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_render.h
@@ -0,0 +1,25 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+/* SDL surface based renderer implementation */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.c
new file mode 100644
index 0000000..3655931
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.c
@@ -0,0 +1,131 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_assert.h"
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_shape.h"
+#include "SDL_DirectFB_window.h"
+
+#include "../SDL_shape_internals.h"
+
+SDL_WindowShaper*
+DirectFB_CreateShaper(SDL_Window* window) {
+ SDL_WindowShaper* result = NULL;
+ SDL_ShapeData* data;
+ int resized_properly;
+
+ result = malloc(sizeof(SDL_WindowShaper));
+ result->window = window;
+ result->mode.mode = ShapeModeDefault;
+ result->mode.parameters.binarizationCutoff = 1;
+ result->userx = result->usery = 0;
+ data = SDL_malloc(sizeof(SDL_ShapeData));
+ result->driverdata = data;
+ data->surface = NULL;
+ window->shaper = result;
+ resized_properly = DirectFB_ResizeWindowShape(window);
+ SDL_assert(resized_properly == 0);
+
+ return result;
+}
+
+int
+DirectFB_ResizeWindowShape(SDL_Window* window) {
+ SDL_ShapeData* data = window->shaper->driverdata;
+ SDL_assert(data != NULL);
+
+ if (window->x != -1000)
+ {
+ window->shaper->userx = window->x;
+ window->shaper->usery = window->y;
+ }
+ SDL_SetWindowPosition(window,-1000,-1000);
+
+ return 0;
+}
+
+int
+DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) {
+
+ if(shaper == NULL || shape == NULL || shaper->driverdata == NULL)
+ return -1;
+ if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode))
+ return -2;
+ if(shape->w != shaper->window->w || shape->h != shaper->window->h)
+ return -3;
+
+ {
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(shaper->window);
+ SDL_DFB_DEVICEDATA(display->device);
+ Uint32 *pixels;
+ Sint32 pitch;
+ Uint32 h,w;
+ Uint8 *src, *bitmap;
+ DFBSurfaceDescription dsc;
+
+ SDL_ShapeData *data = shaper->driverdata;
+
+ SDL_DFB_RELEASE(data->surface);
+
+ dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
+ dsc.width = shape->w;
+ dsc.height = shape->h;
+ dsc.caps = DSCAPS_PREMULTIPLIED;
+ dsc.pixelformat = DSPF_ARGB;
+
+ SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, &data->surface));
+
+ /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
+ SDL_DFB_ALLOC_CLEAR(bitmap, shape->w * shape->h);
+ SDL_CalculateShapeBitmap(shaper->mode,shape,bitmap,1);
+
+ src = bitmap;
+
+ SDL_DFB_CHECK(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, (void **) &pixels, &pitch));
+
+ h = shaper->window->h;
+ while (h--) {
+ for (w = 0; w < shaper->window->w; w++) {
+ if (*src)
+ pixels[w] = 0xFFFFFFFF;
+ else
+ pixels[w] = 0;
+ src++;
+
+ }
+ pixels += (pitch >> 2);
+ }
+ SDL_DFB_CHECK(data->surface->Unlock(data->surface));
+ SDL_DFB_FREE(bitmap);
+
+ /* FIXME: Need to call this here - Big ?? */
+ DirectFB_WM_RedrawLayout(SDL_GetDisplayForWindow(shaper->window)->device, shaper->window);
+ }
+
+ return 0;
+error:
+ return -1;
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.h
new file mode 100644
index 0000000..f0a418d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_shape.h
@@ -0,0 +1,38 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_DirectFB_shape_h_
+#define SDL_DirectFB_shape_h_
+
+#include <directfb.h>
+
+#include "../SDL_sysvideo.h"
+#include "SDL_shape.h"
+
+typedef struct {
+ IDirectFBSurface *surface;
+} SDL_ShapeData;
+
+extern SDL_WindowShaper* DirectFB_CreateShaper(SDL_Window* window);
+extern int DirectFB_ResizeWindowShape(SDL_Window* window);
+extern int DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode);
+
+#endif /* SDL_DirectFB_shape_h_ */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.c
new file mode 100644
index 0000000..8740ce1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.c
@@ -0,0 +1,418 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+/*
+ * #include "SDL_DirectFB_keyboard.h"
+ */
+#include "SDL_DirectFB_modes.h"
+#include "SDL_DirectFB_opengl.h"
+#include "SDL_DirectFB_window.h"
+#include "SDL_DirectFB_WM.h"
+
+
+/* DirectFB video driver implementation.
+*/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <directfb.h>
+#include <directfb_version.h>
+#include <directfb_strings.h>
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_events.h"
+#include "SDL_DirectFB_render.h"
+#include "SDL_DirectFB_mouse.h"
+#include "SDL_DirectFB_shape.h"
+
+
+#include "SDL_DirectFB_dyn.h"
+
+/* Initialization/Query functions */
+static int DirectFB_VideoInit(_THIS);
+static void DirectFB_VideoQuit(_THIS);
+
+static int DirectFB_Available(void);
+static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
+
+VideoBootStrap DirectFB_bootstrap = {
+ "directfb", "DirectFB",
+ DirectFB_Available, DirectFB_CreateDevice
+};
+
+static const DirectFBSurfaceDrawingFlagsNames(drawing_flags);
+static const DirectFBSurfaceBlittingFlagsNames(blitting_flags);
+static const DirectFBAccelerationMaskNames(acceleration_mask);
+
+/* DirectFB driver bootstrap functions */
+
+static int
+DirectFB_Available(void)
+{
+ if (!SDL_DirectFB_LoadLibrary())
+ return 0;
+ SDL_DirectFB_UnLoadLibrary();
+ return 1;
+}
+
+static void
+DirectFB_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_DirectFB_UnLoadLibrary();
+ SDL_DFB_FREE(device->driverdata);
+ SDL_DFB_FREE(device);
+}
+
+static SDL_VideoDevice *
+DirectFB_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ if (!SDL_DirectFB_LoadLibrary()) {
+ return NULL;
+ }
+
+ /* Initialize all variables that we clean on shutdown */
+ SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
+
+ /* Set the function pointers */
+ device->VideoInit = DirectFB_VideoInit;
+ device->VideoQuit = DirectFB_VideoQuit;
+ device->GetDisplayModes = DirectFB_GetDisplayModes;
+ device->SetDisplayMode = DirectFB_SetDisplayMode;
+ device->PumpEvents = DirectFB_PumpEventsWindow;
+ device->CreateSDLWindow = DirectFB_CreateWindow;
+ device->CreateSDLWindowFrom = DirectFB_CreateWindowFrom;
+ device->SetWindowTitle = DirectFB_SetWindowTitle;
+ device->SetWindowIcon = DirectFB_SetWindowIcon;
+ device->SetWindowPosition = DirectFB_SetWindowPosition;
+ device->SetWindowSize = DirectFB_SetWindowSize;
+ device->SetWindowOpacity = DirectFB_SetWindowOpacity;
+ device->ShowWindow = DirectFB_ShowWindow;
+ device->HideWindow = DirectFB_HideWindow;
+ device->RaiseWindow = DirectFB_RaiseWindow;
+ device->MaximizeWindow = DirectFB_MaximizeWindow;
+ device->MinimizeWindow = DirectFB_MinimizeWindow;
+ device->RestoreWindow = DirectFB_RestoreWindow;
+ device->SetWindowGrab = DirectFB_SetWindowGrab;
+ device->DestroyWindow = DirectFB_DestroyWindow;
+ device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
+
+ /* !!! FIXME: implement SetWindowBordered */
+
+#if SDL_DIRECTFB_OPENGL
+ device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
+ device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
+ device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
+
+ device->GL_CreateContext = DirectFB_GL_CreateContext;
+ device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
+ device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
+ device->GL_SwapWindow = DirectFB_GL_SwapWindow;
+ device->GL_DeleteContext = DirectFB_GL_DeleteContext;
+
+#endif
+
+ /* Shaped window support */
+ device->shape_driver.CreateShaper = DirectFB_CreateShaper;
+ device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
+ device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
+
+ device->free = DirectFB_DeleteDevice;
+
+ return device;
+ error:
+ if (device)
+ SDL_free(device);
+ return (0);
+}
+
+static void
+DirectFB_DeviceInformation(IDirectFB * dfb)
+{
+ DFBGraphicsDeviceDescription desc;
+ int n;
+
+ dfb->GetDeviceDescription(dfb, &desc);
+
+ SDL_DFB_LOG( "DirectFB Device Information");
+ SDL_DFB_LOG( "===========================");
+ SDL_DFB_LOG( "Name: %s", desc.name);
+ SDL_DFB_LOG( "Vendor: %s", desc.vendor);
+ SDL_DFB_LOG( "Driver Name: %s", desc.driver.name);
+ SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor);
+ SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
+ desc.driver.minor);
+
+ SDL_DFB_LOG( "Video memory: %d", desc.video_memory);
+
+ SDL_DFB_LOG( "Blitting flags:");
+ for (n = 0; blitting_flags[n].flag; n++) {
+ if (desc.blitting_flags & blitting_flags[n].flag)
+ SDL_DFB_LOG( " %s", blitting_flags[n].name);
+ }
+
+ SDL_DFB_LOG( "Drawing flags:");
+ for (n = 0; drawing_flags[n].flag; n++) {
+ if (desc.drawing_flags & drawing_flags[n].flag)
+ SDL_DFB_LOG( " %s", drawing_flags[n].name);
+ }
+
+
+ SDL_DFB_LOG( "Acceleration flags:");
+ for (n = 0; acceleration_mask[n].mask; n++) {
+ if (desc.acceleration_mask & acceleration_mask[n].mask)
+ SDL_DFB_LOG( " %s", acceleration_mask[n].name);
+ }
+
+
+}
+
+static int readBoolEnv(const char *env_name, int def_val)
+{
+ char *stemp;
+
+ stemp = SDL_getenv(env_name);
+ if (stemp)
+ return atoi(stemp);
+ else
+ return def_val;
+}
+
+static int
+DirectFB_VideoInit(_THIS)
+{
+ IDirectFB *dfb = NULL;
+ DFB_DeviceData *devdata = NULL;
+ DFBResult ret;
+
+ SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
+
+ SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
+
+ /* avoid switching to the framebuffer when we
+ * are running X11 */
+ ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
+ if (ret) {
+ if (SDL_getenv("DISPLAY"))
+ DirectFBSetOption("system", "x11");
+ else
+ DirectFBSetOption("disable-module", "x11input");
+ }
+
+ devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 1); /* default: on */
+
+ if (!devdata->use_linux_input)
+ {
+ SDL_DFB_LOG("Disabling linux input\n");
+ DirectFBSetOption("disable-module", "linux_input");
+ }
+
+ SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
+
+ DirectFB_DeviceInformation(dfb);
+
+ devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */
+ devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */
+
+ /* Create global Eventbuffer for axis events */
+ if (devdata->use_linux_input) {
+ SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
+ DFB_TRUE,
+ &devdata->events));
+ } else {
+ SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
+ /* DICAPS_ALL */ ,
+ DFB_TRUE,
+ &devdata->events));
+ }
+
+ /* simple window manager support */
+ devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
+
+ devdata->initialized = 1;
+
+ devdata->dfb = dfb;
+ devdata->firstwin = NULL;
+ devdata->grabbed_window = NULL;
+
+ _this->driverdata = devdata;
+
+ DirectFB_InitModes(_this);
+
+#if SDL_DIRECTFB_OPENGL
+ DirectFB_GL_Initialize(_this);
+#endif
+
+ DirectFB_InitMouse(_this);
+ DirectFB_InitKeyboard(_this);
+
+ return 0;
+
+
+ error:
+ SDL_DFB_FREE(devdata);
+ SDL_DFB_RELEASE(dfb);
+ return -1;
+}
+
+static void
+DirectFB_VideoQuit(_THIS)
+{
+ DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
+
+ DirectFB_QuitModes(_this);
+ DirectFB_QuitKeyboard(_this);
+ DirectFB_QuitMouse(_this);
+
+ devdata->events->Reset(devdata->events);
+ SDL_DFB_RELEASE(devdata->events);
+ SDL_DFB_RELEASE(devdata->dfb);
+
+#if SDL_DIRECTFB_OPENGL
+ DirectFB_GL_Shutdown(_this);
+#endif
+
+ devdata->initialized = 0;
+}
+
+/* DirectFB driver general support functions */
+
+static const struct {
+ DFBSurfacePixelFormat dfb;
+ Uint32 sdl;
+} pixelformat_tab[] =
+{
+ { DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
+ { DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
+ { DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
+ { DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
+ { DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
+ { DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
+ { DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
+ { DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
+ { DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
+ { DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
+ { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
+ { DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
+ { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
+ { DSPF_ABGR, SDL_PIXELFORMAT_ABGR8888 }, /* 32 bit ABGR (4 byte, alpha 8@24, blue 8@16, green 8@8, red 8@0) */
+#if (ENABLE_LUT8)
+ { DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */
+#endif
+
+#if (DFB_VERSION_ATLEAST(1,2,0))
+ { DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
+#else
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 },
+#endif
+
+ /* Pfff ... nonmatching formats follow */
+
+ { DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */
+ { DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */
+ { DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
+ { DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
+ { DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */
+ { DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */
+ { DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
+ { DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */
+ { DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
+ { DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
+ { DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */
+ { DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */
+ { DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */
+ { DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
+
+#if (DFB_VERSION_ATLEAST(1,3,0))
+ { DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */
+#endif
+
+#if (DFB_VERSION_ATLEAST(1,4,3))
+ { DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */
+ { DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */
+ { DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */
+ { DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */
+ { DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */
+#endif
+
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 },
+ { DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */
+};
+
+Uint32
+DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
+{
+ int i;
+
+ for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
+ if (pixelformat_tab[i].dfb == pixelformat)
+ {
+ return pixelformat_tab[i].sdl;
+ }
+ return SDL_PIXELFORMAT_UNKNOWN;
+}
+
+DFBSurfacePixelFormat
+DirectFB_SDLToDFBPixelFormat(Uint32 format)
+{
+ int i;
+
+ for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
+ if (pixelformat_tab[i].sdl == format)
+ {
+ return pixelformat_tab[i].dfb;
+ }
+ return DSPF_UNKNOWN;
+}
+
+void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri)
+{
+ int i, j;
+
+ for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
+ if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN)
+ ri->texture_formats[j++] = pixelformat_tab[i].sdl;
+ ri->num_texture_formats = j;
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.h
new file mode 100644
index 0000000..f019031
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_video.h
@@ -0,0 +1,170 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_DirectFB_video_h_
+#define SDL_DirectFB_video_h_
+
+#include <directfb.h>
+#include <directfb_version.h>
+
+#include "../SDL_sysvideo.h"
+#include "SDL_scancode.h"
+#include "SDL_render.h"
+
+#include "SDL_log.h"
+
+#define DFB_VERSIONNUM(X, Y, Z) \
+ ((X)*1000 + (Y)*100 + (Z))
+
+#define DFB_COMPILEDVERSION \
+ DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
+
+#define DFB_VERSION_ATLEAST(X, Y, Z) \
+ (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
+
+#if (DFB_VERSION_ATLEAST(1,0,0))
+#ifdef SDL_VIDEO_OPENGL
+#define SDL_DIRECTFB_OPENGL 1
+#endif
+#else
+#error "SDL_DIRECTFB: Please compile against libdirectfb version >= 1.0.0"
+#endif
+
+/* Set below to 1 to compile with (old) multi mice/keyboard api. Code left in
+ * in case we see this again ...
+ */
+
+#define USE_MULTI_API (0)
+
+/* Support for LUT8/INDEX8 pixel format.
+ * This is broken in DirectFB 1.4.3. It works in 1.4.0 and 1.4.5
+ * occurred.
+ */
+
+#if (DFB_COMPILEDVERSION == DFB_VERSIONNUM(1, 4, 3))
+#define ENABLE_LUT8 (0)
+#else
+#define ENABLE_LUT8 (1)
+#endif
+
+#define DIRECTFB_DEBUG 1
+
+#define DFBENV_USE_YUV_UNDERLAY "SDL_DIRECTFB_YUV_UNDERLAY" /* Default: off */
+#define DFBENV_USE_YUV_DIRECT "SDL_DIRECTFB_YUV_DIRECT" /* Default: off */
+#define DFBENV_USE_X11_CHECK "SDL_DIRECTFB_X11_CHECK" /* Default: on */
+#define DFBENV_USE_LINUX_INPUT "SDL_DIRECTFB_LINUX_INPUT" /* Default: on */
+#define DFBENV_USE_WM "SDL_DIRECTFB_WM" /* Default: off */
+
+#define SDL_DFB_RELEASE(x) do { if ( (x) != NULL ) { SDL_DFB_CHECK(x->Release(x)); x = NULL; } } while (0)
+#define SDL_DFB_FREE(x) do { SDL_free((x)); (x) = NULL; } while (0)
+#define SDL_DFB_UNLOCK(x) do { if ( (x) != NULL ) { x->Unlock(x); } } while (0)
+
+#define SDL_DFB_CONTEXT "SDL_DirectFB"
+
+#define SDL_DFB_ERR(x...) SDL_LogError(SDL_LOG_CATEGORY_ERROR, x)
+
+#if (DIRECTFB_DEBUG)
+#define SDL_DFB_LOG(x...) SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, x)
+
+#define SDL_DFB_DEBUG(x...) SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, x)
+
+static SDL_INLINE DFBResult sdl_dfb_check(DFBResult ret, const char *src_file, int src_line) {
+ if (ret != DFB_OK) {
+ SDL_DFB_LOG("%s (%d):%s", src_file, src_line, DirectFBErrorString (ret) );
+ SDL_SetError("%s:%s", SDL_DFB_CONTEXT, DirectFBErrorString (ret) );
+ }
+ return ret;
+}
+
+#define SDL_DFB_CHECK(x...) do { sdl_dfb_check( x, __FILE__, __LINE__); } while (0)
+#define SDL_DFB_CHECKERR(x...) do { if ( sdl_dfb_check( x, __FILE__, __LINE__) != DFB_OK ) goto error; } while (0)
+
+#else
+
+#define SDL_DFB_CHECK(x...) x
+#define SDL_DFB_CHECKERR(x...) do { if (x != DFB_OK ) goto error; } while (0)
+#define SDL_DFB_LOG(x...) do {} while (0)
+#define SDL_DFB_DEBUG(x...) do {} while (0)
+
+#endif
+
+
+#define SDL_DFB_CALLOC(r, n, s) \
+ do { \
+ r = SDL_calloc (n, s); \
+ if (!(r)) { \
+ SDL_DFB_ERR("Out of memory"); \
+ SDL_OutOfMemory(); \
+ goto error; \
+ } \
+ } while (0)
+
+#define SDL_DFB_ALLOC_CLEAR(r, s) SDL_DFB_CALLOC(r, 1, s)
+
+/* Private display data */
+
+#define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (dev ? (DFB_DeviceData *) ((dev)->driverdata) : NULL)
+
+#define DFB_MAX_SCREENS 10
+
+typedef struct _DFB_KeyboardData DFB_KeyboardData;
+struct _DFB_KeyboardData
+{
+ const SDL_Scancode *map; /* keyboard scancode map */
+ int map_size; /* size of map */
+ int map_adjust; /* index adjust */
+ int is_generic; /* generic keyboard */
+ int id;
+};
+
+typedef struct _DFB_DeviceData DFB_DeviceData;
+struct _DFB_DeviceData
+{
+ int initialized;
+
+ IDirectFB *dfb;
+ int num_mice;
+ int mouse_id[0x100];
+ int num_keyboard;
+ DFB_KeyboardData keyboard[10];
+ SDL_Window *firstwin;
+
+ int use_yuv_underlays;
+ int use_yuv_direct;
+ int use_linux_input;
+ int has_own_wm;
+
+
+ /* window grab */
+ SDL_Window *grabbed_window;
+
+ /* global events */
+ IDirectFBEventBuffer *events;
+};
+
+Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat);
+DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format);
+void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo *ri);
+
+
+#endif /* SDL_DirectFB_video_h_ */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.c
new file mode 100644
index 0000000..55171ed
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.c
@@ -0,0 +1,565 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DIRECTFB
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_modes.h"
+#include "SDL_DirectFB_window.h"
+#include "SDL_DirectFB_shape.h"
+
+#if SDL_DIRECTFB_OPENGL
+#include "SDL_DirectFB_opengl.h"
+#endif
+
+#include "SDL_syswm.h"
+
+#include "../SDL_pixels_c.h"
+
+int
+DirectFB_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_DISPLAYDATA(window);
+ DFB_WindowData *windata = NULL;
+ DFBWindowOptions wopts;
+ DFBWindowDescription desc;
+ int x, y;
+ int bshaped = 0;
+
+ SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
+ SDL_memset(&desc, 0, sizeof(DFBWindowDescription));
+ windata = (DFB_WindowData *) window->driverdata;
+
+ windata->is_managed = devdata->has_own_wm;
+#if 1
+ SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
+ DFSCL_NORMAL));
+ SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
+ DLSCL_ADMINISTRATIVE));
+#endif
+ /* FIXME ... ughh, ugly */
+ if (window->x == -1000 && window->y == -1000)
+ bshaped = 1;
+
+ /* Fill the window description. */
+ x = window->x;
+ y = window->y;
+
+ DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
+
+ /* Create Window */
+ desc.caps = 0;
+ desc.flags =
+ DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
+
+ if (bshaped) {
+ desc.flags |= DWDESC_CAPS;
+ desc.caps |= DWCAPS_ALPHACHANNEL;
+ }
+ else
+ {
+ desc.flags |= DWDESC_PIXELFORMAT;
+ }
+
+ if (!(window->flags & SDL_WINDOW_BORDERLESS))
+ desc.caps |= DWCAPS_NODECORATION;
+
+ desc.posx = x;
+ desc.posy = y;
+ desc.width = windata->size.w;
+ desc.height = windata->size.h;
+ desc.pixelformat = dispdata->pixelformat;
+ desc.surface_caps = DSCAPS_PREMULTIPLIED;
+#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ desc.surface_caps |= DSCAPS_GL;
+ }
+#endif
+
+ /* Create the window. */
+ SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
+ &windata->dfbwin));
+
+ /* Set Options */
+ SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
+
+ /* explicit rescaling of surface */
+ wopts |= DWOP_SCALE;
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ wopts &= ~DWOP_KEEP_SIZE;
+ }
+ else {
+ wopts |= DWOP_KEEP_SIZE;
+ }
+
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
+ SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
+ }
+
+ if (bshaped) {
+ wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
+ wopts &= ~DWOP_OPAQUE_REGION;
+ }
+
+ SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
+
+ /* See what we got */
+ SDL_DFB_CHECK(DirectFB_WM_GetClientSize
+ (_this, window, &window->w, &window->h));
+
+ /* Get the window's surface. */
+ SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
+ &windata->window_surface));
+
+ /* And get a subsurface for rendering */
+ SDL_DFB_CHECKERR(windata->window_surface->
+ GetSubSurface(windata->window_surface, &windata->client,
+ &windata->surface));
+
+ SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
+
+ /* Create Eventbuffer */
+
+ SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
+ &windata->
+ eventbuffer));
+ SDL_DFB_CHECKERR(windata->dfbwin->
+ EnableEvents(windata->dfbwin, DWET_ALL));
+
+ /* Create a font */
+ /* FIXME: once during Video_Init */
+ windata->font = NULL;
+
+ /* Make it the top most window. */
+ SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
+
+ /* remember parent */
+ /* windata->sdlwin = window; */
+
+ /* Add to list ... */
+
+ windata->next = devdata->firstwin;
+ windata->opacity = 0xFF;
+ devdata->firstwin = window;
+
+ /* Draw Frame */
+ DirectFB_WM_RedrawLayout(_this, window);
+
+ return 0;
+ error:
+ SDL_DFB_RELEASE(windata->surface);
+ SDL_DFB_RELEASE(windata->dfbwin);
+ return -1;
+}
+
+int
+DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ return SDL_Unsupported();
+}
+
+void
+DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+
+ if (windata->is_managed) {
+ windata->wm_needs_redraw = 1;
+ DirectFB_WM_RedrawLayout(_this, window);
+ } else {
+ SDL_Unsupported();
+ }
+}
+
+void
+DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(window);
+ SDL_Surface *surface = NULL;
+
+ if (icon) {
+ SDL_PixelFormat format;
+ DFBSurfaceDescription dsc;
+ Uint32 *dest;
+ Uint32 *p;
+ int pitch, i;
+
+ /* Convert the icon to ARGB for modern window managers */
+ SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
+ surface = SDL_ConvertSurface(icon, &format, 0);
+ if (!surface) {
+ return;
+ }
+ dsc.flags =
+ DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
+ dsc.caps = DSCAPS_VIDEOONLY;
+ dsc.width = surface->w;
+ dsc.height = surface->h;
+ dsc.pixelformat = DSPF_ARGB;
+
+ SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
+ &windata->icon));
+
+ SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
+ (void *) &dest, &pitch));
+
+ p = surface->pixels;
+ for (i = 0; i < surface->h; i++)
+ memcpy((char *) dest + i * pitch,
+ (char *) p + i * surface->pitch, 4 * surface->w);
+
+ SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
+ SDL_FreeSurface(surface);
+ } else {
+ SDL_DFB_RELEASE(windata->icon);
+ }
+ return;
+ error:
+ SDL_FreeSurface(surface);
+ SDL_DFB_RELEASE(windata->icon);
+ return;
+}
+
+void
+DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ int x, y;
+
+ x = window->x;
+ y = window->y;
+
+ DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
+ SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
+}
+
+void
+DirectFB_SetWindowSize(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+
+ if(SDL_IsShapedWindow(window))
+ DirectFB_ResizeWindowShape(window);
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ int cw;
+ int ch;
+
+ /* Make sure all events are disabled for this operation ! */
+ SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
+ DWET_ALL));
+ SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
+
+ if (cw != window->w || ch != window->h) {
+
+ DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
+ SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
+ windata->size.w,
+ windata->size.h));
+ }
+
+ SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
+ (_this, window, &window->w, &window->h));
+ DirectFB_AdjustWindowSurface(window);
+
+ SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
+ DWET_ALL));
+
+ }
+ return;
+ error:
+ SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
+ return;
+}
+
+void
+DirectFB_ShowWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+
+ SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
+
+}
+
+void
+DirectFB_HideWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+
+ SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
+ SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
+}
+
+void
+DirectFB_RaiseWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+
+ SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
+ SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
+}
+
+void
+DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ DFBWindowOptions wopts;
+
+ SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
+ &windata->restore.x, &windata->restore.y));
+ SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
+ &windata->restore.h));
+
+ DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
+
+ SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
+ SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
+ display->current_mode.w, display->current_mode.h));
+
+ /* Set Options */
+ SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
+ wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
+ SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
+}
+
+void
+DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
+{
+ /* FIXME: Size to 32x32 ? */
+
+ SDL_Unsupported();
+}
+
+void
+DirectFB_RestoreWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ DFBWindowOptions wopts;
+
+ /* Set Options */
+ SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
+ wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
+ SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
+
+ /* Window layout */
+ DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
+ windata->restore.w, windata->restore.h);
+ SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
+ windata->restore.h));
+ SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
+ windata->restore.y));
+
+ if (!(window->flags & SDL_WINDOW_RESIZABLE))
+ wopts |= DWOP_KEEP_SIZE;
+
+ if (window->flags & SDL_WINDOW_FULLSCREEN)
+ wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
+ SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
+
+
+}
+
+void
+DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(window);
+ DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
+
+ if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
+ if (gwindata != NULL)
+ {
+ SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
+ SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
+ }
+ SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
+ SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
+ devdata->grabbed_window = window;
+ } else {
+ SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
+ SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
+ devdata->grabbed_window = NULL;
+ }
+}
+
+void
+DirectFB_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(window);
+ DFB_WindowData *p;
+
+ /* Some cleanups */
+ SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
+ SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
+
+#if SDL_DIRECTFB_OPENGL
+ DirectFB_GL_DestroyWindowContexts(_this, window);
+#endif
+
+ if (window->shaper)
+ {
+ SDL_ShapeData *data = window->shaper->driverdata;
+ SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
+ SDL_DFB_RELEASE(data->surface);
+ SDL_DFB_FREE(data);
+ SDL_DFB_FREE(window->shaper);
+ }
+
+ SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
+ SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
+ SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
+ SDL_DFB_RELEASE(windata->icon);
+ SDL_DFB_RELEASE(windata->font);
+ SDL_DFB_RELEASE(windata->eventbuffer);
+ SDL_DFB_RELEASE(windata->surface);
+ SDL_DFB_RELEASE(windata->window_surface);
+
+ SDL_DFB_RELEASE(windata->dfbwin);
+
+ /* Remove from list ... */
+
+ p = devdata->firstwin->driverdata;
+
+ while (p && p->next != window)
+ p = (p->next ? p->next->driverdata : NULL);
+ if (p)
+ p->next = windata->next;
+ else
+ devdata->firstwin = windata->next;
+ SDL_free(windata);
+ return;
+}
+
+SDL_bool
+DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo * info)
+{
+ const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
+ (((Uint32) info->version.minor) * 10000) +
+ (((Uint32) info->version.patch)));
+
+ SDL_DFB_DEVICEDATA(_this);
+ SDL_DFB_WINDOWDATA(window);
+
+ /* Before 2.0.6, it was possible to build an SDL with DirectFB support
+ (SDL_SysWMinfo will be large enough to hold DirectFB info), but build
+ your app against SDL headers that didn't have DirectFB support
+ (SDL_SysWMinfo could be smaller than DirectFB needs. This would lead
+ to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
+ overflow memory on the stack or heap. To protect against this, we've
+ padded out the struct unconditionally in the headers and DirectFB will
+ just return an error for older apps using this function. Those apps
+ will need to be recompiled against newer headers or not use DirectFB,
+ maybe by forcing SDL_VIDEODRIVER=x11. */
+ if (version < 2000006) {
+ info->subsystem = SDL_SYSWM_UNKNOWN;
+ SDL_SetError("Version must be 2.0.6 or newer");
+ return SDL_FALSE;
+ }
+
+ if (info->version.major == SDL_MAJOR_VERSION &&
+ info->version.minor == SDL_MINOR_VERSION) {
+ info->subsystem = SDL_SYSWM_DIRECTFB;
+ info->info.dfb.dfb = devdata->dfb;
+ info->info.dfb.window = windata->dfbwin;
+ info->info.dfb.surface = windata->surface;
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+}
+
+void
+DirectFB_AdjustWindowSurface(SDL_Window * window)
+{
+ SDL_DFB_WINDOWDATA(window);
+ int adjust = windata->wm_needs_redraw;
+ int cw, ch;
+
+ DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
+
+ SDL_DFB_CHECKERR(windata->
+ window_surface->GetSize(windata->window_surface, &cw,
+ &ch));
+ if (cw != windata->size.w || ch != windata->size.h) {
+ adjust = 1;
+ }
+
+ if (adjust) {
+#if SDL_DIRECTFB_OPENGL
+ DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
+#endif
+
+#if (DFB_VERSION_ATLEAST(1,2,1))
+ SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
+ windata->size.w,
+ windata->size.h));
+ SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
+ windata->
+ window_surface,
+ &windata->client));
+#else
+ DFBWindowOptions opts;
+
+ SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
+ /* recreate subsurface */
+ SDL_DFB_RELEASE(windata->surface);
+
+ if (opts & DWOP_SCALE)
+ SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
+ windata->size.w,
+ windata->size.h));
+ SDL_DFB_CHECKERR(windata->window_surface->
+ GetSubSurface(windata->window_surface,
+ &windata->client, &windata->surface));
+#endif
+ DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
+
+#if SDL_DIRECTFB_OPENGL
+ DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
+#endif
+ }
+ error:
+ return;
+}
+
+int
+DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
+{
+ const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f));
+ SDL_DFB_WINDOWDATA(window);
+ SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha));
+ windata->opacity = alpha;
+ return 0;
+
+error:
+ return -1;
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.h b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.h
new file mode 100644
index 0000000..f03aab2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_window.h
@@ -0,0 +1,82 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_directfb_window_h_
+#define SDL_directfb_window_h_
+
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_WM.h"
+
+#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL)
+
+typedef struct _DFB_WindowData DFB_WindowData;
+struct _DFB_WindowData
+{
+ IDirectFBSurface *window_surface; /* window surface */
+ IDirectFBSurface *surface; /* client drawing surface */
+ IDirectFBWindow *dfbwin;
+ IDirectFBEventBuffer *eventbuffer;
+ /* SDL_Window *sdlwin; */
+ SDL_Window *next;
+ Uint8 opacity;
+ DFBRectangle client;
+ DFBDimension size;
+ DFBRectangle restore;
+
+ /* WM extras */
+ int is_managed;
+ int wm_needs_redraw;
+ IDirectFBSurface *icon;
+ IDirectFBFont *font;
+ DFB_Theme theme;
+
+ /* WM moving and sizing */
+ int wm_grab;
+ int wm_lastx;
+ int wm_lasty;
+};
+
+extern int DirectFB_CreateWindow(_THIS, SDL_Window * window);
+extern int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window,
+ const void *data);
+extern void DirectFB_SetWindowTitle(_THIS, SDL_Window * window);
+extern void DirectFB_SetWindowIcon(_THIS, SDL_Window * window,
+ SDL_Surface * icon);
+
+extern void DirectFB_SetWindowPosition(_THIS, SDL_Window * window);
+extern void DirectFB_SetWindowSize(_THIS, SDL_Window * window);
+extern void DirectFB_ShowWindow(_THIS, SDL_Window * window);
+extern void DirectFB_HideWindow(_THIS, SDL_Window * window);
+extern void DirectFB_RaiseWindow(_THIS, SDL_Window * window);
+extern void DirectFB_MaximizeWindow(_THIS, SDL_Window * window);
+extern void DirectFB_MinimizeWindow(_THIS, SDL_Window * window);
+extern void DirectFB_RestoreWindow(_THIS, SDL_Window * window);
+extern void DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+extern void DirectFB_AdjustWindowSurface(SDL_Window * window);
+extern int DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
+
+#endif /* SDL_directfb_window_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/dummy/SDL_nullevents.c b/source/3rd-party/SDL2/src/video/dummy/SDL_nullevents.c
new file mode 100644
index 0000000..e9918bd
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/dummy/SDL_nullevents.c
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DUMMY
+
+/* Being a null driver, there's no event stream. We just define stubs for
+ most of the API. */
+
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nullvideo.h"
+#include "SDL_nullevents_c.h"
+
+void
+DUMMY_PumpEvents(_THIS)
+{
+ /* do nothing. */
+}
+
+#endif /* SDL_VIDEO_DRIVER_DUMMY */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/dummy/SDL_nullevents_c.h b/source/3rd-party/SDL2/src/video/dummy/SDL_nullevents_c.h
new file mode 100644
index 0000000..454d394
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/dummy/SDL_nullevents_c.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_nullevents_c_h_
+#define SDL_nullevents_c_h_
+
+#include "../../SDL_internal.h"
+
+#include "SDL_nullvideo.h"
+
+extern void DUMMY_PumpEvents(_THIS);
+
+#endif /* SDL_nullevents_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer.c b/source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer.c
new file mode 100644
index 0000000..64c7781
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer.c
@@ -0,0 +1,89 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DUMMY
+
+#include "../SDL_sysvideo.h"
+#include "SDL_nullframebuffer_c.h"
+
+
+#define DUMMY_SURFACE "_SDL_DummySurface"
+
+int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
+{
+ SDL_Surface *surface;
+ const Uint32 surface_format = SDL_PIXELFORMAT_RGB888;
+ int w, h;
+ int bpp;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
+ /* Free the old framebuffer surface */
+ surface = (SDL_Surface *) SDL_GetWindowData(window, DUMMY_SURFACE);
+ SDL_FreeSurface(surface);
+
+ /* Create a new one */
+ SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
+ SDL_GetWindowSize(window, &w, &h);
+ surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
+ if (!surface) {
+ return -1;
+ }
+
+ /* Save the info and return! */
+ SDL_SetWindowData(window, DUMMY_SURFACE, surface);
+ *format = surface_format;
+ *pixels = surface->pixels;
+ *pitch = surface->pitch;
+ return 0;
+}
+
+int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+{
+ static int frame_number;
+ SDL_Surface *surface;
+
+ surface = (SDL_Surface *) SDL_GetWindowData(window, DUMMY_SURFACE);
+ if (!surface) {
+ return SDL_SetError("Couldn't find dummy surface for window");
+ }
+
+ /* Send the data to the display */
+ if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) {
+ char file[128];
+ SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
+ SDL_GetWindowID(window), ++frame_number);
+ SDL_SaveBMP(surface, file);
+ }
+ return 0;
+}
+
+void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
+{
+ SDL_Surface *surface;
+
+ surface = (SDL_Surface *) SDL_SetWindowData(window, DUMMY_SURFACE, NULL);
+ SDL_FreeSurface(surface);
+}
+
+#endif /* SDL_VIDEO_DRIVER_DUMMY */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer_c.h b/source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer_c.h
new file mode 100644
index 0000000..b7d0c63
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/dummy/SDL_nullframebuffer_c.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_nullframebuffer_c_h_
+#define SDL_nullframebuffer_c_h_
+
+#include "../../SDL_internal.h"
+
+extern int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
+extern int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
+extern void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+
+#endif /* SDL_nullframebuffer_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.c b/source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.c
new file mode 100644
index 0000000..317faf4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.c
@@ -0,0 +1,144 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_DUMMY
+
+/* Dummy SDL video driver implementation; this is just enough to make an
+ * SDL-based application THINK it's got a working video driver, for
+ * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it,
+ * and also for use as a collection of stubs when porting SDL to a new
+ * platform for which you haven't yet written a valid video driver.
+ *
+ * This is also a great way to determine bottlenecks: if you think that SDL
+ * is a performance problem for a given platform, enable this driver, and
+ * then see if your application runs faster without video overhead.
+ *
+ * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion
+ * of this was cut-and-pasted from Stephane Peter's work in the AAlib
+ * SDL video driver. Renamed to "DUMMY" by Sam Lantinga.
+ */
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nullvideo.h"
+#include "SDL_nullevents_c.h"
+#include "SDL_nullframebuffer_c.h"
+
+#define DUMMYVID_DRIVER_NAME "dummy"
+
+/* Initialization/Query functions */
+static int DUMMY_VideoInit(_THIS);
+static int DUMMY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+static void DUMMY_VideoQuit(_THIS);
+
+/* DUMMY driver bootstrap functions */
+
+static int
+DUMMY_Available(void)
+{
+ const char *envr = SDL_getenv("SDL_VIDEODRIVER");
+ if ((envr) && (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0)) {
+ return (1);
+ }
+
+ return (0);
+}
+
+static void
+DUMMY_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+DUMMY_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ return (0);
+ }
+ device->is_dummy = SDL_TRUE;
+
+ /* Set the function pointers */
+ device->VideoInit = DUMMY_VideoInit;
+ device->VideoQuit = DUMMY_VideoQuit;
+ device->SetDisplayMode = DUMMY_SetDisplayMode;
+ device->PumpEvents = DUMMY_PumpEvents;
+ device->CreateWindowFramebuffer = SDL_DUMMY_CreateWindowFramebuffer;
+ device->UpdateWindowFramebuffer = SDL_DUMMY_UpdateWindowFramebuffer;
+ device->DestroyWindowFramebuffer = SDL_DUMMY_DestroyWindowFramebuffer;
+
+ device->free = DUMMY_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap DUMMY_bootstrap = {
+ DUMMYVID_DRIVER_NAME, "SDL dummy video driver",
+ DUMMY_Available, DUMMY_CreateDevice
+};
+
+
+int
+DUMMY_VideoInit(_THIS)
+{
+ SDL_DisplayMode mode;
+
+ /* Use a fake 32-bpp desktop mode */
+ mode.format = SDL_PIXELFORMAT_RGB888;
+ mode.w = 1024;
+ mode.h = 768;
+ mode.refresh_rate = 0;
+ mode.driverdata = NULL;
+ if (SDL_AddBasicVideoDisplay(&mode) < 0) {
+ return -1;
+ }
+
+ SDL_zero(mode);
+ SDL_AddDisplayMode(&_this->displays[0], &mode);
+
+ /* We're done! */
+ return 0;
+}
+
+static int
+DUMMY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+void
+DUMMY_VideoQuit(_THIS)
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_DUMMY */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.h b/source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.h
new file mode 100644
index 0000000..c770349
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/dummy/SDL_nullvideo.h
@@ -0,0 +1,30 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_nullvideo_h_
+#define SDL_nullvideo_h_
+
+#include "../SDL_sysvideo.h"
+
+#endif /* SDL_nullvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.c b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.c
new file mode 100644
index 0000000..14bc240
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.c
@@ -0,0 +1,716 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN
+
+#include <emscripten/html5.h>
+
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_touch_c.h"
+
+#include "SDL_emscriptenevents.h"
+#include "SDL_emscriptenvideo.h"
+
+#include "SDL_hints.h"
+
+#define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )
+
+/*
+.keyCode to scancode
+https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
+https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
+*/
+static const SDL_Scancode emscripten_scancode_table[] = {
+ /* 0 */ SDL_SCANCODE_UNKNOWN,
+ /* 1 */ SDL_SCANCODE_UNKNOWN,
+ /* 2 */ SDL_SCANCODE_UNKNOWN,
+ /* 3 */ SDL_SCANCODE_CANCEL,
+ /* 4 */ SDL_SCANCODE_UNKNOWN,
+ /* 5 */ SDL_SCANCODE_UNKNOWN,
+ /* 6 */ SDL_SCANCODE_HELP,
+ /* 7 */ SDL_SCANCODE_UNKNOWN,
+ /* 8 */ SDL_SCANCODE_BACKSPACE,
+ /* 9 */ SDL_SCANCODE_TAB,
+ /* 10 */ SDL_SCANCODE_UNKNOWN,
+ /* 11 */ SDL_SCANCODE_UNKNOWN,
+ /* 12 */ SDL_SCANCODE_UNKNOWN,
+ /* 13 */ SDL_SCANCODE_RETURN,
+ /* 14 */ SDL_SCANCODE_UNKNOWN,
+ /* 15 */ SDL_SCANCODE_UNKNOWN,
+ /* 16 */ SDL_SCANCODE_LSHIFT,
+ /* 17 */ SDL_SCANCODE_LCTRL,
+ /* 18 */ SDL_SCANCODE_LALT,
+ /* 19 */ SDL_SCANCODE_PAUSE,
+ /* 20 */ SDL_SCANCODE_CAPSLOCK,
+ /* 21 */ SDL_SCANCODE_UNKNOWN,
+ /* 22 */ SDL_SCANCODE_UNKNOWN,
+ /* 23 */ SDL_SCANCODE_UNKNOWN,
+ /* 24 */ SDL_SCANCODE_UNKNOWN,
+ /* 25 */ SDL_SCANCODE_UNKNOWN,
+ /* 26 */ SDL_SCANCODE_UNKNOWN,
+ /* 27 */ SDL_SCANCODE_ESCAPE,
+ /* 28 */ SDL_SCANCODE_UNKNOWN,
+ /* 29 */ SDL_SCANCODE_UNKNOWN,
+ /* 30 */ SDL_SCANCODE_UNKNOWN,
+ /* 31 */ SDL_SCANCODE_UNKNOWN,
+ /* 32 */ SDL_SCANCODE_SPACE,
+ /* 33 */ SDL_SCANCODE_PAGEUP,
+ /* 34 */ SDL_SCANCODE_PAGEDOWN,
+ /* 35 */ SDL_SCANCODE_END,
+ /* 36 */ SDL_SCANCODE_HOME,
+ /* 37 */ SDL_SCANCODE_LEFT,
+ /* 38 */ SDL_SCANCODE_UP,
+ /* 39 */ SDL_SCANCODE_RIGHT,
+ /* 40 */ SDL_SCANCODE_DOWN,
+ /* 41 */ SDL_SCANCODE_UNKNOWN,
+ /* 42 */ SDL_SCANCODE_UNKNOWN,
+ /* 43 */ SDL_SCANCODE_UNKNOWN,
+ /* 44 */ SDL_SCANCODE_UNKNOWN,
+ /* 45 */ SDL_SCANCODE_INSERT,
+ /* 46 */ SDL_SCANCODE_DELETE,
+ /* 47 */ SDL_SCANCODE_UNKNOWN,
+ /* 48 */ SDL_SCANCODE_0,
+ /* 49 */ SDL_SCANCODE_1,
+ /* 50 */ SDL_SCANCODE_2,
+ /* 51 */ SDL_SCANCODE_3,
+ /* 52 */ SDL_SCANCODE_4,
+ /* 53 */ SDL_SCANCODE_5,
+ /* 54 */ SDL_SCANCODE_6,
+ /* 55 */ SDL_SCANCODE_7,
+ /* 56 */ SDL_SCANCODE_8,
+ /* 57 */ SDL_SCANCODE_9,
+ /* 58 */ SDL_SCANCODE_UNKNOWN,
+ /* 59 */ SDL_SCANCODE_SEMICOLON,
+ /* 60 */ SDL_SCANCODE_UNKNOWN,
+ /* 61 */ SDL_SCANCODE_EQUALS,
+ /* 62 */ SDL_SCANCODE_UNKNOWN,
+ /* 63 */ SDL_SCANCODE_UNKNOWN,
+ /* 64 */ SDL_SCANCODE_UNKNOWN,
+ /* 65 */ SDL_SCANCODE_A,
+ /* 66 */ SDL_SCANCODE_B,
+ /* 67 */ SDL_SCANCODE_C,
+ /* 68 */ SDL_SCANCODE_D,
+ /* 69 */ SDL_SCANCODE_E,
+ /* 70 */ SDL_SCANCODE_F,
+ /* 71 */ SDL_SCANCODE_G,
+ /* 72 */ SDL_SCANCODE_H,
+ /* 73 */ SDL_SCANCODE_I,
+ /* 74 */ SDL_SCANCODE_J,
+ /* 75 */ SDL_SCANCODE_K,
+ /* 76 */ SDL_SCANCODE_L,
+ /* 77 */ SDL_SCANCODE_M,
+ /* 78 */ SDL_SCANCODE_N,
+ /* 79 */ SDL_SCANCODE_O,
+ /* 80 */ SDL_SCANCODE_P,
+ /* 81 */ SDL_SCANCODE_Q,
+ /* 82 */ SDL_SCANCODE_R,
+ /* 83 */ SDL_SCANCODE_S,
+ /* 84 */ SDL_SCANCODE_T,
+ /* 85 */ SDL_SCANCODE_U,
+ /* 86 */ SDL_SCANCODE_V,
+ /* 87 */ SDL_SCANCODE_W,
+ /* 88 */ SDL_SCANCODE_X,
+ /* 89 */ SDL_SCANCODE_Y,
+ /* 90 */ SDL_SCANCODE_Z,
+ /* 91 */ SDL_SCANCODE_LGUI,
+ /* 92 */ SDL_SCANCODE_UNKNOWN,
+ /* 93 */ SDL_SCANCODE_APPLICATION,
+ /* 94 */ SDL_SCANCODE_UNKNOWN,
+ /* 95 */ SDL_SCANCODE_UNKNOWN,
+ /* 96 */ SDL_SCANCODE_KP_0,
+ /* 97 */ SDL_SCANCODE_KP_1,
+ /* 98 */ SDL_SCANCODE_KP_2,
+ /* 99 */ SDL_SCANCODE_KP_3,
+ /* 100 */ SDL_SCANCODE_KP_4,
+ /* 101 */ SDL_SCANCODE_KP_5,
+ /* 102 */ SDL_SCANCODE_KP_6,
+ /* 103 */ SDL_SCANCODE_KP_7,
+ /* 104 */ SDL_SCANCODE_KP_8,
+ /* 105 */ SDL_SCANCODE_KP_9,
+ /* 106 */ SDL_SCANCODE_KP_MULTIPLY,
+ /* 107 */ SDL_SCANCODE_KP_PLUS,
+ /* 108 */ SDL_SCANCODE_UNKNOWN,
+ /* 109 */ SDL_SCANCODE_KP_MINUS,
+ /* 110 */ SDL_SCANCODE_KP_PERIOD,
+ /* 111 */ SDL_SCANCODE_KP_DIVIDE,
+ /* 112 */ SDL_SCANCODE_F1,
+ /* 113 */ SDL_SCANCODE_F2,
+ /* 114 */ SDL_SCANCODE_F3,
+ /* 115 */ SDL_SCANCODE_F4,
+ /* 116 */ SDL_SCANCODE_F5,
+ /* 117 */ SDL_SCANCODE_F6,
+ /* 118 */ SDL_SCANCODE_F7,
+ /* 119 */ SDL_SCANCODE_F8,
+ /* 120 */ SDL_SCANCODE_F9,
+ /* 121 */ SDL_SCANCODE_F10,
+ /* 122 */ SDL_SCANCODE_F11,
+ /* 123 */ SDL_SCANCODE_F12,
+ /* 124 */ SDL_SCANCODE_F13,
+ /* 125 */ SDL_SCANCODE_F14,
+ /* 126 */ SDL_SCANCODE_F15,
+ /* 127 */ SDL_SCANCODE_F16,
+ /* 128 */ SDL_SCANCODE_F17,
+ /* 129 */ SDL_SCANCODE_F18,
+ /* 130 */ SDL_SCANCODE_F19,
+ /* 131 */ SDL_SCANCODE_F20,
+ /* 132 */ SDL_SCANCODE_F21,
+ /* 133 */ SDL_SCANCODE_F22,
+ /* 134 */ SDL_SCANCODE_F23,
+ /* 135 */ SDL_SCANCODE_F24,
+ /* 136 */ SDL_SCANCODE_UNKNOWN,
+ /* 137 */ SDL_SCANCODE_UNKNOWN,
+ /* 138 */ SDL_SCANCODE_UNKNOWN,
+ /* 139 */ SDL_SCANCODE_UNKNOWN,
+ /* 140 */ SDL_SCANCODE_UNKNOWN,
+ /* 141 */ SDL_SCANCODE_UNKNOWN,
+ /* 142 */ SDL_SCANCODE_UNKNOWN,
+ /* 143 */ SDL_SCANCODE_UNKNOWN,
+ /* 144 */ SDL_SCANCODE_NUMLOCKCLEAR,
+ /* 145 */ SDL_SCANCODE_SCROLLLOCK,
+ /* 146 */ SDL_SCANCODE_UNKNOWN,
+ /* 147 */ SDL_SCANCODE_UNKNOWN,
+ /* 148 */ SDL_SCANCODE_UNKNOWN,
+ /* 149 */ SDL_SCANCODE_UNKNOWN,
+ /* 150 */ SDL_SCANCODE_UNKNOWN,
+ /* 151 */ SDL_SCANCODE_UNKNOWN,
+ /* 152 */ SDL_SCANCODE_UNKNOWN,
+ /* 153 */ SDL_SCANCODE_UNKNOWN,
+ /* 154 */ SDL_SCANCODE_UNKNOWN,
+ /* 155 */ SDL_SCANCODE_UNKNOWN,
+ /* 156 */ SDL_SCANCODE_UNKNOWN,
+ /* 157 */ SDL_SCANCODE_UNKNOWN,
+ /* 158 */ SDL_SCANCODE_UNKNOWN,
+ /* 159 */ SDL_SCANCODE_UNKNOWN,
+ /* 160 */ SDL_SCANCODE_UNKNOWN,
+ /* 161 */ SDL_SCANCODE_UNKNOWN,
+ /* 162 */ SDL_SCANCODE_UNKNOWN,
+ /* 163 */ SDL_SCANCODE_UNKNOWN,
+ /* 164 */ SDL_SCANCODE_UNKNOWN,
+ /* 165 */ SDL_SCANCODE_UNKNOWN,
+ /* 166 */ SDL_SCANCODE_UNKNOWN,
+ /* 167 */ SDL_SCANCODE_UNKNOWN,
+ /* 168 */ SDL_SCANCODE_UNKNOWN,
+ /* 169 */ SDL_SCANCODE_UNKNOWN,
+ /* 170 */ SDL_SCANCODE_UNKNOWN,
+ /* 171 */ SDL_SCANCODE_UNKNOWN,
+ /* 172 */ SDL_SCANCODE_UNKNOWN,
+ /* 173 */ SDL_SCANCODE_MINUS, /*FX*/
+ /* 174 */ SDL_SCANCODE_VOLUMEDOWN, /*IE, Chrome*/
+ /* 175 */ SDL_SCANCODE_VOLUMEUP, /*IE, Chrome*/
+ /* 176 */ SDL_SCANCODE_AUDIONEXT, /*IE, Chrome*/
+ /* 177 */ SDL_SCANCODE_AUDIOPREV, /*IE, Chrome*/
+ /* 178 */ SDL_SCANCODE_UNKNOWN,
+ /* 179 */ SDL_SCANCODE_AUDIOPLAY, /*IE, Chrome*/
+ /* 180 */ SDL_SCANCODE_UNKNOWN,
+ /* 181 */ SDL_SCANCODE_AUDIOMUTE, /*FX*/
+ /* 182 */ SDL_SCANCODE_VOLUMEDOWN, /*FX*/
+ /* 183 */ SDL_SCANCODE_VOLUMEUP, /*FX*/
+ /* 184 */ SDL_SCANCODE_UNKNOWN,
+ /* 185 */ SDL_SCANCODE_UNKNOWN,
+ /* 186 */ SDL_SCANCODE_SEMICOLON, /*IE, Chrome, D3E legacy*/
+ /* 187 */ SDL_SCANCODE_EQUALS, /*IE, Chrome, D3E legacy*/
+ /* 188 */ SDL_SCANCODE_COMMA,
+ /* 189 */ SDL_SCANCODE_MINUS, /*IE, Chrome, D3E legacy*/
+ /* 190 */ SDL_SCANCODE_PERIOD,
+ /* 191 */ SDL_SCANCODE_SLASH,
+ /* 192 */ SDL_SCANCODE_GRAVE, /*FX, D3E legacy (SDL_SCANCODE_APOSTROPHE in IE/Chrome)*/
+ /* 193 */ SDL_SCANCODE_UNKNOWN,
+ /* 194 */ SDL_SCANCODE_UNKNOWN,
+ /* 195 */ SDL_SCANCODE_UNKNOWN,
+ /* 196 */ SDL_SCANCODE_UNKNOWN,
+ /* 197 */ SDL_SCANCODE_UNKNOWN,
+ /* 198 */ SDL_SCANCODE_UNKNOWN,
+ /* 199 */ SDL_SCANCODE_UNKNOWN,
+ /* 200 */ SDL_SCANCODE_UNKNOWN,
+ /* 201 */ SDL_SCANCODE_UNKNOWN,
+ /* 202 */ SDL_SCANCODE_UNKNOWN,
+ /* 203 */ SDL_SCANCODE_UNKNOWN,
+ /* 204 */ SDL_SCANCODE_UNKNOWN,
+ /* 205 */ SDL_SCANCODE_UNKNOWN,
+ /* 206 */ SDL_SCANCODE_UNKNOWN,
+ /* 207 */ SDL_SCANCODE_UNKNOWN,
+ /* 208 */ SDL_SCANCODE_UNKNOWN,
+ /* 209 */ SDL_SCANCODE_UNKNOWN,
+ /* 210 */ SDL_SCANCODE_UNKNOWN,
+ /* 211 */ SDL_SCANCODE_UNKNOWN,
+ /* 212 */ SDL_SCANCODE_UNKNOWN,
+ /* 213 */ SDL_SCANCODE_UNKNOWN,
+ /* 214 */ SDL_SCANCODE_UNKNOWN,
+ /* 215 */ SDL_SCANCODE_UNKNOWN,
+ /* 216 */ SDL_SCANCODE_UNKNOWN,
+ /* 217 */ SDL_SCANCODE_UNKNOWN,
+ /* 218 */ SDL_SCANCODE_UNKNOWN,
+ /* 219 */ SDL_SCANCODE_LEFTBRACKET,
+ /* 220 */ SDL_SCANCODE_BACKSLASH,
+ /* 221 */ SDL_SCANCODE_RIGHTBRACKET,
+ /* 222 */ SDL_SCANCODE_APOSTROPHE, /*FX, D3E legacy*/
+};
+
+
+/* "borrowed" from SDL_windowsevents.c */
+static int
+Emscripten_ConvertUTF32toUTF8(Uint32 codepoint, char * text)
+{
+ if (codepoint <= 0x7F) {
+ text[0] = (char) codepoint;
+ text[1] = '\0';
+ } else if (codepoint <= 0x7FF) {
+ text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
+ text[1] = 0x80 | (char) (codepoint & 0x3F);
+ text[2] = '\0';
+ } else if (codepoint <= 0xFFFF) {
+ text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
+ text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
+ text[2] = 0x80 | (char) (codepoint & 0x3F);
+ text[3] = '\0';
+ } else if (codepoint <= 0x10FFFF) {
+ text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
+ text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
+ text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
+ text[3] = 0x80 | (char) (codepoint & 0x3F);
+ text[4] = '\0';
+ } else {
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+static EM_BOOL
+Emscripten_HandlePointerLockChange(int eventType, const EmscriptenPointerlockChangeEvent *changeEvent, void *userData)
+{
+ SDL_WindowData *window_data = (SDL_WindowData *) userData;
+ /* keep track of lock losses, so we can regrab if/when appropriate. */
+ window_data->has_pointer_lock = changeEvent->isActive;
+ return 0;
+}
+
+
+static EM_BOOL
+Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ const int isPointerLocked = window_data->has_pointer_lock;
+ int mx, my;
+ static double residualx = 0, residualy = 0;
+
+ /* rescale (in case canvas is being scaled)*/
+ double client_w, client_h, xscale, yscale;
+ emscripten_get_element_css_size(NULL, &client_w, &client_h);
+ xscale = window_data->window->w / client_w;
+ yscale = window_data->window->h / client_h;
+
+ if (isPointerLocked) {
+ residualx += mouseEvent->movementX * xscale;
+ residualy += mouseEvent->movementY * yscale;
+ /* Let slow sub-pixel motion accumulate. Don't lose it. */
+ mx = residualx;
+ residualx -= mx;
+ my = residualy;
+ residualy -= my;
+ } else {
+ mx = mouseEvent->canvasX * xscale;
+ my = mouseEvent->canvasY * yscale;
+ }
+
+ SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
+ return 0;
+}
+
+static EM_BOOL
+Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ Uint8 sdl_button;
+ Uint8 sdl_button_state;
+ SDL_EventType sdl_event_type;
+
+ switch (mouseEvent->button) {
+ case 0:
+ sdl_button = SDL_BUTTON_LEFT;
+ break;
+ case 1:
+ sdl_button = SDL_BUTTON_MIDDLE;
+ break;
+ case 2:
+ sdl_button = SDL_BUTTON_RIGHT;
+ break;
+ default:
+ return 0;
+ }
+
+ if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) {
+ if (SDL_GetMouse()->relative_mode && !window_data->has_pointer_lock) {
+ emscripten_request_pointerlock(NULL, 0); /* try to regrab lost pointer lock. */
+ }
+ sdl_button_state = SDL_PRESSED;
+ sdl_event_type = SDL_MOUSEBUTTONDOWN;
+ } else {
+ sdl_button_state = SDL_RELEASED;
+ sdl_event_type = SDL_MOUSEBUTTONUP;
+ }
+ SDL_SendMouseButton(window_data->window, 0, sdl_button_state, sdl_button);
+ return SDL_GetEventState(sdl_event_type) == SDL_ENABLE;
+}
+
+static EM_BOOL
+Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+
+ int mx = mouseEvent->canvasX, my = mouseEvent->canvasY;
+ const int isPointerLocked = window_data->has_pointer_lock;
+
+ if (!isPointerLocked) {
+ /* rescale (in case canvas is being scaled)*/
+ double client_w, client_h;
+ emscripten_get_element_css_size(NULL, &client_w, &client_h);
+
+ mx = mx * (window_data->window->w / client_w);
+ my = my * (window_data->window->h / client_h);
+ SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
+ }
+
+ SDL_SetMouseFocus(eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? window_data->window : NULL);
+ return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE;
+}
+
+static EM_BOOL
+Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, (float)-wheelEvent->deltaY, SDL_MOUSEWHEEL_NORMAL);
+ return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE;
+}
+
+static EM_BOOL
+Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ /* If the user switches away while keys are pressed (such as
+ * via Alt+Tab), key release events won't be received. */
+ if (eventType == EMSCRIPTEN_EVENT_BLUR) {
+ SDL_ResetKeyboard();
+ }
+
+
+ SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_FOCUS ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+ return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE;
+}
+
+static EM_BOOL
+Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ int i;
+ double client_w, client_h;
+ int preventDefault = 0;
+
+ SDL_TouchID deviceId = 1;
+ if (SDL_AddTouch(deviceId, "") < 0) {
+ return 0;
+ }
+
+ emscripten_get_element_css_size(NULL, &client_w, &client_h);
+
+ for (i = 0; i < touchEvent->numTouches; i++) {
+ SDL_FingerID id;
+ float x, y;
+ int mx, my;
+
+ if (!touchEvent->touches[i].isChanged)
+ continue;
+
+ id = touchEvent->touches[i].identifier;
+ x = touchEvent->touches[i].canvasX / client_w;
+ y = touchEvent->touches[i].canvasY / client_h;
+
+ mx = x * window_data->window->w;
+ my = y * window_data->window->h;
+
+ if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
+ if (!window_data->finger_touching) {
+ window_data->finger_touching = SDL_TRUE;
+ window_data->first_finger = id;
+ SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, mx, my);
+ SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+ }
+ SDL_SendTouch(deviceId, id, SDL_TRUE, x, y, 1.0f);
+
+ if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
+ preventDefault = 1;
+ }
+ } else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
+ if ((window_data->finger_touching) && (window_data->first_finger == id)) {
+ SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, mx, my);
+ }
+ SDL_SendTouchMotion(deviceId, id, x, y, 1.0f);
+
+ if (!preventDefault && SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
+ preventDefault = 1;
+ }
+ } else {
+ if ((window_data->finger_touching) && (window_data->first_finger == id)) {
+ SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+ window_data->finger_touching = SDL_FALSE;
+ }
+ SDL_SendTouch(deviceId, id, SDL_FALSE, x, y, 1.0f);
+
+ if (!preventDefault && SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
+ preventDefault = 1;
+ }
+ }
+ }
+
+ return preventDefault;
+}
+
+static EM_BOOL
+Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
+{
+ Uint32 scancode;
+ SDL_bool prevent_default;
+ SDL_bool is_nav_key;
+
+ /* .keyCode is deprecated, but still the most reliable way to get keys */
+ if (keyEvent->keyCode < SDL_arraysize(emscripten_scancode_table)) {
+ scancode = emscripten_scancode_table[keyEvent->keyCode];
+
+ if (scancode != SDL_SCANCODE_UNKNOWN) {
+
+ if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
+ switch (scancode) {
+ case SDL_SCANCODE_LSHIFT:
+ scancode = SDL_SCANCODE_RSHIFT;
+ break;
+ case SDL_SCANCODE_LCTRL:
+ scancode = SDL_SCANCODE_RCTRL;
+ break;
+ case SDL_SCANCODE_LALT:
+ scancode = SDL_SCANCODE_RALT;
+ break;
+ case SDL_SCANCODE_LGUI:
+ scancode = SDL_SCANCODE_RGUI;
+ break;
+ }
+ }
+ SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode);
+ }
+ }
+
+ prevent_default = SDL_GetEventState(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP) == SDL_ENABLE;
+
+ /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress
+ * we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX
+ */
+ is_nav_key = keyEvent->keyCode == 8 /* backspace */ ||
+ keyEvent->keyCode == 9 /* tab */ ||
+ keyEvent->keyCode == 37 /* left */ ||
+ keyEvent->keyCode == 38 /* up */ ||
+ keyEvent->keyCode == 39 /* right */ ||
+ keyEvent->keyCode == 40 /* down */;
+
+ if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && !is_nav_key)
+ prevent_default = SDL_FALSE;
+
+ return prevent_default;
+}
+
+static EM_BOOL
+Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
+{
+ char text[5];
+ if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) {
+ SDL_SendKeyboardText(text);
+ }
+ return SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE;
+}
+
+static EM_BOOL
+Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ if(fullscreenChangeEvent->isFullscreen)
+ {
+ window_data->window->flags |= window_data->requested_fullscreen_mode;
+
+ window_data->requested_fullscreen_mode = 0;
+
+ if(!window_data->requested_fullscreen_mode)
+ window_data->window->flags |= SDL_WINDOW_FULLSCREEN; /*we didn't reqest fullscreen*/
+ }
+ else
+ {
+ window_data->window->flags &= ~FULLSCREEN_MASK;
+ }
+
+ return 0;
+}
+
+static EM_BOOL
+Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+
+ /* update pixel ratio */
+ if (window_data->window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ window_data->pixel_ratio = emscripten_get_device_pixel_ratio();
+ }
+
+ if(!(window_data->window->flags & FULLSCREEN_MASK))
+ {
+ /* this will only work if the canvas size is set through css */
+ if(window_data->window->flags & SDL_WINDOW_RESIZABLE)
+ {
+ double w = window_data->window->w;
+ double h = window_data->window->h;
+
+ if(window_data->external_size) {
+ emscripten_get_element_css_size(NULL, &w, &h);
+ }
+
+ emscripten_set_canvas_size(w * window_data->pixel_ratio, h * window_data->pixel_ratio);
+
+ /* set_canvas_size unsets this */
+ if (!window_data->external_size && window_data->pixel_ratio != 1.0f) {
+ emscripten_set_element_css_size(NULL, w, h);
+ }
+
+ SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, w, h);
+ }
+ }
+
+ return 0;
+}
+
+EM_BOOL
+Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData)
+{
+ /*this is used during fullscreen changes*/
+ SDL_WindowData *window_data = userData;
+
+ if(window_data->fullscreen_resize)
+ {
+ double css_w, css_h;
+ emscripten_get_element_css_size(NULL, &css_w, &css_h);
+ SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, css_w, css_h);
+ }
+
+ return 0;
+}
+
+static EM_BOOL
+Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData)
+{
+ SDL_WindowData *window_data = userData;
+ SDL_SendWindowEvent(window_data->window, visEvent->hidden ? SDL_WINDOWEVENT_HIDDEN : SDL_WINDOWEVENT_SHOWN, 0, 0);
+ return 0;
+}
+
+void
+Emscripten_RegisterEventHandlers(SDL_WindowData *data)
+{
+ const char *keyElement;
+
+ /* There is only one window and that window is the canvas */
+ emscripten_set_mousemove_callback("#canvas", data, 0, Emscripten_HandleMouseMove);
+
+ emscripten_set_mousedown_callback("#canvas", data, 0, Emscripten_HandleMouseButton);
+ emscripten_set_mouseup_callback("#document", data, 0, Emscripten_HandleMouseButton);
+
+ emscripten_set_mouseenter_callback("#canvas", data, 0, Emscripten_HandleMouseFocus);
+ emscripten_set_mouseleave_callback("#canvas", data, 0, Emscripten_HandleMouseFocus);
+
+ emscripten_set_wheel_callback("#canvas", data, 0, Emscripten_HandleWheel);
+
+ emscripten_set_focus_callback("#window", data, 0, Emscripten_HandleFocus);
+ emscripten_set_blur_callback("#window", data, 0, Emscripten_HandleFocus);
+
+ emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch);
+ emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
+ emscripten_set_touchmove_callback("#canvas", data, 0, Emscripten_HandleTouch);
+ emscripten_set_touchcancel_callback("#canvas", data, 0, Emscripten_HandleTouch);
+
+ emscripten_set_pointerlockchange_callback("#document", data, 0, Emscripten_HandlePointerLockChange);
+
+ /* Keyboard events are awkward */
+ keyElement = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
+ if (!keyElement) keyElement = "#window";
+
+ emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey);
+ emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
+ emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress);
+
+ emscripten_set_fullscreenchange_callback("#document", data, 0, Emscripten_HandleFullscreenChange);
+
+ emscripten_set_resize_callback("#window", data, 0, Emscripten_HandleResize);
+
+ emscripten_set_visibilitychange_callback(data, 0, Emscripten_HandleVisibilityChange);
+}
+
+void
+Emscripten_UnregisterEventHandlers(SDL_WindowData *data)
+{
+ const char *target;
+
+ /* only works due to having one window */
+ emscripten_set_mousemove_callback("#canvas", NULL, 0, NULL);
+
+ emscripten_set_mousedown_callback("#canvas", NULL, 0, NULL);
+ emscripten_set_mouseup_callback("#document", NULL, 0, NULL);
+
+ emscripten_set_mouseenter_callback("#canvas", NULL, 0, NULL);
+ emscripten_set_mouseleave_callback("#canvas", NULL, 0, NULL);
+
+ emscripten_set_wheel_callback("#canvas", NULL, 0, NULL);
+
+ emscripten_set_focus_callback("#window", NULL, 0, NULL);
+ emscripten_set_blur_callback("#window", NULL, 0, NULL);
+
+ emscripten_set_touchstart_callback("#canvas", NULL, 0, NULL);
+ emscripten_set_touchend_callback("#canvas", NULL, 0, NULL);
+ emscripten_set_touchmove_callback("#canvas", NULL, 0, NULL);
+ emscripten_set_touchcancel_callback("#canvas", NULL, 0, NULL);
+
+ emscripten_set_pointerlockchange_callback("#document", NULL, 0, NULL);
+
+ target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
+ if (!target) {
+ target = "#window";
+ }
+
+ emscripten_set_keydown_callback(target, NULL, 0, NULL);
+ emscripten_set_keyup_callback(target, NULL, 0, NULL);
+ emscripten_set_keypress_callback(target, NULL, 0, NULL);
+
+ emscripten_set_fullscreenchange_callback("#document", NULL, 0, NULL);
+
+ emscripten_set_resize_callback("#window", NULL, 0, NULL);
+
+ emscripten_set_visibilitychange_callback(NULL, 0, NULL);
+}
+
+#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.h b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.h
new file mode 100644
index 0000000..3a4e058
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenevents.h
@@ -0,0 +1,40 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef SDL_emscriptenevents_h_
+#define SDL_emscriptenevents_h_
+
+#include "SDL_emscriptenvideo.h"
+
+extern void
+Emscripten_RegisterEventHandlers(SDL_WindowData *data);
+
+extern void
+Emscripten_UnregisterEventHandlers(SDL_WindowData *data);
+
+extern EM_BOOL
+Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData);
+
+#endif /* SDL_emscriptenevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.c b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.c
new file mode 100644
index 0000000..bfdec3b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.c
@@ -0,0 +1,178 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN
+
+#include "SDL_emscriptenvideo.h"
+#include "SDL_emscriptenframebuffer.h"
+
+
+int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
+{
+ SDL_Surface *surface;
+ const Uint32 surface_format = SDL_PIXELFORMAT_BGR888;
+ int w, h;
+ int bpp;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
+ /* Free the old framebuffer surface */
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ surface = data->surface;
+ SDL_FreeSurface(surface);
+
+ /* Create a new one */
+ SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
+ SDL_GetWindowSize(window, &w, &h);
+
+ surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
+ if (!surface) {
+ return -1;
+ }
+
+ /* Save the info and return! */
+ data->surface = surface;
+ *format = surface_format;
+ *pixels = surface->pixels;
+ *pitch = surface->pitch;
+ return 0;
+}
+
+int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+{
+ SDL_Surface *surface;
+
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ surface = data->surface;
+ if (!surface) {
+ return SDL_SetError("Couldn't find framebuffer surface for window");
+ }
+
+ /* Send the data to the display */
+
+ EM_ASM_INT({
+ var w = $0;
+ var h = $1;
+ var pixels = $2;
+
+ if (!Module['SDL2']) Module['SDL2'] = {};
+ var SDL2 = Module['SDL2'];
+ if (SDL2.ctxCanvas !== Module['canvas']) {
+ SDL2.ctx = Module['createContext'](Module['canvas'], false, true);
+ SDL2.ctxCanvas = Module['canvas'];
+ }
+ if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) {
+ SDL2.image = SDL2.ctx.createImageData(w, h);
+ SDL2.w = w;
+ SDL2.h = h;
+ SDL2.imageCtx = SDL2.ctx;
+ }
+ var data = SDL2.image.data;
+ var src = pixels >> 2;
+ var dst = 0;
+ var num;
+ if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) {
+ // IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray,
+ // not UInt8ClampedArray. These don't have buffers, so we need to revert
+ // to copying a byte at a time. We do the undefined check because modern
+ // browsers do not define CanvasPixelArray anymore.
+ num = data.length;
+ while (dst < num) {
+ var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
+ data[dst ] = val & 0xff;
+ data[dst+1] = (val >> 8) & 0xff;
+ data[dst+2] = (val >> 16) & 0xff;
+ data[dst+3] = 0xff;
+ src++;
+ dst += 4;
+ }
+ } else {
+ if (SDL2.data32Data !== data) {
+ SDL2.data32 = new Int32Array(data.buffer);
+ SDL2.data8 = new Uint8Array(data.buffer);
+ }
+ var data32 = SDL2.data32;
+ num = data32.length;
+ // logically we need to do
+ // while (dst < num) {
+ // data32[dst++] = HEAP32[src++] | 0xff000000
+ // }
+ // the following code is faster though, because
+ // .set() is almost free - easily 10x faster due to
+ // native memcpy efficiencies, and the remaining loop
+ // just stores, not load + store, so it is faster
+ data32.set(HEAP32.subarray(src, src + num));
+ var data8 = SDL2.data8;
+ var i = 3;
+ var j = i + 4*num;
+ if (num % 8 == 0) {
+ // unrolling gives big speedups
+ while (i < j) {
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ }
+ } else {
+ while (i < j) {
+ data8[i] = 0xff;
+ i = i + 4 | 0;
+ }
+ }
+ }
+
+ SDL2.ctx.putImageData(SDL2.image, 0, 0);
+ return 0;
+ }, surface->w, surface->h, surface->pixels);
+
+ /*if (SDL_getenv("SDL_VIDEO_Emscripten_SAVE_FRAMES")) {
+ static int frame_number = 0;
+ char file[128];
+ SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
+ SDL_GetWindowID(window), ++frame_number);
+ SDL_SaveBMP(surface, file);
+ }*/
+ return 0;
+}
+
+void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ SDL_FreeSurface(data->surface);
+ data->surface = NULL;
+}
+
+#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.h b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.h
new file mode 100644
index 0000000..49a215a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenframebuffer.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_emscriptenframebuffer_h_
+#define SDL_emscriptenframebuffer_h_
+
+extern int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
+extern int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
+extern void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+
+#endif /* SDL_emscriptenframebuffer_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.c b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.c
new file mode 100644
index 0000000..e120980
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.c
@@ -0,0 +1,275 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN
+
+#include <emscripten/emscripten.h>
+#include <emscripten/html5.h>
+
+#include "SDL_emscriptenmouse.h"
+
+#include "../../events/SDL_mouse_c.h"
+#include "SDL_assert.h"
+
+static SDL_Cursor*
+Emscripten_CreateCursorFromString(const char* cursor_str, SDL_bool is_custom)
+{
+ SDL_Cursor* cursor;
+ Emscripten_CursorData *curdata;
+
+ cursor = SDL_calloc(1, sizeof(SDL_Cursor));
+ if (cursor) {
+ curdata = (Emscripten_CursorData *) SDL_calloc(1, sizeof(*curdata));
+ if (!curdata) {
+ SDL_OutOfMemory();
+ SDL_free(cursor);
+ return NULL;
+ }
+
+ curdata->system_cursor = cursor_str;
+ curdata->is_custom = is_custom;
+ cursor->driverdata = curdata;
+ }
+ else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor*
+Emscripten_CreateDefaultCursor()
+{
+ return Emscripten_CreateCursorFromString("default", SDL_FALSE);
+}
+
+static SDL_Cursor*
+Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
+{
+ const char *cursor_url = NULL;
+ SDL_Surface *conv_surf;
+
+ conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
+
+ if (!conv_surf) {
+ return NULL;
+ }
+
+ cursor_url = (const char *)EM_ASM_INT({
+ var w = $0;
+ var h = $1;
+ var hot_x = $2;
+ var hot_y = $3;
+ var pixels = $4;
+
+ var canvas = document.createElement("canvas");
+ canvas.width = w;
+ canvas.height = h;
+
+ var ctx = canvas.getContext("2d");
+
+ var image = ctx.createImageData(w, h);
+ var data = image.data;
+ var src = pixels >> 2;
+ var dst = 0;
+ var num;
+ if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) {
+ // IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray,
+ // not UInt8ClampedArray. These don't have buffers, so we need to revert
+ // to copying a byte at a time. We do the undefined check because modern
+ // browsers do not define CanvasPixelArray anymore.
+ num = data.length;
+ while (dst < num) {
+ var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
+ data[dst ] = val & 0xff;
+ data[dst+1] = (val >> 8) & 0xff;
+ data[dst+2] = (val >> 16) & 0xff;
+ data[dst+3] = (val >> 24) & 0xff;
+ src++;
+ dst += 4;
+ }
+ } else {
+ var data32 = new Int32Array(data.buffer);
+ num = data32.length;
+ data32.set(HEAP32.subarray(src, src + num));
+ }
+
+ ctx.putImageData(image, 0, 0);
+ var url = hot_x === 0 && hot_y === 0
+ ? "url(" + canvas.toDataURL() + "), auto"
+ : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto";
+
+ var urlBuf = _malloc(url.length + 1);
+ stringToUTF8(url, urlBuf, url.length + 1);
+
+ return urlBuf;
+ }, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels);
+
+ SDL_FreeSurface(conv_surf);
+
+ return Emscripten_CreateCursorFromString(cursor_url, SDL_TRUE);
+}
+
+static SDL_Cursor*
+Emscripten_CreateSystemCursor(SDL_SystemCursor id)
+{
+ const char *cursor_name = NULL;
+
+ switch(id) {
+ case SDL_SYSTEM_CURSOR_ARROW:
+ cursor_name = "default";
+ break;
+ case SDL_SYSTEM_CURSOR_IBEAM:
+ cursor_name = "text";
+ break;
+ case SDL_SYSTEM_CURSOR_WAIT:
+ cursor_name = "wait";
+ break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR:
+ cursor_name = "crosshair";
+ break;
+ case SDL_SYSTEM_CURSOR_WAITARROW:
+ cursor_name = "progress";
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE:
+ cursor_name = "nwse-resize";
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENESW:
+ cursor_name = "nesw-resize";
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEWE:
+ cursor_name = "ew-resize";
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENS:
+ cursor_name = "ns-resize";
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEALL:
+ cursor_name = "move";
+ break;
+ case SDL_SYSTEM_CURSOR_NO:
+ cursor_name = "not-allowed";
+ break;
+ case SDL_SYSTEM_CURSOR_HAND:
+ cursor_name = "pointer";
+ break;
+ default:
+ SDL_assert(0);
+ return NULL;
+ }
+
+ return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE);
+}
+
+static void
+Emscripten_FreeCursor(SDL_Cursor* cursor)
+{
+ Emscripten_CursorData *curdata;
+ if (cursor) {
+ curdata = (Emscripten_CursorData *) cursor->driverdata;
+
+ if (curdata != NULL) {
+ if (curdata->is_custom) {
+ SDL_free((char *)curdata->system_cursor);
+ }
+ SDL_free(cursor->driverdata);
+ }
+
+ SDL_free(cursor);
+ }
+}
+
+static int
+Emscripten_ShowCursor(SDL_Cursor* cursor)
+{
+ Emscripten_CursorData *curdata;
+ if (SDL_GetMouseFocus() != NULL) {
+ if(cursor && cursor->driverdata) {
+ curdata = (Emscripten_CursorData *) cursor->driverdata;
+
+ if(curdata->system_cursor) {
+ EM_ASM_INT({
+ if (Module['canvas']) {
+ Module['canvas'].style['cursor'] = Module['Pointer_stringify']($0);
+ }
+ return 0;
+ }, curdata->system_cursor);
+ }
+ }
+ else {
+ EM_ASM(
+ if (Module['canvas']) {
+ Module['canvas'].style['cursor'] = 'none';
+ }
+ );
+ }
+ }
+ return 0;
+}
+
+static void
+Emscripten_WarpMouse(SDL_Window* window, int x, int y)
+{
+ SDL_Unsupported();
+}
+
+static int
+Emscripten_SetRelativeMouseMode(SDL_bool enabled)
+{
+ /* TODO: pointer lock isn't actually enabled yet */
+ if(enabled) {
+ if(emscripten_request_pointerlock(NULL, 1) >= EMSCRIPTEN_RESULT_SUCCESS) {
+ return 0;
+ }
+ } else {
+ if(emscripten_exit_pointerlock() >= EMSCRIPTEN_RESULT_SUCCESS) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void
+Emscripten_InitMouse()
+{
+ SDL_Mouse* mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = Emscripten_CreateCursor;
+ mouse->ShowCursor = Emscripten_ShowCursor;
+ mouse->FreeCursor = Emscripten_FreeCursor;
+ mouse->WarpMouse = Emscripten_WarpMouse;
+ mouse->CreateSystemCursor = Emscripten_CreateSystemCursor;
+ mouse->SetRelativeMouseMode = Emscripten_SetRelativeMouseMode;
+
+ SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor());
+}
+
+void
+Emscripten_FiniMouse()
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.h b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.h
new file mode 100644
index 0000000..d6cd492
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenmouse.h
@@ -0,0 +1,42 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef SDL_emscriptenmouse_h_
+#define SDL_emscriptenmouse_h_
+
+#include "SDL_stdinc.h"
+
+typedef struct _Emscripten_CursorData
+{
+ const char *system_cursor;
+ SDL_bool is_custom;
+} Emscripten_CursorData;
+
+extern void
+Emscripten_InitMouse();
+
+extern void
+Emscripten_FiniMouse();
+
+#endif /* SDL_emscriptenmouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.c b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.c
new file mode 100644
index 0000000..7d8c005
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.c
@@ -0,0 +1,121 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL
+
+#include <emscripten/emscripten.h>
+#include <GLES2/gl2.h>
+
+#include "SDL_emscriptenvideo.h"
+#include "SDL_emscriptenopengles.h"
+
+#define LOAD_FUNC(NAME) _this->egl_data->NAME = NAME;
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+Emscripten_GLES_LoadLibrary(_THIS, const char *path) {
+ /*we can't load EGL dynamically*/
+ _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
+ if (!_this->egl_data) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Emscripten forces you to manually cast eglGetProcAddress to the real
+ function type; grep for "__eglMustCastToProperFunctionPointerType" in
+ Emscripten's egl.h for details. */
+ _this->egl_data->eglGetProcAddress = (void *(EGLAPIENTRY *)(const char *)) eglGetProcAddress;
+
+ LOAD_FUNC(eglGetDisplay);
+ LOAD_FUNC(eglInitialize);
+ LOAD_FUNC(eglTerminate);
+ LOAD_FUNC(eglChooseConfig);
+ LOAD_FUNC(eglGetConfigAttrib);
+ LOAD_FUNC(eglCreateContext);
+ LOAD_FUNC(eglDestroyContext);
+ LOAD_FUNC(eglCreateWindowSurface);
+ LOAD_FUNC(eglDestroySurface);
+ LOAD_FUNC(eglMakeCurrent);
+ LOAD_FUNC(eglSwapBuffers);
+ LOAD_FUNC(eglSwapInterval);
+ LOAD_FUNC(eglWaitNative);
+ LOAD_FUNC(eglWaitGL);
+ LOAD_FUNC(eglBindAPI);
+ LOAD_FUNC(eglQueryString);
+ LOAD_FUNC(eglGetError);
+
+ _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!_this->egl_data->egl_display) {
+ return SDL_SetError("Could not get EGL display");
+ }
+
+ if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
+ return SDL_SetError("Could not initialize EGL");
+ }
+
+ if (path) {
+ SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1);
+ } else {
+ *_this->gl_config.driver_path = '\0';
+ }
+
+ return 0;
+}
+
+void
+Emscripten_GLES_DeleteContext(_THIS, SDL_GLContext context)
+{
+ /*
+ WebGL contexts can't actually be deleted, so we need to reset it.
+ ES2 renderer resets state on init anyway, clearing the canvas should be enough
+ */
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ SDL_EGL_DeleteContext(_this, context);
+}
+
+SDL_EGL_CreateContext_impl(Emscripten)
+SDL_EGL_SwapWindow_impl(Emscripten)
+SDL_EGL_MakeCurrent_impl(Emscripten)
+
+void
+Emscripten_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
+{
+ SDL_WindowData *data;
+ if (window->driverdata) {
+ data = (SDL_WindowData *) window->driverdata;
+
+ if (w) {
+ *w = window->w * data->pixel_ratio;
+ }
+
+ if (h) {
+ *h = window->h * data->pixel_ratio;
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.h b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.h
new file mode 100644
index 0000000..fbd93cb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenopengles.h
@@ -0,0 +1,49 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_emscriptenopengles_h_
+#define SDL_emscriptenopengles_h_
+
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define Emscripten_GLES_GetAttribute SDL_EGL_GetAttribute
+#define Emscripten_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define Emscripten_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define Emscripten_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define Emscripten_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+
+extern int Emscripten_GLES_LoadLibrary(_THIS, const char *path);
+extern void Emscripten_GLES_DeleteContext(_THIS, SDL_GLContext context);
+extern SDL_GLContext Emscripten_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int Emscripten_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int Emscripten_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern void Emscripten_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h);
+
+#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_emscriptenopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.c b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.c
new file mode 100644
index 0000000..cbb933d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.c
@@ -0,0 +1,354 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_EMSCRIPTEN
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../SDL_egl_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_emscriptenvideo.h"
+#include "SDL_emscriptenopengles.h"
+#include "SDL_emscriptenframebuffer.h"
+#include "SDL_emscriptenevents.h"
+#include "SDL_emscriptenmouse.h"
+
+#define EMSCRIPTENVID_DRIVER_NAME "emscripten"
+
+/* Initialization/Query functions */
+static int Emscripten_VideoInit(_THIS);
+static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+static void Emscripten_VideoQuit(_THIS);
+
+static int Emscripten_CreateWindow(_THIS, SDL_Window * window);
+static void Emscripten_SetWindowSize(_THIS, SDL_Window * window);
+static void Emscripten_DestroyWindow(_THIS, SDL_Window * window);
+static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+static void Emscripten_PumpEvents(_THIS);
+static void Emscripten_SetWindowTitle(_THIS, SDL_Window * window);
+
+
+/* Emscripten driver bootstrap functions */
+
+static int
+Emscripten_Available(void)
+{
+ return (1);
+}
+
+static void
+Emscripten_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+Emscripten_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ return (0);
+ }
+
+ /* Firefox sends blur event which would otherwise prevent full screen
+ * when the user clicks to allow full screen.
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=1144964
+ */
+ SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
+
+ /* Set the function pointers */
+ device->VideoInit = Emscripten_VideoInit;
+ device->VideoQuit = Emscripten_VideoQuit;
+ device->SetDisplayMode = Emscripten_SetDisplayMode;
+
+
+ device->PumpEvents = Emscripten_PumpEvents;
+
+ device->CreateSDLWindow = Emscripten_CreateWindow;
+ device->SetWindowTitle = Emscripten_SetWindowTitle;
+ /*device->SetWindowIcon = Emscripten_SetWindowIcon;
+ device->SetWindowPosition = Emscripten_SetWindowPosition;*/
+ device->SetWindowSize = Emscripten_SetWindowSize;
+ /*device->ShowWindow = Emscripten_ShowWindow;
+ device->HideWindow = Emscripten_HideWindow;
+ device->RaiseWindow = Emscripten_RaiseWindow;
+ device->MaximizeWindow = Emscripten_MaximizeWindow;
+ device->MinimizeWindow = Emscripten_MinimizeWindow;
+ device->RestoreWindow = Emscripten_RestoreWindow;
+ device->SetWindowGrab = Emscripten_SetWindowGrab;*/
+ device->DestroyWindow = Emscripten_DestroyWindow;
+ device->SetWindowFullscreen = Emscripten_SetWindowFullscreen;
+
+ device->CreateWindowFramebuffer = Emscripten_CreateWindowFramebuffer;
+ device->UpdateWindowFramebuffer = Emscripten_UpdateWindowFramebuffer;
+ device->DestroyWindowFramebuffer = Emscripten_DestroyWindowFramebuffer;
+
+#if SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = Emscripten_GLES_LoadLibrary;
+ device->GL_GetProcAddress = Emscripten_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = Emscripten_GLES_UnloadLibrary;
+ device->GL_CreateContext = Emscripten_GLES_CreateContext;
+ device->GL_MakeCurrent = Emscripten_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = Emscripten_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = Emscripten_GLES_GetSwapInterval;
+ device->GL_SwapWindow = Emscripten_GLES_SwapWindow;
+ device->GL_DeleteContext = Emscripten_GLES_DeleteContext;
+ device->GL_GetDrawableSize = Emscripten_GLES_GetDrawableSize;
+#endif
+
+ device->free = Emscripten_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap Emscripten_bootstrap = {
+ EMSCRIPTENVID_DRIVER_NAME, "SDL emscripten video driver",
+ Emscripten_Available, Emscripten_CreateDevice
+};
+
+
+int
+Emscripten_VideoInit(_THIS)
+{
+ SDL_DisplayMode mode;
+
+ /* Use a fake 32-bpp desktop mode */
+ mode.format = SDL_PIXELFORMAT_RGB888;
+
+ mode.w = EM_ASM_INT_V({
+ return screen.width;
+ });
+
+ mode.h = EM_ASM_INT_V({
+ return screen.height;
+ });
+
+ mode.refresh_rate = 0;
+ mode.driverdata = NULL;
+ if (SDL_AddBasicVideoDisplay(&mode) < 0) {
+ return -1;
+ }
+
+ SDL_zero(mode);
+ SDL_AddDisplayMode(&_this->displays[0], &mode);
+
+ Emscripten_InitMouse();
+
+ /* We're done! */
+ return 0;
+}
+
+static int
+Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ /* can't do this */
+ return 0;
+}
+
+static void
+Emscripten_VideoQuit(_THIS)
+{
+ Emscripten_FiniMouse();
+}
+
+static void
+Emscripten_PumpEvents(_THIS)
+{
+ /* do nothing. */
+}
+
+static int
+Emscripten_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wdata;
+ double scaled_w, scaled_h;
+ double css_w, css_h;
+
+ /* Allocate window internal data */
+ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (wdata == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ wdata->pixel_ratio = emscripten_get_device_pixel_ratio();
+ } else {
+ wdata->pixel_ratio = 1.0f;
+ }
+
+ scaled_w = SDL_floor(window->w * wdata->pixel_ratio);
+ scaled_h = SDL_floor(window->h * wdata->pixel_ratio);
+
+ emscripten_set_canvas_size(scaled_w, scaled_h);
+
+ emscripten_get_element_css_size(NULL, &css_w, &css_h);
+
+ wdata->external_size = SDL_floor(css_w) != scaled_w || SDL_floor(css_h) != scaled_h;
+
+ if ((window->flags & SDL_WINDOW_RESIZABLE) && wdata->external_size) {
+ /* external css has resized us */
+ scaled_w = css_w * wdata->pixel_ratio;
+ scaled_h = css_h * wdata->pixel_ratio;
+
+ emscripten_set_canvas_size(scaled_w, scaled_h);
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, css_w, css_h);
+ }
+
+ /* if the size is not being controlled by css, we need to scale down for hidpi */
+ if (!wdata->external_size) {
+ if (wdata->pixel_ratio != 1.0f) {
+ /*scale canvas down*/
+ emscripten_set_element_css_size(NULL, window->w, window->h);
+ }
+ }
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ if (!_this->egl_data) {
+ if (SDL_GL_LoadLibrary(NULL) < 0) {
+ return -1;
+ }
+ }
+ wdata->egl_surface = SDL_EGL_CreateSurface(_this, 0);
+
+ if (wdata->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("Could not create GLES window surface");
+ }
+ }
+#endif
+
+ wdata->window = window;
+
+ /* Setup driver data for this window */
+ window->driverdata = wdata;
+
+ /* One window, it always has focus */
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+
+ Emscripten_RegisterEventHandlers(wdata);
+
+ /* Window has been successfully created */
+ return 0;
+}
+
+static void Emscripten_SetWindowSize(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data;
+
+ if (window->driverdata) {
+ data = (SDL_WindowData *) window->driverdata;
+ /* update pixel ratio */
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ data->pixel_ratio = emscripten_get_device_pixel_ratio();
+ }
+ emscripten_set_canvas_size(window->w * data->pixel_ratio, window->h * data->pixel_ratio);
+
+ /*scale canvas down*/
+ if (!data->external_size && data->pixel_ratio != 1.0f) {
+ emscripten_set_element_css_size(NULL, window->w, window->h);
+ }
+ }
+}
+
+static void
+Emscripten_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data;
+
+ if(window->driverdata) {
+ data = (SDL_WindowData *) window->driverdata;
+
+ Emscripten_UnregisterEventHandlers(data);
+#if SDL_VIDEO_OPENGL_EGL
+ if (data->egl_surface != EGL_NO_SURFACE) {
+ SDL_EGL_DestroySurface(_this, data->egl_surface);
+ data->egl_surface = EGL_NO_SURFACE;
+ }
+#endif
+ SDL_free(window->driverdata);
+ window->driverdata = NULL;
+ }
+}
+
+static void
+Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+ SDL_WindowData *data;
+ if(window->driverdata) {
+ data = (SDL_WindowData *) window->driverdata;
+
+ if(fullscreen) {
+ EmscriptenFullscreenStrategy strategy;
+ SDL_bool is_desktop_fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
+ int res;
+
+ strategy.scaleMode = is_desktop_fullscreen ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT;
+
+ if(!is_desktop_fullscreen) {
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE;
+ } else if(window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF;
+ } else {
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
+ }
+
+ strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
+
+ strategy.canvasResizedCallback = Emscripten_HandleCanvasResize;
+ strategy.canvasResizedCallbackUserData = data;
+
+ data->requested_fullscreen_mode = window->flags & (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN);
+ data->fullscreen_resize = is_desktop_fullscreen;
+
+ res = emscripten_request_fullscreen_strategy(NULL, 1, &strategy);
+ if(res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) {
+ /* unset flags, fullscreen failed */
+ window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN);
+ }
+ }
+ else
+ emscripten_exit_fullscreen();
+ }
+}
+
+static void
+Emscripten_SetWindowTitle(_THIS, SDL_Window * window) {
+ EM_ASM_INT({
+ if (typeof Module['setWindowTitle'] !== 'undefined') {
+ Module['setWindowTitle'](Module['Pointer_stringify']($0));
+ }
+ return 0;
+ }, window->title);
+}
+
+#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.h b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.h
new file mode 100644
index 0000000..c2001b0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/emscripten/SDL_emscriptenvideo.h
@@ -0,0 +1,58 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_emscriptenvideo_h_
+#define SDL_emscriptenvideo_h_
+
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_touch_c.h"
+#include <emscripten/emscripten.h>
+#include <emscripten/html5.h>
+
+#if SDL_VIDEO_OPENGL_EGL
+#include <EGL/egl.h>
+#endif
+
+typedef struct SDL_WindowData
+{
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+ SDL_Window *window;
+ SDL_Surface *surface;
+
+ float pixel_ratio;
+
+ SDL_bool external_size;
+
+ int requested_fullscreen_mode;
+ SDL_bool fullscreen_resize;
+
+ SDL_bool finger_touching; /* for mapping touch events to mice */
+ SDL_FingerID first_finger;
+
+ SDL_bool has_pointer_lock;
+} SDL_WindowData;
+
+#endif /* SDL_emscriptenvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_BWin.h b/source/3rd-party/SDL2/src/video/haiku/SDL_BWin.h
new file mode 100644
index 0000000..b22f74b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_BWin.h
@@ -0,0 +1,679 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BWin_h_
+#define SDL_BWin_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../SDL_internal.h"
+#include "SDL.h"
+#include "SDL_syswm.h"
+#include "SDL_bframebuffer.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <stdio.h>
+#include <AppKit.h>
+#include <InterfaceKit.h>
+#include <game/DirectWindow.h>
+#if SDL_VIDEO_OPENGL
+#include <opengl/GLView.h>
+#endif
+#include "SDL_events.h"
+#include "../../main/haiku/SDL_BApp.h"
+
+
+enum WinCommands {
+ BWIN_MOVE_WINDOW,
+ BWIN_RESIZE_WINDOW,
+ BWIN_SHOW_WINDOW,
+ BWIN_HIDE_WINDOW,
+ BWIN_MAXIMIZE_WINDOW,
+ BWIN_MINIMIZE_WINDOW,
+ BWIN_RESTORE_WINDOW,
+ BWIN_SET_TITLE,
+ BWIN_SET_BORDERED,
+ BWIN_SET_RESIZABLE,
+ BWIN_FULLSCREEN
+};
+
+
+class SDL_BWin:public BDirectWindow
+{
+ public:
+ /* Constructor/Destructor */
+ SDL_BWin(BRect bounds, window_look look, uint32 flags)
+ : BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
+ {
+ _last_buttons = 0;
+
+#if SDL_VIDEO_OPENGL
+ _SDL_GLView = NULL;
+ _gl_type = 0;
+#endif
+ _shown = false;
+ _inhibit_resize = false;
+ _mouse_focused = false;
+ _prev_frame = NULL;
+
+ /* Handle framebuffer stuff */
+ _connected = _connection_disabled = false;
+ _buffer_created = _buffer_dirty = false;
+ _trash_window_buffer = false;
+ _buffer_locker = new BLocker();
+ _bitmap = NULL;
+ _clips = NULL;
+
+#ifdef DRAWTHREAD
+ _draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread",
+ B_NORMAL_PRIORITY, (void*) this);
+ resume_thread(_draw_thread_id);
+#endif
+ }
+
+ virtual ~ SDL_BWin()
+ {
+ Lock();
+ _connection_disabled = true;
+ int32 result;
+
+#if SDL_VIDEO_OPENGL
+ if (_SDL_GLView) {
+ _SDL_GLView->UnlockGL();
+ RemoveChild(_SDL_GLView); /* Why was this outside the if
+ statement before? */
+ }
+
+#endif
+ Unlock();
+#if SDL_VIDEO_OPENGL
+ if (_SDL_GLView) {
+ delete _SDL_GLView;
+ }
+#endif
+
+ delete _prev_frame;
+
+ /* Clean up framebuffer stuff */
+ _buffer_locker->Lock();
+#ifdef DRAWTHREAD
+ wait_for_thread(_draw_thread_id, &result);
+#endif
+ free(_clips);
+ delete _buffer_locker;
+ }
+
+
+ /* * * * * OpenGL functionality * * * * */
+#if SDL_VIDEO_OPENGL
+ virtual BGLView *CreateGLView(Uint32 gl_flags) {
+ Lock();
+ if (_SDL_GLView == NULL) {
+ _SDL_GLView = new BGLView(Bounds(), "SDL GLView",
+ B_FOLLOW_ALL_SIDES,
+ (B_WILL_DRAW | B_FRAME_EVENTS),
+ gl_flags);
+ _gl_type = gl_flags;
+ }
+ AddChild(_SDL_GLView);
+ _SDL_GLView->EnableDirectMode(true);
+ _SDL_GLView->LockGL(); /* "New" GLViews are created */
+ Unlock();
+ return (_SDL_GLView);
+ }
+
+ virtual void RemoveGLView() {
+ Lock();
+ if(_SDL_GLView) {
+ _SDL_GLView->UnlockGL();
+ RemoveChild(_SDL_GLView);
+ }
+ Unlock();
+ }
+
+ virtual void SwapBuffers(void) {
+ _SDL_GLView->UnlockGL();
+ _SDL_GLView->LockGL();
+ _SDL_GLView->SwapBuffers();
+ }
+#endif
+
+ /* * * * * Framebuffering* * * * */
+ virtual void DirectConnected(direct_buffer_info *info) {
+ if(!_connected && _connection_disabled) {
+ return;
+ }
+
+ /* Determine if the pixel buffer is usable after this update */
+ _trash_window_buffer = _trash_window_buffer
+ || ((info->buffer_state & B_BUFFER_RESIZED)
+ || (info->buffer_state & B_BUFFER_RESET)
+ || (info->driver_state == B_MODE_CHANGED));
+ LockBuffer();
+
+ switch(info->buffer_state & B_DIRECT_MODE_MASK) {
+ case B_DIRECT_START:
+ _connected = true;
+
+ case B_DIRECT_MODIFY:
+ if(_clips) {
+ free(_clips);
+ _clips = NULL;
+ }
+
+ _num_clips = info->clip_list_count;
+ _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
+ if(_clips) {
+ memcpy(_clips, info->clip_list,
+ _num_clips*sizeof(clipping_rect));
+
+ _bits = (uint8*) info->bits;
+ _row_bytes = info->bytes_per_row;
+ _bounds = info->window_bounds;
+ _bytes_per_px = info->bits_per_pixel / 8;
+ _buffer_dirty = true;
+ }
+ break;
+
+ case B_DIRECT_STOP:
+ _connected = false;
+ break;
+ }
+#if SDL_VIDEO_OPENGL
+ if(_SDL_GLView) {
+ _SDL_GLView->DirectConnected(info);
+ }
+#endif
+
+
+ /* Call the base object directconnected */
+ BDirectWindow::DirectConnected(info);
+
+ UnlockBuffer();
+
+ }
+
+
+
+
+ /* * * * * Event sending * * * * */
+ /* Hook functions */
+ virtual void FrameMoved(BPoint origin) {
+ /* Post a message to the BApp so that it can handle the window event */
+ BMessage msg(BAPP_WINDOW_MOVED);
+ msg.AddInt32("window-x", (int)origin.x);
+ msg.AddInt32("window-y", (int)origin.y);
+ _PostWindowEvent(msg);
+
+ /* Perform normal hook operations */
+ BDirectWindow::FrameMoved(origin);
+ }
+
+ virtual void FrameResized(float width, float height) {
+ /* Post a message to the BApp so that it can handle the window event */
+ BMessage msg(BAPP_WINDOW_RESIZED);
+
+ msg.AddInt32("window-w", (int)width + 1);
+ msg.AddInt32("window-h", (int)height + 1);
+ _PostWindowEvent(msg);
+
+ /* Perform normal hook operations */
+ BDirectWindow::FrameResized(width, height);
+ }
+
+ virtual bool QuitRequested() {
+ BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
+ _PostWindowEvent(msg);
+
+ /* We won't allow a quit unless asked by DestroyWindow() */
+ return false;
+ }
+
+ virtual void WindowActivated(bool active) {
+ BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */
+ msg.AddBool("focusGained", active);
+ _PostWindowEvent(msg);
+ }
+
+ virtual void Zoom(BPoint origin,
+ float width,
+ float height) {
+ BMessage msg(BAPP_MAXIMIZE); /* Closest thing to maximization Haiku has */
+ _PostWindowEvent(msg);
+
+ /* Before the window zooms, record its size */
+ if( !_prev_frame )
+ _prev_frame = new BRect(Frame());
+
+ /* Perform normal hook operations */
+ BDirectWindow::Zoom(origin, width, height);
+ }
+
+ /* Member functions */
+ virtual void Show() {
+ while(IsHidden()) {
+ BDirectWindow::Show();
+ }
+ _shown = true;
+
+ BMessage msg(BAPP_SHOW);
+ _PostWindowEvent(msg);
+ }
+
+ virtual void Hide() {
+ BDirectWindow::Hide();
+ _shown = false;
+
+ BMessage msg(BAPP_HIDE);
+ _PostWindowEvent(msg);
+ }
+
+ virtual void Minimize(bool minimize) {
+ BDirectWindow::Minimize(minimize);
+ int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
+
+ BMessage msg(minState);
+ _PostWindowEvent(msg);
+ }
+
+
+ /* BView message interruption */
+ virtual void DispatchMessage(BMessage * msg, BHandler * target)
+ {
+ BPoint where; /* Used by mouse moved */
+ int32 buttons; /* Used for mouse button events */
+ int32 key; /* Used for key events */
+
+ switch (msg->what) {
+ case B_MOUSE_MOVED:
+ int32 transit;
+ if (msg->FindPoint("where", &where) == B_OK
+ && msg->FindInt32("be:transit", &transit) == B_OK) {
+ _MouseMotionEvent(where, transit);
+ }
+
+ /* FIXME: Apparently a button press/release event might be dropped
+ if made before before a different button is released. Does
+ B_MOUSE_MOVED have the data needed to check if a mouse button
+ state has changed? */
+ if (msg->FindInt32("buttons", &buttons) == B_OK) {
+ _MouseButtonEvent(buttons);
+ }
+ break;
+
+ case B_MOUSE_DOWN:
+ case B_MOUSE_UP:
+ /* _MouseButtonEvent() detects any and all buttons that may have
+ changed state, as well as that button's new state */
+ if (msg->FindInt32("buttons", &buttons) == B_OK) {
+ _MouseButtonEvent(buttons);
+ }
+ break;
+
+ case B_MOUSE_WHEEL_CHANGED:
+ float x, y;
+ if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK
+ && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
+ _MouseWheelEvent((int)x, (int)y);
+ }
+ break;
+
+ case B_KEY_DOWN:
+ {
+ int32 i = 0;
+ int8 byte;
+ int8 bytes[4] = { 0, 0, 0, 0 };
+ while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
+ bytes[i] = byte;
+ i++;
+ }
+ if (msg->FindInt32("key", &key) == B_OK) {
+ _KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED);
+ }
+ }
+ break;
+
+ case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
+ if (msg->FindInt32("key", &key) == B_OK) {
+ _KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED);
+ }
+ break;
+
+ case B_KEY_UP:
+ case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
+ if (msg->FindInt32("key", &key) == B_OK) {
+ _KeyEvent(key, NULL, 0, SDL_RELEASED);
+ }
+ break;
+
+ default:
+ /* move it after switch{} so it's always handled
+ that way we keep Haiku features like:
+ - CTRL+Q to close window (and other shortcuts)
+ - PrintScreen to make screenshot into /boot/home
+ - etc.. */
+ /* BDirectWindow::DispatchMessage(msg, target); */
+ break;
+ }
+
+ BDirectWindow::DispatchMessage(msg, target);
+ }
+
+ /* Handle command messages */
+ virtual void MessageReceived(BMessage* message) {
+ switch (message->what) {
+ /* Handle commands from SDL */
+ case BWIN_SET_TITLE:
+ _SetTitle(message);
+ break;
+ case BWIN_MOVE_WINDOW:
+ _MoveTo(message);
+ break;
+ case BWIN_RESIZE_WINDOW:
+ _ResizeTo(message);
+ break;
+ case BWIN_SET_BORDERED:
+ _SetBordered(message);
+ break;
+ case BWIN_SET_RESIZABLE:
+ _SetResizable(message);
+ break;
+ case BWIN_SHOW_WINDOW:
+ Show();
+ break;
+ case BWIN_HIDE_WINDOW:
+ Hide();
+ break;
+ case BWIN_MAXIMIZE_WINDOW:
+ BWindow::Zoom();
+ break;
+ case BWIN_MINIMIZE_WINDOW:
+ Minimize(true);
+ break;
+ case BWIN_RESTORE_WINDOW:
+ _Restore();
+ break;
+ case BWIN_FULLSCREEN:
+ _SetFullScreen(message);
+ break;
+ default:
+ /* Perform normal message handling */
+ BDirectWindow::MessageReceived(message);
+ break;
+ }
+
+ }
+
+
+
+ /* Accessor methods */
+ bool IsShown() { return _shown; }
+ int32 GetID() { return _id; }
+ uint32 GetRowBytes() { return _row_bytes; }
+ int32 GetFbX() { return _bounds.left; }
+ int32 GetFbY() { return _bounds.top; }
+ bool ConnectionEnabled() { return !_connection_disabled; }
+ bool Connected() { return _connected; }
+ clipping_rect *GetClips() { return _clips; }
+ int32 GetNumClips() { return _num_clips; }
+ uint8* GetBufferPx() { return _bits; }
+ int32 GetBytesPerPx() { return _bytes_per_px; }
+ bool CanTrashWindowBuffer() { return _trash_window_buffer; }
+ bool BufferExists() { return _buffer_created; }
+ bool BufferIsDirty() { return _buffer_dirty; }
+ BBitmap *GetBitmap() { return _bitmap; }
+#if SDL_VIDEO_OPENGL
+ BGLView *GetGLView() { return _SDL_GLView; }
+ Uint32 GetGLType() { return _gl_type; }
+#endif
+
+ /* Setter methods */
+ void SetID(int32 id) { _id = id; }
+ void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
+ void LockBuffer() { _buffer_locker->Lock(); }
+ void UnlockBuffer() { _buffer_locker->Unlock(); }
+ void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
+ void SetTrashBuffer(bool trash) { _trash_window_buffer = trash; }
+ void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; }
+
+
+private:
+ /* Event redirection */
+ void _MouseMotionEvent(BPoint &where, int32 transit) {
+ if(transit == B_EXITED_VIEW) {
+ /* Change mouse focus */
+ if(_mouse_focused) {
+ _MouseFocusEvent(false);
+ }
+ } else {
+ /* Change mouse focus */
+ if (!_mouse_focused) {
+ _MouseFocusEvent(true);
+ }
+ BMessage msg(BAPP_MOUSE_MOVED);
+ msg.AddInt32("x", (int)where.x);
+ msg.AddInt32("y", (int)where.y);
+
+ _PostWindowEvent(msg);
+ }
+ }
+
+ void _MouseFocusEvent(bool focusGained) {
+ _mouse_focused = focusGained;
+ BMessage msg(BAPP_MOUSE_FOCUS);
+ msg.AddBool("focusGained", focusGained);
+ _PostWindowEvent(msg);
+
+/* FIXME: Why were these here?
+ if false: be_app->SetCursor(B_HAND_CURSOR);
+ if true: SDL_SetCursor(NULL); */
+ }
+
+ void _MouseButtonEvent(int32 buttons) {
+ int32 buttonStateChange = buttons ^ _last_buttons;
+
+ /* Make sure at least one button has changed state */
+ if( !(buttonStateChange) ) {
+ return;
+ }
+
+ /* Add any mouse button events */
+ if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
+ _SendMouseButton(SDL_BUTTON_LEFT, buttons &
+ B_PRIMARY_MOUSE_BUTTON);
+ }
+ if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
+ _SendMouseButton(SDL_BUTTON_RIGHT, buttons &
+ B_PRIMARY_MOUSE_BUTTON);
+ }
+ if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
+ _SendMouseButton(SDL_BUTTON_MIDDLE, buttons &
+ B_PRIMARY_MOUSE_BUTTON);
+ }
+
+ _last_buttons = buttons;
+ }
+
+ void _SendMouseButton(int32 button, int32 state) {
+ BMessage msg(BAPP_MOUSE_BUTTON);
+ msg.AddInt32("button-id", button);
+ msg.AddInt32("button-state", state);
+ _PostWindowEvent(msg);
+ }
+
+ void _MouseWheelEvent(int32 x, int32 y) {
+ /* Create a message to pass along to the BeApp thread */
+ BMessage msg(BAPP_MOUSE_WHEEL);
+ msg.AddInt32("xticks", x);
+ msg.AddInt32("yticks", y);
+ _PostWindowEvent(msg);
+ }
+
+ void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t & len, int32 keyState) {
+ /* Create a message to pass along to the BeApp thread */
+ BMessage msg(BAPP_KEY);
+ msg.AddInt32("key-state", keyState);
+ msg.AddInt32("key-scancode", keyCode);
+ if (keyUtf8 != NULL) {
+ msg.AddData("key-utf8", B_INT8_TYPE, (const void*)keyUtf8, len);
+ }
+ be_app->PostMessage(&msg);
+ }
+
+ void _RepaintEvent() {
+ /* Force a repaint: Call the SDL exposed event */
+ BMessage msg(BAPP_REPAINT);
+ _PostWindowEvent(msg);
+ }
+ void _PostWindowEvent(BMessage &msg) {
+ msg.AddInt32("window-id", _id);
+ be_app->PostMessage(&msg);
+ }
+
+ /* Command methods (functions called upon by SDL) */
+ void _SetTitle(BMessage *msg) {
+ const char *title;
+ if(
+ msg->FindString("window-title", &title) != B_OK
+ ) {
+ return;
+ }
+ SetTitle(title);
+ }
+
+ void _MoveTo(BMessage *msg) {
+ int32 x, y;
+ if(
+ msg->FindInt32("window-x", &x) != B_OK ||
+ msg->FindInt32("window-y", &y) != B_OK
+ ) {
+ return;
+ }
+ MoveTo(x, y);
+ }
+
+ void _ResizeTo(BMessage *msg) {
+ int32 w, h;
+ if(
+ msg->FindInt32("window-w", &w) != B_OK ||
+ msg->FindInt32("window-h", &h) != B_OK
+ ) {
+ return;
+ }
+ ResizeTo(w, h);
+ }
+
+ void _SetBordered(BMessage *msg) {
+ bool bEnabled;
+ if(msg->FindBool("window-border", &bEnabled) != B_OK) {
+ return;
+ }
+ SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
+ }
+
+ void _SetResizable(BMessage *msg) {
+ bool bEnabled;
+ if(msg->FindBool("window-resizable", &bEnabled) != B_OK) {
+ return;
+ }
+ if (bEnabled) {
+ SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
+ } else {
+ SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
+ }
+ }
+
+ void _Restore() {
+ if(IsMinimized()) {
+ Minimize(false);
+ } else if(IsHidden()) {
+ Show();
+ } else if(_prev_frame != NULL) { /* Zoomed */
+ MoveTo(_prev_frame->left, _prev_frame->top);
+ ResizeTo(_prev_frame->Width(), _prev_frame->Height());
+ }
+ }
+
+ void _SetFullScreen(BMessage *msg) {
+ bool fullscreen;
+ if(
+ msg->FindBool("fullscreen", &fullscreen) != B_OK
+ ) {
+ return;
+ }
+ SetFullScreen(fullscreen);
+ }
+
+ /* Members */
+#if SDL_VIDEO_OPENGL
+ BGLView * _SDL_GLView;
+ Uint32 _gl_type;
+#endif
+
+ int32 _last_buttons;
+ int32 _id; /* Window id used by SDL_BApp */
+ bool _mouse_focused; /* Does this window have mouse focus? */
+ bool _shown;
+ bool _inhibit_resize;
+
+ BRect *_prev_frame; /* Previous position and size of the window */
+
+ /* Framebuffer members */
+ bool _connected,
+ _connection_disabled,
+ _buffer_created,
+ _buffer_dirty,
+ _trash_window_buffer;
+ uint8 *_bits;
+ uint32 _row_bytes;
+ clipping_rect _bounds;
+ BLocker *_buffer_locker;
+ clipping_rect *_clips;
+ int32 _num_clips;
+ int32 _bytes_per_px;
+ thread_id _draw_thread_id;
+
+ BBitmap *_bitmap;
+};
+
+
+/* FIXME:
+ * An explanation of framebuffer flags.
+ *
+ * _connected - Original variable used to let the drawing thread know
+ * when changes are being made to the other framebuffer
+ * members.
+ * _connection_disabled - Used to signal to the drawing thread that the window
+ * is closing, and the thread should exit.
+ * _buffer_created - True if the current buffer is valid
+ * _buffer_dirty - True if the window should be redrawn.
+ * _trash_window_buffer - True if the window buffer needs to be trashed partway
+ * through a draw cycle. Occurs when the previous
+ * buffer provided by DirectConnected() is invalidated.
+ */
+#endif /* SDL_BWin_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.cc
new file mode 100644
index 0000000..3138603
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.cc
@@ -0,0 +1,95 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+/* BWindow based clipboard implementation */
+
+#include <unistd.h>
+#include <TypeConstants.h>
+
+#include "SDL_BWin.h"
+#include "SDL_timer.h"
+#include "../SDL_sysvideo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int HAIKU_SetClipboardText(_THIS, const char *text) {
+ BMessage *clip = NULL;
+ if(be_clipboard->Lock()) {
+ be_clipboard->Clear();
+ if((clip = be_clipboard->Data())) {
+ /* Presumably the string of characters is ascii-format */
+ ssize_t asciiLength = 0;
+ for(; text[asciiLength] != 0; ++asciiLength) {}
+ clip->AddData("text/plain", B_MIME_TYPE, text, asciiLength);
+ be_clipboard->Commit();
+ }
+ be_clipboard->Unlock();
+ }
+ return 0;
+}
+
+char *HAIKU_GetClipboardText(_THIS) {
+ BMessage *clip = NULL;
+ const char *text = NULL;
+ ssize_t length;
+ char *result;
+ if(be_clipboard->Lock()) {
+ if((clip = be_clipboard->Data())) {
+ /* Presumably the string of characters is ascii-format */
+ clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text,
+ &length);
+ }
+ be_clipboard->Unlock();
+ }
+
+ if (!text) {
+ result = SDL_strdup("");
+ } else {
+ /* Copy the data and pass on to SDL */
+ result = (char *)SDL_malloc((length + 1) * sizeof(char));
+ SDL_strlcpy(result, text, length + 1);
+ }
+
+ return result;
+}
+
+SDL_bool HAIKU_HasClipboardText(_THIS) {
+ SDL_bool result = SDL_FALSE;
+ char *text = HAIKU_GetClipboardText(_this);
+ if (text) {
+ result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
+ SDL_free(text);
+ }
+ return result;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.h
new file mode 100644
index 0000000..de69ed3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bclipboard.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_BCLIPBOARD_H
+#define SDL_BCLIPBOARD_H
+
+extern int HAIKU_SetClipboardText(_THIS, const char *text);
+extern char *HAIKU_GetClipboardText(_THIS);
+extern SDL_bool HAIKU_HasClipboardText(_THIS);
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bevents.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bevents.cc
new file mode 100644
index 0000000..c918ab2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bevents.cc
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+#include "SDL_bevents.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAIKU_PumpEvents(_THIS) {
+ /* Since the event thread is its own thread, this isn't really necessary */
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bevents.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bevents.h
new file mode 100644
index 0000000..5c34fcf
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bevents.h
@@ -0,0 +1,39 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BEVENTS_H
+#define SDL_BEVENTS_H
+
+#include "../SDL_sysvideo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void HAIKU_PumpEvents(_THIS);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.cc
new file mode 100644
index 0000000..9675706
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.cc
@@ -0,0 +1,259 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+#include "SDL_bframebuffer.h"
+
+#include <AppKit.h>
+#include <InterfaceKit.h>
+#include "SDL_bmodes.h"
+#include "SDL_BWin.h"
+
+#include "../../main/haiku/SDL_BApp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DRAWTHREAD
+static int32 HAIKU_UpdateOnce(SDL_Window *window);
+#endif
+
+static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
+ return ((SDL_BWin*)(window->driverdata));
+}
+
+static SDL_INLINE SDL_BApp *_GetBeApp() {
+ return ((SDL_BApp*)be_app);
+}
+
+int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window,
+ Uint32 * format,
+ void ** pixels, int *pitch) {
+ SDL_BWin *bwin = _ToBeWin(window);
+ BScreen bscreen;
+ if(!bscreen.IsValid()) {
+ return -1;
+ }
+
+ while(!bwin->Connected()) { snooze(100); }
+
+ /* Make sure we have exclusive access to frame buffer data */
+ bwin->LockBuffer();
+
+ /* format */
+ display_mode bmode;
+ bscreen.GetMode(&bmode);
+ int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode.space);
+ *format = HAIKU_BPPToSDLPxFormat(bpp);
+
+ /* Create the new bitmap object */
+ BBitmap *bitmap = bwin->GetBitmap();
+
+ if(bitmap) {
+ delete bitmap;
+ }
+ bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
+ false, /* Views not accepted */
+ true); /* Contiguous memory required */
+
+ if(bitmap->InitCheck() != B_OK) {
+ delete bitmap;
+ return SDL_SetError("Could not initialize back buffer!");
+ }
+
+
+ bwin->SetBitmap(bitmap);
+
+ /* Set the pixel pointer */
+ *pixels = bitmap->Bits();
+
+ /* pitch = width of window, in bytes */
+ *pitch = bitmap->BytesPerRow();
+
+ bwin->SetBufferExists(true);
+ bwin->SetTrashBuffer(false);
+ bwin->UnlockBuffer();
+ return 0;
+}
+
+
+
+int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
+ const SDL_Rect * rects, int numrects) {
+ if(!window)
+ return 0;
+
+ SDL_BWin *bwin = _ToBeWin(window);
+
+#ifdef DRAWTHREAD
+ bwin->LockBuffer();
+ bwin->SetBufferDirty(true);
+ bwin->UnlockBuffer();
+#else
+ bwin->SetBufferDirty(true);
+ HAIKU_UpdateOnce(window);
+#endif
+
+ return 0;
+}
+
+int32 HAIKU_DrawThread(void *data) {
+ SDL_BWin *bwin = (SDL_BWin*)data;
+
+ BScreen bscreen;
+ if(!bscreen.IsValid()) {
+ return -1;
+ }
+
+ while(bwin->ConnectionEnabled()) {
+ if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
+ bwin->LockBuffer();
+ BBitmap *bitmap = NULL;
+ bitmap = bwin->GetBitmap();
+ int32 windowPitch = bitmap->BytesPerRow();
+ int32 bufferPitch = bwin->GetRowBytes();
+ uint8 *windowpx;
+ uint8 *bufferpx;
+
+ int32 BPP = bwin->GetBytesPerPx();
+ int32 windowSub = bwin->GetFbX() * BPP +
+ bwin->GetFbY() * windowPitch;
+ clipping_rect *clips = bwin->GetClips();
+ int32 numClips = bwin->GetNumClips();
+ int i, y;
+
+ /* Blit each clipping rectangle */
+ bscreen.WaitForRetrace();
+ for(i = 0; i < numClips; ++i) {
+ /* Get addresses of the start of each clipping rectangle */
+ int32 width = clips[i].right - clips[i].left + 1;
+ int32 height = clips[i].bottom - clips[i].top + 1;
+ bufferpx = bwin->GetBufferPx() +
+ clips[i].top * bufferPitch + clips[i].left * BPP;
+ windowpx = (uint8*)bitmap->Bits() +
+ clips[i].top * windowPitch + clips[i].left * BPP -
+ windowSub;
+
+ /* Copy each row of pixels from the window buffer into the frame
+ buffer */
+ for(y = 0; y < height; ++y)
+ {
+
+ if(bwin->CanTrashWindowBuffer()) {
+ goto escape; /* Break out before the buffer is killed */
+ }
+
+ memcpy(bufferpx, windowpx, width * BPP);
+ bufferpx += bufferPitch;
+ windowpx += windowPitch;
+ }
+ }
+
+ bwin->SetBufferDirty(false);
+escape:
+ bwin->UnlockBuffer();
+ } else {
+ snooze(16000);
+ }
+ }
+
+ return B_OK;
+}
+
+void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
+ SDL_BWin *bwin = _ToBeWin(window);
+
+ bwin->LockBuffer();
+
+ /* Free and clear the window buffer */
+ BBitmap *bitmap = bwin->GetBitmap();
+ delete bitmap;
+ bwin->SetBitmap(NULL);
+ bwin->SetBufferExists(false);
+ bwin->UnlockBuffer();
+}
+
+
+/*
+ * TODO:
+ * This was written to test if certain errors were caused by threading issues.
+ * The specific issues have since become rare enough that they may have been
+ * solved, but I doubt it- they were pretty sporadic before now.
+ */
+#ifndef DRAWTHREAD
+static int32 HAIKU_UpdateOnce(SDL_Window *window) {
+ SDL_BWin *bwin = _ToBeWin(window);
+ BScreen bscreen;
+ if(!bscreen.IsValid()) {
+ return -1;
+ }
+
+ if(bwin->ConnectionEnabled() && bwin->Connected()) {
+ bwin->LockBuffer();
+ int32 windowPitch = window->surface->pitch;
+ int32 bufferPitch = bwin->GetRowBytes();
+ uint8 *windowpx;
+ uint8 *bufferpx;
+
+ int32 BPP = bwin->GetBytesPerPx();
+ uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
+ int32 windowSub = bwin->GetFbX() * BPP +
+ bwin->GetFbY() * windowPitch;
+ clipping_rect *clips = bwin->GetClips();
+ int32 numClips = bwin->GetNumClips();
+ int i, y;
+
+ /* Blit each clipping rectangle */
+ bscreen.WaitForRetrace();
+ for(i = 0; i < numClips; ++i) {
+ /* Get addresses of the start of each clipping rectangle */
+ int32 width = clips[i].right - clips[i].left + 1;
+ int32 height = clips[i].bottom - clips[i].top + 1;
+ bufferpx = bwin->GetBufferPx() +
+ clips[i].top * bufferPitch + clips[i].left * BPP;
+ windowpx = windowBaseAddress +
+ clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
+
+ /* Copy each row of pixels from the window buffer into the frame
+ buffer */
+ for(y = 0; y < height; ++y)
+ {
+ memcpy(bufferpx, windowpx, width * BPP);
+ bufferpx += bufferPitch;
+ windowpx += windowPitch;
+ }
+ }
+ bwin->UnlockBuffer();
+ }
+ return 0;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.h
new file mode 100644
index 0000000..e48156d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bframebuffer.h
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BFRAMEBUFFER_H
+#define SDL_BFRAMEBUFFER_H
+#include <SupportDefs.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DRAWTHREAD
+
+#include "../SDL_sysvideo.h"
+
+extern int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window,
+ Uint32 * format,
+ void ** pixels, int *pitch);
+extern int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
+ const SDL_Rect * rects, int numrects);
+extern void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+extern int32 HAIKU_DrawThread(void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.cc
new file mode 100644
index 0000000..9a8b9a4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.cc
@@ -0,0 +1,190 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+#include <SupportDefs.h>
+#include <support/UTF8.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "SDL_events.h"
+#include "SDL_keycode.h"
+
+#include "SDL_bkeyboard.h"
+
+
+#define KEYMAP_SIZE 128
+
+
+static SDL_Scancode keymap[KEYMAP_SIZE];
+static int8 keystate[KEYMAP_SIZE];
+
+void HAIKU_InitOSKeymap(void) {
+ for( uint i = 0; i < SDL_TABLESIZE(keymap); ++i ) {
+ keymap[i] = SDL_SCANCODE_UNKNOWN;
+ }
+
+ for( uint i = 0; i < KEYMAP_SIZE; ++i ) {
+ keystate[i] = SDL_RELEASED;
+ }
+
+ keymap[0x01] = SDL_GetScancodeFromKey(SDLK_ESCAPE);
+ keymap[B_F1_KEY] = SDL_GetScancodeFromKey(SDLK_F1);
+ keymap[B_F2_KEY] = SDL_GetScancodeFromKey(SDLK_F2);
+ keymap[B_F3_KEY] = SDL_GetScancodeFromKey(SDLK_F3);
+ keymap[B_F4_KEY] = SDL_GetScancodeFromKey(SDLK_F4);
+ keymap[B_F5_KEY] = SDL_GetScancodeFromKey(SDLK_F5);
+ keymap[B_F6_KEY] = SDL_GetScancodeFromKey(SDLK_F6);
+ keymap[B_F7_KEY] = SDL_GetScancodeFromKey(SDLK_F7);
+ keymap[B_F8_KEY] = SDL_GetScancodeFromKey(SDLK_F8);
+ keymap[B_F9_KEY] = SDL_GetScancodeFromKey(SDLK_F9);
+ keymap[B_F10_KEY] = SDL_GetScancodeFromKey(SDLK_F10);
+ keymap[B_F11_KEY] = SDL_GetScancodeFromKey(SDLK_F11);
+ keymap[B_F12_KEY] = SDL_GetScancodeFromKey(SDLK_F12);
+ keymap[B_PRINT_KEY] = SDL_GetScancodeFromKey(SDLK_PRINTSCREEN);
+ keymap[B_SCROLL_KEY] = SDL_GetScancodeFromKey(SDLK_SCROLLLOCK);
+ keymap[B_PAUSE_KEY] = SDL_GetScancodeFromKey(SDLK_PAUSE);
+ keymap[0x11] = SDL_GetScancodeFromKey(SDLK_BACKQUOTE);
+ keymap[0x12] = SDL_GetScancodeFromKey(SDLK_1);
+ keymap[0x13] = SDL_GetScancodeFromKey(SDLK_2);
+ keymap[0x14] = SDL_GetScancodeFromKey(SDLK_3);
+ keymap[0x15] = SDL_GetScancodeFromKey(SDLK_4);
+ keymap[0x16] = SDL_GetScancodeFromKey(SDLK_5);
+ keymap[0x17] = SDL_GetScancodeFromKey(SDLK_6);
+ keymap[0x18] = SDL_GetScancodeFromKey(SDLK_7);
+ keymap[0x19] = SDL_GetScancodeFromKey(SDLK_8);
+ keymap[0x1a] = SDL_GetScancodeFromKey(SDLK_9);
+ keymap[0x1b] = SDL_GetScancodeFromKey(SDLK_0);
+ keymap[0x1c] = SDL_GetScancodeFromKey(SDLK_MINUS);
+ keymap[0x1d] = SDL_GetScancodeFromKey(SDLK_EQUALS);
+ keymap[0x1e] = SDL_GetScancodeFromKey(SDLK_BACKSPACE);
+ keymap[0x1f] = SDL_GetScancodeFromKey(SDLK_INSERT);
+ keymap[0x20] = SDL_GetScancodeFromKey(SDLK_HOME);
+ keymap[0x21] = SDL_GetScancodeFromKey(SDLK_PAGEUP);
+ keymap[0x22] = SDL_GetScancodeFromKey(SDLK_NUMLOCKCLEAR);
+ keymap[0x23] = SDL_GetScancodeFromKey(SDLK_KP_DIVIDE);
+ keymap[0x24] = SDL_GetScancodeFromKey(SDLK_KP_MULTIPLY);
+ keymap[0x25] = SDL_GetScancodeFromKey(SDLK_KP_MINUS);
+ keymap[0x26] = SDL_GetScancodeFromKey(SDLK_TAB);
+ keymap[0x27] = SDL_GetScancodeFromKey(SDLK_q);
+ keymap[0x28] = SDL_GetScancodeFromKey(SDLK_w);
+ keymap[0x29] = SDL_GetScancodeFromKey(SDLK_e);
+ keymap[0x2a] = SDL_GetScancodeFromKey(SDLK_r);
+ keymap[0x2b] = SDL_GetScancodeFromKey(SDLK_t);
+ keymap[0x2c] = SDL_GetScancodeFromKey(SDLK_y);
+ keymap[0x2d] = SDL_GetScancodeFromKey(SDLK_u);
+ keymap[0x2e] = SDL_GetScancodeFromKey(SDLK_i);
+ keymap[0x2f] = SDL_GetScancodeFromKey(SDLK_o);
+ keymap[0x30] = SDL_GetScancodeFromKey(SDLK_p);
+ keymap[0x31] = SDL_GetScancodeFromKey(SDLK_LEFTBRACKET);
+ keymap[0x32] = SDL_GetScancodeFromKey(SDLK_RIGHTBRACKET);
+ keymap[0x33] = SDL_GetScancodeFromKey(SDLK_BACKSLASH);
+ keymap[0x34] = SDL_GetScancodeFromKey(SDLK_DELETE);
+ keymap[0x35] = SDL_GetScancodeFromKey(SDLK_END);
+ keymap[0x36] = SDL_GetScancodeFromKey(SDLK_PAGEDOWN);
+ keymap[0x37] = SDL_GetScancodeFromKey(SDLK_KP_7);
+ keymap[0x38] = SDL_GetScancodeFromKey(SDLK_KP_8);
+ keymap[0x39] = SDL_GetScancodeFromKey(SDLK_KP_9);
+ keymap[0x3a] = SDL_GetScancodeFromKey(SDLK_KP_PLUS);
+ keymap[0x3b] = SDL_GetScancodeFromKey(SDLK_CAPSLOCK);
+ keymap[0x3c] = SDL_GetScancodeFromKey(SDLK_a);
+ keymap[0x3d] = SDL_GetScancodeFromKey(SDLK_s);
+ keymap[0x3e] = SDL_GetScancodeFromKey(SDLK_d);
+ keymap[0x3f] = SDL_GetScancodeFromKey(SDLK_f);
+ keymap[0x40] = SDL_GetScancodeFromKey(SDLK_g);
+ keymap[0x41] = SDL_GetScancodeFromKey(SDLK_h);
+ keymap[0x42] = SDL_GetScancodeFromKey(SDLK_j);
+ keymap[0x43] = SDL_GetScancodeFromKey(SDLK_k);
+ keymap[0x44] = SDL_GetScancodeFromKey(SDLK_l);
+ keymap[0x45] = SDL_GetScancodeFromKey(SDLK_SEMICOLON);
+ keymap[0x46] = SDL_GetScancodeFromKey(SDLK_QUOTE);
+ keymap[0x47] = SDL_GetScancodeFromKey(SDLK_RETURN);
+ keymap[0x48] = SDL_GetScancodeFromKey(SDLK_KP_4);
+ keymap[0x49] = SDL_GetScancodeFromKey(SDLK_KP_5);
+ keymap[0x4a] = SDL_GetScancodeFromKey(SDLK_KP_6);
+ keymap[0x4b] = SDL_GetScancodeFromKey(SDLK_LSHIFT);
+ keymap[0x4c] = SDL_GetScancodeFromKey(SDLK_z);
+ keymap[0x4d] = SDL_GetScancodeFromKey(SDLK_x);
+ keymap[0x4e] = SDL_GetScancodeFromKey(SDLK_c);
+ keymap[0x4f] = SDL_GetScancodeFromKey(SDLK_v);
+ keymap[0x50] = SDL_GetScancodeFromKey(SDLK_b);
+ keymap[0x51] = SDL_GetScancodeFromKey(SDLK_n);
+ keymap[0x52] = SDL_GetScancodeFromKey(SDLK_m);
+ keymap[0x53] = SDL_GetScancodeFromKey(SDLK_COMMA);
+ keymap[0x54] = SDL_GetScancodeFromKey(SDLK_PERIOD);
+ keymap[0x55] = SDL_GetScancodeFromKey(SDLK_SLASH);
+ keymap[0x56] = SDL_GetScancodeFromKey(SDLK_RSHIFT);
+ keymap[0x57] = SDL_GetScancodeFromKey(SDLK_UP);
+ keymap[0x58] = SDL_GetScancodeFromKey(SDLK_KP_1);
+ keymap[0x59] = SDL_GetScancodeFromKey(SDLK_KP_2);
+ keymap[0x5a] = SDL_GetScancodeFromKey(SDLK_KP_3);
+ keymap[0x5b] = SDL_GetScancodeFromKey(SDLK_KP_ENTER);
+ keymap[0x5c] = SDL_GetScancodeFromKey(SDLK_LCTRL);
+ keymap[0x5d] = SDL_GetScancodeFromKey(SDLK_LALT);
+ keymap[0x5e] = SDL_GetScancodeFromKey(SDLK_SPACE);
+ keymap[0x5f] = SDL_GetScancodeFromKey(SDLK_RALT);
+ keymap[0x60] = SDL_GetScancodeFromKey(SDLK_RCTRL);
+ keymap[0x61] = SDL_GetScancodeFromKey(SDLK_LEFT);
+ keymap[0x62] = SDL_GetScancodeFromKey(SDLK_DOWN);
+ keymap[0x63] = SDL_GetScancodeFromKey(SDLK_RIGHT);
+ keymap[0x64] = SDL_GetScancodeFromKey(SDLK_KP_0);
+ keymap[0x65] = SDL_GetScancodeFromKey(SDLK_KP_PERIOD);
+ keymap[0x66] = SDL_GetScancodeFromKey(SDLK_LGUI);
+ keymap[0x67] = SDL_GetScancodeFromKey(SDLK_RGUI);
+ keymap[0x68] = SDL_GetScancodeFromKey(SDLK_MENU);
+ keymap[0x69] = SDL_GetScancodeFromKey(SDLK_2); /* SDLK_EURO */
+ keymap[0x6a] = SDL_GetScancodeFromKey(SDLK_KP_EQUALS);
+ keymap[0x6b] = SDL_GetScancodeFromKey(SDLK_POWER);
+}
+
+SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) {
+ if(bkey > 0 && bkey < (int32)SDL_TABLESIZE(keymap)) {
+ return keymap[bkey];
+ } else {
+ return SDL_SCANCODE_UNKNOWN;
+ }
+}
+
+int8 HAIKU_GetKeyState(int32 bkey) {
+ if(bkey > 0 && bkey < KEYMAP_SIZE) {
+ return keystate[bkey];
+ } else {
+ return SDL_RELEASED;
+ }
+}
+
+void HAIKU_SetKeyState(int32 bkey, int8 state) {
+ if(bkey > 0 && bkey < KEYMAP_SIZE) {
+ keystate[bkey] = state;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.h
new file mode 100644
index 0000000..0184828
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bkeyboard.h
@@ -0,0 +1,44 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BKEYBOARD_H
+#define SDL_BKEYBOARD_H
+
+#include <SupportDefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../../include/SDL_keyboard.h"
+
+extern void HAIKU_InitOSKeymap(void);
+extern SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey);
+extern int8 HAIKU_GetKeyState(int32 bkey);
+extern void HAIKU_SetKeyState(int32 bkey, int8 state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.cc
new file mode 100644
index 0000000..9d71996
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.cc
@@ -0,0 +1,333 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+#include <AppKit.h>
+#include <InterfaceKit.h>
+#include "SDL_bmodes.h"
+#include "SDL_BWin.h"
+
+#if SDL_VIDEO_OPENGL
+#include "SDL_bopengl.h"
+#endif
+
+#include "../../main/haiku/SDL_BApp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define WRAP_BMODE 1 /* FIXME: Some debate as to whether this is necessary */
+
+#if WRAP_BMODE
+/* This wrapper is here so that the driverdata can be freed without freeing
+ the display_mode structure */
+struct SDL_DisplayModeData {
+ display_mode *bmode;
+};
+#endif
+
+static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
+ return ((SDL_BWin*)(window->driverdata));
+}
+
+static SDL_INLINE SDL_BApp *_GetBeApp() {
+ return ((SDL_BApp*)be_app);
+}
+
+static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {
+#if WRAP_BMODE
+ return ((SDL_DisplayModeData*)mode->driverdata)->bmode;
+#else
+ return (display_mode*)(mode->driverdata);
+#endif
+}
+
+/* Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp */
+static float get_refresh_rate(display_mode &mode) {
+ return float(mode.timing.pixel_clock * 1000)
+ / float(mode.timing.h_total * mode.timing.v_total);
+}
+
+
+#if 0
+/* TODO:
+ * This is a useful debugging tool. Uncomment and insert into code as needed.
+ */
+void _SpoutModeData(display_mode *bmode) {
+ printf("BMode:\n");
+ printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height);
+ printf("\th,v = (%i,%i)\n", bmode->h_display_start,
+ bmode->v_display_start);
+ if(bmode->flags) {
+ printf("\tFlags:\n");
+ if(bmode->flags & B_SCROLL) {
+ printf("\t\tB_SCROLL\n");
+ }
+ if(bmode->flags & B_8_BIT_DAC) {
+ printf("\t\tB_8_BIT_DAC\n");
+ }
+ if(bmode->flags & B_HARDWARE_CURSOR) {
+ printf("\t\tB_HARDWARE_CURSOR\n");
+ }
+ if(bmode->flags & B_PARALLEL_ACCESS) {
+ printf("\t\tB_PARALLEL_ACCESS\n");
+ }
+ if(bmode->flags & B_DPMS) {
+ printf("\t\tB_DPMS\n");
+ }
+ if(bmode->flags & B_IO_FB_NA) {
+ printf("\t\tB_IO_FB_NA\n");
+ }
+ }
+ printf("\tTiming:\n");
+ printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock);
+ printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n",
+ bmode->timing.h_display, bmode->timing.h_sync_start,
+ bmode->timing.h_sync_end, bmode->timing.h_total);
+ printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n",
+ bmode->timing.v_display, bmode->timing.v_sync_start,
+ bmode->timing.v_sync_end, bmode->timing.v_total);
+ if(bmode->timing.flags) {
+ printf("\t\tFlags:\n");
+ if(bmode->timing.flags & B_BLANK_PEDESTAL) {
+ printf("\t\t\tB_BLANK_PEDESTAL\n");
+ }
+ if(bmode->timing.flags & B_TIMING_INTERLACED) {
+ printf("\t\t\tB_TIMING_INTERLACED\n");
+ }
+ if(bmode->timing.flags & B_POSITIVE_HSYNC) {
+ printf("\t\t\tB_POSITIVE_HSYNC\n");
+ }
+ if(bmode->timing.flags & B_POSITIVE_VSYNC) {
+ printf("\t\t\tB_POSITIVE_VSYNC\n");
+ }
+ if(bmode->timing.flags & B_SYNC_ON_GREEN) {
+ printf("\t\t\tB_SYNC_ON_GREEN\n");
+ }
+ }
+}
+#endif
+
+
+
+int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace)
+{
+ int bitsperpixel;
+
+ bitsperpixel = 0;
+ switch (colorspace) {
+ case B_CMAP8:
+ bitsperpixel = 8;
+ break;
+ case B_RGB15:
+ case B_RGBA15:
+ case B_RGB15_BIG:
+ case B_RGBA15_BIG:
+ bitsperpixel = 15;
+ break;
+ case B_RGB16:
+ case B_RGB16_BIG:
+ bitsperpixel = 16;
+ break;
+ case B_RGB32:
+ case B_RGBA32:
+ case B_RGB32_BIG:
+ case B_RGBA32_BIG:
+ bitsperpixel = 32;
+ break;
+ default:
+ break;
+ }
+ return(bitsperpixel);
+}
+
+int32 HAIKU_BPPToSDLPxFormat(int32 bpp) {
+ /* Translation taken from SDL_windowsmodes.c */
+ switch (bpp) {
+ case 32:
+ return SDL_PIXELFORMAT_RGB888;
+ break;
+ case 24: /* May not be supported by Haiku */
+ return SDL_PIXELFORMAT_RGB24;
+ break;
+ case 16:
+ return SDL_PIXELFORMAT_RGB565;
+ break;
+ case 15:
+ return SDL_PIXELFORMAT_RGB555;
+ break;
+ case 8:
+ return SDL_PIXELFORMAT_INDEX8;
+ break;
+ case 4: /* May not be supported by Haiku */
+ return SDL_PIXELFORMAT_INDEX4LSB;
+ break;
+ }
+
+ /* May never get here, but safer and needed to shut up compiler */
+ SDL_SetError("Invalid bpp value");
+ return 0;
+}
+
+static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
+ SDL_DisplayMode *mode) {
+ mode->w = bmode->virtual_width;
+ mode->h = bmode->virtual_height;
+ mode->refresh_rate = (int)get_refresh_rate(*bmode);
+
+#if WRAP_BMODE
+ SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1,
+ sizeof(SDL_DisplayModeData));
+ data->bmode = bmode;
+
+ mode->driverdata = data;
+
+#else
+
+ mode->driverdata = bmode;
+#endif
+
+ /* Set the format */
+ int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode->space);
+ mode->format = HAIKU_BPPToSDLPxFormat(bpp);
+}
+
+/* Later, there may be more than one monitor available */
+static void _AddDisplay(BScreen *screen) {
+ SDL_VideoDisplay display;
+ SDL_DisplayMode *mode = (SDL_DisplayMode*)SDL_calloc(1,
+ sizeof(SDL_DisplayMode));
+ display_mode *bmode = (display_mode*)SDL_calloc(1, sizeof(display_mode));
+ screen->GetMode(bmode);
+
+ _BDisplayModeToSdlDisplayMode(bmode, mode);
+
+ SDL_zero(display);
+ display.desktop_mode = *mode;
+ display.current_mode = *mode;
+
+ SDL_AddVideoDisplay(&display);
+}
+
+/*
+ * Functions called by SDL
+ */
+
+int HAIKU_InitModes(_THIS) {
+ BScreen screen;
+
+ /* TODO: When Haiku supports multiple display screens, call
+ _AddDisplayScreen() for each of them. */
+ _AddDisplay(&screen);
+ return 0;
+}
+
+int HAIKU_QuitModes(_THIS) {
+ /* FIXME: Nothing really needs to be done here at the moment? */
+ return 0;
+}
+
+
+int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) {
+ BScreen bscreen;
+ BRect rc = bscreen.Frame();
+ rect->x = (int)rc.left;
+ rect->y = (int)rc.top;
+ rect->w = (int)rc.Width() + 1;
+ rect->h = (int)rc.Height() + 1;
+ return 0;
+}
+
+void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) {
+ /* Get the current screen */
+ BScreen bscreen;
+
+ /* Iterate through all of the modes */
+ SDL_DisplayMode mode;
+ display_mode this_bmode;
+ display_mode *bmodes;
+ uint32 count, i;
+
+ /* Get graphics-hardware supported modes */
+ bscreen.GetModeList(&bmodes, &count);
+ bscreen.GetMode(&this_bmode);
+
+ for(i = 0; i < count; ++i) {
+ // FIXME: Apparently there are errors with colorspace changes
+ if (bmodes[i].space == this_bmode.space) {
+ _BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
+ SDL_AddDisplayMode(display, &mode);
+ }
+ }
+ free(bmodes);
+}
+
+
+int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){
+ /* Get the current screen */
+ BScreen bscreen;
+ if(!bscreen.IsValid()) {
+ printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
+ }
+
+ /* Set the mode using the driver data */
+ display_mode *bmode = _ExtractBMode(mode);
+
+
+ /* FIXME: Is the first option always going to be the right one? */
+ uint32 c = 0, i;
+ display_mode *bmode_list;
+ bscreen.GetModeList(&bmode_list, &c);
+ for(i = 0; i < c; ++i) {
+ if( bmode_list[i].space == bmode->space &&
+ bmode_list[i].virtual_width == bmode->virtual_width &&
+ bmode_list[i].virtual_height == bmode->virtual_height ) {
+ bmode = &bmode_list[i];
+ break;
+ }
+ }
+
+ if(bscreen.SetMode(bmode) != B_OK) {
+ return SDL_SetError("Bad video mode");
+ }
+
+ free(bmode_list);
+
+#if SDL_VIDEO_OPENGL
+ /* FIXME: Is there some way to reboot the OpenGL context? This doesn't
+ help */
+// HAIKU_GL_RebootContexts(_this);
+#endif
+
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.h
new file mode 100644
index 0000000..3abc1dc
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bmodes.h
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BMODES_H
+#define SDL_BMODES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../SDL_sysvideo.h"
+
+extern int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace);
+extern int32 HAIKU_BPPToSDLPxFormat(int32 bpp);
+
+extern int HAIKU_InitModes(_THIS);
+extern int HAIKU_QuitModes(_THIS);
+extern int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display,
+ SDL_Rect *rect);
+extern void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display);
+extern int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
+ SDL_DisplayMode *mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.cc
new file mode 100644
index 0000000..e599062
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.cc
@@ -0,0 +1,176 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL
+
+#include "SDL_bopengl.h"
+
+#include <unistd.h>
+#include <KernelKit.h>
+#include <OpenGLKit.h>
+#include "SDL_BWin.h"
+#include "../../main/haiku/SDL_BApp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
+ return ((SDL_BWin*)(window->driverdata));
+}
+
+static SDL_INLINE SDL_BApp *_GetBeApp() {
+ return ((SDL_BApp*)be_app);
+}
+
+/* Passing a NULL path means load pointers from the application */
+int HAIKU_GL_LoadLibrary(_THIS, const char *path)
+{
+/* FIXME: Is this working correctly? */
+ image_info info;
+ int32 cookie = 0;
+ while (get_next_image_info(0, &cookie, &info) == B_OK) {
+ void *location = NULL;
+ if( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY,
+ &location) == B_OK) {
+
+ _this->gl_config.dll_handle = (void *) (size_t) info.id;
+ _this->gl_config.driver_loaded = 1;
+ SDL_strlcpy(_this->gl_config.driver_path, "libGL.so",
+ SDL_arraysize(_this->gl_config.driver_path));
+ }
+ }
+ return 0;
+}
+
+void *HAIKU_GL_GetProcAddress(_THIS, const char *proc)
+{
+ if (_this->gl_config.dll_handle != NULL) {
+ void *location = NULL;
+ status_t err;
+ if ((err =
+ get_image_symbol((image_id) (size_t) _this->gl_config.dll_handle,
+ proc, B_SYMBOL_TYPE_ANY,
+ &location)) == B_OK) {
+ return location;
+ } else {
+ SDL_SetError("Couldn't find OpenGL symbol");
+ return NULL;
+ }
+ } else {
+ SDL_SetError("OpenGL library not loaded");
+ return NULL;
+ }
+}
+
+
+
+
+int HAIKU_GL_SwapWindow(_THIS, SDL_Window * window) {
+ _ToBeWin(window)->SwapBuffers();
+ return 0;
+}
+
+int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) {
+ SDL_BWin* win = (SDL_BWin*)context;
+ _GetBeApp()->SetCurrentContext(win ? win->GetGLView() : NULL);
+ return 0;
+}
+
+
+SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window) {
+ /* FIXME: Not sure what flags should be included here; may want to have
+ most of them */
+ SDL_BWin *bwin = _ToBeWin(window);
+ Uint32 gl_flags = BGL_RGB;
+ if (_this->gl_config.alpha_size) {
+ gl_flags |= BGL_ALPHA;
+ }
+ if (_this->gl_config.depth_size) {
+ gl_flags |= BGL_DEPTH;
+ }
+ if (_this->gl_config.stencil_size) {
+ gl_flags |= BGL_STENCIL;
+ }
+ if (_this->gl_config.double_buffer) {
+ gl_flags |= BGL_DOUBLE;
+ } else {
+ gl_flags |= BGL_SINGLE;
+ }
+ if (_this->gl_config.accum_red_size ||
+ _this->gl_config.accum_green_size ||
+ _this->gl_config.accum_blue_size ||
+ _this->gl_config.accum_alpha_size) {
+ gl_flags |= BGL_ACCUM;
+ }
+ bwin->CreateGLView(gl_flags);
+ return (SDL_GLContext)(bwin);
+}
+
+void HAIKU_GL_DeleteContext(_THIS, SDL_GLContext context) {
+ /* Currently, automatically unlocks the view */
+ ((SDL_BWin*)context)->RemoveGLView();
+}
+
+
+int HAIKU_GL_SetSwapInterval(_THIS, int interval) {
+ /* TODO: Implement this, if necessary? */
+ return SDL_Unsupported();
+}
+
+int HAIKU_GL_GetSwapInterval(_THIS) {
+ /* TODO: Implement this, if necessary? */
+ return 0;
+}
+
+
+void HAIKU_GL_UnloadLibrary(_THIS) {
+ /* TODO: Implement this, if necessary? */
+}
+
+
+/* FIXME: This function is meant to clear the OpenGL context when the video
+ mode changes (see SDL_bmodes.cc), but it doesn't seem to help, and is not
+ currently in use. */
+void HAIKU_GL_RebootContexts(_THIS) {
+ SDL_Window *window = _this->windows;
+ while(window) {
+ SDL_BWin *bwin = _ToBeWin(window);
+ if(bwin->GetGLView()) {
+ bwin->LockLooper();
+ bwin->RemoveGLView();
+ bwin->CreateGLView(bwin->GetGLType());
+ bwin->UnlockLooper();
+ }
+ window = window->next;
+ }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.h
new file mode 100644
index 0000000..b5b0de6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bopengl.h
@@ -0,0 +1,55 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BOPENGL_H
+#define SDL_BOPENGL_H
+
+#if SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../SDL_sysvideo.h"
+
+
+extern int HAIKU_GL_LoadLibrary(_THIS, const char *path); /* FIXME */
+extern void *HAIKU_GL_GetProcAddress(_THIS, const char *proc); /* FIXME */
+extern void HAIKU_GL_UnloadLibrary(_THIS); /* TODO */
+extern int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern int HAIKU_GL_SetSwapInterval(_THIS, int interval); /* TODO */
+extern int HAIKU_GL_GetSwapInterval(_THIS); /* TODO */
+extern int HAIKU_GL_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window);
+extern void HAIKU_GL_DeleteContext(_THIS, SDL_GLContext context);
+
+extern void HAIKU_GL_RebootContexts(_THIS);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL */
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.cc
new file mode 100644
index 0000000..e7b4b6e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.cc
@@ -0,0 +1,177 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "SDL_bkeyboard.h"
+#include "SDL_bwindow.h"
+#include "SDL_bclipboard.h"
+#include "SDL_bvideo.h"
+#include "SDL_bopengl.h"
+#include "SDL_bmodes.h"
+#include "SDL_bframebuffer.h"
+#include "SDL_bevents.h"
+
+/* FIXME: Undefined functions */
+// #define HAIKU_PumpEvents NULL
+ #define HAIKU_StartTextInput NULL
+ #define HAIKU_StopTextInput NULL
+ #define HAIKU_SetTextInputRect NULL
+
+// #define HAIKU_DeleteDevice NULL
+
+/* End undefined functions */
+
+static SDL_VideoDevice *
+HAIKU_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ /*SDL_VideoData *data;*/
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+
+ device->driverdata = NULL; /* FIXME: Is this the cause of some of the
+ SDL_Quit() errors? */
+
+/* TODO: Figure out if any initialization needs to go here */
+
+ /* Set the function pointers */
+ device->VideoInit = HAIKU_VideoInit;
+ device->VideoQuit = HAIKU_VideoQuit;
+ device->GetDisplayBounds = HAIKU_GetDisplayBounds;
+ device->GetDisplayModes = HAIKU_GetDisplayModes;
+ device->SetDisplayMode = HAIKU_SetDisplayMode;
+ device->PumpEvents = HAIKU_PumpEvents;
+
+ device->CreateSDLWindow = HAIKU_CreateWindow;
+ device->CreateSDLWindowFrom = HAIKU_CreateWindowFrom;
+ device->SetWindowTitle = HAIKU_SetWindowTitle;
+ device->SetWindowIcon = HAIKU_SetWindowIcon;
+ device->SetWindowPosition = HAIKU_SetWindowPosition;
+ device->SetWindowSize = HAIKU_SetWindowSize;
+ device->ShowWindow = HAIKU_ShowWindow;
+ device->HideWindow = HAIKU_HideWindow;
+ device->RaiseWindow = HAIKU_RaiseWindow;
+ device->MaximizeWindow = HAIKU_MaximizeWindow;
+ device->MinimizeWindow = HAIKU_MinimizeWindow;
+ device->RestoreWindow = HAIKU_RestoreWindow;
+ device->SetWindowBordered = HAIKU_SetWindowBordered;
+ device->SetWindowResizable = HAIKU_SetWindowResizable;
+ device->SetWindowFullscreen = HAIKU_SetWindowFullscreen;
+ device->SetWindowGammaRamp = HAIKU_SetWindowGammaRamp;
+ device->GetWindowGammaRamp = HAIKU_GetWindowGammaRamp;
+ device->SetWindowGrab = HAIKU_SetWindowGrab;
+ device->DestroyWindow = HAIKU_DestroyWindow;
+ device->GetWindowWMInfo = HAIKU_GetWindowWMInfo;
+ device->CreateWindowFramebuffer = HAIKU_CreateWindowFramebuffer;
+ device->UpdateWindowFramebuffer = HAIKU_UpdateWindowFramebuffer;
+ device->DestroyWindowFramebuffer = HAIKU_DestroyWindowFramebuffer;
+
+ device->shape_driver.CreateShaper = NULL;
+ device->shape_driver.SetWindowShape = NULL;
+ device->shape_driver.ResizeWindowShape = NULL;
+
+#if SDL_VIDEO_OPENGL
+ device->GL_LoadLibrary = HAIKU_GL_LoadLibrary;
+ device->GL_GetProcAddress = HAIKU_GL_GetProcAddress;
+ device->GL_UnloadLibrary = HAIKU_GL_UnloadLibrary;
+ device->GL_CreateContext = HAIKU_GL_CreateContext;
+ device->GL_MakeCurrent = HAIKU_GL_MakeCurrent;
+ device->GL_SetSwapInterval = HAIKU_GL_SetSwapInterval;
+ device->GL_GetSwapInterval = HAIKU_GL_GetSwapInterval;
+ device->GL_SwapWindow = HAIKU_GL_SwapWindow;
+ device->GL_DeleteContext = HAIKU_GL_DeleteContext;
+#endif
+
+ device->StartTextInput = HAIKU_StartTextInput;
+ device->StopTextInput = HAIKU_StopTextInput;
+ device->SetTextInputRect = HAIKU_SetTextInputRect;
+
+ device->SetClipboardText = HAIKU_SetClipboardText;
+ device->GetClipboardText = HAIKU_GetClipboardText;
+ device->HasClipboardText = HAIKU_HasClipboardText;
+
+ device->free = HAIKU_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap HAIKU_bootstrap = {
+ "haiku", "Haiku graphics",
+ HAIKU_Available, HAIKU_CreateDevice
+};
+
+void HAIKU_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_free(device->driverdata);
+ SDL_free(device);
+}
+
+int HAIKU_VideoInit(_THIS)
+{
+ /* Initialize the Be Application for appserver interaction */
+ if (SDL_InitBeApp() < 0) {
+ return -1;
+ }
+
+ /* Initialize video modes */
+ HAIKU_InitModes(_this);
+
+ /* Init the keymap */
+ HAIKU_InitOSKeymap();
+
+#if SDL_VIDEO_OPENGL
+ /* testgl application doesn't load library, just tries to load symbols */
+ /* is it correct? if so we have to load library here */
+ HAIKU_GL_LoadLibrary(_this, NULL);
+#endif
+
+ /* We're done! */
+ return (0);
+}
+
+int HAIKU_Available(void)
+{
+ return (1);
+}
+
+void HAIKU_VideoQuit(_THIS)
+{
+
+ HAIKU_QuitModes(_this);
+
+ SDL_QuitBeApp();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.h
new file mode 100644
index 0000000..a1d01fb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bvideo.h
@@ -0,0 +1,44 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BVIDEO_H
+#define BVIDEO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../main/haiku/SDL_BeApp.h"
+#include "../SDL_sysvideo.h"
+
+
+extern void HAIKU_VideoQuit(_THIS);
+extern int HAIKU_VideoInit(_THIS);
+extern void HAIKU_DeleteDevice(_THIS);
+extern int HAIKU_Available(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.cc b/source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.cc
new file mode 100644
index 0000000..142a3fa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.cc
@@ -0,0 +1,233 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+#include "../SDL_sysvideo.h"
+
+#include "SDL_BWin.h"
+#include <new>
+
+/* Define a path to window's BWIN data */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
+ return ((SDL_BWin*)(window->driverdata));
+}
+
+static SDL_INLINE SDL_BApp *_GetBeApp() {
+ return ((SDL_BApp*)be_app);
+}
+
+static int _InitWindow(_THIS, SDL_Window *window) {
+ uint32 flags = 0;
+ window_look look = B_TITLED_WINDOW_LOOK;
+
+ BRect bounds(
+ window->x,
+ window->y,
+ window->x + window->w - 1, //BeWindows have an off-by-one px w/h thing
+ window->y + window->h - 1
+ );
+
+ if(window->flags & SDL_WINDOW_FULLSCREEN) {
+ /* TODO: Add support for this flag */
+ printf(__FILE__": %d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__LINE__);
+ }
+ if(window->flags & SDL_WINDOW_OPENGL) {
+ /* TODO: Add support for this flag */
+ }
+ if(!(window->flags & SDL_WINDOW_RESIZABLE)) {
+ flags |= B_NOT_RESIZABLE | B_NOT_ZOOMABLE;
+ }
+ if(window->flags & SDL_WINDOW_BORDERLESS) {
+ look = B_NO_BORDER_WINDOW_LOOK;
+ }
+
+ SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, look, flags);
+ if(bwin == NULL)
+ return -1;
+
+ window->driverdata = bwin;
+ int32 winID = _GetBeApp()->GetID(window);
+ bwin->SetID(winID);
+
+ return 0;
+}
+
+int HAIKU_CreateWindow(_THIS, SDL_Window *window) {
+ if (_InitWindow(_this, window) < 0) {
+ return -1;
+ }
+
+ /* Start window loop */
+ _ToBeWin(window)->Show();
+ return 0;
+}
+
+int HAIKU_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) {
+
+ SDL_BWin *otherBWin = (SDL_BWin*)data;
+ if(!otherBWin->LockLooper())
+ return -1;
+
+ /* Create the new window and initialize its members */
+ window->x = (int)otherBWin->Frame().left;
+ window->y = (int)otherBWin->Frame().top;
+ window->w = (int)otherBWin->Frame().Width();
+ window->h = (int)otherBWin->Frame().Height();
+
+ /* Set SDL flags */
+ if(!(otherBWin->Flags() & B_NOT_RESIZABLE)) {
+ window->flags |= SDL_WINDOW_RESIZABLE;
+ }
+
+ /* If we are out of memory, return the error code */
+ if (_InitWindow(_this, window) < 0) {
+ return -1;
+ }
+
+ /* TODO: Add any other SDL-supported window attributes here */
+ _ToBeWin(window)->SetTitle(otherBWin->Title());
+
+ /* Start window loop and unlock the other window */
+ _ToBeWin(window)->Show();
+
+ otherBWin->UnlockLooper();
+ return 0;
+}
+
+void HAIKU_SetWindowTitle(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_SET_TITLE);
+ msg.AddString("window-title", window->title);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) {
+ /* FIXME: Icons not supported by Haiku */
+}
+
+void HAIKU_SetWindowPosition(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_MOVE_WINDOW);
+ msg.AddInt32("window-x", window->x);
+ msg.AddInt32("window-y", window->y);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_SetWindowSize(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_RESIZE_WINDOW);
+ msg.AddInt32("window-w", window->w - 1);
+ msg.AddInt32("window-h", window->h - 1);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) {
+ BMessage msg(BWIN_SET_BORDERED);
+ msg.AddBool("window-border", bordered != SDL_FALSE);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) {
+ BMessage msg(BWIN_SET_RESIZABLE);
+ msg.AddBool("window-resizable", resizable != SDL_FALSE);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_ShowWindow(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_SHOW_WINDOW);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_HideWindow(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_HIDE_WINDOW);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_RaiseWindow(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_SHOW_WINDOW); /* Activate this window and move to front */
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_MaximizeWindow(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_MAXIMIZE_WINDOW);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_MinimizeWindow(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_MINIMIZE_WINDOW);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_RestoreWindow(_THIS, SDL_Window * window) {
+ BMessage msg(BWIN_RESTORE_WINDOW);
+ _ToBeWin(window)->PostMessage(&msg);
+}
+
+void HAIKU_SetWindowFullscreen(_THIS, SDL_Window * window,
+ SDL_VideoDisplay * display, SDL_bool fullscreen) {
+ /* Haiku tracks all video display information */
+ BMessage msg(BWIN_FULLSCREEN);
+ msg.AddBool("fullscreen", fullscreen);
+ _ToBeWin(window)->PostMessage(&msg);
+
+}
+
+int HAIKU_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) {
+ /* FIXME: Not Haiku supported */
+ return -1;
+}
+
+int HAIKU_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) {
+ /* FIXME: Not Haiku supported */
+ return -1;
+}
+
+
+void HAIKU_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) {
+ /* TODO: Implement this! */
+}
+
+void HAIKU_DestroyWindow(_THIS, SDL_Window * window) {
+ _ToBeWin(window)->LockLooper(); /* This MUST be locked */
+ _GetBeApp()->ClearID(_ToBeWin(window));
+ _ToBeWin(window)->Quit();
+ window->driverdata = NULL;
+}
+
+SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info) {
+ /* FIXME: What is the point of this? What information should be included? */
+ return SDL_FALSE;
+}
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.h b/source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.h
new file mode 100644
index 0000000..2894f27
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/haiku/SDL_bwindow.h
@@ -0,0 +1,55 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BWINDOW_H
+#define SDL_BWINDOW_H
+
+
+#include "../SDL_sysvideo.h"
+
+
+extern int HAIKU_CreateWindow(_THIS, SDL_Window *window);
+extern int HAIKU_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+extern void HAIKU_SetWindowTitle(_THIS, SDL_Window * window);
+extern void HAIKU_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+extern void HAIKU_SetWindowPosition(_THIS, SDL_Window * window);
+extern void HAIKU_SetWindowSize(_THIS, SDL_Window * window);
+extern void HAIKU_ShowWindow(_THIS, SDL_Window * window);
+extern void HAIKU_HideWindow(_THIS, SDL_Window * window);
+extern void HAIKU_RaiseWindow(_THIS, SDL_Window * window);
+extern void HAIKU_MaximizeWindow(_THIS, SDL_Window * window);
+extern void HAIKU_MinimizeWindow(_THIS, SDL_Window * window);
+extern void HAIKU_RestoreWindow(_THIS, SDL_Window * window);
+extern void HAIKU_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
+extern void HAIKU_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
+extern void HAIKU_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern int HAIKU_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
+extern int HAIKU_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
+extern void HAIKU_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+extern void HAIKU_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/khronos/EGL/egl.h b/source/3rd-party/SDL2/src/video/khronos/EGL/egl.h
new file mode 100644
index 0000000..93a2187
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/EGL/egl.h
@@ -0,0 +1,303 @@
+#ifndef __egl_h_
+#define __egl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2017 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.khronos.org/registry/egl
+**
+** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $
+*/
+
+#include <EGL/eglplatform.h>
+
+/* Generated on date 20170627 */
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
+typedef unsigned int EGLBoolean;
+typedef void *EGLDisplay;
+#include <KHR/khrplatform.h>
+#include <EGL/eglplatform.h>
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BAD_ACCESS 0x3002
+#define EGL_BAD_ALLOC 0x3003
+#define EGL_BAD_ATTRIBUTE 0x3004
+#define EGL_BAD_CONFIG 0x3005
+#define EGL_BAD_CONTEXT 0x3006
+#define EGL_BAD_CURRENT_SURFACE 0x3007
+#define EGL_BAD_DISPLAY 0x3008
+#define EGL_BAD_MATCH 0x3009
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
+#define EGL_BAD_NATIVE_WINDOW 0x300B
+#define EGL_BAD_PARAMETER 0x300C
+#define EGL_BAD_SURFACE 0x300D
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_CONFIG_CAVEAT 0x3027
+#define EGL_CONFIG_ID 0x3028
+#define EGL_CORE_NATIVE_ENGINE 0x305B
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
+#define EGL_DRAW 0x3059
+#define EGL_EXTENSIONS 0x3055
+#define EGL_FALSE 0
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_HEIGHT 0x3056
+#define EGL_LARGEST_PBUFFER 0x3058
+#define EGL_LEVEL 0x3029
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
+#define EGL_NATIVE_RENDERABLE 0x302D
+#define EGL_NATIVE_VISUAL_ID 0x302E
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
+#define EGL_NONE 0x3038
+#define EGL_NON_CONFORMANT_CONFIG 0x3051
+#define EGL_NOT_INITIALIZED 0x3001
+#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
+#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
+#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
+#define EGL_PBUFFER_BIT 0x0001
+#define EGL_PIXMAP_BIT 0x0002
+#define EGL_READ 0x305A
+#define EGL_RED_SIZE 0x3024
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_SLOW_CONFIG 0x3050
+#define EGL_STENCIL_SIZE 0x3026
+#define EGL_SUCCESS 0x3000
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
+#define EGL_TRANSPARENT_RGB 0x3052
+#define EGL_TRANSPARENT_TYPE 0x3034
+#define EGL_TRUE 1
+#define EGL_VENDOR 0x3053
+#define EGL_VERSION 0x3054
+#define EGL_WIDTH 0x3057
+#define EGL_WINDOW_BIT 0x0004
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
+EGLAPI EGLint EGLAPIENTRY eglGetError (void);
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
+#endif /* EGL_VERSION_1_0 */
+
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+#define EGL_BACK_BUFFER 0x3084
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define EGL_CONTEXT_LOST 0x300E
+#define EGL_MIN_SWAP_INTERVAL 0x303B
+#define EGL_MAX_SWAP_INTERVAL 0x303C
+#define EGL_MIPMAP_TEXTURE 0x3082
+#define EGL_MIPMAP_LEVEL 0x3083
+#define EGL_NO_TEXTURE 0x305C
+#define EGL_TEXTURE_2D 0x305F
+#define EGL_TEXTURE_FORMAT 0x3080
+#define EGL_TEXTURE_RGB 0x305D
+#define EGL_TEXTURE_RGBA 0x305E
+#define EGL_TEXTURE_TARGET 0x3081
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
+#endif /* EGL_VERSION_1_1 */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+#define EGL_ALPHA_FORMAT 0x3088
+#define EGL_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_ALPHA_FORMAT_PRE 0x308C
+#define EGL_ALPHA_MASK_SIZE 0x303E
+#define EGL_BUFFER_PRESERVED 0x3094
+#define EGL_BUFFER_DESTROYED 0x3095
+#define EGL_CLIENT_APIS 0x308D
+#define EGL_COLORSPACE 0x3087
+#define EGL_COLORSPACE_sRGB 0x3089
+#define EGL_COLORSPACE_LINEAR 0x308A
+#define EGL_COLOR_BUFFER_TYPE 0x303F
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
+#define EGL_DISPLAY_SCALING 10000
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
+#define EGL_LUMINANCE_BUFFER 0x308F
+#define EGL_LUMINANCE_SIZE 0x303D
+#define EGL_OPENGL_ES_BIT 0x0001
+#define EGL_OPENVG_BIT 0x0002
+#define EGL_OPENGL_ES_API 0x30A0
+#define EGL_OPENVG_API 0x30A1
+#define EGL_OPENVG_IMAGE 0x3096
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_RENDER_BUFFER 0x3086
+#define EGL_RGB_BUFFER 0x308E
+#define EGL_SINGLE_BUFFER 0x3085
+#define EGL_SWAP_BEHAVIOR 0x3093
+#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
+#define EGL_VERTICAL_RESOLUTION 0x3091
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
+#endif /* EGL_VERSION_1_2 */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+#define EGL_CONFORMANT 0x3042
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041
+#define EGL_OPENGL_ES2_BIT 0x0004
+#define EGL_VG_ALPHA_FORMAT 0x3088
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
+#define EGL_VG_COLORSPACE 0x3087
+#define EGL_VG_COLORSPACE_sRGB 0x3089
+#define EGL_VG_COLORSPACE_LINEAR 0x308A
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
+#endif /* EGL_VERSION_1_3 */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
+#define EGL_OPENGL_API 0x30A2
+#define EGL_OPENGL_BIT 0x0008
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
+#endif /* EGL_VERSION_1_4 */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+typedef void *EGLImage;
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_CL_EVENT_HANDLE 0x309C
+#define EGL_SYNC_CL_EVENT 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define EGL_SYNC_TYPE 0x30F7
+#define EGL_SYNC_STATUS 0x30F1
+#define EGL_SYNC_CONDITION 0x30F8
+#define EGL_SIGNALED 0x30F2
+#define EGL_UNSIGNALED 0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED 0x30F5
+#define EGL_CONDITION_SATISFIED 0x30F6
+#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
+#define EGL_SYNC_FENCE 0x30F9
+#define EGL_GL_COLORSPACE 0x309D
+#define EGL_GL_COLORSPACE_SRGB 0x3089
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
+#define EGL_GL_RENDERBUFFER 0x30B9
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
+#define EGL_GL_TEXTURE_3D 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_IMAGE_PRESERVED 0x30D2
+#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#endif /* EGL_VERSION_1_5 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/khronos/EGL/eglext.h b/source/3rd-party/SDL2/src/video/khronos/EGL/eglext.h
new file mode 100644
index 0000000..d2def03
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/EGL/eglext.h
@@ -0,0 +1,1241 @@
+#ifndef __eglext_h_
+#define __eglext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2017 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.khronos.org/registry/egl
+**
+** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $
+*/
+
+#include <EGL/eglplatform.h>
+
+#define EGL_EGLEXT_VERSION 20170627
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: _nomatch_^
+ * Default extensions included: egl
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_KHR_cl_event
+#define EGL_KHR_cl_event 1
+#define EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+#endif /* EGL_KHR_cl_event */
+
+#ifndef EGL_KHR_cl_event2
+#define EGL_KHR_cl_event2 1
+typedef void *EGLSyncKHR;
+typedef intptr_t EGLAttribKHR;
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#endif
+#endif /* EGL_KHR_cl_event2 */
+
+#ifndef EGL_KHR_client_get_all_proc_addresses
+#define EGL_KHR_client_get_all_proc_addresses 1
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR 0x3042
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
+#endif /* EGL_KHR_config_attribs */
+
+#ifndef EGL_KHR_context_flush_control
+#define EGL_KHR_context_flush_control 1
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
+#endif /* EGL_KHR_context_flush_control */
+
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#endif /* EGL_KHR_create_context */
+
+#ifndef EGL_KHR_create_context_no_error
+#define EGL_KHR_create_context_no_error 1
+#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3
+#endif /* EGL_KHR_create_context_no_error */
+
+#ifndef EGL_KHR_debug
+#define EGL_KHR_debug 1
+typedef void *EGLLabelKHR;
+typedef void *EGLObjectKHR;
+typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
+#define EGL_OBJECT_THREAD_KHR 0x33B0
+#define EGL_OBJECT_DISPLAY_KHR 0x33B1
+#define EGL_OBJECT_CONTEXT_KHR 0x33B2
+#define EGL_OBJECT_SURFACE_KHR 0x33B3
+#define EGL_OBJECT_IMAGE_KHR 0x33B4
+#define EGL_OBJECT_SYNC_KHR 0x33B5
+#define EGL_OBJECT_STREAM_KHR 0x33B6
+#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9
+#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA
+#define EGL_DEBUG_MSG_WARN_KHR 0x33BB
+#define EGL_DEBUG_MSG_INFO_KHR 0x33BC
+#define EGL_DEBUG_CALLBACK_KHR 0x33B8
+typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value);
+typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value);
+EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#endif
+#endif /* EGL_KHR_debug */
+
+#ifndef EGL_KHR_display_reference
+#define EGL_KHR_display_reference 1
+#define EGL_TRACK_REFERENCES_KHR 0x3352
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value);
+#endif
+#endif /* EGL_KHR_display_reference */
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_fence_sync */
+
+#ifndef EGL_KHR_get_all_proc_addresses
+#define EGL_KHR_get_all_proc_addresses 1
+#endif /* EGL_KHR_get_all_proc_addresses */
+
+#ifndef EGL_KHR_gl_colorspace
+#define EGL_KHR_gl_colorspace 1
+#define EGL_GL_COLORSPACE_KHR 0x309D
+#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
+#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
+#endif /* EGL_KHR_gl_colorspace */
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9
+#endif /* EGL_KHR_gl_renderbuffer_image */
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#endif /* EGL_KHR_gl_texture_2D_image */
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
+#endif /* EGL_KHR_gl_texture_3D_image */
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+typedef void *EGLImageKHR;
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0)
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_KHR_image */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif /* EGL_KHR_image_base */
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+#endif /* EGL_KHR_image_pixmap */
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define EGL_MATCH_FORMAT_KHR 0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define EGL_FORMAT_RGB_565_KHR 0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR 0x30CE
+#define EGL_UPPER_LEFT_KHR 0x30CF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
+#endif
+#endif /* EGL_KHR_lock_surface */
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+#endif /* EGL_KHR_lock_surface2 */
+
+#ifndef EGL_KHR_lock_surface3
+#define EGL_KHR_lock_surface3 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#endif
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifndef EGL_KHR_mutable_render_buffer
+#define EGL_KHR_mutable_render_buffer 1
+#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000
+#endif /* EGL_KHR_mutable_render_buffer */
+
+#ifndef EGL_KHR_no_config_context
+#define EGL_KHR_no_config_context 1
+#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0)
+#endif /* EGL_KHR_no_config_context */
+
+#ifndef EGL_KHR_partial_update
+#define EGL_KHR_partial_update 1
+#define EGL_BUFFER_AGE_KHR 0x313D
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_partial_update */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+#define EGL_PLATFORM_ANDROID_KHR 0x3141
+#endif /* EGL_KHR_platform_android */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+#define EGL_PLATFORM_GBM_KHR 0x31D7
+#endif /* EGL_KHR_platform_gbm */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
+#endif /* EGL_KHR_platform_wayland */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
+#endif /* EGL_KHR_platform_x11 */
+
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_STATUS_KHR 0x30F1
+#define EGL_SIGNALED_KHR 0x30F2
+#define EGL_UNSIGNALED_KHR 0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_REUSABLE_KHR 0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
+#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_reusable_sync */
+
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void *EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_NO_STREAM_KHR EGL_CAST(EGLStreamKHR,0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream */
+
+#ifndef EGL_KHR_stream_attrib
+#define EGL_KHR_stream_attrib 1
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream_attrib */
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#ifdef EGL_KHR_stream
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#ifdef EGL_KHR_stream
+#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1)
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_fifo */
+
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#ifdef EGL_KHR_stream
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_BIT_KHR 0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+#endif /* EGL_KHR_surfaceless_context */
+
+#ifndef EGL_KHR_swap_buffers_with_damage
+#define EGL_KHR_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
+#endif /* EGL_KHR_vg_parent_image */
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif
+#endif /* EGL_KHR_wait_sync */
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifndef EGL_ANDROID_create_native_client_buffer
+#define EGL_ANDROID_create_native_client_buffer 1
+#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143
+#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001
+#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002
+#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list);
+#endif
+#endif /* EGL_ANDROID_create_native_client_buffer */
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+#endif /* EGL_ANDROID_framebuffer_target */
+
+#ifndef EGL_ANDROID_front_buffer_auto_refresh
+#define EGL_ANDROID_front_buffer_auto_refresh 1
+#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
+#endif /* EGL_ANDROID_front_buffer_auto_refresh */
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+#endif /* EGL_ANDROID_image_native_buffer */
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
+#endif
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifndef EGL_ANDROID_presentation_time
+#define EGL_ANDROID_presentation_time 1
+typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+#endif
+#endif /* EGL_ANDROID_presentation_time */
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+#define EGL_RECORDABLE_ANDROID 0x3142
+#endif /* EGL_ANDROID_recordable */
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+
+#ifndef EGL_ANGLE_device_d3d
+#define EGL_ANGLE_device_d3d 1
+#define EGL_D3D9_DEVICE_ANGLE 0x33A0
+#define EGL_D3D11_DEVICE_ANGLE 0x33A1
+#endif /* EGL_ANGLE_device_d3d */
+
+#ifndef EGL_ANGLE_query_surface_pointer
+#define EGL_ANGLE_query_surface_pointer 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#endif
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+#define EGL_FIXED_SIZE_ANGLE 0x3201
+#endif /* EGL_ANGLE_window_fixed_size */
+
+#ifndef EGL_ARM_implicit_external_sync
+#define EGL_ARM_implicit_external_sync 1
+#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A
+#endif /* EGL_ARM_implicit_external_sync */
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+#define EGL_DISCARD_SAMPLES_ARM 0x3286
+#endif /* EGL_ARM_pixmap_multisample_discard */
+
+#ifndef EGL_EXT_bind_to_front
+#define EGL_EXT_bind_to_front 1
+#define EGL_FRONT_BUFFER_EXT 0x3464
+#endif /* EGL_EXT_bind_to_front */
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+#define EGL_BUFFER_AGE_EXT 0x313D
+#endif /* EGL_EXT_buffer_age */
+
+#ifndef EGL_EXT_client_extensions
+#define EGL_EXT_client_extensions 1
+#endif /* EGL_EXT_client_extensions */
+
+#ifndef EGL_EXT_compositor
+#define EGL_EXT_compositor 1
+#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460
+#define EGL_EXTERNAL_REF_ID_EXT 0x3461
+#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462
+#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy);
+#endif
+#endif /* EGL_EXT_compositor */
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+#endif /* EGL_EXT_create_context_robustness */
+
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0)
+#define EGL_BAD_DEVICE_EXT 0x322B
+#define EGL_DEVICE_EXT 0x322C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_EXT_device_base */
+
+#ifndef EGL_EXT_device_drm
+#define EGL_EXT_device_drm 1
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+#endif /* EGL_EXT_device_drm */
+
+#ifndef EGL_EXT_device_enumeration
+#define EGL_EXT_device_enumeration 1
+#endif /* EGL_EXT_device_enumeration */
+
+#ifndef EGL_EXT_device_openwf
+#define EGL_EXT_device_openwf 1
+#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
+#endif /* EGL_EXT_device_openwf */
+
+#ifndef EGL_EXT_device_query
+#define EGL_EXT_device_query 1
+#endif /* EGL_EXT_device_query */
+
+#ifndef EGL_EXT_gl_colorspace_bt2020_linear
+#define EGL_EXT_gl_colorspace_bt2020_linear 1
+#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F
+#endif /* EGL_EXT_gl_colorspace_bt2020_linear */
+
+#ifndef EGL_EXT_gl_colorspace_bt2020_pq
+#define EGL_EXT_gl_colorspace_bt2020_pq 1
+#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340
+#endif /* EGL_EXT_gl_colorspace_bt2020_pq */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3
+#define EGL_EXT_gl_colorspace_display_p3 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363
+#endif /* EGL_EXT_gl_colorspace_display_p3 */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3_linear
+#define EGL_EXT_gl_colorspace_display_p3_linear 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362
+#endif /* EGL_EXT_gl_colorspace_display_p3_linear */
+
+#ifndef EGL_EXT_gl_colorspace_scrgb
+#define EGL_EXT_gl_colorspace_scrgb 1
+#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351
+#endif /* EGL_EXT_gl_colorspace_scrgb */
+
+#ifndef EGL_EXT_gl_colorspace_scrgb_linear
+#define EGL_EXT_gl_colorspace_scrgb_linear 1
+#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350
+#endif /* EGL_EXT_gl_colorspace_scrgb_linear */
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT 0x327F
+#define EGL_ITU_REC709_EXT 0x3280
+#define EGL_ITU_REC2020_EXT 0x3281
+#define EGL_YUV_FULL_RANGE_EXT 0x3282
+#define EGL_YUV_NARROW_RANGE_EXT 0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+#endif /* EGL_EXT_image_dma_buf_import */
+
+#ifndef EGL_EXT_image_dma_buf_import_modifiers
+#define EGL_EXT_image_dma_buf_import_modifiers 1
+#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440
+#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441
+#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442
+#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
+#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
+#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445
+#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446
+#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447
+#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448
+#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449
+#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
+#endif
+#endif /* EGL_EXT_image_dma_buf_import_modifiers */
+
+#ifndef EGL_EXT_image_implicit_sync_control
+#define EGL_EXT_image_implicit_sync_control 1
+#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470
+#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471
+#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472
+#endif /* EGL_EXT_image_implicit_sync_control */
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+#endif /* EGL_EXT_multiview_window */
+
+#ifndef EGL_EXT_output_base
+#define EGL_EXT_output_base 1
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0)
+#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0)
+#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D
+#define EGL_BAD_OUTPUT_PORT_EXT 0x322E
+#define EGL_SWAP_INTERVAL_EXT 0x322F
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#endif
+#endif /* EGL_EXT_output_base */
+
+#ifndef EGL_EXT_output_drm
+#define EGL_EXT_output_drm 1
+#define EGL_DRM_CRTC_EXT 0x3234
+#define EGL_DRM_PLANE_EXT 0x3235
+#define EGL_DRM_CONNECTOR_EXT 0x3236
+#endif /* EGL_EXT_output_drm */
+
+#ifndef EGL_EXT_output_openwf
+#define EGL_EXT_output_openwf 1
+#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238
+#define EGL_OPENWF_PORT_ID_EXT 0x3239
+#endif /* EGL_EXT_output_openwf */
+
+#ifndef EGL_EXT_pixel_format_float
+#define EGL_EXT_pixel_format_float 1
+#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339
+#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A
+#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B
+#endif /* EGL_EXT_pixel_format_float */
+
+#ifndef EGL_EXT_platform_base
+#define EGL_EXT_platform_base 1
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#endif
+#endif /* EGL_EXT_platform_base */
+
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+#endif /* EGL_EXT_platform_device */
+
+#ifndef EGL_EXT_platform_wayland
+#define EGL_EXT_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
+#endif /* EGL_EXT_platform_wayland */
+
+#ifndef EGL_EXT_platform_x11
+#define EGL_EXT_platform_x11 1
+#define EGL_PLATFORM_X11_EXT 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
+#endif /* EGL_EXT_platform_x11 */
+
+#ifndef EGL_EXT_protected_content
+#define EGL_EXT_protected_content 1
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+#endif /* EGL_EXT_protected_content */
+
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+#endif /* EGL_EXT_protected_surface */
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+#define EGL_EXT_stream_consumer_egloutput 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#endif
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
+#ifndef EGL_EXT_surface_CTA861_3_metadata
+#define EGL_EXT_surface_CTA861_3_metadata 1
+#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360
+#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361
+#endif /* EGL_EXT_surface_CTA861_3_metadata */
+
+#ifndef EGL_EXT_surface_SMPTE2086_metadata
+#define EGL_EXT_surface_SMPTE2086_metadata 1
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346
+#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347
+#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348
+#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349
+#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A
+#define EGL_METADATA_SCALING_EXT 50000
+#endif /* EGL_EXT_surface_SMPTE2086_metadata */
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifndef EGL_EXT_yuv_surface
+#define EGL_EXT_yuv_surface 1
+#define EGL_YUV_ORDER_EXT 0x3301
+#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311
+#define EGL_YUV_SUBSAMPLE_EXT 0x3312
+#define EGL_YUV_DEPTH_RANGE_EXT 0x3317
+#define EGL_YUV_CSC_STANDARD_EXT 0x330A
+#define EGL_YUV_PLANE_BPP_EXT 0x331A
+#define EGL_YUV_BUFFER_EXT 0x3300
+#define EGL_YUV_ORDER_YUV_EXT 0x3302
+#define EGL_YUV_ORDER_YVU_EXT 0x3303
+#define EGL_YUV_ORDER_YUYV_EXT 0x3304
+#define EGL_YUV_ORDER_UYVY_EXT 0x3305
+#define EGL_YUV_ORDER_YVYU_EXT 0x3306
+#define EGL_YUV_ORDER_VYUY_EXT 0x3307
+#define EGL_YUV_ORDER_AYUV_EXT 0x3308
+#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313
+#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314
+#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315
+#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318
+#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319
+#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B
+#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C
+#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D
+#define EGL_YUV_PLANE_BPP_0_EXT 0x331B
+#define EGL_YUV_PLANE_BPP_8_EXT 0x331C
+#define EGL_YUV_PLANE_BPP_10_EXT 0x331D
+#endif /* EGL_EXT_yuv_surface */
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+struct EGLClientPixmapHI {
+ void *pData;
+ EGLint iWidth;
+ EGLint iHeight;
+ EGLint iStride;
+};
+#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#endif
+#endif /* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+#define EGL_COLOR_FORMAT_HI 0x8F70
+#define EGL_COLOR_RGB_HI 0x8F71
+#define EGL_COLOR_RGBA_HI 0x8F72
+#define EGL_COLOR_ARGB_HI 0x8F73
+#endif /* EGL_HI_colorformats */
+
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#endif /* EGL_IMG_context_priority */
+
+#ifndef EGL_IMG_image_plane_attribs
+#define EGL_IMG_image_plane_attribs 1
+#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105
+#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106
+#endif /* EGL_IMG_image_plane_attribs */
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
+#define EGL_DRM_BUFFER_USE_MESA 0x31D1
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define EGL_DRM_BUFFER_MESA 0x31D3
+#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+#endif /* EGL_MESA_drm_image */
+
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#endif
+#endif /* EGL_MESA_image_dma_buf_export */
+
+#ifndef EGL_MESA_platform_gbm
+#define EGL_MESA_platform_gbm 1
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+#endif /* EGL_MESA_platform_gbm */
+
+#ifndef EGL_MESA_platform_surfaceless
+#define EGL_MESA_platform_surfaceless 1
+#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD
+#endif /* EGL_MESA_platform_surfaceless */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region2 */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+#define EGL_Y_INVERTED_NOK 0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+#define EGL_AUTO_STEREO_NV 0x3136
+#endif /* EGL_NV_3dvision_surface */
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif /* EGL_NV_coverage_sample */
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+#endif /* EGL_NV_coverage_sample_resolve */
+
+#ifndef EGL_NV_cuda_event
+#define EGL_NV_cuda_event 1
+#define EGL_CUDA_EVENT_HANDLE_NV 0x323B
+#define EGL_SYNC_CUDA_EVENT_NV 0x323C
+#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D
+#endif /* EGL_NV_cuda_event */
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif /* EGL_NV_depth_nonlinear */
+
+#ifndef EGL_NV_device_cuda
+#define EGL_NV_device_cuda 1
+#define EGL_CUDA_DEVICE_NV 0x323A
+#endif /* EGL_NV_device_cuda */
+
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#endif
+#endif /* EGL_NV_native_query */
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+#endif /* EGL_NV_post_convert_rounding */
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifndef EGL_NV_robustness_video_memory_purge
+#define EGL_NV_robustness_video_memory_purge 1
+#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#endif /* EGL_NV_robustness_video_memory_purge */
+
+#ifndef EGL_NV_stream_consumer_gltexture_yuv
+#define EGL_NV_stream_consumer_gltexture_yuv 1
+#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C
+#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D
+#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+#ifndef EGL_NV_stream_cross_display
+#define EGL_NV_stream_cross_display 1
+#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E
+#endif /* EGL_NV_stream_cross_display */
+
+#ifndef EGL_NV_stream_cross_object
+#define EGL_NV_stream_cross_object 1
+#define EGL_STREAM_CROSS_OBJECT_NV 0x334D
+#endif /* EGL_NV_stream_cross_object */
+
+#ifndef EGL_NV_stream_cross_partition
+#define EGL_NV_stream_cross_partition 1
+#define EGL_STREAM_CROSS_PARTITION_NV 0x323F
+#endif /* EGL_NV_stream_cross_partition */
+
+#ifndef EGL_NV_stream_cross_process
+#define EGL_NV_stream_cross_process 1
+#define EGL_STREAM_CROSS_PROCESS_NV 0x3245
+#endif /* EGL_NV_stream_cross_process */
+
+#ifndef EGL_NV_stream_cross_system
+#define EGL_NV_stream_cross_system 1
+#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F
+#endif /* EGL_NV_stream_cross_system */
+
+#ifndef EGL_NV_stream_fifo_next
+#define EGL_NV_stream_fifo_next 1
+#define EGL_PENDING_FRAME_NV 0x3329
+#define EGL_STREAM_TIME_PENDING_NV 0x332A
+#endif /* EGL_NV_stream_fifo_next */
+
+#ifndef EGL_NV_stream_fifo_synchronous
+#define EGL_NV_stream_fifo_synchronous 1
+#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336
+#endif /* EGL_NV_stream_fifo_synchronous */
+
+#ifndef EGL_NV_stream_frame_limits
+#define EGL_NV_stream_frame_limits 1
+#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337
+#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338
+#endif /* EGL_NV_stream_frame_limits */
+
+#ifndef EGL_NV_stream_metadata
+#define EGL_NV_stream_metadata 1
+#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250
+#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251
+#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252
+#define EGL_PRODUCER_METADATA_NV 0x3253
+#define EGL_CONSUMER_METADATA_NV 0x3254
+#define EGL_PENDING_METADATA_NV 0x3328
+#define EGL_METADATA0_SIZE_NV 0x3255
+#define EGL_METADATA1_SIZE_NV 0x3256
+#define EGL_METADATA2_SIZE_NV 0x3257
+#define EGL_METADATA3_SIZE_NV 0x3258
+#define EGL_METADATA0_TYPE_NV 0x3259
+#define EGL_METADATA1_TYPE_NV 0x325A
+#define EGL_METADATA2_TYPE_NV 0x325B
+#define EGL_METADATA3_TYPE_NV 0x325C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#endif
+#endif /* EGL_NV_stream_metadata */
+
+#ifndef EGL_NV_stream_remote
+#define EGL_NV_stream_remote 1
+#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240
+#define EGL_STREAM_TYPE_NV 0x3241
+#define EGL_STREAM_PROTOCOL_NV 0x3242
+#define EGL_STREAM_ENDPOINT_NV 0x3243
+#define EGL_STREAM_LOCAL_NV 0x3244
+#define EGL_STREAM_PRODUCER_NV 0x3247
+#define EGL_STREAM_CONSUMER_NV 0x3248
+#define EGL_STREAM_PROTOCOL_FD_NV 0x3246
+#endif /* EGL_NV_stream_remote */
+
+#ifndef EGL_NV_stream_reset
+#define EGL_NV_stream_reset 1
+#define EGL_SUPPORT_RESET_NV 0x3334
+#define EGL_SUPPORT_REUSE_NV 0x3335
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_NV_stream_reset */
+
+#ifndef EGL_NV_stream_socket
+#define EGL_NV_stream_socket 1
+#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B
+#define EGL_SOCKET_HANDLE_NV 0x324C
+#define EGL_SOCKET_TYPE_NV 0x324D
+#endif /* EGL_NV_stream_socket */
+
+#ifndef EGL_NV_stream_socket_inet
+#define EGL_NV_stream_socket_inet 1
+#define EGL_SOCKET_TYPE_INET_NV 0x324F
+#endif /* EGL_NV_stream_socket_inet */
+
+#ifndef EGL_NV_stream_socket_unix
+#define EGL_NV_stream_socket_unix 1
+#define EGL_SOCKET_TYPE_UNIX_NV 0x324E
+#endif /* EGL_NV_stream_socket_unix */
+
+#ifndef EGL_NV_stream_sync
+#define EGL_NV_stream_sync 1
+#define EGL_SYNC_NEW_FRAME_NV 0x321F
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#endif
+#endif /* EGL_NV_stream_sync */
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+typedef void *EGLSyncNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV 0x30E7
+#define EGL_SIGNALED_NV 0x30E8
+#define EGL_UNSIGNALED_NV 0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV 0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define EGL_CONDITION_SATISFIED_NV 0x30EC
+#define EGL_SYNC_TYPE_NV 0x30ED
+#define EGL_SYNC_CONDITION_NV 0x30EE
+#define EGL_SYNC_FENCE_NV 0x30EF
+#define EGL_NO_SYNC_NV EGL_CAST(EGLSyncNV,0)
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_sync */
+
+#ifndef EGL_NV_system_time
+#define EGL_NV_system_time 1
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_system_time */
+
+#ifndef EGL_TIZEN_image_native_buffer
+#define EGL_TIZEN_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
+#endif /* EGL_TIZEN_image_native_buffer */
+
+#ifndef EGL_TIZEN_image_native_surface
+#define EGL_TIZEN_image_native_surface 1
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif /* EGL_TIZEN_image_native_surface */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/khronos/EGL/eglplatform.h b/source/3rd-party/SDL2/src/video/khronos/EGL/eglplatform.h
new file mode 100644
index 0000000..c77c333
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/EGL/eglplatform.h
@@ -0,0 +1,132 @@
+#ifndef __eglplatform_h_
+#define __eglplatform_h_
+
+/*
+** Copyright (c) 2007-2016 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Platform-specific types and definitions for egl.h
+ * $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file. Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "EGL" component "Registry".
+ */
+
+#include <KHR/khrplatform.h>
+
+/* Macros used in EGL function prototype declarations.
+ *
+ * EGL functions should be prototyped as:
+ *
+ * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
+ * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
+ *
+ * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
+ */
+
+#ifndef EGLAPI
+#define EGLAPI KHRONOS_APICALL
+#endif
+
+#ifndef EGLAPIENTRY
+#define EGLAPIENTRY KHRONOS_APIENTRY
+#endif
+#define EGLAPIENTRYP EGLAPIENTRY*
+
+/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
+ * are aliases of window-system-dependent types, such as X Display * or
+ * Windows Device Context. They must be defined in platform-specific
+ * code below. The EGL-prefixed versions of Native*Type are the same
+ * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ *
+ * Khronos STRONGLY RECOMMENDS that you use the default definitions
+ * provided below, since these changes affect both binary and source
+ * portability of applications using EGL running on different EGL
+ * implementations.
+ */
+
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+
+typedef HDC EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+typedef HWND EGLNativeWindowType;
+
+#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativeWindowType;
+typedef void *EGLNativePixmapType;
+
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+struct ANativeWindow;
+struct egl_native_pixmap_t;
+
+typedef struct ANativeWindow* EGLNativeWindowType;
+typedef struct egl_native_pixmap_t* EGLNativePixmapType;
+typedef void* EGLNativeDisplayType;
+
+#elif defined(__unix__)
+
+/* X11 (tentative) */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+typedef Display *EGLNativeDisplayType;
+typedef Pixmap EGLNativePixmapType;
+typedef Window EGLNativeWindowType;
+
+#else
+#error "Platform not recognized"
+#endif
+
+/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
+typedef EGLNativeDisplayType NativeDisplayType;
+typedef EGLNativePixmapType NativePixmapType;
+typedef EGLNativeWindowType NativeWindowType;
+
+
+/* Define EGLint. This must be a signed integral type large enough to contain
+ * all legal attribute names and values passed into and out of EGL, whether
+ * their type is boolean, bitmask, enumerant (symbolic constant), integer,
+ * handle, or other. While in general a 32-bit integer will suffice, if
+ * handles are 64 bit types, then EGLint should be defined as a signed 64-bit
+ * integer type.
+ */
+typedef khronos_int32_t EGLint;
+
+
+/* C++ / C typecast macros for special EGL handle values */
+#if defined(__cplusplus)
+#define EGL_CAST(type, value) (static_cast<type>(value))
+#else
+#define EGL_CAST(type, value) ((type) (value))
+#endif
+
+#endif /* __eglplatform_h */
diff --git a/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2.h b/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2.h
new file mode 100644
index 0000000..8ba1642
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2.h
@@ -0,0 +1,675 @@
+#ifndef __gl2_h_
+#define __gl2_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2017 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#include <GLES2/gl2platform.h>
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+#ifndef GL_GLES_PROTOTYPES
+#define GL_GLES_PROTOTYPES 1
+#endif
+
+/* Generated on date 20170817 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_ES_VERSION_2_0
+#define GL_ES_VERSION_2_0 1
+#include <KHR/khrplatform.h>
+typedef khronos_int8_t GLbyte;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef short GLshort;
+typedef unsigned short GLushort;
+typedef void GLvoid;
+typedef struct __GLsync *GLsync;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+typedef char GLchar;
+typedef khronos_float_t GLfloat;
+typedef khronos_ssize_t GLsizeiptr;
+typedef khronos_intptr_t GLintptr;
+typedef unsigned int GLbitfield;
+typedef int GLint;
+typedef unsigned char GLboolean;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_NONE 0
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
+typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
+typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ES_VERSION_2_0 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2ext.h b/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2ext.h
new file mode 100644
index 0000000..4e1488c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2ext.h
@@ -0,0 +1,3505 @@
+#ifndef __gl2ext_h_
+#define __gl2ext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2017 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/* Generated on date 20170817 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]
+ * Versions emitted: _nomatch_^
+ * Default extensions included: gles2
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_MULTIPLY_KHR 0x9294
+#define GL_SCREEN_KHR 0x9295
+#define GL_OVERLAY_KHR 0x9296
+#define GL_DARKEN_KHR 0x9297
+#define GL_LIGHTEN_KHR 0x9298
+#define GL_COLORDODGE_KHR 0x9299
+#define GL_COLORBURN_KHR 0x929A
+#define GL_HARDLIGHT_KHR 0x929B
+#define GL_SOFTLIGHT_KHR 0x929C
+#define GL_DIFFERENCE_KHR 0x929E
+#define GL_EXCLUSION_KHR 0x92A0
+#define GL_HSL_HUE_KHR 0x92AD
+#define GL_HSL_SATURATION_KHR 0x92AE
+#define GL_HSL_COLOR_KHR 0x92AF
+#define GL_HSL_LUMINOSITY_KHR 0x92B0
+typedef void (GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void);
+#endif
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+
+#ifndef GL_KHR_context_flush_control
+#define GL_KHR_context_flush_control 1
+#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC
+#endif /* GL_KHR_context_flush_control */
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+typedef void (GL_APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+#define GL_SAMPLER 0x82E6
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245
+#define GL_DEBUG_SOURCE_API_KHR 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A
+#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B
+#define GL_DEBUG_TYPE_ERROR_KHR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250
+#define GL_DEBUG_TYPE_OTHER_KHR 0x8251
+#define GL_DEBUG_TYPE_MARKER_KHR 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D
+#define GL_BUFFER_KHR 0x82E0
+#define GL_SHADER_KHR 0x82E1
+#define GL_PROGRAM_KHR 0x82E2
+#define GL_VERTEX_ARRAY_KHR 0x8074
+#define GL_QUERY_KHR 0x82E3
+#define GL_PROGRAM_PIPELINE_KHR 0x82E4
+#define GL_SAMPLER_KHR 0x82E6
+#define GL_MAX_LABEL_LENGTH_KHR 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147
+#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148
+#define GL_DEBUG_OUTPUT_KHR 0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002
+#define GL_STACK_OVERFLOW_KHR 0x0503
+#define GL_STACK_UNDERFLOW_KHR 0x0504
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam);
+typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void);
+typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam);
+GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void);
+GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params);
+#endif
+#endif /* GL_KHR_debug */
+
+#ifndef GL_KHR_no_error
+#define GL_KHR_no_error 1
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
+#endif /* GL_KHR_no_error */
+
+#ifndef GL_KHR_parallel_shader_compile
+#define GL_KHR_parallel_shader_compile 1
+#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0
+#define GL_COMPLETION_STATUS_KHR 0x91B1
+typedef void (GL_APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
+#endif
+#endif /* GL_KHR_parallel_shader_compile */
+
+#ifndef GL_KHR_robust_buffer_access_behavior
+#define GL_KHR_robust_buffer_access_behavior 1
+#endif /* GL_KHR_robust_buffer_access_behavior */
+
+#ifndef GL_KHR_robustness
+#define GL_KHR_robustness 1
+#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3
+#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252
+#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256
+#define GL_NO_RESET_NOTIFICATION_KHR 0x8261
+#define GL_CONTEXT_LOST_KHR 0x0507
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSKHRPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsKHR (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvKHR (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivKHR (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+#endif
+#endif /* GL_KHR_robustness */
+
+#ifndef GL_KHR_texture_compression_astc_hdr
+#define GL_KHR_texture_compression_astc_hdr 1
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+#endif /* GL_KHR_texture_compression_astc_hdr */
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+#endif /* GL_KHR_texture_compression_astc_ldr */
+
+#ifndef GL_KHR_texture_compression_astc_sliced_3d
+#define GL_KHR_texture_compression_astc_sliced_3d 1
+#endif /* GL_KHR_texture_compression_astc_sliced_3d */
+
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+typedef void *GLeglImageOES;
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+#endif /* GL_OES_EGL_image */
+
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#endif /* GL_OES_EGL_image_external */
+
+#ifndef GL_OES_EGL_image_external_essl3
+#define GL_OES_EGL_image_external_essl3 1
+#endif /* GL_OES_EGL_image_external_essl3 */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture
+#define GL_OES_compressed_ETC1_RGB8_sub_texture 1
+#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#define GL_ETC1_RGB8_OES 0x8D64
+#endif /* GL_OES_compressed_ETC1_RGB8_texture */
+
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#define GL_PALETTE4_RGB8_OES 0x8B90
+#define GL_PALETTE4_RGBA8_OES 0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define GL_PALETTE4_RGBA4_OES 0x8B93
+#define GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define GL_PALETTE8_RGB8_OES 0x8B95
+#define GL_PALETTE8_RGBA8_OES 0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define GL_PALETTE8_RGBA4_OES 0x8B98
+#define GL_PALETTE8_RGB5_A1_OES 0x8B99
+#endif /* GL_OES_compressed_paletted_texture */
+
+#ifndef GL_OES_copy_image
+#define GL_OES_copy_image 1
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAOESPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyImageSubDataOES (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#endif
+#endif /* GL_OES_copy_image */
+
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#define GL_DEPTH_COMPONENT24_OES 0x81A6
+#endif /* GL_OES_depth24 */
+
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#define GL_DEPTH_COMPONENT32_OES 0x81A7
+#endif /* GL_OES_depth32 */
+
+#ifndef GL_OES_depth_texture
+#define GL_OES_depth_texture 1
+#endif /* GL_OES_depth_texture */
+
+#ifndef GL_OES_draw_buffers_indexed
+#define GL_OES_draw_buffers_indexed 1
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+typedef void (GL_APIENTRYP PFNGLENABLEIOESPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIOESPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIOESPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIOESPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIOESPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIOESPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIOESPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIOESPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEnableiOES (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiOES (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationiOES (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparateiOES (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunciOES (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparateiOES (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaskiOES (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index);
+#endif
+#endif /* GL_OES_draw_buffers_indexed */
+
+#ifndef GL_OES_draw_elements_base_vertex
+#define GL_OES_draw_elements_base_vertex 1
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+#endif
+#endif /* GL_OES_draw_elements_base_vertex */
+
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#endif /* GL_OES_element_index_uint */
+
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif /* GL_OES_fbo_render_mipmap */
+
+#ifndef GL_OES_fragment_precision_high
+#define GL_OES_fragment_precision_high 1
+#endif /* GL_OES_fragment_precision_high */
+
+#ifndef GL_OES_geometry_point_size
+#define GL_OES_geometry_point_size 1
+#endif /* GL_OES_geometry_point_size */
+
+#ifndef GL_OES_geometry_shader
+#define GL_OES_geometry_shader 1
+#define GL_GEOMETRY_SHADER_OES 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F
+#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E
+#define GL_LINES_ADJACENCY_OES 0x000A
+#define GL_LINE_STRIP_ADJACENCY_OES 0x000B
+#define GL_TRIANGLES_ADJACENCY_OES 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E
+#define GL_UNDEFINED_VERTEX_OES 0x8260
+#define GL_PRIMITIVES_GENERATED_OES 0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREOESPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureOES (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+#endif /* GL_OES_geometry_shader */
+
+#ifndef GL_OES_get_program_binary
+#define GL_OES_get_program_binary 1
+#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+#endif
+#endif /* GL_OES_get_program_binary */
+
+#ifndef GL_OES_gpu_shader5
+#define GL_OES_gpu_shader5 1
+#endif /* GL_OES_gpu_shader5 */
+
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#define GL_WRITE_ONLY_OES 0x88B9
+#define GL_BUFFER_ACCESS_OES 0x88BB
+#define GL_BUFFER_MAPPED_OES 0x88BC
+#define GL_BUFFER_MAP_POINTER_OES 0x88BD
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void *GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void **params);
+#endif
+#endif /* GL_OES_mapbuffer */
+
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#define GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif /* GL_OES_packed_depth_stencil */
+
+#ifndef GL_OES_primitive_bounding_box
+#define GL_OES_primitive_bounding_box 1
+#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXOESPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxOES (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#endif
+#endif /* GL_OES_primitive_bounding_box */
+
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#define GL_ALPHA8_OES 0x803C
+#define GL_DEPTH_COMPONENT16_OES 0x81A5
+#define GL_LUMINANCE4_ALPHA4_OES 0x8043
+#define GL_LUMINANCE8_ALPHA8_OES 0x8045
+#define GL_LUMINANCE8_OES 0x8040
+#define GL_RGBA4_OES 0x8056
+#define GL_RGB5_A1_OES 0x8057
+#define GL_RGB565_OES 0x8D62
+#define GL_RGB8_OES 0x8051
+#define GL_RGBA8_OES 0x8058
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB10_A2_EXT 0x8059
+#endif /* GL_OES_required_internalformat */
+
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif /* GL_OES_rgb8_rgba8 */
+
+#ifndef GL_OES_sample_shading
+#define GL_OES_sample_shading 1
+#define GL_SAMPLE_SHADING_OES 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37
+typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGOESPROC) (GLfloat value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value);
+#endif
+#endif /* GL_OES_sample_shading */
+
+#ifndef GL_OES_sample_variables
+#define GL_OES_sample_variables 1
+#endif /* GL_OES_sample_variables */
+
+#ifndef GL_OES_shader_image_atomic
+#define GL_OES_shader_image_atomic 1
+#endif /* GL_OES_shader_image_atomic */
+
+#ifndef GL_OES_shader_io_blocks
+#define GL_OES_shader_io_blocks 1
+#endif /* GL_OES_shader_io_blocks */
+
+#ifndef GL_OES_shader_multisample_interpolation
+#define GL_OES_shader_multisample_interpolation 1
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D
+#endif /* GL_OES_shader_multisample_interpolation */
+
+#ifndef GL_OES_standard_derivatives
+#define GL_OES_standard_derivatives 1
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
+#endif /* GL_OES_standard_derivatives */
+
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#define GL_STENCIL_INDEX1_OES 0x8D46
+#endif /* GL_OES_stencil1 */
+
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#define GL_STENCIL_INDEX4_OES 0x8D47
+#endif /* GL_OES_stencil4 */
+
+#ifndef GL_OES_surfaceless_context
+#define GL_OES_surfaceless_context 1
+#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
+#endif /* GL_OES_surfaceless_context */
+
+#ifndef GL_OES_tessellation_point_size
+#define GL_OES_tessellation_point_size 1
+#endif /* GL_OES_tessellation_point_size */
+
+#ifndef GL_OES_tessellation_shader
+#define GL_OES_tessellation_shader 1
+#define GL_PATCHES_OES 0x000E
+#define GL_PATCH_VERTICES_OES 0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75
+#define GL_TESS_GEN_MODE_OES 0x8E76
+#define GL_TESS_GEN_SPACING_OES 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78
+#define GL_TESS_GEN_POINT_MODE_OES 0x8E79
+#define GL_ISOLINES_OES 0x8E7A
+#define GL_QUADS_OES 0x0007
+#define GL_FRACTIONAL_ODD_OES 0x8E7B
+#define GL_FRACTIONAL_EVEN_OES 0x8E7C
+#define GL_MAX_PATCH_VERTICES_OES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221
+#define GL_IS_PER_PATCH_OES 0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308
+#define GL_TESS_CONTROL_SHADER_OES 0x8E88
+#define GL_TESS_EVALUATION_SHADER_OES 0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIOESPROC) (GLenum pname, GLint value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPatchParameteriOES (GLenum pname, GLint value);
+#endif
+#endif /* GL_OES_tessellation_shader */
+
+#ifndef GL_OES_texture_3D
+#define GL_OES_texture_3D 1
+#define GL_TEXTURE_WRAP_R_OES 0x8072
+#define GL_TEXTURE_3D_OES 0x806F
+#define GL_TEXTURE_BINDING_3D_OES 0x806A
+#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073
+#define GL_SAMPLER_3D_OES 0x8B5F
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#endif
+#endif /* GL_OES_texture_3D */
+
+#ifndef GL_OES_texture_border_clamp
+#define GL_OES_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_OES 0x1004
+#define GL_CLAMP_TO_BORDER_OES 0x812D
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexParameterIivOES (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivOES (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivOES (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivOES (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivOES (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivOES (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivOES (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivOES (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+#endif /* GL_OES_texture_border_clamp */
+
+#ifndef GL_OES_texture_buffer
+#define GL_OES_texture_buffer 1
+#define GL_TEXTURE_BUFFER_OES 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F
+#define GL_SAMPLER_BUFFER_OES 0x8DC2
+#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8
+#define GL_IMAGE_BUFFER_OES 0x9051
+#define GL_INT_IMAGE_BUFFER_OES 0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067
+#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D
+#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E
+typedef void (GL_APIENTRYP PFNGLTEXBUFFEROESPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEOESPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexBufferOES (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRangeOES (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+#endif /* GL_OES_texture_buffer */
+
+#ifndef GL_OES_texture_compression_astc
+#define GL_OES_texture_compression_astc 1
+#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0
+#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1
+#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2
+#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3
+#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4
+#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5
+#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6
+#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7
+#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8
+#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9
+#endif /* GL_OES_texture_compression_astc */
+
+#ifndef GL_OES_texture_cube_map_array
+#define GL_OES_texture_cube_map_array 1
+#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A
+#endif /* GL_OES_texture_cube_map_array */
+
+#ifndef GL_OES_texture_float
+#define GL_OES_texture_float 1
+#endif /* GL_OES_texture_float */
+
+#ifndef GL_OES_texture_float_linear
+#define GL_OES_texture_float_linear 1
+#endif /* GL_OES_texture_float_linear */
+
+#ifndef GL_OES_texture_half_float
+#define GL_OES_texture_half_float 1
+#define GL_HALF_FLOAT_OES 0x8D61
+#endif /* GL_OES_texture_half_float */
+
+#ifndef GL_OES_texture_half_float_linear
+#define GL_OES_texture_half_float_linear 1
+#endif /* GL_OES_texture_half_float_linear */
+
+#ifndef GL_OES_texture_npot
+#define GL_OES_texture_npot 1
+#endif /* GL_OES_texture_npot */
+
+#ifndef GL_OES_texture_stencil8
+#define GL_OES_texture_stencil8 1
+#define GL_STENCIL_INDEX_OES 0x1901
+#define GL_STENCIL_INDEX8_OES 0x8D48
+#endif /* GL_OES_texture_stencil8 */
+
+#ifndef GL_OES_texture_storage_multisample_2d_array
+#define GL_OES_texture_storage_multisample_2d_array 1
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage3DMultisampleOES (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_OES_texture_storage_multisample_2d_array */
+
+#ifndef GL_OES_texture_view
+#define GL_OES_texture_view 1
+#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWOESPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureViewOES (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+#endif /* GL_OES_texture_view */
+
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array);
+#endif
+#endif /* GL_OES_vertex_array_object */
+
+#ifndef GL_OES_vertex_half_float
+#define GL_OES_vertex_half_float 1
+#endif /* GL_OES_vertex_half_float */
+
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_OES_vertex_type_10_10_10_2 1
+#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6
+#define GL_INT_10_10_10_2_OES 0x8DF7
+#endif /* GL_OES_vertex_type_10_10_10_2 */
+
+#ifndef GL_OES_viewport_array
+#define GL_OES_viewport_array 1
+#define GL_MAX_VIEWPORTS_OES 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS_OES 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE_OES 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F
+typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVOESPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFOESPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVOESPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVOESPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDOESPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVOESPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVOESPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFOESPROC) (GLuint index, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETFLOATI_VOESPROC) (GLenum target, GLuint index, GLfloat *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportArrayvOES (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glViewportIndexedfOES (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GL_APICALL void GL_APIENTRY glViewportIndexedfvOES (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glScissorArrayvOES (GLuint first, GLsizei count, const GLint *v);
+GL_APICALL void GL_APIENTRY glScissorIndexedOES (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorIndexedvOES (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glDepthRangeArrayfvOES (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glDepthRangeIndexedfOES (GLuint index, GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glGetFloati_vOES (GLenum target, GLuint index, GLfloat *data);
+#endif
+#endif /* GL_OES_viewport_array */
+
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#define GL_3DC_X_AMD 0x87F9
+#define GL_3DC_XY_AMD 0x87FA
+#endif /* GL_AMD_compressed_3DC_texture */
+
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#define GL_ATC_RGB_AMD 0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#endif /* GL_AMD_compressed_ATC_texture */
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);
+typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data);
+GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+#endif /* GL_AMD_performance_monitor */
+
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+#define GL_Z400_BINARY_AMD 0x8740
+#endif /* GL_AMD_program_binary_Z400 */
+
+#ifndef GL_ANDROID_extension_pack_es31a
+#define GL_ANDROID_extension_pack_es31a 1
+#endif /* GL_ANDROID_extension_pack_es31a */
+
+#ifndef GL_ANGLE_depth_texture
+#define GL_ANGLE_depth_texture 1
+#endif /* GL_ANGLE_depth_texture */
+
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+#endif /* GL_ANGLE_framebuffer_blit */
+
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_ANGLE_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor);
+#endif
+#endif /* GL_ANGLE_instanced_arrays */
+
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_ANGLE_pack_reverse_row_order 1
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+#endif /* GL_ANGLE_pack_reverse_row_order */
+
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+#define GL_PROGRAM_BINARY_ANGLE 0x93A6
+#endif /* GL_ANGLE_program_binary */
+
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+
+#ifndef GL_ANGLE_texture_usage
+#define GL_ANGLE_texture_usage 1
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+#endif /* GL_ANGLE_texture_usage */
+
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+#endif
+#endif /* GL_ANGLE_translated_shader_source */
+
+#ifndef GL_APPLE_clip_distance
+#define GL_APPLE_clip_distance 1
+#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32
+#define GL_CLIP_DISTANCE0_APPLE 0x3000
+#define GL_CLIP_DISTANCE1_APPLE 0x3001
+#define GL_CLIP_DISTANCE2_APPLE 0x3002
+#define GL_CLIP_DISTANCE3_APPLE 0x3003
+#define GL_CLIP_DISTANCE4_APPLE 0x3004
+#define GL_CLIP_DISTANCE5_APPLE 0x3005
+#define GL_CLIP_DISTANCE6_APPLE 0x3006
+#define GL_CLIP_DISTANCE7_APPLE 0x3007
+#endif /* GL_APPLE_clip_distance */
+
+#ifndef GL_APPLE_color_buffer_packed_float
+#define GL_APPLE_color_buffer_packed_float 1
+#endif /* GL_APPLE_color_buffer_packed_float */
+
+#ifndef GL_APPLE_copy_texture_levels
+#define GL_APPLE_copy_texture_levels 1
+typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#endif
+#endif /* GL_APPLE_copy_texture_levels */
+
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif
+#endif /* GL_APPLE_framebuffer_multisample */
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#define GL_RGB_422_APPLE 0x8A1F
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define GL_RGB_RAW_422_APPLE 0x8A51
+#endif /* GL_APPLE_rgb_422 */
+
+#ifndef GL_APPLE_sync
+#define GL_APPLE_sync 1
+#define GL_SYNC_OBJECT_APPLE 0x8A53
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define GL_OBJECT_TYPE_APPLE 0x9112
+#define GL_SYNC_CONDITION_APPLE 0x9113
+#define GL_SYNC_STATUS_APPLE 0x9114
+#define GL_SYNC_FLAGS_APPLE 0x9115
+#define GL_SYNC_FENCE_APPLE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_UNSIGNALED_APPLE 0x9118
+#define GL_SIGNALED_APPLE 0x9119
+#define GL_ALREADY_SIGNALED_APPLE 0x911A
+#define GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define GL_CONDITION_SATISFIED_APPLE 0x911C
+#define GL_WAIT_FAILED_APPLE 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+#endif /* GL_APPLE_sync */
+
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#define GL_BGRA_EXT 0x80E1
+#define GL_BGRA8_EXT 0x93A1
+#endif /* GL_APPLE_texture_format_BGRA8888 */
+
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#endif /* GL_APPLE_texture_max_level */
+
+#ifndef GL_APPLE_texture_packed_float
+#define GL_APPLE_texture_packed_float 1
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B
+#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E
+#define GL_R11F_G11F_B10F_APPLE 0x8C3A
+#define GL_RGB9_E5_APPLE 0x8C3D
+#endif /* GL_APPLE_texture_packed_float */
+
+#ifndef GL_ARM_mali_program_binary
+#define GL_ARM_mali_program_binary 1
+#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61
+#endif /* GL_ARM_mali_program_binary */
+
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+#define GL_MALI_SHADER_BINARY_ARM 0x8F60
+#endif /* GL_ARM_mali_shader_binary */
+
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif /* GL_ARM_rgba8 */
+
+#ifndef GL_ARM_shader_framebuffer_fetch
+#define GL_ARM_shader_framebuffer_fetch 1
+#define GL_FETCH_PER_SAMPLE_ARM 0x8F65
+#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
+#endif /* GL_ARM_shader_framebuffer_fetch */
+
+#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil
+#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
+#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */
+
+#ifndef GL_DMP_program_binary
+#define GL_DMP_program_binary 1
+#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251
+#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252
+#define GL_DMP_PROGRAM_BINARY_DMP 0x9253
+#endif /* GL_DMP_program_binary */
+
+#ifndef GL_DMP_shader_binary
+#define GL_DMP_shader_binary 1
+#define GL_SHADER_BINARY_DMP 0x9250
+#endif /* GL_DMP_shader_binary */
+
+#ifndef GL_EXT_EGL_image_array
+#define GL_EXT_EGL_image_array 1
+#endif /* GL_EXT_EGL_image_array */
+
+#ifndef GL_EXT_YUV_target
+#define GL_EXT_YUV_target 1
+#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7
+#endif /* GL_EXT_YUV_target */
+
+#ifndef GL_EXT_base_instance
+#define GL_EXT_base_instance 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceEXT (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+#endif
+#endif /* GL_EXT_base_instance */
+
+#ifndef GL_EXT_blend_func_extended
+#define GL_EXT_blend_func_extended 1
+#define GL_SRC1_COLOR_EXT 0x88F9
+#define GL_SRC1_ALPHA_EXT 0x8589
+#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB
+#define GL_SRC_ALPHA_SATURATE_EXT 0x0308
+#define GL_LOCATION_INDEX_EXT 0x930F
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC
+typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocationIndexEXT (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT (GLuint program, const GLchar *name);
+#endif
+#endif /* GL_EXT_blend_func_extended */
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#endif /* GL_EXT_blend_minmax */
+
+#ifndef GL_EXT_buffer_storage
+#define GL_EXT_buffer_storage 1
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
+#define GL_MAP_COHERENT_BIT_EXT 0x0080
+#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100
+#define GL_CLIENT_STORAGE_BIT_EXT 0x0200
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000
+#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F
+#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+#endif
+#endif /* GL_EXT_buffer_storage */
+
+#ifndef GL_EXT_clear_texture
+#define GL_EXT_clear_texture 1
+typedef void (GL_APIENTRYP PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+typedef void (GL_APIENTRYP PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glClearTexImageEXT (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+GL_APICALL void GL_APIENTRY glClearTexSubImageEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+#endif
+#endif /* GL_EXT_clear_texture */
+
+#ifndef GL_EXT_clip_control
+#define GL_EXT_clip_control 1
+#define GL_LOWER_LEFT_EXT 0x8CA1
+#define GL_UPPER_LEFT_EXT 0x8CA2
+#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E
+#define GL_ZERO_TO_ONE_EXT 0x935F
+#define GL_CLIP_ORIGIN_EXT 0x935C
+#define GL_CLIP_DEPTH_MODE_EXT 0x935D
+typedef void (GL_APIENTRYP PFNGLCLIPCONTROLEXTPROC) (GLenum origin, GLenum depth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glClipControlEXT (GLenum origin, GLenum depth);
+#endif
+#endif /* GL_EXT_clip_control */
+
+#ifndef GL_EXT_clip_cull_distance
+#define GL_EXT_clip_cull_distance 1
+#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32
+#define GL_MAX_CULL_DISTANCES_EXT 0x82F9
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA
+#define GL_CLIP_DISTANCE0_EXT 0x3000
+#define GL_CLIP_DISTANCE1_EXT 0x3001
+#define GL_CLIP_DISTANCE2_EXT 0x3002
+#define GL_CLIP_DISTANCE3_EXT 0x3003
+#define GL_CLIP_DISTANCE4_EXT 0x3004
+#define GL_CLIP_DISTANCE5_EXT 0x3005
+#define GL_CLIP_DISTANCE6_EXT 0x3006
+#define GL_CLIP_DISTANCE7_EXT 0x3007
+#endif /* GL_EXT_clip_cull_distance */
+
+#ifndef GL_EXT_color_buffer_float
+#define GL_EXT_color_buffer_float 1
+#endif /* GL_EXT_color_buffer_float */
+
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_EXT_color_buffer_half_float 1
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_RG16F_EXT 0x822F
+#define GL_R16F_EXT 0x822D
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+#endif /* GL_EXT_color_buffer_half_float */
+
+#ifndef GL_EXT_conservative_depth
+#define GL_EXT_conservative_depth 1
+#endif /* GL_EXT_conservative_depth */
+
+#ifndef GL_EXT_copy_image
+#define GL_EXT_copy_image 1
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAEXTPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyImageSubDataEXT (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#endif
+#endif /* GL_EXT_copy_image */
+
+#ifndef GL_EXT_debug_label
+#define GL_EXT_debug_label 1
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define GL_PROGRAM_OBJECT_EXT 0x8B40
+#define GL_SHADER_OBJECT_EXT 0x8B48
+#define GL_BUFFER_OBJECT_EXT 0x9151
+#define GL_QUERY_OBJECT_EXT 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+#endif /* GL_EXT_debug_label */
+
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void);
+#endif
+#endif /* GL_EXT_debug_marker */
+
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#define GL_COLOR_EXT 0x1800
+#define GL_DEPTH_EXT 0x1801
+#define GL_STENCIL_EXT 0x1802
+typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+#endif /* GL_EXT_discard_framebuffer */
+
+#ifndef GL_EXT_disjoint_timer_query
+#define GL_EXT_disjoint_timer_query 1
+#define GL_QUERY_COUNTER_BITS_EXT 0x8864
+#define GL_CURRENT_QUERY_EXT 0x8865
+#define GL_QUERY_RESULT_EXT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#define GL_TIMESTAMP_EXT 0x8E28
+#define GL_GPU_DISJOINT_EXT 0x8FBB
+typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target);
+GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params);
+#endif
+#endif /* GL_EXT_disjoint_timer_query */
+
+#ifndef GL_EXT_draw_buffers
+#define GL_EXT_draw_buffers 1
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_MAX_DRAW_BUFFERS_EXT 0x8824
+#define GL_DRAW_BUFFER0_EXT 0x8825
+#define GL_DRAW_BUFFER1_EXT 0x8826
+#define GL_DRAW_BUFFER2_EXT 0x8827
+#define GL_DRAW_BUFFER3_EXT 0x8828
+#define GL_DRAW_BUFFER4_EXT 0x8829
+#define GL_DRAW_BUFFER5_EXT 0x882A
+#define GL_DRAW_BUFFER6_EXT 0x882B
+#define GL_DRAW_BUFFER7_EXT 0x882C
+#define GL_DRAW_BUFFER8_EXT 0x882D
+#define GL_DRAW_BUFFER9_EXT 0x882E
+#define GL_DRAW_BUFFER10_EXT 0x882F
+#define GL_DRAW_BUFFER11_EXT 0x8830
+#define GL_DRAW_BUFFER12_EXT 0x8831
+#define GL_DRAW_BUFFER13_EXT 0x8832
+#define GL_DRAW_BUFFER14_EXT 0x8833
+#define GL_DRAW_BUFFER15_EXT 0x8834
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs);
+#endif
+#endif /* GL_EXT_draw_buffers */
+
+#ifndef GL_EXT_draw_buffers_indexed
+#define GL_EXT_draw_buffers_indexed 1
+typedef void (GL_APIENTRYP PFNGLENABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEnableiEXT (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiEXT (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationiEXT (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparateiEXT (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunciEXT (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparateiEXT (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaskiEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index);
+#endif
+#endif /* GL_EXT_draw_buffers_indexed */
+
+#ifndef GL_EXT_draw_elements_base_vertex
+#define GL_EXT_draw_elements_base_vertex 1
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+#endif
+#endif /* GL_EXT_draw_elements_base_vertex */
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#endif
+#endif /* GL_EXT_draw_instanced */
+
+#ifndef GL_EXT_draw_transform_feedback
+#define GL_EXT_draw_transform_feedback 1
+typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKEXTPROC) (GLenum mode, GLuint id);
+typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC) (GLenum mode, GLuint id, GLsizei instancecount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawTransformFeedbackEXT (GLenum mode, GLuint id);
+GL_APICALL void GL_APIENTRY glDrawTransformFeedbackInstancedEXT (GLenum mode, GLuint id, GLsizei instancecount);
+#endif
+#endif /* GL_EXT_draw_transform_feedback */
+
+#ifndef GL_EXT_external_buffer
+#define GL_EXT_external_buffer 1
+typedef void *GLeglClientBufferEXT;
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+GL_APICALL void GL_APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#endif
+#endif /* GL_EXT_external_buffer */
+
+#ifndef GL_EXT_float_blend
+#define GL_EXT_float_blend 1
+#endif /* GL_EXT_float_blend */
+
+#ifndef GL_EXT_geometry_point_size
+#define GL_EXT_geometry_point_size 1
+#endif /* GL_EXT_geometry_point_size */
+
+#ifndef GL_EXT_geometry_shader
+#define GL_EXT_geometry_shader 1
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F
+#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_UNDEFINED_VERTEX_EXT 0x8260
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+#endif /* GL_EXT_geometry_shader */
+
+#ifndef GL_EXT_gpu_shader5
+#define GL_EXT_gpu_shader5 1
+#endif /* GL_EXT_gpu_shader5 */
+
+#ifndef GL_EXT_instanced_arrays
+#define GL_EXT_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT (GLuint index, GLuint divisor);
+#endif
+#endif /* GL_EXT_instanced_arrays */
+
+#ifndef GL_EXT_map_buffer_range
+#define GL_EXT_map_buffer_range 1
+#define GL_MAP_READ_BIT_EXT 0x0001
+#define GL_MAP_WRITE_BIT_EXT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void *GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+#endif /* GL_EXT_map_buffer_range */
+
+#ifndef GL_EXT_memory_object
+#define GL_EXT_memory_object 1
+#define GL_TEXTURE_TILING_EXT 0x9580
+#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581
+#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B
+#define GL_NUM_TILING_TYPES_EXT 0x9582
+#define GL_TILING_TYPES_EXT 0x9583
+#define GL_OPTIMAL_TILING_EXT 0x9584
+#define GL_LINEAR_TILING_EXT 0x9585
+#define GL_NUM_DEVICE_UUIDS_EXT 0x9596
+#define GL_DEVICE_UUID_EXT 0x9597
+#define GL_DRIVER_UUID_EXT 0x9598
+#define GL_UUID_SIZE_EXT 16
+typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data);
+typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data);
+typedef void (GL_APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects);
+typedef GLboolean (GL_APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject);
+typedef void (GL_APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects);
+typedef void (GL_APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data);
+GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data);
+GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects);
+GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT (GLuint memoryObject);
+GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects);
+GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_EXT_memory_object */
+
+#ifndef GL_EXT_memory_object_fd
+#define GL_EXT_memory_object_fd 1
+#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_memory_object_fd */
+
+#ifndef GL_EXT_memory_object_win32
+#define GL_EXT_memory_object_win32 1
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588
+#define GL_DEVICE_LUID_EXT 0x9599
+#define GL_DEVICE_NODE_MASK_EXT 0x959A
+#define GL_LUID_SIZE_EXT 8
+#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589
+#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A
+#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B
+#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_memory_object_win32 */
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount);
+#endif
+#endif /* GL_EXT_multi_draw_arrays */
+
+#ifndef GL_EXT_multi_draw_indirect
+#define GL_EXT_multi_draw_indirect 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysIndirectEXT (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsIndirectEXT (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#endif
+#endif /* GL_EXT_multi_draw_indirect */
+
+#ifndef GL_EXT_multisampled_compatibility
+#define GL_EXT_multisampled_compatibility 1
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#endif /* GL_EXT_multisampled_compatibility */
+
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+#endif /* GL_EXT_multisampled_render_to_texture */
+
+#ifndef GL_EXT_multiview_draw_buffers
+#define GL_EXT_multiview_draw_buffers 1
+#define GL_COLOR_ATTACHMENT_EXT 0x90F0
+#define GL_MULTIVIEW_EXT 0x90F1
+#define GL_DRAW_BUFFER_EXT 0x0C01
+#define GL_READ_BUFFER_EXT 0x0C02
+#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
+typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index);
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index);
+GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices);
+GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data);
+#endif
+#endif /* GL_EXT_multiview_draw_buffers */
+
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_EXT_occlusion_query_boolean 1
+#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#endif /* GL_EXT_occlusion_query_boolean */
+
+#ifndef GL_EXT_polygon_offset_clamp
+#define GL_EXT_polygon_offset_clamp 1
+#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp);
+#endif
+#endif /* GL_EXT_polygon_offset_clamp */
+
+#ifndef GL_EXT_post_depth_coverage
+#define GL_EXT_post_depth_coverage 1
+#endif /* GL_EXT_post_depth_coverage */
+
+#ifndef GL_EXT_primitive_bounding_box
+#define GL_EXT_primitive_bounding_box 1
+#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#endif
+#endif /* GL_EXT_primitive_bounding_box */
+
+#ifndef GL_EXT_protected_textures
+#define GL_EXT_protected_textures 1
+#define GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT 0x00000010
+#define GL_TEXTURE_PROTECTED_EXT 0x8BFA
+#endif /* GL_EXT_protected_textures */
+
+#ifndef GL_EXT_pvrtc_sRGB
+#define GL_EXT_pvrtc_sRGB 1
+#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
+#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1
+#endif /* GL_EXT_pvrtc_sRGB */
+
+#ifndef GL_EXT_raster_multisample
+#define GL_EXT_raster_multisample 1
+#define GL_RASTER_MULTISAMPLE_EXT 0x9327
+#define GL_RASTER_SAMPLES_EXT 0x9328
+#define GL_MAX_RASTER_SAMPLES_EXT 0x9329
+#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A
+#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B
+#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C
+typedef void (GL_APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_EXT_raster_multisample */
+
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#endif /* GL_EXT_read_format_bgra */
+
+#ifndef GL_EXT_render_snorm
+#define GL_EXT_render_snorm 1
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM_EXT 0x8F98
+#define GL_RG16_SNORM_EXT 0x8F99
+#define GL_RGBA16_SNORM_EXT 0x8F9B
+#endif /* GL_EXT_render_snorm */
+
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_EXT_robustness */
+
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif /* GL_EXT_sRGB */
+
+#ifndef GL_EXT_sRGB_write_control
+#define GL_EXT_sRGB_write_control 1
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#endif /* GL_EXT_sRGB_write_control */
+
+#ifndef GL_EXT_semaphore
+#define GL_EXT_semaphore 1
+#define GL_LAYOUT_GENERAL_EXT 0x958D
+#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E
+#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F
+#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590
+#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591
+#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592
+#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593
+typedef void (GL_APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores);
+typedef void (GL_APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores);
+typedef GLboolean (GL_APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore);
+typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+typedef void (GL_APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores);
+GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores);
+GL_APICALL GLboolean GL_APIENTRY glIsSemaphoreEXT (GLuint semaphore);
+GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params);
+GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params);
+GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#endif
+#endif /* GL_EXT_semaphore */
+
+#ifndef GL_EXT_semaphore_fd
+#define GL_EXT_semaphore_fd 1
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_semaphore_fd */
+
+#ifndef GL_EXT_semaphore_win32
+#define GL_EXT_semaphore_win32 1
+#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594
+#define GL_D3D12_FENCE_VALUE_EXT 0x9595
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle);
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle);
+GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_semaphore_win32 */
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#define GL_ACTIVE_PROGRAM_EXT 0x8259
+#define GL_VERTEX_SHADER_BIT_EXT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002
+#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE_EXT 0x8258
+#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A
+typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program);
+typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program);
+GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline);
+GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings);
+GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params);
+GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+#endif /* GL_EXT_separate_shader_objects */
+
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_EXT_shader_framebuffer_fetch 1
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#endif /* GL_EXT_shader_framebuffer_fetch */
+
+#ifndef GL_EXT_shader_group_vote
+#define GL_EXT_shader_group_vote 1
+#endif /* GL_EXT_shader_group_vote */
+
+#ifndef GL_EXT_shader_implicit_conversions
+#define GL_EXT_shader_implicit_conversions 1
+#endif /* GL_EXT_shader_implicit_conversions */
+
+#ifndef GL_EXT_shader_integer_mix
+#define GL_EXT_shader_integer_mix 1
+#endif /* GL_EXT_shader_integer_mix */
+
+#ifndef GL_EXT_shader_io_blocks
+#define GL_EXT_shader_io_blocks 1
+#endif /* GL_EXT_shader_io_blocks */
+
+#ifndef GL_EXT_shader_non_constant_global_initializers
+#define GL_EXT_shader_non_constant_global_initializers 1
+#endif /* GL_EXT_shader_non_constant_global_initializers */
+
+#ifndef GL_EXT_shader_pixel_local_storage
+#define GL_EXT_shader_pixel_local_storage 1
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67
+#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64
+#endif /* GL_EXT_shader_pixel_local_storage */
+
+#ifndef GL_EXT_shader_pixel_local_storage2
+#define GL_EXT_shader_pixel_local_storage2 1
+#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650
+#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651
+#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size);
+typedef GLsizei (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target);
+typedef void (GL_APIENTRYP PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageSizeEXT (GLuint target, GLsizei size);
+GL_APICALL GLsizei GL_APIENTRY glGetFramebufferPixelLocalStorageSizeEXT (GLuint target);
+GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsizei n, const GLuint *values);
+#endif
+#endif /* GL_EXT_shader_pixel_local_storage2 */
+
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+#endif /* GL_EXT_shader_texture_lod */
+
+#ifndef GL_EXT_shadow_samplers
+#define GL_EXT_shadow_samplers 1
+#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+#endif /* GL_EXT_shadow_samplers */
+
+#ifndef GL_EXT_sparse_texture
+#define GL_EXT_sparse_texture 1
+#define GL_TEXTURE_SPARSE_EXT 0x91A6
+#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7
+#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA
+#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8
+#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_3D 0x806F
+#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A
+#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9
+typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexPageCommitmentEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+#endif
+#endif /* GL_EXT_sparse_texture */
+
+#ifndef GL_EXT_sparse_texture2
+#define GL_EXT_sparse_texture2 1
+#endif /* GL_EXT_sparse_texture2 */
+
+#ifndef GL_EXT_tessellation_point_size
+#define GL_EXT_tessellation_point_size 1
+#endif /* GL_EXT_tessellation_point_size */
+
+#ifndef GL_EXT_tessellation_shader
+#define GL_EXT_tessellation_shader 1
+#define GL_PATCHES_EXT 0x000E
+#define GL_PATCH_VERTICES_EXT 0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75
+#define GL_TESS_GEN_MODE_EXT 0x8E76
+#define GL_TESS_GEN_SPACING_EXT 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78
+#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79
+#define GL_ISOLINES_EXT 0x8E7A
+#define GL_QUADS_EXT 0x0007
+#define GL_FRACTIONAL_ODD_EXT 0x8E7B
+#define GL_FRACTIONAL_EVEN_EXT 0x8E7C
+#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_IS_PER_PATCH_EXT 0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308
+#define GL_TESS_CONTROL_SHADER_EXT 0x8E88
+#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIEXTPROC) (GLenum pname, GLint value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPatchParameteriEXT (GLenum pname, GLint value);
+#endif
+#endif /* GL_EXT_tessellation_shader */
+
+#ifndef GL_EXT_texture_border_clamp
+#define GL_EXT_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004
+#define GL_CLAMP_TO_BORDER_EXT 0x812D
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivEXT (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivEXT (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivEXT (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivEXT (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+#endif /* GL_EXT_texture_border_clamp */
+
+#ifndef GL_EXT_texture_buffer
+#define GL_EXT_texture_buffer 1
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D
+#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E
+typedef void (GL_APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEEXTPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+#endif /* GL_EXT_texture_buffer */
+
+#ifndef GL_EXT_texture_compression_astc_decode_mode
+#define GL_EXT_texture_compression_astc_decode_mode 1
+#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69
+#endif /* GL_EXT_texture_compression_astc_decode_mode */
+
+#ifndef GL_EXT_texture_compression_bptc
+#define GL_EXT_texture_compression_bptc 1
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F
+#endif /* GL_EXT_texture_compression_bptc */
+
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif /* GL_EXT_texture_compression_rgtc */
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_EXT_texture_compression_s3tc 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif /* GL_EXT_texture_compression_s3tc */
+
+#ifndef GL_EXT_texture_compression_s3tc_srgb
+#define GL_EXT_texture_compression_s3tc_srgb 1
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif /* GL_EXT_texture_compression_s3tc_srgb */
+
+#ifndef GL_EXT_texture_cube_map_array
+#define GL_EXT_texture_cube_map_array 1
+#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#endif /* GL_EXT_texture_cube_map_array */
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+#ifndef GL_EXT_texture_filter_minmax
+#define GL_EXT_texture_filter_minmax 1
+#endif /* GL_EXT_texture_filter_minmax */
+
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif /* GL_EXT_texture_format_BGRA8888 */
+
+#ifndef GL_EXT_texture_norm16
+#define GL_EXT_texture_norm16 1
+#define GL_R16_EXT 0x822A
+#define GL_RG16_EXT 0x822C
+#define GL_RGBA16_EXT 0x805B
+#define GL_RGB16_EXT 0x8054
+#define GL_RGB16_SNORM_EXT 0x8F9A
+#endif /* GL_EXT_texture_norm16 */
+
+#ifndef GL_EXT_texture_rg
+#define GL_EXT_texture_rg 1
+#define GL_RED_EXT 0x1903
+#define GL_RG_EXT 0x8227
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#endif /* GL_EXT_texture_rg */
+
+#ifndef GL_EXT_texture_sRGB_R8
+#define GL_EXT_texture_sRGB_R8 1
+#define GL_SR8_EXT 0x8FBD
+#endif /* GL_EXT_texture_sRGB_R8 */
+
+#ifndef GL_EXT_texture_sRGB_RG8
+#define GL_EXT_texture_sRGB_RG8 1
+#define GL_SRG8_EXT 0x8FBE
+#endif /* GL_EXT_texture_sRGB_RG8 */
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_DECODE_EXT 0x8A49
+#define GL_SKIP_DECODE_EXT 0x8A4A
+#endif /* GL_EXT_texture_sRGB_decode */
+
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_R32F_EXT 0x822E
+#define GL_RG32F_EXT 0x8230
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+#endif /* GL_EXT_texture_storage */
+
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+#endif /* GL_EXT_texture_type_2_10_10_10_REV */
+
+#ifndef GL_EXT_texture_view
+#define GL_EXT_texture_view 1
+#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+#endif /* GL_EXT_texture_view */
+
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2
+#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4
+#endif /* GL_EXT_unpack_subimage */
+
+#ifndef GL_EXT_win32_keyed_mutex
+#define GL_EXT_win32_keyed_mutex 1
+typedef GLboolean (GL_APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout);
+typedef GLboolean (GL_APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLboolean GL_APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout);
+GL_APICALL GLboolean GL_APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key);
+#endif
+#endif /* GL_EXT_win32_keyed_mutex */
+
+#ifndef GL_EXT_window_rectangles
+#define GL_EXT_window_rectangles 1
+#define GL_INCLUSIVE_EXT 0x8F10
+#define GL_EXCLUSIVE_EXT 0x8F11
+#define GL_WINDOW_RECTANGLE_EXT 0x8F12
+#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13
+#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14
+#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15
+typedef void (GL_APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box);
+#endif
+#endif /* GL_EXT_window_rectangles */
+
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GL_FJ_shader_binary_GCCSO 1
+#define GL_GCCSO_SHADER_BINARY_FJ 0x9260
+#endif /* GL_FJ_shader_binary_GCCSO */
+
+#ifndef GL_IMG_bindless_texture
+#define GL_IMG_bindless_texture 1
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEIMGPROC) (GLuint texture, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64IMGPROC) (GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VIMGPROC) (GLint location, GLsizei count, const GLuint64 *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleIMG (GLuint texture);
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleIMG (GLuint texture, GLuint sampler);
+GL_APICALL void GL_APIENTRY glUniformHandleui64IMG (GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glUniformHandleui64vIMG (GLint location, GLsizei count, const GLuint64 *value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64IMG (GLuint program, GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vIMG (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+#endif
+#endif /* GL_IMG_bindless_texture */
+
+#ifndef GL_IMG_framebuffer_downsample
+#define GL_IMG_framebuffer_downsample 1
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C
+#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D
+#define GL_DOWNSAMPLE_SCALES_IMG 0x913E
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DDownsampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale);
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayerDownsampleIMG (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale);
+#endif
+#endif /* GL_IMG_framebuffer_downsample */
+
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_MAX_SAMPLES_IMG 0x9135
+#define GL_TEXTURE_SAMPLES_IMG 0x9136
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+#endif /* GL_IMG_multisampled_render_to_texture */
+
+#ifndef GL_IMG_program_binary
+#define GL_IMG_program_binary 1
+#define GL_SGX_PROGRAM_BINARY_IMG 0x9130
+#endif /* GL_IMG_program_binary */
+
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#define GL_BGRA_IMG 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365
+#endif /* GL_IMG_read_format */
+
+#ifndef GL_IMG_shader_binary
+#define GL_IMG_shader_binary 1
+#define GL_SGX_BINARY_IMG 0x8C0A
+#endif /* GL_IMG_shader_binary */
+
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#endif /* GL_IMG_texture_compression_pvrtc */
+
+#ifndef GL_IMG_texture_compression_pvrtc2
+#define GL_IMG_texture_compression_pvrtc2 1
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
+#endif /* GL_IMG_texture_compression_pvrtc2 */
+
+#ifndef GL_IMG_texture_filter_cubic
+#define GL_IMG_texture_filter_cubic 1
+#define GL_CUBIC_IMG 0x9139
+#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A
+#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B
+#endif /* GL_IMG_texture_filter_cubic */
+
+#ifndef GL_INTEL_conservative_rasterization
+#define GL_INTEL_conservative_rasterization 1
+#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
+#endif /* GL_INTEL_conservative_rasterization */
+
+#ifndef GL_INTEL_framebuffer_CMAA
+#define GL_INTEL_framebuffer_CMAA 1
+typedef void (GL_APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void);
+#endif
+#endif /* GL_INTEL_framebuffer_CMAA */
+
+#ifndef GL_INTEL_performance_query
+#define GL_INTEL_performance_query 1
+#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000
+#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001
+#define GL_PERFQUERY_WAIT_INTEL 0x83FB
+#define GL_PERFQUERY_FLUSH_INTEL 0x83FA
+#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9
+#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0
+#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1
+#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2
+#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3
+#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4
+#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5
+#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8
+#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9
+#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA
+#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB
+#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC
+#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD
+#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE
+#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF
+#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500
+typedef void (GL_APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId);
+typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId);
+typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle);
+GL_APICALL void GL_APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId);
+GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId);
+GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId);
+GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+#endif
+#endif /* GL_INTEL_performance_query */
+
+#ifndef GL_MESA_shader_integer_functions
+#define GL_MESA_shader_integer_functions 1
+#endif /* GL_MESA_shader_integer_functions */
+
+#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers
+#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1
+#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */
+
+#ifndef GL_NV_bindless_texture
+#define GL_NV_bindless_texture 1
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);
+typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef GLboolean (GL_APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleNV (GLuint texture);
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler);
+GL_APICALL void GL_APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle);
+GL_APICALL void GL_APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle);
+GL_APICALL GLuint64 GL_APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+GL_APICALL void GL_APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access);
+GL_APICALL void GL_APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle);
+GL_APICALL void GL_APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+GL_APICALL GLboolean GL_APIENTRY glIsTextureHandleResidentNV (GLuint64 handle);
+GL_APICALL GLboolean GL_APIENTRY glIsImageHandleResidentNV (GLuint64 handle);
+#endif
+#endif /* GL_NV_bindless_texture */
+
+#ifndef GL_NV_blend_equation_advanced
+#define GL_NV_blend_equation_advanced 1
+#define GL_BLEND_OVERLAP_NV 0x9281
+#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280
+#define GL_BLUE_NV 0x1905
+#define GL_COLORBURN_NV 0x929A
+#define GL_COLORDODGE_NV 0x9299
+#define GL_CONJOINT_NV 0x9284
+#define GL_CONTRAST_NV 0x92A1
+#define GL_DARKEN_NV 0x9297
+#define GL_DIFFERENCE_NV 0x929E
+#define GL_DISJOINT_NV 0x9283
+#define GL_DST_ATOP_NV 0x928F
+#define GL_DST_IN_NV 0x928B
+#define GL_DST_NV 0x9287
+#define GL_DST_OUT_NV 0x928D
+#define GL_DST_OVER_NV 0x9289
+#define GL_EXCLUSION_NV 0x92A0
+#define GL_GREEN_NV 0x1904
+#define GL_HARDLIGHT_NV 0x929B
+#define GL_HARDMIX_NV 0x92A9
+#define GL_HSL_COLOR_NV 0x92AF
+#define GL_HSL_HUE_NV 0x92AD
+#define GL_HSL_LUMINOSITY_NV 0x92B0
+#define GL_HSL_SATURATION_NV 0x92AE
+#define GL_INVERT_OVG_NV 0x92B4
+#define GL_INVERT_RGB_NV 0x92A3
+#define GL_LIGHTEN_NV 0x9298
+#define GL_LINEARBURN_NV 0x92A5
+#define GL_LINEARDODGE_NV 0x92A4
+#define GL_LINEARLIGHT_NV 0x92A7
+#define GL_MINUS_CLAMPED_NV 0x92B3
+#define GL_MINUS_NV 0x929F
+#define GL_MULTIPLY_NV 0x9294
+#define GL_OVERLAY_NV 0x9296
+#define GL_PINLIGHT_NV 0x92A8
+#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2
+#define GL_PLUS_CLAMPED_NV 0x92B1
+#define GL_PLUS_DARKER_NV 0x9292
+#define GL_PLUS_NV 0x9291
+#define GL_RED_NV 0x1903
+#define GL_SCREEN_NV 0x9295
+#define GL_SOFTLIGHT_NV 0x929C
+#define GL_SRC_ATOP_NV 0x928E
+#define GL_SRC_IN_NV 0x928A
+#define GL_SRC_NV 0x9286
+#define GL_SRC_OUT_NV 0x928C
+#define GL_SRC_OVER_NV 0x9288
+#define GL_UNCORRELATED_NV 0x9282
+#define GL_VIVIDLIGHT_NV 0x92A6
+#define GL_XOR_NV 0x1506
+typedef void (GL_APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLBLENDBARRIERNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlendParameteriNV (GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glBlendBarrierNV (void);
+#endif
+#endif /* GL_NV_blend_equation_advanced */
+
+#ifndef GL_NV_blend_equation_advanced_coherent
+#define GL_NV_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
+#endif /* GL_NV_blend_equation_advanced_coherent */
+
+#ifndef GL_NV_blend_minmax_factor
+#define GL_NV_blend_minmax_factor 1
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+#endif /* GL_NV_blend_minmax_factor */
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+typedef void (GL_APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GL_APICALL void GL_APIENTRY glEndConditionalRenderNV (void);
+#endif
+#endif /* GL_NV_conditional_render */
+
+#ifndef GL_NV_conservative_raster
+#define GL_NV_conservative_raster 1
+#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
+#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347
+#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348
+#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349
+typedef void (GL_APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits);
+#endif
+#endif /* GL_NV_conservative_raster */
+
+#ifndef GL_NV_conservative_raster_pre_snap_triangles
+#define GL_NV_conservative_raster_pre_snap_triangles 1
+#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D
+#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F
+typedef void (GL_APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param);
+#endif
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+
+#ifndef GL_NV_copy_buffer
+#define GL_NV_copy_buffer 1
+#define GL_COPY_READ_BUFFER_NV 0x8F36
+#define GL_COPY_WRITE_BUFFER_NV 0x8F37
+typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyBufferSubDataNV (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+#endif /* GL_NV_copy_buffer */
+
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#define GL_COVERAGE_COMPONENT_NV 0x8ED0
+#define GL_COVERAGE_COMPONENT4_NV 0x8ED1
+#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2
+#define GL_COVERAGE_BUFFERS_NV 0x8ED3
+#define GL_COVERAGE_SAMPLES_NV 0x8ED4
+#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5
+#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6
+#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7
+#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
+GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+#endif
+#endif /* GL_NV_coverage_sample */
+
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
+#endif /* GL_NV_depth_nonlinear */
+
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+#define GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define GL_DRAW_BUFFER0_NV 0x8825
+#define GL_DRAW_BUFFER1_NV 0x8826
+#define GL_DRAW_BUFFER2_NV 0x8827
+#define GL_DRAW_BUFFER3_NV 0x8828
+#define GL_DRAW_BUFFER4_NV 0x8829
+#define GL_DRAW_BUFFER5_NV 0x882A
+#define GL_DRAW_BUFFER6_NV 0x882B
+#define GL_DRAW_BUFFER7_NV 0x882C
+#define GL_DRAW_BUFFER8_NV 0x882D
+#define GL_DRAW_BUFFER9_NV 0x882E
+#define GL_DRAW_BUFFER10_NV 0x882F
+#define GL_DRAW_BUFFER11_NV 0x8830
+#define GL_DRAW_BUFFER12_NV 0x8831
+#define GL_DRAW_BUFFER13_NV 0x8832
+#define GL_DRAW_BUFFER14_NV 0x8833
+#define GL_DRAW_BUFFER15_NV 0x8834
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
+#endif
+#endif /* GL_NV_draw_buffers */
+
+#ifndef GL_NV_draw_instanced
+#define GL_NV_draw_instanced 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#endif
+#endif /* GL_NV_draw_instanced */
+
+#ifndef GL_NV_draw_vulkan_image
+#define GL_NV_draw_vulkan_image 1
+typedef void (GL_APIENTRY *GLVULKANPROCNV)(void);
+typedef void (GL_APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+typedef GLVULKANPROCNV (GL_APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+typedef void (GL_APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+typedef void (GL_APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+GL_APICALL GLVULKANPROCNV GL_APIENTRY glGetVkProcAddrNV (const GLchar *name);
+GL_APICALL void GL_APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore);
+GL_APICALL void GL_APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore);
+GL_APICALL void GL_APIENTRY glSignalVkFenceNV (GLuint64 vkFence);
+#endif
+#endif /* GL_NV_draw_vulkan_image */
+
+#ifndef GL_NV_explicit_attrib_location
+#define GL_NV_explicit_attrib_location 1
+#endif /* GL_NV_explicit_attrib_location */
+
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+#endif /* GL_NV_fbo_color_attachments */
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence);
+GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence);
+GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence);
+GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif
+#endif /* GL_NV_fence */
+
+#ifndef GL_NV_fill_rectangle
+#define GL_NV_fill_rectangle 1
+#define GL_FILL_RECTANGLE_NV 0x933C
+#endif /* GL_NV_fill_rectangle */
+
+#ifndef GL_NV_fragment_coverage_to_color
+#define GL_NV_fragment_coverage_to_color 1
+#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD
+#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE
+typedef void (GL_APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFragmentCoverageColorNV (GLuint color);
+#endif
+#endif /* GL_NV_fragment_coverage_to_color */
+
+#ifndef GL_NV_fragment_shader_interlock
+#define GL_NV_fragment_shader_interlock 1
+#endif /* GL_NV_fragment_shader_interlock */
+
+#ifndef GL_NV_framebuffer_blit
+#define GL_NV_framebuffer_blit 1
+#define GL_READ_FRAMEBUFFER_NV 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+#endif /* GL_NV_framebuffer_blit */
+
+#ifndef GL_NV_framebuffer_mixed_samples
+#define GL_NV_framebuffer_mixed_samples 1
+#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#define GL_DEPTH_SAMPLES_NV 0x932D
+#define GL_STENCIL_SAMPLES_NV 0x932E
+#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F
+#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330
+#define GL_COVERAGE_MODULATION_NV 0x9332
+#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v);
+GL_APICALL void GL_APIENTRY glCoverageModulationNV (GLenum components);
+#endif
+#endif /* GL_NV_framebuffer_mixed_samples */
+
+#ifndef GL_NV_framebuffer_multisample
+#define GL_NV_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56
+#define GL_MAX_SAMPLES_NV 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_NV_framebuffer_multisample */
+
+#ifndef GL_NV_generate_mipmap_sRGB
+#define GL_NV_generate_mipmap_sRGB 1
+#endif /* GL_NV_generate_mipmap_sRGB */
+
+#ifndef GL_NV_geometry_shader_passthrough
+#define GL_NV_geometry_shader_passthrough 1
+#endif /* GL_NV_geometry_shader_passthrough */
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+typedef khronos_int64_t GLint64EXT;
+typedef khronos_uint64_t GLuint64EXT;
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+#define GL_PATCHES 0x000E
+typedef void (GL_APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);
+GL_APICALL void GL_APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);
+GL_APICALL void GL_APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GL_APICALL void GL_APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GL_APICALL void GL_APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);
+GL_APICALL void GL_APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);
+GL_APICALL void GL_APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GL_APICALL void GL_APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GL_APICALL void GL_APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);
+GL_APICALL void GL_APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);
+GL_APICALL void GL_APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+GL_APICALL void GL_APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GL_APICALL void GL_APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GL_APICALL void GL_APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);
+GL_APICALL void GL_APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+GL_APICALL void GL_APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GL_APICALL void GL_APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GL_APICALL void GL_APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+#endif /* GL_NV_gpu_shader5 */
+
+#ifndef GL_NV_image_formats
+#define GL_NV_image_formats 1
+#endif /* GL_NV_image_formats */
+
+#ifndef GL_NV_instanced_arrays
+#define GL_NV_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor);
+#endif
+#endif /* GL_NV_instanced_arrays */
+
+#ifndef GL_NV_internalformat_sample_query
+#define GL_NV_internalformat_sample_query 1
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_MULTISAMPLES_NV 0x9371
+#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372
+#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373
+#define GL_CONFORMANT_NV 0x9374
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_NV_internalformat_sample_query */
+
+#ifndef GL_NV_non_square_matrices
+#define GL_NV_non_square_matrices 1
+#define GL_FLOAT_MAT2x3_NV 0x8B65
+#define GL_FLOAT_MAT2x4_NV 0x8B66
+#define GL_FLOAT_MAT3x2_NV 0x8B67
+#define GL_FLOAT_MAT3x4_NV 0x8B68
+#define GL_FLOAT_MAT4x2_NV 0x8B69
+#define GL_FLOAT_MAT4x3_NV 0x8B6A
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+#endif /* GL_NV_non_square_matrices */
+
+#ifndef GL_NV_path_rendering
+#define GL_NV_path_rendering 1
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_LINE_TO_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_BOLD_BIT_NV 0x01
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define GL_ROUNDED_RECT_NV 0xE8
+#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9
+#define GL_ROUNDED_RECT2_NV 0xEA
+#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB
+#define GL_ROUNDED_RECT4_NV 0xEC
+#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED
+#define GL_ROUNDED_RECT8_NV 0xEE
+#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF
+#define GL_RELATIVE_RECT_NV 0xF7
+#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368
+#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369
+#define GL_FONT_UNAVAILABLE_NV 0x936A
+#define GL_FONT_UNINTELLIGIBLE_NV 0x936B
+#define GL_CONIC_CURVE_TO_NV 0x1A
+#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B
+#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000
+#define GL_STANDARD_FONT_FORMAT_NV 0x936C
+#define GL_PATH_PROJECTION_NV 0x1701
+#define GL_PATH_MODELVIEW_NV 0x1700
+#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3
+#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6
+#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36
+#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3
+#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4
+#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7
+#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38
+#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4
+#define GL_FRAGMENT_INPUT_NV 0x936D
+typedef GLuint (GL_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range);
+typedef void (GL_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);
+typedef GLboolean (GL_APIENTRYP PFNGLISPATHNVPROC) (GLuint path);
+typedef void (GL_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString);
+typedef void (GL_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+typedef void (GL_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);
+typedef void (GL_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+typedef void (GL_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);
+typedef void (GL_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+typedef void (GL_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value);
+typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands);
+typedef void (GL_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords);
+typedef void (GL_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray);
+typedef void (GL_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+typedef void (GL_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+typedef void (GL_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);
+typedef GLfloat (GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);
+typedef GLboolean (GL_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range);
+GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range);
+GL_APICALL GLboolean GL_APIENTRY glIsPathNV (GLuint path);
+GL_APICALL void GL_APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString);
+GL_APICALL void GL_APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+GL_APICALL void GL_APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath);
+GL_APICALL void GL_APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+GL_APICALL void GL_APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value);
+GL_APICALL void GL_APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value);
+GL_APICALL void GL_APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+GL_APICALL void GL_APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glPathCoverDepthFuncNV (GLenum func);
+GL_APICALL void GL_APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value);
+GL_APICALL void GL_APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value);
+GL_APICALL void GL_APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands);
+GL_APICALL void GL_APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords);
+GL_APICALL void GL_APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray);
+GL_APICALL void GL_APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+GL_APICALL void GL_APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+GL_APICALL void GL_APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+GL_APICALL GLboolean GL_APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+GL_APICALL GLboolean GL_APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y);
+GL_APICALL GLfloat GL_APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments);
+GL_APICALL GLboolean GL_APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+GL_APICALL void GL_APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+#endif
+#endif /* GL_NV_path_rendering */
+
+#ifndef GL_NV_path_rendering_shared_edge
+#define GL_NV_path_rendering_shared_edge 1
+#define GL_SHARED_EDGE_NV 0xC0
+#endif /* GL_NV_path_rendering_shared_edge */
+
+#ifndef GL_NV_pixel_buffer_object
+#define GL_NV_pixel_buffer_object 1
+#define GL_PIXEL_PACK_BUFFER_NV 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF
+#endif /* GL_NV_pixel_buffer_object */
+
+#ifndef GL_NV_polygon_mode
+#define GL_NV_polygon_mode 1
+#define GL_POLYGON_MODE_NV 0x0B40
+#define GL_POLYGON_OFFSET_POINT_NV 0x2A01
+#define GL_POLYGON_OFFSET_LINE_NV 0x2A02
+#define GL_POINT_NV 0x1B00
+#define GL_LINE_NV 0x1B01
+#define GL_FILL_NV 0x1B02
+typedef void (GL_APIENTRYP PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPolygonModeNV (GLenum face, GLenum mode);
+#endif
+#endif /* GL_NV_polygon_mode */
+
+#ifndef GL_NV_read_buffer
+#define GL_NV_read_buffer 1
+#define GL_READ_BUFFER_NV 0x0C02
+typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
+#endif
+#endif /* GL_NV_read_buffer */
+
+#ifndef GL_NV_read_buffer_front
+#define GL_NV_read_buffer_front 1
+#endif /* GL_NV_read_buffer_front */
+
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
+#endif /* GL_NV_read_depth */
+
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+#endif /* GL_NV_read_depth_stencil */
+
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+#endif /* GL_NV_read_stencil */
+
+#ifndef GL_NV_sRGB_formats
+#define GL_NV_sRGB_formats 1
+#define GL_SLUMINANCE_NV 0x8C46
+#define GL_SLUMINANCE_ALPHA_NV 0x8C44
+#define GL_SRGB8_NV 0x8C41
+#define GL_SLUMINANCE8_NV 0x8C47
+#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
+#define GL_ETC1_SRGB8_NV 0x88EE
+#endif /* GL_NV_sRGB_formats */
+
+#ifndef GL_NV_sample_locations
+#define GL_NV_sample_locations 1
+#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340
+#define GL_SAMPLE_LOCATION_NV 0x8E50
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341
+#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342
+#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void);
+#endif
+#endif /* GL_NV_sample_locations */
+
+#ifndef GL_NV_sample_mask_override_coverage
+#define GL_NV_sample_mask_override_coverage 1
+#endif /* GL_NV_sample_mask_override_coverage */
+
+#ifndef GL_NV_shader_atomic_fp16_vector
+#define GL_NV_shader_atomic_fp16_vector 1
+#endif /* GL_NV_shader_atomic_fp16_vector */
+
+#ifndef GL_NV_shader_noperspective_interpolation
+#define GL_NV_shader_noperspective_interpolation 1
+#endif /* GL_NV_shader_noperspective_interpolation */
+
+#ifndef GL_NV_shadow_samplers_array
+#define GL_NV_shadow_samplers_array 1
+#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
+#endif /* GL_NV_shadow_samplers_array */
+
+#ifndef GL_NV_shadow_samplers_cube
+#define GL_NV_shadow_samplers_cube 1
+#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
+#endif /* GL_NV_shadow_samplers_cube */
+
+#ifndef GL_NV_texture_border_clamp
+#define GL_NV_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_NV 0x1004
+#define GL_CLAMP_TO_BORDER_NV 0x812D
+#endif /* GL_NV_texture_border_clamp */
+
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+#endif /* GL_NV_texture_compression_s3tc_update */
+
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
+#endif /* GL_NV_texture_npot_2D_mipmap */
+
+#ifndef GL_NV_viewport_array
+#define GL_NV_viewport_array 1
+#define GL_MAX_VIEWPORTS_NV 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F
+typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLENABLEINVPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEINVPROC) (GLenum target, GLuint index);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDINVPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportArrayvNV (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glViewportIndexedfNV (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GL_APICALL void GL_APIENTRY glViewportIndexedfvNV (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glScissorArrayvNV (GLuint first, GLsizei count, const GLint *v);
+GL_APICALL void GL_APIENTRY glScissorIndexedNV (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorIndexedvNV (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glDepthRangeArrayfvNV (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glDepthRangeIndexedfNV (GLuint index, GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glGetFloati_vNV (GLenum target, GLuint index, GLfloat *data);
+GL_APICALL void GL_APIENTRY glEnableiNV (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiNV (GLenum target, GLuint index);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediNV (GLenum target, GLuint index);
+#endif
+#endif /* GL_NV_viewport_array */
+
+#ifndef GL_NV_viewport_array2
+#define GL_NV_viewport_array2 1
+#endif /* GL_NV_viewport_array2 */
+
+#ifndef GL_NV_viewport_swizzle
+#define GL_NV_viewport_swizzle 1
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357
+#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358
+#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359
+#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A
+#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B
+typedef void (GL_APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);
+#endif
+#endif /* GL_NV_viewport_swizzle */
+
+#ifndef GL_OVR_multiview
+#define GL_OVR_multiview 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632
+#define GL_MAX_VIEWS_OVR 0x9631
+#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+#endif
+#endif /* GL_OVR_multiview */
+
+#ifndef GL_OVR_multiview2
+#define GL_OVR_multiview2 1
+#endif /* GL_OVR_multiview2 */
+
+#ifndef GL_OVR_multiview_multisampled_render_to_texture
+#define GL_OVR_multiview_multisampled_render_to_texture 1
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+#endif
+#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+#define GL_ALPHA_TEST_QCOM 0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM 0x0BC2
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref);
+#endif
+#endif /* GL_QCOM_alpha_test */
+
+#ifndef GL_QCOM_binning_control
+#define GL_QCOM_binning_control 1
+#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0
+#define GL_CPU_OPTIMIZED_QCOM 0x8FB1
+#define GL_GPU_OPTIMIZED_QCOM 0x8FB2
+#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+#endif /* GL_QCOM_binning_control */
+
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
+GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
+GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
+#endif
+#endif /* GL_QCOM_driver_control */
+
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#define GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define GL_STATE_RESTORE 0x8BDC
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures);
+GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, void **params);
+#endif
+#endif /* GL_QCOM_extended_get */
+
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program);
+GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+#endif /* GL_QCOM_extended_get2 */
+
+#ifndef GL_QCOM_framebuffer_foveated
+#define GL_QCOM_framebuffer_foveated 1
+#define GL_FOVEATION_ENABLE_BIT_QCOM 0x00000001
+#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x00000002
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFoveationConfigQCOM (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures);
+GL_APICALL void GL_APIENTRY glFramebufferFoveationParametersQCOM (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#endif
+#endif /* GL_QCOM_framebuffer_foveated */
+
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+#endif /* GL_QCOM_perfmon_global_mode */
+
+#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent
+#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1
+#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierQCOM (void);
+#endif
+#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */
+
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
+typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
+#endif
+#endif /* GL_QCOM_tiled_rendering */
+
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#define GL_WRITEONLY_RENDERING_QCOM 0x8823
+#endif /* GL_QCOM_writeonly_rendering */
+
+#ifndef GL_VIV_shader_binary
+#define GL_VIV_shader_binary 1
+#define GL_SHADER_BINARY_VIV 0x8FC4
+#endif /* GL_VIV_shader_binary */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2platform.h b/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2platform.h
new file mode 100644
index 0000000..eb318dc
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/GLES2/gl2platform.h
@@ -0,0 +1,38 @@
+#ifndef __gl2platform_h_
+#define __gl2platform_h_
+
+/*
+** Copyright (c) 2017 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * Please contribute modifications back to Khronos as pull requests on the
+ * public github repository:
+ * https://github.com/KhronosGroup/OpenGL-Registry
+ */
+
+#include <KHR/khrplatform.h>
+
+#ifndef GL_APICALL
+#define GL_APICALL KHRONOS_APICALL
+#endif
+
+#ifndef GL_APIENTRY
+#define GL_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#endif /* __gl2platform_h_ */
diff --git a/source/3rd-party/SDL2/src/video/khronos/KHR/khrplatform.h b/source/3rd-party/SDL2/src/video/khronos/KHR/khrplatform.h
new file mode 100644
index 0000000..1ad3554
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/KHR/khrplatform.h
@@ -0,0 +1,284 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by sending them to the public Khronos Bugzilla
+ * (http://khronos.org/bugzilla) by filing a bug against product
+ * "Khronos (general)" component "Registry".
+ *
+ * A predefined template which fills in some of the bug fields can be
+ * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
+ * must create a Bugzilla login first.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include <KHR/khrplatform.h>
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#elif defined(__ANDROID__)
+# define KHRONOS_APICALL __attribute__((visibility("default")))
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using <stdint.h>
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using <inttypes.h>
+ */
+#include <inttypes.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef _WIN64
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/source/3rd-party/SDL2/src/video/khronos/vulkan/vk_platform.h b/source/3rd-party/SDL2/src/video/khronos/vulkan/vk_platform.h
new file mode 100644
index 0000000..72f8049
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/vulkan/vk_platform.h
@@ -0,0 +1,120 @@
+//
+// File: vk_platform.h
+//
+/*
+** Copyright (c) 2014-2017 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+
+#ifndef VK_PLATFORM_H_
+#define VK_PLATFORM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+* Platform-specific directives and type declarations
+***************************************************************************************************
+*/
+
+/* Platform-specific calling convention macros.
+ *
+ * Platforms should define these so that Vulkan clients call Vulkan commands
+ * with the same calling conventions that the Vulkan implementation expects.
+ *
+ * VKAPI_ATTR - Placed before the return type in function declarations.
+ * Useful for C++11 and GCC/Clang-style function attribute syntax.
+ * VKAPI_CALL - Placed after the return type in function declarations.
+ * Useful for MSVC-style calling convention syntax.
+ * VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
+ *
+ * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
+ * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
+ */
+#if defined(_WIN32)
+ // On Windows, Vulkan commands use the stdcall convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
+ #error "Vulkan isn't supported for the 'armeabi' NDK ABI"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
+ // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
+ // calling convention, i.e. float parameters are passed in registers. This
+ // is true even if the rest of the application passes floats on the stack,
+ // as it does by default when compiling for the armeabi-v7a NDK ABI.
+ #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+ #define VKAPI_CALL
+ #define VKAPI_PTR VKAPI_ATTR
+#else
+ // On other platforms, use the default calling convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+#endif
+
+#include <stddef.h>
+
+#if !defined(VK_NO_STDINT_H)
+ #if defined(_MSC_VER) && (_MSC_VER < 1600)
+ typedef signed __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef signed __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ #else
+ #include <stdint.h>
+ #endif
+#endif // !defined(VK_NO_STDINT_H)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+// Platform-specific headers required by platform window system extensions.
+// These are enabled prior to #including "vulkan.h". The same enable then
+// controls inclusion of the extension interfaces in vulkan.h.
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <android/native_window.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#include <mir_toolkit/client_types.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include <wayland-client.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include <windows.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#include <X11/Xlib.h>
+#endif
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#include <xcb/xcb.h>
+#endif
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/khronos/vulkan/vulkan.h b/source/3rd-party/SDL2/src/video/khronos/vulkan/vulkan.h
new file mode 100644
index 0000000..04495fa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/khronos/vulkan/vulkan.h
@@ -0,0 +1,6458 @@
+#ifndef VULKAN_H_
+#define VULKAN_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2015-2017 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*
+** This header is generated from the Khronos Vulkan XML API Registry.
+**
+*/
+
+
+#define VK_VERSION_1_0 1
+#include "./vk_platform.h"
+
+#define VK_MAKE_VERSION(major, minor, patch) \
+ (((major) << 22) | ((minor) << 12) | (patch))
+
+// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead.
+//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0
+
+// Vulkan 1.0 version number
+#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0)// Patch version should always be set to 0
+
+#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
+#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
+#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
+// Version of this file
+#define VK_HEADER_VERSION 59
+
+
+#define VK_NULL_HANDLE 0
+
+
+
+#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+
+#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
+#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+#else
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+#endif
+#endif
+
+
+
+typedef uint32_t VkFlags;
+typedef uint32_t VkBool32;
+typedef uint64_t VkDeviceSize;
+typedef uint32_t VkSampleMask;
+
+VK_DEFINE_HANDLE(VkInstance)
+VK_DEFINE_HANDLE(VkPhysicalDevice)
+VK_DEFINE_HANDLE(VkDevice)
+VK_DEFINE_HANDLE(VkQueue)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
+VK_DEFINE_HANDLE(VkCommandBuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
+
+#define VK_LOD_CLAMP_NONE 1000.0f
+#define VK_REMAINING_MIP_LEVELS (~0U)
+#define VK_REMAINING_ARRAY_LAYERS (~0U)
+#define VK_WHOLE_SIZE (~0ULL)
+#define VK_ATTACHMENT_UNUSED (~0U)
+#define VK_TRUE 1
+#define VK_FALSE 0
+#define VK_QUEUE_FAMILY_IGNORED (~0U)
+#define VK_SUBPASS_EXTERNAL (~0U)
+#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
+#define VK_UUID_SIZE 16
+#define VK_MAX_MEMORY_TYPES 32
+#define VK_MAX_MEMORY_HEAPS 16
+#define VK_MAX_EXTENSION_NAME_SIZE 256
+#define VK_MAX_DESCRIPTION_SIZE 256
+
+
+typedef enum VkPipelineCacheHeaderVersion {
+ VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
+ VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE,
+ VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE,
+ VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1),
+ VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCacheHeaderVersion;
+
+typedef enum VkResult {
+ VK_SUCCESS = 0,
+ VK_NOT_READY = 1,
+ VK_TIMEOUT = 2,
+ VK_EVENT_SET = 3,
+ VK_EVENT_RESET = 4,
+ VK_INCOMPLETE = 5,
+ VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+ VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+ VK_ERROR_INITIALIZATION_FAILED = -3,
+ VK_ERROR_DEVICE_LOST = -4,
+ VK_ERROR_MEMORY_MAP_FAILED = -5,
+ VK_ERROR_LAYER_NOT_PRESENT = -6,
+ VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+ VK_ERROR_FEATURE_NOT_PRESENT = -8,
+ VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+ VK_ERROR_TOO_MANY_OBJECTS = -10,
+ VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+ VK_ERROR_FRAGMENTED_POOL = -12,
+ VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+ VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+ VK_SUBOPTIMAL_KHR = 1000001003,
+ VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+ VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
+ VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
+ VK_ERROR_INVALID_SHADER_NV = -1000012000,
+ VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000,
+ VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = -1000072003,
+ VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL,
+ VK_RESULT_END_RANGE = VK_INCOMPLETE,
+ VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1),
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+} VkResult;
+
+typedef enum VkStructureType {
+ VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
+ VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
+ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
+ VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
+ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
+ VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
+ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
+ VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
+ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
+ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
+ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
+ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
+ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
+ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
+ VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
+ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
+ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
+ VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
+ VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
+ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
+ VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000,
+ VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001,
+ VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000,
+ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
+ VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
+ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
+ VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
+ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000,
+ VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
+ VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001,
+ VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002,
+ VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
+ VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
+ VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
+ VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
+ VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX = 1000053000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX = 1000053001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHX = 1000053002,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
+ VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = 1000059000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = 1000059001,
+ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = 1000059002,
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = 1000059003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = 1000059004,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000059005,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = 1000059006,
+ VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = 1000059007,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = 1000059008,
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHX = 1000060000,
+ VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHX = 1000060001,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHX = 1000060002,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHX = 1000060003,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHX = 1000060004,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHX = 1000060005,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHX = 1000060006,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHX = 1000060007,
+ VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHX = 1000060008,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHX = 1000060009,
+ VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHX = 1000060010,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHX = 1000060011,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHX = 1000060012,
+ VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
+ VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX = 1000070000,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHX = 1000070001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = 1000071000,
+ VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = 1000071001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = 1000071002,
+ VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = 1000071003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = 1000071004,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = 1000072000,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = 1000072001,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = 1000072002,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001,
+ VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002,
+ VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000,
+ VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001,
+ VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002,
+ VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = 1000076000,
+ VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = 1000076001,
+ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = 1000077000,
+ VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000,
+ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001,
+ VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002,
+ VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003,
+ VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000,
+ VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = 1000083000,
+ VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = 1000085000,
+ VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000,
+ VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001,
+ VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002,
+ VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003,
+ VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004,
+ VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000,
+ VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000,
+ VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001,
+ VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003,
+ VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000,
+ VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001,
+ VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
+ VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = 1000112000,
+ VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = 1000112001,
+ VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = 1000113000,
+ VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
+ VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
+ VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002,
+ VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000,
+ VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
+ VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = 1000120000,
+ VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
+ VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = 1000127000,
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = 1000127001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000,
+ VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146000,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146001,
+ VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = 1000146002,
+ VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = 1000146003,
+ VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = 1000146004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
+ VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000,
+ VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
+ VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+ VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
+ VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkStructureType;
+
+typedef enum VkSystemAllocationScope {
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
+ VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4,
+ VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND,
+ VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE,
+ VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1),
+ VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF
+} VkSystemAllocationScope;
+
+typedef enum VkInternalAllocationType {
+ VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0,
+ VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE,
+ VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE,
+ VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1),
+ VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkInternalAllocationType;
+
+typedef enum VkFormat {
+ VK_FORMAT_UNDEFINED = 0,
+ VK_FORMAT_R4G4_UNORM_PACK8 = 1,
+ VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
+ VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
+ VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
+ VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
+ VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
+ VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
+ VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
+ VK_FORMAT_R8_UNORM = 9,
+ VK_FORMAT_R8_SNORM = 10,
+ VK_FORMAT_R8_USCALED = 11,
+ VK_FORMAT_R8_SSCALED = 12,
+ VK_FORMAT_R8_UINT = 13,
+ VK_FORMAT_R8_SINT = 14,
+ VK_FORMAT_R8_SRGB = 15,
+ VK_FORMAT_R8G8_UNORM = 16,
+ VK_FORMAT_R8G8_SNORM = 17,
+ VK_FORMAT_R8G8_USCALED = 18,
+ VK_FORMAT_R8G8_SSCALED = 19,
+ VK_FORMAT_R8G8_UINT = 20,
+ VK_FORMAT_R8G8_SINT = 21,
+ VK_FORMAT_R8G8_SRGB = 22,
+ VK_FORMAT_R8G8B8_UNORM = 23,
+ VK_FORMAT_R8G8B8_SNORM = 24,
+ VK_FORMAT_R8G8B8_USCALED = 25,
+ VK_FORMAT_R8G8B8_SSCALED = 26,
+ VK_FORMAT_R8G8B8_UINT = 27,
+ VK_FORMAT_R8G8B8_SINT = 28,
+ VK_FORMAT_R8G8B8_SRGB = 29,
+ VK_FORMAT_B8G8R8_UNORM = 30,
+ VK_FORMAT_B8G8R8_SNORM = 31,
+ VK_FORMAT_B8G8R8_USCALED = 32,
+ VK_FORMAT_B8G8R8_SSCALED = 33,
+ VK_FORMAT_B8G8R8_UINT = 34,
+ VK_FORMAT_B8G8R8_SINT = 35,
+ VK_FORMAT_B8G8R8_SRGB = 36,
+ VK_FORMAT_R8G8B8A8_UNORM = 37,
+ VK_FORMAT_R8G8B8A8_SNORM = 38,
+ VK_FORMAT_R8G8B8A8_USCALED = 39,
+ VK_FORMAT_R8G8B8A8_SSCALED = 40,
+ VK_FORMAT_R8G8B8A8_UINT = 41,
+ VK_FORMAT_R8G8B8A8_SINT = 42,
+ VK_FORMAT_R8G8B8A8_SRGB = 43,
+ VK_FORMAT_B8G8R8A8_UNORM = 44,
+ VK_FORMAT_B8G8R8A8_SNORM = 45,
+ VK_FORMAT_B8G8R8A8_USCALED = 46,
+ VK_FORMAT_B8G8R8A8_SSCALED = 47,
+ VK_FORMAT_B8G8R8A8_UINT = 48,
+ VK_FORMAT_B8G8R8A8_SINT = 49,
+ VK_FORMAT_B8G8R8A8_SRGB = 50,
+ VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
+ VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
+ VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
+ VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
+ VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
+ VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
+ VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
+ VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
+ VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
+ VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
+ VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
+ VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
+ VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
+ VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
+ VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
+ VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
+ VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
+ VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
+ VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
+ VK_FORMAT_R16_UNORM = 70,
+ VK_FORMAT_R16_SNORM = 71,
+ VK_FORMAT_R16_USCALED = 72,
+ VK_FORMAT_R16_SSCALED = 73,
+ VK_FORMAT_R16_UINT = 74,
+ VK_FORMAT_R16_SINT = 75,
+ VK_FORMAT_R16_SFLOAT = 76,
+ VK_FORMAT_R16G16_UNORM = 77,
+ VK_FORMAT_R16G16_SNORM = 78,
+ VK_FORMAT_R16G16_USCALED = 79,
+ VK_FORMAT_R16G16_SSCALED = 80,
+ VK_FORMAT_R16G16_UINT = 81,
+ VK_FORMAT_R16G16_SINT = 82,
+ VK_FORMAT_R16G16_SFLOAT = 83,
+ VK_FORMAT_R16G16B16_UNORM = 84,
+ VK_FORMAT_R16G16B16_SNORM = 85,
+ VK_FORMAT_R16G16B16_USCALED = 86,
+ VK_FORMAT_R16G16B16_SSCALED = 87,
+ VK_FORMAT_R16G16B16_UINT = 88,
+ VK_FORMAT_R16G16B16_SINT = 89,
+ VK_FORMAT_R16G16B16_SFLOAT = 90,
+ VK_FORMAT_R16G16B16A16_UNORM = 91,
+ VK_FORMAT_R16G16B16A16_SNORM = 92,
+ VK_FORMAT_R16G16B16A16_USCALED = 93,
+ VK_FORMAT_R16G16B16A16_SSCALED = 94,
+ VK_FORMAT_R16G16B16A16_UINT = 95,
+ VK_FORMAT_R16G16B16A16_SINT = 96,
+ VK_FORMAT_R16G16B16A16_SFLOAT = 97,
+ VK_FORMAT_R32_UINT = 98,
+ VK_FORMAT_R32_SINT = 99,
+ VK_FORMAT_R32_SFLOAT = 100,
+ VK_FORMAT_R32G32_UINT = 101,
+ VK_FORMAT_R32G32_SINT = 102,
+ VK_FORMAT_R32G32_SFLOAT = 103,
+ VK_FORMAT_R32G32B32_UINT = 104,
+ VK_FORMAT_R32G32B32_SINT = 105,
+ VK_FORMAT_R32G32B32_SFLOAT = 106,
+ VK_FORMAT_R32G32B32A32_UINT = 107,
+ VK_FORMAT_R32G32B32A32_SINT = 108,
+ VK_FORMAT_R32G32B32A32_SFLOAT = 109,
+ VK_FORMAT_R64_UINT = 110,
+ VK_FORMAT_R64_SINT = 111,
+ VK_FORMAT_R64_SFLOAT = 112,
+ VK_FORMAT_R64G64_UINT = 113,
+ VK_FORMAT_R64G64_SINT = 114,
+ VK_FORMAT_R64G64_SFLOAT = 115,
+ VK_FORMAT_R64G64B64_UINT = 116,
+ VK_FORMAT_R64G64B64_SINT = 117,
+ VK_FORMAT_R64G64B64_SFLOAT = 118,
+ VK_FORMAT_R64G64B64A64_UINT = 119,
+ VK_FORMAT_R64G64B64A64_SINT = 120,
+ VK_FORMAT_R64G64B64A64_SFLOAT = 121,
+ VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
+ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
+ VK_FORMAT_D16_UNORM = 124,
+ VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
+ VK_FORMAT_D32_SFLOAT = 126,
+ VK_FORMAT_S8_UINT = 127,
+ VK_FORMAT_D16_UNORM_S8_UINT = 128,
+ VK_FORMAT_D24_UNORM_S8_UINT = 129,
+ VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
+ VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
+ VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
+ VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
+ VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
+ VK_FORMAT_BC2_UNORM_BLOCK = 135,
+ VK_FORMAT_BC2_SRGB_BLOCK = 136,
+ VK_FORMAT_BC3_UNORM_BLOCK = 137,
+ VK_FORMAT_BC3_SRGB_BLOCK = 138,
+ VK_FORMAT_BC4_UNORM_BLOCK = 139,
+ VK_FORMAT_BC4_SNORM_BLOCK = 140,
+ VK_FORMAT_BC5_UNORM_BLOCK = 141,
+ VK_FORMAT_BC5_SNORM_BLOCK = 142,
+ VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
+ VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
+ VK_FORMAT_BC7_UNORM_BLOCK = 145,
+ VK_FORMAT_BC7_SRGB_BLOCK = 146,
+ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
+ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
+ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
+ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
+ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
+ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
+ VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
+ VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
+ VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
+ VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
+ VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
+ VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
+ VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
+ VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
+ VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
+ VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
+ VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
+ VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
+ VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
+ VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
+ VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
+ VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
+ VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
+ VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
+ VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
+ VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
+ VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
+ VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
+ VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
+ VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
+ VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
+ VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
+ VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
+ VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
+ VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
+ VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
+ VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
+ VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
+ VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
+ VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
+ VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
+ VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
+ VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
+ VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
+ VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
+ VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
+ VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED,
+ VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
+ VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1),
+ VK_FORMAT_MAX_ENUM = 0x7FFFFFFF
+} VkFormat;
+
+typedef enum VkImageType {
+ VK_IMAGE_TYPE_1D = 0,
+ VK_IMAGE_TYPE_2D = 1,
+ VK_IMAGE_TYPE_3D = 2,
+ VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D,
+ VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D,
+ VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1),
+ VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageType;
+
+typedef enum VkImageTiling {
+ VK_IMAGE_TILING_OPTIMAL = 0,
+ VK_IMAGE_TILING_LINEAR = 1,
+ VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL,
+ VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR,
+ VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1),
+ VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF
+} VkImageTiling;
+
+typedef enum VkPhysicalDeviceType {
+ VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
+ VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
+ VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
+ VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
+ VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
+ VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER,
+ VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU,
+ VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1),
+ VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkPhysicalDeviceType;
+
+typedef enum VkQueryType {
+ VK_QUERY_TYPE_OCCLUSION = 0,
+ VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
+ VK_QUERY_TYPE_TIMESTAMP = 2,
+ VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION,
+ VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP,
+ VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1),
+ VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkQueryType;
+
+typedef enum VkSharingMode {
+ VK_SHARING_MODE_EXCLUSIVE = 0,
+ VK_SHARING_MODE_CONCURRENT = 1,
+ VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE,
+ VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT,
+ VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1),
+ VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSharingMode;
+
+typedef enum VkImageLayout {
+ VK_IMAGE_LAYOUT_UNDEFINED = 0,
+ VK_IMAGE_LAYOUT_GENERAL = 1,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7,
+ VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
+ VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
+ VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED,
+ VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1),
+ VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF
+} VkImageLayout;
+
+typedef enum VkImageViewType {
+ VK_IMAGE_VIEW_TYPE_1D = 0,
+ VK_IMAGE_VIEW_TYPE_2D = 1,
+ VK_IMAGE_VIEW_TYPE_3D = 2,
+ VK_IMAGE_VIEW_TYPE_CUBE = 3,
+ VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,
+ VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,
+ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6,
+ VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D,
+ VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,
+ VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1),
+ VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageViewType;
+
+typedef enum VkComponentSwizzle {
+ VK_COMPONENT_SWIZZLE_IDENTITY = 0,
+ VK_COMPONENT_SWIZZLE_ZERO = 1,
+ VK_COMPONENT_SWIZZLE_ONE = 2,
+ VK_COMPONENT_SWIZZLE_R = 3,
+ VK_COMPONENT_SWIZZLE_G = 4,
+ VK_COMPONENT_SWIZZLE_B = 5,
+ VK_COMPONENT_SWIZZLE_A = 6,
+ VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A,
+ VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1),
+ VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF
+} VkComponentSwizzle;
+
+typedef enum VkVertexInputRate {
+ VK_VERTEX_INPUT_RATE_VERTEX = 0,
+ VK_VERTEX_INPUT_RATE_INSTANCE = 1,
+ VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX,
+ VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE,
+ VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1),
+ VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF
+} VkVertexInputRate;
+
+typedef enum VkPrimitiveTopology {
+ VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
+ VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,
+ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,
+ VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6,
+ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9,
+ VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10,
+ VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
+ VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
+ VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1),
+ VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF
+} VkPrimitiveTopology;
+
+typedef enum VkPolygonMode {
+ VK_POLYGON_MODE_FILL = 0,
+ VK_POLYGON_MODE_LINE = 1,
+ VK_POLYGON_MODE_POINT = 2,
+ VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000,
+ VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL,
+ VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT,
+ VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1),
+ VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkPolygonMode;
+
+typedef enum VkFrontFace {
+ VK_FRONT_FACE_COUNTER_CLOCKWISE = 0,
+ VK_FRONT_FACE_CLOCKWISE = 1,
+ VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE,
+ VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE,
+ VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1),
+ VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF
+} VkFrontFace;
+
+typedef enum VkCompareOp {
+ VK_COMPARE_OP_NEVER = 0,
+ VK_COMPARE_OP_LESS = 1,
+ VK_COMPARE_OP_EQUAL = 2,
+ VK_COMPARE_OP_LESS_OR_EQUAL = 3,
+ VK_COMPARE_OP_GREATER = 4,
+ VK_COMPARE_OP_NOT_EQUAL = 5,
+ VK_COMPARE_OP_GREATER_OR_EQUAL = 6,
+ VK_COMPARE_OP_ALWAYS = 7,
+ VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER,
+ VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS,
+ VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1),
+ VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF
+} VkCompareOp;
+
+typedef enum VkStencilOp {
+ VK_STENCIL_OP_KEEP = 0,
+ VK_STENCIL_OP_ZERO = 1,
+ VK_STENCIL_OP_REPLACE = 2,
+ VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3,
+ VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4,
+ VK_STENCIL_OP_INVERT = 5,
+ VK_STENCIL_OP_INCREMENT_AND_WRAP = 6,
+ VK_STENCIL_OP_DECREMENT_AND_WRAP = 7,
+ VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP,
+ VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP,
+ VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1),
+ VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF
+} VkStencilOp;
+
+typedef enum VkLogicOp {
+ VK_LOGIC_OP_CLEAR = 0,
+ VK_LOGIC_OP_AND = 1,
+ VK_LOGIC_OP_AND_REVERSE = 2,
+ VK_LOGIC_OP_COPY = 3,
+ VK_LOGIC_OP_AND_INVERTED = 4,
+ VK_LOGIC_OP_NO_OP = 5,
+ VK_LOGIC_OP_XOR = 6,
+ VK_LOGIC_OP_OR = 7,
+ VK_LOGIC_OP_NOR = 8,
+ VK_LOGIC_OP_EQUIVALENT = 9,
+ VK_LOGIC_OP_INVERT = 10,
+ VK_LOGIC_OP_OR_REVERSE = 11,
+ VK_LOGIC_OP_COPY_INVERTED = 12,
+ VK_LOGIC_OP_OR_INVERTED = 13,
+ VK_LOGIC_OP_NAND = 14,
+ VK_LOGIC_OP_SET = 15,
+ VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR,
+ VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET,
+ VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1),
+ VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF
+} VkLogicOp;
+
+typedef enum VkBlendFactor {
+ VK_BLEND_FACTOR_ZERO = 0,
+ VK_BLEND_FACTOR_ONE = 1,
+ VK_BLEND_FACTOR_SRC_COLOR = 2,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3,
+ VK_BLEND_FACTOR_DST_COLOR = 4,
+ VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5,
+ VK_BLEND_FACTOR_SRC_ALPHA = 6,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7,
+ VK_BLEND_FACTOR_DST_ALPHA = 8,
+ VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9,
+ VK_BLEND_FACTOR_CONSTANT_COLOR = 10,
+ VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11,
+ VK_BLEND_FACTOR_CONSTANT_ALPHA = 12,
+ VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13,
+ VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14,
+ VK_BLEND_FACTOR_SRC1_COLOR = 15,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16,
+ VK_BLEND_FACTOR_SRC1_ALPHA = 17,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18,
+ VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO,
+ VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA,
+ VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1),
+ VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF
+} VkBlendFactor;
+
+typedef enum VkBlendOp {
+ VK_BLEND_OP_ADD = 0,
+ VK_BLEND_OP_SUBTRACT = 1,
+ VK_BLEND_OP_REVERSE_SUBTRACT = 2,
+ VK_BLEND_OP_MIN = 3,
+ VK_BLEND_OP_MAX = 4,
+ VK_BLEND_OP_ZERO_EXT = 1000148000,
+ VK_BLEND_OP_SRC_EXT = 1000148001,
+ VK_BLEND_OP_DST_EXT = 1000148002,
+ VK_BLEND_OP_SRC_OVER_EXT = 1000148003,
+ VK_BLEND_OP_DST_OVER_EXT = 1000148004,
+ VK_BLEND_OP_SRC_IN_EXT = 1000148005,
+ VK_BLEND_OP_DST_IN_EXT = 1000148006,
+ VK_BLEND_OP_SRC_OUT_EXT = 1000148007,
+ VK_BLEND_OP_DST_OUT_EXT = 1000148008,
+ VK_BLEND_OP_SRC_ATOP_EXT = 1000148009,
+ VK_BLEND_OP_DST_ATOP_EXT = 1000148010,
+ VK_BLEND_OP_XOR_EXT = 1000148011,
+ VK_BLEND_OP_MULTIPLY_EXT = 1000148012,
+ VK_BLEND_OP_SCREEN_EXT = 1000148013,
+ VK_BLEND_OP_OVERLAY_EXT = 1000148014,
+ VK_BLEND_OP_DARKEN_EXT = 1000148015,
+ VK_BLEND_OP_LIGHTEN_EXT = 1000148016,
+ VK_BLEND_OP_COLORDODGE_EXT = 1000148017,
+ VK_BLEND_OP_COLORBURN_EXT = 1000148018,
+ VK_BLEND_OP_HARDLIGHT_EXT = 1000148019,
+ VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020,
+ VK_BLEND_OP_DIFFERENCE_EXT = 1000148021,
+ VK_BLEND_OP_EXCLUSION_EXT = 1000148022,
+ VK_BLEND_OP_INVERT_EXT = 1000148023,
+ VK_BLEND_OP_INVERT_RGB_EXT = 1000148024,
+ VK_BLEND_OP_LINEARDODGE_EXT = 1000148025,
+ VK_BLEND_OP_LINEARBURN_EXT = 1000148026,
+ VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027,
+ VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028,
+ VK_BLEND_OP_PINLIGHT_EXT = 1000148029,
+ VK_BLEND_OP_HARDMIX_EXT = 1000148030,
+ VK_BLEND_OP_HSL_HUE_EXT = 1000148031,
+ VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032,
+ VK_BLEND_OP_HSL_COLOR_EXT = 1000148033,
+ VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034,
+ VK_BLEND_OP_PLUS_EXT = 1000148035,
+ VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036,
+ VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037,
+ VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038,
+ VK_BLEND_OP_MINUS_EXT = 1000148039,
+ VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040,
+ VK_BLEND_OP_CONTRAST_EXT = 1000148041,
+ VK_BLEND_OP_INVERT_OVG_EXT = 1000148042,
+ VK_BLEND_OP_RED_EXT = 1000148043,
+ VK_BLEND_OP_GREEN_EXT = 1000148044,
+ VK_BLEND_OP_BLUE_EXT = 1000148045,
+ VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD,
+ VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX,
+ VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1),
+ VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF
+} VkBlendOp;
+
+typedef enum VkDynamicState {
+ VK_DYNAMIC_STATE_VIEWPORT = 0,
+ VK_DYNAMIC_STATE_SCISSOR = 1,
+ VK_DYNAMIC_STATE_LINE_WIDTH = 2,
+ VK_DYNAMIC_STATE_DEPTH_BIAS = 3,
+ VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4,
+ VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5,
+ VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
+ VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
+ VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8,
+ VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000,
+ VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
+ VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT,
+ VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+ VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1),
+ VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF
+} VkDynamicState;
+
+typedef enum VkFilter {
+ VK_FILTER_NEAREST = 0,
+ VK_FILTER_LINEAR = 1,
+ VK_FILTER_CUBIC_IMG = 1000015000,
+ VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST,
+ VK_FILTER_END_RANGE = VK_FILTER_LINEAR,
+ VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1),
+ VK_FILTER_MAX_ENUM = 0x7FFFFFFF
+} VkFilter;
+
+typedef enum VkSamplerMipmapMode {
+ VK_SAMPLER_MIPMAP_MODE_NEAREST = 0,
+ VK_SAMPLER_MIPMAP_MODE_LINEAR = 1,
+ VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST,
+ VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR,
+ VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1),
+ VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerMipmapMode;
+
+typedef enum VkSamplerAddressMode {
+ VK_SAMPLER_ADDRESS_MODE_REPEAT = 0,
+ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1,
+ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2,
+ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3,
+ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4,
+ VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT,
+ VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
+ VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1),
+ VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerAddressMode;
+
+typedef enum VkBorderColor {
+ VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0,
+ VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1,
+ VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2,
+ VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3,
+ VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4,
+ VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5,
+ VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
+ VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE,
+ VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1),
+ VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF
+} VkBorderColor;
+
+typedef enum VkDescriptorType {
+ VK_DESCRIPTOR_TYPE_SAMPLER = 0,
+ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1,
+ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2,
+ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3,
+ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4,
+ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5,
+ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6,
+ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7,
+ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8,
+ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
+ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10,
+ VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER,
+ VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
+ VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1),
+ VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorType;
+
+typedef enum VkAttachmentLoadOp {
+ VK_ATTACHMENT_LOAD_OP_LOAD = 0,
+ VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
+ VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD,
+ VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+ VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1),
+ VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentLoadOp;
+
+typedef enum VkAttachmentStoreOp {
+ VK_ATTACHMENT_STORE_OP_STORE = 0,
+ VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
+ VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE,
+ VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+ VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1),
+ VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentStoreOp;
+
+typedef enum VkPipelineBindPoint {
+ VK_PIPELINE_BIND_POINT_GRAPHICS = 0,
+ VK_PIPELINE_BIND_POINT_COMPUTE = 1,
+ VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS,
+ VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE,
+ VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1),
+ VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineBindPoint;
+
+typedef enum VkCommandBufferLevel {
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0,
+ VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1,
+ VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY,
+ VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1),
+ VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF
+} VkCommandBufferLevel;
+
+typedef enum VkIndexType {
+ VK_INDEX_TYPE_UINT16 = 0,
+ VK_INDEX_TYPE_UINT32 = 1,
+ VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16,
+ VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32,
+ VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1),
+ VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkIndexType;
+
+typedef enum VkSubpassContents {
+ VK_SUBPASS_CONTENTS_INLINE = 0,
+ VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1,
+ VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE,
+ VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS,
+ VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1),
+ VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF
+} VkSubpassContents;
+
+typedef enum VkObjectType {
+ VK_OBJECT_TYPE_UNKNOWN = 0,
+ VK_OBJECT_TYPE_INSTANCE = 1,
+ VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
+ VK_OBJECT_TYPE_DEVICE = 3,
+ VK_OBJECT_TYPE_QUEUE = 4,
+ VK_OBJECT_TYPE_SEMAPHORE = 5,
+ VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
+ VK_OBJECT_TYPE_FENCE = 7,
+ VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
+ VK_OBJECT_TYPE_BUFFER = 9,
+ VK_OBJECT_TYPE_IMAGE = 10,
+ VK_OBJECT_TYPE_EVENT = 11,
+ VK_OBJECT_TYPE_QUERY_POOL = 12,
+ VK_OBJECT_TYPE_BUFFER_VIEW = 13,
+ VK_OBJECT_TYPE_IMAGE_VIEW = 14,
+ VK_OBJECT_TYPE_SHADER_MODULE = 15,
+ VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
+ VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
+ VK_OBJECT_TYPE_RENDER_PASS = 18,
+ VK_OBJECT_TYPE_PIPELINE = 19,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
+ VK_OBJECT_TYPE_SAMPLER = 21,
+ VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
+ VK_OBJECT_TYPE_FRAMEBUFFER = 24,
+ VK_OBJECT_TYPE_COMMAND_POOL = 25,
+ VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+ VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
+ VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
+ VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
+ VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
+ VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = 1000085000,
+ VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000,
+ VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001,
+ VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN,
+ VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_COMMAND_POOL,
+ VK_OBJECT_TYPE_RANGE_SIZE = (VK_OBJECT_TYPE_COMMAND_POOL - VK_OBJECT_TYPE_UNKNOWN + 1),
+ VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkObjectType;
+
+typedef VkFlags VkInstanceCreateFlags;
+
+typedef enum VkFormatFeatureFlagBits {
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001,
+ VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002,
+ VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004,
+ VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008,
+ VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010,
+ VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020,
+ VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040,
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080,
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100,
+ VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200,
+ VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400,
+ VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000,
+ VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = 0x00004000,
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = 0x00008000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000,
+ VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkFormatFeatureFlagBits;
+typedef VkFlags VkFormatFeatureFlags;
+
+typedef enum VkImageUsageFlagBits {
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001,
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002,
+ VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004,
+ VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008,
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010,
+ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
+ VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
+ VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageUsageFlagBits;
+typedef VkFlags VkImageUsageFlags;
+
+typedef enum VkImageCreateFlagBits {
+ VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+ VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+ VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+ VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
+ VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
+ VK_IMAGE_CREATE_BIND_SFR_BIT_KHX = 0x00000040,
+ VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = 0x00000020,
+ VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageCreateFlagBits;
+typedef VkFlags VkImageCreateFlags;
+
+typedef enum VkSampleCountFlagBits {
+ VK_SAMPLE_COUNT_1_BIT = 0x00000001,
+ VK_SAMPLE_COUNT_2_BIT = 0x00000002,
+ VK_SAMPLE_COUNT_4_BIT = 0x00000004,
+ VK_SAMPLE_COUNT_8_BIT = 0x00000008,
+ VK_SAMPLE_COUNT_16_BIT = 0x00000010,
+ VK_SAMPLE_COUNT_32_BIT = 0x00000020,
+ VK_SAMPLE_COUNT_64_BIT = 0x00000040,
+ VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSampleCountFlagBits;
+typedef VkFlags VkSampleCountFlags;
+
+typedef enum VkQueueFlagBits {
+ VK_QUEUE_GRAPHICS_BIT = 0x00000001,
+ VK_QUEUE_COMPUTE_BIT = 0x00000002,
+ VK_QUEUE_TRANSFER_BIT = 0x00000004,
+ VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
+ VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueueFlagBits;
+typedef VkFlags VkQueueFlags;
+
+typedef enum VkMemoryPropertyFlagBits {
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002,
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004,
+ VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008,
+ VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010,
+ VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkMemoryPropertyFlagBits;
+typedef VkFlags VkMemoryPropertyFlags;
+
+typedef enum VkMemoryHeapFlagBits {
+ VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001,
+ VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX = 0x00000002,
+ VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkMemoryHeapFlagBits;
+typedef VkFlags VkMemoryHeapFlags;
+typedef VkFlags VkDeviceCreateFlags;
+typedef VkFlags VkDeviceQueueCreateFlags;
+
+typedef enum VkPipelineStageFlagBits {
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001,
+ VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002,
+ VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004,
+ VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008,
+ VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010,
+ VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020,
+ VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080,
+ VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100,
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400,
+ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800,
+ VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000,
+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000,
+ VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
+ VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
+ VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000,
+ VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineStageFlagBits;
+typedef VkFlags VkPipelineStageFlags;
+typedef VkFlags VkMemoryMapFlags;
+
+typedef enum VkImageAspectFlagBits {
+ VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001,
+ VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002,
+ VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004,
+ VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008,
+ VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageAspectFlagBits;
+typedef VkFlags VkImageAspectFlags;
+
+typedef enum VkSparseImageFormatFlagBits {
+ VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001,
+ VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002,
+ VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004,
+ VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSparseImageFormatFlagBits;
+typedef VkFlags VkSparseImageFormatFlags;
+
+typedef enum VkSparseMemoryBindFlagBits {
+ VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001,
+ VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSparseMemoryBindFlagBits;
+typedef VkFlags VkSparseMemoryBindFlags;
+
+typedef enum VkFenceCreateFlagBits {
+ VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001,
+ VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkFenceCreateFlagBits;
+typedef VkFlags VkFenceCreateFlags;
+typedef VkFlags VkSemaphoreCreateFlags;
+typedef VkFlags VkEventCreateFlags;
+typedef VkFlags VkQueryPoolCreateFlags;
+
+typedef enum VkQueryPipelineStatisticFlagBits {
+ VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001,
+ VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002,
+ VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004,
+ VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008,
+ VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010,
+ VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020,
+ VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040,
+ VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080,
+ VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100,
+ VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200,
+ VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400,
+ VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueryPipelineStatisticFlagBits;
+typedef VkFlags VkQueryPipelineStatisticFlags;
+
+typedef enum VkQueryResultFlagBits {
+ VK_QUERY_RESULT_64_BIT = 0x00000001,
+ VK_QUERY_RESULT_WAIT_BIT = 0x00000002,
+ VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004,
+ VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008,
+ VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueryResultFlagBits;
+typedef VkFlags VkQueryResultFlags;
+
+typedef enum VkBufferCreateFlagBits {
+ VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+ VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+ VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+ VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkBufferCreateFlagBits;
+typedef VkFlags VkBufferCreateFlags;
+
+typedef enum VkBufferUsageFlagBits {
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001,
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002,
+ VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004,
+ VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008,
+ VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010,
+ VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020,
+ VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
+ VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
+ VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
+ VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkBufferUsageFlagBits;
+typedef VkFlags VkBufferUsageFlags;
+typedef VkFlags VkBufferViewCreateFlags;
+typedef VkFlags VkImageViewCreateFlags;
+typedef VkFlags VkShaderModuleCreateFlags;
+typedef VkFlags VkPipelineCacheCreateFlags;
+
+typedef enum VkPipelineCreateFlagBits {
+ VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001,
+ VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002,
+ VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
+ VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHX = 0x00000008,
+ VK_PIPELINE_CREATE_DISPATCH_BASE_KHX = 0x00000010,
+ VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCreateFlagBits;
+typedef VkFlags VkPipelineCreateFlags;
+typedef VkFlags VkPipelineShaderStageCreateFlags;
+
+typedef enum VkShaderStageFlagBits {
+ VK_SHADER_STAGE_VERTEX_BIT = 0x00000001,
+ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002,
+ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004,
+ VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008,
+ VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010,
+ VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
+ VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
+ VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
+ VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkShaderStageFlagBits;
+typedef VkFlags VkPipelineVertexInputStateCreateFlags;
+typedef VkFlags VkPipelineInputAssemblyStateCreateFlags;
+typedef VkFlags VkPipelineTessellationStateCreateFlags;
+typedef VkFlags VkPipelineViewportStateCreateFlags;
+typedef VkFlags VkPipelineRasterizationStateCreateFlags;
+
+typedef enum VkCullModeFlagBits {
+ VK_CULL_MODE_NONE = 0,
+ VK_CULL_MODE_FRONT_BIT = 0x00000001,
+ VK_CULL_MODE_BACK_BIT = 0x00000002,
+ VK_CULL_MODE_FRONT_AND_BACK = 0x00000003,
+ VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCullModeFlagBits;
+typedef VkFlags VkCullModeFlags;
+typedef VkFlags VkPipelineMultisampleStateCreateFlags;
+typedef VkFlags VkPipelineDepthStencilStateCreateFlags;
+typedef VkFlags VkPipelineColorBlendStateCreateFlags;
+
+typedef enum VkColorComponentFlagBits {
+ VK_COLOR_COMPONENT_R_BIT = 0x00000001,
+ VK_COLOR_COMPONENT_G_BIT = 0x00000002,
+ VK_COLOR_COMPONENT_B_BIT = 0x00000004,
+ VK_COLOR_COMPONENT_A_BIT = 0x00000008,
+ VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkColorComponentFlagBits;
+typedef VkFlags VkColorComponentFlags;
+typedef VkFlags VkPipelineDynamicStateCreateFlags;
+typedef VkFlags VkPipelineLayoutCreateFlags;
+typedef VkFlags VkShaderStageFlags;
+typedef VkFlags VkSamplerCreateFlags;
+
+typedef enum VkDescriptorSetLayoutCreateFlagBits {
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorSetLayoutCreateFlagBits;
+typedef VkFlags VkDescriptorSetLayoutCreateFlags;
+
+typedef enum VkDescriptorPoolCreateFlagBits {
+ VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
+ VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorPoolCreateFlagBits;
+typedef VkFlags VkDescriptorPoolCreateFlags;
+typedef VkFlags VkDescriptorPoolResetFlags;
+typedef VkFlags VkFramebufferCreateFlags;
+typedef VkFlags VkRenderPassCreateFlags;
+
+typedef enum VkAttachmentDescriptionFlagBits {
+ VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001,
+ VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentDescriptionFlagBits;
+typedef VkFlags VkAttachmentDescriptionFlags;
+
+typedef enum VkSubpassDescriptionFlagBits {
+ VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001,
+ VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002,
+ VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSubpassDescriptionFlagBits;
+typedef VkFlags VkSubpassDescriptionFlags;
+
+typedef enum VkAccessFlagBits {
+ VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001,
+ VK_ACCESS_INDEX_READ_BIT = 0x00000002,
+ VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004,
+ VK_ACCESS_UNIFORM_READ_BIT = 0x00000008,
+ VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010,
+ VK_ACCESS_SHADER_READ_BIT = 0x00000020,
+ VK_ACCESS_SHADER_WRITE_BIT = 0x00000040,
+ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100,
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200,
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400,
+ VK_ACCESS_TRANSFER_READ_BIT = 0x00000800,
+ VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000,
+ VK_ACCESS_HOST_READ_BIT = 0x00002000,
+ VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
+ VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
+ VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
+ VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000,
+ VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000,
+ VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
+ VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkAccessFlagBits;
+typedef VkFlags VkAccessFlags;
+
+typedef enum VkDependencyFlagBits {
+ VK_DEPENDENCY_BY_REGION_BIT = 0x00000001,
+ VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX = 0x00000002,
+ VK_DEPENDENCY_DEVICE_GROUP_BIT_KHX = 0x00000004,
+ VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDependencyFlagBits;
+typedef VkFlags VkDependencyFlags;
+
+typedef enum VkCommandPoolCreateFlagBits {
+ VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001,
+ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002,
+ VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandPoolCreateFlagBits;
+typedef VkFlags VkCommandPoolCreateFlags;
+
+typedef enum VkCommandPoolResetFlagBits {
+ VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
+ VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandPoolResetFlagBits;
+typedef VkFlags VkCommandPoolResetFlags;
+
+typedef enum VkCommandBufferUsageFlagBits {
+ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001,
+ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002,
+ VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004,
+ VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandBufferUsageFlagBits;
+typedef VkFlags VkCommandBufferUsageFlags;
+
+typedef enum VkQueryControlFlagBits {
+ VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001,
+ VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueryControlFlagBits;
+typedef VkFlags VkQueryControlFlags;
+
+typedef enum VkCommandBufferResetFlagBits {
+ VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
+ VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandBufferResetFlagBits;
+typedef VkFlags VkCommandBufferResetFlags;
+
+typedef enum VkStencilFaceFlagBits {
+ VK_STENCIL_FACE_FRONT_BIT = 0x00000001,
+ VK_STENCIL_FACE_BACK_BIT = 0x00000002,
+ VK_STENCIL_FRONT_AND_BACK = 0x00000003,
+ VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkStencilFaceFlagBits;
+typedef VkFlags VkStencilFaceFlags;
+
+typedef struct VkApplicationInfo {
+ VkStructureType sType;
+ const void* pNext;
+ const char* pApplicationName;
+ uint32_t applicationVersion;
+ const char* pEngineName;
+ uint32_t engineVersion;
+ uint32_t apiVersion;
+} VkApplicationInfo;
+
+typedef struct VkInstanceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkInstanceCreateFlags flags;
+ const VkApplicationInfo* pApplicationInfo;
+ uint32_t enabledLayerCount;
+ const char* const* ppEnabledLayerNames;
+ uint32_t enabledExtensionCount;
+ const char* const* ppEnabledExtensionNames;
+} VkInstanceCreateInfo;
+
+typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
+ void* pUserData,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope);
+
+typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)(
+ void* pUserData,
+ void* pOriginal,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkFreeFunction)(
+ void* pUserData,
+ void* pMemory);
+
+typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)(
+ void* pUserData,
+ size_t size,
+ VkInternalAllocationType allocationType,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)(
+ void* pUserData,
+ size_t size,
+ VkInternalAllocationType allocationType,
+ VkSystemAllocationScope allocationScope);
+
+typedef struct VkAllocationCallbacks {
+ void* pUserData;
+ PFN_vkAllocationFunction pfnAllocation;
+ PFN_vkReallocationFunction pfnReallocation;
+ PFN_vkFreeFunction pfnFree;
+ PFN_vkInternalAllocationNotification pfnInternalAllocation;
+ PFN_vkInternalFreeNotification pfnInternalFree;
+} VkAllocationCallbacks;
+
+typedef struct VkPhysicalDeviceFeatures {
+ VkBool32 robustBufferAccess;
+ VkBool32 fullDrawIndexUint32;
+ VkBool32 imageCubeArray;
+ VkBool32 independentBlend;
+ VkBool32 geometryShader;
+ VkBool32 tessellationShader;
+ VkBool32 sampleRateShading;
+ VkBool32 dualSrcBlend;
+ VkBool32 logicOp;
+ VkBool32 multiDrawIndirect;
+ VkBool32 drawIndirectFirstInstance;
+ VkBool32 depthClamp;
+ VkBool32 depthBiasClamp;
+ VkBool32 fillModeNonSolid;
+ VkBool32 depthBounds;
+ VkBool32 wideLines;
+ VkBool32 largePoints;
+ VkBool32 alphaToOne;
+ VkBool32 multiViewport;
+ VkBool32 samplerAnisotropy;
+ VkBool32 textureCompressionETC2;
+ VkBool32 textureCompressionASTC_LDR;
+ VkBool32 textureCompressionBC;
+ VkBool32 occlusionQueryPrecise;
+ VkBool32 pipelineStatisticsQuery;
+ VkBool32 vertexPipelineStoresAndAtomics;
+ VkBool32 fragmentStoresAndAtomics;
+ VkBool32 shaderTessellationAndGeometryPointSize;
+ VkBool32 shaderImageGatherExtended;
+ VkBool32 shaderStorageImageExtendedFormats;
+ VkBool32 shaderStorageImageMultisample;
+ VkBool32 shaderStorageImageReadWithoutFormat;
+ VkBool32 shaderStorageImageWriteWithoutFormat;
+ VkBool32 shaderUniformBufferArrayDynamicIndexing;
+ VkBool32 shaderSampledImageArrayDynamicIndexing;
+ VkBool32 shaderStorageBufferArrayDynamicIndexing;
+ VkBool32 shaderStorageImageArrayDynamicIndexing;
+ VkBool32 shaderClipDistance;
+ VkBool32 shaderCullDistance;
+ VkBool32 shaderFloat64;
+ VkBool32 shaderInt64;
+ VkBool32 shaderInt16;
+ VkBool32 shaderResourceResidency;
+ VkBool32 shaderResourceMinLod;
+ VkBool32 sparseBinding;
+ VkBool32 sparseResidencyBuffer;
+ VkBool32 sparseResidencyImage2D;
+ VkBool32 sparseResidencyImage3D;
+ VkBool32 sparseResidency2Samples;
+ VkBool32 sparseResidency4Samples;
+ VkBool32 sparseResidency8Samples;
+ VkBool32 sparseResidency16Samples;
+ VkBool32 sparseResidencyAliased;
+ VkBool32 variableMultisampleRate;
+ VkBool32 inheritedQueries;
+} VkPhysicalDeviceFeatures;
+
+typedef struct VkFormatProperties {
+ VkFormatFeatureFlags linearTilingFeatures;
+ VkFormatFeatureFlags optimalTilingFeatures;
+ VkFormatFeatureFlags bufferFeatures;
+} VkFormatProperties;
+
+typedef struct VkExtent3D {
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+} VkExtent3D;
+
+typedef struct VkImageFormatProperties {
+ VkExtent3D maxExtent;
+ uint32_t maxMipLevels;
+ uint32_t maxArrayLayers;
+ VkSampleCountFlags sampleCounts;
+ VkDeviceSize maxResourceSize;
+} VkImageFormatProperties;
+
+typedef struct VkPhysicalDeviceLimits {
+ uint32_t maxImageDimension1D;
+ uint32_t maxImageDimension2D;
+ uint32_t maxImageDimension3D;
+ uint32_t maxImageDimensionCube;
+ uint32_t maxImageArrayLayers;
+ uint32_t maxTexelBufferElements;
+ uint32_t maxUniformBufferRange;
+ uint32_t maxStorageBufferRange;
+ uint32_t maxPushConstantsSize;
+ uint32_t maxMemoryAllocationCount;
+ uint32_t maxSamplerAllocationCount;
+ VkDeviceSize bufferImageGranularity;
+ VkDeviceSize sparseAddressSpaceSize;
+ uint32_t maxBoundDescriptorSets;
+ uint32_t maxPerStageDescriptorSamplers;
+ uint32_t maxPerStageDescriptorUniformBuffers;
+ uint32_t maxPerStageDescriptorStorageBuffers;
+ uint32_t maxPerStageDescriptorSampledImages;
+ uint32_t maxPerStageDescriptorStorageImages;
+ uint32_t maxPerStageDescriptorInputAttachments;
+ uint32_t maxPerStageResources;
+ uint32_t maxDescriptorSetSamplers;
+ uint32_t maxDescriptorSetUniformBuffers;
+ uint32_t maxDescriptorSetUniformBuffersDynamic;
+ uint32_t maxDescriptorSetStorageBuffers;
+ uint32_t maxDescriptorSetStorageBuffersDynamic;
+ uint32_t maxDescriptorSetSampledImages;
+ uint32_t maxDescriptorSetStorageImages;
+ uint32_t maxDescriptorSetInputAttachments;
+ uint32_t maxVertexInputAttributes;
+ uint32_t maxVertexInputBindings;
+ uint32_t maxVertexInputAttributeOffset;
+ uint32_t maxVertexInputBindingStride;
+ uint32_t maxVertexOutputComponents;
+ uint32_t maxTessellationGenerationLevel;
+ uint32_t maxTessellationPatchSize;
+ uint32_t maxTessellationControlPerVertexInputComponents;
+ uint32_t maxTessellationControlPerVertexOutputComponents;
+ uint32_t maxTessellationControlPerPatchOutputComponents;
+ uint32_t maxTessellationControlTotalOutputComponents;
+ uint32_t maxTessellationEvaluationInputComponents;
+ uint32_t maxTessellationEvaluationOutputComponents;
+ uint32_t maxGeometryShaderInvocations;
+ uint32_t maxGeometryInputComponents;
+ uint32_t maxGeometryOutputComponents;
+ uint32_t maxGeometryOutputVertices;
+ uint32_t maxGeometryTotalOutputComponents;
+ uint32_t maxFragmentInputComponents;
+ uint32_t maxFragmentOutputAttachments;
+ uint32_t maxFragmentDualSrcAttachments;
+ uint32_t maxFragmentCombinedOutputResources;
+ uint32_t maxComputeSharedMemorySize;
+ uint32_t maxComputeWorkGroupCount[3];
+ uint32_t maxComputeWorkGroupInvocations;
+ uint32_t maxComputeWorkGroupSize[3];
+ uint32_t subPixelPrecisionBits;
+ uint32_t subTexelPrecisionBits;
+ uint32_t mipmapPrecisionBits;
+ uint32_t maxDrawIndexedIndexValue;
+ uint32_t maxDrawIndirectCount;
+ float maxSamplerLodBias;
+ float maxSamplerAnisotropy;
+ uint32_t maxViewports;
+ uint32_t maxViewportDimensions[2];
+ float viewportBoundsRange[2];
+ uint32_t viewportSubPixelBits;
+ size_t minMemoryMapAlignment;
+ VkDeviceSize minTexelBufferOffsetAlignment;
+ VkDeviceSize minUniformBufferOffsetAlignment;
+ VkDeviceSize minStorageBufferOffsetAlignment;
+ int32_t minTexelOffset;
+ uint32_t maxTexelOffset;
+ int32_t minTexelGatherOffset;
+ uint32_t maxTexelGatherOffset;
+ float minInterpolationOffset;
+ float maxInterpolationOffset;
+ uint32_t subPixelInterpolationOffsetBits;
+ uint32_t maxFramebufferWidth;
+ uint32_t maxFramebufferHeight;
+ uint32_t maxFramebufferLayers;
+ VkSampleCountFlags framebufferColorSampleCounts;
+ VkSampleCountFlags framebufferDepthSampleCounts;
+ VkSampleCountFlags framebufferStencilSampleCounts;
+ VkSampleCountFlags framebufferNoAttachmentsSampleCounts;
+ uint32_t maxColorAttachments;
+ VkSampleCountFlags sampledImageColorSampleCounts;
+ VkSampleCountFlags sampledImageIntegerSampleCounts;
+ VkSampleCountFlags sampledImageDepthSampleCounts;
+ VkSampleCountFlags sampledImageStencilSampleCounts;
+ VkSampleCountFlags storageImageSampleCounts;
+ uint32_t maxSampleMaskWords;
+ VkBool32 timestampComputeAndGraphics;
+ float timestampPeriod;
+ uint32_t maxClipDistances;
+ uint32_t maxCullDistances;
+ uint32_t maxCombinedClipAndCullDistances;
+ uint32_t discreteQueuePriorities;
+ float pointSizeRange[2];
+ float lineWidthRange[2];
+ float pointSizeGranularity;
+ float lineWidthGranularity;
+ VkBool32 strictLines;
+ VkBool32 standardSampleLocations;
+ VkDeviceSize optimalBufferCopyOffsetAlignment;
+ VkDeviceSize optimalBufferCopyRowPitchAlignment;
+ VkDeviceSize nonCoherentAtomSize;
+} VkPhysicalDeviceLimits;
+
+typedef struct VkPhysicalDeviceSparseProperties {
+ VkBool32 residencyStandard2DBlockShape;
+ VkBool32 residencyStandard2DMultisampleBlockShape;
+ VkBool32 residencyStandard3DBlockShape;
+ VkBool32 residencyAlignedMipSize;
+ VkBool32 residencyNonResidentStrict;
+} VkPhysicalDeviceSparseProperties;
+
+typedef struct VkPhysicalDeviceProperties {
+ uint32_t apiVersion;
+ uint32_t driverVersion;
+ uint32_t vendorID;
+ uint32_t deviceID;
+ VkPhysicalDeviceType deviceType;
+ char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
+ uint8_t pipelineCacheUUID[VK_UUID_SIZE];
+ VkPhysicalDeviceLimits limits;
+ VkPhysicalDeviceSparseProperties sparseProperties;
+} VkPhysicalDeviceProperties;
+
+typedef struct VkQueueFamilyProperties {
+ VkQueueFlags queueFlags;
+ uint32_t queueCount;
+ uint32_t timestampValidBits;
+ VkExtent3D minImageTransferGranularity;
+} VkQueueFamilyProperties;
+
+typedef struct VkMemoryType {
+ VkMemoryPropertyFlags propertyFlags;
+ uint32_t heapIndex;
+} VkMemoryType;
+
+typedef struct VkMemoryHeap {
+ VkDeviceSize size;
+ VkMemoryHeapFlags flags;
+} VkMemoryHeap;
+
+typedef struct VkPhysicalDeviceMemoryProperties {
+ uint32_t memoryTypeCount;
+ VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES];
+ uint32_t memoryHeapCount;
+ VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS];
+} VkPhysicalDeviceMemoryProperties;
+
+typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);
+typedef struct VkDeviceQueueCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceQueueCreateFlags flags;
+ uint32_t queueFamilyIndex;
+ uint32_t queueCount;
+ const float* pQueuePriorities;
+} VkDeviceQueueCreateInfo;
+
+typedef struct VkDeviceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceCreateFlags flags;
+ uint32_t queueCreateInfoCount;
+ const VkDeviceQueueCreateInfo* pQueueCreateInfos;
+ uint32_t enabledLayerCount;
+ const char* const* ppEnabledLayerNames;
+ uint32_t enabledExtensionCount;
+ const char* const* ppEnabledExtensionNames;
+ const VkPhysicalDeviceFeatures* pEnabledFeatures;
+} VkDeviceCreateInfo;
+
+typedef struct VkExtensionProperties {
+ char extensionName[VK_MAX_EXTENSION_NAME_SIZE];
+ uint32_t specVersion;
+} VkExtensionProperties;
+
+typedef struct VkLayerProperties {
+ char layerName[VK_MAX_EXTENSION_NAME_SIZE];
+ uint32_t specVersion;
+ uint32_t implementationVersion;
+ char description[VK_MAX_DESCRIPTION_SIZE];
+} VkLayerProperties;
+
+typedef struct VkSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const VkSemaphore* pWaitSemaphores;
+ const VkPipelineStageFlags* pWaitDstStageMask;
+ uint32_t commandBufferCount;
+ const VkCommandBuffer* pCommandBuffers;
+ uint32_t signalSemaphoreCount;
+ const VkSemaphore* pSignalSemaphores;
+} VkSubmitInfo;
+
+typedef struct VkMemoryAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize allocationSize;
+ uint32_t memoryTypeIndex;
+} VkMemoryAllocateInfo;
+
+typedef struct VkMappedMemoryRange {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+} VkMappedMemoryRange;
+
+typedef struct VkMemoryRequirements {
+ VkDeviceSize size;
+ VkDeviceSize alignment;
+ uint32_t memoryTypeBits;
+} VkMemoryRequirements;
+
+typedef struct VkSparseImageFormatProperties {
+ VkImageAspectFlags aspectMask;
+ VkExtent3D imageGranularity;
+ VkSparseImageFormatFlags flags;
+} VkSparseImageFormatProperties;
+
+typedef struct VkSparseImageMemoryRequirements {
+ VkSparseImageFormatProperties formatProperties;
+ uint32_t imageMipTailFirstLod;
+ VkDeviceSize imageMipTailSize;
+ VkDeviceSize imageMipTailOffset;
+ VkDeviceSize imageMipTailStride;
+} VkSparseImageMemoryRequirements;
+
+typedef struct VkSparseMemoryBind {
+ VkDeviceSize resourceOffset;
+ VkDeviceSize size;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ VkSparseMemoryBindFlags flags;
+} VkSparseMemoryBind;
+
+typedef struct VkSparseBufferMemoryBindInfo {
+ VkBuffer buffer;
+ uint32_t bindCount;
+ const VkSparseMemoryBind* pBinds;
+} VkSparseBufferMemoryBindInfo;
+
+typedef struct VkSparseImageOpaqueMemoryBindInfo {
+ VkImage image;
+ uint32_t bindCount;
+ const VkSparseMemoryBind* pBinds;
+} VkSparseImageOpaqueMemoryBindInfo;
+
+typedef struct VkImageSubresource {
+ VkImageAspectFlags aspectMask;
+ uint32_t mipLevel;
+ uint32_t arrayLayer;
+} VkImageSubresource;
+
+typedef struct VkOffset3D {
+ int32_t x;
+ int32_t y;
+ int32_t z;
+} VkOffset3D;
+
+typedef struct VkSparseImageMemoryBind {
+ VkImageSubresource subresource;
+ VkOffset3D offset;
+ VkExtent3D extent;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ VkSparseMemoryBindFlags flags;
+} VkSparseImageMemoryBind;
+
+typedef struct VkSparseImageMemoryBindInfo {
+ VkImage image;
+ uint32_t bindCount;
+ const VkSparseImageMemoryBind* pBinds;
+} VkSparseImageMemoryBindInfo;
+
+typedef struct VkBindSparseInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const VkSemaphore* pWaitSemaphores;
+ uint32_t bufferBindCount;
+ const VkSparseBufferMemoryBindInfo* pBufferBinds;
+ uint32_t imageOpaqueBindCount;
+ const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
+ uint32_t imageBindCount;
+ const VkSparseImageMemoryBindInfo* pImageBinds;
+ uint32_t signalSemaphoreCount;
+ const VkSemaphore* pSignalSemaphores;
+} VkBindSparseInfo;
+
+typedef struct VkFenceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkFenceCreateFlags flags;
+} VkFenceCreateInfo;
+
+typedef struct VkSemaphoreCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphoreCreateFlags flags;
+} VkSemaphoreCreateInfo;
+
+typedef struct VkEventCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkEventCreateFlags flags;
+} VkEventCreateInfo;
+
+typedef struct VkQueryPoolCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkQueryPoolCreateFlags flags;
+ VkQueryType queryType;
+ uint32_t queryCount;
+ VkQueryPipelineStatisticFlags pipelineStatistics;
+} VkQueryPoolCreateInfo;
+
+typedef struct VkBufferCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCreateFlags flags;
+ VkDeviceSize size;
+ VkBufferUsageFlags usage;
+ VkSharingMode sharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+} VkBufferCreateInfo;
+
+typedef struct VkBufferViewCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferViewCreateFlags flags;
+ VkBuffer buffer;
+ VkFormat format;
+ VkDeviceSize offset;
+ VkDeviceSize range;
+} VkBufferViewCreateInfo;
+
+typedef struct VkImageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageCreateFlags flags;
+ VkImageType imageType;
+ VkFormat format;
+ VkExtent3D extent;
+ uint32_t mipLevels;
+ uint32_t arrayLayers;
+ VkSampleCountFlagBits samples;
+ VkImageTiling tiling;
+ VkImageUsageFlags usage;
+ VkSharingMode sharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+ VkImageLayout initialLayout;
+} VkImageCreateInfo;
+
+typedef struct VkSubresourceLayout {
+ VkDeviceSize offset;
+ VkDeviceSize size;
+ VkDeviceSize rowPitch;
+ VkDeviceSize arrayPitch;
+ VkDeviceSize depthPitch;
+} VkSubresourceLayout;
+
+typedef struct VkComponentMapping {
+ VkComponentSwizzle r;
+ VkComponentSwizzle g;
+ VkComponentSwizzle b;
+ VkComponentSwizzle a;
+} VkComponentMapping;
+
+typedef struct VkImageSubresourceRange {
+ VkImageAspectFlags aspectMask;
+ uint32_t baseMipLevel;
+ uint32_t levelCount;
+ uint32_t baseArrayLayer;
+ uint32_t layerCount;
+} VkImageSubresourceRange;
+
+typedef struct VkImageViewCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageViewCreateFlags flags;
+ VkImage image;
+ VkImageViewType viewType;
+ VkFormat format;
+ VkComponentMapping components;
+ VkImageSubresourceRange subresourceRange;
+} VkImageViewCreateInfo;
+
+typedef struct VkShaderModuleCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkShaderModuleCreateFlags flags;
+ size_t codeSize;
+ const uint32_t* pCode;
+} VkShaderModuleCreateInfo;
+
+typedef struct VkPipelineCacheCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCacheCreateFlags flags;
+ size_t initialDataSize;
+ const void* pInitialData;
+} VkPipelineCacheCreateInfo;
+
+typedef struct VkSpecializationMapEntry {
+ uint32_t constantID;
+ uint32_t offset;
+ size_t size;
+} VkSpecializationMapEntry;
+
+typedef struct VkSpecializationInfo {
+ uint32_t mapEntryCount;
+ const VkSpecializationMapEntry* pMapEntries;
+ size_t dataSize;
+ const void* pData;
+} VkSpecializationInfo;
+
+typedef struct VkPipelineShaderStageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineShaderStageCreateFlags flags;
+ VkShaderStageFlagBits stage;
+ VkShaderModule module;
+ const char* pName;
+ const VkSpecializationInfo* pSpecializationInfo;
+} VkPipelineShaderStageCreateInfo;
+
+typedef struct VkVertexInputBindingDescription {
+ uint32_t binding;
+ uint32_t stride;
+ VkVertexInputRate inputRate;
+} VkVertexInputBindingDescription;
+
+typedef struct VkVertexInputAttributeDescription {
+ uint32_t location;
+ uint32_t binding;
+ VkFormat format;
+ uint32_t offset;
+} VkVertexInputAttributeDescription;
+
+typedef struct VkPipelineVertexInputStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineVertexInputStateCreateFlags flags;
+ uint32_t vertexBindingDescriptionCount;
+ const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ uint32_t vertexAttributeDescriptionCount;
+ const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+} VkPipelineVertexInputStateCreateInfo;
+
+typedef struct VkPipelineInputAssemblyStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineInputAssemblyStateCreateFlags flags;
+ VkPrimitiveTopology topology;
+ VkBool32 primitiveRestartEnable;
+} VkPipelineInputAssemblyStateCreateInfo;
+
+typedef struct VkPipelineTessellationStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineTessellationStateCreateFlags flags;
+ uint32_t patchControlPoints;
+} VkPipelineTessellationStateCreateInfo;
+
+typedef struct VkViewport {
+ float x;
+ float y;
+ float width;
+ float height;
+ float minDepth;
+ float maxDepth;
+} VkViewport;
+
+typedef struct VkOffset2D {
+ int32_t x;
+ int32_t y;
+} VkOffset2D;
+
+typedef struct VkExtent2D {
+ uint32_t width;
+ uint32_t height;
+} VkExtent2D;
+
+typedef struct VkRect2D {
+ VkOffset2D offset;
+ VkExtent2D extent;
+} VkRect2D;
+
+typedef struct VkPipelineViewportStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineViewportStateCreateFlags flags;
+ uint32_t viewportCount;
+ const VkViewport* pViewports;
+ uint32_t scissorCount;
+ const VkRect2D* pScissors;
+} VkPipelineViewportStateCreateInfo;
+
+typedef struct VkPipelineRasterizationStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineRasterizationStateCreateFlags flags;
+ VkBool32 depthClampEnable;
+ VkBool32 rasterizerDiscardEnable;
+ VkPolygonMode polygonMode;
+ VkCullModeFlags cullMode;
+ VkFrontFace frontFace;
+ VkBool32 depthBiasEnable;
+ float depthBiasConstantFactor;
+ float depthBiasClamp;
+ float depthBiasSlopeFactor;
+ float lineWidth;
+} VkPipelineRasterizationStateCreateInfo;
+
+typedef struct VkPipelineMultisampleStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineMultisampleStateCreateFlags flags;
+ VkSampleCountFlagBits rasterizationSamples;
+ VkBool32 sampleShadingEnable;
+ float minSampleShading;
+ const VkSampleMask* pSampleMask;
+ VkBool32 alphaToCoverageEnable;
+ VkBool32 alphaToOneEnable;
+} VkPipelineMultisampleStateCreateInfo;
+
+typedef struct VkStencilOpState {
+ VkStencilOp failOp;
+ VkStencilOp passOp;
+ VkStencilOp depthFailOp;
+ VkCompareOp compareOp;
+ uint32_t compareMask;
+ uint32_t writeMask;
+ uint32_t reference;
+} VkStencilOpState;
+
+typedef struct VkPipelineDepthStencilStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineDepthStencilStateCreateFlags flags;
+ VkBool32 depthTestEnable;
+ VkBool32 depthWriteEnable;
+ VkCompareOp depthCompareOp;
+ VkBool32 depthBoundsTestEnable;
+ VkBool32 stencilTestEnable;
+ VkStencilOpState front;
+ VkStencilOpState back;
+ float minDepthBounds;
+ float maxDepthBounds;
+} VkPipelineDepthStencilStateCreateInfo;
+
+typedef struct VkPipelineColorBlendAttachmentState {
+ VkBool32 blendEnable;
+ VkBlendFactor srcColorBlendFactor;
+ VkBlendFactor dstColorBlendFactor;
+ VkBlendOp colorBlendOp;
+ VkBlendFactor srcAlphaBlendFactor;
+ VkBlendFactor dstAlphaBlendFactor;
+ VkBlendOp alphaBlendOp;
+ VkColorComponentFlags colorWriteMask;
+} VkPipelineColorBlendAttachmentState;
+
+typedef struct VkPipelineColorBlendStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineColorBlendStateCreateFlags flags;
+ VkBool32 logicOpEnable;
+ VkLogicOp logicOp;
+ uint32_t attachmentCount;
+ const VkPipelineColorBlendAttachmentState* pAttachments;
+ float blendConstants[4];
+} VkPipelineColorBlendStateCreateInfo;
+
+typedef struct VkPipelineDynamicStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineDynamicStateCreateFlags flags;
+ uint32_t dynamicStateCount;
+ const VkDynamicState* pDynamicStates;
+} VkPipelineDynamicStateCreateInfo;
+
+typedef struct VkGraphicsPipelineCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreateFlags flags;
+ uint32_t stageCount;
+ const VkPipelineShaderStageCreateInfo* pStages;
+ const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ const VkPipelineViewportStateCreateInfo* pViewportState;
+ const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ VkPipelineLayout layout;
+ VkRenderPass renderPass;
+ uint32_t subpass;
+ VkPipeline basePipelineHandle;
+ int32_t basePipelineIndex;
+} VkGraphicsPipelineCreateInfo;
+
+typedef struct VkComputePipelineCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreateFlags flags;
+ VkPipelineShaderStageCreateInfo stage;
+ VkPipelineLayout layout;
+ VkPipeline basePipelineHandle;
+ int32_t basePipelineIndex;
+} VkComputePipelineCreateInfo;
+
+typedef struct VkPushConstantRange {
+ VkShaderStageFlags stageFlags;
+ uint32_t offset;
+ uint32_t size;
+} VkPushConstantRange;
+
+typedef struct VkPipelineLayoutCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineLayoutCreateFlags flags;
+ uint32_t setLayoutCount;
+ const VkDescriptorSetLayout* pSetLayouts;
+ uint32_t pushConstantRangeCount;
+ const VkPushConstantRange* pPushConstantRanges;
+} VkPipelineLayoutCreateInfo;
+
+typedef struct VkSamplerCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSamplerCreateFlags flags;
+ VkFilter magFilter;
+ VkFilter minFilter;
+ VkSamplerMipmapMode mipmapMode;
+ VkSamplerAddressMode addressModeU;
+ VkSamplerAddressMode addressModeV;
+ VkSamplerAddressMode addressModeW;
+ float mipLodBias;
+ VkBool32 anisotropyEnable;
+ float maxAnisotropy;
+ VkBool32 compareEnable;
+ VkCompareOp compareOp;
+ float minLod;
+ float maxLod;
+ VkBorderColor borderColor;
+ VkBool32 unnormalizedCoordinates;
+} VkSamplerCreateInfo;
+
+typedef struct VkDescriptorSetLayoutBinding {
+ uint32_t binding;
+ VkDescriptorType descriptorType;
+ uint32_t descriptorCount;
+ VkShaderStageFlags stageFlags;
+ const VkSampler* pImmutableSamplers;
+} VkDescriptorSetLayoutBinding;
+
+typedef struct VkDescriptorSetLayoutCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSetLayoutCreateFlags flags;
+ uint32_t bindingCount;
+ const VkDescriptorSetLayoutBinding* pBindings;
+} VkDescriptorSetLayoutCreateInfo;
+
+typedef struct VkDescriptorPoolSize {
+ VkDescriptorType type;
+ uint32_t descriptorCount;
+} VkDescriptorPoolSize;
+
+typedef struct VkDescriptorPoolCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorPoolCreateFlags flags;
+ uint32_t maxSets;
+ uint32_t poolSizeCount;
+ const VkDescriptorPoolSize* pPoolSizes;
+} VkDescriptorPoolCreateInfo;
+
+typedef struct VkDescriptorSetAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorPool descriptorPool;
+ uint32_t descriptorSetCount;
+ const VkDescriptorSetLayout* pSetLayouts;
+} VkDescriptorSetAllocateInfo;
+
+typedef struct VkDescriptorImageInfo {
+ VkSampler sampler;
+ VkImageView imageView;
+ VkImageLayout imageLayout;
+} VkDescriptorImageInfo;
+
+typedef struct VkDescriptorBufferInfo {
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize range;
+} VkDescriptorBufferInfo;
+
+typedef struct VkWriteDescriptorSet {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSet dstSet;
+ uint32_t dstBinding;
+ uint32_t dstArrayElement;
+ uint32_t descriptorCount;
+ VkDescriptorType descriptorType;
+ const VkDescriptorImageInfo* pImageInfo;
+ const VkDescriptorBufferInfo* pBufferInfo;
+ const VkBufferView* pTexelBufferView;
+} VkWriteDescriptorSet;
+
+typedef struct VkCopyDescriptorSet {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSet srcSet;
+ uint32_t srcBinding;
+ uint32_t srcArrayElement;
+ VkDescriptorSet dstSet;
+ uint32_t dstBinding;
+ uint32_t dstArrayElement;
+ uint32_t descriptorCount;
+} VkCopyDescriptorSet;
+
+typedef struct VkFramebufferCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkFramebufferCreateFlags flags;
+ VkRenderPass renderPass;
+ uint32_t attachmentCount;
+ const VkImageView* pAttachments;
+ uint32_t width;
+ uint32_t height;
+ uint32_t layers;
+} VkFramebufferCreateInfo;
+
+typedef struct VkAttachmentDescription {
+ VkAttachmentDescriptionFlags flags;
+ VkFormat format;
+ VkSampleCountFlagBits samples;
+ VkAttachmentLoadOp loadOp;
+ VkAttachmentStoreOp storeOp;
+ VkAttachmentLoadOp stencilLoadOp;
+ VkAttachmentStoreOp stencilStoreOp;
+ VkImageLayout initialLayout;
+ VkImageLayout finalLayout;
+} VkAttachmentDescription;
+
+typedef struct VkAttachmentReference {
+ uint32_t attachment;
+ VkImageLayout layout;
+} VkAttachmentReference;
+
+typedef struct VkSubpassDescription {
+ VkSubpassDescriptionFlags flags;
+ VkPipelineBindPoint pipelineBindPoint;
+ uint32_t inputAttachmentCount;
+ const VkAttachmentReference* pInputAttachments;
+ uint32_t colorAttachmentCount;
+ const VkAttachmentReference* pColorAttachments;
+ const VkAttachmentReference* pResolveAttachments;
+ const VkAttachmentReference* pDepthStencilAttachment;
+ uint32_t preserveAttachmentCount;
+ const uint32_t* pPreserveAttachments;
+} VkSubpassDescription;
+
+typedef struct VkSubpassDependency {
+ uint32_t srcSubpass;
+ uint32_t dstSubpass;
+ VkPipelineStageFlags srcStageMask;
+ VkPipelineStageFlags dstStageMask;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ VkDependencyFlags dependencyFlags;
+} VkSubpassDependency;
+
+typedef struct VkRenderPassCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPassCreateFlags flags;
+ uint32_t attachmentCount;
+ const VkAttachmentDescription* pAttachments;
+ uint32_t subpassCount;
+ const VkSubpassDescription* pSubpasses;
+ uint32_t dependencyCount;
+ const VkSubpassDependency* pDependencies;
+} VkRenderPassCreateInfo;
+
+typedef struct VkCommandPoolCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandPoolCreateFlags flags;
+ uint32_t queueFamilyIndex;
+} VkCommandPoolCreateInfo;
+
+typedef struct VkCommandBufferAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandPool commandPool;
+ VkCommandBufferLevel level;
+ uint32_t commandBufferCount;
+} VkCommandBufferAllocateInfo;
+
+typedef struct VkCommandBufferInheritanceInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPass renderPass;
+ uint32_t subpass;
+ VkFramebuffer framebuffer;
+ VkBool32 occlusionQueryEnable;
+ VkQueryControlFlags queryFlags;
+ VkQueryPipelineStatisticFlags pipelineStatistics;
+} VkCommandBufferInheritanceInfo;
+
+typedef struct VkCommandBufferBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandBufferUsageFlags flags;
+ const VkCommandBufferInheritanceInfo* pInheritanceInfo;
+} VkCommandBufferBeginInfo;
+
+typedef struct VkBufferCopy {
+ VkDeviceSize srcOffset;
+ VkDeviceSize dstOffset;
+ VkDeviceSize size;
+} VkBufferCopy;
+
+typedef struct VkImageSubresourceLayers {
+ VkImageAspectFlags aspectMask;
+ uint32_t mipLevel;
+ uint32_t baseArrayLayer;
+ uint32_t layerCount;
+} VkImageSubresourceLayers;
+
+typedef struct VkImageCopy {
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffset;
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffset;
+ VkExtent3D extent;
+} VkImageCopy;
+
+typedef struct VkImageBlit {
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffsets[2];
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffsets[2];
+} VkImageBlit;
+
+typedef struct VkBufferImageCopy {
+ VkDeviceSize bufferOffset;
+ uint32_t bufferRowLength;
+ uint32_t bufferImageHeight;
+ VkImageSubresourceLayers imageSubresource;
+ VkOffset3D imageOffset;
+ VkExtent3D imageExtent;
+} VkBufferImageCopy;
+
+typedef union VkClearColorValue {
+ float float32[4];
+ int32_t int32[4];
+ uint32_t uint32[4];
+} VkClearColorValue;
+
+typedef struct VkClearDepthStencilValue {
+ float depth;
+ uint32_t stencil;
+} VkClearDepthStencilValue;
+
+typedef union VkClearValue {
+ VkClearColorValue color;
+ VkClearDepthStencilValue depthStencil;
+} VkClearValue;
+
+typedef struct VkClearAttachment {
+ VkImageAspectFlags aspectMask;
+ uint32_t colorAttachment;
+ VkClearValue clearValue;
+} VkClearAttachment;
+
+typedef struct VkClearRect {
+ VkRect2D rect;
+ uint32_t baseArrayLayer;
+ uint32_t layerCount;
+} VkClearRect;
+
+typedef struct VkImageResolve {
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffset;
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffset;
+ VkExtent3D extent;
+} VkImageResolve;
+
+typedef struct VkMemoryBarrier {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+} VkMemoryBarrier;
+
+typedef struct VkBufferMemoryBarrier {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ uint32_t srcQueueFamilyIndex;
+ uint32_t dstQueueFamilyIndex;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+} VkBufferMemoryBarrier;
+
+typedef struct VkImageMemoryBarrier {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ VkImageLayout oldLayout;
+ VkImageLayout newLayout;
+ uint32_t srcQueueFamilyIndex;
+ uint32_t dstQueueFamilyIndex;
+ VkImage image;
+ VkImageSubresourceRange subresourceRange;
+} VkImageMemoryBarrier;
+
+typedef struct VkRenderPassBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPass renderPass;
+ VkFramebuffer framebuffer;
+ VkRect2D renderArea;
+ uint32_t clearValueCount;
+ const VkClearValue* pClearValues;
+} VkRenderPassBeginInfo;
+
+typedef struct VkDispatchIndirectCommand {
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+} VkDispatchIndirectCommand;
+
+typedef struct VkDrawIndexedIndirectCommand {
+ uint32_t indexCount;
+ uint32_t instanceCount;
+ uint32_t firstIndex;
+ int32_t vertexOffset;
+ uint32_t firstInstance;
+} VkDrawIndexedIndirectCommand;
+
+typedef struct VkDrawIndirectCommand {
+ uint32_t vertexCount;
+ uint32_t instanceCount;
+ uint32_t firstVertex;
+ uint32_t firstInstance;
+} VkDrawIndirectCommand;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
+typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName);
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
+typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue);
+typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device);
+typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory);
+typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData);
+typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory);
+typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges);
+typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes);
+typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset);
+typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset);
+typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
+typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences);
+typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore);
+typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent);
+typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool);
+typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer);
+typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView);
+typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage);
+typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView);
+typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule);
+typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache);
+typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData);
+typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout);
+typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler);
+typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags);
+typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets);
+typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets);
+typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer);
+typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool);
+typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags);
+typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers);
+typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
+typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer);
+typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports);
+typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors);
+typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor);
+typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference);
+typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets);
+typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType);
+typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets);
+typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
+typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
+typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
+typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects);
+typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask);
+typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask);
+typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
+typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query);
+typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer);
+typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
+ const VkInstanceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkInstance* pInstance);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
+ VkInstance instance,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceCount,
+ VkPhysicalDevice* pPhysicalDevices);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures* pFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties* pFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkImageFormatProperties* pImageFormatProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties* pQueueFamilyProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(
+ VkInstance instance,
+ const char* pName);
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(
+ VkDevice device,
+ const char* pName);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDevice* pDevice);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(
+ VkDevice device,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
+ VkPhysicalDevice physicalDevice,
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
+ uint32_t* pPropertyCount,
+ VkLayerProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkLayerProperties* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(
+ VkDevice device,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex,
+ VkQueue* pQueue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(
+ VkQueue queue,
+ uint32_t submitCount,
+ const VkSubmitInfo* pSubmits,
+ VkFence fence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(
+ VkQueue queue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(
+ VkDevice device);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(
+ VkDevice device,
+ const VkMemoryAllocateInfo* pAllocateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDeviceMemory* pMemory);
+
+VKAPI_ATTR void VKAPI_CALL vkFreeMemory(
+ VkDevice device,
+ VkDeviceMemory memory,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkDeviceSize offset,
+ VkDeviceSize size,
+ VkMemoryMapFlags flags,
+ void** ppData);
+
+VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(
+ VkDevice device,
+ VkDeviceMemory memory);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(
+ VkDevice device,
+ uint32_t memoryRangeCount,
+ const VkMappedMemoryRange* pMemoryRanges);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(
+ VkDevice device,
+ uint32_t memoryRangeCount,
+ const VkMappedMemoryRange* pMemoryRanges);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkDeviceSize* pCommittedMemoryInBytes);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(
+ VkDevice device,
+ VkBuffer buffer,
+ VkDeviceMemory memory,
+ VkDeviceSize memoryOffset);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(
+ VkDevice device,
+ VkImage image,
+ VkDeviceMemory memory,
+ VkDeviceSize memoryOffset);
+
+VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(
+ VkDevice device,
+ VkBuffer buffer,
+ VkMemoryRequirements* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(
+ VkDevice device,
+ VkImage image,
+ VkMemoryRequirements* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(
+ VkDevice device,
+ VkImage image,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkSampleCountFlagBits samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(
+ VkQueue queue,
+ uint32_t bindInfoCount,
+ const VkBindSparseInfo* pBindInfo,
+ VkFence fence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(
+ VkDevice device,
+ const VkFenceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyFence(
+ VkDevice device,
+ VkFence fence,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(
+ VkDevice device,
+ uint32_t fenceCount,
+ const VkFence* pFences);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(
+ VkDevice device,
+ VkFence fence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(
+ VkDevice device,
+ uint32_t fenceCount,
+ const VkFence* pFences,
+ VkBool32 waitAll,
+ uint64_t timeout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(
+ VkDevice device,
+ const VkSemaphoreCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSemaphore* pSemaphore);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(
+ VkDevice device,
+ VkSemaphore semaphore,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(
+ VkDevice device,
+ const VkEventCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkEvent* pEvent);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(
+ VkDevice device,
+ VkEvent event,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(
+ VkDevice device,
+ VkEvent event);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(
+ VkDevice device,
+ VkEvent event);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(
+ VkDevice device,
+ VkEvent event);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(
+ VkDevice device,
+ const VkQueryPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkQueryPool* pQueryPool);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(
+ VkDevice device,
+ VkQueryPool queryPool,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(
+ VkDevice device,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount,
+ size_t dataSize,
+ void* pData,
+ VkDeviceSize stride,
+ VkQueryResultFlags flags);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(
+ VkDevice device,
+ const VkBufferCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBuffer* pBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(
+ VkDevice device,
+ VkBuffer buffer,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(
+ VkDevice device,
+ const VkBufferViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBufferView* pView);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(
+ VkDevice device,
+ VkBufferView bufferView,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(
+ VkDevice device,
+ const VkImageCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImage* pImage);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyImage(
+ VkDevice device,
+ VkImage image,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(
+ VkDevice device,
+ VkImage image,
+ const VkImageSubresource* pSubresource,
+ VkSubresourceLayout* pLayout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(
+ VkDevice device,
+ const VkImageViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImageView* pView);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(
+ VkDevice device,
+ VkImageView imageView,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(
+ VkDevice device,
+ const VkShaderModuleCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkShaderModule* pShaderModule);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(
+ VkDevice device,
+ VkShaderModule shaderModule,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(
+ VkDevice device,
+ const VkPipelineCacheCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipelineCache* pPipelineCache);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ size_t* pDataSize,
+ void* pData);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(
+ VkDevice device,
+ VkPipelineCache dstCache,
+ uint32_t srcCacheCount,
+ const VkPipelineCache* pSrcCaches);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkComputePipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(
+ VkDevice device,
+ VkPipeline pipeline,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(
+ VkDevice device,
+ const VkPipelineLayoutCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipelineLayout* pPipelineLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(
+ VkDevice device,
+ VkPipelineLayout pipelineLayout,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(
+ VkDevice device,
+ const VkSamplerCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSampler* pSampler);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySampler(
+ VkDevice device,
+ VkSampler sampler,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorSetLayout* pSetLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(
+ VkDevice device,
+ VkDescriptorSetLayout descriptorSetLayout,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(
+ VkDevice device,
+ const VkDescriptorPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorPool* pDescriptorPool);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(
+ VkDevice device,
+ VkDescriptorPool descriptorPool,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(
+ VkDevice device,
+ VkDescriptorPool descriptorPool,
+ VkDescriptorPoolResetFlags flags);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(
+ VkDevice device,
+ const VkDescriptorSetAllocateInfo* pAllocateInfo,
+ VkDescriptorSet* pDescriptorSets);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(
+ VkDevice device,
+ VkDescriptorPool descriptorPool,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet* pDescriptorSets);
+
+VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(
+ VkDevice device,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet* pDescriptorCopies);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(
+ VkDevice device,
+ const VkFramebufferCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFramebuffer* pFramebuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(
+ VkDevice device,
+ VkFramebuffer framebuffer,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(
+ VkDevice device,
+ const VkRenderPassCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkRenderPass* pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(
+ VkDevice device,
+ VkRenderPass renderPass,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(
+ VkDevice device,
+ VkRenderPass renderPass,
+ VkExtent2D* pGranularity);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(
+ VkDevice device,
+ const VkCommandPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkCommandPool* pCommandPool);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolResetFlags flags);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers);
+
+VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(
+ VkDevice device,
+ VkCommandPool commandPool,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer* pCommandBuffers);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo* pBeginInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(
+ VkCommandBuffer commandBuffer,
+ VkCommandBufferResetFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipeline pipeline);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewport* pViewports);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstScissor,
+ uint32_t scissorCount,
+ const VkRect2D* pScissors);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(
+ VkCommandBuffer commandBuffer,
+ float lineWidth);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(
+ VkCommandBuffer commandBuffer,
+ float depthBiasConstantFactor,
+ float depthBiasClamp,
+ float depthBiasSlopeFactor);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(
+ VkCommandBuffer commandBuffer,
+ const float blendConstants[4]);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(
+ VkCommandBuffer commandBuffer,
+ float minDepthBounds,
+ float maxDepthBounds);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ uint32_t compareMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ uint32_t writeMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ uint32_t reference);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t firstSet,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet* pDescriptorSets,
+ uint32_t dynamicOffsetCount,
+ const uint32_t* pDynamicOffsets);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkIndexType indexType);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer* pBuffers,
+ const VkDeviceSize* pOffsets);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDraw(
+ VkCommandBuffer commandBuffer,
+ uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(
+ VkCommandBuffer commandBuffer,
+ uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ int32_t vertexOffset,
+ uint32_t firstInstance);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(
+ VkCommandBuffer commandBuffer,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer srcBuffer,
+ VkBuffer dstBuffer,
+ uint32_t regionCount,
+ const VkBufferCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageBlit* pRegions,
+ VkFilter filter);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(
+ VkCommandBuffer commandBuffer,
+ VkBuffer srcBuffer,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkBufferImageCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkBuffer dstBuffer,
+ uint32_t regionCount,
+ const VkBufferImageCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize dataSize,
+ const void* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize size,
+ uint32_t data);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
+ VkCommandBuffer commandBuffer,
+ VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearColorValue* pColor,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange* pRanges);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(
+ VkCommandBuffer commandBuffer,
+ VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearDepthStencilValue* pDepthStencil,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange* pRanges);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(
+ VkCommandBuffer commandBuffer,
+ uint32_t attachmentCount,
+ const VkClearAttachment* pAttachments,
+ uint32_t rectCount,
+ const VkClearRect* pRects);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageResolve* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ VkPipelineStageFlags stageMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ VkPipelineStageFlags stageMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(
+ VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent* pEvents,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier* pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier* pImageMemoryBarriers);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ VkDependencyFlags dependencyFlags,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier* pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier* pImageMemoryBarriers);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query,
+ VkQueryControlFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkQueryPool queryPool,
+ uint32_t query);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize stride,
+ VkQueryResultFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(
+ VkCommandBuffer commandBuffer,
+ VkPipelineLayout layout,
+ VkShaderStageFlags stageFlags,
+ uint32_t offset,
+ uint32_t size,
+ const void* pValues);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(
+ VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo* pRenderPassBegin,
+ VkSubpassContents contents);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(
+ VkCommandBuffer commandBuffer,
+ VkSubpassContents contents);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(
+ VkCommandBuffer commandBuffer,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer* pCommandBuffers);
+#endif
+
+#define VK_KHR_surface 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+
+#define VK_KHR_SURFACE_SPEC_VERSION 25
+#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface"
+#define VK_COLORSPACE_SRGB_NONLINEAR_KHR VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
+
+
+typedef enum VkColorSpaceKHR {
+ VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
+ VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001,
+ VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002,
+ VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104003,
+ VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004,
+ VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005,
+ VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006,
+ VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007,
+ VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008,
+ VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009,
+ VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010,
+ VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,
+ VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,
+ VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013,
+ VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014,
+ VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+ VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+ VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1),
+ VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkColorSpaceKHR;
+
+typedef enum VkPresentModeKHR {
+ VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+ VK_PRESENT_MODE_MAILBOX_KHR = 1,
+ VK_PRESENT_MODE_FIFO_KHR = 2,
+ VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3,
+ VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000,
+ VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001,
+ VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR,
+ VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_RELAXED_KHR,
+ VK_PRESENT_MODE_RANGE_SIZE_KHR = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1),
+ VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPresentModeKHR;
+
+
+typedef enum VkSurfaceTransformFlagBitsKHR {
+ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001,
+ VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002,
+ VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004,
+ VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080,
+ VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
+ VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkSurfaceTransformFlagBitsKHR;
+typedef VkFlags VkSurfaceTransformFlagsKHR;
+
+typedef enum VkCompositeAlphaFlagBitsKHR {
+ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
+ VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002,
+ VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004,
+ VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008,
+ VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkCompositeAlphaFlagBitsKHR;
+typedef VkFlags VkCompositeAlphaFlagsKHR;
+
+typedef struct VkSurfaceCapabilitiesKHR {
+ uint32_t minImageCount;
+ uint32_t maxImageCount;
+ VkExtent2D currentExtent;
+ VkExtent2D minImageExtent;
+ VkExtent2D maxImageExtent;
+ uint32_t maxImageArrayLayers;
+ VkSurfaceTransformFlagsKHR supportedTransforms;
+ VkSurfaceTransformFlagBitsKHR currentTransform;
+ VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
+ VkImageUsageFlags supportedUsageFlags;
+} VkSurfaceCapabilitiesKHR;
+
+typedef struct VkSurfaceFormatKHR {
+ VkFormat format;
+ VkColorSpaceKHR colorSpace;
+} VkSurfaceFormatKHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
+ VkInstance instance,
+ VkSurfaceKHR surface,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ VkSurfaceKHR surface,
+ VkBool32* pSupported);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormatKHR* pSurfaceFormats);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes);
+#endif
+
+#define VK_KHR_swapchain 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
+
+#define VK_KHR_SWAPCHAIN_SPEC_VERSION 68
+#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain"
+
+
+typedef enum VkSwapchainCreateFlagBitsKHR {
+ VK_SWAPCHAIN_CREATE_BIND_SFR_BIT_KHX = 0x00000001,
+ VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkSwapchainCreateFlagBitsKHR;
+typedef VkFlags VkSwapchainCreateFlagsKHR;
+
+typedef struct VkSwapchainCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainCreateFlagsKHR flags;
+ VkSurfaceKHR surface;
+ uint32_t minImageCount;
+ VkFormat imageFormat;
+ VkColorSpaceKHR imageColorSpace;
+ VkExtent2D imageExtent;
+ uint32_t imageArrayLayers;
+ VkImageUsageFlags imageUsage;
+ VkSharingMode imageSharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+ VkSurfaceTransformFlagBitsKHR preTransform;
+ VkCompositeAlphaFlagBitsKHR compositeAlpha;
+ VkPresentModeKHR presentMode;
+ VkBool32 clipped;
+ VkSwapchainKHR oldSwapchain;
+} VkSwapchainCreateInfoKHR;
+
+typedef struct VkPresentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const VkSemaphore* pWaitSemaphores;
+ uint32_t swapchainCount;
+ const VkSwapchainKHR* pSwapchains;
+ const uint32_t* pImageIndices;
+ VkResult* pResults;
+} VkPresentInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
+typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages);
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex);
+typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
+ VkDevice device,
+ const VkSwapchainCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchain);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pSwapchainImageCount,
+ VkImage* pSwapchainImages);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint64_t timeout,
+ VkSemaphore semaphore,
+ VkFence fence,
+ uint32_t* pImageIndex);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
+ VkQueue queue,
+ const VkPresentInfoKHR* pPresentInfo);
+#endif
+
+#define VK_KHR_display 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR)
+
+#define VK_KHR_DISPLAY_SPEC_VERSION 21
+#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display"
+
+
+typedef enum VkDisplayPlaneAlphaFlagBitsKHR {
+ VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
+ VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002,
+ VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004,
+ VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008,
+ VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkDisplayPlaneAlphaFlagBitsKHR;
+typedef VkFlags VkDisplayPlaneAlphaFlagsKHR;
+typedef VkFlags VkDisplayModeCreateFlagsKHR;
+typedef VkFlags VkDisplaySurfaceCreateFlagsKHR;
+
+typedef struct VkDisplayPropertiesKHR {
+ VkDisplayKHR display;
+ const char* displayName;
+ VkExtent2D physicalDimensions;
+ VkExtent2D physicalResolution;
+ VkSurfaceTransformFlagsKHR supportedTransforms;
+ VkBool32 planeReorderPossible;
+ VkBool32 persistentContent;
+} VkDisplayPropertiesKHR;
+
+typedef struct VkDisplayModeParametersKHR {
+ VkExtent2D visibleRegion;
+ uint32_t refreshRate;
+} VkDisplayModeParametersKHR;
+
+typedef struct VkDisplayModePropertiesKHR {
+ VkDisplayModeKHR displayMode;
+ VkDisplayModeParametersKHR parameters;
+} VkDisplayModePropertiesKHR;
+
+typedef struct VkDisplayModeCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayModeCreateFlagsKHR flags;
+ VkDisplayModeParametersKHR parameters;
+} VkDisplayModeCreateInfoKHR;
+
+typedef struct VkDisplayPlaneCapabilitiesKHR {
+ VkDisplayPlaneAlphaFlagsKHR supportedAlpha;
+ VkOffset2D minSrcPosition;
+ VkOffset2D maxSrcPosition;
+ VkExtent2D minSrcExtent;
+ VkExtent2D maxSrcExtent;
+ VkOffset2D minDstPosition;
+ VkOffset2D maxDstPosition;
+ VkExtent2D minDstExtent;
+ VkExtent2D maxDstExtent;
+} VkDisplayPlaneCapabilitiesKHR;
+
+typedef struct VkDisplayPlanePropertiesKHR {
+ VkDisplayKHR currentDisplay;
+ uint32_t currentStackIndex;
+} VkDisplayPlanePropertiesKHR;
+
+typedef struct VkDisplaySurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplaySurfaceCreateFlagsKHR flags;
+ VkDisplayModeKHR displayMode;
+ uint32_t planeIndex;
+ uint32_t planeStackIndex;
+ VkSurfaceTransformFlagBitsKHR transform;
+ float globalAlpha;
+ VkDisplayPlaneAlphaFlagBitsKHR alphaMode;
+ VkExtent2D imageExtent;
+} VkDisplaySurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayPropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayPlanePropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t planeIndex,
+ uint32_t* pDisplayCount,
+ VkDisplayKHR* pDisplays);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ uint32_t* pPropertyCount,
+ VkDisplayModePropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ const VkDisplayModeCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDisplayModeKHR* pMode);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayModeKHR mode,
+ uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR* pCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(
+ VkInstance instance,
+ const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+
+#define VK_KHR_display_swapchain 1
+#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 9
+#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain"
+
+typedef struct VkDisplayPresentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkRect2D srcRect;
+ VkRect2D dstRect;
+ VkBool32 persistent;
+} VkDisplayPresentInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchains);
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#define VK_KHR_xlib_surface 1
+#include <X11/Xlib.h>
+
+#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6
+#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
+
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
+
+typedef struct VkXlibSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkXlibSurfaceCreateFlagsKHR flags;
+ Display* dpy;
+ Window window;
+} VkXlibSurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
+ VkInstance instance,
+ const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ Display* dpy,
+ VisualID visualID);
+#endif
+#endif /* VK_USE_PLATFORM_XLIB_KHR */
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#define VK_KHR_xcb_surface 1
+#include <xcb/xcb.h>
+
+#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6
+#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
+
+typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
+
+typedef struct VkXcbSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkXcbSurfaceCreateFlagsKHR flags;
+ xcb_connection_t* connection;
+ xcb_window_t window;
+} VkXcbSurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
+ VkInstance instance,
+ const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ xcb_connection_t* connection,
+ xcb_visualid_t visual_id);
+#endif
+#endif /* VK_USE_PLATFORM_XCB_KHR */
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#define VK_KHR_wayland_surface 1
+#include <wayland-client.h>
+
+#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6
+#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface"
+
+typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
+
+typedef struct VkWaylandSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkWaylandSurfaceCreateFlagsKHR flags;
+ struct wl_display* display;
+ struct wl_surface* surface;
+} VkWaylandSurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
+ VkInstance instance,
+ const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct wl_display* display);
+#endif
+#endif /* VK_USE_PLATFORM_WAYLAND_KHR */
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+#define VK_KHR_mir_surface 1
+#include <mir_toolkit/client_types.h>
+
+#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4
+#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface"
+
+typedef VkFlags VkMirSurfaceCreateFlagsKHR;
+
+typedef struct VkMirSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkMirSurfaceCreateFlagsKHR flags;
+ MirConnection* connection;
+ MirSurface* mirSurface;
+} VkMirSurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
+ VkInstance instance,
+ const VkMirSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ MirConnection* connection);
+#endif
+#endif /* VK_USE_PLATFORM_MIR_KHR */
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#define VK_KHR_android_surface 1
+#include <android/native_window.h>
+
+#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6
+#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface"
+
+typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
+
+typedef struct VkAndroidSurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAndroidSurfaceCreateFlagsKHR flags;
+ ANativeWindow* window;
+} VkAndroidSurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
+ VkInstance instance,
+ const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_ANDROID_KHR */
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_KHR_win32_surface 1
+#include <windows.h>
+
+#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
+#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface"
+
+typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
+
+typedef struct VkWin32SurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkWin32SurfaceCreateFlagsKHR flags;
+ HINSTANCE hinstance;
+ HWND hwnd;
+} VkWin32SurfaceCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
+ VkInstance instance,
+ const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex);
+#endif
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#define VK_KHR_sampler_mirror_clamp_to_edge 1
+#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1
+#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge"
+
+
+#define VK_KHR_get_physical_device_properties2 1
+#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2"
+
+typedef struct VkPhysicalDeviceFeatures2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkPhysicalDeviceFeatures features;
+} VkPhysicalDeviceFeatures2KHR;
+
+typedef struct VkPhysicalDeviceProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkPhysicalDeviceProperties properties;
+} VkPhysicalDeviceProperties2KHR;
+
+typedef struct VkFormatProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkFormatProperties formatProperties;
+} VkFormatProperties2KHR;
+
+typedef struct VkImageFormatProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageFormatProperties imageFormatProperties;
+} VkImageFormatProperties2KHR;
+
+typedef struct VkPhysicalDeviceImageFormatInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat format;
+ VkImageType type;
+ VkImageTiling tiling;
+ VkImageUsageFlags usage;
+ VkImageCreateFlags flags;
+} VkPhysicalDeviceImageFormatInfo2KHR;
+
+typedef struct VkQueueFamilyProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkQueueFamilyProperties queueFamilyProperties;
+} VkQueueFamilyProperties2KHR;
+
+typedef struct VkPhysicalDeviceMemoryProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkPhysicalDeviceMemoryProperties memoryProperties;
+} VkPhysicalDeviceMemoryProperties2KHR;
+
+typedef struct VkSparseImageFormatProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSparseImageFormatProperties properties;
+} VkSparseImageFormatProperties2KHR;
+
+typedef struct VkPhysicalDeviceSparseImageFormatInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat format;
+ VkImageType type;
+ VkSampleCountFlagBits samples;
+ VkImageUsageFlags usage;
+ VkImageTiling tiling;
+} VkPhysicalDeviceSparseImageFormatInfo2KHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR* pFeatures);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2KHR* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2KHR* pFormatProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, VkImageFormatProperties2KHR* pImageFormatProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR* pQueueFamilyProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2KHR* pProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures2KHR* pFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2KHR* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties2KHR* pFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo,
+ VkImageFormatProperties2KHR* pImageFormatProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2KHR* pQueueFamilyProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties2KHR* pProperties);
+#endif
+
+#define VK_KHR_shader_draw_parameters 1
+#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1
+#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters"
+
+
+#define VK_KHR_maintenance1 1
+#define VK_KHR_MAINTENANCE1_SPEC_VERSION 1
+#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
+
+typedef VkFlags VkCommandPoolTrimFlagsKHR;
+
+typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlagsKHR flags);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlagsKHR flags);
+#endif
+
+#define VK_KHR_external_memory_capabilities 1
+#define VK_LUID_SIZE_KHR 8
+#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities"
+
+
+typedef enum VkExternalMemoryHandleTypeFlagBitsKHR {
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = 0x00000001,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = 0x00000002,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = 0x00000004,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = 0x00000008,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = 0x00000010,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = 0x00000020,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = 0x00000040,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkExternalMemoryHandleTypeFlagBitsKHR;
+typedef VkFlags VkExternalMemoryHandleTypeFlagsKHR;
+
+typedef enum VkExternalMemoryFeatureFlagBitsKHR {
+ VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR = 0x00000001,
+ VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR = 0x00000002,
+ VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR = 0x00000004,
+ VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkExternalMemoryFeatureFlagBitsKHR;
+typedef VkFlags VkExternalMemoryFeatureFlagsKHR;
+
+typedef struct VkExternalMemoryPropertiesKHR {
+ VkExternalMemoryFeatureFlagsKHR externalMemoryFeatures;
+ VkExternalMemoryHandleTypeFlagsKHR exportFromImportedHandleTypes;
+ VkExternalMemoryHandleTypeFlagsKHR compatibleHandleTypes;
+} VkExternalMemoryPropertiesKHR;
+
+typedef struct VkPhysicalDeviceExternalImageFormatInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType;
+} VkPhysicalDeviceExternalImageFormatInfoKHR;
+
+typedef struct VkExternalImageFormatPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalMemoryPropertiesKHR externalMemoryProperties;
+} VkExternalImageFormatPropertiesKHR;
+
+typedef struct VkPhysicalDeviceExternalBufferInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCreateFlags flags;
+ VkBufferUsageFlags usage;
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType;
+} VkPhysicalDeviceExternalBufferInfoKHR;
+
+typedef struct VkExternalBufferPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalMemoryPropertiesKHR externalMemoryProperties;
+} VkExternalBufferPropertiesKHR;
+
+typedef struct VkPhysicalDeviceIDPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint8_t deviceUUID[VK_UUID_SIZE];
+ uint8_t driverUUID[VK_UUID_SIZE];
+ uint8_t deviceLUID[VK_LUID_SIZE_KHR];
+ uint32_t deviceNodeMask;
+ VkBool32 deviceLUIDValid;
+} VkPhysicalDeviceIDPropertiesKHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo, VkExternalBufferPropertiesKHR* pExternalBufferProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo,
+ VkExternalBufferPropertiesKHR* pExternalBufferProperties);
+#endif
+
+#define VK_KHR_external_memory 1
+#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory"
+#define VK_QUEUE_FAMILY_EXTERNAL_KHR (~0U-1)
+
+typedef struct VkExternalMemoryImageCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsKHR handleTypes;
+} VkExternalMemoryImageCreateInfoKHR;
+
+typedef struct VkExternalMemoryBufferCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsKHR handleTypes;
+} VkExternalMemoryBufferCreateInfoKHR;
+
+typedef struct VkExportMemoryAllocateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsKHR handleTypes;
+} VkExportMemoryAllocateInfoKHR;
+
+
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_KHR_external_memory_win32 1
+#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32"
+
+typedef struct VkImportMemoryWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType;
+ HANDLE handle;
+ LPCWSTR name;
+} VkImportMemoryWin32HandleInfoKHR;
+
+typedef struct VkExportMemoryWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ const SECURITY_ATTRIBUTES* pAttributes;
+ DWORD dwAccess;
+ LPCWSTR name;
+} VkExportMemoryWin32HandleInfoKHR;
+
+typedef struct VkMemoryWin32HandlePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t memoryTypeBits;
+} VkMemoryWin32HandlePropertiesKHR;
+
+typedef struct VkMemoryGetWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType;
+} VkMemoryGetWin32HandleInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBitsKHR handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR(
+ VkDevice device,
+ const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType,
+ HANDLE handle,
+ VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
+#endif
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#define VK_KHR_external_memory_fd 1
+#define VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME "VK_KHR_external_memory_fd"
+
+typedef struct VkImportMemoryFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType;
+ int fd;
+} VkImportMemoryFdInfoKHR;
+
+typedef struct VkMemoryFdPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t memoryTypeBits;
+} VkMemoryFdPropertiesKHR;
+
+typedef struct VkMemoryGetFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType;
+} VkMemoryGetFdInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd);
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBitsKHR handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR(
+ VkDevice device,
+ const VkMemoryGetFdInfoKHR* pGetFdInfo,
+ int* pFd);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBitsKHR handleType,
+ int fd,
+ VkMemoryFdPropertiesKHR* pMemoryFdProperties);
+#endif
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_KHR_win32_keyed_mutex 1
+#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1
+#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex"
+
+typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t acquireCount;
+ const VkDeviceMemory* pAcquireSyncs;
+ const uint64_t* pAcquireKeys;
+ const uint32_t* pAcquireTimeouts;
+ uint32_t releaseCount;
+ const VkDeviceMemory* pReleaseSyncs;
+ const uint64_t* pReleaseKeys;
+} VkWin32KeyedMutexAcquireReleaseInfoKHR;
+
+
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#define VK_KHR_external_semaphore_capabilities 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities"
+
+
+typedef enum VkExternalSemaphoreHandleTypeFlagBitsKHR {
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = 0x00000001,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = 0x00000002,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = 0x00000004,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = 0x00000008,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = 0x00000010,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkExternalSemaphoreHandleTypeFlagBitsKHR;
+typedef VkFlags VkExternalSemaphoreHandleTypeFlagsKHR;
+
+typedef enum VkExternalSemaphoreFeatureFlagBitsKHR {
+ VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR = 0x00000001,
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR = 0x00000002,
+ VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkExternalSemaphoreFeatureFlagBitsKHR;
+typedef VkFlags VkExternalSemaphoreFeatureFlagsKHR;
+
+typedef struct VkPhysicalDeviceExternalSemaphoreInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalSemaphoreHandleTypeFlagBitsKHR handleType;
+} VkPhysicalDeviceExternalSemaphoreInfoKHR;
+
+typedef struct VkExternalSemaphorePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalSemaphoreHandleTypeFlagsKHR exportFromImportedHandleTypes;
+ VkExternalSemaphoreHandleTypeFlagsKHR compatibleHandleTypes;
+ VkExternalSemaphoreFeatureFlagsKHR externalSemaphoreFeatures;
+} VkExternalSemaphorePropertiesKHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR* pExternalSemaphoreInfo, VkExternalSemaphorePropertiesKHR* pExternalSemaphoreProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalSemaphoreInfoKHR* pExternalSemaphoreInfo,
+ VkExternalSemaphorePropertiesKHR* pExternalSemaphoreProperties);
+#endif
+
+#define VK_KHR_external_semaphore 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore"
+
+
+typedef enum VkSemaphoreImportFlagBitsKHR {
+ VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = 0x00000001,
+ VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkSemaphoreImportFlagBitsKHR;
+typedef VkFlags VkSemaphoreImportFlagsKHR;
+
+typedef struct VkExportSemaphoreCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalSemaphoreHandleTypeFlagsKHR handleTypes;
+} VkExportSemaphoreCreateInfoKHR;
+
+
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_KHR_external_semaphore_win32 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32"
+
+typedef struct VkImportSemaphoreWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkSemaphoreImportFlagsKHR flags;
+ VkExternalSemaphoreHandleTypeFlagBitsKHR handleType;
+ HANDLE handle;
+ LPCWSTR name;
+} VkImportSemaphoreWin32HandleInfoKHR;
+
+typedef struct VkExportSemaphoreWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ const SECURITY_ATTRIBUTES* pAttributes;
+ DWORD dwAccess;
+ LPCWSTR name;
+} VkExportSemaphoreWin32HandleInfoKHR;
+
+typedef struct VkD3D12FenceSubmitInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreValuesCount;
+ const uint64_t* pWaitSemaphoreValues;
+ uint32_t signalSemaphoreValuesCount;
+ const uint64_t* pSignalSemaphoreValues;
+} VkD3D12FenceSubmitInfoKHR;
+
+typedef struct VkSemaphoreGetWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkExternalSemaphoreHandleTypeFlagBitsKHR handleType;
+} VkSemaphoreGetWin32HandleInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle);
+#endif
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#define VK_KHR_external_semaphore_fd 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME "VK_KHR_external_semaphore_fd"
+
+typedef struct VkImportSemaphoreFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkSemaphoreImportFlagsKHR flags;
+ VkExternalSemaphoreHandleTypeFlagBitsKHR handleType;
+ int fd;
+} VkImportSemaphoreFdInfoKHR;
+
+typedef struct VkSemaphoreGetFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkExternalSemaphoreHandleTypeFlagBitsKHR handleType;
+} VkSemaphoreGetFdInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR(
+ VkDevice device,
+ const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR(
+ VkDevice device,
+ const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
+ int* pFd);
+#endif
+
+#define VK_KHR_push_descriptor 1
+#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 1
+#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor"
+
+typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxPushDescriptors;
+} VkPhysicalDevicePushDescriptorPropertiesKHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites);
+#endif
+
+#define VK_KHR_16bit_storage 1
+#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1
+#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage"
+
+typedef struct VkPhysicalDevice16BitStorageFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 storageBuffer16BitAccess;
+ VkBool32 uniformAndStorageBuffer16BitAccess;
+ VkBool32 storagePushConstant16;
+ VkBool32 storageInputOutput16;
+} VkPhysicalDevice16BitStorageFeaturesKHR;
+
+
+
+#define VK_KHR_incremental_present 1
+#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1
+#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present"
+
+typedef struct VkRectLayerKHR {
+ VkOffset2D offset;
+ VkExtent2D extent;
+ uint32_t layer;
+} VkRectLayerKHR;
+
+typedef struct VkPresentRegionKHR {
+ uint32_t rectangleCount;
+ const VkRectLayerKHR* pRectangles;
+} VkPresentRegionKHR;
+
+typedef struct VkPresentRegionsKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const VkPresentRegionKHR* pRegions;
+} VkPresentRegionsKHR;
+
+
+
+#define VK_KHR_descriptor_update_template 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplateKHR)
+
+#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1
+#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template"
+
+
+typedef enum VkDescriptorUpdateTemplateTypeKHR {
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = 0,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_BEGIN_RANGE_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_END_RANGE_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_RANGE_SIZE_KHR = (VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR + 1),
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkDescriptorUpdateTemplateTypeKHR;
+
+typedef VkFlags VkDescriptorUpdateTemplateCreateFlagsKHR;
+
+typedef struct VkDescriptorUpdateTemplateEntryKHR {
+ uint32_t dstBinding;
+ uint32_t dstArrayElement;
+ uint32_t descriptorCount;
+ VkDescriptorType descriptorType;
+ size_t offset;
+ size_t stride;
+} VkDescriptorUpdateTemplateEntryKHR;
+
+typedef struct VkDescriptorUpdateTemplateCreateInfoKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDescriptorUpdateTemplateCreateFlagsKHR flags;
+ uint32_t descriptorUpdateEntryCount;
+ const VkDescriptorUpdateTemplateEntryKHR* pDescriptorUpdateEntries;
+ VkDescriptorUpdateTemplateTypeKHR templateType;
+ VkDescriptorSetLayout descriptorSetLayout;
+ VkPipelineBindPoint pipelineBindPoint;
+ VkPipelineLayout pipelineLayout;
+ uint32_t set;
+} VkDescriptorUpdateTemplateCreateInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplateKHR* pDescriptorUpdateTemplate);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice device, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, const void* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorUpdateTemplateKHR* pDescriptorUpdateTemplate);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+ const void* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR(
+ VkCommandBuffer commandBuffer,
+ VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+ VkPipelineLayout layout,
+ uint32_t set,
+ const void* pData);
+#endif
+
+#define VK_KHR_shared_presentable_image 1
+#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
+#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
+
+typedef struct VkSharedPresentSurfaceCapabilitiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags sharedPresentSupportedUsageFlags;
+} VkSharedPresentSurfaceCapabilitiesKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain);
+#endif
+
+#define VK_KHR_external_fence_capabilities 1
+#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities"
+
+
+typedef enum VkExternalFenceHandleTypeFlagBitsKHR {
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = 0x00000001,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = 0x00000002,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = 0x00000004,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR = 0x00000008,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkExternalFenceHandleTypeFlagBitsKHR;
+typedef VkFlags VkExternalFenceHandleTypeFlagsKHR;
+
+typedef enum VkExternalFenceFeatureFlagBitsKHR {
+ VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR = 0x00000001,
+ VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR = 0x00000002,
+ VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkExternalFenceFeatureFlagBitsKHR;
+typedef VkFlags VkExternalFenceFeatureFlagsKHR;
+
+typedef struct VkPhysicalDeviceExternalFenceInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalFenceHandleTypeFlagBitsKHR handleType;
+} VkPhysicalDeviceExternalFenceInfoKHR;
+
+typedef struct VkExternalFencePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalFenceHandleTypeFlagsKHR exportFromImportedHandleTypes;
+ VkExternalFenceHandleTypeFlagsKHR compatibleHandleTypes;
+ VkExternalFenceFeatureFlagsKHR externalFenceFeatures;
+} VkExternalFencePropertiesKHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR* pExternalFenceInfo, VkExternalFencePropertiesKHR* pExternalFenceProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfoKHR* pExternalFenceInfo,
+ VkExternalFencePropertiesKHR* pExternalFenceProperties);
+#endif
+
+#define VK_KHR_external_fence 1
+#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence"
+
+
+typedef enum VkFenceImportFlagBitsKHR {
+ VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = 0x00000001,
+ VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkFenceImportFlagBitsKHR;
+typedef VkFlags VkFenceImportFlagsKHR;
+
+typedef struct VkExportFenceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalFenceHandleTypeFlagsKHR handleTypes;
+} VkExportFenceCreateInfoKHR;
+
+
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_KHR_external_fence_win32 1
+#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32"
+
+typedef struct VkImportFenceWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFence fence;
+ VkFenceImportFlagsKHR flags;
+ VkExternalFenceHandleTypeFlagBitsKHR handleType;
+ HANDLE handle;
+ LPCWSTR name;
+} VkImportFenceWin32HandleInfoKHR;
+
+typedef struct VkExportFenceWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ const SECURITY_ATTRIBUTES* pAttributes;
+ DWORD dwAccess;
+ LPCWSTR name;
+} VkExportFenceWin32HandleInfoKHR;
+
+typedef struct VkFenceGetWin32HandleInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFence fence;
+ VkExternalFenceHandleTypeFlagBitsKHR handleType;
+} VkFenceGetWin32HandleInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR(
+ VkDevice device,
+ const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR(
+ VkDevice device,
+ const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle);
+#endif
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#define VK_KHR_external_fence_fd 1
+#define VK_KHR_EXTERNAL_FENCE_FD_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME "VK_KHR_external_fence_fd"
+
+typedef struct VkImportFenceFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFence fence;
+ VkFenceImportFlagsKHR flags;
+ VkExternalFenceHandleTypeFlagBitsKHR handleType;
+ int fd;
+} VkImportFenceFdInfoKHR;
+
+typedef struct VkFenceGetFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFence fence;
+ VkExternalFenceHandleTypeFlagBitsKHR handleType;
+} VkFenceGetFdInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR(
+ VkDevice device,
+ const VkImportFenceFdInfoKHR* pImportFenceFdInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR(
+ VkDevice device,
+ const VkFenceGetFdInfoKHR* pGetFdInfo,
+ int* pFd);
+#endif
+
+#define VK_KHR_get_surface_capabilities2 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
+
+typedef struct VkPhysicalDeviceSurfaceInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSurfaceKHR surface;
+} VkPhysicalDeviceSurfaceInfo2KHR;
+
+typedef struct VkSurfaceCapabilities2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceCapabilitiesKHR surfaceCapabilities;
+} VkSurfaceCapabilities2KHR;
+
+typedef struct VkSurfaceFormat2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceFormatKHR surfaceFormat;
+} VkSurfaceFormat2KHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormat2KHR* pSurfaceFormats);
+#endif
+
+#define VK_KHR_variable_pointers 1
+#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1
+#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers"
+
+typedef struct VkPhysicalDeviceVariablePointerFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 variablePointersStorageBuffer;
+ VkBool32 variablePointers;
+} VkPhysicalDeviceVariablePointerFeaturesKHR;
+
+
+
+#define VK_KHR_dedicated_allocation 1
+#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3
+#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation"
+
+typedef struct VkMemoryDedicatedRequirementsKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 prefersDedicatedAllocation;
+ VkBool32 requiresDedicatedAllocation;
+} VkMemoryDedicatedRequirementsKHR;
+
+typedef struct VkMemoryDedicatedAllocateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+ VkBuffer buffer;
+} VkMemoryDedicatedAllocateInfoKHR;
+
+
+
+#define VK_KHR_storage_buffer_storage_class 1
+#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1
+#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class"
+
+
+#define VK_KHR_relaxed_block_layout 1
+#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1
+#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout"
+
+
+#define VK_KHR_get_memory_requirements2 1
+#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1
+#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2"
+
+typedef struct VkBufferMemoryRequirementsInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer buffer;
+} VkBufferMemoryRequirementsInfo2KHR;
+
+typedef struct VkImageMemoryRequirementsInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+} VkImageMemoryRequirementsInfo2KHR;
+
+typedef struct VkImageSparseMemoryRequirementsInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+} VkImageSparseMemoryRequirementsInfo2KHR;
+
+typedef struct VkMemoryRequirements2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkMemoryRequirements memoryRequirements;
+} VkMemoryRequirements2KHR;
+
+typedef struct VkSparseImageMemoryRequirements2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSparseImageMemoryRequirements memoryRequirements;
+} VkSparseImageMemoryRequirements2KHR;
+
+
+typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2KHR* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2KHR* pInfo,
+ VkMemoryRequirements2KHR* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2KHR* pInfo,
+ VkMemoryRequirements2KHR* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2KHR* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements);
+#endif
+
+#define VK_EXT_debug_report 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
+
+#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 8
+#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
+#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT
+#define VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT
+
+
+typedef enum VkDebugReportObjectTypeEXT {
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0,
+ VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3,
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5,
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6,
+ VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9,
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10,
+ VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11,
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13,
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17,
+ VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23,
+ VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24,
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30,
+ VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31,
+ VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = 1000085000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1),
+ VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDebugReportObjectTypeEXT;
+
+
+typedef enum VkDebugReportFlagBitsEXT {
+ VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001,
+ VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002,
+ VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004,
+ VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008,
+ VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010,
+ VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDebugReportFlagBitsEXT;
+typedef VkFlags VkDebugReportFlagsEXT;
+
+typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char* pLayerPrefix,
+ const char* pMessage,
+ void* pUserData);
+
+typedef struct VkDebugReportCallbackCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugReportFlagsEXT flags;
+ PFN_vkDebugReportCallbackEXT pfnCallback;
+ void* pUserData;
+} VkDebugReportCallbackCreateInfoEXT;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);
+typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
+ VkInstance instance,
+ const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDebugReportCallbackEXT* pCallback);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(
+ VkInstance instance,
+ VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
+ VkInstance instance,
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char* pLayerPrefix,
+ const char* pMessage);
+#endif
+
+#define VK_NV_glsl_shader 1
+#define VK_NV_GLSL_SHADER_SPEC_VERSION 1
+#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader"
+
+
+#define VK_EXT_depth_range_unrestricted 1
+#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1
+#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted"
+
+
+#define VK_IMG_filter_cubic 1
+#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1
+#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic"
+
+
+#define VK_AMD_rasterization_order 1
+#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1
+#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order"
+
+
+typedef enum VkRasterizationOrderAMD {
+ VK_RASTERIZATION_ORDER_STRICT_AMD = 0,
+ VK_RASTERIZATION_ORDER_RELAXED_AMD = 1,
+ VK_RASTERIZATION_ORDER_BEGIN_RANGE_AMD = VK_RASTERIZATION_ORDER_STRICT_AMD,
+ VK_RASTERIZATION_ORDER_END_RANGE_AMD = VK_RASTERIZATION_ORDER_RELAXED_AMD,
+ VK_RASTERIZATION_ORDER_RANGE_SIZE_AMD = (VK_RASTERIZATION_ORDER_RELAXED_AMD - VK_RASTERIZATION_ORDER_STRICT_AMD + 1),
+ VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF
+} VkRasterizationOrderAMD;
+
+typedef struct VkPipelineRasterizationStateRasterizationOrderAMD {
+ VkStructureType sType;
+ const void* pNext;
+ VkRasterizationOrderAMD rasterizationOrder;
+} VkPipelineRasterizationStateRasterizationOrderAMD;
+
+
+
+#define VK_AMD_shader_trinary_minmax 1
+#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1
+#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax"
+
+
+#define VK_AMD_shader_explicit_vertex_parameter 1
+#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1
+#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter"
+
+
+#define VK_EXT_debug_marker 1
+#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 4
+#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker"
+
+typedef struct VkDebugMarkerObjectNameInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugReportObjectTypeEXT objectType;
+ uint64_t object;
+ const char* pObjectName;
+} VkDebugMarkerObjectNameInfoEXT;
+
+typedef struct VkDebugMarkerObjectTagInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugReportObjectTypeEXT objectType;
+ uint64_t object;
+ uint64_t tagName;
+ size_t tagSize;
+ const void* pTag;
+} VkDebugMarkerObjectTagInfoEXT;
+
+typedef struct VkDebugMarkerMarkerInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ const char* pMarkerName;
+ float color[4];
+} VkDebugMarkerMarkerInfoEXT;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer);
+typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectTagInfoEXT* pTagInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectNameInfoEXT* pNameInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+#endif
+
+#define VK_AMD_gcn_shader 1
+#define VK_AMD_GCN_SHADER_SPEC_VERSION 1
+#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader"
+
+
+#define VK_NV_dedicated_allocation 1
+#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1
+#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation"
+
+typedef struct VkDedicatedAllocationImageCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 dedicatedAllocation;
+} VkDedicatedAllocationImageCreateInfoNV;
+
+typedef struct VkDedicatedAllocationBufferCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 dedicatedAllocation;
+} VkDedicatedAllocationBufferCreateInfoNV;
+
+typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+ VkBuffer buffer;
+} VkDedicatedAllocationMemoryAllocateInfoNV;
+
+
+
+#define VK_AMD_draw_indirect_count 1
+#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+#endif
+
+#define VK_AMD_negative_viewport_height 1
+#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1
+#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height"
+
+
+#define VK_AMD_gpu_shader_half_float 1
+#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 1
+#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float"
+
+
+#define VK_AMD_shader_ballot 1
+#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1
+#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot"
+
+
+#define VK_AMD_texture_gather_bias_lod 1
+#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1
+#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod"
+
+typedef struct VkTextureLODGatherFormatPropertiesAMD {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 supportsTextureGatherLODBiasAMD;
+} VkTextureLODGatherFormatPropertiesAMD;
+
+
+
+#define VK_KHX_multiview 1
+#define VK_KHX_MULTIVIEW_SPEC_VERSION 1
+#define VK_KHX_MULTIVIEW_EXTENSION_NAME "VK_KHX_multiview"
+
+typedef struct VkRenderPassMultiviewCreateInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t subpassCount;
+ const uint32_t* pViewMasks;
+ uint32_t dependencyCount;
+ const int32_t* pViewOffsets;
+ uint32_t correlationMaskCount;
+ const uint32_t* pCorrelationMasks;
+} VkRenderPassMultiviewCreateInfoKHX;
+
+typedef struct VkPhysicalDeviceMultiviewFeaturesKHX {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 multiview;
+ VkBool32 multiviewGeometryShader;
+ VkBool32 multiviewTessellationShader;
+} VkPhysicalDeviceMultiviewFeaturesKHX;
+
+typedef struct VkPhysicalDeviceMultiviewPropertiesKHX {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxMultiviewViewCount;
+ uint32_t maxMultiviewInstanceIndex;
+} VkPhysicalDeviceMultiviewPropertiesKHX;
+
+
+
+#define VK_IMG_format_pvrtc 1
+#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1
+#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
+
+
+#define VK_NV_external_memory_capabilities 1
+#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_NV_external_memory_capabilities"
+
+
+typedef enum VkExternalMemoryHandleTypeFlagBitsNV {
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkExternalMemoryHandleTypeFlagBitsNV;
+typedef VkFlags VkExternalMemoryHandleTypeFlagsNV;
+
+typedef enum VkExternalMemoryFeatureFlagBitsNV {
+ VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV = 0x00000001,
+ VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV = 0x00000002,
+ VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV = 0x00000004,
+ VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkExternalMemoryFeatureFlagBitsNV;
+typedef VkFlags VkExternalMemoryFeatureFlagsNV;
+
+typedef struct VkExternalImageFormatPropertiesNV {
+ VkImageFormatProperties imageFormatProperties;
+ VkExternalMemoryFeatureFlagsNV externalMemoryFeatures;
+ VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes;
+ VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes;
+} VkExternalImageFormatPropertiesNV;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties);
+#endif
+
+#define VK_NV_external_memory 1
+#define VK_NV_EXTERNAL_MEMORY_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME "VK_NV_external_memory"
+
+typedef struct VkExternalMemoryImageCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsNV handleTypes;
+} VkExternalMemoryImageCreateInfoNV;
+
+typedef struct VkExportMemoryAllocateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsNV handleTypes;
+} VkExportMemoryAllocateInfoNV;
+
+
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_NV_external_memory_win32 1
+#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32"
+
+typedef struct VkImportMemoryWin32HandleInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsNV handleType;
+ HANDLE handle;
+} VkImportMemoryWin32HandleInfoNV;
+
+typedef struct VkExportMemoryWin32HandleInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ const SECURITY_ATTRIBUTES* pAttributes;
+ DWORD dwAccess;
+} VkExportMemoryWin32HandleInfoNV;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkExternalMemoryHandleTypeFlagsNV handleType,
+ HANDLE* pHandle);
+#endif
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#define VK_NV_win32_keyed_mutex 1
+#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1
+#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
+
+typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t acquireCount;
+ const VkDeviceMemory* pAcquireSyncs;
+ const uint64_t* pAcquireKeys;
+ const uint32_t* pAcquireTimeoutMilliseconds;
+ uint32_t releaseCount;
+ const VkDeviceMemory* pReleaseSyncs;
+ const uint64_t* pReleaseKeys;
+} VkWin32KeyedMutexAcquireReleaseInfoNV;
+
+
+#endif /* VK_USE_PLATFORM_WIN32_KHR */
+
+#define VK_KHX_device_group 1
+#define VK_MAX_DEVICE_GROUP_SIZE_KHX 32
+#define VK_KHX_DEVICE_GROUP_SPEC_VERSION 1
+#define VK_KHX_DEVICE_GROUP_EXTENSION_NAME "VK_KHX_device_group"
+
+
+typedef enum VkPeerMemoryFeatureFlagBitsKHX {
+ VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHX = 0x00000001,
+ VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHX = 0x00000002,
+ VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHX = 0x00000004,
+ VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHX = 0x00000008,
+ VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_KHX = 0x7FFFFFFF
+} VkPeerMemoryFeatureFlagBitsKHX;
+typedef VkFlags VkPeerMemoryFeatureFlagsKHX;
+
+typedef enum VkMemoryAllocateFlagBitsKHX {
+ VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX = 0x00000001,
+ VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM_KHX = 0x7FFFFFFF
+} VkMemoryAllocateFlagBitsKHX;
+typedef VkFlags VkMemoryAllocateFlagsKHX;
+
+typedef enum VkDeviceGroupPresentModeFlagBitsKHX {
+ VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHX = 0x00000001,
+ VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHX = 0x00000002,
+ VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHX = 0x00000004,
+ VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHX = 0x00000008,
+ VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHX = 0x7FFFFFFF
+} VkDeviceGroupPresentModeFlagBitsKHX;
+typedef VkFlags VkDeviceGroupPresentModeFlagsKHX;
+
+typedef struct VkMemoryAllocateFlagsInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkMemoryAllocateFlagsKHX flags;
+ uint32_t deviceMask;
+} VkMemoryAllocateFlagsInfoKHX;
+
+typedef struct VkBindBufferMemoryInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer buffer;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ uint32_t deviceIndexCount;
+ const uint32_t* pDeviceIndices;
+} VkBindBufferMemoryInfoKHX;
+
+typedef struct VkBindImageMemoryInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ uint32_t deviceIndexCount;
+ const uint32_t* pDeviceIndices;
+ uint32_t SFRRectCount;
+ const VkRect2D* pSFRRects;
+} VkBindImageMemoryInfoKHX;
+
+typedef struct VkDeviceGroupRenderPassBeginInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t deviceMask;
+ uint32_t deviceRenderAreaCount;
+ const VkRect2D* pDeviceRenderAreas;
+} VkDeviceGroupRenderPassBeginInfoKHX;
+
+typedef struct VkDeviceGroupCommandBufferBeginInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t deviceMask;
+} VkDeviceGroupCommandBufferBeginInfoKHX;
+
+typedef struct VkDeviceGroupSubmitInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const uint32_t* pWaitSemaphoreDeviceIndices;
+ uint32_t commandBufferCount;
+ const uint32_t* pCommandBufferDeviceMasks;
+ uint32_t signalSemaphoreCount;
+ const uint32_t* pSignalSemaphoreDeviceIndices;
+} VkDeviceGroupSubmitInfoKHX;
+
+typedef struct VkDeviceGroupBindSparseInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t resourceDeviceIndex;
+ uint32_t memoryDeviceIndex;
+} VkDeviceGroupBindSparseInfoKHX;
+
+typedef struct VkDeviceGroupPresentCapabilitiesKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE_KHX];
+ VkDeviceGroupPresentModeFlagsKHX modes;
+} VkDeviceGroupPresentCapabilitiesKHX;
+
+typedef struct VkImageSwapchainCreateInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainKHR swapchain;
+} VkImageSwapchainCreateInfoKHX;
+
+typedef struct VkBindImageMemorySwapchainInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainKHR swapchain;
+ uint32_t imageIndex;
+} VkBindImageMemorySwapchainInfoKHX;
+
+typedef struct VkAcquireNextImageInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainKHR swapchain;
+ uint64_t timeout;
+ VkSemaphore semaphore;
+ VkFence fence;
+ uint32_t deviceMask;
+} VkAcquireNextImageInfoKHX;
+
+typedef struct VkDeviceGroupPresentInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const uint32_t* pDeviceMasks;
+ VkDeviceGroupPresentModeFlagBitsKHX mode;
+} VkDeviceGroupPresentInfoKHX;
+
+typedef struct VkDeviceGroupSwapchainCreateInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceGroupPresentModeFlagsKHX modes;
+} VkDeviceGroupSwapchainCreateInfoKHX;
+
+
+typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHX)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlagsKHX* pPeerMemoryFeatures);
+typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHX)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfoKHX* pBindInfos);
+typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHX)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfoKHX* pBindInfos);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHX)(VkCommandBuffer commandBuffer, uint32_t deviceMask);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHX)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHX* pDeviceGroupPresentCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHX)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHX* pModes);
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHX)(VkDevice device, const VkAcquireNextImageInfoKHX* pAcquireInfo, uint32_t* pImageIndex);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHX)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHX)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHX(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlagsKHX* pPeerMemoryFeatures);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHX(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfoKHX* pBindInfos);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHX(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfoKHX* pBindInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHX(
+ VkCommandBuffer commandBuffer,
+ uint32_t deviceMask);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHX(
+ VkDevice device,
+ VkDeviceGroupPresentCapabilitiesKHX* pDeviceGroupPresentCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHX(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHX* pModes);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHX(
+ VkDevice device,
+ const VkAcquireNextImageInfoKHX* pAcquireInfo,
+ uint32_t* pImageIndex);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHX(
+ VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHX(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pRectCount,
+ VkRect2D* pRects);
+#endif
+
+#define VK_EXT_validation_flags 1
+#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 1
+#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags"
+
+
+typedef enum VkValidationCheckEXT {
+ VK_VALIDATION_CHECK_ALL_EXT = 0,
+ VK_VALIDATION_CHECK_SHADERS_EXT = 1,
+ VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT,
+ VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_SHADERS_EXT,
+ VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_SHADERS_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1),
+ VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkValidationCheckEXT;
+
+typedef struct VkValidationFlagsEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t disabledValidationCheckCount;
+ VkValidationCheckEXT* pDisabledValidationChecks;
+} VkValidationFlagsEXT;
+
+
+
+#ifdef VK_USE_PLATFORM_VI_NN
+#define VK_NN_vi_surface 1
+#define VK_NN_VI_SURFACE_SPEC_VERSION 1
+#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface"
+
+typedef VkFlags VkViSurfaceCreateFlagsNN;
+
+typedef struct VkViSurfaceCreateInfoNN {
+ VkStructureType sType;
+ const void* pNext;
+ VkViSurfaceCreateFlagsNN flags;
+ void* window;
+} VkViSurfaceCreateInfoNN;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(
+ VkInstance instance,
+ const VkViSurfaceCreateInfoNN* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_VI_NN */
+
+#define VK_EXT_shader_subgroup_ballot 1
+#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1
+#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot"
+
+
+#define VK_EXT_shader_subgroup_vote 1
+#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1
+#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
+
+
+#define VK_KHX_device_group_creation 1
+#define VK_KHX_DEVICE_GROUP_CREATION_SPEC_VERSION 1
+#define VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHX_device_group_creation"
+
+typedef struct VkPhysicalDeviceGroupPropertiesKHX {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t physicalDeviceCount;
+ VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE_KHX];
+ VkBool32 subsetAllocation;
+} VkPhysicalDeviceGroupPropertiesKHX;
+
+typedef struct VkDeviceGroupDeviceCreateInfoKHX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t physicalDeviceCount;
+ const VkPhysicalDevice* pPhysicalDevices;
+} VkDeviceGroupDeviceCreateInfoKHX;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHX)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupPropertiesKHX* pPhysicalDeviceGroupProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHX(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupPropertiesKHX* pPhysicalDeviceGroupProperties);
+#endif
+
+#define VK_NVX_device_generated_commands 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX)
+
+#define VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3
+#define VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NVX_device_generated_commands"
+
+
+typedef enum VkIndirectCommandsTokenTypeNVX {
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX = 0,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX = 1,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX = 2,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX = 3,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX = 4,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX = 5,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX = 6,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX = 7,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_BEGIN_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_END_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_RANGE_SIZE_NVX = (VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX + 1),
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkIndirectCommandsTokenTypeNVX;
+
+typedef enum VkObjectEntryTypeNVX {
+ VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX = 0,
+ VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX = 1,
+ VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX = 2,
+ VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX = 3,
+ VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX = 4,
+ VK_OBJECT_ENTRY_TYPE_BEGIN_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX,
+ VK_OBJECT_ENTRY_TYPE_END_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX,
+ VK_OBJECT_ENTRY_TYPE_RANGE_SIZE_NVX = (VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX + 1),
+ VK_OBJECT_ENTRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkObjectEntryTypeNVX;
+
+
+typedef enum VkIndirectCommandsLayoutUsageFlagBitsNVX {
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX = 0x00000001,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX = 0x00000002,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX = 0x00000004,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX = 0x00000008,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkIndirectCommandsLayoutUsageFlagBitsNVX;
+typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX;
+
+typedef enum VkObjectEntryUsageFlagBitsNVX {
+ VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX = 0x00000001,
+ VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX = 0x00000002,
+ VK_OBJECT_ENTRY_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkObjectEntryUsageFlagBitsNVX;
+typedef VkFlags VkObjectEntryUsageFlagsNVX;
+
+typedef struct VkDeviceGeneratedCommandsFeaturesNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 computeBindingPointSupport;
+} VkDeviceGeneratedCommandsFeaturesNVX;
+
+typedef struct VkDeviceGeneratedCommandsLimitsNVX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t maxIndirectCommandsLayoutTokenCount;
+ uint32_t maxObjectEntryCounts;
+ uint32_t minSequenceCountBufferOffsetAlignment;
+ uint32_t minSequenceIndexBufferOffsetAlignment;
+ uint32_t minCommandsTokenBufferOffsetAlignment;
+} VkDeviceGeneratedCommandsLimitsNVX;
+
+typedef struct VkIndirectCommandsTokenNVX {
+ VkIndirectCommandsTokenTypeNVX tokenType;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+} VkIndirectCommandsTokenNVX;
+
+typedef struct VkIndirectCommandsLayoutTokenNVX {
+ VkIndirectCommandsTokenTypeNVX tokenType;
+ uint32_t bindingUnit;
+ uint32_t dynamicCount;
+ uint32_t divisor;
+} VkIndirectCommandsLayoutTokenNVX;
+
+typedef struct VkIndirectCommandsLayoutCreateInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineBindPoint pipelineBindPoint;
+ VkIndirectCommandsLayoutUsageFlagsNVX flags;
+ uint32_t tokenCount;
+ const VkIndirectCommandsLayoutTokenNVX* pTokens;
+} VkIndirectCommandsLayoutCreateInfoNVX;
+
+typedef struct VkCmdProcessCommandsInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkObjectTableNVX objectTable;
+ VkIndirectCommandsLayoutNVX indirectCommandsLayout;
+ uint32_t indirectCommandsTokenCount;
+ const VkIndirectCommandsTokenNVX* pIndirectCommandsTokens;
+ uint32_t maxSequencesCount;
+ VkCommandBuffer targetCommandBuffer;
+ VkBuffer sequencesCountBuffer;
+ VkDeviceSize sequencesCountOffset;
+ VkBuffer sequencesIndexBuffer;
+ VkDeviceSize sequencesIndexOffset;
+} VkCmdProcessCommandsInfoNVX;
+
+typedef struct VkCmdReserveSpaceForCommandsInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkObjectTableNVX objectTable;
+ VkIndirectCommandsLayoutNVX indirectCommandsLayout;
+ uint32_t maxSequencesCount;
+} VkCmdReserveSpaceForCommandsInfoNVX;
+
+typedef struct VkObjectTableCreateInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t objectCount;
+ const VkObjectEntryTypeNVX* pObjectEntryTypes;
+ const uint32_t* pObjectEntryCounts;
+ const VkObjectEntryUsageFlagsNVX* pObjectEntryUsageFlags;
+ uint32_t maxUniformBuffersPerDescriptor;
+ uint32_t maxStorageBuffersPerDescriptor;
+ uint32_t maxStorageImagesPerDescriptor;
+ uint32_t maxSampledImagesPerDescriptor;
+ uint32_t maxPipelineLayouts;
+} VkObjectTableCreateInfoNVX;
+
+typedef struct VkObjectTableEntryNVX {
+ VkObjectEntryTypeNVX type;
+ VkObjectEntryUsageFlagsNVX flags;
+} VkObjectTableEntryNVX;
+
+typedef struct VkObjectTablePipelineEntryNVX {
+ VkObjectEntryTypeNVX type;
+ VkObjectEntryUsageFlagsNVX flags;
+ VkPipeline pipeline;
+} VkObjectTablePipelineEntryNVX;
+
+typedef struct VkObjectTableDescriptorSetEntryNVX {
+ VkObjectEntryTypeNVX type;
+ VkObjectEntryUsageFlagsNVX flags;
+ VkPipelineLayout pipelineLayout;
+ VkDescriptorSet descriptorSet;
+} VkObjectTableDescriptorSetEntryNVX;
+
+typedef struct VkObjectTableVertexBufferEntryNVX {
+ VkObjectEntryTypeNVX type;
+ VkObjectEntryUsageFlagsNVX flags;
+ VkBuffer buffer;
+} VkObjectTableVertexBufferEntryNVX;
+
+typedef struct VkObjectTableIndexBufferEntryNVX {
+ VkObjectEntryTypeNVX type;
+ VkObjectEntryUsageFlagsNVX flags;
+ VkBuffer buffer;
+ VkIndexType indexType;
+} VkObjectTableIndexBufferEntryNVX;
+
+typedef struct VkObjectTablePushConstantEntryNVX {
+ VkObjectEntryTypeNVX type;
+ VkObjectEntryUsageFlagsNVX flags;
+ VkPipelineLayout pipelineLayout;
+ VkShaderStageFlags stageFlags;
+} VkObjectTablePushConstantEntryNVX;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdProcessCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdReserveSpaceForCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNVX)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout);
+typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNVX)(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateObjectTableNVX)(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable);
+typedef void (VKAPI_PTR *PFN_vkDestroyObjectTableNVX)(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkRegisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices);
+typedef VkResult (VKAPI_PTR *PFN_vkUnregisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)(VkPhysicalDevice physicalDevice, VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, VkDeviceGeneratedCommandsLimitsNVX* pLimits);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdProcessCommandsNVX(
+ VkCommandBuffer commandBuffer,
+ const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdReserveSpaceForCommandsNVX(
+ VkCommandBuffer commandBuffer,
+ const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNVX(
+ VkDevice device,
+ const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNVX(
+ VkDevice device,
+ VkIndirectCommandsLayoutNVX indirectCommandsLayout,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateObjectTableNVX(
+ VkDevice device,
+ const VkObjectTableCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkObjectTableNVX* pObjectTable);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyObjectTableNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkRegisterObjectsNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ uint32_t objectCount,
+ const VkObjectTableEntryNVX* const* ppObjectTableEntries,
+ const uint32_t* pObjectIndices);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkUnregisterObjectsNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ uint32_t objectCount,
+ const VkObjectEntryTypeNVX* pObjectEntryTypes,
+ const uint32_t* pObjectIndices);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(
+ VkPhysicalDevice physicalDevice,
+ VkDeviceGeneratedCommandsFeaturesNVX* pFeatures,
+ VkDeviceGeneratedCommandsLimitsNVX* pLimits);
+#endif
+
+#define VK_NV_clip_space_w_scaling 1
+#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1
+#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling"
+
+typedef struct VkViewportWScalingNV {
+ float xcoeff;
+ float ycoeff;
+} VkViewportWScalingNV;
+
+typedef struct VkPipelineViewportWScalingStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 viewportWScalingEnable;
+ uint32_t viewportCount;
+ const VkViewportWScalingNV* pViewportWScalings;
+} VkPipelineViewportWScalingStateCreateInfoNV;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewportWScalingNV* pViewportWScalings);
+#endif
+
+#define VK_EXT_direct_mode_display 1
+#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1
+#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display"
+
+typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display);
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#define VK_EXT_acquire_xlib_display 1
+#include <X11/extensions/Xrandr.h>
+
+#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1
+#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display"
+
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
+typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ Display* dpy,
+ VkDisplayKHR display);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ Display* dpy,
+ RROutput rrOutput,
+ VkDisplayKHR* pDisplay);
+#endif
+#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
+
+#define VK_EXT_display_surface_counter 1
+#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1
+#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter"
+#define VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT
+
+
+typedef enum VkSurfaceCounterFlagBitsEXT {
+ VK_SURFACE_COUNTER_VBLANK_EXT = 0x00000001,
+ VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkSurfaceCounterFlagBitsEXT;
+typedef VkFlags VkSurfaceCounterFlagsEXT;
+
+typedef struct VkSurfaceCapabilities2EXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t minImageCount;
+ uint32_t maxImageCount;
+ VkExtent2D currentExtent;
+ VkExtent2D minImageExtent;
+ VkExtent2D maxImageExtent;
+ uint32_t maxImageArrayLayers;
+ VkSurfaceTransformFlagsKHR supportedTransforms;
+ VkSurfaceTransformFlagBitsKHR currentTransform;
+ VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
+ VkImageUsageFlags supportedUsageFlags;
+ VkSurfaceCounterFlagsEXT supportedSurfaceCounters;
+} VkSurfaceCapabilities2EXT;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+#endif
+
+#define VK_EXT_display_control 1
+#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1
+#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control"
+
+
+typedef enum VkDisplayPowerStateEXT {
+ VK_DISPLAY_POWER_STATE_OFF_EXT = 0,
+ VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1,
+ VK_DISPLAY_POWER_STATE_ON_EXT = 2,
+ VK_DISPLAY_POWER_STATE_BEGIN_RANGE_EXT = VK_DISPLAY_POWER_STATE_OFF_EXT,
+ VK_DISPLAY_POWER_STATE_END_RANGE_EXT = VK_DISPLAY_POWER_STATE_ON_EXT,
+ VK_DISPLAY_POWER_STATE_RANGE_SIZE_EXT = (VK_DISPLAY_POWER_STATE_ON_EXT - VK_DISPLAY_POWER_STATE_OFF_EXT + 1),
+ VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDisplayPowerStateEXT;
+
+typedef enum VkDeviceEventTypeEXT {
+ VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0,
+ VK_DEVICE_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT,
+ VK_DEVICE_EVENT_TYPE_END_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT,
+ VK_DEVICE_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT + 1),
+ VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceEventTypeEXT;
+
+typedef enum VkDisplayEventTypeEXT {
+ VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0,
+ VK_DISPLAY_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT,
+ VK_DISPLAY_EVENT_TYPE_END_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT,
+ VK_DISPLAY_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT + 1),
+ VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDisplayEventTypeEXT;
+
+typedef struct VkDisplayPowerInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayPowerStateEXT powerState;
+} VkDisplayPowerInfoEXT;
+
+typedef struct VkDeviceEventInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceEventTypeEXT deviceEvent;
+} VkDeviceEventInfoEXT;
+
+typedef struct VkDisplayEventInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayEventTypeEXT displayEvent;
+} VkDisplayEventInfoEXT;
+
+typedef struct VkSwapchainCounterCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkSurfaceCounterFlagsEXT surfaceCounters;
+} VkSwapchainCounterCreateInfoEXT;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
+typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT(
+ VkDevice device,
+ const VkDeviceEventInfoEXT* pDeviceEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayEventInfoEXT* pDisplayEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkSurfaceCounterFlagBitsEXT counter,
+ uint64_t* pCounterValue);
+#endif
+
+#define VK_GOOGLE_display_timing 1
+#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1
+#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing"
+
+typedef struct VkRefreshCycleDurationGOOGLE {
+ uint64_t refreshDuration;
+} VkRefreshCycleDurationGOOGLE;
+
+typedef struct VkPastPresentationTimingGOOGLE {
+ uint32_t presentID;
+ uint64_t desiredPresentTime;
+ uint64_t actualPresentTime;
+ uint64_t earliestPresentTime;
+ uint64_t presentMargin;
+} VkPastPresentationTimingGOOGLE;
+
+typedef struct VkPresentTimeGOOGLE {
+ uint32_t presentID;
+ uint64_t desiredPresentTime;
+} VkPresentTimeGOOGLE;
+
+typedef struct VkPresentTimesInfoGOOGLE {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const VkPresentTimeGOOGLE* pTimes;
+} VkPresentTimesInfoGOOGLE;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pPresentationTimingCount,
+ VkPastPresentationTimingGOOGLE* pPresentationTimings);
+#endif
+
+#define VK_NV_sample_mask_override_coverage 1
+#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1
+#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage"
+
+
+#define VK_NV_geometry_shader_passthrough 1
+#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1
+#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough"
+
+
+#define VK_NV_viewport_array2 1
+#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1
+#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2"
+
+
+#define VK_NVX_multiview_per_view_attributes 1
+#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION 1
+#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes"
+
+typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 perViewPositionAllComponents;
+} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX;
+
+
+
+#define VK_NV_viewport_swizzle 1
+#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1
+#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle"
+
+
+typedef enum VkViewportCoordinateSwizzleNV {
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_BEGIN_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_END_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_RANGE_SIZE_NV = (VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV + 1),
+ VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkViewportCoordinateSwizzleNV;
+
+typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV;
+
+typedef struct VkViewportSwizzleNV {
+ VkViewportCoordinateSwizzleNV x;
+ VkViewportCoordinateSwizzleNV y;
+ VkViewportCoordinateSwizzleNV z;
+ VkViewportCoordinateSwizzleNV w;
+} VkViewportSwizzleNV;
+
+typedef struct VkPipelineViewportSwizzleStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineViewportSwizzleStateCreateFlagsNV flags;
+ uint32_t viewportCount;
+ const VkViewportSwizzleNV* pViewportSwizzles;
+} VkPipelineViewportSwizzleStateCreateInfoNV;
+
+
+
+#define VK_EXT_discard_rectangles 1
+#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1
+#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles"
+
+
+typedef enum VkDiscardRectangleModeEXT {
+ VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0,
+ VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1,
+ VK_DISCARD_RECTANGLE_MODE_BEGIN_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT,
+ VK_DISCARD_RECTANGLE_MODE_END_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT,
+ VK_DISCARD_RECTANGLE_MODE_RANGE_SIZE_EXT = (VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT + 1),
+ VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDiscardRectangleModeEXT;
+
+typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT;
+
+typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxDiscardRectangles;
+} VkPhysicalDeviceDiscardRectanglePropertiesEXT;
+
+typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineDiscardRectangleStateCreateFlagsEXT flags;
+ VkDiscardRectangleModeEXT discardRectangleMode;
+ uint32_t discardRectangleCount;
+ const VkRect2D* pDiscardRectangles;
+} VkPipelineDiscardRectangleStateCreateInfoEXT;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D* pDiscardRectangles);
+#endif
+
+#define VK_EXT_swapchain_colorspace 1
+#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 3
+#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace"
+
+
+#define VK_EXT_hdr_metadata 1
+#define VK_EXT_HDR_METADATA_SPEC_VERSION 1
+#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata"
+
+typedef struct VkXYColorEXT {
+ float x;
+ float y;
+} VkXYColorEXT;
+
+typedef struct VkHdrMetadataEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkXYColorEXT displayPrimaryRed;
+ VkXYColorEXT displayPrimaryGreen;
+ VkXYColorEXT displayPrimaryBlue;
+ VkXYColorEXT whitePoint;
+ float maxLuminance;
+ float minLuminance;
+ float maxContentLightLevel;
+ float maxFrameAverageLightLevel;
+} VkHdrMetadataEXT;
+
+
+typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainKHR* pSwapchains,
+ const VkHdrMetadataEXT* pMetadata);
+#endif
+
+#ifdef VK_USE_PLATFORM_IOS_MVK
+#define VK_MVK_ios_surface 1
+#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2
+#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
+
+typedef VkFlags VkIOSSurfaceCreateFlagsMVK;
+
+typedef struct VkIOSSurfaceCreateInfoMVK {
+ VkStructureType sType;
+ const void* pNext;
+ VkIOSSurfaceCreateFlagsMVK flags;
+ const void* pView;
+} VkIOSSurfaceCreateInfoMVK;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(
+ VkInstance instance,
+ const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_IOS_MVK */
+
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+#define VK_MVK_macos_surface 1
+#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2
+#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface"
+
+typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
+
+typedef struct VkMacOSSurfaceCreateInfoMVK {
+ VkStructureType sType;
+ const void* pNext;
+ VkMacOSSurfaceCreateFlagsMVK flags;
+ const void* pView;
+} VkMacOSSurfaceCreateInfoMVK;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(
+ VkInstance instance,
+ const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+#endif /* VK_USE_PLATFORM_MACOS_MVK */
+
+#define VK_EXT_sampler_filter_minmax 1
+#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 1
+#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax"
+
+
+typedef enum VkSamplerReductionModeEXT {
+ VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0,
+ VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1,
+ VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2,
+ VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT,
+ VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT,
+ VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1),
+ VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkSamplerReductionModeEXT;
+
+typedef struct VkSamplerReductionModeCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkSamplerReductionModeEXT reductionMode;
+} VkSamplerReductionModeCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 filterMinmaxSingleComponentFormats;
+ VkBool32 filterMinmaxImageComponentMapping;
+} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
+
+
+
+#define VK_AMD_gpu_shader_int16 1
+#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 1
+#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16"
+
+
+#define VK_AMD_mixed_attachment_samples 1
+#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1
+#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples"
+
+
+#define VK_EXT_shader_stencil_export 1
+#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1
+#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export"
+
+
+#define VK_EXT_blend_operation_advanced 1
+#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2
+#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced"
+
+
+typedef enum VkBlendOverlapEXT {
+ VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0,
+ VK_BLEND_OVERLAP_DISJOINT_EXT = 1,
+ VK_BLEND_OVERLAP_CONJOINT_EXT = 2,
+ VK_BLEND_OVERLAP_BEGIN_RANGE_EXT = VK_BLEND_OVERLAP_UNCORRELATED_EXT,
+ VK_BLEND_OVERLAP_END_RANGE_EXT = VK_BLEND_OVERLAP_CONJOINT_EXT,
+ VK_BLEND_OVERLAP_RANGE_SIZE_EXT = (VK_BLEND_OVERLAP_CONJOINT_EXT - VK_BLEND_OVERLAP_UNCORRELATED_EXT + 1),
+ VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkBlendOverlapEXT;
+
+typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 advancedBlendCoherentOperations;
+} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT;
+
+typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t advancedBlendMaxColorAttachments;
+ VkBool32 advancedBlendIndependentBlend;
+ VkBool32 advancedBlendNonPremultipliedSrcColor;
+ VkBool32 advancedBlendNonPremultipliedDstColor;
+ VkBool32 advancedBlendCorrelatedOverlap;
+ VkBool32 advancedBlendAllOperations;
+} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT;
+
+typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 srcPremultiplied;
+ VkBool32 dstPremultiplied;
+ VkBlendOverlapEXT blendOverlap;
+} VkPipelineColorBlendAdvancedStateCreateInfoEXT;
+
+
+
+#define VK_NV_fragment_coverage_to_color 1
+#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1
+#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color"
+
+typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV;
+
+typedef struct VkPipelineCoverageToColorStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCoverageToColorStateCreateFlagsNV flags;
+ VkBool32 coverageToColorEnable;
+ uint32_t coverageToColorLocation;
+} VkPipelineCoverageToColorStateCreateInfoNV;
+
+
+
+#define VK_NV_framebuffer_mixed_samples 1
+#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1
+#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples"
+
+
+typedef enum VkCoverageModulationModeNV {
+ VK_COVERAGE_MODULATION_MODE_NONE_NV = 0,
+ VK_COVERAGE_MODULATION_MODE_RGB_NV = 1,
+ VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2,
+ VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3,
+ VK_COVERAGE_MODULATION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_MODULATION_MODE_NONE_NV,
+ VK_COVERAGE_MODULATION_MODE_END_RANGE_NV = VK_COVERAGE_MODULATION_MODE_RGBA_NV,
+ VK_COVERAGE_MODULATION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_MODULATION_MODE_RGBA_NV - VK_COVERAGE_MODULATION_MODE_NONE_NV + 1),
+ VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkCoverageModulationModeNV;
+
+typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV;
+
+typedef struct VkPipelineCoverageModulationStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCoverageModulationStateCreateFlagsNV flags;
+ VkCoverageModulationModeNV coverageModulationMode;
+ VkBool32 coverageModulationTableEnable;
+ uint32_t coverageModulationTableCount;
+ const float* pCoverageModulationTable;
+} VkPipelineCoverageModulationStateCreateInfoNV;
+
+
+
+#define VK_NV_fill_rectangle 1
+#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1
+#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle"
+
+
+#define VK_EXT_post_depth_coverage 1
+#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1
+#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage"
+
+
+#define VK_EXT_shader_viewport_index_layer 1
+#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
+#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c
new file mode 100644
index 0000000..c79f372
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c
@@ -0,0 +1,171 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+#define DEBUG_DYNAMIC_KMSDRM 0
+
+#include "SDL_kmsdrmdyn.h"
+
+#if DEBUG_DYNAMIC_KMSDRM
+#include "SDL_log.h"
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+typedef struct
+{
+ void *lib;
+ const char *libname;
+} kmsdrmdynlib;
+
+#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM
+#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL
+#endif
+
+static kmsdrmdynlib kmsdrmlibs[] = {
+ {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC},
+ {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM}
+};
+
+static void *
+KMSDRM_GetSym(const char *fnname, int *pHasModule)
+{
+ int i;
+ void *fn = NULL;
+ for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
+ if (kmsdrmlibs[i].lib != NULL) {
+ fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname);
+ if (fn != NULL)
+ break;
+ }
+ }
+
+#if DEBUG_DYNAMIC_KMSDRM
+ if (fn != NULL)
+ SDL_Log("KMSDRM: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn);
+ else
+ SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!\n", fnname);
+#endif
+
+ if (fn == NULL)
+ *pHasModule = 0; /* kill this module. */
+
+ return fn;
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */
+
+/* Define all the function pointers and wrappers... */
+#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0;
+#define SDL_KMSDRM_SYM(rc,fn,params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
+#define SDL_KMSDRM_SYM_CONST(type,name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL;
+#include "SDL_kmsdrmsym.h"
+
+static int kmsdrm_load_refcount = 0;
+
+void
+SDL_KMSDRM_UnloadSymbols(void)
+{
+ /* Don't actually unload if more than one module is using the libs... */
+ if (kmsdrm_load_refcount > 0) {
+ if (--kmsdrm_load_refcount == 0) {
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+ int i;
+#endif
+
+ /* set all the function pointers to NULL. */
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0;
+#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = NULL;
+#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = NULL;
+#include "SDL_kmsdrmsym.h"
+
+
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+ for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
+ if (kmsdrmlibs[i].lib != NULL) {
+ SDL_UnloadObject(kmsdrmlibs[i].lib);
+ kmsdrmlibs[i].lib = NULL;
+ }
+ }
+#endif
+ }
+ }
+}
+
+/* returns non-zero if all needed symbols were loaded. */
+int
+SDL_KMSDRM_LoadSymbols(void)
+{
+ int rc = 1; /* always succeed if not using Dynamic KMSDRM stuff. */
+
+ /* deal with multiple modules needing these symbols... */
+ if (kmsdrm_load_refcount++ == 0) {
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+ int i;
+ int *thismod = NULL;
+ for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
+ if (kmsdrmlibs[i].libname != NULL) {
+ kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname);
+ }
+ }
+
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */
+#include "SDL_kmsdrmsym.h"
+
+#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname;
+#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn) KMSDRM_GetSym(#fn,thismod);
+#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name*) KMSDRM_GetSym(#name,thismod);
+#include "SDL_kmsdrmsym.h"
+
+ if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) {
+ /* all required symbols loaded. */
+ SDL_ClearError();
+ } else {
+ /* in case something got loaded... */
+ SDL_KMSDRM_UnloadSymbols();
+ rc = 0;
+ }
+
+#else /* no dynamic KMSDRM */
+
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */
+#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = fn;
+#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = name;
+#include "SDL_kmsdrmsym.h"
+
+#endif
+ }
+
+ return rc;
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h
new file mode 100644
index 0000000..578b088
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h
@@ -0,0 +1,53 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_kmsdrmdyn_h_
+#define SDL_kmsdrmdyn_h_
+
+#include "../../SDL_internal.h"
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <gbm.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SDL_KMSDRM_LoadSymbols(void);
+void SDL_KMSDRM_UnloadSymbols(void);
+
+/* Declare all the function pointers and wrappers... */
+#define SDL_KMSDRM_SYM(rc,fn,params) \
+ typedef rc (*SDL_DYNKMSDRMFN_##fn) params; \
+ extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn;
+#define SDL_KMSDRM_SYM_CONST(type, name) \
+ typedef type SDL_DYNKMSDRMCONST_##name; \
+ extern SDL_DYNKMSDRMCONST_##name KMSDRM_##name;
+#include "SDL_kmsdrmsym.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_kmsdrmdyn_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c
new file mode 100644
index 0000000..5a611f6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c
@@ -0,0 +1,42 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmevents.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+void KMSDRM_PumpEvents(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Poll();
+#endif
+
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h
new file mode 100644
index 0000000..3b88c28
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_kmsdrmevents_h_
+#define SDL_kmsdrmevents_h_
+
+extern void KMSDRM_PumpEvents(_THIS);
+extern void KMSDRM_EventInit(_THIS);
+extern void KMSDRM_EventQuit(_THIS);
+
+#endif /* SDL_kmsdrmevents_h_ */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c
new file mode 100644
index 0000000..0474089
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c
@@ -0,0 +1,501 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmmouse.h"
+#include "SDL_kmsdrmdyn.h"
+
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/default_cursor.h"
+
+static SDL_Cursor *KMSDRM_CreateDefaultCursor(void);
+static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
+static int KMSDRM_ShowCursor(SDL_Cursor * cursor);
+static void KMSDRM_MoveCursor(SDL_Cursor * cursor);
+static void KMSDRM_FreeCursor(SDL_Cursor * cursor);
+static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y);
+static int KMSDRM_WarpMouseGlobal(int x, int y);
+
+static SDL_Cursor *
+KMSDRM_CreateDefaultCursor(void)
+{
+ return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
+}
+
+/* Evaluate if a given cursor size is supported or not. Notably, current Intel gfx only support 64x64 and up. */
+static SDL_bool
+KMSDRM_IsCursorSizeSupported (int w, int h, uint32_t bo_format) {
+
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ SDL_VideoData *vdata = ((SDL_VideoData *)dev->driverdata);
+ int ret;
+ uint32_t bo_handle;
+ struct gbm_bo *bo = KMSDRM_gbm_bo_create(vdata->gbm, w, h, bo_format,
+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+
+ if (bo == NULL) {
+ SDL_SetError("Could not create GBM cursor BO width size %dx%d for size testing", w, h);
+ goto cleanup;
+ }
+
+ bo_handle = KMSDRM_gbm_bo_get_handle(bo).u32;
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, vdata->crtc_id, bo_handle, w, h);
+
+ if (ret) {
+ goto cleanup;
+ }
+ else {
+ KMSDRM_gbm_bo_destroy(bo);
+ return SDL_TRUE;
+ }
+
+cleanup:
+ if (bo != NULL) {
+ KMSDRM_gbm_bo_destroy(bo);
+ }
+ return SDL_FALSE;
+}
+
+/* Create a cursor from a surface */
+static SDL_Cursor *
+KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ SDL_VideoData *vdata = ((SDL_VideoData *)dev->driverdata);
+ SDL_PixelFormat *pixlfmt = surface->format;
+ KMSDRM_CursorData *curdata;
+ SDL_Cursor *cursor;
+ SDL_bool cursor_supported = SDL_FALSE;
+ int i, ret, usable_cursor_w, usable_cursor_h;
+ uint32_t bo_format, bo_stride;
+ char *buffer = NULL;
+ size_t bufsize;
+
+ switch(pixlfmt->format) {
+ case SDL_PIXELFORMAT_RGB332:
+ bo_format = GBM_FORMAT_RGB332;
+ break;
+ case SDL_PIXELFORMAT_ARGB4444:
+ bo_format = GBM_FORMAT_ARGB4444;
+ break;
+ case SDL_PIXELFORMAT_RGBA4444:
+ bo_format = GBM_FORMAT_RGBA4444;
+ break;
+ case SDL_PIXELFORMAT_ABGR4444:
+ bo_format = GBM_FORMAT_ABGR4444;
+ break;
+ case SDL_PIXELFORMAT_BGRA4444:
+ bo_format = GBM_FORMAT_BGRA4444;
+ break;
+ case SDL_PIXELFORMAT_ARGB1555:
+ bo_format = GBM_FORMAT_ARGB1555;
+ break;
+ case SDL_PIXELFORMAT_RGBA5551:
+ bo_format = GBM_FORMAT_RGBA5551;
+ break;
+ case SDL_PIXELFORMAT_ABGR1555:
+ bo_format = GBM_FORMAT_ABGR1555;
+ break;
+ case SDL_PIXELFORMAT_BGRA5551:
+ bo_format = GBM_FORMAT_BGRA5551;
+ break;
+ case SDL_PIXELFORMAT_RGB565:
+ bo_format = GBM_FORMAT_RGB565;
+ break;
+ case SDL_PIXELFORMAT_BGR565:
+ bo_format = GBM_FORMAT_BGR565;
+ break;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_RGB24:
+ bo_format = GBM_FORMAT_RGB888;
+ break;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_BGR24:
+ bo_format = GBM_FORMAT_BGR888;
+ break;
+ case SDL_PIXELFORMAT_RGBX8888:
+ bo_format = GBM_FORMAT_RGBX8888;
+ break;
+ case SDL_PIXELFORMAT_BGRX8888:
+ bo_format = GBM_FORMAT_BGRX8888;
+ break;
+ case SDL_PIXELFORMAT_ARGB8888:
+ bo_format = GBM_FORMAT_ARGB8888;
+ break;
+ case SDL_PIXELFORMAT_RGBA8888:
+ bo_format = GBM_FORMAT_RGBA8888;
+ break;
+ case SDL_PIXELFORMAT_ABGR8888:
+ bo_format = GBM_FORMAT_ABGR8888;
+ break;
+ case SDL_PIXELFORMAT_BGRA8888:
+ bo_format = GBM_FORMAT_BGRA8888;
+ break;
+ case SDL_PIXELFORMAT_ARGB2101010:
+ bo_format = GBM_FORMAT_ARGB2101010;
+ break;
+ default:
+ SDL_SetError("Unsupported pixel format for cursor");
+ return NULL;
+ }
+
+ if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, bo_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) {
+ SDL_SetError("Unsupported pixel format for cursor");
+ return NULL;
+ }
+
+ cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+ if (cursor == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ curdata = (KMSDRM_CursorData *) SDL_calloc(1, sizeof(*curdata));
+ if (curdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(cursor);
+ return NULL;
+ }
+
+ /* We have to know beforehand if a cursor with the same size as the surface is supported.
+ * If it's not, we have to find an usable cursor size and use an intermediate and clean buffer.
+ * If we can't find a cursor size supported by the hardware, we won't go on trying to
+ * call SDL_SetCursor() later. */
+
+ usable_cursor_w = surface->w;
+ usable_cursor_h = surface->h;
+
+ while (usable_cursor_w <= MAX_CURSOR_W && usable_cursor_h <= MAX_CURSOR_H) {
+ if (KMSDRM_IsCursorSizeSupported(usable_cursor_w, usable_cursor_h, bo_format)) {
+ cursor_supported = SDL_TRUE;
+ break;
+ }
+ usable_cursor_w += usable_cursor_w;
+ usable_cursor_h += usable_cursor_h;
+ }
+
+ if (!cursor_supported) {
+ SDL_SetError("Could not find a cursor size supported by the kernel driver");
+ goto cleanup;
+ }
+
+ curdata->hot_x = hot_x;
+ curdata->hot_y = hot_y;
+ curdata->w = usable_cursor_w;
+ curdata->h = usable_cursor_h;
+
+ curdata->bo = KMSDRM_gbm_bo_create(vdata->gbm, usable_cursor_w, usable_cursor_h, bo_format,
+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+
+ if (curdata->bo == NULL) {
+ SDL_SetError("Could not create GBM cursor BO");
+ goto cleanup;
+ }
+
+ bo_stride = KMSDRM_gbm_bo_get_stride(curdata->bo);
+ bufsize = bo_stride * curdata->h;
+
+ if (surface->pitch != bo_stride) {
+ /* pitch doesn't match stride, must be copied to temp buffer */
+ buffer = SDL_malloc(bufsize);
+ if (buffer == NULL) {
+ SDL_OutOfMemory();
+ goto cleanup;
+ }
+
+ if (SDL_MUSTLOCK(surface)) {
+ if (SDL_LockSurface(surface) < 0) {
+ /* Could not lock surface */
+ goto cleanup;
+ }
+ }
+
+ /* Clean the whole temporary buffer */
+ SDL_memset(buffer, 0x00, bo_stride * curdata->h);
+
+ /* Copy to temporary buffer */
+ for (i = 0; i < surface->h; i++) {
+ SDL_memcpy(buffer + (i * bo_stride),
+ ((char *)surface->pixels) + (i * surface->pitch),
+ surface->w * pixlfmt->BytesPerPixel);
+ }
+
+ if (SDL_MUSTLOCK(surface)) {
+ SDL_UnlockSurface(surface);
+ }
+
+ if (KMSDRM_gbm_bo_write(curdata->bo, buffer, bufsize)) {
+ SDL_SetError("Could not write to GBM cursor BO");
+ goto cleanup;
+ }
+
+ /* Free temporary buffer */
+ SDL_free(buffer);
+ buffer = NULL;
+ } else {
+ /* surface matches BO format */
+ if (SDL_MUSTLOCK(surface)) {
+ if (SDL_LockSurface(surface) < 0) {
+ /* Could not lock surface */
+ goto cleanup;
+ }
+ }
+
+ ret = KMSDRM_gbm_bo_write(curdata->bo, surface->pixels, bufsize);
+
+ if (SDL_MUSTLOCK(surface)) {
+ SDL_UnlockSurface(surface);
+ }
+
+ if (ret) {
+ SDL_SetError("Could not write to GBM cursor BO");
+ goto cleanup;
+ }
+ }
+
+ cursor->driverdata = curdata;
+
+ return cursor;
+
+cleanup:
+ if (buffer != NULL) {
+ SDL_free(buffer);
+ }
+ if (cursor != NULL) {
+ SDL_free(cursor);
+ }
+ if (curdata != NULL) {
+ if (curdata->bo != NULL) {
+ KMSDRM_gbm_bo_destroy(curdata->bo);
+ }
+ SDL_free(curdata);
+ }
+ return NULL;
+}
+
+/* Show the specified cursor, or hide if cursor is NULL */
+static int
+KMSDRM_ShowCursor(SDL_Cursor * cursor)
+{
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ SDL_VideoData *vdata = ((SDL_VideoData *)dev->driverdata);
+ SDL_Mouse *mouse;
+ KMSDRM_CursorData *curdata;
+ SDL_VideoDisplay *display = NULL;
+ SDL_DisplayData *ddata = NULL;
+ int ret;
+ uint32_t bo_handle;
+
+ mouse = SDL_GetMouse();
+ if (mouse == NULL) {
+ return SDL_SetError("No mouse.");
+ }
+
+ if (mouse->focus != NULL) {
+ display = SDL_GetDisplayForWindow(mouse->focus);
+ if (display != NULL) {
+ ddata = (SDL_DisplayData*) display->driverdata;
+ }
+ }
+
+ if (cursor == NULL) {
+ /* Hide current cursor */
+ if ( mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+ curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
+
+ if (curdata->crtc_id != 0) {
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, curdata->crtc_id, 0, 0, 0);
+ if (ret) {
+ SDL_SetError("Could not hide current cursor with drmModeSetCursor().");
+ return ret;
+ }
+ /* Mark previous cursor as not-displayed */
+ curdata->crtc_id = 0;
+
+ return 0;
+ }
+ }
+ /* otherwise if possible, hide global cursor */
+ if (ddata != NULL && ddata->crtc_id != 0) {
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, ddata->crtc_id, 0, 0, 0);
+ if (ret) {
+ SDL_SetError("Could not hide display's cursor with drmModeSetCursor().");
+ return ret;
+ }
+ return 0;
+ }
+
+ return SDL_SetError("Couldn't find cursor to hide.");
+ }
+ /* If cursor != NULL, show new cursor on display */
+ if (display == NULL) {
+ return SDL_SetError("Could not get display for mouse.");
+ }
+ if (ddata == NULL) {
+ return SDL_SetError("Could not get display driverdata.");
+ }
+
+ curdata = (KMSDRM_CursorData *) cursor->driverdata;
+ if (curdata == NULL || curdata->bo == NULL) {
+ return SDL_SetError("Cursor not initialized properly.");
+ }
+
+ bo_handle = KMSDRM_gbm_bo_get_handle(curdata->bo).u32;
+ if (curdata->hot_x == 0 && curdata->hot_y == 0) {
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, ddata->crtc_id, bo_handle,
+ curdata->w, curdata->h);
+ } else {
+ ret = KMSDRM_drmModeSetCursor2(vdata->drm_fd, ddata->crtc_id, bo_handle,
+ curdata->w, curdata->h,
+ curdata->hot_x, curdata->hot_y);
+ }
+ if (ret) {
+ SDL_SetError("drmModeSetCursor failed.");
+ return ret;
+ }
+
+ curdata->crtc_id = ddata->crtc_id;
+
+ return 0;
+}
+
+/* Free a window manager cursor */
+static void
+KMSDRM_FreeCursor(SDL_Cursor * cursor)
+{
+ KMSDRM_CursorData *curdata;
+ int drm_fd;
+
+ if (cursor != NULL) {
+ curdata = (KMSDRM_CursorData *) cursor->driverdata;
+
+ if (curdata != NULL) {
+ if (curdata->bo != NULL) {
+ if (curdata->crtc_id != 0) {
+ drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(curdata->bo));
+ /* Hide the cursor if previously shown on a CRTC */
+ KMSDRM_drmModeSetCursor(drm_fd, curdata->crtc_id, 0, 0, 0);
+ curdata->crtc_id = 0;
+ }
+ KMSDRM_gbm_bo_destroy(curdata->bo);
+ curdata->bo = NULL;
+ }
+ SDL_free(cursor->driverdata);
+ }
+ SDL_free(cursor);
+ }
+}
+
+/* Warp the mouse to (x,y) */
+static void
+KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
+{
+ /* Only one global/fullscreen window is supported */
+ KMSDRM_WarpMouseGlobal(x, y);
+}
+
+/* Warp the mouse to (x,y) */
+static int
+KMSDRM_WarpMouseGlobal(int x, int y)
+{
+ KMSDRM_CursorData *curdata;
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+ /* Update internal mouse position. */
+ SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+
+ /* And now update the cursor graphic position on screen. */
+ curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
+ if (curdata->bo != NULL) {
+
+ if (curdata->crtc_id != 0) {
+ int ret, drm_fd;
+ drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(curdata->bo));
+ ret = KMSDRM_drmModeMoveCursor(drm_fd, curdata->crtc_id, x, y);
+
+ if (ret) {
+ SDL_SetError("drmModeMoveCursor() failed.");
+ }
+
+ return ret;
+ } else {
+ return SDL_SetError("Cursor is not currently shown.");
+ }
+ } else {
+ return SDL_SetError("Cursor not initialized properly.");
+ }
+ } else {
+ return SDL_SetError("No mouse or current cursor.");
+ }
+}
+
+void
+KMSDRM_InitMouse(_THIS)
+{
+ /* FIXME: Using UDEV it should be possible to scan all mice
+ * but there's no point in doing so as there's no multimice support...yet!
+ */
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = KMSDRM_CreateCursor;
+ mouse->ShowCursor = KMSDRM_ShowCursor;
+ mouse->MoveCursor = KMSDRM_MoveCursor;
+ mouse->FreeCursor = KMSDRM_FreeCursor;
+ mouse->WarpMouse = KMSDRM_WarpMouse;
+ mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
+
+ SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
+}
+
+void
+KMSDRM_QuitMouse(_THIS)
+{
+ /* TODO: ? */
+}
+
+/* This is called when a mouse motion event occurs */
+static void
+KMSDRM_MoveCursor(SDL_Cursor * cursor)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ KMSDRM_CursorData *curdata;
+ int drm_fd, ret;
+
+ /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
+ That's why we move the cursor graphic ONLY. */
+ if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+ curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
+ drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(curdata->bo));
+ ret = KMSDRM_drmModeMoveCursor(drm_fd, curdata->crtc_id, mouse->x, mouse->y);
+
+ if (ret) {
+ SDL_SetError("drmModeMoveCursor() failed.");
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h
new file mode 100644
index 0000000..754417d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_KMSDRM_mouse_h_
+#define SDL_KMSDRM_mouse_h_
+
+#include <gbm.h>
+
+#define MAX_CURSOR_W 512
+#define MAX_CURSOR_H 512
+
+typedef struct _KMSDRM_CursorData
+{
+ struct gbm_bo *bo;
+ uint32_t crtc_id;
+ int hot_x, hot_y;
+ int w, h;
+} KMSDRM_CursorData;
+
+extern void KMSDRM_InitMouse(_THIS);
+extern void KMSDRM_QuitMouse(_THIS);
+
+#endif /* SDL_KMSDRM_mouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c
new file mode 100644
index 0000000..fc6304d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c
@@ -0,0 +1,189 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_log.h"
+
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmopengles.h"
+#include "SDL_kmsdrmdyn.h"
+
+#ifndef EGL_PLATFORM_GBM_MESA
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+#endif
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+KMSDRM_GLES_LoadLibrary(_THIS, const char *path) {
+ return SDL_EGL_LoadLibrary(_this, path, ((SDL_VideoData *)_this->driverdata)->gbm, EGL_PLATFORM_GBM_MESA);
+}
+
+SDL_EGL_CreateContext_impl(KMSDRM)
+
+SDL_bool
+KMSDRM_GLES_SetupCrtc(_THIS, SDL_Window * window) {
+ SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata);
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ KMSDRM_FBInfo *fb_info;
+
+ if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed on CRTC setup");
+ return SDL_FALSE;
+ }
+
+ wdata->crtc_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs);
+ if (wdata->crtc_bo == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer on CRTC setup");
+ return SDL_FALSE;
+ }
+
+ fb_info = KMSDRM_FBFromBO(_this, wdata->crtc_bo);
+ if (fb_info == NULL) {
+ return SDL_FALSE;
+ }
+
+ if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
+ 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode) != 0) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC to a GBM buffer");
+ return SDL_FALSE;
+
+ }
+
+ wdata->crtc_ready = SDL_TRUE;
+ return SDL_TRUE;
+}
+
+int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) {
+ if (!_this->egl_data) {
+ return SDL_SetError("EGL not initialized");
+ }
+
+ if (interval == 0 || interval == 1) {
+ _this->egl_data->egl_swapinterval = interval;
+ } else {
+ return SDL_SetError("Only swap intervals of 0 or 1 are supported");
+ }
+
+ return 0;
+}
+
+int
+KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
+ SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata);
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ KMSDRM_FBInfo *fb_info;
+ int ret;
+
+ /* Do we still need to wait for a flip? */
+ int timeout = 0;
+ if (_this->egl_data->egl_swapinterval == 1) {
+ timeout = -1;
+ }
+ if (!KMSDRM_WaitPageFlip(_this, wdata, timeout)) {
+ return 0;
+ }
+
+ /* Release previously displayed buffer (which is now the backbuffer) and lock a new one */
+ if (wdata->next_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(wdata->gs, wdata->current_bo);
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)wdata->next_bo); */
+
+ wdata->current_bo = wdata->next_bo;
+ wdata->next_bo = NULL;
+ }
+
+ if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed.");
+ return 0;
+ }
+
+ if (wdata->current_bo == NULL) {
+ wdata->current_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs);
+ if (wdata->current_bo == NULL) {
+ return 0;
+ }
+ }
+
+ wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs);
+ if (wdata->next_bo == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer");
+ return 0;
+ /* } else {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)wdata->next_bo); */
+ }
+
+ fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo);
+ if (fb_info == NULL) {
+ return 0;
+ }
+ if (_this->egl_data->egl_swapinterval == 0) {
+ /* Swap buffers instantly, possible tearing */
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModeSetCrtc(%d, %u, %u, 0, 0, &%u, 1, &%ux%u@%u)",
+ vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, vdata->saved_conn_id,
+ displaydata->cur_mode.hdisplay, displaydata->cur_mode.vdisplay, displaydata->cur_mode.vrefresh); */
+ ret = KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
+ 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode);
+ if(ret != 0) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not pageflip with drmModeSetCrtc: %d", ret);
+ }
+ } else {
+ /* Queue page flip at vsync */
+
+ /* Have we already setup the CRTC to one of the GBM buffers? Do so if we have not,
+ or FlipPage won't work in some cases. */
+ if (!wdata->crtc_ready) {
+ if(!KMSDRM_GLES_SetupCrtc(_this, window)) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips");
+ return 0;
+ }
+ }
+
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)",
+ vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */
+ ret = KMSDRM_drmModePageFlip(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip);
+ if (ret == 0) {
+ wdata->waiting_for_flip = SDL_TRUE;
+ } else {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
+ }
+
+ /* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
+ Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>" to enable this. */
+ if (wdata->double_buffer) {
+ KMSDRM_WaitPageFlip(_this, wdata, -1);
+ }
+ }
+
+ return 0;
+}
+
+SDL_EGL_MakeCurrent_impl(KMSDRM)
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h
new file mode 100644
index 0000000..d0a7bfa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_kmsdrmopengles_h_
+#define SDL_kmsdrmopengles_h_
+
+#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define KMSDRM_GLES_GetAttribute SDL_EGL_GetAttribute
+#define KMSDRM_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define KMSDRM_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define KMSDRM_GLES_DeleteContext SDL_EGL_DeleteContext
+#define KMSDRM_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+
+extern int KMSDRM_GLES_SetSwapInterval(_THIS, int interval);
+extern int KMSDRM_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_kmsdrmopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h
new file mode 100644
index 0000000..3ab2318
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h
@@ -0,0 +1,99 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* *INDENT-OFF* */
+
+#ifndef SDL_KMSDRM_MODULE
+#define SDL_KMSDRM_MODULE(modname)
+#endif
+
+#ifndef SDL_KMSDRM_SYM
+#define SDL_KMSDRM_SYM(rc,fn,params)
+#endif
+
+#ifndef SDL_KMSDRM_SYM_CONST
+#define SDL_KMSDRM_SYM_CONST(type, name)
+#endif
+
+
+SDL_KMSDRM_MODULE(LIBDRM)
+SDL_KMSDRM_SYM(void,drmModeFreeResources,(drmModeResPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
+SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd))
+SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
+ uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
+ uint32_t *buf_id))
+SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
+SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
+SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
+SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
+ uint32_t x, uint32_t y, uint32_t *connectors, int count,
+ drmModeModeInfoPtr mode))
+SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
+ uint32_t width, uint32_t height))
+SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,
+ uint32_t width, uint32_t height,
+ int32_t hot_x, int32_t hot_y))
+SDL_KMSDRM_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
+SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
+SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
+SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
+SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
+ uint32_t flags, void *user_data))
+
+
+SDL_KMSDRM_MODULE(GBM)
+SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
+SDL_KMSDRM_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm,
+ uint32_t format, uint32_t usage))
+SDL_KMSDRM_SYM(void,gbm_device_destroy,(struct gbm_device *gbm))
+SDL_KMSDRM_SYM(struct gbm_device *,gbm_create_device,(int fd))
+SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
+SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(void,gbm_bo_set_user_data,(struct gbm_bo *bo, void *data,
+ void (*destroy_user_data)(struct gbm_bo *, void *)))
+SDL_KMSDRM_SYM(void *,gbm_bo_get_user_data,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(void,gbm_bo_destroy,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(struct gbm_bo *,gbm_bo_create,(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t usage))
+SDL_KMSDRM_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t flags))
+SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf))
+SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf))
+SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo))
+
+
+#undef SDL_KMSDRM_MODULE
+#undef SDL_KMSDRM_SYM
+#undef SDL_KMSDRM_SYM_CONST
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c
new file mode 100644
index 0000000..bacbe0c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -0,0 +1,739 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_syswm.h"
+#include "SDL_log.h"
+#include "SDL_hints.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+/* KMS/DRM declarations */
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmevents.h"
+#include "SDL_kmsdrmopengles.h"
+#include "SDL_kmsdrmmouse.h"
+#include "SDL_kmsdrmdyn.h"
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#define KMSDRM_DRI_PATH "/dev/dri/"
+
+static int
+check_modestting(int devindex)
+{
+ SDL_bool available = SDL_FALSE;
+ char device[512];
+ int drm_fd;
+
+ SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_DRI_PATH, devindex);
+
+ drm_fd = open(device, O_RDWR | O_CLOEXEC);
+ if (drm_fd >= 0) {
+ if (SDL_KMSDRM_LoadSymbols()) {
+ drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
+ if (resources != NULL) {
+ available = SDL_TRUE;
+ KMSDRM_drmModeFreeResources(resources);
+ }
+ SDL_KMSDRM_UnloadSymbols();
+ }
+ close(drm_fd);
+ }
+
+ return available;
+}
+
+static int get_dricount(void)
+{
+ int devcount = 0;
+ struct dirent *res;
+ struct stat sb;
+ DIR *folder;
+
+ if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
+ && S_ISDIR(sb.st_mode))) {
+ printf("The path %s cannot be opened or is not available\n",
+ KMSDRM_DRI_PATH);
+ return 0;
+ }
+
+ if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
+ printf("The path %s cannot be opened\n",
+ KMSDRM_DRI_PATH);
+ return 0;
+ }
+
+ folder = opendir(KMSDRM_DRI_PATH);
+ if (folder) {
+ while ((res = readdir(folder))) {
+ if (res->d_type == DT_CHR) {
+ devcount++;
+ }
+ }
+ closedir(folder);
+ }
+
+ return devcount;
+}
+
+static int
+get_driindex(void)
+{
+ const int devcount = get_dricount();
+ int i;
+
+ for (i = 0; i < devcount; i++) {
+ if (check_modestting(i)) {
+ return i;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static int
+KMSDRM_Available(void)
+{
+ int ret = -ENOENT;
+
+ ret = get_driindex();
+ if (ret >= 0)
+ return 1;
+
+ return ret;
+}
+
+static void
+KMSDRM_Destroy(SDL_VideoDevice * device)
+{
+ if (device->driverdata != NULL) {
+ SDL_free(device->driverdata);
+ device->driverdata = NULL;
+ }
+
+ SDL_free(device);
+ SDL_KMSDRM_UnloadSymbols();
+}
+
+static SDL_VideoDevice *
+KMSDRM_Create(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *vdata;
+
+ if (!devindex || (devindex > 99)) {
+ devindex = get_driindex();
+ }
+
+ if (devindex < 0) {
+ SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
+ return NULL;
+ }
+
+ if (!SDL_KMSDRM_LoadSymbols()) {
+ return NULL;
+ }
+
+ /* Initialize SDL_VideoDevice structure */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Initialize internal data */
+ vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (vdata == NULL) {
+ SDL_OutOfMemory();
+ goto cleanup;
+ }
+ vdata->devindex = devindex;
+ vdata->drm_fd = -1;
+
+ device->driverdata = vdata;
+
+ /* Setup amount of available displays and current display */
+ device->num_displays = 0;
+
+ /* Set device free function */
+ device->free = KMSDRM_Destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit = KMSDRM_VideoInit;
+ device->VideoQuit = KMSDRM_VideoQuit;
+ device->GetDisplayModes = KMSDRM_GetDisplayModes;
+ device->SetDisplayMode = KMSDRM_SetDisplayMode;
+ device->CreateSDLWindow = KMSDRM_CreateWindow;
+ device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom;
+ device->SetWindowTitle = KMSDRM_SetWindowTitle;
+ device->SetWindowIcon = KMSDRM_SetWindowIcon;
+ device->SetWindowPosition = KMSDRM_SetWindowPosition;
+ device->SetWindowSize = KMSDRM_SetWindowSize;
+ device->ShowWindow = KMSDRM_ShowWindow;
+ device->HideWindow = KMSDRM_HideWindow;
+ device->RaiseWindow = KMSDRM_RaiseWindow;
+ device->MaximizeWindow = KMSDRM_MaximizeWindow;
+ device->MinimizeWindow = KMSDRM_MinimizeWindow;
+ device->RestoreWindow = KMSDRM_RestoreWindow;
+ device->SetWindowGrab = KMSDRM_SetWindowGrab;
+ device->DestroyWindow = KMSDRM_DestroyWindow;
+ device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
+#if SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
+ device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
+ device->GL_CreateContext = KMSDRM_GLES_CreateContext;
+ device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
+ device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
+ device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
+#endif
+
+ device->PumpEvents = KMSDRM_PumpEvents;
+
+ return device;
+
+cleanup:
+ if (device != NULL)
+ SDL_free(device);
+ if (vdata != NULL)
+ SDL_free(vdata);
+ return NULL;
+}
+
+VideoBootStrap KMSDRM_bootstrap = {
+ "KMSDRM",
+ "KMS/DRM Video Driver",
+ KMSDRM_Available,
+ KMSDRM_Create
+};
+
+
+static void
+KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
+{
+ KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
+
+ if (fb_info && fb_info->drm_fd > 0 && fb_info->fb_id != 0) {
+ KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
+ }
+
+ free(fb_info);
+}
+
+KMSDRM_FBInfo *
+KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
+{
+ uint32_t w, h, stride, handle;
+ int ret;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ KMSDRM_FBInfo *fb_info;
+
+ fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
+ if (fb_info != NULL) {
+ /* Have a previously used framebuffer, return it */
+ return fb_info;
+ }
+
+ /* Here a new DRM FB must be created */
+ fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
+ if (fb_info == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ fb_info->drm_fd = vdata->drm_fd;
+
+ w = KMSDRM_gbm_bo_get_width(bo);
+ h = KMSDRM_gbm_bo_get_height(bo);
+ stride = KMSDRM_gbm_bo_get_stride(bo);
+ handle = KMSDRM_gbm_bo_get_handle(bo).u32;
+
+ ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
+ if (ret < 0) {
+ free(fb_info);
+ return NULL;
+ }
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", fb_info->fb_id, w, h, stride, (void *)bo);
+
+ /* Associate our DRM framebuffer with this buffer object */
+ KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
+ return fb_info;
+}
+
+SDL_bool
+KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout) {
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+
+ while (wdata->waiting_for_flip) {
+ vdata->drm_pollfd.revents = 0;
+ if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
+ return SDL_FALSE;
+ }
+
+ if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
+ return SDL_FALSE;
+ }
+
+ if (vdata->drm_pollfd.revents & POLLIN) {
+ /* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
+ KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
+ } else {
+ /* Timed out and page flip didn't happen */
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
+ return SDL_FALSE;
+ }
+ }
+ return SDL_TRUE;
+}
+
+static void
+KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+{
+ *((SDL_bool *) data) = SDL_FALSE;
+}
+
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions */
+/* _this is a SDL_VideoDevice * */
+/*****************************************************************************/
+int
+KMSDRM_VideoInit(_THIS)
+{
+ int i;
+ int ret = 0;
+ char *devname;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ drmModeRes *resources = NULL;
+ drmModeConnector *connector = NULL;
+ drmModeEncoder *encoder = NULL;
+ SDL_DisplayMode current_mode;
+ SDL_VideoDisplay display;
+
+ /* Allocate display internal data */
+ SDL_DisplayData *data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
+ if (data == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
+
+ /* Open /dev/dri/cardNN */
+ devname = (char *) SDL_calloc(1, 16);
+ if (devname == NULL) {
+ ret = SDL_OutOfMemory();
+ goto cleanup;
+ }
+ SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
+ vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
+ SDL_free(devname);
+
+ if (vdata->drm_fd < 0) {
+ ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
+ goto cleanup;
+ }
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
+
+ vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
+ if (vdata->gbm == NULL) {
+ ret = SDL_SetError("Couldn't create gbm device.");
+ goto cleanup;
+ }
+
+ /* Find the first available connector with modes */
+ resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
+ if (!resources) {
+ ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
+ goto cleanup;
+ }
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
+ if (connector == NULL)
+ continue;
+
+ if (connector->connection == DRM_MODE_CONNECTED &&
+ connector->count_modes > 0) {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
+ connector->connector_id, connector->count_modes);
+ vdata->saved_conn_id = connector->connector_id;
+ break;
+ }
+
+ KMSDRM_drmModeFreeConnector(connector);
+ connector = NULL;
+ }
+
+ if (i == resources->count_connectors) {
+ ret = SDL_SetError("No currently active connector found.");
+ goto cleanup;
+ }
+
+ for (i = 0; i < resources->count_encoders; i++) {
+ encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
+
+ if (encoder == NULL)
+ continue;
+
+ if (encoder->encoder_id == connector->encoder_id) {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
+ data->encoder_id = encoder->encoder_id;
+ break;
+ }
+
+ KMSDRM_drmModeFreeEncoder(encoder);
+ encoder = NULL;
+ }
+
+ if (i == resources->count_encoders) {
+ ret = SDL_SetError("No connected encoder found.");
+ goto cleanup;
+ }
+
+ vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
+ if (vdata->saved_crtc == NULL) {
+ ret = SDL_SetError("No CRTC found.");
+ goto cleanup;
+ }
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
+ vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
+ vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
+ data->crtc_id = encoder->crtc_id;
+ data->cur_mode = vdata->saved_crtc->mode;
+ vdata->crtc_id = encoder->crtc_id;
+
+ SDL_zero(current_mode);
+
+ current_mode.w = vdata->saved_crtc->mode.hdisplay;
+ current_mode.h = vdata->saved_crtc->mode.vdisplay;
+ current_mode.refresh_rate = vdata->saved_crtc->mode.vrefresh;
+
+ /* FIXME ?
+ drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
+ current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
+ drmModeFreeFB(fb);
+ */
+ current_mode.format = SDL_PIXELFORMAT_ARGB8888;
+
+ current_mode.driverdata = NULL;
+
+ SDL_zero(display);
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+
+ display.driverdata = data;
+ /* SDL_VideoQuit will later SDL_free(display.driverdata) */
+ SDL_AddVideoDisplay(&display);
+
+ /* Setup page flip handler */
+ vdata->drm_pollfd.fd = vdata->drm_fd;
+ vdata->drm_pollfd.events = POLLIN;
+ vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
+ vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
+
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Init();
+#endif
+
+ KMSDRM_InitMouse(_this);
+
+cleanup:
+ if (encoder != NULL)
+ KMSDRM_drmModeFreeEncoder(encoder);
+ if (connector != NULL)
+ KMSDRM_drmModeFreeConnector(connector);
+ if (resources != NULL)
+ KMSDRM_drmModeFreeResources(resources);
+
+ if (ret != 0) {
+ /* Error (complete) cleanup */
+ SDL_free(data);
+ if(vdata->saved_crtc != NULL) {
+ KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
+ vdata->saved_crtc = NULL;
+ }
+ if (vdata->gbm != NULL) {
+ KMSDRM_gbm_device_destroy(vdata->gbm);
+ vdata->gbm = NULL;
+ }
+ if (vdata->drm_fd >= 0) {
+ close(vdata->drm_fd);
+ vdata->drm_fd = -1;
+ }
+ }
+ return ret;
+}
+
+void
+KMSDRM_VideoQuit(_THIS)
+{
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
+
+ if (_this->gl_config.driver_loaded) {
+ SDL_GL_UnloadLibrary();
+ }
+
+ if(vdata->saved_crtc != NULL) {
+ if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) {
+ /* Restore saved CRTC settings */
+ drmModeCrtc *crtc = vdata->saved_crtc;
+ if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
+ crtc->x, crtc->y, &vdata->saved_conn_id, 1,
+ &crtc->mode) != 0) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
+ }
+ }
+ KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
+ vdata->saved_crtc = NULL;
+ }
+ if (vdata->gbm != NULL) {
+ KMSDRM_gbm_device_destroy(vdata->gbm);
+ vdata->gbm = NULL;
+ }
+ if (vdata->drm_fd >= 0) {
+ close(vdata->drm_fd);
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
+ vdata->drm_fd = -1;
+ }
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Quit();
+#endif
+}
+
+void
+KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ /* Only one display mode available, the current one */
+ SDL_AddDisplayMode(display, &display->current_mode);
+}
+
+int
+KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+int
+KMSDRM_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wdata;
+ SDL_VideoDisplay *display;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ Uint32 surface_fmt, surface_flags;
+
+ /* Allocate window internal data */
+ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (wdata == NULL) {
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ wdata->waiting_for_flip = SDL_FALSE;
+ display = SDL_GetDisplayForWindow(window);
+
+ /* Windows have one size for now */
+ window->w = display->desktop_mode.w;
+ window->h = display->desktop_mode.h;
+
+ /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
+ window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
+
+ surface_fmt = GBM_FORMAT_XRGB8888;
+ surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
+
+ if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
+ }
+ wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (!_this->egl_data) {
+ if (SDL_GL_LoadLibrary(NULL) < 0) {
+ goto error;
+ }
+ }
+ wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
+
+ if (wdata->egl_surface == EGL_NO_SURFACE) {
+ SDL_SetError("Could not create EGL window surface");
+ goto error;
+ }
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+ /* In case we want low-latency, double-buffer video, we take note here */
+ wdata->double_buffer = SDL_FALSE;
+ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
+ wdata->double_buffer = SDL_TRUE;
+ }
+
+ /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
+ drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
+ need to do eglSwapBuffers so we can get a valid GBM buffer object to call
+ drmModeSetCrtc on it. */
+ wdata->crtc_ready = SDL_FALSE;
+
+ /* Setup driver data for this window */
+ window->driverdata = wdata;
+
+ /* One window, it always has focus */
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+
+ /* Window has been successfully created */
+ return 0;
+
+error:
+ if (wdata != NULL) {
+#if SDL_VIDEO_OPENGL_EGL
+ if (wdata->egl_surface != EGL_NO_SURFACE)
+ SDL_EGL_DestroySurface(_this, wdata->egl_surface);
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ if (wdata->gs != NULL)
+ KMSDRM_gbm_surface_destroy(wdata->gs);
+ SDL_free(wdata);
+ }
+ return -1;
+}
+
+void
+KMSDRM_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ if(data) {
+ /* Wait for any pending page flips and unlock buffer */
+ KMSDRM_WaitPageFlip(_this, data, -1);
+ if (data->crtc_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(data->gs, data->crtc_bo);
+ data->crtc_bo = NULL;
+ }
+ if (data->next_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo);
+ data->next_bo = NULL;
+ }
+ if (data->current_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo);
+ data->current_bo = NULL;
+ }
+#if SDL_VIDEO_OPENGL_EGL
+ SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (data->egl_surface != EGL_NO_SURFACE) {
+ SDL_EGL_DestroySurface(_this, data->egl_surface);
+ }
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ if (data->gs != NULL) {
+ KMSDRM_gbm_surface_destroy(data->gs);
+ data->gs = NULL;
+ }
+ SDL_free(data);
+ window->driverdata = NULL;
+ }
+}
+
+int
+KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ return -1;
+}
+
+void
+KMSDRM_SetWindowTitle(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+}
+void
+KMSDRM_SetWindowPosition(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_ShowWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_HideWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_RaiseWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_MaximizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_MinimizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_RestoreWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function */
+/*****************************************************************************/
+SDL_bool
+KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+
+ /* Failed to get window manager information */
+ return SDL_FALSE;
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h
new file mode 100644
index 0000000..34f0b10
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h
@@ -0,0 +1,125 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef __SDL_KMSDRMVIDEO_H__
+#define __SDL_KMSDRMVIDEO_H__
+
+#include "../SDL_sysvideo.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <poll.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <gbm.h>
+#if SDL_VIDEO_OPENGL_EGL
+#include <EGL/egl.h>
+#endif
+
+typedef struct SDL_VideoData
+{
+ int devindex; /* device index that was passed on creation */
+ int drm_fd; /* DRM file desc */
+ struct gbm_device *gbm;
+ drmEventContext drm_evctx; /* DRM event context */
+ struct pollfd drm_pollfd; /* pollfd containing DRM file desc */
+ drmModeCrtc *saved_crtc; /* Saved CRTC to restore on quit */
+ uint32_t saved_conn_id; /* Saved DRM connector ID */
+ uint32_t crtc_id; /* CRTC in use */
+} SDL_VideoData;
+
+
+typedef struct SDL_DisplayData
+{
+ uint32_t encoder_id;
+ uint32_t crtc_id;
+ drmModeModeInfo cur_mode;
+} SDL_DisplayData;
+
+
+typedef struct SDL_WindowData
+{
+ struct gbm_surface *gs;
+ struct gbm_bo *current_bo;
+ struct gbm_bo *next_bo;
+ struct gbm_bo *crtc_bo;
+ SDL_bool waiting_for_flip;
+ SDL_bool crtc_ready;
+ SDL_bool double_buffer;
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+} SDL_WindowData;
+
+typedef struct KMSDRM_FBInfo
+{
+ int drm_fd; /* DRM file desc */
+ uint32_t fb_id; /* DRM framebuffer ID */
+} KMSDRM_FBInfo;
+
+/* Helper functions */
+KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
+SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout);
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration */
+/****************************************************************************/
+
+/* Display and window functions */
+int KMSDRM_VideoInit(_THIS);
+void KMSDRM_VideoQuit(_THIS);
+void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int KMSDRM_CreateWindow(_THIS, SDL_Window * window);
+int KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+void KMSDRM_SetWindowTitle(_THIS, SDL_Window * window);
+void KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window);
+void KMSDRM_SetWindowSize(_THIS, SDL_Window * window);
+void KMSDRM_ShowWindow(_THIS, SDL_Window * window);
+void KMSDRM_HideWindow(_THIS, SDL_Window * window);
+void KMSDRM_RaiseWindow(_THIS, SDL_Window * window);
+void KMSDRM_MaximizeWindow(_THIS, SDL_Window * window);
+void KMSDRM_MinimizeWindow(_THIS, SDL_Window * window);
+void KMSDRM_RestoreWindow(_THIS, SDL_Window * window);
+void KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+void KMSDRM_DestroyWindow(_THIS, SDL_Window * window);
+
+/* Window manager function */
+SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+/* OpenGL/OpenGL ES functions */
+int KMSDRM_GLES_LoadLibrary(_THIS, const char *path);
+void *KMSDRM_GLES_GetProcAddress(_THIS, const char *proc);
+void KMSDRM_GLES_UnloadLibrary(_THIS);
+SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window);
+int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int KMSDRM_GLES_SetSwapInterval(_THIS, int interval);
+int KMSDRM_GLES_GetSwapInterval(_THIS);
+int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window);
+void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* __SDL_KMSDRMVIDEO_H__ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.c
new file mode 100644
index 0000000..71dc73c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.c
@@ -0,0 +1,170 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#define DEBUG_DYNAMIC_MIR 0
+
+#include "SDL_mirdyn.h"
+
+#if DEBUG_DYNAMIC_MIR
+#include "SDL_log.h"
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
+
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+typedef struct
+{
+ void *lib;
+ const char *libname;
+} mirdynlib;
+
+#ifndef SDL_VIDEO_DRIVER_MIR_DYNAMIC
+#define SDL_VIDEO_DRIVER_MIR_DYNAMIC NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON
+#define SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON NULL
+#endif
+
+static mirdynlib mirlibs[] = {
+ {NULL, SDL_VIDEO_DRIVER_MIR_DYNAMIC},
+ {NULL, SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON}
+};
+
+static void *
+MIR_GetSym(const char *fnname, int *pHasModule)
+{
+ int i;
+ void *fn = NULL;
+ for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) {
+ if (mirlibs[i].lib != NULL) {
+ fn = SDL_LoadFunction(mirlibs[i].lib, fnname);
+ if (fn != NULL)
+ break;
+ }
+ }
+
+#if DEBUG_DYNAMIC_MIR
+ if (fn != NULL)
+ SDL_Log("MIR: Found '%s' in %s (%p)\n", fnname, mirlibs[i].libname, fn);
+ else
+ SDL_Log("MIR: Symbol '%s' NOT FOUND!\n", fnname);
+#endif
+
+ if (fn == NULL)
+ *pHasModule = 0; /* kill this module. */
+
+ return fn;
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR_DYNAMIC */
+
+/* Define all the function pointers and wrappers... */
+#define SDL_MIR_MODULE(modname) int SDL_MIR_HAVE_##modname = 0;
+#define SDL_MIR_SYM(rc,fn,params) SDL_DYNMIRFN_##fn MIR_##fn = NULL;
+#define SDL_MIR_SYM_CONST(type,name) SDL_DYMMIRCONST_##name MIR_##name = NULL;
+#include "SDL_mirsym.h"
+
+static int mir_load_refcount = 0;
+
+void
+SDL_MIR_UnloadSymbols(void)
+{
+ /* Don't actually unload if more than one module is using the libs... */
+ if (mir_load_refcount > 0) {
+ if (--mir_load_refcount == 0) {
+#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
+ int i;
+#endif
+
+ /* set all the function pointers to NULL. */
+#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 0;
+#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = NULL;
+#define SDL_MIR_SYM_CONST(type,name) MIR_##name = NULL;
+#include "SDL_mirsym.h"
+
+
+#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
+ for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) {
+ if (mirlibs[i].lib != NULL) {
+ SDL_UnloadObject(mirlibs[i].lib);
+ mirlibs[i].lib = NULL;
+ }
+ }
+#endif
+ }
+ }
+}
+
+/* returns non-zero if all needed symbols were loaded. */
+int
+SDL_MIR_LoadSymbols(void)
+{
+ int rc = 1; /* always succeed if not using Dynamic MIR stuff. */
+
+ /* deal with multiple modules (dga, wayland, mir, etc) needing these symbols... */
+ if (mir_load_refcount++ == 0) {
+#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
+ int i;
+ int *thismod = NULL;
+ for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) {
+ if (mirlibs[i].libname != NULL) {
+ mirlibs[i].lib = SDL_LoadObject(mirlibs[i].libname);
+ }
+ }
+
+#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
+#include "SDL_mirsym.h"
+
+#define SDL_MIR_MODULE(modname) thismod = &SDL_MIR_HAVE_##modname;
+#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = (SDL_DYNMIRFN_##fn) MIR_GetSym(#fn,thismod);
+#define SDL_MIR_SYM_CONST(type,name) MIR_##name = *(SDL_DYMMIRCONST_##name*) MIR_GetSym(#name,thismod);
+#include "SDL_mirsym.h"
+
+ if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) {
+ /* all required symbols loaded. */
+ SDL_ClearError();
+ } else {
+ /* in case something got loaded... */
+ SDL_MIR_UnloadSymbols();
+ rc = 0;
+ }
+
+#else /* no dynamic MIR */
+
+#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
+#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn;
+#define SDL_MIR_SYM_CONST(type,name) MIR_##name = name;
+#include "SDL_mirsym.h"
+
+#endif
+ }
+
+ return rc;
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.h
new file mode 100644
index 0000000..32364aa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirdyn.h
@@ -0,0 +1,53 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_mirdyn_h_
+#define SDL_mirdyn_h_
+
+#include "../../SDL_internal.h"
+
+#include <EGL/egl.h>
+#include <mir_toolkit/mir_client_library.h>
+#include <xkbcommon/xkbcommon.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SDL_MIR_LoadSymbols(void);
+void SDL_MIR_UnloadSymbols(void);
+
+/* Declare all the function pointers and wrappers... */
+#define SDL_MIR_SYM(rc,fn,params) \
+ typedef rc (*SDL_DYNMIRFN_##fn) params; \
+ extern SDL_DYNMIRFN_##fn MIR_##fn;
+#define SDL_MIR_SYM_CONST(type, name) \
+ typedef type SDL_DYMMIRCONST_##name; \
+ extern SDL_DYMMIRCONST_##name MIR_##name;
+#include "SDL_mirsym.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined SDL_mirdyn_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirevents.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirevents.c
new file mode 100644
index 0000000..df92799
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirevents.c
@@ -0,0 +1,321 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../../events/scancodes_xfree86.h"
+
+#include "SDL_mirevents.h"
+#include "SDL_mirwindow.h"
+
+#include <xkbcommon/xkbcommon.h>
+
+#include "SDL_mirdyn.h"
+
+static void
+HandleKeyText(int32_t key_code)
+{
+ char text[8];
+ int size = 0;
+
+ size = MIR_xkb_keysym_to_utf8(key_code, text, sizeof text);
+
+ if (size > 0) {
+ text[size] = '\0';
+ SDL_SendKeyboardText(text);
+ }
+}
+
+/* FIXME
+ Mir still needs to implement its IM API, for now we assume
+ a single key press produces a character.
+*/
+static void
+HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window)
+{
+ xkb_keysym_t key_code;
+ Uint8 key_state;
+ int event_scancode;
+ uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN;
+
+ MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event);
+
+ key_state = SDL_PRESSED;
+ key_code = MIR_mir_keyboard_event_key_code(key_event);
+ event_scancode = MIR_mir_keyboard_event_scan_code(key_event);
+
+ if (action == mir_keyboard_action_up)
+ key_state = SDL_RELEASED;
+
+ if (event_scancode < SDL_arraysize(xfree86_scancode_table2))
+ sdl_scancode = xfree86_scancode_table2[event_scancode];
+
+ if (sdl_scancode != SDL_SCANCODE_UNKNOWN)
+ SDL_SendKeyboardKey(key_state, sdl_scancode);
+
+ if (key_state == SDL_PRESSED)
+ HandleKeyText(key_code);
+}
+
+static void
+HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer)
+{
+ uint32_t sdl_button = SDL_BUTTON_LEFT;
+ MirPointerButton button_state = mir_pointer_button_primary;
+
+ static uint32_t old_button_states = 0;
+ uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer);
+
+ // XOR on our old button states vs our new states to get the newley pressed/released button
+ button_state = new_button_states ^ old_button_states;
+
+ switch (button_state) {
+ case mir_pointer_button_primary:
+ sdl_button = SDL_BUTTON_LEFT;
+ break;
+ case mir_pointer_button_secondary:
+ sdl_button = SDL_BUTTON_RIGHT;
+ break;
+ case mir_pointer_button_tertiary:
+ sdl_button = SDL_BUTTON_MIDDLE;
+ break;
+ case mir_pointer_button_forward:
+ sdl_button = SDL_BUTTON_X1;
+ break;
+ case mir_pointer_button_back:
+ sdl_button = SDL_BUTTON_X2;
+ break;
+ default:
+ break;
+ }
+
+ old_button_states = new_button_states;
+
+ SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
+}
+
+static void
+HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
+{
+ SDL_Mouse* mouse = SDL_GetMouse();
+ SDL_SendMouseMotion(sdl_window, 0, mouse->relative_mode, x, y);
+}
+
+static void
+HandleTouchPress(int device_id, int source_id, SDL_bool down, float x, float y, float pressure)
+{
+ SDL_SendTouch(device_id, source_id, down, x, y, pressure);
+}
+
+static void
+HandleTouchMotion(int device_id, int source_id, float x, float y, float pressure)
+{
+ SDL_SendTouchMotion(device_id, source_id, x, y, pressure);
+}
+
+static void
+HandleMouseScroll(SDL_Window* sdl_window, float hscroll, float vscroll)
+{
+ SDL_SendMouseWheel(sdl_window, 0, hscroll, vscroll, SDL_MOUSEWHEEL_NORMAL);
+}
+
+static void
+AddTouchDevice(int device_id)
+{
+ if (SDL_AddTouch(device_id, "") < 0)
+ SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__);
+}
+
+static void
+HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window)
+{
+ int i, point_count;
+ point_count = MIR_mir_touch_event_point_count(touch);
+
+ AddTouchDevice(device_id);
+
+ for (i = 0; i < point_count; i++) {
+ int id = MIR_mir_touch_event_id(touch, i);
+
+ int width = sdl_window->w;
+ int height = sdl_window->h;
+
+ float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x);
+ float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y);
+
+ float n_x = x / width;
+ float n_y = y / height;
+
+ float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure);
+
+ switch (MIR_mir_touch_event_action(touch, i)) {
+ case mir_touch_action_up:
+ HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
+ break;
+ case mir_touch_action_down:
+ HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
+ break;
+ case mir_touch_action_change:
+ HandleTouchMotion(device_id, id, n_x, n_y, pressure);
+ break;
+ case mir_touch_actions:
+ break;
+ }
+ }
+}
+
+static void
+HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window)
+{
+ SDL_SetMouseFocus(sdl_window);
+
+ switch (MIR_mir_pointer_event_action(pointer)) {
+ case mir_pointer_action_button_down:
+ HandleMouseButton(sdl_window, SDL_PRESSED, pointer);
+ break;
+ case mir_pointer_action_button_up:
+ HandleMouseButton(sdl_window, SDL_RELEASED, pointer);
+ break;
+ case mir_pointer_action_motion: {
+ int x, y;
+ float hscroll, vscroll;
+ SDL_Mouse* mouse = SDL_GetMouse();
+ x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x);
+ y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y);
+
+ if (mouse) {
+ if (mouse->relative_mode) {
+ int relative_x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x);
+ int relative_y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y);
+ HandleMouseMotion(sdl_window, relative_x, relative_y);
+ }
+ else if (mouse->x != x || mouse->y != y) {
+ HandleMouseMotion(sdl_window, x, y);
+ }
+ }
+
+ hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll);
+ vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll);
+ if (vscroll != 0 || hscroll != 0)
+ HandleMouseScroll(sdl_window, hscroll, vscroll);
+ }
+ break;
+ case mir_pointer_action_leave:
+ SDL_SetMouseFocus(NULL);
+ break;
+ case mir_pointer_action_enter:
+ default:
+ break;
+ }
+}
+
+static void
+HandleInput(MirInputEvent const* input_event, SDL_Window* window)
+{
+ switch (MIR_mir_input_event_get_type(input_event)) {
+ case (mir_input_event_type_key):
+ HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window);
+ break;
+ case (mir_input_event_type_pointer):
+ HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window);
+ break;
+ case (mir_input_event_type_touch):
+ HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event),
+ MIR_mir_input_event_get_device_id(input_event),
+ window);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+HandleResize(MirResizeEvent const* resize_event, SDL_Window* window)
+{
+ int new_w = MIR_mir_resize_event_get_width (resize_event);
+ int new_h = MIR_mir_resize_event_get_height(resize_event);
+
+ int old_w = window->w;
+ int old_h = window->h;
+
+ if (new_w != old_w || new_h != old_h)
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
+}
+
+static void
+HandleWindow(MirWindowEvent const* event, SDL_Window* window)
+{
+ MirWindowAttrib attrib = MIR_mir_window_event_get_attribute(event);
+ int value = MIR_mir_window_event_get_attribute_value(event);
+
+ if (attrib == mir_window_attrib_focus) {
+ if (value == mir_window_focus_state_focused) {
+ SDL_SetKeyboardFocus(window);
+ }
+ else if (value == mir_window_focus_state_unfocused) {
+ SDL_SetKeyboardFocus(NULL);
+ }
+ }
+}
+
+static void
+MIR_HandleClose(SDL_Window* window) {
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0);
+}
+
+void
+MIR_HandleEvent(MirWindow* mirwindow, MirEvent const* ev, void* context)
+{
+ MirEventType event_type = MIR_mir_event_get_type(ev);
+ SDL_Window* window = (SDL_Window*)context;
+
+ if (window) {
+ switch (event_type) {
+ case (mir_event_type_input):
+ HandleInput(MIR_mir_event_get_input_event(ev), window);
+ break;
+ case (mir_event_type_resize):
+ HandleResize(MIR_mir_event_get_resize_event(ev), window);
+ break;
+ case (mir_event_type_window):
+ HandleWindow(MIR_mir_event_get_window_event(ev), window);
+ break;
+ case (mir_event_type_close_window):
+ MIR_HandleClose(window);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirevents.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirevents.h
new file mode 100644
index 0000000..4b0f209
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirevents.h
@@ -0,0 +1,37 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#ifndef SDL_mirevents_h_
+#define SDL_mirevents_h_
+
+#include <mir_toolkit/mir_client_library.h>
+
+extern void
+MIR_HandleEvent(MirWindow*, MirEvent const* ev, void* context);
+
+#endif /* SDL_mirevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.c
new file mode 100644
index 0000000..d678fff
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.c
@@ -0,0 +1,134 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#include "SDL_mirevents.h"
+#include "SDL_mirframebuffer.h"
+#include "SDL_mirwindow.h"
+
+#include "SDL_mirdyn.h"
+
+int
+MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
+ void** pixels, int* pitch)
+{
+ MIR_Data* mir_data = _this->driverdata;
+
+ mir_data->software = SDL_TRUE;
+
+ if (MIR_CreateWindow(_this, window) < 0)
+ return SDL_SetError("Failed to create a mir window.");
+
+ *format = MIR_GetSDLPixelFormat(mir_data->pixel_format);
+ if (*format == SDL_PIXELFORMAT_UNKNOWN)
+ return SDL_SetError("Unknown pixel format");
+
+ *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
+
+ *pixels = SDL_malloc(window->h*(*pitch));
+ if (*pixels == NULL)
+ return SDL_OutOfMemory();
+
+ return 0;
+}
+
+int
+MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
+ const SDL_Rect* rects, int numrects)
+{
+ MIR_Window* mir_window = window->driverdata;
+
+ MirGraphicsRegion region;
+ MirBufferStream* bs;
+ int i, j, x, y, w, h, start;
+ int bytes_per_pixel, bytes_per_row, s_stride, d_stride;
+ char* s_dest;
+ char* pixels;
+
+ bs = MIR_mir_window_get_buffer_stream(mir_window->window);
+ MIR_mir_buffer_stream_get_graphics_region(bs, &region);
+
+ s_dest = region.vaddr;
+ pixels = (char*)window->surface->pixels;
+
+ s_stride = window->surface->pitch;
+ d_stride = region.stride;
+ bytes_per_pixel = window->surface->format->BytesPerPixel;
+
+ for (i = 0; i < numrects; i++) {
+ s_dest = region.vaddr;
+ pixels = (char*)window->surface->pixels;
+
+ x = rects[i].x;
+ y = rects[i].y;
+ w = rects[i].w;
+ h = rects[i].h;
+
+ if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0)
+ continue;
+
+ if (x < 0) {
+ x += w;
+ w += rects[i].x;
+ }
+
+ if (y < 0) {
+ y += h;
+ h += rects[i].y;
+ }
+
+ if (x + w > window->w)
+ w = window->w - x;
+ if (y + h > window->h)
+ h = window->h - y;
+
+ start = y * s_stride + x;
+ pixels += start;
+ s_dest += start;
+
+ bytes_per_row = bytes_per_pixel * w;
+ for (j = 0; j < h; j++) {
+ SDL_memcpy(s_dest, pixels, bytes_per_row);
+ pixels += s_stride;
+ s_dest += d_stride;
+ }
+ }
+
+ MIR_mir_buffer_stream_swap_buffers_sync(bs);
+
+ return 0;
+}
+
+void
+MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.h
new file mode 100644
index 0000000..502337c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirframebuffer.h
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#ifndef SDL_mirframebuffer_h_
+#define SDL_mirframebuffer_h_
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_mirvideo.h"
+
+extern int
+MIR_CreateWindowFramebuffer(_THIS, SDL_Window* sdl_window, Uint32* format,
+ void** pixels, int* pitch);
+
+extern int
+MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* sdl_window,
+ const SDL_Rect* rects, int numrects);
+
+extern void
+MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* sdl_window);
+
+#endif /* SDL_mirframebuffer_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.c
new file mode 100644
index 0000000..5f6e38c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.c
@@ -0,0 +1,292 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#include "../../events/SDL_mouse_c.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_assert.h"
+
+#include "SDL_mirdyn.h"
+
+#include "SDL_mirvideo.h"
+#include "SDL_mirmouse.h"
+#include "SDL_mirwindow.h"
+
+typedef struct
+{
+ MirCursorConfiguration* conf;
+ MirBufferStream* stream;
+ char const* name;
+} MIR_Cursor;
+
+static SDL_Cursor*
+MIR_CreateDefaultCursor()
+{
+ SDL_Cursor* cursor;
+
+ cursor = SDL_calloc(1, sizeof(SDL_Cursor));
+ if (cursor) {
+
+ MIR_Cursor* mir_cursor = SDL_calloc(1, sizeof(MIR_Cursor));
+ if (mir_cursor) {
+ mir_cursor->conf = NULL;
+ mir_cursor->stream = NULL;
+ mir_cursor->name = NULL;
+ cursor->driverdata = mir_cursor;
+ }
+ else {
+ SDL_OutOfMemory();
+ SDL_free(cursor);
+ cursor = NULL;
+ }
+ }
+ else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static void
+CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream)
+{
+ char* dest, *pixels;
+ int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row;
+
+ MirGraphicsRegion region;
+ MIR_mir_buffer_stream_get_graphics_region(stream, &region);
+
+ s_w = surface->w;
+ s_h = surface->h;
+
+ bytes_per_pixel = surface->format->BytesPerPixel;
+ bytes_per_row = bytes_per_pixel * s_w;
+
+ dest = region.vaddr;
+ pixels = (char*)surface->pixels;
+
+ r_stride = region.stride;
+ p_stride = surface->pitch;
+
+ for (i = 0; i < s_h; i++)
+ {
+ SDL_memcpy(dest, pixels, bytes_per_row);
+ dest += r_stride;
+ pixels += p_stride;
+ }
+}
+
+static SDL_Cursor*
+MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
+{
+ MirCursorConfiguration* conf;
+ MirBufferStream* stream;
+
+ int s_w = surface->w;
+ int s_h = surface->h;
+
+ MIR_Data* mir_data = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
+ SDL_Cursor* cursor = MIR_CreateDefaultCursor();
+ MIR_Cursor* mir_cursor;
+
+ if (!cursor) {
+ return NULL;
+ }
+
+ mir_cursor = (MIR_Cursor*)cursor->driverdata;
+
+ stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection,
+ s_w, s_h, mir_data->pixel_format,
+ mir_buffer_usage_software);
+
+ conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y);
+
+ CopySurfacePixelsToMirStream(surface, stream);
+ MIR_mir_buffer_stream_swap_buffers_sync(stream);
+
+ mir_cursor->conf = conf;
+ mir_cursor->stream = stream;
+
+ return cursor;
+}
+
+static SDL_Cursor*
+MIR_CreateSystemCursor(SDL_SystemCursor id)
+{
+ char const* cursor_name = NULL;
+ SDL_Cursor* cursor;
+ MIR_Cursor* mir_cursor;
+
+ switch(id) {
+ case SDL_SYSTEM_CURSOR_ARROW:
+ cursor_name = MIR_mir_arrow_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_IBEAM:
+ cursor_name = MIR_mir_caret_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_WAIT:
+ cursor_name = MIR_mir_busy_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR:
+ /* Unsupported */
+ cursor_name = MIR_mir_arrow_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_WAITARROW:
+ cursor_name = MIR_mir_busy_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE:
+ cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENESW:
+ cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEWE:
+ cursor_name = MIR_mir_horizontal_resize_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENS:
+ cursor_name = MIR_mir_vertical_resize_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEALL:
+ cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_NO:
+ /* Unsupported */
+ cursor_name = MIR_mir_closed_hand_cursor_name;
+ break;
+ case SDL_SYSTEM_CURSOR_HAND:
+ cursor_name = MIR_mir_open_hand_cursor_name;
+ break;
+ default:
+ SDL_assert(0);
+ return NULL;
+ }
+
+ cursor = MIR_CreateDefaultCursor();
+ if (!cursor) {
+ return NULL;
+ }
+
+ mir_cursor = (MIR_Cursor*)cursor->driverdata;
+ mir_cursor->name = cursor_name;
+
+ return cursor;
+}
+
+static void
+MIR_FreeCursor(SDL_Cursor* cursor)
+{
+ if (cursor) {
+
+ if (cursor->driverdata) {
+ MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
+
+ if (mir_cursor->conf)
+ MIR_mir_cursor_configuration_destroy(mir_cursor->conf);
+ if (mir_cursor->stream)
+ MIR_mir_buffer_stream_release_sync(mir_cursor->stream);
+
+ SDL_free(mir_cursor);
+ }
+
+ SDL_free(cursor);
+ }
+}
+
+static int
+MIR_ShowCursor(SDL_Cursor* cursor)
+{
+ MIR_Data* mir_data = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
+ MIR_Window* mir_window = mir_data->current_window;
+
+ if (cursor && cursor->driverdata) {
+ if (mir_window && MIR_mir_window_is_valid(mir_window->window)) {
+ MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
+
+ if (mir_cursor->name != NULL) {
+ MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_cursor_name(spec, mir_cursor->name);
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ MIR_mir_window_spec_release(spec);
+ }
+
+ if (mir_cursor->conf) {
+ MIR_mir_window_configure_cursor(mir_window->window, mir_cursor->conf);
+ }
+ }
+ }
+ else if(mir_window && MIR_mir_window_is_valid(mir_window->window)) {
+ MIR_mir_window_configure_cursor(mir_window->window, NULL);
+ }
+
+ return 0;
+}
+
+static void
+MIR_WarpMouse(SDL_Window* window, int x, int y)
+{
+ SDL_Unsupported();
+}
+
+static int
+MIR_WarpMouseGlobal(int x, int y)
+{
+ return SDL_Unsupported();
+}
+
+static int
+MIR_SetRelativeMouseMode(SDL_bool enabled)
+{
+ return 0;
+}
+
+/* TODO Actually implement the cursor, need to wait for mir support */
+void
+MIR_InitMouse()
+{
+ SDL_Mouse* mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = MIR_CreateCursor;
+ mouse->ShowCursor = MIR_ShowCursor;
+ mouse->FreeCursor = MIR_FreeCursor;
+ mouse->WarpMouse = MIR_WarpMouse;
+ mouse->WarpMouseGlobal = MIR_WarpMouseGlobal;
+ mouse->CreateSystemCursor = MIR_CreateSystemCursor;
+ mouse->SetRelativeMouseMode = MIR_SetRelativeMouseMode;
+
+ SDL_SetDefaultCursor(MIR_CreateDefaultCursor());
+}
+
+void
+MIR_FiniMouse()
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.h
new file mode 100644
index 0000000..de32610
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirmouse.h
@@ -0,0 +1,37 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#ifndef SDL_mirmouse_h_
+#define SDL_mirmouse_h_
+
+extern void
+MIR_InitMouse();
+
+extern void
+MIR_FiniMouse();
+
+#endif /* SDL_mirmouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_miropengl.c b/source/3rd-party/SDL2/src/video/mir/SDL_miropengl.c
new file mode 100644
index 0000000..7795f97
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_miropengl.c
@@ -0,0 +1,78 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#include "SDL_miropengl.h"
+
+#include "SDL_mirdyn.h"
+
+int
+MIR_GL_SwapWindow(_THIS, SDL_Window* window)
+{
+ MIR_Window* mir_wind = window->driverdata;
+
+ return SDL_EGL_SwapBuffers(_this, mir_wind->egl_surface);
+}
+
+int
+MIR_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context)
+{
+ if (window) {
+ EGLSurface egl_surface = ((MIR_Window*)window->driverdata)->egl_surface;
+ return SDL_EGL_MakeCurrent(_this, egl_surface, context);
+ }
+
+ return SDL_EGL_MakeCurrent(_this, NULL, NULL);
+}
+
+SDL_GLContext
+MIR_GL_CreateContext(_THIS, SDL_Window* window)
+{
+ MIR_Window* mir_window = window->driverdata;
+
+ SDL_GLContext context;
+ context = SDL_EGL_CreateContext(_this, mir_window->egl_surface);
+
+ return context;
+}
+
+int
+MIR_GL_LoadLibrary(_THIS, const char* path)
+{
+ MIR_Data* mir_data = _this->driverdata;
+
+ SDL_EGL_LoadLibrary(_this, path, MIR_mir_connection_get_egl_native_display(mir_data->connection), 0);
+
+ SDL_EGL_ChooseConfig(_this);
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_miropengl.h b/source/3rd-party/SDL2/src/video/mir/SDL_miropengl.h
new file mode 100644
index 0000000..2168f96
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_miropengl.h
@@ -0,0 +1,53 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#ifndef SDL_miropengl_h_
+#define SDL_miropengl_h_
+
+#include "SDL_mirwindow.h"
+
+#include "../SDL_egl_c.h"
+
+#define MIR_GL_DeleteContext SDL_EGL_DeleteContext
+#define MIR_GL_GetSwapInterval SDL_EGL_GetSwapInterval
+#define MIR_GL_SetSwapInterval SDL_EGL_SetSwapInterval
+#define MIR_GL_UnloadLibrary SDL_EGL_UnloadLibrary
+#define MIR_GL_GetProcAddress SDL_EGL_GetProcAddress
+
+extern int
+MIR_GL_SwapWindow(_THIS, SDL_Window* window);
+
+extern int
+MIR_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context);
+
+extern SDL_GLContext
+MIR_GL_CreateContext(_THIS, SDL_Window* window);
+
+extern int
+MIR_GL_LoadLibrary(_THIS, const char* path);
+
+#endif /* SDL_miropengl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirsym.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirsym.h
new file mode 100644
index 0000000..6e18b53
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirsym.h
@@ -0,0 +1,143 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* *INDENT-OFF* */
+
+#ifndef SDL_MIR_MODULE
+#define SDL_MIR_MODULE(modname)
+#endif
+
+#ifndef SDL_MIR_SYM
+#define SDL_MIR_SYM(rc,fn,params)
+#endif
+
+#ifndef SDL_MIR_SYM_CONST
+#define SDL_MIR_SYM_CONST(type, name)
+#endif
+
+SDL_MIR_MODULE(MIR_CLIENT)
+SDL_MIR_SYM(MirWindow *,mir_create_window_sync,(MirWindowSpec* spec))
+SDL_MIR_SYM(MirEGLNativeWindowType,mir_buffer_stream_get_egl_native_window,(MirBufferStream *surface))
+SDL_MIR_SYM(bool,mir_buffer_stream_get_graphics_region,(MirBufferStream *stream, MirGraphicsRegion *graphics_region))
+SDL_MIR_SYM(void,mir_buffer_stream_swap_buffers_sync,(MirBufferStream *stream))
+SDL_MIR_SYM(void,mir_window_set_event_handler,(MirWindow* window, MirWindowEventCallback callback, void* context))
+SDL_MIR_SYM(MirWindowSpec*,mir_create_normal_window_spec,(MirConnection *connection, int width, int height))
+SDL_MIR_SYM(MirWindowSpec*,mir_create_window_spec,(MirConnection *connection))
+SDL_MIR_SYM(void,mir_window_spec_set_buffer_usage,(MirWindowSpec *spec, MirBufferUsage usage))
+SDL_MIR_SYM(void,mir_window_spec_set_name,(MirWindowSpec *spec, char const *name))
+SDL_MIR_SYM(void,mir_window_spec_release,(MirWindowSpec *spec))
+SDL_MIR_SYM(void,mir_window_spec_set_width,(MirWindowSpec *spec, unsigned width))
+SDL_MIR_SYM(void,mir_window_spec_set_height,(MirWindowSpec *spec, unsigned height))
+SDL_MIR_SYM(void,mir_window_spec_set_min_width,(MirWindowSpec *spec, unsigned min_width))
+SDL_MIR_SYM(void,mir_window_spec_set_min_height,(MirWindowSpec *spec, unsigned min_height))
+SDL_MIR_SYM(void,mir_window_spec_set_max_width,(MirWindowSpec *spec, unsigned max_width))
+SDL_MIR_SYM(void,mir_window_spec_set_max_height,(MirWindowSpec *spec, unsigned max_height))
+SDL_MIR_SYM(void,mir_window_spec_set_type,(MirWindowSpec *spec, MirWindowType type))
+SDL_MIR_SYM(void,mir_window_spec_set_state,(MirWindowSpec *spec, MirWindowState state))
+SDL_MIR_SYM(void,mir_window_spec_set_pointer_confinement,(MirWindowSpec *spec, MirPointerConfinementState state))
+SDL_MIR_SYM(void,mir_window_spec_set_pixel_format,(MirWindowSpec *spec, MirPixelFormat pixel_format))
+SDL_MIR_SYM(void,mir_window_spec_set_cursor_name,(MirWindowSpec *spec, char const* cursor_name))
+SDL_MIR_SYM(void,mir_window_apply_spec,(MirWindow* window, MirWindowSpec* spec))
+SDL_MIR_SYM(void,mir_window_get_parameters,(MirWindow *window, MirWindowParameters *params))
+SDL_MIR_SYM(MirBufferStream*,mir_window_get_buffer_stream,(MirWindow* window))
+SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_buffer_stream,(MirBufferStream const* stream, int hot_x, int hot_y))
+SDL_MIR_SYM(MirBufferStream*,mir_connection_create_buffer_stream_sync,(MirConnection *connection, int w, int h, MirPixelFormat format, MirBufferUsage usage))
+SDL_MIR_SYM(MirKeyboardAction,mir_keyboard_event_action,(MirKeyboardEvent const *event))
+SDL_MIR_SYM(xkb_keysym_t,mir_keyboard_event_key_code,(MirKeyboardEvent const *event))
+SDL_MIR_SYM(int,mir_keyboard_event_scan_code,(MirKeyboardEvent const *event))
+SDL_MIR_SYM(bool,mir_pointer_event_button_state,(MirPointerEvent const *event, MirPointerButton button))
+SDL_MIR_SYM(MirPointerButtons,mir_pointer_event_buttons,(MirPointerEvent const *event))
+SDL_MIR_SYM(MirInputDeviceId,mir_input_event_get_device_id,(MirInputEvent const* ev))
+SDL_MIR_SYM(MirTouchId,mir_touch_event_id,(MirTouchEvent const *event, size_t touch_index))
+SDL_MIR_SYM(float,mir_touch_event_axis_value,(MirTouchEvent const *event, size_t touch_index, MirTouchAxis axis))
+SDL_MIR_SYM(MirTouchAction,mir_touch_event_action,(MirTouchEvent const *event, size_t touch_index))
+SDL_MIR_SYM(MirPointerAction,mir_pointer_event_action,(MirPointerEvent const *event))
+SDL_MIR_SYM(float,mir_pointer_event_axis_value,(MirPointerEvent const *event, MirPointerAxis))
+SDL_MIR_SYM(MirEventType,mir_event_get_type,(MirEvent const *event))
+SDL_MIR_SYM(MirInputEventType,mir_input_event_get_type,(MirInputEvent const *event))
+SDL_MIR_SYM(MirInputEvent const*,mir_event_get_input_event,(MirEvent const *event))
+SDL_MIR_SYM(MirResizeEvent const*,mir_event_get_resize_event,(MirEvent const *event))
+SDL_MIR_SYM(MirKeyboardEvent const*,mir_input_event_get_keyboard_event,(MirInputEvent const *event))
+SDL_MIR_SYM(MirPointerEvent const*,mir_input_event_get_pointer_event,(MirInputEvent const *event))
+SDL_MIR_SYM(MirTouchEvent const*,mir_input_event_get_touch_event,(MirInputEvent const *event))
+SDL_MIR_SYM(MirWindowEvent const*,mir_event_get_window_event,(MirEvent const *event))
+SDL_MIR_SYM(unsigned int,mir_touch_event_point_count,(MirTouchEvent const *event))
+SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats))
+SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection))
+SDL_MIR_SYM(bool,mir_connection_is_valid,(MirConnection *connection))
+SDL_MIR_SYM(void,mir_connection_release,(MirConnection *connection))
+SDL_MIR_SYM(MirPixelFormat,mir_connection_get_egl_pixel_format,(MirConnection* connection, void* egldisplay, void* eglconfig))
+SDL_MIR_SYM(MirConnection *,mir_connect_sync,(char const *server, char const *app_name))
+SDL_MIR_SYM(char const *,mir_window_get_error_message,(MirWindow *window))
+SDL_MIR_SYM(bool,mir_window_is_valid,(MirWindow *window))
+SDL_MIR_SYM(void,mir_window_release_sync,(MirWindow* window))
+SDL_MIR_SYM(void,mir_buffer_stream_release_sync,(MirBufferStream *stream))
+SDL_MIR_SYM(void,mir_window_configure_cursor,(MirWindow* window, MirCursorConfiguration const* conf))
+SDL_MIR_SYM(void,mir_cursor_configuration_destroy,(MirCursorConfiguration* conf))
+SDL_MIR_SYM(int,mir_resize_event_get_width,(MirResizeEvent const* resize_event))
+SDL_MIR_SYM(int,mir_resize_event_get_height,(MirResizeEvent const* resize_event))
+SDL_MIR_SYM(char const*,mir_connection_get_error_message,(MirConnection* connection))
+SDL_MIR_SYM(MirWindowAttrib,mir_window_event_get_attribute,(MirWindowEvent const* event))
+SDL_MIR_SYM(int,mir_window_event_get_attribute_value,(MirWindowEvent const* window_event))
+SDL_MIR_SYM(MirDisplayConfig*,mir_connection_create_display_configuration,(MirConnection* connection))
+SDL_MIR_SYM(void,mir_display_config_release,(MirDisplayConfig* config))
+SDL_MIR_SYM(int,mir_display_config_get_num_outputs,(MirDisplayConfig const* config))
+SDL_MIR_SYM(MirOutput*,mir_display_config_get_mutable_output,(MirDisplayConfig* config, size_t index))
+SDL_MIR_SYM(int,mir_output_get_num_modes,(MirOutput const* output))
+SDL_MIR_SYM(MirOutputMode const*,mir_output_get_current_mode,(MirOutput const* output))
+SDL_MIR_SYM(MirPixelFormat,mir_output_get_current_pixel_format,(MirOutput const* output))
+SDL_MIR_SYM(int,mir_output_get_position_x,(MirOutput const* output))
+SDL_MIR_SYM(int,mir_output_get_position_y,(MirOutput const* output))
+SDL_MIR_SYM(bool,mir_output_is_enabled,(MirOutput const* output))
+SDL_MIR_SYM(MirOutputConnectionState,mir_output_get_connection_state,(MirOutput const* output))
+SDL_MIR_SYM(size_t,mir_output_get_preferred_mode_index,(MirOutput const* output))
+SDL_MIR_SYM(MirOutputType,mir_output_get_type,(MirOutput const* output))
+SDL_MIR_SYM(char const*,mir_output_type_name,(MirOutputType type))
+SDL_MIR_SYM(void,mir_output_set_current_mode,(MirOutput* output, MirOutputMode const* mode))
+SDL_MIR_SYM(MirOutputMode const*,mir_output_get_mode,(MirOutput const* output, size_t index))
+SDL_MIR_SYM(int,mir_output_mode_get_width,(MirOutputMode const* mode))
+SDL_MIR_SYM(int,mir_output_mode_get_height,(MirOutputMode const* mode))
+SDL_MIR_SYM(double,mir_output_mode_get_refresh_rate,(MirOutputMode const* mode))
+SDL_MIR_SYM(bool,mir_output_is_gamma_supported,(MirOutput const* output))
+SDL_MIR_SYM(uint32_t,mir_output_get_gamma_size,(MirOutput const* output))
+SDL_MIR_SYM(void,mir_output_get_gamma,(MirOutput const* output, uint16_t* red, uint16_t* green, uint16_t* blue, uint32_t size))
+SDL_MIR_SYM(void,mir_output_set_gamma,(MirOutput* output, uint16_t const* red, uint16_t const* green, uint16_t const* blue, uint32_t size))
+
+SDL_MIR_SYM_CONST(char const*,mir_omnidirectional_resize_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_busy_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_arrow_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_caret_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_vertical_resize_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_horizontal_resize_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_open_hand_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_closed_hand_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_disabled_cursor_name)
+
+SDL_MIR_MODULE(XKBCOMMON)
+SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size))
+
+#undef SDL_MIR_MODULE
+#undef SDL_MIR_SYM
+#undef SDL_MIR_SYM_CONST
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.c
new file mode 100644
index 0000000..8f3a368
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.c
@@ -0,0 +1,423 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#include "SDL_assert.h"
+#include "SDL_log.h"
+
+#include "SDL_mirwindow.h"
+#include "SDL_video.h"
+
+#include "SDL_mirframebuffer.h"
+#include "SDL_mirmouse.h"
+#include "SDL_miropengl.h"
+#include "SDL_mirvideo.h"
+#include "SDL_mirvulkan.h"
+
+#include "SDL_mirdyn.h"
+
+#define MIR_DRIVER_NAME "mir"
+
+static const Uint32 mir_pixel_format_to_sdl_format[] = {
+ SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */
+ SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
+ SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */
+ SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
+ SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */
+ SDL_PIXELFORMAT_BGR24, /* mir_pixel_format_bgr_888 */
+ SDL_PIXELFORMAT_RGB24, /* mir_pixel_format_rgb_888 */
+ SDL_PIXELFORMAT_RGB565, /* mir_pixel_format_rgb_565 */
+ SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */
+ SDL_PIXELFORMAT_RGBA4444 /* mir_pixel_format_rgba_4444 */
+};
+
+Uint32
+MIR_GetSDLPixelFormat(MirPixelFormat format)
+{
+ return mir_pixel_format_to_sdl_format[format];
+}
+
+static int
+MIR_VideoInit(_THIS);
+
+static void
+MIR_VideoQuit(_THIS);
+
+static int
+MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect);
+
+static void
+MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display);
+
+static int
+MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode);
+
+static SDL_WindowShaper*
+MIR_CreateShaper(SDL_Window* window)
+{
+ /* FIXME Im not sure if mir support this atm, will have to come back to this */
+ return NULL;
+}
+
+static int
+MIR_SetWindowShape(SDL_WindowShaper* shaper, SDL_Surface* shape, SDL_WindowShapeMode* shape_mode)
+{
+ return SDL_Unsupported();
+}
+
+static int
+MIR_ResizeWindowShape(SDL_Window* window)
+{
+ return SDL_Unsupported();
+}
+
+static int
+MIR_Available()
+{
+ int available = 0;
+
+ if (SDL_MIR_LoadSymbols()) {
+
+ /* Lets ensure we can connect to the mir server */
+ MirConnection* connection = MIR_mir_connect_sync(NULL, SDL_FUNCTION);
+
+ if (!MIR_mir_connection_is_valid(connection)) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Unable to connect to the mir server %s",
+ MIR_mir_connection_get_error_message(connection));
+
+ return available;
+ }
+
+ MIR_mir_connection_release(connection);
+
+ available = 1;
+ SDL_MIR_UnloadSymbols();
+ }
+
+ return available;
+}
+
+static void
+MIR_DeleteDevice(SDL_VideoDevice* device)
+{
+ SDL_free(device);
+ SDL_MIR_UnloadSymbols();
+}
+
+static void
+MIR_PumpEvents(_THIS)
+{
+}
+
+static SDL_VideoDevice*
+MIR_CreateDevice(int device_index)
+{
+ MIR_Data* mir_data;
+ SDL_VideoDevice* device = NULL;
+
+ if (!SDL_MIR_LoadSymbols()) {
+ return NULL;
+ }
+
+ device = SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_MIR_UnloadSymbols();
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ mir_data = SDL_calloc(1, sizeof(MIR_Data));
+ if (!mir_data) {
+ SDL_free(device);
+ SDL_MIR_UnloadSymbols();
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ device->driverdata = mir_data;
+
+ /* mirvideo */
+ device->VideoInit = MIR_VideoInit;
+ device->VideoQuit = MIR_VideoQuit;
+ device->GetDisplayBounds = MIR_GetDisplayBounds;
+ device->GetDisplayModes = MIR_GetDisplayModes;
+ device->SetDisplayMode = MIR_SetDisplayMode;
+ device->free = MIR_DeleteDevice;
+
+ /* miropengles */
+ device->GL_SwapWindow = MIR_GL_SwapWindow;
+ device->GL_MakeCurrent = MIR_GL_MakeCurrent;
+ device->GL_CreateContext = MIR_GL_CreateContext;
+ device->GL_DeleteContext = MIR_GL_DeleteContext;
+ device->GL_LoadLibrary = MIR_GL_LoadLibrary;
+ device->GL_UnloadLibrary = MIR_GL_UnloadLibrary;
+ device->GL_GetSwapInterval = MIR_GL_GetSwapInterval;
+ device->GL_SetSwapInterval = MIR_GL_SetSwapInterval;
+ device->GL_GetProcAddress = MIR_GL_GetProcAddress;
+
+ /* mirwindow */
+ device->CreateSDLWindow = MIR_CreateWindow;
+ device->DestroyWindow = MIR_DestroyWindow;
+ device->GetWindowWMInfo = MIR_GetWindowWMInfo;
+ device->SetWindowFullscreen = MIR_SetWindowFullscreen;
+ device->MaximizeWindow = MIR_MaximizeWindow;
+ device->MinimizeWindow = MIR_MinimizeWindow;
+ device->RestoreWindow = MIR_RestoreWindow;
+ device->ShowWindow = MIR_RestoreWindow;
+ device->HideWindow = MIR_HideWindow;
+ device->SetWindowSize = MIR_SetWindowSize;
+ device->SetWindowMinimumSize = MIR_SetWindowMinimumSize;
+ device->SetWindowMaximumSize = MIR_SetWindowMaximumSize;
+ device->SetWindowTitle = MIR_SetWindowTitle;
+ device->SetWindowGrab = MIR_SetWindowGrab;
+ device->SetWindowGammaRamp = MIR_SetWindowGammaRamp;
+ device->GetWindowGammaRamp = MIR_GetWindowGammaRamp;
+
+ device->CreateSDLWindowFrom = NULL;
+ device->SetWindowIcon = NULL;
+ device->RaiseWindow = NULL;
+ device->SetWindowBordered = NULL;
+ device->SetWindowResizable = NULL;
+ device->OnWindowEnter = NULL;
+ device->SetWindowPosition = NULL;
+
+ /* mirframebuffer */
+ device->CreateWindowFramebuffer = MIR_CreateWindowFramebuffer;
+ device->UpdateWindowFramebuffer = MIR_UpdateWindowFramebuffer;
+ device->DestroyWindowFramebuffer = MIR_DestroyWindowFramebuffer;
+
+ device->shape_driver.CreateShaper = MIR_CreateShaper;
+ device->shape_driver.SetWindowShape = MIR_SetWindowShape;
+ device->shape_driver.ResizeWindowShape = MIR_ResizeWindowShape;
+
+ device->PumpEvents = MIR_PumpEvents;
+
+ device->SuspendScreenSaver = NULL;
+
+ device->StartTextInput = NULL;
+ device->StopTextInput = NULL;
+ device->SetTextInputRect = NULL;
+
+ device->HasScreenKeyboardSupport = NULL;
+ device->ShowScreenKeyboard = NULL;
+ device->HideScreenKeyboard = NULL;
+ device->IsScreenKeyboardShown = NULL;
+
+ device->SetClipboardText = NULL;
+ device->GetClipboardText = NULL;
+ device->HasClipboardText = NULL;
+
+ device->ShowMessageBox = NULL;
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = MIR_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = MIR_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions = MIR_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = MIR_Vulkan_CreateSurface;
+#endif
+
+ return device;
+}
+
+VideoBootStrap MIR_bootstrap = {
+ MIR_DRIVER_NAME, "SDL Mir video driver",
+ MIR_Available, MIR_CreateDevice
+};
+
+static SDL_DisplayMode
+MIR_ConvertModeToSDLMode(MirOutputMode const* mode, MirPixelFormat format)
+{
+ SDL_DisplayMode sdl_mode = {
+ .format = MIR_GetSDLPixelFormat(format),
+ .w = MIR_mir_output_mode_get_width(mode),
+ .h = MIR_mir_output_mode_get_height(mode),
+ .refresh_rate = MIR_mir_output_mode_get_refresh_rate(mode),
+ .driverdata = NULL
+ };
+
+ return sdl_mode;
+}
+
+static void
+MIR_AddModeToDisplay(SDL_VideoDisplay* display, MirOutputMode const* mode, MirPixelFormat format)
+{
+ SDL_DisplayMode sdl_mode = MIR_ConvertModeToSDLMode(mode, format);
+ SDL_AddDisplayMode(display, &sdl_mode);
+}
+
+static void
+MIR_InitDisplayFromOutput(_THIS, MirOutput* output)
+{
+ SDL_VideoDisplay display;
+ int m;
+
+ MirPixelFormat format = MIR_mir_output_get_current_pixel_format(output);
+ int num_modes = MIR_mir_output_get_num_modes(output);
+ SDL_DisplayMode current_mode = MIR_ConvertModeToSDLMode(MIR_mir_output_get_current_mode(output), format);
+
+ SDL_zero(display);
+
+ // Unfortunate cast, but SDL_AddVideoDisplay will strdup this pointer so its read-only in this case.
+ display.name = (char*)MIR_mir_output_type_name(MIR_mir_output_get_type(output));
+
+ for (m = 0; m < num_modes; m++) {
+ MirOutputMode const* mode = MIR_mir_output_get_mode(output, m);
+ MIR_AddModeToDisplay(&display, mode, format);
+ }
+
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+
+ display.driverdata = output;
+ SDL_AddVideoDisplay(&display);
+}
+
+static void
+MIR_InitDisplays(_THIS)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ int num_outputs = MIR_mir_display_config_get_num_outputs(mir_data->display_config);
+ int d;
+
+ for (d = 0; d < num_outputs; d++) {
+ MirOutput* output = MIR_mir_display_config_get_mutable_output(mir_data->display_config, d);
+ SDL_bool enabled = MIR_mir_output_is_enabled(output);
+ MirOutputConnectionState state = MIR_mir_output_get_connection_state(output);
+
+ if (enabled && state == mir_output_connection_state_connected) {
+ MIR_InitDisplayFromOutput(_this, output);
+ }
+ }
+}
+
+static int
+MIR_VideoInit(_THIS)
+{
+ MIR_Data* mir_data = _this->driverdata;
+
+ mir_data->connection = MIR_mir_connect_sync(NULL, SDL_FUNCTION);
+ mir_data->current_window = NULL;
+ mir_data->software = SDL_FALSE;
+ mir_data->pixel_format = mir_pixel_format_invalid;
+
+ if (!MIR_mir_connection_is_valid(mir_data->connection)) {
+ return SDL_SetError("Failed to connect to the mir server: %s",
+ MIR_mir_connection_get_error_message(mir_data->connection));
+ }
+
+ mir_data->display_config = MIR_mir_connection_create_display_configuration(mir_data->connection);
+
+ MIR_InitDisplays(_this);
+ MIR_InitMouse();
+
+ return 0;
+}
+
+static void
+MIR_CleanUpDisplayConfig(_THIS)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ int i;
+
+ // SDL_VideoQuit frees the display driverdata, we own it not them
+ for (i = 0; i < _this->num_displays; ++i) {
+ _this->displays[i].driverdata = NULL;
+ }
+
+ MIR_mir_display_config_release(mir_data->display_config);
+}
+
+static void
+MIR_VideoQuit(_THIS)
+{
+ MIR_Data* mir_data = _this->driverdata;
+
+ MIR_CleanUpDisplayConfig(_this);
+
+ MIR_FiniMouse();
+
+ MIR_GL_DeleteContext(_this, NULL);
+ MIR_GL_UnloadLibrary(_this);
+
+ MIR_mir_connection_release(mir_data->connection);
+
+ SDL_free(mir_data);
+ _this->driverdata = NULL;
+}
+
+static int
+MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
+{
+ MirOutput const* output = display->driverdata;
+
+ rect->x = MIR_mir_output_get_position_x(output);
+ rect->y = MIR_mir_output_get_position_y(output);
+ rect->w = display->current_mode.w;
+ rect->h = display->current_mode.h;
+
+ return 0;
+}
+
+static void
+MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* display)
+{
+}
+
+static int
+MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* display, SDL_DisplayMode* mode)
+{
+ int m;
+ MirOutput* output = display->driverdata;
+ int num_modes = MIR_mir_output_get_num_modes(output);
+ Uint32 sdl_format = MIR_GetSDLPixelFormat(
+ MIR_mir_output_get_current_pixel_format(output));
+
+ for (m = 0; m < num_modes; m++) {
+ MirOutputMode const* mir_mode = MIR_mir_output_get_mode(output, m);
+ int width = MIR_mir_output_mode_get_width(mir_mode);
+ int height = MIR_mir_output_mode_get_height(mir_mode);
+ double refresh_rate = MIR_mir_output_mode_get_refresh_rate(mir_mode);
+
+ if (mode->format == sdl_format &&
+ mode->w == width &&
+ mode->h == height &&
+ mode->refresh_rate == refresh_rate) {
+
+ // FIXME Currently wont actually *set* anything. Need to wait for applying display changes
+ MIR_mir_output_set_current_mode(output, mir_mode);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.h
new file mode 100644
index 0000000..6850bac
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirvideo.h
@@ -0,0 +1,49 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#ifndef SDL_mirvideo_h__
+#define SDL_mirvideo_h__
+
+#include <EGL/egl.h>
+#include <mir_toolkit/mir_client_library.h>
+#include "SDL_stdinc.h"
+
+typedef struct MIR_Window MIR_Window;
+
+typedef struct
+{
+ MirConnection* connection;
+ MirDisplayConfig* display_config;
+ MIR_Window* current_window;
+ SDL_bool software;
+ MirPixelFormat pixel_format;
+} MIR_Data;
+
+extern Uint32
+MIR_GetSDLPixelFormat(MirPixelFormat format);
+
+#endif /* SDL_mirvideo_h__ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.c
new file mode 100644
index 0000000..6ba3fa3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.c
@@ -0,0 +1,176 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_MIR
+
+#include "SDL_mirvideo.h"
+#include "SDL_mirwindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_mirvulkan.h"
+#include "SDL_syswm.h"
+
+int MIR_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasMIRSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+ if(_this->vulkan_config.loader_handle)
+ return SDL_SetError("Vulkan already loaded");
+
+ /* Load the Vulkan loader library */
+ if(!path)
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ if(!path)
+ path = "libvulkan.so.1";
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if(!_this->vulkan_config.loader_handle)
+ return -1;
+ SDL_strlcpy(_this->vulkan_config.loader_path, path,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+ if(!vkGetInstanceProcAddr)
+ goto fail;
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+ if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
+ goto fail;
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+ if(!extensions)
+ goto fail;
+ for(Uint32 i = 0; i < extensionCount; i++)
+ {
+ if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasSurfaceExtension = SDL_TRUE;
+ else if(SDL_strcmp(VK_KHR_MIR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasMIRSurfaceExtension = SDL_TRUE;
+ }
+ SDL_free(extensions);
+ if(!hasSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ }
+ else if(!hasMIRSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_MIR_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+ return 0;
+
+fail:
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void MIR_Vulkan_UnloadLibrary(_THIS)
+{
+ if(_this->vulkan_config.loader_handle)
+ {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool MIR_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForMir[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_MIR_SURFACE_EXTENSION_NAME
+ };
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForMir),
+ extensionsForMir);
+}
+
+SDL_bool MIR_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ MIR_Window *windowData = (MIR_Window *)window->driverdata;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR =
+ (PFN_vkCreateMirSurfaceKHR)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateMirSurfaceKHR");
+ VkMirSurfaceCreateInfoKHR createInfo;
+ VkResult result;
+
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if(!vkCreateMirSurfaceKHR)
+ {
+ SDL_SetError(VK_KHR_MIR_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ SDL_zero(createInfo);
+ createInfo.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.connection = windowData->mir_data->connection;
+ createInfo.mirSurface = windowData->window;
+ result = vkCreateMirSurfaceKHR(instance, &createInfo,
+ NULL, surface);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError("vkCreateMirSurfaceKHR failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+#endif
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.h
new file mode 100644
index 0000000..6f40d5b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirvulkan.h
@@ -0,0 +1,52 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_mirvulkan_h_
+#define SDL_mirvulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_MIR
+
+int MIR_Vulkan_LoadLibrary(_THIS, const char *path);
+void MIR_Vulkan_UnloadLibrary(_THIS);
+SDL_bool MIR_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool MIR_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+#endif
+
+#endif /* SDL_mirvulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.c b/source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.c
new file mode 100644
index 0000000..80877ee
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.c
@@ -0,0 +1,374 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_MIR
+
+#include "../SDL_egl_c.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_keyboard_c.h"
+
+#include "SDL_mirevents.h"
+#include "SDL_mirwindow.h"
+
+#include "SDL_mirdyn.h"
+
+static int
+IsMirWindowValid(MIR_Window* mir_window)
+{
+ if (!MIR_mir_window_is_valid(mir_window->window)) {
+ const char* error = MIR_mir_window_get_error_message(mir_window->window);
+ return SDL_SetError("Failed to create a mir surface: %s", error);
+ }
+
+ return 1;
+}
+
+static MirPixelFormat
+FindValidPixelFormat(MIR_Data* mir_data)
+{
+ unsigned int pf_size = 32;
+ unsigned int valid_formats;
+ unsigned int f;
+
+ MirPixelFormat formats[pf_size];
+ MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
+ pf_size, &valid_formats);
+
+ for (f = 0; f < valid_formats; f++) {
+ MirPixelFormat cur_pf = formats[f];
+
+ if (cur_pf == mir_pixel_format_abgr_8888 ||
+ cur_pf == mir_pixel_format_xbgr_8888 ||
+ cur_pf == mir_pixel_format_argb_8888 ||
+ cur_pf == mir_pixel_format_xrgb_8888) {
+
+ return cur_pf;
+ }
+ }
+
+ return mir_pixel_format_invalid;
+}
+
+int
+MIR_CreateWindow(_THIS, SDL_Window* window)
+{
+ MIR_Window* mir_window;
+ MIR_Data* mir_data;
+ MirPixelFormat pixel_format;
+ MirBufferUsage buffer_usage;
+
+ MirWindowSpec* spec;
+
+ mir_window = SDL_calloc(1, sizeof(MIR_Window));
+ if (!mir_window)
+ return SDL_OutOfMemory();
+
+ mir_data = _this->driverdata;
+ window->driverdata = mir_window;
+
+ if (window->x == SDL_WINDOWPOS_UNDEFINED)
+ window->x = 0;
+
+ if (window->y == SDL_WINDOWPOS_UNDEFINED)
+ window->y = 0;
+
+ mir_window->mir_data = mir_data;
+ mir_window->sdl_window = window;
+
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
+ _this->egl_data->egl_display,
+ _this->egl_data->egl_config);
+ }
+ else {
+ pixel_format = FindValidPixelFormat(mir_data);
+ }
+
+ mir_data->pixel_format = pixel_format;
+ if (pixel_format == mir_pixel_format_invalid) {
+ return SDL_SetError("Failed to find a valid pixel format.");
+ }
+
+ buffer_usage = mir_buffer_usage_hardware;
+ if (mir_data->software)
+ buffer_usage = mir_buffer_usage_software;
+
+ spec = MIR_mir_create_normal_window_spec(mir_data->connection,
+ window->w,
+ window->h);
+
+ MIR_mir_window_spec_set_buffer_usage(spec, buffer_usage);
+ MIR_mir_window_spec_set_name(spec, "Mir surface");
+ MIR_mir_window_spec_set_pixel_format(spec, pixel_format);
+
+ if (window->flags & SDL_WINDOW_INPUT_FOCUS)
+ SDL_SetKeyboardFocus(window);
+
+ mir_window->window = MIR_mir_create_window_sync(spec);
+ MIR_mir_window_set_event_handler(mir_window->window, MIR_HandleEvent, window);
+
+ MIR_mir_window_spec_release(spec);
+
+ if (!MIR_mir_window_is_valid(mir_window->window)) {
+ return SDL_SetError("Failed to create a mir surface: %s",
+ MIR_mir_window_get_error_message(mir_window->window));
+ }
+
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ EGLNativeWindowType egl_native_window =
+ (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
+ MIR_mir_window_get_buffer_stream(mir_window->window));
+
+ mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
+
+ if (mir_window->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("Failed to create a window surface %p",
+ _this->egl_data->egl_display);
+ }
+ }
+ else {
+ mir_window->egl_surface = EGL_NO_SURFACE;
+ }
+
+ mir_data->current_window = mir_window;
+
+ return 0;
+}
+
+void
+MIR_DestroyWindow(_THIS, SDL_Window* window)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ MIR_Window* mir_window = window->driverdata;
+
+ if (mir_data) {
+ SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
+ MIR_mir_window_release_sync(mir_window->window);
+
+ mir_data->current_window = NULL;
+
+ SDL_free(mir_window);
+ }
+ window->driverdata = NULL;
+}
+
+SDL_bool
+MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
+{
+ if (info->version.major == SDL_MAJOR_VERSION &&
+ info->version.minor == SDL_MINOR_VERSION) {
+ MIR_Window* mir_window = window->driverdata;
+
+ info->subsystem = SDL_SYSWM_MIR;
+ info->info.mir.connection = mir_window->mir_data->connection;
+ // Cannot change this to window due to it being in the public API
+ info->info.mir.surface = mir_window->window;
+
+ return SDL_TRUE;
+ }
+
+ return SDL_FALSE;
+}
+
+static void
+UpdateMirWindowState(MIR_Data* mir_data, MIR_Window* mir_window, MirWindowState window_state)
+{
+ if (IsMirWindowValid(mir_window)) {
+ MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_state(spec, window_state);
+
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ MIR_mir_window_spec_release(spec);
+ }
+}
+
+void
+MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
+ SDL_VideoDisplay* display,
+ SDL_bool fullscreen)
+{
+ if (IsMirWindowValid(window->driverdata)) {
+ MirWindowState state;
+
+ if (fullscreen) {
+ state = mir_window_state_fullscreen;
+ }
+ else {
+ state = mir_window_state_restored;
+ }
+
+ UpdateMirWindowState(_this->driverdata, window->driverdata, state);
+ }
+}
+
+void
+MIR_MaximizeWindow(_THIS, SDL_Window* window)
+{
+ UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_maximized);
+}
+
+void
+MIR_MinimizeWindow(_THIS, SDL_Window* window)
+{
+ UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_minimized);
+}
+
+void
+MIR_RestoreWindow(_THIS, SDL_Window * window)
+{
+ UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_restored);
+}
+
+void
+MIR_HideWindow(_THIS, SDL_Window* window)
+{
+ UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_hidden);
+}
+
+void
+MIR_SetWindowSize(_THIS, SDL_Window* window)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ MIR_Window* mir_window = window->driverdata;
+
+ if (IsMirWindowValid(mir_window)) {
+ MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_width (spec, window->w);
+ MIR_mir_window_spec_set_height(spec, window->h);
+
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ }
+}
+
+void
+MIR_SetWindowMinimumSize(_THIS, SDL_Window* window)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ MIR_Window* mir_window = window->driverdata;
+
+ if (IsMirWindowValid(mir_window)) {
+ MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_min_width (spec, window->min_w);
+ MIR_mir_window_spec_set_min_height(spec, window->min_h);
+
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ }
+}
+
+void
+MIR_SetWindowMaximumSize(_THIS, SDL_Window* window)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ MIR_Window* mir_window = window->driverdata;
+
+ if (IsMirWindowValid(mir_window)) {
+ MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_max_width (spec, window->max_w);
+ MIR_mir_window_spec_set_max_height(spec, window->max_h);
+
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ }
+}
+
+void
+MIR_SetWindowTitle(_THIS, SDL_Window* window)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ MIR_Window* mir_window = window->driverdata;
+ char const* title = window->title ? window->title : "";
+ MirWindowSpec* spec;
+
+ if (IsMirWindowValid(mir_window) < 0)
+ return;
+
+ spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_name(spec, title);
+
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ MIR_mir_window_spec_release(spec);
+}
+
+void
+MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed)
+{
+ MIR_Data* mir_data = _this->driverdata;
+ MIR_Window* mir_window = window->driverdata;
+ MirPointerConfinementState confined = mir_pointer_unconfined;
+ MirWindowSpec* spec;
+
+ if (grabbed)
+ confined = mir_pointer_confined_to_window;
+
+ spec = MIR_mir_create_window_spec(mir_data->connection);
+ MIR_mir_window_spec_set_pointer_confinement(spec, confined);
+
+ MIR_mir_window_apply_spec(mir_window->window, spec);
+ MIR_mir_window_spec_release(spec);
+}
+
+int
+MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp)
+{
+ MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
+ Uint32 ramp_size = 256;
+
+ // FIXME Need to apply the changes to the output, once that public API function is around
+ if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
+ MIR_mir_output_set_gamma(output,
+ ramp + ramp_size * 0,
+ ramp + ramp_size * 1,
+ ramp + ramp_size * 2,
+ ramp_size);
+ return 0;
+ }
+
+ return -1;
+}
+
+int
+MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp)
+{
+ MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
+ Uint32 ramp_size = 256;
+
+ if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
+ if (MIR_mir_output_get_gamma_size(output) == ramp_size) {
+ MIR_mir_output_get_gamma(output,
+ ramp + ramp_size * 0,
+ ramp + ramp_size * 1,
+ ramp + ramp_size * 2,
+ ramp_size);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+#endif /* SDL_VIDEO_DRIVER_MIR */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.h b/source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.h
new file mode 100644
index 0000000..af618f5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/mir/SDL_mirwindow.h
@@ -0,0 +1,93 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
+*/
+
+#ifndef SDL_mirwindow_h_
+#define SDL_mirwindow_h_
+
+#include "../SDL_sysvideo.h"
+#include "SDL_syswm.h"
+
+#include "SDL_mirvideo.h"
+
+struct MIR_Window {
+ SDL_Window* sdl_window;
+ MIR_Data* mir_data;
+
+ MirWindow* window;
+ EGLSurface egl_surface;
+};
+
+
+extern int
+MIR_CreateWindow(_THIS, SDL_Window* window);
+
+extern void
+MIR_DestroyWindow(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
+ SDL_VideoDisplay* display,
+ SDL_bool fullscreen);
+
+extern void
+MIR_MaximizeWindow(_THIS, SDL_Window* window);
+
+extern void
+MIR_MinimizeWindow(_THIS, SDL_Window* window);
+
+extern void
+MIR_RestoreWindow(_THIS, SDL_Window* window);
+
+extern void
+MIR_HideWindow(_THIS, SDL_Window* window);
+
+extern SDL_bool
+MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info);
+
+extern void
+MIR_SetWindowSize(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowMinimumSize(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowMaximumSize(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowTitle(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed);
+
+extern int
+MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp);
+
+extern int
+MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp);
+
+#endif /* SDL_mirwindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclevents.c b/source/3rd-party/SDL2/src/video/nacl/SDL_naclevents.c
new file mode 100644
index 0000000..812df2b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclevents.c
@@ -0,0 +1,438 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_NACL
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_naclevents_c.h"
+#include "SDL_naclvideo.h"
+#include "ppapi_simple/ps_event.h"
+
+/* Ref: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent */
+
+static SDL_Scancode NACL_Keycodes[] = {
+ SDL_SCANCODE_UNKNOWN, /* 0 */
+ SDL_SCANCODE_UNKNOWN, /* 1 */
+ SDL_SCANCODE_UNKNOWN, /* 2 */
+ SDL_SCANCODE_CANCEL, /* DOM_VK_CANCEL 3 */
+ SDL_SCANCODE_UNKNOWN, /* 4 */
+ SDL_SCANCODE_UNKNOWN, /* 5 */
+ SDL_SCANCODE_HELP, /* DOM_VK_HELP 6 */
+ SDL_SCANCODE_UNKNOWN, /* 7 */
+ SDL_SCANCODE_BACKSPACE, /* DOM_VK_BACK_SPACE 8 */
+ SDL_SCANCODE_TAB, /* DOM_VK_TAB 9 */
+ SDL_SCANCODE_UNKNOWN, /* 10 */
+ SDL_SCANCODE_UNKNOWN, /* 11 */
+ SDL_SCANCODE_CLEAR, /* DOM_VK_CLEAR 12 */
+ SDL_SCANCODE_RETURN, /* DOM_VK_RETURN 13 */
+ SDL_SCANCODE_RETURN, /* DOM_VK_ENTER 14 */
+ SDL_SCANCODE_UNKNOWN, /* 15 */
+ SDL_SCANCODE_LSHIFT, /* DOM_VK_SHIFT 16 */
+ SDL_SCANCODE_LCTRL, /* DOM_VK_CONTROL 17 */
+ SDL_SCANCODE_LALT, /* DOM_VK_ALT 18 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_PAUSE 19 */
+ SDL_SCANCODE_CAPSLOCK, /* DOM_VK_CAPS_LOCK 20 */
+ SDL_SCANCODE_LANG1, /* DOM_VK_KANA DOM_VK_HANGUL 21 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_EISU 22 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_JUNJA 23 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_FINAL 24 */
+ SDL_SCANCODE_LANG2, /* DOM_VK_HANJA DOM_VK_KANJI 25 */
+ SDL_SCANCODE_UNKNOWN, /* 26 */
+ SDL_SCANCODE_ESCAPE, /* DOM_VK_ESCAPE 27 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_CONVERT 28 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_NONCONVERT 29 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_ACCEPT 30 */
+ SDL_SCANCODE_MODE, /* DOM_VK_MODECHANGE 31 */
+ SDL_SCANCODE_SPACE, /* DOM_VK_SPACE 32 */
+ SDL_SCANCODE_PAGEUP, /* DOM_VK_PAGE_UP 33 */
+ SDL_SCANCODE_PAGEDOWN, /* DOM_VK_PAGE_DOWN 34 */
+ SDL_SCANCODE_END, /* DOM_VK_END 35 */
+ SDL_SCANCODE_HOME, /* DOM_VK_HOME 36 */
+ SDL_SCANCODE_LEFT, /* DOM_VK_LEFT 37 */
+ SDL_SCANCODE_UP, /* DOM_VK_UP 38 */
+ SDL_SCANCODE_RIGHT, /* DOM_VK_RIGHT 39 */
+ SDL_SCANCODE_DOWN, /* DOM_VK_DOWN 40 */
+ SDL_SCANCODE_SELECT, /* DOM_VK_SELECT 41 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_PRINT 42 */
+ SDL_SCANCODE_EXECUTE, /* DOM_VK_EXECUTE 43 */
+ SDL_SCANCODE_PRINTSCREEN, /* DOM_VK_PRINTSCREEN 44 */
+ SDL_SCANCODE_INSERT, /* DOM_VK_INSERT 45 */
+ SDL_SCANCODE_DELETE, /* DOM_VK_DELETE 46 */
+ SDL_SCANCODE_UNKNOWN, /* 47 */
+ SDL_SCANCODE_0, /* DOM_VK_0 48 */
+ SDL_SCANCODE_1, /* DOM_VK_1 49 */
+ SDL_SCANCODE_2, /* DOM_VK_2 50 */
+ SDL_SCANCODE_3, /* DOM_VK_3 51 */
+ SDL_SCANCODE_4, /* DOM_VK_4 52 */
+ SDL_SCANCODE_5, /* DOM_VK_5 53 */
+ SDL_SCANCODE_6, /* DOM_VK_6 54 */
+ SDL_SCANCODE_7, /* DOM_VK_7 55 */
+ SDL_SCANCODE_8, /* DOM_VK_8 56 */
+ SDL_SCANCODE_9, /* DOM_VK_9 57 */
+ SDL_SCANCODE_KP_COLON, /* DOM_VK_COLON 58 */
+ SDL_SCANCODE_SEMICOLON, /* DOM_VK_SEMICOLON 59 */
+ SDL_SCANCODE_KP_LESS, /* DOM_VK_LESS_THAN 60 */
+ SDL_SCANCODE_EQUALS, /* DOM_VK_EQUALS 61 */
+ SDL_SCANCODE_KP_GREATER, /* DOM_VK_GREATER_THAN 62 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_QUESTION_MARK 63 */
+ SDL_SCANCODE_KP_AT, /* DOM_VK_AT 64 */
+ SDL_SCANCODE_A, /* DOM_VK_A 65 */
+ SDL_SCANCODE_B, /* DOM_VK_B 66 */
+ SDL_SCANCODE_C, /* DOM_VK_C 67 */
+ SDL_SCANCODE_D, /* DOM_VK_D 68 */
+ SDL_SCANCODE_E, /* DOM_VK_E 69 */
+ SDL_SCANCODE_F, /* DOM_VK_F 70 */
+ SDL_SCANCODE_G, /* DOM_VK_G 71 */
+ SDL_SCANCODE_H, /* DOM_VK_H 72 */
+ SDL_SCANCODE_I, /* DOM_VK_I 73 */
+ SDL_SCANCODE_J, /* DOM_VK_J 74 */
+ SDL_SCANCODE_K, /* DOM_VK_K 75 */
+ SDL_SCANCODE_L, /* DOM_VK_L 76 */
+ SDL_SCANCODE_M, /* DOM_VK_M 77 */
+ SDL_SCANCODE_N, /* DOM_VK_N 78 */
+ SDL_SCANCODE_O, /* DOM_VK_O 79 */
+ SDL_SCANCODE_P, /* DOM_VK_P 80 */
+ SDL_SCANCODE_Q, /* DOM_VK_Q 81 */
+ SDL_SCANCODE_R, /* DOM_VK_R 82 */
+ SDL_SCANCODE_S, /* DOM_VK_S 83 */
+ SDL_SCANCODE_T, /* DOM_VK_T 84 */
+ SDL_SCANCODE_U, /* DOM_VK_U 85 */
+ SDL_SCANCODE_V, /* DOM_VK_V 86 */
+ SDL_SCANCODE_W, /* DOM_VK_W 87 */
+ SDL_SCANCODE_X, /* DOM_VK_X 88 */
+ SDL_SCANCODE_Y, /* DOM_VK_Y 89 */
+ SDL_SCANCODE_Z, /* DOM_VK_Z 90 */
+ SDL_SCANCODE_LGUI, /* DOM_VK_WIN 91 */
+ SDL_SCANCODE_UNKNOWN, /* 92 */
+ SDL_SCANCODE_APPLICATION, /* DOM_VK_CONTEXT_MENU 93 */
+ SDL_SCANCODE_UNKNOWN, /* 94 */
+ SDL_SCANCODE_SLEEP, /* DOM_VK_SLEEP 95 */
+ SDL_SCANCODE_KP_0, /* DOM_VK_NUMPAD0 96 */
+ SDL_SCANCODE_KP_1, /* DOM_VK_NUMPAD1 97 */
+ SDL_SCANCODE_KP_2, /* DOM_VK_NUMPAD2 98 */
+ SDL_SCANCODE_KP_3, /* DOM_VK_NUMPAD3 99 */
+ SDL_SCANCODE_KP_4, /* DOM_VK_NUMPAD4 100 */
+ SDL_SCANCODE_KP_5, /* DOM_VK_NUMPAD5 101 */
+ SDL_SCANCODE_KP_6, /* DOM_VK_NUMPAD6 102 */
+ SDL_SCANCODE_KP_7, /* DOM_VK_NUMPAD7 103 */
+ SDL_SCANCODE_KP_8, /* DOM_VK_NUMPAD8 104 */
+ SDL_SCANCODE_KP_9, /* DOM_VK_NUMPAD9 105 */
+ SDL_SCANCODE_KP_MULTIPLY, /* DOM_VK_MULTIPLY 106 */
+ SDL_SCANCODE_KP_PLUS, /* DOM_VK_ADD 107 */
+ SDL_SCANCODE_KP_COMMA, /* DOM_VK_SEPARATOR 108 */
+ SDL_SCANCODE_KP_MINUS, /* DOM_VK_SUBTRACT 109 */
+ SDL_SCANCODE_KP_PERIOD, /* DOM_VK_DECIMAL 110 */
+ SDL_SCANCODE_KP_DIVIDE, /* DOM_VK_DIVIDE 111 */
+ SDL_SCANCODE_F1, /* DOM_VK_F1 112 */
+ SDL_SCANCODE_F2, /* DOM_VK_F2 113 */
+ SDL_SCANCODE_F3, /* DOM_VK_F3 114 */
+ SDL_SCANCODE_F4, /* DOM_VK_F4 115 */
+ SDL_SCANCODE_F5, /* DOM_VK_F5 116 */
+ SDL_SCANCODE_F6, /* DOM_VK_F6 117 */
+ SDL_SCANCODE_F7, /* DOM_VK_F7 118 */
+ SDL_SCANCODE_F8, /* DOM_VK_F8 119 */
+ SDL_SCANCODE_F9, /* DOM_VK_F9 120 */
+ SDL_SCANCODE_F10, /* DOM_VK_F10 121 */
+ SDL_SCANCODE_F11, /* DOM_VK_F11 122 */
+ SDL_SCANCODE_F12, /* DOM_VK_F12 123 */
+ SDL_SCANCODE_F13, /* DOM_VK_F13 124 */
+ SDL_SCANCODE_F14, /* DOM_VK_F14 125 */
+ SDL_SCANCODE_F15, /* DOM_VK_F15 126 */
+ SDL_SCANCODE_F16, /* DOM_VK_F16 127 */
+ SDL_SCANCODE_F17, /* DOM_VK_F17 128 */
+ SDL_SCANCODE_F18, /* DOM_VK_F18 129 */
+ SDL_SCANCODE_F19, /* DOM_VK_F19 130 */
+ SDL_SCANCODE_F20, /* DOM_VK_F20 131 */
+ SDL_SCANCODE_F21, /* DOM_VK_F21 132 */
+ SDL_SCANCODE_F22, /* DOM_VK_F22 133 */
+ SDL_SCANCODE_F23, /* DOM_VK_F23 134 */
+ SDL_SCANCODE_F24, /* DOM_VK_F24 135 */
+ SDL_SCANCODE_UNKNOWN, /* 136 */
+ SDL_SCANCODE_UNKNOWN, /* 137 */
+ SDL_SCANCODE_UNKNOWN, /* 138 */
+ SDL_SCANCODE_UNKNOWN, /* 139 */
+ SDL_SCANCODE_UNKNOWN, /* 140 */
+ SDL_SCANCODE_UNKNOWN, /* 141 */
+ SDL_SCANCODE_UNKNOWN, /* 142 */
+ SDL_SCANCODE_UNKNOWN, /* 143 */
+ SDL_SCANCODE_NUMLOCKCLEAR, /* DOM_VK_NUM_LOCK 144 */
+ SDL_SCANCODE_SCROLLLOCK, /* DOM_VK_SCROLL_LOCK 145 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_JISHO 146 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_MASSHOU 147 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_TOUROKU 148 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_LOYA 149 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_ROYA 150 */
+ SDL_SCANCODE_UNKNOWN, /* 151 */
+ SDL_SCANCODE_UNKNOWN, /* 152 */
+ SDL_SCANCODE_UNKNOWN, /* 153 */
+ SDL_SCANCODE_UNKNOWN, /* 154 */
+ SDL_SCANCODE_UNKNOWN, /* 155 */
+ SDL_SCANCODE_UNKNOWN, /* 156 */
+ SDL_SCANCODE_UNKNOWN, /* 157 */
+ SDL_SCANCODE_UNKNOWN, /* 158 */
+ SDL_SCANCODE_UNKNOWN, /* 159 */
+ SDL_SCANCODE_GRAVE, /* DOM_VK_CIRCUMFLEX 160 */
+ SDL_SCANCODE_KP_EXCLAM, /* DOM_VK_EXCLAMATION 161 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_DOUBLE_QUOTE 162 */
+ SDL_SCANCODE_KP_HASH, /* DOM_VK_HASH 163 */
+ SDL_SCANCODE_CURRENCYUNIT, /* DOM_VK_DOLLAR 164 */
+ SDL_SCANCODE_KP_PERCENT, /* DOM_VK_PERCENT 165 */
+ SDL_SCANCODE_KP_AMPERSAND, /* DOM_VK_AMPERSAND 166 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_UNDERSCORE 167 */
+ SDL_SCANCODE_KP_LEFTPAREN, /* DOM_VK_OPEN_PAREN 168 */
+ SDL_SCANCODE_KP_RIGHTPAREN, /* DOM_VK_CLOSE_PAREN 169 */
+ SDL_SCANCODE_KP_MULTIPLY, /* DOM_VK_ASTERISK 170 */
+ SDL_SCANCODE_KP_PLUS, /* DOM_VK_PLUS 171 */
+ SDL_SCANCODE_KP_PLUS, /* DOM_VK_PIPE 172 */
+ SDL_SCANCODE_MINUS, /* DOM_VK_HYPHEN_MINUS 173 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_OPEN_CURLY_BRACKET 174 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_CLOSE_CURLY_BRACKET 175 */
+ SDL_SCANCODE_NONUSBACKSLASH, /* DOM_VK_TILDE 176 */
+ SDL_SCANCODE_UNKNOWN, /* 177 */
+ SDL_SCANCODE_UNKNOWN, /* 178 */
+ SDL_SCANCODE_UNKNOWN, /* 179 */
+ SDL_SCANCODE_UNKNOWN, /* 180 */
+ SDL_SCANCODE_MUTE, /* DOM_VK_VOLUME_MUTE 181 */
+ SDL_SCANCODE_VOLUMEDOWN, /* DOM_VK_VOLUME_DOWN 182 */
+ SDL_SCANCODE_VOLUMEUP, /* DOM_VK_VOLUME_UP 183 */
+ SDL_SCANCODE_UNKNOWN, /* 184 */
+ SDL_SCANCODE_UNKNOWN, /* 185 */
+ SDL_SCANCODE_UNKNOWN, /* 186 */
+ SDL_SCANCODE_UNKNOWN, /* 187 */
+ SDL_SCANCODE_COMMA, /* DOM_VK_COMMA 188 */
+ SDL_SCANCODE_UNKNOWN, /* 189 */
+ SDL_SCANCODE_PERIOD, /* DOM_VK_PERIOD 190 */
+ SDL_SCANCODE_SLASH, /* DOM_VK_SLASH 191 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_BACK_QUOTE 192 */
+ SDL_SCANCODE_UNKNOWN, /* 193 */
+ SDL_SCANCODE_UNKNOWN, /* 194 */
+ SDL_SCANCODE_UNKNOWN, /* 195 */
+ SDL_SCANCODE_UNKNOWN, /* 196 */
+ SDL_SCANCODE_UNKNOWN, /* 197 */
+ SDL_SCANCODE_UNKNOWN, /* 198 */
+ SDL_SCANCODE_UNKNOWN, /* 199 */
+ SDL_SCANCODE_UNKNOWN, /* 200 */
+ SDL_SCANCODE_UNKNOWN, /* 201 */
+ SDL_SCANCODE_UNKNOWN, /* 202 */
+ SDL_SCANCODE_UNKNOWN, /* 203 */
+ SDL_SCANCODE_UNKNOWN, /* 204 */
+ SDL_SCANCODE_UNKNOWN, /* 205 */
+ SDL_SCANCODE_UNKNOWN, /* 206 */
+ SDL_SCANCODE_UNKNOWN, /* 207 */
+ SDL_SCANCODE_UNKNOWN, /* 208 */
+ SDL_SCANCODE_UNKNOWN, /* 209 */
+ SDL_SCANCODE_UNKNOWN, /* 210 */
+ SDL_SCANCODE_UNKNOWN, /* 211 */
+ SDL_SCANCODE_UNKNOWN, /* 212 */
+ SDL_SCANCODE_UNKNOWN, /* 213 */
+ SDL_SCANCODE_UNKNOWN, /* 214 */
+ SDL_SCANCODE_UNKNOWN, /* 215 */
+ SDL_SCANCODE_UNKNOWN, /* 216 */
+ SDL_SCANCODE_UNKNOWN, /* 217 */
+ SDL_SCANCODE_UNKNOWN, /* 218 */
+ SDL_SCANCODE_LEFTBRACKET, /* DOM_VK_OPEN_BRACKET 219 */
+ SDL_SCANCODE_BACKSLASH, /* DOM_VK_BACK_SLASH 220 */
+ SDL_SCANCODE_RIGHTBRACKET, /* DOM_VK_CLOSE_BRACKET 221 */
+ SDL_SCANCODE_APOSTROPHE, /* DOM_VK_QUOTE 222 */
+ SDL_SCANCODE_UNKNOWN, /* 223 */
+ SDL_SCANCODE_RGUI, /* DOM_VK_META 224 */
+ SDL_SCANCODE_RALT, /* DOM_VK_ALTGR 225 */
+ SDL_SCANCODE_UNKNOWN, /* 226 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_ICO_HELP 227 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_ICO_00 228 */
+ SDL_SCANCODE_UNKNOWN, /* 229 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_ICO_CLEAR 230 */
+ SDL_SCANCODE_UNKNOWN, /* 231 */
+ SDL_SCANCODE_UNKNOWN, /* 232 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_RESET 233 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_JUMP 234 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_PA1 235 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_PA2 236 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_PA3 237 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_WSCTRL 238 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_CUSEL 239 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_ATTN 240 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FINISH 241 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_COPY 242 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_AUTO 243 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_ENLW 244 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_BACKTAB 245 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_ATTN 246 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_CRSEL 247 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_EXSEL 248 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_EREOF 249 */
+ SDL_SCANCODE_AUDIOPLAY, /* DOM_VK_PLAY 250 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_ZOOM 251 */
+ SDL_SCANCODE_UNKNOWN, /* 252 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_PA1 253 */
+ SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_CLEAR 254 */
+ SDL_SCANCODE_UNKNOWN, /* 255 */
+};
+
+static Uint8 SDL_NACL_translate_mouse_button(int32_t button) {
+ switch (button) {
+ case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
+ return SDL_BUTTON_LEFT;
+ case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
+ return SDL_BUTTON_MIDDLE;
+ case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
+ return SDL_BUTTON_RIGHT;
+
+ case PP_INPUTEVENT_MOUSEBUTTON_NONE:
+ default:
+ return 0;
+ }
+}
+
+static SDL_Scancode
+SDL_NACL_translate_keycode(int keycode)
+{
+ SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
+
+ if (keycode < SDL_arraysize(NACL_Keycodes)) {
+ scancode = NACL_Keycodes[keycode];
+ }
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list <https://discourse.libsdl.org/> NACL KeyCode %d", keycode);
+ }
+ return scancode;
+}
+
+void NACL_PumpEvents(_THIS) {
+ PSEvent* ps_event;
+ PP_Resource event;
+ PP_InputEvent_Type type;
+ PP_InputEvent_Modifier modifiers;
+ struct PP_Rect rect;
+ struct PP_FloatPoint fp;
+ struct PP_Point location;
+ struct PP_Var var;
+ const char *str;
+ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
+ Uint32 str_len;
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (driverdata->window) {
+ while ((ps_event = PSEventTryAcquire()) != NULL) {
+ event = ps_event->as_resource;
+ switch(ps_event->type) {
+ /* From DidChangeView, contains a view resource */
+ case PSE_INSTANCE_DIDCHANGEVIEW:
+ driverdata->ppb_view->GetRect(event, &rect);
+ NACL_SetScreenResolution(rect.size.width, rect.size.height, SDL_PIXELFORMAT_UNKNOWN);
+ // FIXME: Rebuild context? See life.c UpdateContext
+ break;
+
+ /* From HandleInputEvent, contains an input resource. */
+ case PSE_INSTANCE_HANDLEINPUT:
+ type = driverdata->ppb_input_event->GetType(event);
+ modifiers = driverdata->ppb_input_event->GetModifiers(event);
+ switch(type) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_NACL_translate_mouse_button(driverdata->ppb_mouse_input_event->GetButton(event)));
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_NACL_translate_mouse_button(driverdata->ppb_mouse_input_event->GetButton(event)));
+ break;
+ case PP_INPUTEVENT_TYPE_WHEEL:
+ /* FIXME: GetTicks provides high resolution scroll events */
+ fp = driverdata->ppb_wheel_input_event->GetDelta(event);
+ SDL_SendMouseWheel(mouse->focus, mouse->mouseID, fp.x, fp.y, SDL_MOUSEWHEEL_NORMAL);
+ break;
+
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE:
+ /* FIXME: Mouse Focus */
+ break;
+
+
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ location = driverdata->ppb_mouse_input_event->GetPosition(event);
+ SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, location.x, location.y);
+ break;
+
+ case PP_INPUTEVENT_TYPE_TOUCHSTART:
+ case PP_INPUTEVENT_TYPE_TOUCHMOVE:
+ case PP_INPUTEVENT_TYPE_TOUCHEND:
+ case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
+ /* FIXME: Touch events */
+ break;
+
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_NACL_translate_keycode(driverdata->ppb_keyboard_input_event->GetKeyCode(event)));
+ break;
+
+ case PP_INPUTEVENT_TYPE_KEYUP:
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_NACL_translate_keycode(driverdata->ppb_keyboard_input_event->GetKeyCode(event)));
+ break;
+
+ case PP_INPUTEVENT_TYPE_CHAR:
+ var = driverdata->ppb_keyboard_input_event->GetCharacterText(event);
+ str = driverdata->ppb_var->VarToUtf8(var, &str_len);
+ /* str is not null terminated! */
+ if ( str_len >= SDL_arraysize(text) ) {
+ str_len = SDL_arraysize(text) - 1;
+ }
+ SDL_strlcpy(text, str, str_len );
+ text[str_len] = '\0';
+
+ SDL_SendKeyboardText(text);
+ /* FIXME: Do we have to handle ref counting? driverdata->ppb_var->Release(var);*/
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+
+ /* From HandleMessage, contains a PP_Var. */
+ case PSE_INSTANCE_HANDLEMESSAGE:
+ break;
+
+ /* From DidChangeFocus, contains a PP_Bool with the current focus state. */
+ case PSE_INSTANCE_DIDCHANGEFOCUS:
+ break;
+
+ /* When the 3D context is lost, no resource. */
+ case PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST:
+ break;
+
+ /* When the mouse lock is lost. */
+ case PSE_MOUSELOCK_MOUSELOCKLOST:
+ break;
+
+ default:
+ break;
+ }
+
+ PSEventRelease(ps_event);
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_NACL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclevents_c.h b/source/3rd-party/SDL2/src/video/nacl/SDL_naclevents_c.h
new file mode 100644
index 0000000..8059ea5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclevents_c.h
@@ -0,0 +1,30 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_naclevents_c_h_
+#define SDL_naclevents_c_h_
+
+#include "SDL_naclvideo.h"
+
+extern void NACL_PumpEvents(_THIS);
+
+#endif /* SDL_naclevents_c_h_ */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclglue.c b/source/3rd-party/SDL2/src/video/nacl/SDL_naclglue.c
new file mode 100644
index 0000000..544cc6f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclglue.c
@@ -0,0 +1,24 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_NACL
+#endif /* SDL_VIDEO_DRIVER_NACL */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.c b/source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.c
new file mode 100644
index 0000000..98b9ad3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.c
@@ -0,0 +1,174 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_NACL
+
+/* NaCl SDL video GLES 2 driver implementation */
+
+#include "SDL_video.h"
+#include "SDL_naclvideo.h"
+
+#if SDL_LOADSO_DLOPEN
+#include "dlfcn.h"
+#endif
+
+#include "ppapi/gles2/gl2ext_ppapi.h"
+#include "ppapi_simple/ps.h"
+
+/* GL functions */
+int
+NACL_GLES_LoadLibrary(_THIS, const char *path)
+{
+ /* FIXME: Support dynamic linking when PNACL supports it */
+ return glInitializePPAPI(PSGetInterface) == 0;
+}
+
+void *
+NACL_GLES_GetProcAddress(_THIS, const char *proc)
+{
+#if SDL_LOADSO_DLOPEN
+ return dlsym( 0 /* RTLD_DEFAULT */, proc);
+#else
+ return NULL;
+#endif
+}
+
+void
+NACL_GLES_UnloadLibrary(_THIS)
+{
+ /* FIXME: Support dynamic linking when PNACL supports it */
+ glTerminatePPAPI();
+}
+
+int
+NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext sdl_context)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ /* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
+ driverdata->ppb_instance->BindGraphics(driverdata->instance, (PP_Resource) sdl_context);
+ glSetCurrentContextPPAPI((PP_Resource) sdl_context);
+ return 0;
+}
+
+SDL_GLContext
+NACL_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ PP_Resource context, share_context = 0;
+ /* 64 seems nice. */
+ Sint32 attribs[64];
+ int i = 0;
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (PP_Resource) SDL_GL_GetCurrentContext();
+ }
+
+ /* FIXME: Some ATTRIBS from PP_Graphics3DAttrib are not set here */
+
+ attribs[i++] = PP_GRAPHICS3DATTRIB_WIDTH;
+ attribs[i++] = window->w;
+ attribs[i++] = PP_GRAPHICS3DATTRIB_HEIGHT;
+ attribs[i++] = window->h;
+ attribs[i++] = PP_GRAPHICS3DATTRIB_RED_SIZE;
+ attribs[i++] = _this->gl_config.red_size;
+ attribs[i++] = PP_GRAPHICS3DATTRIB_GREEN_SIZE;
+ attribs[i++] = _this->gl_config.green_size;
+ attribs[i++] = PP_GRAPHICS3DATTRIB_BLUE_SIZE;
+ attribs[i++] = _this->gl_config.blue_size;
+
+ if (_this->gl_config.alpha_size) {
+ attribs[i++] = PP_GRAPHICS3DATTRIB_ALPHA_SIZE;
+ attribs[i++] = _this->gl_config.alpha_size;
+ }
+
+ /*if (_this->gl_config.buffer_size) {
+ attribs[i++] = EGL_BUFFER_SIZE;
+ attribs[i++] = _this->gl_config.buffer_size;
+ }*/
+
+ attribs[i++] = PP_GRAPHICS3DATTRIB_DEPTH_SIZE;
+ attribs[i++] = _this->gl_config.depth_size;
+
+ if (_this->gl_config.stencil_size) {
+ attribs[i++] = PP_GRAPHICS3DATTRIB_STENCIL_SIZE;
+ attribs[i++] = _this->gl_config.stencil_size;
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ attribs[i++] = PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS;
+ attribs[i++] = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ attribs[i++] = PP_GRAPHICS3DATTRIB_SAMPLES;
+ attribs[i++] = _this->gl_config.multisamplesamples;
+ }
+
+ attribs[i++] = PP_GRAPHICS3DATTRIB_NONE;
+
+ context = driverdata->ppb_graphics->Create(driverdata->instance, share_context, attribs);
+
+ if (context) {
+ /* We need to make the context current, otherwise nothing works */
+ SDL_GL_MakeCurrent(window, (SDL_GLContext) context);
+ }
+
+ return (SDL_GLContext) context;
+}
+
+
+
+int
+NACL_GLES_SetSwapInterval(_THIS, int interval)
+{
+ /* STUB */
+ return SDL_Unsupported();
+}
+
+int
+NACL_GLES_GetSwapInterval(_THIS)
+{
+ /* STUB */
+ return 0;
+}
+
+int
+NACL_GLES_SwapWindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ struct PP_CompletionCallback callback = { NULL, 0, PP_COMPLETIONCALLBACK_FLAG_NONE };
+ if (driverdata->ppb_graphics->SwapBuffers((PP_Resource) SDL_GL_GetCurrentContext(), callback ) != 0) {
+ return SDL_SetError("SwapBuffers failed");
+ }
+ return 0;
+}
+
+void
+NACL_GLES_DeleteContext(_THIS, SDL_GLContext context)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ driverdata->ppb_core->ReleaseResource((PP_Resource) context);
+}
+
+#endif /* SDL_VIDEO_DRIVER_NACL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.h b/source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.h
new file mode 100644
index 0000000..744c0e5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclopengles.h
@@ -0,0 +1,38 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_naclopengles_h_
+#define SDL_naclopengles_h_
+
+extern int NACL_GLES_LoadLibrary(_THIS, const char *path);
+extern void *NACL_GLES_GetProcAddress(_THIS, const char *proc);
+extern void NACL_GLES_UnloadLibrary(_THIS);
+extern SDL_GLContext NACL_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern int NACL_GLES_SetSwapInterval(_THIS, int interval);
+extern int NACL_GLES_GetSwapInterval(_THIS);
+extern int NACL_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern void NACL_GLES_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* SDL_naclopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.c b/source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.c
new file mode 100644
index 0000000..24dda2c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.c
@@ -0,0 +1,183 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_NACL
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi_simple/ps.h"
+#include "ppapi_simple/ps_interface.h"
+#include "ppapi_simple/ps_event.h"
+#include "nacl_io/nacl_io.h"
+
+#include "SDL_naclvideo.h"
+#include "SDL_naclwindow.h"
+#include "SDL_naclevents_c.h"
+#include "SDL_naclopengles.h"
+#include "SDL_video.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+
+#define NACLVID_DRIVER_NAME "nacl"
+
+/* Static init required because NACL_SetScreenResolution
+ * may appear even before SDL starts and we want to remember
+ * the window width and height
+ */
+static SDL_VideoData nacl = {0};
+
+void
+NACL_SetScreenResolution(int width, int height, Uint32 format)
+{
+ PP_Resource context;
+
+ nacl.w = width;
+ nacl.h = height;
+ nacl.format = format;
+
+ if (nacl.window) {
+ nacl.window->w = width;
+ nacl.window->h = height;
+ SDL_SendWindowEvent(nacl.window, SDL_WINDOWEVENT_RESIZED, width, height);
+ }
+
+ /* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
+ context = (PP_Resource) SDL_GL_GetCurrentContext();
+ if (context) {
+ PSInterfaceGraphics3D()->ResizeBuffers(context, width, height);
+ }
+
+}
+
+
+
+/* Initialization/Query functions */
+static int NACL_VideoInit(_THIS);
+static void NACL_VideoQuit(_THIS);
+
+static int NACL_Available(void) {
+ return PSGetInstanceId() != 0;
+}
+
+static void NACL_DeleteDevice(SDL_VideoDevice *device) {
+ SDL_VideoData *driverdata = (SDL_VideoData*) device->driverdata;
+ driverdata->ppb_core->ReleaseResource((PP_Resource) driverdata->ppb_message_loop);
+ /* device->driverdata is not freed because it points to static memory */
+ SDL_free(device);
+}
+
+static int
+NACL_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+static SDL_VideoDevice *NACL_CreateDevice(int devindex) {
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ device->driverdata = &nacl;
+
+ /* Set the function pointers */
+ device->VideoInit = NACL_VideoInit;
+ device->VideoQuit = NACL_VideoQuit;
+ device->PumpEvents = NACL_PumpEvents;
+
+ device->CreateSDLWindow = NACL_CreateWindow;
+ device->SetWindowTitle = NACL_SetWindowTitle;
+ device->DestroyWindow = NACL_DestroyWindow;
+
+ device->SetDisplayMode = NACL_SetDisplayMode;
+
+ device->free = NACL_DeleteDevice;
+
+ /* GL pointers */
+ device->GL_LoadLibrary = NACL_GLES_LoadLibrary;
+ device->GL_GetProcAddress = NACL_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = NACL_GLES_UnloadLibrary;
+ device->GL_CreateContext = NACL_GLES_CreateContext;
+ device->GL_MakeCurrent = NACL_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = NACL_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = NACL_GLES_GetSwapInterval;
+ device->GL_SwapWindow = NACL_GLES_SwapWindow;
+ device->GL_DeleteContext = NACL_GLES_DeleteContext;
+
+
+ return device;
+}
+
+VideoBootStrap NACL_bootstrap = {
+ NACLVID_DRIVER_NAME, "SDL Native Client Video Driver",
+ NACL_Available, NACL_CreateDevice
+};
+
+int NACL_VideoInit(_THIS) {
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ SDL_DisplayMode mode;
+
+ SDL_zero(mode);
+ mode.format = driverdata->format;
+ mode.w = driverdata->w;
+ mode.h = driverdata->h;
+ mode.refresh_rate = 0;
+ mode.driverdata = NULL;
+ if (SDL_AddBasicVideoDisplay(&mode) < 0) {
+ return -1;
+ }
+
+ SDL_AddDisplayMode(&_this->displays[0], &mode);
+
+ PSInterfaceInit();
+ driverdata->instance = PSGetInstanceId();
+ driverdata->ppb_graphics = PSInterfaceGraphics3D();
+ driverdata->ppb_message_loop = PSInterfaceMessageLoop();
+ driverdata->ppb_core = PSInterfaceCore();
+ driverdata->ppb_fullscreen = PSInterfaceFullscreen();
+ driverdata->ppb_instance = PSInterfaceInstance();
+ driverdata->ppb_image_data = PSInterfaceImageData();
+ driverdata->ppb_view = PSInterfaceView();
+ driverdata->ppb_var = PSInterfaceVar();
+ driverdata->ppb_input_event = (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
+ driverdata->ppb_keyboard_input_event = (PPB_KeyboardInputEvent*) PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
+ driverdata->ppb_mouse_input_event = (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
+ driverdata->ppb_wheel_input_event = (PPB_WheelInputEvent*) PSGetInterface(PPB_WHEEL_INPUT_EVENT_INTERFACE);
+ driverdata->ppb_touch_input_event = (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
+
+
+ driverdata->message_loop = driverdata->ppb_message_loop->Create(driverdata->instance);
+
+ PSEventSetFilter(PSE_ALL);
+
+ /* We're done! */
+ return 0;
+}
+
+void NACL_VideoQuit(_THIS) {
+}
+
+#endif /* SDL_VIDEO_DRIVER_NACL */
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.h b/source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.h
new file mode 100644
index 0000000..6986aa8
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclvideo.h
@@ -0,0 +1,67 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_naclvideo_h_
+#define SDL_naclvideo_h_
+
+#include "../SDL_sysvideo.h"
+#include "ppapi_simple/ps_interface.h"
+#include "ppapi/c/pp_input_event.h"
+
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *_this
+
+
+/* Private display data */
+
+typedef struct SDL_VideoData {
+ Uint32 format;
+ int w, h;
+ SDL_Window *window;
+
+ const PPB_Graphics3D *ppb_graphics;
+ const PPB_MessageLoop *ppb_message_loop;
+ const PPB_Core *ppb_core;
+ const PPB_Fullscreen *ppb_fullscreen;
+ const PPB_Instance *ppb_instance;
+ const PPB_ImageData *ppb_image_data;
+ const PPB_View *ppb_view;
+ const PPB_Var *ppb_var;
+ const PPB_InputEvent *ppb_input_event;
+ const PPB_KeyboardInputEvent *ppb_keyboard_input_event;
+ const PPB_MouseInputEvent *ppb_mouse_input_event;
+ const PPB_WheelInputEvent *ppb_wheel_input_event;
+ const PPB_TouchInputEvent *ppb_touch_input_event;
+
+ PP_Resource message_loop;
+ PP_Instance instance;
+
+ /* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
+ /* PP_Resource context; */
+
+} SDL_VideoData;
+
+extern void NACL_SetScreenResolution(int width, int height, Uint32 format);
+
+
+#endif /* SDL_naclvideo_h_ */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.c b/source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.c
new file mode 100644
index 0000000..7193331
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.c
@@ -0,0 +1,79 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_NACL
+
+#include "../SDL_sysvideo.h"
+
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "SDL_naclvideo.h"
+#include "SDL_naclwindow.h"
+
+int
+NACL_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+
+ if (driverdata->window) {
+ SDL_SetError("NaCl only supports one window");
+ return -1;
+ }
+ driverdata->window = window;
+
+ /* Adjust the window data to match the screen */
+ window->x = 0;
+ window->y = 0;
+ window->w = driverdata->w;
+ window->h = driverdata->h;
+
+ window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */
+ window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */
+ window->flags &= ~SDL_WINDOW_HIDDEN;
+ window->flags |= SDL_WINDOW_SHOWN; /* only one window on NaCl */
+ window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
+ window->flags |= SDL_WINDOW_OPENGL;
+
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+
+ return 0;
+}
+
+void
+NACL_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ /* TODO */
+}
+
+void
+NACL_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
+ if (window == driverdata->window) {
+ driverdata->window = NULL;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_NACL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.h b/source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.h
new file mode 100644
index 0000000..412b15f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/nacl/SDL_naclwindow.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_naclwindow_h_
+#define SDL_naclwindow_h_
+
+extern int NACL_CreateWindow(_THIS, SDL_Window * window);
+extern void NACL_SetWindowTitle(_THIS, SDL_Window * window);
+extern void NACL_DestroyWindow(_THIS, SDL_Window * window);
+
+#endif /* SDL_naclwindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/pandora/SDL_pandora.c b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora.c
new file mode 100644
index 0000000..b319b16
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora.c
@@ -0,0 +1,838 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_PANDORA
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_version.h"
+#include "SDL_syswm.h"
+#include "SDL_loadso.h"
+#include "SDL_events.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+
+/* PND declarations */
+#include "SDL_pandora.h"
+#include "SDL_pandora_events.h"
+
+/* WIZ declarations */
+#include "GLES/gl.h"
+#ifdef WIZ_GLES_LITE
+static NativeWindowType hNativeWnd = 0; /* A handle to the window we will create. */
+#endif
+
+static int
+PND_available(void)
+{
+ return 1;
+}
+
+static void
+PND_destroy(SDL_VideoDevice * device)
+{
+ if (device->driverdata != NULL) {
+ SDL_free(device->driverdata);
+ device->driverdata = NULL;
+ }
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+PND_create()
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *phdata;
+ int status;
+
+ /* Check if pandora could be initialized */
+ status = PND_available();
+ if (status == 0) {
+ /* PND could not be used */
+ return NULL;
+ }
+
+ /* Initialize SDL_VideoDevice structure */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Initialize internal Pandora specific data */
+ phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (phdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return NULL;
+ }
+
+ device->driverdata = phdata;
+
+ phdata->egl_initialized = SDL_TRUE;
+
+
+ /* Setup amount of available displays */
+ device->num_displays = 0;
+
+ /* Set device free function */
+ device->free = PND_destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit = PND_videoinit;
+ device->VideoQuit = PND_videoquit;
+ device->GetDisplayModes = PND_getdisplaymodes;
+ device->SetDisplayMode = PND_setdisplaymode;
+ device->CreateSDLWindow = PND_createwindow;
+ device->CreateSDLWindowFrom = PND_createwindowfrom;
+ device->SetWindowTitle = PND_setwindowtitle;
+ device->SetWindowIcon = PND_setwindowicon;
+ device->SetWindowPosition = PND_setwindowposition;
+ device->SetWindowSize = PND_setwindowsize;
+ device->ShowWindow = PND_showwindow;
+ device->HideWindow = PND_hidewindow;
+ device->RaiseWindow = PND_raisewindow;
+ device->MaximizeWindow = PND_maximizewindow;
+ device->MinimizeWindow = PND_minimizewindow;
+ device->RestoreWindow = PND_restorewindow;
+ device->SetWindowGrab = PND_setwindowgrab;
+ device->DestroyWindow = PND_destroywindow;
+#if 0
+ device->GetWindowWMInfo = PND_getwindowwminfo;
+#endif
+ device->GL_LoadLibrary = PND_gl_loadlibrary;
+ device->GL_GetProcAddress = PND_gl_getprocaddres;
+ device->GL_UnloadLibrary = PND_gl_unloadlibrary;
+ device->GL_CreateContext = PND_gl_createcontext;
+ device->GL_MakeCurrent = PND_gl_makecurrent;
+ device->GL_SetSwapInterval = PND_gl_setswapinterval;
+ device->GL_GetSwapInterval = PND_gl_getswapinterval;
+ device->GL_SwapWindow = PND_gl_swapwindow;
+ device->GL_DeleteContext = PND_gl_deletecontext;
+ device->PumpEvents = PND_PumpEvents;
+
+ /* !!! FIXME: implement SetWindowBordered */
+
+ return device;
+}
+
+VideoBootStrap PND_bootstrap = {
+#ifdef WIZ_GLES_LITE
+ "wiz",
+ "SDL Wiz Video Driver",
+#else
+ "pandora",
+ "SDL Pandora Video Driver",
+#endif
+ PND_available,
+ PND_create
+};
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions */
+/*****************************************************************************/
+int
+PND_videoinit(_THIS)
+{
+ SDL_VideoDisplay display;
+ SDL_DisplayMode current_mode;
+
+ SDL_zero(current_mode);
+#ifdef WIZ_GLES_LITE
+ current_mode.w = 320;
+ current_mode.h = 240;
+#else
+ current_mode.w = 800;
+ current_mode.h = 480;
+#endif
+ current_mode.refresh_rate = 60;
+ current_mode.format = SDL_PIXELFORMAT_RGB565;
+ current_mode.driverdata = NULL;
+
+ SDL_zero(display);
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+ display.driverdata = NULL;
+
+ SDL_AddVideoDisplay(&display);
+
+ return 1;
+}
+
+void
+PND_videoquit(_THIS)
+{
+
+}
+
+void
+PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display)
+{
+
+}
+
+int
+PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+int
+PND_createwindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+
+ SDL_WindowData *wdata;
+
+ /* Allocate window internal data */
+ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (wdata == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Setup driver data for this window */
+ window->driverdata = wdata;
+
+ /* Check if window must support OpenGL ES rendering */
+ if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
+
+ EGLBoolean initstatus;
+
+ /* Mark this window as OpenGL ES compatible */
+ wdata->uses_gles = SDL_TRUE;
+
+ /* Create connection to OpenGL ES */
+ if (phdata->egl_display == EGL_NO_DISPLAY) {
+ phdata->egl_display = eglGetDisplay((NativeDisplayType) 0);
+ if (phdata->egl_display == EGL_NO_DISPLAY) {
+ return SDL_SetError("PND: Can't get connection to OpenGL ES");
+ }
+
+ initstatus = eglInitialize(phdata->egl_display, NULL, NULL);
+ if (initstatus != EGL_TRUE) {
+ return SDL_SetError("PND: Can't init OpenGL ES library");
+ }
+ }
+
+ phdata->egl_refcount++;
+ }
+
+ /* Window has been successfully created */
+ return 0;
+}
+
+int
+PND_createwindowfrom(_THIS, SDL_Window * window, const void *data)
+{
+ return -1;
+}
+
+void
+PND_setwindowtitle(_THIS, SDL_Window * window)
+{
+}
+void
+PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+}
+void
+PND_setwindowposition(_THIS, SDL_Window * window)
+{
+}
+void
+PND_setwindowsize(_THIS, SDL_Window * window)
+{
+}
+void
+PND_showwindow(_THIS, SDL_Window * window)
+{
+}
+void
+PND_hidewindow(_THIS, SDL_Window * window)
+{
+}
+void
+PND_raisewindow(_THIS, SDL_Window * window)
+{
+}
+void
+PND_maximizewindow(_THIS, SDL_Window * window)
+{
+}
+void
+PND_minimizewindow(_THIS, SDL_Window * window)
+{
+}
+void
+PND_restorewindow(_THIS, SDL_Window * window)
+{
+}
+void
+PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+}
+void
+PND_destroywindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ eglTerminate(phdata->egl_display);
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function */
+/*****************************************************************************/
+#if 0
+SDL_bool
+PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+
+ /* Failed to get window manager information */
+ return SDL_FALSE;
+}
+#endif
+
+/*****************************************************************************/
+/* SDL OpenGL/OpenGL ES functions */
+/*****************************************************************************/
+int
+PND_gl_loadlibrary(_THIS, const char *path)
+{
+ /* Check if OpenGL ES library is specified for GF driver */
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGLES_LIBRARY");
+ }
+ }
+
+ /* Check if default library loading requested */
+ if (path == NULL) {
+ /* Already linked with GF library which provides egl* subset of */
+ /* functions, use Common profile of OpenGL ES library by default */
+#ifdef WIZ_GLES_LITE
+ path = "/lib/libopengles_lite.so";
+#else
+ path = "/usr/lib/libGLES_CM.so";
+#endif
+ }
+
+ /* Load dynamic library */
+ _this->gl_config.dll_handle = SDL_LoadObject(path);
+ if (!_this->gl_config.dll_handle) {
+ /* Failed to load new GL ES library */
+ return SDL_SetError("PND: Failed to locate OpenGL ES library");
+ }
+
+ /* Store OpenGL ES library path and name */
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+
+ /* New OpenGL ES library is loaded */
+ return 0;
+}
+
+void *
+PND_gl_getprocaddres(_THIS, const char *proc)
+{
+ void *function_address;
+
+ /* Try to get function address through the egl interface */
+ function_address = eglGetProcAddress(proc);
+ if (function_address != NULL) {
+ return function_address;
+ }
+
+ /* Then try to get function in the OpenGL ES library */
+ if (_this->gl_config.dll_handle) {
+ function_address =
+ SDL_LoadFunction(_this->gl_config.dll_handle, proc);
+ if (function_address != NULL) {
+ return function_address;
+ }
+ }
+
+ /* Failed to get GL ES function address pointer */
+ SDL_SetError("PND: Cannot locate OpenGL ES function name");
+ return NULL;
+}
+
+void
+PND_gl_unloadlibrary(_THIS)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+
+ if (phdata->egl_initialized == SDL_TRUE) {
+ /* Unload OpenGL ES library */
+ if (_this->gl_config.dll_handle) {
+ SDL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+ }
+ } else {
+ SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
+ }
+}
+
+SDL_GLContext
+PND_gl_createcontext(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
+ EGLBoolean status;
+ EGLint configs;
+ uint32_t attr_pos;
+ EGLint attr_value;
+ EGLint cit;
+
+ /* Check if EGL was initialized */
+ if (phdata->egl_initialized != SDL_TRUE) {
+ SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
+ return NULL;
+ }
+
+ /* Prepare attributes list to pass them to OpenGL ES */
+ attr_pos = 0;
+ wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
+ wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
+ wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.red_size;
+ wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.green_size;
+ wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.blue_size;
+ wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
+
+ /* Setup alpha size in bits */
+ if (_this->gl_config.alpha_size) {
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.alpha_size;
+ } else {
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ }
+
+ /* Setup color buffer size */
+ if (_this->gl_config.buffer_size) {
+ wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
+ } else {
+ wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ }
+
+ /* Setup depth buffer bits */
+ wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.depth_size;
+
+ /* Setup stencil bits */
+ if (_this->gl_config.stencil_size) {
+ wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
+ } else {
+ wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ }
+
+ /* Set number of samples in multisampling */
+ if (_this->gl_config.multisamplesamples) {
+ wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
+ wdata->gles_attributes[attr_pos++] =
+ _this->gl_config.multisamplesamples;
+ }
+
+ /* Multisample buffers, OpenGL ES 1.0 spec defines 0 or 1 buffer */
+ if (_this->gl_config.multisamplebuffers) {
+ wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
+ wdata->gles_attributes[attr_pos++] =
+ _this->gl_config.multisamplebuffers;
+ }
+
+ /* Finish attributes list */
+ wdata->gles_attributes[attr_pos] = EGL_NONE;
+
+ /* Request first suitable framebuffer configuration */
+ status = eglChooseConfig(phdata->egl_display, wdata->gles_attributes,
+ wdata->gles_configs, 1, &configs);
+ if (status != EGL_TRUE) {
+ SDL_SetError("PND: Can't find closest configuration for OpenGL ES");
+ return NULL;
+ }
+
+ /* Check if nothing has been found, try "don't care" settings */
+ if (configs == 0) {
+ int32_t it;
+ int32_t jt;
+ GLint depthbits[4] = { 32, 24, 16, EGL_DONT_CARE };
+
+ for (it = 0; it < 4; it++) {
+ for (jt = 16; jt >= 0; jt--) {
+ /* Don't care about color buffer bits, use what exist */
+ /* Replace previous set data with EGL_DONT_CARE */
+ attr_pos = 0;
+ wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
+ wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
+ wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+
+ /* Try to find requested or smallest depth */
+ if (_this->gl_config.depth_size) {
+ wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
+ wdata->gles_attributes[attr_pos++] = depthbits[it];
+ } else {
+ wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ }
+
+ if (_this->gl_config.stencil_size) {
+ wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++] = jt;
+ } else {
+ wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ }
+
+ wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
+ wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
+ wdata->gles_attributes[attr_pos] = EGL_NONE;
+
+ /* Request first suitable framebuffer configuration */
+ status =
+ eglChooseConfig(phdata->egl_display,
+ wdata->gles_attributes,
+ wdata->gles_configs, 1, &configs);
+
+ if (status != EGL_TRUE) {
+ SDL_SetError
+ ("PND: Can't find closest configuration for OpenGL ES");
+ return NULL;
+ }
+ if (configs != 0) {
+ break;
+ }
+ }
+ if (configs != 0) {
+ break;
+ }
+ }
+
+ /* No available configs */
+ if (configs == 0) {
+ SDL_SetError("PND: Can't find any configuration for OpenGL ES");
+ return NULL;
+ }
+ }
+
+ /* Initialize config index */
+ wdata->gles_config = 0;
+
+ /* Now check each configuration to find out the best */
+ for (cit = 0; cit < configs; cit++) {
+ uint32_t stencil_found;
+ uint32_t depth_found;
+
+ stencil_found = 0;
+ depth_found = 0;
+
+ if (_this->gl_config.stencil_size) {
+ status =
+ eglGetConfigAttrib(phdata->egl_display,
+ wdata->gles_configs[cit], EGL_STENCIL_SIZE,
+ &attr_value);
+ if (status == EGL_TRUE) {
+ if (attr_value != 0) {
+ stencil_found = 1;
+ }
+ }
+ } else {
+ stencil_found = 1;
+ }
+
+ if (_this->gl_config.depth_size) {
+ status =
+ eglGetConfigAttrib(phdata->egl_display,
+ wdata->gles_configs[cit], EGL_DEPTH_SIZE,
+ &attr_value);
+ if (status == EGL_TRUE) {
+ if (attr_value != 0) {
+ depth_found = 1;
+ }
+ }
+ } else {
+ depth_found = 1;
+ }
+
+ /* Exit from loop if found appropriate configuration */
+ if ((depth_found != 0) && (stencil_found != 0)) {
+ break;
+ }
+ }
+
+ /* If best could not be found, use first */
+ if (cit == configs) {
+ cit = 0;
+ }
+ wdata->gles_config = cit;
+
+ /* Create OpenGL ES context */
+ wdata->gles_context =
+ eglCreateContext(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config], NULL, NULL);
+ if (wdata->gles_context == EGL_NO_CONTEXT) {
+ SDL_SetError("PND: OpenGL ES context creation has been failed");
+ return NULL;
+ }
+
+#ifdef WIZ_GLES_LITE
+ if( !hNativeWnd ) {
+ hNativeWnd = (NativeWindowType)malloc(16*1024);
+
+ if(!hNativeWnd)
+ printf( "Error: Wiz framebuffer allocatation failed\n" );
+ else
+ printf( "SDL: Wiz framebuffer allocated: %X\n", hNativeWnd );
+ }
+ else {
+ printf( "SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd );
+ }
+
+ wdata->gles_surface =
+ eglCreateWindowSurface(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config],
+ hNativeWnd, NULL );
+#else
+ wdata->gles_surface =
+ eglCreateWindowSurface(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config],
+ (NativeWindowType) 0, NULL);
+#endif
+
+
+ if (wdata->gles_surface == 0) {
+ SDL_SetError("Error : eglCreateWindowSurface failed;");
+ return NULL;
+ }
+
+ /* Make just created context current */
+ status =
+ eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
+ wdata->gles_surface, wdata->gles_context);
+ if (status != EGL_TRUE) {
+ /* Destroy OpenGL ES surface */
+ eglDestroySurface(phdata->egl_display, wdata->gles_surface);
+ eglDestroyContext(phdata->egl_display, wdata->gles_context);
+ wdata->gles_context = EGL_NO_CONTEXT;
+ SDL_SetError("PND: Can't set OpenGL ES context on creation");
+ return NULL;
+ }
+
+ _this->gl_config.accelerated = 1;
+
+ /* Always clear stereo enable, since OpenGL ES do not supports stereo */
+ _this->gl_config.stereo = 0;
+
+ /* Get back samples and samplebuffers configurations. Rest framebuffer */
+ /* parameters could be obtained through the OpenGL ES API */
+ status =
+ eglGetConfigAttrib(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config],
+ EGL_SAMPLES, &attr_value);
+ if (status == EGL_TRUE) {
+ _this->gl_config.multisamplesamples = attr_value;
+ }
+ status =
+ eglGetConfigAttrib(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config],
+ EGL_SAMPLE_BUFFERS, &attr_value);
+ if (status == EGL_TRUE) {
+ _this->gl_config.multisamplebuffers = attr_value;
+ }
+
+ /* Get back stencil and depth buffer sizes */
+ status =
+ eglGetConfigAttrib(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config],
+ EGL_DEPTH_SIZE, &attr_value);
+ if (status == EGL_TRUE) {
+ _this->gl_config.depth_size = attr_value;
+ }
+ status =
+ eglGetConfigAttrib(phdata->egl_display,
+ wdata->gles_configs[wdata->gles_config],
+ EGL_STENCIL_SIZE, &attr_value);
+ if (status == EGL_TRUE) {
+ _this->gl_config.stencil_size = attr_value;
+ }
+
+ /* Under PND OpenGL ES output can't be double buffered */
+ _this->gl_config.double_buffer = 0;
+
+ /* GL ES context was successfully created */
+ return wdata->gles_context;
+}
+
+int
+PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *wdata;
+ EGLBoolean status;
+
+ if (phdata->egl_initialized != SDL_TRUE) {
+ return SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
+ }
+
+ if ((window == NULL) && (context == NULL)) {
+ status =
+ eglMakeCurrent(phdata->egl_display, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (status != EGL_TRUE) {
+ /* Failed to set current GL ES context */
+ return SDL_SetError("PND: Can't set OpenGL ES context");
+ }
+ } else {
+ wdata = (SDL_WindowData *) window->driverdata;
+ if (wdata->gles_surface == EGL_NO_SURFACE) {
+ return SDL_SetError
+ ("PND: OpenGL ES surface is not initialized for this window");
+ }
+ if (wdata->gles_context == EGL_NO_CONTEXT) {
+ return SDL_SetError
+ ("PND: OpenGL ES context is not initialized for this window");
+ }
+ if (wdata->gles_context != context) {
+ return SDL_SetError
+ ("PND: OpenGL ES context is not belong to this window");
+ }
+ status =
+ eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
+ wdata->gles_surface, wdata->gles_context);
+ if (status != EGL_TRUE) {
+ /* Failed to set current GL ES context */
+ return SDL_SetError("PND: Can't set OpenGL ES context");
+ }
+ }
+ return 0;
+}
+
+int
+PND_gl_setswapinterval(_THIS, int interval)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ EGLBoolean status;
+
+ if (phdata->egl_initialized != SDL_TRUE) {
+ return SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
+ }
+
+ /* Check if OpenGL ES connection has been initialized */
+ if (phdata->egl_display != EGL_NO_DISPLAY) {
+ /* Set swap OpenGL ES interval */
+ status = eglSwapInterval(phdata->egl_display, interval);
+ if (status == EGL_TRUE) {
+ /* Return success to upper level */
+ phdata->swapinterval = interval;
+ return 0;
+ }
+ }
+
+ /* Failed to set swap interval */
+ return SDL_SetError("PND: Cannot set swap interval");
+}
+
+int
+PND_gl_getswapinterval(_THIS)
+{
+ return ((SDL_VideoData *) _this->driverdata)->swapinterval;
+}
+
+int
+PND_gl_swapwindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
+
+ if (phdata->egl_initialized != SDL_TRUE) {
+ return SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
+ }
+
+ /* Many applications do not uses glFinish(), so we call it for them */
+ glFinish();
+
+ /* Wait until OpenGL ES rendering is completed */
+ eglWaitGL();
+
+ eglSwapBuffers(phdata->egl_display, wdata->gles_surface);
+ return 0;
+}
+
+void
+PND_gl_deletecontext(_THIS, SDL_GLContext context)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ EGLBoolean status;
+
+ if (phdata->egl_initialized != SDL_TRUE) {
+ SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
+ return;
+ }
+
+ /* Check if OpenGL ES connection has been initialized */
+ if (phdata->egl_display != EGL_NO_DISPLAY) {
+ if (context != EGL_NO_CONTEXT) {
+ status = eglDestroyContext(phdata->egl_display, context);
+ if (status != EGL_TRUE) {
+ /* Error during OpenGL ES context destroying */
+ SDL_SetError("PND: OpenGL ES context destroy error");
+ return;
+ }
+ }
+ }
+
+#ifdef WIZ_GLES_LITE
+ if( hNativeWnd != 0 )
+ {
+ free(hNativeWnd);
+ hNativeWnd = 0;
+ printf( "SDL: Wiz framebuffer released\n" );
+ }
+#endif
+
+ return;
+}
+
+#endif /* SDL_VIDEO_DRIVER_PANDORA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/pandora/SDL_pandora.h b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora.h
new file mode 100644
index 0000000..9e460e7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora.h
@@ -0,0 +1,101 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __SDL_PANDORA_H__
+#define __SDL_PANDORA_H__
+
+#include <GLES/egl.h>
+
+#include "../../SDL_internal.h"
+#include "../SDL_sysvideo.h"
+
+typedef struct SDL_VideoData
+{
+ SDL_bool egl_initialized; /* OpenGL ES device initialization status */
+ EGLDisplay egl_display; /* OpenGL ES display connection */
+ uint32_t egl_refcount; /* OpenGL ES reference count */
+ uint32_t swapinterval; /* OpenGL ES default swap interval */
+
+} SDL_VideoData;
+
+
+typedef struct SDL_DisplayData
+{
+
+} SDL_DisplayData;
+
+
+typedef struct SDL_WindowData
+{
+ SDL_bool uses_gles; /* if true window must support OpenGL ES */
+
+ EGLConfig gles_configs[32];
+ EGLint gles_config; /* OpenGL ES configuration index */
+ EGLContext gles_context; /* OpenGL ES context */
+ EGLint gles_attributes[256]; /* OpenGL ES attributes for context */
+ EGLSurface gles_surface; /* OpenGL ES target rendering surface */
+
+} SDL_WindowData;
+
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration */
+/****************************************************************************/
+
+/* Display and window functions */
+int PND_videoinit(_THIS);
+void PND_videoquit(_THIS);
+void PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display);
+int PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int PND_createwindow(_THIS, SDL_Window * window);
+int PND_createwindowfrom(_THIS, SDL_Window * window, const void *data);
+void PND_setwindowtitle(_THIS, SDL_Window * window);
+void PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon);
+void PND_setwindowposition(_THIS, SDL_Window * window);
+void PND_setwindowsize(_THIS, SDL_Window * window);
+void PND_showwindow(_THIS, SDL_Window * window);
+void PND_hidewindow(_THIS, SDL_Window * window);
+void PND_raisewindow(_THIS, SDL_Window * window);
+void PND_maximizewindow(_THIS, SDL_Window * window);
+void PND_minimizewindow(_THIS, SDL_Window * window);
+void PND_restorewindow(_THIS, SDL_Window * window);
+void PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+void PND_destroywindow(_THIS, SDL_Window * window);
+
+/* Window manager function */
+SDL_bool PND_getwindowwminfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+/* OpenGL/OpenGL ES functions */
+int PND_gl_loadlibrary(_THIS, const char *path);
+void *PND_gl_getprocaddres(_THIS, const char *proc);
+void PND_gl_unloadlibrary(_THIS);
+SDL_GLContext PND_gl_createcontext(_THIS, SDL_Window * window);
+int PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int PND_gl_setswapinterval(_THIS, int interval);
+int PND_gl_getswapinterval(_THIS);
+int PND_gl_swapwindow(_THIS, SDL_Window * window);
+void PND_gl_deletecontext(_THIS, SDL_GLContext context);
+
+
+#endif /* __SDL_PANDORA_H__ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.c b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.c
new file mode 100644
index 0000000..bff7a36
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.c
@@ -0,0 +1,38 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_PANDORA
+
+/* Being a null driver, there's no event stream. We just define stubs for
+ most of the API. */
+
+#include "../../events/SDL_events_c.h"
+
+void
+PND_PumpEvents(_THIS)
+{
+ /* Not implemented. */
+}
+
+#endif /* SDL_VIDEO_DRIVER_PANDORA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.h b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.h
new file mode 100644
index 0000000..f714384
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/pandora/SDL_pandora_events.h
@@ -0,0 +1,25 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+extern void PND_PumpEvents(_THIS);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspevents.c b/source/3rd-party/SDL2/src/video/psp/SDL_pspevents.c
new file mode 100644
index 0000000..14277b3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspevents.c
@@ -0,0 +1,290 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_PSP
+
+/* Being a null driver, there's no event stream. We just define stubs for
+ most of the API. */
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "SDL_pspvideo.h"
+#include "SDL_pspevents_c.h"
+#include "SDL_keyboard.h"
+#include "../../thread/SDL_systhread.h"
+#include <psphprm.h>
+
+#ifdef PSPIRKEYB
+#include <pspirkeyb.h>
+#include <pspirkeyb_rawkeys.h>
+
+#define IRKBD_CONFIG_FILE NULL /* this will take ms0:/seplugins/pspirkeyb.ini */
+
+static int irkbd_ready = 0;
+static SDL_Keycode keymap[256];
+#endif
+
+static enum PspHprmKeys hprm = 0;
+static SDL_sem *event_sem = NULL;
+static SDL_Thread *thread = NULL;
+static int running = 0;
+static struct {
+ enum PspHprmKeys id;
+ SDL_Keycode sym;
+} keymap_psp[] = {
+ { PSP_HPRM_PLAYPAUSE, SDLK_F10 },
+ { PSP_HPRM_FORWARD, SDLK_F11 },
+ { PSP_HPRM_BACK, SDLK_F12 },
+ { PSP_HPRM_VOL_UP, SDLK_F13 },
+ { PSP_HPRM_VOL_DOWN, SDLK_F14 },
+ { PSP_HPRM_HOLD, SDLK_F15 }
+};
+
+int EventUpdate(void *data)
+{
+ while (running) {
+ SDL_SemWait(event_sem);
+ sceHprmPeekCurrentKey(&hprm);
+ SDL_SemPost(event_sem);
+ /* Delay 1/60th of a second */
+ sceKernelDelayThread(1000000 / 60);
+ }
+ return 0;
+}
+
+void PSP_PumpEvents(_THIS)
+{
+ int i;
+ enum PspHprmKeys keys;
+ enum PspHprmKeys changed;
+ static enum PspHprmKeys old_keys = 0;
+ SDL_Keysym sym;
+
+ SDL_SemWait(event_sem);
+ keys = hprm;
+ SDL_SemPost(event_sem);
+
+ /* HPRM Keyboard */
+ changed = old_keys ^ keys;
+ old_keys = keys;
+ if(changed) {
+ for(i=0; i<sizeof(keymap_psp)/sizeof(keymap_psp[0]); i++) {
+ if(changed & keymap_psp[i].id) {
+ sym.scancode = keymap_psp[i].id;
+ sym.sym = keymap_psp[i].sym;
+
+ /* out of date
+ SDL_PrivateKeyboard((keys & keymap_psp[i].id) ?
+ SDL_PRESSED : SDL_RELEASED,
+ &sym);
+ */
+ SDL_SendKeyboardKey((keys & keymap_psp[i].id) ?
+ SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap_psp[i].sym));
+ }
+ }
+ }
+
+#ifdef PSPIRKEYB
+ if (irkbd_ready) {
+ unsigned char buffer[255];
+ int i, length, count;
+ SIrKeybScanCodeData *scanData;
+
+ if(pspIrKeybReadinput(buffer, &length) >= 0) {
+ if((length % sizeof(SIrKeybScanCodeData)) == 0){
+ count = length / sizeof(SIrKeybScanCodeData);
+ for( i=0; i < count; i++ ) {
+ unsigned char raw, pressed;
+ scanData=(SIrKeybScanCodeData*) buffer+i;
+ raw = scanData->raw;
+ pressed = scanData->pressed;
+ sym.scancode = raw;
+ sym.sym = keymap[raw];
+ /* not tested */
+ /* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */
+ SDL_SendKeyboardKey((keys & keymap_psp[i].id) ?
+ SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw]));
+
+ }
+ }
+ }
+ }
+#endif
+ sceKernelDelayThread(0);
+
+ return;
+}
+
+void PSP_InitOSKeymap(_THIS)
+{
+#ifdef PSPIRKEYB
+ int i;
+ for (i=0; i<SDL_TABLESIZE(keymap); ++i)
+ keymap[i] = SDLK_UNKNOWN;
+
+ keymap[KEY_ESC] = SDLK_ESCAPE;
+
+ keymap[KEY_F1] = SDLK_F1;
+ keymap[KEY_F2] = SDLK_F2;
+ keymap[KEY_F3] = SDLK_F3;
+ keymap[KEY_F4] = SDLK_F4;
+ keymap[KEY_F5] = SDLK_F5;
+ keymap[KEY_F6] = SDLK_F6;
+ keymap[KEY_F7] = SDLK_F7;
+ keymap[KEY_F8] = SDLK_F8;
+ keymap[KEY_F9] = SDLK_F9;
+ keymap[KEY_F10] = SDLK_F10;
+ keymap[KEY_F11] = SDLK_F11;
+ keymap[KEY_F12] = SDLK_F12;
+ keymap[KEY_F13] = SDLK_PRINT;
+ keymap[KEY_F14] = SDLK_PAUSE;
+
+ keymap[KEY_GRAVE] = SDLK_BACKQUOTE;
+ keymap[KEY_1] = SDLK_1;
+ keymap[KEY_2] = SDLK_2;
+ keymap[KEY_3] = SDLK_3;
+ keymap[KEY_4] = SDLK_4;
+ keymap[KEY_5] = SDLK_5;
+ keymap[KEY_6] = SDLK_6;
+ keymap[KEY_7] = SDLK_7;
+ keymap[KEY_8] = SDLK_8;
+ keymap[KEY_9] = SDLK_9;
+ keymap[KEY_0] = SDLK_0;
+ keymap[KEY_MINUS] = SDLK_MINUS;
+ keymap[KEY_EQUAL] = SDLK_EQUALS;
+ keymap[KEY_BACKSPACE] = SDLK_BACKSPACE;
+
+ keymap[KEY_TAB] = SDLK_TAB;
+ keymap[KEY_Q] = SDLK_q;
+ keymap[KEY_W] = SDLK_w;
+ keymap[KEY_E] = SDLK_e;
+ keymap[KEY_R] = SDLK_r;
+ keymap[KEY_T] = SDLK_t;
+ keymap[KEY_Y] = SDLK_y;
+ keymap[KEY_U] = SDLK_u;
+ keymap[KEY_I] = SDLK_i;
+ keymap[KEY_O] = SDLK_o;
+ keymap[KEY_P] = SDLK_p;
+ keymap[KEY_LEFTBRACE] = SDLK_LEFTBRACKET;
+ keymap[KEY_RIGHTBRACE] = SDLK_RIGHTBRACKET;
+ keymap[KEY_ENTER] = SDLK_RETURN;
+
+ keymap[KEY_CAPSLOCK] = SDLK_CAPSLOCK;
+ keymap[KEY_A] = SDLK_a;
+ keymap[KEY_S] = SDLK_s;
+ keymap[KEY_D] = SDLK_d;
+ keymap[KEY_F] = SDLK_f;
+ keymap[KEY_G] = SDLK_g;
+ keymap[KEY_H] = SDLK_h;
+ keymap[KEY_J] = SDLK_j;
+ keymap[KEY_K] = SDLK_k;
+ keymap[KEY_L] = SDLK_l;
+ keymap[KEY_SEMICOLON] = SDLK_SEMICOLON;
+ keymap[KEY_APOSTROPHE] = SDLK_QUOTE;
+ keymap[KEY_BACKSLASH] = SDLK_BACKSLASH;
+
+ keymap[KEY_Z] = SDLK_z;
+ keymap[KEY_X] = SDLK_x;
+ keymap[KEY_C] = SDLK_c;
+ keymap[KEY_V] = SDLK_v;
+ keymap[KEY_B] = SDLK_b;
+ keymap[KEY_N] = SDLK_n;
+ keymap[KEY_M] = SDLK_m;
+ keymap[KEY_COMMA] = SDLK_COMMA;
+ keymap[KEY_DOT] = SDLK_PERIOD;
+ keymap[KEY_SLASH] = SDLK_SLASH;
+
+ keymap[KEY_SPACE] = SDLK_SPACE;
+
+ keymap[KEY_UP] = SDLK_UP;
+ keymap[KEY_DOWN] = SDLK_DOWN;
+ keymap[KEY_LEFT] = SDLK_LEFT;
+ keymap[KEY_RIGHT] = SDLK_RIGHT;
+
+ keymap[KEY_HOME] = SDLK_HOME;
+ keymap[KEY_END] = SDLK_END;
+ keymap[KEY_INSERT] = SDLK_INSERT;
+ keymap[KEY_DELETE] = SDLK_DELETE;
+
+ keymap[KEY_NUMLOCK] = SDLK_NUMLOCK;
+ keymap[KEY_LEFTMETA] = SDLK_LSUPER;
+
+ keymap[KEY_KPSLASH] = SDLK_KP_DIVIDE;
+ keymap[KEY_KPASTERISK] = SDLK_KP_MULTIPLY;
+ keymap[KEY_KPMINUS] = SDLK_KP_MINUS;
+ keymap[KEY_KPPLUS] = SDLK_KP_PLUS;
+ keymap[KEY_KPDOT] = SDLK_KP_PERIOD;
+ keymap[KEY_KPEQUAL] = SDLK_KP_EQUALS;
+
+ keymap[KEY_LEFTCTRL] = SDLK_LCTRL;
+ keymap[KEY_RIGHTCTRL] = SDLK_RCTRL;
+ keymap[KEY_LEFTALT] = SDLK_LALT;
+ keymap[KEY_RIGHTALT] = SDLK_RALT;
+ keymap[KEY_LEFTSHIFT] = SDLK_LSHIFT;
+ keymap[KEY_RIGHTSHIFT] = SDLK_RSHIFT;
+#endif
+}
+
+void PSP_EventInit(_THIS)
+{
+#ifdef PSPIRKEYB
+ int outputmode = PSP_IRKBD_OUTPUT_MODE_SCANCODE;
+ int ret = pspIrKeybInit(IRKBD_CONFIG_FILE, 0);
+ if (ret == PSP_IRKBD_RESULT_OK) {
+ pspIrKeybOutputMode(outputmode);
+ irkbd_ready = 1;
+ } else {
+ irkbd_ready = 0;
+ }
+#endif
+ /* Start thread to read data */
+ if((event_sem = SDL_CreateSemaphore(1)) == NULL) {
+ SDL_SetError("Can't create input semaphore");
+ return;
+ }
+ running = 1;
+ if((thread = SDL_CreateThreadInternal(EventUpdate, "PSPInputThread", 4096, NULL)) == NULL) {
+ SDL_SetError("Can't create input thread");
+ return;
+ }
+}
+
+void PSP_EventQuit(_THIS)
+{
+ running = 0;
+ SDL_WaitThread(thread, NULL);
+ SDL_DestroySemaphore(event_sem);
+#ifdef PSPIRKEYB
+ if (irkbd_ready) {
+ pspIrKeybFinish();
+ irkbd_ready = 0;
+ }
+#endif
+}
+
+/* end of SDL_pspevents.c ... */
+
+#endif /* SDL_VIDEO_DRIVER_PSP */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspevents_c.h b/source/3rd-party/SDL2/src/video/psp/SDL_pspevents_c.h
new file mode 100644
index 0000000..e98beb4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspevents_c.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "SDL_pspvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void PSP_InitOSKeymap(_THIS);
+extern void PSP_PumpEvents(_THIS);
+
+/* end of SDL_pspevents_c.h ... */
+
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspgl.c b/source/3rd-party/SDL2/src/video/psp/SDL_pspgl.c
new file mode 100644
index 0000000..644fb34
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspgl.c
@@ -0,0 +1,210 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_PSP
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "SDL_error.h"
+#include "SDL_pspvideo.h"
+#include "SDL_pspgl_c.h"
+
+/*****************************************************************************/
+/* SDL OpenGL/OpenGL ES functions */
+/*****************************************************************************/
+#define EGLCHK(stmt) \
+ do { \
+ EGLint err; \
+ \
+ stmt; \
+ err = eglGetError(); \
+ if (err != EGL_SUCCESS) { \
+ SDL_SetError("EGL error %d", err); \
+ return 0; \
+ } \
+ } while (0)
+
+int
+PSP_GL_LoadLibrary(_THIS, const char *path)
+{
+ return 0;
+}
+
+/* pspgl doesn't provide this call, so stub it out since SDL requires it.
+#define GLSTUB(func,params) void func params {}
+
+GLSTUB(glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar))
+*/
+void *
+PSP_GL_GetProcAddress(_THIS, const char *proc)
+{
+ return eglGetProcAddress(proc);
+}
+
+void
+PSP_GL_UnloadLibrary(_THIS)
+{
+ eglTerminate(_this->gl_data->display);
+}
+
+static EGLint width = 480;
+static EGLint height = 272;
+
+SDL_GLContext
+PSP_GL_CreateContext(_THIS, SDL_Window * window)
+{
+
+ SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
+
+ EGLint attribs[32];
+ EGLDisplay display;
+ EGLContext context;
+ EGLSurface surface;
+ EGLConfig config;
+ EGLint num_configs;
+ int i;
+
+
+ /* EGL init taken from glutCreateWindow() in PSPGL's glut.c. */
+ EGLCHK(display = eglGetDisplay(0));
+ EGLCHK(eglInitialize(display, NULL, NULL));
+ wdata->uses_gles = SDL_TRUE;
+ window->flags |= SDL_WINDOW_FULLSCREEN;
+
+ /* Setup the config based on SDL's current values. */
+ i = 0;
+ attribs[i++] = EGL_RED_SIZE;
+ attribs[i++] = _this->gl_config.red_size;
+ attribs[i++] = EGL_GREEN_SIZE;
+ attribs[i++] = _this->gl_config.green_size;
+ attribs[i++] = EGL_BLUE_SIZE;
+ attribs[i++] = _this->gl_config.blue_size;
+ attribs[i++] = EGL_DEPTH_SIZE;
+ attribs[i++] = _this->gl_config.depth_size;
+
+ if (_this->gl_config.alpha_size)
+ {
+ attribs[i++] = EGL_ALPHA_SIZE;
+ attribs[i++] = _this->gl_config.alpha_size;
+ }
+ if (_this->gl_config.stencil_size)
+ {
+ attribs[i++] = EGL_STENCIL_SIZE;
+ attribs[i++] = _this->gl_config.stencil_size;
+ }
+
+ attribs[i++] = EGL_NONE;
+
+ EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs));
+
+ if (num_configs == 0)
+ {
+ SDL_SetError("No valid EGL configs for requested mode");
+ return 0;
+ }
+
+ EGLCHK(eglGetConfigAttrib(display, config, EGL_WIDTH, &width));
+ EGLCHK(eglGetConfigAttrib(display, config, EGL_HEIGHT, &height));
+
+ EGLCHK(context = eglCreateContext(display, config, NULL, NULL));
+ EGLCHK(surface = eglCreateWindowSurface(display, config, 0, NULL));
+ EGLCHK(eglMakeCurrent(display, surface, surface, context));
+
+ _this->gl_data->display = display;
+ _this->gl_data->context = context;
+ _this->gl_data->surface = surface;
+
+
+ return context;
+}
+
+int
+PSP_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface,
+ _this->gl_data->surface, _this->gl_data->context))
+ {
+ return SDL_SetError("Unable to make EGL context current");
+ }
+ return 0;
+}
+
+int
+PSP_GL_SetSwapInterval(_THIS, int interval)
+{
+ EGLBoolean status;
+ status = eglSwapInterval(_this->gl_data->display, interval);
+ if (status == EGL_TRUE) {
+ /* Return success to upper level */
+ _this->gl_data->swapinterval = interval;
+ return 0;
+ }
+ /* Failed to set swap interval */
+ return SDL_SetError("Unable to set the EGL swap interval");
+}
+
+int
+PSP_GL_GetSwapInterval(_THIS)
+{
+ return _this->gl_data->swapinterval;
+}
+
+int
+PSP_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) {
+ return SDL_SetError("eglSwapBuffers() failed");
+ }
+ return 0;
+}
+
+void
+PSP_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
+ EGLBoolean status;
+
+ if (phdata->egl_initialized != SDL_TRUE) {
+ SDL_SetError("PSP: GLES initialization failed, no OpenGL ES support");
+ return;
+ }
+
+ /* Check if OpenGL ES connection has been initialized */
+ if (_this->gl_data->display != EGL_NO_DISPLAY) {
+ if (context != EGL_NO_CONTEXT) {
+ status = eglDestroyContext(_this->gl_data->display, context);
+ if (status != EGL_TRUE) {
+ /* Error during OpenGL ES context destroying */
+ SDL_SetError("PSP: OpenGL ES context destroy error");
+ return;
+ }
+ }
+ }
+
+ return;
+}
+
+#endif /* SDL_VIDEO_DRIVER_PSP */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspgl_c.h b/source/3rd-party/SDL2/src/video/psp/SDL_pspgl_c.h
new file mode 100644
index 0000000..49300fb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspgl_c.h
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_pspgl_c_h_
+#define SDL_pspgl_c_h_
+
+
+#include <GLES/egl.h>
+#include <GLES/gl.h>
+
+#include "SDL_pspvideo.h"
+
+
+typedef struct SDL_GLDriverData {
+ EGLDisplay display;
+ EGLContext context;
+ EGLSurface surface;
+ uint32_t swapinterval;
+}SDL_GLDriverData;
+
+extern void * PSP_GL_GetProcAddress(_THIS, const char *proc);
+extern int PSP_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
+extern void PSP_GL_SwapBuffers(_THIS);
+
+extern int PSP_GL_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window * window);
+
+extern int PSP_GL_LoadLibrary(_THIS, const char *path);
+extern void PSP_GL_UnloadLibrary(_THIS);
+extern int PSP_GL_SetSwapInterval(_THIS, int interval);
+extern int PSP_GL_GetSwapInterval(_THIS);
+
+
+#endif /* SDL_pspgl_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspmouse.c b/source/3rd-party/SDL2/src/video/psp/SDL_pspmouse.c
new file mode 100644
index 0000000..bd34dfa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspmouse.c
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_PSP
+
+#include <stdio.h>
+
+#include "SDL_error.h"
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_pspmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
+
+#endif /* SDL_VIDEO_DRIVER_PSP */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspmouse_c.h b/source/3rd-party/SDL2/src/video/psp/SDL_pspmouse_c.h
new file mode 100644
index 0000000..2d2640e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspmouse_c.h
@@ -0,0 +1,24 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "SDL_pspvideo.h"
+
+/* Functions to be exported */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.c b/source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.c
new file mode 100644
index 0000000..8231779
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.c
@@ -0,0 +1,333 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_PSP
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_version.h"
+#include "SDL_syswm.h"
+#include "SDL_loadso.h"
+#include "SDL_events.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+
+
+
+/* PSP declarations */
+#include "SDL_pspvideo.h"
+#include "SDL_pspevents_c.h"
+#include "SDL_pspgl_c.h"
+
+/* unused
+static SDL_bool PSP_initialized = SDL_FALSE;
+*/
+static int
+PSP_Available(void)
+{
+ return 1;
+}
+
+static void
+PSP_Destroy(SDL_VideoDevice * device)
+{
+/* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */
+
+ if (device->driverdata != NULL) {
+ device->driverdata = NULL;
+ }
+}
+
+static SDL_VideoDevice *
+PSP_Create()
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *phdata;
+ SDL_GLDriverData *gldata;
+ int status;
+
+ /* Check if PSP could be initialized */
+ status = PSP_Available();
+ if (status == 0) {
+ /* PSP could not be used */
+ return NULL;
+ }
+
+ /* Initialize SDL_VideoDevice structure */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Initialize internal PSP specific data */
+ phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (phdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return NULL;
+ }
+
+ gldata = (SDL_GLDriverData *) SDL_calloc(1, sizeof(SDL_GLDriverData));
+ if (gldata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ SDL_free(phdata);
+ return NULL;
+ }
+ device->gl_data = gldata;
+
+ device->driverdata = phdata;
+
+ phdata->egl_initialized = SDL_TRUE;
+
+
+ /* Setup amount of available displays */
+ device->num_displays = 0;
+
+ /* Set device free function */
+ device->free = PSP_Destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit = PSP_VideoInit;
+ device->VideoQuit = PSP_VideoQuit;
+ device->GetDisplayModes = PSP_GetDisplayModes;
+ device->SetDisplayMode = PSP_SetDisplayMode;
+ device->CreateSDLWindow = PSP_CreateWindow;
+ device->CreateSDLWindowFrom = PSP_CreateWindowFrom;
+ device->SetWindowTitle = PSP_SetWindowTitle;
+ device->SetWindowIcon = PSP_SetWindowIcon;
+ device->SetWindowPosition = PSP_SetWindowPosition;
+ device->SetWindowSize = PSP_SetWindowSize;
+ device->ShowWindow = PSP_ShowWindow;
+ device->HideWindow = PSP_HideWindow;
+ device->RaiseWindow = PSP_RaiseWindow;
+ device->MaximizeWindow = PSP_MaximizeWindow;
+ device->MinimizeWindow = PSP_MinimizeWindow;
+ device->RestoreWindow = PSP_RestoreWindow;
+ device->SetWindowGrab = PSP_SetWindowGrab;
+ device->DestroyWindow = PSP_DestroyWindow;
+#if 0
+ device->GetWindowWMInfo = PSP_GetWindowWMInfo;
+#endif
+ device->GL_LoadLibrary = PSP_GL_LoadLibrary;
+ device->GL_GetProcAddress = PSP_GL_GetProcAddress;
+ device->GL_UnloadLibrary = PSP_GL_UnloadLibrary;
+ device->GL_CreateContext = PSP_GL_CreateContext;
+ device->GL_MakeCurrent = PSP_GL_MakeCurrent;
+ device->GL_SetSwapInterval = PSP_GL_SetSwapInterval;
+ device->GL_GetSwapInterval = PSP_GL_GetSwapInterval;
+ device->GL_SwapWindow = PSP_GL_SwapWindow;
+ device->GL_DeleteContext = PSP_GL_DeleteContext;
+ device->HasScreenKeyboardSupport = PSP_HasScreenKeyboardSupport;
+ device->ShowScreenKeyboard = PSP_ShowScreenKeyboard;
+ device->HideScreenKeyboard = PSP_HideScreenKeyboard;
+ device->IsScreenKeyboardShown = PSP_IsScreenKeyboardShown;
+
+ device->PumpEvents = PSP_PumpEvents;
+
+ return device;
+}
+
+VideoBootStrap PSP_bootstrap = {
+ "PSP",
+ "PSP Video Driver",
+ PSP_Available,
+ PSP_Create
+};
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions */
+/*****************************************************************************/
+int
+PSP_VideoInit(_THIS)
+{
+ SDL_VideoDisplay display;
+ SDL_DisplayMode current_mode;
+
+ SDL_zero(current_mode);
+
+ current_mode.w = 480;
+ current_mode.h = 272;
+
+ current_mode.refresh_rate = 60;
+ /* 32 bpp for default */
+ current_mode.format = SDL_PIXELFORMAT_ABGR8888;
+
+ current_mode.driverdata = NULL;
+
+ SDL_zero(display);
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+ display.driverdata = NULL;
+
+ SDL_AddVideoDisplay(&display);
+
+ return 1;
+}
+
+void
+PSP_VideoQuit(_THIS)
+{
+
+}
+
+void
+PSP_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+
+}
+
+int
+PSP_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+#define EGLCHK(stmt) \
+ do { \
+ EGLint err; \
+ \
+ stmt; \
+ err = eglGetError(); \
+ if (err != EGL_SUCCESS) { \
+ SDL_SetError("EGL error %d", err); \
+ return 0; \
+ } \
+ } while (0)
+
+int
+PSP_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wdata;
+
+ /* Allocate window internal data */
+ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (wdata == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Setup driver data for this window */
+ window->driverdata = wdata;
+
+
+ /* Window has been successfully created */
+ return 0;
+}
+
+int
+PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ return SDL_Unsupported();
+}
+
+void
+PSP_SetWindowTitle(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+}
+void
+PSP_SetWindowPosition(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_SetWindowSize(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_ShowWindow(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_HideWindow(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_RaiseWindow(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_MaximizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_MinimizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_RestoreWindow(_THIS, SDL_Window * window)
+{
+}
+void
+PSP_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+
+}
+void
+PSP_DestroyWindow(_THIS, SDL_Window * window)
+{
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function */
+/*****************************************************************************/
+#if 0
+SDL_bool
+PSP_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+
+ /* Failed to get window manager information */
+ return SDL_FALSE;
+}
+#endif
+
+
+/* TO Write Me */
+SDL_bool PSP_HasScreenKeyboardSupport(_THIS)
+{
+ return SDL_FALSE;
+}
+void PSP_ShowScreenKeyboard(_THIS, SDL_Window *window)
+{
+}
+void PSP_HideScreenKeyboard(_THIS, SDL_Window *window)
+{
+}
+SDL_bool PSP_IsScreenKeyboardShown(_THIS, SDL_Window *window)
+{
+ return SDL_FALSE;
+}
+
+
+#endif /* SDL_VIDEO_DRIVER_PSP */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.h b/source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.h
new file mode 100644
index 0000000..741bad1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/psp/SDL_pspvideo.h
@@ -0,0 +1,102 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_pspvideo_h_
+#define SDL_pspvideo_h_
+
+#include <GLES/egl.h>
+
+#include "../../SDL_internal.h"
+#include "../SDL_sysvideo.h"
+
+typedef struct SDL_VideoData
+{
+ SDL_bool egl_initialized; /* OpenGL ES device initialization status */
+ uint32_t egl_refcount; /* OpenGL ES reference count */
+
+
+
+} SDL_VideoData;
+
+
+typedef struct SDL_DisplayData
+{
+
+} SDL_DisplayData;
+
+
+typedef struct SDL_WindowData
+{
+ SDL_bool uses_gles; /* if true window must support OpenGL ES */
+
+} SDL_WindowData;
+
+
+
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration */
+/****************************************************************************/
+
+/* Display and window functions */
+int PSP_VideoInit(_THIS);
+void PSP_VideoQuit(_THIS);
+void PSP_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+int PSP_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int PSP_CreateWindow(_THIS, SDL_Window * window);
+int PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+void PSP_SetWindowTitle(_THIS, SDL_Window * window);
+void PSP_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+void PSP_SetWindowPosition(_THIS, SDL_Window * window);
+void PSP_SetWindowSize(_THIS, SDL_Window * window);
+void PSP_ShowWindow(_THIS, SDL_Window * window);
+void PSP_HideWindow(_THIS, SDL_Window * window);
+void PSP_RaiseWindow(_THIS, SDL_Window * window);
+void PSP_MaximizeWindow(_THIS, SDL_Window * window);
+void PSP_MinimizeWindow(_THIS, SDL_Window * window);
+void PSP_RestoreWindow(_THIS, SDL_Window * window);
+void PSP_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+void PSP_DestroyWindow(_THIS, SDL_Window * window);
+
+/* Window manager function */
+SDL_bool PSP_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+/* OpenGL/OpenGL ES functions */
+int PSP_GL_LoadLibrary(_THIS, const char *path);
+void *PSP_GL_GetProcAddress(_THIS, const char *proc);
+void PSP_GL_UnloadLibrary(_THIS);
+SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window * window);
+int PSP_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int PSP_GL_SetSwapInterval(_THIS, int interval);
+int PSP_GL_GetSwapInterval(_THIS);
+int PSP_GL_SwapWindow(_THIS, SDL_Window * window);
+void PSP_GL_DeleteContext(_THIS, SDL_GLContext context);
+
+/* PSP on screen keyboard */
+SDL_bool PSP_HasScreenKeyboardSupport(_THIS);
+void PSP_ShowScreenKeyboard(_THIS, SDL_Window *window);
+void PSP_HideScreenKeyboard(_THIS, SDL_Window *window);
+SDL_bool PSP_IsScreenKeyboardShown(_THIS, SDL_Window *window);
+
+#endif /* SDL_pspvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/qnx/gl.c b/source/3rd-party/SDL2/src/video/qnx/gl.c
new file mode 100644
index 0000000..19e1bd4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/qnx/gl.c
@@ -0,0 +1,285 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 2017 BlackBerry Limited
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+#include "sdl_qnx.h"
+
+static EGLDisplay egl_disp;
+
+/**
+ * Detertmines the pixel format to use based on the current display and EGL
+ * configuration.
+ * @param egl_conf EGL configuration to use
+ * @return A SCREEN_FORMAT* constant for the pixel format to use
+ */
+static int
+chooseFormat(EGLConfig egl_conf)
+{
+ EGLint buffer_bit_depth;
+ EGLint alpha_bit_depth;
+
+ eglGetConfigAttrib(egl_disp, egl_conf, EGL_BUFFER_SIZE, &buffer_bit_depth);
+ eglGetConfigAttrib(egl_disp, egl_conf, EGL_ALPHA_SIZE, &alpha_bit_depth);
+
+ switch (buffer_bit_depth) {
+ case 32:
+ return SCREEN_FORMAT_RGBX8888;
+ case 24:
+ return SCREEN_FORMAT_RGB888;
+ case 16:
+ switch (alpha_bit_depth) {
+ case 4:
+ return SCREEN_FORMAT_RGBX4444;
+ case 1:
+ return SCREEN_FORMAT_RGBA5551;
+ default:
+ return SCREEN_FORMAT_RGB565;
+ }
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Enumerates the supported EGL configurations and chooses a suitable one.
+ * @param[out] pconf The chosen configuration
+ * @param[out] pformat The chosen pixel format
+ * @return 0 if successful, -1 on error
+ */
+int
+glGetConfig(EGLConfig *pconf, int *pformat)
+{
+ EGLConfig egl_conf = (EGLConfig)0;
+ EGLConfig *egl_configs;
+ EGLint egl_num_configs;
+ EGLint val;
+ EGLBoolean rc;
+ EGLint i;
+
+ // Determine the numbfer of configurations.
+ rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs);
+ if (rc != EGL_TRUE) {
+ return -1;
+ }
+
+ if (egl_num_configs == 0) {
+ return -1;
+ }
+
+ // Allocate enough memory for all configurations.
+ egl_configs = malloc(egl_num_configs * sizeof(*egl_configs));
+ if (egl_configs == NULL) {
+ return -1;
+ }
+
+ // Get the list of configurations.
+ rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs,
+ &egl_num_configs);
+ if (rc != EGL_TRUE) {
+ free(egl_configs);
+ return -1;
+ }
+
+ // Find a good configuration.
+ for (i = 0; i < egl_num_configs; i++) {
+ eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val);
+ if (!(val & EGL_WINDOW_BIT)) {
+ continue;
+ }
+
+ eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val);
+ if (!(val & EGL_OPENGL_ES2_BIT)) {
+ continue;
+ }
+
+ eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val);
+ if (val == 0) {
+ continue;
+ }
+
+ egl_conf = egl_configs[i];
+ break;
+ }
+
+ free(egl_configs);
+ *pconf = egl_conf;
+ *pformat = chooseFormat(egl_conf);
+
+ return 0;
+}
+
+/**
+ * Initializes the EGL library.
+ * @param _THIS
+ * @param name unused
+ * @return 0 if successful, -1 on error
+ */
+int
+glLoadLibrary(_THIS, const char *name)
+{
+ EGLNativeDisplayType disp_id = EGL_DEFAULT_DISPLAY;
+
+ egl_disp = eglGetDisplay(disp_id);
+ if (egl_disp == EGL_NO_DISPLAY) {
+ return -1;
+ }
+
+ if (eglInitialize(egl_disp, NULL, NULL) == EGL_FALSE) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Finds the address of an EGL extension function.
+ * @param proc Function name
+ * @return Function address
+ */
+void *
+glGetProcAddress(_THIS, const char *proc)
+{
+ return eglGetProcAddress(proc);
+}
+
+/**
+ * Associates the given window with the necessary EGL structures for drawing and
+ * displaying content.
+ * @param _THIS
+ * @param window The SDL window to create the context for
+ * @return A pointer to the created context, if successful, NULL on error
+ */
+SDL_GLContext
+glCreateContext(_THIS, SDL_Window *window)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ EGLContext context;
+ EGLSurface surface;
+
+ struct {
+ EGLint client_version[2];
+ EGLint none;
+ } egl_ctx_attr = {
+ .client_version = { EGL_CONTEXT_CLIENT_VERSION, 2 },
+ .none = EGL_NONE
+ };
+
+ struct {
+ EGLint render_buffer[2];
+ EGLint none;
+ } egl_surf_attr = {
+ .render_buffer = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER },
+ .none = EGL_NONE
+ };
+
+ context = eglCreateContext(egl_disp, impl->conf, EGL_NO_CONTEXT,
+ (EGLint *)&egl_ctx_attr);
+ if (context == EGL_NO_CONTEXT) {
+ return NULL;
+ }
+
+ surface = eglCreateWindowSurface(egl_disp, impl->conf, impl->window,
+ (EGLint *)&egl_surf_attr);
+ if (surface == EGL_NO_SURFACE) {
+ return NULL;
+ }
+
+ eglMakeCurrent(egl_disp, surface, surface, context);
+
+ impl->surface = surface;
+ return context;
+}
+
+/**
+ * Sets a new value for the number of frames to display before swapping buffers.
+ * @param _THIS
+ * @param interval New interval value
+ * @return 0 if successful, -1 on error
+ */
+int
+glSetSwapInterval(_THIS, int interval)
+{
+ if (eglSwapInterval(egl_disp, interval) != EGL_TRUE) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Swaps the EGL buffers associated with the given window
+ * @param _THIS
+ * @param window Window to swap buffers for
+ * @return 0 if successful, -1 on error
+ */
+int
+glSwapWindow(_THIS, SDL_Window *window)
+{
+ /* !!! FIXME: should we migrate this all over to use SDL_egl.c? */
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ return eglSwapBuffers(egl_disp, impl->surface) == EGL_TRUE ? 0 : -1;
+}
+
+/**
+ * Makes the given context the current one for drawing operations.
+ * @param _THIS
+ * @param window SDL window associated with the context (maybe NULL)
+ * @param context The context to activate
+ * @return 0 if successful, -1 on error
+ */
+int
+glMakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
+{
+ window_impl_t *impl;
+ EGLSurface surface = NULL;
+
+ if (window) {
+ impl = (window_impl_t *)window->driverdata;
+ surface = impl->surface;
+ }
+
+ if (eglMakeCurrent(egl_disp, surface, surface, context) != EGL_TRUE) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Destroys a context.
+ * @param _THIS
+ * @param context The context to destroy
+ */
+void
+glDeleteContext(_THIS, SDL_GLContext context)
+{
+ eglDestroyContext(egl_disp, context);
+}
+
+/**
+ * Terminates access to the EGL library.
+ * @param _THIS
+ */
+void
+glUnloadLibrary(_THIS)
+{
+ eglTerminate(egl_disp);
+}
diff --git a/source/3rd-party/SDL2/src/video/qnx/keyboard.c b/source/3rd-party/SDL2/src/video/qnx/keyboard.c
new file mode 100644
index 0000000..86c6395
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/qnx/keyboard.c
@@ -0,0 +1,133 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 2017 BlackBerry Limited
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "SDL_scancode.h"
+#include "SDL_events.h"
+#include "sdl_qnx.h"
+#include <sys/keycodes.h>
+
+/**
+ * A map thta translates Screen key names to SDL scan codes.
+ * This map is incomplete, but should include most major keys.
+ */
+static int key_to_sdl[] = {
+ [KEYCODE_SPACE] = SDL_SCANCODE_SPACE,
+ [KEYCODE_APOSTROPHE] = SDL_SCANCODE_APOSTROPHE,
+ [KEYCODE_COMMA] = SDL_SCANCODE_COMMA,
+ [KEYCODE_MINUS] = SDL_SCANCODE_MINUS,
+ [KEYCODE_PERIOD] = SDL_SCANCODE_PERIOD,
+ [KEYCODE_SLASH] = SDL_SCANCODE_SLASH,
+ [KEYCODE_ZERO] = SDL_SCANCODE_0,
+ [KEYCODE_ONE] = SDL_SCANCODE_1,
+ [KEYCODE_TWO] = SDL_SCANCODE_2,
+ [KEYCODE_THREE] = SDL_SCANCODE_3,
+ [KEYCODE_FOUR] = SDL_SCANCODE_4,
+ [KEYCODE_FIVE] = SDL_SCANCODE_5,
+ [KEYCODE_SIX] = SDL_SCANCODE_6,
+ [KEYCODE_SEVEN] = SDL_SCANCODE_7,
+ [KEYCODE_EIGHT] = SDL_SCANCODE_8,
+ [KEYCODE_NINE] = SDL_SCANCODE_9,
+ [KEYCODE_SEMICOLON] = SDL_SCANCODE_SEMICOLON,
+ [KEYCODE_EQUAL] = SDL_SCANCODE_EQUALS,
+ [KEYCODE_LEFT_BRACKET] = SDL_SCANCODE_LEFTBRACKET,
+ [KEYCODE_BACK_SLASH] = SDL_SCANCODE_BACKSLASH,
+ [KEYCODE_RIGHT_BRACKET] = SDL_SCANCODE_RIGHTBRACKET,
+ [KEYCODE_GRAVE] = SDL_SCANCODE_GRAVE,
+ [KEYCODE_A] = SDL_SCANCODE_A,
+ [KEYCODE_B] = SDL_SCANCODE_B,
+ [KEYCODE_C] = SDL_SCANCODE_C,
+ [KEYCODE_D] = SDL_SCANCODE_D,
+ [KEYCODE_E] = SDL_SCANCODE_E,
+ [KEYCODE_F] = SDL_SCANCODE_F,
+ [KEYCODE_G] = SDL_SCANCODE_G,
+ [KEYCODE_H] = SDL_SCANCODE_H,
+ [KEYCODE_I] = SDL_SCANCODE_I,
+ [KEYCODE_J] = SDL_SCANCODE_J,
+ [KEYCODE_K] = SDL_SCANCODE_K,
+ [KEYCODE_L] = SDL_SCANCODE_L,
+ [KEYCODE_M] = SDL_SCANCODE_M,
+ [KEYCODE_N] = SDL_SCANCODE_N,
+ [KEYCODE_O] = SDL_SCANCODE_O,
+ [KEYCODE_P] = SDL_SCANCODE_P,
+ [KEYCODE_Q] = SDL_SCANCODE_Q,
+ [KEYCODE_R] = SDL_SCANCODE_R,
+ [KEYCODE_S] = SDL_SCANCODE_S,
+ [KEYCODE_T] = SDL_SCANCODE_T,
+ [KEYCODE_U] = SDL_SCANCODE_U,
+ [KEYCODE_V] = SDL_SCANCODE_V,
+ [KEYCODE_W] = SDL_SCANCODE_W,
+ [KEYCODE_X] = SDL_SCANCODE_X,
+ [KEYCODE_Y] = SDL_SCANCODE_Y,
+ [KEYCODE_Z] = SDL_SCANCODE_Z,
+ [KEYCODE_UP] = SDL_SCANCODE_UP,
+ [KEYCODE_DOWN] = SDL_SCANCODE_DOWN,
+ [KEYCODE_LEFT] = SDL_SCANCODE_LEFT,
+ [KEYCODE_PG_UP] = SDL_SCANCODE_PAGEUP,
+ [KEYCODE_PG_DOWN] = SDL_SCANCODE_PAGEDOWN,
+ [KEYCODE_RIGHT] = SDL_SCANCODE_RIGHT,
+ [KEYCODE_RETURN] = SDL_SCANCODE_RETURN,
+ [KEYCODE_TAB] = SDL_SCANCODE_TAB,
+ [KEYCODE_ESCAPE] = SDL_SCANCODE_ESCAPE,
+};
+
+/**
+ * Called from the event dispatcher when a keyboard event is encountered.
+ * Translates the event such that it can be handled by SDL.
+ * @param event Screen keyboard event
+ */
+void
+handleKeyboardEvent(screen_event_t event)
+{
+ int val;
+ SDL_Scancode scancode;
+
+ // Get the key value.
+ if (screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, &val) < 0) {
+ return;
+ }
+
+ // Skip unrecognized keys.
+ if ((val < 0) || (val >= SDL_TABLESIZE(key_to_sdl))) {
+ return;
+ }
+
+ // Translate to an SDL scan code.
+ scancode = key_to_sdl[val];
+ if (scancode == 0) {
+ return;
+ }
+
+ // Get event flags (key state).
+ if (screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, &val) < 0) {
+ return;
+ }
+
+ // Propagate the event to SDL.
+ // FIXME:
+ // Need to handle more key states (such as key combinations).
+ if (val & KEY_DOWN) {
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ } else {
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+}
diff --git a/source/3rd-party/SDL2/src/video/qnx/sdl_qnx.h b/source/3rd-party/SDL2/src/video/qnx/sdl_qnx.h
new file mode 100644
index 0000000..65e0798
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/qnx/sdl_qnx.h
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 2017 BlackBerry Limited
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __SDL_QNX_H__
+#define __SDL_QNX_H__
+
+#include "../SDL_sysvideo.h"
+#include <screen/screen.h>
+#include <EGL/egl.h>
+
+typedef struct
+{
+ screen_window_t window;
+ EGLSurface surface;
+ EGLConfig conf;
+} window_impl_t;
+
+extern void handleKeyboardEvent(screen_event_t event);
+
+extern int glGetConfig(EGLConfig *pconf, int *pformat);
+extern int glLoadLibrary(_THIS, const char *name);
+void *glGetProcAddress(_THIS, const char *proc);
+extern SDL_GLContext glCreateContext(_THIS, SDL_Window *window);
+extern int glSetSwapInterval(_THIS, int interval);
+extern int glSwapWindow(_THIS, SDL_Window *window);
+extern int glMakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern void glDeleteContext(_THIS, SDL_GLContext context);
+extern void glUnloadLibrary(_THIS);
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/qnx/video.c b/source/3rd-party/SDL2/src/video/qnx/video.c
new file mode 100644
index 0000000..ff8223c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/qnx/video.c
@@ -0,0 +1,364 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 2017 BlackBerry Limited
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+#include "../SDL_sysvideo.h"
+#include "sdl_qnx.h"
+
+static screen_context_t context;
+static screen_event_t event;
+
+/**
+ * Initializes the QNX video plugin.
+ * Creates the Screen context and event handles used for all window operations
+ * by the plugin.
+ * @param _THIS
+ * @return 0 if successful, -1 on error
+ */
+static int
+videoInit(_THIS)
+{
+ SDL_VideoDisplay display;
+
+ if (screen_create_context(&context, 0) < 0) {
+ return -1;
+ }
+
+ if (screen_create_event(&event) < 0) {
+ return -1;
+ }
+
+ SDL_zero(display);
+
+ if (SDL_AddVideoDisplay(&display) < 0) {
+ return -1;
+ }
+
+ _this->num_displays = 1;
+ return 0;
+}
+
+static void
+videoQuit(_THIS)
+{
+}
+
+/**
+ * Creates a new native Screen window and associates it with the given SDL
+ * window.
+ * @param _THIS
+ * @param window SDL window to initialize
+ * @return 0 if successful, -1 on error
+ */
+static int
+createWindow(_THIS, SDL_Window *window)
+{
+ window_impl_t *impl;
+ int size[2];
+ int numbufs;
+ int format;
+ int usage;
+
+ impl = SDL_calloc(1, sizeof(*impl));
+ if (impl == NULL) {
+ return -1;
+ }
+
+ // Create a native window.
+ if (screen_create_window(&impl->window, context) < 0) {
+ goto fail;
+ }
+
+ // Set the native window's size to match the SDL window.
+ size[0] = window->w;
+ size[1] = window->h;
+
+ if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE,
+ size) < 0) {
+ goto fail;
+ }
+
+ if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE,
+ size) < 0) {
+ goto fail;
+ }
+
+ // Create window buffer(s).
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ if (glGetConfig(&impl->conf, &format) < 0) {
+ goto fail;
+ }
+ numbufs = 2;
+
+ usage = SCREEN_USAGE_OPENGL_ES2;
+ if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_USAGE,
+ &usage) < 0) {
+ return -1;
+ }
+ } else {
+ format = SCREEN_FORMAT_RGBX8888;
+ numbufs = 1;
+ }
+
+ // Set pixel format.
+ if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_FORMAT,
+ &format) < 0) {
+ goto fail;
+ }
+
+ // Create buffer(s).
+ if (screen_create_window_buffers(impl->window, numbufs) < 0) {
+ goto fail;
+ }
+
+ window->driverdata = impl;
+ return 0;
+
+fail:
+ if (impl->window) {
+ screen_destroy_window(impl->window);
+ }
+
+ SDL_free(impl);
+ return -1;
+}
+
+/**
+ * Gets a pointer to the Screen buffer associated with the given window. Note
+ * that the buffer is actually created in createWindow().
+ * @param _THIS
+ * @param window SDL window to get the buffer for
+ * @param[out] pixles Holds a pointer to the window's buffer
+ * @param[out] format Holds the pixel format for the buffer
+ * @param[out] pitch Holds the number of bytes per line
+ * @return 0 if successful, -1 on error
+ */
+static int
+createWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format,
+ void ** pixels, int *pitch)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ screen_buffer_t buffer;
+
+ // Get a pointer to the buffer's memory.
+ if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS,
+ (void **)&buffer) < 0) {
+ return -1;
+ }
+
+ if (screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER,
+ pixels) < 0) {
+ return -1;
+ }
+
+ // Set format and pitch.
+ if (screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE,
+ pitch) < 0) {
+ return -1;
+ }
+
+ *format = SDL_PIXELFORMAT_RGB888;
+ return 0;
+}
+
+/**
+ * Informs the window manager that the window needs to be updated.
+ * @param _THIS
+ * @param window The window to update
+ * @param rects An array of reectangular areas to update
+ * @param numrects Rect array length
+ * @return 0 if successful, -1 on error
+ */
+static int
+updateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects,
+ int numrects)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ screen_buffer_t buffer;
+
+ if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS,
+ (void **)&buffer) < 0) {
+ return -1;
+ }
+
+ screen_post_window(impl->window, buffer, numrects, (int *)rects, 0);
+ screen_flush_context(context, 0);
+ return 0;
+}
+
+/**
+ * Runs the main event loop.
+ * @param _THIS
+ */
+static void
+pumpEvents(_THIS)
+{
+ int type;
+
+ for (;;) {
+ if (screen_get_event(context, event, 0) < 0) {
+ break;
+ }
+
+ if (screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type)
+ < 0) {
+ break;
+ }
+
+ if (type == SCREEN_EVENT_NONE) {
+ break;
+ }
+
+ switch (type) {
+ case SCREEN_EVENT_KEYBOARD:
+ handleKeyboardEvent(event);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * Updates the size of the native window using the geometry of the SDL window.
+ * @param _THIS
+ * @param window SDL window to update
+ */
+static void
+setWindowSize(_THIS, SDL_Window *window)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ int size[2];
+
+ size[0] = window->w;
+ size[1] = window->h;
+
+ screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, size);
+ screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE,
+ size);
+}
+
+/**
+ * Makes the native window associated with the given SDL window visible.
+ * @param _THIS
+ * @param window SDL window to update
+ */
+static void
+showWindow(_THIS, SDL_Window *window)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ const int visible = 1;
+
+ screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE,
+ &visible);
+}
+
+/**
+ * Makes the native window associated with the given SDL window invisible.
+ * @param _THIS
+ * @param window SDL window to update
+ */
+static void
+hideWindow(_THIS, SDL_Window *window)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+ const int visible = 0;
+
+ screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE,
+ &visible);
+}
+
+/**
+ * Destroys the native window associated with the given SDL window.
+ * @param _THIS
+ * @param window SDL window that is being destroyed
+ */
+static void
+destroyWindow(_THIS, SDL_Window *window)
+{
+ window_impl_t *impl = (window_impl_t *)window->driverdata;
+
+ if (impl) {
+ screen_destroy_window(impl->window);
+ window->driverdata = NULL;
+ }
+}
+
+/**
+ * Frees the plugin object created by createDevice().
+ * @param device Plugin object to free
+ */
+static void
+deleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device);
+}
+
+/**
+ * Creates the QNX video plugin used by SDL.
+ * @param devindex Unused
+ * @return Initialized device if successful, NULL otherwise
+ */
+static SDL_VideoDevice *
+createDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ return NULL;
+ }
+
+ device->driverdata = NULL;
+ device->VideoInit = videoInit;
+ device->VideoQuit = videoQuit;
+ device->CreateSDLWindow = createWindow;
+ device->CreateWindowFramebuffer = createWindowFramebuffer;
+ device->UpdateWindowFramebuffer = updateWindowFramebuffer;
+ device->SetWindowSize = setWindowSize;
+ device->ShowWindow = showWindow;
+ device->HideWindow = hideWindow;
+ device->PumpEvents = pumpEvents;
+ device->DestroyWindow = destroyWindow;
+
+ device->GL_LoadLibrary = glLoadLibrary;
+ device->GL_GetProcAddress = glGetProcAddress;
+ device->GL_CreateContext = glCreateContext;
+ device->GL_SetSwapInterval = glSetSwapInterval;
+ device->GL_SwapWindow = glSwapWindow;
+ device->GL_MakeCurrent = glMakeCurrent;
+ device->GL_DeleteContext = glDeleteContext;
+ device->GL_UnloadLibrary = glUnloadLibrary;
+
+ device->free = deleteDevice;
+ return device;
+}
+
+static int
+available()
+{
+ return 1;
+}
+
+VideoBootStrap QNX_bootstrap = {
+ "qnx", "QNX Screen",
+ available, createDevice
+};
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents.c b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents.c
new file mode 100644
index 0000000..4064355
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents.c
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_RPI
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "SDL_rpivideo.h"
+#include "SDL_rpievents_c.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+void RPI_PumpEvents(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Poll();
+#endif
+
+}
+
+#endif /* SDL_VIDEO_DRIVER_RPI */
+
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents_c.h b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents_c.h
new file mode 100644
index 0000000..8b1737f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpievents_c.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_rpievents_c_h_
+#define SDL_rpievents_c_h_
+
+#include "SDL_rpivideo.h"
+
+void RPI_PumpEvents(_THIS);
+void RPI_EventInit(_THIS);
+void RPI_EventQuit(_THIS);
+
+#endif /* SDL_rpievents_c_h_ */
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.c b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.c
new file mode 100644
index 0000000..4ea976b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.c
@@ -0,0 +1,386 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_RPI
+
+#include "SDL_assert.h"
+#include "SDL_surface.h"
+#include "SDL_hints.h"
+
+#include "SDL_rpivideo.h"
+#include "SDL_rpimouse.h"
+
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/default_cursor.h"
+
+/* Copied from vc_vchi_dispmanx.h which is bugged and tries to include a non existing file */
+/* Attributes changes flag mask */
+#define ELEMENT_CHANGE_LAYER (1<<0)
+#define ELEMENT_CHANGE_OPACITY (1<<1)
+#define ELEMENT_CHANGE_DEST_RECT (1<<2)
+#define ELEMENT_CHANGE_SRC_RECT (1<<3)
+#define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
+#define ELEMENT_CHANGE_TRANSFORM (1<<5)
+/* End copied from vc_vchi_dispmanx.h */
+
+static SDL_Cursor *RPI_CreateDefaultCursor(void);
+static SDL_Cursor *RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
+static int RPI_ShowCursor(SDL_Cursor * cursor);
+static void RPI_MoveCursor(SDL_Cursor * cursor);
+static void RPI_FreeCursor(SDL_Cursor * cursor);
+static void RPI_WarpMouse(SDL_Window * window, int x, int y);
+static int RPI_WarpMouseGlobal(int x, int y);
+
+static SDL_Cursor *
+RPI_CreateDefaultCursor(void)
+{
+ return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
+}
+
+/* Create a cursor from a surface */
+static SDL_Cursor *
+RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ RPI_CursorData *curdata;
+ SDL_Cursor *cursor;
+ int ret;
+ VC_RECT_T dst_rect;
+ Uint32 dummy;
+
+ SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
+ SDL_assert(surface->pitch == surface->w * 4);
+
+ cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+ if (cursor == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ curdata = (RPI_CursorData *) SDL_calloc(1, sizeof(*curdata));
+ if (curdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(cursor);
+ return NULL;
+ }
+
+ curdata->hot_x = hot_x;
+ curdata->hot_y = hot_y;
+ curdata->w = surface->w;
+ curdata->h = surface->h;
+
+ /* This usage is inspired by Wayland/Weston RPI code, how they figured this out is anyone's guess */
+ curdata->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy);
+ SDL_assert(curdata->resource);
+ vc_dispmanx_rect_set(&dst_rect, 0, 0, curdata->w, curdata->h);
+ /* A note from Weston:
+ * vc_dispmanx_resource_write_data() ignores ifmt,
+ * rect.x, rect.width, and uses stride only for computing
+ * the size of the transfer as rect.height * stride.
+ * Therefore we can only write rows starting at x=0.
+ */
+ ret = vc_dispmanx_resource_write_data(curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect);
+ SDL_assert (ret == DISPMANX_SUCCESS);
+
+ cursor->driverdata = curdata;
+
+ return cursor;
+
+}
+
+/* Show the specified cursor, or hide if cursor is NULL */
+static int
+RPI_ShowCursor(SDL_Cursor * cursor)
+{
+ int ret;
+ DISPMANX_UPDATE_HANDLE_T update;
+ RPI_CursorData *curdata;
+ VC_RECT_T src_rect, dst_rect;
+ SDL_Mouse *mouse;
+ SDL_VideoDisplay *display;
+ SDL_DisplayData *data;
+ VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE /* flags */ , 255 /*opacity 0->255*/, 0 /* mask */ };
+ uint32_t layer = SDL_RPI_MOUSELAYER;
+ const char *env;
+
+ mouse = SDL_GetMouse();
+ if (mouse == NULL) {
+ return -1;
+ }
+
+ if (cursor == NULL) {
+ /* FIXME: We hide the current mouse's cursor, what we actually need is *_HideCursor */
+
+ if (mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+ curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
+ if (curdata->element > DISPMANX_NO_HANDLE) {
+ update = vc_dispmanx_update_start(10);
+ SDL_assert(update);
+ ret = vc_dispmanx_element_remove(update, curdata->element);
+ SDL_assert(ret == DISPMANX_SUCCESS);
+ ret = vc_dispmanx_update_submit_sync(update);
+ SDL_assert(ret == DISPMANX_SUCCESS);
+ curdata->element = DISPMANX_NO_HANDLE;
+ }
+ }
+ return 0;
+ }
+
+ curdata = (RPI_CursorData *) cursor->driverdata;
+ if (curdata == NULL) {
+ return -1;
+ }
+
+ if (mouse->focus == NULL) {
+ return -1;
+ }
+
+ display = SDL_GetDisplayForWindow(mouse->focus);
+ if (display == NULL) {
+ return -1;
+ }
+
+ data = (SDL_DisplayData*) display->driverdata;
+ if (data == NULL) {
+ return -1;
+ }
+
+ if (curdata->element == DISPMANX_NO_HANDLE) {
+ vc_dispmanx_rect_set(&src_rect, 0, 0, curdata->w << 16, curdata->h << 16);
+ vc_dispmanx_rect_set(&dst_rect, mouse->x, mouse->y, curdata->w, curdata->h);
+
+ update = vc_dispmanx_update_start(10);
+ SDL_assert(update);
+
+ env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER);
+ if (env) {
+ layer = SDL_atoi(env) + 1;
+ }
+
+ curdata->element = vc_dispmanx_element_add(update,
+ data->dispman_display,
+ layer,
+ &dst_rect,
+ curdata->resource,
+ &src_rect,
+ DISPMANX_PROTECTION_NONE,
+ &alpha,
+ DISPMANX_NO_HANDLE, // clamp
+ VC_IMAGE_ROT0);
+ SDL_assert(curdata->element > DISPMANX_NO_HANDLE);
+ ret = vc_dispmanx_update_submit_sync(update);
+ SDL_assert(ret == DISPMANX_SUCCESS);
+ }
+
+ return 0;
+}
+
+/* Free a window manager cursor */
+static void
+RPI_FreeCursor(SDL_Cursor * cursor)
+{
+ int ret;
+ DISPMANX_UPDATE_HANDLE_T update;
+ RPI_CursorData *curdata;
+
+ if (cursor != NULL) {
+ curdata = (RPI_CursorData *) cursor->driverdata;
+
+ if (curdata != NULL) {
+ if (curdata->element != DISPMANX_NO_HANDLE) {
+ update = vc_dispmanx_update_start(10);
+ SDL_assert(update);
+ ret = vc_dispmanx_element_remove(update, curdata->element);
+ SDL_assert(ret == DISPMANX_SUCCESS);
+ ret = vc_dispmanx_update_submit_sync(update);
+ SDL_assert(ret == DISPMANX_SUCCESS);
+ }
+
+ if (curdata->resource != DISPMANX_NO_HANDLE) {
+ ret = vc_dispmanx_resource_delete(curdata->resource);
+ SDL_assert(ret == DISPMANX_SUCCESS);
+ }
+
+ SDL_free(cursor->driverdata);
+ }
+ SDL_free(cursor);
+ }
+}
+
+/* Warp the mouse to (x,y) */
+static void
+RPI_WarpMouse(SDL_Window * window, int x, int y)
+{
+ RPI_WarpMouseGlobal(x, y);
+}
+
+/* Warp the mouse to (x,y) */
+static int
+RPI_WarpMouseGlobal(int x, int y)
+{
+ RPI_CursorData *curdata;
+ DISPMANX_UPDATE_HANDLE_T update;
+ int ret;
+ VC_RECT_T dst_rect;
+ VC_RECT_T src_rect;
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) {
+ return 0;
+ }
+
+ /* Update internal mouse position. */
+ SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+
+ curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
+ if (curdata->element == DISPMANX_NO_HANDLE) {
+ return 0;
+ }
+
+ update = vc_dispmanx_update_start(10);
+ if (!update) {
+ return 0;
+ }
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.width = curdata->w << 16;
+ src_rect.height = curdata->h << 16;
+ dst_rect.x = x;
+ dst_rect.y = y;
+ dst_rect.width = curdata->w;
+ dst_rect.height = curdata->h;
+
+ ret = vc_dispmanx_element_change_attributes(
+ update,
+ curdata->element,
+ 0,
+ 0,
+ 0,
+ &dst_rect,
+ &src_rect,
+ DISPMANX_NO_HANDLE,
+ DISPMANX_NO_ROTATE);
+ if (ret != DISPMANX_SUCCESS) {
+ return SDL_SetError("vc_dispmanx_element_change_attributes() failed");
+ }
+
+ /* Submit asynchronously, otherwise the peformance suffers a lot */
+ ret = vc_dispmanx_update_submit(update, 0, NULL);
+ if (ret != DISPMANX_SUCCESS) {
+ return SDL_SetError("vc_dispmanx_update_submit() failed");
+ }
+ return 0;
+}
+
+/* Warp the mouse to (x,y) */
+static int
+RPI_WarpMouseGlobalGraphicOnly(int x, int y)
+{
+ RPI_CursorData *curdata;
+ DISPMANX_UPDATE_HANDLE_T update;
+ int ret;
+ VC_RECT_T dst_rect;
+ VC_RECT_T src_rect;
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) {
+ return 0;
+ }
+
+ curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
+ if (curdata->element == DISPMANX_NO_HANDLE) {
+ return 0;
+ }
+
+ update = vc_dispmanx_update_start(10);
+ if (!update) {
+ return 0;
+ }
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.width = curdata->w << 16;
+ src_rect.height = curdata->h << 16;
+ dst_rect.x = x;
+ dst_rect.y = y;
+ dst_rect.width = curdata->w;
+ dst_rect.height = curdata->h;
+
+ ret = vc_dispmanx_element_change_attributes(
+ update,
+ curdata->element,
+ 0,
+ 0,
+ 0,
+ &dst_rect,
+ &src_rect,
+ DISPMANX_NO_HANDLE,
+ DISPMANX_NO_ROTATE);
+ if (ret != DISPMANX_SUCCESS) {
+ return SDL_SetError("vc_dispmanx_element_change_attributes() failed");
+ }
+
+ /* Submit asynchronously, otherwise the peformance suffers a lot */
+ ret = vc_dispmanx_update_submit(update, 0, NULL);
+ if (ret != DISPMANX_SUCCESS) {
+ return SDL_SetError("vc_dispmanx_update_submit() failed");
+ }
+ return 0;
+}
+
+void
+RPI_InitMouse(_THIS)
+{
+ /* FIXME: Using UDEV it should be possible to scan all mice
+ * but there's no point in doing so as there's no multimice support...yet!
+ */
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = RPI_CreateCursor;
+ mouse->ShowCursor = RPI_ShowCursor;
+ mouse->MoveCursor = RPI_MoveCursor;
+ mouse->FreeCursor = RPI_FreeCursor;
+ mouse->WarpMouse = RPI_WarpMouse;
+ mouse->WarpMouseGlobal = RPI_WarpMouseGlobal;
+
+ SDL_SetDefaultCursor(RPI_CreateDefaultCursor());
+}
+
+void
+RPI_QuitMouse(_THIS)
+{
+
+}
+
+/* This is called when a mouse motion event occurs */
+static void
+RPI_MoveCursor(SDL_Cursor * cursor)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ /* We must NOT call SDL_SendMouseMotion() on the next call or we will enter recursivity,
+ * so we create a version of WarpMouseGlobal without it. */
+ RPI_WarpMouseGlobalGraphicOnly(mouse->x, mouse->y);
+}
+
+#endif /* SDL_VIDEO_DRIVER_RPI */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.h b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.h
new file mode 100644
index 0000000..919f811
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpimouse.h
@@ -0,0 +1,43 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_RPI_mouse_h_
+#define SDL_RPI_mouse_h_
+
+#include "../SDL_sysvideo.h"
+
+typedef struct _RPI_CursorData RPI_CursorData;
+struct _RPI_CursorData
+{
+ DISPMANX_RESOURCE_HANDLE_T resource;
+ DISPMANX_ELEMENT_HANDLE_T element;
+ int hot_x, hot_y;
+ int w, h;
+};
+
+#define SDL_RPI_CURSORDATA(curs) RPI_CursorData *curdata = (RPI_CursorData *) ((curs) ? (curs)->driverdata : NULL)
+
+extern void RPI_InitMouse(_THIS);
+extern void RPI_QuitMouse(_THIS);
+
+#endif /* SDL_RPI_mouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.c b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.c
new file mode 100644
index 0000000..b763007
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.c
@@ -0,0 +1,71 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+#include "SDL_hints.h"
+#include "SDL_log.h"
+
+#if SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_rpivideo.h"
+#include "SDL_rpiopengles.h"
+
+/* EGL implementation of SDL OpenGL support */
+
+void
+RPI_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor)
+{
+ *mask = SDL_GL_CONTEXT_PROFILE_ES;
+ *major = 2;
+ *minor = 0;
+}
+
+int
+RPI_GLES_LoadLibrary(_THIS, const char *path) {
+ return SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0);
+}
+
+int
+RPI_GLES_SwapWindow(_THIS, SDL_Window * window) {
+ SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata);
+
+ if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed.");
+ return 0;
+ }
+
+ /* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
+ * Run your SDL2 program with "SDL_RPI_DOUBLE_BUFFER=1 <program_name>" to enable this. */
+ if (wdata->double_buffer) {
+ SDL_LockMutex(wdata->vsync_cond_mutex);
+ SDL_CondWait(wdata->vsync_cond, wdata->vsync_cond_mutex);
+ SDL_UnlockMutex(wdata->vsync_cond_mutex);
+ }
+
+ return 0;
+}
+
+SDL_EGL_CreateContext_impl(RPI)
+SDL_EGL_MakeCurrent_impl(RPI)
+
+#endif /* SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.h b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.h
new file mode 100644
index 0000000..9724a5f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpiopengles.h
@@ -0,0 +1,49 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_rpiopengles_h_
+#define SDL_rpiopengles_h_
+
+#if SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define RPI_GLES_GetAttribute SDL_EGL_GetAttribute
+#define RPI_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define RPI_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define RPI_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define RPI_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define RPI_GLES_DeleteContext SDL_EGL_DeleteContext
+
+extern int RPI_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int RPI_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern void RPI_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor);
+
+#endif /* SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_rpiopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.c b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.c
new file mode 100644
index 0000000..c4f4a60
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.c
@@ -0,0 +1,442 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_RPI
+
+/* References
+ * http://elinux.org/RPi_VideoCore_APIs
+ * https://github.com/raspberrypi/firmware/blob/master/opt/vc/src/hello_pi/hello_triangle/triangle.c
+ * http://cgit.freedesktop.org/wayland/weston/tree/src/rpi-renderer.c
+ * http://cgit.freedesktop.org/wayland/weston/tree/src/compositor-rpi.c
+ */
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_version.h"
+#include "SDL_syswm.h"
+#include "SDL_loadso.h"
+#include "SDL_events.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "SDL_hints.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+/* RPI declarations */
+#include "SDL_rpivideo.h"
+#include "SDL_rpievents_c.h"
+#include "SDL_rpiopengles.h"
+#include "SDL_rpimouse.h"
+
+static int
+RPI_Available(void)
+{
+ return 1;
+}
+
+static void
+RPI_Destroy(SDL_VideoDevice * device)
+{
+ SDL_free(device->driverdata);
+ SDL_free(device);
+}
+
+static int
+RPI_GetRefreshRate()
+{
+ TV_DISPLAY_STATE_T tvstate;
+ if (vc_tv_get_display_state( &tvstate ) == 0) {
+ //The width/height parameters are in the same position in the union
+ //for HDMI and SDTV
+ HDMI_PROPERTY_PARAM_T property;
+ property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
+ vc_tv_hdmi_get_property(&property);
+ return property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ?
+ tvstate.display.hdmi.frame_rate * (1000.0f/1001.0f) :
+ tvstate.display.hdmi.frame_rate;
+ }
+ return 60; /* Failed to get display state, default to 60 */
+}
+
+static SDL_VideoDevice *
+RPI_Create()
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *phdata;
+
+ /* Initialize SDL_VideoDevice structure */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Initialize internal data */
+ phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (phdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return NULL;
+ }
+
+ device->driverdata = phdata;
+
+ /* Setup amount of available displays */
+ device->num_displays = 0;
+
+ /* Set device free function */
+ device->free = RPI_Destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit = RPI_VideoInit;
+ device->VideoQuit = RPI_VideoQuit;
+ device->GetDisplayModes = RPI_GetDisplayModes;
+ device->SetDisplayMode = RPI_SetDisplayMode;
+ device->CreateSDLWindow = RPI_CreateWindow;
+ device->CreateSDLWindowFrom = RPI_CreateWindowFrom;
+ device->SetWindowTitle = RPI_SetWindowTitle;
+ device->SetWindowIcon = RPI_SetWindowIcon;
+ device->SetWindowPosition = RPI_SetWindowPosition;
+ device->SetWindowSize = RPI_SetWindowSize;
+ device->ShowWindow = RPI_ShowWindow;
+ device->HideWindow = RPI_HideWindow;
+ device->RaiseWindow = RPI_RaiseWindow;
+ device->MaximizeWindow = RPI_MaximizeWindow;
+ device->MinimizeWindow = RPI_MinimizeWindow;
+ device->RestoreWindow = RPI_RestoreWindow;
+ device->SetWindowGrab = RPI_SetWindowGrab;
+ device->DestroyWindow = RPI_DestroyWindow;
+#if 0
+ device->GetWindowWMInfo = RPI_GetWindowWMInfo;
+#endif
+ device->GL_LoadLibrary = RPI_GLES_LoadLibrary;
+ device->GL_GetProcAddress = RPI_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = RPI_GLES_UnloadLibrary;
+ device->GL_CreateContext = RPI_GLES_CreateContext;
+ device->GL_MakeCurrent = RPI_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = RPI_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = RPI_GLES_GetSwapInterval;
+ device->GL_SwapWindow = RPI_GLES_SwapWindow;
+ device->GL_DeleteContext = RPI_GLES_DeleteContext;
+ device->GL_DefaultProfileConfig = RPI_GLES_DefaultProfileConfig;
+
+ device->PumpEvents = RPI_PumpEvents;
+
+ return device;
+}
+
+VideoBootStrap RPI_bootstrap = {
+ "RPI",
+ "RPI Video Driver",
+ RPI_Available,
+ RPI_Create
+};
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions */
+/*****************************************************************************/
+int
+RPI_VideoInit(_THIS)
+{
+ SDL_VideoDisplay display;
+ SDL_DisplayMode current_mode;
+ SDL_DisplayData *data;
+ uint32_t w,h;
+
+ /* Initialize BCM Host */
+ bcm_host_init();
+
+ SDL_zero(current_mode);
+
+ if (graphics_get_display_size( 0, &w, &h) < 0) {
+ return -1;
+ }
+
+ current_mode.w = w;
+ current_mode.h = h;
+ current_mode.refresh_rate = RPI_GetRefreshRate();
+ /* 32 bpp for default */
+ current_mode.format = SDL_PIXELFORMAT_ABGR8888;
+
+ current_mode.driverdata = NULL;
+
+ SDL_zero(display);
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+
+ /* Allocate display internal data */
+ data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
+ if (data == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ data->dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
+
+ display.driverdata = data;
+
+ SDL_AddVideoDisplay(&display);
+
+#ifdef SDL_INPUT_LINUXEV
+ if (SDL_EVDEV_Init() < 0) {
+ return -1;
+ }
+#endif
+
+ RPI_InitMouse(_this);
+
+ return 1;
+}
+
+void
+RPI_VideoQuit(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Quit();
+#endif
+}
+
+void
+RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ /* Only one display mode available, the current one */
+ SDL_AddDisplayMode(display, &display->current_mode);
+}
+
+int
+RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+static void
+RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data)
+{
+ SDL_WindowData *wdata = ((SDL_WindowData *) data);
+
+ SDL_LockMutex(wdata->vsync_cond_mutex);
+ SDL_CondSignal(wdata->vsync_cond);
+ SDL_UnlockMutex(wdata->vsync_cond_mutex);
+}
+
+int
+RPI_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wdata;
+ SDL_VideoDisplay *display;
+ SDL_DisplayData *displaydata;
+ VC_RECT_T dst_rect;
+ VC_RECT_T src_rect;
+ VC_DISPMANX_ALPHA_T dispman_alpha;
+ DISPMANX_UPDATE_HANDLE_T dispman_update;
+ uint32_t layer = SDL_RPI_VIDEOLAYER;
+ const char *env;
+
+ /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
+ dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
+ dispman_alpha.opacity = 0xFF;
+ dispman_alpha.mask = 0;
+
+ /* Allocate window internal data */
+ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (wdata == NULL) {
+ return SDL_OutOfMemory();
+ }
+ display = SDL_GetDisplayForWindow(window);
+ displaydata = (SDL_DisplayData *) display->driverdata;
+
+ /* Windows have one size for now */
+ window->w = display->desktop_mode.w;
+ window->h = display->desktop_mode.h;
+
+ /* OpenGL ES is the law here, buddy */
+ window->flags |= SDL_WINDOW_OPENGL;
+
+ /* Create a dispman element and associate a window to it */
+ dst_rect.x = 0;
+ dst_rect.y = 0;
+ dst_rect.width = window->w;
+ dst_rect.height = window->h;
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.width = window->w << 16;
+ src_rect.height = window->h << 16;
+
+ env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER);
+ if (env) {
+ layer = SDL_atoi(env);
+ }
+
+ dispman_update = vc_dispmanx_update_start( 0 );
+ wdata->dispman_window.element = vc_dispmanx_element_add (dispman_update,
+ displaydata->dispman_display,
+ layer /* layer */,
+ &dst_rect,
+ 0 /*src*/,
+ &src_rect,
+ DISPMANX_PROTECTION_NONE,
+ &dispman_alpha /*alpha*/,
+ 0 /*clamp*/,
+ 0 /*transform*/);
+ wdata->dispman_window.width = window->w;
+ wdata->dispman_window.height = window->h;
+ vc_dispmanx_update_submit_sync(dispman_update);
+
+ if (!_this->egl_data) {
+ if (SDL_GL_LoadLibrary(NULL) < 0) {
+ return -1;
+ }
+ }
+ wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window);
+
+ if (wdata->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("Could not create GLES window surface");
+ }
+
+ /* Start generating vsync callbacks if necesary */
+ wdata->double_buffer = SDL_FALSE;
+ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
+ wdata->vsync_cond = SDL_CreateCond();
+ wdata->vsync_cond_mutex = SDL_CreateMutex();
+ wdata->double_buffer = SDL_TRUE;
+ vc_dispmanx_vsync_callback(displaydata->dispman_display, RPI_vsync_callback, (void*)wdata);
+ }
+
+ /* Setup driver data for this window */
+ window->driverdata = wdata;
+
+ /* One window, it always has focus */
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+
+ /* Window has been successfully created */
+ return 0;
+}
+
+void
+RPI_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
+
+ if(data) {
+ if (data->double_buffer) {
+ /* Wait for vsync, and then stop vsync callbacks and destroy related stuff, if needed */
+ SDL_LockMutex(data->vsync_cond_mutex);
+ SDL_CondWait(data->vsync_cond, data->vsync_cond_mutex);
+ SDL_UnlockMutex(data->vsync_cond_mutex);
+
+ vc_dispmanx_vsync_callback(displaydata->dispman_display, NULL, NULL);
+
+ SDL_DestroyCond(data->vsync_cond);
+ SDL_DestroyMutex(data->vsync_cond_mutex);
+ }
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (data->egl_surface != EGL_NO_SURFACE) {
+ SDL_EGL_DestroySurface(_this, data->egl_surface);
+ }
+#endif
+ SDL_free(data);
+ window->driverdata = NULL;
+ }
+}
+
+int
+RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ return -1;
+}
+
+void
+RPI_SetWindowTitle(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+}
+void
+RPI_SetWindowPosition(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_SetWindowSize(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_ShowWindow(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_HideWindow(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_RaiseWindow(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_MaximizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_MinimizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_RestoreWindow(_THIS, SDL_Window * window)
+{
+}
+void
+RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function */
+/*****************************************************************************/
+#if 0
+SDL_bool
+RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+
+ /* Failed to get window manager information */
+ return SDL_FALSE;
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_RPI */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.h b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.h
new file mode 100644
index 0000000..b2eb670
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/raspberry/SDL_rpivideo.h
@@ -0,0 +1,104 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __SDL_RPIVIDEO_H__
+#define __SDL_RPIVIDEO_H__
+
+#include "../../SDL_internal.h"
+#include "../SDL_sysvideo.h"
+
+#include <bcm_host.h>
+#include "GLES/gl.h"
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+typedef struct SDL_VideoData
+{
+ uint32_t egl_refcount; /* OpenGL ES reference count */
+} SDL_VideoData;
+
+
+typedef struct SDL_DisplayData
+{
+ DISPMANX_DISPLAY_HANDLE_T dispman_display;
+} SDL_DisplayData;
+
+
+typedef struct SDL_WindowData
+{
+ EGL_DISPMANX_WINDOW_T dispman_window;
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+
+ /* Vsync callback cond and mutex */
+ SDL_cond *vsync_cond;
+ SDL_mutex *vsync_cond_mutex;
+ SDL_bool double_buffer;
+
+} SDL_WindowData;
+
+#define SDL_RPI_VIDEOLAYER 10000 /* High enough so to occlude everything */
+#define SDL_RPI_MOUSELAYER SDL_RPI_VIDEOLAYER + 1
+
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration */
+/****************************************************************************/
+
+/* Display and window functions */
+int RPI_VideoInit(_THIS);
+void RPI_VideoQuit(_THIS);
+void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int RPI_CreateWindow(_THIS, SDL_Window * window);
+int RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+void RPI_SetWindowTitle(_THIS, SDL_Window * window);
+void RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+void RPI_SetWindowPosition(_THIS, SDL_Window * window);
+void RPI_SetWindowSize(_THIS, SDL_Window * window);
+void RPI_ShowWindow(_THIS, SDL_Window * window);
+void RPI_HideWindow(_THIS, SDL_Window * window);
+void RPI_RaiseWindow(_THIS, SDL_Window * window);
+void RPI_MaximizeWindow(_THIS, SDL_Window * window);
+void RPI_MinimizeWindow(_THIS, SDL_Window * window);
+void RPI_RestoreWindow(_THIS, SDL_Window * window);
+void RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+void RPI_DestroyWindow(_THIS, SDL_Window * window);
+
+/* Window manager function */
+SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+/* OpenGL/OpenGL ES functions */
+int RPI_GLES_LoadLibrary(_THIS, const char *path);
+void *RPI_GLES_GetProcAddress(_THIS, const char *proc);
+void RPI_GLES_UnloadLibrary(_THIS);
+SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window * window);
+int RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int RPI_GLES_SetSwapInterval(_THIS, int interval);
+int RPI_GLES_GetSwapInterval(_THIS);
+int RPI_GLES_SwapWindow(_THIS, SDL_Window * window);
+void RPI_GLES_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* __SDL_RPIVIDEO_H__ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/sdlgenblit.pl b/source/3rd-party/SDL2/src/video/sdlgenblit.pl
new file mode 100644
index 0000000..d89ae2a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/sdlgenblit.pl
@@ -0,0 +1,535 @@
+#!/usr/bin/perl -w
+#
+# A script to generate optimized C blitters for Simple DirectMedia Layer
+# http://www.libsdl.org/
+
+use warnings;
+use strict;
+
+my %file;
+
+# The formats potentially supported by this script:
+# SDL_PIXELFORMAT_RGB332
+# SDL_PIXELFORMAT_RGB444
+# SDL_PIXELFORMAT_RGB555
+# SDL_PIXELFORMAT_ARGB4444
+# SDL_PIXELFORMAT_ARGB1555
+# SDL_PIXELFORMAT_RGB565
+# SDL_PIXELFORMAT_RGB24
+# SDL_PIXELFORMAT_BGR24
+# SDL_PIXELFORMAT_RGB888
+# SDL_PIXELFORMAT_BGR888
+# SDL_PIXELFORMAT_ARGB8888
+# SDL_PIXELFORMAT_RGBA8888
+# SDL_PIXELFORMAT_ABGR8888
+# SDL_PIXELFORMAT_BGRA8888
+# SDL_PIXELFORMAT_ARGB2101010
+
+# The formats we're actually creating blitters for:
+my @src_formats = (
+ "RGB888",
+ "BGR888",
+ "ARGB8888",
+ "RGBA8888",
+ "ABGR8888",
+ "BGRA8888",
+);
+my @dst_formats = (
+ "RGB888",
+ "BGR888",
+ "ARGB8888",
+);
+
+my %format_size = (
+ "RGB888" => 4,
+ "BGR888" => 4,
+ "ARGB8888" => 4,
+ "RGBA8888" => 4,
+ "ABGR8888" => 4,
+ "BGRA8888" => 4,
+);
+
+my %format_type = (
+ "RGB888" => "Uint32",
+ "BGR888" => "Uint32",
+ "ARGB8888" => "Uint32",
+ "RGBA8888" => "Uint32",
+ "ABGR8888" => "Uint32",
+ "BGRA8888" => "Uint32",
+);
+
+my %get_rgba_string_ignore_alpha = (
+ "RGB888" => "_R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel;",
+ "BGR888" => "_B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel;",
+ "ARGB8888" => "_R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel;",
+ "RGBA8888" => "_R = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _B = (Uint8)(_pixel >> 8);",
+ "ABGR8888" => "_B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel;",
+ "BGRA8888" => "_B = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _R = (Uint8)(_pixel >> 8);",
+);
+
+my %get_rgba_string = (
+ "RGB888" => $get_rgba_string_ignore_alpha{"RGB888"} . " _A = 0xFF;",
+ "BGR888" => $get_rgba_string_ignore_alpha{"BGR888"} . " _A = 0xFF;",
+ "ARGB8888" => $get_rgba_string_ignore_alpha{"ARGB8888"} . " _A = (Uint8)(_pixel >> 24);",
+ "RGBA8888" => $get_rgba_string_ignore_alpha{"RGBA8888"} . " _A = (Uint8)_pixel;",
+ "ABGR8888" => $get_rgba_string_ignore_alpha{"ABGR8888"} . " _A = (Uint8)(_pixel >> 24);",
+ "BGRA8888" => $get_rgba_string_ignore_alpha{"BGRA8888"} . " _A = (Uint8)_pixel;",
+);
+
+my %set_rgba_string = (
+ "RGB888" => "_pixel = ((Uint32)_R << 16) | ((Uint32)_G << 8) | _B;",
+ "BGR888" => "_pixel = ((Uint32)_B << 16) | ((Uint32)_G << 8) | _R;",
+ "ARGB8888" => "_pixel = ((Uint32)_A << 24) | ((Uint32)_R << 16) | ((Uint32)_G << 8) | _B;",
+ "RGBA8888" => "_pixel = ((Uint32)_R << 24) | ((Uint32)_G << 16) | ((Uint32)_B << 8) | _A;",
+ "ABGR8888" => "_pixel = ((Uint32)_A << 24) | ((Uint32)_B << 16) | ((Uint32)_G << 8) | _R;",
+ "BGRA8888" => "_pixel = ((Uint32)_B << 24) | ((Uint32)_G << 16) | ((Uint32)_R << 8) | _A;",
+);
+
+sub open_file {
+ my $name = shift;
+ open(FILE, ">$name.new") || die "Cant' open $name.new: $!";
+ print FILE <<__EOF__;
+/* DO NOT EDIT! This file is generated by sdlgenblit.pl */
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken\@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../SDL_internal.h"
+
+/* *INDENT-OFF* */
+
+__EOF__
+}
+
+sub close_file {
+ my $name = shift;
+ print FILE <<__EOF__;
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
+__EOF__
+ close FILE;
+ if ( ! -f $name || system("cmp -s $name $name.new") != 0 ) {
+ rename("$name.new", "$name");
+ } else {
+ unlink("$name.new");
+ }
+}
+
+sub output_copydefs
+{
+ print FILE <<__EOF__;
+extern SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[];
+__EOF__
+}
+
+sub output_copyfuncname
+{
+ my $prefix = shift;
+ my $src = shift;
+ my $dst = shift;
+ my $modulate = shift;
+ my $blend = shift;
+ my $scale = shift;
+ my $args = shift;
+ my $suffix = shift;
+
+ print FILE "$prefix SDL_Blit_${src}_${dst}";
+ if ( $modulate ) {
+ print FILE "_Modulate";
+ }
+ if ( $blend ) {
+ print FILE "_Blend";
+ }
+ if ( $scale ) {
+ print FILE "_Scale";
+ }
+ if ( $args ) {
+ print FILE "(SDL_BlitInfo *info)";
+ }
+ print FILE "$suffix";
+}
+
+sub get_rgba
+{
+ my $prefix = shift;
+ my $format = shift;
+ my $ignore_alpha = shift;
+
+ my $string;
+ if ($ignore_alpha) {
+ $string = $get_rgba_string_ignore_alpha{$format};
+ } else {
+ $string = $get_rgba_string{$format};
+ }
+
+ $string =~ s/_/$prefix/g;
+ if ( $prefix ne "" ) {
+ print FILE <<__EOF__;
+ ${prefix}pixel = *$prefix;
+__EOF__
+ } else {
+ print FILE <<__EOF__;
+ pixel = *src;
+__EOF__
+ }
+ print FILE <<__EOF__;
+ $string
+__EOF__
+}
+
+sub set_rgba
+{
+ my $prefix = shift;
+ my $format = shift;
+ my $string = $set_rgba_string{$format};
+ $string =~ s/_/$prefix/g;
+ print FILE <<__EOF__;
+ $string
+ *dst = ${prefix}pixel;
+__EOF__
+}
+
+sub output_copycore
+{
+ my $src = shift;
+ my $dst = shift;
+ my $modulate = shift;
+ my $blend = shift;
+ my $s = "";
+ my $d = "";
+
+ # Nice and easy...
+ if ( $src eq $dst && !$modulate && !$blend ) {
+ print FILE <<__EOF__;
+ *dst = *src;
+__EOF__
+ return;
+ }
+
+ my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0;
+ my $ignore_dst_alpha = !$dst_has_alpha && !$blend;
+
+ if ( $blend ) {
+ get_rgba("src", $src, $ignore_dst_alpha);
+ get_rgba("dst", $dst, !$dst_has_alpha);
+ $s = "src";
+ $d = "dst";
+ } else {
+ get_rgba("", $src, $ignore_dst_alpha);
+ }
+
+ if ( $modulate ) {
+ print FILE <<__EOF__;
+ if (flags & SDL_COPY_MODULATE_COLOR) {
+ ${s}R = (${s}R * modulateR) / 255;
+ ${s}G = (${s}G * modulateG) / 255;
+ ${s}B = (${s}B * modulateB) / 255;
+ }
+__EOF__
+ if (not $ignore_dst_alpha) {
+ print FILE <<__EOF__;
+ if (flags & SDL_COPY_MODULATE_ALPHA) {
+ ${s}A = (${s}A * modulateA) / 255;
+ }
+__EOF__
+ }
+ }
+ if ( $blend ) {
+ print FILE <<__EOF__;
+ if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
+ /* This goes away if we ever use premultiplied alpha */
+ if (${s}A < 255) {
+ ${s}R = (${s}R * ${s}A) / 255;
+ ${s}G = (${s}G * ${s}A) / 255;
+ ${s}B = (${s}B * ${s}A) / 255;
+ }
+ }
+ switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
+ case SDL_COPY_BLEND:
+ ${d}R = ${s}R + ((255 - ${s}A) * ${d}R) / 255;
+ ${d}G = ${s}G + ((255 - ${s}A) * ${d}G) / 255;
+ ${d}B = ${s}B + ((255 - ${s}A) * ${d}B) / 255;
+__EOF__
+
+ if ( $dst_has_alpha ) {
+ print FILE <<__EOF__;
+ ${d}A = ${s}A + ((255 - ${s}A) * ${d}A) / 255;
+__EOF__
+ }
+
+ print FILE <<__EOF__;
+ break;
+ case SDL_COPY_ADD:
+ ${d}R = ${s}R + ${d}R; if (${d}R > 255) ${d}R = 255;
+ ${d}G = ${s}G + ${d}G; if (${d}G > 255) ${d}G = 255;
+ ${d}B = ${s}B + ${d}B; if (${d}B > 255) ${d}B = 255;
+ break;
+ case SDL_COPY_MOD:
+ ${d}R = (${s}R * ${d}R) / 255;
+ ${d}G = (${s}G * ${d}G) / 255;
+ ${d}B = (${s}B * ${d}B) / 255;
+ break;
+ }
+__EOF__
+ }
+ if ( $blend ) {
+ set_rgba("dst", $dst);
+ } else {
+ set_rgba("", $dst);
+ }
+}
+
+sub output_copyfunc
+{
+ my $src = shift;
+ my $dst = shift;
+ my $modulate = shift;
+ my $blend = shift;
+ my $scale = shift;
+
+ my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0;
+ my $ignore_dst_alpha = !$dst_has_alpha && !$blend;
+
+ output_copyfuncname("static void", $src, $dst, $modulate, $blend, $scale, 1, "\n");
+ print FILE <<__EOF__;
+{
+__EOF__
+ if ( $modulate || $blend ) {
+ print FILE <<__EOF__;
+ const int flags = info->flags;
+__EOF__
+ }
+ if ( $modulate ) {
+ print FILE <<__EOF__;
+ const Uint32 modulateR = info->r;
+ const Uint32 modulateG = info->g;
+ const Uint32 modulateB = info->b;
+__EOF__
+ if (!$ignore_dst_alpha) {
+ print FILE <<__EOF__;
+ const Uint32 modulateA = info->a;
+__EOF__
+ }
+ }
+ if ( $blend ) {
+ print FILE <<__EOF__;
+ Uint32 srcpixel;
+ Uint32 srcR, srcG, srcB, srcA;
+ Uint32 dstpixel;
+__EOF__
+ if ($dst_has_alpha) {
+ print FILE <<__EOF__;
+ Uint32 dstR, dstG, dstB, dstA;
+__EOF__
+ } else {
+ print FILE <<__EOF__;
+ Uint32 dstR, dstG, dstB;
+__EOF__
+ }
+ } elsif ( $modulate || $src ne $dst ) {
+ print FILE <<__EOF__;
+ Uint32 pixel;
+__EOF__
+ if (!$ignore_dst_alpha) {
+ print FILE <<__EOF__;
+ Uint32 R, G, B, A;
+__EOF__
+ } else {
+ print FILE <<__EOF__;
+ Uint32 R, G, B;
+__EOF__
+ }
+ }
+ if ( $scale ) {
+ print FILE <<__EOF__;
+ int srcy, srcx;
+ int posy, posx;
+ int incy, incx;
+__EOF__
+
+ print FILE <<__EOF__;
+
+ srcy = 0;
+ posy = 0;
+ incy = (info->src_h << 16) / info->dst_h;
+ incx = (info->src_w << 16) / info->dst_w;
+
+ while (info->dst_h--) {
+ $format_type{$src} *src = 0;
+ $format_type{$dst} *dst = ($format_type{$dst} *)info->dst;
+ int n = info->dst_w;
+ srcx = -1;
+ posx = 0x10000L;
+ while (posy >= 0x10000L) {
+ ++srcy;
+ posy -= 0x10000L;
+ }
+ while (n--) {
+ if (posx >= 0x10000L) {
+ while (posx >= 0x10000L) {
+ ++srcx;
+ posx -= 0x10000L;
+ }
+ src = ($format_type{$src} *)(info->src + (srcy * info->src_pitch) + (srcx * $format_size{$src}));
+__EOF__
+ print FILE <<__EOF__;
+ }
+__EOF__
+ output_copycore($src, $dst, $modulate, $blend);
+ print FILE <<__EOF__;
+ posx += incx;
+ ++dst;
+ }
+ posy += incy;
+ info->dst += info->dst_pitch;
+ }
+__EOF__
+ } else {
+ print FILE <<__EOF__;
+
+ while (info->dst_h--) {
+ $format_type{$src} *src = ($format_type{$src} *)info->src;
+ $format_type{$dst} *dst = ($format_type{$dst} *)info->dst;
+ int n = info->dst_w;
+ while (n--) {
+__EOF__
+ output_copycore($src, $dst, $modulate, $blend);
+ print FILE <<__EOF__;
+ ++src;
+ ++dst;
+ }
+ info->src += info->src_pitch;
+ info->dst += info->dst_pitch;
+ }
+__EOF__
+ }
+ print FILE <<__EOF__;
+}
+
+__EOF__
+}
+
+sub output_copyfunc_h
+{
+}
+
+sub output_copyinc
+{
+ print FILE <<__EOF__;
+#include "SDL_video.h"
+#include "SDL_blit.h"
+#include "SDL_blit_auto.h"
+
+__EOF__
+}
+
+sub output_copyfunctable
+{
+ print FILE <<__EOF__;
+SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[] = {
+__EOF__
+ for (my $i = 0; $i <= $#src_formats; ++$i) {
+ my $src = $src_formats[$i];
+ for (my $j = 0; $j <= $#dst_formats; ++$j) {
+ my $dst = $dst_formats[$j];
+ for (my $modulate = 0; $modulate <= 1; ++$modulate) {
+ for (my $blend = 0; $blend <= 1; ++$blend) {
+ for (my $scale = 0; $scale <= 1; ++$scale) {
+ if ( $modulate || $blend || $scale ) {
+ print FILE " { SDL_PIXELFORMAT_$src, SDL_PIXELFORMAT_$dst, ";
+ my $flags = "";
+ my $flag = "";
+ if ( $modulate ) {
+ $flag = "SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA";
+ if ( $flags eq "" ) {
+ $flags = $flag;
+ } else {
+ $flags = "$flags | $flag";
+ }
+ }
+ if ( $blend ) {
+ $flag = "SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD";
+ if ( $flags eq "" ) {
+ $flags = $flag;
+ } else {
+ $flags = "$flags | $flag";
+ }
+ }
+ if ( $scale ) {
+ $flag = "SDL_COPY_NEAREST";
+ if ( $flags eq "" ) {
+ $flags = $flag;
+ } else {
+ $flags = "$flags | $flag";
+ }
+ }
+ if ( $flags eq "" ) {
+ $flags = "0";
+ }
+ print FILE "($flags), SDL_CPU_ANY,";
+ output_copyfuncname("", $src_formats[$i], $dst_formats[$j], $modulate, $blend, $scale, 0, " },\n");
+ }
+ }
+ }
+ }
+ }
+ }
+ print FILE <<__EOF__;
+ { 0, 0, 0, 0, NULL }
+};
+
+__EOF__
+}
+
+sub output_copyfunc_c
+{
+ my $src = shift;
+ my $dst = shift;
+
+ for (my $modulate = 0; $modulate <= 1; ++$modulate) {
+ for (my $blend = 0; $blend <= 1; ++$blend) {
+ for (my $scale = 0; $scale <= 1; ++$scale) {
+ if ( $modulate || $blend || $scale ) {
+ output_copyfunc($src, $dst, $modulate, $blend, $scale);
+ }
+ }
+ }
+ }
+}
+
+open_file("SDL_blit_auto.h");
+output_copydefs();
+for (my $i = 0; $i <= $#src_formats; ++$i) {
+ for (my $j = 0; $j <= $#dst_formats; ++$j) {
+ output_copyfunc_h($src_formats[$i], $dst_formats[$j]);
+ }
+}
+print FILE "\n";
+close_file("SDL_blit_auto.h");
+
+open_file("SDL_blit_auto.c");
+output_copyinc();
+for (my $i = 0; $i <= $#src_formats; ++$i) {
+ for (my $j = 0; $j <= $#dst_formats; ++$j) {
+ output_copyfunc_c($src_formats[$i], $dst_formats[$j]);
+ }
+}
+output_copyfunctable();
+close_file("SDL_blit_auto.c");
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h
new file mode 100644
index 0000000..34b0138
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#import <UIKit/UIKit.h>
+
+@interface SDLLaunchScreenController : UIViewController
+
+- (instancetype)init;
+- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
+- (void)loadView;
+
+@end
+
+@interface SDLUIKitDelegate : NSObject<UIApplicationDelegate>
+
++ (id)sharedAppDelegate;
++ (NSString *)getAppDelegateClassName;
+
+- (void)hideLaunchScreen;
+
+/* This property is marked as optional, and is only intended to be used when
+ * the app's UI is storyboard-based. SDL is not storyboard-based, however
+ * several major third-party ad APIs (e.g. Google admob) incorrectly assume this
+ * property always exists, and will crash if it doesn't. */
+@property (nonatomic) UIWindow *window;
+
+@end
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m
new file mode 100644
index 0000000..15762d2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m
@@ -0,0 +1,516 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "../SDL_sysvideo.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "SDL_system.h"
+#include "SDL_main.h"
+
+#import "SDL_uikitappdelegate.h"
+#import "SDL_uikitmodes.h"
+#import "SDL_uikitwindow.h"
+
+#include "../../events/SDL_events_c.h"
+
+#ifdef main
+#undef main
+#endif
+
+static int forward_argc;
+static char **forward_argv;
+static int exit_status;
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ /* store arguments */
+ forward_argc = argc;
+ forward_argv = (char **)malloc((argc+1) * sizeof(char *));
+ for (i = 0; i < argc; i++) {
+ forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
+ strcpy(forward_argv[i], argv[i]);
+ }
+ forward_argv[i] = NULL;
+
+ /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
+ @autoreleasepool {
+ UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
+ }
+
+ /* free the memory we used to hold copies of argc and argv */
+ for (i = 0; i < forward_argc; i++) {
+ free(forward_argv[i]);
+ }
+ free(forward_argv);
+
+ return exit_status;
+}
+
+static void SDLCALL
+SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ BOOL disable = (hint && *hint != '0');
+ [UIApplication sharedApplication].idleTimerDisabled = disable;
+}
+
+#if !TARGET_OS_TV
+/* Load a launch image using the old UILaunchImageFile-era naming rules. */
+static UIImage *
+SDL_LoadLaunchImageNamed(NSString *name, int screenh)
+{
+ UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
+ UIUserInterfaceIdiom idiom = [UIDevice currentDevice].userInterfaceIdiom;
+ UIImage *image = nil;
+
+ if (idiom == UIUserInterfaceIdiomPhone && screenh == 568) {
+ /* The image name for the iPhone 5 uses its height as a suffix. */
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-568h", name]];
+ } else if (idiom == UIUserInterfaceIdiomPad) {
+ /* iPad apps can launch in any orientation. */
+ if (UIInterfaceOrientationIsLandscape(curorient)) {
+ if (curorient == UIInterfaceOrientationLandscapeLeft) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-LandscapeLeft", name]];
+ } else {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-LandscapeRight", name]];
+ }
+ if (!image) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-Landscape", name]];
+ }
+ } else {
+ if (curorient == UIInterfaceOrientationPortraitUpsideDown) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-PortraitUpsideDown", name]];
+ }
+ if (!image) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-Portrait", name]];
+ }
+ }
+ }
+
+ if (!image) {
+ image = [UIImage imageNamed:name];
+ }
+
+ return image;
+}
+#endif /* !TARGET_OS_TV */
+
+@interface SDLLaunchScreenController ()
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations;
+#endif
+
+@end
+
+@implementation SDLLaunchScreenController
+
+- (instancetype)init
+{
+ return [self initWithNibName:nil bundle:[NSBundle mainBundle]];
+}
+
+- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ if (!(self = [super initWithNibName:nil bundle:nil])) {
+ return nil;
+ }
+
+ NSString *screenname = nibNameOrNil;
+ NSBundle *bundle = nibBundleOrNil;
+ BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0);
+
+ /* Launch screens were added in iOS 8. Otherwise we use launch images. */
+ if (screenname && atleastiOS8) {
+ @try {
+ self.view = [bundle loadNibNamed:screenname owner:self options:nil][0];
+ }
+ @catch (NSException *exception) {
+ /* If a launch screen name is specified but it fails to load, iOS
+ * displays a blank screen rather than falling back to an image. */
+ return nil;
+ }
+ }
+
+ if (!self.view) {
+ NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
+ NSString *imagename = nil;
+ UIImage *image = nil;
+
+ int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5);
+ int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5);
+
+#if !TARGET_OS_TV
+ UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
+
+ /* We always want portrait-oriented size, to match UILaunchImageSize. */
+ if (screenw > screenh) {
+ int width = screenw;
+ screenw = screenh;
+ screenh = width;
+ }
+#endif
+
+ /* Xcode 5 introduced a dictionary of launch images in Info.plist. */
+ if (launchimages) {
+ for (NSDictionary *dict in launchimages) {
+ NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"];
+ NSString *sizestring = dict[@"UILaunchImageSize"];
+
+ /* Ignore this image if the current version is too low. */
+ if (minversion && !UIKit_IsSystemVersionAtLeast(minversion.doubleValue)) {
+ continue;
+ }
+
+ /* Ignore this image if the size doesn't match. */
+ if (sizestring) {
+ CGSize size = CGSizeFromString(sizestring);
+ if ((int)(size.width + 0.5) != screenw || (int)(size.height + 0.5) != screenh) {
+ continue;
+ }
+ }
+
+#if !TARGET_OS_TV
+ UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
+ NSString *orientstring = dict[@"UILaunchImageOrientation"];
+
+ if (orientstring) {
+ if ([orientstring isEqualToString:@"PortraitUpsideDown"]) {
+ orientmask = UIInterfaceOrientationMaskPortraitUpsideDown;
+ } else if ([orientstring isEqualToString:@"Landscape"]) {
+ orientmask = UIInterfaceOrientationMaskLandscape;
+ } else if ([orientstring isEqualToString:@"LandscapeLeft"]) {
+ orientmask = UIInterfaceOrientationMaskLandscapeLeft;
+ } else if ([orientstring isEqualToString:@"LandscapeRight"]) {
+ orientmask = UIInterfaceOrientationMaskLandscapeRight;
+ }
+ }
+
+ /* Ignore this image if the orientation doesn't match. */
+ if ((orientmask & (1 << curorient)) == 0) {
+ continue;
+ }
+#endif
+
+ imagename = dict[@"UILaunchImageName"];
+ }
+
+ if (imagename) {
+ image = [UIImage imageNamed:imagename];
+ }
+ }
+#if !TARGET_OS_TV
+ else {
+ imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"];
+
+ if (imagename) {
+ image = SDL_LoadLaunchImageNamed(imagename, screenh);
+ }
+
+ if (!image) {
+ image = SDL_LoadLaunchImageNamed(@"Default", screenh);
+ }
+ }
+#endif
+
+ if (image) {
+ UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
+ UIImageOrientation imageorient = UIImageOrientationUp;
+
+#if !TARGET_OS_TV
+ /* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */
+ if (UIInterfaceOrientationIsLandscape(curorient)) {
+ if (atleastiOS8 && image.size.width < image.size.height) {
+ /* On iOS 8, portrait launch images displayed in forced-
+ * landscape mode (e.g. a standard Default.png on an iPhone
+ * when Info.plist only supports landscape orientations) need
+ * to be rotated to display in the expected orientation. */
+ if (curorient == UIInterfaceOrientationLandscapeLeft) {
+ imageorient = UIImageOrientationRight;
+ } else if (curorient == UIInterfaceOrientationLandscapeRight) {
+ imageorient = UIImageOrientationLeft;
+ }
+ } else if (!atleastiOS8 && image.size.width > image.size.height) {
+ /* On iOS 7 and below, landscape launch images displayed in
+ * landscape mode (e.g. landscape iPad launch images) need
+ * to be rotated to display in the expected orientation. */
+ if (curorient == UIInterfaceOrientationLandscapeLeft) {
+ imageorient = UIImageOrientationLeft;
+ } else if (curorient == UIInterfaceOrientationLandscapeRight) {
+ imageorient = UIImageOrientationRight;
+ }
+ }
+ }
+#endif
+
+ /* Create the properly oriented image. */
+ view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient];
+
+ self.view = view;
+ }
+ }
+
+ return self;
+}
+
+- (void)loadView
+{
+ /* Do nothing. */
+}
+
+#if !TARGET_OS_TV
+- (BOOL)shouldAutorotate
+{
+ /* If YES, the launch image will be incorrectly rotated in some cases. */
+ return NO;
+}
+
+- (NSUInteger)supportedInterfaceOrientations
+{
+ /* We keep the supported orientations unrestricted to avoid the case where
+ * there are no common orientations between the ones set in Info.plist and
+ * the ones set here (it will cause an exception in that case.) */
+ return UIInterfaceOrientationMaskAll;
+}
+#endif /* !TARGET_OS_TV */
+
+@end
+
+@implementation SDLUIKitDelegate {
+ UIWindow *launchWindow;
+}
+
+/* convenience method */
++ (id)sharedAppDelegate
+{
+ /* the delegate is set in UIApplicationMain(), which is guaranteed to be
+ * called before this method */
+ return [UIApplication sharedApplication].delegate;
+}
+
++ (NSString *)getAppDelegateClassName
+{
+ /* subclassing notice: when you subclass this appdelegate, make sure to add
+ * a category to override this method and return the actual name of the
+ * delegate */
+ return @"SDLUIKitDelegate";
+}
+
+- (void)hideLaunchScreen
+{
+ UIWindow *window = launchWindow;
+
+ if (!window || window.hidden) {
+ return;
+ }
+
+ launchWindow = nil;
+
+ /* Do a nice animated fade-out (roughly matches the real launch behavior.) */
+ [UIView animateWithDuration:0.2 animations:^{
+ window.alpha = 0.0;
+ } completion:^(BOOL finished) {
+ window.hidden = YES;
+ }];
+}
+
+- (void)postFinishLaunch
+{
+ /* Hide the launch screen the next time the run loop is run. SDL apps will
+ * have a chance to load resources while the launch screen is still up. */
+ [self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0];
+
+ /* run the user's application, passing argc and argv */
+ SDL_iPhoneSetEventPump(SDL_TRUE);
+ exit_status = SDL_main(forward_argc, forward_argv);
+ SDL_iPhoneSetEventPump(SDL_FALSE);
+
+ if (launchWindow) {
+ launchWindow.hidden = YES;
+ launchWindow = nil;
+ }
+
+ /* exit, passing the return status from the user's application */
+ /* We don't actually exit to support applications that do setup in their
+ * main function and then allow the Cocoa event loop to run. */
+ /* exit(exit_status); */
+}
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ NSBundle *bundle = [NSBundle mainBundle];
+
+#if SDL_IPHONE_LAUNCHSCREEN
+ /* The normal launch screen is displayed until didFinishLaunching returns,
+ * but SDL_main is called after that happens and there may be a noticeable
+ * delay between the start of SDL_main and when the first real frame is
+ * displayed (e.g. if resources are loaded before SDL_GL_SwapWindow is
+ * called), so we show the launch screen programmatically until the first
+ * time events are pumped. */
+ UIViewController *vc = nil;
+ NSString *screenname = nil;
+
+ /* tvOS only uses a plain launch image. */
+#if !TARGET_OS_TV
+ screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
+
+ if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) {
+ @try {
+ /* The launch storyboard is actually a nib in some older versions of
+ * Xcode. We'll try to load it as a storyboard first, as it's more
+ * modern. */
+ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle];
+ vc = [storyboard instantiateInitialViewController];
+ }
+ @catch (NSException *exception) {
+ /* Do nothing (there's more code to execute below). */
+ }
+ }
+#endif
+
+ if (vc == nil) {
+ vc = [[SDLLaunchScreenController alloc] initWithNibName:screenname bundle:bundle];
+ }
+
+ if (vc.view) {
+ launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+
+ /* We don't want the launch window immediately hidden when a real SDL
+ * window is shown - we fade it out ourselves when we're ready. */
+ launchWindow.windowLevel = UIWindowLevelNormal + 1.0;
+
+ /* Show the window but don't make it key. Events should always go to
+ * other windows when possible. */
+ launchWindow.hidden = NO;
+
+ launchWindow.rootViewController = vc;
+ }
+#endif
+
+ /* Set working directory to resource path */
+ [[NSFileManager defaultManager] changeCurrentDirectoryPath:[bundle resourcePath]];
+
+ /* register a callback for the idletimer hint */
+ SDL_AddHintCallback(SDL_HINT_IDLE_TIMER_DISABLED,
+ SDL_IdleTimerDisabledChanged, NULL);
+
+ SDL_SetMainReady();
+ [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];
+
+ return YES;
+}
+
+- (UIWindow *)window
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+ if (_this) {
+ SDL_Window *window = NULL;
+ for (window = _this->windows; window != NULL; window = window->next) {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ if (data != nil) {
+ return data.uiwindow;
+ }
+ }
+ }
+ return nil;
+}
+
+- (void)setWindow:(UIWindow *)window
+{
+ /* Do nothing. */
+}
+
+#if !TARGET_OS_TV
+- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
+{
+ SDL_OnApplicationDidChangeStatusBarOrientation();
+}
+#endif
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ SDL_OnApplicationWillTerminate();
+}
+
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
+{
+ SDL_OnApplicationDidReceiveMemoryWarning();
+}
+
+- (void)applicationWillResignActive:(UIApplication*)application
+{
+ SDL_OnApplicationWillResignActive();
+}
+
+- (void)applicationDidEnterBackground:(UIApplication*)application
+{
+ SDL_OnApplicationDidEnterBackground();
+}
+
+- (void)applicationWillEnterForeground:(UIApplication*)application
+{
+ SDL_OnApplicationWillEnterForeground();
+}
+
+- (void)applicationDidBecomeActive:(UIApplication*)application
+{
+ SDL_OnApplicationDidBecomeActive();
+}
+
+- (void)sendDropFileForURL:(NSURL *)url
+{
+ NSURL *fileURL = url.filePathURL;
+ if (fileURL != nil) {
+ SDL_SendDropFile(NULL, fileURL.path.UTF8String);
+ } else {
+ SDL_SendDropFile(NULL, url.absoluteString.UTF8String);
+ }
+ SDL_SendDropComplete(NULL);
+}
+
+#if TARGET_OS_TV || (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0)
+
+- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
+{
+ /* TODO: Handle options */
+ [self sendDropFileForURL:url];
+ return YES;
+}
+
+#else
+
+- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
+{
+ [self sendDropFileForURL:url];
+ return YES;
+}
+
+#endif
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h
new file mode 100644
index 0000000..c4b689d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h
@@ -0,0 +1,35 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitclipboard_h_
+#define SDL_uikitclipboard_h_
+
+#include "../SDL_sysvideo.h"
+
+extern int UIKit_SetClipboardText(_THIS, const char *text);
+extern char *UIKit_GetClipboardText(_THIS);
+extern SDL_bool UIKit_HasClipboardText(_THIS);
+
+extern void UIKit_InitClipboard(_THIS);
+extern void UIKit_QuitClipboard(_THIS);
+
+#endif /* SDL_uikitclipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m
new file mode 100644
index 0000000..b1d4f6d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m
@@ -0,0 +1,111 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitvideo.h"
+#include "../../events/SDL_clipboardevents_c.h"
+
+#import <UIKit/UIPasteboard.h>
+
+int
+UIKit_SetClipboardText(_THIS, const char *text)
+{
+#if TARGET_OS_TV
+ return SDL_SetError("The clipboard is not available on tvOS");
+#else
+ @autoreleasepool {
+ [UIPasteboard generalPasteboard].string = @(text);
+ return 0;
+ }
+#endif
+}
+
+char *
+UIKit_GetClipboardText(_THIS)
+{
+#if TARGET_OS_TV
+ return SDL_strdup(""); // Unsupported.
+#else
+ @autoreleasepool {
+ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
+ NSString *string = pasteboard.string;
+
+ if (string != nil) {
+ return SDL_strdup(string.UTF8String);
+ } else {
+ return SDL_strdup("");
+ }
+ }
+#endif
+}
+
+SDL_bool
+UIKit_HasClipboardText(_THIS)
+{
+ @autoreleasepool {
+#if !TARGET_OS_TV
+ if ([UIPasteboard generalPasteboard].string != nil) {
+ return SDL_TRUE;
+ }
+#endif
+ return SDL_FALSE;
+ }
+}
+
+void
+UIKit_InitClipboard(_THIS)
+{
+#if !TARGET_OS_TV
+ @autoreleasepool {
+ SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ id observer = [center addObserverForName:UIPasteboardChangedNotification
+ object:nil
+ queue:nil
+ usingBlock:^(NSNotification *note) {
+ SDL_SendClipboardUpdate();
+ }];
+
+ data.pasteboardObserver = observer;
+ }
+#endif
+}
+
+void
+UIKit_QuitClipboard(_THIS)
+{
+ @autoreleasepool {
+ SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
+
+ if (data.pasteboardObserver != nil) {
+ [[NSNotificationCenter defaultCenter] removeObserver:data.pasteboardObserver];
+ }
+
+ data.pasteboardObserver = nil;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h
new file mode 100644
index 0000000..0c48829
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h
@@ -0,0 +1,30 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitevents_h_
+#define SDL_uikitevents_h_
+
+#include "../SDL_sysvideo.h"
+
+extern void UIKit_PumpEvents(_THIS);
+
+#endif /* SDL_uikitevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m
new file mode 100644
index 0000000..d64e330
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m
@@ -0,0 +1,73 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitevents.h"
+#include "SDL_uikitopengles.h"
+
+#import <Foundation/Foundation.h>
+
+static BOOL UIKit_EventPumpEnabled = YES;
+
+void
+SDL_iPhoneSetEventPump(SDL_bool enabled)
+{
+ UIKit_EventPumpEnabled = enabled;
+}
+
+void
+UIKit_PumpEvents(_THIS)
+{
+ if (!UIKit_EventPumpEnabled) {
+ return;
+ }
+
+ /* Let the run loop run for a short amount of time: long enough for
+ touch events to get processed (which is important to get certain
+ elements of Game Center's GKLeaderboardViewController to respond
+ to touch input), but not long enough to introduce a significant
+ delay in the rest of the app.
+ */
+ const CFTimeInterval seconds = 0.000002;
+
+ /* Pump most event types. */
+ SInt32 result;
+ do {
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, TRUE);
+ } while (result == kCFRunLoopRunHandledSource);
+
+ /* Make sure UIScrollView objects scroll properly. */
+ do {
+ result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE);
+ } while(result == kCFRunLoopRunHandledSource);
+
+ /* See the comment in the function definition. */
+ UIKit_GL_RestoreCurrentContext();
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h
new file mode 100644
index 0000000..a766b57
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+extern SDL_bool UIKit_ShowingMessageBox(void);
+
+extern int UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m
new file mode 100644
index 0000000..cf2a8f3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m
@@ -0,0 +1,208 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL.h"
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitwindow.h"
+
+/* Display a UIKit message box */
+
+static SDL_bool s_showingMessageBox = SDL_FALSE;
+
+SDL_bool
+UIKit_ShowingMessageBox(void)
+{
+ return s_showingMessageBox;
+}
+
+static void
+UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex)
+{
+ *clickedindex = messageboxdata->numbuttons;
+
+ @autoreleasepool {
+ /* Run the main event loop until the alert has finished */
+ /* Note that this needs to be done on the main thread */
+ s_showingMessageBox = SDL_TRUE;
+ while ((*clickedindex) == messageboxdata->numbuttons) {
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+ }
+ s_showingMessageBox = SDL_FALSE;
+ }
+}
+
+static BOOL
+UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+#ifdef __IPHONE_8_0
+ int i;
+ int __block clickedindex = messageboxdata->numbuttons;
+ const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+ UIWindow *window = nil;
+ UIWindow *alertwindow = nil;
+
+ if (![UIAlertController class]) {
+ return NO;
+ }
+
+ UIAlertController *alert;
+ alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title)
+ message:@(messageboxdata->message)
+ preferredStyle:UIAlertControllerStyleAlert];
+
+ for (i = 0; i < messageboxdata->numbuttons; i++) {
+ UIAlertAction *action;
+ UIAlertActionStyle style = UIAlertActionStyleDefault;
+
+ if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+ style = UIAlertActionStyleCancel;
+ }
+
+ action = [UIAlertAction actionWithTitle:@(buttons[i].text)
+ style:style
+ handler:^(UIAlertAction *action) {
+ clickedindex = i;
+ }];
+ [alert addAction:action];
+ }
+
+ if (messageboxdata->window) {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) messageboxdata->window->driverdata;
+ window = data.uiwindow;
+ }
+
+ if (window == nil || window.rootViewController == nil) {
+ alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+ alertwindow.rootViewController = [UIViewController new];
+ alertwindow.windowLevel = UIWindowLevelAlert;
+
+ window = alertwindow;
+
+ [alertwindow makeKeyAndVisible];
+ }
+
+ [window.rootViewController presentViewController:alert animated:YES completion:nil];
+ UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
+
+ if (alertwindow) {
+ alertwindow.hidden = YES;
+ }
+
+#if !TARGET_OS_TV
+ /* Force the main SDL window to re-evaluate home indicator state */
+ SDL_Window *focus = SDL_GetFocusWindow();
+ if (focus) {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) focus->driverdata;
+ if (data != nil) {
+ if (@available(iOS 11.0, *)) {
+ [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden) withObject:nil waitUntilDone:NO];
+ [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfScreenEdgesDeferringSystemGestures) withObject:nil waitUntilDone:NO];
+ }
+ }
+ }
+#endif /* !TARGET_OS_TV */
+
+ *buttonid = messageboxdata->buttons[clickedindex].buttonid;
+ return YES;
+#else
+ return NO;
+#endif /* __IPHONE_8_0 */
+}
+
+/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
+@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>
+
+@property (nonatomic, assign) int *clickedIndex;
+
+@end
+
+@implementation SDLAlertViewDelegate
+
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ if (_clickedIndex != NULL) {
+ *_clickedIndex = (int) buttonIndex;
+ }
+}
+
+@end
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
+
+static BOOL
+UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ /* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
+ int i;
+ int clickedindex = messageboxdata->numbuttons;
+ const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+ UIAlertView *alert = [[UIAlertView alloc] init];
+ SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
+
+ alert.delegate = delegate;
+ alert.title = @(messageboxdata->title);
+ alert.message = @(messageboxdata->message);
+
+ for (i = 0; i < messageboxdata->numbuttons; i++) {
+ [alert addButtonWithTitle:@(buttons[i].text)];
+ }
+
+ delegate.clickedIndex = &clickedindex;
+
+ [alert show];
+
+ UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
+
+ alert.delegate = nil;
+
+ *buttonid = messageboxdata->buttons[clickedindex].buttonid;
+ return YES;
+#else
+ return NO;
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
+}
+
+int
+UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ BOOL success = NO;
+
+ @autoreleasepool {
+ success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid);
+ if (!success) {
+ success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid);
+ }
+ }
+
+ if (!success) {
+ return SDL_SetError("Could not show message box.");
+ }
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h
new file mode 100644
index 0000000..bc97778
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h
@@ -0,0 +1,58 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com.
+ *
+ * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
+ * how to add a CAMetalLayer backed view.
+ */
+
+#ifndef SDL_uikitmetalview_h_
+#define SDL_uikitmetalview_h_
+
+#import "../SDL_sysvideo.h"
+#import "SDL_uikitwindow.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN)
+
+#import <UIKit/UIKit.h>
+#import <Metal/Metal.h>
+#import <QuartzCore/CAMetalLayer.h>
+
+#define METALVIEW_TAG 255
+
+@interface SDL_uikitmetalview : SDL_uikitview
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale;
+
+@end
+
+SDL_uikitmetalview* UIKit_Mtl_AddMetalView(SDL_Window* window);
+
+void UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN) */
+
+#endif /* SDL_uikitmetalview_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m
new file mode 100644
index 0000000..436e742
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m
@@ -0,0 +1,132 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com.
+ *
+ * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
+ * how to add a CAMetalLayer backed view.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN)
+
+#import "../SDL_sysvideo.h"
+#import "SDL_uikitwindow.h"
+#import "SDL_uikitmetalview.h"
+
+#include "SDL_assert.h"
+
+@implementation SDL_uikitmetalview
+
+/* Returns a Metal-compatible layer. */
++ (Class)layerClass
+{
+ return [CAMetalLayer class];
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale
+{
+ if ((self = [super initWithFrame:frame])) {
+ self.tag = METALVIEW_TAG;
+ self.layer.contentsScale = scale;
+ [self updateDrawableSize];
+ }
+
+ return self;
+}
+
+/* Set the size of the metal drawables when the view is resized. */
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+ [self updateDrawableSize];
+}
+
+- (void)updateDrawableSize
+{
+ CGSize size = self.bounds.size;
+ size.width *= self.layer.contentsScale;
+ size.height *= self.layer.contentsScale;
+ ((CAMetalLayer *)self.layer).drawableSize = size;
+}
+
+@end
+
+SDL_uikitmetalview*
+UIKit_Mtl_AddMetalView(SDL_Window* window)
+{
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
+ CGFloat scale = 1.0;
+
+ if ([view isKindOfClass:[SDL_uikitmetalview class]]) {
+ return (SDL_uikitmetalview *)view;
+ }
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ /* Set the scale to the natural scale factor of the screen - then
+ * the backing dimensions of the Metal view will match the pixel
+ * dimensions of the screen rather than the dimensions in points
+ * yielding high resolution on retine displays.
+ */
+#ifdef __IPHONE_8_0
+ if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
+ scale = data.uiwindow.screen.nativeScale;
+ } else
+#endif
+ {
+ scale = data.uiwindow.screen.scale;
+ }
+ }
+ SDL_uikitmetalview *metalview
+ = [[SDL_uikitmetalview alloc] initWithFrame:view.frame
+ scale:scale];
+ [metalview setSDLWindow:window];
+
+ return metalview;
+}
+
+void
+UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
+ SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG];
+ if (metalview) {
+ CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
+ assert(layer != NULL);
+ if (w) {
+ *w = layer.drawableSize.width;
+ }
+ if (h) {
+ *h = layer.drawableSize.height;
+ }
+ } else {
+ SDL_GetWindowSize(window, w, h);
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN) */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h
new file mode 100644
index 0000000..b5c0c65
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_uikitmodes_h_
+#define SDL_uikitmodes_h_
+
+#include "SDL_uikitvideo.h"
+
+@interface SDL_DisplayData : NSObject
+
+@property (nonatomic, strong) UIScreen *uiscreen;
+
+@end
+
+@interface SDL_DisplayModeData : NSObject
+
+@property (nonatomic, strong) UIScreenMode *uiscreenmode;
+
+@end
+
+extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
+
+extern int UIKit_InitModes(_THIS);
+extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void UIKit_QuitModes(_THIS);
+extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+
+#if !TARGET_OS_TV
+extern void SDL_OnApplicationDidChangeStatusBarOrientation(void);
+#endif
+
+#endif /* SDL_uikitmodes_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m
new file mode 100644
index 0000000..7ddf107
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m
@@ -0,0 +1,380 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_assert.h"
+#include "SDL_uikitmodes.h"
+
+#include "../../events/SDL_events_c.h"
+
+@implementation SDL_DisplayData
+
+@synthesize uiscreen;
+
+@end
+
+@implementation SDL_DisplayModeData
+
+@synthesize uiscreenmode;
+
+@end
+
+
+static int
+UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
+ UIScreenMode * uiscreenmode)
+{
+ SDL_DisplayModeData *data = nil;
+
+ if (uiscreenmode != nil) {
+ /* Allocate the display mode data */
+ data = [[SDL_DisplayModeData alloc] init];
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+
+ data.uiscreenmode = uiscreenmode;
+ }
+
+ mode->driverdata = (void *) CFBridgingRetain(data);
+
+ return 0;
+}
+
+static void
+UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
+{
+ if (mode->driverdata != NULL) {
+ CFRelease(mode->driverdata);
+ mode->driverdata = NULL;
+ }
+}
+
+static NSUInteger
+UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen)
+{
+#ifdef __IPHONE_10_3
+ if ([uiscreen respondsToSelector:@selector(maximumFramesPerSecond)]) {
+ return uiscreen.maximumFramesPerSecond;
+ }
+#endif
+ return 0;
+}
+
+static int
+UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
+ UIScreen * uiscreen, UIScreenMode * uiscreenmode)
+{
+ SDL_DisplayMode mode;
+ SDL_zero(mode);
+
+ if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
+ return -1;
+ }
+
+ mode.format = SDL_PIXELFORMAT_ABGR8888;
+ mode.refresh_rate = (int) UIKit_GetDisplayModeRefreshRate(uiscreen);
+ mode.w = w;
+ mode.h = h;
+
+ if (SDL_AddDisplayMode(display, &mode)) {
+ return 0;
+ } else {
+ UIKit_FreeDisplayModeData(&mode);
+ return -1;
+ }
+}
+
+static int
+UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscreen,
+ UIScreenMode * uiscreenmode, SDL_bool addRotation)
+{
+ if (UIKit_AddSingleDisplayMode(display, w, h, uiscreen, uiscreenmode) < 0) {
+ return -1;
+ }
+
+ if (addRotation) {
+ /* Add the rotated version */
+ if (UIKit_AddSingleDisplayMode(display, h, w, uiscreen, uiscreenmode) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+UIKit_AddDisplay(UIScreen *uiscreen)
+{
+ UIScreenMode *uiscreenmode = uiscreen.currentMode;
+ CGSize size = uiscreen.bounds.size;
+ SDL_VideoDisplay display;
+ SDL_DisplayMode mode;
+ SDL_zero(mode);
+
+ /* Make sure the width/height are oriented correctly */
+ if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
+ CGFloat height = size.width;
+ size.width = size.height;
+ size.height = height;
+ }
+
+ mode.format = SDL_PIXELFORMAT_ABGR8888;
+ mode.refresh_rate = (int) UIKit_GetDisplayModeRefreshRate(uiscreen);
+ mode.w = (int) size.width;
+ mode.h = (int) size.height;
+
+ if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
+ return -1;
+ }
+
+ SDL_zero(display);
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+
+ /* Allocate the display data */
+ SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
+ if (!data) {
+ UIKit_FreeDisplayModeData(&display.desktop_mode);
+ return SDL_OutOfMemory();
+ }
+
+ data.uiscreen = uiscreen;
+
+ display.driverdata = (void *) CFBridgingRetain(data);
+ SDL_AddVideoDisplay(&display);
+
+ return 0;
+}
+
+SDL_bool
+UIKit_IsDisplayLandscape(UIScreen *uiscreen)
+{
+#if !TARGET_OS_TV
+ if (uiscreen == [UIScreen mainScreen]) {
+ return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
+ } else
+#endif /* !TARGET_OS_TV */
+ {
+ CGSize size = uiscreen.bounds.size;
+ return (size.width > size.height);
+ }
+}
+
+int
+UIKit_InitModes(_THIS)
+{
+ @autoreleasepool {
+ for (UIScreen *uiscreen in [UIScreen screens]) {
+ if (UIKit_AddDisplay(uiscreen) < 0) {
+ return -1;
+ }
+ }
+#if !TARGET_OS_TV
+ SDL_OnApplicationDidChangeStatusBarOrientation();
+#endif
+ }
+
+ return 0;
+}
+
+void
+UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ @autoreleasepool {
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+ SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
+ SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
+ CGFloat scale = data.uiscreen.scale;
+ NSArray *availableModes = nil;
+
+#if TARGET_OS_TV
+ addRotation = SDL_FALSE;
+ availableModes = @[data.uiscreen.currentMode];
+#else
+ availableModes = data.uiscreen.availableModes;
+#endif
+
+#ifdef __IPHONE_8_0
+ /* The UIScreenMode of an iPhone 6 Plus should be 1080x1920 rather than
+ * 1242x2208 (414x736@3x), so we should use the native scale. */
+ if ([data.uiscreen respondsToSelector:@selector(nativeScale)]) {
+ scale = data.uiscreen.nativeScale;
+ }
+#endif
+
+ for (UIScreenMode *uimode in availableModes) {
+ /* The size of a UIScreenMode is in pixels, but we deal exclusively
+ * in points (except in SDL_GL_GetDrawableSize.) */
+ int w = (int)(uimode.size.width / scale);
+ int h = (int)(uimode.size.height / scale);
+
+ /* Make sure the width/height are oriented correctly */
+ if (isLandscape != (w > h)) {
+ int tmp = w;
+ w = h;
+ h = tmp;
+ }
+
+ UIKit_AddDisplayMode(display, w, h, data.uiscreen, uimode, addRotation);
+ }
+ }
+}
+
+int
+UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ @autoreleasepool {
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+#if !TARGET_OS_TV
+ SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
+ [data.uiscreen setCurrentMode:modedata.uiscreenmode];
+#endif
+
+ if (data.uiscreen == [UIScreen mainScreen]) {
+ /* [UIApplication setStatusBarOrientation:] no longer works reliably
+ * in recent iOS versions, so we can't rotate the screen when setting
+ * the display mode. */
+ if (mode->w > mode->h) {
+ if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
+ return SDL_SetError("Screen orientation does not match display mode size");
+ }
+ } else if (mode->w < mode->h) {
+ if (UIKit_IsDisplayLandscape(data.uiscreen)) {
+ return SDL_SetError("Screen orientation does not match display mode size");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
+{
+ @autoreleasepool {
+ int displayIndex = (int) (display - _this->displays);
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+ CGRect frame = data.uiscreen.bounds;
+
+ /* the default function iterates displays to make a fake offset,
+ as if all the displays were side-by-side, which is fine for iOS. */
+ if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
+ return -1;
+ }
+
+#if !TARGET_OS_TV && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
+ if (!UIKit_IsSystemVersionAtLeast(7.0)) {
+ frame = [data.uiscreen applicationFrame];
+ }
+#endif
+
+ rect->x += frame.origin.x;
+ rect->y += frame.origin.y;
+ rect->w = frame.size.width;
+ rect->h = frame.size.height;
+ }
+
+ return 0;
+}
+
+void
+UIKit_QuitModes(_THIS)
+{
+ /* Release Objective-C objects, so higher level doesn't free() them. */
+ int i, j;
+ @autoreleasepool {
+ for (i = 0; i < _this->num_displays; i++) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+
+ UIKit_FreeDisplayModeData(&display->desktop_mode);
+ for (j = 0; j < display->num_display_modes; j++) {
+ SDL_DisplayMode *mode = &display->display_modes[j];
+ UIKit_FreeDisplayModeData(mode);
+ }
+
+ if (display->driverdata != NULL) {
+ CFRelease(display->driverdata);
+ display->driverdata = NULL;
+ }
+ }
+ }
+}
+
+#if !TARGET_OS_TV
+void SDL_OnApplicationDidChangeStatusBarOrientation()
+{
+ BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
+ SDL_VideoDisplay *display = SDL_GetDisplay(0);
+
+ if (display) {
+ SDL_DisplayMode *desktopmode = &display->desktop_mode;
+ SDL_DisplayMode *currentmode = &display->current_mode;
+ SDL_DisplayOrientation orientation = SDL_ORIENTATION_UNKNOWN;
+
+ /* The desktop display mode should be kept in sync with the screen
+ * orientation so that updating a window's fullscreen state to
+ * SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the
+ * correct orientation. */
+ if (isLandscape != (desktopmode->w > desktopmode->h)) {
+ int height = desktopmode->w;
+ desktopmode->w = desktopmode->h;
+ desktopmode->h = height;
+ }
+
+ /* Same deal with the current mode + SDL_GetCurrentDisplayMode. */
+ if (isLandscape != (currentmode->w > currentmode->h)) {
+ int height = currentmode->w;
+ currentmode->w = currentmode->h;
+ currentmode->h = height;
+ }
+
+ switch ([UIApplication sharedApplication].statusBarOrientation) {
+ case UIInterfaceOrientationPortrait:
+ orientation = SDL_ORIENTATION_PORTRAIT;
+ break;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ orientation = SDL_ORIENTATION_PORTRAIT_FLIPPED;
+ break;
+ case UIInterfaceOrientationLandscapeLeft:
+ /* Bug: UIInterfaceOrientationLandscapeLeft/Right are reversed - http://openradar.appspot.com/7216046 */
+ orientation = SDL_ORIENTATION_LANDSCAPE_FLIPPED;
+ break;
+ case UIInterfaceOrientationLandscapeRight:
+ /* Bug: UIInterfaceOrientationLandscapeLeft/Right are reversed - http://openradar.appspot.com/7216046 */
+ orientation = SDL_ORIENTATION_LANDSCAPE;
+ break;
+ default:
+ break;
+ }
+ SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation);
+ }
+}
+#endif /* !TARGET_OS_TV */
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h
new file mode 100644
index 0000000..6b57289
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h
@@ -0,0 +1,40 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitopengles_
+#define SDL_uikitopengles_
+
+#include "../SDL_sysvideo.h"
+
+extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window,
+ int * w, int * h);
+extern int UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
+extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
+extern void *UIKit_GL_GetProcAddress(_THIS, const char *proc);
+extern int UIKit_GL_LoadLibrary(_THIS, const char *path);
+
+extern void UIKit_GL_RestoreCurrentContext(void);
+
+#endif /* SDL_uikitopengles_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m
new file mode 100644
index 0000000..2f6dec4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m
@@ -0,0 +1,250 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitopengles.h"
+#import "SDL_uikitopenglview.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_uikitevents.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../power/uikit/SDL_syspower.h"
+#include "SDL_loadso.h"
+#include <dlfcn.h>
+
+@interface SDLEAGLContext : EAGLContext
+
+/* The OpenGL ES context owns a view / drawable. */
+@property (nonatomic, strong) SDL_uikitopenglview *sdlView;
+
+@end
+
+@implementation SDLEAGLContext
+
+- (void)dealloc
+{
+ /* When the context is deallocated, its view should be removed from any
+ * SDL window that it's attached to. */
+ [self.sdlView setSDLWindow:NULL];
+}
+
+@end
+
+void *
+UIKit_GL_GetProcAddress(_THIS, const char *proc)
+{
+ /* Look through all SO's for the proc symbol. Here's why:
+ * -Looking for the path to the OpenGL Library seems not to work in the iOS Simulator.
+ * -We don't know that the path won't change in the future. */
+ return dlsym(RTLD_DEFAULT, proc);
+}
+
+/*
+ note that SDL_GL_DeleteContext makes it current without passing the window
+*/
+int
+UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ @autoreleasepool {
+ SDLEAGLContext *eaglcontext = (__bridge SDLEAGLContext *) context;
+
+ if (![EAGLContext setCurrentContext:eaglcontext]) {
+ return SDL_SetError("Could not make EAGL context current");
+ }
+
+ if (eaglcontext) {
+ [eaglcontext.sdlView setSDLWindow:window];
+ }
+ }
+
+ return 0;
+}
+
+void
+UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ UIView *view = data.viewcontroller.view;
+ if ([view isKindOfClass:[SDL_uikitopenglview class]]) {
+ SDL_uikitopenglview *glview = (SDL_uikitopenglview *) view;
+ if (w) {
+ *w = glview.backingWidth;
+ }
+ if (h) {
+ *h = glview.backingHeight;
+ }
+ }
+ }
+}
+
+int
+UIKit_GL_LoadLibrary(_THIS, const char *path)
+{
+ /* We shouldn't pass a path to this function, since we've already loaded the
+ * library. */
+ if (path != NULL) {
+ return SDL_SetError("iOS GL Load Library just here for compatibility");
+ }
+ return 0;
+}
+
+int UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDLEAGLContext *context = (__bridge SDLEAGLContext *) SDL_GL_GetCurrentContext();
+
+#if SDL_POWER_UIKIT
+ /* Check once a frame to see if we should turn off the battery monitor. */
+ SDL_UIKit_UpdateBatteryMonitoring();
+#endif
+
+ [context.sdlView swapBuffers];
+
+ /* You need to pump events in order for the OS to make changes visible.
+ * We don't pump events here because we don't want iOS application events
+ * (low memory, terminate, etc.) to happen inside low level rendering. */
+ }
+ return 0;
+}
+
+SDL_GLContext
+UIKit_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDLEAGLContext *context = nil;
+ SDL_uikitopenglview *view;
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ CGRect frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
+ EAGLSharegroup *sharegroup = nil;
+ CGFloat scale = 1.0;
+ int samples = 0;
+ int major = _this->gl_config.major_version;
+ int minor = _this->gl_config.minor_version;
+
+ /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
+ * versions. */
+ EAGLRenderingAPI api = major;
+
+ /* iOS currently doesn't support GLES >3.0. iOS 6 also only supports up
+ * to GLES 2.0. */
+ if (major > 3 || (major == 3 && (minor > 0 || !UIKit_IsSystemVersionAtLeast(7.0)))) {
+ SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor);
+ return NULL;
+ }
+
+ if (_this->gl_config.multisamplebuffers > 0) {
+ samples = _this->gl_config.multisamplesamples;
+ }
+
+ if (_this->gl_config.share_with_current_context) {
+ EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
+ sharegroup = context.sharegroup;
+ }
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ /* Set the scale to the natural scale factor of the screen - the
+ * backing dimensions of the OpenGL view will match the pixel
+ * dimensions of the screen rather than the dimensions in points. */
+#ifdef __IPHONE_8_0
+ if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
+ scale = data.uiwindow.screen.nativeScale;
+ } else
+#endif
+ {
+ scale = data.uiwindow.screen.scale;
+ }
+ }
+
+ context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:sharegroup];
+ if (!context) {
+ SDL_SetError("OpenGL ES %d context could not be created", _this->gl_config.major_version);
+ return NULL;
+ }
+
+ /* construct our view, passing in SDL's OpenGL configuration data */
+ view = [[SDL_uikitopenglview alloc] initWithFrame:frame
+ scale:scale
+ retainBacking:_this->gl_config.retained_backing
+ rBits:_this->gl_config.red_size
+ gBits:_this->gl_config.green_size
+ bBits:_this->gl_config.blue_size
+ aBits:_this->gl_config.alpha_size
+ depthBits:_this->gl_config.depth_size
+ stencilBits:_this->gl_config.stencil_size
+ sRGB:_this->gl_config.framebuffer_srgb_capable
+ multisamples:samples
+ context:context];
+
+ if (!view) {
+ return NULL;
+ }
+
+ /* The context owns the view / drawable. */
+ context.sdlView = view;
+
+ if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext) context) < 0) {
+ UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(context));
+ return NULL;
+ }
+
+ /* We return a +1'd context. The window's driverdata owns the view (via
+ * MakeCurrent.) */
+ return (SDL_GLContext) CFBridgingRetain(context);
+ }
+}
+
+void
+UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ @autoreleasepool {
+ /* The context was retained in SDL_GL_CreateContext, so we release it
+ * here. The context's view will be detached from its window when the
+ * context is deallocated. */
+ CFRelease(context);
+ }
+}
+
+void
+UIKit_GL_RestoreCurrentContext(void)
+{
+ @autoreleasepool {
+ /* Some iOS system functionality (such as Dictation on the on-screen
+ keyboard) uses its own OpenGL ES context but doesn't restore the
+ previous one when it's done. This is a workaround to make sure the
+ expected SDL-created OpenGL ES context is active after the OS is
+ finished running its own code for the frame. If this isn't done, the
+ app may crash or have other nasty symptoms when Dictation is used.
+ */
+ EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
+ if (context != NULL && [EAGLContext currentContext] != context) {
+ [EAGLContext setCurrentContext:context];
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h
new file mode 100644
index 0000000..8d12c9f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h
@@ -0,0 +1,60 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#import <UIKit/UIKit.h>
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES3/gl.h>
+
+#import "SDL_uikitview.h"
+#include "SDL_uikitvideo.h"
+
+@interface SDL_uikitopenglview : SDL_uikitview
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale
+ retainBacking:(BOOL)retained
+ rBits:(int)rBits
+ gBits:(int)gBits
+ bBits:(int)bBits
+ aBits:(int)aBits
+ depthBits:(int)depthBits
+ stencilBits:(int)stencilBits
+ sRGB:(BOOL)sRGB
+ multisamples:(int)multisamples
+ context:(EAGLContext *)glcontext;
+
+@property (nonatomic, readonly, weak) EAGLContext *context;
+
+/* The width and height of the drawable in pixels (as opposed to points.) */
+@property (nonatomic, readonly) int backingWidth;
+@property (nonatomic, readonly) int backingHeight;
+
+@property (nonatomic, readonly) GLuint drawableRenderbuffer;
+@property (nonatomic, readonly) GLuint drawableFramebuffer;
+@property (nonatomic, readonly) GLuint msaaResolveFramebuffer;
+
+- (void)swapBuffers;
+
+- (void)updateFrame;
+
+@end
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m
new file mode 100644
index 0000000..9024376
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m
@@ -0,0 +1,384 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include <OpenGLES/EAGLDrawable.h>
+#include <OpenGLES/ES2/glext.h>
+#import "SDL_uikitopenglview.h"
+#include "SDL_uikitwindow.h"
+
+@implementation SDL_uikitopenglview {
+ /* The renderbuffer and framebuffer used to render to this layer. */
+ GLuint viewRenderbuffer, viewFramebuffer;
+
+ /* The depth buffer that is attached to viewFramebuffer, if it exists. */
+ GLuint depthRenderbuffer;
+
+ GLenum colorBufferFormat;
+
+ /* format of depthRenderbuffer */
+ GLenum depthBufferFormat;
+
+ /* The framebuffer and renderbuffer used for rendering with MSAA. */
+ GLuint msaaFramebuffer, msaaRenderbuffer;
+
+ /* The number of MSAA samples. */
+ int samples;
+
+ BOOL retainedBacking;
+}
+
+@synthesize context;
+@synthesize backingWidth;
+@synthesize backingHeight;
+
++ (Class)layerClass
+{
+ return [CAEAGLLayer class];
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale
+ retainBacking:(BOOL)retained
+ rBits:(int)rBits
+ gBits:(int)gBits
+ bBits:(int)bBits
+ aBits:(int)aBits
+ depthBits:(int)depthBits
+ stencilBits:(int)stencilBits
+ sRGB:(BOOL)sRGB
+ multisamples:(int)multisamples
+ context:(EAGLContext *)glcontext
+{
+ if ((self = [super initWithFrame:frame])) {
+ const BOOL useStencilBuffer = (stencilBits != 0);
+ const BOOL useDepthBuffer = (depthBits != 0);
+ NSString *colorFormat = nil;
+
+ context = glcontext;
+ samples = multisamples;
+ retainedBacking = retained;
+
+ if (!context || ![EAGLContext setCurrentContext:context]) {
+ SDL_SetError("Could not create OpenGL ES drawable (could not make context current)");
+ return nil;
+ }
+
+ if (samples > 0) {
+ GLint maxsamples = 0;
+ glGetIntegerv(GL_MAX_SAMPLES, &maxsamples);
+
+ /* Clamp the samples to the max supported count. */
+ samples = MIN(samples, maxsamples);
+ }
+
+ if (sRGB) {
+ /* sRGB EAGL drawable support was added in iOS 7. */
+ if (UIKit_IsSystemVersionAtLeast(7.0)) {
+ colorFormat = kEAGLColorFormatSRGBA8;
+ colorBufferFormat = GL_SRGB8_ALPHA8;
+ } else {
+ SDL_SetError("sRGB drawables are not supported.");
+ return nil;
+ }
+ } else if (rBits >= 8 || gBits >= 8 || bBits >= 8 || aBits > 0) {
+ /* if user specifically requests rbg888 or some color format higher than 16bpp */
+ colorFormat = kEAGLColorFormatRGBA8;
+ colorBufferFormat = GL_RGBA8;
+ } else {
+ /* default case (potentially faster) */
+ colorFormat = kEAGLColorFormatRGB565;
+ colorBufferFormat = GL_RGB565;
+ }
+
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+
+ eaglLayer.opaque = YES;
+ eaglLayer.drawableProperties = @{
+ kEAGLDrawablePropertyRetainedBacking:@(retained),
+ kEAGLDrawablePropertyColorFormat:colorFormat
+ };
+
+ /* Set the appropriate scale (for retina display support) */
+ self.contentScaleFactor = scale;
+
+ /* Create the color Renderbuffer Object */
+ glGenRenderbuffers(1, &viewRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+
+ if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]) {
+ SDL_SetError("Failed to create OpenGL ES drawable");
+ return nil;
+ }
+
+ /* Create the Framebuffer Object */
+ glGenFramebuffers(1, &viewFramebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
+
+ /* attach the color renderbuffer to the FBO */
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
+
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ SDL_SetError("Failed creating OpenGL ES framebuffer");
+ return nil;
+ }
+
+ /* When MSAA is used we'll use a separate framebuffer for rendering to,
+ * since we'll need to do an explicit MSAA resolve before presenting. */
+ if (samples > 0) {
+ glGenFramebuffers(1, &msaaFramebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
+
+ glGenRenderbuffers(1, &msaaRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
+
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderbuffer);
+ }
+
+ if (useDepthBuffer || useStencilBuffer) {
+ if (useStencilBuffer) {
+ /* Apparently you need to pack stencil and depth into one buffer. */
+ depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
+ } else if (useDepthBuffer) {
+ /* iOS only uses 32-bit float (exposed as fixed point 24-bit)
+ * depth buffers. */
+ depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
+ }
+
+ glGenRenderbuffers(1, &depthRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
+
+ if (samples > 0) {
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
+ } else {
+ glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
+ }
+
+ if (useDepthBuffer) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
+ }
+ if (useStencilBuffer) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
+ }
+ }
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ SDL_SetError("Failed creating OpenGL ES framebuffer");
+ return nil;
+ }
+
+ glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+
+ [self setDebugLabels];
+ }
+
+ return self;
+}
+
+- (GLuint)drawableRenderbuffer
+{
+ return viewRenderbuffer;
+}
+
+- (GLuint)drawableFramebuffer
+{
+ /* When MSAA is used, the MSAA draw framebuffer is used for drawing. */
+ if (msaaFramebuffer) {
+ return msaaFramebuffer;
+ } else {
+ return viewFramebuffer;
+ }
+}
+
+- (GLuint)msaaResolveFramebuffer
+{
+ /* When MSAA is used, the MSAA draw framebuffer is used for drawing and the
+ * view framebuffer is used as a MSAA resolve framebuffer. */
+ if (msaaFramebuffer) {
+ return viewFramebuffer;
+ } else {
+ return 0;
+ }
+}
+
+- (void)updateFrame
+{
+ GLint prevRenderbuffer = 0;
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRenderbuffer);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+ [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
+
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
+
+ if (msaaRenderbuffer != 0) {
+ glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
+ }
+
+ if (depthRenderbuffer != 0) {
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
+
+ if (samples > 0) {
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
+ } else {
+ glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
+ }
+ }
+
+ glBindRenderbuffer(GL_RENDERBUFFER, prevRenderbuffer);
+}
+
+- (void)setDebugLabels
+{
+ if (viewFramebuffer != 0) {
+ glLabelObjectEXT(GL_FRAMEBUFFER, viewFramebuffer, 0, "context FBO");
+ }
+
+ if (viewRenderbuffer != 0) {
+ glLabelObjectEXT(GL_RENDERBUFFER, viewRenderbuffer, 0, "context color buffer");
+ }
+
+ if (depthRenderbuffer != 0) {
+ if (depthBufferFormat == GL_DEPTH24_STENCIL8_OES) {
+ glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth-stencil buffer");
+ } else {
+ glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth buffer");
+ }
+ }
+
+ if (msaaFramebuffer != 0) {
+ glLabelObjectEXT(GL_FRAMEBUFFER, msaaFramebuffer, 0, "context MSAA FBO");
+ }
+
+ if (msaaRenderbuffer != 0) {
+ glLabelObjectEXT(GL_RENDERBUFFER, msaaRenderbuffer, 0, "context MSAA renderbuffer");
+ }
+}
+
+- (void)swapBuffers
+{
+ if (msaaFramebuffer) {
+ const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, viewFramebuffer);
+
+ /* OpenGL ES 3+ provides explicit MSAA resolves via glBlitFramebuffer.
+ * In OpenGL ES 1 and 2, MSAA resolves must be done via an extension. */
+ if (context.API >= kEAGLRenderingAPIOpenGLES3) {
+ int w = backingWidth;
+ int h = backingHeight;
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ if (!retainedBacking) {
+ /* Discard the contents of the MSAA drawable color buffer. */
+ glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, attachments);
+ }
+ } else {
+ glResolveMultisampleFramebufferAPPLE();
+
+ if (!retainedBacking) {
+ glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER, 1, attachments);
+ }
+ }
+
+ /* We assume the "drawable framebuffer" (MSAA draw framebuffer) was
+ * previously bound... */
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFramebuffer);
+ }
+
+ /* viewRenderbuffer should always be bound here. Code that binds something
+ * else is responsible for rebinding viewRenderbuffer, to reduce duplicate
+ * state changes. */
+ [context presentRenderbuffer:GL_RENDERBUFFER];
+}
+
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+
+ int width = (int) (self.bounds.size.width * self.contentScaleFactor);
+ int height = (int) (self.bounds.size.height * self.contentScaleFactor);
+
+ /* Update the color and depth buffer storage if the layer size has changed. */
+ if (width != backingWidth || height != backingHeight) {
+ EAGLContext *prevContext = [EAGLContext currentContext];
+ if (prevContext != context) {
+ [EAGLContext setCurrentContext:context];
+ }
+
+ [self updateFrame];
+
+ if (prevContext != context) {
+ [EAGLContext setCurrentContext:prevContext];
+ }
+ }
+}
+
+- (void)destroyFramebuffer
+{
+ if (viewFramebuffer != 0) {
+ glDeleteFramebuffers(1, &viewFramebuffer);
+ viewFramebuffer = 0;
+ }
+
+ if (viewRenderbuffer != 0) {
+ glDeleteRenderbuffers(1, &viewRenderbuffer);
+ viewRenderbuffer = 0;
+ }
+
+ if (depthRenderbuffer != 0) {
+ glDeleteRenderbuffers(1, &depthRenderbuffer);
+ depthRenderbuffer = 0;
+ }
+
+ if (msaaFramebuffer != 0) {
+ glDeleteFramebuffers(1, &msaaFramebuffer);
+ msaaFramebuffer = 0;
+ }
+
+ if (msaaRenderbuffer != 0) {
+ glDeleteRenderbuffers(1, &msaaRenderbuffer);
+ msaaRenderbuffer = 0;
+ }
+}
+
+- (void)dealloc
+{
+ if (context && context == [EAGLContext currentContext]) {
+ [self destroyFramebuffer];
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h
new file mode 100644
index 0000000..e24183a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h
@@ -0,0 +1,46 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitvideo_h_
+#define SDL_uikitvideo_h_
+
+#include "../SDL_sysvideo.h"
+
+#ifdef __OBJC__
+
+#include <UIKit/UIKit.h>
+
+@interface SDL_VideoData : NSObject
+
+@property (nonatomic, assign) id pasteboardObserver;
+
+@end
+
+CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
+
+#endif /* __OBJC__ */
+
+void UIKit_SuspendScreenSaver(_THIS);
+
+SDL_bool UIKit_IsSystemVersionAtLeast(double version);
+
+#endif /* SDL_uikitvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m
new file mode 100644
index 0000000..10d1dde
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m
@@ -0,0 +1,249 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#import <UIKit/UIKit.h>
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitevents.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_uikitopengles.h"
+#include "SDL_uikitclipboard.h"
+#include "SDL_uikitvulkan.h"
+
+#define UIKITVID_DRIVER_NAME "uikit"
+
+@implementation SDL_VideoData
+
+@end
+
+/* Initialization/Query functions */
+static int UIKit_VideoInit(_THIS);
+static void UIKit_VideoQuit(_THIS);
+
+/* DUMMY driver bootstrap functions */
+
+static int
+UIKit_Available(void)
+{
+ return 1;
+}
+
+static void UIKit_DeleteDevice(SDL_VideoDevice * device)
+{
+ @autoreleasepool {
+ CFRelease(device->driverdata);
+ SDL_free(device);
+ }
+}
+
+static SDL_VideoDevice *
+UIKit_CreateDevice(int devindex)
+{
+ @autoreleasepool {
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device) {
+ data = [SDL_VideoData new];
+ } else {
+ SDL_free(device);
+ SDL_OutOfMemory();
+ return (0);
+ }
+
+ device->driverdata = (void *) CFBridgingRetain(data);
+
+ /* Set the function pointers */
+ device->VideoInit = UIKit_VideoInit;
+ device->VideoQuit = UIKit_VideoQuit;
+ device->GetDisplayModes = UIKit_GetDisplayModes;
+ device->SetDisplayMode = UIKit_SetDisplayMode;
+ device->PumpEvents = UIKit_PumpEvents;
+ device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
+ device->CreateSDLWindow = UIKit_CreateWindow;
+ device->SetWindowTitle = UIKit_SetWindowTitle;
+ device->ShowWindow = UIKit_ShowWindow;
+ device->HideWindow = UIKit_HideWindow;
+ device->RaiseWindow = UIKit_RaiseWindow;
+ device->SetWindowBordered = UIKit_SetWindowBordered;
+ device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
+ device->DestroyWindow = UIKit_DestroyWindow;
+ device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
+ device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
+
+#if SDL_IPHONE_KEYBOARD
+ device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
+ device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
+ device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
+ device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
+ device->SetTextInputRect = UIKit_SetTextInputRect;
+#endif
+
+ device->SetClipboardText = UIKit_SetClipboardText;
+ device->GetClipboardText = UIKit_GetClipboardText;
+ device->HasClipboardText = UIKit_HasClipboardText;
+
+ /* OpenGL (ES) functions */
+ device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
+ device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize;
+ device->GL_SwapWindow = UIKit_GL_SwapWindow;
+ device->GL_CreateContext = UIKit_GL_CreateContext;
+ device->GL_DeleteContext = UIKit_GL_DeleteContext;
+ device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
+ device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
+ device->free = UIKit_DeleteDevice;
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = UIKit_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = UIKit_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions
+ = UIKit_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = UIKit_Vulkan_CreateSurface;
+ device->Vulkan_GetDrawableSize = UIKit_Vulkan_GetDrawableSize;
+#endif
+
+ device->gl_config.accelerated = 1;
+
+ return device;
+ }
+}
+
+VideoBootStrap UIKIT_bootstrap = {
+ UIKITVID_DRIVER_NAME, "SDL UIKit video driver",
+ UIKit_Available, UIKit_CreateDevice
+};
+
+
+int
+UIKit_VideoInit(_THIS)
+{
+ _this->gl_config.driver_loaded = 1;
+
+ if (UIKit_InitModes(_this) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+UIKit_VideoQuit(_THIS)
+{
+ UIKit_QuitModes(_this);
+}
+
+void
+UIKit_SuspendScreenSaver(_THIS)
+{
+ @autoreleasepool {
+ /* Ignore ScreenSaver API calls if the idle timer hint has been set. */
+ /* FIXME: The idle timer hint should be deprecated for SDL 2.1. */
+ if (!SDL_GetHintBoolean(SDL_HINT_IDLE_TIMER_DISABLED, SDL_FALSE)) {
+ UIApplication *app = [UIApplication sharedApplication];
+
+ /* Prevent the display from dimming and going to sleep. */
+ app.idleTimerDisabled = (_this->suspend_screensaver != SDL_FALSE);
+ }
+ }
+}
+
+SDL_bool
+UIKit_IsSystemVersionAtLeast(double version)
+{
+ return [[UIDevice currentDevice].systemVersion doubleValue] >= version;
+}
+
+CGRect
+UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
+{
+ CGRect frame = screen.bounds;
+
+#if !TARGET_OS_TV && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0)
+ BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(7.0);
+
+ /* The view should always show behind the status bar in iOS 7+. */
+ if (!hasiOS7 && !(window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) {
+ frame = screen.applicationFrame;
+ }
+#endif
+
+#if !TARGET_OS_TV
+ /* iOS 10 seems to have a bug where, in certain conditions, putting the
+ * device to sleep with the a landscape-only app open, re-orienting the
+ * device to portrait, and turning it back on will result in the screen
+ * bounds returning portrait orientation despite the app being in landscape.
+ * This is a workaround until a better solution can be found.
+ * https://bugzilla.libsdl.org/show_bug.cgi?id=3505
+ * https://bugzilla.libsdl.org/show_bug.cgi?id=3465
+ * https://forums.developer.apple.com/thread/65337 */
+ if (UIKit_IsSystemVersionAtLeast(8.0)) {
+ UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation;
+ BOOL isLandscape = UIInterfaceOrientationIsLandscape(orient);
+
+ if (isLandscape != (frame.size.width > frame.size.height)) {
+ float height = frame.size.width;
+ frame.size.width = frame.size.height;
+ frame.size.height = height;
+ }
+ }
+#endif
+
+ return frame;
+}
+
+/*
+ * iOS log support.
+ *
+ * This doesn't really have aything to do with the interfaces of the SDL video
+ * subsystem, but we need to stuff this into an Objective-C source code file.
+ */
+
+void SDL_NSLog(const char *text)
+{
+ NSLog(@"%s", text);
+}
+
+/*
+ * iOS Tablet detection
+ *
+ * This doesn't really have aything to do with the interfaces of the SDL video
+ * subsystem, but we need to stuff this into an Objective-C source code file.
+ */
+SDL_bool SDL_IsIPad(void)
+{
+ return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h
new file mode 100644
index 0000000..4457f6c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#import <UIKit/UIKit.h>
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_touch.h"
+
+@interface SDL_uikitview : UIView
+
+- (instancetype)initWithFrame:(CGRect)frame;
+
+- (void)setSDLWindow:(SDL_Window *)window;
+
+- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
+
+@end
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m
new file mode 100644
index 0000000..caabfac
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m
@@ -0,0 +1,328 @@
+ /*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitview.h"
+
+#include "SDL_hints.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../../events/SDL_events_c.h"
+
+#import "SDL_uikitappdelegate.h"
+#import "SDL_uikitmodes.h"
+#import "SDL_uikitwindow.h"
+
+/* This is defined in SDL_sysjoystick.m */
+extern int SDL_AppleTVRemoteOpenedAsJoystick;
+
+@implementation SDL_uikitview {
+ SDL_Window *sdlwindow;
+
+ SDL_TouchID touchId;
+ UITouch * __weak firstFingerDown;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame])) {
+#if TARGET_OS_TV
+ /* Apple TV Remote touchpad swipe gestures. */
+ UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
+ [self addGestureRecognizer:swipeUp];
+
+ UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
+ [self addGestureRecognizer:swipeDown];
+
+ UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
+ [self addGestureRecognizer:swipeLeft];
+
+ UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
+ [self addGestureRecognizer:swipeRight];
+#endif
+
+ self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.autoresizesSubviews = YES;
+
+#if !TARGET_OS_TV
+ self.multipleTouchEnabled = YES;
+#endif
+
+ touchId = 1;
+ SDL_AddTouch(touchId, "");
+ }
+
+ return self;
+}
+
+- (void)setSDLWindow:(SDL_Window *)window
+{
+ SDL_WindowData *data = nil;
+
+ if (window == sdlwindow) {
+ return;
+ }
+
+ /* Remove ourself from the old window. */
+ if (sdlwindow) {
+ SDL_uikitview *view = nil;
+ data = (__bridge SDL_WindowData *) sdlwindow->driverdata;
+
+ [data.views removeObject:self];
+
+ [self removeFromSuperview];
+
+ /* Restore the next-oldest view in the old window. */
+ view = data.views.lastObject;
+
+ data.viewcontroller.view = view;
+
+ data.uiwindow.rootViewController = nil;
+ data.uiwindow.rootViewController = data.viewcontroller;
+
+ [data.uiwindow layoutIfNeeded];
+ }
+
+ /* Add ourself to the new window. */
+ if (window) {
+ data = (__bridge SDL_WindowData *) window->driverdata;
+
+ /* Make sure the SDL window has a strong reference to this view. */
+ [data.views addObject:self];
+
+ /* Replace the view controller's old view with this one. */
+ [data.viewcontroller.view removeFromSuperview];
+ data.viewcontroller.view = self;
+
+ /* The root view controller handles rotation and the status bar.
+ * Assigning it also adds the controller's view to the window. We
+ * explicitly re-set it to make sure the view is properly attached to
+ * the window. Just adding the sub-view if the root view controller is
+ * already correct causes orientation issues on iOS 7 and below. */
+ data.uiwindow.rootViewController = nil;
+ data.uiwindow.rootViewController = data.viewcontroller;
+
+ /* The view's bounds may not be correct until the next event cycle. That
+ * might happen after the current dimensions are queried, so we force a
+ * layout now to immediately update the bounds. */
+ [data.uiwindow layoutIfNeeded];
+ }
+
+ sdlwindow = window;
+}
+
+- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
+{
+ CGPoint point = [touch locationInView:self];
+
+ if (normalize) {
+ CGRect bounds = self.bounds;
+ point.x /= bounds.size.width;
+ point.y /= bounds.size.height;
+ }
+
+ return point;
+}
+
+- (float)pressureForTouch:(UITouch *)touch
+{
+#ifdef __IPHONE_9_0
+ if ([touch respondsToSelector:@selector(force)]) {
+ return (float) touch.force;
+ }
+#endif
+
+ return 1.0f;
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ for (UITouch *touch in touches) {
+ float pressure = [self pressureForTouch:touch];
+
+ if (!firstFingerDown) {
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
+ int clicks = (int) touch.tapCount;
+
+ /* send mouse moved event */
+ SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+
+ /* send mouse down event */
+ SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT, clicks);
+
+ firstFingerDown = touch;
+ }
+
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
+ SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
+ SDL_TRUE, locationInView.x, locationInView.y, pressure);
+ }
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ for (UITouch *touch in touches) {
+ float pressure = [self pressureForTouch:touch];
+
+ if (touch == firstFingerDown) {
+ /* send mouse up */
+ int clicks = (int) touch.tapCount;
+ SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT, clicks);
+ firstFingerDown = nil;
+ }
+
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
+ SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
+ SDL_FALSE, locationInView.x, locationInView.y, pressure);
+ }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self touchesEnded:touches withEvent:event];
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ for (UITouch *touch in touches) {
+ float pressure = [self pressureForTouch:touch];
+
+ if (touch == firstFingerDown) {
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
+
+ /* send moved event */
+ SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+ }
+
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
+ SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
+ locationInView.x, locationInView.y, pressure);
+ }
+}
+
+#if TARGET_OS_TV || defined(__IPHONE_9_1)
+- (SDL_Scancode)scancodeFromPressType:(UIPressType)presstype
+{
+ switch (presstype) {
+ case UIPressTypeUpArrow:
+ return SDL_SCANCODE_UP;
+ case UIPressTypeDownArrow:
+ return SDL_SCANCODE_DOWN;
+ case UIPressTypeLeftArrow:
+ return SDL_SCANCODE_LEFT;
+ case UIPressTypeRightArrow:
+ return SDL_SCANCODE_RIGHT;
+ case UIPressTypeSelect:
+ /* HIG says: "primary button behavior" */
+ return SDL_SCANCODE_RETURN;
+ case UIPressTypeMenu:
+ /* HIG says: "returns to previous screen" */
+ return SDL_SCANCODE_ESCAPE;
+ case UIPressTypePlayPause:
+ /* HIG says: "secondary button behavior" */
+ return SDL_SCANCODE_PAUSE;
+ default:
+ return SDL_SCANCODE_UNKNOWN;
+ }
+}
+
+- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ for (UIPress *press in presses) {
+ SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ }
+ }
+ [super pressesBegan:presses withEvent:event];
+}
+
+- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ for (UIPress *press in presses) {
+ SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+ }
+ [super pressesEnded:presses withEvent:event];
+}
+
+- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ for (UIPress *press in presses) {
+ SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+ }
+ [super pressesCancelled:presses withEvent:event];
+}
+
+- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ /* This is only called when the force of a press changes. */
+ [super pressesChanged:presses withEvent:event];
+}
+#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */
+
+#if TARGET_OS_TV
+-(void)swipeGesture:(UISwipeGestureRecognizer *)gesture
+{
+ /* Swipe gestures don't trigger begin states. */
+ if (gesture.state == UIGestureRecognizerStateEnded) {
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ /* Send arrow key presses for now, as we don't have an external API
+ * which better maps to swipe gestures. */
+ switch (gesture.direction) {
+ case UISwipeGestureRecognizerDirectionUp:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_UP);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_UP);
+ break;
+ case UISwipeGestureRecognizerDirectionDown:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DOWN);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DOWN);
+ break;
+ case UISwipeGestureRecognizerDirectionLeft:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LEFT);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LEFT);
+ break;
+ case UISwipeGestureRecognizerDirectionRight:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RIGHT);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RIGHT);
+ break;
+ }
+ }
+ }
+}
+#endif /* TARGET_OS_TV */
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h
new file mode 100644
index 0000000..fffb142
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h
@@ -0,0 +1,91 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#import <UIKit/UIKit.h>
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_touch.h"
+
+#if TARGET_OS_TV
+#import <GameController/GameController.h>
+#define SDLRootViewController GCEventViewController
+#else
+#define SDLRootViewController UIViewController
+#endif
+
+#if SDL_IPHONE_KEYBOARD
+@interface SDL_uikitviewcontroller : SDLRootViewController <UITextFieldDelegate>
+#else
+@interface SDL_uikitviewcontroller : SDLRootViewController
+#endif
+
+@property (nonatomic, assign) SDL_Window *window;
+
+- (instancetype)initWithSDLWindow:(SDL_Window *)_window;
+
+- (void)setAnimationCallback:(int)interval
+ callback:(void (*)(void*))callback
+ callbackParam:(void*)callbackParam;
+
+- (void)startAnimation;
+- (void)stopAnimation;
+
+- (void)doLoop:(CADisplayLink*)sender;
+
+- (void)loadView;
+- (void)viewDidLayoutSubviews;
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations;
+- (BOOL)prefersStatusBarHidden;
+- (BOOL)prefersHomeIndicatorAutoHidden;
+- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures;
+
+@property (nonatomic, assign) int homeIndicatorHidden;
+#endif
+
+#if SDL_IPHONE_KEYBOARD
+- (void)showKeyboard;
+- (void)hideKeyboard;
+- (void)initKeyboard;
+- (void)deinitKeyboard;
+
+- (void)keyboardWillShow:(NSNotification *)notification;
+- (void)keyboardWillHide:(NSNotification *)notification;
+
+- (void)updateKeyboard;
+
+@property (nonatomic, assign, getter=isKeyboardVisible) BOOL keyboardVisible;
+@property (nonatomic, assign) SDL_Rect textInputRect;
+@property (nonatomic, assign) int keyboardHeight;
+#endif
+
+@end
+
+#if SDL_IPHONE_KEYBOARD
+SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
+void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
+void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window);
+SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window);
+void UIKit_SetTextInputRect(_THIS, SDL_Rect *rect);
+#endif
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m
new file mode 100644
index 0000000..49a39b6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m
@@ -0,0 +1,553 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_video.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+
+#import "SDL_uikitviewcontroller.h"
+#import "SDL_uikitmessagebox.h"
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_uikitopengles.h"
+
+#if SDL_IPHONE_KEYBOARD
+#include "keyinfotable.h"
+#endif
+
+#if TARGET_OS_TV
+static void SDLCALL
+SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata;
+ viewcontroller.controllerUserInteractionEnabled = hint && (*hint != '0');
+ }
+}
+#endif
+
+#if !TARGET_OS_TV
+static void SDLCALL
+SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata;
+ viewcontroller.homeIndicatorHidden = (hint && *hint) ? SDL_atoi(hint) : -1;
+ if (@available(iOS 11.0, *)) {
+ [viewcontroller setNeedsUpdateOfHomeIndicatorAutoHidden];
+ [viewcontroller setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
+ }
+ }
+}
+#endif
+
+@implementation SDL_uikitviewcontroller {
+ CADisplayLink *displayLink;
+ int animationInterval;
+ void (*animationCallback)(void*);
+ void *animationCallbackParam;
+
+#if SDL_IPHONE_KEYBOARD
+ UITextField *textField;
+ BOOL rotatingOrientation;
+ NSString *changeText;
+ NSString *obligateForBackspace;
+#endif
+}
+
+@synthesize window;
+
+- (instancetype)initWithSDLWindow:(SDL_Window *)_window
+{
+ if (self = [super initWithNibName:nil bundle:nil]) {
+ self.window = _window;
+
+#if SDL_IPHONE_KEYBOARD
+ [self initKeyboard];
+ rotatingOrientation = FALSE;
+#endif
+
+#if TARGET_OS_TV
+ SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
+ SDL_AppleTVControllerUIHintChanged,
+ (__bridge void *) self);
+#endif
+
+#if !TARGET_OS_TV
+ SDL_AddHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR,
+ SDL_HideHomeIndicatorHintChanged,
+ (__bridge void *) self);
+#endif
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+#if SDL_IPHONE_KEYBOARD
+ [self deinitKeyboard];
+#endif
+
+#if TARGET_OS_TV
+ SDL_DelHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
+ SDL_AppleTVControllerUIHintChanged,
+ (__bridge void *) self);
+#endif
+
+#if !TARGET_OS_TV
+ SDL_DelHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR,
+ SDL_HideHomeIndicatorHintChanged,
+ (__bridge void *) self);
+#endif
+}
+
+- (void)setAnimationCallback:(int)interval
+ callback:(void (*)(void*))callback
+ callbackParam:(void*)callbackParam
+{
+ [self stopAnimation];
+
+ animationInterval = interval;
+ animationCallback = callback;
+ animationCallbackParam = callbackParam;
+
+ if (animationCallback) {
+ [self startAnimation];
+ }
+}
+
+- (void)startAnimation
+{
+ displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)];
+
+#ifdef __IPHONE_10_3
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+
+ if ([displayLink respondsToSelector:@selector(preferredFramesPerSecond)]
+ && data != nil && data.uiwindow != nil
+ && [data.uiwindow.screen respondsToSelector:@selector(maximumFramesPerSecond)]) {
+ displayLink.preferredFramesPerSecond = data.uiwindow.screen.maximumFramesPerSecond / animationInterval;
+ } else
+#endif
+ {
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 100300
+ [displayLink setFrameInterval:animationInterval];
+#endif
+ }
+
+ [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+}
+
+- (void)stopAnimation
+{
+ [displayLink invalidate];
+ displayLink = nil;
+}
+
+- (void)doLoop:(CADisplayLink*)sender
+{
+ /* Don't run the game loop while a messagebox is up */
+ if (!UIKit_ShowingMessageBox()) {
+ /* See the comment in the function definition. */
+ UIKit_GL_RestoreCurrentContext();
+
+ animationCallback(animationCallbackParam);
+ }
+}
+
+- (void)loadView
+{
+ /* Do nothing. */
+}
+
+- (void)viewDidLayoutSubviews
+{
+ const CGSize size = self.view.bounds.size;
+ int w = (int) size.width;
+ int h = (int) size.height;
+
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
+}
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations
+{
+ return UIKit_GetSupportedOrientations(window);
+}
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
+{
+ return ([self supportedInterfaceOrientations] & (1 << orient)) != 0;
+}
+#endif
+
+- (BOOL)prefersStatusBarHidden
+{
+ BOOL hidden = (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0;
+ return hidden;
+}
+
+- (BOOL)prefersHomeIndicatorAutoHidden
+{
+ BOOL hidden = NO;
+ if (self.homeIndicatorHidden == 1) {
+ hidden = YES;
+ }
+ return hidden;
+}
+
+- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
+{
+ if (self.homeIndicatorHidden >= 0) {
+ if (self.homeIndicatorHidden == 2) {
+ return UIRectEdgeAll;
+ } else {
+ return UIRectEdgeNone;
+ }
+ }
+
+ /* By default, fullscreen and borderless windows get all screen gestures */
+ if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0) {
+ return UIRectEdgeAll;
+ } else {
+ return UIRectEdgeNone;
+ }
+}
+#endif
+
+/*
+ ---- Keyboard related functionality below this line ----
+ */
+#if SDL_IPHONE_KEYBOARD
+
+@synthesize textInputRect;
+@synthesize keyboardHeight;
+@synthesize keyboardVisible;
+
+/* Set ourselves up as a UITextFieldDelegate */
+- (void)initKeyboard
+{
+ changeText = nil;
+ obligateForBackspace = @" "; /* 64 space */
+ textField = [[UITextField alloc] initWithFrame:CGRectZero];
+ textField.delegate = self;
+ /* placeholder so there is something to delete! */
+ textField.text = obligateForBackspace;
+
+ /* set UITextInputTrait properties, mostly to defaults */
+ textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
+ textField.autocorrectionType = UITextAutocorrectionTypeNo;
+ textField.enablesReturnKeyAutomatically = NO;
+ textField.keyboardAppearance = UIKeyboardAppearanceDefault;
+ textField.keyboardType = UIKeyboardTypeDefault;
+ textField.returnKeyType = UIReturnKeyDefault;
+ textField.secureTextEntry = NO;
+
+ textField.hidden = YES;
+ keyboardVisible = NO;
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+#if !TARGET_OS_TV
+ [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
+ [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
+#endif
+ [center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
+}
+
+- (void)setView:(UIView *)view
+{
+ [super setView:view];
+
+ [view addSubview:textField];
+
+ if (keyboardVisible) {
+ [self showKeyboard];
+ }
+}
+
+/* willRotateToInterfaceOrientation and didRotateFromInterfaceOrientation are deprecated in iOS 8+ in favor of viewWillTransitionToSize */
+#if TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
+{
+ [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+ rotatingOrientation = TRUE;
+ [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {}
+ completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
+ rotatingOrientation = FALSE;
+ }];
+}
+#else
+- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ rotatingOrientation = TRUE;
+}
+
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
+ rotatingOrientation = FALSE;
+}
+#endif /* TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 */
+
+- (void)deinitKeyboard
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+#if !TARGET_OS_TV
+ [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
+ [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
+#endif
+ [center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
+}
+
+/* reveal onscreen virtual keyboard */
+- (void)showKeyboard
+{
+ keyboardVisible = YES;
+ if (textField.window) {
+ [textField becomeFirstResponder];
+ }
+}
+
+/* hide onscreen virtual keyboard */
+- (void)hideKeyboard
+{
+ keyboardVisible = NO;
+ [textField resignFirstResponder];
+}
+
+- (void)keyboardWillShow:(NSNotification *)notification
+{
+#if !TARGET_OS_TV
+ CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
+
+ /* The keyboard rect is in the coordinate space of the screen/window, but we
+ * want its height in the coordinate space of the view. */
+ kbrect = [self.view convertRect:kbrect fromView:nil];
+
+ [self setKeyboardHeight:(int)kbrect.size.height];
+#endif
+}
+
+- (void)keyboardWillHide:(NSNotification *)notification
+{
+ if (!rotatingOrientation) {
+ SDL_StopTextInput();
+ }
+ [self setKeyboardHeight:0];
+}
+
+- (void)textFieldTextDidChange:(NSNotification *)notification
+{
+ if (changeText!=nil && textField.markedTextRange == nil)
+ {
+ NSUInteger len = changeText.length;
+ if (len > 0) {
+ /* Go through all the characters in the string we've been sent and
+ * convert them to key presses */
+ int i;
+ for (i = 0; i < len; i++) {
+ unichar c = [changeText characterAtIndex:i];
+ SDL_Scancode code;
+ Uint16 mod;
+
+ if (c < 127) {
+ /* Figure out the SDL_Scancode and SDL_keymod for this unichar */
+ code = unicharToUIKeyInfoTable[c].code;
+ mod = unicharToUIKeyInfoTable[c].mod;
+ } else {
+ /* We only deal with ASCII right now */
+ code = SDL_SCANCODE_UNKNOWN;
+ mod = 0;
+ }
+
+ if (mod & KMOD_SHIFT) {
+ /* If character uses shift, press shift down */
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
+ }
+
+ /* send a keydown and keyup even for the character */
+ SDL_SendKeyboardKey(SDL_PRESSED, code);
+ SDL_SendKeyboardKey(SDL_RELEASED, code);
+
+ if (mod & KMOD_SHIFT) {
+ /* If character uses shift, press shift back up */
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+ }
+ }
+ SDL_SendKeyboardText([changeText UTF8String]);
+ }
+ changeText = nil;
+ }
+}
+
+- (void)updateKeyboard
+{
+ CGAffineTransform t = self.view.transform;
+ CGPoint offset = CGPointMake(0.0, 0.0);
+ CGRect frame = UIKit_ComputeViewFrame(window, self.view.window.screen);
+
+ if (self.keyboardHeight) {
+ int rectbottom = self.textInputRect.y + self.textInputRect.h;
+ int keybottom = self.view.bounds.size.height - self.keyboardHeight;
+ if (keybottom < rectbottom) {
+ offset.y = keybottom - rectbottom;
+ }
+ }
+
+ /* Apply this view's transform (except any translation) to the offset, in
+ * order to orient it correctly relative to the frame's coordinate space. */
+ t.tx = 0.0;
+ t.ty = 0.0;
+ offset = CGPointApplyAffineTransform(offset, t);
+
+ /* Apply the updated offset to the view's frame. */
+ frame.origin.x += offset.x;
+ frame.origin.y += offset.y;
+
+ self.view.frame = frame;
+}
+
+- (void)setKeyboardHeight:(int)height
+{
+ keyboardVisible = height > 0;
+ keyboardHeight = height;
+ [self updateKeyboard];
+}
+
+/* UITextFieldDelegate method. Invoked when user types something. */
+- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
+{
+ NSUInteger len = string.length;
+ if (len == 0) {
+ changeText = nil;
+ if (textField.markedTextRange == nil) {
+ /* it wants to replace text with nothing, ie a delete */
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
+ }
+ if (textField.text.length < 16) {
+ textField.text = obligateForBackspace;
+ }
+ } else {
+ changeText = string;
+ }
+ return YES;
+}
+
+/* Terminates the editing session */
+- (BOOL)textFieldShouldReturn:(UITextField*)_textField
+{
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RETURN);
+ if (SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) {
+ SDL_StopTextInput();
+ }
+ return YES;
+}
+
+#endif
+
+@end
+
+/* iPhone keyboard addition functions */
+#if SDL_IPHONE_KEYBOARD
+
+static SDL_uikitviewcontroller *
+GetWindowViewController(SDL_Window * window)
+{
+ if (!window || !window->driverdata) {
+ SDL_SetError("Invalid window");
+ return nil;
+ }
+
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+
+ return data.viewcontroller;
+}
+
+SDL_bool
+UIKit_HasScreenKeyboardSupport(_THIS)
+{
+ return SDL_TRUE;
+}
+
+void
+UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(window);
+ [vc showKeyboard];
+ }
+}
+
+void
+UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(window);
+ [vc hideKeyboard];
+ }
+}
+
+SDL_bool
+UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(window);
+ if (vc != nil) {
+ return vc.keyboardVisible;
+ }
+ return SDL_FALSE;
+ }
+}
+
+void
+UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
+{
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return;
+ }
+
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(SDL_GetFocusWindow());
+ if (vc != nil) {
+ vc.textInputRect = *rect;
+
+ if (vc.keyboardVisible) {
+ [vc updateKeyboard];
+ }
+ }
+ }
+}
+
+
+#endif /* SDL_IPHONE_KEYBOARD */
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h
new file mode 100644
index 0000000..e3ec350
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_uikitvulkan_h_
+#define SDL_uikitvulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT
+
+int UIKit_Vulkan_LoadLibrary(_THIS, const char *path);
+void UIKit_Vulkan_UnloadLibrary(_THIS);
+SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
+
+#endif
+
+#endif /* SDL_uikitvulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m
new file mode 100644
index 0000000..771c7a4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m
@@ -0,0 +1,222 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_uikitvulkan.h"
+#include "SDL_uikitmetalview.h"
+#include "SDL_syswm.h"
+
+#include <dlfcn.h>
+
+#define DEFAULT_MOLTENVK "libMoltenVK.dylib"
+/* Since libSDL is static, could use RTLD_SELF. Using RTLD_DEFAULT is future
+ * proofing. */
+#define DEFAULT_HANDLE RTLD_DEFAULT
+
+int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasIOSSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+
+ if (_this->vulkan_config.loader_handle) {
+ return SDL_SetError("MoltenVK/Vulkan already loaded");
+ }
+
+ /* Load the Vulkan loader library */
+ if (!path) {
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ }
+
+ if (!path) {
+ /* MoltenVK framework, currently, v0.17.0, has a static library and is
+ * the recommended way to use the package. There is likely no object to
+ * load. */
+ vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
+ "vkGetInstanceProcAddr");
+ }
+
+ if (vkGetInstanceProcAddr) {
+ _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
+ } else {
+ if (!path) {
+ /* Look for the .dylib packaged with the application instead. */
+ path = DEFAULT_MOLTENVK;
+ }
+
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if (!_this->vulkan_config.loader_handle) {
+ return -1;
+ }
+ SDL_strlcpy(_this->vulkan_config.loader_path, path,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle,
+ "vkGetInstanceProcAddr");
+ }
+
+ if (!vkGetInstanceProcAddr) {
+ SDL_SetError("Failed to find %s in either executable or %s: %s",
+ "vkGetInstanceProcAddr",
+ DEFAULT_MOLTENVK,
+ (const char *) dlerror());
+ goto fail;
+ }
+
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+
+ if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
+ SDL_SetError("No vkEnumerateInstanceExtensionProperties found.");
+ goto fail;
+ }
+
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+
+ if (!extensions) {
+ goto fail;
+ }
+
+ for (Uint32 i = 0; i < extensionCount; i++) {
+ if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
+ hasSurfaceExtension = SDL_TRUE;
+ } else if (SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
+ hasIOSSurfaceExtension = SDL_TRUE;
+ }
+ }
+
+ SDL_free(extensions);
+
+ if (!hasSurfaceExtension) {
+ SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ } else if (!hasIOSSurfaceExtension) {
+ SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
+ VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void UIKit_Vulkan_UnloadLibrary(_THIS)
+{
+ if (_this->vulkan_config.loader_handle) {
+ if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE) {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ }
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForUIKit[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME
+ };
+ if (!_this->vulkan_config.loader_handle) {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForUIKit),
+ extensionsForUIKit);
+}
+
+SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK =
+ (PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateIOSSurfaceMVK");
+ VkIOSSurfaceCreateInfoMVK createInfo = {};
+ VkResult result;
+
+ if (!_this->vulkan_config.loader_handle) {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if (!vkCreateIOSSurfaceMVK) {
+ SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+
+ createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.pView = (__bridge void *)UIKit_Mtl_AddMetalView(window);
+ result = vkCreateIOSSurfaceMVK(instance, &createInfo,
+ NULL, surface);
+ if (result != VK_SUCCESS) {
+ SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+
+ return SDL_TRUE;
+}
+
+void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
+{
+ UIKit_Mtl_GetDrawableSize(window, w, h);
+}
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h
new file mode 100644
index 0000000..46073ee
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h
@@ -0,0 +1,56 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitwindow_h_
+#define SDL_uikitwindow_h_
+
+#include "../SDL_sysvideo.h"
+#import "SDL_uikitvideo.h"
+#import "SDL_uikitview.h"
+#import "SDL_uikitviewcontroller.h"
+
+extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
+extern void UIKit_SetWindowTitle(_THIS, SDL_Window * window);
+extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
+extern void UIKit_HideWindow(_THIS, SDL_Window * window);
+extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
+extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
+extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo * info);
+
+extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window * window);
+
+@class UIWindow;
+
+@interface SDL_WindowData : NSObject
+
+@property (nonatomic, strong) UIWindow *uiwindow;
+@property (nonatomic, strong) SDL_uikitviewcontroller *viewcontroller;
+
+/* Array of SDL_uikitviews owned by this window. */
+@property (nonatomic, copy) NSMutableArray *views;
+
+@end
+
+#endif /* SDL_uikitwindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m
new file mode 100644
index 0000000..d01cff3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m
@@ -0,0 +1,465 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_syswm.h"
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitevents.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#import "SDL_uikitappdelegate.h"
+
+#import "SDL_uikitview.h"
+#import "SDL_uikitopenglview.h"
+
+#include <Foundation/Foundation.h>
+
+@implementation SDL_WindowData
+
+@synthesize uiwindow;
+@synthesize viewcontroller;
+@synthesize views;
+
+- (instancetype)init
+{
+ if ((self = [super init])) {
+ views = [NSMutableArray new];
+ }
+
+ return self;
+}
+
+@end
+
+@interface SDL_uikitwindow : UIWindow
+
+- (void)layoutSubviews;
+
+@end
+
+@implementation SDL_uikitwindow
+
+- (void)layoutSubviews
+{
+ /* Workaround to fix window orientation issues in iOS 8+. */
+ self.frame = self.screen.bounds;
+ [super layoutSubviews];
+}
+
+@end
+
+
+static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
+ SDL_uikitview *view;
+
+ CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
+ int width = (int) frame.size.width;
+ int height = (int) frame.size.height;
+
+ SDL_WindowData *data = [[SDL_WindowData alloc] init];
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+
+ window->driverdata = (void *) CFBridgingRetain(data);
+
+ data.uiwindow = uiwindow;
+
+ /* only one window on iOS, always shown */
+ window->flags &= ~SDL_WINDOW_HIDDEN;
+
+ if (displaydata.uiscreen != [UIScreen mainScreen]) {
+ window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizable */
+ window->flags &= ~SDL_WINDOW_INPUT_FOCUS; /* never has input focus */
+ window->flags |= SDL_WINDOW_BORDERLESS; /* never has a status bar. */
+ }
+
+#if !TARGET_OS_TV
+ if (displaydata.uiscreen == [UIScreen mainScreen]) {
+ /* SDL_CreateWindow sets the window w&h to the display's bounds if the
+ * fullscreen flag is set. But the display bounds orientation might not
+ * match what we want, and GetSupportedOrientations call below uses the
+ * window w&h. They're overridden below anyway, so we'll just set them
+ * to the requested size for the purposes of determining orientation. */
+ window->w = window->windowed.w;
+ window->h = window->windowed.h;
+
+ NSUInteger orients = UIKit_GetSupportedOrientations(window);
+ BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0;
+ BOOL supportsPortrait = (orients & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown)) != 0;
+
+ /* Make sure the width/height are oriented correctly */
+ if ((width > height && !supportsLandscape) || (height > width && !supportsPortrait)) {
+ int temp = width;
+ width = height;
+ height = temp;
+ }
+ }
+#endif /* !TARGET_OS_TV */
+
+ window->x = 0;
+ window->y = 0;
+ window->w = width;
+ window->h = height;
+
+ /* The View Controller will handle rotating the view when the device
+ * orientation changes. This will trigger resize events, if appropriate. */
+ data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
+
+ /* The window will initially contain a generic view so resizes, touch events,
+ * etc. can be handled without an active OpenGL view/context. */
+ view = [[SDL_uikitview alloc] initWithFrame:frame];
+
+ /* Sets this view as the controller's view, and adds the view to the window
+ * heirarchy. */
+ [view setSDLWindow:window];
+
+ /* Make this window the current mouse focus for touch input */
+ if (displaydata.uiscreen == [UIScreen mainScreen]) {
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+ }
+
+ return 0;
+}
+
+int
+UIKit_CreateWindow(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+ /* SDL currently puts this window at the start of display's linked list. We rely on this. */
+ SDL_assert(_this->windows == window);
+
+ /* We currently only handle a single window per display on iOS */
+ if (window->next != NULL) {
+ return SDL_SetError("Only one window allowed per display.");
+ }
+
+ /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
+ * user, so it's in standby), try to force the display to a resolution
+ * that most closely matches the desired window size. */
+#if !TARGET_OS_TV
+ const CGSize origsize = data.uiscreen.currentMode.size;
+ if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
+ if (display->num_display_modes == 0) {
+ _this->GetDisplayModes(_this, display);
+ }
+
+ int i;
+ const SDL_DisplayMode *bestmode = NULL;
+ for (i = display->num_display_modes; i >= 0; i--) {
+ const SDL_DisplayMode *mode = &display->display_modes[i];
+ if ((mode->w >= window->w) && (mode->h >= window->h)) {
+ bestmode = mode;
+ }
+ }
+
+ if (bestmode) {
+ SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata;
+ [data.uiscreen setCurrentMode:modedata.uiscreenmode];
+
+ /* desktop_mode doesn't change here (the higher level will
+ * use it to set all the screens back to their defaults
+ * upon window destruction, SDL_Quit(), etc. */
+ display->current_mode = *bestmode;
+ }
+ }
+
+ if (data.uiscreen == [UIScreen mainScreen]) {
+ if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
+ [UIApplication sharedApplication].statusBarHidden = YES;
+ } else {
+ [UIApplication sharedApplication].statusBarHidden = NO;
+ }
+ }
+#endif /* !TARGET_OS_TV */
+
+ /* ignore the size user requested, and make a fullscreen window */
+ /* !!! FIXME: can we have a smaller view? */
+ UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
+
+ /* put the window on an external display if appropriate. */
+ if (data.uiscreen != [UIScreen mainScreen]) {
+ [uiwindow setScreen:data.uiscreen];
+ }
+
+ if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+void
+UIKit_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ data.viewcontroller.title = @(window->title);
+ }
+}
+
+void
+UIKit_ShowWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ [data.uiwindow makeKeyAndVisible];
+ }
+}
+
+void
+UIKit_HideWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ data.uiwindow.hidden = YES;
+ }
+}
+
+void
+UIKit_RaiseWindow(_THIS, SDL_Window * window)
+{
+ /* We don't currently offer a concept of "raising" the SDL window, since
+ * we only allow one per display, in the iOS fashion.
+ * However, we use this entry point to rebind the context to the view
+ * during OnWindowRestored processing. */
+ _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
+}
+
+static void
+UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
+
+#if !TARGET_OS_TV
+ if (data.uiwindow.screen == [UIScreen mainScreen]) {
+ if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
+ [UIApplication sharedApplication].statusBarHidden = YES;
+ } else {
+ [UIApplication sharedApplication].statusBarHidden = NO;
+ }
+
+ /* iOS 7+ won't update the status bar until we tell it to. */
+ if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
+ [viewcontroller setNeedsStatusBarAppearanceUpdate];
+ }
+ }
+
+ /* Update the view's frame to account for the status bar change. */
+ viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
+#endif /* !TARGET_OS_TV */
+
+#ifdef SDL_IPHONE_KEYBOARD
+ /* Make sure the view is offset correctly when the keyboard is visible. */
+ [viewcontroller updateKeyboard];
+#endif
+
+ [viewcontroller.view setNeedsLayout];
+ [viewcontroller.view layoutIfNeeded];
+}
+
+void
+UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
+{
+ @autoreleasepool {
+ UIKit_UpdateWindowBorder(_this, window);
+ }
+}
+
+void
+UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+ @autoreleasepool {
+ UIKit_UpdateWindowBorder(_this, window);
+ }
+}
+
+void
+UIKit_DestroyWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ if (window->driverdata != NULL) {
+ SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata);
+ NSArray *views = nil;
+
+ [data.viewcontroller stopAnimation];
+
+ /* Detach all views from this window. We use a copy of the array
+ * because setSDLWindow will remove the object from the original
+ * array, which would be undesirable if we were iterating over it. */
+ views = [data.views copy];
+ for (SDL_uikitview *view in views) {
+ [view setSDLWindow:NULL];
+ }
+
+ /* iOS may still hold a reference to the window after we release it.
+ * We want to make sure the SDL view controller isn't accessed in
+ * that case, because it would contain an invalid pointer to the old
+ * SDL window. */
+ data.uiwindow.rootViewController = nil;
+ data.uiwindow.hidden = YES;
+ }
+ }
+ window->driverdata = NULL;
+}
+
+SDL_bool
+UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ int versionnum = SDL_VERSIONNUM(info->version.major, info->version.minor, info->version.patch);
+
+ info->subsystem = SDL_SYSWM_UIKIT;
+ info->info.uikit.window = data.uiwindow;
+
+ /* These struct members were added in SDL 2.0.4. */
+ if (versionnum >= SDL_VERSIONNUM(2,0,4)) {
+ if ([data.viewcontroller.view isKindOfClass:[SDL_uikitopenglview class]]) {
+ SDL_uikitopenglview *glview = (SDL_uikitopenglview *)data.viewcontroller.view;
+ info->info.uikit.framebuffer = glview.drawableFramebuffer;
+ info->info.uikit.colorbuffer = glview.drawableRenderbuffer;
+ info->info.uikit.resolveFramebuffer = glview.msaaResolveFramebuffer;
+ } else {
+ info->info.uikit.framebuffer = 0;
+ info->info.uikit.colorbuffer = 0;
+ info->info.uikit.resolveFramebuffer = 0;
+ }
+ }
+
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+ }
+}
+
+#if !TARGET_OS_TV
+NSUInteger
+UIKit_GetSupportedOrientations(SDL_Window * window)
+{
+ const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
+ NSUInteger validOrientations = UIInterfaceOrientationMaskAll;
+ NSUInteger orientationMask = 0;
+
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ UIApplication *app = [UIApplication sharedApplication];
+
+ /* Get all possible valid orientations. If the app delegate doesn't tell
+ * us, we get the orientations from Info.plist via UIApplication. */
+ if ([app.delegate respondsToSelector:@selector(application:supportedInterfaceOrientationsForWindow:)]) {
+ validOrientations = [app.delegate application:app supportedInterfaceOrientationsForWindow:data.uiwindow];
+ } else if ([app respondsToSelector:@selector(supportedInterfaceOrientationsForWindow:)]) {
+ validOrientations = [app supportedInterfaceOrientationsForWindow:data.uiwindow];
+ }
+
+ if (hint != NULL) {
+ NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
+
+ if ([orientations containsObject:@"LandscapeLeft"]) {
+ orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
+ }
+ if ([orientations containsObject:@"LandscapeRight"]) {
+ orientationMask |= UIInterfaceOrientationMaskLandscapeRight;
+ }
+ if ([orientations containsObject:@"Portrait"]) {
+ orientationMask |= UIInterfaceOrientationMaskPortrait;
+ }
+ if ([orientations containsObject:@"PortraitUpsideDown"]) {
+ orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
+ }
+ }
+
+ if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
+ /* any orientation is okay. */
+ orientationMask = UIInterfaceOrientationMaskAll;
+ }
+
+ if (orientationMask == 0) {
+ if (window->w >= window->h) {
+ orientationMask |= UIInterfaceOrientationMaskLandscape;
+ }
+ if (window->h >= window->w) {
+ orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
+ }
+ }
+
+ /* Don't allow upside-down orientation on phones, so answering calls is in the natural orientation */
+ if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
+ orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
+ }
+
+ /* If none of the specified orientations are actually supported by the
+ * app, we'll revert to what the app supports. An exception would be
+ * thrown by the system otherwise. */
+ if ((validOrientations & orientationMask) == 0) {
+ orientationMask = validOrientations;
+ }
+ }
+
+ return orientationMask;
+}
+#endif /* !TARGET_OS_TV */
+
+int
+SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
+{
+ if (!window || !window->driverdata) {
+ return SDL_SetError("Invalid window");
+ }
+
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ [data.viewcontroller setAnimationCallback:interval
+ callback:callback
+ callbackParam:callbackParam];
+ }
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/keyinfotable.h b/source/3rd-party/SDL2/src/video/uikit/keyinfotable.h
new file mode 100644
index 0000000..3b23837
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/keyinfotable.h
@@ -0,0 +1,174 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef _UIKIT_KeyInfo
+#define _UIKIT_KeyInfo
+
+#include "SDL_scancode.h"
+
+/*
+ This file is used by the keyboard code in SDL_uikitview.m to convert between characters
+ passed in from the iPhone's virtual keyboard, and tuples of SDL_Scancode and SDL_keymods.
+ For example unicharToUIKeyInfoTable['a'] would give you the scan code and keymod for lower
+ case a.
+*/
+
+typedef struct
+{
+ SDL_Scancode code;
+ Uint16 mod;
+} UIKitKeyInfo;
+
+/* So far only ASCII characters here */
+static UIKitKeyInfo unicharToUIKeyInfoTable[] = {
+/* 0 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 1 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 2 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 3 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 4 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 5 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 6 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 7 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 8 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 9 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 10 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 11 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 12 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 13 */ { SDL_SCANCODE_RETURN, 0 },
+/* 14 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 15 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 16 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 17 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 18 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 19 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 20 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 21 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 22 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 23 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 24 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 25 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 26 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 27 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 28 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 29 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 30 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 31 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 32 */ { SDL_SCANCODE_SPACE, 0 },
+/* 33 */ { SDL_SCANCODE_1, KMOD_SHIFT }, /* plus shift modifier '!' */
+/* 34 */ { SDL_SCANCODE_APOSTROPHE, KMOD_SHIFT }, /* plus shift modifier '"' */
+/* 35 */ { SDL_SCANCODE_3, KMOD_SHIFT }, /* plus shift modifier '#' */
+/* 36 */ { SDL_SCANCODE_4, KMOD_SHIFT }, /* plus shift modifier '$' */
+/* 37 */ { SDL_SCANCODE_5, KMOD_SHIFT }, /* plus shift modifier '%' */
+/* 38 */ { SDL_SCANCODE_7, KMOD_SHIFT }, /* plus shift modifier '&' */
+/* 39 */ { SDL_SCANCODE_APOSTROPHE, 0 }, /* ''' */
+/* 40 */ { SDL_SCANCODE_9, KMOD_SHIFT }, /* plus shift modifier '(' */
+/* 41 */ { SDL_SCANCODE_0, KMOD_SHIFT }, /* plus shift modifier ')' */
+/* 42 */ { SDL_SCANCODE_8, KMOD_SHIFT }, /* '*' */
+/* 43 */ { SDL_SCANCODE_EQUALS, KMOD_SHIFT }, /* plus shift modifier '+' */
+/* 44 */ { SDL_SCANCODE_COMMA, 0 }, /* ',' */
+/* 45 */ { SDL_SCANCODE_MINUS, 0 }, /* '-' */
+/* 46 */ { SDL_SCANCODE_PERIOD, 0 }, /* '.' */
+/* 47 */ { SDL_SCANCODE_SLASH, 0 }, /* '/' */
+/* 48 */ { SDL_SCANCODE_0, 0 },
+/* 49 */ { SDL_SCANCODE_1, 0 },
+/* 50 */ { SDL_SCANCODE_2, 0 },
+/* 51 */ { SDL_SCANCODE_3, 0 },
+/* 52 */ { SDL_SCANCODE_4, 0 },
+/* 53 */ { SDL_SCANCODE_5, 0 },
+/* 54 */ { SDL_SCANCODE_6, 0 },
+/* 55 */ { SDL_SCANCODE_7, 0 },
+/* 56 */ { SDL_SCANCODE_8, 0 },
+/* 57 */ { SDL_SCANCODE_9, 0 },
+/* 58 */ { SDL_SCANCODE_SEMICOLON, KMOD_SHIFT }, /* plus shift modifier ';' */
+/* 59 */ { SDL_SCANCODE_SEMICOLON, 0 },
+/* 60 */ { SDL_SCANCODE_COMMA, KMOD_SHIFT }, /* plus shift modifier '<' */
+/* 61 */ { SDL_SCANCODE_EQUALS, 0 },
+/* 62 */ { SDL_SCANCODE_PERIOD, KMOD_SHIFT }, /* plus shift modifier '>' */
+/* 63 */ { SDL_SCANCODE_SLASH, KMOD_SHIFT }, /* plus shift modifier '?' */
+/* 64 */ { SDL_SCANCODE_2, KMOD_SHIFT }, /* plus shift modifier '@' */
+/* 65 */ { SDL_SCANCODE_A, KMOD_SHIFT }, /* all the following need shift modifiers */
+/* 66 */ { SDL_SCANCODE_B, KMOD_SHIFT },
+/* 67 */ { SDL_SCANCODE_C, KMOD_SHIFT },
+/* 68 */ { SDL_SCANCODE_D, KMOD_SHIFT },
+/* 69 */ { SDL_SCANCODE_E, KMOD_SHIFT },
+/* 70 */ { SDL_SCANCODE_F, KMOD_SHIFT },
+/* 71 */ { SDL_SCANCODE_G, KMOD_SHIFT },
+/* 72 */ { SDL_SCANCODE_H, KMOD_SHIFT },
+/* 73 */ { SDL_SCANCODE_I, KMOD_SHIFT },
+/* 74 */ { SDL_SCANCODE_J, KMOD_SHIFT },
+/* 75 */ { SDL_SCANCODE_K, KMOD_SHIFT },
+/* 76 */ { SDL_SCANCODE_L, KMOD_SHIFT },
+/* 77 */ { SDL_SCANCODE_M, KMOD_SHIFT },
+/* 78 */ { SDL_SCANCODE_N, KMOD_SHIFT },
+/* 79 */ { SDL_SCANCODE_O, KMOD_SHIFT },
+/* 80 */ { SDL_SCANCODE_P, KMOD_SHIFT },
+/* 81 */ { SDL_SCANCODE_Q, KMOD_SHIFT },
+/* 82 */ { SDL_SCANCODE_R, KMOD_SHIFT },
+/* 83 */ { SDL_SCANCODE_S, KMOD_SHIFT },
+/* 84 */ { SDL_SCANCODE_T, KMOD_SHIFT },
+/* 85 */ { SDL_SCANCODE_U, KMOD_SHIFT },
+/* 86 */ { SDL_SCANCODE_V, KMOD_SHIFT },
+/* 87 */ { SDL_SCANCODE_W, KMOD_SHIFT },
+/* 88 */ { SDL_SCANCODE_X, KMOD_SHIFT },
+/* 89 */ { SDL_SCANCODE_Y, KMOD_SHIFT },
+/* 90 */ { SDL_SCANCODE_Z, KMOD_SHIFT },
+/* 91 */ { SDL_SCANCODE_LEFTBRACKET, 0 },
+/* 92 */ { SDL_SCANCODE_BACKSLASH, 0 },
+/* 93 */ { SDL_SCANCODE_RIGHTBRACKET, 0 },
+/* 94 */ { SDL_SCANCODE_6, KMOD_SHIFT }, /* plus shift modifier '^' */
+/* 95 */ { SDL_SCANCODE_MINUS, KMOD_SHIFT }, /* plus shift modifier '_' */
+/* 96 */ { SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* '`' */
+/* 97 */ { SDL_SCANCODE_A, 0 },
+/* 98 */ { SDL_SCANCODE_B, 0 },
+/* 99 */ { SDL_SCANCODE_C, 0 },
+/* 100 */{ SDL_SCANCODE_D, 0 },
+/* 101 */{ SDL_SCANCODE_E, 0 },
+/* 102 */{ SDL_SCANCODE_F, 0 },
+/* 103 */{ SDL_SCANCODE_G, 0 },
+/* 104 */{ SDL_SCANCODE_H, 0 },
+/* 105 */{ SDL_SCANCODE_I, 0 },
+/* 106 */{ SDL_SCANCODE_J, 0 },
+/* 107 */{ SDL_SCANCODE_K, 0 },
+/* 108 */{ SDL_SCANCODE_L, 0 },
+/* 109 */{ SDL_SCANCODE_M, 0 },
+/* 110 */{ SDL_SCANCODE_N, 0 },
+/* 111 */{ SDL_SCANCODE_O, 0 },
+/* 112 */{ SDL_SCANCODE_P, 0 },
+/* 113 */{ SDL_SCANCODE_Q, 0 },
+/* 114 */{ SDL_SCANCODE_R, 0 },
+/* 115 */{ SDL_SCANCODE_S, 0 },
+/* 116 */{ SDL_SCANCODE_T, 0 },
+/* 117 */{ SDL_SCANCODE_U, 0 },
+/* 118 */{ SDL_SCANCODE_V, 0 },
+/* 119 */{ SDL_SCANCODE_W, 0 },
+/* 120 */{ SDL_SCANCODE_X, 0 },
+/* 121 */{ SDL_SCANCODE_Y, 0 },
+/* 122 */{ SDL_SCANCODE_Z, 0 },
+/* 123 */{ SDL_SCANCODE_LEFTBRACKET, KMOD_SHIFT }, /* plus shift modifier '{' */
+/* 124 */{ SDL_SCANCODE_BACKSLASH, KMOD_SHIFT }, /* plus shift modifier '|' */
+/* 125 */{ SDL_SCANCODE_RIGHTBRACKET, KMOD_SHIFT }, /* plus shift modifier '}' */
+/* 126 */{ SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* plus shift modifier '~' */
+/* 127 */{ SDL_SCANCODE_BACKSPACE, KMOD_SHIFT }
+};
+
+#endif /* _UIKIT_KeyInfo */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.c b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.c
new file mode 100644
index 0000000..135e838
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.c
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_vivanteopengles.h"
+#include "SDL_vivantevideo.h"
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+VIVANTE_GLES_LoadLibrary(_THIS, const char *path)
+{
+ SDL_DisplayData *displaydata;
+
+ displaydata = SDL_GetDisplayDriverData(0);
+
+ return SDL_EGL_LoadLibrary(_this, path, displaydata->native_display, 0);
+}
+
+SDL_EGL_CreateContext_impl(VIVANTE)
+SDL_EGL_SwapWindow_impl(VIVANTE)
+SDL_EGL_MakeCurrent_impl(VIVANTE)
+
+#endif /* SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.h b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.h
new file mode 100644
index 0000000..162d61a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteopengles.h
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_vivanteopengles_h_
+#define SDL_vivanteopengles_h_
+
+#if SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define VIVANTE_GLES_GetAttribute SDL_EGL_GetAttribute
+#define VIVANTE_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define VIVANTE_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define VIVANTE_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define VIVANTE_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define VIVANTE_GLES_DeleteContext SDL_EGL_DeleteContext
+
+extern int VIVANTE_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext VIVANTE_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int VIVANTE_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int VIVANTE_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_vivanteopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.c b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.c
new file mode 100644
index 0000000..67ea633
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.c
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_VIVANTE
+
+#include "SDL_vivanteplatform.h"
+
+#ifdef VIVANTE_PLATFORM_GENERIC
+
+int
+VIVANTE_SetupPlatform(_THIS)
+{
+ return 0;
+}
+
+char *VIVANTE_GetDisplayName(_THIS)
+{
+ return NULL;
+}
+
+void
+VIVANTE_UpdateDisplayScale(_THIS)
+{
+}
+
+void
+VIVANTE_CleanupPlatform(_THIS)
+{
+}
+
+#endif /* VIVANTE_PLATFORM_GENERIC */
+
+#endif /* SDL_VIDEO_DRIVER_VIVANTE */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.h b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.h
new file mode 100644
index 0000000..59fbf60
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/vivante/SDL_vivanteplatform.h
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_vivanteplatform_h_
+#define SDL_vivanteplatform_h_
+
+#if SDL_VIDEO_DRIVER_VIVANTE
+
+#include "SDL_vivantevideo.h"
+
+#if defined(CAVIUM)
+#define VIVANTE_PLATFORM_CAVIUM
+#elif defined(MARVELL)
+#define VIVANTE_PLATFORM_MARVELL
+#else
+#define VIVANTE_PLATFORM_GENERIC
+#endif
+
+extern int VIVANTE_SetupPlatform(_THIS);
+extern char *VIVANTE_GetDisplayName(_THIS);
+extern void VIVANTE_UpdateDisplayScale(_THIS);
+extern void VIVANTE_CleanupPlatform(_THIS);
+
+#endif /* SDL_VIDEO_DRIVER_VIVANTE */
+
+#endif /* SDL_vivanteplatform_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.c b/source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.c
new file mode 100644
index 0000000..656ab55
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.c
@@ -0,0 +1,409 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_VIVANTE
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_version.h"
+#include "SDL_syswm.h"
+#include "SDL_loadso.h"
+#include "SDL_events.h"
+#include "../../events/SDL_events_c.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+#include "SDL_vivantevideo.h"
+#include "SDL_vivanteplatform.h"
+#include "SDL_vivanteopengles.h"
+
+
+static int
+VIVANTE_Available(void)
+{
+ return 1;
+}
+
+static void
+VIVANTE_Destroy(SDL_VideoDevice * device)
+{
+ if (device->driverdata != NULL) {
+ SDL_free(device->driverdata);
+ device->driverdata = NULL;
+ }
+}
+
+static SDL_VideoDevice *
+VIVANTE_Create()
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ /* Initialize SDL_VideoDevice structure */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Initialize internal data */
+ data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (data == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return NULL;
+ }
+
+ device->driverdata = data;
+
+ /* Setup amount of available displays */
+ device->num_displays = 0;
+
+ /* Set device free function */
+ device->free = VIVANTE_Destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit = VIVANTE_VideoInit;
+ device->VideoQuit = VIVANTE_VideoQuit;
+ device->GetDisplayModes = VIVANTE_GetDisplayModes;
+ device->SetDisplayMode = VIVANTE_SetDisplayMode;
+ device->CreateSDLWindow = VIVANTE_CreateWindow;
+ device->SetWindowTitle = VIVANTE_SetWindowTitle;
+ device->SetWindowPosition = VIVANTE_SetWindowPosition;
+ device->SetWindowSize = VIVANTE_SetWindowSize;
+ device->ShowWindow = VIVANTE_ShowWindow;
+ device->HideWindow = VIVANTE_HideWindow;
+ device->DestroyWindow = VIVANTE_DestroyWindow;
+ device->GetWindowWMInfo = VIVANTE_GetWindowWMInfo;
+
+#if SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary;
+ device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary;
+ device->GL_CreateContext = VIVANTE_GLES_CreateContext;
+ device->GL_MakeCurrent = VIVANTE_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = VIVANTE_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = VIVANTE_GLES_GetSwapInterval;
+ device->GL_SwapWindow = VIVANTE_GLES_SwapWindow;
+ device->GL_DeleteContext = VIVANTE_GLES_DeleteContext;
+#endif
+
+ device->PumpEvents = VIVANTE_PumpEvents;
+
+ return device;
+}
+
+VideoBootStrap VIVANTE_bootstrap = {
+ "vivante",
+ "Vivante EGL Video Driver",
+ VIVANTE_Available,
+ VIVANTE_Create
+};
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions */
+/*****************************************************************************/
+
+static int
+VIVANTE_AddVideoDisplays(_THIS)
+{
+ SDL_VideoData *videodata = _this->driverdata;
+ SDL_VideoDisplay display;
+ SDL_DisplayMode current_mode;
+ SDL_DisplayData *data;
+ int pitch = 0, bpp = 0;
+ unsigned long pixels = 0;
+
+ data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
+ if (data == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ SDL_zero(current_mode);
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ data->native_display = vdkGetDisplay(videodata->vdk_private);
+
+ vdkGetDisplayInfo(data->native_display, &current_mode.w, &current_mode.h, &pixels, &pitch, &bpp);
+#else
+ data->native_display = videodata->fbGetDisplayByIndex(0);
+
+ videodata->fbGetDisplayInfo(data->native_display, &current_mode.w, &current_mode.h, &pixels, &pitch, &bpp);
+#endif /* SDL_VIDEO_DRIVER_VIVANTE_VDK */
+
+ switch (bpp)
+ {
+ default: /* Is another format used? */
+ case 32:
+ current_mode.format = SDL_PIXELFORMAT_ARGB8888;
+ break;
+ case 16:
+ current_mode.format = SDL_PIXELFORMAT_RGB565;
+ break;
+ }
+ /* FIXME: How do we query refresh rate? */
+ current_mode.refresh_rate = 60;
+
+ SDL_zero(display);
+ display.name = VIVANTE_GetDisplayName(_this);
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+ display.driverdata = data;
+ SDL_AddVideoDisplay(&display);
+ return 0;
+}
+
+int
+VIVANTE_VideoInit(_THIS)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ videodata->vdk_private = vdkInitialize();
+ if (!videodata->vdk_private) {
+ return SDL_SetError("vdkInitialize() failed");
+ }
+#else
+ videodata->egl_handle = SDL_LoadObject("libEGL.so.1");
+ if (!videodata->egl_handle) {
+ videodata->egl_handle = SDL_LoadObject("libEGL.so");
+ if (!videodata->egl_handle) {
+ return -1;
+ }
+ }
+#define LOAD_FUNC(NAME) \
+ videodata->NAME = SDL_LoadFunction(videodata->egl_handle, #NAME); \
+ if (!videodata->NAME) return -1;
+
+ LOAD_FUNC(fbGetDisplay);
+ LOAD_FUNC(fbGetDisplayByIndex);
+ LOAD_FUNC(fbGetDisplayGeometry);
+ LOAD_FUNC(fbGetDisplayInfo);
+ LOAD_FUNC(fbDestroyDisplay);
+ LOAD_FUNC(fbCreateWindow);
+ LOAD_FUNC(fbGetWindowGeometry);
+ LOAD_FUNC(fbGetWindowInfo);
+ LOAD_FUNC(fbDestroyWindow);
+#endif
+
+ if (VIVANTE_SetupPlatform(_this) < 0) {
+ return -1;
+ }
+
+ if (VIVANTE_AddVideoDisplays(_this) < 0) {
+ return -1;
+ }
+
+ VIVANTE_UpdateDisplayScale(_this);
+
+#ifdef SDL_INPUT_LINUXEV
+ if (SDL_EVDEV_Init() < 0) {
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+void
+VIVANTE_VideoQuit(_THIS)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Quit();
+#endif
+
+ VIVANTE_CleanupPlatform(_this);
+
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ if (videodata->vdk_private) {
+ vdkExit(videodata->vdk_private);
+ videodata->vdk_private = NULL;
+ }
+#else
+ if (videodata->egl_handle) {
+ SDL_UnloadObject(videodata->egl_handle);
+ videodata->egl_handle = NULL;
+ }
+#endif
+}
+
+void
+VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ /* Only one display mode available, the current one */
+ SDL_AddDisplayMode(display, &display->current_mode);
+}
+
+int
+VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+int
+VIVANTE_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ SDL_DisplayData *displaydata;
+ SDL_WindowData *data;
+
+ displaydata = SDL_GetDisplayDriverData(0);
+
+ /* Allocate window internal data */
+ data = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (data == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Setup driver data for this window */
+ window->driverdata = data;
+
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ data->native_window = vdkCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);
+#else
+ data->native_window = videodata->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h);
+#endif
+ if (!data->native_window) {
+ return SDL_SetError("VIVANTE: Can't create native window");
+ }
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (window->flags & SDL_WINDOW_OPENGL) {
+ data->egl_surface = SDL_EGL_CreateSurface(_this, data->native_window);
+ if (data->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("VIVANTE: Can't create EGL surface");
+ }
+ } else {
+ data->egl_surface = EGL_NO_SURFACE;
+ }
+#endif
+
+ /* Window has been successfully created */
+ return 0;
+}
+
+void
+VIVANTE_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ SDL_WindowData *data;
+
+ data = window->driverdata;
+ if (data) {
+#if SDL_VIDEO_OPENGL_EGL
+ if (data->egl_surface != EGL_NO_SURFACE) {
+ SDL_EGL_DestroySurface(_this, data->egl_surface);
+ }
+#endif
+
+ if (data->native_window) {
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ vdkDestroyWindow(data->native_window);
+#else
+ videodata->fbDestroyWindow(data->native_window);
+#endif
+ }
+
+ SDL_free(data);
+ }
+ window->driverdata = NULL;
+}
+
+void
+VIVANTE_SetWindowTitle(_THIS, SDL_Window * window)
+{
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ SDL_WindowData *data = window->driverdata;
+ vdkSetWindowTitle(data->native_window, window->title);
+#endif
+}
+
+void
+VIVANTE_SetWindowPosition(_THIS, SDL_Window * window)
+{
+ /* FIXME */
+}
+
+void
+VIVANTE_SetWindowSize(_THIS, SDL_Window * window)
+{
+ /* FIXME */
+}
+
+void
+VIVANTE_ShowWindow(_THIS, SDL_Window * window)
+{
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ SDL_WindowData *data = window->driverdata;
+ vdkShowWindow(data->native_window);
+#endif
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+}
+
+void
+VIVANTE_HideWindow(_THIS, SDL_Window * window)
+{
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ SDL_WindowData *data = window->driverdata;
+ vdkHideWindow(data->native_window);
+#endif
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function */
+/*****************************************************************************/
+SDL_bool
+VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0);
+
+ if (info->version.major == SDL_MAJOR_VERSION &&
+ info->version.minor == SDL_MINOR_VERSION) {
+ info->subsystem = SDL_SYSWM_VIVANTE;
+ info->info.vivante.display = displaydata->native_display;
+ info->info.vivante.window = data->native_window;
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+}
+
+/*****************************************************************************/
+/* SDL event functions */
+/*****************************************************************************/
+void VIVANTE_PumpEvents(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Poll();
+#endif
+}
+
+#endif /* SDL_VIDEO_DRIVER_VIVANTE */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.h b/source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.h
new file mode 100644
index 0000000..d335564
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/vivante/SDL_vivantevideo.h
@@ -0,0 +1,91 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_vivantevideo_h_
+#define SDL_vivantevideo_h_
+
+#include "../../SDL_internal.h"
+#include "../SDL_sysvideo.h"
+
+#include "SDL_egl.h"
+
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+#include <gc_vdk.h>
+#else
+#include <EGL/egl.h>
+#endif
+
+typedef struct SDL_VideoData
+{
+#if SDL_VIDEO_DRIVER_VIVANTE_VDK
+ vdkPrivate vdk_private;
+#else
+ void *egl_handle; /* EGL shared library handle */
+ EGLNativeDisplayType (EGLAPIENTRY *fbGetDisplay)(void *context);
+ EGLNativeDisplayType (EGLAPIENTRY *fbGetDisplayByIndex)(int DisplayIndex);
+ void (EGLAPIENTRY *fbGetDisplayGeometry)(EGLNativeDisplayType Display, int *Width, int *Height);
+ void (EGLAPIENTRY *fbGetDisplayInfo)(EGLNativeDisplayType Display, int *Width, int *Height, unsigned long *Physical, int *Stride, int *BitsPerPixel);
+ void (EGLAPIENTRY *fbDestroyDisplay)(EGLNativeDisplayType Display);
+ EGLNativeWindowType (EGLAPIENTRY *fbCreateWindow)(EGLNativeDisplayType Display, int X, int Y, int Width, int Height);
+ void (EGLAPIENTRY *fbGetWindowGeometry)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height);
+ void (EGLAPIENTRY *fbGetWindowInfo)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height, int *BitsPerPixel, unsigned int *Offset);
+ void (EGLAPIENTRY *fbDestroyWindow)(EGLNativeWindowType Window);
+#endif
+} SDL_VideoData;
+
+typedef struct SDL_DisplayData
+{
+ EGLNativeDisplayType native_display;
+} SDL_DisplayData;
+
+typedef struct SDL_WindowData
+{
+ EGLNativeWindowType native_window;
+ EGLSurface egl_surface;
+} SDL_WindowData;
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration */
+/****************************************************************************/
+
+/* Display and window functions */
+int VIVANTE_VideoInit(_THIS);
+void VIVANTE_VideoQuit(_THIS);
+void VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+int VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int VIVANTE_CreateWindow(_THIS, SDL_Window * window);
+void VIVANTE_SetWindowTitle(_THIS, SDL_Window * window);
+void VIVANTE_SetWindowPosition(_THIS, SDL_Window * window);
+void VIVANTE_SetWindowSize(_THIS, SDL_Window * window);
+void VIVANTE_ShowWindow(_THIS, SDL_Window * window);
+void VIVANTE_HideWindow(_THIS, SDL_Window * window);
+void VIVANTE_DestroyWindow(_THIS, SDL_Window * window);
+
+/* Window manager function */
+SDL_bool VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+/* Event functions */
+void VIVANTE_PumpEvents(_THIS);
+
+#endif /* SDL_vivantevideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.c
new file mode 100644
index 0000000..5fd826b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.c
@@ -0,0 +1,123 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+#include "SDL_waylanddatamanager.h"
+#include "SDL_waylandevents_c.h"
+
+int
+Wayland_SetClipboardText(_THIS, const char *text)
+{
+ SDL_VideoData *video_data = NULL;
+ SDL_WaylandDataDevice *data_device = NULL;
+
+ int status = 0;
+
+ if (_this == NULL || _this->driverdata == NULL) {
+ status = SDL_SetError("Video driver uninitialized");
+ } else {
+ video_data = _this->driverdata;
+ /* TODO: Support more than one seat */
+ data_device = Wayland_get_data_device(video_data->input);
+ if (text[0] != '\0') {
+ SDL_WaylandDataSource* source = Wayland_data_source_create(_this);
+ Wayland_data_source_add_data(source, TEXT_MIME, text,
+ strlen(text) + 1);
+
+ status = Wayland_data_device_set_selection(data_device, source);
+ if (status != 0) {
+ Wayland_data_source_destroy(source);
+ }
+ } else {
+ status = Wayland_data_device_clear_selection(data_device);
+ }
+ }
+
+ return status;
+}
+
+char *
+Wayland_GetClipboardText(_THIS)
+{
+ SDL_VideoData *video_data = NULL;
+ SDL_WaylandDataDevice *data_device = NULL;
+
+ char *text = NULL;
+
+ void *buffer = NULL;
+ size_t length = 0;
+
+ if (_this == NULL || _this->driverdata == NULL) {
+ SDL_SetError("Video driver uninitialized");
+ } else {
+ video_data = _this->driverdata;
+ /* TODO: Support more than one seat */
+ data_device = Wayland_get_data_device(video_data->input);
+ if (data_device->selection_offer != NULL) {
+ buffer = Wayland_data_offer_receive(data_device->selection_offer,
+ &length, TEXT_MIME, SDL_TRUE);
+ if (length > 0) {
+ text = (char*) buffer;
+ }
+ } else if (data_device->selection_source != NULL) {
+ buffer = Wayland_data_source_get_data(data_device->selection_source,
+ &length, TEXT_MIME, SDL_TRUE);
+ if (length > 0) {
+ text = (char*) buffer;
+ }
+ }
+ }
+
+ if (text == NULL) {
+ text = SDL_strdup("");
+ }
+
+ return text;
+}
+
+SDL_bool
+Wayland_HasClipboardText(_THIS)
+{
+ SDL_VideoData *video_data = NULL;
+ SDL_WaylandDataDevice *data_device = NULL;
+
+ SDL_bool result = SDL_FALSE;
+ if (_this == NULL || _this->driverdata == NULL) {
+ SDL_SetError("Video driver uninitialized");
+ } else {
+ video_data = _this->driverdata;
+ data_device = Wayland_get_data_device(video_data->input);
+ if (data_device != NULL && Wayland_data_offer_has_mime(
+ data_device->selection_offer, TEXT_MIME)) {
+ result = SDL_TRUE;
+ } else if(data_device != NULL && Wayland_data_source_has_mime(
+ data_device->selection_source, TEXT_MIME)) {
+ result = SDL_TRUE;
+ }
+ }
+ return result;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.h
new file mode 100644
index 0000000..467e1c7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandclipboard.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylandclipboard_h_
+#define SDL_waylandclipboard_h_
+
+extern int Wayland_SetClipboardText(_THIS, const char *text);
+extern char *Wayland_GetClipboardText(_THIS);
+extern SDL_bool Wayland_HasClipboardText(_THIS);
+
+#endif /* SDL_waylandclipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.c
new file mode 100644
index 0000000..f1b9742
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.c
@@ -0,0 +1,468 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <signal.h>
+
+#include "SDL_stdinc.h"
+#include "SDL_assert.h"
+#include "../../core/unix/SDL_poll.h"
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylanddatamanager.h"
+
+#include "SDL_waylanddyn.h"
+
+static ssize_t
+write_pipe(int fd, const void* buffer, size_t total_length, size_t *pos)
+{
+ int ready = 0;
+ ssize_t bytes_written = 0;
+ ssize_t length = total_length - *pos;
+
+ sigset_t sig_set;
+ sigset_t old_sig_set;
+ struct timespec zerotime = {0};
+
+ ready = SDL_IOReady(fd, SDL_TRUE, 1 * 1000);
+
+ sigemptyset(&sig_set);
+ sigaddset(&sig_set, SIGPIPE);
+
+ pthread_sigmask(SIG_BLOCK, &sig_set, &old_sig_set);
+
+ if (ready == 0) {
+ bytes_written = SDL_SetError("Pipe timeout");
+ } else if (ready < 0) {
+ bytes_written = SDL_SetError("Pipe select error");
+ } else {
+ if (length > 0) {
+ bytes_written = write(fd, (Uint8*)buffer + *pos, SDL_min(length, PIPE_BUF));
+ }
+
+ if (bytes_written > 0) {
+ *pos += bytes_written;
+ }
+ }
+
+ sigtimedwait(&sig_set, 0, &zerotime);
+ pthread_sigmask(SIG_SETMASK, &old_sig_set, NULL);
+
+ return bytes_written;
+}
+
+static ssize_t
+read_pipe(int fd, void** buffer, size_t* total_length, SDL_bool null_terminate)
+{
+ int ready = 0;
+ void* output_buffer = NULL;
+ char temp[PIPE_BUF];
+ size_t new_buffer_length = 0;
+ ssize_t bytes_read = 0;
+ size_t pos = 0;
+
+ ready = SDL_IOReady(fd, SDL_FALSE, 1 * 1000);
+
+ if (ready == 0) {
+ bytes_read = SDL_SetError("Pipe timeout");
+ } else if (ready < 0) {
+ bytes_read = SDL_SetError("Pipe select error");
+ } else {
+ bytes_read = read(fd, temp, sizeof(temp));
+ }
+
+ if (bytes_read > 0) {
+ pos = *total_length;
+ *total_length += bytes_read;
+
+ if (null_terminate == SDL_TRUE) {
+ new_buffer_length = *total_length + 1;
+ } else {
+ new_buffer_length = *total_length;
+ }
+
+ if (*buffer == NULL) {
+ output_buffer = SDL_malloc(new_buffer_length);
+ } else {
+ output_buffer = SDL_realloc(*buffer, new_buffer_length);
+ }
+
+ if (output_buffer == NULL) {
+ bytes_read = SDL_OutOfMemory();
+ } else {
+ SDL_memcpy((Uint8*)output_buffer + pos, temp, bytes_read);
+
+ if (null_terminate == SDL_TRUE) {
+ SDL_memset((Uint8*)output_buffer + (new_buffer_length - 1), 0, 1);
+ }
+
+ *buffer = output_buffer;
+ }
+ }
+
+ return bytes_read;
+}
+
+#define MIME_LIST_SIZE 4
+
+static const char* mime_conversion_list[MIME_LIST_SIZE][2] = {
+ {"text/plain", TEXT_MIME},
+ {"TEXT", TEXT_MIME},
+ {"UTF8_STRING", TEXT_MIME},
+ {"STRING", TEXT_MIME}
+};
+
+const char*
+Wayland_convert_mime_type(const char *mime_type)
+{
+ const char *found = mime_type;
+
+ size_t index = 0;
+
+ for (index = 0; index < MIME_LIST_SIZE; ++index) {
+ if (strcmp(mime_conversion_list[index][0], mime_type) == 0) {
+ found = mime_conversion_list[index][1];
+ break;
+ }
+ }
+
+ return found;
+}
+
+static SDL_MimeDataList*
+mime_data_list_find(struct wl_list* list,
+ const char* mime_type)
+{
+ SDL_MimeDataList *found = NULL;
+
+ SDL_MimeDataList *mime_list = NULL;
+ wl_list_for_each(mime_list, list, link) {
+ if (strcmp(mime_list->mime_type, mime_type) == 0) {
+ found = mime_list;
+ break;
+ }
+ }
+ return found;
+}
+
+static int
+mime_data_list_add(struct wl_list* list,
+ const char* mime_type,
+ void* buffer, size_t length)
+{
+ int status = 0;
+ size_t mime_type_length = 0;
+
+ SDL_MimeDataList *mime_data = NULL;
+
+ mime_data = mime_data_list_find(list, mime_type);
+
+ if (mime_data == NULL) {
+ mime_data = SDL_calloc(1, sizeof(*mime_data));
+ if (mime_data == NULL) {
+ status = SDL_OutOfMemory();
+ } else {
+ WAYLAND_wl_list_insert(list, &(mime_data->link));
+
+ mime_type_length = strlen(mime_type) + 1;
+ mime_data->mime_type = SDL_malloc(mime_type_length);
+ if (mime_data->mime_type == NULL) {
+ status = SDL_OutOfMemory();
+ } else {
+ SDL_memcpy(mime_data->mime_type, mime_type, mime_type_length);
+ }
+ }
+ }
+
+ if (mime_data != NULL && buffer != NULL && length > 0) {
+ if (mime_data->data != NULL) {
+ SDL_free(mime_data->data);
+ }
+ mime_data->data = buffer;
+ mime_data->length = length;
+ }
+
+ return status;
+}
+
+static void
+mime_data_list_free(struct wl_list *list)
+{
+ SDL_MimeDataList *mime_data = NULL;
+ SDL_MimeDataList *next = NULL;
+
+ wl_list_for_each_safe(mime_data, next, list, link) {
+ if (mime_data->data != NULL) {
+ SDL_free(mime_data->data);
+ }
+ if (mime_data->mime_type != NULL) {
+ SDL_free(mime_data->mime_type);
+ }
+ SDL_free(mime_data);
+ }
+}
+
+ssize_t
+Wayland_data_source_send(SDL_WaylandDataSource *source,
+ const char *mime_type, int fd)
+{
+ size_t written_bytes = 0;
+ ssize_t status = 0;
+ SDL_MimeDataList *mime_data = NULL;
+
+ mime_type = Wayland_convert_mime_type(mime_type);
+ mime_data = mime_data_list_find(&source->mimes,
+ mime_type);
+
+ if (mime_data == NULL || mime_data->data == NULL) {
+ status = SDL_SetError("Invalid mime type");
+ close(fd);
+ } else {
+ while (write_pipe(fd, mime_data->data, mime_data->length,
+ &written_bytes) > 0);
+ close(fd);
+ status = written_bytes;
+ }
+ return status;
+}
+
+int Wayland_data_source_add_data(SDL_WaylandDataSource *source,
+ const char *mime_type,
+ const void *buffer,
+ size_t length)
+{
+ int status = 0;
+ if (length > 0) {
+ void *internal_buffer = SDL_malloc(length);
+ if (internal_buffer == NULL) {
+ status = SDL_OutOfMemory();
+ } else {
+ SDL_memcpy(internal_buffer, buffer, length);
+ status = mime_data_list_add(&source->mimes, mime_type,
+ internal_buffer, length);
+ }
+ }
+ return status;
+}
+
+SDL_bool
+Wayland_data_source_has_mime(SDL_WaylandDataSource *source,
+ const char *mime_type)
+{
+ SDL_bool found = SDL_FALSE;
+
+ if (source != NULL) {
+ found = mime_data_list_find(&source->mimes, mime_type) != NULL;
+ }
+ return found;
+}
+
+void*
+Wayland_data_source_get_data(SDL_WaylandDataSource *source,
+ size_t *length, const char* mime_type,
+ SDL_bool null_terminate)
+{
+ SDL_MimeDataList *mime_data = NULL;
+ void *buffer = NULL;
+ *length = 0;
+
+ if (source == NULL) {
+ SDL_SetError("Invalid data source");
+ } else {
+ mime_data = mime_data_list_find(&source->mimes, mime_type);
+ if (mime_data != NULL && mime_data->length > 0) {
+ buffer = SDL_malloc(mime_data->length);
+ if (buffer == NULL) {
+ *length = SDL_OutOfMemory();
+ } else {
+ *length = mime_data->length;
+ SDL_memcpy(buffer, mime_data->data, mime_data->length);
+ }
+ }
+ }
+
+ return buffer;
+}
+
+void
+Wayland_data_source_destroy(SDL_WaylandDataSource *source)
+{
+ if (source != NULL) {
+ wl_data_source_destroy(source->source);
+ mime_data_list_free(&source->mimes);
+ SDL_free(source);
+ }
+}
+
+void*
+Wayland_data_offer_receive(SDL_WaylandDataOffer *offer,
+ size_t *length, const char* mime_type,
+ SDL_bool null_terminate)
+{
+ SDL_WaylandDataDevice *data_device = NULL;
+
+ int pipefd[2];
+ void *buffer = NULL;
+ *length = 0;
+
+ if (offer == NULL) {
+ SDL_SetError("Invalid data offer");
+ } else if ((data_device = offer->data_device) == NULL) {
+ SDL_SetError("Data device not initialized");
+ } else if (pipe2(pipefd, O_CLOEXEC|O_NONBLOCK) == -1) {
+ SDL_SetError("Could not read pipe");
+ } else {
+ wl_data_offer_receive(offer->offer, mime_type, pipefd[1]);
+
+ /* TODO: Needs pump and flush? */
+ WAYLAND_wl_display_flush(data_device->video_data->display);
+
+ close(pipefd[1]);
+
+ while (read_pipe(pipefd[0], &buffer, length, null_terminate) > 0);
+ close(pipefd[0]);
+ }
+ return buffer;
+}
+
+int
+Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer,
+ const char* mime_type)
+{
+ return mime_data_list_add(&offer->mimes, mime_type, NULL, 0);
+}
+
+
+SDL_bool
+Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer,
+ const char *mime_type)
+{
+ SDL_bool found = SDL_FALSE;
+
+ if (offer != NULL) {
+ found = mime_data_list_find(&offer->mimes, mime_type) != NULL;
+ }
+ return found;
+}
+
+void
+Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
+{
+ if (offer != NULL) {
+ wl_data_offer_destroy(offer->offer);
+ mime_data_list_free(&offer->mimes);
+ SDL_free(offer);
+ }
+}
+
+int
+Wayland_data_device_clear_selection(SDL_WaylandDataDevice *data_device)
+{
+ int status = 0;
+
+ if (data_device == NULL || data_device->data_device == NULL) {
+ status = SDL_SetError("Invalid Data Device");
+ } else if (data_device->selection_source != 0) {
+ wl_data_device_set_selection(data_device->data_device, NULL, 0);
+ data_device->selection_source = NULL;
+ }
+ return status;
+}
+
+int
+Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device,
+ SDL_WaylandDataSource *source)
+{
+ int status = 0;
+ size_t num_offers = 0;
+ size_t index = 0;
+
+ if (data_device == NULL) {
+ status = SDL_SetError("Invalid Data Device");
+ } else if (source == NULL) {
+ status = SDL_SetError("Invalid source");
+ } else {
+ SDL_MimeDataList *mime_data = NULL;
+
+ wl_list_for_each(mime_data, &(source->mimes), link) {
+ wl_data_source_offer(source->source,
+ mime_data->mime_type);
+
+ /* TODO - Improve system for multiple mime types to same data */
+ for (index = 0; index < MIME_LIST_SIZE; ++index) {
+ if (strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) {
+ wl_data_source_offer(source->source,
+ mime_conversion_list[index][0]);
+ }
+ }
+ /* */
+
+ ++num_offers;
+ }
+
+ if (num_offers == 0) {
+ Wayland_data_device_clear_selection(data_device);
+ status = SDL_SetError("No mime data");
+ } else {
+ /* Only set if there is a valid serial if not set it later */
+ if (data_device->selection_serial != 0) {
+ wl_data_device_set_selection(data_device->data_device,
+ source->source,
+ data_device->selection_serial);
+ }
+ data_device->selection_source = source;
+ }
+ }
+
+ return status;
+}
+
+int
+Wayland_data_device_set_serial(SDL_WaylandDataDevice *data_device,
+ uint32_t serial)
+{
+ int status = -1;
+ if (data_device != NULL) {
+ status = 0;
+
+ /* If there was no serial and there is a pending selection set it now. */
+ if (data_device->selection_serial == 0
+ && data_device->selection_source != NULL) {
+ wl_data_device_set_selection(data_device->data_device,
+ data_device->selection_source->source,
+ serial);
+ }
+
+ data_device->selection_serial = serial;
+ }
+
+ return status;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.h
new file mode 100644
index 0000000..9b13e64
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddatamanager.h
@@ -0,0 +1,103 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylanddatamanager_h_
+#define SDL_waylanddatamanager_h_
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandwindow.h"
+
+#define TEXT_MIME "text/plain;charset=utf-8"
+#define FILE_MIME "text/uri-list"
+
+typedef struct {
+ char *mime_type;
+ void *data;
+ size_t length;
+ struct wl_list link;
+} SDL_MimeDataList;
+
+typedef struct {
+ struct wl_data_source *source;
+ struct wl_list mimes;
+} SDL_WaylandDataSource;
+
+typedef struct {
+ struct wl_data_offer *offer;
+ struct wl_list mimes;
+ void *data_device;
+} SDL_WaylandDataOffer;
+
+typedef struct {
+ struct wl_data_device *data_device;
+ SDL_VideoData *video_data;
+
+ /* Drag and Drop */
+ uint32_t drag_serial;
+ SDL_WaylandDataOffer *drag_offer;
+ SDL_WaylandDataOffer *selection_offer;
+
+ /* Clipboard */
+ uint32_t selection_serial;
+ SDL_WaylandDataSource *selection_source;
+} SDL_WaylandDataDevice;
+
+extern const char* Wayland_convert_mime_type(const char *mime_type);
+
+/* Wayland Data Source - (Sending) */
+extern SDL_WaylandDataSource* Wayland_data_source_create(_THIS);
+extern ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source,
+ const char *mime_type, int fd);
+extern int Wayland_data_source_add_data(SDL_WaylandDataSource *source,
+ const char *mime_type,
+ const void *buffer,
+ size_t length);
+extern SDL_bool Wayland_data_source_has_mime(SDL_WaylandDataSource *source,
+ const char *mime_type);
+extern void* Wayland_data_source_get_data(SDL_WaylandDataSource *source,
+ size_t *length,
+ const char *mime_type,
+ SDL_bool null_terminate);
+extern void Wayland_data_source_destroy(SDL_WaylandDataSource *source);
+
+/* Wayland Data Offer - (Receiving) */
+extern void* Wayland_data_offer_receive(SDL_WaylandDataOffer *offer,
+ size_t *length,
+ const char *mime_type,
+ SDL_bool null_terminate);
+extern SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer,
+ const char *mime_type);
+extern int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer,
+ const char *mime_type);
+extern void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer);
+
+/* Clipboard */
+extern int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *device);
+extern int Wayland_data_device_set_selection(SDL_WaylandDataDevice *device,
+ SDL_WaylandDataSource *source);
+extern int Wayland_data_device_set_serial(SDL_WaylandDataDevice *device,
+ uint32_t serial);
+#endif /* SDL_waylanddatamanager_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.c
new file mode 100644
index 0000000..98cc518
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.c
@@ -0,0 +1,178 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+#define DEBUG_DYNAMIC_WAYLAND 0
+
+#include "SDL_waylanddyn.h"
+
+#if DEBUG_DYNAMIC_WAYLAND
+#include "SDL_log.h"
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+typedef struct
+{
+ void *lib;
+ const char *libname;
+} waylanddynlib;
+
+#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
+#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
+#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
+#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON NULL
+#endif
+
+static waylanddynlib waylandlibs[] = {
+ {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC},
+ {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL},
+ {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR},
+ {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON}
+};
+
+static void *
+WAYLAND_GetSym(const char *fnname, int *pHasModule)
+{
+ int i;
+ void *fn = NULL;
+ for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) {
+ if (waylandlibs[i].lib != NULL) {
+ fn = SDL_LoadFunction(waylandlibs[i].lib, fnname);
+ if (fn != NULL)
+ break;
+ }
+ }
+
+#if DEBUG_DYNAMIC_WAYLAND
+ if (fn != NULL)
+ SDL_Log("WAYLAND: Found '%s' in %s (%p)\n", fnname, waylandlibs[i].libname, fn);
+ else
+ SDL_Log("WAYLAND: Symbol '%s' NOT FOUND!\n", fnname);
+#endif
+
+ if (fn == NULL)
+ *pHasModule = 0; /* kill this module. */
+
+ return fn;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */
+
+/* Define all the function pointers and wrappers... */
+#define SDL_WAYLAND_MODULE(modname) int SDL_WAYLAND_HAVE_##modname = 0;
+#define SDL_WAYLAND_SYM(rc,fn,params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL;
+#define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL;
+#include "SDL_waylandsym.h"
+
+static int wayland_load_refcount = 0;
+
+void
+SDL_WAYLAND_UnloadSymbols(void)
+{
+ /* Don't actually unload if more than one module is using the libs... */
+ if (wayland_load_refcount > 0) {
+ if (--wayland_load_refcount == 0) {
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+ int i;
+#endif
+
+ /* set all the function pointers to NULL. */
+#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 0;
+#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = NULL;
+#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL;
+#include "SDL_waylandsym.h"
+
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+ for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) {
+ if (waylandlibs[i].lib != NULL) {
+ SDL_UnloadObject(waylandlibs[i].lib);
+ waylandlibs[i].lib = NULL;
+ }
+ }
+#endif
+ }
+ }
+}
+
+/* returns non-zero if all needed symbols were loaded. */
+int
+SDL_WAYLAND_LoadSymbols(void)
+{
+ int rc = 1; /* always succeed if not using Dynamic WAYLAND stuff. */
+
+ /* deal with multiple modules (dga, wayland, etc) needing these symbols... */
+ if (wayland_load_refcount++ == 0) {
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+ int i;
+ int *thismod = NULL;
+ for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) {
+ if (waylandlibs[i].libname != NULL) {
+ waylandlibs[i].lib = SDL_LoadObject(waylandlibs[i].libname);
+ }
+ }
+
+#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */
+#include "SDL_waylandsym.h"
+
+#define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname;
+#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn) WAYLAND_GetSym(#fn,thismod);
+#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *) WAYLAND_GetSym(#iface,thismod);
+#include "SDL_waylandsym.h"
+
+ if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT) {
+ /* all required symbols loaded. */
+ SDL_ClearError();
+ } else {
+ /* in case something got loaded... */
+ SDL_WAYLAND_UnloadSymbols();
+ rc = 0;
+ }
+
+#else /* no dynamic WAYLAND */
+
+#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */
+#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = fn;
+#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface;
+#include "SDL_waylandsym.h"
+
+#endif
+ }
+
+ return rc;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.h
new file mode 100644
index 0000000..720427e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylanddyn.h
@@ -0,0 +1,107 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_waylanddyn_h_
+#define SDL_waylanddyn_h_
+
+#include "../../SDL_internal.h"
+
+/* We can't include wayland-client.h here
+ * but we need some structs from it
+ */
+struct wl_interface;
+struct wl_proxy;
+struct wl_event_queue;
+struct wl_display;
+struct wl_surface;
+struct wl_shm;
+
+#include <stdint.h>
+#include "wayland-cursor.h"
+#include "wayland-util.h"
+#include "xkbcommon/xkbcommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int SDL_WAYLAND_LoadSymbols(void);
+void SDL_WAYLAND_UnloadSymbols(void);
+
+#define SDL_WAYLAND_MODULE(modname) extern int SDL_WAYLAND_HAVE_##modname;
+#define SDL_WAYLAND_SYM(rc,fn,params) \
+ typedef rc (*SDL_DYNWAYLANDFN_##fn) params; \
+ extern SDL_DYNWAYLANDFN_##fn WAYLAND_##fn;
+#define SDL_WAYLAND_INTERFACE(iface) extern const struct wl_interface *WAYLAND_##iface;
+#include "SDL_waylandsym.h"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+
+#ifdef _WAYLAND_CLIENT_H
+#error Do not include wayland-client ahead of SDL_waylanddyn.h in dynamic loading mode
+#endif
+
+/* wayland-client-protocol.h included from wayland-client.h
+ * has inline functions that require these to be defined in dynamic loading mode
+ */
+
+#define wl_proxy_create (*WAYLAND_wl_proxy_create)
+#define wl_proxy_destroy (*WAYLAND_wl_proxy_destroy)
+#define wl_proxy_marshal (*WAYLAND_wl_proxy_marshal)
+#define wl_proxy_set_user_data (*WAYLAND_wl_proxy_set_user_data)
+#define wl_proxy_get_user_data (*WAYLAND_wl_proxy_get_user_data)
+#define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener)
+#define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor)
+#define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned)
+
+#define wl_seat_interface (*WAYLAND_wl_seat_interface)
+#define wl_surface_interface (*WAYLAND_wl_surface_interface)
+#define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface)
+#define wl_buffer_interface (*WAYLAND_wl_buffer_interface)
+#define wl_registry_interface (*WAYLAND_wl_registry_interface)
+#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface)
+#define wl_region_interface (*WAYLAND_wl_region_interface)
+#define wl_pointer_interface (*WAYLAND_wl_pointer_interface)
+#define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface)
+#define wl_compositor_interface (*WAYLAND_wl_compositor_interface)
+#define wl_output_interface (*WAYLAND_wl_output_interface)
+#define wl_shell_interface (*WAYLAND_wl_shell_interface)
+#define wl_shm_interface (*WAYLAND_wl_shm_interface)
+#define wl_data_device_interface (*WAYLAND_wl_data_device_interface)
+#define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface)
+#define wl_data_source_interface (*WAYLAND_wl_data_source_interface)
+#define wl_data_device_manager_interface (*WAYLAND_wl_data_device_manager_interface)
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */
+
+#include "wayland-client-core.h"
+#include "wayland-client-protocol.h"
+#include "wayland-egl.h"
+
+#endif /* SDL_waylanddyn_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents.c
new file mode 100644
index 0000000..0c953a5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents.c
@@ -0,0 +1,1136 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+#include "SDL_stdinc.h"
+#include "SDL_assert.h"
+#include "SDL_log.h"
+
+#include "../../core/unix/SDL_poll.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/scancodes_xfree86.h"
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandevents_c.h"
+#include "SDL_waylandwindow.h"
+
+#include "SDL_waylanddyn.h"
+
+#include "pointer-constraints-unstable-v1-client-protocol.h"
+#include "relative-pointer-unstable-v1-client-protocol.h"
+#include "xdg-shell-client-protocol.h"
+#include "xdg-shell-unstable-v6-client-protocol.h"
+
+#include <linux/input.h>
+#include <sys/select.h>
+#include <sys/mman.h>
+#include <poll.h>
+#include <unistd.h>
+#include <xkbcommon/xkbcommon.h>
+
+struct SDL_WaylandInput {
+ SDL_VideoData *display;
+ struct wl_seat *seat;
+ struct wl_pointer *pointer;
+ struct wl_touch *touch;
+ struct wl_keyboard *keyboard;
+ SDL_WaylandDataDevice *data_device;
+ struct zwp_relative_pointer_v1 *relative_pointer;
+ SDL_WindowData *pointer_focus;
+ SDL_WindowData *keyboard_focus;
+
+ /* Last motion location */
+ wl_fixed_t sx_w;
+ wl_fixed_t sy_w;
+
+ double dx_frac;
+ double dy_frac;
+
+ struct {
+ struct xkb_keymap *keymap;
+ struct xkb_state *state;
+ } xkb;
+};
+
+struct SDL_WaylandTouchPoint {
+ SDL_TouchID id;
+ float x;
+ float y;
+ struct wl_surface* surface;
+
+ struct SDL_WaylandTouchPoint* prev;
+ struct SDL_WaylandTouchPoint* next;
+};
+
+struct SDL_WaylandTouchPointList {
+ struct SDL_WaylandTouchPoint* head;
+ struct SDL_WaylandTouchPoint* tail;
+};
+
+static struct SDL_WaylandTouchPointList touch_points = {NULL, NULL};
+
+static void
+touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
+{
+ struct SDL_WaylandTouchPoint* tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
+
+ tp->id = id;
+ tp->x = x;
+ tp->y = y;
+ tp->surface = surface;
+
+ if (touch_points.tail) {
+ touch_points.tail->next = tp;
+ tp->prev = touch_points.tail;
+ } else {
+ touch_points.head = tp;
+ tp->prev = NULL;
+ }
+
+ touch_points.tail = tp;
+ tp->next = NULL;
+}
+
+static void
+touch_update(SDL_TouchID id, float x, float y)
+{
+ struct SDL_WaylandTouchPoint* tp = touch_points.head;
+
+ while (tp) {
+ if (tp->id == id) {
+ tp->x = x;
+ tp->y = y;
+ }
+
+ tp = tp->next;
+ }
+}
+
+static void
+touch_del(SDL_TouchID id, float* x, float* y)
+{
+ struct SDL_WaylandTouchPoint* tp = touch_points.head;
+
+ while (tp) {
+ if (tp->id == id) {
+ *x = tp->x;
+ *y = tp->y;
+
+ if (tp->prev) {
+ tp->prev->next = tp->next;
+ } else {
+ touch_points.head = tp->next;
+ }
+
+ if (tp->next) {
+ tp->next->prev = tp->prev;
+ } else {
+ touch_points.tail = tp->prev;
+ }
+
+ SDL_free(tp);
+ }
+
+ tp = tp->next;
+ }
+}
+
+static struct wl_surface*
+touch_surface(SDL_TouchID id)
+{
+ struct SDL_WaylandTouchPoint* tp = touch_points.head;
+
+ while (tp) {
+ if (tp->id == id) {
+ return tp->surface;
+ }
+
+ tp = tp->next;
+ }
+
+ return NULL;
+}
+
+void
+Wayland_PumpEvents(_THIS)
+{
+ SDL_VideoData *d = _this->driverdata;
+
+ WAYLAND_wl_display_flush(d->display);
+
+ if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_FALSE, 0)) {
+ WAYLAND_wl_display_dispatch(d->display);
+ }
+ else
+ {
+ WAYLAND_wl_display_dispatch_pending(d->display);
+ }
+}
+
+static void
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface,
+ wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+ struct SDL_WaylandInput *input = data;
+ SDL_WindowData *window;
+
+ if (!surface) {
+ /* enter event for a window we've just destroyed */
+ return;
+ }
+
+ /* This handler will be called twice in Wayland 1.4
+ * Once for the window surface which has valid user data
+ * and again for the mouse cursor surface which does not have valid user data
+ * We ignore the later
+ */
+
+ window = (SDL_WindowData *)wl_surface_get_user_data(surface);
+
+ if (window) {
+ input->pointer_focus = window;
+ SDL_SetMouseFocus(window->sdlwindow);
+ }
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface)
+{
+ struct SDL_WaylandInput *input = data;
+
+ if (input->pointer_focus) {
+ SDL_SetMouseFocus(NULL);
+ input->pointer_focus = NULL;
+ }
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+ uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+ struct SDL_WaylandInput *input = data;
+ SDL_WindowData *window = input->pointer_focus;
+ input->sx_w = sx_w;
+ input->sy_w = sy_w;
+ if (input->pointer_focus) {
+ const int sx = wl_fixed_to_int(sx_w);
+ const int sy = wl_fixed_to_int(sy_w);
+ SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
+ }
+}
+
+static SDL_bool
+ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
+{
+ SDL_WindowData *window_data = input->pointer_focus;
+ SDL_Window *window = window_data->sdlwindow;
+
+ if (window->hit_test) {
+ const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
+ const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
+
+ static const uint32_t directions_wl[] = {
+ WL_SHELL_SURFACE_RESIZE_TOP_LEFT, WL_SHELL_SURFACE_RESIZE_TOP,
+ WL_SHELL_SURFACE_RESIZE_TOP_RIGHT, WL_SHELL_SURFACE_RESIZE_RIGHT,
+ WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, WL_SHELL_SURFACE_RESIZE_BOTTOM,
+ WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT, WL_SHELL_SURFACE_RESIZE_LEFT
+ };
+
+ /* the names are different (ZXDG_TOPLEVEL_V6_RESIZE_EDGE_* vs
+ WL_SHELL_SURFACE_RESIZE_*), but the values are the same. */
+ const uint32_t *directions_zxdg = directions_wl;
+
+ switch (rc) {
+ case SDL_HITTEST_DRAGGABLE:
+ if (input->display->shell.xdg) {
+ xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial);
+ } else if (input->display->shell.zxdg) {
+ zxdg_toplevel_v6_move(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial);
+ } else {
+ wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
+ }
+ return SDL_TRUE;
+
+ case SDL_HITTEST_RESIZE_TOPLEFT:
+ case SDL_HITTEST_RESIZE_TOP:
+ case SDL_HITTEST_RESIZE_TOPRIGHT:
+ case SDL_HITTEST_RESIZE_RIGHT:
+ case SDL_HITTEST_RESIZE_BOTTOMRIGHT:
+ case SDL_HITTEST_RESIZE_BOTTOM:
+ case SDL_HITTEST_RESIZE_BOTTOMLEFT:
+ case SDL_HITTEST_RESIZE_LEFT:
+ if (input->display->shell.xdg) {
+ xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
+ } else if (input->display->shell.zxdg) {
+ zxdg_toplevel_v6_resize(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
+ } else {
+ wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions_wl[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
+ }
+ return SDL_TRUE;
+
+ default: return SDL_FALSE;
+ }
+ }
+
+ return SDL_FALSE;
+}
+
+static void
+pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial,
+ uint32_t time, uint32_t button, uint32_t state_w)
+{
+ SDL_WindowData *window = input->pointer_focus;
+ enum wl_pointer_button_state state = state_w;
+ uint32_t sdl_button;
+
+ if (input->pointer_focus) {
+ switch (button) {
+ case BTN_LEFT:
+ sdl_button = SDL_BUTTON_LEFT;
+ if (ProcessHitTest(input, serial)) {
+ return; /* don't pass this event on to app. */
+ }
+ break;
+ case BTN_MIDDLE:
+ sdl_button = SDL_BUTTON_MIDDLE;
+ break;
+ case BTN_RIGHT:
+ sdl_button = SDL_BUTTON_RIGHT;
+ break;
+ case BTN_SIDE:
+ sdl_button = SDL_BUTTON_X1;
+ break;
+ case BTN_EXTRA:
+ sdl_button = SDL_BUTTON_X2;
+ break;
+ default:
+ return;
+ }
+
+ Wayland_data_device_set_serial(input->data_device, serial);
+
+ SDL_SendMouseButton(window->sdlwindow, 0,
+ state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
+ }
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
+ uint32_t time, uint32_t button, uint32_t state_w)
+{
+ struct SDL_WaylandInput *input = data;
+
+ pointer_handle_button_common(input, serial, time, button, state_w);
+}
+
+static void
+pointer_handle_axis_common(struct SDL_WaylandInput *input,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ SDL_WindowData *window = input->pointer_focus;
+ enum wl_pointer_axis a = axis;
+ float x, y;
+
+ if (input->pointer_focus) {
+ switch (a) {
+ case WL_POINTER_AXIS_VERTICAL_SCROLL:
+ x = 0;
+ y = 0 - (float)wl_fixed_to_double(value);
+ break;
+ case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
+ x = 0 - (float)wl_fixed_to_double(value);
+ y = 0;
+ break;
+ default:
+ return;
+ }
+
+ SDL_SendMouseWheel(window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
+ }
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ struct SDL_WaylandInput *input = data;
+
+ pointer_handle_axis_common(input, time, axis, value);
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter,
+ pointer_handle_leave,
+ pointer_handle_motion,
+ pointer_handle_button,
+ pointer_handle_axis,
+ NULL, /* frame */
+ NULL, /* axis_source */
+ NULL, /* axis_stop */
+ NULL, /* axis_discrete */
+};
+
+static void
+touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial,
+ unsigned int timestamp, struct wl_surface *surface,
+ int id, wl_fixed_t fx, wl_fixed_t fy)
+{
+ float x, y;
+ SDL_WindowData* window;
+
+ window = (SDL_WindowData *)wl_surface_get_user_data(surface);
+
+ x = wl_fixed_to_double(fx) / window->sdlwindow->w;
+ y = wl_fixed_to_double(fy) / window->sdlwindow->h;
+
+ touch_add(id, x, y, surface);
+ SDL_SendTouch(1, (SDL_FingerID)id, SDL_TRUE, x, y, 1.0f);
+}
+
+static void
+touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial,
+ unsigned int timestamp, int id)
+{
+ float x = 0, y = 0;
+
+ touch_del(id, &x, &y);
+ SDL_SendTouch(1, (SDL_FingerID)id, SDL_FALSE, x, y, 0.0f);
+}
+
+static void
+touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
+ int id, wl_fixed_t fx, wl_fixed_t fy)
+{
+ float x, y;
+ SDL_WindowData* window;
+
+ window = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
+
+ x = wl_fixed_to_double(fx) / window->sdlwindow->w;
+ y = wl_fixed_to_double(fy) / window->sdlwindow->h;
+
+ touch_update(id, x, y);
+ SDL_SendTouchMotion(1, (SDL_FingerID)id, x, y, 1.0f);
+}
+
+static void
+touch_handler_frame(void *data, struct wl_touch *touch)
+{
+
+}
+
+static void
+touch_handler_cancel(void *data, struct wl_touch *touch)
+{
+
+}
+
+static const struct wl_touch_listener touch_listener = {
+ touch_handler_down,
+ touch_handler_up,
+ touch_handler_motion,
+ touch_handler_frame,
+ touch_handler_cancel,
+ NULL, /* shape */
+ NULL, /* orientation */
+};
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+ uint32_t format, int fd, uint32_t size)
+{
+ struct SDL_WaylandInput *input = data;
+ char *map_str;
+
+ if (!data) {
+ close(fd);
+ return;
+ }
+
+ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
+ close(fd);
+ return;
+ }
+
+ map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+ if (map_str == MAP_FAILED) {
+ close(fd);
+ return;
+ }
+
+ input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
+ map_str,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ 0);
+ munmap(map_str, size);
+ close(fd);
+
+ if (!input->xkb.keymap) {
+ fprintf(stderr, "failed to compile keymap\n");
+ return;
+ }
+
+ input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
+ if (!input->xkb.state) {
+ fprintf(stderr, "failed to create XKB state\n");
+ WAYLAND_xkb_keymap_unref(input->xkb.keymap);
+ input->xkb.keymap = NULL;
+ return;
+ }
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, struct wl_surface *surface,
+ struct wl_array *keys)
+{
+ struct SDL_WaylandInput *input = data;
+ SDL_WindowData *window;
+
+ if (!surface) {
+ /* enter event for a window we've just destroyed */
+ return;
+ }
+
+ window = wl_surface_get_user_data(surface);
+
+ if (window) {
+ input->keyboard_focus = window;
+ window->keyboard_device = input;
+ SDL_SetKeyboardFocus(window->sdlwindow);
+ }
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, struct wl_surface *surface)
+{
+ SDL_SetKeyboardFocus(NULL);
+}
+
+static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, uint32_t time, uint32_t key,
+ uint32_t state_w)
+{
+ struct SDL_WaylandInput *input = data;
+ SDL_WindowData *window = input->keyboard_focus;
+ enum wl_keyboard_key_state state = state_w;
+ const xkb_keysym_t *syms;
+ uint32_t scancode;
+ char text[8];
+ int size;
+
+ if (key < SDL_arraysize(xfree86_scancode_table2)) {
+ scancode = xfree86_scancode_table2[key];
+
+ // TODO when do we get WL_KEYBOARD_KEY_STATE_REPEAT?
+ if (scancode != SDL_SCANCODE_UNKNOWN)
+ SDL_SendKeyboardKey(state == WL_KEYBOARD_KEY_STATE_PRESSED ?
+ SDL_PRESSED : SDL_RELEASED, scancode);
+ }
+
+ if (!window || window->keyboard_device != input || !input->xkb.state)
+ return;
+
+ // TODO can this happen?
+ if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1)
+ return;
+
+ if (state) {
+ size = WAYLAND_xkb_keysym_to_utf8(syms[0], text, sizeof text);
+
+ if (size > 0) {
+ text[size] = 0;
+
+ Wayland_data_device_set_serial(input->data_device, serial);
+
+ SDL_SendKeyboardText(text);
+ }
+ }
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, uint32_t mods_depressed,
+ uint32_t mods_latched, uint32_t mods_locked,
+ uint32_t group)
+{
+ struct SDL_WaylandInput *input = data;
+
+ WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
+ mods_locked, 0, 0, group);
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+ keyboard_handle_keymap,
+ keyboard_handle_enter,
+ keyboard_handle_leave,
+ keyboard_handle_key,
+ keyboard_handle_modifiers,
+ NULL, /* repeat_info */
+};
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+ enum wl_seat_capability caps)
+{
+ struct SDL_WaylandInput *input = data;
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
+ input->pointer = wl_seat_get_pointer(seat);
+ input->display->pointer = input->pointer;
+ wl_pointer_set_user_data(input->pointer, input);
+ wl_pointer_add_listener(input->pointer, &pointer_listener,
+ input);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
+ wl_pointer_destroy(input->pointer);
+ input->pointer = NULL;
+ input->display->pointer = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
+ SDL_AddTouch(1, "wayland_touch");
+ input->touch = wl_seat_get_touch(seat);
+ wl_touch_set_user_data(input->touch, input);
+ wl_touch_add_listener(input->touch, &touch_listener,
+ input);
+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
+ SDL_DelTouch(1);
+ wl_touch_destroy(input->touch);
+ input->touch = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
+ input->keyboard = wl_seat_get_keyboard(seat);
+ wl_keyboard_set_user_data(input->keyboard, input);
+ wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
+ input);
+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
+ wl_keyboard_destroy(input->keyboard);
+ input->keyboard = NULL;
+ }
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_handle_capabilities,
+ NULL, /* name */
+};
+
+static void
+data_source_handle_target(void *data, struct wl_data_source *wl_data_source,
+ const char *mime_type)
+{
+}
+
+static void
+data_source_handle_send(void *data, struct wl_data_source *wl_data_source,
+ const char *mime_type, int32_t fd)
+{
+ Wayland_data_source_send((SDL_WaylandDataSource *)data, mime_type, fd);
+}
+
+static void
+data_source_handle_cancelled(void *data, struct wl_data_source *wl_data_source)
+{
+ Wayland_data_source_destroy(data);
+}
+
+static void
+data_source_handle_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source)
+{
+}
+
+static void
+data_source_handle_dnd_finished(void *data, struct wl_data_source *wl_data_source)
+{
+}
+
+static void
+data_source_handle_action(void *data, struct wl_data_source *wl_data_source,
+ uint32_t dnd_action)
+{
+}
+
+static const struct wl_data_source_listener data_source_listener = {
+ data_source_handle_target,
+ data_source_handle_send,
+ data_source_handle_cancelled,
+ data_source_handle_dnd_drop_performed, // Version 3
+ data_source_handle_dnd_finished, // Version 3
+ data_source_handle_action, // Version 3
+};
+
+SDL_WaylandDataSource*
+Wayland_data_source_create(_THIS)
+{
+ SDL_WaylandDataSource *data_source = NULL;
+ SDL_VideoData *driver_data = NULL;
+ struct wl_data_source *id = NULL;
+
+ if (_this == NULL || _this->driverdata == NULL) {
+ SDL_SetError("Video driver uninitialized");
+ } else {
+ driver_data = _this->driverdata;
+
+ if (driver_data->data_device_manager != NULL) {
+ id = wl_data_device_manager_create_data_source(
+ driver_data->data_device_manager);
+ }
+
+ if (id == NULL) {
+ SDL_SetError("Wayland unable to create data source");
+ } else {
+ data_source = SDL_calloc(1, sizeof *data_source);
+ if (data_source == NULL) {
+ SDL_OutOfMemory();
+ wl_data_source_destroy(id);
+ } else {
+ WAYLAND_wl_list_init(&(data_source->mimes));
+ data_source->source = id;
+ wl_data_source_set_user_data(id, data_source);
+ wl_data_source_add_listener(id, &data_source_listener,
+ data_source);
+ }
+ }
+ }
+ return data_source;
+}
+
+static void
+data_offer_handle_offer(void *data, struct wl_data_offer *wl_data_offer,
+ const char *mime_type)
+{
+ SDL_WaylandDataOffer *offer = data;
+ Wayland_data_offer_add_mime(offer, mime_type);
+}
+
+static void
+data_offer_handle_source_actions(void *data, struct wl_data_offer *wl_data_offer,
+ uint32_t source_actions)
+{
+}
+
+static void
+data_offer_handle_actions(void *data, struct wl_data_offer *wl_data_offer,
+ uint32_t dnd_action)
+{
+}
+
+static const struct wl_data_offer_listener data_offer_listener = {
+ data_offer_handle_offer,
+ data_offer_handle_source_actions, // Version 3
+ data_offer_handle_actions, // Version 3
+};
+
+static void
+data_device_handle_data_offer(void *data, struct wl_data_device *wl_data_device,
+ struct wl_data_offer *id)
+{
+ SDL_WaylandDataOffer *data_offer = NULL;
+
+ data_offer = SDL_calloc(1, sizeof *data_offer);
+ if (data_offer == NULL) {
+ SDL_OutOfMemory();
+ } else {
+ data_offer->offer = id;
+ data_offer->data_device = data;
+ WAYLAND_wl_list_init(&(data_offer->mimes));
+ wl_data_offer_set_user_data(id, data_offer);
+ wl_data_offer_add_listener(id, &data_offer_listener, data_offer);
+ }
+}
+
+static void
+data_device_handle_enter(void *data, struct wl_data_device *wl_data_device,
+ uint32_t serial, struct wl_surface *surface,
+ wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id)
+{
+ SDL_WaylandDataDevice *data_device = data;
+ SDL_bool has_mime = SDL_FALSE;
+ uint32_t dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
+
+ data_device->drag_serial = serial;
+
+ if (id != NULL) {
+ data_device->drag_offer = wl_data_offer_get_user_data(id);
+
+ /* TODO: SDL Support more mime types */
+ has_mime = Wayland_data_offer_has_mime(
+ data_device->drag_offer, FILE_MIME);
+
+ /* If drag_mime is NULL this will decline the offer */
+ wl_data_offer_accept(id, serial,
+ (has_mime == SDL_TRUE) ? FILE_MIME : NULL);
+
+ /* SDL only supports "copy" style drag and drop */
+ if (has_mime == SDL_TRUE) {
+ dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
+ }
+ wl_data_offer_set_actions(data_device->drag_offer->offer,
+ dnd_action, dnd_action);
+ }
+}
+
+static void
+data_device_handle_leave(void *data, struct wl_data_device *wl_data_device)
+{
+ SDL_WaylandDataDevice *data_device = data;
+ SDL_WaylandDataOffer *offer = NULL;
+
+ if (data_device->selection_offer != NULL) {
+ data_device->selection_offer = NULL;
+ Wayland_data_offer_destroy(offer);
+ }
+}
+
+static void
+data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
+ uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
+}
+
+static void
+data_device_handle_drop(void *data, struct wl_data_device *wl_data_device)
+{
+ SDL_WaylandDataDevice *data_device = data;
+ void *buffer = NULL;
+ size_t length = 0;
+
+ const char *current_uri = NULL;
+ const char *last_char = NULL;
+ char *current_char = NULL;
+
+ if (data_device->drag_offer != NULL) {
+ /* TODO: SDL Support more mime types */
+ buffer = Wayland_data_offer_receive(data_device->drag_offer,
+ &length, FILE_MIME, SDL_FALSE);
+
+ /* uri-list */
+ current_uri = (const char *)buffer;
+ last_char = (const char *)buffer + length;
+ for (current_char = buffer; current_char < last_char; ++current_char) {
+ if (*current_char == '\n' || *current_char == 0) {
+ if (*current_uri != 0 && *current_uri != '#') {
+ *current_char = 0;
+ SDL_SendDropFile(NULL, current_uri);
+ }
+ current_uri = (const char *)current_char + 1;
+ }
+ }
+
+ SDL_free(buffer);
+ }
+}
+
+static void
+data_device_handle_selection(void *data, struct wl_data_device *wl_data_device,
+ struct wl_data_offer *id)
+{
+ SDL_WaylandDataDevice *data_device = data;
+ SDL_WaylandDataOffer *offer = NULL;
+
+ if (id != NULL) {
+ offer = wl_data_offer_get_user_data(id);
+ }
+
+ if (data_device->selection_offer != offer) {
+ Wayland_data_offer_destroy(data_device->selection_offer);
+ data_device->selection_offer = offer;
+ }
+
+ SDL_SendClipboardUpdate();
+}
+
+static const struct wl_data_device_listener data_device_listener = {
+ data_device_handle_data_offer,
+ data_device_handle_enter,
+ data_device_handle_leave,
+ data_device_handle_motion,
+ data_device_handle_drop,
+ data_device_handle_selection
+};
+
+void
+Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
+{
+ struct SDL_WaylandInput *input;
+ SDL_WaylandDataDevice *data_device = NULL;
+
+ input = SDL_calloc(1, sizeof *input);
+ if (input == NULL)
+ return;
+
+ input->display = d;
+ input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
+ input->sx_w = wl_fixed_from_int(0);
+ input->sy_w = wl_fixed_from_int(0);
+ d->input = input;
+
+ if (d->data_device_manager != NULL) {
+ data_device = SDL_calloc(1, sizeof *data_device);
+ if (data_device == NULL) {
+ return;
+ }
+
+ data_device->data_device = wl_data_device_manager_get_data_device(
+ d->data_device_manager, input->seat
+ );
+ data_device->video_data = d;
+
+ if (data_device->data_device == NULL) {
+ SDL_free(data_device);
+ } else {
+ wl_data_device_set_user_data(data_device->data_device, data_device);
+ wl_data_device_add_listener(data_device->data_device,
+ &data_device_listener, data_device);
+ input->data_device = data_device;
+ }
+ }
+
+ wl_seat_add_listener(input->seat, &seat_listener, input);
+ wl_seat_set_user_data(input->seat, input);
+
+ WAYLAND_wl_display_flush(d->display);
+}
+
+void Wayland_display_destroy_input(SDL_VideoData *d)
+{
+ struct SDL_WaylandInput *input = d->input;
+
+ if (!input)
+ return;
+
+ if (input->data_device != NULL) {
+ Wayland_data_device_clear_selection(input->data_device);
+ if (input->data_device->selection_offer != NULL) {
+ Wayland_data_offer_destroy(input->data_device->selection_offer);
+ }
+ if (input->data_device->drag_offer != NULL) {
+ Wayland_data_offer_destroy(input->data_device->drag_offer);
+ }
+ if (input->data_device->data_device != NULL) {
+ wl_data_device_release(input->data_device->data_device);
+ }
+ SDL_free(input->data_device);
+ }
+
+ if (input->keyboard)
+ wl_keyboard_destroy(input->keyboard);
+
+ if (input->pointer)
+ wl_pointer_destroy(input->pointer);
+
+ if (input->touch) {
+ SDL_DelTouch(1);
+ wl_touch_destroy(input->touch);
+ }
+
+ if (input->seat)
+ wl_seat_destroy(input->seat);
+
+ if (input->xkb.state)
+ WAYLAND_xkb_state_unref(input->xkb.state);
+
+ if (input->xkb.keymap)
+ WAYLAND_xkb_keymap_unref(input->xkb.keymap);
+
+ SDL_free(input);
+ d->input = NULL;
+}
+
+SDL_WaylandDataDevice* Wayland_get_data_device(struct SDL_WaylandInput *input)
+{
+ if (input == NULL) {
+ return NULL;
+ }
+
+ return input->data_device;
+}
+
+/* !!! FIXME: just merge these into display_handle_global(). */
+void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
+{
+ d->relative_pointer_manager =
+ wl_registry_bind(d->registry, id,
+ &zwp_relative_pointer_manager_v1_interface, 1);
+}
+
+void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
+{
+ if (d->relative_pointer_manager)
+ zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
+}
+
+void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
+{
+ d->pointer_constraints =
+ wl_registry_bind(d->registry, id,
+ &zwp_pointer_constraints_v1_interface, 1);
+}
+
+void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
+{
+ if (d->pointer_constraints)
+ zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
+}
+
+static void
+relative_pointer_handle_relative_motion(void *data,
+ struct zwp_relative_pointer_v1 *pointer,
+ uint32_t time_hi,
+ uint32_t time_lo,
+ wl_fixed_t dx_w,
+ wl_fixed_t dy_w,
+ wl_fixed_t dx_unaccel_w,
+ wl_fixed_t dy_unaccel_w)
+{
+ struct SDL_WaylandInput *input = data;
+ SDL_VideoData *d = input->display;
+ SDL_WindowData *window = input->pointer_focus;
+ double dx_unaccel;
+ double dy_unaccel;
+ double dx;
+ double dy;
+
+ dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
+ dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
+
+ /* Add left over fraction from last event. */
+ dx_unaccel += input->dx_frac;
+ dy_unaccel += input->dy_frac;
+
+ input->dx_frac = modf(dx_unaccel, &dx);
+ input->dy_frac = modf(dy_unaccel, &dy);
+
+ if (input->pointer_focus && d->relative_mouse_mode) {
+ SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
+ }
+}
+
+static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
+ relative_pointer_handle_relative_motion,
+};
+
+static void
+locked_pointer_locked(void *data,
+ struct zwp_locked_pointer_v1 *locked_pointer)
+{
+}
+
+static void
+locked_pointer_unlocked(void *data,
+ struct zwp_locked_pointer_v1 *locked_pointer)
+{
+}
+
+static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
+ locked_pointer_locked,
+ locked_pointer_unlocked,
+};
+
+static void
+lock_pointer_to_window(SDL_Window *window,
+ struct SDL_WaylandInput *input)
+{
+ SDL_WindowData *w = window->driverdata;
+ SDL_VideoData *d = input->display;
+ struct zwp_locked_pointer_v1 *locked_pointer;
+
+ if (w->locked_pointer)
+ return;
+
+ locked_pointer =
+ zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints,
+ w->surface,
+ input->pointer,
+ NULL,
+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
+ zwp_locked_pointer_v1_add_listener(locked_pointer,
+ &locked_pointer_listener,
+ window);
+
+ w->locked_pointer = locked_pointer;
+}
+
+int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
+{
+ SDL_VideoDevice *vd = SDL_GetVideoDevice();
+ SDL_VideoData *d = input->display;
+ SDL_Window *window;
+ struct zwp_relative_pointer_v1 *relative_pointer;
+
+ if (!d->relative_pointer_manager)
+ return -1;
+
+ if (!d->pointer_constraints)
+ return -1;
+
+ if (!input->relative_pointer) {
+ relative_pointer =
+ zwp_relative_pointer_manager_v1_get_relative_pointer(
+ d->relative_pointer_manager,
+ input->pointer);
+ zwp_relative_pointer_v1_add_listener(relative_pointer,
+ &relative_pointer_listener,
+ input);
+ input->relative_pointer = relative_pointer;
+ }
+
+ for (window = vd->windows; window; window = window->next)
+ lock_pointer_to_window(window, input);
+
+ d->relative_mouse_mode = 1;
+
+ return 0;
+}
+
+int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
+{
+ SDL_VideoDevice *vd = SDL_GetVideoDevice();
+ SDL_VideoData *d = input->display;
+ SDL_Window *window;
+ SDL_WindowData *w;
+
+ for (window = vd->windows; window; window = window->next) {
+ w = window->driverdata;
+ if (w->locked_pointer)
+ zwp_locked_pointer_v1_destroy(w->locked_pointer);
+ w->locked_pointer = NULL;
+ }
+
+ zwp_relative_pointer_v1_destroy(input->relative_pointer);
+ input->relative_pointer = NULL;
+
+ d->relative_mouse_mode = 0;
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents_c.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents_c.h
new file mode 100644
index 0000000..1c5ffe5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandevents_c.h
@@ -0,0 +1,51 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylandevents_h_
+#define SDL_waylandevents_h_
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_waylanddatamanager.h"
+
+struct SDL_WaylandInput;
+
+extern void Wayland_PumpEvents(_THIS);
+
+extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id);
+extern void Wayland_display_destroy_input(SDL_VideoData *d);
+
+extern SDL_WaylandDataDevice* Wayland_get_data_device(struct SDL_WaylandInput *input);
+
+extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id);
+extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d);
+
+extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input);
+extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input);
+
+extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id);
+extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d);
+
+#endif /* SDL_waylandevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.c
new file mode 100644
index 0000000..c77b53e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.c
@@ -0,0 +1,396 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_mouse_c.h"
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandevents_c.h"
+
+#include "SDL_waylanddyn.h"
+#include "wayland-cursor.h"
+
+#include "SDL_assert.h"
+
+
+typedef struct {
+ struct wl_buffer *buffer;
+ struct wl_surface *surface;
+
+ int hot_x, hot_y;
+ int w, h;
+
+ /* Either a preloaded cursor, or one we created ourselves */
+ struct wl_cursor *cursor;
+ void *shm_data;
+} Wayland_CursorData;
+
+static int
+wayland_create_tmp_file(off_t size)
+{
+ static const char template[] = "/sdl-shared-XXXXXX";
+ char *xdg_path;
+ char tmp_path[PATH_MAX];
+ int fd;
+
+ xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
+ if (!xdg_path) {
+ return -1;
+ }
+
+ SDL_strlcpy(tmp_path, xdg_path, PATH_MAX);
+ SDL_strlcat(tmp_path, template, PATH_MAX);
+
+ fd = mkostemp(tmp_path, O_CLOEXEC);
+ if (fd < 0)
+ return -1;
+
+ if (ftruncate(fd, size) < 0) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+static void
+mouse_buffer_release(void *data, struct wl_buffer *buffer)
+{
+}
+
+static const struct wl_buffer_listener mouse_buffer_listener = {
+ mouse_buffer_release
+};
+
+static int
+create_buffer_from_shm(Wayland_CursorData *d,
+ int width,
+ int height,
+ uint32_t format)
+{
+ SDL_VideoDevice *vd = SDL_GetVideoDevice();
+ SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
+ struct wl_shm_pool *shm_pool;
+
+ int stride = width * 4;
+ int size = stride * height;
+
+ int shm_fd;
+
+ shm_fd = wayland_create_tmp_file(size);
+ if (shm_fd < 0)
+ {
+ return SDL_SetError("Creating mouse cursor buffer failed.");
+ }
+
+ d->shm_data = mmap(NULL,
+ size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ shm_fd,
+ 0);
+ if (d->shm_data == MAP_FAILED) {
+ d->shm_data = NULL;
+ close (shm_fd);
+ return SDL_SetError("mmap() failed.");
+ }
+
+ shm_pool = wl_shm_create_pool(data->shm, shm_fd, size);
+ d->buffer = wl_shm_pool_create_buffer(shm_pool,
+ 0,
+ width,
+ height,
+ stride,
+ format);
+ wl_buffer_add_listener(d->buffer,
+ &mouse_buffer_listener,
+ d);
+
+ wl_shm_pool_destroy (shm_pool);
+ close (shm_fd);
+
+ return 0;
+}
+
+static SDL_Cursor *
+Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
+{
+ SDL_Cursor *cursor;
+
+ cursor = calloc(1, sizeof (*cursor));
+ if (cursor) {
+ SDL_VideoDevice *vd = SDL_GetVideoDevice ();
+ SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata;
+ Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
+ if (!data) {
+ SDL_OutOfMemory();
+ free(cursor);
+ return NULL;
+ }
+ cursor->driverdata = (void *) data;
+
+ /* Assume ARGB8888 */
+ SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
+ SDL_assert(surface->pitch == surface->w * 4);
+
+ /* Allocate shared memory buffer for this cursor */
+ if (create_buffer_from_shm (data,
+ surface->w,
+ surface->h,
+ WL_SHM_FORMAT_ARGB8888) < 0)
+ {
+ free (cursor->driverdata);
+ free (cursor);
+ return NULL;
+ }
+
+ SDL_memcpy(data->shm_data,
+ surface->pixels,
+ surface->h * surface->pitch);
+
+ data->surface = wl_compositor_create_surface(wd->compositor);
+ wl_surface_set_user_data(data->surface, NULL);
+
+ data->hot_x = hot_x;
+ data->hot_y = hot_y;
+ data->w = surface->w;
+ data->h = surface->h;
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
+{
+ SDL_Cursor *cursor;
+
+ cursor = calloc(1, sizeof (*cursor));
+ if (cursor) {
+ Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
+ if (!data) {
+ SDL_OutOfMemory();
+ free(cursor);
+ return NULL;
+ }
+ cursor->driverdata = (void *) data;
+
+ data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]);
+ data->surface = wl_compositor_create_surface(d->compositor);
+ wl_surface_set_user_data(data->surface, NULL);
+ data->hot_x = wlcursor->images[0]->hotspot_x;
+ data->hot_y = wlcursor->images[0]->hotspot_y;
+ data->w = wlcursor->images[0]->width;
+ data->h = wlcursor->images[0]->height;
+ data->cursor= wlcursor;
+ } else {
+ SDL_OutOfMemory ();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+Wayland_CreateDefaultCursor()
+{
+ SDL_VideoDevice *device = SDL_GetVideoDevice();
+ SDL_VideoData *data = device->driverdata;
+
+ return CreateCursorFromWlCursor (data,
+ WAYLAND_wl_cursor_theme_get_cursor(data->cursor_theme,
+ "left_ptr"));
+}
+
+static SDL_Cursor *
+Wayland_CreateSystemCursor(SDL_SystemCursor id)
+{
+ SDL_VideoDevice *vd = SDL_GetVideoDevice();
+ SDL_VideoData *d = vd->driverdata;
+
+ struct wl_cursor *cursor = NULL;
+
+ switch(id)
+ {
+ default:
+ SDL_assert(0);
+ return NULL;
+ case SDL_SYSTEM_CURSOR_ARROW:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
+ break;
+ case SDL_SYSTEM_CURSOR_IBEAM:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
+ break;
+ case SDL_SYSTEM_CURSOR_WAIT:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch");
+ break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ case SDL_SYSTEM_CURSOR_WAITARROW:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch");
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENESW:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEWE:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ case SDL_SYSTEM_CURSOR_SIZENS:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ case SDL_SYSTEM_CURSOR_SIZEALL:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ case SDL_SYSTEM_CURSOR_NO:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
+ break;
+ case SDL_SYSTEM_CURSOR_HAND:
+ cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
+ break;
+ }
+
+ return CreateCursorFromWlCursor(d, cursor);
+}
+
+static void
+Wayland_FreeCursor(SDL_Cursor *cursor)
+{
+ Wayland_CursorData *d;
+
+ if (!cursor)
+ return;
+
+ d = cursor->driverdata;
+
+ /* Probably not a cursor we own */
+ if (!d)
+ return;
+
+ if (d->buffer && !d->cursor)
+ wl_buffer_destroy(d->buffer);
+
+ if (d->surface)
+ wl_surface_destroy(d->surface);
+
+ /* Not sure what's meant to happen to shm_data */
+ free (cursor->driverdata);
+ SDL_free(cursor);
+}
+
+static int
+Wayland_ShowCursor(SDL_Cursor *cursor)
+{
+ SDL_VideoDevice *vd = SDL_GetVideoDevice();
+ SDL_VideoData *d = vd->driverdata;
+
+ struct wl_pointer *pointer = d->pointer;
+
+ if (!pointer)
+ return -1;
+
+ if (cursor)
+ {
+ Wayland_CursorData *data = cursor->driverdata;
+
+ wl_pointer_set_cursor (pointer, 0,
+ data->surface,
+ data->hot_x,
+ data->hot_y);
+ wl_surface_attach(data->surface, data->buffer, 0, 0);
+ wl_surface_damage(data->surface, 0, 0, data->w, data->h);
+ wl_surface_commit(data->surface);
+ }
+ else
+ {
+ wl_pointer_set_cursor (pointer, 0,
+ NULL,
+ 0,
+ 0);
+ }
+
+ return 0;
+}
+
+static void
+Wayland_WarpMouse(SDL_Window *window, int x, int y)
+{
+ SDL_Unsupported();
+}
+
+static int
+Wayland_WarpMouseGlobal(int x, int y)
+{
+ return SDL_Unsupported();
+}
+
+static int
+Wayland_SetRelativeMouseMode(SDL_bool enabled)
+{
+ SDL_VideoDevice *vd = SDL_GetVideoDevice();
+ SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
+
+ if (enabled)
+ return Wayland_input_lock_pointer(data->input);
+ else
+ return Wayland_input_unlock_pointer(data->input);
+}
+
+void
+Wayland_InitMouse(void)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = Wayland_CreateCursor;
+ mouse->CreateSystemCursor = Wayland_CreateSystemCursor;
+ mouse->ShowCursor = Wayland_ShowCursor;
+ mouse->FreeCursor = Wayland_FreeCursor;
+ mouse->WarpMouse = Wayland_WarpMouse;
+ mouse->WarpMouseGlobal = Wayland_WarpMouseGlobal;
+ mouse->SetRelativeMouseMode = Wayland_SetRelativeMouseMode;
+
+ SDL_SetDefaultCursor(Wayland_CreateDefaultCursor());
+}
+
+void
+Wayland_FiniMouse(void)
+{
+ /* This effectively assumes that nobody else
+ * touches SDL_Mouse which is effectively
+ * a singleton */
+}
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.h
new file mode 100644
index 0000000..2c50e5f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandmouse.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+#include "SDL_mouse.h"
+#include "SDL_waylandvideo.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+extern void Wayland_InitMouse(void);
+extern void Wayland_FiniMouse(void);
+
+#endif
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.c
new file mode 100644
index 0000000..9c0b845
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.c
@@ -0,0 +1,93 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandopengles.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_waylandevents_c.h"
+#include "SDL_waylanddyn.h"
+
+/* EGL implementation of SDL OpenGL ES support */
+
+int
+Wayland_GLES_LoadLibrary(_THIS, const char *path) {
+ int ret;
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0);
+
+ Wayland_PumpEvents(_this);
+ WAYLAND_wl_display_flush(data->display);
+
+ return ret;
+}
+
+
+SDL_GLContext
+Wayland_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_GLContext context;
+ context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+
+ return context;
+}
+
+int
+Wayland_GLES_SwapWindow(_THIS, SDL_Window *window)
+{
+ if (SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface) < 0) {
+ return -1;
+ }
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+ return 0;
+}
+
+int
+Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ int ret;
+
+ if (window && context) {
+ ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
+ }
+ else {
+ ret = SDL_EGL_MakeCurrent(_this, NULL, NULL);
+ }
+
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+
+ return ret;
+}
+
+void
+Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context)
+{
+ SDL_EGL_DeleteContext(_this, context);
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.h
new file mode 100644
index 0000000..58d7f9b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandopengles.h
@@ -0,0 +1,49 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylandopengles_h_
+#define SDL_waylandopengles_h_
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+typedef struct SDL_PrivateGLESData
+{
+ int dummy;
+} SDL_PrivateGLESData;
+
+/* OpenGLES functions */
+#define Wayland_GLES_GetAttribute SDL_EGL_GetAttribute
+#define Wayland_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define Wayland_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define Wayland_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define Wayland_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+
+extern int Wayland_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int Wayland_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* SDL_waylandopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandsym.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandsym.h
new file mode 100644
index 0000000..77783df
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandsym.h
@@ -0,0 +1,127 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* *INDENT-OFF* */
+
+#ifndef SDL_WAYLAND_MODULE
+#define SDL_WAYLAND_MODULE(modname)
+#endif
+
+#ifndef SDL_WAYLAND_SYM
+#define SDL_WAYLAND_SYM(rc,fn,params)
+#endif
+
+#ifndef SDL_WAYLAND_INTERFACE
+#define SDL_WAYLAND_INTERFACE(iface)
+#endif
+
+SDL_WAYLAND_MODULE(WAYLAND_CLIENT)
+SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...))
+SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *))
+SDL_WAYLAND_SYM(void, wl_proxy_destroy, (struct wl_proxy *))
+SDL_WAYLAND_SYM(int, wl_proxy_add_listener, (struct wl_proxy *, void (**)(void), void *))
+SDL_WAYLAND_SYM(void, wl_proxy_set_user_data, (struct wl_proxy *, void *))
+SDL_WAYLAND_SYM(void *, wl_proxy_get_user_data, (struct wl_proxy *))
+SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_id, (struct wl_proxy *))
+SDL_WAYLAND_SYM(const char *, wl_proxy_get_class, (struct wl_proxy *))
+SDL_WAYLAND_SYM(void, wl_proxy_set_queue, (struct wl_proxy *, struct wl_event_queue *))
+SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect, (const char *))
+SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect_to_fd, (int))
+SDL_WAYLAND_SYM(void, wl_display_disconnect, (struct wl_display *))
+SDL_WAYLAND_SYM(int, wl_display_get_fd, (struct wl_display *))
+SDL_WAYLAND_SYM(int, wl_display_dispatch, (struct wl_display *))
+SDL_WAYLAND_SYM(int, wl_display_dispatch_queue, (struct wl_display *, struct wl_event_queue *))
+SDL_WAYLAND_SYM(int, wl_display_dispatch_queue_pending, (struct wl_display *, struct wl_event_queue *))
+SDL_WAYLAND_SYM(int, wl_display_dispatch_pending, (struct wl_display *))
+SDL_WAYLAND_SYM(int, wl_display_get_error, (struct wl_display *))
+SDL_WAYLAND_SYM(int, wl_display_flush, (struct wl_display *))
+SDL_WAYLAND_SYM(int, wl_display_roundtrip, (struct wl_display *))
+SDL_WAYLAND_SYM(struct wl_event_queue *, wl_display_create_queue, (struct wl_display *))
+SDL_WAYLAND_SYM(void, wl_log_set_handler_client, (wl_log_func_t))
+SDL_WAYLAND_SYM(void, wl_list_init, (struct wl_list *))
+SDL_WAYLAND_SYM(void, wl_list_insert, (struct wl_list *, struct wl_list *) )
+SDL_WAYLAND_SYM(void, wl_list_remove, (struct wl_list *))
+SDL_WAYLAND_SYM(int, wl_list_length, (const struct wl_list *))
+SDL_WAYLAND_SYM(int, wl_list_empty, (const struct wl_list *))
+SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *))
+
+/* These functions are available in Wayland >= 1.4 */
+SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_4)
+SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...))
+
+SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10)
+SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...))
+
+SDL_WAYLAND_INTERFACE(wl_seat_interface)
+SDL_WAYLAND_INTERFACE(wl_surface_interface)
+SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
+SDL_WAYLAND_INTERFACE(wl_buffer_interface)
+SDL_WAYLAND_INTERFACE(wl_registry_interface)
+SDL_WAYLAND_INTERFACE(wl_shell_surface_interface)
+SDL_WAYLAND_INTERFACE(wl_region_interface)
+SDL_WAYLAND_INTERFACE(wl_pointer_interface)
+SDL_WAYLAND_INTERFACE(wl_keyboard_interface)
+SDL_WAYLAND_INTERFACE(wl_compositor_interface)
+SDL_WAYLAND_INTERFACE(wl_output_interface)
+SDL_WAYLAND_INTERFACE(wl_shell_interface)
+SDL_WAYLAND_INTERFACE(wl_shm_interface)
+SDL_WAYLAND_INTERFACE(wl_data_device_interface)
+SDL_WAYLAND_INTERFACE(wl_data_source_interface)
+SDL_WAYLAND_INTERFACE(wl_data_offer_interface)
+SDL_WAYLAND_INTERFACE(wl_data_device_manager_interface)
+
+SDL_WAYLAND_MODULE(WAYLAND_EGL)
+SDL_WAYLAND_SYM(struct wl_egl_window *, wl_egl_window_create, (struct wl_surface *, int, int))
+SDL_WAYLAND_SYM(void, wl_egl_window_destroy, (struct wl_egl_window *))
+SDL_WAYLAND_SYM(void, wl_egl_window_resize, (struct wl_egl_window *, int, int, int, int))
+SDL_WAYLAND_SYM(void, wl_egl_window_get_attached_size, (struct wl_egl_window *, int *, int *))
+
+SDL_WAYLAND_MODULE(WAYLAND_CURSOR)
+SDL_WAYLAND_SYM(struct wl_cursor_theme *, wl_cursor_theme_load, (const char *, int , struct wl_shm *))
+SDL_WAYLAND_SYM(void, wl_cursor_theme_destroy, (struct wl_cursor_theme *))
+SDL_WAYLAND_SYM(struct wl_cursor *, wl_cursor_theme_get_cursor, (struct wl_cursor_theme *, const char *))
+SDL_WAYLAND_SYM(struct wl_buffer *, wl_cursor_image_get_buffer, (struct wl_cursor_image *))
+SDL_WAYLAND_SYM(int, wl_cursor_frame, (struct wl_cursor *, uint32_t))
+
+SDL_WAYLAND_MODULE(WAYLAND_XKB)
+SDL_WAYLAND_SYM(int, xkb_state_key_get_syms, (struct xkb_state *, xkb_keycode_t, const xkb_keysym_t **))
+SDL_WAYLAND_SYM(int, xkb_keysym_to_utf8, (xkb_keysym_t, char *, size_t) )
+SDL_WAYLAND_SYM(struct xkb_keymap *, xkb_keymap_new_from_string, (struct xkb_context *, const char *, enum xkb_keymap_format, enum xkb_keymap_compile_flags))
+SDL_WAYLAND_SYM(struct xkb_state *, xkb_state_new, (struct xkb_keymap *) )
+SDL_WAYLAND_SYM(void, xkb_keymap_unref, (struct xkb_keymap *) )
+SDL_WAYLAND_SYM(void, xkb_state_unref, (struct xkb_state *) )
+SDL_WAYLAND_SYM(void, xkb_context_unref, (struct xkb_context *) )
+SDL_WAYLAND_SYM(struct xkb_context *, xkb_context_new, (enum xkb_context_flags flags) )
+SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_state *state,\
+ xkb_mod_mask_t depressed_mods,\
+ xkb_mod_mask_t latched_mods,\
+ xkb_mod_mask_t locked_mods,\
+ xkb_layout_index_t depressed_layout,\
+ xkb_layout_index_t latched_layout,\
+ xkb_layout_index_t locked_layout) )
+
+#undef SDL_WAYLAND_MODULE
+#undef SDL_WAYLAND_SYM
+#undef SDL_WAYLAND_INTERFACE
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.c
new file mode 100644
index 0000000..1cf37c1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.c
@@ -0,0 +1,265 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* Contributed by Thomas Perl <thomas.perl@jollamobile.com> */
+
+#include "../../SDL_internal.h"
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+
+#include "SDL_log.h"
+#include "SDL_waylandtouch.h"
+#include "../../events/SDL_touch_c.h"
+
+struct SDL_WaylandTouch {
+ struct qt_touch_extension *touch_extension;
+};
+
+
+/**
+ * Qt TouchPointState
+ * adapted from qtbase/src/corelib/global/qnamespace.h
+ **/
+enum QtWaylandTouchPointState {
+ QtWaylandTouchPointPressed = 0x01,
+ QtWaylandTouchPointMoved = 0x02,
+ /*
+ Never sent by the server:
+ QtWaylandTouchPointStationary = 0x04,
+ */
+ QtWaylandTouchPointReleased = 0x08,
+};
+
+static void
+touch_handle_touch(void *data,
+ struct qt_touch_extension *qt_touch_extension,
+ uint32_t time,
+ uint32_t id,
+ uint32_t state,
+ int32_t x,
+ int32_t y,
+ int32_t normalized_x,
+ int32_t normalized_y,
+ int32_t width,
+ int32_t height,
+ uint32_t pressure,
+ int32_t velocity_x,
+ int32_t velocity_y,
+ uint32_t flags,
+ struct wl_array *rawdata)
+{
+ /**
+ * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent
+ * (src/compositor/wayland_wrapper/qwltouch.cpp)
+ **/
+
+ float FIXED_TO_FLOAT = 1. / 10000.;
+ float xf = FIXED_TO_FLOAT * x;
+ float yf = FIXED_TO_FLOAT * y;
+
+ float PRESSURE_TO_FLOAT = 1. / 255.;
+ float pressuref = PRESSURE_TO_FLOAT * pressure;
+
+ uint32_t touchState = state & 0xFFFF;
+ /*
+ Other fields that are sent by the server (qwltouch.cpp),
+ but not used at the moment can be decoded in this way:
+
+ uint32_t sentPointCount = state >> 16;
+ uint32_t touchFlags = flags & 0xFFFF;
+ uint32_t capabilities = flags >> 16;
+ */
+
+ SDL_TouchID deviceId = 1;
+ if (SDL_AddTouch(deviceId, "qt_touch_extension") < 0) {
+ SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
+ }
+
+ switch (touchState) {
+ case QtWaylandTouchPointPressed:
+ case QtWaylandTouchPointReleased:
+ SDL_SendTouch(deviceId, (SDL_FingerID)id,
+ (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
+ xf, yf, pressuref);
+ break;
+ case QtWaylandTouchPointMoved:
+ SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, xf, yf, pressuref);
+ break;
+ default:
+ /* Should not happen */
+ break;
+ }
+}
+
+static void
+touch_handle_configure(void *data,
+ struct qt_touch_extension *qt_touch_extension,
+ uint32_t flags)
+{
+}
+
+
+/* wayland-qt-touch-extension.c BEGINS */
+
+static const struct qt_touch_extension_listener touch_listener = {
+ touch_handle_touch,
+ touch_handle_configure,
+};
+
+static const struct wl_interface *qt_touch_extension_types[] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static const struct wl_message qt_touch_extension_requests[] = {
+ { "dummy", "", qt_touch_extension_types + 0 },
+};
+
+static const struct wl_message qt_touch_extension_events[] = {
+ { "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 },
+ { "configure", "u", qt_touch_extension_types + 0 },
+};
+
+WL_EXPORT const struct wl_interface qt_touch_extension_interface = {
+ "qt_touch_extension", 1,
+ 1, qt_touch_extension_requests,
+ 2, qt_touch_extension_events,
+};
+
+/* wayland-qt-touch-extension.c ENDS */
+
+/* wayland-qt-windowmanager.c BEGINS */
+static const struct wl_interface *qt_windowmanager_types[] = {
+ NULL,
+ NULL,
+};
+
+static const struct wl_message qt_windowmanager_requests[] = {
+ { "open_url", "us", qt_windowmanager_types + 0 },
+};
+
+static const struct wl_message qt_windowmanager_events[] = {
+ { "hints", "i", qt_windowmanager_types + 0 },
+ { "quit", "", qt_windowmanager_types + 0 },
+};
+
+WL_EXPORT const struct wl_interface qt_windowmanager_interface = {
+ "qt_windowmanager", 1,
+ 1, qt_windowmanager_requests,
+ 2, qt_windowmanager_events,
+};
+/* wayland-qt-windowmanager.c ENDS */
+
+/* wayland-qt-surface-extension.c BEGINS */
+extern const struct wl_interface qt_extended_surface_interface;
+#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+extern const struct wl_interface wl_surface_interface;
+#endif
+
+static const struct wl_interface *qt_surface_extension_types[] = {
+ NULL,
+ NULL,
+ &qt_extended_surface_interface,
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
+ /* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ?
+ * The value comes from auto generated code and does
+ * not appear to actually be used anywhere
+ */
+ NULL,
+#else
+ &wl_surface_interface,
+#endif
+};
+
+static const struct wl_message qt_surface_extension_requests[] = {
+ { "get_extended_surface", "no", qt_surface_extension_types + 2 },
+};
+
+WL_EXPORT const struct wl_interface qt_surface_extension_interface = {
+ "qt_surface_extension", 1,
+ 1, qt_surface_extension_requests,
+ 0, NULL,
+};
+
+static const struct wl_message qt_extended_surface_requests[] = {
+ { "update_generic_property", "sa", qt_surface_extension_types + 0 },
+ { "set_content_orientation", "i", qt_surface_extension_types + 0 },
+ { "set_window_flags", "i", qt_surface_extension_types + 0 },
+};
+
+static const struct wl_message qt_extended_surface_events[] = {
+ { "onscreen_visibility", "i", qt_surface_extension_types + 0 },
+ { "set_generic_property", "sa", qt_surface_extension_types + 0 },
+ { "close", "", qt_surface_extension_types + 0 },
+};
+
+WL_EXPORT const struct wl_interface qt_extended_surface_interface = {
+ "qt_extended_surface", 1,
+ 3, qt_extended_surface_requests,
+ 3, qt_extended_surface_events,
+};
+
+/* wayland-qt-surface-extension.c ENDS */
+
+void
+Wayland_touch_create(SDL_VideoData *data, uint32_t id)
+{
+ struct SDL_WaylandTouch *touch;
+
+ if (data->touch) {
+ Wayland_touch_destroy(data);
+ }
+
+ /* !!! FIXME: check for failure, call SDL_OutOfMemory() */
+ data->touch = SDL_malloc(sizeof(struct SDL_WaylandTouch));
+
+ touch = data->touch;
+ touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1);
+ qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data);
+}
+
+void
+Wayland_touch_destroy(SDL_VideoData *data)
+{
+ if (data->touch) {
+ struct SDL_WaylandTouch *touch = data->touch;
+ if (touch->touch_extension) {
+ qt_touch_extension_destroy(touch->touch_extension);
+ }
+
+ SDL_free(data->touch);
+ data->touch = NULL;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.h
new file mode 100644
index 0000000..eba0da8
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandtouch.h
@@ -0,0 +1,352 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_waylandtouch_h_
+#define SDL_waylandtouch_h_
+
+#include "../../SDL_internal.h"
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+
+#include "SDL_waylandvideo.h"
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+#include "SDL_waylanddyn.h"
+
+
+void Wayland_touch_create(SDL_VideoData *data, uint32_t id);
+void Wayland_touch_destroy(SDL_VideoData *data);
+
+struct qt_touch_extension;
+
+/* Autogenerated QT headers */
+
+/*
+ Support for Wayland with QmlCompositor as Server
+================================================
+
+The Wayland video driver has support for some additional features when
+using QtWayland's "qmlcompositor" as Wayland server. This is needed for touch
+input when running SDL applications under a qmlcompositor Wayland server.
+
+The files following headers have been
+generated from the Wayland XML Protocol Definition in QtWayland as follows:
+
+Clone QtWayland from Git:
+ http://qt.gitorious.org/qt/qtwayland/
+
+Generate headers and glue code:
+ for extension in touch-extension surface-extension windowmanager; do
+ wayland-scanner client-header < src/extensions/$extension.xml > wayland-qt-$extension.h
+ wayland-scanner code < src/extensions/$extension.xml > wayland-qt-$extension.c
+ done
+
+*/
+
+/* wayland-qt-surface-extension.h */
+
+struct wl_client;
+struct wl_resource;
+
+struct qt_surface_extension;
+struct qt_extended_surface;
+
+extern const struct wl_interface qt_surface_extension_interface;
+extern const struct wl_interface qt_extended_surface_interface;
+
+#define QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE 0
+
+static inline void
+qt_surface_extension_set_user_data(struct qt_surface_extension *qt_surface_extension, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) qt_surface_extension, user_data);
+}
+
+static inline void *
+qt_surface_extension_get_user_data(struct qt_surface_extension *qt_surface_extension)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) qt_surface_extension);
+}
+
+static inline void
+qt_surface_extension_destroy(struct qt_surface_extension *qt_surface_extension)
+{
+ WAYLAND_wl_proxy_destroy((struct wl_proxy *) qt_surface_extension);
+}
+
+static inline struct qt_extended_surface *
+qt_surface_extension_get_extended_surface(struct qt_surface_extension *qt_surface_extension, struct wl_surface *surface)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) qt_surface_extension,
+ &qt_extended_surface_interface);
+ if (!id)
+ return NULL;
+
+ WAYLAND_wl_proxy_marshal((struct wl_proxy *) qt_surface_extension,
+ QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE, id, surface);
+
+ return (struct qt_extended_surface *) id;
+}
+
+#ifndef QT_EXTENDED_SURFACE_ORIENTATION_ENUM
+#define QT_EXTENDED_SURFACE_ORIENTATION_ENUM
+enum qt_extended_surface_orientation {
+ QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION = 0,
+ QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION = 1,
+ QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION = 2,
+ QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION = 4,
+ QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION = 8,
+};
+#endif /* QT_EXTENDED_SURFACE_ORIENTATION_ENUM */
+
+#ifndef QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM
+#define QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM
+enum qt_extended_surface_windowflag {
+ QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES = 1,
+ QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP = 2,
+};
+#endif /* QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM */
+
+struct qt_extended_surface_listener {
+ /**
+ * onscreen_visibility - (none)
+ * @visible: (none)
+ */
+ void (*onscreen_visibility)(void *data,
+ struct qt_extended_surface *qt_extended_surface,
+ int32_t visible);
+ /**
+ * set_generic_property - (none)
+ * @name: (none)
+ * @value: (none)
+ */
+ void (*set_generic_property)(void *data,
+ struct qt_extended_surface *qt_extended_surface,
+ const char *name,
+ struct wl_array *value);
+ /**
+ * close - (none)
+ */
+ void (*close)(void *data,
+ struct qt_extended_surface *qt_extended_surface);
+};
+
+static inline int
+qt_extended_surface_add_listener(struct qt_extended_surface *qt_extended_surface,
+ const struct qt_extended_surface_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) qt_extended_surface,
+ (void (**)(void)) listener, data);
+}
+
+#define QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY 0
+#define QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION 1
+#define QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS 2
+
+static inline void
+qt_extended_surface_set_user_data(struct qt_extended_surface *qt_extended_surface, void *user_data)
+{
+ WAYLAND_wl_proxy_set_user_data((struct wl_proxy *) qt_extended_surface, user_data);
+}
+
+static inline void *
+qt_extended_surface_get_user_data(struct qt_extended_surface *qt_extended_surface)
+{
+ return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *) qt_extended_surface);
+}
+
+static inline void
+qt_extended_surface_destroy(struct qt_extended_surface *qt_extended_surface)
+{
+ WAYLAND_wl_proxy_destroy((struct wl_proxy *) qt_extended_surface);
+}
+
+static inline void
+qt_extended_surface_update_generic_property(struct qt_extended_surface *qt_extended_surface, const char *name, struct wl_array *value)
+{
+ WAYLAND_wl_proxy_marshal((struct wl_proxy *) qt_extended_surface,
+ QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY, name, value);
+}
+
+static inline void
+qt_extended_surface_set_content_orientation(struct qt_extended_surface *qt_extended_surface, int32_t orientation)
+{
+ WAYLAND_wl_proxy_marshal((struct wl_proxy *) qt_extended_surface,
+ QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION, orientation);
+}
+
+static inline void
+qt_extended_surface_set_window_flags(struct qt_extended_surface *qt_extended_surface, int32_t flags)
+{
+ WAYLAND_wl_proxy_marshal((struct wl_proxy *) qt_extended_surface,
+ QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS, flags);
+}
+
+/* wayland-qt-touch-extension.h */
+
+extern const struct wl_interface qt_touch_extension_interface;
+
+#ifndef QT_TOUCH_EXTENSION_FLAGS_ENUM
+#define QT_TOUCH_EXTENSION_FLAGS_ENUM
+enum qt_touch_extension_flags {
+ QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH = 0x1,
+};
+#endif /* QT_TOUCH_EXTENSION_FLAGS_ENUM */
+
+struct qt_touch_extension_listener {
+ /**
+ * touch - (none)
+ * @time: (none)
+ * @id: (none)
+ * @state: (none)
+ * @x: (none)
+ * @y: (none)
+ * @normalized_x: (none)
+ * @normalized_y: (none)
+ * @width: (none)
+ * @height: (none)
+ * @pressure: (none)
+ * @velocity_x: (none)
+ * @velocity_y: (none)
+ * @flags: (none)
+ * @rawdata: (none)
+ */
+ void (*touch)(void *data,
+ struct qt_touch_extension *qt_touch_extension,
+ uint32_t time,
+ uint32_t id,
+ uint32_t state,
+ int32_t x,
+ int32_t y,
+ int32_t normalized_x,
+ int32_t normalized_y,
+ int32_t width,
+ int32_t height,
+ uint32_t pressure,
+ int32_t velocity_x,
+ int32_t velocity_y,
+ uint32_t flags,
+ struct wl_array *rawdata);
+ /**
+ * configure - (none)
+ * @flags: (none)
+ */
+ void (*configure)(void *data,
+ struct qt_touch_extension *qt_touch_extension,
+ uint32_t flags);
+};
+
+static inline int
+qt_touch_extension_add_listener(struct qt_touch_extension *qt_touch_extension,
+ const struct qt_touch_extension_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) qt_touch_extension,
+ (void (**)(void)) listener, data);
+}
+
+#define QT_TOUCH_EXTENSION_DUMMY 0
+
+static inline void
+qt_touch_extension_set_user_data(struct qt_touch_extension *qt_touch_extension, void *user_data)
+{
+ WAYLAND_wl_proxy_set_user_data((struct wl_proxy *) qt_touch_extension, user_data);
+}
+
+static inline void *
+qt_touch_extension_get_user_data(struct qt_touch_extension *qt_touch_extension)
+{
+ return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *) qt_touch_extension);
+}
+
+static inline void
+qt_touch_extension_destroy(struct qt_touch_extension *qt_touch_extension)
+{
+ WAYLAND_wl_proxy_destroy((struct wl_proxy *) qt_touch_extension);
+}
+
+static inline void
+qt_touch_extension_dummy(struct qt_touch_extension *qt_touch_extension)
+{
+ WAYLAND_wl_proxy_marshal((struct wl_proxy *) qt_touch_extension,
+ QT_TOUCH_EXTENSION_DUMMY);
+}
+
+
+/* wayland-qt-windowmanager.h */
+
+extern const struct wl_interface qt_windowmanager_interface;
+
+struct qt_windowmanager_listener {
+ /**
+ * hints - (none)
+ * @show_is_fullscreen: (none)
+ */
+ void (*hints)(void *data,
+ struct qt_windowmanager *qt_windowmanager,
+ int32_t show_is_fullscreen);
+ /**
+ * quit - (none)
+ */
+ void (*quit)(void *data,
+ struct qt_windowmanager *qt_windowmanager);
+};
+
+static inline int
+qt_windowmanager_add_listener(struct qt_windowmanager *qt_windowmanager,
+ const struct qt_windowmanager_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) qt_windowmanager,
+ (void (**)(void)) listener, data);
+}
+
+#define QT_WINDOWMANAGER_OPEN_URL 0
+
+static inline void
+qt_windowmanager_set_user_data(struct qt_windowmanager *qt_windowmanager, void *user_data)
+{
+ WAYLAND_wl_proxy_set_user_data((struct wl_proxy *) qt_windowmanager, user_data);
+}
+
+static inline void *
+qt_windowmanager_get_user_data(struct qt_windowmanager *qt_windowmanager)
+{
+ return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *) qt_windowmanager);
+}
+
+static inline void
+qt_windowmanager_destroy(struct qt_windowmanager *qt_windowmanager)
+{
+ WAYLAND_wl_proxy_destroy((struct wl_proxy *) qt_windowmanager);
+}
+
+static inline void
+qt_windowmanager_open_url(struct qt_windowmanager *qt_windowmanager, uint32_t remaining, const char *url)
+{
+ WAYLAND_wl_proxy_marshal((struct wl_proxy *) qt_windowmanager,
+ QT_WINDOWMANAGER_OPEN_URL, remaining, url);
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+#endif /* SDL_waylandtouch_h_ */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.c
new file mode 100644
index 0000000..b6155e7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.c
@@ -0,0 +1,517 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_stdinc.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandevents_c.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_waylandopengles.h"
+#include "SDL_waylandmouse.h"
+#include "SDL_waylandtouch.h"
+#include "SDL_waylandclipboard.h"
+#include "SDL_waylandvulkan.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <xkbcommon/xkbcommon.h>
+
+#include "SDL_waylanddyn.h"
+#include <wayland-util.h>
+
+#include "xdg-shell-client-protocol.h"
+#include "xdg-shell-unstable-v6-client-protocol.h"
+
+#define WAYLANDVID_DRIVER_NAME "wayland"
+
+/* Initialization/Query functions */
+static int
+Wayland_VideoInit(_THIS);
+
+static void
+Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display);
+static int
+Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
+
+static void
+Wayland_VideoQuit(_THIS);
+
+/* Find out what class name we should use
+ * Based on src/video/x11/SDL_x11video.c */
+static char *
+get_classname()
+{
+/* !!! FIXME: this is probably wrong, albeit harmless in many common cases. From protocol spec:
+ "The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use the
+ file name (or the full path if it is a non-standard location) of
+ the application's .desktop file as the class." */
+
+ char *spot;
+#if defined(__LINUX__) || defined(__FREEBSD__)
+ char procfile[1024];
+ char linkfile[1024];
+ int linksize;
+#endif
+
+ /* First allow environment variable override */
+ spot = SDL_getenv("SDL_VIDEO_WAYLAND_WMCLASS");
+ if (spot) {
+ return SDL_strdup(spot);
+ } else {
+ /* Fallback to the "old" envvar */
+ spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
+ if (spot) {
+ return SDL_strdup(spot);
+ }
+ }
+
+ /* Next look at the application's executable name */
+#if defined(__LINUX__) || defined(__FREEBSD__)
+#if defined(__LINUX__)
+ SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
+#elif defined(__FREEBSD__)
+ SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
+ getpid());
+#else
+#error Where can we find the executable name?
+#endif
+ linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
+ if (linksize > 0) {
+ linkfile[linksize] = '\0';
+ spot = SDL_strrchr(linkfile, '/');
+ if (spot) {
+ return SDL_strdup(spot + 1);
+ } else {
+ return SDL_strdup(linkfile);
+ }
+ }
+#endif /* __LINUX__ || __FREEBSD__ */
+
+ /* Finally use the default we've used forever */
+ return SDL_strdup("SDL_App");
+}
+
+/* Wayland driver bootstrap functions */
+static int
+Wayland_Available(void)
+{
+ struct wl_display *display = NULL;
+ if (SDL_WAYLAND_LoadSymbols()) {
+ display = WAYLAND_wl_display_connect(NULL);
+ if (display != NULL) {
+ WAYLAND_wl_display_disconnect(display);
+ }
+ SDL_WAYLAND_UnloadSymbols();
+ }
+
+ return (display != NULL);
+}
+
+static void
+Wayland_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device);
+ SDL_WAYLAND_UnloadSymbols();
+}
+
+static SDL_VideoDevice *
+Wayland_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ if (!SDL_WAYLAND_LoadSymbols()) {
+ return NULL;
+ }
+
+ /* Initialize all variables that we clean on shutdown */
+ device = SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_WAYLAND_UnloadSymbols();
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Set the function pointers */
+ device->VideoInit = Wayland_VideoInit;
+ device->VideoQuit = Wayland_VideoQuit;
+ device->SetDisplayMode = Wayland_SetDisplayMode;
+ device->GetDisplayModes = Wayland_GetDisplayModes;
+ device->GetWindowWMInfo = Wayland_GetWindowWMInfo;
+
+ device->PumpEvents = Wayland_PumpEvents;
+
+ device->GL_SwapWindow = Wayland_GLES_SwapWindow;
+ device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval;
+ device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval;
+ device->GL_MakeCurrent = Wayland_GLES_MakeCurrent;
+ device->GL_CreateContext = Wayland_GLES_CreateContext;
+ device->GL_LoadLibrary = Wayland_GLES_LoadLibrary;
+ device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary;
+ device->GL_GetProcAddress = Wayland_GLES_GetProcAddress;
+ device->GL_DeleteContext = Wayland_GLES_DeleteContext;
+
+ device->CreateSDLWindow = Wayland_CreateWindow;
+ device->ShowWindow = Wayland_ShowWindow;
+ device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
+ device->MaximizeWindow = Wayland_MaximizeWindow;
+ device->RestoreWindow = Wayland_RestoreWindow;
+ device->SetWindowSize = Wayland_SetWindowSize;
+ device->SetWindowTitle = Wayland_SetWindowTitle;
+ device->DestroyWindow = Wayland_DestroyWindow;
+ device->SetWindowHitTest = Wayland_SetWindowHitTest;
+
+ device->SetClipboardText = Wayland_SetClipboardText;
+ device->GetClipboardText = Wayland_GetClipboardText;
+ device->HasClipboardText = Wayland_HasClipboardText;
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = Wayland_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface;
+#endif
+
+ device->free = Wayland_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap Wayland_bootstrap = {
+ WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
+ Wayland_Available, Wayland_CreateDevice
+};
+
+static void
+display_handle_geometry(void *data,
+ struct wl_output *output,
+ int x, int y,
+ int physical_width,
+ int physical_height,
+ int subpixel,
+ const char *make,
+ const char *model,
+ int transform)
+
+{
+ SDL_VideoDisplay *display = data;
+
+ display->name = SDL_strdup(model);
+ display->driverdata = output;
+}
+
+static void
+display_handle_mode(void *data,
+ struct wl_output *output,
+ uint32_t flags,
+ int width,
+ int height,
+ int refresh)
+{
+ SDL_VideoDisplay *display = data;
+ SDL_DisplayMode mode;
+
+ SDL_zero(mode);
+ mode.format = SDL_PIXELFORMAT_RGB888;
+ mode.w = width;
+ mode.h = height;
+ mode.refresh_rate = refresh / 1000; // mHz to Hz
+ mode.driverdata = display->driverdata;
+ SDL_AddDisplayMode(display, &mode);
+
+ if (flags & WL_OUTPUT_MODE_CURRENT) {
+ display->current_mode = mode;
+ display->desktop_mode = mode;
+ }
+}
+
+static void
+display_handle_done(void *data,
+ struct wl_output *output)
+{
+ SDL_VideoDisplay *display = data;
+ SDL_AddVideoDisplay(display);
+ SDL_free(display->name);
+ SDL_free(display);
+}
+
+static void
+display_handle_scale(void *data,
+ struct wl_output *output,
+ int32_t factor)
+{
+ // TODO: do HiDPI stuff.
+}
+
+static const struct wl_output_listener output_listener = {
+ display_handle_geometry,
+ display_handle_mode,
+ display_handle_done,
+ display_handle_scale
+};
+
+static void
+Wayland_add_display(SDL_VideoData *d, uint32_t id)
+{
+ struct wl_output *output;
+ SDL_VideoDisplay *display = SDL_malloc(sizeof *display);
+ if (!display) {
+ SDL_OutOfMemory();
+ return;
+ }
+ SDL_zero(*display);
+
+ output = wl_registry_bind(d->registry, id, &wl_output_interface, 2);
+ if (!output) {
+ SDL_SetError("Failed to retrieve output.");
+ SDL_free(display);
+ return;
+ }
+
+ wl_output_add_listener(output, &output_listener, display);
+}
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+static void
+windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
+ int32_t show_is_fullscreen)
+{
+}
+
+static void
+windowmanager_quit(void *data, struct qt_windowmanager *qt_windowmanager)
+{
+ SDL_SendQuit();
+}
+
+static const struct qt_windowmanager_listener windowmanager_listener = {
+ windowmanager_hints,
+ windowmanager_quit,
+};
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+
+static void
+handle_ping_zxdg_shell(void *data, struct zxdg_shell_v6 *zxdg, uint32_t serial)
+{
+ zxdg_shell_v6_pong(zxdg, serial);
+}
+
+static const struct zxdg_shell_v6_listener shell_listener_zxdg = {
+ handle_ping_zxdg_shell
+};
+
+
+static void
+handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial)
+{
+ xdg_wm_base_pong(xdg, serial);
+}
+
+static const struct xdg_wm_base_listener shell_listener_xdg = {
+ handle_ping_xdg_wm_base
+};
+
+
+static void
+display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
+ const char *interface, uint32_t version)
+{
+ SDL_VideoData *d = data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "wl_output") == 0) {
+ Wayland_add_display(d, id);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ Wayland_display_add_input(d, id);
+ } else if (strcmp(interface, "xdg_wm_base") == 0) {
+ d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1);
+ xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
+ } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
+ d->shell.zxdg = wl_registry_bind(d->registry, id, &zxdg_shell_v6_interface, 1);
+ zxdg_shell_v6_add_listener(d->shell.zxdg, &shell_listener_zxdg, NULL);
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
+ d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
+ } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
+ Wayland_display_add_relative_pointer_manager(d, id);
+ } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
+ Wayland_display_add_pointer_constraints(d, id);
+ } else if (strcmp(interface, "wl_data_device_manager") == 0) {
+ d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, 3);
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ } else if (strcmp(interface, "qt_touch_extension") == 0) {
+ Wayland_touch_create(d, id);
+ } else if (strcmp(interface, "qt_surface_extension") == 0) {
+ d->surface_extension = wl_registry_bind(registry, id,
+ &qt_surface_extension_interface, 1);
+ } else if (strcmp(interface, "qt_windowmanager") == 0) {
+ d->windowmanager = wl_registry_bind(registry, id,
+ &qt_windowmanager_interface, 1);
+ qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d);
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+ }
+}
+
+static const struct wl_registry_listener registry_listener = {
+ display_handle_global,
+ NULL, /* global_remove */
+};
+
+int
+Wayland_VideoInit(_THIS)
+{
+ SDL_VideoData *data = SDL_malloc(sizeof *data);
+ if (data == NULL)
+ return SDL_OutOfMemory();
+ memset(data, 0, sizeof *data);
+
+ _this->driverdata = data;
+
+ data->xkb_context = WAYLAND_xkb_context_new(0);
+ if (!data->xkb_context) {
+ return SDL_SetError("Failed to create XKB context");
+ }
+
+ data->display = WAYLAND_wl_display_connect(NULL);
+ if (data->display == NULL) {
+ return SDL_SetError("Failed to connect to a Wayland display");
+ }
+
+ data->registry = wl_display_get_registry(data->display);
+ if (data->registry == NULL) {
+ return SDL_SetError("Failed to get the Wayland registry");
+ }
+
+ wl_registry_add_listener(data->registry, &registry_listener, data);
+
+ // First roundtrip to receive all registry objects.
+ WAYLAND_wl_display_roundtrip(data->display);
+
+ // Second roundtrip to receive all output events.
+ WAYLAND_wl_display_roundtrip(data->display);
+
+ Wayland_InitMouse();
+
+ /* Get the surface class name, usually the name of the application */
+ data->classname = get_classname();
+
+ WAYLAND_wl_display_flush(data->display);
+
+ return 0;
+}
+
+static void
+Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display)
+{
+ // Nothing to do here, everything was already done in the wl_output
+ // callbacks.
+}
+
+static int
+Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
+{
+ return SDL_Unsupported();
+}
+
+void
+Wayland_VideoQuit(_THIS)
+{
+ SDL_VideoData *data = _this->driverdata;
+ int i, j;
+
+ Wayland_FiniMouse ();
+
+ for (i = 0; i < _this->num_displays; ++i) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+ wl_output_destroy(display->driverdata);
+ display->driverdata = NULL;
+
+ for (j = display->num_display_modes; j--;) {
+ display->display_modes[j].driverdata = NULL;
+ }
+ display->desktop_mode.driverdata = NULL;
+ }
+
+ Wayland_display_destroy_input(data);
+ Wayland_display_destroy_pointer_constraints(data);
+ Wayland_display_destroy_relative_pointer_manager(data);
+
+ if (data->xkb_context) {
+ WAYLAND_xkb_context_unref(data->xkb_context);
+ data->xkb_context = NULL;
+ }
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ if (data->windowmanager)
+ qt_windowmanager_destroy(data->windowmanager);
+
+ if (data->surface_extension)
+ qt_surface_extension_destroy(data->surface_extension);
+
+ Wayland_touch_destroy(data);
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+ if (data->shm)
+ wl_shm_destroy(data->shm);
+
+ if (data->cursor_theme)
+ WAYLAND_wl_cursor_theme_destroy(data->cursor_theme);
+
+ if (data->shell.wl)
+ wl_shell_destroy(data->shell.wl);
+
+ if (data->shell.xdg)
+ xdg_wm_base_destroy(data->shell.xdg);
+
+ if (data->shell.zxdg)
+ zxdg_shell_v6_destroy(data->shell.zxdg);
+
+ if (data->compositor)
+ wl_compositor_destroy(data->compositor);
+
+ if (data->registry)
+ wl_registry_destroy(data->registry);
+
+ if (data->display) {
+ WAYLAND_wl_display_flush(data->display);
+ WAYLAND_wl_display_disconnect(data->display);
+ }
+
+ SDL_free(data->classname);
+ SDL_free(data);
+ _this->driverdata = NULL;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.h
new file mode 100644
index 0000000..c16c0bd
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvideo.h
@@ -0,0 +1,85 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylandvideo_h_
+#define SDL_waylandvideo_h_
+
+
+/*
+!!! FIXME: xdg_wm_base is the stable replacement for zxdg_shell_v6. While it's
+!!! FIXME: harmless to leave it here, consider deleting the obsolete codepath
+!!! FIXME: soon, since Wayland (with xdg_wm_base) will probably be mainline
+!!! FIXME: by the time people are relying on this SDL target. It's available
+!!! FIXME: in Ubuntu 18.04 (and other distros).
+*/
+
+
+#include <EGL/egl.h>
+#include "wayland-util.h"
+
+struct xkb_context;
+struct SDL_WaylandInput;
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+struct SDL_WaylandTouch;
+struct qt_surface_extension;
+struct qt_windowmanager;
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+typedef struct {
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_compositor *compositor;
+ struct wl_shm *shm;
+ struct wl_cursor_theme *cursor_theme;
+ struct wl_pointer *pointer;
+ struct {
+ struct xdg_wm_base *xdg;
+ struct zxdg_shell_v6 *zxdg;
+ struct wl_shell *wl;
+ } shell;
+ struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
+ struct zwp_pointer_constraints_v1 *pointer_constraints;
+ struct wl_data_device_manager *data_device_manager;
+
+ EGLDisplay edpy;
+ EGLContext context;
+ EGLConfig econf;
+
+ struct xkb_context *xkb_context;
+ struct SDL_WaylandInput *input;
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ struct SDL_WaylandTouch *touch;
+ struct qt_surface_extension *surface_extension;
+ struct qt_windowmanager *windowmanager;
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+ char *classname;
+
+ int relative_mouse_mode;
+} SDL_VideoData;
+
+#endif /* SDL_waylandvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.c
new file mode 100644
index 0000000..d67472c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.c
@@ -0,0 +1,176 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WAYLAND
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_waylandvulkan.h"
+#include "SDL_syswm.h"
+
+int Wayland_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 i, extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasWaylandSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+ if(_this->vulkan_config.loader_handle)
+ return SDL_SetError("Vulkan already loaded");
+
+ /* Load the Vulkan loader library */
+ if(!path)
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ if(!path)
+ path = "libvulkan.so.1";
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if(!_this->vulkan_config.loader_handle)
+ return -1;
+ SDL_strlcpy(_this->vulkan_config.loader_path, path,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+ if(!vkGetInstanceProcAddr)
+ goto fail;
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+ if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
+ goto fail;
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+ if(!extensions)
+ goto fail;
+ for(i = 0; i < extensionCount; i++)
+ {
+ if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasSurfaceExtension = SDL_TRUE;
+ else if(SDL_strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasWaylandSurfaceExtension = SDL_TRUE;
+ }
+ SDL_free(extensions);
+ if(!hasSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ }
+ else if(!hasWaylandSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+ return 0;
+
+fail:
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void Wayland_Vulkan_UnloadLibrary(_THIS)
+{
+ if(_this->vulkan_config.loader_handle)
+ {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForWayland[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+ };
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForWayland),
+ extensionsForWayland);
+}
+
+SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR =
+ (PFN_vkCreateWaylandSurfaceKHR)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateWaylandSurfaceKHR");
+ VkWaylandSurfaceCreateInfoKHR createInfo;
+ VkResult result;
+
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if(!vkCreateWaylandSurfaceKHR)
+ {
+ SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ SDL_zero(createInfo);
+ createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.display = windowData->waylandData->display;
+ createInfo.surface = windowData->surface;
+ result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
+ NULL, surface);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+#endif
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.h
new file mode 100644
index 0000000..5ad3a46
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandvulkan.h
@@ -0,0 +1,52 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylandvulkan_h_
+#define SDL_waylandvulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WAYLAND
+
+int Wayland_Vulkan_LoadLibrary(_THIS, const char *path);
+void Wayland_Vulkan_UnloadLibrary(_THIS);
+SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+#endif
+
+#endif /* SDL_waylandvulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.c b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.c
new file mode 100644
index 0000000..aa72991
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.c
@@ -0,0 +1,676 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_windowevents_c.h"
+#include "../SDL_egl_c.h"
+#include "SDL_waylandevents_c.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandtouch.h"
+#include "SDL_waylanddyn.h"
+#include "SDL_hints.h"
+
+#include "xdg-shell-client-protocol.h"
+#include "xdg-shell-unstable-v6-client-protocol.h"
+
+/* On modern desktops, we probably will use the xdg-shell protocol instead
+ of wl_shell, but wl_shell might be useful on older Wayland installs that
+ don't have the newer protocol, or embedded things that don't have a full
+ window manager. */
+
+static void
+handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t serial)
+{
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ SDL_WindowData *wind = (SDL_WindowData *)data;
+ SDL_Window *window = wind->sdlwindow;
+ struct wl_region *region;
+
+ /* wl_shell_surface spec states that this is a suggestion.
+ Ignore if less than or greater than max/min size. */
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if ((window->flags & SDL_WINDOW_RESIZABLE)) {
+ if (window->max_w > 0) {
+ width = SDL_min(width, window->max_w);
+ }
+ width = SDL_max(width, window->min_w);
+
+ if (window->max_h > 0) {
+ height = SDL_min(height, window->max_h);
+ }
+ height = SDL_max(height, window->min_h);
+ } else {
+ return;
+ }
+ }
+
+ WAYLAND_wl_egl_window_resize(wind->egl_window, width, height, 0, 0);
+ region = wl_compositor_create_region(wind->waylandData->compositor);
+ wl_region_add(region, 0, 0, width, height);
+ wl_surface_set_opaque_region(wind->surface, region);
+ wl_region_destroy(region);
+
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
+ window->w = width;
+ window->h = height;
+}
+
+static void
+handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface)
+{
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener_wl = {
+ handle_ping_wl_shell_surface,
+ handle_configure_wl_shell_surface,
+ handle_popup_done_wl_shell_surface
+};
+
+
+
+
+static void
+handle_configure_zxdg_shell_surface(void *data, struct zxdg_surface_v6 *zxdg, uint32_t serial)
+{
+ SDL_WindowData *wind = (SDL_WindowData *)data;
+ SDL_Window *window = wind->sdlwindow;
+ struct wl_region *region;
+
+ wind->shell_surface.zxdg.initial_configure_seen = SDL_TRUE;
+
+ WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
+
+ region = wl_compositor_create_region(wind->waylandData->compositor);
+ wl_region_add(region, 0, 0, window->w, window->h);
+ wl_surface_set_opaque_region(wind->surface, region);
+ wl_region_destroy(region);
+ zxdg_surface_v6_ack_configure(zxdg, serial);
+}
+
+static const struct zxdg_surface_v6_listener shell_surface_listener_zxdg = {
+ handle_configure_zxdg_shell_surface
+};
+
+
+static void
+handle_configure_zxdg_toplevel(void *data,
+ struct zxdg_toplevel_v6 *zxdg_toplevel_v6,
+ int32_t width,
+ int32_t height,
+ struct wl_array *states)
+{
+ SDL_WindowData *wind = (SDL_WindowData *)data;
+ SDL_Window *window = wind->sdlwindow;
+
+ /* wl_shell_surface spec states that this is a suggestion.
+ Ignore if less than or greater than max/min size. */
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if ((window->flags & SDL_WINDOW_RESIZABLE)) {
+ if (window->max_w > 0) {
+ width = SDL_min(width, window->max_w);
+ }
+ width = SDL_max(width, window->min_w);
+
+ if (window->max_h > 0) {
+ height = SDL_min(height, window->max_h);
+ }
+ height = SDL_max(height, window->min_h);
+ } else {
+ return;
+ }
+ }
+
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
+ window->w = width;
+ window->h = height;
+}
+
+static void
+handle_close_zxdg_toplevel(void *data, struct zxdg_toplevel_v6 *zxdg_toplevel_v6)
+{
+ SDL_WindowData *window = (SDL_WindowData *)data;
+ SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
+}
+
+static const struct zxdg_toplevel_v6_listener toplevel_listener_zxdg = {
+ handle_configure_zxdg_toplevel,
+ handle_close_zxdg_toplevel
+};
+
+
+
+static void
+handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
+{
+ SDL_WindowData *wind = (SDL_WindowData *)data;
+ SDL_Window *window = wind->sdlwindow;
+ struct wl_region *region;
+
+ wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE;
+
+ WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
+
+ region = wl_compositor_create_region(wind->waylandData->compositor);
+ wl_region_add(region, 0, 0, window->w, window->h);
+ wl_surface_set_opaque_region(wind->surface, region);
+ wl_region_destroy(region);
+ xdg_surface_ack_configure(xdg, serial);
+}
+
+static const struct xdg_surface_listener shell_surface_listener_xdg = {
+ handle_configure_xdg_shell_surface
+};
+
+
+static void
+handle_configure_xdg_toplevel(void *data,
+ struct xdg_toplevel *xdg_toplevel,
+ int32_t width,
+ int32_t height,
+ struct wl_array *states)
+{
+ SDL_WindowData *wind = (SDL_WindowData *)data;
+ SDL_Window *window = wind->sdlwindow;
+
+ /* wl_shell_surface spec states that this is a suggestion.
+ Ignore if less than or greater than max/min size. */
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if ((window->flags & SDL_WINDOW_RESIZABLE)) {
+ if (window->max_w > 0) {
+ width = SDL_min(width, window->max_w);
+ }
+ width = SDL_max(width, window->min_w);
+
+ if (window->max_h > 0) {
+ height = SDL_min(height, window->max_h);
+ }
+ height = SDL_max(height, window->min_h);
+ } else {
+ return;
+ }
+ }
+
+ if (width == window->w && height == window->h) {
+ return;
+ }
+
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
+ window->w = width;
+ window->h = height;
+}
+
+static void
+handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel)
+{
+ SDL_WindowData *window = (SDL_WindowData *)data;
+ SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
+}
+
+static const struct xdg_toplevel_listener toplevel_listener_xdg = {
+ handle_configure_xdg_toplevel,
+ handle_close_xdg_toplevel
+};
+
+
+
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+static void
+handle_onscreen_visibility(void *data,
+ struct qt_extended_surface *qt_extended_surface, int32_t visible)
+{
+}
+
+static void
+handle_set_generic_property(void *data,
+ struct qt_extended_surface *qt_extended_surface, const char *name,
+ struct wl_array *value)
+{
+}
+
+static void
+handle_close(void *data, struct qt_extended_surface *qt_extended_surface)
+{
+ SDL_WindowData *window = (SDL_WindowData *)data;
+ SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
+}
+
+static const struct qt_extended_surface_listener extended_surface_listener = {
+ handle_onscreen_visibility,
+ handle_set_generic_property,
+ handle_close,
+};
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+SDL_bool
+Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
+ (((Uint32) info->version.minor) * 10000) +
+ (((Uint32) info->version.patch)));
+
+ /* Before 2.0.6, it was possible to build an SDL with Wayland support
+ (SDL_SysWMinfo will be large enough to hold Wayland info), but build
+ your app against SDL headers that didn't have Wayland support
+ (SDL_SysWMinfo could be smaller than Wayland needs. This would lead
+ to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
+ overflow memory on the stack or heap. To protect against this, we've
+ padded out the struct unconditionally in the headers and Wayland will
+ just return an error for older apps using this function. Those apps
+ will need to be recompiled against newer headers or not use Wayland,
+ maybe by forcing SDL_VIDEODRIVER=x11. */
+ if (version < 2000006) {
+ info->subsystem = SDL_SYSWM_UNKNOWN;
+ SDL_SetError("Version must be 2.0.6 or newer");
+ return SDL_FALSE;
+ }
+
+ info->info.wl.display = data->waylandData->display;
+ info->info.wl.surface = data->surface;
+ info->info.wl.shell_surface = data->shell_surface.wl;
+ info->subsystem = SDL_SYSWM_WAYLAND;
+
+ return SDL_TRUE;
+}
+
+int
+Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
+{
+ return 0; /* just succeed, the real work is done elsewhere. */
+}
+
+static void
+SetFullscreen(_THIS, SDL_Window * window, struct wl_output *output)
+{
+ const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *wind = window->driverdata;
+
+ if (viddata->shell.xdg) {
+ if (output) {
+ xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output);
+ } else {
+ xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
+ }
+ } else if (viddata->shell.zxdg) {
+ if (output) {
+ zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output);
+ } else {
+ zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel);
+ }
+ } else {
+ if (output) {
+ wl_shell_surface_set_fullscreen(wind->shell_surface.wl,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0, output);
+ } else {
+ wl_shell_surface_set_toplevel(wind->shell_surface.wl);
+ }
+ }
+
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+}
+
+void Wayland_ShowWindow(_THIS, SDL_Window *window)
+{
+ struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata;
+ SetFullscreen(_this, window, (window->flags & SDL_WINDOW_FULLSCREEN) ? output : NULL);
+}
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+static void SDLCALL
+QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
+ const char *oldValue, const char *newValue)
+{
+ struct qt_extended_surface *qt_extended_surface = userdata;
+
+ if (name == NULL) {
+ return;
+ }
+
+ if (strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) {
+ int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
+
+ if (newValue != NULL) {
+ if (strcmp(newValue, "portrait") == 0) {
+ orientation = QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION;
+ } else if (strcmp(newValue, "landscape") == 0) {
+ orientation = QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION;
+ } else if (strcmp(newValue, "inverted-portrait") == 0) {
+ orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION;
+ } else if (strcmp(newValue, "inverted-landscape") == 0) {
+ orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION;
+ }
+ }
+
+ qt_extended_surface_set_content_orientation(qt_extended_surface, orientation);
+ } else if (strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) {
+ uint32_t flags = 0;
+
+ if (newValue != NULL) {
+ char *tmp = strdup(newValue);
+ char *saveptr = NULL;
+
+ char *flag = strtok_r(tmp, " ", &saveptr);
+ while (flag) {
+ if (strcmp(flag, "OverridesSystemGestures") == 0) {
+ flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES;
+ } else if (strcmp(flag, "StaysOnTop") == 0) {
+ flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP;
+ } else if (strcmp(flag, "BypassWindowManager") == 0) {
+ // See https://github.com/qtproject/qtwayland/commit/fb4267103d
+ flags |= 4 /* QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER */;
+ }
+
+ flag = strtok_r(NULL, " ", &saveptr);
+ }
+
+ free(tmp);
+ }
+
+ qt_extended_surface_set_window_flags(qt_extended_surface, flags);
+ }
+}
+
+static void QtExtendedSurface_Subscribe(struct qt_extended_surface *surface, const char *name)
+{
+ SDL_AddHintCallback(name, QtExtendedSurface_OnHintChanged, surface);
+}
+
+static void QtExtendedSurface_Unsubscribe(struct qt_extended_surface *surface, const char *name)
+{
+ SDL_DelHintCallback(name, QtExtendedSurface_OnHintChanged, surface);
+}
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+void
+Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
+ SDL_VideoDisplay * _display, SDL_bool fullscreen)
+{
+ struct wl_output *output = (struct wl_output *) _display->driverdata;
+ SetFullscreen(_this, window, fullscreen ? output : NULL);
+}
+
+void
+Wayland_RestoreWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wind = window->driverdata;
+ const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
+
+ if (viddata->shell.xdg) {
+ } else if (viddata->shell.zxdg) {
+ } else {
+ wl_shell_surface_set_toplevel(wind->shell_surface.wl);
+ }
+
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+}
+
+void
+Wayland_MaximizeWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wind = window->driverdata;
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+
+ if (viddata->shell.xdg) {
+ xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel);
+ } else if (viddata->shell.zxdg) {
+ zxdg_toplevel_v6_set_maximized(wind->shell_surface.zxdg.roleobj.toplevel);
+ } else {
+ wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL);
+ }
+
+ WAYLAND_wl_display_flush( viddata->display );
+}
+
+int Wayland_CreateWindow(_THIS, SDL_Window *window)
+{
+ SDL_WindowData *data;
+ SDL_VideoData *c;
+ struct wl_region *region;
+
+ data = calloc(1, sizeof *data);
+ if (data == NULL)
+ return SDL_OutOfMemory();
+
+ c = _this->driverdata;
+ window->driverdata = data;
+
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ SDL_GL_LoadLibrary(NULL);
+ window->flags |= SDL_WINDOW_OPENGL;
+ }
+
+ if (window->x == SDL_WINDOWPOS_UNDEFINED) {
+ window->x = 0;
+ }
+ if (window->y == SDL_WINDOWPOS_UNDEFINED) {
+ window->y = 0;
+ }
+
+ data->waylandData = c;
+ data->sdlwindow = window;
+
+ data->surface =
+ wl_compositor_create_surface(c->compositor);
+ wl_surface_set_user_data(data->surface, data);
+
+ if (c->shell.xdg) {
+ data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface);
+ /* !!! FIXME: add popup role */
+ data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
+ xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
+ xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
+ } else if (c->shell.zxdg) {
+ data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface);
+ /* !!! FIXME: add popup role */
+ data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface);
+ zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data);
+ zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname);
+ } else {
+ data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface);
+ wl_shell_surface_set_class(data->shell_surface.wl, c->classname);
+ }
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ if (c->surface_extension) {
+ data->extended_surface = qt_surface_extension_get_extended_surface(
+ c->surface_extension, data->surface);
+
+ QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION);
+ QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS);
+ }
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+ data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
+ window->w, window->h);
+
+ /* Create the GLES window surface */
+ data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
+
+ if (data->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("failed to create a window surface");
+ }
+
+ if (c->shell.xdg) {
+ if (data->shell_surface.xdg.surface) {
+ xdg_surface_set_user_data(data->shell_surface.xdg.surface, data);
+ xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data);
+ }
+ } else if (c->shell.zxdg) {
+ if (data->shell_surface.zxdg.surface) {
+ zxdg_surface_v6_set_user_data(data->shell_surface.zxdg.surface, data);
+ zxdg_surface_v6_add_listener(data->shell_surface.zxdg.surface, &shell_surface_listener_zxdg, data);
+ }
+ } else {
+ if (data->shell_surface.wl) {
+ wl_shell_surface_set_user_data(data->shell_surface.wl, data);
+ wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data);
+ }
+ }
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ if (data->extended_surface) {
+ qt_extended_surface_set_user_data(data->extended_surface, data);
+ qt_extended_surface_add_listener(data->extended_surface,
+ &extended_surface_listener, data);
+ }
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+
+ region = wl_compositor_create_region(c->compositor);
+ wl_region_add(region, 0, 0, window->w, window->h);
+ wl_surface_set_opaque_region(data->surface, region);
+ wl_region_destroy(region);
+
+ if (c->relative_mouse_mode) {
+ Wayland_input_lock_pointer(c->input);
+ }
+
+ wl_surface_commit(data->surface);
+ WAYLAND_wl_display_flush(c->display);
+
+ /* we have to wait until the surface gets a "configure" event, or
+ use of this surface will fail. This is a new rule for xdg_shell. */
+ if (c->shell.xdg) {
+ if (data->shell_surface.xdg.surface) {
+ while (!data->shell_surface.xdg.initial_configure_seen) {
+ WAYLAND_wl_display_flush(c->display);
+ WAYLAND_wl_display_dispatch(c->display);
+ }
+ }
+ } else if (c->shell.zxdg) {
+ if (data->shell_surface.zxdg.surface) {
+ while (!data->shell_surface.zxdg.initial_configure_seen) {
+ WAYLAND_wl_display_flush(c->display);
+ WAYLAND_wl_display_dispatch(c->display);
+ }
+ }
+ }
+
+ return 0;
+}
+
+void Wayland_SetWindowSize(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *data = _this->driverdata;
+ SDL_WindowData *wind = window->driverdata;
+ struct wl_region *region;
+
+ WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
+
+ region =wl_compositor_create_region(data->compositor);
+ wl_region_add(region, 0, 0, window->w, window->h);
+ wl_surface_set_opaque_region(wind->surface, region);
+ wl_region_destroy(region);
+}
+
+void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wind = window->driverdata;
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+
+ if (window->title != NULL) {
+ if (viddata->shell.xdg) {
+ xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, window->title);
+ } else if (viddata->shell.zxdg) {
+ zxdg_toplevel_v6_set_title(wind->shell_surface.zxdg.roleobj.toplevel, window->title);
+ } else {
+ wl_shell_surface_set_title(wind->shell_surface.wl, window->title);
+ }
+ }
+
+ WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+}
+
+void Wayland_DestroyWindow(_THIS, SDL_Window *window)
+{
+ SDL_VideoData *data = _this->driverdata;
+ SDL_WindowData *wind = window->driverdata;
+
+ if (data) {
+ SDL_EGL_DestroySurface(_this, wind->egl_surface);
+ WAYLAND_wl_egl_window_destroy(wind->egl_window);
+
+ if (data->shell.xdg) {
+ if (wind->shell_surface.xdg.roleobj.toplevel) {
+ xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel);
+ }
+ if (wind->shell_surface.zxdg.surface) {
+ xdg_surface_destroy(wind->shell_surface.xdg.surface);
+ }
+ } else if (data->shell.zxdg) {
+ if (wind->shell_surface.zxdg.roleobj.toplevel) {
+ zxdg_toplevel_v6_destroy(wind->shell_surface.zxdg.roleobj.toplevel);
+ }
+ if (wind->shell_surface.zxdg.surface) {
+ zxdg_surface_v6_destroy(wind->shell_surface.zxdg.surface);
+ }
+ } else {
+ if (wind->shell_surface.wl) {
+ wl_shell_surface_destroy(wind->shell_surface.wl);
+ }
+ }
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ if (wind->extended_surface) {
+ QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION);
+ QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS);
+ qt_extended_surface_destroy(wind->extended_surface);
+ }
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+ wl_surface_destroy(wind->surface);
+
+ SDL_free(wind);
+ WAYLAND_wl_display_flush(data->display);
+ }
+ window->driverdata = NULL;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.h b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.h
new file mode 100644
index 0000000..69b9889
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/wayland/SDL_waylandwindow.h
@@ -0,0 +1,88 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_waylandwindow_h_
+#define SDL_waylandwindow_h_
+
+#include "../SDL_sysvideo.h"
+#include "SDL_syswm.h"
+
+#include "SDL_waylandvideo.h"
+
+struct SDL_WaylandInput;
+
+typedef struct {
+ struct zxdg_surface_v6 *surface;
+ union {
+ struct zxdg_toplevel_v6 *toplevel;
+ struct zxdg_popup_v6 *popup;
+ } roleobj;
+ SDL_bool initial_configure_seen;
+} SDL_zxdg_shell_surface;
+
+typedef struct {
+ struct xdg_surface *surface;
+ union {
+ struct xdg_toplevel *toplevel;
+ struct xdg_popup *popup;
+ } roleobj;
+ SDL_bool initial_configure_seen;
+} SDL_xdg_shell_surface;
+
+typedef struct {
+ SDL_Window *sdlwindow;
+ SDL_VideoData *waylandData;
+ struct wl_surface *surface;
+ union {
+ SDL_xdg_shell_surface xdg;
+ SDL_zxdg_shell_surface zxdg;
+ struct wl_shell_surface *wl;
+ } shell_surface;
+ struct wl_egl_window *egl_window;
+ struct SDL_WaylandInput *keyboard_device;
+ EGLSurface egl_surface;
+ struct zwp_locked_pointer_v1 *locked_pointer;
+
+#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
+ struct qt_extended_surface *extended_surface;
+#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
+} SDL_WindowData;
+
+extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
+extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
+ SDL_VideoDisplay * _display,
+ SDL_bool fullscreen);
+extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window);
+extern void Wayland_RestoreWindow(_THIS, SDL_Window * window);
+extern int Wayland_CreateWindow(_THIS, SDL_Window *window);
+extern void Wayland_SetWindowSize(_THIS, SDL_Window * window);
+extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window);
+extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
+
+extern SDL_bool
+Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
+extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
+
+#endif /* SDL_waylandwindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_msctf.h b/source/3rd-party/SDL2/src/video/windows/SDL_msctf.h
new file mode 100644
index 0000000..53cec3d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_msctf.h
@@ -0,0 +1,242 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_msctf_h_
+#define SDL_msctf_h_
+
+#include <unknwn.h>
+
+#define TF_INVALID_COOKIE (0xffffffff)
+#define TF_IPSINK_FLAG_ACTIVE 0x0001
+#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004
+
+typedef struct ITfThreadMgr ITfThreadMgr;
+typedef struct ITfDocumentMgr ITfDocumentMgr;
+typedef struct ITfClientId ITfClientId;
+
+typedef struct IEnumTfDocumentMgrs IEnumTfDocumentMgrs;
+typedef struct IEnumTfFunctionProviders IEnumTfFunctionProviders;
+typedef struct ITfFunctionProvider ITfFunctionProvider;
+typedef struct ITfCompartmentMgr ITfCompartmentMgr;
+typedef struct ITfContext ITfContext;
+typedef struct IEnumTfContexts IEnumTfContexts;
+typedef struct ITfUIElementSink ITfUIElementSink;
+typedef struct ITfUIElement ITfUIElement;
+typedef struct ITfUIElementMgr ITfUIElementMgr;
+typedef struct IEnumTfUIElements IEnumTfUIElements;
+typedef struct ITfThreadMgrEx ITfThreadMgrEx;
+typedef struct ITfCandidateListUIElement ITfCandidateListUIElement;
+typedef struct ITfReadingInformationUIElement ITfReadingInformationUIElement;
+typedef struct ITfInputProcessorProfileActivationSink ITfInputProcessorProfileActivationSink;
+typedef struct ITfSource ITfSource;
+
+typedef DWORD TfClientId;
+typedef DWORD TfEditCookie;
+
+typedef struct ITfThreadMgrVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgr *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgr *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgr *);
+ HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgr *, TfClientId *);
+ HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgr *);
+ HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgr *);
+ HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgr *, IEnumTfDocumentMgrs **);
+ HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgr *, ITfDocumentMgr **);
+ HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgr *, ITfDocumentMgr *);
+ HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgr *, HWND, ITfDocumentMgr *, ITfDocumentMgr **);
+ HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgr *, BOOL *);
+ HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgr *, REFCLSID, ITfFunctionProvider **);
+ HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgr *, IEnumTfFunctionProviders **);
+ HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgr *, ITfCompartmentMgr **);
+} ITfThreadMgrVtbl;
+
+struct ITfThreadMgr
+{
+ const struct ITfThreadMgrVtbl *lpVtbl;
+};
+
+typedef struct ITfThreadMgrExVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgrEx *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgrEx *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgrEx *);
+ HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgrEx *, TfClientId *);
+ HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgrEx *);
+ HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgrEx *, ITfDocumentMgr **);
+ HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgrEx *, IEnumTfDocumentMgrs **);
+ HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgrEx *, ITfDocumentMgr **);
+ HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgrEx *, ITfDocumentMgr *);
+ HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgrEx *, ITfDocumentMgr *, ITfDocumentMgr **);
+ HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgrEx *, BOOL *);
+ HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgrEx *, REFCLSID, ITfFunctionProvider **);
+ HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgrEx *, IEnumTfFunctionProviders **);
+ HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgrEx *, ITfCompartmentMgr **);
+ HRESULT (STDMETHODCALLTYPE *ActivateEx)(ITfThreadMgrEx *, TfClientId *, DWORD);
+ HRESULT (STDMETHODCALLTYPE *GetActiveFlags)(ITfThreadMgrEx *, DWORD *);
+} ITfThreadMgrExVtbl;
+
+struct ITfThreadMgrEx
+{
+ const struct ITfThreadMgrExVtbl *lpVtbl;
+};
+
+typedef struct ITfDocumentMgrVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfDocumentMgr *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfDocumentMgr *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfDocumentMgr *);
+ HRESULT (STDMETHODCALLTYPE *CreateContext)(ITfDocumentMgr *, TfClientId, DWORD, IUnknown *, ITfContext **, TfEditCookie *);
+ HRESULT (STDMETHODCALLTYPE *Push)(ITfDocumentMgr *, ITfContext *);
+ HRESULT (STDMETHODCALLTYPE *Pop)(ITfDocumentMgr *);
+ HRESULT (STDMETHODCALLTYPE *GetTop)(ITfDocumentMgr *, ITfContext **);
+ HRESULT (STDMETHODCALLTYPE *GetBase)(ITfDocumentMgr *, ITfContext **);
+ HRESULT (STDMETHODCALLTYPE *EnumContexts)(ITfDocumentMgr *, IEnumTfContexts **);
+} ITfDocumentMgrVtbl;
+
+struct ITfDocumentMgr
+{
+ const struct ITfDocumentMgrVtbl *lpVtbl;
+};
+
+typedef struct ITfUIElementSinkVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementSink *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementSink *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementSink *);
+ HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementSink *, DWORD, BOOL *);
+ HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementSink *, DWORD);
+ HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementSink *, DWORD);
+} ITfUIElementSinkVtbl;
+
+struct ITfUIElementSink
+{
+ const struct ITfUIElementSinkVtbl *lpVtbl;
+};
+
+typedef struct ITfUIElementMgrVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementMgr *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementMgr *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementMgr *);
+ HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementMgr *, ITfUIElement *, BOOL *, DWORD *);
+ HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementMgr *, DWORD);
+ HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementMgr *, DWORD);
+ HRESULT (STDMETHODCALLTYPE *GetUIElement)(ITfUIElementMgr *, DWORD, ITfUIElement **);
+ HRESULT (STDMETHODCALLTYPE *EnumUIElements)(ITfUIElementMgr *, IEnumTfUIElements **);
+} ITfUIElementMgrVtbl;
+
+struct ITfUIElementMgr
+{
+ const struct ITfUIElementMgrVtbl *lpVtbl;
+};
+
+typedef struct ITfCandidateListUIElementVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfCandidateListUIElement *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfCandidateListUIElement *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfCandidateListUIElement *);
+ HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfCandidateListUIElement *, BSTR *);
+ HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfCandidateListUIElement *, GUID *);
+ HRESULT (STDMETHODCALLTYPE *Show)(ITfCandidateListUIElement *, BOOL);
+ HRESULT (STDMETHODCALLTYPE *IsShown)(ITfCandidateListUIElement *, BOOL *);
+ HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfCandidateListUIElement *, DWORD *);
+ HRESULT (STDMETHODCALLTYPE *GetDocumentMgr)(ITfCandidateListUIElement *, ITfDocumentMgr **);
+ HRESULT (STDMETHODCALLTYPE *GetCount)(ITfCandidateListUIElement *, UINT *);
+ HRESULT (STDMETHODCALLTYPE *GetSelection)(ITfCandidateListUIElement *, UINT *);
+ HRESULT (STDMETHODCALLTYPE *GetString)(ITfCandidateListUIElement *, UINT, BSTR *);
+ HRESULT (STDMETHODCALLTYPE *GetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT, UINT *);
+ HRESULT (STDMETHODCALLTYPE *SetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT);
+ HRESULT (STDMETHODCALLTYPE *GetCurrentPage)(ITfCandidateListUIElement *, UINT *);
+} ITfCandidateListUIElementVtbl;
+
+struct ITfCandidateListUIElement
+{
+ const struct ITfCandidateListUIElementVtbl *lpVtbl;
+};
+
+typedef struct ITfReadingInformationUIElementVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfReadingInformationUIElement *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfReadingInformationUIElement *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfReadingInformationUIElement *);
+ HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfReadingInformationUIElement *, BSTR *);
+ HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfReadingInformationUIElement *, GUID *);
+ HRESULT (STDMETHODCALLTYPE *Show)(ITfReadingInformationUIElement *, BOOL);
+ HRESULT (STDMETHODCALLTYPE *IsShown)(ITfReadingInformationUIElement *, BOOL *);
+ HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfReadingInformationUIElement *, DWORD *);
+ HRESULT (STDMETHODCALLTYPE *GetContext)(ITfReadingInformationUIElement *, ITfContext **);
+ HRESULT (STDMETHODCALLTYPE *GetString)(ITfReadingInformationUIElement *, BSTR *);
+ HRESULT (STDMETHODCALLTYPE *GetMaxReadingStringLength)(ITfReadingInformationUIElement *, UINT *);
+ HRESULT (STDMETHODCALLTYPE *GetErrorIndex)(ITfReadingInformationUIElement *, UINT *);
+ HRESULT (STDMETHODCALLTYPE *IsVerticalOrderPreferred)(ITfReadingInformationUIElement *, BOOL *);
+} ITfReadingInformationUIElementVtbl;
+
+struct ITfReadingInformationUIElement
+{
+ const struct ITfReadingInformationUIElementVtbl *lpVtbl;
+};
+
+typedef struct ITfUIElementVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElement *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElement *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfUIElement *);
+ HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfUIElement *, BSTR *);
+ HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfUIElement *, GUID *);
+ HRESULT (STDMETHODCALLTYPE *Show)(ITfUIElement *, BOOL);
+ HRESULT (STDMETHODCALLTYPE *IsShown)(ITfUIElement *, BOOL *);
+} ITfUIElementVtbl;
+
+struct ITfUIElement
+{
+ const struct ITfUIElementVtbl *lpVtbl;
+};
+
+typedef struct ITfInputProcessorProfileActivationSinkVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfInputProcessorProfileActivationSink *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfInputProcessorProfileActivationSink *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfInputProcessorProfileActivationSink *);
+ HRESULT (STDMETHODCALLTYPE *OnActivated)(ITfInputProcessorProfileActivationSink *, DWORD, LANGID, REFCLSID, REFGUID, REFGUID, HKL, DWORD);
+
+} ITfInputProcessorProfileActivationSinkVtbl;
+
+struct ITfInputProcessorProfileActivationSink
+{
+ const struct ITfInputProcessorProfileActivationSinkVtbl *lpVtbl;
+};
+
+typedef struct ITfSourceVtbl
+{
+ HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfSource *, REFIID, void **);
+ ULONG (STDMETHODCALLTYPE *AddRef)(ITfSource *);
+ ULONG (STDMETHODCALLTYPE *Release)(ITfSource *);
+ HRESULT (STDMETHODCALLTYPE *AdviseSink)(ITfSource *, REFIID, IUnknown *, DWORD *);
+ HRESULT (STDMETHODCALLTYPE *UnadviseSink)(ITfSource *, DWORD);
+} ITfSourceVtbl;
+
+struct ITfSource
+{
+ const struct ITfSourceVtbl *lpVtbl;
+};
+
+#endif /* SDL_msctf_h_ */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_vkeys.h b/source/3rd-party/SDL2/src/video/windows/SDL_vkeys.h
new file mode 100644
index 0000000..a38e3a2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_vkeys.h
@@ -0,0 +1,76 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef VK_0
+#define VK_0 '0'
+#define VK_1 '1'
+#define VK_2 '2'
+#define VK_3 '3'
+#define VK_4 '4'
+#define VK_5 '5'
+#define VK_6 '6'
+#define VK_7 '7'
+#define VK_8 '8'
+#define VK_9 '9'
+#define VK_A 'A'
+#define VK_B 'B'
+#define VK_C 'C'
+#define VK_D 'D'
+#define VK_E 'E'
+#define VK_F 'F'
+#define VK_G 'G'
+#define VK_H 'H'
+#define VK_I 'I'
+#define VK_J 'J'
+#define VK_K 'K'
+#define VK_L 'L'
+#define VK_M 'M'
+#define VK_N 'N'
+#define VK_O 'O'
+#define VK_P 'P'
+#define VK_Q 'Q'
+#define VK_R 'R'
+#define VK_S 'S'
+#define VK_T 'T'
+#define VK_U 'U'
+#define VK_V 'V'
+#define VK_W 'W'
+#define VK_X 'X'
+#define VK_Y 'Y'
+#define VK_Z 'Z'
+#endif /* VK_0 */
+
+/* These keys haven't been defined, but were experimentally determined */
+#define VK_SEMICOLON 0xBA
+#define VK_EQUALS 0xBB
+#define VK_COMMA 0xBC
+#define VK_MINUS 0xBD
+#define VK_PERIOD 0xBE
+#define VK_SLASH 0xBF
+#define VK_GRAVE 0xC0
+#define VK_LBRACKET 0xDB
+#define VK_BACKSLASH 0xDC
+#define VK_RBRACKET 0xDD
+#define VK_APOSTROPHE 0xDE
+#define VK_BACKTICK 0xDF
+#define VK_OEM_102 0xE2
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.c
new file mode 100644
index 0000000..4e61d7a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.c
@@ -0,0 +1,160 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_windowsvideo.h"
+#include "SDL_windowswindow.h"
+#include "../../events/SDL_clipboardevents_c.h"
+
+
+#ifdef UNICODE
+#define TEXT_FORMAT CF_UNICODETEXT
+#else
+#define TEXT_FORMAT CF_TEXT
+#endif
+
+
+/* Get any application owned window handle for clipboard association */
+static HWND
+GetWindowHandle(_THIS)
+{
+ SDL_Window *window;
+
+ window = _this->windows;
+ if (window) {
+ return ((SDL_WindowData *) window->driverdata)->hwnd;
+ }
+ return NULL;
+}
+
+int
+WIN_SetClipboardText(_THIS, const char *text)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ int result = 0;
+
+ if (OpenClipboard(GetWindowHandle(_this))) {
+ HANDLE hMem;
+ LPTSTR tstr;
+ SIZE_T i, size;
+
+ /* Convert the text from UTF-8 to Windows Unicode */
+ tstr = WIN_UTF8ToString(text);
+ if (!tstr) {
+ return -1;
+ }
+
+ /* Find out the size of the data */
+ for (size = 0, i = 0; tstr[i]; ++i, ++size) {
+ if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
+ /* We're going to insert a carriage return */
+ ++size;
+ }
+ }
+ size = (size+1)*sizeof(*tstr);
+
+ /* Save the data to the clipboard */
+ hMem = GlobalAlloc(GMEM_MOVEABLE, size);
+ if (hMem) {
+ LPTSTR dst = (LPTSTR)GlobalLock(hMem);
+ if (dst) {
+ /* Copy the text over, adding carriage returns as necessary */
+ for (i = 0; tstr[i]; ++i) {
+ if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) {
+ *dst++ = '\r';
+ }
+ *dst++ = tstr[i];
+ }
+ *dst = 0;
+ GlobalUnlock(hMem);
+ }
+
+ EmptyClipboard();
+ if (!SetClipboardData(TEXT_FORMAT, hMem)) {
+ result = WIN_SetError("Couldn't set clipboard data");
+ }
+ data->clipboard_count = GetClipboardSequenceNumber();
+ }
+ SDL_free(tstr);
+
+ CloseClipboard();
+ } else {
+ result = WIN_SetError("Couldn't open clipboard");
+ }
+ return result;
+}
+
+char *
+WIN_GetClipboardText(_THIS)
+{
+ char *text;
+
+ text = NULL;
+ if (IsClipboardFormatAvailable(TEXT_FORMAT) &&
+ OpenClipboard(GetWindowHandle(_this))) {
+ HANDLE hMem;
+ LPTSTR tstr;
+
+ hMem = GetClipboardData(TEXT_FORMAT);
+ if (hMem) {
+ tstr = (LPTSTR)GlobalLock(hMem);
+ text = WIN_StringToUTF8(tstr);
+ GlobalUnlock(hMem);
+ } else {
+ WIN_SetError("Couldn't get clipboard data");
+ }
+ CloseClipboard();
+ }
+ if (!text) {
+ text = SDL_strdup("");
+ }
+ return text;
+}
+
+SDL_bool
+WIN_HasClipboardText(_THIS)
+{
+ SDL_bool result = SDL_FALSE;
+ char *text = WIN_GetClipboardText(_this);
+ if (text) {
+ result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
+ SDL_free(text);
+ }
+ return result;
+}
+
+void
+WIN_CheckClipboardUpdate(struct SDL_VideoData * data)
+{
+ const DWORD count = GetClipboardSequenceNumber();
+ if (count != data->clipboard_count) {
+ if (data->clipboard_count) {
+ SDL_SendClipboardUpdate();
+ }
+ data->clipboard_count = count;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.h
new file mode 100644
index 0000000..937b7d0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsclipboard.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsclipboard_h_
+#define SDL_windowsclipboard_h_
+
+/* Forward declaration */
+struct SDL_VideoData;
+
+extern int WIN_SetClipboardText(_THIS, const char *text);
+extern char *WIN_GetClipboardText(_THIS);
+extern SDL_bool WIN_HasClipboardText(_THIS);
+extern void WIN_CheckClipboardUpdate(struct SDL_VideoData * data);
+
+#endif /* SDL_windowsclipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.c
new file mode 100644
index 0000000..e961cf5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.c
@@ -0,0 +1,1236 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_windowsvideo.h"
+#include "SDL_windowsshape.h"
+#include "SDL_system.h"
+#include "SDL_syswm.h"
+#include "SDL_timer.h"
+#include "SDL_vkeys.h"
+#include "SDL_hints.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../../events/scancodes_windows.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+
+/* Dropfile support */
+#include <shellapi.h>
+
+/* For GET_X_LPARAM, GET_Y_LPARAM. */
+#include <windowsx.h>
+
+/* #define WMMSG_DEBUG */
+#ifdef WMMSG_DEBUG
+#include <stdio.h>
+#include "wmmsg.h"
+#endif
+
+/* For processing mouse WM_*BUTTON* and WM_MOUSEMOVE message-data from GetMessageExtraInfo() */
+#define MOUSEEVENTF_FROMTOUCH 0xFF515700
+
+/* Masks for processing the windows KEYDOWN and KEYUP messages */
+#define REPEATED_KEYMASK (1<<30)
+#define EXTENDED_KEYMASK (1<<24)
+
+#define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */
+#ifndef VK_OEM_NEC_EQUAL
+#define VK_OEM_NEC_EQUAL 0x92
+#endif
+
+/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
+#ifndef WM_XBUTTONDOWN
+#define WM_XBUTTONDOWN 0x020B
+#endif
+#ifndef WM_XBUTTONUP
+#define WM_XBUTTONUP 0x020C
+#endif
+#ifndef GET_XBUTTON_WPARAM
+#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
+#endif
+#ifndef WM_INPUT
+#define WM_INPUT 0x00ff
+#endif
+#ifndef WM_TOUCH
+#define WM_TOUCH 0x0240
+#endif
+#ifndef WM_MOUSEHWHEEL
+#define WM_MOUSEHWHEEL 0x020E
+#endif
+#ifndef WM_UNICHAR
+#define WM_UNICHAR 0x0109
+#endif
+
+static SDL_Scancode
+VKeytoScancode(WPARAM vkey)
+{
+ switch (vkey) {
+ case VK_CLEAR: return SDL_SCANCODE_CLEAR;
+ case VK_MODECHANGE: return SDL_SCANCODE_MODE;
+ case VK_SELECT: return SDL_SCANCODE_SELECT;
+ case VK_EXECUTE: return SDL_SCANCODE_EXECUTE;
+ case VK_HELP: return SDL_SCANCODE_HELP;
+ case VK_PAUSE: return SDL_SCANCODE_PAUSE;
+ case VK_NUMLOCK: return SDL_SCANCODE_NUMLOCKCLEAR;
+
+ case VK_F13: return SDL_SCANCODE_F13;
+ case VK_F14: return SDL_SCANCODE_F14;
+ case VK_F15: return SDL_SCANCODE_F15;
+ case VK_F16: return SDL_SCANCODE_F16;
+ case VK_F17: return SDL_SCANCODE_F17;
+ case VK_F18: return SDL_SCANCODE_F18;
+ case VK_F19: return SDL_SCANCODE_F19;
+ case VK_F20: return SDL_SCANCODE_F20;
+ case VK_F21: return SDL_SCANCODE_F21;
+ case VK_F22: return SDL_SCANCODE_F22;
+ case VK_F23: return SDL_SCANCODE_F23;
+ case VK_F24: return SDL_SCANCODE_F24;
+
+ case VK_OEM_NEC_EQUAL: return SDL_SCANCODE_KP_EQUALS;
+ case VK_BROWSER_BACK: return SDL_SCANCODE_AC_BACK;
+ case VK_BROWSER_FORWARD: return SDL_SCANCODE_AC_FORWARD;
+ case VK_BROWSER_REFRESH: return SDL_SCANCODE_AC_REFRESH;
+ case VK_BROWSER_STOP: return SDL_SCANCODE_AC_STOP;
+ case VK_BROWSER_SEARCH: return SDL_SCANCODE_AC_SEARCH;
+ case VK_BROWSER_FAVORITES: return SDL_SCANCODE_AC_BOOKMARKS;
+ case VK_BROWSER_HOME: return SDL_SCANCODE_AC_HOME;
+ case VK_VOLUME_MUTE: return SDL_SCANCODE_AUDIOMUTE;
+ case VK_VOLUME_DOWN: return SDL_SCANCODE_VOLUMEDOWN;
+ case VK_VOLUME_UP: return SDL_SCANCODE_VOLUMEUP;
+
+ case VK_MEDIA_NEXT_TRACK: return SDL_SCANCODE_AUDIONEXT;
+ case VK_MEDIA_PREV_TRACK: return SDL_SCANCODE_AUDIOPREV;
+ case VK_MEDIA_STOP: return SDL_SCANCODE_AUDIOSTOP;
+ case VK_MEDIA_PLAY_PAUSE: return SDL_SCANCODE_AUDIOPLAY;
+ case VK_LAUNCH_MAIL: return SDL_SCANCODE_MAIL;
+ case VK_LAUNCH_MEDIA_SELECT: return SDL_SCANCODE_MEDIASELECT;
+
+ case VK_OEM_102: return SDL_SCANCODE_NONUSBACKSLASH;
+
+ case VK_ATTN: return SDL_SCANCODE_SYSREQ;
+ case VK_CRSEL: return SDL_SCANCODE_CRSEL;
+ case VK_EXSEL: return SDL_SCANCODE_EXSEL;
+ case VK_OEM_CLEAR: return SDL_SCANCODE_CLEAR;
+
+ case VK_LAUNCH_APP1: return SDL_SCANCODE_APP1;
+ case VK_LAUNCH_APP2: return SDL_SCANCODE_APP2;
+
+ default: return SDL_SCANCODE_UNKNOWN;
+ }
+}
+
+static SDL_Scancode
+WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam)
+{
+ SDL_Scancode code;
+ int nScanCode = (lParam >> 16) & 0xFF;
+ SDL_bool bIsExtended = (lParam & (1 << 24)) != 0;
+
+ code = VKeytoScancode(wParam);
+
+ if (code == SDL_SCANCODE_UNKNOWN && nScanCode <= 127) {
+ code = windows_scancode_table[nScanCode];
+
+ if (bIsExtended) {
+ switch (code) {
+ case SDL_SCANCODE_RETURN:
+ code = SDL_SCANCODE_KP_ENTER;
+ break;
+ case SDL_SCANCODE_LALT:
+ code = SDL_SCANCODE_RALT;
+ break;
+ case SDL_SCANCODE_LCTRL:
+ code = SDL_SCANCODE_RCTRL;
+ break;
+ case SDL_SCANCODE_SLASH:
+ code = SDL_SCANCODE_KP_DIVIDE;
+ break;
+ case SDL_SCANCODE_CAPSLOCK:
+ code = SDL_SCANCODE_KP_PLUS;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (code) {
+ case SDL_SCANCODE_HOME:
+ code = SDL_SCANCODE_KP_7;
+ break;
+ case SDL_SCANCODE_UP:
+ code = SDL_SCANCODE_KP_8;
+ break;
+ case SDL_SCANCODE_PAGEUP:
+ code = SDL_SCANCODE_KP_9;
+ break;
+ case SDL_SCANCODE_LEFT:
+ code = SDL_SCANCODE_KP_4;
+ break;
+ case SDL_SCANCODE_RIGHT:
+ code = SDL_SCANCODE_KP_6;
+ break;
+ case SDL_SCANCODE_END:
+ code = SDL_SCANCODE_KP_1;
+ break;
+ case SDL_SCANCODE_DOWN:
+ code = SDL_SCANCODE_KP_2;
+ break;
+ case SDL_SCANCODE_PAGEDOWN:
+ code = SDL_SCANCODE_KP_3;
+ break;
+ case SDL_SCANCODE_INSERT:
+ code = SDL_SCANCODE_KP_0;
+ break;
+ case SDL_SCANCODE_DELETE:
+ code = SDL_SCANCODE_KP_PERIOD;
+ break;
+ case SDL_SCANCODE_PRINTSCREEN:
+ code = SDL_SCANCODE_KP_MULTIPLY;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return code;
+}
+
+static SDL_bool
+WIN_ShouldIgnoreFocusClick()
+{
+ return !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE);
+}
+
+static void
+WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
+{
+ if (data->focus_click_pending & SDL_BUTTON(button)) {
+ /* Ignore the button click for activation */
+ if (!bwParamMousePressed) {
+ data->focus_click_pending &= ~SDL_BUTTON(button);
+ WIN_UpdateClipCursor(data->window);
+ }
+ if (WIN_ShouldIgnoreFocusClick()) {
+ return;
+ }
+ }
+
+ if (bwParamMousePressed && !bSDLMousePressed) {
+ SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
+ } else if (!bwParamMousePressed && bSDLMousePressed) {
+ SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
+ }
+}
+
+/*
+* Some windows systems fail to send a WM_LBUTTONDOWN sometimes, but each mouse move contains the current button state also
+* so this funciton reconciles our view of the world with the current buttons reported by windows
+*/
+static void
+WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID)
+{
+ if (wParam != data->mouse_button_flags) {
+ Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
+ WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, mouseID);
+ WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, mouseID);
+ WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, mouseID);
+ WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, mouseID);
+ WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, mouseID);
+ data->mouse_button_flags = wParam;
+ }
+}
+
+
+static void
+WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data)
+{
+ if (rawButtons != data->mouse_button_flags) {
+ Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
+ if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
+ WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
+ if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
+ WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
+ data->mouse_button_flags = rawButtons;
+ }
+}
+
+static void
+WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
+{
+ Uint32 mouseFlags;
+ SHORT keyState;
+
+ /* mouse buttons may have changed state here, we need to resync them,
+ but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also
+ */
+ mouseFlags = SDL_GetMouseState(NULL, NULL);
+
+ keyState = GetAsyncKeyState(VK_LBUTTON);
+ if (!(keyState & 0x8000)) {
+ WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
+ }
+ keyState = GetAsyncKeyState(VK_RBUTTON);
+ if (!(keyState & 0x8000)) {
+ WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
+ }
+ keyState = GetAsyncKeyState(VK_MBUTTON);
+ if (!(keyState & 0x8000)) {
+ WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
+ }
+ keyState = GetAsyncKeyState(VK_XBUTTON1);
+ if (!(keyState & 0x8000)) {
+ WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
+ }
+ keyState = GetAsyncKeyState(VK_XBUTTON2);
+ if (!(keyState & 0x8000)) {
+ WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
+ }
+ data->mouse_button_flags = 0;
+}
+
+static BOOL
+WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
+{
+ if (codepoint <= 0x7F) {
+ text[0] = (char) codepoint;
+ text[1] = '\0';
+ } else if (codepoint <= 0x7FF) {
+ text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
+ text[1] = 0x80 | (char) (codepoint & 0x3F);
+ text[2] = '\0';
+ } else if (codepoint <= 0xFFFF) {
+ text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
+ text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
+ text[2] = 0x80 | (char) (codepoint & 0x3F);
+ text[3] = '\0';
+ } else if (codepoint <= 0x10FFFF) {
+ text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
+ text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
+ text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
+ text[3] = 0x80 | (char) (codepoint & 0x3F);
+ text[4] = '\0';
+ } else {
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+static SDL_bool
+ShouldGenerateWindowCloseOnAltF4(void)
+{
+ return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE);
+}
+
+/* Win10 "Fall Creators Update" introduced the bug that SetCursorPos() (as used by SDL_WarpMouseInWindow())
+ doesn't reliably generate WM_MOUSEMOVE events anymore (see #3931) which breaks relative mouse mode via warping.
+ This is used to implement a workaround.. */
+static SDL_bool isWin10FCUorNewer = SDL_FALSE;
+
+LRESULT CALLBACK
+WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SDL_WindowData *data;
+ LRESULT returnCode = -1;
+
+ /* Send a SDL_SYSWMEVENT if the application wants them */
+ if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.subsystem = SDL_SYSWM_WINDOWS;
+ wmmsg.msg.win.hwnd = hwnd;
+ wmmsg.msg.win.msg = msg;
+ wmmsg.msg.win.wParam = wParam;
+ wmmsg.msg.win.lParam = lParam;
+ SDL_SendSysWMEvent(&wmmsg);
+ }
+
+ /* Get the window data for the window */
+ data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
+ if (!data) {
+ return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
+ }
+
+#ifdef WMMSG_DEBUG
+ {
+ char message[1024];
+ if (msg > MAX_WMMSG) {
+ SDL_snprintf(message, sizeof(message), "Received windows message: %p UNKNOWN (%d) -- 0x%X, 0x%X\n", hwnd, msg, wParam, lParam);
+ } else {
+ SDL_snprintf(message, sizeof(message), "Received windows message: %p %s -- 0x%X, 0x%X\n", hwnd, wmtab[msg], wParam, lParam);
+ }
+ OutputDebugStringA(message);
+ }
+#endif /* WMMSG_DEBUG */
+
+ if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
+ return 0;
+
+ switch (msg) {
+
+ case WM_SHOWWINDOW:
+ {
+ if (wParam) {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+ } else {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+ }
+ }
+ break;
+
+ case WM_NCACTIVATE:
+ {
+ /* Don't immediately clip the cursor in case we're clicking minimize/maximize buttons */
+ data->skip_update_clipcursor = SDL_TRUE;
+ }
+ break;
+
+ case WM_ACTIVATE:
+ {
+ POINT cursorPos;
+ BOOL minimized;
+
+ /* Don't mark the window as shown if it's activated before being shown */
+ if (!IsWindowVisible(hwnd)) {
+ break;
+ }
+
+ minimized = HIWORD(wParam);
+ if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
+ if (LOWORD(wParam) == WA_CLICKACTIVE) {
+ if (GetAsyncKeyState(VK_LBUTTON)) {
+ data->focus_click_pending |= SDL_BUTTON_LMASK;
+ }
+ if (GetAsyncKeyState(VK_RBUTTON)) {
+ data->focus_click_pending |= SDL_BUTTON_RMASK;
+ }
+ if (GetAsyncKeyState(VK_MBUTTON)) {
+ data->focus_click_pending |= SDL_BUTTON_MMASK;
+ }
+ if (GetAsyncKeyState(VK_XBUTTON1)) {
+ data->focus_click_pending |= SDL_BUTTON_X1MASK;
+ }
+ if (GetAsyncKeyState(VK_XBUTTON2)) {
+ data->focus_click_pending |= SDL_BUTTON_X2MASK;
+ }
+ }
+
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+ if (SDL_GetKeyboardFocus() != data->window) {
+ SDL_SetKeyboardFocus(data->window);
+ }
+
+ GetCursorPos(&cursorPos);
+ ScreenToClient(hwnd, &cursorPos);
+ SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
+
+ WIN_CheckAsyncMouseRelease(data);
+
+ /*
+ * FIXME: Update keyboard state
+ */
+ WIN_CheckClipboardUpdate(data->videodata);
+
+ SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
+ SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
+ } else {
+ RECT rect;
+
+ data->in_window_deactivation = SDL_TRUE;
+
+ if (SDL_GetKeyboardFocus() == data->window) {
+ SDL_SetKeyboardFocus(NULL);
+ WIN_ResetDeadKeys();
+ }
+
+ if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect) == 0)) {
+ ClipCursor(NULL);
+ SDL_zero(data->cursor_clipped_rect);
+ }
+
+ data->in_window_deactivation = SDL_FALSE;
+ }
+ }
+ returnCode = 0;
+ break;
+
+ case WM_MOUSEMOVE:
+ {
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if (!mouse->relative_mode || mouse->relative_mode_warp) {
+ SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
+ SDL_SendMouseMotion(data->window, mouseID, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ if (isWin10FCUorNewer && mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
+ /* To work around #3931, Win10 bug introduced in Fall Creators Update, where
+ SetCursorPos() (SDL_WarpMouseInWindow()) doesn't reliably generate mouse events anymore,
+ after each windows mouse event generate a fake event for the middle of the window
+ if relative_mode_warp is used */
+ int center_x = 0, center_y = 0;
+ SDL_GetWindowSize(data->window, &center_x, &center_y);
+ center_x /= 2;
+ center_y /= 2;
+ SDL_SendMouseMotion(data->window, mouseID, 0, center_x, center_y);
+ }
+ }
+ }
+ /* don't break here, fall through to check the wParam like the button presses */
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_XBUTTONUP:
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONDBLCLK:
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONDBLCLK:
+ {
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if (!mouse->relative_mode || mouse->relative_mode_warp) {
+ SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
+ WIN_CheckWParamMouseButtons(wParam, data, mouseID);
+ }
+ }
+ break;
+
+ case WM_INPUT:
+ {
+ SDL_Mouse *mouse = SDL_GetMouse();
+ HRAWINPUT hRawInput = (HRAWINPUT)lParam;
+ RAWINPUT inp;
+ UINT size = sizeof(inp);
+ const SDL_bool isRelative = mouse->relative_mode || mouse->relative_mode_warp;
+ const SDL_bool isCapture = ((data->window->flags & SDL_WINDOW_MOUSE_CAPTURE) != 0);
+
+ if (!isRelative || mouse->focus != data->window) {
+ if (!isCapture) {
+ break;
+ }
+ }
+
+ GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
+
+ /* Mouse data */
+ if (inp.header.dwType == RIM_TYPEMOUSE) {
+ if (isRelative) {
+ RAWMOUSE* rawmouse = &inp.data.mouse;
+
+ if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
+ SDL_SendMouseMotion(data->window, 0, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
+ } else {
+ /* synthesize relative moves from the abs position */
+ static SDL_Point initialMousePoint;
+ if (initialMousePoint.x == 0 && initialMousePoint.y == 0) {
+ initialMousePoint.x = rawmouse->lLastX;
+ initialMousePoint.y = rawmouse->lLastY;
+ }
+
+ SDL_SendMouseMotion(data->window, 0, 1, (int)(rawmouse->lLastX-initialMousePoint.x), (int)(rawmouse->lLastY-initialMousePoint.y));
+
+ initialMousePoint.x = rawmouse->lLastX;
+ initialMousePoint.y = rawmouse->lLastY;
+ }
+ WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data);
+ } else if (isCapture) {
+ /* we check for where Windows thinks the system cursor lives in this case, so we don't really lose mouse accel, etc. */
+ POINT pt;
+ RECT hwndRect;
+ HWND currentHnd;
+
+ GetCursorPos(&pt);
+ currentHnd = WindowFromPoint(pt);
+ ScreenToClient(hwnd, &pt);
+ GetClientRect(hwnd, &hwndRect);
+
+ /* if in the window, WM_MOUSEMOVE, etc, will cover it. */
+ if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) {
+ SDL_SendMouseMotion(data->window, 0, 0, (int)pt.x, (int)pt.y);
+ SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT);
+ SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT);
+ SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
+ SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
+ SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
+ }
+ } else {
+ SDL_assert(0 && "Shouldn't happen");
+ }
+ }
+ }
+ break;
+
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
+ {
+ short amount = GET_WHEEL_DELTA_WPARAM(wParam);
+ float fAmount = (float) amount / WHEEL_DELTA;
+ if (msg == WM_MOUSEWHEEL)
+ SDL_SendMouseWheel(data->window, 0, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL);
+ else
+ SDL_SendMouseWheel(data->window, 0, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
+ }
+ break;
+
+#ifdef WM_MOUSELEAVE
+ case WM_MOUSELEAVE:
+ if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
+ if (!IsIconic(hwnd)) {
+ POINT cursorPos;
+ GetCursorPos(&cursorPos);
+ ScreenToClient(hwnd, &cursorPos);
+ SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
+ }
+ SDL_SetMouseFocus(NULL);
+ }
+ returnCode = 0;
+ break;
+#endif /* WM_MOUSELEAVE */
+
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ {
+ SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam);
+ const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
+
+ /* Detect relevant keyboard shortcuts */
+ if (keyboardState[SDL_SCANCODE_LALT] == SDL_PRESSED || keyboardState[SDL_SCANCODE_RALT] == SDL_PRESSED) {
+ /* ALT+F4: Close window */
+ if (code == SDL_SCANCODE_F4 && ShouldGenerateWindowCloseOnAltF4()) {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
+ }
+ }
+
+ if (code != SDL_SCANCODE_UNKNOWN) {
+ SDL_SendKeyboardKey(SDL_PRESSED, code);
+ }
+ }
+
+ returnCode = 0;
+ break;
+
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ {
+ SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam);
+ const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
+
+ if (code != SDL_SCANCODE_UNKNOWN) {
+ if (code == SDL_SCANCODE_PRINTSCREEN &&
+ keyboardState[code] == SDL_RELEASED) {
+ SDL_SendKeyboardKey(SDL_PRESSED, code);
+ }
+ SDL_SendKeyboardKey(SDL_RELEASED, code);
+ }
+ }
+ returnCode = 0;
+ break;
+
+ case WM_UNICHAR:
+ if (wParam == UNICODE_NOCHAR) {
+ returnCode = 1;
+ break;
+ }
+ /* otherwise fall through to below */
+ case WM_CHAR:
+ {
+ char text[5];
+ if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) {
+ SDL_SendKeyboardText(text);
+ }
+ }
+ returnCode = 0;
+ break;
+
+#ifdef WM_INPUTLANGCHANGE
+ case WM_INPUTLANGCHANGE:
+ {
+ WIN_UpdateKeymap();
+ SDL_SendKeymapChangedEvent();
+ }
+ returnCode = 1;
+ break;
+#endif /* WM_INPUTLANGCHANGE */
+
+ case WM_NCLBUTTONDOWN:
+ {
+ data->in_title_click = SDL_TRUE;
+ }
+ break;
+
+ case WM_CAPTURECHANGED:
+ {
+ data->in_title_click = SDL_FALSE;
+
+ /* The mouse may have been released during a modal loop */
+ WIN_CheckAsyncMouseRelease(data);
+ }
+ break;
+
+#ifdef WM_GETMINMAXINFO
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *info;
+ RECT size;
+ int x, y;
+ int w, h;
+ int min_w, min_h;
+ int max_w, max_h;
+ BOOL constrain_max_size;
+
+ if (SDL_IsShapedWindow(data->window))
+ Win32_ResizeWindowShape(data->window);
+
+ /* If this is an expected size change, allow it */
+ if (data->expected_resize) {
+ break;
+ }
+
+ /* Get the current position of our window */
+ GetWindowRect(hwnd, &size);
+ x = size.left;
+ y = size.top;
+
+ /* Calculate current size of our window */
+ SDL_GetWindowSize(data->window, &w, &h);
+ SDL_GetWindowMinimumSize(data->window, &min_w, &min_h);
+ SDL_GetWindowMaximumSize(data->window, &max_w, &max_h);
+
+ /* Store in min_w and min_h difference between current size and minimal
+ size so we don't need to call AdjustWindowRectEx twice */
+ min_w -= w;
+ min_h -= h;
+ if (max_w && max_h) {
+ max_w -= w;
+ max_h -= h;
+ constrain_max_size = TRUE;
+ } else {
+ constrain_max_size = FALSE;
+ }
+
+ if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) {
+ LONG style = GetWindowLong(hwnd, GWL_STYLE);
+ /* DJM - according to the docs for GetMenu(), the
+ return value is undefined if hwnd is a child window.
+ Apparently it's too difficult for MS to check
+ inside their function, so I have to do it here.
+ */
+ BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
+ size.top = 0;
+ size.left = 0;
+ size.bottom = h;
+ size.right = w;
+
+ AdjustWindowRectEx(&size, style, menu, 0);
+ w = size.right - size.left;
+ h = size.bottom - size.top;
+ }
+
+ /* Fix our size to the current size */
+ info = (MINMAXINFO *) lParam;
+ if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) {
+ info->ptMinTrackSize.x = w + min_w;
+ info->ptMinTrackSize.y = h + min_h;
+ if (constrain_max_size) {
+ info->ptMaxTrackSize.x = w + max_w;
+ info->ptMaxTrackSize.y = h + max_h;
+ }
+ } else {
+ info->ptMaxSize.x = w;
+ info->ptMaxSize.y = h;
+ info->ptMaxPosition.x = x;
+ info->ptMaxPosition.y = y;
+ info->ptMinTrackSize.x = w;
+ info->ptMinTrackSize.y = h;
+ info->ptMaxTrackSize.x = w;
+ info->ptMaxTrackSize.y = h;
+ }
+ }
+ returnCode = 0;
+ break;
+#endif /* WM_GETMINMAXINFO */
+
+ case WM_WINDOWPOSCHANGING:
+
+ if (data->expected_resize) {
+ returnCode = 0;
+ }
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ RECT rect;
+ int x, y;
+ int w, h;
+
+ if (data->initializing || data->in_border_change) {
+ break;
+ }
+
+ if (!GetClientRect(hwnd, &rect) || IsRectEmpty(&rect)) {
+ break;
+ }
+ ClientToScreen(hwnd, (LPPOINT) & rect);
+ ClientToScreen(hwnd, (LPPOINT) & rect + 1);
+
+ WIN_UpdateClipCursor(data->window);
+
+ x = rect.left;
+ y = rect.top;
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);
+
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
+ h);
+
+ /* Forces a WM_PAINT event */
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ break;
+
+ case WM_SIZE:
+ {
+ switch (wParam) {
+ case SIZE_MAXIMIZED:
+ SDL_SendWindowEvent(data->window,
+ SDL_WINDOWEVENT_RESTORED, 0, 0);
+ SDL_SendWindowEvent(data->window,
+ SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
+ break;
+ case SIZE_MINIMIZED:
+ SDL_SendWindowEvent(data->window,
+ SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+ break;
+ default:
+ SDL_SendWindowEvent(data->window,
+ SDL_WINDOWEVENT_RESTORED, 0, 0);
+ break;
+ }
+ }
+ break;
+
+ case WM_SETCURSOR:
+ {
+ Uint16 hittest;
+
+ hittest = LOWORD(lParam);
+ if (hittest == HTCLIENT) {
+ SetCursor(SDL_cursor);
+ returnCode = TRUE;
+ } else if (!g_WindowFrameUsableWhileCursorHidden && !SDL_cursor) {
+ SetCursor(NULL);
+ returnCode = TRUE;
+ }
+ }
+ break;
+
+ /* We were occluded, refresh our display */
+ case WM_PAINT:
+ {
+ RECT rect;
+ if (GetUpdateRect(hwnd, &rect, FALSE)) {
+ ValidateRect(hwnd, NULL);
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED,
+ 0, 0);
+ }
+ }
+ returnCode = 0;
+ break;
+
+ /* We'll do our own drawing, prevent flicker */
+ case WM_ERASEBKGND:
+ {
+ }
+ return (1);
+
+ case WM_SYSCOMMAND:
+ {
+ if ((wParam & 0xFFF0) == SC_KEYMENU) {
+ return (0);
+ }
+
+#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
+ /* Don't start the screensaver or blank the monitor in fullscreen apps */
+ if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
+ (wParam & 0xFFF0) == SC_MONITORPOWER) {
+ if (SDL_GetVideoDevice()->suspend_screensaver) {
+ return (0);
+ }
+ }
+#endif /* System has screensaver support */
+ }
+ break;
+
+ case WM_CLOSE:
+ {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
+ }
+ returnCode = 0;
+ break;
+
+ case WM_TOUCH:
+ if (data->videodata->GetTouchInputInfo && data->videodata->CloseTouchInputHandle) {
+ UINT i, num_inputs = LOWORD(wParam);
+ PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs);
+ if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
+ RECT rect;
+ float x, y;
+
+ if (!GetClientRect(hwnd, &rect) ||
+ (rect.right == rect.left && rect.bottom == rect.top)) {
+ if (inputs) {
+ SDL_stack_free(inputs);
+ }
+ break;
+ }
+ ClientToScreen(hwnd, (LPPOINT) & rect);
+ ClientToScreen(hwnd, (LPPOINT) & rect + 1);
+ rect.top *= 100;
+ rect.left *= 100;
+ rect.bottom *= 100;
+ rect.right *= 100;
+
+ for (i = 0; i < num_inputs; ++i) {
+ PTOUCHINPUT input = &inputs[i];
+
+ const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);
+ if (SDL_AddTouch(touchId, "") < 0) {
+ continue;
+ }
+
+ /* Get the normalized coordinates for the window */
+ x = (float)(input->x - rect.left)/(rect.right - rect.left);
+ y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
+
+ if (input->dwFlags & TOUCHEVENTF_DOWN) {
+ SDL_SendTouch(touchId, input->dwID, SDL_TRUE, x, y, 1.0f);
+ }
+ if (input->dwFlags & TOUCHEVENTF_MOVE) {
+ SDL_SendTouchMotion(touchId, input->dwID, x, y, 1.0f);
+ }
+ if (input->dwFlags & TOUCHEVENTF_UP) {
+ SDL_SendTouch(touchId, input->dwID, SDL_FALSE, x, y, 1.0f);
+ }
+ }
+ }
+ SDL_stack_free(inputs);
+
+ data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
+ return 0;
+ }
+ break;
+
+ case WM_DROPFILES:
+ {
+ UINT i;
+ HDROP drop = (HDROP) wParam;
+ UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
+ for (i = 0; i < count; ++i) {
+ UINT size = DragQueryFile(drop, i, NULL, 0) + 1;
+ LPTSTR buffer = SDL_stack_alloc(TCHAR, size);
+ if (buffer) {
+ if (DragQueryFile(drop, i, buffer, size)) {
+ char *file = WIN_StringToUTF8(buffer);
+ SDL_SendDropFile(data->window, file);
+ SDL_free(file);
+ }
+ SDL_stack_free(buffer);
+ }
+ }
+ SDL_SendDropComplete(data->window);
+ DragFinish(drop);
+ return 0;
+ }
+ break;
+
+ case WM_NCCALCSIZE:
+ {
+ Uint32 window_flags = SDL_GetWindowFlags(data->window);
+ if (wParam == TRUE && (window_flags & SDL_WINDOW_BORDERLESS) && !(window_flags & SDL_WINDOW_FULLSCREEN)) {
+ /* When borderless, need to tell windows that the size of the non-client area is 0 */
+ if (!(window_flags & SDL_WINDOW_RESIZABLE)) {
+ int w, h;
+ NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam;
+ w = data->window->windowed.w;
+ h = data->window->windowed.h;
+ params->rgrc[0].right = params->rgrc[0].left + w;
+ params->rgrc[0].bottom = params->rgrc[0].top + h;
+ }
+ return 0;
+ }
+ }
+ break;
+
+ case WM_NCHITTEST:
+ {
+ SDL_Window *window = data->window;
+ if (window->hit_test) {
+ POINT winpoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ if (ScreenToClient(hwnd, &winpoint)) {
+ const SDL_Point point = { (int) winpoint.x, (int) winpoint.y };
+ const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
+ switch (rc) {
+ #define POST_HIT_TEST(ret) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return ret; }
+ case SDL_HITTEST_DRAGGABLE: POST_HIT_TEST(HTCAPTION);
+ case SDL_HITTEST_RESIZE_TOPLEFT: POST_HIT_TEST(HTTOPLEFT);
+ case SDL_HITTEST_RESIZE_TOP: POST_HIT_TEST(HTTOP);
+ case SDL_HITTEST_RESIZE_TOPRIGHT: POST_HIT_TEST(HTTOPRIGHT);
+ case SDL_HITTEST_RESIZE_RIGHT: POST_HIT_TEST(HTRIGHT);
+ case SDL_HITTEST_RESIZE_BOTTOMRIGHT: POST_HIT_TEST(HTBOTTOMRIGHT);
+ case SDL_HITTEST_RESIZE_BOTTOM: POST_HIT_TEST(HTBOTTOM);
+ case SDL_HITTEST_RESIZE_BOTTOMLEFT: POST_HIT_TEST(HTBOTTOMLEFT);
+ case SDL_HITTEST_RESIZE_LEFT: POST_HIT_TEST(HTLEFT);
+ #undef POST_HIT_TEST
+ case SDL_HITTEST_NORMAL: return HTCLIENT;
+ }
+ }
+ /* If we didn't return, this will call DefWindowProc below. */
+ }
+ }
+ break;
+ }
+
+ /* If there's a window proc, assume it's going to handle messages */
+ if (data->wndproc) {
+ return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
+ } else if (returnCode >= 0) {
+ return returnCode;
+ } else {
+ return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
+ }
+}
+
+static void WIN_UpdateClipCursorForWindows()
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+ SDL_Window *window;
+
+ if (_this) {
+ for (window = _this->windows; window; window = window->next) {
+ if (window->driverdata) {
+ WIN_UpdateClipCursor(window);
+ }
+ }
+ }
+}
+
+/* A message hook called before TranslateMessage() */
+static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
+static void *g_WindowsMessageHookData = NULL;
+
+void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
+{
+ g_WindowsMessageHook = callback;
+ g_WindowsMessageHookData = userdata;
+}
+
+void
+WIN_PumpEvents(_THIS)
+{
+ const Uint8 *keystate;
+ MSG msg;
+ DWORD start_ticks = GetTickCount();
+
+ if (g_WindowsEnableMessageLoop) {
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (g_WindowsMessageHook) {
+ g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam);
+ }
+
+ /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+
+ /* Make sure we don't busy loop here forever if there are lots of events coming in */
+ if (SDL_TICKS_PASSED(msg.time, start_ticks)) {
+ break;
+ }
+ }
+ }
+
+ /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.
+ You won't get a KEYUP until both are released, and that keyup will only be for the second
+ key you released. Take heroic measures and check the keystate as of the last handled event,
+ and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
+ keystate = SDL_GetKeyboardState(NULL);
+ if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+ }
+ if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
+ }
+
+ /* Update the clipping rect in case someone else has stolen it */
+ WIN_UpdateClipCursorForWindows();
+}
+
+/* to work around #3931, a bug introduced in Win10 Fall Creators Update (build nr. 16299)
+ we need to detect the windows version. this struct and the function below does that.
+ usually this struct and the corresponding function (RtlGetVersion) are in <Ntddk.h>
+ but here we just load it dynamically */
+struct SDL_WIN_OSVERSIONINFOW {
+ ULONG dwOSVersionInfoSize;
+ ULONG dwMajorVersion;
+ ULONG dwMinorVersion;
+ ULONG dwBuildNumber;
+ ULONG dwPlatformId;
+ WCHAR szCSDVersion[128];
+};
+
+static SDL_bool
+IsWin10FCUorNewer(void)
+{
+ HMODULE handle = GetModuleHandleW(L"ntdll.dll");
+ if (handle) {
+ typedef LONG(WINAPI* RtlGetVersionPtr)(struct SDL_WIN_OSVERSIONINFOW*);
+ RtlGetVersionPtr getVersionPtr = (RtlGetVersionPtr)GetProcAddress(handle, "RtlGetVersion");
+ if (getVersionPtr != NULL) {
+ struct SDL_WIN_OSVERSIONINFOW info;
+ SDL_zero(info);
+ info.dwOSVersionInfoSize = sizeof(info);
+ if (getVersionPtr(&info) == 0) { /* STATUS_SUCCESS == 0 */
+ if ((info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && info.dwBuildNumber >= 16299) ||
+ (info.dwMajorVersion == 10 && info.dwMinorVersion > 0) ||
+ (info.dwMajorVersion > 10))
+ {
+ return SDL_TRUE;
+ }
+ }
+ }
+ }
+ return SDL_FALSE;
+}
+
+static int app_registered = 0;
+LPTSTR SDL_Appname = NULL;
+Uint32 SDL_Appstyle = 0;
+HINSTANCE SDL_Instance = NULL;
+
+/* Register the class for this application */
+int
+SDL_RegisterApp(char *name, Uint32 style, void *hInst)
+{
+ const char *hint;
+ WNDCLASSEX wcex;
+ TCHAR path[MAX_PATH];
+
+ /* Only do this once... */
+ if (app_registered) {
+ ++app_registered;
+ return (0);
+ }
+ if (!name && !SDL_Appname) {
+ name = "SDL_app";
+#if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
+ SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
+#endif
+ SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
+ }
+
+ if (name) {
+ SDL_Appname = WIN_UTF8ToString(name);
+ SDL_Appstyle = style;
+ SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
+ }
+
+ /* Register the application class */
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.hCursor = NULL;
+ wcex.hIcon = NULL;
+ wcex.hIconSm = NULL;
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = SDL_Appname;
+ wcex.style = SDL_Appstyle;
+ wcex.hbrBackground = NULL;
+ wcex.lpfnWndProc = WIN_WindowProc;
+ wcex.hInstance = SDL_Instance;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+
+ hint = SDL_GetHint(SDL_HINT_WINDOWS_INTRESOURCE_ICON);
+ if (hint && *hint) {
+ wcex.hIcon = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint)));
+
+ hint = SDL_GetHint(SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL);
+ if (hint && *hint) {
+ wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint)));
+ }
+ } else {
+ /* Use the first icon as a default icon, like in the Explorer */
+ GetModuleFileName(SDL_Instance, path, MAX_PATH);
+ ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1);
+ }
+
+ if (!RegisterClassEx(&wcex)) {
+ return SDL_SetError("Couldn't register application class");
+ }
+
+ isWin10FCUorNewer = IsWin10FCUorNewer();
+
+ app_registered = 1;
+ return 0;
+}
+
+/* Unregisters the windowclass registered in SDL_RegisterApp above. */
+void
+SDL_UnregisterApp()
+{
+ WNDCLASSEX wcex;
+
+ /* SDL_RegisterApp might not have been called before */
+ if (!app_registered) {
+ return;
+ }
+ --app_registered;
+ if (app_registered == 0) {
+ /* Check for any registered window classes. */
+ if (GetClassInfoEx(SDL_Instance, SDL_Appname, &wcex)) {
+ UnregisterClass(SDL_Appname, SDL_Instance);
+ if (wcex.hIcon) DestroyIcon(wcex.hIcon);
+ if (wcex.hIconSm) DestroyIcon(wcex.hIconSm);
+ }
+ SDL_free(SDL_Appname);
+ SDL_Appname = NULL;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.h
new file mode 100644
index 0000000..1ce2fb4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsevents.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsevents_h_
+#define SDL_windowsevents_h_
+
+extern LPTSTR SDL_Appname;
+extern Uint32 SDL_Appstyle;
+extern HINSTANCE SDL_Instance;
+
+extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
+ LPARAM lParam);
+extern void WIN_PumpEvents(_THIS);
+
+#endif /* SDL_windowsevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.c
new file mode 100644
index 0000000..e07d9c4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.c
@@ -0,0 +1,127 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_windowsvideo.h"
+
+int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ size_t size;
+ LPBITMAPINFO info;
+ HBITMAP hbm;
+
+ /* Free the old framebuffer surface */
+ if (data->mdc) {
+ DeleteDC(data->mdc);
+ }
+ if (data->hbm) {
+ DeleteObject(data->hbm);
+ }
+
+ /* Find out the format of the screen */
+ size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
+ info = (LPBITMAPINFO)SDL_stack_alloc(Uint8, size);
+ if (!info) {
+ return SDL_OutOfMemory();
+ }
+
+ SDL_memset(info, 0, size);
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+ /* The second call to GetDIBits() fills in the bitfields */
+ hbm = CreateCompatibleBitmap(data->hdc, 1, 1);
+ GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
+ GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
+ DeleteObject(hbm);
+
+ *format = SDL_PIXELFORMAT_UNKNOWN;
+ if (info->bmiHeader.biCompression == BI_BITFIELDS) {
+ int bpp;
+ Uint32 *masks;
+
+ bpp = info->bmiHeader.biPlanes * info->bmiHeader.biBitCount;
+ masks = (Uint32*)((Uint8*)info + info->bmiHeader.biSize);
+ *format = SDL_MasksToPixelFormatEnum(bpp, masks[0], masks[1], masks[2], 0);
+ }
+ if (*format == SDL_PIXELFORMAT_UNKNOWN)
+ {
+ /* We'll use RGB format for now */
+ *format = SDL_PIXELFORMAT_RGB888;
+
+ /* Create a new one */
+ SDL_memset(info, 0, size);
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = 32;
+ info->bmiHeader.biCompression = BI_RGB;
+ }
+
+ /* Fill in the size information */
+ *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
+ info->bmiHeader.biWidth = window->w;
+ info->bmiHeader.biHeight = -window->h; /* negative for topdown bitmap */
+ info->bmiHeader.biSizeImage = window->h * (*pitch);
+
+ data->mdc = CreateCompatibleDC(data->hdc);
+ data->hbm = CreateDIBSection(data->hdc, info, DIB_RGB_COLORS, pixels, NULL, 0);
+ SDL_stack_free(info);
+
+ if (!data->hbm) {
+ return WIN_SetError("Unable to create DIB");
+ }
+ SelectObject(data->mdc, data->hbm);
+
+ return 0;
+}
+
+int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ BitBlt(data->hdc, 0, 0, window->w, window->h, data->mdc, 0, 0, SRCCOPY);
+ return 0;
+}
+
+void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (!data) {
+ /* The window wasn't fully initialized */
+ return;
+ }
+
+ if (data->mdc) {
+ DeleteDC(data->mdc);
+ data->mdc = NULL;
+ }
+ if (data->hbm) {
+ DeleteObject(data->hbm);
+ data->hbm = NULL;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.h
new file mode 100644
index 0000000..a83cca5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsframebuffer.h
@@ -0,0 +1,27 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+extern int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
+extern int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
+extern void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.c
new file mode 100644
index 0000000..c7f357b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.c
@@ -0,0 +1,1579 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_windowsvideo.h"
+
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/scancodes_windows.h"
+
+#include <imm.h>
+#include <oleauto.h>
+
+#ifndef SDL_DISABLE_WINDOWS_IME
+static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
+static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
+static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
+static void IME_Quit(SDL_VideoData *videodata);
+#endif /* !SDL_DISABLE_WINDOWS_IME */
+
+#ifndef MAPVK_VK_TO_VSC
+#define MAPVK_VK_TO_VSC 0
+#endif
+#ifndef MAPVK_VSC_TO_VK
+#define MAPVK_VSC_TO_VK 1
+#endif
+#ifndef MAPVK_VK_TO_CHAR
+#define MAPVK_VK_TO_CHAR 2
+#endif
+
+/* Alphabetic scancodes for PC keyboards */
+void
+WIN_InitKeyboard(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ data->ime_com_initialized = SDL_FALSE;
+ data->ime_threadmgr = 0;
+ data->ime_initialized = SDL_FALSE;
+ data->ime_enabled = SDL_FALSE;
+ data->ime_available = SDL_FALSE;
+ data->ime_hwnd_main = 0;
+ data->ime_hwnd_current = 0;
+ data->ime_himc = 0;
+ data->ime_composition[0] = 0;
+ data->ime_readingstring[0] = 0;
+ data->ime_cursor = 0;
+
+ data->ime_candlist = SDL_FALSE;
+ SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates));
+ data->ime_candcount = 0;
+ data->ime_candref = 0;
+ data->ime_candsel = 0;
+ data->ime_candpgsize = 0;
+ data->ime_candlistindexbase = 0;
+ data->ime_candvertical = SDL_TRUE;
+
+ data->ime_dirty = SDL_FALSE;
+ SDL_memset(&data->ime_rect, 0, sizeof(data->ime_rect));
+ SDL_memset(&data->ime_candlistrect, 0, sizeof(data->ime_candlistrect));
+ data->ime_winwidth = 0;
+ data->ime_winheight = 0;
+
+ data->ime_hkl = 0;
+ data->ime_himm32 = 0;
+ data->GetReadingString = 0;
+ data->ShowReadingWindow = 0;
+ data->ImmLockIMC = 0;
+ data->ImmUnlockIMC = 0;
+ data->ImmLockIMCC = 0;
+ data->ImmUnlockIMCC = 0;
+ data->ime_uiless = SDL_FALSE;
+ data->ime_threadmgrex = 0;
+ data->ime_uielemsinkcookie = TF_INVALID_COOKIE;
+ data->ime_alpnsinkcookie = TF_INVALID_COOKIE;
+ data->ime_openmodesinkcookie = TF_INVALID_COOKIE;
+ data->ime_convmodesinkcookie = TF_INVALID_COOKIE;
+ data->ime_uielemsink = 0;
+ data->ime_ippasink = 0;
+
+ WIN_UpdateKeymap();
+
+ SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
+ SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows");
+ SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows");
+
+ /* Are system caps/num/scroll lock active? Set our state to match. */
+ SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
+ SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
+}
+
+void
+WIN_UpdateKeymap()
+{
+ int i;
+ SDL_Scancode scancode;
+ SDL_Keycode keymap[SDL_NUM_SCANCODES];
+
+ SDL_GetDefaultKeymap(keymap);
+
+ for (i = 0; i < SDL_arraysize(windows_scancode_table); i++) {
+ int vk;
+ /* Make sure this scancode is a valid character scancode */
+ scancode = windows_scancode_table[i];
+ if (scancode == SDL_SCANCODE_UNKNOWN ) {
+ continue;
+ }
+
+ /* If this key is one of the non-mappable keys, ignore it */
+ /* Not mapping numbers fixes the French layout, giving numeric keycodes for the number keys, which is the expected behavior */
+ if ((keymap[scancode] & SDLK_SCANCODE_MASK) ||
+ /* scancode == SDL_SCANCODE_GRAVE || */ /* Uncomment this line to re-enable the behavior of not mapping the "`"(grave) key to the users actual keyboard layout */
+ (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0) ) {
+ continue;
+ }
+
+ vk = MapVirtualKey(i, MAPVK_VSC_TO_VK);
+ if ( vk ) {
+ int ch = (MapVirtualKey( vk, MAPVK_VK_TO_CHAR ) & 0x7FFF);
+ if ( ch ) {
+ if ( ch >= 'A' && ch <= 'Z' ) {
+ keymap[scancode] = SDLK_a + ( ch - 'A' );
+ } else {
+ keymap[scancode] = ch;
+ }
+ }
+ }
+ }
+
+ SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
+}
+
+void
+WIN_QuitKeyboard(_THIS)
+{
+#ifndef SDL_DISABLE_WINDOWS_IME
+ IME_Quit((SDL_VideoData *)_this->driverdata);
+#endif
+}
+
+void
+WIN_ResetDeadKeys()
+{
+ /*
+ if a deadkey has been typed, but not the next character (which the deadkey might modify),
+ this tries to undo the effect pressing the deadkey.
+ see: http://archives.miloush.net/michkap/archive/2006/09/10/748775.html
+ */
+ BYTE keyboardState[256];
+ WCHAR buffer[16];
+ int keycode, scancode, result, i;
+
+ GetKeyboardState(keyboardState);
+
+ keycode = VK_SPACE;
+ scancode = MapVirtualKey(keycode, MAPVK_VK_TO_VSC);
+ if (scancode == 0) {
+ /* the keyboard doesn't have this key */
+ return;
+ }
+
+ for (i = 0; i < 5; i++) {
+ result = ToUnicode(keycode, scancode, keyboardState, (LPWSTR)buffer, 16, 0);
+ if (result > 0) {
+ /* success */
+ return;
+ }
+ }
+}
+
+void
+WIN_StartTextInput(_THIS)
+{
+#ifndef SDL_DISABLE_WINDOWS_IME
+ SDL_Window *window;
+#endif
+
+ WIN_ResetDeadKeys();
+
+#ifndef SDL_DISABLE_WINDOWS_IME
+ window = SDL_GetKeyboardFocus();
+ if (window) {
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ SDL_GetWindowSize(window, &videodata->ime_winwidth, &videodata->ime_winheight);
+ IME_Init(videodata, hwnd);
+ IME_Enable(videodata, hwnd);
+ }
+#endif /* !SDL_DISABLE_WINDOWS_IME */
+}
+
+void
+WIN_StopTextInput(_THIS)
+{
+#ifndef SDL_DISABLE_WINDOWS_IME
+ SDL_Window *window;
+#endif
+
+ WIN_ResetDeadKeys();
+
+#ifndef SDL_DISABLE_WINDOWS_IME
+ window = SDL_GetKeyboardFocus();
+ if (window) {
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ IME_Init(videodata, hwnd);
+ IME_Disable(videodata, hwnd);
+ }
+#endif /* !SDL_DISABLE_WINDOWS_IME */
+}
+
+void
+WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ HIMC himc = 0;
+
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return;
+ }
+
+ videodata->ime_rect = *rect;
+
+ himc = ImmGetContext(videodata->ime_hwnd_current);
+ if (himc)
+ {
+ COMPOSITIONFORM cf;
+ cf.ptCurrentPos.x = videodata->ime_rect.x;
+ cf.ptCurrentPos.y = videodata->ime_rect.y;
+ cf.dwStyle = CFS_FORCE_POSITION;
+ ImmSetCompositionWindow(himc, &cf);
+ ImmReleaseContext(videodata->ime_hwnd_current, himc);
+ }
+}
+
+#ifdef SDL_DISABLE_WINDOWS_IME
+
+
+SDL_bool
+IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
+{
+ return SDL_FALSE;
+}
+
+void IME_Present(SDL_VideoData *videodata)
+{
+}
+
+#else
+
+#ifdef SDL_msctf_h_
+#define USE_INIT_GUID
+#elif defined(__GNUC__)
+#define USE_INIT_GUID
+#endif
+#ifdef USE_INIT_GUID
+#undef DEFINE_GUID
+#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C);
+DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
+DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31);
+DEFINE_GUID(IID_ITfSource, 0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7);
+DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
+DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
+DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
+DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E);
+DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50);
+DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C);
+#endif
+
+#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
+#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
+
+#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
+#define IMEID_VER(id) ((id) & 0xffff0000)
+#define IMEID_LANG(id) ((id) & 0x0000ffff)
+
+#define CHT_HKL_DAYI ((HKL)(UINT_PTR)0xE0060404)
+#define CHT_HKL_NEW_PHONETIC ((HKL)(UINT_PTR)0xE0080404)
+#define CHT_HKL_NEW_CHANG_JIE ((HKL)(UINT_PTR)0xE0090404)
+#define CHT_HKL_NEW_QUICK ((HKL)(UINT_PTR)0xE00A0404)
+#define CHT_HKL_HK_CANTONESE ((HKL)(UINT_PTR)0xE00B0404)
+#define CHT_IMEFILENAME1 "TINTLGNT.IME"
+#define CHT_IMEFILENAME2 "CINTLGNT.IME"
+#define CHT_IMEFILENAME3 "MSTCIPHA.IME"
+#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2))
+#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3))
+#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4))
+#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0))
+#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1))
+#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2))
+#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0))
+#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0))
+
+#define CHS_HKL ((HKL)(UINT_PTR)0xE00E0804)
+#define CHS_IMEFILENAME1 "PINTLGNT.IME"
+#define CHS_IMEFILENAME2 "MSSCIPYA.IME"
+#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1))
+#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2))
+#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3))
+
+#define LANG() LOWORD((videodata->ime_hkl))
+#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
+#define SUBLANG() SUBLANGID(LANG())
+
+static void IME_UpdateInputLocale(SDL_VideoData *videodata);
+static void IME_ClearComposition(SDL_VideoData *videodata);
+static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
+static void IME_SetupAPI(SDL_VideoData *videodata);
+static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
+static void IME_SendEditingEvent(SDL_VideoData *videodata);
+static void IME_DestroyTextures(SDL_VideoData *videodata);
+
+static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata);
+static void UILess_ReleaseSinks(SDL_VideoData *videodata);
+static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
+static void UILess_DisableUIUpdates(SDL_VideoData *videodata);
+
+static void
+IME_Init(SDL_VideoData *videodata, HWND hwnd)
+{
+ if (videodata->ime_initialized)
+ return;
+
+ videodata->ime_hwnd_main = hwnd;
+ if (SUCCEEDED(WIN_CoInitialize())) {
+ videodata->ime_com_initialized = SDL_TRUE;
+ CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr);
+ }
+ videodata->ime_initialized = SDL_TRUE;
+ videodata->ime_himm32 = SDL_LoadObject("imm32.dll");
+ if (!videodata->ime_himm32) {
+ videodata->ime_available = SDL_FALSE;
+ SDL_ClearError();
+ return;
+ }
+ videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMC");
+ videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMC");
+ videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMCC");
+ videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMCC");
+
+ IME_SetWindow(videodata, hwnd);
+ videodata->ime_himc = ImmGetContext(hwnd);
+ ImmReleaseContext(hwnd, videodata->ime_himc);
+ if (!videodata->ime_himc) {
+ videodata->ime_available = SDL_FALSE;
+ IME_Disable(videodata, hwnd);
+ return;
+ }
+ videodata->ime_available = SDL_TRUE;
+ IME_UpdateInputLocale(videodata);
+ IME_SetupAPI(videodata);
+ videodata->ime_uiless = UILess_SetupSinks(videodata);
+ IME_UpdateInputLocale(videodata);
+ IME_Disable(videodata, hwnd);
+}
+
+static void
+IME_Enable(SDL_VideoData *videodata, HWND hwnd)
+{
+ if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
+ return;
+
+ if (!videodata->ime_available) {
+ IME_Disable(videodata, hwnd);
+ return;
+ }
+ if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
+ ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc);
+
+ videodata->ime_enabled = SDL_TRUE;
+ IME_UpdateInputLocale(videodata);
+ UILess_EnableUIUpdates(videodata);
+}
+
+static void
+IME_Disable(SDL_VideoData *videodata, HWND hwnd)
+{
+ if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
+ return;
+
+ IME_ClearComposition(videodata);
+ if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
+ ImmAssociateContext(videodata->ime_hwnd_current, (HIMC)0);
+
+ videodata->ime_enabled = SDL_FALSE;
+ UILess_DisableUIUpdates(videodata);
+}
+
+static void
+IME_Quit(SDL_VideoData *videodata)
+{
+ if (!videodata->ime_initialized)
+ return;
+
+ UILess_ReleaseSinks(videodata);
+ if (videodata->ime_hwnd_main)
+ ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc);
+
+ videodata->ime_hwnd_main = 0;
+ videodata->ime_himc = 0;
+ if (videodata->ime_himm32) {
+ SDL_UnloadObject(videodata->ime_himm32);
+ videodata->ime_himm32 = 0;
+ }
+ if (videodata->ime_threadmgr) {
+ videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr);
+ videodata->ime_threadmgr = 0;
+ }
+ if (videodata->ime_com_initialized) {
+ WIN_CoUninitialize();
+ videodata->ime_com_initialized = SDL_FALSE;
+ }
+ IME_DestroyTextures(videodata);
+ videodata->ime_initialized = SDL_FALSE;
+}
+
+static void
+IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd)
+{
+ DWORD id = 0;
+ HIMC himc = 0;
+ WCHAR buffer[16];
+ WCHAR *s = buffer;
+ DWORD len = 0;
+ INT err = 0;
+ BOOL vertical = FALSE;
+ UINT maxuilen = 0;
+
+ if (videodata->ime_uiless)
+ return;
+
+ videodata->ime_readingstring[0] = 0;
+
+ id = IME_GetId(videodata, 0);
+ if (!id)
+ return;
+
+ himc = ImmGetContext(hwnd);
+ if (!himc)
+ return;
+
+ if (videodata->GetReadingString) {
+ len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
+ if (len) {
+ if (len > SDL_arraysize(buffer))
+ len = SDL_arraysize(buffer);
+
+ len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
+ }
+ SDL_wcslcpy(videodata->ime_readingstring, s, len);
+ }
+ else {
+ LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
+ LPBYTE p = 0;
+ s = 0;
+ switch (id)
+ {
+ case IMEID_CHT_VER42:
+ case IMEID_CHT_VER43:
+ case IMEID_CHT_VER44:
+ p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
+ if (!p)
+ break;
+
+ len = *(DWORD *)(p + 7*4 + 32*4);
+ s = (WCHAR *)(p + 56);
+ break;
+ case IMEID_CHT_VER51:
+ case IMEID_CHT_VER52:
+ case IMEID_CHS_VER53:
+ p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
+ if (!p)
+ break;
+
+ p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
+ if (!p)
+ break;
+
+ len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
+ s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
+ break;
+ case IMEID_CHS_VER41:
+ {
+ int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
+ p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
+ if (!p)
+ break;
+
+ len = *(DWORD *)(p + 7*4 + 16*2*4);
+ s = (WCHAR *)(p + 6*4 + 16*2*1);
+ }
+ break;
+ case IMEID_CHS_VER42:
+ p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
+ if (!p)
+ break;
+
+ len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
+ s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
+ break;
+ }
+ if (s) {
+ size_t size = SDL_min((size_t)(len + 1), SDL_arraysize(videodata->ime_readingstring));
+ SDL_wcslcpy(videodata->ime_readingstring, s, size);
+ }
+
+ videodata->ImmUnlockIMCC(lpimc->hPrivate);
+ videodata->ImmUnlockIMC(himc);
+ }
+ ImmReleaseContext(hwnd, himc);
+ IME_SendEditingEvent(videodata);
+}
+
+static void
+IME_InputLangChanged(SDL_VideoData *videodata)
+{
+ UINT lang = PRIMLANG();
+ IME_UpdateInputLocale(videodata);
+ if (!videodata->ime_uiless)
+ videodata->ime_candlistindexbase = (videodata->ime_hkl == CHT_HKL_DAYI) ? 0 : 1;
+
+ IME_SetupAPI(videodata);
+ if (lang != PRIMLANG()) {
+ IME_ClearComposition(videodata);
+ }
+}
+
+static DWORD
+IME_GetId(SDL_VideoData *videodata, UINT uIndex)
+{
+ static HKL hklprev = 0;
+ static DWORD dwRet[2] = {0};
+ DWORD dwVerSize = 0;
+ DWORD dwVerHandle = 0;
+ LPVOID lpVerBuffer = 0;
+ LPVOID lpVerData = 0;
+ UINT cbVerData = 0;
+ char szTemp[256];
+ HKL hkl = 0;
+ DWORD dwLang = 0;
+ if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0]))
+ return 0;
+
+ hkl = videodata->ime_hkl;
+ if (hklprev == hkl)
+ return dwRet[uIndex];
+
+ hklprev = hkl;
+ dwLang = ((DWORD_PTR)hkl & 0xffff);
+ if (videodata->ime_uiless && LANG() == LANG_CHT) {
+ dwRet[0] = IMEID_CHT_VER_VISTA;
+ dwRet[1] = 0;
+ return dwRet[0];
+ }
+ if (hkl != CHT_HKL_NEW_PHONETIC
+ && hkl != CHT_HKL_NEW_CHANG_JIE
+ && hkl != CHT_HKL_NEW_QUICK
+ && hkl != CHT_HKL_HK_CANTONESE
+ && hkl != CHS_HKL) {
+ dwRet[0] = dwRet[1] = 0;
+ return dwRet[uIndex];
+ }
+ if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) {
+ dwRet[0] = dwRet[1] = 0;
+ return dwRet[uIndex];
+ }
+ if (!videodata->GetReadingString) {
+ #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
+ if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
+ && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
+ && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
+ && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
+ && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) {
+ dwRet[0] = dwRet[1] = 0;
+ return dwRet[uIndex];
+ }
+ #undef LCID_INVARIANT
+ dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
+ if (dwVerSize) {
+ lpVerBuffer = SDL_malloc(dwVerSize);
+ if (lpVerBuffer) {
+ if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) {
+ if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) {
+ #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData)
+ DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
+ dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
+ if ((videodata->GetReadingString) ||
+ ((dwLang == LANG_CHT) && (
+ dwVer == MAKEIMEVERSION(4, 2) ||
+ dwVer == MAKEIMEVERSION(4, 3) ||
+ dwVer == MAKEIMEVERSION(4, 4) ||
+ dwVer == MAKEIMEVERSION(5, 0) ||
+ dwVer == MAKEIMEVERSION(5, 1) ||
+ dwVer == MAKEIMEVERSION(5, 2) ||
+ dwVer == MAKEIMEVERSION(6, 0)))
+ ||
+ ((dwLang == LANG_CHS) && (
+ dwVer == MAKEIMEVERSION(4, 1) ||
+ dwVer == MAKEIMEVERSION(4, 2) ||
+ dwVer == MAKEIMEVERSION(5, 3)))) {
+ dwRet[0] = dwVer | dwLang;
+ dwRet[1] = pVerFixedInfo->dwFileVersionLS;
+ SDL_free(lpVerBuffer);
+ return dwRet[0];
+ }
+ #undef pVerFixedInfo
+ }
+ }
+ }
+ SDL_free(lpVerBuffer);
+ }
+ }
+ dwRet[0] = dwRet[1] = 0;
+ return dwRet[uIndex];
+}
+
+static void
+IME_SetupAPI(SDL_VideoData *videodata)
+{
+ char ime_file[MAX_PATH + 1];
+ void* hime = 0;
+ HKL hkl = 0;
+ videodata->GetReadingString = 0;
+ videodata->ShowReadingWindow = 0;
+ if (videodata->ime_uiless)
+ return;
+
+ hkl = videodata->ime_hkl;
+ if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0)
+ return;
+
+ hime = SDL_LoadObject(ime_file);
+ if (!hime)
+ return;
+
+ videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
+ SDL_LoadFunction(hime, "GetReadingString");
+ videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
+ SDL_LoadFunction(hime, "ShowReadingWindow");
+
+ if (videodata->ShowReadingWindow) {
+ HIMC himc = ImmGetContext(videodata->ime_hwnd_current);
+ if (himc) {
+ videodata->ShowReadingWindow(himc, FALSE);
+ ImmReleaseContext(videodata->ime_hwnd_current, himc);
+ }
+ }
+}
+
+static void
+IME_SetWindow(SDL_VideoData* videodata, HWND hwnd)
+{
+ videodata->ime_hwnd_current = hwnd;
+ if (videodata->ime_threadmgr) {
+ struct ITfDocumentMgr *document_mgr = 0;
+ if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) {
+ if (document_mgr)
+ document_mgr->lpVtbl->Release(document_mgr);
+ }
+ }
+}
+
+static void
+IME_UpdateInputLocale(SDL_VideoData *videodata)
+{
+ static HKL hklprev = 0;
+ videodata->ime_hkl = GetKeyboardLayout(0);
+ if (hklprev == videodata->ime_hkl)
+ return;
+
+ hklprev = videodata->ime_hkl;
+ switch (PRIMLANG()) {
+ case LANG_CHINESE:
+ videodata->ime_candvertical = SDL_TRUE;
+ if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED)
+ videodata->ime_candvertical = SDL_FALSE;
+
+ break;
+ case LANG_JAPANESE:
+ videodata->ime_candvertical = SDL_TRUE;
+ break;
+ case LANG_KOREAN:
+ videodata->ime_candvertical = SDL_FALSE;
+ break;
+ }
+}
+
+static void
+IME_ClearComposition(SDL_VideoData *videodata)
+{
+ HIMC himc = 0;
+ if (!videodata->ime_initialized)
+ return;
+
+ himc = ImmGetContext(videodata->ime_hwnd_current);
+ if (!himc)
+ return;
+
+ ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
+ if (videodata->ime_uiless)
+ ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR));
+
+ ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
+ ImmReleaseContext(videodata->ime_hwnd_current, himc);
+ SDL_SendEditingText("", 0, 0);
+}
+
+static void
+IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
+{
+ LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition) - sizeof(videodata->ime_composition[0]));
+ if (length < 0)
+ length = 0;
+
+ length /= sizeof(videodata->ime_composition[0]);
+ videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
+ if (videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) && videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
+ int i;
+ for (i = videodata->ime_cursor + 1; i < length; ++i)
+ videodata->ime_composition[i - 1] = videodata->ime_composition[i];
+
+ --length;
+ }
+ videodata->ime_composition[length] = 0;
+}
+
+static void
+IME_SendInputEvent(SDL_VideoData *videodata)
+{
+ char *s = 0;
+ s = WIN_StringToUTF8(videodata->ime_composition);
+ SDL_SendKeyboardText(s);
+ SDL_free(s);
+
+ videodata->ime_composition[0] = 0;
+ videodata->ime_readingstring[0] = 0;
+ videodata->ime_cursor = 0;
+}
+
+static void
+IME_SendEditingEvent(SDL_VideoData *videodata)
+{
+ char *s = 0;
+ WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
+ const size_t size = SDL_arraysize(buffer);
+ buffer[0] = 0;
+ if (videodata->ime_readingstring[0]) {
+ size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
+ SDL_wcslcpy(buffer, videodata->ime_composition, len + 1);
+ SDL_wcslcat(buffer, videodata->ime_readingstring, size);
+ SDL_wcslcat(buffer, &videodata->ime_composition[len], size);
+ }
+ else {
+ SDL_wcslcpy(buffer, videodata->ime_composition, size);
+ }
+ s = WIN_StringToUTF8(buffer);
+ SDL_SendEditingText(s, videodata->ime_cursor + (int)SDL_wcslen(videodata->ime_readingstring), 0);
+ SDL_free(s);
+}
+
+static void
+IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate)
+{
+ LPWSTR dst = videodata->ime_candidates[i];
+ *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10));
+ if (videodata->ime_candvertical)
+ *dst++ = TEXT(' ');
+
+ while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i])))
+ *dst++ = *candidate++;
+
+ *dst = (WCHAR)'\0';
+}
+
+static void
+IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata)
+{
+ LPCANDIDATELIST cand_list = 0;
+ DWORD size = ImmGetCandidateListW(himc, 0, 0, 0);
+ if (size) {
+ cand_list = (LPCANDIDATELIST)SDL_malloc(size);
+ if (cand_list) {
+ size = ImmGetCandidateListW(himc, 0, cand_list, size);
+ if (size) {
+ UINT i, j;
+ UINT page_start = 0;
+ videodata->ime_candsel = cand_list->dwSelection;
+ videodata->ime_candcount = cand_list->dwCount;
+
+ if (LANG() == LANG_CHS && IME_GetId(videodata, 0)) {
+ const UINT maxcandchar = 18;
+ size_t cchars = 0;
+
+ for (i = 0; i < videodata->ime_candcount; ++i) {
+ size_t len = SDL_wcslen((LPWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i])) + 1;
+ if (len + cchars > maxcandchar) {
+ if (i > cand_list->dwSelection)
+ break;
+
+ page_start = i;
+ cchars = len;
+ }
+ else {
+ cchars += len;
+ }
+ }
+ videodata->ime_candpgsize = i - page_start;
+ } else {
+ videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST);
+ if (videodata->ime_candpgsize > 0) {
+ page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize;
+ } else {
+ page_start = 0;
+ }
+ }
+ SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
+ for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) {
+ LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i]);
+ IME_AddCandidate(videodata, j, candidate);
+ }
+ if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0)))
+ videodata->ime_candsel = -1;
+
+ }
+ SDL_free(cand_list);
+ }
+ }
+}
+
+static void
+IME_ShowCandidateList(SDL_VideoData *videodata)
+{
+ videodata->ime_dirty = SDL_TRUE;
+ videodata->ime_candlist = SDL_TRUE;
+ IME_DestroyTextures(videodata);
+ IME_SendEditingEvent(videodata);
+}
+
+static void
+IME_HideCandidateList(SDL_VideoData *videodata)
+{
+ videodata->ime_dirty = SDL_FALSE;
+ videodata->ime_candlist = SDL_FALSE;
+ IME_DestroyTextures(videodata);
+ IME_SendEditingEvent(videodata);
+}
+
+SDL_bool
+IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
+{
+ SDL_bool trap = SDL_FALSE;
+ HIMC himc = 0;
+ if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled)
+ return SDL_FALSE;
+
+ switch (msg) {
+ case WM_INPUTLANGCHANGE:
+ IME_InputLangChanged(videodata);
+ break;
+ case WM_IME_SETCONTEXT:
+ *lParam = 0;
+ break;
+ case WM_IME_STARTCOMPOSITION:
+ trap = SDL_TRUE;
+ break;
+ case WM_IME_COMPOSITION:
+ trap = SDL_TRUE;
+ himc = ImmGetContext(hwnd);
+ if (*lParam & GCS_RESULTSTR) {
+ IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
+ IME_SendInputEvent(videodata);
+ }
+ if (*lParam & GCS_COMPSTR) {
+ if (!videodata->ime_uiless)
+ videodata->ime_readingstring[0] = 0;
+
+ IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
+ IME_SendEditingEvent(videodata);
+ }
+ ImmReleaseContext(hwnd, himc);
+ break;
+ case WM_IME_ENDCOMPOSITION:
+ videodata->ime_composition[0] = 0;
+ videodata->ime_readingstring[0] = 0;
+ videodata->ime_cursor = 0;
+ SDL_SendEditingText("", 0, 0);
+ break;
+ case WM_IME_NOTIFY:
+ switch (wParam) {
+ case IMN_SETCONVERSIONMODE:
+ case IMN_SETOPENSTATUS:
+ IME_UpdateInputLocale(videodata);
+ break;
+ case IMN_OPENCANDIDATE:
+ case IMN_CHANGECANDIDATE:
+ if (videodata->ime_uiless)
+ break;
+
+ trap = SDL_TRUE;
+ IME_ShowCandidateList(videodata);
+ himc = ImmGetContext(hwnd);
+ if (!himc)
+ break;
+
+ IME_GetCandidateList(himc, videodata);
+ ImmReleaseContext(hwnd, himc);
+ break;
+ case IMN_CLOSECANDIDATE:
+ trap = SDL_TRUE;
+ IME_HideCandidateList(videodata);
+ break;
+ case IMN_PRIVATE:
+ {
+ DWORD dwId = IME_GetId(videodata, 0);
+ IME_GetReadingString(videodata, hwnd);
+ switch (dwId)
+ {
+ case IMEID_CHT_VER42:
+ case IMEID_CHT_VER43:
+ case IMEID_CHT_VER44:
+ case IMEID_CHS_VER41:
+ case IMEID_CHS_VER42:
+ if (*lParam == 1 || *lParam == 2)
+ trap = SDL_TRUE;
+
+ break;
+ case IMEID_CHT_VER50:
+ case IMEID_CHT_VER51:
+ case IMEID_CHT_VER52:
+ case IMEID_CHT_VER60:
+ case IMEID_CHS_VER53:
+ if (*lParam == 16
+ || *lParam == 17
+ || *lParam == 26
+ || *lParam == 27
+ || *lParam == 28)
+ trap = SDL_TRUE;
+ break;
+ }
+ }
+ break;
+ default:
+ trap = SDL_TRUE;
+ break;
+ }
+ break;
+ }
+ return trap;
+}
+
+static void
+IME_CloseCandidateList(SDL_VideoData *videodata)
+{
+ IME_HideCandidateList(videodata);
+ videodata->ime_candcount = 0;
+ SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
+}
+
+static void
+UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist)
+{
+ UINT selection = 0;
+ UINT count = 0;
+ UINT page = 0;
+ UINT pgcount = 0;
+ DWORD pgstart = 0;
+ DWORD pgsize = 0;
+ UINT i, j;
+ pcandlist->lpVtbl->GetSelection(pcandlist, &selection);
+ pcandlist->lpVtbl->GetCount(pcandlist, &count);
+ pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page);
+
+ videodata->ime_candsel = selection;
+ videodata->ime_candcount = count;
+ IME_ShowCandidateList(videodata);
+
+ pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount);
+ if (pgcount > 0) {
+ UINT *idxlist = SDL_malloc(sizeof(UINT) * pgcount);
+ if (idxlist) {
+ pcandlist->lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount);
+ pgstart = idxlist[page];
+ if (page < pgcount - 1)
+ pgsize = SDL_min(count, idxlist[page + 1]) - pgstart;
+ else
+ pgsize = count - pgstart;
+
+ SDL_free(idxlist);
+ }
+ }
+ videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST);
+ videodata->ime_candsel = videodata->ime_candsel - pgstart;
+
+ SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
+ for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) {
+ BSTR bstr;
+ if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) {
+ if (bstr) {
+ IME_AddCandidate(videodata, j, bstr);
+ SysFreeString(bstr);
+ }
+ }
+ }
+ if (PRIMLANG() == LANG_KOREAN)
+ videodata->ime_candsel = -1;
+}
+
+STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink)
+{
+ return ++sink->refcount;
+}
+
+STDMETHODIMP_(ULONG) TSFSink_Release(TSFSink *sink)
+{
+ --sink->refcount;
+ if (sink->refcount == 0) {
+ SDL_free(sink);
+ return 0;
+ }
+ return sink->refcount;
+}
+
+STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
+{
+ if (!ppv)
+ return E_INVALIDARG;
+
+ *ppv = 0;
+ if (WIN_IsEqualIID(riid, &IID_IUnknown))
+ *ppv = (IUnknown *)sink;
+ else if (WIN_IsEqualIID(riid, &IID_ITfUIElementSink))
+ *ppv = (ITfUIElementSink *)sink;
+
+ if (*ppv) {
+ TSFSink_AddRef(sink);
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId)
+{
+ ITfUIElementMgr *puiem = 0;
+ ITfUIElement *pelem = 0;
+ ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex;
+
+ if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) {
+ puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
+ puiem->lpVtbl->Release(puiem);
+ }
+ return pelem;
+}
+
+STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
+{
+ ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
+ ITfReadingInformationUIElement *preading = 0;
+ ITfCandidateListUIElement *pcandlist = 0;
+ SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
+ if (!element)
+ return E_INVALIDARG;
+
+ *pbShow = FALSE;
+ if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
+ BSTR bstr;
+ if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
+ SysFreeString(bstr);
+ }
+ preading->lpVtbl->Release(preading);
+ }
+ else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
+ videodata->ime_candref++;
+ UILess_GetCandidateList(videodata, pcandlist);
+ pcandlist->lpVtbl->Release(pcandlist);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId)
+{
+ ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
+ ITfReadingInformationUIElement *preading = 0;
+ ITfCandidateListUIElement *pcandlist = 0;
+ SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
+ if (!element)
+ return E_INVALIDARG;
+
+ if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
+ BSTR bstr;
+ if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
+ WCHAR *s = (WCHAR *)bstr;
+ SDL_wcslcpy(videodata->ime_readingstring, s, SDL_arraysize(videodata->ime_readingstring));
+ IME_SendEditingEvent(videodata);
+ SysFreeString(bstr);
+ }
+ preading->lpVtbl->Release(preading);
+ }
+ else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
+ UILess_GetCandidateList(videodata, pcandlist);
+ pcandlist->lpVtbl->Release(pcandlist);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId)
+{
+ ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
+ ITfReadingInformationUIElement *preading = 0;
+ ITfCandidateListUIElement *pcandlist = 0;
+ SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
+ if (!element)
+ return E_INVALIDARG;
+
+ if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
+ videodata->ime_readingstring[0] = 0;
+ IME_SendEditingEvent(videodata);
+ preading->lpVtbl->Release(preading);
+ }
+ if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
+ videodata->ime_candref--;
+ if (videodata->ime_candref == 0)
+ IME_CloseCandidateList(videodata);
+
+ pcandlist->lpVtbl->Release(pcandlist);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
+{
+ if (!ppv)
+ return E_INVALIDARG;
+
+ *ppv = 0;
+ if (WIN_IsEqualIID(riid, &IID_IUnknown))
+ *ppv = (IUnknown *)sink;
+ else if (WIN_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
+ *ppv = (ITfInputProcessorProfileActivationSink *)sink;
+
+ if (*ppv) {
+ TSFSink_AddRef(sink);
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
+{
+ static const GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } };
+ SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
+ videodata->ime_candlistindexbase = WIN_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1;
+ if (WIN_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE))
+ IME_InputLangChanged((SDL_VideoData *)sink->data);
+
+ IME_HideCandidateList(videodata);
+ return S_OK;
+}
+
+static void *vtUIElementSink[] = {
+ (void *)(UIElementSink_QueryInterface),
+ (void *)(TSFSink_AddRef),
+ (void *)(TSFSink_Release),
+ (void *)(UIElementSink_BeginUIElement),
+ (void *)(UIElementSink_UpdateUIElement),
+ (void *)(UIElementSink_EndUIElement)
+};
+
+static void *vtIPPASink[] = {
+ (void *)(IPPASink_QueryInterface),
+ (void *)(TSFSink_AddRef),
+ (void *)(TSFSink_Release),
+ (void *)(IPPASink_OnActivated)
+};
+
+static void
+UILess_EnableUIUpdates(SDL_VideoData *videodata)
+{
+ ITfSource *source = 0;
+ if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE)
+ return;
+
+ if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
+ source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie);
+ source->lpVtbl->Release(source);
+ }
+}
+
+static void
+UILess_DisableUIUpdates(SDL_VideoData *videodata)
+{
+ ITfSource *source = 0;
+ if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE)
+ return;
+
+ if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
+ source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
+ videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE;
+ source->lpVtbl->Release(source);
+ }
+}
+
+static SDL_bool
+UILess_SetupSinks(SDL_VideoData *videodata)
+{
+ TfClientId clientid = 0;
+ SDL_bool result = SDL_FALSE;
+ ITfSource *source = 0;
+ if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex)))
+ return SDL_FALSE;
+
+ if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY)))
+ return SDL_FALSE;
+
+ videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink));
+ videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink));
+
+ videodata->ime_uielemsink->lpVtbl = vtUIElementSink;
+ videodata->ime_uielemsink->refcount = 1;
+ videodata->ime_uielemsink->data = videodata;
+
+ videodata->ime_ippasink->lpVtbl = vtIPPASink;
+ videodata->ime_ippasink->refcount = 1;
+ videodata->ime_ippasink->data = videodata;
+
+ if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
+ if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) {
+ if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) {
+ result = SDL_TRUE;
+ }
+ }
+ source->lpVtbl->Release(source);
+ }
+ return result;
+}
+
+#define SAFE_RELEASE(p) \
+{ \
+ if (p) { \
+ (p)->lpVtbl->Release((p)); \
+ (p) = 0; \
+ } \
+}
+
+static void
+UILess_ReleaseSinks(SDL_VideoData *videodata)
+{
+ ITfSource *source = 0;
+ if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
+ source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
+ source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie);
+ SAFE_RELEASE(source);
+ videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex);
+ SAFE_RELEASE(videodata->ime_threadmgrex);
+ TSFSink_Release(videodata->ime_uielemsink);
+ videodata->ime_uielemsink = 0;
+ TSFSink_Release(videodata->ime_ippasink);
+ videodata->ime_ippasink = 0;
+ }
+}
+
+static void *
+StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height)
+{
+ BITMAPINFO info;
+ BITMAPINFOHEADER *infoHeader = &info.bmiHeader;
+ BYTE *bits = NULL;
+ if (hhbm) {
+ SDL_zero(info);
+ infoHeader->biSize = sizeof(BITMAPINFOHEADER);
+ infoHeader->biWidth = width;
+ infoHeader->biHeight = -1 * SDL_abs(height);
+ infoHeader->biPlanes = 1;
+ infoHeader->biBitCount = 32;
+ infoHeader->biCompression = BI_RGB;
+ *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (void **)&bits, 0, 0);
+ if (*hhbm)
+ SelectObject(hdc, *hhbm);
+ }
+ return bits;
+}
+
+static void
+StopDrawToBitmap(HDC hdc, HBITMAP *hhbm)
+{
+ if (hhbm && *hhbm) {
+ DeleteObject(*hhbm);
+ *hhbm = NULL;
+ }
+}
+
+/* This draws only within the specified area and fills the entire region. */
+static void
+DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize)
+{
+ /* The case of no pen (PenSize = 0) is automatically taken care of. */
+ const int penadjust = (int)SDL_floor(pensize / 2.0f - 0.5f);
+ left += pensize / 2;
+ top += pensize / 2;
+ right -= penadjust;
+ bottom -= penadjust;
+ Rectangle(hdc, left, top, right, bottom);
+}
+
+static void
+IME_DestroyTextures(SDL_VideoData *videodata)
+{
+}
+
+#define SDL_swap(a,b) { \
+ int c = (a); \
+ (a) = (b); \
+ (b) = c; \
+ }
+
+static void
+IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size)
+{
+ int left, top, right, bottom;
+ SDL_bool ok = SDL_FALSE;
+ int winw = videodata->ime_winwidth;
+ int winh = videodata->ime_winheight;
+
+ /* Bottom */
+ left = videodata->ime_rect.x;
+ top = videodata->ime_rect.y + videodata->ime_rect.h;
+ right = left + size.cx;
+ bottom = top + size.cy;
+ if (right >= winw) {
+ left -= right - winw;
+ right = winw;
+ }
+ if (bottom < winh)
+ ok = SDL_TRUE;
+
+ /* Top */
+ if (!ok) {
+ left = videodata->ime_rect.x;
+ top = videodata->ime_rect.y - size.cy;
+ right = left + size.cx;
+ bottom = videodata->ime_rect.y;
+ if (right >= winw) {
+ left -= right - winw;
+ right = winw;
+ }
+ if (top >= 0)
+ ok = SDL_TRUE;
+ }
+
+ /* Right */
+ if (!ok) {
+ left = videodata->ime_rect.x + size.cx;
+ top = 0;
+ right = left + size.cx;
+ bottom = size.cy;
+ if (right < winw)
+ ok = SDL_TRUE;
+ }
+
+ /* Left */
+ if (!ok) {
+ left = videodata->ime_rect.x - size.cx;
+ top = 0;
+ right = videodata->ime_rect.x;
+ bottom = size.cy;
+ if (right >= 0)
+ ok = SDL_TRUE;
+ }
+
+ /* Window too small, show at (0,0) */
+ if (!ok) {
+ left = 0;
+ top = 0;
+ right = size.cx;
+ bottom = size.cy;
+ }
+
+ videodata->ime_candlistrect.x = left;
+ videodata->ime_candlistrect.y = top;
+ videodata->ime_candlistrect.w = right - left;
+ videodata->ime_candlistrect.h = bottom - top;
+}
+
+static void
+IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc)
+{
+ int i, j;
+ SIZE size = {0};
+ SIZE candsizes[MAX_CANDLIST];
+ SIZE maxcandsize = {0};
+ HBITMAP hbm = NULL;
+ const int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize);
+ SDL_bool vertical = videodata->ime_candvertical;
+
+ const int listborder = 1;
+ const int listpadding = 0;
+ const int listbordercolor = RGB(0xB4, 0xC7, 0xAA);
+ const int listfillcolor = RGB(255, 255, 255);
+
+ const int candborder = 1;
+ const int candpadding = 0;
+ const int candmargin = 1;
+ const COLORREF candbordercolor = RGB(255, 255, 255);
+ const COLORREF candfillcolor = RGB(255, 255, 255);
+ const COLORREF candtextcolor = RGB(0, 0, 0);
+ const COLORREF selbordercolor = RGB(0x84, 0xAC, 0xDD);
+ const COLORREF selfillcolor = RGB(0xD2, 0xE6, 0xFF);
+ const COLORREF seltextcolor = RGB(0, 0, 0);
+ const int horzcandspacing = 5;
+
+ HPEN listpen = listborder != 0 ? CreatePen(PS_SOLID, listborder, listbordercolor) : (HPEN)GetStockObject(NULL_PEN);
+ HBRUSH listbrush = CreateSolidBrush(listfillcolor);
+ HPEN candpen = candborder != 0 ? CreatePen(PS_SOLID, candborder, candbordercolor) : (HPEN)GetStockObject(NULL_PEN);
+ HBRUSH candbrush = CreateSolidBrush(candfillcolor);
+ HPEN selpen = candborder != 0 ? CreatePen(PS_DOT, candborder, selbordercolor) : (HPEN)GetStockObject(NULL_PEN);
+ HBRUSH selbrush = CreateSolidBrush(selfillcolor);
+ HFONT font = CreateFont((int)(1 + videodata->ime_rect.h * 0.75f), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("Microsoft Sans Serif"));
+
+ SetBkMode(hdc, TRANSPARENT);
+ SelectObject(hdc, font);
+
+ for (i = 0; i < candcount; ++i) {
+ const WCHAR *s = videodata->ime_candidates[i];
+ if (!*s)
+ break;
+
+ GetTextExtentPoint32W(hdc, s, (int)SDL_wcslen(s), &candsizes[i]);
+ maxcandsize.cx = SDL_max(maxcandsize.cx, candsizes[i].cx);
+ maxcandsize.cy = SDL_max(maxcandsize.cy, candsizes[i].cy);
+
+ }
+ if (vertical) {
+ size.cx =
+ (listborder * 2) +
+ (listpadding * 2) +
+ (candmargin * 2) +
+ (candborder * 2) +
+ (candpadding * 2) +
+ (maxcandsize.cx)
+ ;
+ size.cy =
+ (listborder * 2) +
+ (listpadding * 2) +
+ ((candcount + 1) * candmargin) +
+ (candcount * candborder * 2) +
+ (candcount * candpadding * 2) +
+ (candcount * maxcandsize.cy)
+ ;
+ }
+ else {
+ size.cx =
+ (listborder * 2) +
+ (listpadding * 2) +
+ ((candcount + 1) * candmargin) +
+ (candcount * candborder * 2) +
+ (candcount * candpadding * 2) +
+ ((candcount - 1) * horzcandspacing);
+ ;
+
+ for (i = 0; i < candcount; ++i)
+ size.cx += candsizes[i].cx;
+
+ size.cy =
+ (listborder * 2) +
+ (listpadding * 2) +
+ (candmargin * 2) +
+ (candborder * 2) +
+ (candpadding * 2) +
+ (maxcandsize.cy)
+ ;
+ }
+
+ StartDrawToBitmap(hdc, &hbm, size.cx, size.cy);
+
+ SelectObject(hdc, listpen);
+ SelectObject(hdc, listbrush);
+ DrawRect(hdc, 0, 0, size.cx, size.cy, listborder);
+
+ SelectObject(hdc, candpen);
+ SelectObject(hdc, candbrush);
+ SetTextColor(hdc, candtextcolor);
+ SetBkMode(hdc, TRANSPARENT);
+
+ for (i = 0; i < candcount; ++i) {
+ const WCHAR *s = videodata->ime_candidates[i];
+ int left, top, right, bottom;
+ if (!*s)
+ break;
+
+ if (vertical) {
+ left = listborder + listpadding + candmargin;
+ top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy);
+ right = size.cx - listborder - listpadding - candmargin;
+ bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2);
+ }
+ else {
+ left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing);
+
+ for (j = 0; j < i; ++j)
+ left += candsizes[j].cx;
+
+ top = listborder + listpadding + candmargin;
+ right = left + candsizes[i].cx + (candpadding * 2) + (candborder * 2);
+ bottom = size.cy - listborder - listpadding - candmargin;
+ }
+
+ if (i == videodata->ime_candsel) {
+ SelectObject(hdc, selpen);
+ SelectObject(hdc, selbrush);
+ SetTextColor(hdc, seltextcolor);
+ }
+ else {
+ SelectObject(hdc, candpen);
+ SelectObject(hdc, candbrush);
+ SetTextColor(hdc, candtextcolor);
+ }
+
+ DrawRect(hdc, left, top, right, bottom, candborder);
+ ExtTextOutW(hdc, left + candborder + candpadding, top + candborder + candpadding, 0, NULL, s, (int)SDL_wcslen(s), NULL);
+ }
+ StopDrawToBitmap(hdc, &hbm);
+
+ DeleteObject(listpen);
+ DeleteObject(listbrush);
+ DeleteObject(candpen);
+ DeleteObject(candbrush);
+ DeleteObject(selpen);
+ DeleteObject(selbrush);
+ DeleteObject(font);
+
+ IME_PositionCandidateList(videodata, size);
+}
+
+static void
+IME_Render(SDL_VideoData *videodata)
+{
+ HDC hdc = CreateCompatibleDC(NULL);
+
+ if (videodata->ime_candlist)
+ IME_RenderCandidateList(videodata, hdc);
+
+ DeleteDC(hdc);
+
+ videodata->ime_dirty = SDL_FALSE;
+}
+
+void IME_Present(SDL_VideoData *videodata)
+{
+ if (videodata->ime_dirty)
+ IME_Render(videodata);
+
+ /* FIXME: Need to show the IME bitmap */
+}
+
+#endif /* SDL_DISABLE_WINDOWS_IME */
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.h
new file mode 100644
index 0000000..49a1b87
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowskeyboard.h
@@ -0,0 +1,40 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowskeyboard_h_
+#define SDL_windowskeyboard_h_
+
+extern void WIN_InitKeyboard(_THIS);
+extern void WIN_UpdateKeymap(void);
+extern void WIN_QuitKeyboard(_THIS);
+
+extern void WIN_ResetDeadKeys(void);
+
+extern void WIN_StartTextInput(_THIS);
+extern void WIN_StopTextInput(_THIS);
+extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect);
+
+extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata);
+
+#endif /* SDL_windowskeyboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.c
new file mode 100644
index 0000000..9ddb9e2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.c
@@ -0,0 +1,905 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)-1)
+#endif
+#endif
+
+#include "../../core/windows/SDL_windows.h"
+
+#include "SDL_assert.h"
+#include "SDL_windowsvideo.h"
+#include "SDL_windowstaskdialog.h"
+
+#ifndef SS_EDITCONTROL
+#define SS_EDITCONTROL 0x2000
+#endif
+
+#ifndef IDOK
+#define IDOK 1
+#endif
+
+#ifndef IDCANCEL
+#define IDCANCEL 2
+#endif
+
+/* Custom dialog return codes */
+#define IDCLOSED 20
+#define IDINVALPTRINIT 50
+#define IDINVALPTRCOMMAND 51
+#define IDINVALPTRSETFOCUS 52
+#define IDINVALPTRDLGITEM 53
+/* First button ID */
+#define IDBUTTONINDEX0 100
+
+#define DLGITEMTYPEBUTTON 0x0080
+#define DLGITEMTYPESTATIC 0x0082
+
+/* Windows only sends the lower 16 bits of the control ID when a button
+ * gets clicked. There are also some predefined and custom IDs that lower
+ * the available number further. 2^16 - 101 buttons should be enough for
+ * everyone, no need to make the code more complex.
+ */
+#define MAX_BUTTONS (0xffff - 100)
+
+
+/* Display a Windows message box */
+
+#pragma pack(push, 1)
+
+typedef struct
+{
+ WORD dlgVer;
+ WORD signature;
+ DWORD helpID;
+ DWORD exStyle;
+ DWORD style;
+ WORD cDlgItems;
+ short x;
+ short y;
+ short cx;
+ short cy;
+} DLGTEMPLATEEX;
+
+typedef struct
+{
+ DWORD helpID;
+ DWORD exStyle;
+ DWORD style;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ DWORD id;
+} DLGITEMTEMPLATEEX;
+
+#pragma pack(pop)
+
+typedef struct
+{
+ DLGTEMPLATEEX* lpDialog;
+ Uint8 *data;
+ size_t size;
+ size_t used;
+ WORD numbuttons;
+} WIN_DialogData;
+
+static SDL_bool GetButtonIndex(const SDL_MessageBoxData *messageboxdata, Uint32 flags, size_t *i)
+{
+ for (*i = 0; *i < (size_t)messageboxdata->numbuttons; ++*i) {
+ if (messageboxdata->buttons[*i].flags & flags) {
+ return SDL_TRUE;
+ }
+ }
+ return SDL_FALSE;
+}
+
+static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
+{
+ const SDL_MessageBoxData *messageboxdata;
+ size_t buttonindex;
+
+ switch ( iMessage ) {
+ case WM_INITDIALOG:
+ if (lParam == 0) {
+ EndDialog(hDlg, IDINVALPTRINIT);
+ return TRUE;
+ }
+ messageboxdata = (const SDL_MessageBoxData *)lParam;
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
+
+ if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
+ /* Focus on the first default return-key button */
+ HWND buttonctl = GetDlgItem(hDlg, (int)(IDBUTTONINDEX0 + buttonindex));
+ if (buttonctl == NULL) {
+ EndDialog(hDlg, IDINVALPTRDLGITEM);
+ }
+ PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)buttonctl, TRUE);
+ } else {
+ /* Give the focus to the dialog window instead */
+ SetFocus(hDlg);
+ }
+ return FALSE;
+ case WM_SETFOCUS:
+ messageboxdata = (const SDL_MessageBoxData *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if (messageboxdata == NULL) {
+ EndDialog(hDlg, IDINVALPTRSETFOCUS);
+ return TRUE;
+ }
+
+ /* Let the default button be focused if there is one. Otherwise, prevent any initial focus. */
+ if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
+ return FALSE;
+ }
+ return TRUE;
+ case WM_COMMAND:
+ messageboxdata = (const SDL_MessageBoxData *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ if (messageboxdata == NULL) {
+ EndDialog(hDlg, IDINVALPTRCOMMAND);
+ return TRUE;
+ }
+
+ /* Return the ID of the button that was pushed */
+ if (wParam == IDOK) {
+ if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) {
+ EndDialog(hDlg, IDBUTTONINDEX0 + buttonindex);
+ }
+ } else if (wParam == IDCANCEL) {
+ if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, &buttonindex)) {
+ EndDialog(hDlg, IDBUTTONINDEX0 + buttonindex);
+ } else {
+ /* Closing of window was requested by user or system. It would be rude not to comply. */
+ EndDialog(hDlg, IDCLOSED);
+ }
+ } else if (wParam >= IDBUTTONINDEX0 && (int)wParam - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
+ EndDialog(hDlg, wParam);
+ }
+ return TRUE;
+
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
+{
+ /* Growing memory in 64 KiB steps. */
+ const size_t sizestep = 0x10000;
+ size_t size = dialog->size;
+
+ if (size == 0) {
+ /* Start with 4 KiB or a multiple of 64 KiB to fit the data. */
+ size = 0x1000;
+ if (SIZE_MAX - sizestep < space) {
+ size = space;
+ } else if (space > size) {
+ size = (space + sizestep) & ~(sizestep - 1);
+ }
+ } else if (SIZE_MAX - dialog->used < space) {
+ SDL_OutOfMemory();
+ return SDL_FALSE;
+ } else if (SIZE_MAX - (dialog->used + space) < sizestep) {
+ /* Close to the maximum. */
+ size = dialog->used + space;
+ } else if (size < dialog->used + space) {
+ /* Round up to the next 64 KiB block. */
+ size = dialog->used + space;
+ size += sizestep - size % sizestep;
+ }
+
+ if (size > dialog->size) {
+ void *data = SDL_realloc(dialog->data, size);
+ if (!data) {
+ SDL_OutOfMemory();
+ return SDL_FALSE;
+ }
+ dialog->data = data;
+ dialog->size = size;
+ dialog->lpDialog = (DLGTEMPLATEEX*)dialog->data;
+ }
+ return SDL_TRUE;
+}
+
+static SDL_bool AlignDialogData(WIN_DialogData *dialog, size_t size)
+{
+ size_t padding = (dialog->used % size);
+
+ if (!ExpandDialogSpace(dialog, padding)) {
+ return SDL_FALSE;
+ }
+
+ dialog->used += padding;
+
+ return SDL_TRUE;
+}
+
+static SDL_bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t size)
+{
+ if (!ExpandDialogSpace(dialog, size)) {
+ return SDL_FALSE;
+ }
+
+ SDL_memcpy(dialog->data+dialog->used, data, size);
+ dialog->used += size;
+
+ return SDL_TRUE;
+}
+
+static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string)
+{
+ WCHAR *wstring;
+ WCHAR *p;
+ size_t count;
+ SDL_bool status;
+
+ if (!string) {
+ string = "";
+ }
+
+ wstring = WIN_UTF8ToString(string);
+ if (!wstring) {
+ return SDL_FALSE;
+ }
+
+ /* Find out how many characters we have, including null terminator */
+ count = 0;
+ for (p = wstring; *p; ++p) {
+ ++count;
+ }
+ ++count;
+
+ status = AddDialogData(dialog, wstring, count*sizeof(WCHAR));
+ SDL_free(wstring);
+ return status;
+}
+
+static int s_BaseUnitsX;
+static int s_BaseUnitsY;
+static void Vec2ToDLU(short *x, short *y)
+{
+ SDL_assert(s_BaseUnitsX != 0); /* we init in WIN_ShowMessageBox(), which is the only public function... */
+
+ *x = MulDiv(*x, 4, s_BaseUnitsX);
+ *y = MulDiv(*y, 8, s_BaseUnitsY);
+}
+
+
+static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style, DWORD exStyle, int x, int y, int w, int h, int id, const char *caption, WORD ordinal)
+{
+ DLGITEMTEMPLATEEX item;
+ WORD marker = 0xFFFF;
+ WORD extraData = 0;
+
+ SDL_zero(item);
+ item.style = style;
+ item.exStyle = exStyle;
+ item.x = x;
+ item.y = y;
+ item.cx = w;
+ item.cy = h;
+ item.id = id;
+
+ Vec2ToDLU(&item.x, &item.y);
+ Vec2ToDLU(&item.cx, &item.cy);
+
+ if (!AlignDialogData(dialog, sizeof(DWORD))) {
+ return SDL_FALSE;
+ }
+ if (!AddDialogData(dialog, &item, sizeof(item))) {
+ return SDL_FALSE;
+ }
+ if (!AddDialogData(dialog, &marker, sizeof(marker))) {
+ return SDL_FALSE;
+ }
+ if (!AddDialogData(dialog, &type, sizeof(type))) {
+ return SDL_FALSE;
+ }
+ if (type == DLGITEMTYPEBUTTON || (type == DLGITEMTYPESTATIC && caption != NULL)) {
+ if (!AddDialogString(dialog, caption)) {
+ return SDL_FALSE;
+ }
+ } else {
+ if (!AddDialogData(dialog, &marker, sizeof(marker))) {
+ return SDL_FALSE;
+ }
+ if (!AddDialogData(dialog, &ordinal, sizeof(ordinal))) {
+ return SDL_FALSE;
+ }
+ }
+ if (!AddDialogData(dialog, &extraData, sizeof(extraData))) {
+ return SDL_FALSE;
+ }
+ if (type == DLGITEMTYPEBUTTON) {
+ dialog->numbuttons++;
+ }
+ ++dialog->lpDialog->cDlgItems;
+
+ return SDL_TRUE;
+}
+
+static SDL_bool AddDialogStaticText(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
+{
+ DWORD style = WS_VISIBLE | WS_CHILD | SS_LEFT | SS_NOPREFIX | SS_EDITCONTROL | WS_GROUP;
+ return AddDialogControl(dialog, DLGITEMTYPESTATIC, style, 0, x, y, w, h, -1, text, 0);
+}
+
+static SDL_bool AddDialogStaticIcon(WIN_DialogData *dialog, int x, int y, int w, int h, Uint16 ordinal)
+{
+ DWORD style = WS_VISIBLE | WS_CHILD | SS_ICON | WS_GROUP;
+ return AddDialogControl(dialog, DLGITEMTYPESTATIC, style, 0, x, y, w, h, -2, NULL, ordinal);
+}
+
+static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text, int id, SDL_bool isDefault)
+{
+ DWORD style = WS_VISIBLE | WS_CHILD | WS_TABSTOP;
+ if (isDefault) {
+ style |= BS_DEFPUSHBUTTON;
+ } else {
+ style |= BS_PUSHBUTTON;
+ }
+ /* The first button marks the start of the group. */
+ if (dialog->numbuttons == 0) {
+ style |= WS_GROUP;
+ }
+ return AddDialogControl(dialog, DLGITEMTYPEBUTTON, style, 0, x, y, w, h, IDBUTTONINDEX0 + dialog->numbuttons, text, 0);
+}
+
+static void FreeDialogData(WIN_DialogData *dialog)
+{
+ SDL_free(dialog->data);
+ SDL_free(dialog);
+}
+
+static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
+{
+ WIN_DialogData *dialog;
+ DLGTEMPLATEEX dialogTemplate;
+ WORD WordToPass;
+
+ SDL_zero(dialogTemplate);
+ dialogTemplate.dlgVer = 1;
+ dialogTemplate.signature = 0xffff;
+ dialogTemplate.style = (WS_CAPTION | DS_CENTER | DS_SHELLFONT);
+ dialogTemplate.x = 0;
+ dialogTemplate.y = 0;
+ dialogTemplate.cx = w;
+ dialogTemplate.cy = h;
+ Vec2ToDLU(&dialogTemplate.cx, &dialogTemplate.cy);
+
+ dialog = (WIN_DialogData *)SDL_calloc(1, sizeof(*dialog));
+ if (!dialog) {
+ return NULL;
+ }
+
+ if (!AddDialogData(dialog, &dialogTemplate, sizeof(dialogTemplate))) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* No menu */
+ WordToPass = 0;
+ if (!AddDialogData(dialog, &WordToPass, 2)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* No custom class */
+ if (!AddDialogData(dialog, &WordToPass, 2)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* title */
+ if (!AddDialogString(dialog, caption)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* Font stuff */
+ {
+ /*
+ * We want to use the system messagebox font.
+ */
+ BYTE ToPass;
+
+ NONCLIENTMETRICSA NCM;
+ NCM.cbSize = sizeof(NCM);
+ SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
+
+ /* Font size - convert to logical font size for dialog parameter. */
+ {
+ HDC ScreenDC = GetDC(NULL);
+ int LogicalPixelsY = GetDeviceCaps(ScreenDC, LOGPIXELSY);
+ if (!LogicalPixelsY) /* This can happen if the application runs out of GDI handles */
+ LogicalPixelsY = 72;
+ WordToPass = (WORD)(-72 * NCM.lfMessageFont.lfHeight / LogicalPixelsY);
+ ReleaseDC(NULL, ScreenDC);
+ }
+
+ if (!AddDialogData(dialog, &WordToPass, 2)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* Font weight */
+ WordToPass = (WORD)NCM.lfMessageFont.lfWeight;
+ if (!AddDialogData(dialog, &WordToPass, 2)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* italic? */
+ ToPass = NCM.lfMessageFont.lfItalic;
+ if (!AddDialogData(dialog, &ToPass, 1)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* charset? */
+ ToPass = NCM.lfMessageFont.lfCharSet;
+ if (!AddDialogData(dialog, &ToPass, 1)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+
+ /* font typeface. */
+ if (!AddDialogString(dialog, NCM.lfMessageFont.lfFaceName)) {
+ FreeDialogData(dialog);
+ return NULL;
+ }
+ }
+
+ return dialog;
+}
+
+/* Escaping ampersands is necessary to disable mnemonics in dialog controls.
+ * The caller provides a char** for dst and a size_t* for dstlen where the
+ * address of the work buffer and its size will be stored. Their values must be
+ * NULL and 0 on the first call. src is the string to be escaped. On error, the
+ * function returns NULL and, on success, returns a pointer to the escaped
+ * sequence as a read-only string that is valid until the next call or until the
+ * work buffer is freed. Once all strings have been processed, it's the caller's
+ * responsibilty to free the work buffer with SDL_free, even on errors.
+ */
+static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src)
+{
+ char *newdst;
+ size_t ampcount = 0;
+ size_t srclen = 0;
+
+ if (src == NULL) {
+ return NULL;
+ }
+
+ while (src[srclen]) {
+ if (src[srclen] == '&') {
+ ampcount++;
+ }
+ srclen++;
+ }
+ srclen++;
+
+ if (ampcount == 0) {
+ /* Nothing to do. */
+ return src;
+ }
+ if (SIZE_MAX - srclen < ampcount) {
+ return NULL;
+ }
+ if (*dst == NULL || *dstlen < srclen + ampcount) {
+ /* Allocating extra space in case the next strings are a bit longer. */
+ size_t extraspace = SIZE_MAX - (srclen + ampcount);
+ if (extraspace > 512) {
+ extraspace = 512;
+ }
+ *dstlen = srclen + ampcount + extraspace;
+ SDL_free(*dst);
+ *dst = NULL;
+ newdst = SDL_malloc(*dstlen);
+ if (newdst == NULL) {
+ return NULL;
+ }
+ *dst = newdst;
+ } else {
+ newdst = *dst;
+ }
+
+ /* The escape character is the ampersand itself. */
+ while (srclen--) {
+ if (*src == '&') {
+ *newdst++ = '&';
+ }
+ *newdst++ = *src++;
+ }
+
+ return *dst;
+}
+
+/* This function is called if a Task Dialog is unsupported. */
+static int
+WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ WIN_DialogData *dialog;
+ int i, x, y, retval;
+ const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+ HFONT DialogFont;
+ SIZE Size;
+ RECT TextSize;
+ wchar_t* wmessage;
+ TEXTMETRIC TM;
+ HDC FontDC;
+ INT_PTR result;
+ char *ampescape = NULL;
+ size_t ampescapesize = 0;
+ Uint16 defbuttoncount = 0;
+ Uint16 icon = 0;
+
+ HWND ParentWindow = NULL;
+
+ const int ButtonWidth = 88;
+ const int ButtonHeight = 26;
+ const int TextMargin = 16;
+ const int ButtonMargin = 12;
+ const int IconWidth = GetSystemMetrics(SM_CXICON);
+ const int IconHeight = GetSystemMetrics(SM_CYICON);
+ const int IconMargin = 20;
+
+ if (messageboxdata->numbuttons > MAX_BUTTONS) {
+ return SDL_SetError("Number of butons exceeds limit of %d", MAX_BUTTONS);
+ }
+
+ switch (messageboxdata->flags) {
+ case SDL_MESSAGEBOX_ERROR:
+ icon = (Uint16)(size_t)IDI_ERROR;
+ break;
+ case SDL_MESSAGEBOX_WARNING:
+ icon = (Uint16)(size_t)IDI_WARNING;
+ break;
+ case SDL_MESSAGEBOX_INFORMATION:
+ icon = (Uint16)(size_t)IDI_INFORMATION;
+ break;
+ }
+
+ /* Jan 25th, 2013 - dant@fleetsa.com
+ *
+ *
+ * I've tried to make this more reasonable, but I've run in to a lot
+ * of nonsense.
+ *
+ * The original issue is the code was written in pixels and not
+ * dialog units (DLUs). All DialogBox functions use DLUs, which
+ * vary based on the selected font (yay).
+ *
+ * According to MSDN, the most reliable way to convert is via
+ * MapDialogUnits, which requires an HWND, which we don't have
+ * at time of template creation.
+ *
+ * We do however have:
+ * The system font (DLU width 8 for me)
+ * The font we select for the dialog (DLU width 6 for me)
+ *
+ * Based on experimentation, *neither* of these return the value
+ * actually used. Stepping in to MapDialogUnits(), the conversion
+ * is fairly clear, and uses 7 for me.
+ *
+ * As a result, some of this is hacky to ensure the sizing is
+ * somewhat correct.
+ *
+ * Honestly, a long term solution is to use CreateWindow, not CreateDialog.
+ *
+
+ *
+ * In order to get text dimensions we need to have a DC with the desired font.
+ * I'm assuming a dialog box in SDL is rare enough we can to the create.
+ */
+ FontDC = CreateCompatibleDC(0);
+
+ {
+ /* Create a duplicate of the font used in system message boxes. */
+ LOGFONT lf;
+ NONCLIENTMETRICS NCM;
+ NCM.cbSize = sizeof(NCM);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
+ lf = NCM.lfMessageFont;
+ DialogFont = CreateFontIndirect(&lf);
+ }
+
+ /* Select the font in to our DC */
+ SelectObject(FontDC, DialogFont);
+
+ {
+ /* Get the metrics to try and figure our DLU conversion. */
+ GetTextMetrics(FontDC, &TM);
+
+ /* Calculation from the following documentation:
+ * https://support.microsoft.com/en-gb/help/125681/how-to-calculate-dialog-base-units-with-non-system-based-font
+ * This fixes bug 2137, dialog box calculation with a fixed-width system font
+ */
+ {
+ SIZE extent;
+ GetTextExtentPoint32A(FontDC, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &extent);
+ s_BaseUnitsX = (extent.cx / 26 + 1) / 2;
+ }
+ /*s_BaseUnitsX = TM.tmAveCharWidth + 1;*/
+ s_BaseUnitsY = TM.tmHeight;
+ }
+
+ /* Measure the *pixel* size of the string. */
+ wmessage = WIN_UTF8ToString(messageboxdata->message);
+ SDL_zero(TextSize);
+ DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL);
+
+ /* Add margins and some padding for hangs, etc. */
+ TextSize.left += TextMargin;
+ TextSize.right += TextMargin + 2;
+ TextSize.top += TextMargin;
+ TextSize.bottom += TextMargin + 2;
+
+ /* Done with the DC, and the string */
+ DeleteDC(FontDC);
+ SDL_free(wmessage);
+
+ /* Increase the size of the dialog by some border spacing around the text. */
+ Size.cx = TextSize.right - TextSize.left;
+ Size.cy = TextSize.bottom - TextSize.top;
+ Size.cx += TextMargin * 2;
+ Size.cy += TextMargin * 2;
+
+ /* Make dialog wider and shift text over for the icon. */
+ if (icon) {
+ Size.cx += IconMargin + IconWidth;
+ TextSize.left += IconMargin + IconWidth;
+ TextSize.right += IconMargin + IconWidth;
+ }
+
+ /* Ensure the size is wide enough for all of the buttons. */
+ if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
+ Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;
+
+ /* Reset the height to the icon size if it is actually bigger than the text. */
+ if (icon && Size.cy < IconMargin * 2 + IconHeight) {
+ Size.cy = IconMargin * 2 + IconHeight;
+ }
+
+ /* Add vertical space for the buttons and border. */
+ Size.cy += ButtonHeight + TextMargin;
+
+ dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->title);
+ if (!dialog) {
+ return -1;
+ }
+
+ if (icon && ! AddDialogStaticIcon(dialog, IconMargin, IconMargin, IconWidth, IconHeight, icon)) {
+ FreeDialogData(dialog);
+ return -1;
+ }
+
+ if (!AddDialogStaticText(dialog, TextSize.left, TextSize.top, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
+ FreeDialogData(dialog);
+ return -1;
+ }
+
+ /* Align the buttons to the right/bottom. */
+ x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
+ y = Size.cy - ButtonHeight - ButtonMargin;
+ for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
+ SDL_bool isdefault = SDL_FALSE;
+ const char *buttontext;
+
+ if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
+ defbuttoncount++;
+ if (defbuttoncount == 1) {
+ isdefault = SDL_TRUE;
+ }
+ }
+
+ buttontext = EscapeAmpersands(&ampescape, &ampescapesize, buttons[i].text);
+ if (buttontext == NULL || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, buttons[i].buttonid, isdefault)) {
+ FreeDialogData(dialog);
+ SDL_free(ampescape);
+ return -1;
+ }
+ x += ButtonWidth + ButtonMargin;
+ }
+ SDL_free(ampescape);
+
+ /* If we have a parent window, get the Instance and HWND for them
+ * so that our little dialog gets exclusive focus at all times. */
+ if (messageboxdata->window) {
+ ParentWindow = ((SDL_WindowData*)messageboxdata->window->driverdata)->hwnd;
+ }
+
+ result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc, (LPARAM)messageboxdata);
+ if (result >= IDBUTTONINDEX0 && result - IDBUTTONINDEX0 < messageboxdata->numbuttons) {
+ *buttonid = messageboxdata->buttons[(messageboxdata->numbuttons - 1) - (result - IDBUTTONINDEX0)].buttonid;
+ retval = 0;
+ } else if (result == IDCLOSED) {
+ /* Dialog window closed by user or system. */
+ /* This could use a special return code. */
+ retval = 0;
+ *buttonid = -1;
+ } else {
+ if (result == 0) {
+ SDL_SetError("Invalid parent window handle");
+ } else if (result == -1) {
+ SDL_SetError("The message box encountered an error.");
+ } else if (result == IDINVALPTRINIT || result == IDINVALPTRSETFOCUS || result == IDINVALPTRCOMMAND) {
+ SDL_SetError("Invalid message box pointer in dialog procedure");
+ } else if (result == IDINVALPTRDLGITEM) {
+ SDL_SetError("Couldn't find dialog control of the default enter-key button");
+ } else {
+ SDL_SetError("An unknown error occured");
+ }
+ retval = -1;
+ }
+
+ FreeDialogData(dialog);
+ return retval;
+}
+
+/* TaskDialogIndirect procedure
+ * This is because SDL targets Windows XP (0x501), so this is not defined in the platform SDK.
+ */
+typedef HRESULT(FAR WINAPI *TASKDIALOGINDIRECTPROC)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked);
+
+int
+WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ HWND ParentWindow = NULL;
+ wchar_t *wmessage;
+ wchar_t *wtitle;
+ TASKDIALOGCONFIG TaskConfig;
+ TASKDIALOG_BUTTON *pButtons;
+ TASKDIALOG_BUTTON *pButton;
+ HMODULE hComctl32;
+ TASKDIALOGINDIRECTPROC pfnTaskDialogIndirect;
+ HRESULT hr;
+ char *ampescape = NULL;
+ size_t ampescapesize = 0;
+ int nButton;
+ int nCancelButton;
+ int i;
+
+ if (SIZE_MAX / sizeof(TASKDIALOG_BUTTON) < messageboxdata->numbuttons) {
+ return SDL_OutOfMemory();
+ }
+
+ /* If we cannot load comctl32.dll use the old messagebox! */
+ hComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
+ if (hComctl32 == NULL) {
+ return WIN_ShowOldMessageBox(messageboxdata, buttonid);
+ }
+
+ /* If TaskDialogIndirect doesn't exist use the old messagebox!
+ This will fail prior to Windows Vista.
+ The manifest file in the application may require targeting version 6 of comctl32.dll, even
+ when we use LoadLibrary here!
+ If you don't want to bother with manifests, put this #pragma in your app's source code somewhere:
+ pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+ */
+ pfnTaskDialogIndirect = (TASKDIALOGINDIRECTPROC) GetProcAddress(hComctl32, "TaskDialogIndirect");
+ if (pfnTaskDialogIndirect == NULL) {
+ FreeLibrary(hComctl32);
+ return WIN_ShowOldMessageBox(messageboxdata, buttonid);
+ }
+
+ /* If we have a parent window, get the Instance and HWND for them
+ so that our little dialog gets exclusive focus at all times. */
+ if (messageboxdata->window) {
+ ParentWindow = ((SDL_WindowData *) messageboxdata->window->driverdata)->hwnd;
+ }
+
+ wmessage = WIN_UTF8ToString(messageboxdata->message);
+ wtitle = WIN_UTF8ToString(messageboxdata->title);
+
+ SDL_zero(TaskConfig);
+ TaskConfig.cbSize = sizeof (TASKDIALOGCONFIG);
+ TaskConfig.hwndParent = ParentWindow;
+ TaskConfig.dwFlags = TDF_SIZE_TO_CONTENT;
+ TaskConfig.pszWindowTitle = wtitle;
+ if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
+ TaskConfig.pszMainIcon = TD_ERROR_ICON;
+ } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
+ TaskConfig.pszMainIcon = TD_WARNING_ICON;
+ } else if (messageboxdata->flags & SDL_MESSAGEBOX_INFORMATION) {
+ TaskConfig.pszMainIcon = TD_INFORMATION_ICON;
+ } else {
+ TaskConfig.pszMainIcon = NULL;
+ }
+
+ TaskConfig.pszContent = wmessage;
+ TaskConfig.cButtons = messageboxdata->numbuttons;
+ pButtons = SDL_malloc(sizeof (TASKDIALOG_BUTTON) * messageboxdata->numbuttons);
+ TaskConfig.nDefaultButton = 0;
+ nCancelButton = 0;
+ for (i = 0; i < messageboxdata->numbuttons; i++)
+ {
+ const char *buttontext;
+ pButton = &pButtons[messageboxdata->numbuttons-1-i];
+ if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+ nCancelButton = messageboxdata->buttons[i].buttonid;
+ pButton->nButtonID = 2;
+ } else {
+ pButton->nButtonID = messageboxdata->buttons[i].buttonid + 1;
+ if (pButton->nButtonID >= 2) {
+ pButton->nButtonID++;
+ }
+ }
+ buttontext = EscapeAmpersands(&ampescape, &ampescapesize, messageboxdata->buttons[i].text);
+ if (buttontext == NULL) {
+ int j;
+ FreeLibrary(hComctl32);
+ SDL_free(ampescape);
+ SDL_free(wmessage);
+ SDL_free(wtitle);
+ for (j = 0; j < i; j++) {
+ SDL_free((wchar_t *) pButtons[j].pszButtonText);
+ }
+ SDL_free(pButtons);
+ return -1;
+ }
+ pButton->pszButtonText = WIN_UTF8ToString(buttontext);
+ if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
+ TaskConfig.nDefaultButton = pButton->nButtonID;
+ }
+ }
+ TaskConfig.pButtons = pButtons;
+
+ /* Show the Task Dialog */
+ hr = pfnTaskDialogIndirect(&TaskConfig, &nButton, NULL, NULL);
+
+ /* Free everything */
+ FreeLibrary(hComctl32);
+ SDL_free(ampescape);
+ SDL_free(wmessage);
+ SDL_free(wtitle);
+ for (i = 0; i < messageboxdata->numbuttons; i++) {
+ SDL_free((wchar_t *) pButtons[i].pszButtonText);
+ }
+ SDL_free(pButtons);
+
+ /* Check the Task Dialog was successful and give the result */
+ if (SUCCEEDED(hr)) {
+ if (nButton == 2) {
+ *buttonid = nCancelButton;
+ } else if (nButton > 2) {
+ *buttonid = nButton-1-1;
+ } else {
+ *buttonid = nButton-1;
+ }
+ return 0;
+ }
+
+ /* We failed showing the Task Dialog, use the old message box! */
+ return WIN_ShowOldMessageBox(messageboxdata, buttonid);
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.h
new file mode 100644
index 0000000..2cb29be
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmessagebox.h
@@ -0,0 +1,29 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+extern int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.c
new file mode 100644
index 0000000..7425d9a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.c
@@ -0,0 +1,407 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_windowsvideo.h"
+#include "../../../include/SDL_assert.h"
+#include "../../../include/SDL_log.h"
+
+/* Windows CE compatibility */
+#ifndef CDS_FULLSCREEN
+#define CDS_FULLSCREEN 0
+#endif
+
+/* #define DEBUG_MODES */
+
+static void
+WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
+{
+ SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
+ HDC hdc;
+
+ data->DeviceMode.dmFields =
+ (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
+ DM_DISPLAYFLAGS);
+
+ if (index == ENUM_CURRENT_SETTINGS
+ && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
+ char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
+ LPBITMAPINFO bmi;
+ HBITMAP hbm;
+ int logical_width = GetDeviceCaps( hdc, HORZRES );
+ int logical_height = GetDeviceCaps( hdc, VERTRES );
+
+ mode->w = logical_width;
+ mode->h = logical_height;
+
+ SDL_zero(bmi_data);
+ bmi = (LPBITMAPINFO) bmi_data;
+ bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+
+ hbm = CreateCompatibleBitmap(hdc, 1, 1);
+ GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
+ GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
+ DeleteObject(hbm);
+ DeleteDC(hdc);
+ if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
+ switch (*(Uint32 *) bmi->bmiColors) {
+ case 0x00FF0000:
+ mode->format = SDL_PIXELFORMAT_RGB888;
+ break;
+ case 0x000000FF:
+ mode->format = SDL_PIXELFORMAT_BGR888;
+ break;
+ case 0xF800:
+ mode->format = SDL_PIXELFORMAT_RGB565;
+ break;
+ case 0x7C00:
+ mode->format = SDL_PIXELFORMAT_RGB555;
+ break;
+ }
+ } else if (bmi->bmiHeader.biBitCount == 8) {
+ mode->format = SDL_PIXELFORMAT_INDEX8;
+ } else if (bmi->bmiHeader.biBitCount == 4) {
+ mode->format = SDL_PIXELFORMAT_INDEX4LSB;
+ }
+ } else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) {
+ /* FIXME: Can we tell what this will be? */
+ if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
+ switch (data->DeviceMode.dmBitsPerPel) {
+ case 32:
+ mode->format = SDL_PIXELFORMAT_RGB888;
+ break;
+ case 24:
+ mode->format = SDL_PIXELFORMAT_RGB24;
+ break;
+ case 16:
+ mode->format = SDL_PIXELFORMAT_RGB565;
+ break;
+ case 15:
+ mode->format = SDL_PIXELFORMAT_RGB555;
+ break;
+ case 8:
+ mode->format = SDL_PIXELFORMAT_INDEX8;
+ break;
+ case 4:
+ mode->format = SDL_PIXELFORMAT_INDEX4LSB;
+ break;
+ }
+ }
+ }
+}
+
+static SDL_bool
+WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
+{
+ SDL_DisplayModeData *data;
+ DEVMODE devmode;
+
+ devmode.dmSize = sizeof(devmode);
+ devmode.dmDriverExtra = 0;
+ if (!EnumDisplaySettings(deviceName, index, &devmode)) {
+ return SDL_FALSE;
+ }
+
+ data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
+ if (!data) {
+ return SDL_FALSE;
+ }
+
+ mode->driverdata = data;
+ data->DeviceMode = devmode;
+
+ mode->format = SDL_PIXELFORMAT_UNKNOWN;
+ mode->w = data->DeviceMode.dmPelsWidth;
+ mode->h = data->DeviceMode.dmPelsHeight;
+ mode->refresh_rate = data->DeviceMode.dmDisplayFrequency;
+
+ /* Fill in the mode information */
+ WIN_UpdateDisplayMode(_this, deviceName, index, mode);
+ return SDL_TRUE;
+}
+
+static SDL_bool
+WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEX *info)
+{
+ SDL_VideoDisplay display;
+ SDL_DisplayData *displaydata;
+ SDL_DisplayMode mode;
+ DISPLAY_DEVICE device;
+
+#ifdef DEBUG_MODES
+ SDL_Log("Display: %s\n", WIN_StringToUTF8(info->szDevice));
+#endif
+
+ if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode)) {
+ return SDL_FALSE;
+ }
+
+ displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
+ if (!displaydata) {
+ return SDL_FALSE;
+ }
+ SDL_memcpy(displaydata->DeviceName, info->szDevice,
+ sizeof(displaydata->DeviceName));
+ displaydata->MonitorHandle = hMonitor;
+
+ SDL_zero(display);
+ device.cb = sizeof(device);
+ if (EnumDisplayDevices(info->szDevice, 0, &device, 0)) {
+ display.name = WIN_StringToUTF8(device.DeviceString);
+ }
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ display.driverdata = displaydata;
+ SDL_AddVideoDisplay(&display);
+ SDL_free(display.name);
+ return SDL_TRUE;
+}
+
+typedef struct _WIN_AddDisplaysData {
+ SDL_VideoDevice *video_device;
+ SDL_bool want_primary;
+} WIN_AddDisplaysData;
+
+static BOOL CALLBACK
+WIN_AddDisplaysCallback(HMONITOR hMonitor,
+ HDC hdcMonitor,
+ LPRECT lprcMonitor,
+ LPARAM dwData)
+{
+ WIN_AddDisplaysData *data = (WIN_AddDisplaysData*)dwData;
+ MONITORINFOEX info;
+
+ SDL_zero(info);
+ info.cbSize = sizeof(info);
+
+ if (GetMonitorInfo(hMonitor, (LPMONITORINFO)&info) != 0) {
+ const SDL_bool is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY);
+
+ if (is_primary == data->want_primary) {
+ WIN_AddDisplay(data->video_device, hMonitor, &info);
+ }
+ }
+
+ // continue enumeration
+ return TRUE;
+}
+
+static void
+WIN_AddDisplays(_THIS)
+{
+ WIN_AddDisplaysData callback_data;
+ callback_data.video_device = _this;
+
+ callback_data.want_primary = SDL_TRUE;
+ EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data);
+
+ callback_data.want_primary = SDL_FALSE;
+ EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data);
+}
+
+int
+WIN_InitModes(_THIS)
+{
+ WIN_AddDisplays(_this);
+
+ if (_this->num_displays == 0) {
+ return SDL_SetError("No displays available");
+ }
+ return 0;
+}
+
+int
+WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
+{
+ const SDL_DisplayData *data = (const SDL_DisplayData *)display->driverdata;
+ MONITORINFO minfo;
+ BOOL rc;
+
+ SDL_zero(minfo);
+ minfo.cbSize = sizeof(MONITORINFO);
+ rc = GetMonitorInfo(data->MonitorHandle, &minfo);
+
+ if (!rc) {
+ return SDL_SetError("Couldn't find monitor data");
+ }
+
+ rect->x = minfo.rcMonitor.left;
+ rect->y = minfo.rcMonitor.top;
+ rect->w = minfo.rcMonitor.right - minfo.rcMonitor.left;
+ rect->h = minfo.rcMonitor.bottom - minfo.rcMonitor.top;
+
+ return 0;
+}
+
+int
+WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi_out, float * hdpi_out, float * vdpi_out)
+{
+ const SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
+ const SDL_VideoData *videodata = (SDL_VideoData *)display->device->driverdata;
+ float hdpi = 0, vdpi = 0, ddpi = 0;
+
+ if (videodata->GetDpiForMonitor) {
+ UINT hdpi_uint, vdpi_uint;
+ // Windows 8.1+ codepath
+ if (videodata->GetDpiForMonitor(displaydata->MonitorHandle, MDT_EFFECTIVE_DPI, &hdpi_uint, &vdpi_uint) == S_OK) {
+ // GetDpiForMonitor docs promise to return the same hdpi/vdpi
+ hdpi = (float)hdpi_uint;
+ vdpi = (float)hdpi_uint;
+ ddpi = (float)hdpi_uint;
+ } else {
+ return SDL_SetError("GetDpiForMonitor failed");
+ }
+ } else {
+ // Window 8.0 and below: same DPI for all monitors.
+ HDC hdc;
+ int hdpi_int, vdpi_int, hpoints, vpoints, hpix, vpix;
+ float hinches, vinches;
+
+ hdc = GetDC(NULL);
+ if (hdc == NULL) {
+ return SDL_SetError("GetDC failed");
+ }
+ hdpi_int = GetDeviceCaps(hdc, LOGPIXELSX);
+ vdpi_int = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+
+ hpoints = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ vpoints = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+
+ hpix = MulDiv(hpoints, hdpi_int, 96);
+ vpix = MulDiv(vpoints, vdpi_int, 96);
+
+ hinches = (float)hpoints / 96.0f;
+ vinches = (float)vpoints / 96.0f;
+
+ hdpi = (float)hdpi_int;
+ vdpi = (float)vdpi_int;
+ ddpi = SDL_ComputeDiagonalDPI(hpix, vpix, hinches, vinches);
+ }
+
+ if (ddpi_out) {
+ *ddpi_out = ddpi;
+ }
+ if (hdpi_out) {
+ *hdpi_out = hdpi;
+ }
+ if (vdpi_out) {
+ *vdpi_out = vdpi;
+ }
+
+ return ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
+}
+
+int
+WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
+{
+ const SDL_DisplayData *data = (const SDL_DisplayData *)display->driverdata;
+ MONITORINFO minfo;
+ BOOL rc;
+
+ SDL_zero(minfo);
+ minfo.cbSize = sizeof(MONITORINFO);
+ rc = GetMonitorInfo(data->MonitorHandle, &minfo);
+
+ if (!rc) {
+ return SDL_SetError("Couldn't find monitor data");
+ }
+
+ rect->x = minfo.rcWork.left;
+ rect->y = minfo.rcWork.top;
+ rect->w = minfo.rcWork.right - minfo.rcWork.left;
+ rect->h = minfo.rcWork.bottom - minfo.rcWork.top;
+
+ return 0;
+}
+
+void
+WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+ DWORD i;
+ SDL_DisplayMode mode;
+
+ for (i = 0;; ++i) {
+ if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode)) {
+ break;
+ }
+ if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
+ /* We don't support palettized modes now */
+ SDL_free(mode.driverdata);
+ continue;
+ }
+ if (mode.format != SDL_PIXELFORMAT_UNKNOWN) {
+ if (!SDL_AddDisplayMode(display, &mode)) {
+ SDL_free(mode.driverdata);
+ }
+ } else {
+ SDL_free(mode.driverdata);
+ }
+ }
+}
+
+int
+WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
+ SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
+ LONG status;
+
+ if (mode->driverdata == display->desktop_mode.driverdata) {
+ status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL);
+ } else {
+ status = ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL);
+ }
+ if (status != DISP_CHANGE_SUCCESSFUL) {
+ const char *reason = "Unknown reason";
+ switch (status) {
+ case DISP_CHANGE_BADFLAGS:
+ reason = "DISP_CHANGE_BADFLAGS";
+ break;
+ case DISP_CHANGE_BADMODE:
+ reason = "DISP_CHANGE_BADMODE";
+ break;
+ case DISP_CHANGE_BADPARAM:
+ reason = "DISP_CHANGE_BADPARAM";
+ break;
+ case DISP_CHANGE_FAILED:
+ reason = "DISP_CHANGE_FAILED";
+ break;
+ }
+ return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
+ }
+ EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
+ WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode);
+ return 0;
+}
+
+void
+WIN_QuitModes(_THIS)
+{
+ /* All fullscreen windows should have restored modes by now */
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.h
new file mode 100644
index 0000000..a5c19b7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmodes.h
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsmodes_h_
+#define SDL_windowsmodes_h_
+
+typedef struct
+{
+ TCHAR DeviceName[32];
+ HMONITOR MonitorHandle;
+} SDL_DisplayData;
+
+typedef struct
+{
+ DEVMODE DeviceMode;
+} SDL_DisplayModeData;
+
+extern int WIN_InitModes(_THIS);
+extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+extern int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+extern int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
+extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void WIN_QuitModes(_THIS);
+
+#endif /* SDL_windowsmodes_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.c
new file mode 100644
index 0000000..eff3160
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.c
@@ -0,0 +1,320 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_assert.h"
+#include "SDL_windowsvideo.h"
+
+#include "../../events/SDL_mouse_c.h"
+
+
+HCURSOR SDL_cursor = NULL;
+
+static int rawInputEnableCount = 0;
+
+static int
+ToggleRawInput(SDL_bool enabled)
+{
+ RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */
+
+ if (enabled) {
+ rawInputEnableCount++;
+ if (rawInputEnableCount > 1) {
+ return 0; /* already done. */
+ }
+ } else {
+ if (rawInputEnableCount == 0) {
+ return 0; /* already done. */
+ }
+ rawInputEnableCount--;
+ if (rawInputEnableCount > 0) {
+ return 0; /* not time to disable yet */
+ }
+ }
+
+ if (!enabled) {
+ rawMouse.dwFlags |= RIDEV_REMOVE;
+ }
+
+ /* (Un)register raw input for mice */
+ if (RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) {
+
+ /* Only return an error when registering. If we unregister and fail,
+ then it's probably that we unregistered twice. That's OK. */
+ if (enabled) {
+ return SDL_Unsupported();
+ }
+ }
+ return 0;
+}
+
+
+static SDL_Cursor *
+WIN_CreateDefaultCursor()
+{
+ SDL_Cursor *cursor;
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ cursor->driverdata = LoadCursor(NULL, IDC_ARROW);
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ /* msdn says cursor mask has to be padded out to word alignment. Not sure
+ if that means machine word or WORD, but this handles either case. */
+ const size_t pad = (sizeof (size_t) * 8); /* 32 or 64, or whatever. */
+ SDL_Cursor *cursor;
+ HICON hicon;
+ HDC hdc;
+ BITMAPV4HEADER bmh;
+ LPVOID pixels;
+ LPVOID maskbits;
+ size_t maskbitslen;
+ ICONINFO ii;
+
+ SDL_zero(bmh);
+ bmh.bV4Size = sizeof(bmh);
+ bmh.bV4Width = surface->w;
+ bmh.bV4Height = -surface->h; /* Invert the image */
+ bmh.bV4Planes = 1;
+ bmh.bV4BitCount = 32;
+ bmh.bV4V4Compression = BI_BITFIELDS;
+ bmh.bV4AlphaMask = 0xFF000000;
+ bmh.bV4RedMask = 0x00FF0000;
+ bmh.bV4GreenMask = 0x0000FF00;
+ bmh.bV4BlueMask = 0x000000FF;
+
+ maskbitslen = ((surface->w + (pad - (surface->w % pad))) / 8) * surface->h;
+ maskbits = SDL_stack_alloc(Uint8,maskbitslen);
+ if (maskbits == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* AND the cursor against full bits: no change. We already have alpha. */
+ SDL_memset(maskbits, 0xFF, maskbitslen);
+
+ hdc = GetDC(NULL);
+ SDL_zero(ii);
+ ii.fIcon = FALSE;
+ ii.xHotspot = (DWORD)hot_x;
+ ii.yHotspot = (DWORD)hot_y;
+ ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, DIB_RGB_COLORS, &pixels, NULL, 0);
+ ii.hbmMask = CreateBitmap(surface->w, surface->h, 1, 1, maskbits);
+ ReleaseDC(NULL, hdc);
+ SDL_stack_free(maskbits);
+
+ SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
+ SDL_assert(surface->pitch == surface->w * 4);
+ SDL_memcpy(pixels, surface->pixels, surface->h * surface->pitch);
+
+ hicon = CreateIconIndirect(&ii);
+
+ DeleteObject(ii.hbmColor);
+ DeleteObject(ii.hbmMask);
+
+ if (!hicon) {
+ WIN_SetError("CreateIconIndirect()");
+ return NULL;
+ }
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ cursor->driverdata = hicon;
+ } else {
+ DestroyIcon(hicon);
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+WIN_CreateSystemCursor(SDL_SystemCursor id)
+{
+ SDL_Cursor *cursor;
+ LPCTSTR name;
+
+ switch(id)
+ {
+ default:
+ SDL_assert(0);
+ return NULL;
+ case SDL_SYSTEM_CURSOR_ARROW: name = IDC_ARROW; break;
+ case SDL_SYSTEM_CURSOR_IBEAM: name = IDC_IBEAM; break;
+ case SDL_SYSTEM_CURSOR_WAIT: name = IDC_WAIT; break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR: name = IDC_CROSS; break;
+ case SDL_SYSTEM_CURSOR_WAITARROW: name = IDC_WAIT; break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE: name = IDC_SIZENWSE; break;
+ case SDL_SYSTEM_CURSOR_SIZENESW: name = IDC_SIZENESW; break;
+ case SDL_SYSTEM_CURSOR_SIZEWE: name = IDC_SIZEWE; break;
+ case SDL_SYSTEM_CURSOR_SIZENS: name = IDC_SIZENS; break;
+ case SDL_SYSTEM_CURSOR_SIZEALL: name = IDC_SIZEALL; break;
+ case SDL_SYSTEM_CURSOR_NO: name = IDC_NO; break;
+ case SDL_SYSTEM_CURSOR_HAND: name = IDC_HAND; break;
+ }
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ HICON hicon;
+
+ hicon = LoadCursor(NULL, name);
+
+ cursor->driverdata = hicon;
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static void
+WIN_FreeCursor(SDL_Cursor * cursor)
+{
+ HICON hicon = (HICON)cursor->driverdata;
+
+ DestroyIcon(hicon);
+ SDL_free(cursor);
+}
+
+static int
+WIN_ShowCursor(SDL_Cursor * cursor)
+{
+ if (cursor) {
+ SDL_cursor = (HCURSOR)cursor->driverdata;
+ } else {
+ SDL_cursor = NULL;
+ }
+ if (SDL_GetMouseFocus() != NULL) {
+ SetCursor(SDL_cursor);
+ }
+ return 0;
+}
+
+static void
+WIN_WarpMouse(SDL_Window * window, int x, int y)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ POINT pt;
+
+ /* Don't warp the mouse while we're doing a modal interaction */
+ if (data->in_title_click || data->focus_click_pending) {
+ return;
+ }
+
+ pt.x = x;
+ pt.y = y;
+ ClientToScreen(hwnd, &pt);
+ SetCursorPos(pt.x, pt.y);
+}
+
+static int
+WIN_WarpMouseGlobal(int x, int y)
+{
+ POINT pt;
+
+ pt.x = x;
+ pt.y = y;
+ SetCursorPos(pt.x, pt.y);
+ return 0;
+}
+
+static int
+WIN_SetRelativeMouseMode(SDL_bool enabled)
+{
+ return ToggleRawInput(enabled);
+}
+
+static int
+WIN_CaptureMouse(SDL_Window *window)
+{
+ if (!window) {
+ SDL_Window *focusWin = SDL_GetKeyboardFocus();
+ if (focusWin) {
+ WIN_OnWindowEnter(SDL_GetVideoDevice(), focusWin); /* make sure WM_MOUSELEAVE messages are (re)enabled. */
+ }
+ }
+
+ /* While we were thinking of SetCapture() when designing this API in SDL,
+ we didn't count on the fact that SetCapture() only tracks while the
+ left mouse button is held down! Instead, we listen for raw mouse input
+ and manually query the mouse when it leaves the window. :/ */
+ return ToggleRawInput(window != NULL);
+}
+
+static Uint32
+WIN_GetGlobalMouseState(int *x, int *y)
+{
+ Uint32 retval = 0;
+ POINT pt = { 0, 0 };
+ GetCursorPos(&pt);
+ *x = (int) pt.x;
+ *y = (int) pt.y;
+
+ retval |= GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0;
+ retval |= GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0;
+ retval |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0;
+ retval |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0;
+ retval |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0;
+
+ return retval;
+}
+
+void
+WIN_InitMouse(_THIS)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = WIN_CreateCursor;
+ mouse->CreateSystemCursor = WIN_CreateSystemCursor;
+ mouse->ShowCursor = WIN_ShowCursor;
+ mouse->FreeCursor = WIN_FreeCursor;
+ mouse->WarpMouse = WIN_WarpMouse;
+ mouse->WarpMouseGlobal = WIN_WarpMouseGlobal;
+ mouse->SetRelativeMouseMode = WIN_SetRelativeMouseMode;
+ mouse->CaptureMouse = WIN_CaptureMouse;
+ mouse->GetGlobalMouseState = WIN_GetGlobalMouseState;
+
+ SDL_SetDefaultCursor(WIN_CreateDefaultCursor());
+}
+
+void
+WIN_QuitMouse(_THIS)
+{
+ if (rawInputEnableCount) { /* force RAWINPUT off here. */
+ rawInputEnableCount = 1;
+ ToggleRawInput(SDL_FALSE);
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.h
new file mode 100644
index 0000000..775c32c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsmouse.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsmouse_h_
+#define SDL_windowsmouse_h_
+
+extern HCURSOR SDL_cursor;
+
+extern void WIN_InitMouse(_THIS);
+extern void WIN_QuitMouse(_THIS);
+
+#endif /* SDL_windowsmouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.c
new file mode 100644
index 0000000..c3ba56c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.c
@@ -0,0 +1,895 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_assert.h"
+#include "SDL_loadso.h"
+#include "SDL_windowsvideo.h"
+#include "SDL_windowsopengles.h"
+#include "SDL_hints.h"
+
+/* WGL implementation of SDL OpenGL support */
+
+#if SDL_VIDEO_OPENGL_WGL
+#include "SDL_opengl.h"
+
+#define DEFAULT_OPENGL "OPENGL32.DLL"
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#endif
+#endif
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_EXT_create_context_es2_profile
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_EXT_create_context_es_profile
+#define WGL_EXT_create_context_es_profile
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif
+
+#ifndef WGL_ARB_context_flush_control
+#define WGL_ARB_context_flush_control
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#endif
+
+#ifndef WGL_ARB_create_context_no_error
+#define WGL_ARB_create_context_no_error
+#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
+#endif
+
+typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
+ HGLRC
+ hShareContext,
+ const int
+ *attribList);
+
+int
+WIN_GL_LoadLibrary(_THIS, const char *path)
+{
+ void *handle;
+
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ }
+ if (path == NULL) {
+ path = DEFAULT_OPENGL;
+ }
+ _this->gl_config.dll_handle = SDL_LoadObject(path);
+ if (!_this->gl_config.dll_handle) {
+ return -1;
+ }
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+
+ /* Allocate OpenGL memory */
+ _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData));
+ if (!_this->gl_data) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Load function pointers */
+ handle = _this->gl_config.dll_handle;
+ _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
+ SDL_LoadFunction(handle, "wglGetProcAddress");
+ _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
+ SDL_LoadFunction(handle, "wglCreateContext");
+ _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
+ SDL_LoadFunction(handle, "wglDeleteContext");
+ _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
+ SDL_LoadFunction(handle, "wglMakeCurrent");
+ _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
+ SDL_LoadFunction(handle, "wglShareLists");
+
+ if (!_this->gl_data->wglGetProcAddress ||
+ !_this->gl_data->wglCreateContext ||
+ !_this->gl_data->wglDeleteContext ||
+ !_this->gl_data->wglMakeCurrent) {
+ return SDL_SetError("Could not retrieve OpenGL functions");
+ }
+
+ /* XXX Too sleazy? WIN_GL_InitExtensions looks for certain OpenGL
+ extensions via SDL_GL_DeduceMaxSupportedESProfile. This uses
+ SDL_GL_ExtensionSupported which in turn calls SDL_GL_GetProcAddress.
+ However SDL_GL_GetProcAddress will fail if the library is not
+ loaded; it checks for gl_config.driver_loaded > 0. To avoid this
+ test failing, increment driver_loaded around the call to
+ WIN_GLInitExtensions.
+
+ Successful loading of the library is normally indicated by
+ SDL_GL_LoadLibrary incrementing driver_loaded immediately after
+ this function returns 0 to it.
+
+ Alternatives to this are:
+ - moving SDL_GL_DeduceMaxSupportedESProfile to both the WIN and
+ X11 platforms while adding a function equivalent to
+ SDL_GL_ExtensionSupported but which directly calls
+ glGetProcAddress(). Having 3 copies of the
+ SDL_GL_ExtensionSupported makes this alternative unattractive.
+ - moving SDL_GL_DeduceMaxSupportedESProfile to a new file shared
+ by the WIN and X11 platforms while adding a function equivalent
+ to SDL_GL_ExtensionSupported. This is unattractive due to the
+ number of project files that will need updating, plus there
+ will be 2 copies of the SDL_GL_ExtensionSupported code.
+ - Add a private equivalent of SDL_GL_ExtensionSupported to
+ SDL_video.c.
+ - Move the call to WIN_GL_InitExtensions back to WIN_CreateWindow
+ and add a flag to gl_data to avoid multiple calls to this
+ expensive function. This is probably the least objectionable
+ alternative if this increment/decrement trick is unacceptable.
+
+ Note that the driver_loaded > 0 check needs to remain in
+ SDL_GL_ExtensionSupported and SDL_GL_GetProcAddress as they are
+ public API functions.
+ */
+ ++_this->gl_config.driver_loaded;
+ WIN_GL_InitExtensions(_this);
+ --_this->gl_config.driver_loaded;
+
+ return 0;
+}
+
+void *
+WIN_GL_GetProcAddress(_THIS, const char *proc)
+{
+ void *func;
+
+ /* This is to pick up extensions */
+ func = _this->gl_data->wglGetProcAddress(proc);
+ if (!func) {
+ /* This is probably a normal GL function */
+ func = GetProcAddress(_this->gl_config.dll_handle, proc);
+ }
+ return func;
+}
+
+void
+WIN_GL_UnloadLibrary(_THIS)
+{
+ SDL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+
+ /* Free OpenGL memory */
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
+}
+
+static void
+WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
+{
+ SDL_zerop(pfd);
+ pfd->nSize = sizeof(*pfd);
+ pfd->nVersion = 1;
+ pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
+ if (_this->gl_config.double_buffer) {
+ pfd->dwFlags |= PFD_DOUBLEBUFFER;
+ }
+ if (_this->gl_config.stereo) {
+ pfd->dwFlags |= PFD_STEREO;
+ }
+ pfd->iLayerType = PFD_MAIN_PLANE;
+ pfd->iPixelType = PFD_TYPE_RGBA;
+ pfd->cRedBits = _this->gl_config.red_size;
+ pfd->cGreenBits = _this->gl_config.green_size;
+ pfd->cBlueBits = _this->gl_config.blue_size;
+ pfd->cAlphaBits = _this->gl_config.alpha_size;
+ if (_this->gl_config.buffer_size) {
+ pfd->cColorBits =
+ _this->gl_config.buffer_size - _this->gl_config.alpha_size;
+ } else {
+ pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
+ }
+ pfd->cAccumRedBits = _this->gl_config.accum_red_size;
+ pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
+ pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
+ pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
+ pfd->cAccumBits =
+ (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
+ pfd->cAccumAlphaBits);
+ pfd->cDepthBits = _this->gl_config.depth_size;
+ pfd->cStencilBits = _this->gl_config.stencil_size;
+}
+
+/* Choose the closest pixel format that meets or exceeds the target.
+ FIXME: Should we weight any particular attribute over any other?
+*/
+static int
+WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ int count, index, best = 0;
+ unsigned int dist, best_dist = ~0U;
+
+ count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
+
+ for (index = 1; index <= count; index++) {
+
+ if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
+ continue;
+ }
+
+ if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
+ continue;
+ }
+
+ if (pfd.iLayerType != target->iLayerType) {
+ continue;
+ }
+ if (pfd.iPixelType != target->iPixelType) {
+ continue;
+ }
+
+ dist = 0;
+
+ if (pfd.cColorBits < target->cColorBits) {
+ continue;
+ } else {
+ dist += (pfd.cColorBits - target->cColorBits);
+ }
+ if (pfd.cRedBits < target->cRedBits) {
+ continue;
+ } else {
+ dist += (pfd.cRedBits - target->cRedBits);
+ }
+ if (pfd.cGreenBits < target->cGreenBits) {
+ continue;
+ } else {
+ dist += (pfd.cGreenBits - target->cGreenBits);
+ }
+ if (pfd.cBlueBits < target->cBlueBits) {
+ continue;
+ } else {
+ dist += (pfd.cBlueBits - target->cBlueBits);
+ }
+ if (pfd.cAlphaBits < target->cAlphaBits) {
+ continue;
+ } else {
+ dist += (pfd.cAlphaBits - target->cAlphaBits);
+ }
+ if (pfd.cAccumBits < target->cAccumBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumBits - target->cAccumBits);
+ }
+ if (pfd.cAccumRedBits < target->cAccumRedBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumRedBits - target->cAccumRedBits);
+ }
+ if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
+ }
+ if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
+ }
+ if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
+ }
+ if (pfd.cDepthBits < target->cDepthBits) {
+ continue;
+ } else {
+ dist += (pfd.cDepthBits - target->cDepthBits);
+ }
+ if (pfd.cStencilBits < target->cStencilBits) {
+ continue;
+ } else {
+ dist += (pfd.cStencilBits - target->cStencilBits);
+ }
+
+ if (dist < best_dist) {
+ best = index;
+ best_dist = dist;
+ }
+ }
+
+ return best;
+}
+
+static SDL_bool
+HasExtension(const char *extension, const char *extensions)
+{
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = SDL_strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return SDL_FALSE;
+
+ if (!extensions)
+ return SDL_FALSE;
+
+ /* It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings,
+ * etc. */
+
+ start = extensions;
+
+ for (;;) {
+ where = SDL_strstr(start, extension);
+ if (!where)
+ break;
+
+ terminator = where + SDL_strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0')
+ return SDL_TRUE;
+
+ start = terminator;
+ }
+ return SDL_FALSE;
+}
+
+void
+WIN_GL_InitExtensions(_THIS)
+{
+ const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
+ const char *extensions;
+ HWND hwnd;
+ HDC hdc;
+ HGLRC hglrc;
+ PIXELFORMATDESCRIPTOR pfd;
+
+ if (!_this->gl_data) {
+ return;
+ }
+
+ hwnd =
+ CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
+ 10, 10, NULL, NULL, SDL_Instance, NULL);
+ if (!hwnd) {
+ return;
+ }
+ WIN_PumpEvents(_this);
+
+ hdc = GetDC(hwnd);
+
+ WIN_GL_SetupPixelFormat(_this, &pfd);
+
+ SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
+
+ hglrc = _this->gl_data->wglCreateContext(hdc);
+ if (!hglrc) {
+ return;
+ }
+ _this->gl_data->wglMakeCurrent(hdc, hglrc);
+
+ wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
+ _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
+ if (wglGetExtensionsStringARB) {
+ extensions = wglGetExtensionsStringARB(hdc);
+ } else {
+ extensions = NULL;
+ }
+
+ /* Check for WGL_ARB_pixel_format */
+ _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
+ if (HasExtension("WGL_ARB_pixel_format", extensions)) {
+ _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
+ (HDC, const int *,
+ const FLOAT *, UINT,
+ int *, UINT *))
+ WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
+ _this->gl_data->wglGetPixelFormatAttribivARB =
+ (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
+ WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
+
+ if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
+ (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
+ _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
+ }
+ }
+
+ /* Check for WGL_EXT_swap_control */
+ _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
+ if (HasExtension("WGL_EXT_swap_control", extensions)) {
+ _this->gl_data->wglSwapIntervalEXT =
+ WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
+ _this->gl_data->wglGetSwapIntervalEXT =
+ WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
+ if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
+ _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
+ }
+ } else {
+ _this->gl_data->wglSwapIntervalEXT = NULL;
+ _this->gl_data->wglGetSwapIntervalEXT = NULL;
+ }
+
+ /* Check for WGL_EXT_create_context_es2_profile */
+ if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) {
+ SDL_GL_DeduceMaxSupportedESProfile(
+ &_this->gl_data->es_profile_max_supported_version.major,
+ &_this->gl_data->es_profile_max_supported_version.minor
+ );
+ }
+
+ /* Check for WGL_ARB_context_flush_control */
+ if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
+ _this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
+ }
+
+ /* Check for WGL_ARB_create_context_robustness */
+ if (HasExtension("WGL_ARB_create_context_robustness", extensions)) {
+ _this->gl_data->HAS_WGL_ARB_create_context_robustness = SDL_TRUE;
+ }
+
+ /* Check for WGL_ARB_create_context_no_error */
+ if (HasExtension("WGL_ARB_create_context_no_error", extensions)) {
+ _this->gl_data->HAS_WGL_ARB_create_context_no_error = SDL_TRUE;
+ }
+
+ _this->gl_data->wglMakeCurrent(hdc, NULL);
+ _this->gl_data->wglDeleteContext(hglrc);
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ WIN_PumpEvents(_this);
+}
+
+static int
+WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
+{
+ HWND hwnd;
+ HDC hdc;
+ PIXELFORMATDESCRIPTOR pfd;
+ HGLRC hglrc;
+ int pixel_format = 0;
+ unsigned int matching;
+
+ hwnd =
+ CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
+ 10, 10, NULL, NULL, SDL_Instance, NULL);
+ WIN_PumpEvents(_this);
+
+ hdc = GetDC(hwnd);
+
+ WIN_GL_SetupPixelFormat(_this, &pfd);
+
+ SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
+
+ hglrc = _this->gl_data->wglCreateContext(hdc);
+ if (hglrc) {
+ _this->gl_data->wglMakeCurrent(hdc, hglrc);
+
+ if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
+ _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
+ 1, &pixel_format,
+ &matching);
+ }
+
+ _this->gl_data->wglMakeCurrent(hdc, NULL);
+ _this->gl_data->wglDeleteContext(hglrc);
+ }
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ WIN_PumpEvents(_this);
+
+ return pixel_format;
+}
+
+/* actual work of WIN_GL_SetupWindow() happens here. */
+static int
+WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window)
+{
+ HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+ PIXELFORMATDESCRIPTOR pfd;
+ int pixel_format = 0;
+ int iAttribs[64];
+ int *iAttr;
+ int *iAccelAttr;
+ float fAttribs[1] = { 0 };
+
+ WIN_GL_SetupPixelFormat(_this, &pfd);
+
+ /* setup WGL_ARB_pixel_format attribs */
+ iAttr = &iAttribs[0];
+
+ *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
+ *iAttr++ = GL_TRUE;
+ *iAttr++ = WGL_RED_BITS_ARB;
+ *iAttr++ = _this->gl_config.red_size;
+ *iAttr++ = WGL_GREEN_BITS_ARB;
+ *iAttr++ = _this->gl_config.green_size;
+ *iAttr++ = WGL_BLUE_BITS_ARB;
+ *iAttr++ = _this->gl_config.blue_size;
+
+ if (_this->gl_config.alpha_size) {
+ *iAttr++ = WGL_ALPHA_BITS_ARB;
+ *iAttr++ = _this->gl_config.alpha_size;
+ }
+
+ *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
+ *iAttr++ = _this->gl_config.double_buffer;
+
+ *iAttr++ = WGL_DEPTH_BITS_ARB;
+ *iAttr++ = _this->gl_config.depth_size;
+
+ if (_this->gl_config.stencil_size) {
+ *iAttr++ = WGL_STENCIL_BITS_ARB;
+ *iAttr++ = _this->gl_config.stencil_size;
+ }
+
+ if (_this->gl_config.accum_red_size) {
+ *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_red_size;
+ }
+
+ if (_this->gl_config.accum_green_size) {
+ *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_green_size;
+ }
+
+ if (_this->gl_config.accum_blue_size) {
+ *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_blue_size;
+ }
+
+ if (_this->gl_config.accum_alpha_size) {
+ *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_alpha_size;
+ }
+
+ if (_this->gl_config.stereo) {
+ *iAttr++ = WGL_STEREO_ARB;
+ *iAttr++ = GL_TRUE;
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
+ *iAttr++ = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ *iAttr++ = WGL_SAMPLES_ARB;
+ *iAttr++ = _this->gl_config.multisamplesamples;
+ }
+
+ if (_this->gl_config.framebuffer_srgb_capable) {
+ *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
+ *iAttr++ = _this->gl_config.framebuffer_srgb_capable;
+ }
+
+ /* We always choose either FULL or NO accel on Windows, because of flaky
+ drivers. If the app didn't specify, we use FULL, because that's
+ probably what they wanted (and if you didn't care and got FULL, that's
+ a perfectly valid result in any case). */
+ *iAttr++ = WGL_ACCELERATION_ARB;
+ iAccelAttr = iAttr;
+ if (_this->gl_config.accelerated) {
+ *iAttr++ = WGL_FULL_ACCELERATION_ARB;
+ } else {
+ *iAttr++ = WGL_NO_ACCELERATION_ARB;
+ }
+
+ *iAttr = 0;
+
+ /* Choose and set the closest available pixel format */
+ pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
+
+ /* App said "don't care about accel" and FULL accel failed. Try NO. */
+ if ( ( !pixel_format ) && ( _this->gl_config.accelerated < 0 ) ) {
+ *iAccelAttr = WGL_NO_ACCELERATION_ARB;
+ pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
+ *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */
+ }
+ if (!pixel_format) {
+ pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
+ }
+ if (!pixel_format) {
+ return SDL_SetError("No matching GL pixel format available");
+ }
+ if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
+ return WIN_SetError("SetPixelFormat()");
+ }
+ return 0;
+}
+
+int
+WIN_GL_SetupWindow(_THIS, SDL_Window * window)
+{
+ /* The current context is lost in here; save it and reset it. */
+ SDL_Window *current_win = SDL_GL_GetCurrentWindow();
+ SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
+ const int retval = WIN_GL_SetupWindowInternal(_this, window);
+ WIN_GL_MakeCurrent(_this, current_win, current_ctx);
+ return retval;
+}
+
+SDL_bool
+WIN_GL_UseEGL(_THIS)
+{
+ SDL_assert(_this->gl_data != NULL);
+ SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
+
+ return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE)
+ || _this->gl_config.major_version == 1 /* No WGL extension for OpenGL ES 1.x profiles. */
+ || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major
+ || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major
+ && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor));
+}
+
+SDL_GLContext
+WIN_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+ HGLRC context, share_context;
+
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) {
+#if SDL_VIDEO_OPENGL_EGL
+ /* Switch to EGL based functions */
+ WIN_GL_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = WIN_GLES_LoadLibrary;
+ _this->GL_GetProcAddress = WIN_GLES_GetProcAddress;
+ _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
+ _this->GL_CreateContext = WIN_GLES_CreateContext;
+ _this->GL_MakeCurrent = WIN_GLES_MakeCurrent;
+ _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
+ _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
+ _this->GL_SwapWindow = WIN_GLES_SwapWindow;
+ _this->GL_DeleteContext = WIN_GLES_DeleteContext;
+
+ if (WIN_GLES_LoadLibrary(_this, NULL) != 0) {
+ return NULL;
+ }
+
+ return WIN_GLES_CreateContext(_this, window);
+#else
+ SDL_SetError("SDL not configured with EGL support");
+ return NULL;
+#endif
+ }
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (HGLRC)SDL_GL_GetCurrentContext();
+ } else {
+ share_context = 0;
+ }
+
+ if (_this->gl_config.major_version < 3 &&
+ _this->gl_config.profile_mask == 0 &&
+ _this->gl_config.flags == 0) {
+ /* Create legacy context */
+ context = _this->gl_data->wglCreateContext(hdc);
+ if( share_context != 0 ) {
+ _this->gl_data->wglShareLists(share_context, context);
+ }
+ } else {
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+ HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
+ if (!temp_context) {
+ SDL_SetError("Could not create GL context");
+ return NULL;
+ }
+
+ /* Make the context current */
+ if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
+ WIN_GL_DeleteContext(_this, temp_context);
+ return NULL;
+ }
+
+ wglCreateContextAttribsARB =
+ (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
+ wglGetProcAddress("wglCreateContextAttribsARB");
+ if (!wglCreateContextAttribsARB) {
+ SDL_SetError("GL 3.x is not supported");
+ context = temp_context;
+ } else {
+ int attribs[15]; /* max 14 attributes plus terminator */
+ int iattr = 0;
+
+ attribs[iattr++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
+ attribs[iattr++] = _this->gl_config.major_version;
+ attribs[iattr++] = WGL_CONTEXT_MINOR_VERSION_ARB;
+ attribs[iattr++] = _this->gl_config.minor_version;
+
+ /* SDL profile bits match WGL profile bits */
+ if (_this->gl_config.profile_mask != 0) {
+ attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attribs[iattr++] = _this->gl_config.profile_mask;
+ }
+
+ /* SDL flags match WGL flags */
+ if (_this->gl_config.flags != 0) {
+ attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
+ attribs[iattr++] = _this->gl_config.flags;
+ }
+
+ /* only set if wgl extension is available */
+ if (_this->gl_data->HAS_WGL_ARB_context_flush_control) {
+ attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
+ attribs[iattr++] = _this->gl_config.release_behavior ?
+ WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
+ WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
+ }
+
+ /* only set if wgl extension is available */
+ if (_this->gl_data->HAS_WGL_ARB_create_context_robustness) {
+ attribs[iattr++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
+ attribs[iattr++] = _this->gl_config.reset_notification ?
+ WGL_LOSE_CONTEXT_ON_RESET_ARB :
+ WGL_NO_RESET_NOTIFICATION_ARB;
+ }
+
+ /* only set if wgl extension is available */
+ if (_this->gl_data->HAS_WGL_ARB_create_context_no_error) {
+ attribs[iattr++] = WGL_CONTEXT_OPENGL_NO_ERROR_ARB;
+ attribs[iattr++] = _this->gl_config.no_error;
+ }
+
+ attribs[iattr++] = 0;
+
+ /* Create the GL 3.x context */
+ context = wglCreateContextAttribsARB(hdc, share_context, attribs);
+ /* Delete the GL 2.x context */
+ _this->gl_data->wglDeleteContext(temp_context);
+ }
+ }
+
+ if (!context) {
+ WIN_SetError("Could not create GL context");
+ return NULL;
+ }
+
+ if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
+ WIN_GL_DeleteContext(_this, context);
+ return NULL;
+ }
+
+ return context;
+}
+
+int
+WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ HDC hdc;
+
+ if (!_this->gl_data) {
+ return SDL_SetError("OpenGL not initialized");
+ }
+
+ /* sanity check that higher level handled this. */
+ SDL_assert(window || (!window && !context));
+
+ /* Some Windows drivers freak out if hdc is NULL, even when context is
+ NULL, against spec. Since hdc is _supposed_ to be ignored if context
+ is NULL, we either use the current GL window, or do nothing if we
+ already have no current context. */
+ if (!window) {
+ window = SDL_GL_GetCurrentWindow();
+ if (!window) {
+ SDL_assert(SDL_GL_GetCurrentContext() == NULL);
+ return 0; /* already done. */
+ }
+ }
+
+ hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+ if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
+ return WIN_SetError("wglMakeCurrent()");
+ }
+ return 0;
+}
+
+int
+WIN_GL_SetSwapInterval(_THIS, int interval)
+{
+ if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
+ return SDL_SetError("Negative swap interval unsupported in this GL");
+ } else if (_this->gl_data->wglSwapIntervalEXT) {
+ if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
+ return WIN_SetError("wglSwapIntervalEXT()");
+ }
+ } else {
+ return SDL_Unsupported();
+ }
+ return 0;
+}
+
+int
+WIN_GL_GetSwapInterval(_THIS)
+{
+ int retval = 0;
+ if (_this->gl_data->wglGetSwapIntervalEXT) {
+ retval = _this->gl_data->wglGetSwapIntervalEXT();
+ }
+ return retval;
+}
+
+int
+WIN_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+
+ if (!SwapBuffers(hdc)) {
+ return WIN_SetError("SwapBuffers()");
+ }
+ return 0;
+}
+
+void
+WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ if (!_this->gl_data) {
+ return;
+ }
+ _this->gl_data->wglDeleteContext((HGLRC) context);
+}
+
+
+SDL_bool
+WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow)
+{
+ HDC hfromdc = ((SDL_WindowData *) fromWindow->driverdata)->hdc;
+ HDC htodc = ((SDL_WindowData *) toWindow->driverdata)->hdc;
+ BOOL result;
+
+ /* get the pixel format of the fromWindow */
+ int pixel_format = GetPixelFormat(hfromdc);
+ PIXELFORMATDESCRIPTOR pfd;
+ SDL_memset(&pfd, 0, sizeof(pfd));
+ DescribePixelFormat(hfromdc, pixel_format, sizeof(pfd), &pfd);
+
+ /* set the pixel format of the toWindow */
+ result = SetPixelFormat(htodc, pixel_format, &pfd);
+
+ return result ? SDL_TRUE : SDL_FALSE;
+}
+
+#endif /* SDL_VIDEO_OPENGL_WGL */
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.h
new file mode 100644
index 0000000..8704411
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengl.h
@@ -0,0 +1,142 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsopengl_h_
+#define SDL_windowsopengl_h_
+
+#if SDL_VIDEO_OPENGL_WGL
+
+struct SDL_GLDriverData
+{
+ SDL_bool HAS_WGL_ARB_pixel_format;
+ SDL_bool HAS_WGL_EXT_swap_control_tear;
+ SDL_bool HAS_WGL_ARB_context_flush_control;
+ SDL_bool HAS_WGL_ARB_create_context_robustness;
+ SDL_bool HAS_WGL_ARB_create_context_no_error;
+
+ /* Max version of OpenGL ES context that can be created if the
+ implementation supports WGL_EXT_create_context_es2_profile.
+ major = minor = 0 when unsupported.
+ */
+ struct {
+ int major;
+ int minor;
+ } es_profile_max_supported_version;
+
+ void *(WINAPI * wglGetProcAddress) (const char *proc);
+ HGLRC(WINAPI * wglCreateContext) (HDC hdc);
+ BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
+ BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
+ BOOL(WINAPI * wglShareLists) (HGLRC hglrc1, HGLRC hglrc2);
+ BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
+ const int *piAttribIList,
+ const FLOAT * pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT * nNumFormats);
+ BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat,
+ int iLayerPlane,
+ UINT nAttributes,
+ const int *piAttributes,
+ int *piValues);
+ BOOL (WINAPI * wglSwapIntervalEXT) (int interval);
+ int (WINAPI * wglGetSwapIntervalEXT) (void);
+};
+
+/* OpenGL functions */
+extern int WIN_GL_LoadLibrary(_THIS, const char *path);
+extern void *WIN_GL_GetProcAddress(_THIS, const char *proc);
+extern void WIN_GL_UnloadLibrary(_THIS);
+extern SDL_bool WIN_GL_UseEGL(_THIS);
+extern int WIN_GL_SetupWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window);
+extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern int WIN_GL_SetSwapInterval(_THIS, int interval);
+extern int WIN_GL_GetSwapInterval(_THIS);
+extern int WIN_GL_SwapWindow(_THIS, SDL_Window * window);
+extern void WIN_GL_DeleteContext(_THIS, SDL_GLContext context);
+extern void WIN_GL_InitExtensions(_THIS);
+extern SDL_bool WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow);
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#endif /* SDL_VIDEO_OPENGL_WGL */
+
+#endif /* SDL_windowsopengl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.c
new file mode 100644
index 0000000..0ff61c3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.c
@@ -0,0 +1,131 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_windowsvideo.h"
+#include "SDL_windowsopengles.h"
+#include "SDL_windowsopengl.h"
+#include "SDL_log.h"
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+WIN_GLES_LoadLibrary(_THIS, const char *path) {
+
+ /* If the profile requested is not GL ES, switch over to WIN_GL functions */
+ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
+#if SDL_VIDEO_OPENGL_WGL
+ WIN_GLES_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = WIN_GL_LoadLibrary;
+ _this->GL_GetProcAddress = WIN_GL_GetProcAddress;
+ _this->GL_UnloadLibrary = WIN_GL_UnloadLibrary;
+ _this->GL_CreateContext = WIN_GL_CreateContext;
+ _this->GL_MakeCurrent = WIN_GL_MakeCurrent;
+ _this->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
+ _this->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
+ _this->GL_SwapWindow = WIN_GL_SwapWindow;
+ _this->GL_DeleteContext = WIN_GL_DeleteContext;
+ return WIN_GL_LoadLibrary(_this, path);
+#else
+ return SDL_SetError("SDL not configured with OpenGL/WGL support");
+#endif
+ }
+
+ if (_this->egl_data == NULL) {
+ return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0);
+ }
+
+ return 0;
+}
+
+SDL_GLContext
+WIN_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_GLContext context;
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+
+#if SDL_VIDEO_OPENGL_WGL
+ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
+ /* Switch to WGL based functions */
+ WIN_GLES_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = WIN_GL_LoadLibrary;
+ _this->GL_GetProcAddress = WIN_GL_GetProcAddress;
+ _this->GL_UnloadLibrary = WIN_GL_UnloadLibrary;
+ _this->GL_CreateContext = WIN_GL_CreateContext;
+ _this->GL_MakeCurrent = WIN_GL_MakeCurrent;
+ _this->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
+ _this->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
+ _this->GL_SwapWindow = WIN_GL_SwapWindow;
+ _this->GL_DeleteContext = WIN_GL_DeleteContext;
+
+ if (WIN_GL_LoadLibrary(_this, NULL) != 0) {
+ return NULL;
+ }
+
+ return WIN_GL_CreateContext(_this, window);
+ }
+#endif
+
+ context = SDL_EGL_CreateContext(_this, data->egl_surface);
+ return context;
+}
+
+void
+WIN_GLES_DeleteContext(_THIS, SDL_GLContext context)
+{
+ SDL_EGL_DeleteContext(_this, context);
+ WIN_GLES_UnloadLibrary(_this);
+}
+
+SDL_EGL_SwapWindow_impl(WIN)
+SDL_EGL_MakeCurrent_impl(WIN)
+
+int
+WIN_GLES_SetupWindow(_THIS, SDL_Window * window)
+{
+ /* The current context is lost in here; save it and reset it. */
+ SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
+ SDL_Window *current_win = SDL_GL_GetCurrentWindow();
+ SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
+
+
+ if (_this->egl_data == NULL) {
+ if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) {
+ SDL_EGL_UnloadLibrary(_this);
+ return -1;
+ }
+ }
+
+ /* Create the GLES window surface */
+ windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windowdata->hwnd);
+
+ if (windowdata->egl_surface == EGL_NO_SURFACE) {
+ return SDL_SetError("Could not create GLES window surface");
+ }
+
+ return WIN_GLES_MakeCurrent(_this, current_win, current_ctx);
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.h
new file mode 100644
index 0000000..8684429
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsopengles.h
@@ -0,0 +1,49 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_winopengles_h_
+#define SDL_winopengles_h_
+
+#if SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define WIN_GLES_GetAttribute SDL_EGL_GetAttribute
+#define WIN_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define WIN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define WIN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define WIN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+
+extern int WIN_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext WIN_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int WIN_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int WIN_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+extern void WIN_GLES_DeleteContext(_THIS, SDL_GLContext context);
+extern int WIN_GLES_SetupWindow(_THIS, SDL_Window * window);
+
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_winopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.c
new file mode 100644
index 0000000..bed4588
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.c
@@ -0,0 +1,110 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_assert.h"
+#include "SDL_windowsshape.h"
+#include "SDL_windowsvideo.h"
+
+SDL_WindowShaper*
+Win32_CreateShaper(SDL_Window * window) {
+ int resized_properly;
+ SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper));
+ result->window = window;
+ result->mode.mode = ShapeModeDefault;
+ result->mode.parameters.binarizationCutoff = 1;
+ result->userx = result->usery = 0;
+ result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData));
+ ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL;
+ /* Put some driver-data here. */
+ window->shaper = result;
+ resized_properly = Win32_ResizeWindowShape(window);
+ if (resized_properly != 0)
+ return NULL;
+
+ return result;
+}
+
+static void
+CombineRectRegions(SDL_ShapeTree* node,void* closure) {
+ HRGN mask_region = *((HRGN*)closure),temp_region = NULL;
+ if(node->kind == OpaqueShape) {
+ /* Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. */
+ temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1);
+ if(mask_region != NULL) {
+ CombineRgn(mask_region,mask_region,temp_region,RGN_OR);
+ DeleteObject(temp_region);
+ }
+ else
+ *((HRGN*)closure) = temp_region;
+ }
+}
+
+int
+Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) {
+ SDL_ShapeData *data;
+ HRGN mask_region = NULL;
+
+ if( (shaper == NULL) ||
+ (shape == NULL) ||
+ ((shape->format->Amask == 0) && (shape_mode->mode != ShapeModeColorKey)) ||
+ (shape->w != shaper->window->w) ||
+ (shape->h != shaper->window->h) ) {
+ return SDL_INVALID_SHAPE_ARGUMENT;
+ }
+
+ data = (SDL_ShapeData*)shaper->driverdata;
+ if(data->mask_tree != NULL)
+ SDL_FreeShapeTree(&data->mask_tree);
+ data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape);
+
+ SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region);
+ SDL_assert(mask_region != NULL);
+
+ SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE);
+
+ return 0;
+}
+
+int
+Win32_ResizeWindowShape(SDL_Window *window) {
+ SDL_ShapeData* data;
+
+ if (window == NULL)
+ return -1;
+ data = (SDL_ShapeData *)window->shaper->driverdata;
+ if (data == NULL)
+ return -1;
+
+ if(data->mask_tree != NULL)
+ SDL_FreeShapeTree(&data->mask_tree);
+ if(window->shaper->hasshape == SDL_TRUE) {
+ window->shaper->userx = window->x;
+ window->shaper->usery = window->y;
+ SDL_SetWindowPosition(window,-1000,-1000);
+ }
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.h
new file mode 100644
index 0000000..eb1a887
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsshape.h
@@ -0,0 +1,40 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsshape_h_
+#define SDL_windowsshape_h_
+
+#include "SDL_video.h"
+#include "SDL_shape.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_shape_internals.h"
+
+typedef struct {
+ SDL_ShapeTree *mask_tree;
+} SDL_ShapeData;
+
+extern SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window);
+extern int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode);
+extern int Win32_ResizeWindowShape(SDL_Window *window);
+
+#endif /* SDL_windowsshape_h_ */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowstaskdialog.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowstaskdialog.h
new file mode 100644
index 0000000..a2a9e8a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowstaskdialog.h
@@ -0,0 +1,156 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include <pshpack1.h>
+
+typedef HRESULT(CALLBACK *PFTASKDIALOGCALLBACK)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData);
+
+enum _TASKDIALOG_FLAGS
+{
+ TDF_ENABLE_HYPERLINKS = 0x0001,
+ TDF_USE_HICON_MAIN = 0x0002,
+ TDF_USE_HICON_FOOTER = 0x0004,
+ TDF_ALLOW_DIALOG_CANCELLATION = 0x0008,
+ TDF_USE_COMMAND_LINKS = 0x0010,
+ TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020,
+ TDF_EXPAND_FOOTER_AREA = 0x0040,
+ TDF_EXPANDED_BY_DEFAULT = 0x0080,
+ TDF_VERIFICATION_FLAG_CHECKED = 0x0100,
+ TDF_SHOW_PROGRESS_BAR = 0x0200,
+ TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400,
+ TDF_CALLBACK_TIMER = 0x0800,
+ TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000,
+ TDF_RTL_LAYOUT = 0x2000,
+ TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000,
+ TDF_CAN_BE_MINIMIZED = 0x8000,
+ //#if (NTDDI_VERSION >= NTDDI_WIN8)
+ TDF_NO_SET_FOREGROUND = 0x00010000, // Don't call SetForegroundWindow() when activating the dialog
+ //#endif // (NTDDI_VERSION >= NTDDI_WIN8)
+ TDF_SIZE_TO_CONTENT = 0x01000000 // used by ShellMessageBox to emulate MessageBox sizing behavior
+};
+typedef int TASKDIALOG_FLAGS; // Note: _TASKDIALOG_FLAGS is an int
+
+typedef enum _TASKDIALOG_MESSAGES
+{
+ TDM_NAVIGATE_PAGE = WM_USER + 101,
+ TDM_CLICK_BUTTON = WM_USER + 102, // wParam = Button ID
+ TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER + 103, // wParam = 0 (nonMarque) wParam != 0 (Marquee)
+ TDM_SET_PROGRESS_BAR_STATE = WM_USER + 104, // wParam = new progress state
+ TDM_SET_PROGRESS_BAR_RANGE = WM_USER + 105, // lParam = MAKELPARAM(nMinRange, nMaxRange)
+ TDM_SET_PROGRESS_BAR_POS = WM_USER + 106, // wParam = new position
+ TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER + 107, // wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints)
+ TDM_SET_ELEMENT_TEXT = WM_USER + 108, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
+ TDM_CLICK_RADIO_BUTTON = WM_USER + 110, // wParam = Radio Button ID
+ TDM_ENABLE_BUTTON = WM_USER + 111, // lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID
+ TDM_ENABLE_RADIO_BUTTON = WM_USER + 112, // lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID
+ TDM_CLICK_VERIFICATION = WM_USER + 113, // wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus)
+ TDM_UPDATE_ELEMENT_TEXT = WM_USER + 114, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
+ TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER + 115, // wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required)
+ TDM_UPDATE_ICON = WM_USER + 116 // wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise)
+} TASKDIALOG_MESSAGES;
+
+typedef enum _TASKDIALOG_NOTIFICATIONS
+{
+ TDN_CREATED = 0,
+ TDN_NAVIGATED = 1,
+ TDN_BUTTON_CLICKED = 2, // wParam = Button ID
+ TDN_HYPERLINK_CLICKED = 3, // lParam = (LPCWSTR)pszHREF
+ TDN_TIMER = 4, // wParam = Milliseconds since dialog created or timer reset
+ TDN_DESTROYED = 5,
+ TDN_RADIO_BUTTON_CLICKED = 6, // wParam = Radio Button ID
+ TDN_DIALOG_CONSTRUCTED = 7,
+ TDN_VERIFICATION_CLICKED = 8, // wParam = 1 if checkbox checked, 0 if not, lParam is unused and always 0
+ TDN_HELP = 9,
+ TDN_EXPANDO_BUTTON_CLICKED = 10 // wParam = 0 (dialog is now collapsed), wParam != 0 (dialog is now expanded)
+} TASKDIALOG_NOTIFICATIONS;
+
+typedef struct _TASKDIALOG_BUTTON
+{
+ int nButtonID;
+ PCWSTR pszButtonText;
+} TASKDIALOG_BUTTON;
+
+typedef enum _TASKDIALOG_ELEMENTS
+{
+ TDE_CONTENT,
+ TDE_EXPANDED_INFORMATION,
+ TDE_FOOTER,
+ TDE_MAIN_INSTRUCTION
+} TASKDIALOG_ELEMENTS;
+
+typedef enum _TASKDIALOG_ICON_ELEMENTS
+{
+ TDIE_ICON_MAIN,
+ TDIE_ICON_FOOTER
+} TASKDIALOG_ICON_ELEMENTS;
+
+#define TD_WARNING_ICON MAKEINTRESOURCEW(-1)
+#define TD_ERROR_ICON MAKEINTRESOURCEW(-2)
+#define TD_INFORMATION_ICON MAKEINTRESOURCEW(-3)
+#define TD_SHIELD_ICON MAKEINTRESOURCEW(-4)
+
+enum _TASKDIALOG_COMMON_BUTTON_FLAGS
+{
+ TDCBF_OK_BUTTON = 0x0001, // selected control return value IDOK
+ TDCBF_YES_BUTTON = 0x0002, // selected control return value IDYES
+ TDCBF_NO_BUTTON = 0x0004, // selected control return value IDNO
+ TDCBF_CANCEL_BUTTON = 0x0008, // selected control return value IDCANCEL
+ TDCBF_RETRY_BUTTON = 0x0010, // selected control return value IDRETRY
+ TDCBF_CLOSE_BUTTON = 0x0020 // selected control return value IDCLOSE
+};
+typedef int TASKDIALOG_COMMON_BUTTON_FLAGS; // Note: _TASKDIALOG_COMMON_BUTTON_FLAGS is an int
+
+typedef struct _TASKDIALOGCONFIG
+{
+ UINT cbSize;
+ HWND hwndParent; // incorrectly named, this is the owner window, not a parent.
+ HINSTANCE hInstance; // used for MAKEINTRESOURCE() strings
+ TASKDIALOG_FLAGS dwFlags; // TASKDIALOG_FLAGS (TDF_XXX) flags
+ TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons; // TASKDIALOG_COMMON_BUTTON (TDCBF_XXX) flags
+ PCWSTR pszWindowTitle; // string or MAKEINTRESOURCE()
+ union
+ {
+ HICON hMainIcon;
+ PCWSTR pszMainIcon;
+ } /*DUMMYUNIONNAME*/;
+ PCWSTR pszMainInstruction;
+ PCWSTR pszContent;
+ UINT cButtons;
+ const TASKDIALOG_BUTTON *pButtons;
+ int nDefaultButton;
+ UINT cRadioButtons;
+ const TASKDIALOG_BUTTON *pRadioButtons;
+ int nDefaultRadioButton;
+ PCWSTR pszVerificationText;
+ PCWSTR pszExpandedInformation;
+ PCWSTR pszExpandedControlText;
+ PCWSTR pszCollapsedControlText;
+ union
+ {
+ HICON hFooterIcon;
+ PCWSTR pszFooterIcon;
+ } /*DUMMYUNIONNAME2*/;
+ PCWSTR pszFooter;
+ PFTASKDIALOGCALLBACK pfCallback;
+ LONG_PTR lpCallbackData;
+ UINT cxWidth; // width of the Task Dialog's client area in DLU's. If 0, Task Dialog will calculate the ideal width.
+} TASKDIALOGCONFIG;
+
+#include <poppack.h>
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.c
new file mode 100644
index 0000000..358ab23
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.c
@@ -0,0 +1,452 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_main.h"
+#include "SDL_video.h"
+#include "SDL_hints.h"
+#include "SDL_mouse.h"
+#include "SDL_system.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+
+#include "SDL_windowsvideo.h"
+#include "SDL_windowsframebuffer.h"
+#include "SDL_windowsshape.h"
+#include "SDL_windowsvulkan.h"
+
+/* Initialization/Query functions */
+static int WIN_VideoInit(_THIS);
+static void WIN_VideoQuit(_THIS);
+
+/* Hints */
+SDL_bool g_WindowsEnableMessageLoop = SDL_TRUE;
+SDL_bool g_WindowFrameUsableWhileCursorHidden = SDL_TRUE;
+
+static void SDLCALL
+UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue)
+{
+ if (newValue && *newValue == '0') {
+ g_WindowsEnableMessageLoop = SDL_FALSE;
+ } else {
+ g_WindowsEnableMessageLoop = SDL_TRUE;
+ }
+}
+
+static void SDLCALL
+UpdateWindowFrameUsableWhileCursorHidden(void *userdata, const char *name, const char *oldValue, const char *newValue)
+{
+ if (newValue && *newValue == '0') {
+ g_WindowFrameUsableWhileCursorHidden = SDL_FALSE;
+ } else {
+ g_WindowFrameUsableWhileCursorHidden = SDL_TRUE;
+ }
+}
+
+static void WIN_SuspendScreenSaver(_THIS)
+{
+ if (_this->suspend_screensaver) {
+ SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
+ } else {
+ SetThreadExecutionState(ES_CONTINUOUS);
+ }
+}
+
+
+/* Windows driver bootstrap functions */
+
+static int
+WIN_Available(void)
+{
+ return (1);
+}
+
+static void
+WIN_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
+
+ SDL_UnregisterApp();
+ if (data->userDLL) {
+ SDL_UnloadObject(data->userDLL);
+ }
+ if (data->shcoreDLL) {
+ SDL_UnloadObject(data->shcoreDLL);
+ }
+
+ SDL_free(device->driverdata);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+WIN_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ SDL_RegisterApp(NULL, 0, NULL);
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device) {
+ data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ } else {
+ data = NULL;
+ }
+ if (!data) {
+ SDL_free(device);
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ device->driverdata = data;
+
+ data->userDLL = SDL_LoadObject("USER32.DLL");
+ if (data->userDLL) {
+ data->CloseTouchInputHandle = (BOOL (WINAPI *)(HTOUCHINPUT)) SDL_LoadFunction(data->userDLL, "CloseTouchInputHandle");
+ data->GetTouchInputInfo = (BOOL (WINAPI *)(HTOUCHINPUT, UINT, PTOUCHINPUT, int)) SDL_LoadFunction(data->userDLL, "GetTouchInputInfo");
+ data->RegisterTouchWindow = (BOOL (WINAPI *)(HWND, ULONG)) SDL_LoadFunction(data->userDLL, "RegisterTouchWindow");
+ } else {
+ SDL_ClearError();
+ }
+
+ data->shcoreDLL = SDL_LoadObject("SHCORE.DLL");
+ if (data->shcoreDLL) {
+ data->GetDpiForMonitor = (HRESULT (WINAPI *)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *)) SDL_LoadFunction(data->shcoreDLL, "GetDpiForMonitor");
+ } else {
+ SDL_ClearError();
+ }
+
+ /* Set the function pointers */
+ device->VideoInit = WIN_VideoInit;
+ device->VideoQuit = WIN_VideoQuit;
+ device->GetDisplayBounds = WIN_GetDisplayBounds;
+ device->GetDisplayUsableBounds = WIN_GetDisplayUsableBounds;
+ device->GetDisplayDPI = WIN_GetDisplayDPI;
+ device->GetDisplayModes = WIN_GetDisplayModes;
+ device->SetDisplayMode = WIN_SetDisplayMode;
+ device->PumpEvents = WIN_PumpEvents;
+ device->SuspendScreenSaver = WIN_SuspendScreenSaver;
+
+ device->CreateSDLWindow = WIN_CreateWindow;
+ device->CreateSDLWindowFrom = WIN_CreateWindowFrom;
+ device->SetWindowTitle = WIN_SetWindowTitle;
+ device->SetWindowIcon = WIN_SetWindowIcon;
+ device->SetWindowPosition = WIN_SetWindowPosition;
+ device->SetWindowSize = WIN_SetWindowSize;
+ device->GetWindowBordersSize = WIN_GetWindowBordersSize;
+ device->SetWindowOpacity = WIN_SetWindowOpacity;
+ device->ShowWindow = WIN_ShowWindow;
+ device->HideWindow = WIN_HideWindow;
+ device->RaiseWindow = WIN_RaiseWindow;
+ device->MaximizeWindow = WIN_MaximizeWindow;
+ device->MinimizeWindow = WIN_MinimizeWindow;
+ device->RestoreWindow = WIN_RestoreWindow;
+ device->SetWindowBordered = WIN_SetWindowBordered;
+ device->SetWindowResizable = WIN_SetWindowResizable;
+ device->SetWindowFullscreen = WIN_SetWindowFullscreen;
+ device->SetWindowGammaRamp = WIN_SetWindowGammaRamp;
+ device->GetWindowGammaRamp = WIN_GetWindowGammaRamp;
+ device->SetWindowGrab = WIN_SetWindowGrab;
+ device->DestroyWindow = WIN_DestroyWindow;
+ device->GetWindowWMInfo = WIN_GetWindowWMInfo;
+ device->CreateWindowFramebuffer = WIN_CreateWindowFramebuffer;
+ device->UpdateWindowFramebuffer = WIN_UpdateWindowFramebuffer;
+ device->DestroyWindowFramebuffer = WIN_DestroyWindowFramebuffer;
+ device->OnWindowEnter = WIN_OnWindowEnter;
+ device->SetWindowHitTest = WIN_SetWindowHitTest;
+ device->AcceptDragAndDrop = WIN_AcceptDragAndDrop;
+
+ device->shape_driver.CreateShaper = Win32_CreateShaper;
+ device->shape_driver.SetWindowShape = Win32_SetWindowShape;
+ device->shape_driver.ResizeWindowShape = Win32_ResizeWindowShape;
+
+#if SDL_VIDEO_OPENGL_WGL
+ device->GL_LoadLibrary = WIN_GL_LoadLibrary;
+ device->GL_GetProcAddress = WIN_GL_GetProcAddress;
+ device->GL_UnloadLibrary = WIN_GL_UnloadLibrary;
+ device->GL_CreateContext = WIN_GL_CreateContext;
+ device->GL_MakeCurrent = WIN_GL_MakeCurrent;
+ device->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
+ device->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
+ device->GL_SwapWindow = WIN_GL_SwapWindow;
+ device->GL_DeleteContext = WIN_GL_DeleteContext;
+#elif SDL_VIDEO_OPENGL_EGL
+ /* Use EGL based functions */
+ device->GL_LoadLibrary = WIN_GLES_LoadLibrary;
+ device->GL_GetProcAddress = WIN_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
+ device->GL_CreateContext = WIN_GLES_CreateContext;
+ device->GL_MakeCurrent = WIN_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
+ device->GL_SwapWindow = WIN_GLES_SwapWindow;
+ device->GL_DeleteContext = WIN_GLES_DeleteContext;
+#endif
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = WIN_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = WIN_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions = WIN_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface;
+#endif
+
+ device->StartTextInput = WIN_StartTextInput;
+ device->StopTextInput = WIN_StopTextInput;
+ device->SetTextInputRect = WIN_SetTextInputRect;
+
+ device->SetClipboardText = WIN_SetClipboardText;
+ device->GetClipboardText = WIN_GetClipboardText;
+ device->HasClipboardText = WIN_HasClipboardText;
+
+ device->free = WIN_DeleteDevice;
+
+ return device;
+}
+
+
+VideoBootStrap WINDOWS_bootstrap = {
+ "windows", "SDL Windows video driver", WIN_Available, WIN_CreateDevice
+};
+
+int
+WIN_VideoInit(_THIS)
+{
+ if (WIN_InitModes(_this) < 0) {
+ return -1;
+ }
+
+ WIN_InitKeyboard(_this);
+ WIN_InitMouse(_this);
+
+ SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
+ SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
+
+ return 0;
+}
+
+void
+WIN_VideoQuit(_THIS)
+{
+ WIN_QuitModes(_this);
+ WIN_QuitKeyboard(_this);
+ WIN_QuitMouse(_this);
+}
+
+
+#define D3D_DEBUG_INFO
+#include <d3d9.h>
+
+SDL_bool
+D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
+{
+ *pD3DDLL = SDL_LoadObject("D3D9.DLL");
+ if (*pD3DDLL) {
+ typedef IDirect3D9 *(WINAPI *Direct3DCreate9_t) (UINT SDKVersion);
+ Direct3DCreate9_t Direct3DCreate9Func;
+
+#ifdef USE_D3D9EX
+ typedef HRESULT (WINAPI *Direct3DCreate9Ex_t)(UINT SDKVersion, IDirect3D9Ex **ppD3D);
+ Direct3DCreate9Ex_t Direct3DCreate9ExFunc;
+
+ Direct3DCreate9ExFunc = (Direct3DCreate9Ex_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9Ex");
+ if (Direct3DCreate9ExFunc) {
+ IDirect3D9Ex *pDirect3D9ExInterface;
+ HRESULT hr = Direct3DCreate9ExFunc(D3D_SDK_VERSION, &pDirect3D9ExInterface);
+ if (SUCCEEDED(hr)) {
+ const GUID IDirect3D9_GUID = { 0x81bdcbca, 0x64d4, 0x426d, { 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c } };
+ hr = IDirect3D9Ex_QueryInterface(pDirect3D9ExInterface, &IDirect3D9_GUID, (void**)pDirect3D9Interface);
+ IDirect3D9Ex_Release(pDirect3D9ExInterface);
+ if (SUCCEEDED(hr)) {
+ return SDL_TRUE;
+ }
+ }
+ }
+#endif /* USE_D3D9EX */
+
+ Direct3DCreate9Func = (Direct3DCreate9_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9");
+ if (Direct3DCreate9Func) {
+ *pDirect3D9Interface = Direct3DCreate9Func(D3D_SDK_VERSION);
+ if (*pDirect3D9Interface) {
+ return SDL_TRUE;
+ }
+ }
+
+ SDL_UnloadObject(*pD3DDLL);
+ *pD3DDLL = NULL;
+ }
+ *pDirect3D9Interface = NULL;
+ return SDL_FALSE;
+}
+
+
+int
+SDL_Direct3D9GetAdapterIndex(int displayIndex)
+{
+ void *pD3DDLL;
+ IDirect3D9 *pD3D;
+ if (!D3D_LoadDLL(&pD3DDLL, &pD3D)) {
+ SDL_SetError("Unable to create Direct3D interface");
+ return D3DADAPTER_DEFAULT;
+ } else {
+ SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex);
+ int adapterIndex = D3DADAPTER_DEFAULT;
+
+ if (!pData) {
+ SDL_SetError("Invalid display index");
+ adapterIndex = -1; /* make sure we return something invalid */
+ } else {
+ char *displayName = WIN_StringToUTF8(pData->DeviceName);
+ unsigned int count = IDirect3D9_GetAdapterCount(pD3D);
+ unsigned int i;
+ for (i=0; i<count; i++) {
+ D3DADAPTER_IDENTIFIER9 id;
+ IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &id);
+
+ if (SDL_strcmp(id.DeviceName, displayName) == 0) {
+ adapterIndex = i;
+ break;
+ }
+ }
+ SDL_free(displayName);
+ }
+
+ /* free up the D3D stuff we inited */
+ IDirect3D9_Release(pD3D);
+ SDL_UnloadObject(pD3DDLL);
+
+ return adapterIndex;
+ }
+}
+
+#if HAVE_DXGI_H
+#define CINTERFACE
+#define COBJMACROS
+#include <dxgi.h>
+
+static SDL_bool
+DXGI_LoadDLL(void **pDXGIDLL, IDXGIFactory **pDXGIFactory)
+{
+ *pDXGIDLL = SDL_LoadObject("DXGI.DLL");
+ if (*pDXGIDLL) {
+ HRESULT (WINAPI *CreateDXGI)(REFIID riid, void **ppFactory);
+
+ CreateDXGI =
+ (HRESULT (WINAPI *) (REFIID, void**)) SDL_LoadFunction(*pDXGIDLL,
+ "CreateDXGIFactory");
+ if (CreateDXGI) {
+ GUID dxgiGUID = {0x7b7166ec,0x21c7,0x44ae,{0xb2,0x1a,0xc9,0xae,0x32,0x1a,0xe3,0x69}};
+ if (!SUCCEEDED(CreateDXGI(&dxgiGUID, (void**)pDXGIFactory))) {
+ *pDXGIFactory = NULL;
+ }
+ }
+ if (!*pDXGIFactory) {
+ SDL_UnloadObject(*pDXGIDLL);
+ *pDXGIDLL = NULL;
+ return SDL_FALSE;
+ }
+
+ return SDL_TRUE;
+ } else {
+ *pDXGIFactory = NULL;
+ return SDL_FALSE;
+ }
+}
+#endif
+
+
+SDL_bool
+SDL_DXGIGetOutputInfo(int displayIndex, int *adapterIndex, int *outputIndex)
+{
+#if !HAVE_DXGI_H
+ if (adapterIndex) *adapterIndex = -1;
+ if (outputIndex) *outputIndex = -1;
+ SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header");
+ return SDL_FALSE;
+#else
+ SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex);
+ void *pDXGIDLL;
+ char *displayName;
+ int nAdapter, nOutput;
+ IDXGIFactory *pDXGIFactory;
+ IDXGIAdapter *pDXGIAdapter;
+ IDXGIOutput* pDXGIOutput;
+
+ if (!adapterIndex) {
+ SDL_InvalidParamError("adapterIndex");
+ return SDL_FALSE;
+ }
+
+ if (!outputIndex) {
+ SDL_InvalidParamError("outputIndex");
+ return SDL_FALSE;
+ }
+
+ *adapterIndex = -1;
+ *outputIndex = -1;
+
+ if (!pData) {
+ SDL_SetError("Invalid display index");
+ return SDL_FALSE;
+ }
+
+ if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) {
+ SDL_SetError("Unable to create DXGI interface");
+ return SDL_FALSE;
+ }
+
+ displayName = WIN_StringToUTF8(pData->DeviceName);
+ nAdapter = 0;
+ while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) {
+ nOutput = 0;
+ while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) {
+ DXGI_OUTPUT_DESC outputDesc;
+ if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) {
+ char *outputName = WIN_StringToUTF8(outputDesc.DeviceName);
+ if (SDL_strcmp(outputName, displayName) == 0) {
+ *adapterIndex = nAdapter;
+ *outputIndex = nOutput;
+ }
+ SDL_free(outputName);
+ }
+ IDXGIOutput_Release(pDXGIOutput);
+ nOutput++;
+ }
+ IDXGIAdapter_Release(pDXGIAdapter);
+ nAdapter++;
+ }
+ SDL_free(displayName);
+
+ /* free up the DXGI factory */
+ IDXGIFactory_Release(pDXGIFactory);
+ SDL_UnloadObject(pDXGIDLL);
+
+ if (*adapterIndex == -1) {
+ return SDL_FALSE;
+ } else {
+ return SDL_TRUE;
+ }
+#endif
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.h
new file mode 100644
index 0000000..1303754
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvideo.h
@@ -0,0 +1,199 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsvideo_h_
+#define SDL_windowsvideo_h_
+
+#include "../../core/windows/SDL_windows.h"
+
+#include "../SDL_sysvideo.h"
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#include <msctf.h>
+#else
+#include "SDL_msctf.h"
+#endif
+
+#include <imm.h>
+
+#define MAX_CANDLIST 10
+#define MAX_CANDLENGTH 256
+
+#include "SDL_windowsclipboard.h"
+#include "SDL_windowsevents.h"
+#include "SDL_windowskeyboard.h"
+#include "SDL_windowsmodes.h"
+#include "SDL_windowsmouse.h"
+#include "SDL_windowsopengl.h"
+#include "SDL_windowsopengles.h"
+#include "SDL_windowswindow.h"
+#include "SDL_events.h"
+#include "SDL_loadso.h"
+
+
+#if WINVER < 0x0601
+/* Touch input definitions */
+#define TWF_FINETOUCH 1
+#define TWF_WANTPALM 2
+
+#define TOUCHEVENTF_MOVE 0x0001
+#define TOUCHEVENTF_DOWN 0x0002
+#define TOUCHEVENTF_UP 0x0004
+
+DECLARE_HANDLE(HTOUCHINPUT);
+
+typedef struct _TOUCHINPUT {
+ LONG x;
+ LONG y;
+ HANDLE hSource;
+ DWORD dwID;
+ DWORD dwFlags;
+ DWORD dwMask;
+ DWORD dwTime;
+ ULONG_PTR dwExtraInfo;
+ DWORD cxContact;
+ DWORD cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+
+#endif /* WINVER < 0x0601 */
+
+#if WINVER < 0x0603
+
+typedef enum MONITOR_DPI_TYPE {
+ MDT_EFFECTIVE_DPI = 0,
+ MDT_ANGULAR_DPI = 1,
+ MDT_RAW_DPI = 2,
+ MDT_DEFAULT = MDT_EFFECTIVE_DPI
+} MONITOR_DPI_TYPE;
+
+#endif /* WINVER < 0x0603 */
+
+typedef BOOL (*PFNSHFullScreen)(HWND, DWORD);
+typedef void (*PFCoordTransform)(SDL_Window*, POINT*);
+
+typedef struct
+{
+ void **lpVtbl;
+ int refcount;
+ void *data;
+} TSFSink;
+
+/* Definition from Win98DDK version of IMM.H */
+typedef struct tagINPUTCONTEXT2 {
+ HWND hWnd;
+ BOOL fOpen;
+ POINT ptStatusWndPos;
+ POINT ptSoftKbdPos;
+ DWORD fdwConversion;
+ DWORD fdwSentence;
+ union {
+ LOGFONTA A;
+ LOGFONTW W;
+ } lfFont;
+ COMPOSITIONFORM cfCompForm;
+ CANDIDATEFORM cfCandForm[4];
+ HIMCC hCompStr;
+ HIMCC hCandInfo;
+ HIMCC hGuideLine;
+ HIMCC hPrivate;
+ DWORD dwNumMsgBuf;
+ HIMCC hMsgBuf;
+ DWORD fdwInit;
+ DWORD dwReserve[3];
+} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2;
+
+/* Private display data */
+
+typedef struct SDL_VideoData
+{
+ int render;
+
+ DWORD clipboard_count;
+
+ /* Touch input functions */
+ void* userDLL;
+ BOOL (WINAPI *CloseTouchInputHandle)( HTOUCHINPUT );
+ BOOL (WINAPI *GetTouchInputInfo)( HTOUCHINPUT, UINT, PTOUCHINPUT, int );
+ BOOL (WINAPI *RegisterTouchWindow)( HWND, ULONG );
+
+ void* shcoreDLL;
+ HRESULT (WINAPI *GetDpiForMonitor)( HMONITOR hmonitor,
+ MONITOR_DPI_TYPE dpiType,
+ UINT *dpiX,
+ UINT *dpiY );
+
+ SDL_bool ime_com_initialized;
+ struct ITfThreadMgr *ime_threadmgr;
+ SDL_bool ime_initialized;
+ SDL_bool ime_enabled;
+ SDL_bool ime_available;
+ HWND ime_hwnd_main;
+ HWND ime_hwnd_current;
+ HIMC ime_himc;
+
+ WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
+ WCHAR ime_readingstring[16];
+ int ime_cursor;
+
+ SDL_bool ime_candlist;
+ WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH];
+ DWORD ime_candcount;
+ DWORD ime_candref;
+ DWORD ime_candsel;
+ UINT ime_candpgsize;
+ int ime_candlistindexbase;
+ SDL_bool ime_candvertical;
+
+ SDL_bool ime_dirty;
+ SDL_Rect ime_rect;
+ SDL_Rect ime_candlistrect;
+ int ime_winwidth;
+ int ime_winheight;
+
+ HKL ime_hkl;
+ void* ime_himm32;
+ UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen);
+ BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow);
+ LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc);
+ BOOL (WINAPI *ImmUnlockIMC)(HIMC himc);
+ LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc);
+ BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc);
+
+ SDL_bool ime_uiless;
+ struct ITfThreadMgrEx *ime_threadmgrex;
+ DWORD ime_uielemsinkcookie;
+ DWORD ime_alpnsinkcookie;
+ DWORD ime_openmodesinkcookie;
+ DWORD ime_convmodesinkcookie;
+ TSFSink *ime_uielemsink;
+ TSFSink *ime_ippasink;
+} SDL_VideoData;
+
+extern SDL_bool g_WindowsEnableMessageLoop;
+extern SDL_bool g_WindowFrameUsableWhileCursorHidden;
+
+typedef struct IDirect3D9 IDirect3D9;
+extern SDL_bool D3D_LoadDLL( void **pD3DDLL, IDirect3D9 **pDirect3D9Interface );
+
+#endif /* SDL_windowsvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.c
new file mode 100644
index 0000000..6bb8f2a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.c
@@ -0,0 +1,176 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_windowsvideo.h"
+#include "SDL_windowswindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_windowsvulkan.h"
+#include "SDL_syswm.h"
+
+int WIN_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 extensionCount = 0;
+ Uint32 i;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasWin32SurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+ if(_this->vulkan_config.loader_handle)
+ return SDL_SetError("Vulkan already loaded");
+
+ /* Load the Vulkan loader library */
+ if(!path)
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ if(!path)
+ path = "vulkan-1.dll";
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if(!_this->vulkan_config.loader_handle)
+ return -1;
+ SDL_strlcpy(_this->vulkan_config.loader_path, path,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+ if(!vkGetInstanceProcAddr)
+ goto fail;
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+ if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
+ goto fail;
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+ if(!extensions)
+ goto fail;
+ for(i = 0; i < extensionCount; i++)
+ {
+ if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasSurfaceExtension = SDL_TRUE;
+ else if(SDL_strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasWin32SurfaceExtension = SDL_TRUE;
+ }
+ SDL_free(extensions);
+ if(!hasSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ }
+ else if(!hasWin32SurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_WIN32_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+ return 0;
+
+fail:
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void WIN_Vulkan_UnloadLibrary(_THIS)
+{
+ if(_this->vulkan_config.loader_handle)
+ {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForWin32[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME
+ };
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForWin32),
+ extensionsForWin32);
+}
+
+SDL_bool WIN_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR =
+ (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateWin32SurfaceKHR");
+ VkWin32SurfaceCreateInfoKHR createInfo;
+ VkResult result;
+
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if(!vkCreateWin32SurfaceKHR)
+ {
+ SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.hinstance = windowData->hinstance;
+ createInfo.hwnd = windowData->hwnd;
+ result = vkCreateWin32SurfaceKHR(instance, &createInfo,
+ NULL, surface);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError("vkCreateWin32SurfaceKHR failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.h
new file mode 100644
index 0000000..0acc0a9
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowsvulkan.h
@@ -0,0 +1,52 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowsvulkan_h_
+#define SDL_windowsvulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WINDOWS
+
+int WIN_Vulkan_LoadLibrary(_THIS, const char *path);
+void WIN_Vulkan_UnloadLibrary(_THIS);
+SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool WIN_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+#endif
+
+#endif /* SDL_windowsvulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.c b/source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.c
new file mode 100644
index 0000000..45463c4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.c
@@ -0,0 +1,996 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "../../core/windows/SDL_windows.h"
+
+#include "SDL_assert.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
+
+#include "SDL_windowsvideo.h"
+#include "SDL_windowswindow.h"
+#include "SDL_hints.h"
+
+/* Dropfile support */
+#include <shellapi.h>
+
+/* This is included after SDL_windowsvideo.h, which includes windows.h */
+#include "SDL_syswm.h"
+
+/* Windows CE compatibility */
+#ifndef SWP_NOCOPYBITS
+#define SWP_NOCOPYBITS 0
+#endif
+
+/* Fake window to help with DirectInput events. */
+HWND SDL_HelperWindow = NULL;
+static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
+static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
+static ATOM SDL_HelperWindowClass = 0;
+
+/* For borderless Windows, still want the following flags:
+ - WS_CAPTION: this seems to enable the Windows minimize animation
+ - WS_SYSMENU: enables system context menu on task bar
+ - WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc.
+ This will also cause the task bar to overlap the window and other windowed behaviors, so only use this for windows that shouldn't appear to be fullscreen
+ */
+
+#define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
+#define STYLE_FULLSCREEN (WS_POPUP)
+#define STYLE_BORDERLESS (WS_POPUP)
+#define STYLE_BORDERLESS_WINDOWED (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
+#define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
+#define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
+#define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
+
+static DWORD
+GetWindowStyle(SDL_Window * window)
+{
+ DWORD style = 0;
+
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ style |= STYLE_FULLSCREEN;
+ } else {
+ if (window->flags & SDL_WINDOW_BORDERLESS) {
+ /* SDL 2.1:
+ This behavior more closely matches other platform where the window is borderless
+ but still interacts with the window manager (e.g. task bar shows above it, it can
+ be resized to fit within usable desktop area, etc.) so this should be the behavior
+ for a future SDL release.
+
+ If you want a borderless window the size of the desktop that looks like a fullscreen
+ window, then you should use the SDL_WINDOW_FULLSCREEN_DESKTOP flag.
+ */
+ if (SDL_GetHintBoolean("SDL_BORDERLESS_WINDOWED_STYLE", SDL_FALSE)) {
+ style |= STYLE_BORDERLESS_WINDOWED;
+ } else {
+ style |= STYLE_BORDERLESS;
+ }
+ } else {
+ style |= STYLE_NORMAL;
+ }
+
+ /* You can have a borderless resizable window */
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ style |= STYLE_RESIZABLE;
+ }
+
+ /* Need to set initialize minimize style, or when we call ShowWindow with WS_MINIMIZE it will activate a random window */
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ style |= WS_MINIMIZE;
+ }
+ }
+ return style;
+}
+
+static void
+WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x, int *y, int *width, int *height, SDL_bool use_current)
+{
+ RECT rect;
+
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = (use_current ? window->w : window->windowed.w);
+ rect.bottom = (use_current ? window->h : window->windowed.h);
+
+ /* borderless windows will have WM_NCCALCSIZE return 0 for the non-client area. When this happens, it looks like windows will send a resize message
+ expanding the window client area to the previous window + chrome size, so shouldn't need to adjust the window size for the set styles.
+ */
+ if (!(window->flags & SDL_WINDOW_BORDERLESS))
+ AdjustWindowRectEx(&rect, style, menu, 0);
+
+ *x = (use_current ? window->x : window->windowed.x) + rect.left;
+ *y = (use_current ? window->y : window->windowed.y) + rect.top;
+ *width = (rect.right - rect.left);
+ *height = (rect.bottom - rect.top);
+}
+
+static void
+WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_bool use_current)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ DWORD style;
+ BOOL menu;
+
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
+ WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, use_current);
+}
+
+static void
+WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ HWND top;
+ int x, y;
+ int w, h;
+
+ /* Figure out what the window area will be */
+ if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || (window->flags & SDL_WINDOW_ALWAYS_ON_TOP))) {
+ top = HWND_TOPMOST;
+ } else {
+ top = HWND_NOTOPMOST;
+ }
+
+ WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_TRUE);
+
+ data->expected_resize = SDL_TRUE;
+ SetWindowPos(hwnd, top, x, y, w, h, flags);
+ data->expected_resize = SDL_FALSE;
+}
+
+static int
+SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool created)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *data;
+
+ /* Allocate the window data */
+ data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+ data->window = window;
+ data->hwnd = hwnd;
+ data->parent = parent;
+ data->hdc = GetDC(hwnd);
+ data->hinstance = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
+ data->created = created;
+ data->mouse_button_flags = 0;
+ data->videodata = videodata;
+ data->initializing = SDL_TRUE;
+
+ window->driverdata = data;
+
+ /* Associate the data with the window */
+ if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
+ ReleaseDC(hwnd, data->hdc);
+ SDL_free(data);
+ return WIN_SetError("SetProp() failed");
+ }
+
+ /* Set up the window proc function */
+#ifdef GWLP_WNDPROC
+ data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+ if (data->wndproc == WIN_WindowProc) {
+ data->wndproc = NULL;
+ } else {
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
+ }
+#else
+ data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
+ if (data->wndproc == WIN_WindowProc) {
+ data->wndproc = NULL;
+ } else {
+ SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc);
+ }
+#endif
+
+ /* Fill in the SDL window with the window data */
+ {
+ RECT rect;
+ if (GetClientRect(hwnd, &rect)) {
+ int w = rect.right;
+ int h = rect.bottom;
+ if ((window->windowed.w && window->windowed.w != w) || (window->windowed.h && window->windowed.h != h)) {
+ /* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */
+ int x, y;
+ /* Figure out what the window area will be */
+ WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_FALSE);
+ SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
+ } else {
+ window->w = w;
+ window->h = h;
+ }
+ }
+ }
+ {
+ POINT point;
+ point.x = 0;
+ point.y = 0;
+ if (ClientToScreen(hwnd, &point)) {
+ window->x = point.x;
+ window->y = point.y;
+ }
+ }
+ {
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ if (style & WS_VISIBLE) {
+ window->flags |= SDL_WINDOW_SHOWN;
+ } else {
+ window->flags &= ~SDL_WINDOW_SHOWN;
+ }
+ if (style & WS_POPUP) {
+ window->flags |= SDL_WINDOW_BORDERLESS;
+ } else {
+ window->flags &= ~SDL_WINDOW_BORDERLESS;
+ }
+ if (style & WS_THICKFRAME) {
+ window->flags |= SDL_WINDOW_RESIZABLE;
+ } else {
+ window->flags &= ~SDL_WINDOW_RESIZABLE;
+ }
+#ifdef WS_MAXIMIZE
+ if (style & WS_MAXIMIZE) {
+ window->flags |= SDL_WINDOW_MAXIMIZED;
+ } else
+#endif
+ {
+ window->flags &= ~SDL_WINDOW_MAXIMIZED;
+ }
+#ifdef WS_MINIMIZE
+ if (style & WS_MINIMIZE) {
+ window->flags |= SDL_WINDOW_MINIMIZED;
+ } else
+#endif
+ {
+ window->flags &= ~SDL_WINDOW_MINIMIZED;
+ }
+ }
+ if (GetFocus() == hwnd) {
+ window->flags |= SDL_WINDOW_INPUT_FOCUS;
+ SDL_SetKeyboardFocus(data->window);
+
+ if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
+ RECT rect;
+ GetClientRect(hwnd, &rect);
+ ClientToScreen(hwnd, (LPPOINT) & rect);
+ ClientToScreen(hwnd, (LPPOINT) & rect + 1);
+ ClipCursor(&rect);
+ }
+ }
+
+ /* Enable multi-touch */
+ if (videodata->RegisterTouchWindow) {
+ videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
+ }
+
+ data->initializing = SDL_FALSE;
+
+ /* All done! */
+ return 0;
+}
+
+
+
+int
+WIN_CreateWindow(_THIS, SDL_Window * window)
+{
+ HWND hwnd, parent = NULL;
+ DWORD style = STYLE_BASIC;
+ int x, y;
+ int w, h;
+
+ if (window->flags & SDL_WINDOW_SKIP_TASKBAR) {
+ parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL);
+ }
+
+ style |= GetWindowStyle(window);
+
+ /* Figure out what the window area will be */
+ WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE);
+
+ hwnd =
+ CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL,
+ SDL_Instance, NULL);
+ if (!hwnd) {
+ return WIN_SetError("Couldn't create window");
+ }
+
+ WIN_PumpEvents(_this);
+
+ if (SetupWindowData(_this, window, hwnd, parent, SDL_TRUE) < 0) {
+ DestroyWindow(hwnd);
+ if (parent) {
+ DestroyWindow(parent);
+ }
+ return -1;
+ }
+
+ /* Inform Windows of the frame change so we can respond to WM_NCCALCSIZE */
+ SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
+
+ if (window->flags & SDL_WINDOW_MINIMIZED) {
+ ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
+ }
+
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ return 0;
+ }
+
+ /* The rest of this macro mess is for OpenGL or OpenGL ES windows */
+#if SDL_VIDEO_OPENGL_ES2
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES
+#if SDL_VIDEO_OPENGL_WGL
+ && (!_this->gl_data || WIN_GL_UseEGL(_this))
+#endif /* SDL_VIDEO_OPENGL_WGL */
+ ) {
+#if SDL_VIDEO_OPENGL_EGL
+ if (WIN_GLES_SetupWindow(_this, window) < 0) {
+ WIN_DestroyWindow(_this, window);
+ return -1;
+ }
+ return 0;
+#else
+ return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ }
+#endif /* SDL_VIDEO_OPENGL_ES2 */
+
+#if SDL_VIDEO_OPENGL_WGL
+ if (WIN_GL_SetupWindow(_this, window) < 0) {
+ WIN_DestroyWindow(_this, window);
+ return -1;
+ }
+#else
+ return SDL_SetError("Could not create GL window (WGL support not configured)");
+#endif
+
+ return 0;
+}
+
+int
+WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ HWND hwnd = (HWND) data;
+ LPTSTR title;
+ int titleLen;
+
+ /* Query the title from the existing window */
+ titleLen = GetWindowTextLength(hwnd);
+ title = SDL_stack_alloc(TCHAR, titleLen + 1);
+ if (title) {
+ titleLen = GetWindowText(hwnd, title, titleLen);
+ } else {
+ titleLen = 0;
+ }
+ if (titleLen > 0) {
+ window->title = WIN_StringToUTF8(title);
+ }
+ if (title) {
+ SDL_stack_free(title);
+ }
+
+ if (SetupWindowData(_this, window, hwnd, GetParent(hwnd), SDL_FALSE) < 0) {
+ return -1;
+ }
+
+#if SDL_VIDEO_OPENGL_WGL
+ {
+ const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT);
+ if (hint) {
+ /* This hint is a pointer (in string form) of the address of
+ the window to share a pixel format with
+ */
+ SDL_Window *otherWindow = NULL;
+ SDL_sscanf(hint, "%p", (void**)&otherWindow);
+
+ /* Do some error checking on the pointer */
+ if (otherWindow != NULL && otherWindow->magic == &_this->window_magic) {
+ /* If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well */
+ if (otherWindow->flags & SDL_WINDOW_OPENGL) {
+ window->flags |= SDL_WINDOW_OPENGL;
+ if (!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
+ return -1;
+ }
+ }
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+void
+WIN_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ LPTSTR title = WIN_UTF8ToString(window->title);
+ SetWindowText(hwnd, title);
+ SDL_free(title);
+}
+
+void
+WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ HICON hicon = NULL;
+ BYTE *icon_bmp;
+ int icon_len, mask_len, y;
+ SDL_RWops *dst;
+
+ /* Create temporary buffer for ICONIMAGE structure */
+ mask_len = (icon->h * (icon->w + 7)/8);
+ icon_len = 40 + icon->h * icon->w * sizeof(Uint32) + mask_len;
+ icon_bmp = SDL_stack_alloc(BYTE, icon_len);
+ dst = SDL_RWFromMem(icon_bmp, icon_len);
+ if (!dst) {
+ SDL_stack_free(icon_bmp);
+ return;
+ }
+
+ /* Write the BITMAPINFO header */
+ SDL_WriteLE32(dst, 40);
+ SDL_WriteLE32(dst, icon->w);
+ SDL_WriteLE32(dst, icon->h * 2);
+ SDL_WriteLE16(dst, 1);
+ SDL_WriteLE16(dst, 32);
+ SDL_WriteLE32(dst, BI_RGB);
+ SDL_WriteLE32(dst, icon->h * icon->w * sizeof(Uint32));
+ SDL_WriteLE32(dst, 0);
+ SDL_WriteLE32(dst, 0);
+ SDL_WriteLE32(dst, 0);
+ SDL_WriteLE32(dst, 0);
+
+ /* Write the pixels upside down into the bitmap buffer */
+ SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888);
+ y = icon->h;
+ while (y--) {
+ Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch;
+ SDL_RWwrite(dst, src, icon->w * sizeof(Uint32), 1);
+ }
+
+ /* Write the mask */
+ SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len);
+
+ hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
+
+ SDL_RWclose(dst);
+ SDL_stack_free(icon_bmp);
+
+ /* Set the icon for the window */
+ SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
+
+ /* Set the icon in the task manager (should we do this?) */
+ SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
+}
+
+void
+WIN_SetWindowPosition(_THIS, SDL_Window * window)
+{
+ WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
+}
+
+void
+WIN_SetWindowSize(_THIS, SDL_Window * window)
+{
+ WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
+}
+
+int
+WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right)
+{
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ RECT rcClient, rcWindow;
+ POINT ptDiff;
+
+ /* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left
+ * screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */
+ GetClientRect(hwnd, &rcClient);
+ GetWindowRect(hwnd, &rcWindow);
+
+ /* convert the top/left values to make them relative to
+ * the window; they will end up being slightly negative */
+ ptDiff.y = rcWindow.top;
+ ptDiff.x = rcWindow.left;
+
+ ScreenToClient(hwnd, &ptDiff);
+
+ rcWindow.top = ptDiff.y;
+ rcWindow.left = ptDiff.x;
+
+ /* convert the bottom/right values to make them relative to the window,
+ * these will be slightly bigger than the inner width/height */
+ ptDiff.y = rcWindow.bottom;
+ ptDiff.x = rcWindow.right;
+
+ ScreenToClient(hwnd, &ptDiff);
+
+ rcWindow.bottom = ptDiff.y;
+ rcWindow.right = ptDiff.x;
+
+ /* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size.
+ * Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0},
+ * so switch them around because SDL2 wants them in positive. */
+ *top = rcClient.top - rcWindow.top;
+ *left = rcClient.left - rcWindow.left;
+ *bottom = rcWindow.bottom - rcClient.bottom;
+ *right = rcWindow.right - rcClient.right;
+
+ return 0;
+}
+
+void
+WIN_ShowWindow(_THIS, SDL_Window * window)
+{
+ DWORD style;
+ HWND hwnd;
+ int nCmdShow;
+
+ hwnd = ((SDL_WindowData *)window->driverdata)->hwnd;
+ nCmdShow = SW_SHOW;
+ style = GetWindowLong(hwnd, GWL_EXSTYLE);
+ if (style & WS_EX_NOACTIVATE) {
+ nCmdShow = SW_SHOWNOACTIVATE;
+ }
+ ShowWindow(hwnd, nCmdShow);
+}
+
+void
+WIN_HideWindow(_THIS, SDL_Window * window)
+{
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ ShowWindow(hwnd, SW_HIDE);
+}
+
+void
+WIN_RaiseWindow(_THIS, SDL_Window * window)
+{
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ SetForegroundWindow(hwnd);
+}
+
+void
+WIN_MaximizeWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ data->expected_resize = SDL_TRUE;
+ ShowWindow(hwnd, SW_MAXIMIZE);
+ data->expected_resize = SDL_FALSE;
+}
+
+void
+WIN_MinimizeWindow(_THIS, SDL_Window * window)
+{
+ HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+ ShowWindow(hwnd, SW_MINIMIZE);
+}
+
+void
+WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ DWORD style;
+
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ style &= ~STYLE_MASK;
+ style |= GetWindowStyle(window);
+
+ data->in_border_change = SDL_TRUE;
+ SetWindowLong(hwnd, GWL_STYLE, style);
+ WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
+ data->in_border_change = SDL_FALSE;
+}
+
+void
+WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ DWORD style;
+
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ style &= ~STYLE_MASK;
+ style |= GetWindowStyle(window);
+
+ SetWindowLong(hwnd, GWL_STYLE, style);
+}
+
+void
+WIN_RestoreWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ HWND hwnd = data->hwnd;
+ data->expected_resize = SDL_TRUE;
+ ShowWindow(hwnd, SW_RESTORE);
+ data->expected_resize = SDL_FALSE;
+}
+
+void
+WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ HWND hwnd = data->hwnd;
+ SDL_Rect bounds;
+ DWORD style;
+ HWND top;
+ int x, y;
+ int w, h;
+
+ if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) {
+ top = HWND_TOPMOST;
+ } else {
+ top = HWND_NOTOPMOST;
+ }
+
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ style &= ~STYLE_MASK;
+ style |= GetWindowStyle(window);
+
+ WIN_GetDisplayBounds(_this, display, &bounds);
+
+ if (fullscreen) {
+ x = bounds.x;
+ y = bounds.y;
+ w = bounds.w;
+ h = bounds.h;
+
+ /* Unset the maximized flag. This fixes
+ https://bugzilla.libsdl.org/show_bug.cgi?id=3215
+ */
+ if (style & WS_MAXIMIZE) {
+ data->windowed_mode_was_maximized = SDL_TRUE;
+ style &= ~WS_MAXIMIZE;
+ }
+ } else {
+ BOOL menu;
+
+ /* Restore window-maximization state, as applicable.
+ Special care is taken to *not* do this if and when we're
+ alt-tab'ing away (to some other window; as indicated by
+ in_window_deactivation), otherwise
+ https://bugzilla.libsdl.org/show_bug.cgi?id=3215 can reproduce!
+ */
+ if (data->windowed_mode_was_maximized && !data->in_window_deactivation) {
+ style |= WS_MAXIMIZE;
+ data->windowed_mode_was_maximized = SDL_FALSE;
+ }
+
+ menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
+ WIN_AdjustWindowRectWithStyle(window, style, menu, &x, &y, &w, &h, SDL_FALSE);
+ }
+ SetWindowLong(hwnd, GWL_STYLE, style);
+ data->expected_resize = SDL_TRUE;
+ SetWindowPos(hwnd, top, x, y, w, h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
+ data->expected_resize = SDL_FALSE;
+}
+
+int
+WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+ HDC hdc;
+ BOOL succeeded = FALSE;
+
+ hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
+ if (hdc) {
+ succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
+ if (!succeeded) {
+ WIN_SetError("SetDeviceGammaRamp()");
+ }
+ DeleteDC(hdc);
+ }
+ return succeeded ? 0 : -1;
+}
+
+int
+WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+ HDC hdc;
+ BOOL succeeded = FALSE;
+
+ hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
+ if (hdc) {
+ succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
+ if (!succeeded) {
+ WIN_SetError("GetDeviceGammaRamp()");
+ }
+ DeleteDC(hdc);
+ }
+ return succeeded ? 0 : -1;
+}
+
+void
+WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+ WIN_UpdateClipCursor(window);
+
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
+
+ if (!(window->flags & SDL_WINDOW_SHOWN)) {
+ flags |= SWP_NOACTIVATE;
+ }
+ WIN_SetWindowPositionInternal(_this, window, flags);
+ }
+}
+
+void
+WIN_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (data) {
+ ReleaseDC(data->hwnd, data->hdc);
+ RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
+ if (data->created) {
+ DestroyWindow(data->hwnd);
+ if (data->parent) {
+ DestroyWindow(data->parent);
+ }
+ } else {
+ /* Restore any original event handler... */
+ if (data->wndproc != NULL) {
+#ifdef GWLP_WNDPROC
+ SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
+ (LONG_PTR) data->wndproc);
+#else
+ SetWindowLong(data->hwnd, GWL_WNDPROC,
+ (LONG_PTR) data->wndproc);
+#endif
+ }
+ }
+ SDL_free(data);
+ }
+ window->driverdata = NULL;
+}
+
+SDL_bool
+WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ int versionnum = SDL_VERSIONNUM(info->version.major, info->version.minor, info->version.patch);
+
+ info->subsystem = SDL_SYSWM_WINDOWS;
+ info->info.win.window = data->hwnd;
+
+ if (versionnum >= SDL_VERSIONNUM(2, 0, 4)) {
+ info->info.win.hdc = data->hdc;
+ }
+
+ if (versionnum >= SDL_VERSIONNUM(2, 0, 5)) {
+ info->info.win.hinstance = data->hinstance;
+ }
+
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+}
+
+
+/*
+ * Creates a HelperWindow used for DirectInput events.
+ */
+int
+SDL_HelperWindowCreate(void)
+{
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+ WNDCLASS wce;
+
+ /* Make sure window isn't created twice. */
+ if (SDL_HelperWindow != NULL) {
+ return 0;
+ }
+
+ /* Create the class. */
+ SDL_zero(wce);
+ wce.lpfnWndProc = DefWindowProc;
+ wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
+ wce.hInstance = hInstance;
+
+ /* Register the class. */
+ SDL_HelperWindowClass = RegisterClass(&wce);
+ if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
+ return WIN_SetError("Unable to create Helper Window Class");
+ }
+
+ /* Create the window. */
+ SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
+ SDL_HelperWindowName,
+ WS_OVERLAPPED, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, HWND_MESSAGE, NULL,
+ hInstance, NULL);
+ if (SDL_HelperWindow == NULL) {
+ UnregisterClass(SDL_HelperWindowClassName, hInstance);
+ return WIN_SetError("Unable to create Helper Window");
+ }
+
+ return 0;
+}
+
+
+/*
+ * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
+ */
+void
+SDL_HelperWindowDestroy(void)
+{
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+
+ /* Destroy the window. */
+ if (SDL_HelperWindow != NULL) {
+ if (DestroyWindow(SDL_HelperWindow) == 0) {
+ WIN_SetError("Unable to destroy Helper Window");
+ return;
+ }
+ SDL_HelperWindow = NULL;
+ }
+
+ /* Unregister the class. */
+ if (SDL_HelperWindowClass != 0) {
+ if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
+ WIN_SetError("Unable to destroy Helper Window Class");
+ return;
+ }
+ SDL_HelperWindowClass = 0;
+ }
+}
+
+void WIN_OnWindowEnter(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (!data || !data->hwnd) {
+ /* The window wasn't fully initialized */
+ return;
+ }
+
+ if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
+ WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
+ }
+
+#ifdef WM_MOUSELEAVE
+ {
+ TRACKMOUSEEVENT trackMouseEvent;
+
+ trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
+ trackMouseEvent.dwFlags = TME_LEAVE;
+ trackMouseEvent.hwndTrack = data->hwnd;
+
+ TrackMouseEvent(&trackMouseEvent);
+ }
+#endif /* WM_MOUSELEAVE */
+}
+
+void
+WIN_UpdateClipCursor(SDL_Window *window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_Mouse *mouse = SDL_GetMouse();
+ RECT rect;
+
+ if (data->in_title_click || data->focus_click_pending) {
+ return;
+ }
+ if (data->skip_update_clipcursor) {
+ data->skip_update_clipcursor = SDL_FALSE;
+ return;
+ }
+
+ if ((mouse->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
+ (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
+ if (mouse->relative_mode && !mouse->relative_mode_warp) {
+ LONG cx, cy;
+ GetWindowRect(data->hwnd, &rect);
+
+ cx = (rect.left + rect.right) / 2;
+ cy = (rect.top + rect.bottom) / 2;
+
+ /* Make an absurdly small clip rect */
+ rect.left = cx - 1;
+ rect.right = cx + 1;
+ rect.top = cy - 1;
+ rect.bottom = cy + 1;
+
+ if (ClipCursor(&rect)) {
+ data->cursor_clipped_rect = rect;
+ }
+ } else {
+ if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) {
+ ClientToScreen(data->hwnd, (LPPOINT) & rect);
+ ClientToScreen(data->hwnd, (LPPOINT) & rect + 1);
+ if (ClipCursor(&rect)) {
+ data->cursor_clipped_rect = rect;
+ }
+ }
+ }
+ } else if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) {
+ ClipCursor(NULL);
+ SDL_zero(data->cursor_clipped_rect);
+ }
+}
+
+int
+WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
+{
+ return 0; /* just succeed, the real work is done elsewhere. */
+}
+
+int
+WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
+{
+ const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ const HWND hwnd = data->hwnd;
+ const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
+
+ SDL_assert(style != 0);
+
+ if (opacity == 1.0f) {
+ /* want it fully opaque, just mark it unlayered if necessary. */
+ if (style & WS_EX_LAYERED) {
+ if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
+ return WIN_SetError("SetWindowLong()");
+ }
+ }
+ } else {
+ const BYTE alpha = (BYTE) ((int) (opacity * 255.0f));
+ /* want it transparent, mark it layered if necessary. */
+ if ((style & WS_EX_LAYERED) == 0) {
+ if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
+ return WIN_SetError("SetWindowLong()");
+ }
+ }
+
+ if (SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA) == 0) {
+ return WIN_SetError("SetLayeredWindowAttributes()");
+ }
+ }
+
+ return 0;
+}
+
+void
+WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
+{
+ const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ DragAcceptFiles(data->hwnd, accept ? TRUE : FALSE);
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.h b/source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.h
new file mode 100644
index 0000000..b738c34
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/SDL_windowswindow.h
@@ -0,0 +1,87 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_windowswindow_h_
+#define SDL_windowswindow_h_
+
+#if SDL_VIDEO_OPENGL_EGL
+#include "../SDL_egl_c.h"
+#endif
+
+typedef struct
+{
+ SDL_Window *window;
+ HWND hwnd;
+ HWND parent;
+ HDC hdc;
+ HDC mdc;
+ HINSTANCE hinstance;
+ HBITMAP hbm;
+ WNDPROC wndproc;
+ SDL_bool created;
+ WPARAM mouse_button_flags;
+ SDL_bool initializing;
+ SDL_bool expected_resize;
+ SDL_bool in_border_change;
+ SDL_bool in_title_click;
+ Uint8 focus_click_pending;
+ SDL_bool skip_update_clipcursor;
+ SDL_bool windowed_mode_was_maximized;
+ SDL_bool in_window_deactivation;
+ RECT cursor_clipped_rect;
+ struct SDL_VideoData *videodata;
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+} SDL_WindowData;
+
+extern int WIN_CreateWindow(_THIS, SDL_Window * window);
+extern int WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+extern void WIN_SetWindowTitle(_THIS, SDL_Window * window);
+extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+extern void WIN_SetWindowPosition(_THIS, SDL_Window * window);
+extern void WIN_SetWindowSize(_THIS, SDL_Window * window);
+extern int WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
+extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
+extern void WIN_ShowWindow(_THIS, SDL_Window * window);
+extern void WIN_HideWindow(_THIS, SDL_Window * window);
+extern void WIN_RaiseWindow(_THIS, SDL_Window * window);
+extern void WIN_MaximizeWindow(_THIS, SDL_Window * window);
+extern void WIN_MinimizeWindow(_THIS, SDL_Window * window);
+extern void WIN_RestoreWindow(_THIS, SDL_Window * window);
+extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
+extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
+extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
+extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
+extern void WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+extern void WIN_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+extern void WIN_OnWindowEnter(_THIS, SDL_Window * window);
+extern void WIN_UpdateClipCursor(SDL_Window *window);
+extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
+extern void WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
+
+#endif /* SDL_windowswindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/windows/wmmsg.h b/source/3rd-party/SDL2/src/video/windows/wmmsg.h
new file mode 100644
index 0000000..19c1bf4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/windows/wmmsg.h
@@ -0,0 +1,1052 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0]))
+
+char *wmtab[] = {
+ "WM_NULL",
+ "WM_CREATE",
+ "WM_DESTROY",
+ "WM_MOVE",
+ "UNKNOWN (4)",
+ "WM_SIZE",
+ "WM_ACTIVATE",
+ "WM_SETFOCUS",
+ "WM_KILLFOCUS",
+ "UNKNOWN (9)",
+ "WM_ENABLE",
+ "WM_SETREDRAW",
+ "WM_SETTEXT",
+ "WM_GETTEXT",
+ "WM_GETTEXTLENGTH",
+ "WM_PAINT",
+ "WM_CLOSE",
+ "WM_QUERYENDSESSION",
+ "WM_QUIT",
+ "WM_QUERYOPEN",
+ "WM_ERASEBKGND",
+ "WM_SYSCOLORCHANGE",
+ "WM_ENDSESSION",
+ "UNKNOWN (23)",
+ "WM_SHOWWINDOW",
+ "UNKNOWN (25)",
+ "WM_SETTINGCHANGE",
+ "WM_DEVMODECHANGE",
+ "WM_ACTIVATEAPP",
+ "WM_FONTCHANGE",
+ "WM_TIMECHANGE",
+ "WM_CANCELMODE",
+ "WM_SETCURSOR",
+ "WM_MOUSEACTIVATE",
+ "WM_CHILDACTIVATE",
+ "WM_QUEUESYNC",
+ "WM_GETMINMAXINFO",
+ "UNKNOWN (37)",
+ "WM_PAINTICON",
+ "WM_ICONERASEBKGND",
+ "WM_NEXTDLGCTL",
+ "UNKNOWN (41)",
+ "WM_SPOOLERSTATUS",
+ "WM_DRAWITEM",
+ "WM_MEASUREITEM",
+ "WM_DELETEITEM",
+ "WM_VKEYTOITEM",
+ "WM_CHARTOITEM",
+ "WM_SETFONT",
+ "WM_GETFONT",
+ "WM_SETHOTKEY",
+ "WM_GETHOTKEY",
+ "UNKNOWN (52)",
+ "UNKNOWN (53)",
+ "UNKNOWN (54)",
+ "WM_QUERYDRAGICON",
+ "UNKNOWN (56)",
+ "WM_COMPAREITEM",
+ "UNKNOWN (58)",
+ "UNKNOWN (59)",
+ "UNKNOWN (60)",
+ "WM_GETOBJECT",
+ "UNKNOWN (62)",
+ "UNKNOWN (63)",
+ "UNKNOWN (64)",
+ "WM_COMPACTING",
+ "UNKNOWN (66)",
+ "UNKNOWN (67)",
+ "WM_COMMNOTIFY",
+ "UNKNOWN (69)",
+ "WM_WINDOWPOSCHANGING",
+ "WM_WINDOWPOSCHANGED",
+ "WM_POWER",
+ "UNKNOWN (73)",
+ "WM_COPYDATA",
+ "WM_CANCELJOURNAL",
+ "UNKNOWN (76)",
+ "UNKNOWN (77)",
+ "WM_NOTIFY",
+ "UNKNOWN (79)",
+ "WM_INPUTLANGCHANGEREQUEST",
+ "WM_INPUTLANGCHANGE",
+ "WM_TCARD",
+ "WM_HELP",
+ "WM_USERCHANGED",
+ "WM_NOTIFYFORMAT",
+ "UNKNOWN (86)",
+ "UNKNOWN (87)",
+ "UNKNOWN (88)",
+ "UNKNOWN (89)",
+ "UNKNOWN (90)",
+ "UNKNOWN (91)",
+ "UNKNOWN (92)",
+ "UNKNOWN (93)",
+ "UNKNOWN (94)",
+ "UNKNOWN (95)",
+ "UNKNOWN (96)",
+ "UNKNOWN (97)",
+ "UNKNOWN (98)",
+ "UNKNOWN (99)",
+ "UNKNOWN (100)",
+ "UNKNOWN (101)",
+ "UNKNOWN (102)",
+ "UNKNOWN (103)",
+ "UNKNOWN (104)",
+ "UNKNOWN (105)",
+ "UNKNOWN (106)",
+ "UNKNOWN (107)",
+ "UNKNOWN (108)",
+ "UNKNOWN (109)",
+ "UNKNOWN (110)",
+ "UNKNOWN (111)",
+ "UNKNOWN (112)",
+ "UNKNOWN (113)",
+ "UNKNOWN (114)",
+ "UNKNOWN (115)",
+ "UNKNOWN (116)",
+ "UNKNOWN (117)",
+ "UNKNOWN (118)",
+ "UNKNOWN (119)",
+ "UNKNOWN (120)",
+ "UNKNOWN (121)",
+ "UNKNOWN (122)",
+ "WM_CONTEXTMENU",
+ "WM_STYLECHANGING",
+ "WM_STYLECHANGED",
+ "WM_DISPLAYCHANGE",
+ "WM_GETICON",
+ "WM_SETICON",
+ "WM_NCCREATE",
+ "WM_NCDESTROY",
+ "WM_NCCALCSIZE",
+ "WM_NCHITTEST",
+ "WM_NCPAINT",
+ "WM_NCACTIVATE",
+ "WM_GETDLGCODE",
+ "WM_SYNCPAINT",
+ "UNKNOWN (137)",
+ "UNKNOWN (138)",
+ "UNKNOWN (139)",
+ "UNKNOWN (140)",
+ "UNKNOWN (141)",
+ "UNKNOWN (142)",
+ "UNKNOWN (143)",
+ "UNKNOWN (144)",
+ "UNKNOWN (145)",
+ "UNKNOWN (146)",
+ "UNKNOWN (147)",
+ "UNKNOWN (148)",
+ "UNKNOWN (149)",
+ "UNKNOWN (150)",
+ "UNKNOWN (151)",
+ "UNKNOWN (152)",
+ "UNKNOWN (153)",
+ "UNKNOWN (154)",
+ "UNKNOWN (155)",
+ "UNKNOWN (156)",
+ "UNKNOWN (157)",
+ "UNKNOWN (158)",
+ "UNKNOWN (159)",
+ "WM_NCMOUSEMOVE",
+ "WM_NCLBUTTONDOWN",
+ "WM_NCLBUTTONUP",
+ "WM_NCLBUTTONDBLCLK",
+ "WM_NCRBUTTONDOWN",
+ "WM_NCRBUTTONUP",
+ "WM_NCRBUTTONDBLCLK",
+ "WM_NCMBUTTONDOWN",
+ "WM_NCMBUTTONUP",
+ "WM_NCMBUTTONDBLCLK",
+ "UNKNOWN (170)",
+ "WM_NCXBUTTONDOWN",
+ "WM_NCXBUTTONUP",
+ "WM_NCXBUTTONDBLCLK",
+ "WM_NCUAHDRAWCAPTION",
+ "WM_NCUAHDRAWFRAME",
+ "UNKNOWN (176)",
+ "UNKNOWN (177)",
+ "UNKNOWN (178)",
+ "UNKNOWN (179)",
+ "UNKNOWN (180)",
+ "UNKNOWN (181)",
+ "UNKNOWN (182)",
+ "UNKNOWN (183)",
+ "UNKNOWN (184)",
+ "UNKNOWN (185)",
+ "UNKNOWN (186)",
+ "UNKNOWN (187)",
+ "UNKNOWN (188)",
+ "UNKNOWN (189)",
+ "UNKNOWN (190)",
+ "UNKNOWN (191)",
+ "UNKNOWN (192)",
+ "UNKNOWN (193)",
+ "UNKNOWN (194)",
+ "UNKNOWN (195)",
+ "UNKNOWN (196)",
+ "UNKNOWN (197)",
+ "UNKNOWN (198)",
+ "UNKNOWN (199)",
+ "UNKNOWN (200)",
+ "UNKNOWN (201)",
+ "UNKNOWN (202)",
+ "UNKNOWN (203)",
+ "UNKNOWN (204)",
+ "UNKNOWN (205)",
+ "UNKNOWN (206)",
+ "UNKNOWN (207)",
+ "UNKNOWN (208)",
+ "UNKNOWN (209)",
+ "UNKNOWN (210)",
+ "UNKNOWN (211)",
+ "UNKNOWN (212)",
+ "UNKNOWN (213)",
+ "UNKNOWN (214)",
+ "UNKNOWN (215)",
+ "UNKNOWN (216)",
+ "UNKNOWN (217)",
+ "UNKNOWN (218)",
+ "UNKNOWN (219)",
+ "UNKNOWN (220)",
+ "UNKNOWN (221)",
+ "UNKNOWN (222)",
+ "UNKNOWN (223)",
+ "UNKNOWN (224)",
+ "UNKNOWN (225)",
+ "UNKNOWN (226)",
+ "UNKNOWN (227)",
+ "UNKNOWN (228)",
+ "UNKNOWN (229)",
+ "UNKNOWN (230)",
+ "UNKNOWN (231)",
+ "UNKNOWN (232)",
+ "UNKNOWN (233)",
+ "UNKNOWN (234)",
+ "UNKNOWN (235)",
+ "UNKNOWN (236)",
+ "UNKNOWN (237)",
+ "UNKNOWN (238)",
+ "UNKNOWN (239)",
+ "UNKNOWN (240)",
+ "UNKNOWN (241)",
+ "UNKNOWN (242)",
+ "UNKNOWN (243)",
+ "UNKNOWN (244)",
+ "UNKNOWN (245)",
+ "UNKNOWN (246)",
+ "UNKNOWN (247)",
+ "UNKNOWN (248)",
+ "UNKNOWN (249)",
+ "UNKNOWN (250)",
+ "UNKNOWN (251)",
+ "UNKNOWN (252)",
+ "UNKNOWN (253)",
+ "UNKNOWN (254)",
+ "WM_INPUT",
+ "WM_KEYDOWN",
+ "WM_KEYUP",
+ "WM_CHAR",
+ "WM_DEADCHAR",
+ "WM_SYSKEYDOWN",
+ "WM_SYSKEYUP",
+ "WM_SYSCHAR",
+ "WM_SYSDEADCHAR",
+ "WM_KEYLAST",
+ "UNKNOWN (265)",
+ "UNKNOWN (266)",
+ "UNKNOWN (267)",
+ "UNKNOWN (268)",
+ "UNKNOWN (269)",
+ "UNKNOWN (270)",
+ "UNKNOWN (271)",
+ "WM_INITDIALOG",
+ "WM_COMMAND",
+ "WM_SYSCOMMAND",
+ "WM_TIMER",
+ "WM_HSCROLL",
+ "WM_VSCROLL",
+ "WM_INITMENU",
+ "WM_INITMENUPOPUP",
+ "UNKNOWN (280)",
+ "WM_GESTURE",
+ "UNKNOWN (282)",
+ "UNKNOWN (283)",
+ "UNKNOWN (284)",
+ "UNKNOWN (285)",
+ "UNKNOWN (286)",
+ "WM_MENUSELECT",
+ "WM_MENUCHAR",
+ "WM_ENTERIDLE",
+ "WM_MENURBUTTONUP",
+ "WM_MENUDRAG",
+ "WM_MENUGETOBJECT",
+ "WM_UNINITMENUPOPUP",
+ "WM_MENUCOMMAND",
+ "UNKNOWN (295)",
+ "UNKNOWN (296)",
+ "UNKNOWN (297)",
+ "UNKNOWN (298)",
+ "UNKNOWN (299)",
+ "UNKNOWN (300)",
+ "UNKNOWN (301)",
+ "UNKNOWN (302)",
+ "UNKNOWN (303)",
+ "UNKNOWN (304)",
+ "UNKNOWN (305)",
+ "WM_CTLCOLORMSGBOX",
+ "WM_CTLCOLOREDIT",
+ "WM_CTLCOLORLISTBOX",
+ "WM_CTLCOLORBTN",
+ "WM_CTLCOLORDLG",
+ "WM_CTLCOLORSCROLLBAR",
+ "WM_CTLCOLORSTATIC",
+ "UNKNOWN (313)",
+ "UNKNOWN (314)",
+ "UNKNOWN (315)",
+ "UNKNOWN (316)",
+ "UNKNOWN (317)",
+ "UNKNOWN (318)",
+ "UNKNOWN (319)",
+ "UNKNOWN (320)",
+ "UNKNOWN (321)",
+ "UNKNOWN (322)",
+ "UNKNOWN (323)",
+ "UNKNOWN (324)",
+ "UNKNOWN (325)",
+ "UNKNOWN (326)",
+ "UNKNOWN (327)",
+ "UNKNOWN (328)",
+ "UNKNOWN (329)",
+ "UNKNOWN (330)",
+ "UNKNOWN (331)",
+ "UNKNOWN (332)",
+ "UNKNOWN (333)",
+ "UNKNOWN (334)",
+ "UNKNOWN (335)",
+ "UNKNOWN (336)",
+ "UNKNOWN (337)",
+ "UNKNOWN (338)",
+ "UNKNOWN (339)",
+ "UNKNOWN (340)",
+ "UNKNOWN (341)",
+ "UNKNOWN (342)",
+ "UNKNOWN (343)",
+ "UNKNOWN (344)",
+ "UNKNOWN (345)",
+ "UNKNOWN (346)",
+ "UNKNOWN (347)",
+ "UNKNOWN (348)",
+ "UNKNOWN (349)",
+ "UNKNOWN (350)",
+ "UNKNOWN (351)",
+ "UNKNOWN (352)",
+ "UNKNOWN (353)",
+ "UNKNOWN (354)",
+ "UNKNOWN (355)",
+ "UNKNOWN (356)",
+ "UNKNOWN (357)",
+ "UNKNOWN (358)",
+ "UNKNOWN (359)",
+ "UNKNOWN (360)",
+ "UNKNOWN (361)",
+ "UNKNOWN (362)",
+ "UNKNOWN (363)",
+ "UNKNOWN (364)",
+ "UNKNOWN (365)",
+ "UNKNOWN (366)",
+ "UNKNOWN (367)",
+ "UNKNOWN (368)",
+ "UNKNOWN (369)",
+ "UNKNOWN (370)",
+ "UNKNOWN (371)",
+ "UNKNOWN (372)",
+ "UNKNOWN (373)",
+ "UNKNOWN (374)",
+ "UNKNOWN (375)",
+ "UNKNOWN (376)",
+ "UNKNOWN (377)",
+ "UNKNOWN (378)",
+ "UNKNOWN (379)",
+ "UNKNOWN (380)",
+ "UNKNOWN (381)",
+ "UNKNOWN (382)",
+ "UNKNOWN (383)",
+ "UNKNOWN (384)",
+ "UNKNOWN (385)",
+ "UNKNOWN (386)",
+ "UNKNOWN (387)",
+ "UNKNOWN (388)",
+ "UNKNOWN (389)",
+ "UNKNOWN (390)",
+ "UNKNOWN (391)",
+ "UNKNOWN (392)",
+ "UNKNOWN (393)",
+ "UNKNOWN (394)",
+ "UNKNOWN (395)",
+ "UNKNOWN (396)",
+ "UNKNOWN (397)",
+ "UNKNOWN (398)",
+ "UNKNOWN (399)",
+ "UNKNOWN (400)",
+ "UNKNOWN (401)",
+ "UNKNOWN (402)",
+ "UNKNOWN (403)",
+ "UNKNOWN (404)",
+ "UNKNOWN (405)",
+ "UNKNOWN (406)",
+ "UNKNOWN (407)",
+ "UNKNOWN (408)",
+ "UNKNOWN (409)",
+ "UNKNOWN (410)",
+ "UNKNOWN (411)",
+ "UNKNOWN (412)",
+ "UNKNOWN (413)",
+ "UNKNOWN (414)",
+ "UNKNOWN (415)",
+ "UNKNOWN (416)",
+ "UNKNOWN (417)",
+ "UNKNOWN (418)",
+ "UNKNOWN (419)",
+ "UNKNOWN (420)",
+ "UNKNOWN (421)",
+ "UNKNOWN (422)",
+ "UNKNOWN (423)",
+ "UNKNOWN (424)",
+ "UNKNOWN (425)",
+ "UNKNOWN (426)",
+ "UNKNOWN (427)",
+ "UNKNOWN (428)",
+ "UNKNOWN (429)",
+ "UNKNOWN (430)",
+ "UNKNOWN (431)",
+ "UNKNOWN (432)",
+ "UNKNOWN (433)",
+ "UNKNOWN (434)",
+ "UNKNOWN (435)",
+ "UNKNOWN (436)",
+ "UNKNOWN (437)",
+ "UNKNOWN (438)",
+ "UNKNOWN (439)",
+ "UNKNOWN (440)",
+ "UNKNOWN (441)",
+ "UNKNOWN (442)",
+ "UNKNOWN (443)",
+ "UNKNOWN (444)",
+ "UNKNOWN (445)",
+ "UNKNOWN (446)",
+ "UNKNOWN (447)",
+ "UNKNOWN (448)",
+ "UNKNOWN (449)",
+ "UNKNOWN (450)",
+ "UNKNOWN (451)",
+ "UNKNOWN (452)",
+ "UNKNOWN (453)",
+ "UNKNOWN (454)",
+ "UNKNOWN (455)",
+ "UNKNOWN (456)",
+ "UNKNOWN (457)",
+ "UNKNOWN (458)",
+ "UNKNOWN (459)",
+ "UNKNOWN (460)",
+ "UNKNOWN (461)",
+ "UNKNOWN (462)",
+ "UNKNOWN (463)",
+ "UNKNOWN (464)",
+ "UNKNOWN (465)",
+ "UNKNOWN (466)",
+ "UNKNOWN (467)",
+ "UNKNOWN (468)",
+ "UNKNOWN (469)",
+ "UNKNOWN (470)",
+ "UNKNOWN (471)",
+ "UNKNOWN (472)",
+ "UNKNOWN (473)",
+ "UNKNOWN (474)",
+ "UNKNOWN (475)",
+ "UNKNOWN (476)",
+ "UNKNOWN (477)",
+ "UNKNOWN (478)",
+ "UNKNOWN (479)",
+ "UNKNOWN (480)",
+ "UNKNOWN (481)",
+ "UNKNOWN (482)",
+ "UNKNOWN (483)",
+ "UNKNOWN (484)",
+ "UNKNOWN (485)",
+ "UNKNOWN (486)",
+ "UNKNOWN (487)",
+ "UNKNOWN (488)",
+ "UNKNOWN (489)",
+ "UNKNOWN (490)",
+ "UNKNOWN (491)",
+ "UNKNOWN (492)",
+ "UNKNOWN (493)",
+ "UNKNOWN (494)",
+ "UNKNOWN (495)",
+ "UNKNOWN (496)",
+ "UNKNOWN (497)",
+ "UNKNOWN (498)",
+ "UNKNOWN (499)",
+ "UNKNOWN (500)",
+ "UNKNOWN (501)",
+ "UNKNOWN (502)",
+ "UNKNOWN (503)",
+ "UNKNOWN (504)",
+ "UNKNOWN (505)",
+ "UNKNOWN (506)",
+ "UNKNOWN (507)",
+ "UNKNOWN (508)",
+ "UNKNOWN (509)",
+ "UNKNOWN (510)",
+ "UNKNOWN (511)",
+ "WM_MOUSEMOVE",
+ "WM_LBUTTONDOWN",
+ "WM_LBUTTONUP",
+ "WM_LBUTTONDBLCLK",
+ "WM_RBUTTONDOWN",
+ "WM_RBUTTONUP",
+ "WM_RBUTTONDBLCLK",
+ "WM_MBUTTONDOWN",
+ "WM_MBUTTONUP",
+ "WM_MOUSELAST",
+ "WM_MOUSEWHEEL",
+ "WM_XBUTTONDOWN",
+ "WM_XBUTTONUP",
+ "UNKNOWN (525)",
+ "UNKNOWN (526)",
+ "UNKNOWN (527)",
+ "WM_PARENTNOTIFY",
+ "WM_ENTERMENULOOP",
+ "WM_EXITMENULOOP",
+ "WM_NEXTMENU",
+ "WM_SIZING",
+ "WM_CAPTURECHANGED",
+ "WM_MOVING",
+ "UNKNOWN (535)",
+ "WM_POWERBROADCAST",
+ "WM_DEVICECHANGE",
+ "UNKNOWN (538)",
+ "UNKNOWN (539)",
+ "UNKNOWN (540)",
+ "UNKNOWN (541)",
+ "UNKNOWN (542)",
+ "UNKNOWN (543)",
+ "WM_MDICREATE",
+ "WM_MDIDESTROY",
+ "WM_MDIACTIVATE",
+ "WM_MDIRESTORE",
+ "WM_MDINEXT",
+ "WM_MDIMAXIMIZE",
+ "WM_MDITILE",
+ "WM_MDICASCADE",
+ "WM_MDIICONARRANGE",
+ "WM_MDIGETACTIVE",
+ "UNKNOWN (554)",
+ "UNKNOWN (555)",
+ "UNKNOWN (556)",
+ "UNKNOWN (557)",
+ "UNKNOWN (558)",
+ "UNKNOWN (559)",
+ "WM_MDISETMENU",
+ "WM_ENTERSIZEMOVE",
+ "WM_EXITSIZEMOVE",
+ "WM_DROPFILES",
+ "WM_MDIREFRESHMENU",
+ "UNKNOWN (565)",
+ "UNKNOWN (566)",
+ "UNKNOWN (567)",
+ "WM_POINTERDEVICECHANGE",
+ "WM_POINTERDEVICEINRANGE",
+ "WM_POINTERDEVICEOUTOFRANGE",
+ "UNKNOWN (571)",
+ "UNKNOWN (572)",
+ "UNKNOWN (573)",
+ "UNKNOWN (574)",
+ "UNKNOWN (575)",
+ "WM_TOUCH",
+ "WM_NCPOINTERUPDATE",
+ "WM_NCPOINTERDOWN",
+ "WM_NCPOINTERUP",
+ "UNKNOWN (580)",
+ "WM_POINTERUPDATE",
+ "WM_POINTERDOWN",
+ "WM_POINTERUP",
+ "WM_POINTERENTER",
+ "WM_POINTERLEAVE",
+ "WM_POINTERACTIVATE",
+ "WM_POINTERCAPTURECHANGED",
+ "WM_TOUCHHITTESTING",
+ "WM_POINTERWHEEL",
+ "WM_POINTERHWHEEL",
+ "DM_POINTERHITTEST",
+ "UNKNOWN (592)",
+ "UNKNOWN (593)",
+ "UNKNOWN (594)",
+ "UNKNOWN (595)",
+ "UNKNOWN (596)",
+ "UNKNOWN (597)",
+ "UNKNOWN (598)",
+ "UNKNOWN (599)",
+ "UNKNOWN (600)",
+ "UNKNOWN (601)",
+ "UNKNOWN (602)",
+ "UNKNOWN (603)",
+ "UNKNOWN (604)",
+ "UNKNOWN (605)",
+ "UNKNOWN (606)",
+ "UNKNOWN (607)",
+ "UNKNOWN (608)",
+ "UNKNOWN (609)",
+ "UNKNOWN (610)",
+ "UNKNOWN (611)",
+ "UNKNOWN (612)",
+ "UNKNOWN (613)",
+ "UNKNOWN (614)",
+ "UNKNOWN (615)",
+ "UNKNOWN (616)",
+ "UNKNOWN (617)",
+ "UNKNOWN (618)",
+ "UNKNOWN (619)",
+ "UNKNOWN (620)",
+ "UNKNOWN (621)",
+ "UNKNOWN (622)",
+ "UNKNOWN (623)",
+ "UNKNOWN (624)",
+ "UNKNOWN (625)",
+ "UNKNOWN (626)",
+ "UNKNOWN (627)",
+ "UNKNOWN (628)",
+ "UNKNOWN (629)",
+ "UNKNOWN (630)",
+ "UNKNOWN (631)",
+ "UNKNOWN (632)",
+ "UNKNOWN (633)",
+ "UNKNOWN (634)",
+ "UNKNOWN (635)",
+ "UNKNOWN (636)",
+ "UNKNOWN (637)",
+ "UNKNOWN (638)",
+ "UNKNOWN (639)",
+ "UNKNOWN (640)",
+ "WM_IME_SETCONTEXT",
+ "WM_IME_NOTIFY",
+ "WM_IME_CONTROL",
+ "WM_IME_COMPOSITIONFULL",
+ "WM_IME_SELECT",
+ "WM_IME_CHAR",
+ "UNKNOWN (647)",
+ "WM_IME_REQUEST",
+ "UNKNOWN (649)",
+ "UNKNOWN (650)",
+ "UNKNOWN (651)",
+ "UNKNOWN (652)",
+ "UNKNOWN (653)",
+ "UNKNOWN (654)",
+ "UNKNOWN (655)",
+ "WM_IME_KEYDOWN",
+ "WM_IME_KEYUP",
+ "UNKNOWN (658)",
+ "UNKNOWN (659)",
+ "UNKNOWN (660)",
+ "UNKNOWN (661)",
+ "UNKNOWN (662)",
+ "UNKNOWN (663)",
+ "UNKNOWN (664)",
+ "UNKNOWN (665)",
+ "UNKNOWN (666)",
+ "UNKNOWN (667)",
+ "UNKNOWN (668)",
+ "UNKNOWN (669)",
+ "UNKNOWN (670)",
+ "UNKNOWN (671)",
+ "WM_NCMOUSEHOVER",
+ "WM_MOUSEHOVER",
+ "WM_NCMOUSELEAVE",
+ "WM_MOUSELEAVE",
+ "UNKNOWN (676)",
+ "UNKNOWN (677)",
+ "UNKNOWN (678)",
+ "UNKNOWN (679)",
+ "UNKNOWN (680)",
+ "UNKNOWN (681)",
+ "UNKNOWN (682)",
+ "UNKNOWN (683)",
+ "UNKNOWN (684)",
+ "UNKNOWN (685)",
+ "UNKNOWN (686)",
+ "UNKNOWN (687)",
+ "UNKNOWN (688)",
+ "WM_WTSSESSION_CHANGE",
+ "UNKNOWN (690)",
+ "UNKNOWN (691)",
+ "UNKNOWN (692)",
+ "UNKNOWN (693)",
+ "UNKNOWN (694)",
+ "UNKNOWN (695)",
+ "UNKNOWN (696)",
+ "UNKNOWN (697)",
+ "UNKNOWN (698)",
+ "UNKNOWN (699)",
+ "UNKNOWN (700)",
+ "UNKNOWN (701)",
+ "UNKNOWN (702)",
+ "UNKNOWN (703)",
+ "UNKNOWN (704)",
+ "UNKNOWN (705)",
+ "UNKNOWN (706)",
+ "UNKNOWN (707)",
+ "UNKNOWN (708)",
+ "UNKNOWN (709)",
+ "UNKNOWN (710)",
+ "UNKNOWN (711)",
+ "UNKNOWN (712)",
+ "UNKNOWN (713)",
+ "UNKNOWN (714)",
+ "UNKNOWN (715)",
+ "UNKNOWN (716)",
+ "UNKNOWN (717)",
+ "UNKNOWN (718)",
+ "UNKNOWN (719)",
+ "UNKNOWN (720)",
+ "UNKNOWN (721)",
+ "UNKNOWN (722)",
+ "UNKNOWN (723)",
+ "UNKNOWN (724)",
+ "UNKNOWN (725)",
+ "UNKNOWN (726)",
+ "UNKNOWN (727)",
+ "UNKNOWN (728)",
+ "UNKNOWN (729)",
+ "UNKNOWN (730)",
+ "UNKNOWN (731)",
+ "UNKNOWN (732)",
+ "UNKNOWN (733)",
+ "UNKNOWN (734)",
+ "UNKNOWN (735)",
+ "WM_DPICHANGED",
+ "UNKNOWN (737)",
+ "UNKNOWN (738)",
+ "UNKNOWN (739)",
+ "UNKNOWN (740)",
+ "UNKNOWN (741)",
+ "UNKNOWN (742)",
+ "UNKNOWN (743)",
+ "UNKNOWN (744)",
+ "UNKNOWN (745)",
+ "UNKNOWN (746)",
+ "UNKNOWN (747)",
+ "UNKNOWN (748)",
+ "UNKNOWN (749)",
+ "UNKNOWN (750)",
+ "UNKNOWN (751)",
+ "UNKNOWN (752)",
+ "UNKNOWN (753)",
+ "UNKNOWN (754)",
+ "UNKNOWN (755)",
+ "UNKNOWN (756)",
+ "UNKNOWN (757)",
+ "UNKNOWN (758)",
+ "UNKNOWN (759)",
+ "UNKNOWN (760)",
+ "UNKNOWN (761)",
+ "UNKNOWN (762)",
+ "UNKNOWN (763)",
+ "UNKNOWN (764)",
+ "UNKNOWN (765)",
+ "UNKNOWN (766)",
+ "UNKNOWN (767)",
+ "WM_CUT",
+ "WM_COPY",
+ "WM_PASTE",
+ "WM_CLEAR",
+ "WM_UNDO",
+ "WM_RENDERFORMAT",
+ "WM_RENDERALLFORMATS",
+ "WM_DESTROYCLIPBOARD",
+ "WM_DRAWCLIPBOARD",
+ "WM_PAINTCLIPBOARD",
+ "WM_VSCROLLCLIPBOARD",
+ "WM_SIZECLIPBOARD",
+ "WM_ASKCBFORMATNAME",
+ "WM_CHANGECBCHAIN",
+ "WM_HSCROLLCLIPBOARD",
+ "WM_QUERYNEWPALETTE",
+ "WM_PALETTEISCHANGING",
+ "WM_PALETTECHANGED",
+ "WM_HOTKEY",
+ "UNKNOWN (787)",
+ "UNKNOWN (788)",
+ "UNKNOWN (789)",
+ "UNKNOWN (790)",
+ "WM_PRINT",
+ "WM_PRINTCLIENT",
+ "WM_APPCOMMAND",
+ "WM_THEMECHANGED",
+ "UNKNOWN (795)",
+ "UNKNOWN (796)",
+ "WM_CLIPBOARDUPDATE",
+ "WM_DWMCOMPOSITIONCHANGED",
+ "WM_DWMNCRENDERINGCHANGED",
+ "WM_DWMCOLORIZATIONCOLORCHANGED",
+ "WM_DWMWINDOWMAXIMIZEDCHANGE",
+ "UNKNOWN (802)",
+ "WM_DWMSENDICONICTHUMBNAIL",
+ "UNKNOWN (804)",
+ "UNKNOWN (805)",
+ "WM_DWMSENDICONICLIVEPREVIEWBITMAP",
+ "UNKNOWN (807)",
+ "UNKNOWN (808)",
+ "UNKNOWN (809)",
+ "UNKNOWN (810)",
+ "UNKNOWN (811)",
+ "UNKNOWN (812)",
+ "UNKNOWN (813)",
+ "UNKNOWN (814)",
+ "UNKNOWN (815)",
+ "UNKNOWN (816)",
+ "UNKNOWN (817)",
+ "UNKNOWN (818)",
+ "UNKNOWN (819)",
+ "UNKNOWN (820)",
+ "UNKNOWN (821)",
+ "UNKNOWN (822)",
+ "UNKNOWN (823)",
+ "UNKNOWN (824)",
+ "UNKNOWN (825)",
+ "UNKNOWN (826)",
+ "UNKNOWN (827)",
+ "UNKNOWN (828)",
+ "UNKNOWN (829)",
+ "UNKNOWN (830)",
+ "WM_GETTITLEBARINFOEX",
+ "UNKNOWN (832)",
+ "UNKNOWN (833)",
+ "UNKNOWN (834)",
+ "UNKNOWN (835)",
+ "UNKNOWN (836)",
+ "UNKNOWN (837)",
+ "UNKNOWN (838)",
+ "UNKNOWN (839)",
+ "UNKNOWN (840)",
+ "UNKNOWN (841)",
+ "UNKNOWN (842)",
+ "UNKNOWN (843)",
+ "UNKNOWN (844)",
+ "UNKNOWN (845)",
+ "UNKNOWN (846)",
+ "UNKNOWN (847)",
+ "UNKNOWN (848)",
+ "UNKNOWN (849)",
+ "UNKNOWN (850)",
+ "UNKNOWN (851)",
+ "UNKNOWN (852)",
+ "UNKNOWN (853)",
+ "UNKNOWN (854)",
+ "UNKNOWN (855)",
+ "WM_HANDHELDFIRST",
+ "UNKNOWN (857)",
+ "UNKNOWN (858)",
+ "UNKNOWN (859)",
+ "UNKNOWN (860)",
+ "UNKNOWN (861)",
+ "UNKNOWN (862)",
+ "WM_HANDHELDLAST",
+ "WM_AFXFIRST",
+ "UNKNOWN (865)",
+ "UNKNOWN (866)",
+ "UNKNOWN (867)",
+ "UNKNOWN (868)",
+ "UNKNOWN (869)",
+ "UNKNOWN (870)",
+ "UNKNOWN (871)",
+ "UNKNOWN (872)",
+ "UNKNOWN (873)",
+ "UNKNOWN (874)",
+ "UNKNOWN (875)",
+ "UNKNOWN (876)",
+ "UNKNOWN (877)",
+ "UNKNOWN (878)",
+ "UNKNOWN (879)",
+ "UNKNOWN (880)",
+ "UNKNOWN (881)",
+ "UNKNOWN (882)",
+ "UNKNOWN (883)",
+ "UNKNOWN (884)",
+ "UNKNOWN (885)",
+ "UNKNOWN (886)",
+ "UNKNOWN (887)",
+ "UNKNOWN (888)",
+ "UNKNOWN (889)",
+ "UNKNOWN (890)",
+ "UNKNOWN (891)",
+ "UNKNOWN (892)",
+ "UNKNOWN (893)",
+ "UNKNOWN (894)",
+ "WM_AFXLAST",
+ "WM_PENWINFIRST",
+ "UNKNOWN (897)",
+ "UNKNOWN (898)",
+ "UNKNOWN (899)",
+ "UNKNOWN (900)",
+ "UNKNOWN (901)",
+ "UNKNOWN (902)",
+ "UNKNOWN (903)",
+ "UNKNOWN (904)",
+ "UNKNOWN (905)",
+ "UNKNOWN (906)",
+ "UNKNOWN (907)",
+ "UNKNOWN (908)",
+ "UNKNOWN (909)",
+ "UNKNOWN (910)",
+ "WM_PENWINLAST",
+ "UNKNOWN (912)",
+ "UNKNOWN (913)",
+ "UNKNOWN (914)",
+ "UNKNOWN (915)",
+ "UNKNOWN (916)",
+ "UNKNOWN (917)",
+ "UNKNOWN (918)",
+ "UNKNOWN (919)",
+ "UNKNOWN (920)",
+ "UNKNOWN (921)",
+ "UNKNOWN (922)",
+ "UNKNOWN (923)",
+ "UNKNOWN (924)",
+ "UNKNOWN (925)",
+ "UNKNOWN (926)",
+ "UNKNOWN (927)",
+ "UNKNOWN (928)",
+ "UNKNOWN (929)",
+ "UNKNOWN (930)",
+ "UNKNOWN (931)",
+ "UNKNOWN (932)",
+ "UNKNOWN (933)",
+ "UNKNOWN (934)",
+ "UNKNOWN (935)",
+ "UNKNOWN (936)",
+ "UNKNOWN (937)",
+ "UNKNOWN (938)",
+ "UNKNOWN (939)",
+ "UNKNOWN (940)",
+ "UNKNOWN (941)",
+ "UNKNOWN (942)",
+ "UNKNOWN (943)",
+ "UNKNOWN (944)",
+ "UNKNOWN (945)",
+ "UNKNOWN (946)",
+ "UNKNOWN (947)",
+ "UNKNOWN (948)",
+ "UNKNOWN (949)",
+ "UNKNOWN (950)",
+ "UNKNOWN (951)",
+ "UNKNOWN (952)",
+ "UNKNOWN (953)",
+ "UNKNOWN (954)",
+ "UNKNOWN (955)",
+ "UNKNOWN (956)",
+ "UNKNOWN (957)",
+ "UNKNOWN (958)",
+ "UNKNOWN (959)",
+ "UNKNOWN (960)",
+ "UNKNOWN (961)",
+ "UNKNOWN (962)",
+ "UNKNOWN (963)",
+ "UNKNOWN (964)",
+ "UNKNOWN (965)",
+ "UNKNOWN (966)",
+ "UNKNOWN (967)",
+ "UNKNOWN (968)",
+ "UNKNOWN (969)",
+ "UNKNOWN (970)",
+ "UNKNOWN (971)",
+ "UNKNOWN (972)",
+ "UNKNOWN (973)",
+ "UNKNOWN (974)",
+ "UNKNOWN (975)",
+ "UNKNOWN (976)",
+ "UNKNOWN (977)",
+ "UNKNOWN (978)",
+ "UNKNOWN (979)",
+ "UNKNOWN (980)",
+ "UNKNOWN (981)",
+ "UNKNOWN (982)",
+ "UNKNOWN (983)",
+ "UNKNOWN (984)",
+ "UNKNOWN (985)",
+ "UNKNOWN (986)",
+ "UNKNOWN (987)",
+ "UNKNOWN (988)",
+ "UNKNOWN (989)",
+ "UNKNOWN (990)",
+ "UNKNOWN (991)",
+ "UNKNOWN (992)",
+ "UNKNOWN (993)",
+ "UNKNOWN (994)",
+ "UNKNOWN (995)",
+ "UNKNOWN (996)",
+ "UNKNOWN (997)",
+ "UNKNOWN (998)",
+ "UNKNOWN (999)",
+ "UNKNOWN (1000)",
+ "UNKNOWN (1001)",
+ "UNKNOWN (1002)",
+ "UNKNOWN (1003)",
+ "UNKNOWN (1004)",
+ "UNKNOWN (1005)",
+ "UNKNOWN (1006)",
+ "UNKNOWN (1007)",
+ "UNKNOWN (1008)",
+ "UNKNOWN (1009)",
+ "UNKNOWN (1010)",
+ "UNKNOWN (1011)",
+ "UNKNOWN (1012)",
+ "UNKNOWN (1013)",
+ "UNKNOWN (1014)",
+ "UNKNOWN (1015)",
+ "UNKNOWN (1016)",
+ "UNKNOWN (1017)",
+ "UNKNOWN (1018)",
+ "UNKNOWN (1019)",
+ "UNKNOWN (1020)",
+ "UNKNOWN (1021)",
+ "UNKNOWN (1022)",
+ "UNKNOWN (1023)",
+ "WM_USER"
+};
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp
new file mode 100644
index 0000000..370e8c5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents.cpp
@@ -0,0 +1,154 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/*
+ * Windows includes:
+ */
+#include <Windows.h>
+using namespace Windows::UI::Core;
+using Windows::UI::Core::CoreCursor;
+
+/*
+ * SDL includes:
+ */
+#include "SDL_winrtevents_c.h"
+#include "../../core/winrt/SDL_winrtapp_common.h"
+#include "../../core/winrt/SDL_winrtapp_direct3d.h"
+#include "../../core/winrt/SDL_winrtapp_xaml.h"
+#include "SDL_assert.h"
+#include "SDL_system.h"
+
+extern "C" {
+#include "../../thread/SDL_systhread.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+}
+
+
+/* Forward declarations */
+static void WINRT_YieldXAMLThread();
+
+
+/* Global event management */
+
+void
+WINRT_PumpEvents(_THIS)
+{
+ if (SDL_WinRTGlobalApp) {
+ SDL_WinRTGlobalApp->PumpEvents();
+ } else if (WINRT_XAMLWasEnabled) {
+ WINRT_YieldXAMLThread();
+ }
+}
+
+
+/* XAML Thread management */
+
+enum SDL_XAMLAppThreadState
+{
+ ThreadState_NotLaunched = 0,
+ ThreadState_Running,
+ ThreadState_Yielding
+};
+
+static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched;
+static SDL_Thread * _XAMLThread = nullptr;
+static SDL_mutex * _mutex = nullptr;
+static SDL_cond * _cond = nullptr;
+
+static void
+WINRT_YieldXAMLThread()
+{
+ SDL_LockMutex(_mutex);
+ SDL_assert(_threadState == ThreadState_Running);
+ _threadState = ThreadState_Yielding;
+ SDL_UnlockMutex(_mutex);
+
+ SDL_CondSignal(_cond);
+
+ SDL_LockMutex(_mutex);
+ while (_threadState != ThreadState_Running) {
+ SDL_CondWait(_cond, _mutex);
+ }
+ SDL_UnlockMutex(_mutex);
+}
+
+static int
+WINRT_XAMLThreadMain(void * userdata)
+{
+ // TODO, WinRT: pass the C-style main() a reasonably realistic
+ // representation of command line arguments.
+ int argc = 0;
+ char **argv = NULL;
+ return WINRT_SDLAppEntryPoint(argc, argv);
+}
+
+void
+WINRT_CycleXAMLThread(void)
+{
+ switch (_threadState) {
+ case ThreadState_NotLaunched:
+ {
+ _cond = SDL_CreateCond();
+
+ _mutex = SDL_CreateMutex();
+ _threadState = ThreadState_Running;
+ _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr);
+
+ SDL_LockMutex(_mutex);
+ while (_threadState != ThreadState_Yielding) {
+ SDL_CondWait(_cond, _mutex);
+ }
+ SDL_UnlockMutex(_mutex);
+
+ break;
+ }
+
+ case ThreadState_Running:
+ {
+ SDL_assert(false);
+ break;
+ }
+
+ case ThreadState_Yielding:
+ {
+ SDL_LockMutex(_mutex);
+ SDL_assert(_threadState == ThreadState_Yielding);
+ _threadState = ThreadState_Running;
+ SDL_UnlockMutex(_mutex);
+
+ SDL_CondSignal(_cond);
+
+ SDL_LockMutex(_mutex);
+ while (_threadState != ThreadState_Yielding) {
+ SDL_CondWait(_cond, _mutex);
+ }
+ SDL_UnlockMutex(_mutex);
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h
new file mode 100644
index 0000000..8b346ec
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtevents_c.h
@@ -0,0 +1,82 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+extern "C" {
+#include "../SDL_sysvideo.h"
+}
+
+/*
+ * Internal-use, C-style functions:
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void WINRT_InitTouch(_THIS);
+extern void WINRT_PumpEvents(_THIS);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+ * Internal-use, C++/CX functions:
+ */
+#ifdef __cplusplus_winrt
+
+/* Pointers (Mice, Touch, etc.) */
+typedef enum {
+ NormalizeZeroToOne,
+ TransformToSDLWindowSize
+} WINRT_CursorNormalizationType;
+extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window,
+ Windows::Foundation::Point rawPosition,
+ WINRT_CursorNormalizationType normalization);
+extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt);
+extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
+extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
+extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
+extern void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
+extern void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
+extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint);
+extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args);
+
+/* Keyboard */
+extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args);
+extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args);
+extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args);
+
+#if NTDDI_VERSION >= NTDDI_WIN10
+extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS);
+extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window);
+extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window);
+extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window);
+#endif // NTDDI_VERSION >= ...
+
+/* XAML Thread Management */
+extern void WINRT_CycleXAMLThread(void);
+
+#endif // ifdef __cplusplus_winrt
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp
new file mode 100644
index 0000000..9617111
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar.cpp
@@ -0,0 +1,196 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/* Windows includes */
+#include <roapi.h>
+#include <windows.foundation.h>
+#include <EventToken.h>
+
+
+/* SDL includes */
+extern "C" {
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+}
+#include "SDL_winrtvideo_cpp.h"
+
+
+/* Game Bar events can come in off the main thread. Use the following
+ WinRT CoreDispatcher to deal with them on SDL's thread.
+*/
+static Platform::WeakReference WINRT_MainThreadDispatcher;
+
+
+/* Win10's initial SDK (the 10.0.10240.0 release) does not include references
+ to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0.
+
+ Declare its WinRT/COM interface here, to allow compilation with earlier
+ Windows SDKs.
+*/
+MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7")
+IGameBarStatics_ : public IInspectable
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
+ __FIEventHandler_1_IInspectable *handler,
+ Windows::Foundation::EventRegistrationToken *token) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
+ Windows::Foundation::EventRegistrationToken token) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged(
+ __FIEventHandler_1_IInspectable *handler,
+ Windows::Foundation::EventRegistrationToken *token) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged(
+ Windows::Foundation::EventRegistrationToken token) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE get_Visible(
+ boolean *value) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected(
+ boolean *value) = 0;
+};
+
+/* Declare the game bar's COM GUID */
+static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };
+
+/* Retrieves a pointer to the game bar, or NULL if it is not available.
+ If a pointer is returned, it's ->Release() method must be called
+ after the caller has finished using it.
+*/
+static IGameBarStatics_ *
+WINRT_GetGameBar()
+{
+ wchar_t *wClassName = L"Windows.Gaming.UI.GameBar";
+ HSTRING hClassName;
+ IActivationFactory *pActivationFactory = NULL;
+ IGameBarStatics_ *pGameBar = NULL;
+ HRESULT hr;
+
+ hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
+ if (FAILED(hr)) {
+ goto done;
+ }
+
+ hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
+ if (FAILED(hr)) {
+ goto done;
+ }
+
+ pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar);
+
+done:
+ if (pActivationFactory) {
+ pActivationFactory->Release();
+ }
+ if (hClassName) {
+ ::WindowsDeleteString(hClassName);
+ }
+ return pGameBar;
+}
+
+static void
+WINRT_HandleGameBarIsInputRedirected_MainThread()
+{
+ IGameBarStatics_ *gameBar;
+ boolean isInputRedirected = 0;
+ if (!WINRT_MainThreadDispatcher) {
+ /* The game bar event handler has been deregistered! */
+ return;
+ }
+ gameBar = WINRT_GetGameBar();
+ if (!gameBar) {
+ /* Shouldn't happen, but just in case... */
+ return;
+ }
+ if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
+ if ( ! isInputRedirected) {
+ /* Input-control is now back to the SDL app. Restore the cursor,
+ in case Windows does not (it does not in either Win10
+ 10.0.10240.0 or 10.0.10586.0, maybe later version(s) too.
+ */
+ SDL_Cursor *cursor = SDL_GetCursor();
+ SDL_SetCursor(cursor);
+ }
+ }
+ gameBar->Release();
+}
+
+static void
+WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2)
+{
+ Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>();
+ if (dispatcher) {
+ dispatcher->RunAsync(
+ Windows::UI::Core::CoreDispatcherPriority::Normal,
+ ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread));
+ }
+}
+
+void
+WINRT_InitGameBar(_THIS)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
+ IGameBarStatics_ *gameBar = WINRT_GetGameBar();
+ if (gameBar) {
+ /* GameBar.IsInputRedirected events can come in via something other than
+ the main/SDL thread.
+
+ Get a WinRT 'CoreDispatcher' that can be used to call back into the
+ SDL thread.
+ */
+ WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
+ Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \
+ ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread);
+ __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler);
+ gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken);
+ gameBar->Release();
+ }
+}
+
+void
+WINRT_QuitGameBar(_THIS)
+{
+ SDL_VideoData *driverdata;
+ IGameBarStatics_ *gameBar;
+ if (!_this || !_this->driverdata) {
+ return;
+ }
+ gameBar = WINRT_GetGameBar();
+ if (!gameBar) {
+ return;
+ }
+ driverdata = (SDL_VideoData *)_this->driverdata;
+ if (driverdata->gameBarIsInputRedirectedToken.Value) {
+ gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken);
+ driverdata->gameBarIsInputRedirectedToken.Value = 0;
+ }
+ WINRT_MainThreadDispatcher = nullptr;
+ gameBar->Release();
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h
new file mode 100644
index 0000000..a3e4777
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtgamebar_cpp.h
@@ -0,0 +1,35 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef SDL_winrtgamebar_h_
+#define SDL_winrtgamebar_h_
+
+#ifdef __cplusplus
+/* These are exported as C++ functions, rather than C, to fix a compilation
+ bug with MSVC 2013, for Windows 8.x builds. */
+extern void WINRT_InitGameBar(_THIS);
+extern void WINRT_QuitGameBar(_THIS);
+#endif
+
+#endif /* SDL_winrtgamebar_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp
new file mode 100644
index 0000000..34f2421
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtkeyboard.cpp
@@ -0,0 +1,430 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/* Windows-specific includes */
+#include <Windows.h>
+#include <agile.h>
+
+
+/* SDL-specific includes */
+#include "SDL.h"
+#include "SDL_winrtevents_c.h"
+
+extern "C" {
+#include "../../events/scancodes_windows.h"
+#include "../../events/SDL_keyboard_c.h"
+}
+
+
+static SDL_Scancode WinRT_Official_Keycodes[] = {
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.None -- 0 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.LeftButton -- 1 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.RightButton -- 2 */
+ SDL_SCANCODE_CANCEL, /* VirtualKey.Cancel -- 3 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.MiddleButton -- 4 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.XButton1 -- 5 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.XButton2 -- 6 */
+ SDL_SCANCODE_UNKNOWN, /* -- 7 */
+ SDL_SCANCODE_BACKSPACE, /* VirtualKey.Back -- 8 */
+ SDL_SCANCODE_TAB, /* VirtualKey.Tab -- 9 */
+ SDL_SCANCODE_UNKNOWN, /* -- 10 */
+ SDL_SCANCODE_UNKNOWN, /* -- 11 */
+ SDL_SCANCODE_CLEAR, /* VirtualKey.Clear -- 12 */
+ SDL_SCANCODE_RETURN, /* VirtualKey.Enter -- 13 */
+ SDL_SCANCODE_UNKNOWN, /* -- 14 */
+ SDL_SCANCODE_UNKNOWN, /* -- 15 */
+ SDL_SCANCODE_LSHIFT, /* VirtualKey.Shift -- 16 */
+ SDL_SCANCODE_LCTRL, /* VirtualKey.Control -- 17 */
+ SDL_SCANCODE_MENU, /* VirtualKey.Menu -- 18 */
+ SDL_SCANCODE_PAUSE, /* VirtualKey.Pause -- 19 */
+ SDL_SCANCODE_CAPSLOCK, /* VirtualKey.CapitalLock -- 20 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Kana or VirtualKey.Hangul -- 21 */
+ SDL_SCANCODE_UNKNOWN, /* -- 22 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Junja -- 23 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Final -- 24 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Hanja or VirtualKey.Kanji -- 25 */
+ SDL_SCANCODE_UNKNOWN, /* -- 26 */
+ SDL_SCANCODE_ESCAPE, /* VirtualKey.Escape -- 27 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Convert -- 28 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.NonConvert -- 29 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Accept -- 30 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.ModeChange -- 31 (maybe SDL_SCANCODE_MODE ?) */
+ SDL_SCANCODE_SPACE, /* VirtualKey.Space -- 32 */
+ SDL_SCANCODE_PAGEUP, /* VirtualKey.PageUp -- 33 */
+ SDL_SCANCODE_PAGEDOWN, /* VirtualKey.PageDown -- 34 */
+ SDL_SCANCODE_END, /* VirtualKey.End -- 35 */
+ SDL_SCANCODE_HOME, /* VirtualKey.Home -- 36 */
+ SDL_SCANCODE_LEFT, /* VirtualKey.Left -- 37 */
+ SDL_SCANCODE_UP, /* VirtualKey.Up -- 38 */
+ SDL_SCANCODE_RIGHT, /* VirtualKey.Right -- 39 */
+ SDL_SCANCODE_DOWN, /* VirtualKey.Down -- 40 */
+ SDL_SCANCODE_SELECT, /* VirtualKey.Select -- 41 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Print -- 42 (maybe SDL_SCANCODE_PRINTSCREEN ?) */
+ SDL_SCANCODE_EXECUTE, /* VirtualKey.Execute -- 43 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Snapshot -- 44 */
+ SDL_SCANCODE_INSERT, /* VirtualKey.Insert -- 45 */
+ SDL_SCANCODE_DELETE, /* VirtualKey.Delete -- 46 */
+ SDL_SCANCODE_HELP, /* VirtualKey.Help -- 47 */
+ SDL_SCANCODE_0, /* VirtualKey.Number0 -- 48 */
+ SDL_SCANCODE_1, /* VirtualKey.Number1 -- 49 */
+ SDL_SCANCODE_2, /* VirtualKey.Number2 -- 50 */
+ SDL_SCANCODE_3, /* VirtualKey.Number3 -- 51 */
+ SDL_SCANCODE_4, /* VirtualKey.Number4 -- 52 */
+ SDL_SCANCODE_5, /* VirtualKey.Number5 -- 53 */
+ SDL_SCANCODE_6, /* VirtualKey.Number6 -- 54 */
+ SDL_SCANCODE_7, /* VirtualKey.Number7 -- 55 */
+ SDL_SCANCODE_8, /* VirtualKey.Number8 -- 56 */
+ SDL_SCANCODE_9, /* VirtualKey.Number9 -- 57 */
+ SDL_SCANCODE_UNKNOWN, /* -- 58 */
+ SDL_SCANCODE_UNKNOWN, /* -- 59 */
+ SDL_SCANCODE_UNKNOWN, /* -- 60 */
+ SDL_SCANCODE_UNKNOWN, /* -- 61 */
+ SDL_SCANCODE_UNKNOWN, /* -- 62 */
+ SDL_SCANCODE_UNKNOWN, /* -- 63 */
+ SDL_SCANCODE_UNKNOWN, /* -- 64 */
+ SDL_SCANCODE_A, /* VirtualKey.A -- 65 */
+ SDL_SCANCODE_B, /* VirtualKey.B -- 66 */
+ SDL_SCANCODE_C, /* VirtualKey.C -- 67 */
+ SDL_SCANCODE_D, /* VirtualKey.D -- 68 */
+ SDL_SCANCODE_E, /* VirtualKey.E -- 69 */
+ SDL_SCANCODE_F, /* VirtualKey.F -- 70 */
+ SDL_SCANCODE_G, /* VirtualKey.G -- 71 */
+ SDL_SCANCODE_H, /* VirtualKey.H -- 72 */
+ SDL_SCANCODE_I, /* VirtualKey.I -- 73 */
+ SDL_SCANCODE_J, /* VirtualKey.J -- 74 */
+ SDL_SCANCODE_K, /* VirtualKey.K -- 75 */
+ SDL_SCANCODE_L, /* VirtualKey.L -- 76 */
+ SDL_SCANCODE_M, /* VirtualKey.M -- 77 */
+ SDL_SCANCODE_N, /* VirtualKey.N -- 78 */
+ SDL_SCANCODE_O, /* VirtualKey.O -- 79 */
+ SDL_SCANCODE_P, /* VirtualKey.P -- 80 */
+ SDL_SCANCODE_Q, /* VirtualKey.Q -- 81 */
+ SDL_SCANCODE_R, /* VirtualKey.R -- 82 */
+ SDL_SCANCODE_S, /* VirtualKey.S -- 83 */
+ SDL_SCANCODE_T, /* VirtualKey.T -- 84 */
+ SDL_SCANCODE_U, /* VirtualKey.U -- 85 */
+ SDL_SCANCODE_V, /* VirtualKey.V -- 86 */
+ SDL_SCANCODE_W, /* VirtualKey.W -- 87 */
+ SDL_SCANCODE_X, /* VirtualKey.X -- 88 */
+ SDL_SCANCODE_Y, /* VirtualKey.Y -- 89 */
+ SDL_SCANCODE_Z, /* VirtualKey.Z -- 90 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.LeftWindows -- 91 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?) */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.RightWindows -- 92 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?) */
+ SDL_SCANCODE_APPLICATION, /* VirtualKey.Application -- 93 */
+ SDL_SCANCODE_UNKNOWN, /* -- 94 */
+ SDL_SCANCODE_SLEEP, /* VirtualKey.Sleep -- 95 */
+ SDL_SCANCODE_KP_0, /* VirtualKey.NumberPad0 -- 96 */
+ SDL_SCANCODE_KP_1, /* VirtualKey.NumberPad1 -- 97 */
+ SDL_SCANCODE_KP_2, /* VirtualKey.NumberPad2 -- 98 */
+ SDL_SCANCODE_KP_3, /* VirtualKey.NumberPad3 -- 99 */
+ SDL_SCANCODE_KP_4, /* VirtualKey.NumberPad4 -- 100 */
+ SDL_SCANCODE_KP_5, /* VirtualKey.NumberPad5 -- 101 */
+ SDL_SCANCODE_KP_6, /* VirtualKey.NumberPad6 -- 102 */
+ SDL_SCANCODE_KP_7, /* VirtualKey.NumberPad7 -- 103 */
+ SDL_SCANCODE_KP_8, /* VirtualKey.NumberPad8 -- 104 */
+ SDL_SCANCODE_KP_9, /* VirtualKey.NumberPad9 -- 105 */
+ SDL_SCANCODE_KP_MULTIPLY, /* VirtualKey.Multiply -- 106 */
+ SDL_SCANCODE_KP_PLUS, /* VirtualKey.Add -- 107 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Separator -- 108 */
+ SDL_SCANCODE_KP_MINUS, /* VirtualKey.Subtract -- 109 */
+ SDL_SCANCODE_UNKNOWN, /* VirtualKey.Decimal -- 110 (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?) */
+ SDL_SCANCODE_KP_DIVIDE, /* VirtualKey.Divide -- 111 */
+ SDL_SCANCODE_F1, /* VirtualKey.F1 -- 112 */
+ SDL_SCANCODE_F2, /* VirtualKey.F2 -- 113 */
+ SDL_SCANCODE_F3, /* VirtualKey.F3 -- 114 */
+ SDL_SCANCODE_F4, /* VirtualKey.F4 -- 115 */
+ SDL_SCANCODE_F5, /* VirtualKey.F5 -- 116 */
+ SDL_SCANCODE_F6, /* VirtualKey.F6 -- 117 */
+ SDL_SCANCODE_F7, /* VirtualKey.F7 -- 118 */
+ SDL_SCANCODE_F8, /* VirtualKey.F8 -- 119 */
+ SDL_SCANCODE_F9, /* VirtualKey.F9 -- 120 */
+ SDL_SCANCODE_F10, /* VirtualKey.F10 -- 121 */
+ SDL_SCANCODE_F11, /* VirtualKey.F11 -- 122 */
+ SDL_SCANCODE_F12, /* VirtualKey.F12 -- 123 */
+ SDL_SCANCODE_F13, /* VirtualKey.F13 -- 124 */
+ SDL_SCANCODE_F14, /* VirtualKey.F14 -- 125 */
+ SDL_SCANCODE_F15, /* VirtualKey.F15 -- 126 */
+ SDL_SCANCODE_F16, /* VirtualKey.F16 -- 127 */
+ SDL_SCANCODE_F17, /* VirtualKey.F17 -- 128 */
+ SDL_SCANCODE_F18, /* VirtualKey.F18 -- 129 */
+ SDL_SCANCODE_F19, /* VirtualKey.F19 -- 130 */
+ SDL_SCANCODE_F20, /* VirtualKey.F20 -- 131 */
+ SDL_SCANCODE_F21, /* VirtualKey.F21 -- 132 */
+ SDL_SCANCODE_F22, /* VirtualKey.F22 -- 133 */
+ SDL_SCANCODE_F23, /* VirtualKey.F23 -- 134 */
+ SDL_SCANCODE_F24, /* VirtualKey.F24 -- 135 */
+ SDL_SCANCODE_UNKNOWN, /* -- 136 */
+ SDL_SCANCODE_UNKNOWN, /* -- 137 */
+ SDL_SCANCODE_UNKNOWN, /* -- 138 */
+ SDL_SCANCODE_UNKNOWN, /* -- 139 */
+ SDL_SCANCODE_UNKNOWN, /* -- 140 */
+ SDL_SCANCODE_UNKNOWN, /* -- 141 */
+ SDL_SCANCODE_UNKNOWN, /* -- 142 */
+ SDL_SCANCODE_UNKNOWN, /* -- 143 */
+ SDL_SCANCODE_NUMLOCKCLEAR, /* VirtualKey.NumberKeyLock -- 144 */
+ SDL_SCANCODE_SCROLLLOCK, /* VirtualKey.Scroll -- 145 */
+ SDL_SCANCODE_UNKNOWN, /* -- 146 */
+ SDL_SCANCODE_UNKNOWN, /* -- 147 */
+ SDL_SCANCODE_UNKNOWN, /* -- 148 */
+ SDL_SCANCODE_UNKNOWN, /* -- 149 */
+ SDL_SCANCODE_UNKNOWN, /* -- 150 */
+ SDL_SCANCODE_UNKNOWN, /* -- 151 */
+ SDL_SCANCODE_UNKNOWN, /* -- 152 */
+ SDL_SCANCODE_UNKNOWN, /* -- 153 */
+ SDL_SCANCODE_UNKNOWN, /* -- 154 */
+ SDL_SCANCODE_UNKNOWN, /* -- 155 */
+ SDL_SCANCODE_UNKNOWN, /* -- 156 */
+ SDL_SCANCODE_UNKNOWN, /* -- 157 */
+ SDL_SCANCODE_UNKNOWN, /* -- 158 */
+ SDL_SCANCODE_UNKNOWN, /* -- 159 */
+ SDL_SCANCODE_LSHIFT, /* VirtualKey.LeftShift -- 160 */
+ SDL_SCANCODE_RSHIFT, /* VirtualKey.RightShift -- 161 */
+ SDL_SCANCODE_LCTRL, /* VirtualKey.LeftControl -- 162 */
+ SDL_SCANCODE_RCTRL, /* VirtualKey.RightControl -- 163 */
+ SDL_SCANCODE_MENU, /* VirtualKey.LeftMenu -- 164 */
+ SDL_SCANCODE_MENU, /* VirtualKey.RightMenu -- 165 */
+ SDL_SCANCODE_AC_BACK, /* VirtualKey.GoBack -- 166 : The go back key. */
+ SDL_SCANCODE_AC_FORWARD, /* VirtualKey.GoForward -- 167 : The go forward key. */
+ SDL_SCANCODE_AC_REFRESH, /* VirtualKey.Refresh -- 168 : The refresh key. */
+ SDL_SCANCODE_AC_STOP, /* VirtualKey.Stop -- 169 : The stop key. */
+ SDL_SCANCODE_AC_SEARCH, /* VirtualKey.Search -- 170 : The search key. */
+ SDL_SCANCODE_AC_BOOKMARKS, /* VirtualKey.Favorites -- 171 : The favorites key. */
+ SDL_SCANCODE_AC_HOME /* VirtualKey.GoHome -- 172 : The go home key. */
+};
+
+/* Attempt to translate a keycode that isn't listed in WinRT's VirtualKey enum.
+ */
+static SDL_Scancode
+WINRT_TranslateUnofficialKeycode(int keycode)
+{
+ switch (keycode) {
+ case 173: return SDL_SCANCODE_MUTE; /* VK_VOLUME_MUTE */
+ case 174: return SDL_SCANCODE_VOLUMEDOWN; /* VK_VOLUME_DOWN */
+ case 175: return SDL_SCANCODE_VOLUMEUP; /* VK_VOLUME_UP */
+ case 176: return SDL_SCANCODE_AUDIONEXT; /* VK_MEDIA_NEXT_TRACK */
+ case 177: return SDL_SCANCODE_AUDIOPREV; /* VK_MEDIA_PREV_TRACK */
+ // case 178: return ; /* VK_MEDIA_STOP */
+ case 179: return SDL_SCANCODE_AUDIOPLAY; /* VK_MEDIA_PLAY_PAUSE */
+ case 180: return SDL_SCANCODE_MAIL; /* VK_LAUNCH_MAIL */
+ case 181: return SDL_SCANCODE_MEDIASELECT; /* VK_LAUNCH_MEDIA_SELECT */
+ // case 182: return ; /* VK_LAUNCH_APP1 */
+ case 183: return SDL_SCANCODE_CALCULATOR; /* VK_LAUNCH_APP2 */
+ // case 184: return ; /* ... reserved ... */
+ // case 185: return ; /* ... reserved ... */
+ case 186: return SDL_SCANCODE_SEMICOLON; /* VK_OEM_1, ';:' key on US standard keyboards */
+ case 187: return SDL_SCANCODE_EQUALS; /* VK_OEM_PLUS */
+ case 188: return SDL_SCANCODE_COMMA; /* VK_OEM_COMMA */
+ case 189: return SDL_SCANCODE_MINUS; /* VK_OEM_MINUS */
+ case 190: return SDL_SCANCODE_PERIOD; /* VK_OEM_PERIOD */
+ case 191: return SDL_SCANCODE_SLASH; /* VK_OEM_2, '/?' key on US standard keyboards */
+ case 192: return SDL_SCANCODE_GRAVE; /* VK_OEM_3, '`~' key on US standard keyboards */
+ // ?
+ // ... reserved or unassigned ...
+ // ?
+ case 219: return SDL_SCANCODE_LEFTBRACKET; /* VK_OEM_4, '[{' key on US standard keyboards */
+ case 220: return SDL_SCANCODE_BACKSLASH; /* VK_OEM_5, '\|' key on US standard keyboards */
+ case 221: return SDL_SCANCODE_RIGHTBRACKET; /* VK_OEM_6, ']}' key on US standard keyboards */
+ case 222: return SDL_SCANCODE_APOSTROPHE; /* VK_OEM_7, 'single/double quote' on US standard keyboards */
+ default: break;
+ }
+ return SDL_SCANCODE_UNKNOWN;
+}
+
+static SDL_Scancode
+WINRT_TranslateKeycode(int keycode, unsigned int nativeScancode)
+{
+ // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints
+
+ SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
+
+ /* HACK ALERT: At least one VirtualKey constant (Shift) with a left/right
+ * designation might not get reported with its correct handedness, however
+ * its hardware scan code can fill in the gaps. If this is detected,
+ * use the hardware scan code to try telling if the left, or the right
+ * side's key was used.
+ *
+ * If Microsoft ever allows MapVirtualKey or MapVirtualKeyEx to be used
+ * in WinRT apps, or something similar to these (it doesn't appear to be,
+ * at least not for Windows [Phone] 8/8.1, as of Oct 24, 2014), then this
+ * hack might become deprecated, or obsolete.
+ */
+ if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
+ switch (keycode) {
+ case 16: // VirtualKey.Shift
+ switch (windows_scancode_table[nativeScancode]) {
+ case SDL_SCANCODE_LSHIFT:
+ case SDL_SCANCODE_RSHIFT:
+ return windows_scancode_table[nativeScancode];
+ }
+ break;
+
+ // Add others, as necessary.
+ //
+ // Unfortunately, this hack doesn't seem to work in determining
+ // handedness with Control keys.
+
+ default:
+ break;
+ }
+ }
+
+ /* Try to get a documented, WinRT, 'VirtualKey' next (as documented at
+ http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ).
+ If that fails, fall back to a Win32 virtual key.
+ If that fails, attempt to fall back to a scancode-derived key.
+ */
+ if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
+ scancode = WinRT_Official_Keycodes[keycode];
+ }
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ scancode = WINRT_TranslateUnofficialKeycode(keycode);
+ }
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
+ scancode = windows_scancode_table[nativeScancode];
+ }
+ }
+ /*
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
+ }
+ */
+ return scancode;
+}
+
+void
+WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args)
+{
+ SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
+#if 0
+ SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
+ SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
+ "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
+ "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
+ (args->Handled ? "1" : "0"),
+ (args->KeyStatus.IsExtendedKey ? "1" : "0"),
+ (args->KeyStatus.IsKeyReleased ? "1" : "0"),
+ (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
+ args->KeyStatus.RepeatCount,
+ args->KeyStatus.ScanCode,
+ (args->KeyStatus.WasKeyDown ? "1" : "0"),
+ args->VirtualKey,
+ sdlScancode,
+ SDL_GetScancodeName(sdlScancode),
+ keycode,
+ SDL_GetKeyName(keycode));
+ //args->Handled = true;
+#endif
+ SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
+}
+
+void
+WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args)
+{
+ SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
+#if 0
+ SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
+ SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
+ "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
+ "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
+ (args->Handled ? "1" : "0"),
+ (args->KeyStatus.IsExtendedKey ? "1" : "0"),
+ (args->KeyStatus.IsKeyReleased ? "1" : "0"),
+ (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
+ args->KeyStatus.RepeatCount,
+ args->KeyStatus.ScanCode,
+ (args->KeyStatus.WasKeyDown ? "1" : "0"),
+ args->VirtualKey,
+ sdlScancode,
+ SDL_GetScancodeName(sdlScancode),
+ keycode,
+ SDL_GetKeyName(keycode));
+ //args->Handled = true;
+#endif
+ SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
+}
+
+void
+WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args)
+{
+ wchar_t src_ucs2[2];
+ char dest_utf8[16];
+ int result;
+
+ /* Setup src */
+ src_ucs2[0] = args->KeyCode;
+ src_ucs2[1] = L'\0';
+
+ /* Convert the text, then send an SDL_TEXTINPUT event. */
+ result = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)&src_ucs2, -1, (LPSTR)dest_utf8, sizeof(dest_utf8), NULL, NULL);
+ if (result > 0) {
+ SDL_SendKeyboardText(dest_utf8);
+ }
+}
+
+
+#if NTDDI_VERSION >= NTDDI_WIN10
+
+SDL_bool WINRT_HasScreenKeyboardSupport(_THIS)
+{
+ return SDL_TRUE;
+}
+
+void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window)
+{
+ using namespace Windows::UI::ViewManagement;
+ InputPane ^ inputPane = InputPane::GetForCurrentView();
+ if (inputPane) {
+ inputPane->TryShow();
+ }
+}
+
+void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window)
+{
+ using namespace Windows::UI::ViewManagement;
+ InputPane ^ inputPane = InputPane::GetForCurrentView();
+ if (inputPane) {
+ inputPane->TryHide();
+ }
+}
+
+SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window)
+{
+ using namespace Windows::UI::ViewManagement;
+ InputPane ^ inputPane = InputPane::GetForCurrentView();
+ if (inputPane) {
+ // dludwig@pobox.com: checking inputPane->Visible doesn't seem to detect visibility,
+ // at least not on the Windows Phone 10.0.10240.0 emulator. Checking
+ // the size of inputPane->OccludedRect, however, does seem to work.
+ Windows::Foundation::Rect rect = inputPane->OccludedRect;
+ if (rect.Width > 0 && rect.Height > 0) {
+ return SDL_TRUE;
+ }
+ }
+ return SDL_FALSE;
+}
+
+#endif // NTDDI_VERSION >= ...
+
+#endif // SDL_VIDEO_DRIVER_WINRT
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp
new file mode 100644
index 0000000..3576a3f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.cpp
@@ -0,0 +1,112 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+extern "C" {
+#include "SDL_messagebox.h"
+#include "../../core/windows/SDL_windows.h"
+}
+
+#include "SDL_winrtevents_c.h"
+
+#include <windows.ui.popups.h>
+using namespace Platform;
+using namespace Windows::Foundation;
+using namespace Windows::UI::Popups;
+
+static String ^
+WINRT_UTF8ToPlatformString(const char * str)
+{
+ wchar_t * wstr = WIN_UTF8ToString(str);
+ String ^ rtstr = ref new String(wstr);
+ SDL_free(wstr);
+ return rtstr;
+}
+
+extern "C" int
+WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8)
+ /* Sadly, Windows Phone 8 doesn't include the MessageDialog class that
+ * Windows 8.x/RT does, even though MSDN's reference documentation for
+ * Windows Phone 8 mentions it.
+ *
+ * The .NET runtime on Windows Phone 8 does, however, include a
+ * MessageBox class. Perhaps this could be called, somehow?
+ */
+ return SDL_SetError("SDL_messagebox support is not available for Windows Phone 8.0");
+#else
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+ const int maxbuttons = 2;
+ const char * platform = "Windows Phone 8.1+";
+#else
+ const int maxbuttons = 3;
+ const char * platform = "Windows 8.x";
+#endif
+
+ if (messageboxdata->numbuttons > maxbuttons) {
+ return SDL_SetError("WinRT's MessageDialog only supports %d buttons, at most, on %s. %d were requested.",
+ maxbuttons, platform, messageboxdata->numbuttons);
+ }
+
+ /* Build a MessageDialog object and its buttons */
+ MessageDialog ^ dialog = ref new MessageDialog(WINRT_UTF8ToPlatformString(messageboxdata->message));
+ dialog->Title = WINRT_UTF8ToPlatformString(messageboxdata->title);
+ for (int i = 0; i < messageboxdata->numbuttons; ++i) {
+ UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(messageboxdata->buttons[i].text));
+ button->Id = safe_cast<IntPtr>(i);
+ dialog->Commands->Append(button);
+ if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+ dialog->CancelCommandIndex = i;
+ }
+ if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
+ dialog->DefaultCommandIndex = i;
+ }
+ }
+
+ /* Display the MessageDialog, then wait for it to be closed */
+ /* TODO, WinRT: Find a way to redraw MessageDialog instances if a GPU device-reset occurs during the following event-loop */
+ auto operation = dialog->ShowAsync();
+ while (operation->Status == Windows::Foundation::AsyncStatus::Started) {
+ WINRT_PumpEvents(_this);
+ }
+
+ /* Retrieve results from the MessageDialog and process them accordingly */
+ if (operation->Status != Windows::Foundation::AsyncStatus::Completed) {
+ return SDL_SetError("An unknown error occurred in displaying the WinRT MessageDialog");
+ }
+ if (buttonid) {
+ IntPtr results = safe_cast<IntPtr>(operation->GetResults()->Id);
+ int clicked_index = results.ToInt32();
+ *buttonid = messageboxdata->buttons[clicked_index].buttonid;
+ }
+ return 0;
+#endif /* if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else */
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h
new file mode 100644
index 0000000..204cf4a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmessagebox.h
@@ -0,0 +1,29 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+extern int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp
new file mode 100644
index 0000000..093a1b9
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse.cpp
@@ -0,0 +1,224 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/*
+ * Windows includes:
+ */
+#include <Windows.h>
+#include <windows.ui.core.h>
+using namespace Windows::UI::Core;
+using Windows::UI::Core::CoreCursor;
+
+/*
+ * SDL includes:
+ */
+extern "C" {
+#include "SDL_assert.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_events.h"
+#include "SDL_log.h"
+}
+
+#include "../../core/winrt/SDL_winrtapp_direct3d.h"
+#include "SDL_winrtvideo_cpp.h"
+#include "SDL_winrtmouse_c.h"
+
+
+extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE;
+
+
+static SDL_Cursor *
+WINRT_CreateSystemCursor(SDL_SystemCursor id)
+{
+ SDL_Cursor *cursor;
+ CoreCursorType cursorType = CoreCursorType::Arrow;
+
+ switch(id)
+ {
+ default:
+ SDL_assert(0);
+ return NULL;
+ case SDL_SYSTEM_CURSOR_ARROW: cursorType = CoreCursorType::Arrow; break;
+ case SDL_SYSTEM_CURSOR_IBEAM: cursorType = CoreCursorType::IBeam; break;
+ case SDL_SYSTEM_CURSOR_WAIT: cursorType = CoreCursorType::Wait; break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break;
+ case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE: cursorType = CoreCursorType::SizeNorthwestSoutheast; break;
+ case SDL_SYSTEM_CURSOR_SIZENESW: cursorType = CoreCursorType::SizeNortheastSouthwest; break;
+ case SDL_SYSTEM_CURSOR_SIZEWE: cursorType = CoreCursorType::SizeWestEast; break;
+ case SDL_SYSTEM_CURSOR_SIZENS: cursorType = CoreCursorType::SizeNorthSouth; break;
+ case SDL_SYSTEM_CURSOR_SIZEALL: cursorType = CoreCursorType::SizeAll; break;
+ case SDL_SYSTEM_CURSOR_NO: cursorType = CoreCursorType::UniversalNo; break;
+ case SDL_SYSTEM_CURSOR_HAND: cursorType = CoreCursorType::Hand; break;
+ }
+
+ cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ /* Create a pointer to a COM reference to a cursor. The extra
+ pointer is used (on top of the COM reference) to allow the cursor
+ to be referenced by the SDL_cursor's driverdata field, which is
+ a void pointer.
+ */
+ CoreCursor ^* theCursor = new CoreCursor^(nullptr);
+ *theCursor = ref new CoreCursor(cursorType, 0);
+ cursor->driverdata = (void *) theCursor;
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+WINRT_CreateDefaultCursor()
+{
+ return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
+}
+
+static void
+WINRT_FreeCursor(SDL_Cursor * cursor)
+{
+ if (cursor->driverdata) {
+ CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
+ *theCursor = nullptr; // Release the COM reference to the CoreCursor
+ delete theCursor; // Delete the pointer to the COM reference
+ }
+ SDL_free(cursor);
+}
+
+static int
+WINRT_ShowCursor(SDL_Cursor * cursor)
+{
+ // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled.
+ if ( ! CoreWindow::GetForCurrentThread()) {
+ return 0;
+ }
+
+ CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
+ if (cursor) {
+ CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
+ coreWindow->PointerCursor = *theCursor;
+ } else {
+ // HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and
+ // a Win32-style cursor resource file must be directly included in apps,
+ // otherwise hiding the cursor will cause mouse-motion data to never be
+ // received.
+ //
+ // Here's the lengthy explanation:
+ //
+ // There are two ways to hide a cursor in WinRT/UWP apps.
+ // Both involve setting the WinRT CoreWindow's (which is somewhat analogous
+ // to a Win32 HWND) 'PointerCursor' property.
+ //
+ // The first way to hide a cursor sets PointerCursor to nullptr. This
+ // is, arguably, the easiest to implement for an app. It does have an
+ // unfortunate side-effect: it'll prevent mouse-motion events from being
+ // sent to the app (via CoreWindow).
+ //
+ // The second way to hide a cursor sets PointerCursor to a transparent
+ // cursor. This allows mouse-motion events to be sent to the app, but is
+ // more difficult to set up, as:
+ // 1. WinRT/UWP, while providing a few stock cursors, does not provide
+ // a completely transparent cursor.
+ // 2. WinRT/UWP allows apps to provide custom-built cursors, but *ONLY*
+ // if they are linked directly inside the app, via Win32-style
+ // cursor resource files. APIs to create cursors at runtime are
+ // not provided to apps, and attempting to link-to or use Win32
+ // cursor-creation APIs could cause an app to fail Windows Store
+ // certification.
+ //
+ // SDL can use either means of hiding the cursor. It provides a Win32-style
+ // set of cursor resource files in its source distribution, inside
+ // src/main/winrt/. If those files are linked to an SDL-for-WinRT/UWP app
+ // (by including them in a MSVC project, for example), SDL will attempt to
+ // use those, if and when the cursor is hidden via SDL APIs. If those
+ // files are not linked in, SDL will attempt to hide the cursor via the
+ // 'set PointerCursor to nullptr' means (which, if you recall, causes
+ // mouse-motion data to NOT be sent to the app!).
+ //
+ // Tech notes:
+ // - SDL's blank cursor resource uses a resource ID of 5000.
+ // - SDL's cursor resources consist of the following two files:
+ // - src/main/winrt/SDL2-WinRTResource_BlankCursor.cur -- cursor pixel data
+ // - src/main/winrt/SDL2-WinRTResources.rc -- declares the cursor resource, and its ID (of 5000)
+ //
+
+ const unsigned int win32CursorResourceID = 5000;
+ CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID);
+
+ // Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw
+ // an exception if the app hasn't loaded that resource.
+ ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast<ABI::Windows::UI::Core::ICoreCursor *>(blankCursor);
+ ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow *>(coreWindow);
+ HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor);
+ if (FAILED(hr)) {
+ // The app doesn't contain the cursor resource, or some other error
+ // occurred. Just use the other, but mouse-motion-preventing, means of
+ // hiding the cursor.
+ coreWindow->PointerCursor = nullptr;
+ }
+ }
+ return 0;
+}
+
+static int
+WINRT_SetRelativeMouseMode(SDL_bool enabled)
+{
+ WINRT_UsingRelativeMouseMode = enabled;
+ return 0;
+}
+
+void
+WINRT_InitMouse(_THIS)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ /* DLudwig, Dec 3, 2012: WinRT does not currently provide APIs for
+ the following features, AFAIK:
+ - custom cursors (multiple system cursors are, however, available)
+ - programmatically moveable cursors
+ */
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+ //mouse->CreateCursor = WINRT_CreateCursor;
+ mouse->CreateSystemCursor = WINRT_CreateSystemCursor;
+ mouse->ShowCursor = WINRT_ShowCursor;
+ mouse->FreeCursor = WINRT_FreeCursor;
+ //mouse->WarpMouse = WINRT_WarpMouse;
+ mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode;
+
+ SDL_SetDefaultCursor(WINRT_CreateDefaultCursor());
+#endif
+}
+
+void
+WINRT_QuitMouse(_THIS)
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h
new file mode 100644
index 0000000..22a80fc
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtmouse_c.h
@@ -0,0 +1,40 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef SDL_winrtmouse_h_
+#define SDL_winrtmouse_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void WINRT_InitMouse(_THIS);
+extern void WINRT_QuitMouse(_THIS);
+extern SDL_bool WINRT_UsingRelativeMouseMode;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_winrtmouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp
new file mode 100644
index 0000000..7874501
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.cpp
@@ -0,0 +1,203 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL
+
+/* EGL implementation of SDL OpenGL support */
+
+#include "SDL_winrtvideo_cpp.h"
+extern "C" {
+#include "SDL_winrtopengles.h"
+#include "SDL_loadso.h"
+#include "../SDL_egl_c.h"
+}
+
+/* Windows includes */
+#include <wrl/client.h>
+using namespace Windows::UI::Core;
+
+/* ANGLE/WinRT constants */
+static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0;
+#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
+#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
+
+#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B
+
+
+/*
+ * SDL/EGL top-level implementation
+ */
+
+extern "C" int
+WINRT_GLES_LoadLibrary(_THIS, const char *path)
+{
+ SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata;
+
+ if (SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0) != 0) {
+ return -1;
+ }
+
+ /* Load ANGLE/WinRT-specific functions */
+ CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function) SDL_LoadFunction(_this->egl_data->egl_dll_handle, "CreateWinrtEglWindow");
+ if (CreateWinrtEglWindow) {
+ /* 'CreateWinrtEglWindow' was found, which means that an an older
+ * version of ANGLE/WinRT is being used. Continue setting up EGL,
+ * as appropriate to this version of ANGLE.
+ */
+
+ /* Create an ANGLE/WinRT EGL-window */
+ /* TODO, WinRT: check for XAML usage before accessing the CoreWindow, as not doing so could lead to a crash */
+ CoreWindow ^ native_win = CoreWindow::GetForCurrentThread();
+ Microsoft::WRL::ComPtr<IUnknown> cpp_win = reinterpret_cast<IUnknown *>(native_win);
+ HRESULT result = CreateWinrtEglWindow(cpp_win, ANGLE_D3D_FEATURE_LEVEL_ANY, &(video_data->winrtEglWindow));
+ if (FAILED(result)) {
+ return -1;
+ }
+
+ /* Call eglGetDisplay and eglInitialize as appropriate. On other
+ * platforms, this would probably get done by SDL_EGL_LoadLibrary,
+ * however ANGLE/WinRT's current implementation (as of Mar 22, 2014) of
+ * eglGetDisplay requires that a C++ object be passed into it, so the
+ * call will be made in this file, a C++ file, instead.
+ */
+ Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
+ _this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display);
+ if (!_this->egl_data->egl_display) {
+ return SDL_EGL_SetError("Could not get Windows 8.0 EGL display", "eglGetDisplay");
+ }
+
+ if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
+ return SDL_EGL_SetError("Could not initialize Windows 8.0 EGL", "eglInitialize");
+ }
+ } else {
+ /* Declare some ANGLE/EGL initialization property-sets, as suggested by
+ * MSOpenTech's ANGLE-for-WinRT template apps:
+ */
+ const EGLint defaultDisplayAttributes[] =
+ {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_NONE,
+ };
+
+ const EGLint fl9_3DisplayAttributes[] =
+ {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_NONE,
+ };
+
+ const EGLint warpDisplayAttributes[] =
+ {
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_NONE,
+ };
+
+ /* 'CreateWinrtEglWindow' was NOT found, which either means that a
+ * newer version of ANGLE/WinRT is being used, or that we don't have
+ * a valid copy of ANGLE.
+ *
+ * Try loading ANGLE as if it were the newer version.
+ */
+ eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT");
+ if (!eglGetPlatformDisplayEXT) {
+ return SDL_EGL_SetError("Could not retrieve ANGLE/WinRT display function(s)", "eglGetProcAddress");
+ }
+
+#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ /* Try initializing EGL at D3D11 Feature Level 10_0+ (which is not
+ * supported on WinPhone 8.x.
+ */
+ _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
+ if (!_this->egl_data->egl_display) {
+ return SDL_EGL_SetError("Could not get EGL display for Direct3D 10_0+", "eglGetPlatformDisplayEXT");
+ }
+
+ if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE)
+#endif
+ {
+ /* Try initializing EGL at D3D11 Feature Level 9_3, in case the
+ * 10_0 init fails, or we're on Windows Phone (which only supports
+ * 9_3).
+ */
+ _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
+ if (!_this->egl_data->egl_display) {
+ return SDL_EGL_SetError("Could not get EGL display for Direct3D 9_3", "eglGetPlatformDisplayEXT");
+ }
+
+ if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
+ /* Try initializing EGL at D3D11 Feature Level 11_0 on WARP
+ * (a Windows-provided, software rasterizer) if all else fails.
+ */
+ _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
+ if (!_this->egl_data->egl_display) {
+ return SDL_EGL_SetError("Could not get EGL display for Direct3D WARP", "eglGetPlatformDisplayEXT");
+ }
+
+ if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
+ return SDL_EGL_SetError("Could not initialize WinRT 8.x+ EGL", "eglInitialize");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+extern "C" void
+WINRT_GLES_UnloadLibrary(_THIS)
+{
+ SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata;
+
+ /* Release SDL's own COM reference to the ANGLE/WinRT IWinrtEglWindow */
+ if (video_data->winrtEglWindow) {
+ video_data->winrtEglWindow->Release();
+ video_data->winrtEglWindow = nullptr;
+ }
+
+ /* Perform the bulk of the unloading */
+ SDL_EGL_UnloadLibrary(_this);
+}
+
+extern "C" {
+SDL_EGL_CreateContext_impl(WINRT)
+SDL_EGL_SwapWindow_impl(WINRT)
+SDL_EGL_MakeCurrent_impl(WINRT)
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h
new file mode 100644
index 0000000..a222c2b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtopengles.h
@@ -0,0 +1,70 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef SDL_winrtopengles_h_
+#define SDL_winrtopengles_h_
+
+#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute
+#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext
+
+extern int WINRT_GLES_LoadLibrary(_THIS, const char *path);
+extern void WINRT_GLES_UnloadLibrary(_THIS);
+extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int WINRT_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+
+
+#ifdef __cplusplus
+
+/* Typedefs for ANGLE/WinRT's C++-based native-display and native-window types,
+ * which are used when calling eglGetDisplay and eglCreateWindowSurface.
+ */
+typedef Microsoft::WRL::ComPtr<IUnknown> WINRT_EGLNativeWindowType_Old;
+
+/* Function pointer typedefs for 'old' ANGLE/WinRT's functions, which may
+ * require that C++ objects be passed in:
+ */
+typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_Old_Function)(WINRT_EGLNativeWindowType_Old);
+typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_Old_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType_Old, const EGLint *);
+typedef HRESULT (EGLAPIENTRY *CreateWinrtEglWindow_Old_Function)(Microsoft::WRL::ComPtr<IUnknown>, int, IUnknown ** result);
+
+#endif /* __cplusplus */
+
+/* Function pointer typedefs for 'new' ANGLE/WinRT functions, which, unlike
+ * the old functions, do not require C++ support and work with plain C.
+ */
+typedef EGLDisplay (EGLAPIENTRY *eglGetPlatformDisplayEXT_Function)(EGLenum, void *, const EGLint *);
+
+#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_winrtopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp
new file mode 100644
index 0000000..bc438f2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtpointerinput.cpp
@@ -0,0 +1,415 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/* SDL includes */
+#include "SDL_winrtevents_c.h"
+#include "SDL_winrtmouse_c.h"
+#include "SDL_winrtvideo_cpp.h"
+#include "SDL_assert.h"
+#include "SDL_system.h"
+
+extern "C" {
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+}
+
+/* File-specific globals: */
+static SDL_TouchID WINRT_TouchID = 1;
+static unsigned int WINRT_LeftFingerDown = 0;
+
+
+void
+WINRT_InitTouch(_THIS)
+{
+ SDL_AddTouch(WINRT_TouchID, "");
+}
+
+
+//
+// Applies necessary geometric transformations to raw cursor positions:
+//
+Windows::Foundation::Point
+WINRT_TransformCursorPosition(SDL_Window * window,
+ Windows::Foundation::Point rawPosition,
+ WINRT_CursorNormalizationType normalization)
+{
+ using namespace Windows::UI::Core;
+ using namespace Windows::Graphics::Display;
+
+ if (!window) {
+ return rawPosition;
+ }
+
+ SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata;
+ if (windowData->coreWindow == nullptr) {
+ // For some reason, the window isn't associated with a CoreWindow.
+ // This might end up being the case as XAML support is extended.
+ // For now, if there's no CoreWindow attached to the SDL_Window,
+ // don't do any transforms.
+
+ // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support
+ return rawPosition;
+ }
+
+ // The CoreWindow can only be accessed on certain thread(s).
+ SDL_assert(CoreWindow::GetForCurrentThread() != nullptr);
+
+ CoreWindow ^ nativeWindow = windowData->coreWindow.Get();
+ Windows::Foundation::Point outputPosition;
+
+ // Compute coordinates normalized from 0..1.
+ // If the coordinates need to be sized to the SDL window,
+ // we'll do that after.
+#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
+ outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
+ outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
+#else
+ switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation))
+ {
+ case DisplayOrientations::Portrait:
+ outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
+ outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
+ break;
+ case DisplayOrientations::PortraitFlipped:
+ outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
+ outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
+ break;
+ case DisplayOrientations::Landscape:
+ outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height;
+ outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
+ break;
+ case DisplayOrientations::LandscapeFlipped:
+ outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
+ outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width;
+ break;
+ default:
+ break;
+ }
+#endif
+
+ if (normalization == TransformToSDLWindowSize) {
+ outputPosition.X *= ((float32) window->w);
+ outputPosition.Y *= ((float32) window->h);
+ }
+
+ return outputPosition;
+}
+
+static inline int
+_lround(float arg)
+{
+ if (arg >= 0.0f) {
+ return (int)floor(arg + 0.5f);
+ } else {
+ return (int)ceil(arg - 0.5f);
+ }
+}
+
+Uint8
+WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt)
+{
+ using namespace Windows::UI::Input;
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+ return SDL_BUTTON_LEFT;
+#else
+ switch (pt->Properties->PointerUpdateKind)
+ {
+ case PointerUpdateKind::LeftButtonPressed:
+ case PointerUpdateKind::LeftButtonReleased:
+ return SDL_BUTTON_LEFT;
+
+ case PointerUpdateKind::RightButtonPressed:
+ case PointerUpdateKind::RightButtonReleased:
+ return SDL_BUTTON_RIGHT;
+
+ case PointerUpdateKind::MiddleButtonPressed:
+ case PointerUpdateKind::MiddleButtonReleased:
+ return SDL_BUTTON_MIDDLE;
+
+ case PointerUpdateKind::XButton1Pressed:
+ case PointerUpdateKind::XButton1Released:
+ return SDL_BUTTON_X1;
+
+ case PointerUpdateKind::XButton2Pressed:
+ case PointerUpdateKind::XButton2Released:
+ return SDL_BUTTON_X2;
+
+ default:
+ break;
+ }
+#endif
+
+ return 0;
+}
+
+//const char *
+//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind)
+//{
+// using namespace Windows::UI::Input;
+//
+// switch (kind)
+// {
+// case PointerUpdateKind::Other:
+// return "Other";
+// case PointerUpdateKind::LeftButtonPressed:
+// return "LeftButtonPressed";
+// case PointerUpdateKind::LeftButtonReleased:
+// return "LeftButtonReleased";
+// case PointerUpdateKind::RightButtonPressed:
+// return "RightButtonPressed";
+// case PointerUpdateKind::RightButtonReleased:
+// return "RightButtonReleased";
+// case PointerUpdateKind::MiddleButtonPressed:
+// return "MiddleButtonPressed";
+// case PointerUpdateKind::MiddleButtonReleased:
+// return "MiddleButtonReleased";
+// case PointerUpdateKind::XButton1Pressed:
+// return "XButton1Pressed";
+// case PointerUpdateKind::XButton1Released:
+// return "XButton1Released";
+// case PointerUpdateKind::XButton2Pressed:
+// return "XButton2Pressed";
+// case PointerUpdateKind::XButton2Released:
+// return "XButton2Released";
+// }
+//
+// return "";
+//}
+
+static bool
+WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+ return true;
+#else
+ using namespace Windows::Devices::Input;
+ switch (pointerPoint->PointerDevice->PointerDeviceType) {
+ case PointerDeviceType::Touch:
+ case PointerDeviceType::Pen:
+ return true;
+ default:
+ return false;
+ }
+#endif
+}
+
+void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+ if (!window) {
+ return;
+ }
+
+ Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
+
+ if ( ! WINRT_IsTouchEvent(pointerPoint)) {
+ SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
+ } else {
+ Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
+ Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
+
+ if (!WINRT_LeftFingerDown) {
+ if (button) {
+ SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y);
+ SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, button);
+ }
+
+ WINRT_LeftFingerDown = pointerPoint->PointerId;
+ }
+
+ SDL_SendTouch(
+ WINRT_TouchID,
+ (SDL_FingerID) pointerPoint->PointerId,
+ SDL_TRUE,
+ normalizedPoint.X,
+ normalizedPoint.Y,
+ pointerPoint->Properties->Pressure);
+ }
+}
+
+void
+WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+ if (!window || WINRT_UsingRelativeMouseMode) {
+ return;
+ }
+
+ Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
+ Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);
+
+ if ( ! WINRT_IsTouchEvent(pointerPoint)) {
+ SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
+ } else {
+ if (pointerPoint->PointerId == WINRT_LeftFingerDown) {
+ SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y);
+ }
+
+ SDL_SendTouchMotion(
+ WINRT_TouchID,
+ (SDL_FingerID) pointerPoint->PointerId,
+ normalizedPoint.X,
+ normalizedPoint.Y,
+ pointerPoint->Properties->Pressure);
+ }
+}
+
+void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+ if (!window) {
+ return;
+ }
+
+ Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);
+
+ if (!WINRT_IsTouchEvent(pointerPoint)) {
+ SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
+ } else {
+ Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
+
+ if (WINRT_LeftFingerDown == pointerPoint->PointerId) {
+ if (button) {
+ SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, button);
+ }
+ WINRT_LeftFingerDown = 0;
+ }
+
+ SDL_SendTouch(
+ WINRT_TouchID,
+ (SDL_FingerID) pointerPoint->PointerId,
+ SDL_FALSE,
+ normalizedPoint.X,
+ normalizedPoint.Y,
+ pointerPoint->Properties->Pressure);
+ }
+}
+
+void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+ if (!window) {
+ return;
+ }
+
+ if (!WINRT_IsTouchEvent(pointerPoint)) {
+ SDL_SetMouseFocus(window);
+ }
+}
+
+void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+ if (!window) {
+ return;
+ }
+
+ if (!WINRT_IsTouchEvent(pointerPoint)) {
+ SDL_SetMouseFocus(NULL);
+ }
+}
+
+void
+WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
+{
+ if (!window) {
+ return;
+ }
+
+ float motion = (float) pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
+ SDL_SendMouseWheel(window, 0, 0, (float) motion, SDL_MOUSEWHEEL_NORMAL);
+}
+
+void
+WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args)
+{
+ if (!window || !WINRT_UsingRelativeMouseMode) {
+ return;
+ }
+
+ // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
+ // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
+ // MouseDelta field often reports very large values. More information
+ // on this can be found at the following pages on MSDN:
+ // - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
+ // - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
+ //
+ // The values do not appear to be as large when running on some systems,
+ // most notably a Surface RT. Furthermore, the values returned by
+ // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
+ // method, do not ever appear to be large, even when MouseEventArgs'
+ // MouseDelta is reporting to the contrary.
+ //
+ // On systems with the large-values behavior, it appears that the values
+ // get reported as if the screen's size is 65536 units in both the X and Y
+ // dimensions. This can be viewed by using Windows' now-private, "Raw Input"
+ // APIs. (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
+ //
+ // MSDN's documentation on MouseEventArgs' MouseDelta field (at
+ // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
+ // does not seem to indicate (to me) that its values should be so large. It
+ // says that its values should be a "change in screen location". I could
+ // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see:
+ // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
+ // indicates that these values are in DIPs, which is the same unit used
+ // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
+ // property. See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
+ // for details.)
+ //
+ // To note, PointerMoved events are sent a 'RawPosition' value (via the
+ // CurrentPoint property in MouseEventArgs), however these do not seem
+ // to exhibit the same large-value behavior.
+ //
+ // The values passed via PointerMoved events can't always be used for relative
+ // mouse motion, unfortunately. Its values are bound to the cursor's position,
+ // which stops when it hits one of the screen's edges. This can be a problem in
+ // first person shooters, whereby it is normal for mouse motion to travel far
+ // along any one axis for a period of time. MouseMoved events do not have the
+ // screen-bounding limitation, and can be used regardless of where the system's
+ // cursor is.
+ //
+ // One possible workaround would be to programmatically set the cursor's
+ // position to the screen's center (when SDL's relative mouse mode is enabled),
+ // however WinRT does not yet seem to have the ability to set the cursor's
+ // position via a public API. Win32 did this via an API call, SetCursorPos,
+ // however WinRT makes this function be private. Apps that use it won't get
+ // approved for distribution in the Windows Store. I've yet to be able to find
+ // a suitable, store-friendly counterpart for WinRT.
+ //
+ // There may be some room for a workaround whereby OnPointerMoved's values
+ // are compared to the values from OnMouseMoved in order to detect
+ // when this bug is active. A suitable transformation could then be made to
+ // OnMouseMoved's values. For now, however, the system-reported values are sent
+ // to SDL with minimal transformation: from native screen coordinates (in DIPs)
+ // to SDL window coordinates.
+ //
+ const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
+ const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize);
+ SDL_SendMouseMotion(
+ window,
+ 0,
+ 1,
+ _lround(mouseDeltaInSDLWindowCoords.X),
+ _lround(mouseDeltaInSDLWindowCoords.Y));
+}
+
+#endif // SDL_VIDEO_DRIVER_WINRT
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp
new file mode 100644
index 0000000..99bfd07
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo.cpp
@@ -0,0 +1,842 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/* WinRT SDL video driver implementation
+
+ Initial work on this was done by David Ludwig (dludwig@pobox.com), and
+ was based off of SDL's "dummy" video driver.
+ */
+
+/* Windows includes */
+#include <agile.h>
+#include <windows.graphics.display.h>
+#include <windows.system.display.h>
+#include <dxgi.h>
+#include <dxgi1_2.h>
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::ViewManagement;
+
+
+/* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */
+static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } };
+static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
+
+
+/* SDL includes */
+extern "C" {
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "../../render/SDL_sysrender.h"
+#include "SDL_syswm.h"
+#include "SDL_winrtopengles.h"
+#include "../../core/windows/SDL_windows.h"
+}
+
+#include "../../core/winrt/SDL_winrtapp_direct3d.h"
+#include "../../core/winrt/SDL_winrtapp_xaml.h"
+#include "SDL_winrtvideo_cpp.h"
+#include "SDL_winrtevents_c.h"
+#include "SDL_winrtgamebar_cpp.h"
+#include "SDL_winrtmouse_c.h"
+#include "SDL_main.h"
+#include "SDL_system.h"
+//#include "SDL_log.h"
+
+
+/* Initialization/Query functions */
+static int WINRT_VideoInit(_THIS);
+static int WINRT_InitModes(_THIS);
+static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+static void WINRT_VideoQuit(_THIS);
+
+
+/* Window functions */
+static int WINRT_CreateWindow(_THIS, SDL_Window * window);
+static void WINRT_SetWindowSize(_THIS, SDL_Window * window);
+static void WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
+static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
+
+
+/* Misc functions */
+static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(_THIS);
+extern void WINRT_SuspendScreenSaver(_THIS);
+
+
+/* SDL-internal globals: */
+SDL_Window * WINRT_GlobalSDLWindow = NULL;
+
+
+/* WinRT driver bootstrap functions */
+
+static int
+WINRT_Available(void)
+{
+ return (1);
+}
+
+static void
+WINRT_DeleteDevice(SDL_VideoDevice * device)
+{
+ if (device->driverdata) {
+ SDL_VideoData * video_data = (SDL_VideoData *)device->driverdata;
+ if (video_data->winrtEglWindow) {
+ video_data->winrtEglWindow->Release();
+ }
+ SDL_free(video_data);
+ }
+
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+WINRT_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ return (0);
+ }
+
+ data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (!data) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return (0);
+ }
+ device->driverdata = data;
+
+ /* Set the function pointers */
+ device->VideoInit = WINRT_VideoInit;
+ device->VideoQuit = WINRT_VideoQuit;
+ device->CreateSDLWindow = WINRT_CreateWindow;
+ device->SetWindowSize = WINRT_SetWindowSize;
+ device->SetWindowFullscreen = WINRT_SetWindowFullscreen;
+ device->DestroyWindow = WINRT_DestroyWindow;
+ device->SetDisplayMode = WINRT_SetDisplayMode;
+ device->PumpEvents = WINRT_PumpEvents;
+ device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
+ device->SuspendScreenSaver = WINRT_SuspendScreenSaver;
+
+#if NTDDI_VERSION >= NTDDI_WIN10
+ device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport;
+ device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard;
+ device->HideScreenKeyboard = WINRT_HideScreenKeyboard;
+ device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown;
+#endif
+
+#ifdef SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = WINRT_GLES_LoadLibrary;
+ device->GL_GetProcAddress = WINRT_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary;
+ device->GL_CreateContext = WINRT_GLES_CreateContext;
+ device->GL_MakeCurrent = WINRT_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval;
+ device->GL_SwapWindow = WINRT_GLES_SwapWindow;
+ device->GL_DeleteContext = WINRT_GLES_DeleteContext;
+#endif
+ device->free = WINRT_DeleteDevice;
+
+ return device;
+}
+
+#define WINRTVID_DRIVER_NAME "winrt"
+VideoBootStrap WINRT_bootstrap = {
+ WINRTVID_DRIVER_NAME, "SDL WinRT video driver",
+ WINRT_Available, WINRT_CreateDevice
+};
+
+int
+WINRT_VideoInit(_THIS)
+{
+ SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
+ if (WINRT_InitModes(_this) < 0) {
+ return -1;
+ }
+ WINRT_InitMouse(_this);
+ WINRT_InitTouch(_this);
+ WINRT_InitGameBar(_this);
+ if (driverdata) {
+ /* Initialize screensaver-disabling support */
+ driverdata->displayRequest = WINRT_CreateDisplayRequest(_this);
+ }
+ return 0;
+}
+
+extern "C"
+Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat);
+
+static void
+WINRT_DXGIModeToSDLDisplayMode(const DXGI_MODE_DESC * dxgiMode, SDL_DisplayMode * sdlMode)
+{
+ SDL_zerop(sdlMode);
+ sdlMode->w = dxgiMode->Width;
+ sdlMode->h = dxgiMode->Height;
+ sdlMode->refresh_rate = dxgiMode->RefreshRate.Numerator / dxgiMode->RefreshRate.Denominator;
+ sdlMode->format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format);
+}
+
+static int
+WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex)
+{
+ HRESULT hr;
+ IDXGIOutput * dxgiOutput = NULL;
+ DXGI_OUTPUT_DESC dxgiOutputDesc;
+ SDL_VideoDisplay display;
+ char * displayName = NULL;
+ UINT numModes;
+ DXGI_MODE_DESC * dxgiModes = NULL;
+ int functionResult = -1; /* -1 for failure, 0 for success */
+ DXGI_MODE_DESC modeToMatch, closestMatch;
+
+ SDL_zero(display);
+
+ hr = dxgiAdapter1->EnumOutputs(outputIndex, &dxgiOutput);
+ if (FAILED(hr)) {
+ if (hr != DXGI_ERROR_NOT_FOUND) {
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter1::EnumOutputs failed", hr);
+ }
+ goto done;
+ }
+
+ hr = dxgiOutput->GetDesc(&dxgiOutputDesc);
+ if (FAILED(hr)) {
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDesc failed", hr);
+ goto done;
+ }
+
+ SDL_zero(modeToMatch);
+ modeToMatch.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ modeToMatch.Width = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
+ modeToMatch.Height = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
+ hr = dxgiOutput->FindClosestMatchingMode(&modeToMatch, &closestMatch, NULL);
+ if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
+ /* DXGI_ERROR_NOT_CURRENTLY_AVAILABLE gets returned by IDXGIOutput::FindClosestMatchingMode
+ when running under the Windows Simulator, which uses Remote Desktop (formerly known as Terminal
+ Services) under the hood. According to the MSDN docs for the similar function,
+ IDXGIOutput::GetDisplayModeList, DXGI_ERROR_NOT_CURRENTLY_AVAILABLE is returned if and
+ when an app is run under a Terminal Services session, hence the assumption.
+
+ In this case, just add an SDL display mode, with approximated values.
+ */
+ SDL_DisplayMode mode;
+ SDL_zero(mode);
+ display.name = "Windows Simulator / Terminal Services Display";
+ mode.w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left);
+ mode.h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top);
+ mode.format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ if ( ! SDL_AddDisplayMode(&display, &mode)) {
+ goto done;
+ }
+ } else if (FAILED(hr)) {
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::FindClosestMatchingMode failed", hr);
+ goto done;
+ } else {
+ displayName = WIN_StringToUTF8(dxgiOutputDesc.DeviceName);
+ display.name = displayName;
+ WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.desktop_mode);
+ display.current_mode = display.desktop_mode;
+
+ hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL);
+ if (FAILED(hr)) {
+ if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) {
+ // TODO, WinRT: make sure display mode(s) are added when using Terminal Services / Windows Simulator
+ }
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode list size] failed", hr);
+ goto done;
+ }
+
+ dxgiModes = (DXGI_MODE_DESC *)SDL_calloc(numModes, sizeof(DXGI_MODE_DESC));
+ if ( ! dxgiModes) {
+ SDL_OutOfMemory();
+ goto done;
+ }
+
+ hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, dxgiModes);
+ if (FAILED(hr)) {
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::GetDisplayModeList [get mode contents] failed", hr);
+ goto done;
+ }
+
+ for (UINT i = 0; i < numModes; ++i) {
+ SDL_DisplayMode sdlMode;
+ WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[i], &sdlMode);
+ SDL_AddDisplayMode(&display, &sdlMode);
+ }
+ }
+
+ if (SDL_AddVideoDisplay(&display) < 0) {
+ goto done;
+ }
+
+ functionResult = 0; /* 0 for Success! */
+done:
+ if (dxgiModes) {
+ SDL_free(dxgiModes);
+ }
+ if (dxgiOutput) {
+ dxgiOutput->Release();
+ }
+ if (displayName) {
+ SDL_free(displayName);
+ }
+ return functionResult;
+}
+
+static int
+WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterIndex)
+{
+ HRESULT hr;
+ IDXGIAdapter1 * dxgiAdapter1;
+
+ hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1);
+ if (FAILED(hr)) {
+ if (hr != DXGI_ERROR_NOT_FOUND) {
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory1::EnumAdapters1() failed", hr);
+ }
+ return -1;
+ }
+
+ for (int outputIndex = 0; ; ++outputIndex) {
+ if (WINRT_AddDisplaysForOutput(_this, dxgiAdapter1, outputIndex) < 0) {
+ /* HACK: The Windows App Certification Kit 10.0 can fail, when
+ running the Store Apps' test, "Direct3D Feature Test". The
+ certification kit's error is:
+
+ "Application App was not running at the end of the test. It likely crashed or was terminated for having become unresponsive."
+
+ This was caused by SDL/WinRT's DXGI failing to report any
+ outputs. Attempts to get the 1st display-output from the
+ 1st display-adapter can fail, with IDXGIAdapter::EnumOutputs
+ returning DXGI_ERROR_NOT_FOUND. This could be a bug in Windows,
+ the Windows App Certification Kit, or possibly in SDL/WinRT's
+ display detection code. Either way, try to detect when this
+ happens, and use a hackish means to create a reasonable-as-possible
+ 'display mode'. -- DavidL
+ */
+ if (adapterIndex == 0 && outputIndex == 0) {
+ SDL_VideoDisplay display;
+ SDL_DisplayMode mode;
+#if SDL_WINRT_USE_APPLICATIONVIEW
+ ApplicationView ^ appView = ApplicationView::GetForCurrentView();
+#endif
+ CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread();
+ SDL_zero(display);
+ SDL_zero(mode);
+ display.name = "DXGI Display-detection Workaround";
+
+ /* HACK: ApplicationView's VisibleBounds property, appeared, via testing, to
+ give a better approximation of display-size, than did CoreWindow's
+ Bounds property, insofar that ApplicationView::VisibleBounds seems like
+ it will, at least some of the time, give the full display size (during the
+ failing test), whereas CoreWindow might not. -- DavidL
+ */
+
+#if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width);
+ mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height);
+#else
+ /* On platform(s) that do not support VisibleBounds, such as Windows 8.1,
+ fall back to CoreWindow's Bounds property.
+ */
+ mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Width);
+ mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(coreWin->Bounds.Height);
+#endif
+
+ mode.format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ if ((SDL_AddDisplayMode(&display, &mode) < 0) ||
+ (SDL_AddVideoDisplay(&display) < 0))
+ {
+ return SDL_SetError("Failed to apply DXGI Display-detection workaround");
+ }
+ }
+
+ break;
+ }
+ }
+
+ dxgiAdapter1->Release();
+ return 0;
+}
+
+int
+WINRT_InitModes(_THIS)
+{
+ /* HACK: Initialize a single display, for whatever screen the app's
+ CoreApplicationView is on.
+ TODO, WinRT: Try initializing multiple displays, one for each monitor.
+ Appropriate WinRT APIs for this seem elusive, though. -- DavidL
+ */
+
+ HRESULT hr;
+ IDXGIFactory2 * dxgiFactory2 = NULL;
+
+ hr = CreateDXGIFactory1(IID_IDXGIFactory2, (void **)&dxgiFactory2);
+ if (FAILED(hr)) {
+ WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr);
+ return -1;
+ }
+
+ for (int adapterIndex = 0; ; ++adapterIndex) {
+ if (WINRT_AddDisplaysForAdapter(_this, dxgiFactory2, adapterIndex) < 0) {
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int
+WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+void
+WINRT_VideoQuit(_THIS)
+{
+ SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
+ if (driverdata && driverdata->displayRequest) {
+ driverdata->displayRequest->Release();
+ driverdata->displayRequest = NULL;
+ }
+ WINRT_QuitGameBar(_this);
+ WINRT_QuitMouse(_this);
+}
+
+static const Uint32 WINRT_DetectableFlags =
+ SDL_WINDOW_MAXIMIZED |
+ SDL_WINDOW_FULLSCREEN_DESKTOP |
+ SDL_WINDOW_SHOWN |
+ SDL_WINDOW_HIDDEN |
+ SDL_WINDOW_MOUSE_FOCUS;
+
+extern "C" Uint32
+WINRT_DetectWindowFlags(SDL_Window * window)
+{
+ Uint32 latestFlags = 0;
+ SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
+ bool is_fullscreen = false;
+
+#if SDL_WINRT_USE_APPLICATIONVIEW
+ if (data->appView) {
+ is_fullscreen = data->appView->IsFullScreen;
+ }
+#elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8)
+ is_fullscreen = true;
+#endif
+
+ if (data->coreWindow.Get()) {
+ if (is_fullscreen) {
+ SDL_VideoDisplay * display = SDL_GetDisplayForWindow(window);
+ int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
+ int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
+
+#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
+ // On all WinRT platforms, except for WinPhone 8.0, rotate the
+ // window size. This is needed to properly calculate
+ // fullscreen vs. maximized.
+ const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
+ switch (currentOrientation) {
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ case DisplayOrientations::Landscape:
+ case DisplayOrientations::LandscapeFlipped:
+#else
+ case DisplayOrientations::Portrait:
+ case DisplayOrientations::PortraitFlipped:
+#endif
+ {
+ int tmp = w;
+ w = h;
+ h = tmp;
+ } break;
+ }
+#endif
+
+ if (display->desktop_mode.w != w || display->desktop_mode.h != h) {
+ latestFlags |= SDL_WINDOW_MAXIMIZED;
+ } else {
+ latestFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+ }
+ }
+
+ if (data->coreWindow->Visible) {
+ latestFlags |= SDL_WINDOW_SHOWN;
+ } else {
+ latestFlags |= SDL_WINDOW_HIDDEN;
+ }
+
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE)
+ // data->coreWindow->PointerPosition is not supported on WinPhone 8.0
+ latestFlags |= SDL_WINDOW_MOUSE_FOCUS;
+#else
+ if (data->coreWindow->Visible && data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) {
+ latestFlags |= SDL_WINDOW_MOUSE_FOCUS;
+ }
+#endif
+ }
+
+ return latestFlags;
+}
+
+// TODO, WinRT: consider removing WINRT_UpdateWindowFlags, and just calling WINRT_DetectWindowFlags as-appropriate (with appropriate calls to SDL_SendWindowEvent)
+void
+WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask)
+{
+ mask &= WINRT_DetectableFlags;
+ if (window) {
+ Uint32 apply = WINRT_DetectWindowFlags(window);
+ if ((apply & mask) & SDL_WINDOW_FULLSCREEN) {
+ window->last_fullscreen_flags = window->flags; // seems necessary to programmatically un-fullscreen, via SDL APIs
+ }
+ window->flags = (window->flags & ~mask) | (apply & mask);
+ }
+}
+
+static bool
+WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow)
+{
+ /* WinRT does not appear to offer API(s) to determine window-activation state,
+ at least not that I am aware of in Win8 - Win10. As such, SDL tracks this
+ itself, via window-activation events.
+
+ If there *is* an API to track this, it should probably get used instead
+ of the following hack (that uses "SDLHelperWindowActivationState").
+ -- DavidL.
+ */
+ if (coreWindow->CustomProperties->HasKey("SDLHelperWindowActivationState")) {
+ CoreWindowActivationState activationState = \
+ safe_cast<CoreWindowActivationState>(coreWindow->CustomProperties->Lookup("SDLHelperWindowActivationState"));
+ return (activationState != CoreWindowActivationState::Deactivated);
+ }
+
+ /* Assume that non-SDL tracked windows are active, although this should
+ probably be avoided, if possible.
+
+ This might not even be possible, in normal SDL use, at least as of
+ this writing (Dec 22, 2015; via latest hg.libsdl.org/SDL clone) -- DavidL
+ */
+ return true;
+}
+
+int
+WINRT_CreateWindow(_THIS, SDL_Window * window)
+{
+ // Make sure that only one window gets created, at least until multimonitor
+ // support is added.
+ if (WINRT_GlobalSDLWindow != NULL) {
+ SDL_SetError("WinRT only supports one window");
+ return -1;
+ }
+
+ SDL_WindowData *data = new SDL_WindowData; /* use 'new' here as SDL_WindowData may use WinRT/C++ types */
+ if (!data) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ window->driverdata = data;
+ data->sdlWindow = window;
+
+ /* To note, when XAML support is enabled, access to the CoreWindow will not
+ be possible, at least not via the SDL/XAML thread. Attempts to access it
+ from there will throw exceptions. As such, the SDL_WindowData's
+ 'coreWindow' field will only be set (to a non-null value) if XAML isn't
+ enabled.
+ */
+ if (!WINRT_XAMLWasEnabled) {
+ data->coreWindow = CoreWindow::GetForCurrentThread();
+#if SDL_WINRT_USE_APPLICATIONVIEW
+ data->appView = ApplicationView::GetForCurrentView();
+#endif
+ }
+
+ /* Make note of the requested window flags, before they start getting changed. */
+ const Uint32 requestedFlags = window->flags;
+
+#if SDL_VIDEO_OPENGL_EGL
+ /* Setup the EGL surface, but only if OpenGL ES 2 was requested. */
+ if (!(window->flags & SDL_WINDOW_OPENGL)) {
+ /* OpenGL ES 2 wasn't requested. Don't set up an EGL surface. */
+ data->egl_surface = EGL_NO_SURFACE;
+ } else {
+ /* OpenGL ES 2 was reuqested. Set up an EGL surface. */
+ SDL_VideoData * video_data = (SDL_VideoData *)_this->driverdata;
+
+ /* Call SDL_EGL_ChooseConfig and eglCreateWindowSurface directly,
+ * rather than via SDL_EGL_CreateSurface, as older versions of
+ * ANGLE/WinRT may require that a C++ object, ComPtr<IUnknown>,
+ * be passed into eglCreateWindowSurface.
+ */
+ if (SDL_EGL_ChooseConfig(_this) != 0) {
+ char buf[512];
+ SDL_snprintf(buf, sizeof(buf), "SDL_EGL_ChooseConfig failed: %s", SDL_GetError());
+ return SDL_SetError("%s", buf);
+ }
+
+ if (video_data->winrtEglWindow) { /* ... is the 'old' version of ANGLE/WinRT being used? */
+ /* Attempt to create a window surface using older versions of
+ * ANGLE/WinRT:
+ */
+ Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->winrtEglWindow;
+ data->egl_surface = ((eglCreateWindowSurface_Old_Function)_this->egl_data->eglCreateWindowSurface)(
+ _this->egl_data->egl_display,
+ _this->egl_data->egl_config,
+ cpp_winrtEglWindow, NULL);
+ if (data->egl_surface == NULL) {
+ return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
+ }
+ } else if (data->coreWindow.Get() != nullptr) {
+ /* Attempt to create a window surface using newer versions of
+ * ANGLE/WinRT:
+ */
+ IInspectable * coreWindowAsIInspectable = reinterpret_cast<IInspectable *>(data->coreWindow.Get());
+ data->egl_surface = _this->egl_data->eglCreateWindowSurface(
+ _this->egl_data->egl_display,
+ _this->egl_data->egl_config,
+ coreWindowAsIInspectable,
+ NULL);
+ if (data->egl_surface == NULL) {
+ return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
+ }
+ } else {
+ return SDL_SetError("No supported means to create an EGL window surface are available");
+ }
+ }
+#endif
+
+ /* Determine as many flags dynamically, as possible. */
+ window->flags =
+ SDL_WINDOW_BORDERLESS |
+ SDL_WINDOW_RESIZABLE;
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (data->egl_surface) {
+ window->flags |= SDL_WINDOW_OPENGL;
+ }
+#endif
+
+ if (WINRT_XAMLWasEnabled) {
+ /* TODO, WinRT: set SDL_Window size, maybe position too, from XAML control */
+ window->x = 0;
+ window->y = 0;
+ window->flags |= SDL_WINDOW_SHOWN;
+ SDL_SetMouseFocus(NULL); // TODO: detect this
+ SDL_SetKeyboardFocus(NULL); // TODO: detect this
+ } else {
+ /* WinRT 8.x apps seem to live in an environment where the OS controls the
+ app's window size, with some apps being fullscreen, depending on
+ user choice of various things. For now, just adapt the SDL_Window to
+ whatever Windows set-up as the native-window's geometry.
+ */
+ window->x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left);
+ window->y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top);
+#if NTDDI_VERSION < NTDDI_WIN10
+ /* On WinRT 8.x / pre-Win10, just use the size we were given. */
+ window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
+ window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
+#else
+ /* On Windows 10, we occasionally get control over window size. For windowed
+ mode apps, try this.
+ */
+ bool didSetSize = false;
+ if (!(requestedFlags & SDL_WINDOW_FULLSCREEN)) {
+ const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w),
+ WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h));
+ didSetSize = data->appView->TryResizeView(size);
+ }
+ if (!didSetSize) {
+ /* We either weren't able to set the window size, or a request for
+ fullscreen was made. Get window-size info from the OS.
+ */
+ window->w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
+ window->h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
+ }
+#endif
+
+ WINRT_UpdateWindowFlags(
+ window,
+ 0xffffffff /* Update any window flag(s) that WINRT_UpdateWindow can handle */
+ );
+
+ /* Try detecting if the window is active */
+ bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
+ if (isWindowActive) {
+ SDL_SetKeyboardFocus(window);
+ }
+ }
+
+ /* Make sure the WinRT app's IFramworkView can post events on
+ behalf of SDL:
+ */
+ WINRT_GlobalSDLWindow = window;
+
+ /* All done! */
+ return 0;
+}
+
+void
+WINRT_SetWindowSize(_THIS, SDL_Window * window)
+{
+#if NTDDI_VERSION >= NTDDI_WIN10
+ SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
+ const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w),
+ WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h));
+ data->appView->TryResizeView(size); // TODO, WinRT: return failure (to caller?) from TryResizeView()
+#endif
+}
+
+void
+WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+#if NTDDI_VERSION >= NTDDI_WIN10
+ SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
+ bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get());
+ if (isWindowActive) {
+ if (fullscreen) {
+ if (!data->appView->IsFullScreenMode) {
+ data->appView->TryEnterFullScreenMode(); // TODO, WinRT: return failure (to caller?) from TryEnterFullScreenMode()
+ }
+ } else {
+ if (data->appView->IsFullScreenMode) {
+ data->appView->ExitFullScreenMode();
+ }
+ }
+ }
+#endif
+}
+
+
+void
+WINRT_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
+
+ if (WINRT_GlobalSDLWindow == window) {
+ WINRT_GlobalSDLWindow = NULL;
+ }
+
+ if (data) {
+ // Delete the internal window data:
+ delete data;
+ data = NULL;
+ window->driverdata = NULL;
+ }
+}
+
+SDL_bool
+WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
+
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ info->subsystem = SDL_SYSWM_WINRT;
+ info->info.winrt.window = reinterpret_cast<IInspectable *>(data->coreWindow.Get());
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+ return SDL_FALSE;
+}
+
+static ABI::Windows::System::Display::IDisplayRequest *
+WINRT_CreateDisplayRequest(_THIS)
+{
+ /* Setup a WinRT DisplayRequest object, usable for enabling/disabling screensaver requests */
+ wchar_t *wClassName = L"Windows.System.Display.DisplayRequest";
+ HSTRING hClassName;
+ IActivationFactory *pActivationFactory = NULL;
+ IInspectable * pDisplayRequestRaw = nullptr;
+ ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr;
+ HRESULT hr;
+
+ hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
+ if (FAILED(hr)) {
+ goto done;
+ }
+
+ hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
+ if (FAILED(hr)) {
+ goto done;
+ }
+
+ hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw);
+ if (FAILED(hr)) {
+ goto done;
+ }
+
+ hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest);
+ if (FAILED(hr)) {
+ goto done;
+ }
+
+done:
+ if (pDisplayRequestRaw) {
+ pDisplayRequestRaw->Release();
+ }
+ if (pActivationFactory) {
+ pActivationFactory->Release();
+ }
+ if (hClassName) {
+ ::WindowsDeleteString(hClassName);
+ }
+
+ return pDisplayRequest;
+}
+
+void
+WINRT_SuspendScreenSaver(_THIS)
+{
+ SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
+ if (driverdata && driverdata->displayRequest) {
+ ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->displayRequest;
+ if (_this->suspend_screensaver) {
+ displayRequest->RequestActive();
+ } else {
+ displayRequest->RequestRelease();
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h
new file mode 100644
index 0000000..91e967e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/winrt/SDL_winrtvideo_cpp.h
@@ -0,0 +1,106 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* Windows includes: */
+#include <windows.h>
+#ifdef __cplusplus_winrt
+#include <agile.h>
+#endif
+
+/* SDL includes: */
+#include "SDL_video.h"
+#include "SDL_events.h"
+
+#if NTDDI_VERSION >= NTDDI_WINBLUE /* ApplicationView's functionality only becomes
+ useful for SDL in Win[Phone] 8.1 and up.
+ Plus, it is not available at all in WinPhone 8.0. */
+#define SDL_WINRT_USE_APPLICATIONVIEW 1
+#endif
+
+extern "C" {
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+}
+
+/* Private display data */
+typedef struct SDL_VideoData {
+ /* An object created by ANGLE/WinRT (OpenGL ES 2 for WinRT) that gets
+ * passed to eglGetDisplay and eglCreateWindowSurface:
+ */
+ IUnknown *winrtEglWindow;
+
+ /* Event token(s), for unregistering WinRT event handler(s).
+ These are just a struct with a 64-bit integer inside them
+ */
+ Windows::Foundation::EventRegistrationToken gameBarIsInputRedirectedToken;
+
+ /* A WinRT DisplayRequest, used for implementing SDL_*ScreenSaver() functions.
+ * This is really a pointer to a 'ABI::Windows::System::Display::IDisplayRequest *',
+ * It's casted to 'IUnknown *', to help with building SDL.
+ */
+ IUnknown *displayRequest;
+} SDL_VideoData;
+
+/* The global, WinRT, SDL Window.
+ For now, SDL/WinRT only supports one window (due to platform limitations of
+ WinRT.
+*/
+extern SDL_Window * WINRT_GlobalSDLWindow;
+
+/* Updates one or more SDL_Window flags, by querying the OS' native windowing APIs.
+ SDL_Window flags that can be updated should be specified in 'mask'.
+*/
+extern void WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask);
+extern "C" Uint32 WINRT_DetectWindowFlags(SDL_Window * window); /* detects flags w/o applying them */
+
+/* Display mode internals */
+//typedef struct
+//{
+// Windows::Graphics::Display::DisplayOrientations currentOrientation;
+//} SDL_DisplayModeData;
+
+#ifdef __cplusplus_winrt
+
+/* A convenience macro to get a WinRT display property */
+#if NTDDI_VERSION > NTDDI_WIN8
+#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayInformation::GetForCurrentView()->NAME)
+#else
+#define WINRT_DISPLAY_PROPERTY(NAME) (Windows::Graphics::Display::DisplayProperties::NAME)
+#endif
+
+/* Converts DIPS to/from physical pixels */
+#define WINRT_DIPS_TO_PHYSICAL_PIXELS(DIPS) ((int)(0.5f + (((float)(DIPS) * (float)WINRT_DISPLAY_PROPERTY(LogicalDpi)) / 96.f)))
+#define WINRT_PHYSICAL_PIXELS_TO_DIPS(PHYSPIX) (((float)(PHYSPIX) * 96.f)/WINRT_DISPLAY_PROPERTY(LogicalDpi))
+
+/* Internal window data */
+struct SDL_WindowData
+{
+ SDL_Window *sdlWindow;
+ Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow;
+#ifdef SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+#if SDL_WINRT_USE_APPLICATIONVIEW
+ Windows::UI::ViewManagement::ApplicationView ^ appView;
+#endif
+};
+
+#endif // ifdef __cplusplus_winrt
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.c
new file mode 100644
index 0000000..fad8c9c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.c
@@ -0,0 +1,199 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include <limits.h> /* For INT_MAX */
+
+#include "SDL_events.h"
+#include "SDL_x11video.h"
+#include "SDL_timer.h"
+
+
+/* If you don't support UTF-8, you might use XA_STRING here */
+#ifdef X_HAVE_UTF8_STRING
+#define TEXT_FORMAT X11_XInternAtom(display, "UTF8_STRING", False)
+#else
+#define TEXT_FORMAT XA_STRING
+#endif
+
+/* Get any application owned window handle for clipboard association */
+static Window
+GetWindow(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ /* We create an unmapped window that exists just to manage the clipboard,
+ since X11 selection data is tied to a specific window and dies with it.
+ We create the window on demand, so apps that don't use the clipboard
+ don't have to keep an unnecessary resource around. */
+ if (data->clipboard_window == None) {
+ Display *dpy = data->display;
+ Window parent = RootWindow(dpy, DefaultScreen(dpy));
+ XSetWindowAttributes xattr;
+ data->clipboard_window = X11_XCreateWindow(dpy, parent, -10, -10, 1, 1, 0,
+ CopyFromParent, InputOnly,
+ CopyFromParent, 0, &xattr);
+ X11_XFlush(data->display);
+ }
+
+ return data->clipboard_window;
+}
+
+/* We use our own cut-buffer for intermediate storage instead of
+ XA_CUT_BUFFER0 because their use isn't really defined for holding UTF8. */
+Atom
+X11_GetSDLCutBufferClipboardType(Display *display)
+{
+ return X11_XInternAtom(display, "SDL_CUTBUFFER", False);
+}
+
+int
+X11_SetClipboardText(_THIS, const char *text)
+{
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ Atom format;
+ Window window;
+ Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);
+
+ /* Get the SDL window that will own the selection */
+ window = GetWindow(_this);
+ if (window == None) {
+ return SDL_SetError("Couldn't find a window to own the selection");
+ }
+
+ /* Save the selection on the root window */
+ format = TEXT_FORMAT;
+ X11_XChangeProperty(display, DefaultRootWindow(display),
+ X11_GetSDLCutBufferClipboardType(display), format, 8, PropModeReplace,
+ (const unsigned char *)text, SDL_strlen(text));
+
+ if (XA_CLIPBOARD != None &&
+ X11_XGetSelectionOwner(display, XA_CLIPBOARD) != window) {
+ X11_XSetSelectionOwner(display, XA_CLIPBOARD, window, CurrentTime);
+ }
+
+ if (X11_XGetSelectionOwner(display, XA_PRIMARY) != window) {
+ X11_XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime);
+ }
+ return 0;
+}
+
+char *
+X11_GetClipboardText(_THIS)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ Display *display = videodata->display;
+ Atom format;
+ Window window;
+ Window owner;
+ Atom selection;
+ Atom seln_type;
+ int seln_format;
+ unsigned long nbytes;
+ unsigned long overflow;
+ unsigned char *src;
+ char *text;
+ Uint32 waitStart;
+ Uint32 waitElapsed;
+ Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);
+ if (XA_CLIPBOARD == None) {
+ SDL_SetError("Couldn't access X clipboard");
+ return SDL_strdup("");
+ }
+
+ text = NULL;
+
+ /* Get the window that holds the selection */
+ window = GetWindow(_this);
+ format = TEXT_FORMAT;
+ owner = X11_XGetSelectionOwner(display, XA_CLIPBOARD);
+ if (owner == None) {
+ /* Fall back to ancient X10 cut-buffers which do not support UTF8 strings*/
+ owner = DefaultRootWindow(display);
+ selection = XA_CUT_BUFFER0;
+ format = XA_STRING;
+ } else if (owner == window) {
+ owner = DefaultRootWindow(display);
+ selection = X11_GetSDLCutBufferClipboardType(display);
+ } else {
+ /* Request that the selection owner copy the data to our window */
+ owner = window;
+ selection = X11_XInternAtom(display, "SDL_SELECTION", False);
+ X11_XConvertSelection(display, XA_CLIPBOARD, format, selection, owner,
+ CurrentTime);
+
+ /* When using synergy on Linux and when data has been put in the clipboard
+ on the remote (Windows anyway) machine then selection_waiting may never
+ be set to False. Time out after a while. */
+ waitStart = SDL_GetTicks();
+ videodata->selection_waiting = SDL_TRUE;
+ while (videodata->selection_waiting) {
+ SDL_PumpEvents();
+ waitElapsed = SDL_GetTicks() - waitStart;
+ /* Wait one second for a clipboard response. */
+ if (waitElapsed > 1000) {
+ videodata->selection_waiting = SDL_FALSE;
+ SDL_SetError("Clipboard timeout");
+ /* We need to set the clipboard text so that next time we won't
+ timeout, otherwise we will hang on every call to this function. */
+ X11_SetClipboardText(_this, "");
+ return SDL_strdup("");
+ }
+ }
+ }
+
+ if (X11_XGetWindowProperty(display, owner, selection, 0, INT_MAX/4, False,
+ format, &seln_type, &seln_format, &nbytes, &overflow, &src)
+ == Success) {
+ if (seln_type == format) {
+ text = (char *)SDL_malloc(nbytes+1);
+ if (text) {
+ SDL_memcpy(text, src, nbytes);
+ text[nbytes] = '\0';
+ }
+ }
+ X11_XFree(src);
+ }
+
+ if (!text) {
+ text = SDL_strdup("");
+ }
+
+ return text;
+}
+
+SDL_bool
+X11_HasClipboardText(_THIS)
+{
+ SDL_bool result = SDL_FALSE;
+ char *text = X11_GetClipboardText(_this);
+ if (text) {
+ result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
+ SDL_free(text);
+ }
+ return result;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.h
new file mode 100644
index 0000000..97aff1b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11clipboard.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11clipboard_h_
+#define SDL_x11clipboard_h_
+
+extern int X11_SetClipboardText(_THIS, const char *text);
+extern char *X11_GetClipboardText(_THIS);
+extern SDL_bool X11_HasClipboardText(_THIS);
+extern Atom X11_GetSDLCutBufferClipboardType(Display *display);
+
+#endif /* SDL_x11clipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.c
new file mode 100644
index 0000000..89f736a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.c
@@ -0,0 +1,212 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#define DEBUG_DYNAMIC_X11 0
+
+#include "SDL_x11dyn.h"
+
+#if DEBUG_DYNAMIC_X11
+#include <stdio.h>
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+typedef struct
+{
+ void *lib;
+ const char *libname;
+} x11dynlib;
+
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE NULL
+#endif
+
+static x11dynlib x11libs[] = {
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS},
+ {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE}
+};
+
+static void *
+X11_GetSym(const char *fnname, int *pHasModule)
+{
+ int i;
+ void *fn = NULL;
+ for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
+ if (x11libs[i].lib != NULL) {
+ fn = SDL_LoadFunction(x11libs[i].lib, fnname);
+ if (fn != NULL)
+ break;
+ }
+ }
+
+#if DEBUG_DYNAMIC_X11
+ if (fn != NULL)
+ printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, fn);
+ else
+ printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
+#endif
+
+ if (fn == NULL)
+ *pHasModule = 0; /* kill this module. */
+
+ return fn;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
+
+/* Define all the function pointers and wrappers... */
+#define SDL_X11_SYM(rc,fn,params,args,ret) SDL_DYNX11FN_##fn X11_##fn = NULL;
+#include "SDL_x11sym.h"
+
+/* Annoying varargs entry point... */
+#ifdef X_HAVE_UTF8_STRING
+SDL_DYNX11FN_XCreateIC X11_XCreateIC = NULL;
+SDL_DYNX11FN_XGetICValues X11_XGetICValues = NULL;
+#endif
+
+/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
+#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 0;
+#include "SDL_x11sym.h"
+
+static int x11_load_refcount = 0;
+
+void
+SDL_X11_UnloadSymbols(void)
+{
+ /* Don't actually unload if more than one module is using the libs... */
+ if (x11_load_refcount > 0) {
+ if (--x11_load_refcount == 0) {
+ int i;
+
+ /* set all the function pointers to NULL. */
+#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0;
+#define SDL_X11_SYM(rc,fn,params,args,ret) X11_##fn = NULL;
+#include "SDL_x11sym.h"
+
+#ifdef X_HAVE_UTF8_STRING
+ X11_XCreateIC = NULL;
+ X11_XGetICValues = NULL;
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+ for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
+ if (x11libs[i].lib != NULL) {
+ SDL_UnloadObject(x11libs[i].lib);
+ x11libs[i].lib = NULL;
+ }
+ }
+#endif
+ }
+ }
+}
+
+/* returns non-zero if all needed symbols were loaded. */
+int
+SDL_X11_LoadSymbols(void)
+{
+ int rc = 1; /* always succeed if not using Dynamic X11 stuff. */
+
+ /* deal with multiple modules (dga, x11, etc) needing these symbols... */
+ if (x11_load_refcount++ == 0) {
+#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+ int i;
+ int *thismod = NULL;
+ for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
+ if (x11libs[i].libname != NULL) {
+ x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
+ }
+ }
+
+#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
+#include "SDL_x11sym.h"
+
+#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
+#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod);
+#include "SDL_x11sym.h"
+
+#ifdef X_HAVE_UTF8_STRING
+ X11_XCreateIC = (SDL_DYNX11FN_XCreateIC)
+ X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8);
+ X11_XGetICValues = (SDL_DYNX11FN_XGetICValues)
+ X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8);
+#endif
+
+ if (SDL_X11_HAVE_BASEXLIB) {
+ /* all required symbols loaded. */
+ SDL_ClearError();
+ } else {
+ /* in case something got loaded... */
+ SDL_X11_UnloadSymbols();
+ rc = 0;
+ }
+
+#else /* no dynamic X11 */
+
+#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
+#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) fn;
+#include "SDL_x11sym.h"
+
+#ifdef X_HAVE_UTF8_STRING
+ X11_XCreateIC = XCreateIC;
+ X11_XGetICValues = XGetICValues;
+#endif
+#endif
+ }
+
+ return rc;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.h
new file mode 100644
index 0000000..d3866e7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11dyn.h
@@ -0,0 +1,111 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11dyn_h_
+#define SDL_x11dyn_h_
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+#include <X11/XKBlib.h>
+#endif
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include <X11/Xproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+
+#ifndef NO_SHARED_MEMORY
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
+#include <X11/extensions/scrnsaver.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XSHAPE
+#include <X11/extensions/shape.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+#include <X11/extensions/xf86vmode.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* evil function signatures... */
+typedef Bool(*SDL_X11_XESetWireToEventRetType) (Display *, XEvent *, xEvent *);
+typedef int (*SDL_X11_XSynchronizeRetType) (Display *);
+typedef Status(*SDL_X11_XESetEventToWireRetType) (Display *, XEvent *, xEvent *);
+
+int SDL_X11_LoadSymbols(void);
+void SDL_X11_UnloadSymbols(void);
+
+/* Declare all the function pointers and wrappers... */
+#define SDL_X11_SYM(rc,fn,params,args,ret) \
+ typedef rc (*SDL_DYNX11FN_##fn) params; \
+ extern SDL_DYNX11FN_##fn X11_##fn;
+#include "SDL_x11sym.h"
+
+/* Annoying varargs entry point... */
+#ifdef X_HAVE_UTF8_STRING
+typedef XIC(*SDL_DYNX11FN_XCreateIC) (XIM,...);
+typedef char *(*SDL_DYNX11FN_XGetICValues) (XIC, ...);
+extern SDL_DYNX11FN_XCreateIC X11_XCreateIC;
+extern SDL_DYNX11FN_XGetICValues X11_XGetICValues;
+#endif
+
+/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
+#define SDL_X11_MODULE(modname) extern int SDL_X11_HAVE_##modname;
+#include "SDL_x11sym.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined SDL_x11dyn_h_ */
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11events.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11events.c
new file mode 100644
index 0000000..d293a5e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11events.c
@@ -0,0 +1,1500 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <limits.h> /* For INT_MAX */
+
+#include "SDL_x11video.h"
+#include "SDL_x11touch.h"
+#include "SDL_x11xinput2.h"
+#include "../../core/unix/SDL_poll.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+
+#include "SDL_hints.h"
+#include "SDL_timer.h"
+#include "SDL_syswm.h"
+#include "SDL_assert.h"
+
+#include <stdio.h>
+
+/*#define DEBUG_XEVENTS*/
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_TOP
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_SIZE_LEFT
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
+#endif
+
+#ifndef _NET_WM_MOVERESIZE_MOVE
+#define _NET_WM_MOVERESIZE_MOVE 8
+#endif
+
+typedef struct {
+ unsigned char *data;
+ int format, count;
+ Atom type;
+} SDL_x11Prop;
+
+/* Reads property
+ Must call X11_XFree on results
+ */
+static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop)
+{
+ unsigned char *ret=NULL;
+ Atom type;
+ int fmt;
+ unsigned long count;
+ unsigned long bytes_left;
+ int bytes_fetch = 0;
+
+ do {
+ if (ret != 0) X11_XFree(ret);
+ X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret);
+ bytes_fetch += bytes_left;
+ } while (bytes_left != 0);
+
+ p->data=ret;
+ p->format=fmt;
+ p->count=count;
+ p->type=type;
+}
+
+/* Find text-uri-list in a list of targets and return it's atom
+ if available, else return None */
+static Atom X11_PickTarget(Display *disp, Atom list[], int list_count)
+{
+ Atom request = None;
+ char *name;
+ int i;
+ for (i=0; i < list_count && request == None; i++) {
+ name = X11_XGetAtomName(disp, list[i]);
+ if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain", name) == 0)) {
+ request = list[i];
+ }
+ X11_XFree(name);
+ }
+ return request;
+}
+
+/* Wrapper for X11_PickTarget for a maximum of three targets, a special
+ case in the Xdnd protocol */
+static Atom X11_PickTargetFromAtoms(Display *disp, Atom a0, Atom a1, Atom a2)
+{
+ int count=0;
+ Atom atom[3];
+ if (a0 != None) atom[count++] = a0;
+ if (a1 != None) atom[count++] = a1;
+ if (a2 != None) atom[count++] = a2;
+ return X11_PickTarget(disp, atom, count);
+}
+
+struct KeyRepeatCheckData
+{
+ XEvent *event;
+ SDL_bool found;
+};
+
+static Bool X11_KeyRepeatCheckIfEvent(Display *display, XEvent *chkev,
+ XPointer arg)
+{
+ struct KeyRepeatCheckData *d = (struct KeyRepeatCheckData *) arg;
+ if (chkev->type == KeyPress &&
+ chkev->xkey.keycode == d->event->xkey.keycode &&
+ chkev->xkey.time - d->event->xkey.time < 2)
+ d->found = SDL_TRUE;
+ return False;
+}
+
+/* Check to see if this is a repeated key.
+ (idea shamelessly lifted from GII -- thanks guys! :)
+ */
+static SDL_bool X11_KeyRepeat(Display *display, XEvent *event)
+{
+ XEvent dummyev;
+ struct KeyRepeatCheckData d;
+ d.event = event;
+ d.found = SDL_FALSE;
+ if (X11_XPending(display))
+ X11_XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent,
+ (XPointer) &d);
+ return d.found;
+}
+
+static SDL_bool
+X11_IsWheelEvent(Display * display,XEvent * event,int * xticks,int * yticks)
+{
+ /* according to the xlib docs, no specific mouse wheel events exist.
+ However, the defacto standard is that the vertical wheel is X buttons
+ 4 (up) and 5 (down) and a horizontal wheel is 6 (left) and 7 (right). */
+
+ /* Xlib defines "Button1" through 5, so we just use literals here. */
+ switch (event->xbutton.button) {
+ case 4: *yticks = 1; return SDL_TRUE;
+ case 5: *yticks = -1; return SDL_TRUE;
+ case 6: *xticks = 1; return SDL_TRUE;
+ case 7: *xticks = -1; return SDL_TRUE;
+ default: break;
+ }
+ return SDL_FALSE;
+}
+
+/* Decodes URI escape sequences in string buf of len bytes
+ (excluding the terminating NULL byte) in-place. Since
+ URI-encoded characters take three times the space of
+ normal characters, this should not be an issue.
+
+ Returns the number of decoded bytes that wound up in
+ the buffer, excluding the terminating NULL byte.
+
+ The buffer is guaranteed to be NULL-terminated but
+ may contain embedded NULL bytes.
+
+ On error, -1 is returned.
+ */
+static int X11_URIDecode(char *buf, int len) {
+ int ri, wi, di;
+ char decode = '\0';
+ if (buf == NULL || len < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (len == 0) {
+ len = SDL_strlen(buf);
+ }
+ for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) {
+ if (di == 0) {
+ /* start decoding */
+ if (buf[ri] == '%') {
+ decode = '\0';
+ di += 1;
+ continue;
+ }
+ /* normal write */
+ buf[wi] = buf[ri];
+ wi += 1;
+ continue;
+ } else if (di == 1 || di == 2) {
+ char off = '\0';
+ char isa = buf[ri] >= 'a' && buf[ri] <= 'f';
+ char isA = buf[ri] >= 'A' && buf[ri] <= 'F';
+ char isn = buf[ri] >= '0' && buf[ri] <= '9';
+ if (!(isa || isA || isn)) {
+ /* not a hexadecimal */
+ int sri;
+ for (sri = ri - di; sri <= ri; sri += 1) {
+ buf[wi] = buf[sri];
+ wi += 1;
+ }
+ di = 0;
+ continue;
+ }
+ /* itsy bitsy magicsy */
+ if (isn) {
+ off = 0 - '0';
+ } else if (isa) {
+ off = 10 - 'a';
+ } else if (isA) {
+ off = 10 - 'A';
+ }
+ decode |= (buf[ri] + off) << (2 - di) * 4;
+ if (di == 2) {
+ buf[wi] = decode;
+ wi += 1;
+ di = 0;
+ } else {
+ di += 1;
+ }
+ continue;
+ }
+ }
+ buf[wi] = '\0';
+ return wi;
+}
+
+/* Convert URI to local filename
+ return filename if possible, else NULL
+*/
+static char* X11_URIToLocal(char* uri) {
+ char *file = NULL;
+ SDL_bool local;
+
+ if (memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */
+ else if (strstr(uri,":/") != NULL) return file; /* wrong scheme */
+
+ local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/');
+
+ /* got a hostname? */
+ if (!local && uri[0] == '/' && uri[2] != '/') {
+ char* hostname_end = strchr(uri+1, '/');
+ if (hostname_end != NULL) {
+ char hostname[ 257 ];
+ if (gethostname(hostname, 255) == 0) {
+ hostname[ 256 ] = '\0';
+ if (memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
+ uri = hostname_end + 1;
+ local = SDL_TRUE;
+ }
+ }
+ }
+ }
+ if (local) {
+ file = uri;
+ /* Convert URI escape sequences to real characters */
+ X11_URIDecode(file, 0);
+ if (uri[1] == '/') {
+ file++;
+ } else {
+ file--;
+ }
+ }
+ return file;
+}
+
+#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
+static void X11_HandleGenericEvent(SDL_VideoData *videodata, XEvent *xev)
+{
+ /* event is a union, so cookie == &event, but this is type safe. */
+ XGenericEventCookie *cookie = &xev->xcookie;
+ if (X11_XGetEventData(videodata->display, cookie)) {
+ X11_HandleXinput2Event(videodata, cookie);
+ X11_XFreeEventData(videodata->display, cookie);
+ }
+}
+#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */
+
+static unsigned
+X11_GetNumLockModifierMask(_THIS)
+{
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+ Display *display = viddata->display;
+ unsigned num_mask = 0;
+ int i, j;
+ XModifierKeymap *xmods;
+ unsigned n;
+
+ xmods = X11_XGetModifierMapping(display);
+ n = xmods->max_keypermod;
+ for(i = 3; i < 8; i++) {
+ for(j = 0; j < n; j++) {
+ KeyCode kc = xmods->modifiermap[i * n + j];
+ if (viddata->key_layout[kc] == SDL_SCANCODE_NUMLOCKCLEAR) {
+ num_mask = 1 << i;
+ break;
+ }
+ }
+ }
+ X11_XFreeModifiermap(xmods);
+
+ return num_mask;
+}
+
+static void
+X11_ReconcileKeyboardState(_THIS)
+{
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+ Display *display = viddata->display;
+ char keys[32];
+ int keycode;
+ Window junk_window;
+ int x, y;
+ unsigned int mask;
+ const Uint8 *keyboardState;
+
+ X11_XQueryKeymap(display, keys);
+
+ /* Sync up the keyboard modifier state */
+ if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) {
+ SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) != 0);
+ SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) != 0);
+ }
+
+ keyboardState = SDL_GetKeyboardState(0);
+ for (keycode = 0; keycode < 256; ++keycode) {
+ SDL_Scancode scancode = viddata->key_layout[keycode];
+ SDL_bool x11KeyPressed = (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
+ SDL_bool sdlKeyPressed = keyboardState[scancode] == SDL_PRESSED;
+
+ if (x11KeyPressed && !sdlKeyPressed) {
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ } else if (!x11KeyPressed && sdlKeyPressed) {
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+ }
+}
+
+
+static void
+X11_DispatchFocusIn(_THIS, SDL_WindowData *data)
+{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: Dispatching FocusIn\n", data);
+#endif
+ SDL_SetKeyboardFocus(data->window);
+ X11_ReconcileKeyboardState(_this);
+#ifdef X_HAVE_UTF8_STRING
+ if (data->ic) {
+ X11_XSetICFocus(data->ic);
+ }
+#endif
+#ifdef SDL_USE_IME
+ SDL_IME_SetFocus(SDL_TRUE);
+#endif
+}
+
+static void
+X11_DispatchFocusOut(_THIS, SDL_WindowData *data)
+{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: Dispatching FocusOut\n", data);
+#endif
+ /* If another window has already processed a focus in, then don't try to
+ * remove focus here. Doing so will incorrectly remove focus from that
+ * window, and the focus lost event for this window will have already
+ * been dispatched anyway. */
+ if (data->window == SDL_GetKeyboardFocus()) {
+ SDL_SetKeyboardFocus(NULL);
+ }
+#ifdef X_HAVE_UTF8_STRING
+ if (data->ic) {
+ X11_XUnsetICFocus(data->ic);
+ }
+#endif
+#ifdef SDL_USE_IME
+ SDL_IME_SetFocus(SDL_FALSE);
+#endif
+}
+
+static void
+X11_DispatchMapNotify(SDL_WindowData *data)
+{
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+}
+
+static void
+X11_DispatchUnmapNotify(SDL_WindowData *data)
+{
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+}
+
+static void
+InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point)
+{
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+ SDL_Window* window = data->window;
+ Display *display = viddata->display;
+ XEvent evt;
+
+ /* !!! FIXME: we need to regrab this if necessary when the drag is done. */
+ X11_XUngrabPointer(display, 0L);
+ X11_XFlush(display);
+
+ evt.xclient.type = ClientMessage;
+ evt.xclient.window = data->xwindow;
+ evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True);
+ evt.xclient.format = 32;
+ evt.xclient.data.l[0] = window->x + point->x;
+ evt.xclient.data.l[1] = window->y + point->y;
+ evt.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE;
+ evt.xclient.data.l[3] = Button1;
+ evt.xclient.data.l[4] = 0;
+ X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
+
+ X11_XSync(display, 0);
+}
+
+static void
+InitiateWindowResize(_THIS, const SDL_WindowData *data, const SDL_Point *point, int direction)
+{
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+ SDL_Window* window = data->window;
+ Display *display = viddata->display;
+ XEvent evt;
+
+ if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT)
+ return;
+
+ /* !!! FIXME: we need to regrab this if necessary when the drag is done. */
+ X11_XUngrabPointer(display, 0L);
+ X11_XFlush(display);
+
+ evt.xclient.type = ClientMessage;
+ evt.xclient.window = data->xwindow;
+ evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True);
+ evt.xclient.format = 32;
+ evt.xclient.data.l[0] = window->x + point->x;
+ evt.xclient.data.l[1] = window->y + point->y;
+ evt.xclient.data.l[2] = direction;
+ evt.xclient.data.l[3] = Button1;
+ evt.xclient.data.l[4] = 0;
+ X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
+
+ X11_XSync(display, 0);
+}
+
+static SDL_bool
+ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev)
+{
+ SDL_Window *window = data->window;
+
+ if (window->hit_test) {
+ const SDL_Point point = { xev->xbutton.x, xev->xbutton.y };
+ const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
+ static const int directions[] = {
+ _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP,
+ _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT,
+ _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM,
+ _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT
+ };
+
+ switch (rc) {
+ case SDL_HITTEST_DRAGGABLE:
+ InitiateWindowMove(_this, data, &point);
+ return SDL_TRUE;
+
+ case SDL_HITTEST_RESIZE_TOPLEFT:
+ case SDL_HITTEST_RESIZE_TOP:
+ case SDL_HITTEST_RESIZE_TOPRIGHT:
+ case SDL_HITTEST_RESIZE_RIGHT:
+ case SDL_HITTEST_RESIZE_BOTTOMRIGHT:
+ case SDL_HITTEST_RESIZE_BOTTOM:
+ case SDL_HITTEST_RESIZE_BOTTOMLEFT:
+ case SDL_HITTEST_RESIZE_LEFT:
+ InitiateWindowResize(_this, data, &point, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
+ return SDL_TRUE;
+
+ default: return SDL_FALSE;
+ }
+ }
+
+ return SDL_FALSE;
+}
+
+static void
+X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest)
+{
+ if (latest && (latest != data->user_time)) {
+ SDL_VideoData *videodata = data->videodata;
+ Display *display = videodata->display;
+ X11_XChangeProperty(display, data->xwindow, videodata->_NET_WM_USER_TIME,
+ XA_CARDINAL, 32, PropModeReplace,
+ (const unsigned char *) &latest, 1);
+#ifdef DEBUG_XEVENTS
+ printf("window %p: updating _NET_WM_USER_TIME to %lu\n", data, latest);
+#endif
+ data->user_time = latest;
+ }
+}
+
+static void
+X11_HandleClipboardEvent(_THIS, const XEvent *xevent)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ Display *display = videodata->display;
+
+ SDL_assert(videodata->clipboard_window != None);
+ SDL_assert(xevent->xany.window == videodata->clipboard_window);
+
+ switch (xevent->type) {
+ /* Copy the selection from our own CUTBUFFER to the requested property */
+ case SelectionRequest: {
+ const XSelectionRequestEvent *req = &xevent->xselectionrequest;
+ XEvent sevent;
+ int seln_format;
+ unsigned long nbytes;
+ unsigned long overflow;
+ unsigned char *seln_data;
+
+#ifdef DEBUG_XEVENTS
+ printf("window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n",
+ req->requestor, req->target);
+#endif
+
+ SDL_zero(sevent);
+ sevent.xany.type = SelectionNotify;
+ sevent.xselection.selection = req->selection;
+ sevent.xselection.target = None;
+ sevent.xselection.property = None; /* tell them no by default */
+ sevent.xselection.requestor = req->requestor;
+ sevent.xselection.time = req->time;
+
+ /* !!! FIXME: We were probably storing this on the root window
+ because an SDL window might go away...? but we don't have to do
+ this now (or ever, really). */
+ if (X11_XGetWindowProperty(display, DefaultRootWindow(display),
+ X11_GetSDLCutBufferClipboardType(display), 0, INT_MAX/4, False, req->target,
+ &sevent.xselection.target, &seln_format, &nbytes,
+ &overflow, &seln_data) == Success) {
+ /* !!! FIXME: cache atoms */
+ Atom XA_TARGETS = X11_XInternAtom(display, "TARGETS", 0);
+ if (sevent.xselection.target == req->target) {
+ X11_XChangeProperty(display, req->requestor, req->property,
+ sevent.xselection.target, seln_format, PropModeReplace,
+ seln_data, nbytes);
+ sevent.xselection.property = req->property;
+ } else if (XA_TARGETS == req->target) {
+ Atom SupportedFormats[] = { XA_TARGETS, sevent.xselection.target };
+ X11_XChangeProperty(display, req->requestor, req->property,
+ XA_ATOM, 32, PropModeReplace,
+ (unsigned char*)SupportedFormats,
+ SDL_arraysize(SupportedFormats));
+ sevent.xselection.property = req->property;
+ sevent.xselection.target = XA_TARGETS;
+ }
+ X11_XFree(seln_data);
+ }
+ X11_XSendEvent(display, req->requestor, False, 0, &sevent);
+ X11_XSync(display, False);
+ }
+ break;
+
+ case SelectionNotify: {
+#ifdef DEBUG_XEVENTS
+ printf("window CLIPBOARD: SelectionNotify (requestor = %ld, target = %ld)\n",
+ xevent->xselection.requestor, xevent->xselection.target);
+#endif
+ videodata->selection_waiting = SDL_FALSE;
+ }
+ break;
+
+ case SelectionClear: {
+ /* !!! FIXME: cache atoms */
+ Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0);
+
+#ifdef DEBUG_XEVENTS
+ printf("window CLIPBOARD: SelectionClear (requestor = %ld, target = %ld)\n",
+ xevent->xselection.requestor, xevent->xselection.target);
+#endif
+
+ if (xevent->xselectionclear.selection == XA_PRIMARY ||
+ (XA_CLIPBOARD != None && xevent->xselectionclear.selection == XA_CLIPBOARD)) {
+ SDL_SendClipboardUpdate();
+ }
+ }
+ break;
+ }
+}
+
+
+static void
+X11_DispatchEvent(_THIS)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ Display *display;
+ SDL_WindowData *data;
+ XEvent xevent;
+ int orig_event_type;
+ KeyCode orig_keycode;
+ XClientMessageEvent m;
+ int i;
+
+ if (!videodata) {
+ return;
+ }
+ display = videodata->display;
+
+ SDL_zero(xevent); /* valgrind fix. --ryan. */
+ X11_XNextEvent(display, &xevent);
+
+ /* Save the original keycode for dead keys, which are filtered out by
+ the XFilterEvent() call below.
+ */
+ orig_event_type = xevent.type;
+ if (orig_event_type == KeyPress || orig_event_type == KeyRelease) {
+ orig_keycode = xevent.xkey.keycode;
+ } else {
+ orig_keycode = 0;
+ }
+
+ /* filter events catchs XIM events and sends them to the correct handler */
+ if (X11_XFilterEvent(&xevent, None) == True) {
+#if 0
+ printf("Filtered event type = %d display = %d window = %d\n",
+ xevent.type, xevent.xany.display, xevent.xany.window);
+#endif
+ /* Make sure dead key press/release events are sent */
+ /* But only if we're using one of the DBus IMEs, otherwise
+ some XIM IMEs will generate duplicate events */
+ if (orig_keycode) {
+#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
+ SDL_Scancode scancode = videodata->key_layout[orig_keycode];
+ videodata->filter_code = orig_keycode;
+ videodata->filter_time = xevent.xkey.time;
+
+ if (orig_event_type == KeyPress) {
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ } else {
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+#endif
+ }
+ return;
+ }
+
+ /* Send a SDL_SYSWMEVENT if the application wants them */
+ if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.subsystem = SDL_SYSWM_X11;
+ wmmsg.msg.x11.event = xevent;
+ SDL_SendSysWMEvent(&wmmsg);
+ }
+
+#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
+ if(xevent.type == GenericEvent) {
+ X11_HandleGenericEvent(videodata, &xevent);
+ return;
+ }
+#endif
+
+#if 0
+ printf("type = %d display = %d window = %d\n",
+ xevent.type, xevent.xany.display, xevent.xany.window);
+#endif
+
+ if ((videodata->clipboard_window != None) &&
+ (videodata->clipboard_window == xevent.xany.window)) {
+ X11_HandleClipboardEvent(_this, &xevent);
+ return;
+ }
+
+ data = NULL;
+ if (videodata && videodata->windowlist) {
+ for (i = 0; i < videodata->numwindows; ++i) {
+ if ((videodata->windowlist[i] != NULL) &&
+ (videodata->windowlist[i]->xwindow == xevent.xany.window)) {
+ data = videodata->windowlist[i];
+ break;
+ }
+ }
+ }
+ if (!data) {
+ /* The window for KeymapNotify, etc events is 0 */
+ if (xevent.type == KeymapNotify) {
+ if (SDL_GetKeyboardFocus() != NULL) {
+ X11_ReconcileKeyboardState(_this);
+ }
+ } else if (xevent.type == MappingNotify) {
+ /* Has the keyboard layout changed? */
+ const int request = xevent.xmapping.request;
+
+#ifdef DEBUG_XEVENTS
+ printf("window %p: MappingNotify!\n", data);
+#endif
+ if ((request == MappingKeyboard) || (request == MappingModifier)) {
+ X11_XRefreshKeyboardMapping(&xevent.xmapping);
+ }
+
+ X11_UpdateKeymap(_this);
+ SDL_SendKeymapChangedEvent();
+ }
+ return;
+ }
+
+ switch (xevent.type) {
+
+ /* Gaining mouse coverage? */
+ case EnterNotify:{
+ SDL_Mouse *mouse = SDL_GetMouse();
+#ifdef DEBUG_XEVENTS
+ printf("window %p: EnterNotify! (%d,%d,%d)\n", data,
+ xevent.xcrossing.x,
+ xevent.xcrossing.y,
+ xevent.xcrossing.mode);
+ if (xevent.xcrossing.mode == NotifyGrab)
+ printf("Mode: NotifyGrab\n");
+ if (xevent.xcrossing.mode == NotifyUngrab)
+ printf("Mode: NotifyUngrab\n");
+#endif
+ SDL_SetMouseFocus(data->window);
+
+ mouse->last_x = xevent.xcrossing.x;
+ mouse->last_y = xevent.xcrossing.y;
+
+ if (!mouse->relative_mode) {
+ SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y);
+ }
+ }
+ break;
+ /* Losing mouse coverage? */
+ case LeaveNotify:{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: LeaveNotify! (%d,%d,%d)\n", data,
+ xevent.xcrossing.x,
+ xevent.xcrossing.y,
+ xevent.xcrossing.mode);
+ if (xevent.xcrossing.mode == NotifyGrab)
+ printf("Mode: NotifyGrab\n");
+ if (xevent.xcrossing.mode == NotifyUngrab)
+ printf("Mode: NotifyUngrab\n");
+#endif
+ if (!SDL_GetMouse()->relative_mode) {
+ SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y);
+ }
+
+ if (xevent.xcrossing.mode != NotifyGrab &&
+ xevent.xcrossing.mode != NotifyUngrab &&
+ xevent.xcrossing.detail != NotifyInferior) {
+ SDL_SetMouseFocus(NULL);
+ }
+ }
+ break;
+
+ /* Gaining input focus? */
+ case FocusIn:{
+ if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
+ /* Someone is handling a global hotkey, ignore it */
+#ifdef DEBUG_XEVENTS
+ printf("window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n", data);
+#endif
+ break;
+ }
+
+ if (xevent.xfocus.detail == NotifyInferior) {
+#ifdef DEBUG_XEVENTS
+ printf("window %p: FocusIn (NotifierInferior, ignoring)\n", data);
+#endif
+ break;
+ }
+#ifdef DEBUG_XEVENTS
+ printf("window %p: FocusIn!\n", data);
+#endif
+ if (!videodata->last_mode_change_deadline) /* no recent mode changes */
+ {
+ data->pending_focus = PENDING_FOCUS_NONE;
+ data->pending_focus_time = 0;
+ X11_DispatchFocusIn(_this, data);
+ }
+ else
+ {
+ data->pending_focus = PENDING_FOCUS_IN;
+ data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
+ }
+ data->last_focus_event_time = SDL_GetTicks();
+ }
+ break;
+
+ /* Losing input focus? */
+ case FocusOut:{
+ if (xevent.xfocus.mode == NotifyGrab || xevent.xfocus.mode == NotifyUngrab) {
+ /* Someone is handling a global hotkey, ignore it */
+#ifdef DEBUG_XEVENTS
+ printf("window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n", data);
+#endif
+ break;
+ }
+ if (xevent.xfocus.detail == NotifyInferior) {
+ /* We still have focus if a child gets focus */
+#ifdef DEBUG_XEVENTS
+ printf("window %p: FocusOut (NotifierInferior, ignoring)\n", data);
+#endif
+ break;
+ }
+#ifdef DEBUG_XEVENTS
+ printf("window %p: FocusOut!\n", data);
+#endif
+ if (!videodata->last_mode_change_deadline) /* no recent mode changes */
+ {
+ data->pending_focus = PENDING_FOCUS_NONE;
+ data->pending_focus_time = 0;
+ X11_DispatchFocusOut(_this, data);
+ }
+ else
+ {
+ data->pending_focus = PENDING_FOCUS_OUT;
+ data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
+ }
+ }
+ break;
+
+ /* Key press? */
+ case KeyPress:{
+ KeyCode keycode = xevent.xkey.keycode;
+ KeySym keysym = NoSymbol;
+ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
+ Status status = 0;
+ SDL_bool handled_by_ime = SDL_FALSE;
+
+#ifdef DEBUG_XEVENTS
+ printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
+#endif
+#if 1
+ if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
+ int min_keycode, max_keycode;
+ X11_XDisplayKeycodes(display, &min_keycode, &max_keycode);
+ keysym = X11_KeyCodeToSym(_this, keycode, xevent.xkey.state >> 13);
+ fprintf(stderr,
+ "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list <https://discourse.libsdl.org/> X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n",
+ keycode, keycode - min_keycode, keysym,
+ X11_XKeysymToString(keysym));
+ }
+#endif
+ /* */
+ SDL_zero(text);
+#ifdef X_HAVE_UTF8_STRING
+ if (data->ic) {
+ X11_Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
+ &keysym, &status);
+ } else {
+ X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
+ }
+#else
+ X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
+#endif
+
+#ifdef SDL_USE_IME
+ if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
+ handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode);
+ }
+#endif
+ if (!handled_by_ime) {
+ /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
+ if (xevent.xkey.keycode != videodata->filter_code || xevent.xkey.time != videodata->filter_time) {
+ SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
+ }
+ if(*text) {
+ SDL_SendKeyboardText(text);
+ }
+ }
+
+ X11_UpdateUserTime(data, xevent.xkey.time);
+ }
+ break;
+
+ /* Key release? */
+ case KeyRelease:{
+ KeyCode keycode = xevent.xkey.keycode;
+
+#ifdef DEBUG_XEVENTS
+ printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
+#endif
+ if (X11_KeyRepeat(display, &xevent)) {
+ /* We're about to get a repeated key down, ignore the key up */
+ break;
+ }
+ SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
+ }
+ break;
+
+ /* Have we been iconified? */
+ case UnmapNotify:{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: UnmapNotify!\n", data);
+#endif
+ X11_DispatchUnmapNotify(data);
+ }
+ break;
+
+ /* Have we been restored? */
+ case MapNotify:{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: MapNotify!\n", data);
+#endif
+ X11_DispatchMapNotify(data);
+ }
+ break;
+
+ /* Have we been resized or moved? */
+ case ConfigureNotify:{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data,
+ xevent.xconfigure.x, xevent.xconfigure.y,
+ xevent.xconfigure.width, xevent.xconfigure.height);
+#endif
+ /* Real configure notify events are relative to the parent, synthetic events are absolute. */
+ if (!xevent.xconfigure.send_event) {
+ unsigned int NumChildren;
+ Window ChildReturn, Root, Parent;
+ Window * Children;
+ /* Translate these coodinates back to relative to root */
+ X11_XQueryTree(data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren);
+ X11_XTranslateCoordinates(xevent.xconfigure.display,
+ Parent, DefaultRootWindow(xevent.xconfigure.display),
+ xevent.xconfigure.x, xevent.xconfigure.y,
+ &xevent.xconfigure.x, &xevent.xconfigure.y,
+ &ChildReturn);
+ }
+
+ if (xevent.xconfigure.x != data->last_xconfigure.x ||
+ xevent.xconfigure.y != data->last_xconfigure.y) {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
+ xevent.xconfigure.x, xevent.xconfigure.y);
+#ifdef SDL_USE_IME
+ if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
+ /* Update IME candidate list position */
+ SDL_IME_UpdateTextRect(NULL);
+ }
+#endif
+ }
+ if (xevent.xconfigure.width != data->last_xconfigure.width ||
+ xevent.xconfigure.height != data->last_xconfigure.height) {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED,
+ xevent.xconfigure.width,
+ xevent.xconfigure.height);
+ }
+ data->last_xconfigure = xevent.xconfigure;
+ }
+ break;
+
+ /* Have we been requested to quit (or another client message?) */
+ case ClientMessage:{
+
+ static int xdnd_version=0;
+
+ if (xevent.xclient.message_type == videodata->XdndEnter) {
+
+ SDL_bool use_list = xevent.xclient.data.l[1] & 1;
+ data->xdnd_source = xevent.xclient.data.l[0];
+ xdnd_version = (xevent.xclient.data.l[1] >> 24);
+#ifdef DEBUG_XEVENTS
+ printf("XID of source window : %ld\n", data->xdnd_source);
+ printf("Protocol version to use : %d\n", xdnd_version);
+ printf("More then 3 data types : %d\n", (int) use_list);
+#endif
+
+ if (use_list) {
+ /* fetch conversion targets */
+ SDL_x11Prop p;
+ X11_ReadProperty(&p, display, data->xdnd_source, videodata->XdndTypeList);
+ /* pick one */
+ data->xdnd_req = X11_PickTarget(display, (Atom*)p.data, p.count);
+ X11_XFree(p.data);
+ } else {
+ /* pick from list of three */
+ data->xdnd_req = X11_PickTargetFromAtoms(display, xevent.xclient.data.l[2], xevent.xclient.data.l[3], xevent.xclient.data.l[4]);
+ }
+ }
+ else if (xevent.xclient.message_type == videodata->XdndPosition) {
+
+#ifdef DEBUG_XEVENTS
+ Atom act= videodata->XdndActionCopy;
+ if(xdnd_version >= 2) {
+ act = xevent.xclient.data.l[4];
+ }
+ printf("Action requested by user is : %s\n", X11_XGetAtomName(display , act));
+#endif
+
+
+ /* reply with status */
+ memset(&m, 0, sizeof(XClientMessageEvent));
+ m.type = ClientMessage;
+ m.display = xevent.xclient.display;
+ m.window = xevent.xclient.data.l[0];
+ m.message_type = videodata->XdndStatus;
+ m.format=32;
+ m.data.l[0] = data->xwindow;
+ m.data.l[1] = (data->xdnd_req != None);
+ m.data.l[2] = 0; /* specify an empty rectangle */
+ m.data.l[3] = 0;
+ m.data.l[4] = videodata->XdndActionCopy; /* we only accept copying anyway */
+
+ X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
+ X11_XFlush(display);
+ }
+ else if(xevent.xclient.message_type == videodata->XdndDrop) {
+ if (data->xdnd_req == None) {
+ /* say again - not interested! */
+ memset(&m, 0, sizeof(XClientMessageEvent));
+ m.type = ClientMessage;
+ m.display = xevent.xclient.display;
+ m.window = xevent.xclient.data.l[0];
+ m.message_type = videodata->XdndFinished;
+ m.format=32;
+ m.data.l[0] = data->xwindow;
+ m.data.l[1] = 0;
+ m.data.l[2] = None; /* fail! */
+ X11_XSendEvent(display, xevent.xclient.data.l[0], False, NoEventMask, (XEvent*)&m);
+ } else {
+ /* convert */
+ if(xdnd_version >= 1) {
+ X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent.xclient.data.l[2]);
+ } else {
+ X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, CurrentTime);
+ }
+ }
+ }
+ else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
+ (xevent.xclient.format == 32) &&
+ (xevent.xclient.data.l[0] == videodata->_NET_WM_PING)) {
+ Window root = DefaultRootWindow(display);
+
+#ifdef DEBUG_XEVENTS
+ printf("window %p: _NET_WM_PING\n", data);
+#endif
+ xevent.xclient.window = root;
+ X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
+ break;
+ }
+
+ else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
+ (xevent.xclient.format == 32) &&
+ (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
+
+#ifdef DEBUG_XEVENTS
+ printf("window %p: WM_DELETE_WINDOW\n", data);
+#endif
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
+ break;
+ }
+ else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
+ (xevent.xclient.format == 32) &&
+ (xevent.xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) {
+
+#ifdef DEBUG_XEVENTS
+ printf("window %p: WM_TAKE_FOCUS\n", data);
+#endif
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_TAKE_FOCUS, 0, 0);
+ break;
+ }
+ }
+ break;
+
+ /* Do we need to refresh ourselves? */
+ case Expose:{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: Expose (count = %d)\n", data, xevent.xexpose.count);
+#endif
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
+ }
+ break;
+
+ case MotionNotify:{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ if(!mouse->relative_mode || mouse->relative_mode_warp) {
+#ifdef DEBUG_MOTION
+ printf("window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y);
+#endif
+
+ SDL_SendMouseMotion(data->window, 0, 0, xevent.xmotion.x, xevent.xmotion.y);
+ }
+ }
+ break;
+
+ case ButtonPress:{
+ int xticks = 0, yticks = 0;
+#ifdef DEBUG_XEVENTS
+ printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button);
+#endif
+ if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
+ SDL_SendMouseWheel(data->window, 0, (float) xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL);
+ } else {
+ SDL_bool ignore_click = SDL_FALSE;
+ int button = xevent.xbutton.button;
+ if(button == Button1) {
+ if (ProcessHitTest(_this, data, &xevent)) {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
+ break; /* don't pass this event on to app. */
+ }
+ }
+ else if(button > 7) {
+ /* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ...
+ => subtract (8-SDL_BUTTON_X1) to get value SDL expects */
+ button -= (8-SDL_BUTTON_X1);
+ }
+ if (data->last_focus_event_time) {
+ const int X11_FOCUS_CLICK_TIMEOUT = 10;
+ if (!SDL_TICKS_PASSED(SDL_GetTicks(), data->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) {
+ ignore_click = !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE);
+ }
+ data->last_focus_event_time = 0;
+ }
+ if (!ignore_click) {
+ SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
+ }
+ }
+ X11_UpdateUserTime(data, xevent.xbutton.time);
+ }
+ break;
+
+ case ButtonRelease:{
+ int button = xevent.xbutton.button;
+ /* The X server sends a Release event for each Press for wheels. Ignore them. */
+ int xticks = 0, yticks = 0;
+#ifdef DEBUG_XEVENTS
+ printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button);
+#endif
+ if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) {
+ if (button > 7) {
+ /* see explanation at case ButtonPress */
+ button -= (8-SDL_BUTTON_X1);
+ }
+ SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button);
+ }
+ }
+ break;
+
+ case PropertyNotify:{
+#ifdef DEBUG_XEVENTS
+ unsigned char *propdata;
+ int status, real_format;
+ Atom real_type;
+ unsigned long items_read, items_left;
+
+ char *name = X11_XGetAtomName(display, xevent.xproperty.atom);
+ if (name) {
+ printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent.xproperty.time);
+ X11_XFree(name);
+ }
+
+ status = X11_XGetWindowProperty(display, data->xwindow, xevent.xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata);
+ if (status == Success && items_read > 0) {
+ if (real_type == XA_INTEGER) {
+ int *values = (int *)propdata;
+
+ printf("{");
+ for (i = 0; i < items_read; i++) {
+ printf(" %d", values[i]);
+ }
+ printf(" }\n");
+ } else if (real_type == XA_CARDINAL) {
+ if (real_format == 32) {
+ Uint32 *values = (Uint32 *)propdata;
+
+ printf("{");
+ for (i = 0; i < items_read; i++) {
+ printf(" %d", values[i]);
+ }
+ printf(" }\n");
+ } else if (real_format == 16) {
+ Uint16 *values = (Uint16 *)propdata;
+
+ printf("{");
+ for (i = 0; i < items_read; i++) {
+ printf(" %d", values[i]);
+ }
+ printf(" }\n");
+ } else if (real_format == 8) {
+ Uint8 *values = (Uint8 *)propdata;
+
+ printf("{");
+ for (i = 0; i < items_read; i++) {
+ printf(" %d", values[i]);
+ }
+ printf(" }\n");
+ }
+ } else if (real_type == XA_STRING ||
+ real_type == videodata->UTF8_STRING) {
+ printf("{ \"%s\" }\n", propdata);
+ } else if (real_type == XA_ATOM) {
+ Atom *atoms = (Atom *)propdata;
+
+ printf("{");
+ for (i = 0; i < items_read; i++) {
+ char *atomname = X11_XGetAtomName(display, atoms[i]);
+ if (atomname) {
+ printf(" %s", atomname);
+ X11_XFree(atomname);
+ }
+ }
+ printf(" }\n");
+ } else {
+ char *atomname = X11_XGetAtomName(display, real_type);
+ printf("Unknown type: %ld (%s)\n", real_type, atomname ? atomname : "UNKNOWN");
+ if (atomname) {
+ X11_XFree(atomname);
+ }
+ }
+ }
+ if (status == Success) {
+ X11_XFree(propdata);
+ }
+#endif /* DEBUG_XEVENTS */
+
+ /* Take advantage of this moment to make sure user_time has a
+ valid timestamp from the X server, so if we later try to
+ raise/restore this window, _NET_ACTIVE_WINDOW can have a
+ non-zero timestamp, even if there's never been a mouse or
+ key press to this window so far. Note that we don't try to
+ set _NET_WM_USER_TIME here, though. That's only for legit
+ user interaction with the window. */
+ if (!data->user_time) {
+ data->user_time = xevent.xproperty.time;
+ }
+
+ if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) {
+ /* Get the new state from the window manager.
+ Compositing window managers can alter visibility of windows
+ without ever mapping / unmapping them, so we handle that here,
+ because they use the NETWM protocol to notify us of changes.
+ */
+ const Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window);
+ const Uint32 changed = flags ^ data->window->flags;
+
+ if ((changed & SDL_WINDOW_HIDDEN) || (changed & SDL_WINDOW_FULLSCREEN)) {
+ if (flags & SDL_WINDOW_HIDDEN) {
+ X11_DispatchUnmapNotify(data);
+ } else {
+ X11_DispatchMapNotify(data);
+ }
+ }
+
+ if (changed & SDL_WINDOW_MAXIMIZED) {
+ if (flags & SDL_WINDOW_MAXIMIZED) {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
+ } else {
+ SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+ }
+ }
+ } else if (xevent.xproperty.atom == videodata->XKLAVIER_STATE) {
+ /* Hack for Ubuntu 12.04 (etc) that doesn't send MappingNotify
+ events when the keyboard layout changes (for example,
+ changing from English to French on the menubar's keyboard
+ icon). Since it changes the XKLAVIER_STATE property, we
+ notice and reinit our keymap here. This might not be the
+ right approach, but it seems to work. */
+ X11_UpdateKeymap(_this);
+ SDL_SendKeymapChangedEvent();
+ } else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) {
+ Atom type;
+ int format;
+ unsigned long nitems, bytes_after;
+ unsigned char *property;
+ if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) {
+ if (type != None && nitems == 4) {
+ data->border_left = (int) ((long*)property)[0];
+ data->border_right = (int) ((long*)property)[1];
+ data->border_top = (int) ((long*)property)[2];
+ data->border_bottom = (int) ((long*)property)[3];
+ }
+ X11_XFree(property);
+
+ #ifdef DEBUG_XEVENTS
+ printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom);
+ #endif
+ }
+ }
+ }
+ break;
+
+ case SelectionNotify: {
+ Atom target = xevent.xselection.target;
+#ifdef DEBUG_XEVENTS
+ printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data,
+ xevent.xselection.requestor, xevent.xselection.target);
+#endif
+ if (target == data->xdnd_req) {
+ /* read data */
+ SDL_x11Prop p;
+ X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY);
+
+ if (p.format == 8) {
+ /* !!! FIXME: don't use strtok here. It's not reentrant and not in SDL_stdinc. */
+ char* name = X11_XGetAtomName(display, target);
+ char *token = strtok((char *) p.data, "\r\n");
+ while (token != NULL) {
+ if (SDL_strcmp("text/plain", name)==0) {
+ SDL_SendDropText(data->window, token);
+ } else if (SDL_strcmp("text/uri-list", name)==0) {
+ char *fn = X11_URIToLocal(token);
+ if (fn) {
+ SDL_SendDropFile(data->window, fn);
+ }
+ }
+ token = strtok(NULL, "\r\n");
+ }
+ SDL_SendDropComplete(data->window);
+ }
+ X11_XFree(p.data);
+
+ /* send reply */
+ SDL_memset(&m, 0, sizeof(XClientMessageEvent));
+ m.type = ClientMessage;
+ m.display = display;
+ m.window = data->xdnd_source;
+ m.message_type = videodata->XdndFinished;
+ m.format = 32;
+ m.data.l[0] = data->xwindow;
+ m.data.l[1] = 1;
+ m.data.l[2] = videodata->XdndActionCopy;
+ X11_XSendEvent(display, data->xdnd_source, False, NoEventMask, (XEvent*)&m);
+
+ X11_XSync(display, False);
+ }
+ }
+ break;
+
+ default:{
+#ifdef DEBUG_XEVENTS
+ printf("window %p: Unhandled event %d\n", data, xevent.type);
+#endif
+ }
+ break;
+ }
+}
+
+static void
+X11_HandleFocusChanges(_THIS)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ int i;
+
+ if (videodata && videodata->windowlist) {
+ for (i = 0; i < videodata->numwindows; ++i) {
+ SDL_WindowData *data = videodata->windowlist[i];
+ if (data && data->pending_focus != PENDING_FOCUS_NONE) {
+ Uint32 now = SDL_GetTicks();
+ if (SDL_TICKS_PASSED(now, data->pending_focus_time)) {
+ if (data->pending_focus == PENDING_FOCUS_IN) {
+ X11_DispatchFocusIn(_this, data);
+ } else {
+ X11_DispatchFocusOut(_this, data);
+ }
+ data->pending_focus = PENDING_FOCUS_NONE;
+ }
+ }
+ }
+ }
+}
+/* Ack! X11_XPending() actually performs a blocking read if no events available */
+static int
+X11_Pending(Display * display)
+{
+ /* Flush the display connection and look to see if events are queued */
+ X11_XFlush(display);
+ if (X11_XEventsQueued(display, QueuedAlready)) {
+ return (1);
+ }
+
+ /* More drastic measures are required -- see if X is ready to talk */
+ if (SDL_IOReady(ConnectionNumber(display), SDL_FALSE, 0)) {
+ return (X11_XPending(display));
+ }
+
+ /* Oh well, nothing is ready .. */
+ return (0);
+}
+
+void
+X11_PumpEvents(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (data->last_mode_change_deadline) {
+ if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) {
+ data->last_mode_change_deadline = 0; /* assume we're done. */
+ }
+ }
+
+ /* Update activity every 30 seconds to prevent screensaver */
+ if (_this->suspend_screensaver) {
+ const Uint32 now = SDL_GetTicks();
+ if (!data->screensaver_activity ||
+ SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
+ X11_XResetScreenSaver(data->display);
+
+#if SDL_USE_LIBDBUS
+ SDL_DBus_ScreensaverTickle();
+#endif
+
+ data->screensaver_activity = now;
+ }
+ }
+
+ /* Keep processing pending events */
+ while (X11_Pending(data->display)) {
+ X11_DispatchEvent(_this);
+ }
+
+#ifdef SDL_USE_IME
+ if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
+ SDL_IME_PumpEvents();
+ }
+#endif
+
+ /* FIXME: Only need to do this when there are pending focus changes */
+ X11_HandleFocusChanges(_this);
+}
+
+
+void
+X11_SuspendScreenSaver(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ int dummy;
+ int major_version, minor_version;
+#endif /* SDL_VIDEO_DRIVER_X11_XSCRNSAVER */
+
+#if SDL_USE_LIBDBUS
+ if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) {
+ return;
+ }
+
+ if (_this->suspend_screensaver) {
+ SDL_DBus_ScreensaverTickle();
+ }
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
+ if (SDL_X11_HAVE_XSS) {
+ /* X11_XScreenSaverSuspend was introduced in MIT-SCREEN-SAVER 1.1 */
+ if (!X11_XScreenSaverQueryExtension(data->display, &dummy, &dummy) ||
+ !X11_XScreenSaverQueryVersion(data->display,
+ &major_version, &minor_version) ||
+ major_version < 1 || (major_version == 1 && minor_version < 1)) {
+ return;
+ }
+
+ X11_XScreenSaverSuspend(data->display, _this->suspend_screensaver);
+ X11_XResetScreenSaver(data->display);
+ }
+#endif
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11events.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11events.h
new file mode 100644
index 0000000..53c69a5
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11events.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11events_h_
+#define SDL_x11events_h_
+
+extern void X11_PumpEvents(_THIS);
+extern void X11_SuspendScreenSaver(_THIS);
+
+#endif /* SDL_x11events_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.c
new file mode 100644
index 0000000..ad58170
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.c
@@ -0,0 +1,257 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+#include "SDL_x11framebuffer.h"
+
+
+#ifndef NO_SHARED_MEMORY
+
+/* Shared memory error handler routine */
+static int shm_error;
+static int (*X_handler)(Display *, XErrorEvent *) = NULL;
+static int shm_errhandler(Display *d, XErrorEvent *e)
+{
+ if ( e->error_code == BadAccess ) {
+ shm_error = True;
+ return(0);
+ } else
+ return(X_handler(d,e));
+}
+
+static SDL_bool have_mitshm(void)
+{
+ /* Only use shared memory on local X servers */
+ if ( (SDL_strncmp(X11_XDisplayName(NULL), ":", 1) == 0) ||
+ (SDL_strncmp(X11_XDisplayName(NULL), "unix:", 5) == 0) ) {
+ return SDL_X11_HAVE_SHM;
+ }
+ return SDL_FALSE;
+}
+
+#endif /* !NO_SHARED_MEMORY */
+
+int
+X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format,
+ void ** pixels, int *pitch)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ XGCValues gcv;
+ XVisualInfo vinfo;
+
+ /* Free the old framebuffer surface */
+ X11_DestroyWindowFramebuffer(_this, window);
+
+ /* Create the graphics context for drawing */
+ gcv.graphics_exposures = False;
+ data->gc = X11_XCreateGC(display, data->xwindow, GCGraphicsExposures, &gcv);
+ if (!data->gc) {
+ return SDL_SetError("Couldn't create graphics context");
+ }
+
+ /* Find out the pixel format and depth */
+ if (X11_GetVisualInfoFromVisual(display, data->visual, &vinfo) < 0) {
+ return SDL_SetError("Couldn't get window visual information");
+ }
+
+ *format = X11_GetPixelFormatFromVisualInfo(display, &vinfo);
+ if (*format == SDL_PIXELFORMAT_UNKNOWN) {
+ return SDL_SetError("Unknown window pixel format");
+ }
+
+ /* Calculate pitch */
+ *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
+
+ /* Create the actual image */
+#ifndef NO_SHARED_MEMORY
+ if (have_mitshm()) {
+ XShmSegmentInfo *shminfo = &data->shminfo;
+
+ shminfo->shmid = shmget(IPC_PRIVATE, window->h*(*pitch), IPC_CREAT | 0777);
+ if ( shminfo->shmid >= 0 ) {
+ shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0);
+ shminfo->readOnly = False;
+ if ( shminfo->shmaddr != (char *)-1 ) {
+ shm_error = False;
+ X_handler = X11_XSetErrorHandler(shm_errhandler);
+ X11_XShmAttach(display, shminfo);
+ X11_XSync(display, False);
+ X11_XSetErrorHandler(X_handler);
+ if ( shm_error )
+ shmdt(shminfo->shmaddr);
+ } else {
+ shm_error = True;
+ }
+ shmctl(shminfo->shmid, IPC_RMID, NULL);
+ } else {
+ shm_error = True;
+ }
+ if (!shm_error) {
+ data->ximage = X11_XShmCreateImage(display, data->visual,
+ vinfo.depth, ZPixmap,
+ shminfo->shmaddr, shminfo,
+ window->w, window->h);
+ if (!data->ximage) {
+ X11_XShmDetach(display, shminfo);
+ X11_XSync(display, False);
+ shmdt(shminfo->shmaddr);
+ } else {
+ /* Done! */
+ data->use_mitshm = SDL_TRUE;
+ *pixels = shminfo->shmaddr;
+ return 0;
+ }
+ }
+ }
+#endif /* not NO_SHARED_MEMORY */
+
+ *pixels = SDL_malloc(window->h*(*pitch));
+ if (*pixels == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ data->ximage = X11_XCreateImage(display, data->visual,
+ vinfo.depth, ZPixmap, 0, (char *)(*pixels),
+ window->w, window->h, 32, 0);
+ if (!data->ximage) {
+ SDL_free(*pixels);
+ return SDL_SetError("Couldn't create XImage");
+ }
+ return 0;
+}
+
+int
+X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects,
+ int numrects)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ int i;
+ int x, y, w ,h;
+#ifndef NO_SHARED_MEMORY
+ if (data->use_mitshm) {
+ for (i = 0; i < numrects; ++i) {
+ x = rects[i].x;
+ y = rects[i].y;
+ w = rects[i].w;
+ h = rects[i].h;
+
+ if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) {
+ /* Clipped? */
+ continue;
+ }
+ if (x < 0)
+ {
+ x += w;
+ w += rects[i].x;
+ }
+ if (y < 0)
+ {
+ y += h;
+ h += rects[i].y;
+ }
+ if (x + w > window->w)
+ w = window->w - x;
+ if (y + h > window->h)
+ h = window->h - y;
+
+ X11_XShmPutImage(display, data->xwindow, data->gc, data->ximage,
+ x, y, x, y, w, h, False);
+ }
+ }
+ else
+#endif /* !NO_SHARED_MEMORY */
+ {
+ for (i = 0; i < numrects; ++i) {
+ x = rects[i].x;
+ y = rects[i].y;
+ w = rects[i].w;
+ h = rects[i].h;
+
+ if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) {
+ /* Clipped? */
+ continue;
+ }
+ if (x < 0)
+ {
+ x += w;
+ w += rects[i].x;
+ }
+ if (y < 0)
+ {
+ y += h;
+ h += rects[i].y;
+ }
+ if (x + w > window->w)
+ w = window->w - x;
+ if (y + h > window->h)
+ h = window->h - y;
+
+ X11_XPutImage(display, data->xwindow, data->gc, data->ximage,
+ x, y, x, y, w, h);
+ }
+ }
+
+ X11_XSync(display, False);
+
+ return 0;
+}
+
+void
+X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display;
+
+ if (!data) {
+ /* The window wasn't fully initialized */
+ return;
+ }
+
+ display = data->videodata->display;
+
+ if (data->ximage) {
+ XDestroyImage(data->ximage);
+
+#ifndef NO_SHARED_MEMORY
+ if (data->use_mitshm) {
+ X11_XShmDetach(display, &data->shminfo);
+ X11_XSync(display, False);
+ shmdt(data->shminfo.shmaddr);
+ data->use_mitshm = SDL_FALSE;
+ }
+#endif /* !NO_SHARED_MEMORY */
+
+ data->ximage = NULL;
+ }
+ if (data->gc) {
+ X11_XFreeGC(display, data->gc);
+ data->gc = NULL;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.h
new file mode 100644
index 0000000..6a31788
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11framebuffer.h
@@ -0,0 +1,37 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_x11framebuffer_h_
+#define SDL_x11framebuffer_h_
+
+#include "../../SDL_internal.h"
+
+
+extern int X11_CreateWindowFramebuffer(_THIS, SDL_Window * window,
+ Uint32 * format,
+ void ** pixels, int *pitch);
+extern int X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
+ const SDL_Rect * rects, int numrects);
+extern void X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+
+#endif /* SDL_x11framebuffer_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.c
new file mode 100644
index 0000000..a57adf9
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.c
@@ -0,0 +1,543 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/scancodes_darwin.h"
+#include "../../events/scancodes_xfree86.h"
+
+#include <X11/keysym.h>
+#include <X11/XKBlib.h>
+
+#include "imKStoUCS.h"
+
+#ifdef X_HAVE_UTF8_STRING
+#include <locale.h>
+#endif
+
+/* *INDENT-OFF* */
+static const struct {
+ KeySym keysym;
+ SDL_Scancode scancode;
+} KeySymToSDLScancode[] = {
+ { XK_Return, SDL_SCANCODE_RETURN },
+ { XK_Escape, SDL_SCANCODE_ESCAPE },
+ { XK_BackSpace, SDL_SCANCODE_BACKSPACE },
+ { XK_Tab, SDL_SCANCODE_TAB },
+ { XK_Caps_Lock, SDL_SCANCODE_CAPSLOCK },
+ { XK_F1, SDL_SCANCODE_F1 },
+ { XK_F2, SDL_SCANCODE_F2 },
+ { XK_F3, SDL_SCANCODE_F3 },
+ { XK_F4, SDL_SCANCODE_F4 },
+ { XK_F5, SDL_SCANCODE_F5 },
+ { XK_F6, SDL_SCANCODE_F6 },
+ { XK_F7, SDL_SCANCODE_F7 },
+ { XK_F8, SDL_SCANCODE_F8 },
+ { XK_F9, SDL_SCANCODE_F9 },
+ { XK_F10, SDL_SCANCODE_F10 },
+ { XK_F11, SDL_SCANCODE_F11 },
+ { XK_F12, SDL_SCANCODE_F12 },
+ { XK_Print, SDL_SCANCODE_PRINTSCREEN },
+ { XK_Scroll_Lock, SDL_SCANCODE_SCROLLLOCK },
+ { XK_Pause, SDL_SCANCODE_PAUSE },
+ { XK_Insert, SDL_SCANCODE_INSERT },
+ { XK_Home, SDL_SCANCODE_HOME },
+ { XK_Prior, SDL_SCANCODE_PAGEUP },
+ { XK_Delete, SDL_SCANCODE_DELETE },
+ { XK_End, SDL_SCANCODE_END },
+ { XK_Next, SDL_SCANCODE_PAGEDOWN },
+ { XK_Right, SDL_SCANCODE_RIGHT },
+ { XK_Left, SDL_SCANCODE_LEFT },
+ { XK_Down, SDL_SCANCODE_DOWN },
+ { XK_Up, SDL_SCANCODE_UP },
+ { XK_Num_Lock, SDL_SCANCODE_NUMLOCKCLEAR },
+ { XK_KP_Divide, SDL_SCANCODE_KP_DIVIDE },
+ { XK_KP_Multiply, SDL_SCANCODE_KP_MULTIPLY },
+ { XK_KP_Subtract, SDL_SCANCODE_KP_MINUS },
+ { XK_KP_Add, SDL_SCANCODE_KP_PLUS },
+ { XK_KP_Enter, SDL_SCANCODE_KP_ENTER },
+ { XK_KP_Delete, SDL_SCANCODE_KP_PERIOD },
+ { XK_KP_End, SDL_SCANCODE_KP_1 },
+ { XK_KP_Down, SDL_SCANCODE_KP_2 },
+ { XK_KP_Next, SDL_SCANCODE_KP_3 },
+ { XK_KP_Left, SDL_SCANCODE_KP_4 },
+ { XK_KP_Begin, SDL_SCANCODE_KP_5 },
+ { XK_KP_Right, SDL_SCANCODE_KP_6 },
+ { XK_KP_Home, SDL_SCANCODE_KP_7 },
+ { XK_KP_Up, SDL_SCANCODE_KP_8 },
+ { XK_KP_Prior, SDL_SCANCODE_KP_9 },
+ { XK_KP_Insert, SDL_SCANCODE_KP_0 },
+ { XK_KP_Decimal, SDL_SCANCODE_KP_PERIOD },
+ { XK_KP_1, SDL_SCANCODE_KP_1 },
+ { XK_KP_2, SDL_SCANCODE_KP_2 },
+ { XK_KP_3, SDL_SCANCODE_KP_3 },
+ { XK_KP_4, SDL_SCANCODE_KP_4 },
+ { XK_KP_5, SDL_SCANCODE_KP_5 },
+ { XK_KP_6, SDL_SCANCODE_KP_6 },
+ { XK_KP_7, SDL_SCANCODE_KP_7 },
+ { XK_KP_8, SDL_SCANCODE_KP_8 },
+ { XK_KP_9, SDL_SCANCODE_KP_9 },
+ { XK_KP_0, SDL_SCANCODE_KP_0 },
+ { XK_KP_Decimal, SDL_SCANCODE_KP_PERIOD },
+ { XK_Hyper_R, SDL_SCANCODE_APPLICATION },
+ { XK_KP_Equal, SDL_SCANCODE_KP_EQUALS },
+ { XK_F13, SDL_SCANCODE_F13 },
+ { XK_F14, SDL_SCANCODE_F14 },
+ { XK_F15, SDL_SCANCODE_F15 },
+ { XK_F16, SDL_SCANCODE_F16 },
+ { XK_F17, SDL_SCANCODE_F17 },
+ { XK_F18, SDL_SCANCODE_F18 },
+ { XK_F19, SDL_SCANCODE_F19 },
+ { XK_F20, SDL_SCANCODE_F20 },
+ { XK_F21, SDL_SCANCODE_F21 },
+ { XK_F22, SDL_SCANCODE_F22 },
+ { XK_F23, SDL_SCANCODE_F23 },
+ { XK_F24, SDL_SCANCODE_F24 },
+ { XK_Execute, SDL_SCANCODE_EXECUTE },
+ { XK_Help, SDL_SCANCODE_HELP },
+ { XK_Menu, SDL_SCANCODE_MENU },
+ { XK_Select, SDL_SCANCODE_SELECT },
+ { XK_Cancel, SDL_SCANCODE_STOP },
+ { XK_Redo, SDL_SCANCODE_AGAIN },
+ { XK_Undo, SDL_SCANCODE_UNDO },
+ { XK_Find, SDL_SCANCODE_FIND },
+ { XK_KP_Separator, SDL_SCANCODE_KP_COMMA },
+ { XK_Sys_Req, SDL_SCANCODE_SYSREQ },
+ { XK_Control_L, SDL_SCANCODE_LCTRL },
+ { XK_Shift_L, SDL_SCANCODE_LSHIFT },
+ { XK_Alt_L, SDL_SCANCODE_LALT },
+ { XK_Meta_L, SDL_SCANCODE_LGUI },
+ { XK_Super_L, SDL_SCANCODE_LGUI },
+ { XK_Control_R, SDL_SCANCODE_RCTRL },
+ { XK_Shift_R, SDL_SCANCODE_RSHIFT },
+ { XK_Alt_R, SDL_SCANCODE_RALT },
+ { XK_ISO_Level3_Shift, SDL_SCANCODE_RALT },
+ { XK_Meta_R, SDL_SCANCODE_RGUI },
+ { XK_Super_R, SDL_SCANCODE_RGUI },
+ { XK_Mode_switch, SDL_SCANCODE_MODE },
+ { XK_period, SDL_SCANCODE_PERIOD },
+ { XK_comma, SDL_SCANCODE_COMMA },
+ { XK_slash, SDL_SCANCODE_SLASH },
+ { XK_backslash, SDL_SCANCODE_BACKSLASH },
+ { XK_minus, SDL_SCANCODE_MINUS },
+ { XK_equal, SDL_SCANCODE_EQUALS },
+ { XK_space, SDL_SCANCODE_SPACE },
+ { XK_grave, SDL_SCANCODE_GRAVE },
+ { XK_apostrophe, SDL_SCANCODE_APOSTROPHE },
+ { XK_bracketleft, SDL_SCANCODE_LEFTBRACKET },
+ { XK_bracketright, SDL_SCANCODE_RIGHTBRACKET },
+};
+
+static const struct
+{
+ SDL_Scancode const *table;
+ int table_size;
+} scancode_set[] = {
+ { darwin_scancode_table, SDL_arraysize(darwin_scancode_table) },
+ { xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) },
+ { xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) },
+ { xvnc_scancode_table, SDL_arraysize(xvnc_scancode_table) },
+};
+/* *INDENT-OFF* */
+
+/* This function only works for keyboards in US QWERTY layout */
+static SDL_Scancode
+X11_KeyCodeToSDLScancode(_THIS, KeyCode keycode)
+{
+ KeySym keysym;
+ int i;
+
+ keysym = X11_KeyCodeToSym(_this, keycode, 0);
+ if (keysym == NoSymbol) {
+ return SDL_SCANCODE_UNKNOWN;
+ }
+
+ if (keysym >= XK_a && keysym <= XK_z) {
+ return SDL_SCANCODE_A + (keysym - XK_a);
+ }
+ if (keysym >= XK_A && keysym <= XK_Z) {
+ return SDL_SCANCODE_A + (keysym - XK_A);
+ }
+
+ if (keysym == XK_0) {
+ return SDL_SCANCODE_0;
+ }
+ if (keysym >= XK_1 && keysym <= XK_9) {
+ return SDL_SCANCODE_1 + (keysym - XK_1);
+ }
+
+ for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) {
+ if (keysym == KeySymToSDLScancode[i].keysym) {
+ return KeySymToSDLScancode[i].scancode;
+ }
+ }
+ return SDL_SCANCODE_UNKNOWN;
+}
+
+static Uint32
+X11_KeyCodeToUcs4(_THIS, KeyCode keycode, unsigned char group)
+{
+ KeySym keysym = X11_KeyCodeToSym(_this, keycode, group);
+
+ if (keysym == NoSymbol) {
+ return 0;
+ }
+
+ return X11_KeySymToUcs4(keysym);
+}
+
+KeySym
+X11_KeyCodeToSym(_THIS, KeyCode keycode, unsigned char group)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ KeySym keysym;
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+ if (data->xkb) {
+ int num_groups = XkbKeyNumGroups(data->xkb, keycode);
+ unsigned char info = XkbKeyGroupInfo(data->xkb, keycode);
+
+ if (num_groups && group >= num_groups) {
+
+ int action = XkbOutOfRangeGroupAction(info);
+
+ if (action == XkbRedirectIntoRange) {
+ if ((group = XkbOutOfRangeGroupNumber(info)) >= num_groups) {
+ group = 0;
+ }
+ } else if (action == XkbClampIntoRange) {
+ group = num_groups - 1;
+ } else {
+ group %= num_groups;
+ }
+ }
+ keysym = X11_XkbKeycodeToKeysym(data->display, keycode, group, 0);
+ } else {
+ keysym = X11_XKeycodeToKeysym(data->display, keycode, 0);
+ }
+#else
+ keysym = X11_XKeycodeToKeysym(data->display, keycode, 0);
+#endif
+
+ return keysym;
+}
+
+int
+X11_InitKeyboard(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ int i = 0;
+ int j = 0;
+ int min_keycode, max_keycode;
+ struct {
+ SDL_Scancode scancode;
+ KeySym keysym;
+ int value;
+ } fingerprint[] = {
+ { SDL_SCANCODE_HOME, XK_Home, 0 },
+ { SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
+ { SDL_SCANCODE_UP, XK_Up, 0 },
+ { SDL_SCANCODE_LEFT, XK_Left, 0 },
+ { SDL_SCANCODE_DELETE, XK_Delete, 0 },
+ { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 },
+ };
+ int best_distance;
+ int best_index;
+ int distance;
+ Bool xkb_repeat = 0;
+
+ X11_XAutoRepeatOn(data->display);
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+ {
+ int xkb_major = XkbMajorVersion;
+ int xkb_minor = XkbMinorVersion;
+
+ if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
+ data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
+ }
+
+ /* This will remove KeyRelease events for held keys */
+ X11_XkbSetDetectableAutoRepeat(data->display, True, &xkb_repeat);
+ }
+#endif
+
+ /* Open a connection to the X input manager */
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8) {
+ /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that
+ Compose keys will work correctly. */
+ char *prev_locale = setlocale(LC_ALL, NULL);
+ char *prev_xmods = X11_XSetLocaleModifiers(NULL);
+ const char *new_xmods = "";
+ const char *env_xmods = SDL_getenv("XMODIFIERS");
+ SDL_bool has_dbus_ime_support = SDL_FALSE;
+
+ if (prev_locale) {
+ prev_locale = SDL_strdup(prev_locale);
+ }
+
+ if (prev_xmods) {
+ prev_xmods = SDL_strdup(prev_xmods);
+ }
+
+ /* IBus resends some key events that were filtered by XFilterEvents
+ when it is used via XIM which causes issues. Prevent this by forcing
+ @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via
+ the DBus implementation, which also has support for pre-editing. */
+ if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
+ has_dbus_ime_support = SDL_TRUE;
+ }
+ if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) {
+ has_dbus_ime_support = SDL_TRUE;
+ }
+ if (has_dbus_ime_support || !xkb_repeat) {
+ new_xmods = "@im=none";
+ }
+
+ setlocale(LC_ALL, "");
+ X11_XSetLocaleModifiers(new_xmods);
+
+ data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname);
+
+ /* Reset the locale + X locale modifiers back to how they were,
+ locale first because the X locale modifiers depend on it. */
+ setlocale(LC_ALL, prev_locale);
+ X11_XSetLocaleModifiers(prev_xmods);
+
+ if (prev_locale) {
+ SDL_free(prev_locale);
+ }
+
+ if (prev_xmods) {
+ SDL_free(prev_xmods);
+ }
+ }
+#endif
+ /* Try to determine which scancodes are being used based on fingerprint */
+ best_distance = SDL_arraysize(fingerprint) + 1;
+ best_index = -1;
+ X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
+ for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
+ fingerprint[i].value =
+ X11_XKeysymToKeycode(data->display, fingerprint[i].keysym) -
+ min_keycode;
+ }
+ for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
+ /* Make sure the scancode set isn't too big */
+ if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
+ continue;
+ }
+ distance = 0;
+ for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
+ if (fingerprint[j].value < 0
+ || fingerprint[j].value >= scancode_set[i].table_size) {
+ distance += 1;
+ } else if (scancode_set[i].table[fingerprint[j].value] != fingerprint[j].scancode) {
+ distance += 1;
+ }
+ }
+ if (distance < best_distance) {
+ best_distance = distance;
+ best_index = i;
+ }
+ }
+ if (best_index >= 0 && best_distance <= 2) {
+#ifdef DEBUG_KEYBOARD
+ printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", best_index, min_keycode, max_keycode, scancode_set[best_index].table_size);
+#endif
+ SDL_memcpy(&data->key_layout[min_keycode], scancode_set[best_index].table,
+ sizeof(SDL_Scancode) * scancode_set[best_index].table_size);
+ } else {
+ SDL_Keycode keymap[SDL_NUM_SCANCODES];
+
+ printf
+ ("Keyboard layout unknown, please report the following to the SDL forums/mailing list (https://discourse.libsdl.org/):\n");
+
+ /* Determine key_layout - only works on US QWERTY layout */
+ SDL_GetDefaultKeymap(keymap);
+ for (i = min_keycode; i <= max_keycode; ++i) {
+ KeySym sym;
+ sym = X11_KeyCodeToSym(_this, (KeyCode) i, 0);
+ if (sym != NoSymbol) {
+ SDL_Scancode scancode;
+ printf("code = %d, sym = 0x%X (%s) ", i - min_keycode,
+ (unsigned int) sym, X11_XKeysymToString(sym));
+ scancode = X11_KeyCodeToSDLScancode(_this, i);
+ data->key_layout[i] = scancode;
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ printf("scancode not found\n");
+ } else {
+ printf("scancode = %d (%s)\n", scancode, SDL_GetScancodeName(scancode));
+ }
+ }
+ }
+ }
+
+ X11_UpdateKeymap(_this);
+
+ SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
+
+#ifdef SDL_USE_IME
+ SDL_IME_Init();
+#endif
+
+ return 0;
+}
+
+void
+X11_UpdateKeymap(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ int i;
+ SDL_Scancode scancode;
+ SDL_Keycode keymap[SDL_NUM_SCANCODES];
+ unsigned char group = 0;
+
+ SDL_GetDefaultKeymap(keymap);
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+ if (data->xkb) {
+ XkbStateRec state;
+ X11_XkbGetUpdatedMap(data->display, XkbAllClientInfoMask, data->xkb);
+
+ if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) {
+ group = state.group;
+ }
+ }
+#endif
+
+
+ for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
+ Uint32 key;
+
+ /* Make sure this is a valid scancode */
+ scancode = data->key_layout[i];
+ if (scancode == SDL_SCANCODE_UNKNOWN) {
+ continue;
+ }
+
+ /* See if there is a UCS keycode for this scancode */
+ key = X11_KeyCodeToUcs4(_this, (KeyCode)i, group);
+ if (key) {
+ keymap[scancode] = key;
+ } else {
+ SDL_Scancode keyScancode = X11_KeyCodeToSDLScancode(_this, (KeyCode)i);
+
+ switch (keyScancode) {
+ case SDL_SCANCODE_RETURN:
+ keymap[scancode] = SDLK_RETURN;
+ break;
+ case SDL_SCANCODE_ESCAPE:
+ keymap[scancode] = SDLK_ESCAPE;
+ break;
+ case SDL_SCANCODE_BACKSPACE:
+ keymap[scancode] = SDLK_BACKSPACE;
+ break;
+ case SDL_SCANCODE_TAB:
+ keymap[scancode] = SDLK_TAB;
+ break;
+ case SDL_SCANCODE_DELETE:
+ keymap[scancode] = SDLK_DELETE;
+ break;
+ default:
+ keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(keyScancode);
+ break;
+ }
+ }
+ }
+ SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
+}
+
+void
+X11_QuitKeyboard(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+ if (data->xkb) {
+ X11_XkbFreeKeyboard(data->xkb, 0, True);
+ data->xkb = NULL;
+ }
+#endif
+
+#ifdef SDL_USE_IME
+ SDL_IME_Quit();
+#endif
+}
+
+static void
+X11_ResetXIM(_THIS)
+{
+#ifdef X_HAVE_UTF8_STRING
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ int i;
+
+ if (videodata && videodata->windowlist) {
+ for (i = 0; i < videodata->numwindows; ++i) {
+ SDL_WindowData *data = videodata->windowlist[i];
+ if (data && data->ic) {
+ /* Clear any partially entered dead keys */
+ char *contents = X11_Xutf8ResetIC(data->ic);
+ if (contents) {
+ X11_XFree(contents);
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+X11_StartTextInput(_THIS)
+{
+ X11_ResetXIM(_this);
+}
+
+void
+X11_StopTextInput(_THIS)
+{
+ X11_ResetXIM(_this);
+#ifdef SDL_USE_IME
+ SDL_IME_Reset();
+#endif
+}
+
+void
+X11_SetTextInputRect(_THIS, SDL_Rect *rect)
+{
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return;
+ }
+
+#ifdef SDL_USE_IME
+ SDL_IME_UpdateTextRect(rect);
+#endif
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.h
new file mode 100644
index 0000000..c1cc69c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11keyboard.h
@@ -0,0 +1,36 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11keyboard_h_
+#define SDL_x11keyboard_h_
+
+extern int X11_InitKeyboard(_THIS);
+extern void X11_UpdateKeymap(_THIS);
+extern void X11_QuitKeyboard(_THIS);
+extern void X11_StartTextInput(_THIS);
+extern void X11_StopTextInput(_THIS);
+extern void X11_SetTextInputRect(_THIS, SDL_Rect *rect);
+extern KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group);
+
+#endif /* SDL_x11keyboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.c
new file mode 100644
index 0000000..70a472a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.c
@@ -0,0 +1,872 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL.h"
+#include "SDL_x11video.h"
+#include "SDL_x11dyn.h"
+#include "SDL_assert.h"
+#include "SDL_x11messagebox.h"
+
+#include <X11/keysym.h>
+#include <locale.h>
+
+
+#define SDL_FORK_MESSAGEBOX 1
+#define SDL_SET_LOCALE 1
+
+#if SDL_FORK_MESSAGEBOX
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#define MAX_BUTTONS 8 /* Maximum number of buttons supported */
+#define MIN_BUTTON_WIDTH 64 /* Minimum button width */
+#define MIN_DIALOG_WIDTH 200 /* Minimum dialog width */
+#define MIN_DIALOG_HEIGHT 100 /* Minimum dialog height */
+
+static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
+static const char g_MessageBoxFont[] = "-*-*-medium-r-normal--*-120-*-*-*-*-*-*";
+
+static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] = {
+ { 56, 54, 53 }, /* SDL_MESSAGEBOX_COLOR_BACKGROUND, */
+ { 209, 207, 205 }, /* SDL_MESSAGEBOX_COLOR_TEXT, */
+ { 140, 135, 129 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, */
+ { 105, 102, 99 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, */
+ { 205, 202, 53 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, */
+};
+
+#define SDL_MAKE_RGB( _r, _g, _b ) ( ( ( Uint32 )( _r ) << 16 ) | \
+ ( ( Uint32 )( _g ) << 8 ) | \
+ ( ( Uint32 )( _b ) ) )
+
+typedef struct SDL_MessageBoxButtonDataX11 {
+ int x, y; /* Text position */
+ int length; /* Text length */
+ int text_width; /* Text width */
+
+ SDL_Rect rect; /* Rectangle for entire button */
+
+ const SDL_MessageBoxButtonData *buttondata; /* Button data from caller */
+} SDL_MessageBoxButtonDataX11;
+
+typedef struct TextLineData {
+ int width; /* Width of this text line */
+ int length; /* String length of this text line */
+ const char *text; /* Text for this line */
+} TextLineData;
+
+typedef struct SDL_MessageBoxDataX11
+{
+ Display *display;
+ int screen;
+ Window window;
+#if SDL_VIDEO_DRIVER_X11_XDBE
+ XdbeBackBuffer buf;
+ SDL_bool xdbe; /* Whether Xdbe is present or not */
+#endif
+ long event_mask;
+ Atom wm_protocols;
+ Atom wm_delete_message;
+
+ int dialog_width; /* Dialog box width. */
+ int dialog_height; /* Dialog box height. */
+
+ XFontSet font_set; /* for UTF-8 systems */
+ XFontStruct *font_struct; /* Latin1 (ASCII) fallback. */
+ int xtext, ytext; /* Text position to start drawing at. */
+ int numlines; /* Count of Text lines. */
+ int text_height; /* Height for text lines. */
+ TextLineData *linedata;
+
+ int *pbuttonid; /* Pointer to user return buttonid value. */
+
+ int button_press_index; /* Index into buttondata/buttonpos for button which is pressed (or -1). */
+ int mouse_over_index; /* Index into buttondata/buttonpos for button mouse is over (or -1). */
+
+ int numbuttons; /* Count of buttons. */
+ const SDL_MessageBoxButtonData *buttondata;
+ SDL_MessageBoxButtonDataX11 buttonpos[ MAX_BUTTONS ];
+
+ Uint32 color[ SDL_MESSAGEBOX_COLOR_MAX ];
+
+ const SDL_MessageBoxData *messageboxdata;
+} SDL_MessageBoxDataX11;
+
+/* Maximum helper for ints. */
+static SDL_INLINE int
+IntMax( int a, int b )
+{
+ return ( a > b ) ? a : b;
+}
+
+/* Return width and height for a string. */
+static void
+GetTextWidthHeight( SDL_MessageBoxDataX11 *data, const char *str, int nbytes, int *pwidth, int *pheight )
+{
+ if (SDL_X11_HAVE_UTF8) {
+ XRectangle overall_ink, overall_logical;
+ X11_Xutf8TextExtents(data->font_set, str, nbytes, &overall_ink, &overall_logical);
+ *pwidth = overall_logical.width;
+ *pheight = overall_logical.height;
+ } else {
+ XCharStruct text_structure;
+ int font_direction, font_ascent, font_descent;
+ X11_XTextExtents( data->font_struct, str, nbytes,
+ &font_direction, &font_ascent, &font_descent,
+ &text_structure );
+ *pwidth = text_structure.width;
+ *pheight = text_structure.ascent + text_structure.descent;
+ }
+}
+
+/* Return index of button if position x,y is contained therein. */
+static int
+GetHitButtonIndex( SDL_MessageBoxDataX11 *data, int x, int y )
+{
+ int i;
+ int numbuttons = data->numbuttons;
+ SDL_MessageBoxButtonDataX11 *buttonpos = data->buttonpos;
+
+ for ( i = 0; i < numbuttons; i++ ) {
+ SDL_Rect *rect = &buttonpos[ i ].rect;
+
+ if ( ( x >= rect->x ) &&
+ ( x <= ( rect->x + rect->w ) ) &&
+ ( y >= rect->y ) &&
+ ( y <= ( rect->y + rect->h ) ) ) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+/* Initialize SDL_MessageBoxData structure and Display, etc. */
+static int
+X11_MessageBoxInit( SDL_MessageBoxDataX11 *data, const SDL_MessageBoxData * messageboxdata, int * pbuttonid )
+{
+ int i;
+ int numbuttons = messageboxdata->numbuttons;
+ const SDL_MessageBoxButtonData *buttondata = messageboxdata->buttons;
+ const SDL_MessageBoxColor *colorhints;
+
+ if ( numbuttons > MAX_BUTTONS ) {
+ return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS);
+ }
+
+ data->dialog_width = MIN_DIALOG_WIDTH;
+ data->dialog_height = MIN_DIALOG_HEIGHT;
+ data->messageboxdata = messageboxdata;
+ data->buttondata = buttondata;
+ data->numbuttons = numbuttons;
+ data->pbuttonid = pbuttonid;
+
+ data->display = X11_XOpenDisplay( NULL );
+ if ( !data->display ) {
+ return SDL_SetError("Couldn't open X11 display");
+ }
+
+ if (SDL_X11_HAVE_UTF8) {
+ char **missing = NULL;
+ int num_missing = 0;
+ data->font_set = X11_XCreateFontSet(data->display, g_MessageBoxFont,
+ &missing, &num_missing, NULL);
+ if ( missing != NULL ) {
+ X11_XFreeStringList(missing);
+ }
+ if ( data->font_set == NULL ) {
+ return SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
+ }
+ } else {
+ data->font_struct = X11_XLoadQueryFont( data->display, g_MessageBoxFontLatin1 );
+ if ( data->font_struct == NULL ) {
+ return SDL_SetError("Couldn't load font %s", g_MessageBoxFontLatin1);
+ }
+ }
+
+ if ( messageboxdata->colorScheme ) {
+ colorhints = messageboxdata->colorScheme->colors;
+ } else {
+ colorhints = g_default_colors;
+ }
+
+ /* Convert our SDL_MessageBoxColor r,g,b values to packed RGB format. */
+ for ( i = 0; i < SDL_MESSAGEBOX_COLOR_MAX; i++ ) {
+ data->color[ i ] = SDL_MAKE_RGB( colorhints[ i ].r, colorhints[ i ].g, colorhints[ i ].b );
+ }
+
+ return 0;
+}
+
+static int
+CountLinesOfText(const char *text)
+{
+ int retval = 0;
+ while (text && *text) {
+ const char *lf = SDL_strchr(text, '\n');
+ retval++; /* even without an endline, this counts as a line. */
+ text = lf ? lf + 1 : NULL;
+ }
+ return retval;
+}
+
+/* Calculate and initialize text and button locations. */
+static int
+X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
+{
+ int i;
+ int ybuttons;
+ int text_width_max = 0;
+ int button_text_height = 0;
+ int button_width = MIN_BUTTON_WIDTH;
+ const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
+
+ /* Go over text and break linefeeds into separate lines. */
+ if ( messageboxdata->message && messageboxdata->message[ 0 ] ) {
+ const char *text = messageboxdata->message;
+ const int linecount = CountLinesOfText(text);
+ TextLineData *plinedata = (TextLineData *) SDL_malloc(sizeof (TextLineData) * linecount);
+
+ if (!plinedata) {
+ return SDL_OutOfMemory();
+ }
+
+ data->linedata = plinedata;
+ data->numlines = linecount;
+
+ for ( i = 0; i < linecount; i++, plinedata++ ) {
+ const char *lf = SDL_strchr( text, '\n' );
+ const int length = lf ? ( lf - text ) : SDL_strlen( text );
+ int height;
+
+ plinedata->text = text;
+
+ GetTextWidthHeight( data, text, length, &plinedata->width, &height );
+
+ /* Text and widths are the largest we've ever seen. */
+ data->text_height = IntMax( data->text_height, height );
+ text_width_max = IntMax( text_width_max, plinedata->width );
+
+ plinedata->length = length;
+ if (lf && (lf > text) && (lf[-1] == '\r')) {
+ plinedata->length--;
+ }
+
+ text += length + 1;
+
+ /* Break if there are no more linefeeds. */
+ if ( !lf )
+ break;
+ }
+
+ /* Bump up the text height slightly. */
+ data->text_height += 2;
+ }
+
+ /* Loop through all buttons and calculate the button widths and height. */
+ for ( i = 0; i < data->numbuttons; i++ ) {
+ int height;
+
+ data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
+ data->buttonpos[ i ].length = SDL_strlen( data->buttondata[ i ].text );
+
+ GetTextWidthHeight( data, data->buttondata[ i ].text, SDL_strlen( data->buttondata[ i ].text ),
+ &data->buttonpos[ i ].text_width, &height );
+
+ button_width = IntMax( button_width, data->buttonpos[ i ].text_width );
+ button_text_height = IntMax( button_text_height, height );
+ }
+
+ if ( data->numlines ) {
+ /* x,y for this line of text. */
+ data->xtext = data->text_height;
+ data->ytext = data->text_height + data->text_height;
+
+ /* Bump button y down to bottom of text. */
+ ybuttons = 3 * data->ytext / 2 + ( data->numlines - 1 ) * data->text_height;
+
+ /* Bump the dialog box width and height up if needed. */
+ data->dialog_width = IntMax( data->dialog_width, 2 * data->xtext + text_width_max );
+ data->dialog_height = IntMax( data->dialog_height, ybuttons );
+ } else {
+ /* Button y starts at height of button text. */
+ ybuttons = button_text_height;
+ }
+
+ if ( data->numbuttons ) {
+ int x, y;
+ int width_of_buttons;
+ int button_spacing = button_text_height;
+ int button_height = 2 * button_text_height;
+
+ /* Bump button width up a bit. */
+ button_width += button_text_height;
+
+ /* Get width of all buttons lined up. */
+ width_of_buttons = data->numbuttons * button_width + ( data->numbuttons - 1 ) * button_spacing;
+
+ /* Bump up dialog width and height if buttons are wider than text. */
+ data->dialog_width = IntMax( data->dialog_width, width_of_buttons + 2 * button_spacing );
+ data->dialog_height = IntMax( data->dialog_height, ybuttons + 2 * button_height );
+
+ /* Location for first button. */
+ x = ( data->dialog_width - width_of_buttons ) / 2;
+ y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2;
+
+ for ( i = 0; i < data->numbuttons; i++ ) {
+ /* Button coordinates. */
+ data->buttonpos[ i ].rect.x = x;
+ data->buttonpos[ i ].rect.y = y;
+ data->buttonpos[ i ].rect.w = button_width;
+ data->buttonpos[ i ].rect.h = button_height;
+
+ /* Button text coordinates. */
+ data->buttonpos[ i ].x = x + ( button_width - data->buttonpos[ i ].text_width ) / 2;
+ data->buttonpos[ i ].y = y + ( button_height - button_text_height - 1 ) / 2 + button_text_height;
+
+ /* Scoot over for next button. */
+ x += button_width + button_spacing;
+ }
+ }
+
+ return 0;
+}
+
+/* Free SDL_MessageBoxData data. */
+static void
+X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
+{
+ if ( data->font_set != NULL ) {
+ X11_XFreeFontSet( data->display, data->font_set );
+ data->font_set = NULL;
+ }
+
+ if ( data->font_struct != NULL ) {
+ X11_XFreeFont( data->display, data->font_struct );
+ data->font_struct = NULL;
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XDBE
+ if ( SDL_X11_HAVE_XDBE && data->xdbe ) {
+ X11_XdbeDeallocateBackBufferName(data->display, data->buf);
+ }
+#endif
+
+ if ( data->display ) {
+ if ( data->window != None ) {
+ X11_XWithdrawWindow( data->display, data->window, data->screen );
+ X11_XDestroyWindow( data->display, data->window );
+ data->window = None;
+ }
+
+ X11_XCloseDisplay( data->display );
+ data->display = NULL;
+ }
+
+ SDL_free(data->linedata);
+}
+
+/* Create and set up our X11 dialog box indow. */
+static int
+X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
+{
+ int x, y;
+ XSizeHints *sizehints;
+ XSetWindowAttributes wnd_attr;
+ Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_NAME;
+ Display *display = data->display;
+ SDL_WindowData *windowdata = NULL;
+ const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
+ char *title_locale = NULL;
+
+ if ( messageboxdata->window ) {
+ SDL_DisplayData *displaydata =
+ (SDL_DisplayData *) SDL_GetDisplayForWindow(messageboxdata->window)->driverdata;
+ windowdata = (SDL_WindowData *)messageboxdata->window->driverdata;
+ data->screen = displaydata->screen;
+ } else {
+ data->screen = DefaultScreen( display );
+ }
+
+ data->event_mask = ExposureMask |
+ ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
+ StructureNotifyMask | FocusChangeMask | PointerMotionMask;
+ wnd_attr.event_mask = data->event_mask;
+
+ data->window = X11_XCreateWindow(
+ display, RootWindow(display, data->screen),
+ 0, 0,
+ data->dialog_width, data->dialog_height,
+ 0, CopyFromParent, InputOutput, CopyFromParent,
+ CWEventMask, &wnd_attr );
+ if ( data->window == None ) {
+ return SDL_SetError("Couldn't create X window");
+ }
+
+ if ( windowdata ) {
+ /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */
+ X11_XSetTransientForHint( display, data->window, windowdata->xwindow );
+ }
+
+ X11_XStoreName( display, data->window, messageboxdata->title );
+ _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False);
+
+ title_locale = SDL_iconv_utf8_locale(messageboxdata->title);
+ if (title_locale) {
+ XTextProperty titleprop;
+ Status status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
+ SDL_free(title_locale);
+ if (status) {
+ X11_XSetTextProperty(display, data->window, &titleprop, XA_WM_NAME);
+ X11_XFree(titleprop.value);
+ }
+ }
+
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8) {
+ XTextProperty titleprop;
+ Status status = X11_Xutf8TextListToTextProperty(display, (char **) &messageboxdata->title, 1,
+ XUTF8StringStyle, &titleprop);
+ if (status == Success) {
+ X11_XSetTextProperty(display, data->window, &titleprop,
+ _NET_WM_NAME);
+ X11_XFree(titleprop.value);
+ }
+ }
+#endif
+
+ /* Let the window manager know this is a dialog box */
+ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
+ _NET_WM_WINDOW_TYPE_DIALOG = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ X11_XChangeProperty(display, data->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
+ PropModeReplace,
+ (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1);
+
+ /* Allow the window to be deleted by the window manager */
+ data->wm_protocols = X11_XInternAtom( display, "WM_PROTOCOLS", False );
+ data->wm_delete_message = X11_XInternAtom( display, "WM_DELETE_WINDOW", False );
+ X11_XSetWMProtocols( display, data->window, &data->wm_delete_message, 1 );
+
+ if ( windowdata ) {
+ XWindowAttributes attrib;
+ Window dummy;
+
+ X11_XGetWindowAttributes(display, windowdata->xwindow, &attrib);
+ x = attrib.x + ( attrib.width - data->dialog_width ) / 2;
+ y = attrib.y + ( attrib.height - data->dialog_height ) / 3 ;
+ X11_XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy);
+ } else {
+ const SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ if ((dev) && (dev->displays) && (dev->num_displays > 0)) {
+ const SDL_VideoDisplay *dpy = &dev->displays[0];
+ const SDL_DisplayData *dpydata = (SDL_DisplayData *) dpy->driverdata;
+ x = dpydata->x + (( dpy->current_mode.w - data->dialog_width ) / 2);
+ y = dpydata->y + (( dpy->current_mode.h - data->dialog_height ) / 3);
+ } else { /* oh well. This will misposition on a multi-head setup. Init first next time. */
+ x = ( DisplayWidth( display, data->screen ) - data->dialog_width ) / 2;
+ y = ( DisplayHeight( display, data->screen ) - data->dialog_height ) / 3 ;
+ }
+ }
+ X11_XMoveWindow( display, data->window, x, y );
+
+ sizehints = X11_XAllocSizeHints();
+ if ( sizehints ) {
+ sizehints->flags = USPosition | USSize | PMaxSize | PMinSize;
+ sizehints->x = x;
+ sizehints->y = y;
+ sizehints->width = data->dialog_width;
+ sizehints->height = data->dialog_height;
+
+ sizehints->min_width = sizehints->max_width = data->dialog_width;
+ sizehints->min_height = sizehints->max_height = data->dialog_height;
+
+ X11_XSetWMNormalHints( display, data->window, sizehints );
+
+ X11_XFree( sizehints );
+ }
+
+ X11_XMapRaised( display, data->window );
+
+#if SDL_VIDEO_DRIVER_X11_XDBE
+ /* Initialise a back buffer for double buffering */
+ if (SDL_X11_HAVE_XDBE) {
+ int xdbe_major, xdbe_minor;
+ if (X11_XdbeQueryExtension(display, &xdbe_major, &xdbe_minor) != 0) {
+ data->xdbe = SDL_TRUE;
+ data->buf = X11_XdbeAllocateBackBufferName(display, data->window, XdbeUndefined);
+ } else {
+ data->xdbe = SDL_FALSE;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+/* Draw our message box. */
+static void
+X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx )
+{
+ int i;
+ Drawable window = data->window;
+ Display *display = data->display;
+
+#if SDL_VIDEO_DRIVER_X11_XDBE
+ if (SDL_X11_HAVE_XDBE && data->xdbe) {
+ window = data->buf;
+ X11_XdbeBeginIdiom(data->display);
+ }
+#endif
+
+ X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ] );
+ X11_XFillRectangle( display, window, ctx, 0, 0, data->dialog_width, data->dialog_height );
+
+ X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
+ for ( i = 0; i < data->numlines; i++ ) {
+ TextLineData *plinedata = &data->linedata[ i ];
+
+ if (SDL_X11_HAVE_UTF8) {
+ X11_Xutf8DrawString( display, window, data->font_set, ctx,
+ data->xtext, data->ytext + i * data->text_height,
+ plinedata->text, plinedata->length );
+ } else {
+ X11_XDrawString( display, window, ctx,
+ data->xtext, data->ytext + i * data->text_height,
+ plinedata->text, plinedata->length );
+ }
+ }
+
+ for ( i = 0; i < data->numbuttons; i++ ) {
+ SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
+ const SDL_MessageBoxButtonData *buttondata = buttondatax11->buttondata;
+ int border = ( buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT ) ? 2 : 0;
+ int offset = ( ( data->mouse_over_index == i ) && ( data->button_press_index == data->mouse_over_index ) ) ? 1 : 0;
+
+ X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND ] );
+ X11_XFillRectangle( display, window, ctx,
+ buttondatax11->rect.x - border, buttondatax11->rect.y - border,
+ buttondatax11->rect.w + 2 * border, buttondatax11->rect.h + 2 * border );
+
+ X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_BORDER ] );
+ X11_XDrawRectangle( display, window, ctx,
+ buttondatax11->rect.x, buttondatax11->rect.y,
+ buttondatax11->rect.w, buttondatax11->rect.h );
+
+ X11_XSetForeground( display, ctx, ( data->mouse_over_index == i ) ?
+ data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED ] :
+ data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
+
+ if (SDL_X11_HAVE_UTF8) {
+ X11_Xutf8DrawString( display, window, data->font_set, ctx,
+ buttondatax11->x + offset,
+ buttondatax11->y + offset,
+ buttondata->text, buttondatax11->length );
+ } else {
+ X11_XDrawString( display, window, ctx,
+ buttondatax11->x + offset, buttondatax11->y + offset,
+ buttondata->text, buttondatax11->length );
+ }
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XDBE
+ if (SDL_X11_HAVE_XDBE && data->xdbe) {
+ XdbeSwapInfo swap_info;
+ swap_info.swap_window = data->window;
+ swap_info.swap_action = XdbeUndefined;
+ X11_XdbeSwapBuffers(data->display, &swap_info, 1);
+ X11_XdbeEndIdiom(data->display);
+ }
+#endif
+}
+
+static Bool
+X11_MessageBoxEventTest(Display *display, XEvent *event, XPointer arg)
+{
+ const SDL_MessageBoxDataX11 *data = (const SDL_MessageBoxDataX11 *) arg;
+ return ((event->xany.display == data->display) && (event->xany.window == data->window)) ? True : False;
+}
+
+/* Loop and handle message box event messages until something kills it. */
+static int
+X11_MessageBoxLoop( SDL_MessageBoxDataX11 *data )
+{
+ GC ctx;
+ XGCValues ctx_vals;
+ SDL_bool close_dialog = SDL_FALSE;
+ SDL_bool has_focus = SDL_TRUE;
+ KeySym last_key_pressed = XK_VoidSymbol;
+ unsigned long gcflags = GCForeground | GCBackground;
+
+ SDL_zero(ctx_vals);
+ ctx_vals.foreground = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
+ ctx_vals.background = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
+
+ if (!SDL_X11_HAVE_UTF8) {
+ gcflags |= GCFont;
+ ctx_vals.font = data->font_struct->fid;
+ }
+
+ ctx = X11_XCreateGC( data->display, data->window, gcflags, &ctx_vals );
+ if ( ctx == None ) {
+ return SDL_SetError("Couldn't create graphics context");
+ }
+
+ data->button_press_index = -1; /* Reset what button is currently depressed. */
+ data->mouse_over_index = -1; /* Reset what button the mouse is over. */
+
+ while( !close_dialog ) {
+ XEvent e;
+ SDL_bool draw = SDL_TRUE;
+
+ /* can't use XWindowEvent() because it can't handle ClientMessage events. */
+ /* can't use XNextEvent() because we only want events for this window. */
+ X11_XIfEvent( data->display, &e, X11_MessageBoxEventTest, (XPointer) data );
+
+ /* If X11_XFilterEvent returns True, then some input method has filtered the
+ event, and the client should discard the event. */
+ if ( ( e.type != Expose ) && X11_XFilterEvent( &e, None ) )
+ continue;
+
+ switch( e.type ) {
+ case Expose:
+ if ( e.xexpose.count > 0 ) {
+ draw = SDL_FALSE;
+ }
+ break;
+
+ case FocusIn:
+ /* Got focus. */
+ has_focus = SDL_TRUE;
+ break;
+
+ case FocusOut:
+ /* lost focus. Reset button and mouse info. */
+ has_focus = SDL_FALSE;
+ data->button_press_index = -1;
+ data->mouse_over_index = -1;
+ break;
+
+ case MotionNotify:
+ if ( has_focus ) {
+ /* Mouse moved... */
+ const int previndex = data->mouse_over_index;
+ data->mouse_over_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
+ if (data->mouse_over_index == previndex) {
+ draw = SDL_FALSE;
+ }
+ }
+ break;
+
+ case ClientMessage:
+ if ( e.xclient.message_type == data->wm_protocols &&
+ e.xclient.format == 32 &&
+ e.xclient.data.l[ 0 ] == data->wm_delete_message ) {
+ close_dialog = SDL_TRUE;
+ }
+ break;
+
+ case KeyPress:
+ /* Store key press - we make sure in key release that we got both. */
+ last_key_pressed = X11_XLookupKeysym( &e.xkey, 0 );
+ break;
+
+ case KeyRelease: {
+ Uint32 mask = 0;
+ KeySym key = X11_XLookupKeysym( &e.xkey, 0 );
+
+ /* If this is a key release for something we didn't get the key down for, then bail. */
+ if ( key != last_key_pressed )
+ break;
+
+ if ( key == XK_Escape )
+ mask = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ else if ( ( key == XK_Return ) || ( key == XK_KP_Enter ) )
+ mask = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
+
+ if ( mask ) {
+ int i;
+
+ /* Look for first button with this mask set, and return it if found. */
+ for ( i = 0; i < data->numbuttons; i++ ) {
+ SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
+
+ if ( buttondatax11->buttondata->flags & mask ) {
+ *data->pbuttonid = buttondatax11->buttondata->buttonid;
+ close_dialog = SDL_TRUE;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case ButtonPress:
+ data->button_press_index = -1;
+ if ( e.xbutton.button == Button1 ) {
+ /* Find index of button they clicked on. */
+ data->button_press_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
+ }
+ break;
+
+ case ButtonRelease:
+ /* If button is released over the same button that was clicked down on, then return it. */
+ if ( ( e.xbutton.button == Button1 ) && ( data->button_press_index >= 0 ) ) {
+ int button = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
+
+ if ( data->button_press_index == button ) {
+ SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ button ];
+
+ *data->pbuttonid = buttondatax11->buttondata->buttonid;
+ close_dialog = SDL_TRUE;
+ }
+ }
+ data->button_press_index = -1;
+ break;
+ }
+
+ if ( draw ) {
+ /* Draw our dialog box. */
+ X11_MessageBoxDraw( data, ctx );
+ }
+ }
+
+ X11_XFreeGC( data->display, ctx );
+ return 0;
+}
+
+static int
+X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ int ret;
+ SDL_MessageBoxDataX11 data;
+#if SDL_SET_LOCALE
+ char *origlocale;
+#endif
+
+ SDL_zero(data);
+
+ if ( !SDL_X11_LoadSymbols() )
+ return -1;
+
+#if SDL_SET_LOCALE
+ origlocale = setlocale(LC_ALL, NULL);
+ if (origlocale != NULL) {
+ origlocale = SDL_strdup(origlocale);
+ if (origlocale == NULL) {
+ return SDL_OutOfMemory();
+ }
+ setlocale(LC_ALL, "");
+ }
+#endif
+
+ /* This code could get called from multiple threads maybe? */
+ X11_XInitThreads();
+
+ /* Initialize the return buttonid value to -1 (for error or dialogbox closed). */
+ *buttonid = -1;
+
+ /* Init and display the message box. */
+ ret = X11_MessageBoxInit( &data, messageboxdata, buttonid );
+ if ( ret != -1 ) {
+ ret = X11_MessageBoxInitPositions( &data );
+ if ( ret != -1 ) {
+ ret = X11_MessageBoxCreateWindow( &data );
+ if ( ret != -1 ) {
+ ret = X11_MessageBoxLoop( &data );
+ }
+ }
+ }
+
+ X11_MessageBoxShutdown( &data );
+
+#if SDL_SET_LOCALE
+ if (origlocale) {
+ setlocale(LC_ALL, origlocale);
+ SDL_free(origlocale);
+ }
+#endif
+
+ return ret;
+}
+
+/* Display an x11 message box. */
+int
+X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+#if SDL_FORK_MESSAGEBOX
+ /* Use a child process to protect against setlocale(). Annoying. */
+ pid_t pid;
+ int fds[2];
+ int status = 0;
+
+ if (pipe(fds) == -1) {
+ return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
+ }
+
+ pid = fork();
+ if (pid == -1) { /* failed */
+ close(fds[0]);
+ close(fds[1]);
+ return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
+ } else if (pid == 0) { /* we're the child */
+ int exitcode = 0;
+ close(fds[0]);
+ status = X11_ShowMessageBoxImpl(messageboxdata, buttonid);
+ if (write(fds[1], &status, sizeof (int)) != sizeof (int))
+ exitcode = 1;
+ else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int))
+ exitcode = 1;
+ close(fds[1]);
+ _exit(exitcode); /* don't run atexit() stuff, static destructors, etc. */
+ } else { /* we're the parent */
+ pid_t rc;
+ close(fds[1]);
+ do {
+ rc = waitpid(pid, &status, 0);
+ } while ((rc == -1) && (errno == EINTR));
+
+ SDL_assert(rc == pid); /* not sure what to do if this fails. */
+
+ if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
+ return SDL_SetError("msgbox child process failed");
+ }
+
+ if (read(fds[0], &status, sizeof (int)) != sizeof (int))
+ status = -1;
+ else if (read(fds[0], buttonid, sizeof (int)) != sizeof (int))
+ status = -1;
+ close(fds[0]);
+
+ return status;
+ }
+#else
+ return X11_ShowMessageBoxImpl(messageboxdata, buttonid);
+#endif
+}
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.h
new file mode 100644
index 0000000..6515983
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11messagebox.h
@@ -0,0 +1,33 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_x11messagebox_h_
+#define SDL_x11messagebox_h_
+
+#if SDL_VIDEO_DRIVER_X11
+
+extern int X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+#endif /* SDL_x11messagebox_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11modes.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11modes.c
new file mode 100644
index 0000000..5eafe73
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11modes.c
@@ -0,0 +1,1112 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_hints.h"
+#include "SDL_x11video.h"
+#include "SDL_timer.h"
+#include "edid.h"
+
+/* #define X11MODES_DEBUG */
+
+/* I'm becoming more and more convinced that the application should never
+ * use XRandR, and it's the window manager's responsibility to track and
+ * manage display modes for fullscreen windows. Right now XRandR is completely
+ * broken with respect to window manager behavior on every window manager that
+ * I can find. For example, on Unity 3D if you show a fullscreen window while
+ * the resolution is changing (within ~250 ms) your window will retain the
+ * fullscreen state hint but be decorated and windowed.
+ *
+ * However, many people swear by it, so let them swear at it. :)
+*/
+/* #define XRANDR_DISABLED_BY_DEFAULT */
+
+
+static int
+get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
+{
+ const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
+ int depth;
+
+ /* Look for an exact visual, if requested */
+ if (visual_id) {
+ XVisualInfo *vi, template;
+ int nvis;
+
+ SDL_zero(template);
+ template.visualid = SDL_strtol(visual_id, NULL, 0);
+ vi = X11_XGetVisualInfo(display, VisualIDMask, &template, &nvis);
+ if (vi) {
+ *vinfo = *vi;
+ X11_XFree(vi);
+ return 0;
+ }
+ }
+
+ depth = DefaultDepth(display, screen);
+ if ((X11_UseDirectColorVisuals() &&
+ X11_XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
+ X11_XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
+ X11_XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
+ X11_XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
+ return 0;
+ }
+ return -1;
+}
+
+int
+X11_GetVisualInfoFromVisual(Display * display, Visual * visual, XVisualInfo * vinfo)
+{
+ XVisualInfo *vi;
+ int nvis;
+
+ vinfo->visualid = X11_XVisualIDFromVisual(visual);
+ vi = X11_XGetVisualInfo(display, VisualIDMask, vinfo, &nvis);
+ if (vi) {
+ *vinfo = *vi;
+ X11_XFree(vi);
+ return 0;
+ }
+ return -1;
+}
+
+Uint32
+X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
+{
+ if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
+ int bpp;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
+ Rmask = vinfo->visual->red_mask;
+ Gmask = vinfo->visual->green_mask;
+ Bmask = vinfo->visual->blue_mask;
+ if (vinfo->depth == 32) {
+ Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
+ } else {
+ Amask = 0;
+ }
+
+ bpp = vinfo->depth;
+ if (bpp == 24) {
+ int i, n;
+ XPixmapFormatValues *p = X11_XListPixmapFormats(display, &n);
+ if (p) {
+ for (i = 0; i < n; ++i) {
+ if (p[i].depth == 24) {
+ bpp = p[i].bits_per_pixel;
+ break;
+ }
+ }
+ X11_XFree(p);
+ }
+ }
+
+ return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
+ }
+
+ if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
+ switch (vinfo->depth) {
+ case 8:
+ return SDL_PIXELTYPE_INDEX8;
+ case 4:
+ if (BitmapBitOrder(display) == LSBFirst) {
+ return SDL_PIXELFORMAT_INDEX4LSB;
+ } else {
+ return SDL_PIXELFORMAT_INDEX4MSB;
+ }
+ /* break; -Wunreachable-code-break */
+ case 1:
+ if (BitmapBitOrder(display) == LSBFirst) {
+ return SDL_PIXELFORMAT_INDEX1LSB;
+ } else {
+ return SDL_PIXELFORMAT_INDEX1MSB;
+ }
+ /* break; -Wunreachable-code-break */
+ }
+ }
+
+ return SDL_PIXELFORMAT_UNKNOWN;
+}
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+static SDL_bool
+CheckXinerama(Display * display, int *major, int *minor)
+{
+ int event_base = 0;
+ int error_base = 0;
+
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+ if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XINERAMA, SDL_TRUE)) {
+#ifdef X11MODES_DEBUG
+ printf("Xinerama disabled due to hint\n");
+#endif
+ return SDL_FALSE;
+ }
+
+ if (!SDL_X11_HAVE_XINERAMA) {
+#ifdef X11MODES_DEBUG
+ printf("Xinerama support not available\n");
+#endif
+ return SDL_FALSE;
+ }
+
+ /* Query the extension version */
+ if (!X11_XineramaQueryExtension(display, &event_base, &error_base) ||
+ !X11_XineramaQueryVersion(display, major, minor) ||
+ !X11_XineramaIsActive(display)) {
+#ifdef X11MODES_DEBUG
+ printf("Xinerama not active on the display\n");
+#endif
+ return SDL_FALSE;
+ }
+#ifdef X11MODES_DEBUG
+ printf("Xinerama available at version %d.%d!\n", *major, *minor);
+#endif
+ return SDL_TRUE;
+}
+
+/* !!! FIXME: remove this later. */
+/* we have a weird bug where XineramaQueryScreens() throws an X error, so this
+ is here to help track it down (and not crash, too!). */
+static SDL_bool xinerama_triggered_error = SDL_FALSE;
+static int
+X11_XineramaFailed(Display * d, XErrorEvent * e)
+{
+ xinerama_triggered_error = SDL_TRUE;
+ fprintf(stderr, "XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n",
+ e->type, e->serial, (unsigned int) e->error_code,
+ (unsigned int) e->request_code, (unsigned int) e->minor_code);
+ fflush(stderr);
+ return 0;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+static SDL_bool
+CheckXRandR(Display * display, int *major, int *minor)
+{
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+#ifdef XRANDR_DISABLED_BY_DEFAULT
+ if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_FALSE)) {
+#ifdef X11MODES_DEBUG
+ printf("XRandR disabled by default due to window manager issues\n");
+#endif
+ return SDL_FALSE;
+ }
+#else
+ if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_TRUE)) {
+#ifdef X11MODES_DEBUG
+ printf("XRandR disabled due to hint\n");
+#endif
+ return SDL_FALSE;
+ }
+#endif /* XRANDR_ENABLED_BY_DEFAULT */
+
+ if (!SDL_X11_HAVE_XRANDR) {
+#ifdef X11MODES_DEBUG
+ printf("XRandR support not available\n");
+#endif
+ return SDL_FALSE;
+ }
+
+ /* Query the extension version */
+ *major = 1; *minor = 3; /* we want 1.3 */
+ if (!X11_XRRQueryVersion(display, major, minor)) {
+#ifdef X11MODES_DEBUG
+ printf("XRandR not active on the display\n");
+#endif
+ *major = *minor = 0;
+ return SDL_FALSE;
+ }
+#ifdef X11MODES_DEBUG
+ printf("XRandR available at version %d.%d!\n", *major, *minor);
+#endif
+ return SDL_TRUE;
+}
+
+#define XRANDR_ROTATION_LEFT (1 << 1)
+#define XRANDR_ROTATION_RIGHT (1 << 3)
+
+static int
+CalculateXRandRRefreshRate(const XRRModeInfo *info)
+{
+ return (info->hTotal && info->vTotal) ?
+ round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0;
+}
+
+static SDL_bool
+SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRCrtc crtc,
+ RRMode modeID, SDL_DisplayMode *mode)
+{
+ int i;
+ for (i = 0; i < res->nmode; ++i) {
+ const XRRModeInfo *info = &res->modes[i];
+ if (info->id == modeID) {
+ XRRCrtcInfo *crtcinfo;
+ Rotation rotation = 0;
+
+ crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc);
+ if (crtcinfo) {
+ rotation = crtcinfo->rotation;
+ X11_XRRFreeCrtcInfo(crtcinfo);
+ }
+
+ if (rotation & (XRANDR_ROTATION_LEFT|XRANDR_ROTATION_RIGHT)) {
+ mode->w = info->height;
+ mode->h = info->width;
+ } else {
+ mode->w = info->width;
+ mode->h = info->height;
+ }
+ mode->refresh_rate = CalculateXRandRRefreshRate(info);
+ ((SDL_DisplayModeData*)mode->driverdata)->xrandr_mode = modeID;
+#ifdef X11MODES_DEBUG
+ printf("XRandR mode %d: %dx%d@%dHz\n", (int) modeID, mode->w, mode->h, mode->refresh_rate);
+#endif
+ return SDL_TRUE;
+ }
+ }
+ return SDL_FALSE;
+}
+
+static void
+SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, RROutput output, const unsigned long widthmm, const unsigned long heightmm)
+{
+ /* See if we can get the EDID data for the real monitor name */
+ int inches;
+ int nprop;
+ Atom *props = X11_XRRListOutputProperties(dpy, output, &nprop);
+ int i;
+
+ for (i = 0; i < nprop; ++i) {
+ unsigned char *prop;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ Atom actual_type;
+
+ if (props[i] == EDID) {
+ if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False,
+ False, AnyPropertyType, &actual_type,
+ &actual_format, &nitems, &bytes_after,
+ &prop) == Success) {
+ MonitorInfo *info = decode_edid(prop);
+ if (info) {
+#ifdef X11MODES_DEBUG
+ printf("Found EDID data for %s\n", name);
+ dump_monitor_info(info);
+#endif
+ SDL_strlcpy(name, info->dsc_product_name, namelen);
+ free(info);
+ }
+ X11_XFree(prop);
+ }
+ break;
+ }
+ }
+
+ if (props) {
+ X11_XFree(props);
+ }
+
+ inches = (int)((SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f);
+ if (*name && inches) {
+ const size_t len = SDL_strlen(name);
+ SDL_snprintf(&name[len], namelen-len, " %d\"", inches);
+ }
+
+#ifdef X11MODES_DEBUG
+ printf("Display name: %s\n", name);
+#endif
+}
+
+
+static int
+X11_InitModes_XRandR(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ Display *dpy = data->display;
+ const int screencount = ScreenCount(dpy);
+ const int default_screen = DefaultScreen(dpy);
+ RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen));
+ Atom EDID = X11_XInternAtom(dpy, "EDID", False);
+ XRRScreenResources *res = NULL;
+ Uint32 pixelformat;
+ XVisualInfo vinfo;
+ XPixmapFormatValues *pixmapformats;
+ int looking_for_primary;
+ int scanline_pad;
+ int output;
+ int screen, i, n;
+
+ for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) {
+ for (screen = 0; screen < screencount; screen++) {
+
+ /* we want the primary output first, and then skipped later. */
+ if (looking_for_primary && (screen != default_screen)) {
+ continue;
+ }
+
+ if (get_visualinfo(dpy, screen, &vinfo) < 0) {
+ continue; /* uh, skip this screen? */
+ }
+
+ pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo);
+ if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) {
+ continue; /* Palettized video modes are no longer supported */
+ }
+
+ scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8;
+ pixmapformats = X11_XListPixmapFormats(dpy, &n);
+ if (pixmapformats) {
+ for (i = 0; i < n; ++i) {
+ if (pixmapformats[i].depth == vinfo.depth) {
+ scanline_pad = pixmapformats[i].scanline_pad;
+ break;
+ }
+ }
+ X11_XFree(pixmapformats);
+ }
+
+ res = X11_XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen));
+ if (!res || res->noutput == 0) {
+ if (res) {
+ X11_XRRFreeScreenResources(res);
+ }
+
+ res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen));
+ if (!res) {
+ continue;
+ }
+ }
+
+ for (output = 0; output < res->noutput; output++) {
+ XRROutputInfo *output_info;
+ int display_x, display_y;
+ unsigned long display_mm_width, display_mm_height;
+ SDL_DisplayData *displaydata;
+ char display_name[128];
+ SDL_DisplayMode mode;
+ SDL_DisplayModeData *modedata;
+ SDL_VideoDisplay display;
+ RRMode modeID;
+ RRCrtc output_crtc;
+ XRRCrtcInfo *crtc;
+
+ /* The primary output _should_ always be sorted first, but just in case... */
+ if ((looking_for_primary && (res->outputs[output] != primary)) ||
+ (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) {
+ continue;
+ }
+
+ output_info = X11_XRRGetOutputInfo(dpy, res, res->outputs[output]);
+ if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) {
+ X11_XRRFreeOutputInfo(output_info);
+ continue;
+ }
+
+ SDL_strlcpy(display_name, output_info->name, sizeof(display_name));
+ display_mm_width = output_info->mm_width;
+ display_mm_height = output_info->mm_height;
+ output_crtc = output_info->crtc;
+ X11_XRRFreeOutputInfo(output_info);
+
+ crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc);
+ if (!crtc) {
+ continue;
+ }
+
+ SDL_zero(mode);
+ modeID = crtc->mode;
+ mode.w = crtc->width;
+ mode.h = crtc->height;
+ mode.format = pixelformat;
+
+ display_x = crtc->x;
+ display_y = crtc->y;
+
+ X11_XRRFreeCrtcInfo(crtc);
+
+ displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
+ if (!displaydata) {
+ return SDL_OutOfMemory();
+ }
+
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (!modedata) {
+ SDL_free(displaydata);
+ return SDL_OutOfMemory();
+ }
+ modedata->xrandr_mode = modeID;
+ mode.driverdata = modedata;
+
+ displaydata->screen = screen;
+ displaydata->visual = vinfo.visual;
+ displaydata->depth = vinfo.depth;
+ displaydata->hdpi = display_mm_width ? (((float) mode.w) * 25.4f / display_mm_width) : 0.0f;
+ displaydata->vdpi = display_mm_height ? (((float) mode.h) * 25.4f / display_mm_height) : 0.0f;
+ displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f);
+ displaydata->scanline_pad = scanline_pad;
+ displaydata->x = display_x;
+ displaydata->y = display_y;
+ displaydata->use_xrandr = 1;
+ displaydata->xrandr_output = res->outputs[output];
+
+ SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
+ SetXRandRDisplayName(dpy, EDID, display_name, sizeof (display_name), res->outputs[output], display_mm_width, display_mm_height);
+
+ SDL_zero(display);
+ if (*display_name) {
+ display.name = display_name;
+ }
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ display.driverdata = displaydata;
+ SDL_AddVideoDisplay(&display);
+ }
+
+ X11_XRRFreeScreenResources(res);
+ }
+ }
+
+ if (_this->num_displays == 0) {
+ return SDL_SetError("No available displays");
+ }
+
+ return 0;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+static SDL_bool
+CheckVidMode(Display * display, int *major, int *minor)
+{
+ int vm_event, vm_error = -1;
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+ if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XVIDMODE, SDL_TRUE)) {
+#ifdef X11MODES_DEBUG
+ printf("XVidMode disabled due to hint\n");
+#endif
+ return SDL_FALSE;
+ }
+
+ if (!SDL_X11_HAVE_XVIDMODE) {
+#ifdef X11MODES_DEBUG
+ printf("XVidMode support not available\n");
+#endif
+ return SDL_FALSE;
+ }
+
+ /* Query the extension version */
+ if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error)
+ || !X11_XF86VidModeQueryVersion(display, major, minor)) {
+#ifdef X11MODES_DEBUG
+ printf("XVidMode not active on the display\n");
+#endif
+ return SDL_FALSE;
+ }
+#ifdef X11MODES_DEBUG
+ printf("XVidMode available at version %d.%d!\n", *major, *minor);
+#endif
+ return SDL_TRUE;
+}
+
+static
+Bool XF86VidModeGetModeInfo(Display * dpy, int scr,
+ XF86VidModeModeInfo* info)
+{
+ Bool retval;
+ int dotclock;
+ XF86VidModeModeLine l;
+ SDL_zerop(info);
+ SDL_zero(l);
+ retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l);
+ info->dotclock = dotclock;
+ info->hdisplay = l.hdisplay;
+ info->hsyncstart = l.hsyncstart;
+ info->hsyncend = l.hsyncend;
+ info->htotal = l.htotal;
+ info->hskew = l.hskew;
+ info->vdisplay = l.vdisplay;
+ info->vsyncstart = l.vsyncstart;
+ info->vsyncend = l.vsyncend;
+ info->vtotal = l.vtotal;
+ info->flags = l.flags;
+ info->privsize = l.privsize;
+ info->private = l.private;
+ return retval;
+}
+
+static int
+CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info)
+{
+ return (info->htotal
+ && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
+ info->vtotal)) : 0;
+}
+
+static SDL_bool
+SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode)
+{
+ mode->w = info->hdisplay;
+ mode->h = info->vdisplay;
+ mode->refresh_rate = CalculateXVidModeRefreshRate(info);
+ ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info;
+ return SDL_TRUE;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
+
+int
+X11_InitModes(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ int snum, screen, screencount = 0;
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ int xinerama_major, xinerama_minor;
+ int use_xinerama = 0;
+ XineramaScreenInfo *xinerama = NULL;
+#endif
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ int xrandr_major, xrandr_minor;
+#endif
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ int vm_major, vm_minor;
+ int use_vidmode = 0;
+#endif
+
+/* XRandR is the One True Modern Way to do this on X11. If it's enabled and
+ available, don't even look at other ways of doing things. */
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ /* require at least XRandR v1.3 */
+ if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
+ (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
+ if (X11_InitModes_XRandR(_this) == 0)
+ return 0;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+/* !!! FIXME: eventually remove support for Xinerama and XVidMode (everything below here). */
+
+ /* This is a workaround for some apps (UnrealEngine4, for example) until
+ we sort out the ramifications of removing XVidMode support outright.
+ This block should be removed with the XVidMode support. */
+ {
+ if (SDL_GetHintBoolean("SDL_VIDEO_X11_REQUIRE_XRANDR", SDL_FALSE)) {
+ #if SDL_VIDEO_DRIVER_X11_XRANDR
+ return SDL_SetError("XRandR support is required but not available");
+ #else
+ return SDL_SetError("XRandR support is required but not built into SDL!");
+ #endif
+ }
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ /* Query Xinerama extention
+ * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012)
+ * or newer of the Nvidia binary drivers
+ */
+ if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) {
+ int (*handler) (Display *, XErrorEvent *);
+ X11_XSync(data->display, False);
+ handler = X11_XSetErrorHandler(X11_XineramaFailed);
+ xinerama = X11_XineramaQueryScreens(data->display, &screencount);
+ X11_XSync(data->display, False);
+ X11_XSetErrorHandler(handler);
+ if (xinerama_triggered_error) {
+ xinerama = 0;
+ }
+ if (xinerama) {
+ use_xinerama = xinerama_major * 100 + xinerama_minor;
+ }
+ }
+ if (!xinerama) {
+ screencount = ScreenCount(data->display);
+ }
+#else
+ screencount = ScreenCount(data->display);
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ if (CheckVidMode(data->display, &vm_major, &vm_minor)) {
+ use_vidmode = vm_major * 100 + vm_minor;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
+
+ for (snum = 0; snum < screencount; ++snum) {
+ XVisualInfo vinfo;
+ SDL_VideoDisplay display;
+ SDL_DisplayData *displaydata;
+ SDL_DisplayMode mode;
+ SDL_DisplayModeData *modedata;
+ XPixmapFormatValues *pixmapFormats;
+ char display_name[128];
+ int i, n;
+
+ /* Re-order screens to always put default screen first */
+ if (snum == 0) {
+ screen = DefaultScreen(data->display);
+ } else if (snum == DefaultScreen(data->display)) {
+ screen = 0;
+ } else {
+ screen = snum;
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if (xinerama) {
+ if (get_visualinfo(data->display, 0, &vinfo) < 0) {
+ continue;
+ }
+ } else {
+ if (get_visualinfo(data->display, screen, &vinfo) < 0) {
+ continue;
+ }
+ }
+#else
+ if (get_visualinfo(data->display, screen, &vinfo) < 0) {
+ continue;
+ }
+#endif
+
+ displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata));
+ if (!displaydata) {
+ continue;
+ }
+ display_name[0] = '\0';
+
+ mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
+ if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
+ /* We don't support palettized modes now */
+ SDL_free(displaydata);
+ continue;
+ }
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if (xinerama) {
+ mode.w = xinerama[screen].width;
+ mode.h = xinerama[screen].height;
+ } else {
+ mode.w = DisplayWidth(data->display, screen);
+ mode.h = DisplayHeight(data->display, screen);
+ }
+#else
+ mode.w = DisplayWidth(data->display, screen);
+ mode.h = DisplayHeight(data->display, screen);
+#endif
+ mode.refresh_rate = 0;
+
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (!modedata) {
+ SDL_free(displaydata);
+ continue;
+ }
+ mode.driverdata = modedata;
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active,
+ * there's only one screen available. So we force the screen number to zero and
+ * let Xinerama specific code handle specific functionality using displaydata->xinerama_info
+ */
+ if (use_xinerama) {
+ displaydata->screen = 0;
+ displaydata->use_xinerama = use_xinerama;
+ displaydata->xinerama_info = xinerama[screen];
+ displaydata->xinerama_screen = screen;
+ }
+ else displaydata->screen = screen;
+#else
+ displaydata->screen = screen;
+#endif
+ displaydata->visual = vinfo.visual;
+ displaydata->depth = vinfo.depth;
+
+ /* We use the displaydata screen index here so that this works
+ for both the Xinerama case, where we get the overall DPI,
+ and the regular X11 screen info case. */
+ displaydata->hdpi = (float)DisplayWidth(data->display, displaydata->screen) * 25.4f /
+ DisplayWidthMM(data->display, displaydata->screen);
+ displaydata->vdpi = (float)DisplayHeight(data->display, displaydata->screen) * 25.4f /
+ DisplayHeightMM(data->display, displaydata->screen);
+ displaydata->ddpi = SDL_ComputeDiagonalDPI(DisplayWidth(data->display, displaydata->screen),
+ DisplayHeight(data->display, displaydata->screen),
+ (float)DisplayWidthMM(data->display, displaydata->screen) / 25.4f,
+ (float)DisplayHeightMM(data->display, displaydata->screen) / 25.4f);
+
+ displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8;
+ pixmapFormats = X11_XListPixmapFormats(data->display, &n);
+ if (pixmapFormats) {
+ for (i = 0; i < n; ++i) {
+ if (pixmapFormats[i].depth == displaydata->depth) {
+ displaydata->scanline_pad = pixmapFormats[i].scanline_pad;
+ break;
+ }
+ }
+ X11_XFree(pixmapFormats);
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if (use_xinerama) {
+ displaydata->x = xinerama[screen].x_org;
+ displaydata->y = xinerama[screen].y_org;
+ }
+ else
+#endif
+ {
+ displaydata->x = 0;
+ displaydata->y = 0;
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ if (!displaydata->use_xrandr &&
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ /* XVidMode only works on the screen at the origin */
+ (!displaydata->use_xinerama ||
+ (displaydata->x == 0 && displaydata->y == 0)) &&
+#endif
+ use_vidmode) {
+ displaydata->use_vidmode = use_vidmode;
+ if (displaydata->use_xinerama) {
+ displaydata->vidmode_screen = 0;
+ } else {
+ displaydata->vidmode_screen = screen;
+ }
+ XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode);
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
+
+ SDL_zero(display);
+ if (*display_name) {
+ display.name = display_name;
+ }
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ display.driverdata = displaydata;
+ SDL_AddVideoDisplay(&display);
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if (xinerama) X11_XFree(xinerama);
+#endif
+
+ if (_this->num_displays == 0) {
+ return SDL_SetError("No available displays");
+ }
+ return 0;
+}
+
+void
+X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
+{
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ int nmodes;
+ XF86VidModeModeInfo ** modes;
+#endif
+ SDL_DisplayMode mode;
+
+ /* Unfortunately X11 requires the window to be created with the correct
+ * visual and depth ahead of time, but the SDL API allows you to create
+ * a window before setting the fullscreen display mode. This means that
+ * we have to use the same format for all windows and all display modes.
+ * (or support recreating the window with a new visual behind the scenes)
+ */
+ mode.format = sdl_display->current_mode.format;
+ mode.driverdata = NULL;
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if (data->use_xinerama) {
+ int screen_w;
+ int screen_h;
+
+ screen_w = DisplayWidth(display, data->screen);
+ screen_h = DisplayHeight(display, data->screen);
+
+ if (data->use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org &&
+ (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) {
+ SDL_DisplayModeData *modedata;
+ /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0
+ * if we're using vidmode.
+ */
+ mode.w = screen_w;
+ mode.h = screen_h;
+ mode.refresh_rate = 0;
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (modedata) {
+ *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
+ }
+ mode.driverdata = modedata;
+ if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+ SDL_free(modedata);
+ }
+ }
+ else if (!data->use_xrandr)
+ {
+ SDL_DisplayModeData *modedata;
+ /* Add the current mode of each monitor otherwise if we can't get them from xrandr */
+ mode.w = data->xinerama_info.width;
+ mode.h = data->xinerama_info.height;
+ mode.refresh_rate = 0;
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (modedata) {
+ *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
+ }
+ mode.driverdata = modedata;
+ if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+ SDL_free(modedata);
+ }
+ }
+
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ if (data->use_xrandr) {
+ XRRScreenResources *res;
+
+ res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen));
+ if (res) {
+ SDL_DisplayModeData *modedata;
+ XRROutputInfo *output_info;
+ int i;
+
+ output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
+ if (output_info && output_info->connection != RR_Disconnected) {
+ for (i = 0; i < output_info->nmode; ++i) {
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (!modedata) {
+ continue;
+ }
+ mode.driverdata = modedata;
+
+ if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) ||
+ !SDL_AddDisplayMode(sdl_display, &mode)) {
+ SDL_free(modedata);
+ }
+ }
+ }
+ X11_XRRFreeOutputInfo(output_info);
+ X11_XRRFreeScreenResources(res);
+ }
+ return;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ if (data->use_vidmode &&
+ X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) {
+ int i;
+ SDL_DisplayModeData *modedata;
+
+#ifdef X11MODES_DEBUG
+ printf("VidMode modes: (unsorted)\n");
+ for (i = 0; i < nmodes; ++i) {
+ printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i,
+ modes[i]->hdisplay, modes[i]->vdisplay,
+ CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags);
+ }
+#endif
+ for (i = 0; i < nmodes; ++i) {
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (!modedata) {
+ continue;
+ }
+ mode.driverdata = modedata;
+
+ if (!SetXVidModeModeInfo(modes[i], &mode) || !SDL_AddDisplayMode(sdl_display, &mode)) {
+ SDL_free(modedata);
+ }
+ }
+ X11_XFree(modes);
+ return;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
+
+ if (!data->use_xrandr && !data->use_vidmode) {
+ SDL_DisplayModeData *modedata;
+ /* Add the desktop mode */
+ mode = sdl_display->desktop_mode;
+ modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData));
+ if (modedata) {
+ *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata;
+ }
+ mode.driverdata = modedata;
+ if (!SDL_AddDisplayMode(sdl_display, &mode)) {
+ SDL_free(modedata);
+ }
+ }
+}
+
+int
+X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
+{
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+ Display *display = viddata->display;
+ SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
+ SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
+
+ viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ if (data->use_xrandr) {
+ XRRScreenResources *res;
+ XRROutputInfo *output_info;
+ XRRCrtcInfo *crtc;
+ Status status;
+
+ res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen));
+ if (!res) {
+ return SDL_SetError("Couldn't get XRandR screen resources");
+ }
+
+ output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output);
+ if (!output_info || output_info->connection == RR_Disconnected) {
+ X11_XRRFreeScreenResources(res);
+ return SDL_SetError("Couldn't get XRandR output info");
+ }
+
+ crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc);
+ if (!crtc) {
+ X11_XRRFreeOutputInfo(output_info);
+ X11_XRRFreeScreenResources(res);
+ return SDL_SetError("Couldn't get XRandR crtc info");
+ }
+
+ status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
+ crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
+ &data->xrandr_output, 1);
+
+ X11_XRRFreeCrtcInfo(crtc);
+ X11_XRRFreeOutputInfo(output_info);
+ X11_XRRFreeScreenResources(res);
+
+ if (status != Success) {
+ return SDL_SetError("X11_XRRSetCrtcConfig failed");
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ if (data->use_vidmode) {
+ X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode);
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */
+
+ return 0;
+}
+
+void
+X11_QuitModes(_THIS)
+{
+}
+
+int
+X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
+{
+ SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
+
+ rect->x = data->x;
+ rect->y = data->y;
+ rect->w = sdl_display->current_mode.w;
+ rect->h = sdl_display->current_mode.h;
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ /* Get the real current bounds of the display */
+ if (data->use_xinerama) {
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ int screencount;
+ XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount);
+ if (xinerama) {
+ rect->x = xinerama[data->xinerama_screen].x_org;
+ rect->y = xinerama[data->xinerama_screen].y_org;
+ X11_XFree(xinerama);
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+ return 0;
+}
+
+int
+X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi)
+{
+ SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
+
+ if (ddpi) {
+ *ddpi = data->ddpi;
+ }
+ if (hdpi) {
+ *hdpi = data->hdpi;
+ }
+ if (vdpi) {
+ *vdpi = data->vdpi;
+ }
+
+ return data->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
+}
+
+int
+X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ Display *display = data->display;
+ Atom _NET_WORKAREA;
+ int status, real_format;
+ int retval = -1;
+ Atom real_type;
+ unsigned long items_read = 0, items_left = 0;
+ unsigned char *propdata = NULL;
+
+ if (X11_GetDisplayBounds(_this, sdl_display, rect) < 0) {
+ return -1;
+ }
+
+ _NET_WORKAREA = X11_XInternAtom(display, "_NET_WORKAREA", False);
+ status = X11_XGetWindowProperty(display, DefaultRootWindow(display),
+ _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL,
+ &real_type, &real_format, &items_read,
+ &items_left, &propdata);
+ if ((status == Success) && (items_read >= 4)) {
+ const long *p = (long*) propdata;
+ const SDL_Rect usable = { (int)p[0], (int)p[1], (int)p[2], (int)p[3] };
+ retval = 0;
+ if (!SDL_IntersectRect(rect, &usable, rect)) {
+ SDL_zerop(rect);
+ }
+ }
+
+ if (propdata) {
+ X11_XFree(propdata);
+ }
+
+ return retval;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11modes.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11modes.h
new file mode 100644
index 0000000..7d3ff3e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11modes.h
@@ -0,0 +1,85 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11modes_h_
+#define SDL_x11modes_h_
+
+typedef struct
+{
+ int screen;
+ Visual *visual;
+ int depth;
+ int scanline_pad;
+ int x;
+ int y;
+ float ddpi;
+ float hdpi;
+ float vdpi;
+
+ int use_xinerama;
+ int use_xrandr;
+ int use_vidmode;
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ XineramaScreenInfo xinerama_info;
+ int xinerama_screen;
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ RROutput xrandr_output;
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ int vidmode_screen;
+#endif
+
+} SDL_DisplayData;
+
+typedef struct
+{
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ RRMode xrandr_mode;
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ XF86VidModeModeInfo vm_mode;
+#endif
+
+} SDL_DisplayModeData;
+
+extern int X11_InitModes(_THIS);
+extern void X11_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int X11_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void X11_QuitModes(_THIS);
+
+/* Some utility functions for working with visuals */
+extern int X11_GetVisualInfoFromVisual(Display * display, Visual * visual,
+ XVisualInfo * vinfo);
+extern Uint32 X11_GetPixelFormatFromVisualInfo(Display * display,
+ XVisualInfo * vinfo);
+extern int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect);
+extern int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect);
+extern int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi);
+
+#endif /* SDL_x11modes_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.c
new file mode 100644
index 0000000..3b98726
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.c
@@ -0,0 +1,448 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include <X11/cursorfont.h>
+#include "SDL_assert.h"
+#include "SDL_x11video.h"
+#include "SDL_x11mouse.h"
+#include "SDL_x11xinput2.h"
+#include "../../events/SDL_mouse_c.h"
+
+
+/* FIXME: Find a better place to put this... */
+static Cursor x11_empty_cursor = None;
+
+static Display *
+GetDisplay(void)
+{
+ return ((SDL_VideoData *)SDL_GetVideoDevice()->driverdata)->display;
+}
+
+static Cursor
+X11_CreateEmptyCursor()
+{
+ if (x11_empty_cursor == None) {
+ Display *display = GetDisplay();
+ char data[1];
+ XColor color;
+ Pixmap pixmap;
+
+ SDL_zero(data);
+ color.red = color.green = color.blue = 0;
+ pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
+ data, 1, 1);
+ if (pixmap) {
+ x11_empty_cursor = X11_XCreatePixmapCursor(display, pixmap, pixmap,
+ &color, &color, 0, 0);
+ X11_XFreePixmap(display, pixmap);
+ }
+ }
+ return x11_empty_cursor;
+}
+
+static void
+X11_DestroyEmptyCursor(void)
+{
+ if (x11_empty_cursor != None) {
+ X11_XFreeCursor(GetDisplay(), x11_empty_cursor);
+ x11_empty_cursor = None;
+ }
+}
+
+static SDL_Cursor *
+X11_CreateDefaultCursor()
+{
+ SDL_Cursor *cursor;
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ /* None is used to indicate the default cursor */
+ cursor->driverdata = (void*)None;
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+#if SDL_VIDEO_DRIVER_X11_XCURSOR
+static Cursor
+X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ Display *display = GetDisplay();
+ Cursor cursor = None;
+ XcursorImage *image;
+
+ image = X11_XcursorImageCreate(surface->w, surface->h);
+ if (!image) {
+ SDL_OutOfMemory();
+ return None;
+ }
+ image->xhot = hot_x;
+ image->yhot = hot_y;
+ image->delay = 0;
+
+ SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
+ SDL_assert(surface->pitch == surface->w * 4);
+ SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch);
+
+ cursor = X11_XcursorImageLoadCursor(display, image);
+
+ X11_XcursorImageDestroy(image);
+
+ return cursor;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XCURSOR */
+
+static Cursor
+X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ Display *display = GetDisplay();
+ XColor fg, bg;
+ Cursor cursor = None;
+ Uint32 *ptr;
+ Uint8 *data_bits, *mask_bits;
+ Pixmap data_pixmap, mask_pixmap;
+ int x, y;
+ unsigned int rfg, gfg, bfg, rbg, gbg, bbg, fgBits, bgBits;
+ unsigned int width_bytes = ((surface->w + 7) & ~7) / 8;
+
+ data_bits = SDL_calloc(1, surface->h * width_bytes);
+ if (!data_bits) {
+ SDL_OutOfMemory();
+ return None;
+ }
+
+ mask_bits = SDL_calloc(1, surface->h * width_bytes);
+ if (!mask_bits) {
+ SDL_free(data_bits);
+ SDL_OutOfMemory();
+ return None;
+ }
+
+ /* Code below assumes ARGB pixel format */
+ SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
+
+ rfg = gfg = bfg = rbg = gbg = bbg = fgBits = bgBits = 0;
+ for (y = 0; y < surface->h; ++y) {
+ ptr = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch);
+ for (x = 0; x < surface->w; ++x) {
+ int alpha = (*ptr >> 24) & 0xff;
+ int red = (*ptr >> 16) & 0xff;
+ int green = (*ptr >> 8) & 0xff;
+ int blue = (*ptr >> 0) & 0xff;
+ if (alpha > 25) {
+ mask_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
+
+ if ((red + green + blue) > 0x40) {
+ fgBits++;
+ rfg += red;
+ gfg += green;
+ bfg += blue;
+ data_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8));
+ } else {
+ bgBits++;
+ rbg += red;
+ gbg += green;
+ bbg += blue;
+ }
+ }
+ ++ptr;
+ }
+ }
+
+ if (fgBits) {
+ fg.red = rfg * 257 / fgBits;
+ fg.green = gfg * 257 / fgBits;
+ fg.blue = bfg * 257 / fgBits;
+ }
+ else fg.red = fg.green = fg.blue = 0;
+
+ if (bgBits) {
+ bg.red = rbg * 257 / bgBits;
+ bg.green = gbg * 257 / bgBits;
+ bg.blue = bbg * 257 / bgBits;
+ }
+ else bg.red = bg.green = bg.blue = 0;
+
+ data_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
+ (char*)data_bits,
+ surface->w, surface->h);
+ mask_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display),
+ (char*)mask_bits,
+ surface->w, surface->h);
+ cursor = X11_XCreatePixmapCursor(display, data_pixmap, mask_pixmap,
+ &fg, &bg, hot_x, hot_y);
+ X11_XFreePixmap(display, data_pixmap);
+ X11_XFreePixmap(display, mask_pixmap);
+
+ return cursor;
+}
+
+static SDL_Cursor *
+X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ SDL_Cursor *cursor;
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ Cursor x11_cursor = None;
+
+#if SDL_VIDEO_DRIVER_X11_XCURSOR
+ if (SDL_X11_HAVE_XCURSOR) {
+ x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y);
+ }
+#endif
+ if (x11_cursor == None) {
+ x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y);
+ }
+ cursor->driverdata = (void*)x11_cursor;
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static SDL_Cursor *
+X11_CreateSystemCursor(SDL_SystemCursor id)
+{
+ SDL_Cursor *cursor;
+ unsigned int shape;
+
+ switch(id)
+ {
+ default:
+ SDL_assert(0);
+ return NULL;
+ /* X Font Cursors reference: */
+ /* http://tronche.com/gui/x/xlib/appendix/b/ */
+ case SDL_SYSTEM_CURSOR_ARROW: shape = XC_left_ptr; break;
+ case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; break;
+ case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break;
+ case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break;
+ case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break;
+ case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break;
+ case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break;
+ case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break;
+ case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break;
+ case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break;
+ case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; break;
+ case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; break;
+ }
+
+ cursor = SDL_calloc(1, sizeof(*cursor));
+ if (cursor) {
+ Cursor x11_cursor;
+
+ x11_cursor = X11_XCreateFontCursor(GetDisplay(), shape);
+
+ cursor->driverdata = (void*)x11_cursor;
+ } else {
+ SDL_OutOfMemory();
+ }
+
+ return cursor;
+}
+
+static void
+X11_FreeCursor(SDL_Cursor * cursor)
+{
+ Cursor x11_cursor = (Cursor)cursor->driverdata;
+
+ if (x11_cursor != None) {
+ X11_XFreeCursor(GetDisplay(), x11_cursor);
+ }
+ SDL_free(cursor);
+}
+
+static int
+X11_ShowCursor(SDL_Cursor * cursor)
+{
+ Cursor x11_cursor = 0;
+
+ if (cursor) {
+ x11_cursor = (Cursor)cursor->driverdata;
+ } else {
+ x11_cursor = X11_CreateEmptyCursor();
+ }
+
+ /* FIXME: Is there a better way than this? */
+ {
+ SDL_VideoDevice *video = SDL_GetVideoDevice();
+ Display *display = GetDisplay();
+ SDL_Window *window;
+ SDL_WindowData *data;
+
+ for (window = video->windows; window; window = window->next) {
+ data = (SDL_WindowData *)window->driverdata;
+ if (x11_cursor != None) {
+ X11_XDefineCursor(display, data->xwindow, x11_cursor);
+ } else {
+ X11_XUndefineCursor(display, data->xwindow);
+ }
+ }
+ X11_XFlush(display);
+ }
+ return 0;
+}
+
+static void
+WarpMouseInternal(Window xwindow, const int x, const int y)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
+ Display *display = videodata->display;
+ X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, x, y);
+ X11_XSync(display, False);
+ videodata->global_mouse_changed = SDL_TRUE;
+}
+
+static void
+X11_WarpMouse(SDL_Window * window, int x, int y)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ WarpMouseInternal(data->xwindow, x, y);
+}
+
+static int
+X11_WarpMouseGlobal(int x, int y)
+{
+ WarpMouseInternal(DefaultRootWindow(GetDisplay()), x, y);
+ return 0;
+}
+
+static int
+X11_SetRelativeMouseMode(SDL_bool enabled)
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+ if(X11_Xinput2IsInitialized())
+ return 0;
+#else
+ SDL_Unsupported();
+#endif
+ return -1;
+}
+
+static int
+X11_CaptureMouse(SDL_Window *window)
+{
+ Display *display = GetDisplay();
+
+ if (window) {
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
+ const int rc = X11_XGrabPointer(display, data->xwindow, False,
+ mask, GrabModeAsync, GrabModeAsync,
+ None, None, CurrentTime);
+ if (rc != GrabSuccess) {
+ return SDL_SetError("X server refused mouse capture");
+ }
+ } else {
+ X11_XUngrabPointer(display, CurrentTime);
+ }
+
+ X11_XSync(display, False);
+
+ return 0;
+}
+
+static Uint32
+X11_GetGlobalMouseState(int *x, int *y)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata;
+ Display *display = GetDisplay();
+ const int num_screens = SDL_GetNumVideoDisplays();
+ int i;
+
+ /* !!! FIXME: should we XSync() here first? */
+
+#if !SDL_VIDEO_DRIVER_X11_XINPUT2
+ videodata->global_mouse_changed = SDL_TRUE;
+#endif
+
+ /* check if we have this cached since XInput last saw the mouse move. */
+ /* !!! FIXME: can we just calculate this from XInput's events? */
+ if (videodata->global_mouse_changed) {
+ for (i = 0; i < num_screens; i++) {
+ SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i);
+ if (data != NULL) {
+ Window root, child;
+ int rootx, rooty, winx, winy;
+ unsigned int mask;
+ if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) {
+ XWindowAttributes root_attrs;
+ Uint32 buttons = 0;
+ buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0;
+ buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0;
+ buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0;
+ /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing
+ * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right).
+ *
+ * Adding root position to root-relative coordinates seems to be a better way to get absolute position. */
+ X11_XGetWindowAttributes(display, root, &root_attrs);
+ videodata->global_mouse_position.x = root_attrs.x + rootx;
+ videodata->global_mouse_position.y = root_attrs.y + rooty;
+ videodata->global_mouse_buttons = buttons;
+ videodata->global_mouse_changed = SDL_FALSE;
+ break;
+ }
+ }
+ }
+ }
+
+ SDL_assert(!videodata->global_mouse_changed); /* The pointer wasn't on any X11 screen?! */
+
+ *x = videodata->global_mouse_position.x;
+ *y = videodata->global_mouse_position.y;
+ return videodata->global_mouse_buttons;
+}
+
+
+void
+X11_InitMouse(_THIS)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = X11_CreateCursor;
+ mouse->CreateSystemCursor = X11_CreateSystemCursor;
+ mouse->ShowCursor = X11_ShowCursor;
+ mouse->FreeCursor = X11_FreeCursor;
+ mouse->WarpMouse = X11_WarpMouse;
+ mouse->WarpMouseGlobal = X11_WarpMouseGlobal;
+ mouse->SetRelativeMouseMode = X11_SetRelativeMouseMode;
+ mouse->CaptureMouse = X11_CaptureMouse;
+ mouse->GetGlobalMouseState = X11_GetGlobalMouseState;
+
+ SDL_SetDefaultCursor(X11_CreateDefaultCursor());
+}
+
+void
+X11_QuitMouse(_THIS)
+{
+ X11_DestroyEmptyCursor();
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.h
new file mode 100644
index 0000000..1041858
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11mouse.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11mouse_h_
+#define SDL_x11mouse_h_
+
+extern void X11_InitMouse(_THIS);
+extern void X11_QuitMouse(_THIS);
+
+#endif /* SDL_x11mouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.c
new file mode 100644
index 0000000..7c3cb33
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.c
@@ -0,0 +1,946 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+
+/* GLX implementation of SDL OpenGL support */
+
+#if SDL_VIDEO_OPENGL_GLX
+#include "SDL_loadso.h"
+#include "SDL_x11opengles.h"
+
+#if defined(__IRIX__)
+/* IRIX doesn't have a GL library versioning system */
+#define DEFAULT_OPENGL "libGL.so"
+#elif defined(__MACOSX__)
+#define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib"
+#elif defined(__QNXNTO__)
+#define DEFAULT_OPENGL "libGL.so.3"
+#else
+#define DEFAULT_OPENGL "libGL.so.1"
+#endif
+
+#ifndef GLX_NONE_EXT
+#define GLX_NONE_EXT 0x8000
+#endif
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+#endif
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+#define GLX_NONE_EXT 0x8000
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+#endif
+
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info
+#define GLX_X_VISUAL_TYPE_EXT 0x22
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#endif
+
+#ifndef GLX_ARB_create_context
+#define GLX_ARB_create_context
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+
+/* Typedef for the GL 3.0 context creation function */
+typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy,
+ GLXFBConfig config,
+ GLXContext
+ share_context,
+ Bool direct,
+ const int
+ *attrib_list);
+#endif
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#endif
+
+#ifndef GLX_ARB_create_context_robustness
+#define GLX_ARB_create_context_robustness
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#endif
+
+#ifndef GLX_EXT_create_context_es2_profile
+#define GLX_EXT_create_context_es2_profile
+#ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT
+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002
+#endif
+#endif
+
+#ifndef GLX_ARB_framebuffer_sRGB
+#define GLX_ARB_framebuffer_sRGB
+#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+#endif
+#endif
+
+#ifndef GLX_ARB_create_context_no_error
+#define GLX_ARB_create_context_no_error
+#ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB
+#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
+#endif
+#endif
+
+#ifndef GLX_EXT_swap_control
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+#endif
+
+#ifndef GLX_EXT_swap_control_tear
+#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
+#endif
+
+#ifndef GLX_ARB_context_flush_control
+#define GLX_ARB_context_flush_control
+#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
+#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#endif
+
+#define OPENGL_REQUIRES_DLOPEN
+#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
+#include <dlfcn.h>
+#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
+#define GL_LoadFunction dlsym
+#define GL_UnloadObject dlclose
+#else
+#define GL_LoadObject SDL_LoadObject
+#define GL_LoadFunction SDL_LoadFunction
+#define GL_UnloadObject SDL_UnloadObject
+#endif
+
+static void X11_GL_InitExtensions(_THIS);
+
+int
+X11_GL_LoadLibrary(_THIS, const char *path)
+{
+ Display *display;
+ void *handle;
+
+ if (_this->gl_data) {
+ return SDL_SetError("OpenGL context already created");
+ }
+
+ /* Load the OpenGL library */
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ }
+ if (path == NULL) {
+ path = DEFAULT_OPENGL;
+ }
+ _this->gl_config.dll_handle = GL_LoadObject(path);
+ if (!_this->gl_config.dll_handle) {
+#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
+ SDL_SetError("Failed loading %s: %s", path, dlerror());
+#endif
+ return -1;
+ }
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+
+ /* Allocate OpenGL memory */
+ _this->gl_data =
+ (struct SDL_GLDriverData *) SDL_calloc(1,
+ sizeof(struct
+ SDL_GLDriverData));
+ if (!_this->gl_data) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Load function pointers */
+ handle = _this->gl_config.dll_handle;
+ _this->gl_data->glXQueryExtension =
+ (Bool (*)(Display *, int *, int *))
+ GL_LoadFunction(handle, "glXQueryExtension");
+ _this->gl_data->glXGetProcAddress =
+ (void *(*)(const GLubyte *))
+ GL_LoadFunction(handle, "glXGetProcAddressARB");
+ _this->gl_data->glXChooseVisual =
+ (XVisualInfo * (*)(Display *, int, int *))
+ X11_GL_GetProcAddress(_this, "glXChooseVisual");
+ _this->gl_data->glXCreateContext =
+ (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int))
+ X11_GL_GetProcAddress(_this, "glXCreateContext");
+ _this->gl_data->glXDestroyContext =
+ (void (*)(Display *, GLXContext))
+ X11_GL_GetProcAddress(_this, "glXDestroyContext");
+ _this->gl_data->glXMakeCurrent =
+ (int (*)(Display *, GLXDrawable, GLXContext))
+ X11_GL_GetProcAddress(_this, "glXMakeCurrent");
+ _this->gl_data->glXSwapBuffers =
+ (void (*)(Display *, GLXDrawable))
+ X11_GL_GetProcAddress(_this, "glXSwapBuffers");
+ _this->gl_data->glXQueryDrawable =
+ (void (*)(Display*,GLXDrawable,int,unsigned int*))
+ X11_GL_GetProcAddress(_this, "glXQueryDrawable");
+
+ if (!_this->gl_data->glXQueryExtension ||
+ !_this->gl_data->glXChooseVisual ||
+ !_this->gl_data->glXCreateContext ||
+ !_this->gl_data->glXDestroyContext ||
+ !_this->gl_data->glXMakeCurrent ||
+ !_this->gl_data->glXSwapBuffers) {
+ return SDL_SetError("Could not retrieve OpenGL functions");
+ }
+
+ display = ((SDL_VideoData *) _this->driverdata)->display;
+ if (!_this->gl_data->glXQueryExtension(display, &_this->gl_data->errorBase, &_this->gl_data->eventBase)) {
+ return SDL_SetError("GLX is not supported");
+ }
+
+ /* Initialize extensions */
+ /* See lengthy comment about the inc/dec in
+ ../windows/SDL_windowsopengl.c. */
+ ++_this->gl_config.driver_loaded;
+ X11_GL_InitExtensions(_this);
+ --_this->gl_config.driver_loaded;
+
+ /* If we need a GL ES context and there's no
+ * GLX_EXT_create_context_es2_profile extension, switch over to X11_GLES functions
+ */
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES &&
+ X11_GL_UseEGL(_this) ) {
+#if SDL_VIDEO_OPENGL_EGL
+ X11_GL_UnloadLibrary(_this);
+ /* Better avoid conflicts! */
+ if (_this->gl_config.dll_handle != NULL ) {
+ GL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+ }
+ _this->GL_LoadLibrary = X11_GLES_LoadLibrary;
+ _this->GL_GetProcAddress = X11_GLES_GetProcAddress;
+ _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
+ _this->GL_CreateContext = X11_GLES_CreateContext;
+ _this->GL_MakeCurrent = X11_GLES_MakeCurrent;
+ _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval;
+ _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval;
+ _this->GL_SwapWindow = X11_GLES_SwapWindow;
+ _this->GL_DeleteContext = X11_GLES_DeleteContext;
+ return X11_GLES_LoadLibrary(_this, NULL);
+#else
+ return SDL_SetError("SDL not configured with EGL support");
+#endif
+ }
+
+ return 0;
+}
+
+void *
+X11_GL_GetProcAddress(_THIS, const char *proc)
+{
+ if (_this->gl_data->glXGetProcAddress) {
+ return _this->gl_data->glXGetProcAddress((const GLubyte *) proc);
+ }
+ return GL_LoadFunction(_this->gl_config.dll_handle, proc);
+}
+
+void
+X11_GL_UnloadLibrary(_THIS)
+{
+ /* Don't actually unload the library, since it may have registered
+ * X11 shutdown hooks, per the notes at:
+ * http://dri.sourceforge.net/doc/DRIuserguide.html
+ */
+#if 0
+ GL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+#endif
+
+ /* Free OpenGL memory */
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
+}
+
+static SDL_bool
+HasExtension(const char *extension, const char *extensions)
+{
+ const char *start;
+ const char *where, *terminator;
+
+ if (!extensions)
+ return SDL_FALSE;
+
+ /* Extension names should not have spaces. */
+ where = SDL_strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return SDL_FALSE;
+
+ /* It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings,
+ * etc. */
+
+ start = extensions;
+
+ for (;;) {
+ where = SDL_strstr(start, extension);
+ if (!where)
+ break;
+
+ terminator = where + SDL_strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0')
+ return SDL_TRUE;
+
+ start = terminator;
+ }
+ return SDL_FALSE;
+}
+
+static void
+X11_GL_InitExtensions(_THIS)
+{
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ const int screen = DefaultScreen(display);
+ XVisualInfo *vinfo = NULL;
+ Window w = 0;
+ GLXContext prev_ctx = 0;
+ GLXDrawable prev_drawable = 0;
+ GLXContext context = 0;
+ const char *(*glXQueryExtensionsStringFunc) (Display *, int);
+ const char *extensions;
+
+ vinfo = X11_GL_GetVisual(_this, display, screen);
+ if (vinfo) {
+ GLXContext (*glXGetCurrentContextFunc) (void) =
+ (GLXContext(*)(void))
+ X11_GL_GetProcAddress(_this, "glXGetCurrentContext");
+
+ GLXDrawable (*glXGetCurrentDrawableFunc) (void) =
+ (GLXDrawable(*)(void))
+ X11_GL_GetProcAddress(_this, "glXGetCurrentDrawable");
+
+ if (glXGetCurrentContextFunc && glXGetCurrentDrawableFunc) {
+ XSetWindowAttributes xattr;
+ prev_ctx = glXGetCurrentContextFunc();
+ prev_drawable = glXGetCurrentDrawableFunc();
+
+ xattr.background_pixel = 0;
+ xattr.border_pixel = 0;
+ xattr.colormap =
+ X11_XCreateColormap(display, RootWindow(display, screen),
+ vinfo->visual, AllocNone);
+ w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0,
+ 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual,
+ (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
+
+ context = _this->gl_data->glXCreateContext(display, vinfo,
+ NULL, True);
+ if (context) {
+ _this->gl_data->glXMakeCurrent(display, w, context);
+ }
+ }
+
+ X11_XFree(vinfo);
+ }
+
+ glXQueryExtensionsStringFunc =
+ (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this,
+ "glXQueryExtensionsString");
+ if (glXQueryExtensionsStringFunc) {
+ extensions = glXQueryExtensionsStringFunc(display, screen);
+ } else {
+ extensions = NULL;
+ }
+
+ /* Check for GLX_EXT_swap_control(_tear) */
+ _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE;
+ if (HasExtension("GLX_EXT_swap_control", extensions)) {
+ _this->gl_data->glXSwapIntervalEXT =
+ (void (*)(Display*,GLXDrawable,int))
+ X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
+ if (HasExtension("GLX_EXT_swap_control_tear", extensions)) {
+ _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE;
+ }
+ }
+
+ /* Check for GLX_MESA_swap_control */
+ if (HasExtension("GLX_MESA_swap_control", extensions)) {
+ _this->gl_data->glXSwapIntervalMESA =
+ (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA");
+ _this->gl_data->glXGetSwapIntervalMESA =
+ (int(*)(void)) X11_GL_GetProcAddress(_this,
+ "glXGetSwapIntervalMESA");
+ }
+
+ /* Check for GLX_SGI_swap_control */
+ if (HasExtension("GLX_SGI_swap_control", extensions)) {
+ _this->gl_data->glXSwapIntervalSGI =
+ (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI");
+ }
+
+ /* Check for GLX_ARB_create_context */
+ if (HasExtension("GLX_ARB_create_context", extensions)) {
+ _this->gl_data->glXCreateContextAttribsARB =
+ (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,const int *))
+ X11_GL_GetProcAddress(_this, "glXCreateContextAttribsARB");
+ _this->gl_data->glXChooseFBConfig =
+ (GLXFBConfig *(*)(Display *, int, const int *, int *))
+ X11_GL_GetProcAddress(_this, "glXChooseFBConfig");
+ }
+
+ /* Check for GLX_EXT_visual_rating */
+ if (HasExtension("GLX_EXT_visual_rating", extensions)) {
+ _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE;
+ }
+
+ /* Check for GLX_EXT_visual_info */
+ if (HasExtension("GLX_EXT_visual_info", extensions)) {
+ _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE;
+ }
+
+ /* Check for GLX_EXT_create_context_es2_profile */
+ if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) {
+ /* this wants to call glGetString(), so it needs a context. */
+ /* !!! FIXME: it would be nice not to make a context here though! */
+ if (context) {
+ SDL_GL_DeduceMaxSupportedESProfile(
+ &_this->gl_data->es_profile_max_supported_version.major,
+ &_this->gl_data->es_profile_max_supported_version.minor
+ );
+ }
+ }
+
+ /* Check for GLX_ARB_context_flush_control */
+ if (HasExtension("GLX_ARB_context_flush_control", extensions)) {
+ _this->gl_data->HAS_GLX_ARB_context_flush_control = SDL_TRUE;
+ }
+
+ /* Check for GLX_ARB_create_context_robustness */
+ if (HasExtension("GLX_ARB_create_context_robustness", extensions)) {
+ _this->gl_data->HAS_GLX_ARB_create_context_robustness = SDL_TRUE;
+ }
+
+ /* Check for GLX_ARB_create_context_no_error */
+ if (HasExtension("GLX_ARB_create_context_no_error", extensions)) {
+ _this->gl_data->HAS_GLX_ARB_create_context_no_error = SDL_TRUE;
+ }
+
+ if (context) {
+ _this->gl_data->glXMakeCurrent(display, None, NULL);
+ _this->gl_data->glXDestroyContext(display, context);
+ if (prev_ctx && prev_drawable) {
+ _this->gl_data->glXMakeCurrent(display, prev_drawable, prev_ctx);
+ }
+ }
+
+ if (w) {
+ X11_XDestroyWindow(display, w);
+ }
+ X11_PumpEvents(_this);
+}
+
+/* glXChooseVisual and glXChooseFBConfig have some small differences in
+ * the attribute encoding, it can be chosen with the for_FBConfig parameter.
+ * Some targets fail if you use GLX_X_VISUAL_TYPE_EXT/GLX_DIRECT_COLOR_EXT,
+ * so it gets specified last if used and is pointed to by *_pvistypeattr.
+ * In case of failure, if that pointer is not NULL, set that pointer to None
+ * and try again.
+ */
+static int
+X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig, int **_pvistypeattr)
+{
+ int i = 0;
+ const int MAX_ATTRIBUTES = 64;
+ int *pvistypeattr = NULL;
+
+ /* assert buffer is large enough to hold all SDL attributes. */
+ SDL_assert(size >= MAX_ATTRIBUTES);
+
+ /* Setup our GLX attributes according to the gl_config. */
+ if( for_FBConfig ) {
+ attribs[i++] = GLX_RENDER_TYPE;
+ attribs[i++] = GLX_RGBA_BIT;
+ } else {
+ attribs[i++] = GLX_RGBA;
+ }
+ attribs[i++] = GLX_RED_SIZE;
+ attribs[i++] = _this->gl_config.red_size;
+ attribs[i++] = GLX_GREEN_SIZE;
+ attribs[i++] = _this->gl_config.green_size;
+ attribs[i++] = GLX_BLUE_SIZE;
+ attribs[i++] = _this->gl_config.blue_size;
+
+ if (_this->gl_config.alpha_size) {
+ attribs[i++] = GLX_ALPHA_SIZE;
+ attribs[i++] = _this->gl_config.alpha_size;
+ }
+
+ if (_this->gl_config.double_buffer) {
+ attribs[i++] = GLX_DOUBLEBUFFER;
+ if( for_FBConfig ) {
+ attribs[i++] = True;
+ }
+ }
+
+ attribs[i++] = GLX_DEPTH_SIZE;
+ attribs[i++] = _this->gl_config.depth_size;
+
+ if (_this->gl_config.stencil_size) {
+ attribs[i++] = GLX_STENCIL_SIZE;
+ attribs[i++] = _this->gl_config.stencil_size;
+ }
+
+ if (_this->gl_config.accum_red_size) {
+ attribs[i++] = GLX_ACCUM_RED_SIZE;
+ attribs[i++] = _this->gl_config.accum_red_size;
+ }
+
+ if (_this->gl_config.accum_green_size) {
+ attribs[i++] = GLX_ACCUM_GREEN_SIZE;
+ attribs[i++] = _this->gl_config.accum_green_size;
+ }
+
+ if (_this->gl_config.accum_blue_size) {
+ attribs[i++] = GLX_ACCUM_BLUE_SIZE;
+ attribs[i++] = _this->gl_config.accum_blue_size;
+ }
+
+ if (_this->gl_config.accum_alpha_size) {
+ attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
+ attribs[i++] = _this->gl_config.accum_alpha_size;
+ }
+
+ if (_this->gl_config.stereo) {
+ attribs[i++] = GLX_STEREO;
+ if( for_FBConfig ) {
+ attribs[i++] = True;
+ }
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
+ attribs[i++] = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ attribs[i++] = GLX_SAMPLES_ARB;
+ attribs[i++] = _this->gl_config.multisamplesamples;
+ }
+
+ if (_this->gl_config.framebuffer_srgb_capable) {
+ attribs[i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
+ attribs[i++] = True; /* always needed, for_FBConfig or not! */
+ }
+
+ if (_this->gl_config.accelerated >= 0 &&
+ _this->gl_data->HAS_GLX_EXT_visual_rating) {
+ attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
+ attribs[i++] = _this->gl_config.accelerated ? GLX_NONE_EXT :
+ GLX_SLOW_VISUAL_EXT;
+ }
+
+ /* If we're supposed to use DirectColor visuals, and we've got the
+ EXT_visual_info extension, then add GLX_X_VISUAL_TYPE_EXT. */
+ if (X11_UseDirectColorVisuals() &&
+ _this->gl_data->HAS_GLX_EXT_visual_info) {
+ pvistypeattr = &attribs[i];
+ attribs[i++] = GLX_X_VISUAL_TYPE_EXT;
+ attribs[i++] = GLX_DIRECT_COLOR_EXT;
+ }
+
+ attribs[i++] = None;
+
+ SDL_assert(i <= MAX_ATTRIBUTES);
+
+ if (_pvistypeattr) {
+ *_pvistypeattr = pvistypeattr;
+ }
+
+ return i;
+}
+
+XVisualInfo *
+X11_GL_GetVisual(_THIS, Display * display, int screen)
+{
+ /* 64 seems nice. */
+ int attribs[64];
+ XVisualInfo *vinfo;
+ int *pvistypeattr = NULL;
+
+ if (!_this->gl_data) {
+ /* The OpenGL library wasn't loaded, SDL_GetError() should have info */
+ return NULL;
+ }
+
+ X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE, &pvistypeattr);
+ vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs);
+
+ if (!vinfo && (pvistypeattr != NULL)) {
+ *pvistypeattr = None;
+ vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs);
+ }
+
+ if (!vinfo) {
+ SDL_SetError("Couldn't find matching GLX visual");
+ }
+ return vinfo;
+}
+
+static int (*handler) (Display *, XErrorEvent *) = NULL;
+static const char *errorHandlerOperation = NULL;
+static int errorBase = 0;
+static int errorCode = 0;
+static int
+X11_GL_ErrorHandler(Display * d, XErrorEvent * e)
+{
+ char *x11_error = NULL;
+ char x11_error_locale[256];
+
+ errorCode = e->error_code;
+ if (X11_XGetErrorText(d, errorCode, x11_error_locale, sizeof(x11_error_locale)) == Success)
+ {
+ x11_error = SDL_iconv_string("UTF-8", "", x11_error_locale, SDL_strlen(x11_error_locale)+1);
+ }
+
+ if (x11_error)
+ {
+ SDL_SetError("Could not %s: %s", errorHandlerOperation, x11_error);
+ SDL_free(x11_error);
+ }
+ else
+ {
+ SDL_SetError("Could not %s: %i (Base %i)", errorHandlerOperation, errorCode, errorBase);
+ }
+
+ return (0);
+}
+
+SDL_bool
+X11_GL_UseEGL(_THIS)
+{
+ SDL_assert(_this->gl_data != NULL);
+ SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
+
+ return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE)
+ || _this->gl_config.major_version == 1 /* No GLX extension for OpenGL ES 1.x profiles. */
+ || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major
+ || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major
+ && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor));
+}
+
+SDL_GLContext
+X11_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ int screen =
+ ((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen;
+ XWindowAttributes xattr;
+ XVisualInfo v, *vinfo;
+ int n;
+ GLXContext context = NULL, share_context;
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (GLXContext)SDL_GL_GetCurrentContext();
+ } else {
+ share_context = NULL;
+ }
+
+ /* We do this to create a clean separation between X and GLX errors. */
+ X11_XSync(display, False);
+ errorHandlerOperation = "create GL context";
+ errorBase = _this->gl_data->errorBase;
+ errorCode = Success;
+ handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
+ X11_XGetWindowAttributes(display, data->xwindow, &xattr);
+ v.screen = screen;
+ v.visualid = X11_XVisualIDFromVisual(xattr.visual);
+ vinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
+ if (vinfo) {
+ if (_this->gl_config.major_version < 3 &&
+ _this->gl_config.profile_mask == 0 &&
+ _this->gl_config.flags == 0) {
+ /* Create legacy context */
+ context =
+ _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
+ } else {
+ /* max 14 attributes plus terminator */
+ int attribs[15] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB,
+ _this->gl_config.major_version,
+ GLX_CONTEXT_MINOR_VERSION_ARB,
+ _this->gl_config.minor_version,
+ 0
+ };
+ int iattr = 4;
+
+ /* SDL profile bits match GLX profile bits */
+ if( _this->gl_config.profile_mask != 0 ) {
+ attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
+ attribs[iattr++] = _this->gl_config.profile_mask;
+ }
+
+ /* SDL flags match GLX flags */
+ if( _this->gl_config.flags != 0 ) {
+ attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
+ attribs[iattr++] = _this->gl_config.flags;
+ }
+
+ /* only set if glx extension is available */
+ if( _this->gl_data->HAS_GLX_ARB_context_flush_control ) {
+ attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
+ attribs[iattr++] =
+ _this->gl_config.release_behavior ?
+ GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
+ GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
+ }
+
+ /* only set if glx extension is available */
+ if( _this->gl_data->HAS_GLX_ARB_create_context_robustness ) {
+ attribs[iattr++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
+ attribs[iattr++] =
+ _this->gl_config.reset_notification ?
+ GLX_LOSE_CONTEXT_ON_RESET_ARB :
+ GLX_NO_RESET_NOTIFICATION_ARB;
+ }
+
+ /* only set if glx extension is available */
+ if( _this->gl_data->HAS_GLX_ARB_create_context_no_error ) {
+ attribs[iattr++] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB;
+ attribs[iattr++] = _this->gl_config.no_error;
+ }
+
+ attribs[iattr++] = 0;
+
+ /* Get a pointer to the context creation function for GL 3.0 */
+ if (!_this->gl_data->glXCreateContextAttribsARB) {
+ SDL_SetError("OpenGL 3.0 and later are not supported by this system");
+ } else {
+ int glxAttribs[64];
+
+ /* Create a GL 3.x context */
+ GLXFBConfig *framebuffer_config = NULL;
+ int fbcount = 0;
+ int *pvistypeattr = NULL;
+
+ X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE,&pvistypeattr);
+
+ if (_this->gl_data->glXChooseFBConfig) {
+ framebuffer_config = _this->gl_data->glXChooseFBConfig(display,
+ DefaultScreen(display), glxAttribs,
+ &fbcount);
+
+ if (!framebuffer_config && (pvistypeattr != NULL)) {
+ *pvistypeattr = None;
+ framebuffer_config = _this->gl_data->glXChooseFBConfig(display,
+ DefaultScreen(display), glxAttribs,
+ &fbcount);
+ }
+
+ if (framebuffer_config) {
+ context = _this->gl_data->glXCreateContextAttribsARB(display,
+ framebuffer_config[0],
+ share_context, True, attribs);
+ X11_XFree(framebuffer_config);
+ }
+ }
+ }
+ }
+ X11_XFree(vinfo);
+ }
+ X11_XSync(display, False);
+ X11_XSetErrorHandler(handler);
+
+ if (!context) {
+ if (errorCode == Success) {
+ SDL_SetError("Could not create GL context");
+ }
+ return NULL;
+ }
+
+ if (X11_GL_MakeCurrent(_this, window, context) < 0) {
+ X11_GL_DeleteContext(_this, context);
+ return NULL;
+ }
+
+ return context;
+}
+
+int
+X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ Window drawable =
+ (context ? ((SDL_WindowData *) window->driverdata)->xwindow : None);
+ GLXContext glx_context = (GLXContext) context;
+ int rc;
+
+ if (!_this->gl_data) {
+ return SDL_SetError("OpenGL not initialized");
+ }
+
+ /* We do this to create a clean separation between X and GLX errors. */
+ X11_XSync(display, False);
+ errorHandlerOperation = "make GL context current";
+ errorBase = _this->gl_data->errorBase;
+ errorCode = Success;
+ handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
+ rc = _this->gl_data->glXMakeCurrent(display, drawable, glx_context);
+ X11_XSetErrorHandler(handler);
+
+ if (errorCode != Success) { /* uhoh, an X error was thrown! */
+ return -1; /* the error handler called SDL_SetError() already. */
+ } else if (!rc) { /* glXMakeCurrent() failed without throwing an X error */
+ return SDL_SetError("Unable to make GL context current");
+ }
+
+ return 0;
+}
+
+/*
+ 0 is a valid argument to glXSwapInterval(MESA|EXT) and setting it to 0
+ will undo the effect of a previous call with a value that is greater
+ than zero (or at least that is what the docs say). OTOH, 0 is an invalid
+ argument to glXSwapIntervalSGI and it returns an error if you call it
+ with 0 as an argument.
+*/
+
+static int swapinterval = 0;
+int
+X11_GL_SetSwapInterval(_THIS, int interval)
+{
+ int status = -1;
+
+ if ((interval < 0) && (!_this->gl_data->HAS_GLX_EXT_swap_control_tear)) {
+ SDL_SetError("Negative swap interval unsupported in this GL");
+ } else if (_this->gl_data->glXSwapIntervalEXT) {
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ const SDL_WindowData *windowdata = (SDL_WindowData *)
+ SDL_GL_GetCurrentWindow()->driverdata;
+
+ Window drawable = windowdata->xwindow;
+
+ /*
+ * This is a workaround for a bug in NVIDIA drivers. Bug has been reported
+ * and will be fixed in a future release (probably 319.xx).
+ *
+ * There's a bug where glXSetSwapIntervalEXT ignores updates because
+ * it has the wrong value cached. To work around it, we just run a no-op
+ * update to the current value.
+ */
+ int currentInterval = X11_GL_GetSwapInterval(_this);
+ _this->gl_data->glXSwapIntervalEXT(display, drawable, currentInterval);
+ _this->gl_data->glXSwapIntervalEXT(display, drawable, interval);
+
+ status = 0;
+ swapinterval = interval;
+ } else if (_this->gl_data->glXSwapIntervalMESA) {
+ status = _this->gl_data->glXSwapIntervalMESA(interval);
+ if (status != 0) {
+ SDL_SetError("glXSwapIntervalMESA failed");
+ } else {
+ swapinterval = interval;
+ }
+ } else if (_this->gl_data->glXSwapIntervalSGI) {
+ status = _this->gl_data->glXSwapIntervalSGI(interval);
+ if (status != 0) {
+ SDL_SetError("glXSwapIntervalSGI failed");
+ } else {
+ swapinterval = interval;
+ }
+ } else {
+ SDL_Unsupported();
+ }
+ return status;
+}
+
+int
+X11_GL_GetSwapInterval(_THIS)
+{
+ if (_this->gl_data->glXSwapIntervalEXT) {
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ const SDL_WindowData *windowdata = (SDL_WindowData *)
+ SDL_GL_GetCurrentWindow()->driverdata;
+ Window drawable = windowdata->xwindow;
+ unsigned int allow_late_swap_tearing = 0;
+ unsigned int interval = 0;
+
+ if (_this->gl_data->HAS_GLX_EXT_swap_control_tear) {
+ _this->gl_data->glXQueryDrawable(display, drawable,
+ GLX_LATE_SWAPS_TEAR_EXT,
+ &allow_late_swap_tearing);
+ }
+
+ _this->gl_data->glXQueryDrawable(display, drawable,
+ GLX_SWAP_INTERVAL_EXT, &interval);
+
+ if ((allow_late_swap_tearing) && (interval > 0)) {
+ return -((int) interval);
+ }
+
+ return (int) interval;
+ } else if (_this->gl_data->glXGetSwapIntervalMESA) {
+ return _this->gl_data->glXGetSwapIntervalMESA();
+ } else {
+ return swapinterval;
+ }
+}
+
+int
+X11_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ _this->gl_data->glXSwapBuffers(display, data->xwindow);
+ return 0;
+}
+
+void
+X11_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ GLXContext glx_context = (GLXContext) context;
+
+ if (!_this->gl_data) {
+ return;
+ }
+ _this->gl_data->glXDestroyContext(display, glx_context);
+ X11_XSync(display, False);
+}
+
+#endif /* SDL_VIDEO_OPENGL_GLX */
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.h
new file mode 100644
index 0000000..7331b71
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengl.h
@@ -0,0 +1,84 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11opengl_h_
+#define SDL_x11opengl_h_
+
+#if SDL_VIDEO_OPENGL_GLX
+#include "SDL_opengl.h"
+#include <GL/glx.h>
+
+struct SDL_GLDriverData
+{
+ int errorBase, eventBase;
+
+ SDL_bool HAS_GLX_EXT_visual_rating;
+ SDL_bool HAS_GLX_EXT_visual_info;
+ SDL_bool HAS_GLX_EXT_swap_control_tear;
+ SDL_bool HAS_GLX_ARB_context_flush_control;
+ SDL_bool HAS_GLX_ARB_create_context_robustness;
+ SDL_bool HAS_GLX_ARB_create_context_no_error;
+
+ /* Max version of OpenGL ES context that can be created if the
+ implementation supports GLX_EXT_create_context_es2_profile.
+ major = minor = 0 when unsupported.
+ */
+ struct {
+ int major;
+ int minor;
+ } es_profile_max_supported_version;
+
+ Bool (*glXQueryExtension) (Display*,int*,int*);
+ void *(*glXGetProcAddress) (const GLubyte*);
+ XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
+ GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool);
+ GLXContext (*glXCreateContextAttribsARB) (Display*,GLXFBConfig,GLXContext,Bool,const int *);
+ GLXFBConfig *(*glXChooseFBConfig) (Display*,int,const int *,int *);
+ void (*glXDestroyContext) (Display*, GLXContext);
+ Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext);
+ void (*glXSwapBuffers) (Display*, GLXDrawable);
+ void (*glXQueryDrawable) (Display*,GLXDrawable,int,unsigned int*);
+ void (*glXSwapIntervalEXT) (Display*,GLXDrawable,int);
+ int (*glXSwapIntervalSGI) (int);
+ int (*glXSwapIntervalMESA) (int);
+ int (*glXGetSwapIntervalMESA) (void);
+};
+
+/* OpenGL functions */
+extern int X11_GL_LoadLibrary(_THIS, const char *path);
+extern void *X11_GL_GetProcAddress(_THIS, const char *proc);
+extern void X11_GL_UnloadLibrary(_THIS);
+extern SDL_bool X11_GL_UseEGL(_THIS);
+extern XVisualInfo *X11_GL_GetVisual(_THIS, Display * display, int screen);
+extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window);
+extern int X11_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern int X11_GL_SetSwapInterval(_THIS, int interval);
+extern int X11_GL_GetSwapInterval(_THIS);
+extern int X11_GL_SwapWindow(_THIS, SDL_Window * window);
+extern void X11_GL_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_OPENGL_GLX */
+
+#endif /* SDL_x11opengl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.c
new file mode 100644
index 0000000..76b6cd7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.c
@@ -0,0 +1,109 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_x11video.h"
+#include "SDL_x11opengles.h"
+#include "SDL_x11opengl.h"
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+X11_GLES_LoadLibrary(_THIS, const char *path)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ /* If the profile requested is not GL ES, switch over to X11_GL functions */
+ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
+ #if SDL_VIDEO_OPENGL_GLX
+ X11_GLES_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = X11_GL_LoadLibrary;
+ _this->GL_GetProcAddress = X11_GL_GetProcAddress;
+ _this->GL_UnloadLibrary = X11_GL_UnloadLibrary;
+ _this->GL_CreateContext = X11_GL_CreateContext;
+ _this->GL_MakeCurrent = X11_GL_MakeCurrent;
+ _this->GL_SetSwapInterval = X11_GL_SetSwapInterval;
+ _this->GL_GetSwapInterval = X11_GL_GetSwapInterval;
+ _this->GL_SwapWindow = X11_GL_SwapWindow;
+ _this->GL_DeleteContext = X11_GL_DeleteContext;
+ return X11_GL_LoadLibrary(_this, path);
+ #else
+ return SDL_SetError("SDL not configured with OpenGL/GLX support");
+ #endif
+ }
+
+ return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0);
+}
+
+XVisualInfo *
+X11_GLES_GetVisual(_THIS, Display * display, int screen)
+{
+
+ XVisualInfo *egl_visualinfo = NULL;
+ EGLint visual_id;
+ XVisualInfo vi_in;
+ int out_count;
+
+ if (!_this->egl_data) {
+ /* The EGL library wasn't loaded, SDL_GetError() should have info */
+ return NULL;
+ }
+
+ if (_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
+ _this->egl_data->egl_config,
+ EGL_NATIVE_VISUAL_ID,
+ &visual_id) == EGL_FALSE || !visual_id) {
+ /* Use the default visual when all else fails */
+ vi_in.screen = screen;
+ egl_visualinfo = X11_XGetVisualInfo(display,
+ VisualScreenMask,
+ &vi_in, &out_count);
+ } else {
+ vi_in.screen = screen;
+ vi_in.visualid = visual_id;
+ egl_visualinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &vi_in, &out_count);
+ }
+
+ return egl_visualinfo;
+}
+
+SDL_GLContext
+X11_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_GLContext context;
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ X11_XSync(display, False);
+ context = SDL_EGL_CreateContext(_this, data->egl_surface);
+ X11_XSync(display, False);
+
+ return context;
+}
+
+SDL_EGL_SwapWindow_impl(X11)
+SDL_EGL_MakeCurrent_impl(X11)
+
+#endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.h
new file mode 100644
index 0000000..b189b76
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11opengles.h
@@ -0,0 +1,56 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11opengles_h_
+#define SDL_x11opengles_h_
+
+#if SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+typedef struct SDL_PrivateGLESData
+{
+ /* 1401 If the struct-declaration-list contains no named members, the behavior is undefined. */
+ /* warning: empty struct has size 0 in C, size 1 in C++ [-Wc++-compat] */
+ int dummy;
+} SDL_PrivateGLESData;
+
+/* OpenGLES functions */
+#define X11_GLES_GetAttribute SDL_EGL_GetAttribute
+#define X11_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define X11_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define X11_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+#define X11_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+#define X11_GLES_DeleteContext SDL_EGL_DeleteContext
+
+extern int X11_GLES_LoadLibrary(_THIS, const char *path);
+extern XVisualInfo *X11_GLES_GetVisual(_THIS, Display * display, int screen);
+extern SDL_GLContext X11_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int X11_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_x11opengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11shape.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11shape.c
new file mode 100644
index 0000000..4d68fe0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11shape.c
@@ -0,0 +1,115 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_assert.h"
+#include "SDL_x11video.h"
+#include "SDL_x11shape.h"
+#include "SDL_x11window.h"
+#include "../SDL_shape_internals.h"
+
+SDL_WindowShaper*
+X11_CreateShaper(SDL_Window* window) {
+ SDL_WindowShaper* result = NULL;
+ SDL_ShapeData* data = NULL;
+ int resized_properly;
+
+#if SDL_VIDEO_DRIVER_X11_XSHAPE
+ if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */
+ result = malloc(sizeof(SDL_WindowShaper));
+ result->window = window;
+ result->mode.mode = ShapeModeDefault;
+ result->mode.parameters.binarizationCutoff = 1;
+ result->userx = result->usery = 0;
+ data = SDL_malloc(sizeof(SDL_ShapeData));
+ result->driverdata = data;
+ data->bitmapsize = 0;
+ data->bitmap = NULL;
+ window->shaper = result;
+ resized_properly = X11_ResizeWindowShape(window);
+ SDL_assert(resized_properly == 0);
+ }
+#endif
+
+ return result;
+}
+
+int
+X11_ResizeWindowShape(SDL_Window* window) {
+ SDL_ShapeData* data = window->shaper->driverdata;
+ unsigned int bitmapsize = window->w / 8;
+ SDL_assert(data != NULL);
+
+ if(window->w % 8 > 0)
+ bitmapsize += 1;
+ bitmapsize *= window->h;
+ if(data->bitmapsize != bitmapsize || data->bitmap == NULL) {
+ data->bitmapsize = bitmapsize;
+ if(data->bitmap != NULL)
+ free(data->bitmap);
+ data->bitmap = malloc(data->bitmapsize);
+ if(data->bitmap == NULL) {
+ return SDL_SetError("Could not allocate memory for shaped-window bitmap.");
+ }
+ }
+ memset(data->bitmap,0,data->bitmapsize);
+
+ window->shaper->userx = window->x;
+ window->shaper->usery = window->y;
+ SDL_SetWindowPosition(window,-1000,-1000);
+
+ return 0;
+}
+
+int
+X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) {
+ SDL_ShapeData *data = NULL;
+ SDL_WindowData *windowdata = NULL;
+ Pixmap shapemask;
+
+ if(shaper == NULL || shape == NULL || shaper->driverdata == NULL)
+ return -1;
+
+#if SDL_VIDEO_DRIVER_X11_XSHAPE
+ if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode))
+ return -2;
+ if(shape->w != shaper->window->w || shape->h != shaper->window->h)
+ return -3;
+ data = shaper->driverdata;
+
+ /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
+ SDL_CalculateShapeBitmap(shaper->mode,shape,data->bitmap,8);
+
+ windowdata = (SDL_WindowData*)(shaper->window->driverdata);
+ shapemask = X11_XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);
+
+ X11_XShapeCombineMask(windowdata->videodata->display,windowdata->xwindow, ShapeBounding, 0, 0,shapemask, ShapeSet);
+ X11_XSync(windowdata->videodata->display,False);
+
+ X11_XFreePixmap(windowdata->videodata->display,shapemask);
+#endif
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11shape.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11shape.h
new file mode 100644
index 0000000..a8c2e2c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11shape.h
@@ -0,0 +1,39 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11shape_h_
+#define SDL_x11shape_h_
+
+#include "SDL_video.h"
+#include "SDL_shape.h"
+#include "../SDL_sysvideo.h"
+
+typedef struct {
+ void* bitmap;
+ Uint32 bitmapsize;
+} SDL_ShapeData;
+
+extern SDL_WindowShaper* X11_CreateShaper(SDL_Window* window);
+extern int X11_ResizeWindowShape(SDL_Window* window);
+extern int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode);
+
+#endif /* SDL_x11shape_h_ */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11sym.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11sym.h
new file mode 100644
index 0000000..6709992
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11sym.h
@@ -0,0 +1,337 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* *INDENT-OFF* */
+
+#ifndef SDL_X11_MODULE
+#define SDL_X11_MODULE(modname)
+#endif
+
+#ifndef SDL_X11_SYM
+#define SDL_X11_SYM(rc,fn,params,args,ret)
+#endif
+
+SDL_X11_MODULE(BASEXLIB)
+SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return)
+SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return)
+SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return)
+SDL_X11_SYM(int,XAutoRepeatOn,(Display* a),(a),return)
+SDL_X11_SYM(int,XAutoRepeatOff,(Display* a),(a),return)
+SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(Bool,XCheckIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return)
+SDL_X11_SYM(int,XClearWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return)
+SDL_X11_SYM(int,XConvertSelection,(Display* a,Atom b,Atom c,Atom d,Window e,Time f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *data,unsigned int width,unsigned int height),(dpy,d,data,width,height),return)
+SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(Cursor,XCreateFontCursor,(Display* a,unsigned int b),(a,b),return)
+SDL_X11_SYM(XFontSet,XCreateFontSet,(Display* a, _Xconst char* b, char*** c, int* d, char** e),(a,b,c,d,e),return)
+SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return)
+SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j),(a,b,c,d,e,f,g,h,i,j),return)
+SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
+SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return)
+SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return)
+SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XDisplayKeycodes,(Display* a,int* b,int* c),(a,b,c),return)
+SDL_X11_SYM(int,XDrawRectangle,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a),(a),return)
+SDL_X11_SYM(int,XDrawString,(Display* a,Drawable b,GC c,int d,int e,_Xconst char* f,int g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(int,XEventsQueued,(Display* a,int b),(a,b),return)
+SDL_X11_SYM(int,XFillRectangle,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event,Window w),(event,w),return)
+SDL_X11_SYM(int,XFlush,(Display* a),(a),return)
+SDL_X11_SYM(int,XFree,(void*a),(a),return)
+SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return)
+SDL_X11_SYM(void,XFreeFontSet,(Display* a, XFontSet b),(a,b),)
+SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
+SDL_X11_SYM(int,XFreeFont,(Display* a, XFontStruct* b),(a,b),return)
+SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
+SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
+SDL_X11_SYM(void,XFreeStringList,(char** a),(a),)
+SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return)
+SDL_X11_SYM(int,XGetInputFocus,(Display *a,Window *b,int *c),(a,b,c),return)
+SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
+SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
+SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return)
+SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
+SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
+SDL_X11_SYM(int,XGetWindowProperty,(Display* a,Window b,Atom c,long d,long e,Bool f,Atom g,Atom* h,int* i,unsigned long* j,unsigned long *k,unsigned char **l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
+SDL_X11_SYM(XWMHints*,XGetWMHints,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(Status,XGetWMNormalHints,(Display *a,Window b, XSizeHints *c, long *d),(a,b,c,d),return)
+SDL_X11_SYM(int,XIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return)
+SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XGrabPointer,(Display* a,Window b,Bool c,unsigned int d,int e,int f,Window g,Cursor h,Time i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(int,XGrabServer,(Display* a),(a),return)
+SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return)
+SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return)
+SDL_X11_SYM(char*,XKeysymToString,(KeySym a),(a),return)
+SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return)
+SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return)
+SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return)
+SDL_X11_SYM(XFontStruct*,XLoadQueryFont,(Display* a,_Xconst char* b),(a,b),return)
+SDL_X11_SYM(KeySym,XLookupKeysym,(XKeyEvent* a,int b),(a,b),return)
+SDL_X11_SYM(int,XLookupString,(XKeyEvent* a,char* b,int c,KeySym* d,XComposeStatus* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return)
+SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return)
+SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return)
+SDL_X11_SYM(Status,XInitThreads,(void),(),return)
+SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return)
+SDL_X11_SYM(int,XPending,(Display* a),(a),return)
+SDL_X11_SYM(int,XPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j),(a,b,c,d,e,f,g,h,i,j),return)
+SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return)
+SDL_X11_SYM(Bool,XQueryPointer,(Display* a,Window b,Window* c,Window* d,int* e,int* f,int* g,int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return)
+SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return)
+SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return)
+SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return)
+SDL_X11_SYM(int,XSetForeground,(Display* a,GC b,unsigned long c),(a,b,c),return)
+SDL_X11_SYM(XIOErrorHandler,XSetIOErrorHandler,(XIOErrorHandler a),(a),return)
+SDL_X11_SYM(int,XSetInputFocus,(Display *a,Window b,int c,Time d),(a,b,c,d),return)
+SDL_X11_SYM(int,XSetSelectionOwner,(Display* a,Atom b,Window c,Time d),(a,b,c,d),return)
+SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return)
+SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),)
+SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return)
+SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),)
+SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),)
+SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XStoreName,(Display* a,Window b,_Xconst char* c),(a,b,c),return)
+SDL_X11_SYM(Status,XStringListToTextProperty,(char** a,int b,XTextProperty* c),(a,b,c),return)
+SDL_X11_SYM(int,XSync,(Display* a,Bool b),(a,b),return)
+SDL_X11_SYM(int,XTextExtents,(XFontStruct* a,_Xconst char* b,int c,int* d,int* e,int* f,XCharStruct* g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(Bool,XTranslateCoordinates,(Display *a,Window b,Window c,int d,int e,int* f,int* g,Window* h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(int,XUndefineCursor,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XUngrabKeyboard,(Display* a,Time b),(a,b),return)
+SDL_X11_SYM(int,XUngrabPointer,(Display* a,Time b),(a,b),return)
+SDL_X11_SYM(int,XUngrabServer,(Display* a),(a),return)
+SDL_X11_SYM(int,XUninstallColormap,(Display* a,Colormap b),(a,b),return)
+SDL_X11_SYM(int,XUnloadFont,(Display* a,Font b),(a,b),return)
+SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned int f,unsigned int g,int h,int i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(int,XWindowEvent,(Display* a,Window b,long c,XEvent* d),(a,b,c,d),return)
+SDL_X11_SYM(Status,XWithdrawWindow,(Display* a,Window b,int c),(a,b,c),return)
+SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return)
+#if SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY
+SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
+#else
+SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
+#endif
+SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return)
+SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),)
+SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
+SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
+SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return)
+SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return)
+SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(void,_XEatData,(Display* a,unsigned long b),(a,b),)
+SDL_X11_SYM(void,_XFlush,(Display* a),(a),)
+SDL_X11_SYM(void,_XFlushGCCache,(Display* a,GC b),(a,b),)
+SDL_X11_SYM(int,_XRead,(Display* a,char* b,long c),(a,b,c),return)
+SDL_X11_SYM(void,_XReadPad,(Display* a,char* b,long c),(a,b,c),)
+SDL_X11_SYM(void,_XSend,(Display* a,_Xconst char* b,long c),(a,b,c),)
+SDL_X11_SYM(Status,_XReply,(Display* a,xReply* b,int c,Bool d),(a,b,c,d),return)
+SDL_X11_SYM(unsigned long,_XSetLastRequestRead,(Display* a,xGenericReply* b),(a,b),return)
+SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),return)
+SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return)
+SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
+SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),)
+SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return)
+
+#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
+SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return)
+SDL_X11_SYM(void,XFreeEventData,(Display* a,XGenericEventCookie* b),(a,b),)
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+SDL_X11_SYM(Bool,XkbQueryExtension,(Display* a,int * b,int * c,int * d,int * e, int *f),(a,b,c,d,e,f),return)
+#if NeedWidePrototypes
+SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,unsigned int b,int c,int d),(a,b,c,d),return)
+#else
+SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return)
+#endif
+SDL_X11_SYM(Status,XkbGetState,(Display* a,unsigned int b,XkbStatePtr c),(a,b,c),return)
+SDL_X11_SYM(Status,XkbGetUpdatedMap,(Display* a,unsigned int b,XkbDescPtr c),(a,b,c),return)
+SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b,c),return)
+SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
+SDL_X11_SYM(void,XkbFreeKeyboard,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
+SDL_X11_SYM(Bool,XkbSetDetectableAutoRepeat,(Display* a, Bool b, Bool* c),(a,b,c),return)
+#endif
+
+#if NeedWidePrototypes
+SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
+#else
+SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,KeyCode b,int c),(a,b,c),return)
+#endif
+
+#ifdef X_HAVE_UTF8_STRING
+SDL_X11_MODULE(UTF8)
+SDL_X11_SYM(int,Xutf8TextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,Xutf8LookupString,(XIC a,XKeyPressedEvent* b,char* c,int d,KeySym* e,Status* f),(a,b,c,d,e,f),return)
+/* SDL_X11_SYM(XIC,XCreateIC,(XIM, ...),return) !!! ARGH! */
+SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),)
+/* SDL_X11_SYM(char*,XGetICValues,(XIC, ...),return) !!! ARGH! */
+SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),)
+SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),)
+SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)
+SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return)
+SDL_X11_SYM(void,Xutf8DrawString,(Display *a, Drawable b, XFontSet c, GC d, int e, int f, _Xconst char *g, int h),(a,b,c,d,e,f,g,h),)
+SDL_X11_SYM(int,Xutf8TextExtents,(XFontSet a, _Xconst char* b, int c, XRectangle* d, XRectangle* e),(a,b,c,d,e),return)
+SDL_X11_SYM(char*,XSetLocaleModifiers,(const char *a),(a),return)
+SDL_X11_SYM(char*,Xutf8ResetIC,(XIC a),(a),return)
+#endif
+
+#ifndef NO_SHARED_MEMORY
+SDL_X11_MODULE(SHM)
+SDL_X11_SYM(Status,XShmAttach,(Display* a,XShmSegmentInfo* b),(a,b),return)
+SDL_X11_SYM(Status,XShmDetach,(Display* a,XShmSegmentInfo* b),(a,b),return)
+SDL_X11_SYM(Status,XShmPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j,Bool k),(a,b,c,d,e,f,g,h,i,j,k),return)
+SDL_X11_SYM(XImage*,XShmCreateImage,(Display* a,Visual* b,unsigned int c,int d,char* e,XShmSegmentInfo* f,unsigned int g,unsigned int h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(Pixmap,XShmCreatePixmap,(Display *a,Drawable b,char* c,XShmSegmentInfo* d, unsigned int e, unsigned int f, unsigned int g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(Bool,XShmQueryExtension,(Display* a),(a),return)
+#endif
+
+/*
+ * Not required...these only exist in code in headers on some 64-bit platforms,
+ * and are removed via macros elsewhere, so it's safe for them to be missing.
+ */
+#ifdef LONG64
+SDL_X11_MODULE(IO_32BIT)
+SDL_X11_SYM(int,_XData32,(Display *dpy,register _Xconst long *data,unsigned len),(dpy,data,len),return)
+SDL_X11_SYM(void,_XRead32,(Display *dpy,register long *data,long len),(dpy,data,len),)
+#endif
+
+/*
+ * These only show up on some variants of Unix.
+ */
+#if defined(__osf__)
+SDL_X11_MODULE(OSF_ENTRY_POINTS)
+SDL_X11_SYM(void,_SmtBufferOverflow,(Display *dpy,register smtDisplayPtr p),(dpy,p),)
+SDL_X11_SYM(void,_SmtIpError,(Display *dpy,register smtDisplayPtr p,int i),(dpy,p,i),)
+SDL_X11_SYM(int,ipAllocateData,(ChannelPtr a,IPCard b,IPDataPtr * c),(a,b,c),return)
+SDL_X11_SYM(int,ipUnallocateAndSendData,(ChannelPtr a,IPCard b),(a,b),return)
+#endif
+
+/* XCursor support */
+#if SDL_VIDEO_DRIVER_X11_XCURSOR
+SDL_X11_MODULE(XCURSOR)
+SDL_X11_SYM(XcursorImage*,XcursorImageCreate,(int a,int b),(a,b),return)
+SDL_X11_SYM(void,XcursorImageDestroy,(XcursorImage *a),(a),)
+SDL_X11_SYM(Cursor,XcursorImageLoadCursor,(Display *a,const XcursorImage *b),(a,b),return)
+#endif
+
+/* Xdbe support */
+#if SDL_VIDEO_DRIVER_X11_XDBE
+SDL_X11_MODULE(XDBE)
+SDL_X11_SYM(Status,XdbeQueryExtension,(Display *dpy,int *major_version_return,int *minor_version_return),(dpy,major_version_return,minor_version_return),return)
+SDL_X11_SYM(XdbeBackBuffer,XdbeAllocateBackBufferName,(Display *dpy,Window window,XdbeSwapAction swap_action),(dpy,window,swap_action),return)
+SDL_X11_SYM(Status,XdbeDeallocateBackBufferName,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return)
+SDL_X11_SYM(Status,XdbeSwapBuffers,(Display *dpy,XdbeSwapInfo *swap_info,int num_windows),(dpy,swap_info,num_windows),return)
+SDL_X11_SYM(Status,XdbeBeginIdiom,(Display *dpy),(dpy),return)
+SDL_X11_SYM(Status,XdbeEndIdiom,(Display *dpy),(dpy),return)
+SDL_X11_SYM(XdbeScreenVisualInfo*,XdbeGetVisualInfo,(Display *dpy,Drawable *screen_specifiers,int *num_screens),(dpy,screen_specifiers,num_screens),return)
+SDL_X11_SYM(void,XdbeFreeVisualInfo,(XdbeScreenVisualInfo *visual_info),(visual_info),)
+SDL_X11_SYM(XdbeBackBufferAttributes*,XdbeGetBackBufferAttributes,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return)
+#endif
+
+/* Xinerama support */
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+SDL_X11_MODULE(XINERAMA)
+SDL_X11_SYM(Bool,XineramaIsActive,(Display *a),(a),return)
+SDL_X11_SYM(Bool,XineramaQueryExtension,(Display *a,int *b,int *c),(a,b,c),return)
+SDL_X11_SYM(Status,XineramaQueryVersion,(Display *a,int *b,int *c),(a,b,c),return)
+SDL_X11_SYM(XineramaScreenInfo*,XineramaQueryScreens,(Display *a, int *b),(a,b),return)
+#endif
+
+/* XInput2 support for multiple mice, tablets, etc. */
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+SDL_X11_MODULE(XINPUT2)
+SDL_X11_SYM(XIDeviceInfo*,XIQueryDevice,(Display *a,int b,int *c),(a,b,c),return)
+SDL_X11_SYM(void,XIFreeDeviceInfo,(XIDeviceInfo *a),(a),)
+SDL_X11_SYM(int,XISelectEvents,(Display *a,Window b,XIEventMask *c,int d),(a,b,c,d),return)
+SDL_X11_SYM(Status,XIQueryVersion,(Display *a,int *b,int *c),(a,b,c),return)
+SDL_X11_SYM(XIEventMask*,XIGetSelectedEvents,(Display *a,Window b,int *c),(a,b,c),return)
+#endif
+
+/* XRandR support */
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+SDL_X11_MODULE(XRANDR)
+SDL_X11_SYM(Status,XRRQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return)
+SDL_X11_SYM(XRRScreenConfiguration *,XRRGetScreenInfo,(Display *dpy,Drawable draw),(dpy,draw),return)
+SDL_X11_SYM(SizeID,XRRConfigCurrentConfiguration,(XRRScreenConfiguration *config,Rotation *rotation),(config,rotation),return)
+SDL_X11_SYM(short,XRRConfigCurrentRate,(XRRScreenConfiguration *config),(config),return)
+SDL_X11_SYM(short *,XRRConfigRates,(XRRScreenConfiguration *config,int sizeID,int *nrates),(config,sizeID,nrates),return)
+SDL_X11_SYM(XRRScreenSize *,XRRConfigSizes,(XRRScreenConfiguration *config,int *nsizes),(config,nsizes),return)
+SDL_X11_SYM(Status,XRRSetScreenConfigAndRate,(Display *dpy,XRRScreenConfiguration *config,Drawable draw,int size_index,Rotation rotation,short rate,Time timestamp),(dpy,config,draw,size_index,rotation,rate,timestamp),return)
+SDL_X11_SYM(void,XRRFreeScreenConfigInfo,(XRRScreenConfiguration *config),(config),)
+SDL_X11_SYM(void,XRRSetScreenSize,(Display *dpy, Window window,int width, int height,int mmWidth, int mmHeight),(dpy,window,width,height,mmWidth,mmHeight),)
+SDL_X11_SYM(Status,XRRGetScreenSizeRange,(Display *dpy, Window window,int *minWidth, int *minHeight, int *maxWidth, int *maxHeight),(dpy,window,minWidth,minHeight,maxWidth,maxHeight),return)
+SDL_X11_SYM(XRRScreenResources *,XRRGetScreenResources,(Display *dpy, Window window),(dpy, window),return)
+SDL_X11_SYM(XRRScreenResources *,XRRGetScreenResourcesCurrent,(Display *dpy, Window window),(dpy, window),return)
+SDL_X11_SYM(void,XRRFreeScreenResources,(XRRScreenResources *resources),(resources),)
+SDL_X11_SYM(XRROutputInfo *,XRRGetOutputInfo,(Display *dpy, XRRScreenResources *resources, RROutput output),(dpy,resources,output),return)
+SDL_X11_SYM(void,XRRFreeOutputInfo,(XRROutputInfo *outputInfo),(outputInfo),)
+SDL_X11_SYM(XRRCrtcInfo *,XRRGetCrtcInfo,(Display *dpy, XRRScreenResources *resources, RRCrtc crtc),(dpy,resources,crtc),return)
+SDL_X11_SYM(void,XRRFreeCrtcInfo,(XRRCrtcInfo *crtcInfo),(crtcInfo),)
+SDL_X11_SYM(Status,XRRSetCrtcConfig,(Display *dpy, XRRScreenResources *resources, RRCrtc crtc, Time timestamp, int x, int y, RRMode mode, Rotation rotation, RROutput *outputs, int noutputs),(dpy,resources,crtc,timestamp,x,y,mode,rotation,outputs,noutputs),return)
+SDL_X11_SYM(Atom*,XRRListOutputProperties,(Display *dpy, RROutput output, int *nprop),(dpy,output,nprop),return)
+SDL_X11_SYM(XRRPropertyInfo*,XRRQueryOutputProperty,(Display *dpy,RROutput output, Atom property),(dpy,output,property),return)
+SDL_X11_SYM(int,XRRGetOutputProperty,(Display *dpy,RROutput output, Atom property, long offset, long length, Bool _delete, Bool pending, Atom req_type, Atom *actual_type, int *actual_format, unsigned long *nitems, unsigned long *bytes_after, unsigned char **prop),(dpy,output,property,offset,length, _delete, pending, req_type, actual_type, actual_format, nitems, bytes_after, prop),return)
+SDL_X11_SYM(RROutput,XRRGetOutputPrimary,(Display *dpy,Window window),(dpy,window),return)
+#endif
+
+/* MIT-SCREEN-SAVER support */
+#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
+SDL_X11_MODULE(XSS)
+SDL_X11_SYM(Bool,XScreenSaverQueryExtension,(Display *dpy,int *event_base,int *error_base),(dpy,event_base,error_base),return)
+SDL_X11_SYM(Status,XScreenSaverQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return)
+SDL_X11_SYM(void,XScreenSaverSuspend,(Display *dpy,Bool suspend),(dpy,suspend),return)
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XSHAPE
+SDL_X11_MODULE(XSHAPE)
+SDL_X11_SYM(void,XShapeCombineMask,(Display *dpy,Window dest,int dest_kind,int x_off,int y_off,Pixmap src,int op),(dpy,dest,dest_kind,x_off,y_off,src,op),)
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+SDL_X11_MODULE(XVIDMODE)
+SDL_X11_SYM(Bool,XF86VidModeGetAllModeLines,(Display *a,int b,int *c,XF86VidModeModeInfo ***d),(a,b,c,d),return)
+SDL_X11_SYM(Bool,XF86VidModeGetModeLine,(Display *a,int b,int *c,XF86VidModeModeLine *d),(a,b,c,d),return)
+SDL_X11_SYM(Bool,XF86VidModeGetViewPort,(Display *a,int b,int *c,int *d),(a,b,c,d),return)
+SDL_X11_SYM(Bool,XF86VidModeQueryExtension,(Display *a,int *b,int *c),(a,b,c),return)
+SDL_X11_SYM(Bool,XF86VidModeQueryVersion,(Display *a,int *b,int *c),(a,b,c),return)
+SDL_X11_SYM(Bool,XF86VidModeSwitchToMode,(Display *a,int b,XF86VidModeModeInfo *c),(a,b,c),return)
+SDL_X11_SYM(Bool,XF86VidModeLockModeSwitch,(Display *a,int b,int c),(a,b,c),return)
+#endif
+
+#undef SDL_X11_MODULE
+#undef SDL_X11_SYM
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11touch.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11touch.c
new file mode 100644
index 0000000..2d0e73b
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11touch.c
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+#include "SDL_x11touch.h"
+#include "SDL_x11xinput2.h"
+#include "../../events/SDL_touch_c.h"
+
+
+void
+X11_InitTouch(_THIS)
+{
+ if (X11_Xinput2IsMultitouchSupported()) {
+ X11_InitXinput2Multitouch(_this);
+ }
+}
+
+void
+X11_QuitTouch(_THIS)
+{
+ SDL_TouchQuit();
+}
+
+void
+X11_ResetTouch(_THIS)
+{
+ X11_QuitTouch(_this);
+ X11_InitTouch(_this);
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11touch.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11touch.h
new file mode 100644
index 0000000..5a59af0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11touch.h
@@ -0,0 +1,32 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11touch_h_
+#define SDL_x11touch_h_
+
+extern void X11_InitTouch(_THIS);
+extern void X11_QuitTouch(_THIS);
+extern void X11_ResetTouch(_THIS);
+
+#endif /* SDL_x11touch_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11video.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11video.c
new file mode 100644
index 0000000..b3b1a70
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11video.c
@@ -0,0 +1,497 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include <unistd.h> /* For getpid() and readlink() */
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_timer.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+
+#include "SDL_x11video.h"
+#include "SDL_x11framebuffer.h"
+#include "SDL_x11shape.h"
+#include "SDL_x11touch.h"
+#include "SDL_x11xinput2.h"
+
+#if SDL_VIDEO_OPENGL_EGL
+#include "SDL_x11opengles.h"
+#endif
+
+#include "SDL_x11vulkan.h"
+
+/* Initialization/Query functions */
+static int X11_VideoInit(_THIS);
+static void X11_VideoQuit(_THIS);
+
+/* Find out what class name we should use */
+static char *
+get_classname()
+{
+ char *spot;
+#if defined(__LINUX__) || defined(__FREEBSD__)
+ char procfile[1024];
+ char linkfile[1024];
+ int linksize;
+#endif
+
+ /* First allow environment variable override */
+ spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
+ if (spot) {
+ return SDL_strdup(spot);
+ }
+
+ /* Next look at the application's executable name */
+#if defined(__LINUX__) || defined(__FREEBSD__)
+#if defined(__LINUX__)
+ SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
+#elif defined(__FREEBSD__)
+ SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
+ getpid());
+#else
+#error Where can we find the executable name?
+#endif
+ linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
+ if (linksize > 0) {
+ linkfile[linksize] = '\0';
+ spot = SDL_strrchr(linkfile, '/');
+ if (spot) {
+ return SDL_strdup(spot + 1);
+ } else {
+ return SDL_strdup(linkfile);
+ }
+ }
+#endif /* __LINUX__ || __FREEBSD__ */
+
+ /* Finally use the default we've used forever */
+ return SDL_strdup("SDL_App");
+}
+
+/* X11 driver bootstrap functions */
+
+static int
+X11_Available(void)
+{
+ Display *display = NULL;
+ if (SDL_X11_LoadSymbols()) {
+ display = X11_XOpenDisplay(NULL);
+ if (display != NULL) {
+ X11_XCloseDisplay(display);
+ }
+ SDL_X11_UnloadSymbols();
+ }
+ return (display != NULL);
+}
+
+static void
+X11_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
+ if (device->vulkan_config.loader_handle) {
+ device->Vulkan_UnloadLibrary(device);
+ }
+ if (data->display) {
+ X11_XCloseDisplay(data->display);
+ }
+ SDL_free(data->windowlist);
+ SDL_free(device->driverdata);
+ SDL_free(device);
+
+ SDL_X11_UnloadSymbols();
+}
+
+/* An error handler to reset the vidmode and then call the default handler. */
+static SDL_bool safety_net_triggered = SDL_FALSE;
+static int (*orig_x11_errhandler) (Display *, XErrorEvent *) = NULL;
+static int
+X11_SafetyNetErrHandler(Display * d, XErrorEvent * e)
+{
+ SDL_VideoDevice *device = NULL;
+ /* if we trigger an error in our error handler, don't try again. */
+ if (!safety_net_triggered) {
+ safety_net_triggered = SDL_TRUE;
+ device = SDL_GetVideoDevice();
+ if (device != NULL) {
+ int i;
+ for (i = 0; i < device->num_displays; i++) {
+ SDL_VideoDisplay *display = &device->displays[i];
+ if (SDL_memcmp(&display->current_mode, &display->desktop_mode,
+ sizeof (SDL_DisplayMode)) != 0) {
+ X11_SetDisplayMode(device, display, &display->desktop_mode);
+ }
+ }
+ }
+ }
+
+ if (orig_x11_errhandler != NULL) {
+ return orig_x11_errhandler(d, e); /* probably terminate. */
+ }
+
+ return 0;
+}
+
+static SDL_VideoDevice *
+X11_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+ const char *display = NULL; /* Use the DISPLAY environment variable */
+
+ if (!SDL_X11_LoadSymbols()) {
+ return NULL;
+ }
+
+ /* Need for threading gl calls. This is also required for the proprietary
+ nVidia driver to be threaded. */
+ X11_XInitThreads();
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (!data) {
+ SDL_free(device);
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ device->driverdata = data;
+
+ data->global_mouse_changed = SDL_TRUE;
+
+ /* FIXME: Do we need this?
+ if ( (SDL_strncmp(X11_XDisplayName(display), ":", 1) == 0) ||
+ (SDL_strncmp(X11_XDisplayName(display), "unix:", 5) == 0) ) {
+ local_X11 = 1;
+ } else {
+ local_X11 = 0;
+ }
+ */
+ data->display = X11_XOpenDisplay(display);
+#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+ /* On some systems if linking without -lX11, it fails and you get following message.
+ * Xlib: connection to ":0.0" refused by server
+ * Xlib: XDM authorization key matches an existing client!
+ *
+ * It succeeds if retrying 1 second later
+ * or if running xhost +localhost on shell.
+ */
+ if (data->display == NULL) {
+ SDL_Delay(1000);
+ data->display = X11_XOpenDisplay(display);
+ }
+#endif
+ if (data->display == NULL) {
+ SDL_free(device->driverdata);
+ SDL_free(device);
+ SDL_SetError("Couldn't open X11 display");
+ return NULL;
+ }
+#ifdef X11_DEBUG
+ X11_XSynchronize(data->display, True);
+#endif
+
+ /* Hook up an X11 error handler to recover the desktop resolution. */
+ safety_net_triggered = SDL_FALSE;
+ orig_x11_errhandler = X11_XSetErrorHandler(X11_SafetyNetErrHandler);
+
+ /* Set the function pointers */
+ device->VideoInit = X11_VideoInit;
+ device->VideoQuit = X11_VideoQuit;
+ device->ResetTouch = X11_ResetTouch;
+ device->GetDisplayModes = X11_GetDisplayModes;
+ device->GetDisplayBounds = X11_GetDisplayBounds;
+ device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds;
+ device->GetDisplayDPI = X11_GetDisplayDPI;
+ device->SetDisplayMode = X11_SetDisplayMode;
+ device->SuspendScreenSaver = X11_SuspendScreenSaver;
+ device->PumpEvents = X11_PumpEvents;
+
+ device->CreateSDLWindow = X11_CreateWindow;
+ device->CreateSDLWindowFrom = X11_CreateWindowFrom;
+ device->SetWindowTitle = X11_SetWindowTitle;
+ device->SetWindowIcon = X11_SetWindowIcon;
+ device->SetWindowPosition = X11_SetWindowPosition;
+ device->SetWindowSize = X11_SetWindowSize;
+ device->SetWindowMinimumSize = X11_SetWindowMinimumSize;
+ device->SetWindowMaximumSize = X11_SetWindowMaximumSize;
+ device->GetWindowBordersSize = X11_GetWindowBordersSize;
+ device->SetWindowOpacity = X11_SetWindowOpacity;
+ device->SetWindowModalFor = X11_SetWindowModalFor;
+ device->SetWindowInputFocus = X11_SetWindowInputFocus;
+ device->ShowWindow = X11_ShowWindow;
+ device->HideWindow = X11_HideWindow;
+ device->RaiseWindow = X11_RaiseWindow;
+ device->MaximizeWindow = X11_MaximizeWindow;
+ device->MinimizeWindow = X11_MinimizeWindow;
+ device->RestoreWindow = X11_RestoreWindow;
+ device->SetWindowBordered = X11_SetWindowBordered;
+ device->SetWindowResizable = X11_SetWindowResizable;
+ device->SetWindowFullscreen = X11_SetWindowFullscreen;
+ device->SetWindowGammaRamp = X11_SetWindowGammaRamp;
+ device->SetWindowGrab = X11_SetWindowGrab;
+ device->DestroyWindow = X11_DestroyWindow;
+ device->CreateWindowFramebuffer = X11_CreateWindowFramebuffer;
+ device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer;
+ device->DestroyWindowFramebuffer = X11_DestroyWindowFramebuffer;
+ device->GetWindowWMInfo = X11_GetWindowWMInfo;
+ device->SetWindowHitTest = X11_SetWindowHitTest;
+ device->AcceptDragAndDrop = X11_AcceptDragAndDrop;
+
+ device->shape_driver.CreateShaper = X11_CreateShaper;
+ device->shape_driver.SetWindowShape = X11_SetWindowShape;
+ device->shape_driver.ResizeWindowShape = X11_ResizeWindowShape;
+
+#if SDL_VIDEO_OPENGL_GLX
+ device->GL_LoadLibrary = X11_GL_LoadLibrary;
+ device->GL_GetProcAddress = X11_GL_GetProcAddress;
+ device->GL_UnloadLibrary = X11_GL_UnloadLibrary;
+ device->GL_CreateContext = X11_GL_CreateContext;
+ device->GL_MakeCurrent = X11_GL_MakeCurrent;
+ device->GL_SetSwapInterval = X11_GL_SetSwapInterval;
+ device->GL_GetSwapInterval = X11_GL_GetSwapInterval;
+ device->GL_SwapWindow = X11_GL_SwapWindow;
+ device->GL_DeleteContext = X11_GL_DeleteContext;
+#elif SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = X11_GLES_LoadLibrary;
+ device->GL_GetProcAddress = X11_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
+ device->GL_CreateContext = X11_GLES_CreateContext;
+ device->GL_MakeCurrent = X11_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = X11_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = X11_GLES_GetSwapInterval;
+ device->GL_SwapWindow = X11_GLES_SwapWindow;
+ device->GL_DeleteContext = X11_GLES_DeleteContext;
+#endif
+
+ device->SetClipboardText = X11_SetClipboardText;
+ device->GetClipboardText = X11_GetClipboardText;
+ device->HasClipboardText = X11_HasClipboardText;
+ device->StartTextInput = X11_StartTextInput;
+ device->StopTextInput = X11_StopTextInput;
+ device->SetTextInputRect = X11_SetTextInputRect;
+
+ device->free = X11_DeleteDevice;
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = X11_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = X11_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions = X11_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = X11_Vulkan_CreateSurface;
+#endif
+
+ return device;
+}
+
+VideoBootStrap X11_bootstrap = {
+ "x11", "SDL X11 video driver",
+ X11_Available, X11_CreateDevice
+};
+
+static int (*handler) (Display *, XErrorEvent *) = NULL;
+static int
+X11_CheckWindowManagerErrorHandler(Display * d, XErrorEvent * e)
+{
+ if (e->error_code == BadWindow) {
+ return (0);
+ } else {
+ return (handler(d, e));
+ }
+}
+
+static void
+X11_CheckWindowManager(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ Display *display = data->display;
+ Atom _NET_SUPPORTING_WM_CHECK;
+ int status, real_format;
+ Atom real_type;
+ unsigned long items_read = 0, items_left = 0;
+ unsigned char *propdata = NULL;
+ Window wm_window = 0;
+#ifdef DEBUG_WINDOW_MANAGER
+ char *wm_name;
+#endif
+
+ /* Set up a handler to gracefully catch errors */
+ X11_XSync(display, False);
+ handler = X11_XSetErrorHandler(X11_CheckWindowManagerErrorHandler);
+
+ _NET_SUPPORTING_WM_CHECK = X11_XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
+ status = X11_XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
+ if (status == Success) {
+ if (items_read) {
+ wm_window = ((Window*)propdata)[0];
+ }
+ if (propdata) {
+ X11_XFree(propdata);
+ propdata = NULL;
+ }
+ }
+
+ if (wm_window) {
+ status = X11_XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
+ if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) {
+ wm_window = None;
+ }
+ if (status == Success && propdata) {
+ X11_XFree(propdata);
+ propdata = NULL;
+ }
+ }
+
+ /* Reset the error handler, we're done checking */
+ X11_XSync(display, False);
+ X11_XSetErrorHandler(handler);
+
+ if (!wm_window) {
+#ifdef DEBUG_WINDOW_MANAGER
+ printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n");
+#endif
+ return;
+ }
+ data->net_wm = SDL_TRUE;
+
+#ifdef DEBUG_WINDOW_MANAGER
+ wm_name = X11_GetWindowTitle(_this, wm_window);
+ printf("Window manager: %s\n", wm_name);
+ SDL_free(wm_name);
+#endif
+}
+
+
+int
+X11_VideoInit(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ /* Get the window class name, usually the name of the application */
+ data->classname = get_classname();
+
+ /* Get the process PID to be associated to the window */
+ data->pid = getpid();
+
+ /* I have no idea how random this actually is, or has to be. */
+ data->window_group = (XID) (((size_t) data->pid) ^ ((size_t) _this));
+
+ /* Look up some useful Atoms */
+#define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False)
+ GET_ATOM(WM_PROTOCOLS);
+ GET_ATOM(WM_DELETE_WINDOW);
+ GET_ATOM(WM_TAKE_FOCUS);
+ GET_ATOM(_NET_WM_STATE);
+ GET_ATOM(_NET_WM_STATE_HIDDEN);
+ GET_ATOM(_NET_WM_STATE_FOCUSED);
+ GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
+ GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
+ GET_ATOM(_NET_WM_STATE_FULLSCREEN);
+ GET_ATOM(_NET_WM_STATE_ABOVE);
+ GET_ATOM(_NET_WM_STATE_SKIP_TASKBAR);
+ GET_ATOM(_NET_WM_STATE_SKIP_PAGER);
+ GET_ATOM(_NET_WM_ALLOWED_ACTIONS);
+ GET_ATOM(_NET_WM_ACTION_FULLSCREEN);
+ GET_ATOM(_NET_WM_NAME);
+ GET_ATOM(_NET_WM_ICON_NAME);
+ GET_ATOM(_NET_WM_ICON);
+ GET_ATOM(_NET_WM_PING);
+ GET_ATOM(_NET_WM_WINDOW_OPACITY);
+ GET_ATOM(_NET_WM_USER_TIME);
+ GET_ATOM(_NET_ACTIVE_WINDOW);
+ GET_ATOM(_NET_FRAME_EXTENTS);
+ GET_ATOM(UTF8_STRING);
+ GET_ATOM(PRIMARY);
+ GET_ATOM(XdndEnter);
+ GET_ATOM(XdndPosition);
+ GET_ATOM(XdndStatus);
+ GET_ATOM(XdndTypeList);
+ GET_ATOM(XdndActionCopy);
+ GET_ATOM(XdndDrop);
+ GET_ATOM(XdndFinished);
+ GET_ATOM(XdndSelection);
+ GET_ATOM(XKLAVIER_STATE);
+
+ /* Detect the window manager */
+ X11_CheckWindowManager(_this);
+
+ if (X11_InitModes(_this) < 0) {
+ return -1;
+ }
+
+ X11_InitXinput2(_this);
+
+ if (X11_InitKeyboard(_this) != 0) {
+ return -1;
+ }
+ X11_InitMouse(_this);
+
+ X11_InitTouch(_this);
+
+#if SDL_USE_LIBDBUS
+ SDL_DBus_Init();
+#endif
+
+ return 0;
+}
+
+void
+X11_VideoQuit(_THIS)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (data->clipboard_window) {
+ X11_XDestroyWindow(data->display, data->clipboard_window);
+ }
+
+ SDL_free(data->classname);
+#ifdef X_HAVE_UTF8_STRING
+ if (data->im) {
+ X11_XCloseIM(data->im);
+ }
+#endif
+
+ X11_QuitModes(_this);
+ X11_QuitKeyboard(_this);
+ X11_QuitMouse(_this);
+ X11_QuitTouch(_this);
+
+/* !!! FIXME: other subsystems use D-Bus, so we shouldn't quit it here;
+ have SDL.c do this at a higher level, or add refcounting. */
+#if SDL_USE_LIBDBUS
+ SDL_DBus_Quit();
+#endif
+}
+
+SDL_bool
+X11_UseDirectColorVisuals(void)
+{
+ return SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ? SDL_FALSE : SDL_TRUE;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11video.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11video.h
new file mode 100644
index 0000000..c0dc08e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11video.h
@@ -0,0 +1,156 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11video_h_
+#define SDL_x11video_h_
+
+#include "SDL_keycode.h"
+
+#include "../SDL_sysvideo.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#if SDL_VIDEO_DRIVER_X11_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER
+#include <X11/extensions/scrnsaver.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XSHAPE
+#include <X11/extensions/shape.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+#include <X11/extensions/xf86vmode.h>
+#endif
+
+#include "../../core/linux/SDL_dbus.h"
+#include "../../core/linux/SDL_ime.h"
+
+#include "SDL_x11dyn.h"
+
+#include "SDL_x11clipboard.h"
+#include "SDL_x11events.h"
+#include "SDL_x11keyboard.h"
+#include "SDL_x11modes.h"
+#include "SDL_x11mouse.h"
+#include "SDL_x11opengl.h"
+#include "SDL_x11window.h"
+#include "SDL_x11vulkan.h"
+
+/* Private display data */
+
+typedef struct SDL_VideoData
+{
+ Display *display;
+ char *classname;
+ pid_t pid;
+ XIM im;
+ Uint32 screensaver_activity;
+ int numwindows;
+ SDL_WindowData **windowlist;
+ int windowlistlength;
+ XID window_group;
+ Window clipboard_window;
+
+ /* This is true for ICCCM2.0-compliant window managers */
+ SDL_bool net_wm;
+
+ /* Useful atoms */
+ Atom WM_PROTOCOLS;
+ Atom WM_DELETE_WINDOW;
+ Atom WM_TAKE_FOCUS;
+ Atom _NET_WM_STATE;
+ Atom _NET_WM_STATE_HIDDEN;
+ Atom _NET_WM_STATE_FOCUSED;
+ Atom _NET_WM_STATE_MAXIMIZED_VERT;
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ;
+ Atom _NET_WM_STATE_FULLSCREEN;
+ Atom _NET_WM_STATE_ABOVE;
+ Atom _NET_WM_STATE_SKIP_TASKBAR;
+ Atom _NET_WM_STATE_SKIP_PAGER;
+ Atom _NET_WM_ALLOWED_ACTIONS;
+ Atom _NET_WM_ACTION_FULLSCREEN;
+ Atom _NET_WM_NAME;
+ Atom _NET_WM_ICON_NAME;
+ Atom _NET_WM_ICON;
+ Atom _NET_WM_PING;
+ Atom _NET_WM_WINDOW_OPACITY;
+ Atom _NET_WM_USER_TIME;
+ Atom _NET_ACTIVE_WINDOW;
+ Atom _NET_FRAME_EXTENTS;
+ Atom UTF8_STRING;
+ Atom PRIMARY;
+ Atom XdndEnter;
+ Atom XdndPosition;
+ Atom XdndStatus;
+ Atom XdndTypeList;
+ Atom XdndActionCopy;
+ Atom XdndDrop;
+ Atom XdndFinished;
+ Atom XdndSelection;
+ Atom XKLAVIER_STATE;
+
+ SDL_Scancode key_layout[256];
+ SDL_bool selection_waiting;
+
+ SDL_bool broken_pointer_grab; /* true if XGrabPointer seems unreliable. */
+
+ Uint32 last_mode_change_deadline;
+
+ SDL_bool global_mouse_changed;
+ SDL_Point global_mouse_position;
+ Uint32 global_mouse_buttons;
+
+#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
+ XkbDescPtr xkb;
+#endif
+
+ KeyCode filter_code;
+ Time filter_time;
+
+#if SDL_VIDEO_VULKAN
+ /* Vulkan variables only valid if _this->vulkan_config.loader_handle is not NULL */
+ void *vulkan_xlib_xcb_library;
+ PFN_XGetXCBConnection vulkan_XGetXCBConnection;
+#endif
+
+} SDL_VideoData;
+
+extern SDL_bool X11_UseDirectColorVisuals(void);
+
+#endif /* SDL_x11video_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.c
new file mode 100644
index 0000000..ec43aef
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.c
@@ -0,0 +1,243 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_x11vulkan.h"
+
+#include <X11/Xlib.h>
+/*#include <xcb/xcb.h>*/
+/*
+typedef uint32_t xcb_window_t;
+typedef uint32_t xcb_visualid_t;
+*/
+
+int X11_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+ VkExtensionProperties *extensions = NULL;
+ Uint32 extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasXlibSurfaceExtension = SDL_FALSE;
+ SDL_bool hasXCBSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+ Uint32 i;
+ if(_this->vulkan_config.loader_handle)
+ return SDL_SetError("Vulkan already loaded");
+
+ /* Load the Vulkan loader library */
+ if(!path)
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ if(!path)
+ path = "libvulkan.so.1";
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if(!_this->vulkan_config.loader_handle)
+ return -1;
+ SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+ if(!vkGetInstanceProcAddr)
+ goto fail;
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+ if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
+ goto fail;
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+ if(!extensions)
+ goto fail;
+ for(i = 0; i < extensionCount; i++)
+ {
+ if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasSurfaceExtension = SDL_TRUE;
+ else if(SDL_strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasXCBSurfaceExtension = SDL_TRUE;
+ else if(SDL_strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+ hasXlibSurfaceExtension = SDL_TRUE;
+ }
+ SDL_free(extensions);
+ if(!hasSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ }
+ if(hasXlibSurfaceExtension)
+ {
+ videoData->vulkan_xlib_xcb_library = NULL;
+ }
+ else if(!hasXCBSurfaceExtension)
+ {
+ SDL_SetError("Installed Vulkan doesn't implement either the "
+ VK_KHR_XCB_SURFACE_EXTENSION_NAME "extension or the "
+ VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ }
+ else
+ {
+ const char *libX11XCBLibraryName = SDL_getenv("SDL_X11_XCB_LIBRARY");
+ if(!libX11XCBLibraryName)
+ libX11XCBLibraryName = "libX11-xcb.so";
+ videoData->vulkan_xlib_xcb_library = SDL_LoadObject(libX11XCBLibraryName);
+ if(!videoData->vulkan_xlib_xcb_library)
+ goto fail;
+ videoData->vulkan_XGetXCBConnection =
+ SDL_LoadFunction(videoData->vulkan_xlib_xcb_library, "XGetXCBConnection");
+ if(!videoData->vulkan_XGetXCBConnection)
+ {
+ SDL_UnloadObject(videoData->vulkan_xlib_xcb_library);
+ goto fail;
+ }
+ }
+ return 0;
+
+fail:
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void X11_Vulkan_UnloadLibrary(_THIS)
+{
+ SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+ if(_this->vulkan_config.loader_handle)
+ {
+ if(videoData->vulkan_xlib_xcb_library)
+ SDL_UnloadObject(videoData->vulkan_xlib_xcb_library);
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ if(videoData->vulkan_xlib_xcb_library)
+ {
+ static const char *const extensionsForXCB[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+ };
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForXCB), extensionsForXCB);
+ }
+ else
+ {
+ static const char *const extensionsForXlib[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+ };
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForXlib), extensionsForXlib);
+ }
+}
+
+SDL_bool X11_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
+ SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ if(!_this->vulkan_config.loader_handle)
+ {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ if(videoData->vulkan_xlib_xcb_library)
+ {
+ PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR =
+ (PFN_vkCreateXcbSurfaceKHR)vkGetInstanceProcAddr((VkInstance)instance,
+ "vkCreateXcbSurfaceKHR");
+ VkXcbSurfaceCreateInfoKHR createInfo;
+ VkResult result;
+ if(!vkCreateXcbSurfaceKHR)
+ {
+ SDL_SetError(VK_KHR_XCB_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ SDL_zero(createInfo);
+ createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+ createInfo.connection = videoData->vulkan_XGetXCBConnection(videoData->display);
+ if(!createInfo.connection)
+ {
+ SDL_SetError("XGetXCBConnection failed");
+ return SDL_FALSE;
+ }
+ createInfo.window = (xcb_window_t)windowData->xwindow;
+ result = vkCreateXcbSurfaceKHR(instance, &createInfo,
+ NULL, surface);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+ }
+ else
+ {
+ PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR =
+ (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr((VkInstance)instance,
+ "vkCreateXlibSurfaceKHR");
+ VkXlibSurfaceCreateInfoKHR createInfo;
+ VkResult result;
+ if(!vkCreateXlibSurfaceKHR)
+ {
+ SDL_SetError(VK_KHR_XLIB_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+ SDL_zero(createInfo);
+ createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
+ createInfo.dpy = videoData->display;
+ createInfo.window = (xcb_window_t)windowData->xwindow;
+ result = vkCreateXlibSurfaceKHR(instance, &createInfo,
+ NULL, surface);
+ if(result != VK_SUCCESS)
+ {
+ SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+ }
+}
+
+#endif
+
+/* vim: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.h
new file mode 100644
index 0000000..152d9d7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11vulkan.h
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11vulkan_h_
+#define SDL_x11vulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_X11
+
+/*typedef struct xcb_connection_t xcb_connection_t;*/
+typedef xcb_connection_t *(*PFN_XGetXCBConnection)(Display *dpy);
+
+int X11_Vulkan_LoadLibrary(_THIS, const char *path);
+void X11_Vulkan_UnloadLibrary(_THIS);
+SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool X11_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+#endif
+
+#endif /* SDL_x11vulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11window.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11window.c
new file mode 100644
index 0000000..0a254b0
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11window.c
@@ -0,0 +1,1619 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
+
+#include "SDL_x11video.h"
+#include "SDL_x11mouse.h"
+#include "SDL_x11shape.h"
+#include "SDL_x11xinput2.h"
+
+#if SDL_VIDEO_OPENGL_EGL
+#include "SDL_x11opengles.h"
+#endif
+
+#include "SDL_timer.h"
+#include "SDL_syswm.h"
+#include "SDL_log.h"
+
+#define _NET_WM_STATE_REMOVE 0l
+#define _NET_WM_STATE_ADD 1l
+
+static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win)
+{
+ return ev->type == MapNotify && ev->xmap.window == *((Window*)win);
+}
+static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win)
+{
+ return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win);
+}
+
+/*
+static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
+{
+ return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win);
+}
+static Bool
+X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS)
+{
+ Uint32 start = SDL_GetTicks();
+
+ while (!X11_XCheckIfEvent(display, event_return, predicate, arg)) {
+ if (SDL_TICKS_PASSED(SDL_GetTicks(), start + timeoutMS)) {
+ return False;
+ }
+ }
+ return True;
+}
+*/
+
+static SDL_bool
+X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ return (data->fswindow != 0);
+}
+
+static SDL_bool
+X11_IsWindowMapped(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ XWindowAttributes attr;
+
+ X11_XGetWindowAttributes(videodata->display, data->xwindow, &attr);
+ if (attr.map_state != IsUnmapped) {
+ return SDL_TRUE;
+ } else {
+ return SDL_FALSE;
+ }
+}
+
+#if 0
+static SDL_bool
+X11_IsActionAllowed(SDL_Window *window, Atom action)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS;
+ Atom type;
+ Display *display = data->videodata->display;
+ int form;
+ unsigned long remain;
+ unsigned long len, i;
+ Atom *list;
+ SDL_bool ret = SDL_FALSE;
+
+ if (X11_XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success)
+ {
+ for (i=0; i<len; ++i)
+ {
+ if (list[i] == action) {
+ ret = SDL_TRUE;
+ break;
+ }
+ }
+ X11_XFree(list);
+ }
+ return ret;
+}
+#endif /* 0 */
+
+void
+X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ Display *display = videodata->display;
+ /* !!! FIXME: just dereference videodata below instead of copying to locals. */
+ Atom _NET_WM_STATE = videodata->_NET_WM_STATE;
+ /* Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; */
+ Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED;
+ Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT;
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
+ Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN;
+ Atom _NET_WM_STATE_ABOVE = videodata->_NET_WM_STATE_ABOVE;
+ Atom _NET_WM_STATE_SKIP_TASKBAR = videodata->_NET_WM_STATE_SKIP_TASKBAR;
+ Atom _NET_WM_STATE_SKIP_PAGER = videodata->_NET_WM_STATE_SKIP_PAGER;
+ Atom atoms[16];
+ int count = 0;
+
+ /* The window manager sets this property, we shouldn't set it.
+ If we did, this would indicate to the window manager that we don't
+ actually want to be mapped during X11_XMapRaised(), which would be bad.
+ *
+ if (flags & SDL_WINDOW_HIDDEN) {
+ atoms[count++] = _NET_WM_STATE_HIDDEN;
+ }
+ */
+
+ if (flags & SDL_WINDOW_ALWAYS_ON_TOP) {
+ atoms[count++] = _NET_WM_STATE_ABOVE;
+ }
+ if (flags & SDL_WINDOW_SKIP_TASKBAR) {
+ atoms[count++] = _NET_WM_STATE_SKIP_TASKBAR;
+ atoms[count++] = _NET_WM_STATE_SKIP_PAGER;
+ }
+ if (flags & SDL_WINDOW_INPUT_FOCUS) {
+ atoms[count++] = _NET_WM_STATE_FOCUSED;
+ }
+ if (flags & SDL_WINDOW_MAXIMIZED) {
+ atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
+ atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
+ }
+ if (flags & SDL_WINDOW_FULLSCREEN) {
+ atoms[count++] = _NET_WM_STATE_FULLSCREEN;
+ }
+
+ SDL_assert(count <= SDL_arraysize(atoms));
+
+ if (count > 0) {
+ X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)atoms, count);
+ } else {
+ X11_XDeleteProperty(display, xwindow, _NET_WM_STATE);
+ }
+}
+
+Uint32
+X11_GetNetWMState(_THIS, Window xwindow)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ Display *display = videodata->display;
+ Atom _NET_WM_STATE = videodata->_NET_WM_STATE;
+ Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN;
+ Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED;
+ Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT;
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
+ Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN;
+ Atom actualType;
+ int actualFormat;
+ unsigned long i, numItems, bytesAfter;
+ unsigned char *propertyValue = NULL;
+ long maxLength = 1024;
+ Uint32 flags = 0;
+
+ if (X11_XGetWindowProperty(display, xwindow, _NET_WM_STATE,
+ 0l, maxLength, False, XA_ATOM, &actualType,
+ &actualFormat, &numItems, &bytesAfter,
+ &propertyValue) == Success) {
+ Atom *atoms = (Atom *) propertyValue;
+ int maximized = 0;
+ int fullscreen = 0;
+
+ for (i = 0; i < numItems; ++i) {
+ if (atoms[i] == _NET_WM_STATE_HIDDEN) {
+ flags |= SDL_WINDOW_HIDDEN;
+ } else if (atoms[i] == _NET_WM_STATE_FOCUSED) {
+ flags |= SDL_WINDOW_INPUT_FOCUS;
+ } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
+ maximized |= 1;
+ } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
+ maximized |= 2;
+ } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
+ fullscreen = 1;
+ }
+ }
+ if (maximized == 3) {
+ flags |= SDL_WINDOW_MAXIMIZED;
+ }
+
+ if (fullscreen == 1) {
+ flags |= SDL_WINDOW_FULLSCREEN;
+ }
+
+ /* If the window is unmapped, numItems will be zero and _NET_WM_STATE_HIDDEN
+ * will not be set. Do an additional check to see if the window is unmapped
+ * and mark it as SDL_WINDOW_HIDDEN if it is.
+ */
+ {
+ XWindowAttributes attr;
+ SDL_memset(&attr,0,sizeof(attr));
+ X11_XGetWindowAttributes(videodata->display, xwindow, &attr);
+ if (attr.map_state == IsUnmapped) {
+ flags |= SDL_WINDOW_HIDDEN;
+ }
+ }
+ X11_XFree(propertyValue);
+ }
+
+ /* FIXME, check the size hints for resizable */
+ /* flags |= SDL_WINDOW_RESIZABLE; */
+
+ return flags;
+}
+
+static int
+SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ SDL_WindowData *data;
+ int numwindows = videodata->numwindows;
+ int windowlistlength = videodata->windowlistlength;
+ SDL_WindowData **windowlist = videodata->windowlist;
+
+ /* Allocate the window data */
+ data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+ data->window = window;
+ data->xwindow = w;
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8 && videodata->im) {
+ data->ic =
+ X11_XCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w,
+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ NULL);
+ }
+#endif
+ data->created = created;
+ data->videodata = videodata;
+
+ /* Associate the data with the window */
+
+ if (numwindows < windowlistlength) {
+ windowlist[numwindows] = data;
+ videodata->numwindows++;
+ } else {
+ windowlist =
+ (SDL_WindowData **) SDL_realloc(windowlist,
+ (numwindows +
+ 1) * sizeof(*windowlist));
+ if (!windowlist) {
+ SDL_free(data);
+ return SDL_OutOfMemory();
+ }
+ windowlist[numwindows] = data;
+ videodata->numwindows++;
+ videodata->windowlistlength++;
+ videodata->windowlist = windowlist;
+ }
+
+ /* Fill in the SDL window with the window data */
+ {
+ XWindowAttributes attrib;
+
+ X11_XGetWindowAttributes(data->videodata->display, w, &attrib);
+ window->x = attrib.x;
+ window->y = attrib.y;
+ window->w = attrib.width;
+ window->h = attrib.height;
+ if (attrib.map_state != IsUnmapped) {
+ window->flags |= SDL_WINDOW_SHOWN;
+ } else {
+ window->flags &= ~SDL_WINDOW_SHOWN;
+ }
+ data->visual = attrib.visual;
+ data->colormap = attrib.colormap;
+ }
+
+ window->flags |= X11_GetNetWMState(_this, w);
+
+ {
+ Window FocalWindow;
+ int RevertTo=0;
+ X11_XGetInputFocus(data->videodata->display, &FocalWindow, &RevertTo);
+ if (FocalWindow==w)
+ {
+ window->flags |= SDL_WINDOW_INPUT_FOCUS;
+ }
+
+ if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
+ SDL_SetKeyboardFocus(data->window);
+ }
+
+ if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
+ /* Tell x11 to clip mouse */
+ }
+ }
+
+ /* All done! */
+ window->driverdata = data;
+ return 0;
+}
+
+static void
+SetWindowBordered(Display *display, int screen, Window window, SDL_bool border)
+{
+ /*
+ * this code used to check for KWM_WIN_DECORATION, but KDE hasn't
+ * supported it for years and years. It now respects _MOTIF_WM_HINTS.
+ * Gnome is similar: just use the Motif atom.
+ */
+
+ Atom WM_HINTS = X11_XInternAtom(display, "_MOTIF_WM_HINTS", True);
+ if (WM_HINTS != None) {
+ /* Hints used by Motif compliant window managers */
+ struct
+ {
+ unsigned long flags;
+ unsigned long functions;
+ unsigned long decorations;
+ long input_mode;
+ unsigned long status;
+ } MWMHints = {
+ (1L << 1), 0, border ? 1 : 0, 0, 0
+ };
+
+ X11_XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32,
+ PropModeReplace, (unsigned char *) &MWMHints,
+ sizeof(MWMHints) / sizeof(long));
+ } else { /* set the transient hints instead, if necessary */
+ X11_XSetTransientForHint(display, window, RootWindow(display, screen));
+ }
+}
+
+int
+X11_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ SDL_DisplayData *displaydata =
+ (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ SDL_WindowData *windowdata;
+ Display *display = data->display;
+ int screen = displaydata->screen;
+ Visual *visual;
+ int depth;
+ XSetWindowAttributes xattr;
+ Window w;
+ XSizeHints *sizehints;
+ XWMHints *wmhints;
+ XClassHint *classhints;
+ Atom _NET_WM_BYPASS_COMPOSITOR;
+ Atom _NET_WM_WINDOW_TYPE;
+ Atom wintype;
+ const char *wintype_name = NULL;
+ long compositor = 1;
+ Atom _NET_WM_PID;
+ long fevent = 0;
+
+#if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL
+ if ((window->flags & SDL_WINDOW_OPENGL) &&
+ !SDL_getenv("SDL_VIDEO_X11_VISUALID")) {
+ XVisualInfo *vinfo = NULL;
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES
+#if SDL_VIDEO_OPENGL_GLX
+ && ( !_this->gl_data || X11_GL_UseEGL(_this) )
+#endif
+ ) {
+ vinfo = X11_GLES_GetVisual(_this, display, screen);
+ } else
+#endif
+ {
+#if SDL_VIDEO_OPENGL_GLX
+ vinfo = X11_GL_GetVisual(_this, display, screen);
+#endif
+ }
+
+ if (!vinfo) {
+ return -1;
+ }
+ visual = vinfo->visual;
+ depth = vinfo->depth;
+ X11_XFree(vinfo);
+ } else
+#endif
+ {
+ visual = displaydata->visual;
+ depth = displaydata->depth;
+ }
+
+ xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False;
+ xattr.background_pixmap = None;
+ xattr.border_pixel = 0;
+
+ if (visual->class == DirectColor) {
+ XColor *colorcells;
+ int i;
+ int ncolors;
+ int rmax, gmax, bmax;
+ int rmask, gmask, bmask;
+ int rshift, gshift, bshift;
+
+ xattr.colormap =
+ X11_XCreateColormap(display, RootWindow(display, screen),
+ visual, AllocAll);
+
+ /* If we can't create a colormap, then we must die */
+ if (!xattr.colormap) {
+ return SDL_SetError("Could not create writable colormap");
+ }
+
+ /* OK, we got a colormap, now fill it in as best as we can */
+ colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
+ if (!colorcells) {
+ return SDL_OutOfMemory();
+ }
+ ncolors = visual->map_entries;
+ rmax = 0xffff;
+ gmax = 0xffff;
+ bmax = 0xffff;
+
+ rshift = 0;
+ rmask = visual->red_mask;
+ while (0 == (rmask & 1)) {
+ rshift++;
+ rmask >>= 1;
+ }
+
+ gshift = 0;
+ gmask = visual->green_mask;
+ while (0 == (gmask & 1)) {
+ gshift++;
+ gmask >>= 1;
+ }
+
+ bshift = 0;
+ bmask = visual->blue_mask;
+ while (0 == (bmask & 1)) {
+ bshift++;
+ bmask >>= 1;
+ }
+
+ /* build the color table pixel values */
+ for (i = 0; i < ncolors; i++) {
+ Uint32 red = (rmax * i) / (ncolors - 1);
+ Uint32 green = (gmax * i) / (ncolors - 1);
+ Uint32 blue = (bmax * i) / (ncolors - 1);
+
+ Uint32 rbits = (rmask * i) / (ncolors - 1);
+ Uint32 gbits = (gmask * i) / (ncolors - 1);
+ Uint32 bbits = (bmask * i) / (ncolors - 1);
+
+ Uint32 pix =
+ (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
+
+ colorcells[i].pixel = pix;
+
+ colorcells[i].red = red;
+ colorcells[i].green = green;
+ colorcells[i].blue = blue;
+
+ colorcells[i].flags = DoRed | DoGreen | DoBlue;
+ }
+
+ X11_XStoreColors(display, xattr.colormap, colorcells, ncolors);
+
+ SDL_free(colorcells);
+ } else {
+ xattr.colormap =
+ X11_XCreateColormap(display, RootWindow(display, screen),
+ visual, AllocNone);
+ }
+
+ w = X11_XCreateWindow(display, RootWindow(display, screen),
+ window->x, window->y, window->w, window->h,
+ 0, depth, InputOutput, visual,
+ (CWOverrideRedirect | CWBackPixmap | CWBorderPixel |
+ CWColormap), &xattr);
+ if (!w) {
+ return SDL_SetError("Couldn't create window");
+ }
+
+ SetWindowBordered(display, screen, w,
+ (window->flags & SDL_WINDOW_BORDERLESS) == 0);
+
+ sizehints = X11_XAllocSizeHints();
+ /* Setup the normal size hints */
+ sizehints->flags = 0;
+ if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
+ sizehints->min_width = sizehints->max_width = window->w;
+ sizehints->min_height = sizehints->max_height = window->h;
+ sizehints->flags |= (PMaxSize | PMinSize);
+ }
+ sizehints->x = window->x;
+ sizehints->y = window->y;
+ sizehints->flags |= USPosition;
+
+ /* Setup the input hints so we get keyboard input */
+ wmhints = X11_XAllocWMHints();
+ wmhints->input = True;
+ wmhints->window_group = data->window_group;
+ wmhints->flags = InputHint | WindowGroupHint;
+
+ /* Setup the class hints so we can get an icon (AfterStep) */
+ classhints = X11_XAllocClassHint();
+ classhints->res_name = data->classname;
+ classhints->res_class = data->classname;
+
+ /* Set the size, input and class hints, and define WM_CLIENT_MACHINE and WM_LOCALE_NAME */
+ X11_XSetWMProperties(display, w, NULL, NULL, NULL, 0, sizehints, wmhints, classhints);
+
+ X11_XFree(sizehints);
+ X11_XFree(wmhints);
+ X11_XFree(classhints);
+ /* Set the PID related to the window for the given hostname, if possible */
+ if (data->pid > 0) {
+ long pid = (long) data->pid;
+ _NET_WM_PID = X11_XInternAtom(display, "_NET_WM_PID", False);
+ X11_XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &pid, 1);
+ }
+
+ /* Set the window manager state */
+ X11_SetNetWMState(_this, w, window->flags);
+
+ compositor = 2; /* don't disable compositing except for "normal" windows */
+
+ if (window->flags & SDL_WINDOW_UTILITY) {
+ wintype_name = "_NET_WM_WINDOW_TYPE_UTILITY";
+ } else if (window->flags & SDL_WINDOW_TOOLTIP) {
+ wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP";
+ } else if (window->flags & SDL_WINDOW_POPUP_MENU) {
+ wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU";
+ } else {
+ wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL";
+ compositor = 1; /* disable compositing for "normal" windows */
+ }
+
+ /* Let the window manager know what type of window we are. */
+ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
+ wintype = X11_XInternAtom(display, wintype_name, False);
+ X11_XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)&wintype, 1);
+ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, SDL_TRUE)) {
+ _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False);
+ X11_XChangeProperty(display, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
+ PropModeReplace,
+ (unsigned char *)&compositor, 1);
+ }
+
+ {
+ Atom protocols[3];
+ int proto_count = 0;
+
+ protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */
+ protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */
+
+ /* Default to using ping if there is no hint */
+ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_PING, SDL_TRUE)) {
+ protocols[proto_count++] = data->_NET_WM_PING; /* Respond so WM knows we're alive */
+ }
+
+ SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0]));
+
+ X11_XSetWMProtocols(display, w, protocols, proto_count);
+ }
+
+ if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
+ X11_XDestroyWindow(display, w);
+ return -1;
+ }
+ windowdata = (SDL_WindowData *) window->driverdata;
+
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+ if ((window->flags & SDL_WINDOW_OPENGL) &&
+ _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES
+#if SDL_VIDEO_OPENGL_GLX
+ && ( !_this->gl_data || X11_GL_UseEGL(_this) )
+#endif
+ ) {
+#if SDL_VIDEO_OPENGL_EGL
+ if (!_this->egl_data) {
+ X11_XDestroyWindow(display, w);
+ return -1;
+ }
+
+ /* Create the GLES window surface */
+ windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) w);
+
+ if (windowdata->egl_surface == EGL_NO_SURFACE) {
+ X11_XDestroyWindow(display, w);
+ return SDL_SetError("Could not create GLES window surface");
+ }
+#else
+ return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ }
+#endif
+
+
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8 && windowdata->ic) {
+ X11_XGetICValues(windowdata->ic, XNFilterEvents, &fevent, NULL);
+ }
+#endif
+
+ X11_Xinput2SelectTouch(_this, window);
+
+ X11_XSelectInput(display, w,
+ (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
+ ExposureMask | ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | KeyPressMask | KeyReleaseMask |
+ PropertyChangeMask | StructureNotifyMask |
+ KeymapStateMask | fevent));
+
+ X11_XFlush(display);
+
+ return 0;
+}
+
+int
+X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ Window w = (Window) data;
+
+ window->title = X11_GetWindowTitle(_this, w);
+
+ if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+char *
+X11_GetWindowTitle(_THIS, Window xwindow)
+{
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ Display *display = data->display;
+ int status, real_format;
+ Atom real_type;
+ unsigned long items_read, items_left;
+ unsigned char *propdata;
+ char *title = NULL;
+
+ status = X11_XGetWindowProperty(display, xwindow, data->_NET_WM_NAME,
+ 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format,
+ &items_read, &items_left, &propdata);
+ if (status == Success && propdata) {
+ title = SDL_strdup(SDL_static_cast(char*, propdata));
+ X11_XFree(propdata);
+ } else {
+ status = X11_XGetWindowProperty(display, xwindow, XA_WM_NAME,
+ 0L, 8192L, False, XA_STRING, &real_type, &real_format,
+ &items_read, &items_left, &propdata);
+ if (status == Success && propdata) {
+ title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
+ X11_XFree(propdata);
+ } else {
+ title = SDL_strdup("");
+ }
+ }
+ return title;
+}
+
+void
+X11_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ XTextProperty titleprop;
+ Status status;
+ const char *title = window->title ? window->title : "";
+ char *title_locale = NULL;
+
+#ifdef X_HAVE_UTF8_STRING
+ Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
+#endif
+
+ title_locale = SDL_iconv_utf8_locale(title);
+ if (!title_locale) {
+ SDL_OutOfMemory();
+ return;
+ }
+
+ status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
+ SDL_free(title_locale);
+ if (status) {
+ X11_XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME);
+ X11_XFree(titleprop.value);
+ }
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8) {
+ status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1,
+ XUTF8StringStyle, &titleprop);
+ if (status == Success) {
+ X11_XSetTextProperty(display, data->xwindow, &titleprop,
+ _NET_WM_NAME);
+ X11_XFree(titleprop.value);
+ }
+ }
+#endif
+
+ X11_XFlush(display);
+}
+
+void
+X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
+
+ if (icon) {
+ int propsize;
+ long *propdata;
+
+ /* Set the _NET_WM_ICON property */
+ SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888);
+ propsize = 2 + (icon->w * icon->h);
+ propdata = SDL_malloc(propsize * sizeof(long));
+ if (propdata) {
+ int x, y;
+ Uint32 *src;
+ long *dst;
+
+ propdata[0] = icon->w;
+ propdata[1] = icon->h;
+ dst = &propdata[2];
+ for (y = 0; y < icon->h; ++y) {
+ src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch);
+ for (x = 0; x < icon->w; ++x) {
+ *dst++ = *src++;
+ }
+ }
+ X11_XChangeProperty(display, data->xwindow, _NET_WM_ICON, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *) propdata,
+ propsize);
+ }
+ SDL_free(propdata);
+ } else {
+ X11_XDeleteProperty(display, data->xwindow, _NET_WM_ICON);
+ }
+ X11_XFlush(display);
+}
+
+void
+X11_SetWindowPosition(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
+ X11_XFlush(display);
+}
+
+void
+X11_SetWindowMinimumSize(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ XSizeHints *sizehints = X11_XAllocSizeHints();
+ long userhints;
+
+ X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
+
+ sizehints->min_width = window->min_w;
+ sizehints->min_height = window->min_h;
+ sizehints->flags |= PMinSize;
+
+ X11_XSetWMNormalHints(display, data->xwindow, sizehints);
+
+ X11_XFree(sizehints);
+
+ /* See comment in X11_SetWindowSize. */
+ X11_XResizeWindow(display, data->xwindow, window->w, window->h);
+ X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
+ X11_XRaiseWindow(display, data->xwindow);
+ }
+
+ X11_XFlush(display);
+}
+
+void
+X11_SetWindowMaximumSize(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ if (window->flags & SDL_WINDOW_RESIZABLE) {
+ XSizeHints *sizehints = X11_XAllocSizeHints();
+ long userhints;
+
+ X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
+
+ sizehints->max_width = window->max_w;
+ sizehints->max_height = window->max_h;
+ sizehints->flags |= PMaxSize;
+
+ X11_XSetWMNormalHints(display, data->xwindow, sizehints);
+
+ X11_XFree(sizehints);
+
+ /* See comment in X11_SetWindowSize. */
+ X11_XResizeWindow(display, data->xwindow, window->w, window->h);
+ X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
+ X11_XRaiseWindow(display, data->xwindow);
+ }
+
+ X11_XFlush(display);
+}
+
+void
+X11_SetWindowSize(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ if (SDL_IsShapedWindow(window)) {
+ X11_ResizeWindowShape(window);
+ }
+ if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
+ /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the X11_XResizeWindow, thus
+ we must set the size hints to adjust the window size. */
+ XSizeHints *sizehints = X11_XAllocSizeHints();
+ long userhints;
+
+ X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
+
+ sizehints->min_width = sizehints->max_width = window->w;
+ sizehints->min_height = sizehints->max_height = window->h;
+ sizehints->flags |= PMinSize | PMaxSize;
+
+ X11_XSetWMNormalHints(display, data->xwindow, sizehints);
+
+ X11_XFree(sizehints);
+
+ /* From Pierre-Loup:
+ WMs each have their little quirks with that. When you change the
+ size hints, they get a ConfigureNotify event with the
+ WM_NORMAL_SIZE_HINTS Atom. They all save the hints then, but they
+ don't all resize the window right away to enforce the new hints.
+
+ Some of them resize only after:
+ - A user-initiated move or resize
+ - A code-initiated move or resize
+ - Hiding & showing window (Unmap & map)
+
+ The following move & resize seems to help a lot of WMs that didn't
+ properly update after the hints were changed. We don't do a
+ hide/show, because there are supposedly subtle problems with doing so
+ and transitioning from windowed to fullscreen in Unity.
+ */
+ X11_XResizeWindow(display, data->xwindow, window->w, window->h);
+ X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
+ X11_XRaiseWindow(display, data->xwindow);
+ } else {
+ X11_XResizeWindow(display, data->xwindow, window->w, window->h);
+ }
+
+ X11_XFlush(display);
+}
+
+int
+X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right)
+{
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+
+ *left = data->border_left;
+ *right = data->border_right;
+ *top = data->border_top;
+ *bottom = data->border_bottom;
+
+ return 0;
+}
+
+int
+X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY;
+
+ if (opacity == 1.0f) {
+ X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY);
+ } else {
+ const Uint32 FullyOpaque = 0xFFFFFFFF;
+ const long alpha = (long) ((double)opacity * (double)FullyOpaque);
+ X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *)&alpha, 1);
+ }
+
+ return 0;
+}
+
+int
+X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window) {
+ SDL_WindowData *data = (SDL_WindowData *) modal_window->driverdata;
+ SDL_WindowData *parent_data = (SDL_WindowData *) parent_window->driverdata;
+ Display *display = data->videodata->display;
+
+ X11_XSetTransientForHint(display, data->xwindow, parent_data->xwindow);
+ return 0;
+}
+
+int
+X11_SetWindowInputFocus(_THIS, SDL_Window * window)
+{
+ if (X11_IsWindowMapped(_this, window)) {
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime);
+ X11_XFlush(display);
+ return 0;
+ }
+ return -1;
+}
+
+void
+X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
+{
+ const SDL_bool focused = ((window->flags & SDL_WINDOW_INPUT_FOCUS) != 0);
+ const SDL_bool visible = ((window->flags & SDL_WINDOW_HIDDEN) == 0);
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata =
+ (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ Display *display = data->videodata->display;
+ XEvent event;
+
+ SetWindowBordered(display, displaydata->screen, data->xwindow, bordered);
+ X11_XFlush(display);
+
+ if (visible) {
+ XWindowAttributes attr;
+ do {
+ X11_XSync(display, False);
+ X11_XGetWindowAttributes(display, data->xwindow, &attr);
+ } while (attr.map_state != IsViewable);
+
+ if (focused) {
+ X11_XSetInputFocus(display, data->xwindow, RevertToParent, CurrentTime);
+ }
+ }
+
+ /* make sure these don't make it to the real event queue if they fired here. */
+ X11_XSync(display, False);
+ X11_XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow);
+ X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
+}
+
+void
+X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ XSizeHints *sizehints = X11_XAllocSizeHints();
+ long userhints;
+
+ X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
+
+ if (resizable) {
+ /* FIXME: Is there a better way to get max window size from X? -flibit */
+ const int maxsize = 0x7FFFFFFF;
+ sizehints->min_width = window->min_w;
+ sizehints->min_height = window->min_h;
+ sizehints->max_width = (window->max_w == 0) ? maxsize : window->max_w;
+ sizehints->max_height = (window->max_h == 0) ? maxsize : window->max_h;
+ } else {
+ sizehints->min_width = window->w;
+ sizehints->min_height = window->h;
+ sizehints->max_width = window->w;
+ sizehints->max_height = window->h;
+ }
+ sizehints->flags |= PMinSize | PMaxSize;
+
+ X11_XSetWMNormalHints(display, data->xwindow, sizehints);
+
+ X11_XFree(sizehints);
+
+ /* See comment in X11_SetWindowSize. */
+ X11_XResizeWindow(display, data->xwindow, window->w, window->h);
+ X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
+ X11_XRaiseWindow(display, data->xwindow);
+
+ X11_XFlush(display);
+}
+
+void
+X11_ShowWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ XEvent event;
+
+ if (!X11_IsWindowMapped(_this, window)) {
+ X11_XMapRaised(display, data->xwindow);
+ /* Blocking wait for "MapNotify" event.
+ * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type,
+ * and XCheckTypedWindowEvent doesn't block */
+ if(!(window->flags & SDL_WINDOW_FOREIGN))
+ X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
+ X11_XFlush(display);
+ }
+
+ if (!data->videodata->net_wm) {
+ /* no WM means no FocusIn event, which confuses us. Force it. */
+ X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime);
+ X11_XFlush(display);
+ }
+}
+
+void
+X11_HideWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ Display *display = data->videodata->display;
+ XEvent event;
+
+ if (X11_IsWindowMapped(_this, window)) {
+ X11_XWithdrawWindow(display, data->xwindow, displaydata->screen);
+ /* Blocking wait for "UnmapNotify" event */
+ if(!(window->flags & SDL_WINDOW_FOREIGN))
+ X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow);
+ X11_XFlush(display);
+ }
+}
+
+static void
+SetWindowActive(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata =
+ (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ Display *display = data->videodata->display;
+ Atom _NET_ACTIVE_WINDOW = data->videodata->_NET_ACTIVE_WINDOW;
+
+ if (X11_IsWindowMapped(_this, window)) {
+ XEvent e;
+
+ /*printf("SDL Window %p: sending _NET_ACTIVE_WINDOW with timestamp %lu\n", window, data->user_time);*/
+
+ SDL_zero(e);
+ e.xany.type = ClientMessage;
+ e.xclient.message_type = _NET_ACTIVE_WINDOW;
+ e.xclient.format = 32;
+ e.xclient.window = data->xwindow;
+ e.xclient.data.l[0] = 1; /* source indication. 1 = application */
+ e.xclient.data.l[1] = data->user_time;
+ e.xclient.data.l[2] = 0;
+
+ X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
+ SubstructureNotifyMask | SubstructureRedirectMask, &e);
+
+ X11_XFlush(display);
+ }
+}
+
+void
+X11_RaiseWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ X11_XRaiseWindow(display, data->xwindow);
+ SetWindowActive(_this, window);
+ X11_XFlush(display);
+}
+
+static void
+SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata =
+ (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ Display *display = data->videodata->display;
+ Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
+ Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
+ Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
+
+ if (maximized) {
+ window->flags |= SDL_WINDOW_MAXIMIZED;
+ } else {
+ window->flags &= ~SDL_WINDOW_MAXIMIZED;
+ }
+
+ if (X11_IsWindowMapped(_this, window)) {
+ XEvent e;
+
+ SDL_zero(e);
+ e.xany.type = ClientMessage;
+ e.xclient.message_type = _NET_WM_STATE;
+ e.xclient.format = 32;
+ e.xclient.window = data->xwindow;
+ e.xclient.data.l[0] =
+ maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+ e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
+ e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
+ e.xclient.data.l[3] = 0l;
+
+ X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
+ SubstructureNotifyMask | SubstructureRedirectMask, &e);
+ } else {
+ X11_SetNetWMState(_this, data->xwindow, window->flags);
+ }
+ X11_XFlush(display);
+}
+
+void
+X11_MaximizeWindow(_THIS, SDL_Window * window)
+{
+ SetWindowMaximized(_this, window, SDL_TRUE);
+}
+
+void
+X11_MinimizeWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata =
+ (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ Display *display = data->videodata->display;
+
+ X11_XIconifyWindow(display, data->xwindow, displaydata->screen);
+ X11_XFlush(display);
+}
+
+void
+X11_RestoreWindow(_THIS, SDL_Window * window)
+{
+ SetWindowMaximized(_this, window, SDL_FALSE);
+ X11_ShowWindow(_this, window);
+ SetWindowActive(_this, window);
+}
+
+/* This asks the Window Manager to handle fullscreen for us. This is the modern way. */
+static void
+X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
+ Display *display = data->videodata->display;
+ Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
+ Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
+
+ if (X11_IsWindowMapped(_this, window)) {
+ XEvent e;
+
+ if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
+ /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we
+ can be resized to the fullscreen resolution (or reset so we're not resizable again) */
+ XSizeHints *sizehints = X11_XAllocSizeHints();
+ long flags = 0;
+ X11_XGetWMNormalHints(display, data->xwindow, sizehints, &flags);
+ /* set the resize flags on */
+ if (fullscreen) {
+ /* we are going fullscreen so turn the flags off */
+ sizehints->flags &= ~(PMinSize | PMaxSize);
+ } else {
+ /* Reset the min/max width height to make the window non-resizable again */
+ sizehints->flags |= PMinSize | PMaxSize;
+ sizehints->min_width = sizehints->max_width = window->windowed.w;
+ sizehints->min_height = sizehints->max_height = window->windowed.h;
+ }
+ X11_XSetWMNormalHints(display, data->xwindow, sizehints);
+ X11_XFree(sizehints);
+ }
+
+ SDL_zero(e);
+ e.xany.type = ClientMessage;
+ e.xclient.message_type = _NET_WM_STATE;
+ e.xclient.format = 32;
+ e.xclient.window = data->xwindow;
+ e.xclient.data.l[0] =
+ fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+ e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
+ e.xclient.data.l[3] = 0l;
+
+ X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
+ SubstructureNotifyMask | SubstructureRedirectMask, &e);
+
+ /* Fullscreen windows sometimes end up being marked maximized by
+ window managers. Force it back to how we expect it to be. */
+ if (!fullscreen && ((window->flags & SDL_WINDOW_MAXIMIZED) == 0)) {
+ SDL_zero(e);
+ e.xany.type = ClientMessage;
+ e.xclient.message_type = _NET_WM_STATE;
+ e.xclient.format = 32;
+ e.xclient.window = data->xwindow;
+ e.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+ e.xclient.data.l[1] = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
+ e.xclient.data.l[2] = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
+ e.xclient.data.l[3] = 0l;
+ X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
+ SubstructureNotifyMask | SubstructureRedirectMask, &e);
+ }
+ } else {
+ Uint32 flags;
+
+ flags = window->flags;
+ if (fullscreen) {
+ flags |= SDL_WINDOW_FULLSCREEN;
+ } else {
+ flags &= ~SDL_WINDOW_FULLSCREEN;
+ }
+ X11_SetNetWMState(_this, data->xwindow, flags);
+ }
+
+ if (data->visual->class == DirectColor) {
+ if ( fullscreen ) {
+ X11_XInstallColormap(display, data->colormap);
+ } else {
+ X11_XUninstallColormap(display, data->colormap);
+ }
+ }
+
+ X11_XFlush(display);
+}
+
+/* This handles fullscreen itself, outside the Window Manager. */
+static void
+X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
+ Visual *visual = data->visual;
+ Display *display = data->videodata->display;
+ const int screen = displaydata->screen;
+ Window root = RootWindow(display, screen);
+ const int def_vis = (visual == DefaultVisual(display, screen));
+ unsigned long xattrmask = 0;
+ XSetWindowAttributes xattr;
+ XEvent ev;
+ SDL_Rect rect;
+
+ if ( data->fswindow ) {
+ return; /* already fullscreen, I hope. */
+ }
+
+ X11_GetDisplayBounds(_this, _display, &rect);
+
+ SDL_zero(xattr);
+ xattr.override_redirect = True;
+ xattrmask |= CWOverrideRedirect;
+ xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0;
+ xattrmask |= CWBackPixel;
+ xattr.border_pixel = 0;
+ xattrmask |= CWBorderPixel;
+ xattr.colormap = data->colormap;
+ xattrmask |= CWColormap;
+
+ data->fswindow = X11_XCreateWindow(display, root,
+ rect.x, rect.y, rect.w, rect.h, 0,
+ displaydata->depth, InputOutput,
+ visual, xattrmask, &xattr);
+
+ X11_XSelectInput(display, data->fswindow, StructureNotifyMask);
+ X11_XSetWindowBackground(display, data->fswindow, 0);
+ X11_XInstallColormap(display, data->colormap);
+ X11_XClearWindow(display, data->fswindow);
+ X11_XMapRaised(display, data->fswindow);
+
+ /* Make sure the fswindow is in view by warping mouse to the corner */
+ X11_XUngrabPointer(display, CurrentTime);
+ X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
+
+ /* Wait to be mapped, filter Unmap event out if it arrives. */
+ X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow);
+ X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow);
+
+#if SDL_VIDEO_DRIVER_X11_XVIDMODE
+ if ( displaydata->use_vidmode ) {
+ X11_XF86VidModeLockModeSwitch(display, screen, True);
+ }
+#endif
+
+ SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE);
+
+ /* Center actual window within our cover-the-screen window. */
+ X11_XReparentWindow(display, data->xwindow, data->fswindow,
+ (rect.w - window->w) / 2, (rect.h - window->h) / 2);
+
+ /* Move the mouse to the upper left to make sure it's on-screen */
+ X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
+
+ /* Center mouse in the fullscreen window. */
+ rect.x += (rect.w / 2);
+ rect.y += (rect.h / 2);
+ X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
+
+ /* Wait to be mapped, filter Unmap event out if it arrives. */
+ X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
+ X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
+
+ SDL_UpdateWindowGrab(window);
+}
+
+static void
+X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
+ Display *display = data->videodata->display;
+ const int screen = displaydata->screen;
+ Window root = RootWindow(display, screen);
+ Window fswindow = data->fswindow;
+ XEvent ev;
+
+ if (!data->fswindow) {
+ return; /* already not fullscreen, I hope. */
+ }
+
+ data->fswindow = None;
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ if ( displaydata->use_vidmode ) {
+ X11_XF86VidModeLockModeSwitch(display, screen, False);
+ }
+#endif
+
+ SDL_UpdateWindowGrab(window);
+
+ X11_XReparentWindow(display, data->xwindow, root, window->x, window->y);
+
+ /* flush these events so they don't confuse normal event handling */
+ X11_XSync(display, False);
+ X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
+ X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
+
+ SetWindowBordered(display, screen, data->xwindow,
+ (window->flags & SDL_WINDOW_BORDERLESS) == 0);
+
+ X11_XWithdrawWindow(display, fswindow, screen);
+
+ /* Wait to be unmapped. */
+ X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow);
+ X11_XDestroyWindow(display, fswindow);
+}
+
+
+void
+X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
+{
+ /* !!! FIXME: SDL_Hint? */
+ SDL_bool legacy = SDL_FALSE;
+ const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN");
+ if (env) {
+ legacy = SDL_atoi(env);
+ } else {
+ SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
+ if ( displaydata->use_vidmode ) {
+ legacy = SDL_TRUE; /* the new stuff only works with XRandR. */
+ } else if ( !videodata->net_wm ) {
+ legacy = SDL_TRUE; /* The window manager doesn't support it */
+ } else {
+ /* !!! FIXME: look at the window manager name, and blacklist certain ones? */
+ /* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */
+ legacy = SDL_FALSE; /* try the new way. */
+ }
+ }
+
+ if (legacy) {
+ if (fullscreen) {
+ X11_BeginWindowFullscreenLegacy(_this, window, _display);
+ } else {
+ X11_EndWindowFullscreenLegacy(_this, window, _display);
+ }
+ } else {
+ X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen);
+ }
+}
+
+
+int
+X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ Visual *visual = data->visual;
+ Colormap colormap = data->colormap;
+ XColor *colorcells;
+ int ncolors;
+ int rmask, gmask, bmask;
+ int rshift, gshift, bshift;
+ int i;
+
+ if (visual->class != DirectColor) {
+ return SDL_SetError("Window doesn't have DirectColor visual");
+ }
+
+ ncolors = visual->map_entries;
+ colorcells = SDL_malloc(ncolors * sizeof(XColor));
+ if (!colorcells) {
+ return SDL_OutOfMemory();
+ }
+
+ rshift = 0;
+ rmask = visual->red_mask;
+ while (0 == (rmask & 1)) {
+ rshift++;
+ rmask >>= 1;
+ }
+
+ gshift = 0;
+ gmask = visual->green_mask;
+ while (0 == (gmask & 1)) {
+ gshift++;
+ gmask >>= 1;
+ }
+
+ bshift = 0;
+ bmask = visual->blue_mask;
+ while (0 == (bmask & 1)) {
+ bshift++;
+ bmask >>= 1;
+ }
+
+ /* build the color table pixel values */
+ for (i = 0; i < ncolors; i++) {
+ Uint32 rbits = (rmask * i) / (ncolors - 1);
+ Uint32 gbits = (gmask * i) / (ncolors - 1);
+ Uint32 bbits = (bmask * i) / (ncolors - 1);
+ Uint32 pix = (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
+
+ colorcells[i].pixel = pix;
+
+ colorcells[i].red = ramp[(0 * 256) + i];
+ colorcells[i].green = ramp[(1 * 256) + i];
+ colorcells[i].blue = ramp[(2 * 256) + i];
+
+ colorcells[i].flags = DoRed | DoGreen | DoBlue;
+ }
+
+ X11_XStoreColors(display, colormap, colorcells, ncolors);
+ X11_XFlush(display);
+ SDL_free(colorcells);
+
+ return 0;
+}
+
+void
+X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ SDL_bool oldstyle_fullscreen;
+ SDL_bool grab_keyboard;
+
+ /* ICCCM2.0-compliant window managers can handle fullscreen windows
+ If we're using XVidMode to change resolution we need to confine
+ the cursor so we don't pan around the virtual desktop.
+ */
+ oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window);
+
+ if (oldstyle_fullscreen || grabbed) {
+ /* Try to grab the mouse */
+ if (!data->videodata->broken_pointer_grab) {
+ const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
+ int attempts;
+ int result;
+
+ /* Try for up to 5000ms (5s) to grab. If it still fails, stop trying. */
+ for (attempts = 0; attempts < 100; attempts++) {
+ result = X11_XGrabPointer(display, data->xwindow, True, mask, GrabModeAsync,
+ GrabModeAsync, data->xwindow, None, CurrentTime);
+ if (result == GrabSuccess) {
+ break;
+ }
+ SDL_Delay(50);
+ }
+
+ if (result != GrabSuccess) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "The X server refused to let us grab the mouse. You might experience input bugs.");
+ data->videodata->broken_pointer_grab = SDL_TRUE; /* don't try again. */
+ }
+ }
+
+ /* Raise the window if we grab the mouse */
+ X11_XRaiseWindow(display, data->xwindow);
+
+ /* Now grab the keyboard */
+ if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) {
+ grab_keyboard = SDL_TRUE;
+ } else {
+ /* We need to do this with the old style override_redirect
+ fullscreen window otherwise we won't get keyboard focus.
+ */
+ grab_keyboard = oldstyle_fullscreen;
+ }
+ if (grab_keyboard) {
+ X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
+ GrabModeAsync, CurrentTime);
+ }
+ } else {
+ X11_XUngrabPointer(display, CurrentTime);
+ X11_XUngrabKeyboard(display, CurrentTime);
+ }
+ X11_XSync(display, False);
+}
+
+void
+X11_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (data) {
+ SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
+ Display *display = videodata->display;
+ int numwindows = videodata->numwindows;
+ SDL_WindowData **windowlist = videodata->windowlist;
+ int i;
+
+ if (windowlist) {
+ for (i = 0; i < numwindows; ++i) {
+ if (windowlist[i] && (windowlist[i]->window == window)) {
+ windowlist[i] = windowlist[numwindows - 1];
+ windowlist[numwindows - 1] = NULL;
+ videodata->numwindows--;
+ break;
+ }
+ }
+ }
+#ifdef X_HAVE_UTF8_STRING
+ if (data->ic) {
+ X11_XDestroyIC(data->ic);
+ }
+#endif
+ if (data->created) {
+ X11_XDestroyWindow(display, data->xwindow);
+ X11_XFlush(display);
+ }
+ SDL_free(data);
+ }
+ window->driverdata = NULL;
+}
+
+SDL_bool
+X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ if (info->version.major == SDL_MAJOR_VERSION &&
+ info->version.minor == SDL_MINOR_VERSION) {
+ info->subsystem = SDL_SYSWM_X11;
+ info->info.x11.display = display;
+ info->info.x11.window = data->xwindow;
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+}
+
+int
+X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
+{
+ return 0; /* just succeed, the real work is done elsewhere. */
+}
+
+void
+X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+ Atom XdndAware = X11_XInternAtom(display, "XdndAware", False);
+
+ if (accept) {
+ Atom xdnd_version = 5;
+ X11_XChangeProperty(display, data->xwindow, XdndAware, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*)&xdnd_version, 1);
+ } else {
+ X11_XDeleteProperty(display, data->xwindow, XdndAware);
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11window.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11window.h
new file mode 100644
index 0000000..6ee8016
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11window.h
@@ -0,0 +1,111 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11window_h_
+#define SDL_x11window_h_
+
+/* We need to queue the focus in/out changes because they may occur during
+ video mode changes and we can respond to them by triggering more mode
+ changes.
+*/
+#define PENDING_FOCUS_TIME 200
+
+#if SDL_VIDEO_OPENGL_EGL
+#include <EGL/egl.h>
+#endif
+
+typedef enum
+{
+ PENDING_FOCUS_NONE,
+ PENDING_FOCUS_IN,
+ PENDING_FOCUS_OUT
+} PendingFocusEnum;
+
+typedef struct
+{
+ SDL_Window *window;
+ Window xwindow;
+ Window fswindow; /* used if we can't have the WM handle fullscreen. */
+ Visual *visual;
+ Colormap colormap;
+#ifndef NO_SHARED_MEMORY
+ /* MIT shared memory extension information */
+ SDL_bool use_mitshm;
+ XShmSegmentInfo shminfo;
+#endif
+ XImage *ximage;
+ GC gc;
+ XIC ic;
+ SDL_bool created;
+ int border_left;
+ int border_right;
+ int border_top;
+ int border_bottom;
+ Uint32 last_focus_event_time;
+ PendingFocusEnum pending_focus;
+ Uint32 pending_focus_time;
+ XConfigureEvent last_xconfigure;
+ struct SDL_VideoData *videodata;
+ unsigned long user_time;
+ Atom xdnd_req;
+ Window xdnd_source;
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+} SDL_WindowData;
+
+extern void X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags);
+extern Uint32 X11_GetNetWMState(_THIS, Window xwindow);
+
+extern int X11_CreateWindow(_THIS, SDL_Window * window);
+extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+extern char *X11_GetWindowTitle(_THIS, Window xwindow);
+extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
+extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
+extern void X11_SetWindowMinimumSize(_THIS, SDL_Window * window);
+extern void X11_SetWindowMaximumSize(_THIS, SDL_Window * window);
+extern int X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
+extern int X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
+extern int X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window);
+extern int X11_SetWindowInputFocus(_THIS, SDL_Window * window);
+extern void X11_SetWindowSize(_THIS, SDL_Window * window);
+extern void X11_ShowWindow(_THIS, SDL_Window * window);
+extern void X11_HideWindow(_THIS, SDL_Window * window);
+extern void X11_RaiseWindow(_THIS, SDL_Window * window);
+extern void X11_MaximizeWindow(_THIS, SDL_Window * window);
+extern void X11_MinimizeWindow(_THIS, SDL_Window * window);
+extern void X11_RestoreWindow(_THIS, SDL_Window * window);
+extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
+extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
+extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
+extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
+extern void X11_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
+extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
+
+#endif /* SDL_x11window_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.c b/source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.c
new file mode 100644
index 0000000..06a8937
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.c
@@ -0,0 +1,313 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+
+#include "SDL_x11video.h"
+#include "SDL_x11xinput2.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+
+#define MAX_AXIS 16
+
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+static int xinput2_initialized = 0;
+
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
+static int xinput2_multitouch_supported = 0;
+#endif
+
+/* Opcode returned X11_XQueryExtension
+ * It will be used in event processing
+ * to know that the event came from
+ * this extension */
+static int xinput2_opcode;
+
+static void parse_valuators(const double *input_values,unsigned char *mask,int mask_len,
+ double *output_values,int output_values_len) {
+ int i = 0,z = 0;
+ int top = mask_len * 8;
+ if (top > MAX_AXIS)
+ top = MAX_AXIS;
+
+ SDL_memset(output_values,0,output_values_len * sizeof(double));
+ for (; i < top && z < output_values_len; i++) {
+ if (XIMaskIsSet(mask, i)) {
+ const int value = (int) *input_values;
+ output_values[z] = value;
+ input_values++;
+ }
+ z++;
+ }
+}
+
+static int
+query_xinput2_version(Display *display, int major, int minor)
+{
+ /* We don't care if this fails, so long as it sets major/minor on it's way out the door. */
+ X11_XIQueryVersion(display, &major, &minor);
+ return ((major * 1000) + minor);
+}
+
+static SDL_bool
+xinput2_version_atleast(const int version, const int wantmajor, const int wantminor)
+{
+ return ( version >= ((wantmajor * 1000) + wantminor) );
+}
+
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
+static void
+xinput2_normalize_touch_coordinates(SDL_VideoData *videodata, Window window,
+ double in_x, double in_y, float *out_x, float *out_y)
+{
+ int i;
+ for (i = 0; i < videodata->numwindows; i++) {
+ SDL_WindowData *d = videodata->windowlist[i];
+ if (d->xwindow == window) {
+ if (d->window->w == 1) {
+ *out_x = 0.5f;
+ } else {
+ *out_x = in_x / (d->window->w - 1);
+ }
+ if (d->window->h == 1) {
+ *out_y = 0.5f;
+ } else {
+ *out_y = in_y / (d->window->h - 1);
+ }
+ return;
+ }
+ }
+ // couldn't find the window...
+ *out_x = in_x;
+ *out_y = in_y;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH */
+
+#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */
+
+void
+X11_InitXinput2(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ int version = 0;
+ XIEventMask eventmask;
+ unsigned char mask[3] = { 0,0,0 };
+ int event, err;
+
+ /*
+ * Initialize XInput 2
+ * According to http://who-t.blogspot.com/2009/05/xi2-recipes-part-1.html its better
+ * to inform Xserver what version of Xinput we support.The server will store the version we support.
+ * "As XI2 progresses it becomes important that you use this call as the server may treat the client
+ * differently depending on the supported version".
+ *
+ * FIXME:event and err are not needed but if not passed X11_XQueryExtension returns SegmentationFault
+ */
+ if (!SDL_X11_HAVE_XINPUT2 ||
+ !X11_XQueryExtension(data->display, "XInputExtension", &xinput2_opcode, &event, &err)) {
+ return; /* X server does not have XInput at all */
+ }
+
+ /* We need at least 2.2 for Multitouch, 2.0 otherwise. */
+ version = query_xinput2_version(data->display, 2, 2);
+ if (!xinput2_version_atleast(version, 2, 0)) {
+ return; /* X server does not support the version we want at all. */
+ }
+
+ xinput2_initialized = 1;
+
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH /* Multitouch needs XInput 2.2 */
+ xinput2_multitouch_supported = xinput2_version_atleast(version, 2, 2);
+#endif
+
+ /* Enable Raw motion events for this display */
+ eventmask.deviceid = XIAllMasterDevices;
+ eventmask.mask_len = sizeof(mask);
+ eventmask.mask = mask;
+
+ XISetMask(mask, XI_RawMotion);
+ XISetMask(mask, XI_RawButtonPress);
+ XISetMask(mask, XI_RawButtonRelease);
+
+ if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) {
+ return;
+ }
+#endif
+}
+
+int
+X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+ if(cookie->extension != xinput2_opcode) {
+ return 0;
+ }
+ switch(cookie->evtype) {
+ case XI_RawMotion: {
+ const XIRawEvent *rawev = (const XIRawEvent*)cookie->data;
+ SDL_Mouse *mouse = SDL_GetMouse();
+ double relative_coords[2];
+ static Time prev_time = 0;
+ static double prev_rel_coords[2];
+
+ videodata->global_mouse_changed = SDL_TRUE;
+
+ if (!mouse->relative_mode || mouse->relative_mode_warp) {
+ return 0;
+ }
+
+ parse_valuators(rawev->raw_values,rawev->valuators.mask,
+ rawev->valuators.mask_len,relative_coords,2);
+
+ if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) {
+ return 0; /* duplicate event, drop it. */
+ }
+
+ SDL_SendMouseMotion(mouse->focus,mouse->mouseID,1,(int)relative_coords[0],(int)relative_coords[1]);
+ prev_rel_coords[0] = relative_coords[0];
+ prev_rel_coords[1] = relative_coords[1];
+ prev_time = rawev->time;
+ return 1;
+ }
+ break;
+
+ case XI_RawButtonPress:
+ case XI_RawButtonRelease:
+ videodata->global_mouse_changed = SDL_TRUE;
+ break;
+
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
+ case XI_TouchBegin: {
+ const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
+ float x, y;
+ xinput2_normalize_touch_coordinates(videodata, xev->event,
+ xev->event_x, xev->event_y, &x, &y);
+ SDL_SendTouch(xev->sourceid,xev->detail, SDL_TRUE, x, y, 1.0);
+ return 1;
+ }
+ break;
+ case XI_TouchEnd: {
+ const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
+ float x, y;
+ xinput2_normalize_touch_coordinates(videodata, xev->event,
+ xev->event_x, xev->event_y, &x, &y);
+ SDL_SendTouch(xev->sourceid,xev->detail, SDL_FALSE, x, y, 1.0);
+ return 1;
+ }
+ break;
+ case XI_TouchUpdate: {
+ const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data;
+ float x, y;
+ xinput2_normalize_touch_coordinates(videodata, xev->event,
+ xev->event_x, xev->event_y, &x, &y);
+ SDL_SendTouchMotion(xev->sourceid,xev->detail, x, y, 1.0);
+ return 1;
+ }
+ break;
+#endif
+ }
+#endif
+ return 0;
+}
+
+void
+X11_InitXinput2Multitouch(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ XIDeviceInfo *info;
+ int ndevices,i,j;
+ info = X11_XIQueryDevice(data->display, XIAllDevices, &ndevices);
+
+ for (i = 0; i < ndevices; i++) {
+ XIDeviceInfo *dev = &info[i];
+ for (j = 0; j < dev->num_classes; j++) {
+ SDL_TouchID touchId;
+ XIAnyClassInfo *class = dev->classes[j];
+ XITouchClassInfo *t = (XITouchClassInfo*)class;
+
+ /* Only touch devices */
+ if (class->type != XITouchClass)
+ continue;
+
+ touchId = t->sourceid;
+ SDL_AddTouch(touchId, dev->name);
+ }
+ }
+ X11_XIFreeDeviceInfo(info);
+#endif
+}
+
+void
+X11_Xinput2SelectTouch(_THIS, SDL_Window *window)
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
+ SDL_VideoData *data = NULL;
+ XIEventMask eventmask;
+ unsigned char mask[3] = { 0,0,0 };
+ SDL_WindowData *window_data = NULL;
+
+ if (!X11_Xinput2IsMultitouchSupported()) {
+ return;
+ }
+
+ data = (SDL_VideoData *) _this->driverdata;
+ window_data = (SDL_WindowData*)window->driverdata;
+
+ eventmask.deviceid = XIAllMasterDevices;
+ eventmask.mask_len = sizeof(mask);
+ eventmask.mask = mask;
+
+ XISetMask(mask, XI_TouchBegin);
+ XISetMask(mask, XI_TouchUpdate);
+ XISetMask(mask, XI_TouchEnd);
+
+ X11_XISelectEvents(data->display,window_data->xwindow,&eventmask,1);
+#endif
+}
+
+
+int
+X11_Xinput2IsInitialized()
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2
+ return xinput2_initialized;
+#else
+ return 0;
+#endif
+}
+
+int
+X11_Xinput2IsMultitouchSupported()
+{
+#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
+ return xinput2_initialized && xinput2_multitouch_supported;
+#else
+ return 0;
+#endif
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.h b/source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.h
new file mode 100644
index 0000000..4780fbb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/SDL_x11xinput2.h
@@ -0,0 +1,42 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_x11xinput2_h_
+#define SDL_x11xinput2_h_
+
+#ifndef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
+/* Define XGenericEventCookie as forward declaration when
+ *xinput2 is not available in order to compile */
+struct XGenericEventCookie;
+typedef struct XGenericEventCookie XGenericEventCookie;
+#endif
+
+extern void X11_InitXinput2(_THIS);
+extern void X11_InitXinput2Multitouch(_THIS);
+extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie);
+extern int X11_Xinput2IsInitialized(void);
+extern int X11_Xinput2IsMultitouchSupported(void);
+extern void X11_Xinput2SelectTouch(_THIS, SDL_Window *window);
+
+#endif /* SDL_x11xinput2_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/x11/edid-parse.c b/source/3rd-party/SDL2/src/video/x11/edid-parse.c
new file mode 100644
index 0000000..e22324f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/edid-parse.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Author: Soren Sandmann <sandmann@redhat.com> */
+#include "../../SDL_internal.h"
+#include "SDL_stdinc.h"
+
+#include "edid.h"
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#define TRUE 1
+#define FALSE 0
+
+static int
+get_bit (int in, int bit)
+{
+ return (in & (1 << bit)) >> bit;
+}
+
+static int
+get_bits (int in, int begin, int end)
+{
+ int mask = (1 << (end - begin + 1)) - 1;
+
+ return (in >> begin) & mask;
+}
+
+static int
+decode_header (const uchar *edid)
+{
+ if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static int
+decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info)
+{
+ int is_model_year;
+
+ /* Manufacturer Code */
+ info->manufacturer_code[0] = get_bits (edid[0x08], 2, 6);
+ info->manufacturer_code[1] = get_bits (edid[0x08], 0, 1) << 3;
+ info->manufacturer_code[1] |= get_bits (edid[0x09], 5, 7);
+ info->manufacturer_code[2] = get_bits (edid[0x09], 0, 4);
+ info->manufacturer_code[3] = '\0';
+
+ info->manufacturer_code[0] += 'A' - 1;
+ info->manufacturer_code[1] += 'A' - 1;
+ info->manufacturer_code[2] += 'A' - 1;
+
+ /* Product Code */
+ info->product_code = edid[0x0b] << 8 | edid[0x0a];
+
+ /* Serial Number */
+ info->serial_number =
+ edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24;
+
+ /* Week and Year */
+ is_model_year = FALSE;
+ switch (edid[0x10])
+ {
+ case 0x00:
+ info->production_week = -1;
+ break;
+
+ case 0xff:
+ info->production_week = -1;
+ is_model_year = TRUE;
+ break;
+
+ default:
+ info->production_week = edid[0x10];
+ break;
+ }
+
+ if (is_model_year)
+ {
+ info->production_year = -1;
+ info->model_year = 1990 + edid[0x11];
+ }
+ else
+ {
+ info->production_year = 1990 + edid[0x11];
+ info->model_year = -1;
+ }
+
+ return TRUE;
+}
+
+static int
+decode_edid_version (const uchar *edid, MonitorInfo *info)
+{
+ info->major_version = edid[0x12];
+ info->minor_version = edid[0x13];
+
+ return TRUE;
+}
+
+static int
+decode_display_parameters (const uchar *edid, MonitorInfo *info)
+{
+ /* Digital vs Analog */
+ info->is_digital = get_bit (edid[0x14], 7);
+
+ if (info->is_digital)
+ {
+ int bits;
+
+ static const int bit_depth[8] =
+ {
+ -1, 6, 8, 10, 12, 14, 16, -1
+ };
+
+ static const Interface interfaces[6] =
+ {
+ UNDEFINED, DVI, HDMI_A, HDMI_B, MDDI, DISPLAY_PORT
+ };
+
+ bits = get_bits (edid[0x14], 4, 6);
+ info->ad.digital.bits_per_primary = bit_depth[bits];
+
+ bits = get_bits (edid[0x14], 0, 3);
+
+ if (bits <= 5)
+ info->ad.digital.interface = interfaces[bits];
+ else
+ info->ad.digital.interface = UNDEFINED;
+ }
+ else
+ {
+ int bits = get_bits (edid[0x14], 5, 6);
+
+ static const double levels[][3] =
+ {
+ { 0.7, 0.3, 1.0 },
+ { 0.714, 0.286, 1.0 },
+ { 1.0, 0.4, 1.4 },
+ { 0.7, 0.0, 0.7 },
+ };
+
+ info->ad.analog.video_signal_level = levels[bits][0];
+ info->ad.analog.sync_signal_level = levels[bits][1];
+ info->ad.analog.total_signal_level = levels[bits][2];
+
+ info->ad.analog.blank_to_black = get_bit (edid[0x14], 4);
+
+ info->ad.analog.separate_hv_sync = get_bit (edid[0x14], 3);
+ info->ad.analog.composite_sync_on_h = get_bit (edid[0x14], 2);
+ info->ad.analog.composite_sync_on_green = get_bit (edid[0x14], 1);
+
+ info->ad.analog.serration_on_vsync = get_bit (edid[0x14], 0);
+ }
+
+ /* Screen Size / Aspect Ratio */
+ if (edid[0x15] == 0 && edid[0x16] == 0)
+ {
+ info->width_mm = -1;
+ info->height_mm = -1;
+ info->aspect_ratio = -1.0;
+ }
+ else if (edid[0x16] == 0)
+ {
+ info->width_mm = -1;
+ info->height_mm = -1;
+ info->aspect_ratio = 100.0 / (edid[0x15] + 99);
+ }
+ else if (edid[0x15] == 0)
+ {
+ info->width_mm = -1;
+ info->height_mm = -1;
+ info->aspect_ratio = 100.0 / (edid[0x16] + 99);
+ info->aspect_ratio = 1/info->aspect_ratio; /* portrait */
+ }
+ else
+ {
+ info->width_mm = 10 * edid[0x15];
+ info->height_mm = 10 * edid[0x16];
+ }
+
+ /* Gamma */
+ if (edid[0x17] == 0xFF)
+ info->gamma = -1.0;
+ else
+ info->gamma = (edid[0x17] + 100.0) / 100.0;
+
+ /* Features */
+ info->standby = get_bit (edid[0x18], 7);
+ info->suspend = get_bit (edid[0x18], 6);
+ info->active_off = get_bit (edid[0x18], 5);
+
+ if (info->is_digital)
+ {
+ info->ad.digital.rgb444 = TRUE;
+ if (get_bit (edid[0x18], 3))
+ info->ad.digital.ycrcb444 = 1;
+ if (get_bit (edid[0x18], 4))
+ info->ad.digital.ycrcb422 = 1;
+ }
+ else
+ {
+ int bits = get_bits (edid[0x18], 3, 4);
+ ColorType color_type[4] =
+ {
+ MONOCHROME, RGB, OTHER_COLOR, UNDEFINED_COLOR
+ };
+
+ info->ad.analog.color_type = color_type[bits];
+ }
+
+ info->srgb_is_standard = get_bit (edid[0x18], 2);
+
+ /* In 1.3 this is called "has preferred timing" */
+ info->preferred_timing_includes_native = get_bit (edid[0x18], 1);
+
+ /* FIXME: In 1.3 this indicates whether the monitor accepts GTF */
+ info->continuous_frequency = get_bit (edid[0x18], 0);
+ return TRUE;
+}
+
+static double
+decode_fraction (int high, int low)
+{
+ double result = 0.0;
+ int i;
+
+ high = (high << 2) | low;
+
+ for (i = 0; i < 10; ++i)
+ result += get_bit (high, i) * SDL_pow (2, i - 10);
+
+ return result;
+}
+
+static int
+decode_color_characteristics (const uchar *edid, MonitorInfo *info)
+{
+ info->red_x = decode_fraction (edid[0x1b], get_bits (edid[0x19], 6, 7));
+ info->red_y = decode_fraction (edid[0x1c], get_bits (edid[0x19], 5, 4));
+ info->green_x = decode_fraction (edid[0x1d], get_bits (edid[0x19], 2, 3));
+ info->green_y = decode_fraction (edid[0x1e], get_bits (edid[0x19], 0, 1));
+ info->blue_x = decode_fraction (edid[0x1f], get_bits (edid[0x1a], 6, 7));
+ info->blue_y = decode_fraction (edid[0x20], get_bits (edid[0x1a], 4, 5));
+ info->white_x = decode_fraction (edid[0x21], get_bits (edid[0x1a], 2, 3));
+ info->white_y = decode_fraction (edid[0x22], get_bits (edid[0x1a], 0, 1));
+
+ return TRUE;
+}
+
+static int
+decode_established_timings (const uchar *edid, MonitorInfo *info)
+{
+ static const Timing established[][8] =
+ {
+ {
+ { 800, 600, 60 },
+ { 800, 600, 56 },
+ { 640, 480, 75 },
+ { 640, 480, 72 },
+ { 640, 480, 67 },
+ { 640, 480, 60 },
+ { 720, 400, 88 },
+ { 720, 400, 70 }
+ },
+ {
+ { 1280, 1024, 75 },
+ { 1024, 768, 75 },
+ { 1024, 768, 70 },
+ { 1024, 768, 60 },
+ { 1024, 768, 87 },
+ { 832, 624, 75 },
+ { 800, 600, 75 },
+ { 800, 600, 72 }
+ },
+ {
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 1152, 870, 75 }
+ },
+ };
+
+ int i, j, idx;
+
+ idx = 0;
+ for (i = 0; i < 3; ++i)
+ {
+ for (j = 0; j < 8; ++j)
+ {
+ int byte = edid[0x23 + i];
+
+ if (get_bit (byte, j) && established[i][j].frequency != 0)
+ info->established[idx++] = established[i][j];
+ }
+ }
+ return TRUE;
+}
+
+static int
+decode_standard_timings (const uchar *edid, MonitorInfo *info)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ int first = edid[0x26 + 2 * i];
+ int second = edid[0x27 + 2 * i];
+
+ if (first != 0x01 && second != 0x01)
+ {
+ int w = 8 * (first + 31);
+ int h = 0;
+
+ switch (get_bits (second, 6, 7))
+ {
+ case 0x00: h = (w / 16) * 10; break;
+ case 0x01: h = (w / 4) * 3; break;
+ case 0x02: h = (w / 5) * 4; break;
+ case 0x03: h = (w / 16) * 9; break;
+ }
+
+ info->standard[i].width = w;
+ info->standard[i].height = h;
+ info->standard[i].frequency = get_bits (second, 0, 5) + 60;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+decode_lf_string (const uchar *s, int n_chars, char *result)
+{
+ int i;
+ for (i = 0; i < n_chars; ++i)
+ {
+ if (s[i] == 0x0a)
+ {
+ *result++ = '\0';
+ break;
+ }
+ else if (s[i] == 0x00)
+ {
+ /* Convert embedded 0's to spaces */
+ *result++ = ' ';
+ }
+ else
+ {
+ *result++ = s[i];
+ }
+ }
+}
+
+static void
+decode_display_descriptor (const uchar *desc,
+ MonitorInfo *info)
+{
+ switch (desc[0x03])
+ {
+ case 0xFC:
+ decode_lf_string (desc + 5, 13, info->dsc_product_name);
+ break;
+ case 0xFF:
+ decode_lf_string (desc + 5, 13, info->dsc_serial_number);
+ break;
+ case 0xFE:
+ decode_lf_string (desc + 5, 13, info->dsc_string);
+ break;
+ case 0xFD:
+ /* Range Limits */
+ break;
+ case 0xFB:
+ /* Color Point */
+ break;
+ case 0xFA:
+ /* Timing Identifications */
+ break;
+ case 0xF9:
+ /* Color Management */
+ break;
+ case 0xF8:
+ /* Timing Codes */
+ break;
+ case 0xF7:
+ /* Established Timings */
+ break;
+ case 0x10:
+ break;
+ }
+}
+
+static void
+decode_detailed_timing (const uchar *timing,
+ DetailedTiming *detailed)
+{
+ int bits;
+ StereoType stereo[] =
+ {
+ NO_STEREO, NO_STEREO, FIELD_RIGHT, FIELD_LEFT,
+ TWO_WAY_RIGHT_ON_EVEN, TWO_WAY_LEFT_ON_EVEN,
+ FOUR_WAY_INTERLEAVED, SIDE_BY_SIDE
+ };
+
+ detailed->pixel_clock = (timing[0x00] | timing[0x01] << 8) * 10000;
+ detailed->h_addr = timing[0x02] | ((timing[0x04] & 0xf0) << 4);
+ detailed->h_blank = timing[0x03] | ((timing[0x04] & 0x0f) << 8);
+ detailed->v_addr = timing[0x05] | ((timing[0x07] & 0xf0) << 4);
+ detailed->v_blank = timing[0x06] | ((timing[0x07] & 0x0f) << 8);
+ detailed->h_front_porch = timing[0x08] | get_bits (timing[0x0b], 6, 7) << 8;
+ detailed->h_sync = timing[0x09] | get_bits (timing[0x0b], 4, 5) << 8;
+ detailed->v_front_porch =
+ get_bits (timing[0x0a], 4, 7) | get_bits (timing[0x0b], 2, 3) << 4;
+ detailed->v_sync =
+ get_bits (timing[0x0a], 0, 3) | get_bits (timing[0x0b], 0, 1) << 4;
+ detailed->width_mm = timing[0x0c] | get_bits (timing[0x0e], 4, 7) << 8;
+ detailed->height_mm = timing[0x0d] | get_bits (timing[0x0e], 0, 3) << 8;
+ detailed->right_border = timing[0x0f];
+ detailed->top_border = timing[0x10];
+
+ detailed->interlaced = get_bit (timing[0x11], 7);
+
+ /* Stereo */
+ bits = get_bits (timing[0x11], 5, 6) << 1 | get_bit (timing[0x11], 0);
+ detailed->stereo = stereo[bits];
+
+ /* Sync */
+ bits = timing[0x11];
+
+ detailed->digital_sync = get_bit (bits, 4);
+ if (detailed->digital_sync)
+ {
+ detailed->ad.digital.composite = !get_bit (bits, 3);
+
+ if (detailed->ad.digital.composite)
+ {
+ detailed->ad.digital.serrations = get_bit (bits, 2);
+ detailed->ad.digital.negative_vsync = FALSE;
+ }
+ else
+ {
+ detailed->ad.digital.serrations = FALSE;
+ detailed->ad.digital.negative_vsync = !get_bit (bits, 2);
+ }
+
+ detailed->ad.digital.negative_hsync = !get_bit (bits, 0);
+ }
+ else
+ {
+ detailed->ad.analog.bipolar = get_bit (bits, 3);
+ detailed->ad.analog.serrations = get_bit (bits, 2);
+ detailed->ad.analog.sync_on_green = !get_bit (bits, 1);
+ }
+}
+
+static int
+decode_descriptors (const uchar *edid, MonitorInfo *info)
+{
+ int i;
+ int timing_idx;
+
+ timing_idx = 0;
+
+ for (i = 0; i < 4; ++i)
+ {
+ int index = 0x36 + i * 18;
+
+ if (edid[index + 0] == 0x00 && edid[index + 1] == 0x00)
+ {
+ decode_display_descriptor (edid + index, info);
+ }
+ else
+ {
+ decode_detailed_timing (
+ edid + index, &(info->detailed_timings[timing_idx++]));
+ }
+ }
+
+ info->n_detailed_timings = timing_idx;
+
+ return TRUE;
+}
+
+static void
+decode_check_sum (const uchar *edid,
+ MonitorInfo *info)
+{
+ int i;
+ uchar check = 0;
+
+ for (i = 0; i < 128; ++i)
+ check += edid[i];
+
+ info->checksum = check;
+}
+
+MonitorInfo *
+decode_edid (const uchar *edid)
+{
+ MonitorInfo *info = calloc (1, sizeof (MonitorInfo));
+
+ decode_check_sum (edid, info);
+
+ if (!decode_header (edid) ||
+ !decode_vendor_and_product_identification (edid, info) ||
+ !decode_edid_version (edid, info) ||
+ !decode_display_parameters (edid, info) ||
+ !decode_color_characteristics (edid, info) ||
+ !decode_established_timings (edid, info) ||
+ !decode_standard_timings (edid, info) ||
+ !decode_descriptors (edid, info)) {
+ free(info);
+ return NULL;
+ }
+
+ return info;
+}
+
+static const char *
+yesno (int v)
+{
+ return v? "yes" : "no";
+}
+
+void
+dump_monitor_info (MonitorInfo *info)
+{
+ int i;
+
+ printf ("Checksum: %d (%s)\n",
+ info->checksum, info->checksum? "incorrect" : "correct");
+ printf ("Manufacturer Code: %s\n", info->manufacturer_code);
+ printf ("Product Code: 0x%x\n", info->product_code);
+ printf ("Serial Number: %u\n", info->serial_number);
+
+ if (info->production_week != -1)
+ printf ("Production Week: %d\n", info->production_week);
+ else
+ printf ("Production Week: unspecified\n");
+
+ if (info->production_year != -1)
+ printf ("Production Year: %d\n", info->production_year);
+ else
+ printf ("Production Year: unspecified\n");
+
+ if (info->model_year != -1)
+ printf ("Model Year: %d\n", info->model_year);
+ else
+ printf ("Model Year: unspecified\n");
+
+ printf ("EDID revision: %d.%d\n", info->major_version, info->minor_version);
+
+ printf ("Display is %s\n", info->is_digital? "digital" : "analog");
+ if (info->is_digital)
+ {
+ const char *interface;
+ if (info->ad.digital.bits_per_primary != -1)
+ printf ("Bits Per Primary: %d\n", info->ad.digital.bits_per_primary);
+ else
+ printf ("Bits Per Primary: undefined\n");
+
+ switch (info->ad.digital.interface)
+ {
+ case DVI: interface = "DVI"; break;
+ case HDMI_A: interface = "HDMI-a"; break;
+ case HDMI_B: interface = "HDMI-b"; break;
+ case MDDI: interface = "MDDI"; break;
+ case DISPLAY_PORT: interface = "DisplayPort"; break;
+ case UNDEFINED: interface = "undefined"; break;
+ default: interface = "unknown"; break;
+ }
+ printf ("Interface: %s\n", interface);
+
+ printf ("RGB 4:4:4: %s\n", yesno (info->ad.digital.rgb444));
+ printf ("YCrCb 4:4:4: %s\n", yesno (info->ad.digital.ycrcb444));
+ printf ("YCrCb 4:2:2: %s\n", yesno (info->ad.digital.ycrcb422));
+ }
+ else
+ {
+ const char *s;
+ printf ("Video Signal Level: %f\n", info->ad.analog.video_signal_level);
+ printf ("Sync Signal Level: %f\n", info->ad.analog.sync_signal_level);
+ printf ("Total Signal Level: %f\n", info->ad.analog.total_signal_level);
+
+ printf ("Blank to Black: %s\n",
+ yesno (info->ad.analog.blank_to_black));
+ printf ("Separate HV Sync: %s\n",
+ yesno (info->ad.analog.separate_hv_sync));
+ printf ("Composite Sync on H: %s\n",
+ yesno (info->ad.analog.composite_sync_on_h));
+ printf ("Serration on VSync: %s\n",
+ yesno (info->ad.analog.serration_on_vsync));
+
+ switch (info->ad.analog.color_type)
+ {
+ case UNDEFINED_COLOR: s = "undefined"; break;
+ case MONOCHROME: s = "monochrome"; break;
+ case RGB: s = "rgb"; break;
+ case OTHER_COLOR: s = "other color"; break;
+ default: s = "unknown"; break;
+ };
+
+ printf ("Color: %s\n", s);
+ }
+
+ if (info->width_mm == -1)
+ printf ("Width: undefined\n");
+ else
+ printf ("Width: %d mm\n", info->width_mm);
+
+ if (info->height_mm == -1)
+ printf ("Height: undefined\n");
+ else
+ printf ("Height: %d mm\n", info->height_mm);
+
+ if (info->aspect_ratio > 0)
+ printf ("Aspect Ratio: %f\n", info->aspect_ratio);
+ else
+ printf ("Aspect Ratio: undefined\n");
+
+ if (info->gamma >= 0)
+ printf ("Gamma: %f\n", info->gamma);
+ else
+ printf ("Gamma: undefined\n");
+
+ printf ("Standby: %s\n", yesno (info->standby));
+ printf ("Suspend: %s\n", yesno (info->suspend));
+ printf ("Active Off: %s\n", yesno (info->active_off));
+
+ printf ("SRGB is Standard: %s\n", yesno (info->srgb_is_standard));
+ printf ("Preferred Timing Includes Native: %s\n",
+ yesno (info->preferred_timing_includes_native));
+ printf ("Continuous Frequency: %s\n", yesno (info->continuous_frequency));
+
+ printf ("Red X: %f\n", info->red_x);
+ printf ("Red Y: %f\n", info->red_y);
+ printf ("Green X: %f\n", info->green_x);
+ printf ("Green Y: %f\n", info->green_y);
+ printf ("Blue X: %f\n", info->blue_x);
+ printf ("Blue Y: %f\n", info->blue_y);
+ printf ("White X: %f\n", info->white_x);
+ printf ("White Y: %f\n", info->white_y);
+
+ printf ("Established Timings:\n");
+
+ for (i = 0; i < 24; ++i)
+ {
+ Timing *timing = &(info->established[i]);
+
+ if (timing->frequency == 0)
+ break;
+
+ printf (" %d x %d @ %d Hz\n",
+ timing->width, timing->height, timing->frequency);
+
+ }
+
+ printf ("Standard Timings:\n");
+ for (i = 0; i < 8; ++i)
+ {
+ Timing *timing = &(info->standard[i]);
+
+ if (timing->frequency == 0)
+ break;
+
+ printf (" %d x %d @ %d Hz\n",
+ timing->width, timing->height, timing->frequency);
+ }
+
+ for (i = 0; i < info->n_detailed_timings; ++i)
+ {
+ DetailedTiming *timing = &(info->detailed_timings[i]);
+ const char *s;
+
+ printf ("Timing%s: \n",
+ (i == 0 && info->preferred_timing_includes_native)?
+ " (Preferred)" : "");
+ printf (" Pixel Clock: %d\n", timing->pixel_clock);
+ printf (" H Addressable: %d\n", timing->h_addr);
+ printf (" H Blank: %d\n", timing->h_blank);
+ printf (" H Front Porch: %d\n", timing->h_front_porch);
+ printf (" H Sync: %d\n", timing->h_sync);
+ printf (" V Addressable: %d\n", timing->v_addr);
+ printf (" V Blank: %d\n", timing->v_blank);
+ printf (" V Front Porch: %d\n", timing->v_front_porch);
+ printf (" V Sync: %d\n", timing->v_sync);
+ printf (" Width: %d mm\n", timing->width_mm);
+ printf (" Height: %d mm\n", timing->height_mm);
+ printf (" Right Border: %d\n", timing->right_border);
+ printf (" Top Border: %d\n", timing->top_border);
+ switch (timing->stereo)
+ {
+ default:
+ case NO_STEREO: s = "No Stereo"; break;
+ case FIELD_RIGHT: s = "Field Sequential, Right on Sync"; break;
+ case FIELD_LEFT: s = "Field Sequential, Left on Sync"; break;
+ case TWO_WAY_RIGHT_ON_EVEN: s = "Two-way, Right on Even"; break;
+ case TWO_WAY_LEFT_ON_EVEN: s = "Two-way, Left on Even"; break;
+ case FOUR_WAY_INTERLEAVED: s = "Four-way Interleaved"; break;
+ case SIDE_BY_SIDE: s = "Side-by-Side"; break;
+ }
+ printf (" Stereo: %s\n", s);
+
+ if (timing->digital_sync)
+ {
+ printf (" Digital Sync:\n");
+ printf (" composite: %s\n", yesno (timing->ad.digital.composite));
+ printf (" serrations: %s\n", yesno (timing->ad.digital.serrations));
+ printf (" negative vsync: %s\n",
+ yesno (timing->ad.digital.negative_vsync));
+ printf (" negative hsync: %s\n",
+ yesno (timing->ad.digital.negative_hsync));
+ }
+ else
+ {
+ printf (" Analog Sync:\n");
+ printf (" bipolar: %s\n", yesno (timing->ad.analog.bipolar));
+ printf (" serrations: %s\n", yesno (timing->ad.analog.serrations));
+ printf (" sync on green: %s\n", yesno (
+ timing->ad.analog.sync_on_green));
+ }
+ }
+
+ printf ("Detailed Product information:\n");
+ printf (" Product Name: %s\n", info->dsc_product_name);
+ printf (" Serial Number: %s\n", info->dsc_serial_number);
+ printf (" Unspecified String: %s\n", info->dsc_string);
+}
+
diff --git a/source/3rd-party/SDL2/src/video/x11/edid.h b/source/3rd-party/SDL2/src/video/x11/edid.h
new file mode 100644
index 0000000..cb9f0e8
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/edid.h
@@ -0,0 +1,167 @@
+typedef unsigned char uchar;
+typedef struct MonitorInfo MonitorInfo;
+typedef struct Timing Timing;
+typedef struct DetailedTiming DetailedTiming;
+
+typedef enum
+{
+ UNDEFINED,
+ DVI,
+ HDMI_A,
+ HDMI_B,
+ MDDI,
+ DISPLAY_PORT
+} Interface;
+
+typedef enum
+{
+ UNDEFINED_COLOR,
+ MONOCHROME,
+ RGB,
+ OTHER_COLOR
+} ColorType;
+
+typedef enum
+{
+ NO_STEREO,
+ FIELD_RIGHT,
+ FIELD_LEFT,
+ TWO_WAY_RIGHT_ON_EVEN,
+ TWO_WAY_LEFT_ON_EVEN,
+ FOUR_WAY_INTERLEAVED,
+ SIDE_BY_SIDE
+} StereoType;
+
+struct Timing
+{
+ int width;
+ int height;
+ int frequency;
+};
+
+struct DetailedTiming
+{
+ int pixel_clock;
+ int h_addr;
+ int h_blank;
+ int h_sync;
+ int h_front_porch;
+ int v_addr;
+ int v_blank;
+ int v_sync;
+ int v_front_porch;
+ int width_mm;
+ int height_mm;
+ int right_border;
+ int top_border;
+ int interlaced;
+ StereoType stereo;
+
+ int digital_sync;
+ union
+ {
+ struct
+ {
+ int bipolar;
+ int serrations;
+ int sync_on_green;
+ } analog;
+
+ struct
+ {
+ int composite;
+ int serrations;
+ int negative_vsync;
+ int negative_hsync;
+ } digital;
+ } ad;
+};
+
+struct MonitorInfo
+{
+ int checksum;
+ char manufacturer_code[4];
+ int product_code;
+ unsigned int serial_number;
+
+ int production_week; /* -1 if not specified */
+ int production_year; /* -1 if not specified */
+ int model_year; /* -1 if not specified */
+
+ int major_version;
+ int minor_version;
+
+ int is_digital;
+
+ union
+ {
+ struct
+ {
+ int bits_per_primary;
+ Interface interface;
+ int rgb444;
+ int ycrcb444;
+ int ycrcb422;
+ } digital;
+
+ struct
+ {
+ double video_signal_level;
+ double sync_signal_level;
+ double total_signal_level;
+
+ int blank_to_black;
+
+ int separate_hv_sync;
+ int composite_sync_on_h;
+ int composite_sync_on_green;
+ int serration_on_vsync;
+ ColorType color_type;
+ } analog;
+ } ad;
+
+ int width_mm; /* -1 if not specified */
+ int height_mm; /* -1 if not specified */
+ double aspect_ratio; /* -1.0 if not specififed */
+
+ double gamma; /* -1.0 if not specified */
+
+ int standby;
+ int suspend;
+ int active_off;
+
+ int srgb_is_standard;
+ int preferred_timing_includes_native;
+ int continuous_frequency;
+
+ double red_x;
+ double red_y;
+ double green_x;
+ double green_y;
+ double blue_x;
+ double blue_y;
+ double white_x;
+ double white_y;
+
+ Timing established[24]; /* Terminated by 0x0x0 */
+ Timing standard[8];
+
+ int n_detailed_timings;
+ DetailedTiming detailed_timings[4]; /* If monitor has a preferred
+ * mode, it is the first one
+ * (whether it has, is
+ * determined by the
+ * preferred_timing_includes
+ * bit.
+ */
+
+ /* Optional product description */
+ char dsc_serial_number[14];
+ char dsc_product_name[14];
+ char dsc_string[14]; /* Unspecified ASCII data */
+};
+
+MonitorInfo *decode_edid (const uchar *data);
+void dump_monitor_info (MonitorInfo *info);
+char * make_display_name (const char *output_name,
+ const MonitorInfo *info);
diff --git a/source/3rd-party/SDL2/src/video/x11/imKStoUCS.c b/source/3rd-party/SDL2/src/video/x11/imKStoUCS.c
new file mode 100644
index 0000000..40e2242
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/imKStoUCS.c
@@ -0,0 +1,350 @@
+/*
+Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
+Copyright © 2009 Red Hat, Inc.
+Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_X11
+#include <X11/X.h>
+#include "imKStoUCS.h"
+
+static unsigned short const keysym_to_unicode_1a1_1ff[] = {
+ 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */
+ 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */
+ 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */
+ 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */
+ 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */
+ 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */
+ 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */
+ 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */
+ 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */
+ 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */
+ 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */
+ 0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */
+};
+
+static unsigned short const keysym_to_unicode_2a1_2fe[] = {
+ 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */
+ 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */
+ 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */
+ 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */
+ 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */
+ 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */
+};
+
+static unsigned short const keysym_to_unicode_3a2_3fe[] = {
+ 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */
+ 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */
+ 0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */
+ 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */
+ 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */
+ 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */
+ 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */
+ 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */
+ 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */
+ 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */
+};
+
+static unsigned short const keysym_to_unicode_4a1_4df[] = {
+ 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */
+ 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */
+ 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */
+ 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */
+ 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */
+ 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */
+ 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */
+ 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */
+};
+
+static unsigned short const keysym_to_unicode_590_5fe[] = {
+ 0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */
+ 0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */
+
+ 0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */
+ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */
+ 0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */
+ 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */
+ 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */
+ 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */
+ 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */
+ 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */
+ 0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */
+};
+
+static unsigned short keysym_to_unicode_680_6ff[] = {
+ 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */
+ 0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */
+ 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */
+ 0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */
+ 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */
+ 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */
+ 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */
+ 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */
+ 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */
+ 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */
+ 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */
+ 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */
+ 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */
+ 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */
+};
+
+static unsigned short const keysym_to_unicode_7a1_7f9[] = {
+ 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */
+ 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */
+ 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */
+ 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */
+ 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */
+ 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */
+ 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */
+ 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */
+ 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */
+ 0x03c8, 0x03c9 /* 0x07f8-0x07ff */
+};
+
+static unsigned short const keysym_to_unicode_8a4_8fe[] = {
+ 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */
+ 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */
+ 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */
+ 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x21d2, 0x0000, /* 0x08c8-0x08cf */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */
+ 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202, /* 0x08e8-0x08ef */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */
+ 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */
+};
+
+static unsigned short const keysym_to_unicode_9df_9f8[] = {
+ 0x2422, /* 0x09d8-0x09df */
+ 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */
+ 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */
+ 0x2502 /* 0x09f8-0x09ff */
+};
+
+static unsigned short const keysym_to_unicode_aa1_afe[] = {
+ 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */
+ 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */
+ 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */
+ 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */
+ 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */
+ 0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */
+ 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x2030, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */
+ 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */
+ 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */
+ 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */
+ 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */
+ 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */
+};
+
+/* none of the APL keysyms match the Unicode characters */
+
+static unsigned short const keysym_to_unicode_cdf_cfa[] = {
+ 0x2017, /* 0x0cd8-0x0cdf */
+ 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */
+ 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */
+ 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */
+ 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */
+};
+
+static unsigned short const keysym_to_unicode_da1_df9[] = {
+ 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */
+ 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */
+ 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */
+ 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */
+ 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */
+ 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */
+ 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */
+ 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */
+ 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */
+ 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */
+ 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */
+ 0x0e58, 0x0e59 /* 0x0df8-0x0dff */
+};
+
+static unsigned short const keysym_to_unicode_ea0_eff[] = {
+ 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */
+ 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */
+ 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */
+ 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */
+ 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */
+ 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */
+ 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */
+ 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */
+ 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */
+ 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */
+ 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */
+ 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */
+};
+
+static unsigned short keysym_to_unicode_12a1_12fe[] = {
+ 0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */
+ 0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */
+ 0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */
+ 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */
+ 0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */
+ 0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */
+};
+
+static unsigned short const keysym_to_unicode_13bc_13be[] = {
+ 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */
+};
+
+static unsigned short keysym_to_unicode_14a1_14ff[] = {
+ 0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */
+ 0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */
+ 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */
+ 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */
+ 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */
+ 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */
+ 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */
+ 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */
+ 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */
+ 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */
+ 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */
+ 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */
+};
+
+static unsigned short keysym_to_unicode_15d0_15f6[] = {
+ 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */
+ 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */
+ 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */
+ 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */
+ 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */
+};
+
+static unsigned short keysym_to_unicode_16a0_16f6[] = {
+ 0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */
+ 0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */
+ 0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */
+ 0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */
+ 0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */
+ 0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */
+};
+
+static unsigned short const keysym_to_unicode_1e9f_1eff[] = {
+ 0x0303,
+ 0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */
+ 0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */
+ 0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */
+ 0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */
+ 0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */
+ 0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */
+ 0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */
+ 0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */
+ 0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */
+ 0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */
+ 0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */
+ 0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */
+};
+
+static unsigned short const keysym_to_unicode_20a0_20ac[] = {
+ 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */
+ 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */
+};
+
+unsigned int
+X11_KeySymToUcs4(KeySym keysym)
+{
+ /* 'Unicode keysym' */
+ if ((keysym & 0xff000000) == 0x01000000)
+ return (keysym & 0x00ffffff);
+
+ if (keysym > 0 && keysym < 0x100)
+ return keysym;
+ else if (keysym > 0x1a0 && keysym < 0x200)
+ return keysym_to_unicode_1a1_1ff[keysym - 0x1a1];
+ else if (keysym > 0x2a0 && keysym < 0x2ff)
+ return keysym_to_unicode_2a1_2fe[keysym - 0x2a1];
+ else if (keysym > 0x3a1 && keysym < 0x3ff)
+ return keysym_to_unicode_3a2_3fe[keysym - 0x3a2];
+ else if (keysym > 0x4a0 && keysym < 0x4e0)
+ return keysym_to_unicode_4a1_4df[keysym - 0x4a1];
+ else if (keysym > 0x589 && keysym < 0x5ff)
+ return keysym_to_unicode_590_5fe[keysym - 0x590];
+ else if (keysym > 0x67f && keysym < 0x700)
+ return keysym_to_unicode_680_6ff[keysym - 0x680];
+ else if (keysym > 0x7a0 && keysym < 0x7fa)
+ return keysym_to_unicode_7a1_7f9[keysym - 0x7a1];
+ else if (keysym > 0x8a3 && keysym < 0x8ff)
+ return keysym_to_unicode_8a4_8fe[keysym - 0x8a4];
+ else if (keysym > 0x9de && keysym < 0x9f9)
+ return keysym_to_unicode_9df_9f8[keysym - 0x9df];
+ else if (keysym > 0xaa0 && keysym < 0xaff)
+ return keysym_to_unicode_aa1_afe[keysym - 0xaa1];
+ else if (keysym > 0xcde && keysym < 0xcfb)
+ return keysym_to_unicode_cdf_cfa[keysym - 0xcdf];
+ else if (keysym > 0xda0 && keysym < 0xdfa)
+ return keysym_to_unicode_da1_df9[keysym - 0xda1];
+ else if (keysym > 0xe9f && keysym < 0xf00)
+ return keysym_to_unicode_ea0_eff[keysym - 0xea0];
+ else if (keysym > 0x12a0 && keysym < 0x12ff)
+ return keysym_to_unicode_12a1_12fe[keysym - 0x12a1];
+ else if (keysym > 0x13bb && keysym < 0x13bf)
+ return keysym_to_unicode_13bc_13be[keysym - 0x13bc];
+ else if (keysym > 0x14a0 && keysym < 0x1500)
+ return keysym_to_unicode_14a1_14ff[keysym - 0x14a1];
+ else if (keysym > 0x15cf && keysym < 0x15f7)
+ return keysym_to_unicode_15d0_15f6[keysym - 0x15d0];
+ else if (keysym > 0x169f && keysym < 0x16f7)
+ return keysym_to_unicode_16a0_16f6[keysym - 0x16a0];
+ else if (keysym > 0x1e9e && keysym < 0x1f00)
+ return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f];
+ else if (keysym > 0x209f && keysym < 0x20ad)
+ return keysym_to_unicode_20a0_20ac[keysym - 0x20a0];
+ else
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11 */
+
diff --git a/source/3rd-party/SDL2/src/video/x11/imKStoUCS.h b/source/3rd-party/SDL2/src/video/x11/imKStoUCS.h
new file mode 100644
index 0000000..fe4381d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/x11/imKStoUCS.h
@@ -0,0 +1,32 @@
+#ifndef _imKStoUCS_h
+#define _imKStoUCS_h
+
+/*
+Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
+Copyright © 2009 Red Hat, Inc.
+Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+extern unsigned int X11_KeySymToUcs4(KeySym keysym);
+
+#endif /* _imKStoUCS_h */
diff --git a/source/3rd-party/SDL2/src/video/yuv2rgb/LICENSE b/source/3rd-party/SDL2/src/video/yuv2rgb/LICENSE
new file mode 100644
index 0000000..a76efd7
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/yuv2rgb/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2016, Adrien Descamps
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of yuv2rgb nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/source/3rd-party/SDL2/src/video/yuv2rgb/README.md b/source/3rd-party/SDL2/src/video/yuv2rgb/README.md
new file mode 100644
index 0000000..21191e9
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/yuv2rgb/README.md
@@ -0,0 +1,63 @@
+From: https://github.com/descampsa/yuv2rgb
+# yuv2rgb
+C library for fast image conversion between yuv420p and rgb24.
+
+This is a simple library for optimized image conversion between YUV420p and rgb24.
+It was done mainly as an exercise to learn to use sse intrinsics, so there may still be room for optimization.
+
+For each conversion, a standard c optimized function and two sse function (with aligned and unaligned memory) are implemented.
+The sse version requires only SSE2, which is available on any reasonably recent CPU.
+The library also supports the three different YUV (YCrCb to be correct) color spaces that exist (see comments in code), and others can be added simply.
+
+There is a simple test program, that convert a raw YUV file to rgb ppm format, and measure computation time.
+Optionally, it also compares the result and computation time with the ffmpeg implementation (that uses MMX), and with the IPP functions.
+
+To compile, simply do :
+
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release ..
+ make
+
+The test program only support raw YUV files for the YUV420 format, and ppm for the RGB24 format.
+To generate a raw yuv file, you can use avconv:
+
+ avconv -i example.jpg -c:v rawvideo -pix_fmt yuv420p example.yuv
+
+To generate the rgb file, you can use the ImageMagick convert program:
+
+ convert example.jpg example.ppm
+
+Then, for YUV420 to RGB24 conversion, use the test program like that:
+
+ ./test_yuv_rgb yuv2rgb image.yuv 4096 2160 image
+
+The second and third parameters are image width and height (that are needed because not available in the raw YUV file), and fourth parameter is the output filename template (several output files will be generated, named for example output_sse.ppm, output_av.ppm, etc.)
+
+Similarly, for RGB24 to YUV420 conversion:
+
+ ./test_yuv_rgb yuv2rgb image.ppm image
+
+On my computer, the test program on a 4K image give the following for yuv2rgb:
+
+ Time will be measured in each configuration for 100 iterations...
+ Processing time (std) : 2.630193 sec
+ Processing time (sse2_unaligned) : 0.704394 sec
+ Processing time (ffmpeg_unaligned) : 1.221432 sec
+ Processing time (ipp_unaligned) : 0.636274 sec
+ Processing time (sse2_aligned) : 0.606648 sec
+ Processing time (ffmpeg_aligned) : 1.227100 sec
+ Processing time (ipp_aligned) : 0.636951 sec
+
+And for rgb2yuv:
+
+ Time will be measured in each configuration for 100 iterations...
+ Processing time (std) : 2.588675 sec
+ Processing time (sse2_unaligned) : 0.676625 sec
+ Processing time (ffmpeg_unaligned) : 3.385816 sec
+ Processing time (ipp_unaligned) : 0.593890 sec
+ Processing time (sse2_aligned) : 0.640630 sec
+ Processing time (ffmpeg_aligned) : 3.397952 sec
+ Processing time (ipp_aligned) : 0.579043 sec
+
+configuration : gcc 4.9.2, swscale 3.0.0, IPP 9.0.1, intel i7-5500U
diff --git a/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.c b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.c
new file mode 100644
index 0000000..891dae2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.c
@@ -0,0 +1,687 @@
+// Copyright 2016 Adrien Descamps
+// Distributed under BSD 3-Clause License
+#include "../../SDL_internal.h"
+
+#include "yuv_rgb.h"
+
+#include "SDL_cpuinfo.h"
+/*#include <x86intrin.h>*/
+
+#define PRECISION 6
+#define PRECISION_FACTOR (1<<PRECISION)
+
+typedef struct
+{
+ uint8_t y_shift;
+ int16_t matrix[3][3];
+} RGB2YUVParam;
+// |Y| |y_shift| |matrix[0][0] matrix[0][1] matrix[0][2]| |R|
+// |U| = | 128 | + 1/PRECISION_FACTOR * |matrix[1][0] matrix[1][1] matrix[1][2]| * |G|
+// |V| | 128 | |matrix[2][0] matrix[2][1] matrix[2][2]| |B|
+
+typedef struct
+{
+ uint8_t y_shift;
+ int16_t y_factor;
+ int16_t v_r_factor;
+ int16_t u_g_factor;
+ int16_t v_g_factor;
+ int16_t u_b_factor;
+} YUV2RGBParam;
+// |R| |y_factor 0 v_r_factor| |Y-y_shift|
+// |G| = 1/PRECISION_FACTOR * |y_factor u_g_factor v_g_factor| * | U-128 |
+// |B| |y_factor u_b_factor 0 | | V-128 |
+
+#define V(value) (int16_t)((value*PRECISION_FACTOR)+0.5)
+
+// for ITU-T T.871, values can be found in section 7
+// for ITU-R BT.601-7 values are derived from equations in sections 2.5.1-2.5.3, assuming RGB is encoded using full range ([0-1]<->[0-255])
+// for ITU-R BT.709-6 values are derived from equations in sections 3.2-3.4, assuming RGB is encoded using full range ([0-1]<->[0-255])
+// all values are rounded to the fourth decimal
+
+static const YUV2RGBParam YUV2RGB[3] = {
+ // ITU-T T.871 (JPEG)
+ {/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.402), /*.u_g_factor=*/ -V(0.3441), /*.v_g_factor=*/ -V(0.7141), /*.u_b_factor=*/ V(1.772)},
+ // ITU-R BT.601-7
+ {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.596), /*.u_g_factor=*/ -V(0.3918), /*.v_g_factor=*/ -V(0.813), /*.u_b_factor=*/ V(2.0172)},
+ // ITU-R BT.709-6
+ {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.7927), /*.u_g_factor=*/ -V(0.2132), /*.v_g_factor=*/ -V(0.5329), /*.u_b_factor=*/ V(2.1124)}
+};
+
+static const RGB2YUVParam RGB2YUV[3] = {
+ // ITU-T T.871 (JPEG)
+ {/*.y_shift=*/ 0, /*.matrix=*/ {{V(0.299), V(0.587), V(0.114)}, {-V(0.1687), -V(0.3313), V(0.5)}, {V(0.5), -V(0.4187), -V(0.0813)}}},
+ // ITU-R BT.601-7
+ {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.2568), V(0.5041), V(0.0979)}, {-V(0.1482), -V(0.291), V(0.4392)}, {V(0.4392), -V(0.3678), -V(0.0714)}}},
+ // ITU-R BT.709-6
+ {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.1826), V(0.6142), V(0.062)}, {-V(0.1006), -V(0.3386), V(0.4392)}, {V(0.4392), -V(0.3989), -V(0.0403)}}}
+};
+
+/* The various layouts of YUV data we support */
+#define YUV_FORMAT_420 1
+#define YUV_FORMAT_422 2
+#define YUV_FORMAT_NV12 3
+
+/* The various formats of RGB pixel that we support */
+#define RGB_FORMAT_RGB565 1
+#define RGB_FORMAT_RGB24 2
+#define RGB_FORMAT_RGBA 3
+#define RGB_FORMAT_BGRA 4
+#define RGB_FORMAT_ARGB 5
+#define RGB_FORMAT_ABGR 6
+
+// divide by PRECISION_FACTOR and clamp to [0:255] interval
+// input must be in the [-128*PRECISION_FACTOR:384*PRECISION_FACTOR] range
+static uint8_t clampU8(int32_t v)
+{
+ static const uint8_t lut[512] =
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,
+ 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,
+ 91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
+ 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,
+ 159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
+ 225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+ };
+ return lut[(v+128*PRECISION_FACTOR)>>PRECISION];
+}
+
+
+#define STD_FUNCTION_NAME yuv420_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv420_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv420_rgba_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv420_bgra_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv420_argb_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv420_abgr_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv422_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv422_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv422_rgba_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv422_bgra_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv422_argb_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuv422_abgr_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuvnv12_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuvnv12_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuvnv12_rgba_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuvnv12_bgra_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuvnv12_argb_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#include "yuv_rgb_std_func.h"
+
+#define STD_FUNCTION_NAME yuvnv12_abgr_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#include "yuv_rgb_std_func.h"
+
+void rgb24_yuv420_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *RGB, uint32_t RGB_stride,
+ uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride,
+ YCbCrType yuv_type)
+{
+ const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]);
+
+ uint32_t x, y;
+ for(y=0; y<(height-1); y+=2)
+ {
+ const uint8_t *rgb_ptr1=RGB+y*RGB_stride,
+ *rgb_ptr2=RGB+(y+1)*RGB_stride;
+
+ uint8_t *y_ptr1=Y+y*Y_stride,
+ *y_ptr2=Y+(y+1)*Y_stride,
+ *u_ptr=U+(y/2)*UV_stride,
+ *v_ptr=V+(y/2)*UV_stride;
+
+ for(x=0; x<(width-1); x+=2)
+ {
+ // compute yuv for the four pixels, u and v values are summed
+ int32_t y_tmp, u_tmp, v_tmp;
+
+ y_tmp = param->matrix[0][0]*rgb_ptr1[0] + param->matrix[0][1]*rgb_ptr1[1] + param->matrix[0][2]*rgb_ptr1[2];
+ u_tmp = param->matrix[1][0]*rgb_ptr1[0] + param->matrix[1][1]*rgb_ptr1[1] + param->matrix[1][2]*rgb_ptr1[2];
+ v_tmp = param->matrix[2][0]*rgb_ptr1[0] + param->matrix[2][1]*rgb_ptr1[1] + param->matrix[2][2]*rgb_ptr1[2];
+ y_ptr1[0]=clampU8(y_tmp+((param->y_shift)<<PRECISION));
+
+ y_tmp = param->matrix[0][0]*rgb_ptr1[3] + param->matrix[0][1]*rgb_ptr1[4] + param->matrix[0][2]*rgb_ptr1[5];
+ u_tmp += param->matrix[1][0]*rgb_ptr1[3] + param->matrix[1][1]*rgb_ptr1[4] + param->matrix[1][2]*rgb_ptr1[5];
+ v_tmp += param->matrix[2][0]*rgb_ptr1[3] + param->matrix[2][1]*rgb_ptr1[4] + param->matrix[2][2]*rgb_ptr1[5];
+ y_ptr1[1]=clampU8(y_tmp+((param->y_shift)<<PRECISION));
+
+ y_tmp = param->matrix[0][0]*rgb_ptr2[0] + param->matrix[0][1]*rgb_ptr2[1] + param->matrix[0][2]*rgb_ptr2[2];
+ u_tmp += param->matrix[1][0]*rgb_ptr2[0] + param->matrix[1][1]*rgb_ptr2[1] + param->matrix[1][2]*rgb_ptr2[2];
+ v_tmp += param->matrix[2][0]*rgb_ptr2[0] + param->matrix[2][1]*rgb_ptr2[1] + param->matrix[2][2]*rgb_ptr2[2];
+ y_ptr2[0]=clampU8(y_tmp+((param->y_shift)<<PRECISION));
+
+ y_tmp = param->matrix[0][0]*rgb_ptr2[3] + param->matrix[0][1]*rgb_ptr2[4] + param->matrix[0][2]*rgb_ptr2[5];
+ u_tmp += param->matrix[1][0]*rgb_ptr2[3] + param->matrix[1][1]*rgb_ptr2[4] + param->matrix[1][2]*rgb_ptr2[5];
+ v_tmp += param->matrix[2][0]*rgb_ptr2[3] + param->matrix[2][1]*rgb_ptr2[4] + param->matrix[2][2]*rgb_ptr2[5];
+ y_ptr2[1]=clampU8(y_tmp+((param->y_shift)<<PRECISION));
+
+ u_ptr[0] = clampU8(u_tmp/4+(128<<PRECISION));
+ v_ptr[0] = clampU8(v_tmp/4+(128<<PRECISION));
+
+ rgb_ptr1 += 6;
+ rgb_ptr2 += 6;
+ y_ptr1 += 2;
+ y_ptr2 += 2;
+ u_ptr += 1;
+ v_ptr += 1;
+ }
+ }
+}
+
+#ifdef __SSE2__
+
+#define SSE_FUNCTION_NAME yuv420_rgb565_sse
+#define STD_FUNCTION_NAME yuv420_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_rgb565_sseu
+#define STD_FUNCTION_NAME yuv420_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_rgb24_sse
+#define STD_FUNCTION_NAME yuv420_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_rgb24_sseu
+#define STD_FUNCTION_NAME yuv420_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_rgba_sse
+#define STD_FUNCTION_NAME yuv420_rgba_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_rgba_sseu
+#define STD_FUNCTION_NAME yuv420_rgba_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_bgra_sse
+#define STD_FUNCTION_NAME yuv420_bgra_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_bgra_sseu
+#define STD_FUNCTION_NAME yuv420_bgra_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_argb_sse
+#define STD_FUNCTION_NAME yuv420_argb_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_argb_sseu
+#define STD_FUNCTION_NAME yuv420_argb_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_abgr_sse
+#define STD_FUNCTION_NAME yuv420_abgr_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv420_abgr_sseu
+#define STD_FUNCTION_NAME yuv420_abgr_std
+#define YUV_FORMAT YUV_FORMAT_420
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_rgb565_sse
+#define STD_FUNCTION_NAME yuv422_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_rgb565_sseu
+#define STD_FUNCTION_NAME yuv422_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_rgb24_sse
+#define STD_FUNCTION_NAME yuv422_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_rgb24_sseu
+#define STD_FUNCTION_NAME yuv422_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_rgba_sse
+#define STD_FUNCTION_NAME yuv422_rgba_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_rgba_sseu
+#define STD_FUNCTION_NAME yuv422_rgba_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_bgra_sse
+#define STD_FUNCTION_NAME yuv422_bgra_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_bgra_sseu
+#define STD_FUNCTION_NAME yuv422_bgra_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_argb_sse
+#define STD_FUNCTION_NAME yuv422_argb_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_argb_sseu
+#define STD_FUNCTION_NAME yuv422_argb_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_abgr_sse
+#define STD_FUNCTION_NAME yuv422_abgr_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuv422_abgr_sseu
+#define STD_FUNCTION_NAME yuv422_abgr_std
+#define YUV_FORMAT YUV_FORMAT_422
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_rgb565_sse
+#define STD_FUNCTION_NAME yuvnv12_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_rgb565_sseu
+#define STD_FUNCTION_NAME yuvnv12_rgb565_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGB565
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_rgb24_sse
+#define STD_FUNCTION_NAME yuvnv12_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_rgb24_sseu
+#define STD_FUNCTION_NAME yuvnv12_rgb24_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGB24
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_rgba_sse
+#define STD_FUNCTION_NAME yuvnv12_rgba_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_rgba_sseu
+#define STD_FUNCTION_NAME yuvnv12_rgba_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_RGBA
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_bgra_sse
+#define STD_FUNCTION_NAME yuvnv12_bgra_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_bgra_sseu
+#define STD_FUNCTION_NAME yuvnv12_bgra_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_BGRA
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_argb_sse
+#define STD_FUNCTION_NAME yuvnv12_argb_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_argb_sseu
+#define STD_FUNCTION_NAME yuvnv12_argb_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_ARGB
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_abgr_sse
+#define STD_FUNCTION_NAME yuvnv12_abgr_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#define SSE_ALIGNED
+#include "yuv_rgb_sse_func.h"
+
+#define SSE_FUNCTION_NAME yuvnv12_abgr_sseu
+#define STD_FUNCTION_NAME yuvnv12_abgr_std
+#define YUV_FORMAT YUV_FORMAT_NV12
+#define RGB_FORMAT RGB_FORMAT_ABGR
+#include "yuv_rgb_sse_func.h"
+
+
+#define UNPACK_RGB24_32_STEP1(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+R1 = _mm_unpacklo_epi8(RGB1, RGB4); \
+R2 = _mm_unpackhi_epi8(RGB1, RGB4); \
+G1 = _mm_unpacklo_epi8(RGB2, RGB5); \
+G2 = _mm_unpackhi_epi8(RGB2, RGB5); \
+B1 = _mm_unpacklo_epi8(RGB3, RGB6); \
+B2 = _mm_unpackhi_epi8(RGB3, RGB6);
+
+#define UNPACK_RGB24_32_STEP2(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+RGB1 = _mm_unpacklo_epi8(R1, G2); \
+RGB2 = _mm_unpackhi_epi8(R1, G2); \
+RGB3 = _mm_unpacklo_epi8(R2, B1); \
+RGB4 = _mm_unpackhi_epi8(R2, B1); \
+RGB5 = _mm_unpacklo_epi8(G1, B2); \
+RGB6 = _mm_unpackhi_epi8(G1, B2); \
+
+#define UNPACK_RGB24_32(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+UNPACK_RGB24_32_STEP1(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+UNPACK_RGB24_32_STEP2(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+UNPACK_RGB24_32_STEP1(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+UNPACK_RGB24_32_STEP2(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+UNPACK_RGB24_32_STEP1(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \
+
+#define RGB2YUV_16(R, G, B, Y, U, V) \
+Y = _mm_add_epi16(_mm_mullo_epi16(R, _mm_set1_epi16(param->matrix[0][0])), \
+ _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[0][1]))); \
+Y = _mm_add_epi16(Y, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[0][2]))); \
+Y = _mm_add_epi16(Y, _mm_set1_epi16((param->y_shift)<<PRECISION)); \
+Y = _mm_srai_epi16(Y, PRECISION); \
+U = _mm_add_epi16(_mm_mullo_epi16(R, _mm_set1_epi16(param->matrix[1][0])), \
+ _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[1][1]))); \
+U = _mm_add_epi16(U, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[1][2]))); \
+U = _mm_add_epi16(U, _mm_set1_epi16(128<<PRECISION)); \
+U = _mm_srai_epi16(U, PRECISION); \
+V = _mm_add_epi16(_mm_mullo_epi16(R, _mm_set1_epi16(param->matrix[2][0])), \
+ _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[2][1]))); \
+V = _mm_add_epi16(V, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[2][2]))); \
+V = _mm_add_epi16(V, _mm_set1_epi16(128<<PRECISION)); \
+V = _mm_srai_epi16(V, PRECISION);
+
+#define RGB2YUV_32 \
+ __m128i r1, r2, b1, b2, g1, g2; \
+ __m128i r_16, g_16, b_16; \
+ __m128i y1_16, y2_16, u1_16, u2_16, v1_16, v2_16, y, u1, u2, v1, v2, u1_tmp, u2_tmp, v1_tmp, v2_tmp; \
+ __m128i rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1)), \
+ rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1+16)), \
+ rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1+32)), \
+ rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr2)), \
+ rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2+16)), \
+ rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2+32)); \
+ /* unpack rgb24 data to r, g and b data in separate channels*/ \
+ UNPACK_RGB24_32(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, r1, r2, g1, g2, b1, b2) \
+ /* process pixels of first line */ \
+ r_16 = _mm_unpacklo_epi8(r1, _mm_setzero_si128()); \
+ g_16 = _mm_unpacklo_epi8(g1, _mm_setzero_si128()); \
+ b_16 = _mm_unpacklo_epi8(b1, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y1_16, u1_16, v1_16) \
+ r_16 = _mm_unpackhi_epi8(r1, _mm_setzero_si128()); \
+ g_16 = _mm_unpackhi_epi8(g1, _mm_setzero_si128()); \
+ b_16 = _mm_unpackhi_epi8(b1, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y2_16, u2_16, v2_16) \
+ y = _mm_packus_epi16(y1_16, y2_16); \
+ u1 = _mm_packus_epi16(u1_16, u2_16); \
+ v1 = _mm_packus_epi16(v1_16, v2_16); \
+ /* save Y values */ \
+ SAVE_SI128((__m128i*)(y_ptr1), y); \
+ /* process pixels of second line */ \
+ r_16 = _mm_unpacklo_epi8(r2, _mm_setzero_si128()); \
+ g_16 = _mm_unpacklo_epi8(g2, _mm_setzero_si128()); \
+ b_16 = _mm_unpacklo_epi8(b2, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y1_16, u1_16, v1_16) \
+ r_16 = _mm_unpackhi_epi8(r2, _mm_setzero_si128()); \
+ g_16 = _mm_unpackhi_epi8(g2, _mm_setzero_si128()); \
+ b_16 = _mm_unpackhi_epi8(b2, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y2_16, u2_16, v2_16) \
+ y = _mm_packus_epi16(y1_16, y2_16); \
+ u2 = _mm_packus_epi16(u1_16, u2_16); \
+ v2 = _mm_packus_epi16(v1_16, v2_16); \
+ /* save Y values */ \
+ SAVE_SI128((__m128i*)(y_ptr2), y); \
+ /* vertical subsampling of u/v values */ \
+ u1_tmp = _mm_avg_epu8(u1, u2); \
+ v1_tmp = _mm_avg_epu8(v1, v2); \
+ /* do the same again with next data */ \
+ rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1+48)); \
+ rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1+64)); \
+ rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1+80)); \
+ rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr2+48)); \
+ rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2+64)); \
+ rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2+80)); \
+ /* unpack rgb24 data to r, g and b data in separate channels*/ \
+ UNPACK_RGB24_32(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, r1, r2, g1, g2, b1, b2) \
+ /* process pixels of first line */ \
+ r_16 = _mm_unpacklo_epi8(r1, _mm_setzero_si128()); \
+ g_16 = _mm_unpacklo_epi8(g1, _mm_setzero_si128()); \
+ b_16 = _mm_unpacklo_epi8(b1, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y1_16, u1_16, v1_16) \
+ r_16 = _mm_unpackhi_epi8(r1, _mm_setzero_si128()); \
+ g_16 = _mm_unpackhi_epi8(g1, _mm_setzero_si128()); \
+ b_16 = _mm_unpackhi_epi8(b1, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y2_16, u2_16, v2_16) \
+ y = _mm_packus_epi16(y1_16, y2_16); \
+ u1 = _mm_packus_epi16(u1_16, u2_16); \
+ v1 = _mm_packus_epi16(v1_16, v2_16); \
+ /* save Y values */ \
+ SAVE_SI128((__m128i*)(y_ptr1+16), y); \
+ /* process pixels of second line */ \
+ r_16 = _mm_unpacklo_epi8(r2, _mm_setzero_si128()); \
+ g_16 = _mm_unpacklo_epi8(g2, _mm_setzero_si128()); \
+ b_16 = _mm_unpacklo_epi8(b2, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y1_16, u1_16, v1_16) \
+ r_16 = _mm_unpackhi_epi8(r2, _mm_setzero_si128()); \
+ g_16 = _mm_unpackhi_epi8(g2, _mm_setzero_si128()); \
+ b_16 = _mm_unpackhi_epi8(b2, _mm_setzero_si128()); \
+ RGB2YUV_16(r_16, g_16, b_16, y2_16, u2_16, v2_16) \
+ y = _mm_packus_epi16(y1_16, y2_16); \
+ u2 = _mm_packus_epi16(u1_16, u2_16); \
+ v2 = _mm_packus_epi16(v1_16, v2_16); \
+ /* save Y values */ \
+ SAVE_SI128((__m128i*)(y_ptr2+16), y); \
+ /* vertical subsampling of u/v values */ \
+ u2_tmp = _mm_avg_epu8(u1, u2); \
+ v2_tmp = _mm_avg_epu8(v1, v2); \
+ /* horizontal subsampling of u/v values */ \
+ u1 = _mm_packus_epi16(_mm_srl_epi16(u1_tmp, _mm_cvtsi32_si128(8)), _mm_srl_epi16(u2_tmp, _mm_cvtsi32_si128(8))); \
+ v1 = _mm_packus_epi16(_mm_srl_epi16(v1_tmp, _mm_cvtsi32_si128(8)), _mm_srl_epi16(v2_tmp, _mm_cvtsi32_si128(8))); \
+ u2 = _mm_packus_epi16(_mm_and_si128(u1_tmp, _mm_set1_epi16(0xFF)), _mm_and_si128(u2_tmp, _mm_set1_epi16(0xFF))); \
+ v2 = _mm_packus_epi16(_mm_and_si128(v1_tmp, _mm_set1_epi16(0xFF)), _mm_and_si128(v2_tmp, _mm_set1_epi16(0xFF))); \
+ u1 = _mm_avg_epu8(u1, u2); \
+ v1 = _mm_avg_epu8(v1, v2); \
+ SAVE_SI128((__m128i*)(u_ptr), u1); \
+ SAVE_SI128((__m128i*)(v_ptr), v1);
+
+void rgb24_yuv420_sse(uint32_t width, uint32_t height,
+ const uint8_t *RGB, uint32_t RGB_stride,
+ uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride,
+ YCbCrType yuv_type)
+{
+ #define LOAD_SI128 _mm_load_si128
+ #define SAVE_SI128 _mm_stream_si128
+ const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]);
+
+ uint32_t xpos, ypos;
+ for(ypos=0; ypos<(height-1); ypos+=2)
+ {
+ const uint8_t *rgb_ptr1=RGB+ypos*RGB_stride,
+ *rgb_ptr2=RGB+(ypos+1)*RGB_stride;
+
+ uint8_t *y_ptr1=Y+ypos*Y_stride,
+ *y_ptr2=Y+(ypos+1)*Y_stride,
+ *u_ptr=U+(ypos/2)*UV_stride,
+ *v_ptr=V+(ypos/2)*UV_stride;
+
+ for(xpos=0; xpos<(width-31); xpos+=32)
+ {
+ RGB2YUV_32
+
+ rgb_ptr1+=96;
+ rgb_ptr2+=96;
+ y_ptr1+=32;
+ y_ptr2+=32;
+ u_ptr+=16;
+ v_ptr+=16;
+ }
+ }
+ #undef LOAD_SI128
+ #undef SAVE_SI128
+}
+
+void rgb24_yuv420_sseu(uint32_t width, uint32_t height,
+ const uint8_t *RGB, uint32_t RGB_stride,
+ uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride,
+ YCbCrType yuv_type)
+{
+ #define LOAD_SI128 _mm_loadu_si128
+ #define SAVE_SI128 _mm_storeu_si128
+ const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]);
+
+ uint32_t xpos, ypos;
+ for(ypos=0; ypos<(height-1); ypos+=2)
+ {
+ const uint8_t *rgb_ptr1=RGB+ypos*RGB_stride,
+ *rgb_ptr2=RGB+(ypos+1)*RGB_stride;
+
+ uint8_t *y_ptr1=Y+ypos*Y_stride,
+ *y_ptr2=Y+(ypos+1)*Y_stride,
+ *u_ptr=U+(ypos/2)*UV_stride,
+ *v_ptr=V+(ypos/2)*UV_stride;
+
+ for(xpos=0; xpos<(width-31); xpos+=32)
+ {
+ RGB2YUV_32
+
+ rgb_ptr1+=96;
+ rgb_ptr2+=96;
+ y_ptr1+=32;
+ y_ptr2+=32;
+ u_ptr+=16;
+ v_ptr+=16;
+ }
+ }
+ #undef LOAD_SI128
+ #undef SAVE_SI128
+}
+
+
+#endif //__SSE2__
+
diff --git a/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.h b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.h
new file mode 100644
index 0000000..81d97eb
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb.h
@@ -0,0 +1,381 @@
+// Copyright 2016 Adrien Descamps
+// Distributed under BSD 3-Clause License
+
+// Provide optimized functions to convert images from 8bits yuv420 to rgb24 format
+
+// There are a few slightly different variations of the YCbCr color space with different parameters that
+// change the conversion matrix.
+// The three most common YCbCr color space, defined by BT.601, BT.709 and JPEG standard are implemented here.
+// See the respective standards for details
+// The matrix values used are derived from http://www.equasys.de/colorconversion.html
+
+// YUV420 is stored as three separate channels, with U and V (Cb and Cr) subsampled by a 2 factor
+// For conversion from yuv to rgb, no interpolation is done, and the same UV value are used for 4 rgb pixels. This
+// is suboptimal for image quality, but by far the fastest method.
+
+// For all methods, width and height should be even, if not, the last row/column of the result image won't be affected.
+// For sse methods, if the width if not divisable by 32, the last (width%32) pixels of each line won't be affected.
+
+#include "SDL_stdinc.h"
+/*#include <stdint.h>*/
+
+typedef enum
+{
+ YCBCR_JPEG,
+ YCBCR_601,
+ YCBCR_709
+} YCbCrType;
+
+// yuv to rgb, standard c implementation
+void yuv420_rgb565_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_rgb24_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_rgba_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_bgra_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_argb_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_abgr_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgb565_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgb24_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgba_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_bgra_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_argb_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_abgr_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgb565_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgb24_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgba_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_bgra_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_argb_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_abgr_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+// yuv to rgb, sse implementation
+// pointers must be 16 byte aligned, and strides must be divisable by 16
+void yuv420_rgb565_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_rgb24_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_rgba_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_bgra_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_argb_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_abgr_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgb565_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgb24_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgba_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_bgra_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_argb_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_abgr_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgb565_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgb24_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgba_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_bgra_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_argb_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_abgr_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+// yuv to rgb, sse implementation
+// pointers do not need to be 16 byte aligned
+void yuv420_rgb565_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_rgb24_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_rgba_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_bgra_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_argb_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv420_abgr_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgb565_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgb24_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_rgba_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_bgra_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_argb_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuv422_abgr_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgb565_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgb24_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_rgba_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_bgra_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_argb_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+void yuvnv12_abgr_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ uint8_t *rgb, uint32_t rgb_stride,
+ YCbCrType yuv_type);
+
+
+// rgb to yuv, standard c implementation
+void rgb24_yuv420_std(
+ uint32_t width, uint32_t height,
+ const uint8_t *rgb, uint32_t rgb_stride,
+ uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ YCbCrType yuv_type);
+
+// rgb to yuv, sse implementation
+// pointers must be 16 byte aligned, and strides must be divisible by 16
+void rgb24_yuv420_sse(
+ uint32_t width, uint32_t height,
+ const uint8_t *rgb, uint32_t rgb_stride,
+ uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ YCbCrType yuv_type);
+
+// rgb to yuv, sse implementation
+// pointers do not need to be 16 byte aligned
+void rgb24_yuv420_sseu(
+ uint32_t width, uint32_t height,
+ const uint8_t *rgb, uint32_t rgb_stride,
+ uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride,
+ YCbCrType yuv_type);
+
diff --git a/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_sse_func.h b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_sse_func.h
new file mode 100644
index 0000000..f81140e
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_sse_func.h
@@ -0,0 +1,498 @@
+// Copyright 2016 Adrien Descamps
+// Distributed under BSD 3-Clause License
+
+/* You need to define the following macros before including this file:
+ SSE_FUNCTION_NAME
+ STD_FUNCTION_NAME
+ YUV_FORMAT
+ RGB_FORMAT
+*/
+/* You may define the following macro, which affects generated code:
+ SSE_ALIGNED
+*/
+
+#ifdef SSE_ALIGNED
+/* Unaligned instructions seem faster, even on aligned data? */
+/*
+#define LOAD_SI128 _mm_load_si128
+#define SAVE_SI128 _mm_stream_si128
+*/
+#define LOAD_SI128 _mm_loadu_si128
+#define SAVE_SI128 _mm_storeu_si128
+#else
+#define LOAD_SI128 _mm_loadu_si128
+#define SAVE_SI128 _mm_storeu_si128
+#endif
+
+#define UV2RGB_16(U,V,R1,G1,B1,R2,G2,B2) \
+ r_tmp = _mm_mullo_epi16(V, _mm_set1_epi16(param->v_r_factor)); \
+ g_tmp = _mm_add_epi16( \
+ _mm_mullo_epi16(U, _mm_set1_epi16(param->u_g_factor)), \
+ _mm_mullo_epi16(V, _mm_set1_epi16(param->v_g_factor))); \
+ b_tmp = _mm_mullo_epi16(U, _mm_set1_epi16(param->u_b_factor)); \
+ R1 = _mm_unpacklo_epi16(r_tmp, r_tmp); \
+ G1 = _mm_unpacklo_epi16(g_tmp, g_tmp); \
+ B1 = _mm_unpacklo_epi16(b_tmp, b_tmp); \
+ R2 = _mm_unpackhi_epi16(r_tmp, r_tmp); \
+ G2 = _mm_unpackhi_epi16(g_tmp, g_tmp); \
+ B2 = _mm_unpackhi_epi16(b_tmp, b_tmp); \
+
+#define ADD_Y2RGB_16(Y1,Y2,R1,G1,B1,R2,G2,B2) \
+ Y1 = _mm_mullo_epi16(_mm_sub_epi16(Y1, _mm_set1_epi16(param->y_shift)), _mm_set1_epi16(param->y_factor)); \
+ Y2 = _mm_mullo_epi16(_mm_sub_epi16(Y2, _mm_set1_epi16(param->y_shift)), _mm_set1_epi16(param->y_factor)); \
+ \
+ R1 = _mm_srai_epi16(_mm_add_epi16(R1, Y1), PRECISION); \
+ G1 = _mm_srai_epi16(_mm_add_epi16(G1, Y1), PRECISION); \
+ B1 = _mm_srai_epi16(_mm_add_epi16(B1, Y1), PRECISION); \
+ R2 = _mm_srai_epi16(_mm_add_epi16(R2, Y2), PRECISION); \
+ G2 = _mm_srai_epi16(_mm_add_epi16(G2, Y2), PRECISION); \
+ B2 = _mm_srai_epi16(_mm_add_epi16(B2, Y2), PRECISION); \
+
+#define PACK_RGB565_32(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4) \
+{ \
+ __m128i red_mask, tmp1, tmp2, tmp3, tmp4; \
+\
+ red_mask = _mm_set1_epi16((short)0xF800); \
+ RGB1 = _mm_and_si128(_mm_unpacklo_epi8(_mm_setzero_si128(), R1), red_mask); \
+ RGB2 = _mm_and_si128(_mm_unpackhi_epi8(_mm_setzero_si128(), R1), red_mask); \
+ RGB3 = _mm_and_si128(_mm_unpacklo_epi8(_mm_setzero_si128(), R2), red_mask); \
+ RGB4 = _mm_and_si128(_mm_unpackhi_epi8(_mm_setzero_si128(), R2), red_mask); \
+ tmp1 = _mm_slli_epi16(_mm_srli_epi16(_mm_unpacklo_epi8(G1, _mm_setzero_si128()), 2), 5); \
+ tmp2 = _mm_slli_epi16(_mm_srli_epi16(_mm_unpackhi_epi8(G1, _mm_setzero_si128()), 2), 5); \
+ tmp3 = _mm_slli_epi16(_mm_srli_epi16(_mm_unpacklo_epi8(G2, _mm_setzero_si128()), 2), 5); \
+ tmp4 = _mm_slli_epi16(_mm_srli_epi16(_mm_unpackhi_epi8(G2, _mm_setzero_si128()), 2), 5); \
+ RGB1 = _mm_or_si128(RGB1, tmp1); \
+ RGB2 = _mm_or_si128(RGB2, tmp2); \
+ RGB3 = _mm_or_si128(RGB3, tmp3); \
+ RGB4 = _mm_or_si128(RGB4, tmp4); \
+ tmp1 = _mm_srli_epi16(_mm_unpacklo_epi8(B1, _mm_setzero_si128()), 3); \
+ tmp2 = _mm_srli_epi16(_mm_unpackhi_epi8(B1, _mm_setzero_si128()), 3); \
+ tmp3 = _mm_srli_epi16(_mm_unpacklo_epi8(B2, _mm_setzero_si128()), 3); \
+ tmp4 = _mm_srli_epi16(_mm_unpackhi_epi8(B2, _mm_setzero_si128()), 3); \
+ RGB1 = _mm_or_si128(RGB1, tmp1); \
+ RGB2 = _mm_or_si128(RGB2, tmp2); \
+ RGB3 = _mm_or_si128(RGB3, tmp3); \
+ RGB4 = _mm_or_si128(RGB4, tmp4); \
+}
+
+#define PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+RGB1 = _mm_packus_epi16(_mm_and_si128(R1,_mm_set1_epi16(0xFF)), _mm_and_si128(R2,_mm_set1_epi16(0xFF))); \
+RGB2 = _mm_packus_epi16(_mm_and_si128(G1,_mm_set1_epi16(0xFF)), _mm_and_si128(G2,_mm_set1_epi16(0xFF))); \
+RGB3 = _mm_packus_epi16(_mm_and_si128(B1,_mm_set1_epi16(0xFF)), _mm_and_si128(B2,_mm_set1_epi16(0xFF))); \
+RGB4 = _mm_packus_epi16(_mm_srli_epi16(R1,8), _mm_srli_epi16(R2,8)); \
+RGB5 = _mm_packus_epi16(_mm_srli_epi16(G1,8), _mm_srli_epi16(G2,8)); \
+RGB6 = _mm_packus_epi16(_mm_srli_epi16(B1,8), _mm_srli_epi16(B2,8)); \
+
+#define PACK_RGB24_32_STEP2(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+R1 = _mm_packus_epi16(_mm_and_si128(RGB1,_mm_set1_epi16(0xFF)), _mm_and_si128(RGB2,_mm_set1_epi16(0xFF))); \
+R2 = _mm_packus_epi16(_mm_and_si128(RGB3,_mm_set1_epi16(0xFF)), _mm_and_si128(RGB4,_mm_set1_epi16(0xFF))); \
+G1 = _mm_packus_epi16(_mm_and_si128(RGB5,_mm_set1_epi16(0xFF)), _mm_and_si128(RGB6,_mm_set1_epi16(0xFF))); \
+G2 = _mm_packus_epi16(_mm_srli_epi16(RGB1,8), _mm_srli_epi16(RGB2,8)); \
+B1 = _mm_packus_epi16(_mm_srli_epi16(RGB3,8), _mm_srli_epi16(RGB4,8)); \
+B2 = _mm_packus_epi16(_mm_srli_epi16(RGB5,8), _mm_srli_epi16(RGB6,8)); \
+
+#define PACK_RGB24_32(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+PACK_RGB24_32_STEP2(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+PACK_RGB24_32_STEP2(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \
+
+#define PACK_RGBA_32(R1, R2, G1, G2, B1, B2, A1, A2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, RGB7, RGB8) \
+{ \
+ __m128i lo_ab, hi_ab, lo_gr, hi_gr; \
+\
+ lo_ab = _mm_unpacklo_epi8( A1, B1 ); \
+ hi_ab = _mm_unpackhi_epi8( A1, B1 ); \
+ lo_gr = _mm_unpacklo_epi8( G1, R1 ); \
+ hi_gr = _mm_unpackhi_epi8( G1, R1 ); \
+ RGB1 = _mm_unpacklo_epi16( lo_ab, lo_gr ); \
+ RGB2 = _mm_unpackhi_epi16( lo_ab, lo_gr ); \
+ RGB3 = _mm_unpacklo_epi16( hi_ab, hi_gr ); \
+ RGB4 = _mm_unpackhi_epi16( hi_ab, hi_gr ); \
+\
+ lo_ab = _mm_unpacklo_epi8( A2, B2 ); \
+ hi_ab = _mm_unpackhi_epi8( A2, B2 ); \
+ lo_gr = _mm_unpacklo_epi8( G2, R2 ); \
+ hi_gr = _mm_unpackhi_epi8( G2, R2 ); \
+ RGB5 = _mm_unpacklo_epi16( lo_ab, lo_gr ); \
+ RGB6 = _mm_unpackhi_epi16( lo_ab, lo_gr ); \
+ RGB7 = _mm_unpacklo_epi16( hi_ab, hi_gr ); \
+ RGB8 = _mm_unpackhi_epi16( hi_ab, hi_gr ); \
+}
+
+#if RGB_FORMAT == RGB_FORMAT_RGB565
+
+#define PACK_PIXEL \
+ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \
+ \
+ PACK_RGB565_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, rgb_1, rgb_2, rgb_3, rgb_4) \
+ \
+ PACK_RGB565_32(r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, rgb_5, rgb_6, rgb_7, rgb_8) \
+
+#elif RGB_FORMAT == RGB_FORMAT_RGB24
+
+#define PACK_PIXEL \
+ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6; \
+ __m128i rgb_7, rgb_8, rgb_9, rgb_10, rgb_11, rgb_12; \
+ \
+ PACK_RGB24_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6) \
+ \
+ PACK_RGB24_32(r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, rgb_7, rgb_8, rgb_9, rgb_10, rgb_11, rgb_12) \
+
+#elif RGB_FORMAT == RGB_FORMAT_RGBA
+
+#define PACK_PIXEL \
+ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \
+ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \
+ __m128i a = _mm_set1_epi8((char)0xFF); \
+ \
+ PACK_RGBA_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, a, a, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \
+ \
+ PACK_RGBA_32(r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, a, a, rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \
+
+#elif RGB_FORMAT == RGB_FORMAT_BGRA
+
+#define PACK_PIXEL \
+ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \
+ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \
+ __m128i a = _mm_set1_epi8((char)0xFF); \
+ \
+ PACK_RGBA_32(b_8_11, b_8_12, g_8_11, g_8_12, r_8_11, r_8_12, a, a, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \
+ \
+ PACK_RGBA_32(b_8_21, b_8_22, g_8_21, g_8_22, r_8_21, r_8_22, a, a, rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \
+
+#elif RGB_FORMAT == RGB_FORMAT_ARGB
+
+#define PACK_PIXEL \
+ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \
+ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \
+ __m128i a = _mm_set1_epi8((char)0xFF); \
+ \
+ PACK_RGBA_32(a, a, r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \
+ \
+ PACK_RGBA_32(a, a, r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \
+
+#elif RGB_FORMAT == RGB_FORMAT_ABGR
+
+#define PACK_PIXEL \
+ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \
+ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \
+ __m128i a = _mm_set1_epi8((char)0xFF); \
+ \
+ PACK_RGBA_32(a, a, b_8_11, b_8_12, g_8_11, g_8_12, r_8_11, r_8_12, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \
+ \
+ PACK_RGBA_32(a, a, b_8_21, b_8_22, g_8_21, g_8_22, r_8_21, r_8_22, rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \
+
+#else
+#error PACK_PIXEL unimplemented
+#endif
+
+#if RGB_FORMAT == RGB_FORMAT_RGB565
+
+#define SAVE_LINE1 \
+ SAVE_SI128((__m128i*)(rgb_ptr1), rgb_1); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+16), rgb_2); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+32), rgb_3); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+48), rgb_4); \
+
+#define SAVE_LINE2 \
+ SAVE_SI128((__m128i*)(rgb_ptr2), rgb_5); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+16), rgb_6); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+32), rgb_7); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+48), rgb_8); \
+
+#elif RGB_FORMAT == RGB_FORMAT_RGB24
+
+#define SAVE_LINE1 \
+ SAVE_SI128((__m128i*)(rgb_ptr1), rgb_1); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+16), rgb_2); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+32), rgb_3); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+48), rgb_4); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+64), rgb_5); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+80), rgb_6); \
+
+#define SAVE_LINE2 \
+ SAVE_SI128((__m128i*)(rgb_ptr2), rgb_7); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+16), rgb_8); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+32), rgb_9); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+48), rgb_10); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+64), rgb_11); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+80), rgb_12); \
+
+#elif RGB_FORMAT == RGB_FORMAT_RGBA || RGB_FORMAT == RGB_FORMAT_BGRA || \
+ RGB_FORMAT == RGB_FORMAT_ARGB || RGB_FORMAT == RGB_FORMAT_ABGR
+
+#define SAVE_LINE1 \
+ SAVE_SI128((__m128i*)(rgb_ptr1), rgb_1); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+16), rgb_2); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+32), rgb_3); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+48), rgb_4); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+64), rgb_5); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+80), rgb_6); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+96), rgb_7); \
+ SAVE_SI128((__m128i*)(rgb_ptr1+112), rgb_8); \
+
+#define SAVE_LINE2 \
+ SAVE_SI128((__m128i*)(rgb_ptr2), rgb_9); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+16), rgb_10); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+32), rgb_11); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+48), rgb_12); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+64), rgb_13); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+80), rgb_14); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+96), rgb_15); \
+ SAVE_SI128((__m128i*)(rgb_ptr2+112), rgb_16); \
+
+#else
+#error SAVE_LINE unimplemented
+#endif
+
+#if YUV_FORMAT == YUV_FORMAT_420
+
+#define READ_Y(y_ptr) \
+ y = LOAD_SI128((const __m128i*)(y_ptr)); \
+
+#define READ_UV \
+ u = LOAD_SI128((const __m128i*)(u_ptr)); \
+ v = LOAD_SI128((const __m128i*)(v_ptr)); \
+
+#elif YUV_FORMAT == YUV_FORMAT_422
+
+#define READ_Y(y_ptr) \
+{ \
+ __m128i y1, y2; \
+ y1 = _mm_srli_epi16(_mm_slli_epi16(LOAD_SI128((const __m128i*)(y_ptr)), 8), 8); \
+ y2 = _mm_srli_epi16(_mm_slli_epi16(LOAD_SI128((const __m128i*)(y_ptr+16)), 8), 8); \
+ y = _mm_packus_epi16(y1, y2); \
+}
+
+#define READ_UV \
+{ \
+ __m128i u1, u2, u3, u4, v1, v2, v3, v4; \
+ u1 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(u_ptr)), 24), 24); \
+ u2 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(u_ptr+16)), 24), 24); \
+ u3 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(u_ptr+32)), 24), 24); \
+ u4 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(u_ptr+48)), 24), 24); \
+ u = _mm_packus_epi16(_mm_packs_epi32(u1, u2), _mm_packs_epi32(u3, u4)); \
+ v1 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(v_ptr)), 24), 24); \
+ v2 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(v_ptr+16)), 24), 24); \
+ v3 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(v_ptr+32)), 24), 24); \
+ v4 = _mm_srli_epi32(_mm_slli_epi32(LOAD_SI128((const __m128i*)(v_ptr+48)), 24), 24); \
+ v = _mm_packus_epi16(_mm_packs_epi32(v1, v2), _mm_packs_epi32(v3, v4)); \
+}
+
+#elif YUV_FORMAT == YUV_FORMAT_NV12
+
+#define READ_Y(y_ptr) \
+ y = LOAD_SI128((const __m128i*)(y_ptr)); \
+
+#define READ_UV \
+{ \
+ __m128i u1, u2, v1, v2; \
+ u1 = _mm_srli_epi16(_mm_slli_epi16(LOAD_SI128((const __m128i*)(u_ptr)), 8), 8); \
+ u2 = _mm_srli_epi16(_mm_slli_epi16(LOAD_SI128((const __m128i*)(u_ptr+16)), 8), 8); \
+ u = _mm_packus_epi16(u1, u2); \
+ v1 = _mm_srli_epi16(_mm_slli_epi16(LOAD_SI128((const __m128i*)(v_ptr)), 8), 8); \
+ v2 = _mm_srli_epi16(_mm_slli_epi16(LOAD_SI128((const __m128i*)(v_ptr+16)), 8), 8); \
+ v = _mm_packus_epi16(v1, v2); \
+}
+
+#else
+#error READ_UV unimplemented
+#endif
+
+#define YUV2RGB_32 \
+ __m128i r_tmp, g_tmp, b_tmp; \
+ __m128i r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2; \
+ __m128i r_uv_16_1, g_uv_16_1, b_uv_16_1, r_uv_16_2, g_uv_16_2, b_uv_16_2; \
+ __m128i y_16_1, y_16_2; \
+ __m128i y, u, v, u_16, v_16; \
+ __m128i r_8_11, g_8_11, b_8_11, r_8_21, g_8_21, b_8_21; \
+ __m128i r_8_12, g_8_12, b_8_12, r_8_22, g_8_22, b_8_22; \
+ \
+ READ_UV \
+ \
+ /* process first 16 pixels of first line */\
+ u_16 = _mm_unpacklo_epi8(u, _mm_setzero_si128()); \
+ v_16 = _mm_unpacklo_epi8(v, _mm_setzero_si128()); \
+ u_16 = _mm_add_epi16(u_16, _mm_set1_epi16(-128)); \
+ v_16 = _mm_add_epi16(v_16, _mm_set1_epi16(-128)); \
+ \
+ UV2RGB_16(u_16, v_16, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \
+ r_uv_16_1=r_16_1; g_uv_16_1=g_16_1; b_uv_16_1=b_16_1; \
+ r_uv_16_2=r_16_2; g_uv_16_2=g_16_2; b_uv_16_2=b_16_2; \
+ \
+ READ_Y(y_ptr1) \
+ y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \
+ y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \
+ \
+ ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \
+ \
+ r_8_11 = _mm_packus_epi16(r_16_1, r_16_2); \
+ g_8_11 = _mm_packus_epi16(g_16_1, g_16_2); \
+ b_8_11 = _mm_packus_epi16(b_16_1, b_16_2); \
+ \
+ /* process first 16 pixels of second line */\
+ r_16_1=r_uv_16_1; g_16_1=g_uv_16_1; b_16_1=b_uv_16_1; \
+ r_16_2=r_uv_16_2; g_16_2=g_uv_16_2; b_16_2=b_uv_16_2; \
+ \
+ READ_Y(y_ptr2) \
+ y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \
+ y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \
+ \
+ ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \
+ \
+ r_8_21 = _mm_packus_epi16(r_16_1, r_16_2); \
+ g_8_21 = _mm_packus_epi16(g_16_1, g_16_2); \
+ b_8_21 = _mm_packus_epi16(b_16_1, b_16_2); \
+ \
+ /* process last 16 pixels of first line */\
+ u_16 = _mm_unpackhi_epi8(u, _mm_setzero_si128()); \
+ v_16 = _mm_unpackhi_epi8(v, _mm_setzero_si128()); \
+ u_16 = _mm_add_epi16(u_16, _mm_set1_epi16(-128)); \
+ v_16 = _mm_add_epi16(v_16, _mm_set1_epi16(-128)); \
+ \
+ UV2RGB_16(u_16, v_16, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \
+ r_uv_16_1=r_16_1; g_uv_16_1=g_16_1; b_uv_16_1=b_16_1; \
+ r_uv_16_2=r_16_2; g_uv_16_2=g_16_2; b_uv_16_2=b_16_2; \
+ \
+ READ_Y(y_ptr1+16*y_pixel_stride) \
+ y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \
+ y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \
+ \
+ ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \
+ \
+ r_8_12 = _mm_packus_epi16(r_16_1, r_16_2); \
+ g_8_12 = _mm_packus_epi16(g_16_1, g_16_2); \
+ b_8_12 = _mm_packus_epi16(b_16_1, b_16_2); \
+ \
+ /* process last 16 pixels of second line */\
+ r_16_1=r_uv_16_1; g_16_1=g_uv_16_1; b_16_1=b_uv_16_1; \
+ r_16_2=r_uv_16_2; g_16_2=g_uv_16_2; b_16_2=b_uv_16_2; \
+ \
+ READ_Y(y_ptr2+16*y_pixel_stride) \
+ y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \
+ y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \
+ \
+ ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \
+ \
+ r_8_22 = _mm_packus_epi16(r_16_1, r_16_2); \
+ g_8_22 = _mm_packus_epi16(g_16_1, g_16_2); \
+ b_8_22 = _mm_packus_epi16(b_16_1, b_16_2); \
+ \
+
+
+void SSE_FUNCTION_NAME(uint32_t width, uint32_t height,
+ const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride,
+ uint8_t *RGB, uint32_t RGB_stride,
+ YCbCrType yuv_type)
+{
+ const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]);
+#if YUV_FORMAT == YUV_FORMAT_420
+ const int y_pixel_stride = 1;
+ const int uv_pixel_stride = 1;
+ const int uv_x_sample_interval = 2;
+ const int uv_y_sample_interval = 2;
+#elif YUV_FORMAT == YUV_FORMAT_422
+ const int y_pixel_stride = 2;
+ const int uv_pixel_stride = 4;
+ const int uv_x_sample_interval = 2;
+ const int uv_y_sample_interval = 1;
+#elif YUV_FORMAT == YUV_FORMAT_NV12
+ const int y_pixel_stride = 1;
+ const int uv_pixel_stride = 2;
+ const int uv_x_sample_interval = 2;
+ const int uv_y_sample_interval = 2;
+#endif
+#if RGB_FORMAT == RGB_FORMAT_RGB565
+ const int rgb_pixel_stride = 2;
+#elif RGB_FORMAT == RGB_FORMAT_RGB24
+ const int rgb_pixel_stride = 3;
+#elif RGB_FORMAT == RGB_FORMAT_RGBA || RGB_FORMAT == RGB_FORMAT_BGRA || \
+ RGB_FORMAT == RGB_FORMAT_ARGB || RGB_FORMAT == RGB_FORMAT_ABGR
+ const int rgb_pixel_stride = 4;
+#else
+#error Unknown RGB pixel size
+#endif
+
+ if (width >= 32) {
+ uint32_t xpos, ypos;
+ for(ypos=0; ypos<(height-(uv_y_sample_interval-1)); ypos+=uv_y_sample_interval)
+ {
+ const uint8_t *y_ptr1=Y+ypos*Y_stride,
+ *y_ptr2=Y+(ypos+1)*Y_stride,
+ *u_ptr=U+(ypos/uv_y_sample_interval)*UV_stride,
+ *v_ptr=V+(ypos/uv_y_sample_interval)*UV_stride;
+
+ uint8_t *rgb_ptr1=RGB+ypos*RGB_stride,
+ *rgb_ptr2=RGB+(ypos+1)*RGB_stride;
+
+ for(xpos=0; xpos<(width-31); xpos+=32)
+ {
+ YUV2RGB_32
+ {
+ PACK_PIXEL
+ SAVE_LINE1
+ if (uv_y_sample_interval > 1)
+ {
+ SAVE_LINE2
+ }
+ }
+
+ y_ptr1+=32*y_pixel_stride;
+ y_ptr2+=32*y_pixel_stride;
+ u_ptr+=32*uv_pixel_stride/uv_x_sample_interval;
+ v_ptr+=32*uv_pixel_stride/uv_x_sample_interval;
+ rgb_ptr1+=32*rgb_pixel_stride;
+ rgb_ptr2+=32*rgb_pixel_stride;
+ }
+ }
+
+ /* Catch the last line, if needed */
+ if (uv_y_sample_interval == 2 && ypos == (height-1))
+ {
+ const uint8_t *y_ptr=Y+ypos*Y_stride,
+ *u_ptr=U+(ypos/uv_y_sample_interval)*UV_stride,
+ *v_ptr=V+(ypos/uv_y_sample_interval)*UV_stride;
+
+ uint8_t *rgb_ptr=RGB+ypos*RGB_stride;
+
+ STD_FUNCTION_NAME(width, 1, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type);
+ }
+ }
+
+ /* Catch the right column, if needed */
+ {
+ int converted = (width & ~31);
+ if (converted != width)
+ {
+ const uint8_t *y_ptr=Y+converted*y_pixel_stride,
+ *u_ptr=U+converted*uv_pixel_stride/uv_x_sample_interval,
+ *v_ptr=V+converted*uv_pixel_stride/uv_x_sample_interval;
+
+ uint8_t *rgb_ptr=RGB+converted*rgb_pixel_stride;
+
+ STD_FUNCTION_NAME(width-converted, height, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type);
+ }
+ }
+}
+
+#undef SSE_FUNCTION_NAME
+#undef STD_FUNCTION_NAME
+#undef YUV_FORMAT
+#undef RGB_FORMAT
+#undef SSE_ALIGNED
+#undef LOAD_SI128
+#undef SAVE_SI128
+#undef UV2RGB_16
+#undef ADD_Y2RGB_16
+#undef PACK_RGB24_32_STEP1
+#undef PACK_RGB24_32_STEP2
+#undef PACK_RGB24_32
+#undef PACK_RGBA_32
+#undef PACK_PIXEL
+#undef SAVE_LINE1
+#undef SAVE_LINE2
+#undef READ_Y
+#undef READ_UV
+#undef YUV2RGB_32
diff --git a/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_std_func.h b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_std_func.h
new file mode 100644
index 0000000..f0ab5c6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/yuv2rgb/yuv_rgb_std_func.h
@@ -0,0 +1,228 @@
+// Copyright 2016 Adrien Descamps
+// Distributed under BSD 3-Clause License
+
+/* You need to define the following macros before including this file:
+ STD_FUNCTION_NAME
+ YUV_FORMAT
+ RGB_FORMAT
+*/
+
+#if RGB_FORMAT == RGB_FORMAT_RGB565
+
+#define PACK_PIXEL(rgb_ptr) \
+ *(Uint16 *)rgb_ptr = \
+ ((((Uint16)clampU8(y_tmp+r_tmp)) << 8 ) & 0xF800) | \
+ ((((Uint16)clampU8(y_tmp+g_tmp)) << 3) & 0x07E0) | \
+ (((Uint16)clampU8(y_tmp+b_tmp)) >> 3); \
+ rgb_ptr += 2; \
+
+#elif RGB_FORMAT == RGB_FORMAT_RGB24
+
+#define PACK_PIXEL(rgb_ptr) \
+ rgb_ptr[0] = clampU8(y_tmp+r_tmp); \
+ rgb_ptr[1] = clampU8(y_tmp+g_tmp); \
+ rgb_ptr[2] = clampU8(y_tmp+b_tmp); \
+ rgb_ptr += 3; \
+
+#elif RGB_FORMAT == RGB_FORMAT_RGBA
+
+#define PACK_PIXEL(rgb_ptr) \
+ *(Uint32 *)rgb_ptr = \
+ (((Uint32)clampU8(y_tmp+r_tmp)) << 24) | \
+ (((Uint32)clampU8(y_tmp+g_tmp)) << 16) | \
+ (((Uint32)clampU8(y_tmp+b_tmp)) << 8) | \
+ 0x000000FF; \
+ rgb_ptr += 4; \
+
+#elif RGB_FORMAT == RGB_FORMAT_BGRA
+
+#define PACK_PIXEL(rgb_ptr) \
+ *(Uint32 *)rgb_ptr = \
+ (((Uint32)clampU8(y_tmp+b_tmp)) << 24) | \
+ (((Uint32)clampU8(y_tmp+g_tmp)) << 16) | \
+ (((Uint32)clampU8(y_tmp+r_tmp)) << 8) | \
+ 0x000000FF; \
+ rgb_ptr += 4; \
+
+#elif RGB_FORMAT == RGB_FORMAT_ARGB
+
+#define PACK_PIXEL(rgb_ptr) \
+ *(Uint32 *)rgb_ptr = \
+ 0xFF000000 | \
+ (((Uint32)clampU8(y_tmp+r_tmp)) << 16) | \
+ (((Uint32)clampU8(y_tmp+g_tmp)) << 8) | \
+ (((Uint32)clampU8(y_tmp+b_tmp)) << 0); \
+ rgb_ptr += 4; \
+
+#elif RGB_FORMAT == RGB_FORMAT_ABGR
+
+#define PACK_PIXEL(rgb_ptr) \
+ *(Uint32 *)rgb_ptr = \
+ 0xFF000000 | \
+ (((Uint32)clampU8(y_tmp+b_tmp)) << 16) | \
+ (((Uint32)clampU8(y_tmp+g_tmp)) << 8) | \
+ (((Uint32)clampU8(y_tmp+r_tmp)) << 0); \
+ rgb_ptr += 4; \
+
+#else
+#error PACK_PIXEL unimplemented
+#endif
+
+
+void STD_FUNCTION_NAME(
+ uint32_t width, uint32_t height,
+ const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride,
+ uint8_t *RGB, uint32_t RGB_stride,
+ YCbCrType yuv_type)
+{
+ const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]);
+#if YUV_FORMAT == YUV_FORMAT_420
+ #define y_pixel_stride 1
+ #define uv_pixel_stride 1
+ #define uv_x_sample_interval 2
+ #define uv_y_sample_interval 2
+#elif YUV_FORMAT == YUV_FORMAT_422
+ #define y_pixel_stride 2
+ #define uv_pixel_stride 4
+ #define uv_x_sample_interval 2
+ #define uv_y_sample_interval 1
+#elif YUV_FORMAT == YUV_FORMAT_NV12
+ #define y_pixel_stride 1
+ #define uv_pixel_stride 2
+ #define uv_x_sample_interval 2
+ #define uv_y_sample_interval 2
+#endif
+
+ uint32_t x, y;
+ for(y=0; y<(height-(uv_y_sample_interval-1)); y+=uv_y_sample_interval)
+ {
+ const uint8_t *y_ptr1=Y+y*Y_stride,
+ *y_ptr2=Y+(y+1)*Y_stride,
+ *u_ptr=U+(y/uv_y_sample_interval)*UV_stride,
+ *v_ptr=V+(y/uv_y_sample_interval)*UV_stride;
+
+ uint8_t *rgb_ptr1=RGB+y*RGB_stride;
+
+ #if uv_y_sample_interval > 1
+ uint8_t *rgb_ptr2=RGB+(y+1)*RGB_stride;
+ #endif
+
+ for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval)
+ {
+ // Compute U and V contributions, common to the four pixels
+
+ int32_t u_tmp = ((*u_ptr)-128);
+ int32_t v_tmp = ((*v_ptr)-128);
+
+ int32_t r_tmp = (v_tmp*param->v_r_factor);
+ int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor);
+ int32_t b_tmp = (u_tmp*param->u_b_factor);
+
+ // Compute the Y contribution for each pixel
+
+ int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr1);
+
+ y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr1);
+
+ #if uv_y_sample_interval > 1
+ y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr2);
+
+ y_tmp = ((y_ptr2[y_pixel_stride]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr2);
+ #endif
+
+ y_ptr1+=2*y_pixel_stride;
+ y_ptr2+=2*y_pixel_stride;
+ u_ptr+=2*uv_pixel_stride/uv_x_sample_interval;
+ v_ptr+=2*uv_pixel_stride/uv_x_sample_interval;
+ }
+
+ /* Catch the last pixel, if needed */
+ if (uv_x_sample_interval == 2 && x == (width-1))
+ {
+ // Compute U and V contributions, common to the four pixels
+
+ int32_t u_tmp = ((*u_ptr)-128);
+ int32_t v_tmp = ((*v_ptr)-128);
+
+ int32_t r_tmp = (v_tmp*param->v_r_factor);
+ int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor);
+ int32_t b_tmp = (u_tmp*param->u_b_factor);
+
+ // Compute the Y contribution for each pixel
+
+ int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr1);
+
+ #if uv_y_sample_interval > 1
+ y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr2);
+ #endif
+ }
+ }
+
+ /* Catch the last line, if needed */
+ if (uv_y_sample_interval == 2 && y == (height-1))
+ {
+ const uint8_t *y_ptr1=Y+y*Y_stride,
+ *u_ptr=U+(y/uv_y_sample_interval)*UV_stride,
+ *v_ptr=V+(y/uv_y_sample_interval)*UV_stride;
+
+ uint8_t *rgb_ptr1=RGB+y*RGB_stride;
+
+ for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval)
+ {
+ // Compute U and V contributions, common to the four pixels
+
+ int32_t u_tmp = ((*u_ptr)-128);
+ int32_t v_tmp = ((*v_ptr)-128);
+
+ int32_t r_tmp = (v_tmp*param->v_r_factor);
+ int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor);
+ int32_t b_tmp = (u_tmp*param->u_b_factor);
+
+ // Compute the Y contribution for each pixel
+
+ int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr1);
+
+ y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr1);
+
+ y_ptr1+=2*y_pixel_stride;
+ u_ptr+=2*uv_pixel_stride/uv_x_sample_interval;
+ v_ptr+=2*uv_pixel_stride/uv_x_sample_interval;
+ }
+
+ /* Catch the last pixel, if needed */
+ if (uv_x_sample_interval == 2 && x == (width-1))
+ {
+ // Compute U and V contributions, common to the four pixels
+
+ int32_t u_tmp = ((*u_ptr)-128);
+ int32_t v_tmp = ((*v_ptr)-128);
+
+ int32_t r_tmp = (v_tmp*param->v_r_factor);
+ int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor);
+ int32_t b_tmp = (u_tmp*param->u_b_factor);
+
+ // Compute the Y contribution for each pixel
+
+ int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor);
+ PACK_PIXEL(rgb_ptr1);
+ }
+ }
+
+ #undef y_pixel_stride
+ #undef uv_pixel_stride
+ #undef uv_x_sample_interval
+ #undef uv_y_sample_interval
+}
+
+#undef STD_FUNCTION_NAME
+#undef YUV_FORMAT
+#undef RGB_FORMAT
+#undef PACK_PIXEL