cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_windowsvideo.c (13374B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21#include "../../SDL_internal.h"
     22
     23#if SDL_VIDEO_DRIVER_WINDOWS
     24
     25#include "SDL_main.h"
     26#include "SDL_video.h"
     27#include "SDL_hints.h"
     28#include "SDL_mouse.h"
     29#include "SDL_system.h"
     30#include "../SDL_sysvideo.h"
     31#include "../SDL_pixels_c.h"
     32
     33#include "SDL_windowsvideo.h"
     34#include "SDL_windowsframebuffer.h"
     35#include "SDL_windowsshape.h"
     36
     37/* Initialization/Query functions */
     38static int WIN_VideoInit(_THIS);
     39static void WIN_VideoQuit(_THIS);
     40
     41/* Hints */
     42SDL_bool g_WindowsEnableMessageLoop = SDL_TRUE;
     43SDL_bool g_WindowFrameUsableWhileCursorHidden = SDL_TRUE;
     44
     45static void UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue)
     46{
     47    if (newValue && *newValue == '0') {
     48        g_WindowsEnableMessageLoop = SDL_FALSE;
     49    } else {
     50        g_WindowsEnableMessageLoop = SDL_TRUE;
     51    }
     52}
     53
     54static void UpdateWindowFrameUsableWhileCursorHidden(void *userdata, const char *name, const char *oldValue, const char *newValue)
     55{
     56    if (newValue && *newValue == '0') {
     57        g_WindowFrameUsableWhileCursorHidden = SDL_FALSE;
     58    } else {
     59        g_WindowFrameUsableWhileCursorHidden = SDL_TRUE;
     60    }
     61}
     62
     63
     64/* Windows driver bootstrap functions */
     65
     66static int
     67WIN_Available(void)
     68{
     69    return (1);
     70}
     71
     72static void
     73WIN_DeleteDevice(SDL_VideoDevice * device)
     74{
     75    SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
     76
     77    SDL_UnregisterApp();
     78    if (data->userDLL) {
     79        SDL_UnloadObject(data->userDLL);
     80    }
     81
     82    SDL_free(device->driverdata);
     83    SDL_free(device);
     84}
     85
     86static SDL_VideoDevice *
     87WIN_CreateDevice(int devindex)
     88{
     89    SDL_VideoDevice *device;
     90    SDL_VideoData *data;
     91
     92    SDL_RegisterApp(NULL, 0, NULL);
     93
     94    /* Initialize all variables that we clean on shutdown */
     95    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
     96    if (device) {
     97        data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
     98    } else {
     99        data = NULL;
    100    }
    101    if (!data) {
    102        SDL_free(device);
    103        SDL_OutOfMemory();
    104        return NULL;
    105    }
    106    device->driverdata = data;
    107
    108    data->userDLL = SDL_LoadObject("USER32.DLL");
    109    if (data->userDLL) {
    110        data->CloseTouchInputHandle = (BOOL (WINAPI *)(HTOUCHINPUT)) SDL_LoadFunction(data->userDLL, "CloseTouchInputHandle");
    111        data->GetTouchInputInfo = (BOOL (WINAPI *)(HTOUCHINPUT, UINT, PTOUCHINPUT, int)) SDL_LoadFunction(data->userDLL, "GetTouchInputInfo");
    112        data->RegisterTouchWindow = (BOOL (WINAPI *)(HWND, ULONG)) SDL_LoadFunction(data->userDLL, "RegisterTouchWindow");
    113    }
    114
    115    /* Set the function pointers */
    116    device->VideoInit = WIN_VideoInit;
    117    device->VideoQuit = WIN_VideoQuit;
    118    device->GetDisplayBounds = WIN_GetDisplayBounds;
    119    device->GetDisplayModes = WIN_GetDisplayModes;
    120    device->SetDisplayMode = WIN_SetDisplayMode;
    121    device->PumpEvents = WIN_PumpEvents;
    122
    123#undef CreateWindow
    124    device->CreateWindow = WIN_CreateWindow;
    125    device->CreateWindowFrom = WIN_CreateWindowFrom;
    126    device->SetWindowTitle = WIN_SetWindowTitle;
    127    device->SetWindowIcon = WIN_SetWindowIcon;
    128    device->SetWindowPosition = WIN_SetWindowPosition;
    129    device->SetWindowSize = WIN_SetWindowSize;
    130    device->ShowWindow = WIN_ShowWindow;
    131    device->HideWindow = WIN_HideWindow;
    132    device->RaiseWindow = WIN_RaiseWindow;
    133    device->MaximizeWindow = WIN_MaximizeWindow;
    134    device->MinimizeWindow = WIN_MinimizeWindow;
    135    device->RestoreWindow = WIN_RestoreWindow;
    136    device->SetWindowBordered = WIN_SetWindowBordered;
    137    device->SetWindowFullscreen = WIN_SetWindowFullscreen;
    138    device->SetWindowGammaRamp = WIN_SetWindowGammaRamp;
    139    device->GetWindowGammaRamp = WIN_GetWindowGammaRamp;
    140    device->SetWindowGrab = WIN_SetWindowGrab;
    141    device->DestroyWindow = WIN_DestroyWindow;
    142    device->GetWindowWMInfo = WIN_GetWindowWMInfo;
    143    device->CreateWindowFramebuffer = WIN_CreateWindowFramebuffer;
    144    device->UpdateWindowFramebuffer = WIN_UpdateWindowFramebuffer;
    145    device->DestroyWindowFramebuffer = WIN_DestroyWindowFramebuffer;
    146    device->OnWindowEnter = WIN_OnWindowEnter;
    147    device->SetWindowHitTest = WIN_SetWindowHitTest;
    148
    149    device->shape_driver.CreateShaper = Win32_CreateShaper;
    150    device->shape_driver.SetWindowShape = Win32_SetWindowShape;
    151    device->shape_driver.ResizeWindowShape = Win32_ResizeWindowShape;
    152
    153#if SDL_VIDEO_OPENGL_WGL
    154    device->GL_LoadLibrary = WIN_GL_LoadLibrary;
    155    device->GL_GetProcAddress = WIN_GL_GetProcAddress;
    156    device->GL_UnloadLibrary = WIN_GL_UnloadLibrary;
    157    device->GL_CreateContext = WIN_GL_CreateContext;
    158    device->GL_MakeCurrent = WIN_GL_MakeCurrent;
    159    device->GL_SetSwapInterval = WIN_GL_SetSwapInterval;
    160    device->GL_GetSwapInterval = WIN_GL_GetSwapInterval;
    161    device->GL_SwapWindow = WIN_GL_SwapWindow;
    162    device->GL_DeleteContext = WIN_GL_DeleteContext;
    163#elif SDL_VIDEO_OPENGL_EGL        
    164    /* Use EGL based functions */
    165    device->GL_LoadLibrary = WIN_GLES_LoadLibrary;
    166    device->GL_GetProcAddress = WIN_GLES_GetProcAddress;
    167    device->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
    168    device->GL_CreateContext = WIN_GLES_CreateContext;
    169    device->GL_MakeCurrent = WIN_GLES_MakeCurrent;
    170    device->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
    171    device->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
    172    device->GL_SwapWindow = WIN_GLES_SwapWindow;
    173    device->GL_DeleteContext = WIN_GLES_DeleteContext;
    174#endif
    175    device->StartTextInput = WIN_StartTextInput;
    176    device->StopTextInput = WIN_StopTextInput;
    177    device->SetTextInputRect = WIN_SetTextInputRect;
    178
    179    device->SetClipboardText = WIN_SetClipboardText;
    180    device->GetClipboardText = WIN_GetClipboardText;
    181    device->HasClipboardText = WIN_HasClipboardText;
    182
    183    device->free = WIN_DeleteDevice;
    184
    185    return device;
    186}
    187
    188
    189VideoBootStrap WINDOWS_bootstrap = {
    190    "windows", "SDL Windows video driver", WIN_Available, WIN_CreateDevice
    191};
    192
    193int
    194WIN_VideoInit(_THIS)
    195{
    196    if (WIN_InitModes(_this) < 0) {
    197        return -1;
    198    }
    199
    200    WIN_InitKeyboard(_this);
    201    WIN_InitMouse(_this);
    202
    203    SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
    204    SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
    205
    206    return 0;
    207}
    208
    209void
    210WIN_VideoQuit(_THIS)
    211{
    212    WIN_QuitModes(_this);
    213    WIN_QuitKeyboard(_this);
    214    WIN_QuitMouse(_this);
    215}
    216
    217
    218#define D3D_DEBUG_INFO
    219#include <d3d9.h>
    220
    221SDL_bool 
    222D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
    223{
    224    *pD3DDLL = SDL_LoadObject("D3D9.DLL");
    225    if (*pD3DDLL) {
    226        typedef IDirect3D9 *(WINAPI *Direct3DCreate9_t) (UINT SDKVersion);
    227        Direct3DCreate9_t Direct3DCreate9Func;
    228
    229#ifdef USE_D3D9EX
    230        typedef HRESULT (WINAPI *Direct3DCreate9Ex_t)(UINT SDKVersion, IDirect3D9Ex **ppD3D);
    231        Direct3DCreate9Ex_t Direct3DCreate9ExFunc;
    232
    233        Direct3DCreate9ExFunc = (Direct3DCreate9Ex_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9Ex");
    234        if (Direct3DCreate9ExFunc) {
    235            IDirect3D9Ex *pDirect3D9ExInterface;
    236            HRESULT hr = Direct3DCreate9ExFunc(D3D_SDK_VERSION, &pDirect3D9ExInterface);
    237            if (SUCCEEDED(hr)) {
    238                const GUID IDirect3D9_GUID = { 0x81bdcbca, 0x64d4, 0x426d, { 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c } };
    239                hr = IDirect3D9Ex_QueryInterface(pDirect3D9ExInterface, &IDirect3D9_GUID, (void**)pDirect3D9Interface);
    240                IDirect3D9Ex_Release(pDirect3D9ExInterface);
    241                if (SUCCEEDED(hr)) {
    242                    return SDL_TRUE;
    243                }
    244            }
    245        }
    246#endif /* USE_D3D9EX */
    247
    248        Direct3DCreate9Func = (Direct3DCreate9_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9");
    249        if (Direct3DCreate9Func) {
    250            *pDirect3D9Interface = Direct3DCreate9Func(D3D_SDK_VERSION);
    251            if (*pDirect3D9Interface) {
    252                return SDL_TRUE;
    253            }
    254        }
    255
    256        SDL_UnloadObject(*pD3DDLL);
    257        *pD3DDLL = NULL;
    258    }
    259    *pDirect3D9Interface = NULL;
    260    return SDL_FALSE;
    261}
    262
    263
    264int
    265SDL_Direct3D9GetAdapterIndex(int displayIndex)
    266{
    267    void *pD3DDLL;
    268    IDirect3D9 *pD3D;
    269    if (!D3D_LoadDLL(&pD3DDLL, &pD3D)) {
    270        SDL_SetError("Unable to create Direct3D interface");
    271        return D3DADAPTER_DEFAULT;
    272    } else {
    273        SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex);
    274        int adapterIndex = D3DADAPTER_DEFAULT;
    275
    276        if (!pData) {
    277            SDL_SetError("Invalid display index");
    278            adapterIndex = -1; /* make sure we return something invalid */
    279        } else {
    280            char *displayName = WIN_StringToUTF8(pData->DeviceName);
    281            unsigned int count = IDirect3D9_GetAdapterCount(pD3D);
    282            unsigned int i;
    283            for (i=0; i<count; i++) {
    284                D3DADAPTER_IDENTIFIER9 id;
    285                IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &id);
    286
    287                if (SDL_strcmp(id.DeviceName, displayName) == 0) {
    288                    adapterIndex = i;
    289                    break;
    290                }
    291            }
    292            SDL_free(displayName);
    293        }
    294
    295        /* free up the D3D stuff we inited */
    296        IDirect3D9_Release(pD3D);
    297        SDL_UnloadObject(pD3DDLL);
    298
    299        return adapterIndex;
    300    }
    301}
    302
    303#if HAVE_DXGI_H
    304#define CINTERFACE
    305#define COBJMACROS
    306#include <dxgi.h>
    307
    308static SDL_bool
    309DXGI_LoadDLL(void **pDXGIDLL, IDXGIFactory **pDXGIFactory)
    310{
    311    *pDXGIDLL = SDL_LoadObject("DXGI.DLL");
    312    if (*pDXGIDLL) {
    313        HRESULT (WINAPI *CreateDXGI)(REFIID riid, void **ppFactory);
    314
    315        CreateDXGI =
    316            (HRESULT (WINAPI *) (REFIID, void**)) SDL_LoadFunction(*pDXGIDLL,
    317            "CreateDXGIFactory");
    318        if (CreateDXGI) {
    319            GUID dxgiGUID = {0x7b7166ec,0x21c7,0x44ae,{0xb2,0x1a,0xc9,0xae,0x32,0x1a,0xe3,0x69}};
    320            if (!SUCCEEDED(CreateDXGI(&dxgiGUID, (void**)pDXGIFactory))) {
    321                *pDXGIFactory = NULL;
    322            }
    323        }
    324        if (!*pDXGIFactory) {
    325            SDL_UnloadObject(*pDXGIDLL);
    326            *pDXGIDLL = NULL;
    327            return SDL_FALSE;
    328        }
    329
    330        return SDL_TRUE;
    331    } else {
    332        *pDXGIFactory = NULL;
    333        return SDL_FALSE;
    334    }
    335}
    336#endif
    337
    338
    339SDL_bool
    340SDL_DXGIGetOutputInfo(int displayIndex, int *adapterIndex, int *outputIndex)
    341{
    342#if !HAVE_DXGI_H
    343    if (adapterIndex) *adapterIndex = -1;
    344    if (outputIndex) *outputIndex = -1;
    345    SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header");
    346    return SDL_FALSE;
    347#else
    348    SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex);
    349    void *pDXGIDLL;
    350    char *displayName;
    351    int nAdapter, nOutput;
    352    IDXGIFactory *pDXGIFactory;
    353    IDXGIAdapter *pDXGIAdapter;
    354    IDXGIOutput* pDXGIOutput;
    355
    356    if (!adapterIndex) {
    357        SDL_InvalidParamError("adapterIndex");
    358        return SDL_FALSE;
    359    }
    360
    361    if (!outputIndex) {
    362        SDL_InvalidParamError("outputIndex");
    363        return SDL_FALSE;
    364    }
    365
    366    *adapterIndex = -1;
    367    *outputIndex = -1;
    368
    369    if (!pData) {
    370        SDL_SetError("Invalid display index");
    371        return SDL_FALSE;
    372    }
    373
    374    if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) {
    375        SDL_SetError("Unable to create DXGI interface");
    376        return SDL_FALSE;
    377    }
    378
    379    displayName = WIN_StringToUTF8(pData->DeviceName);
    380    nAdapter = 0;
    381    while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) {
    382        nOutput = 0;
    383        while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) {
    384            DXGI_OUTPUT_DESC outputDesc;
    385            if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) {
    386                char *outputName = WIN_StringToUTF8(outputDesc.DeviceName);
    387                if (SDL_strcmp(outputName, displayName) == 0) {
    388                    *adapterIndex = nAdapter;
    389                    *outputIndex = nOutput;
    390                }
    391                SDL_free(outputName);
    392            }
    393            IDXGIOutput_Release(pDXGIOutput);
    394            nOutput++;
    395        }
    396        IDXGIAdapter_Release(pDXGIAdapter);
    397        nAdapter++;
    398    }
    399    SDL_free(displayName);
    400
    401    /* free up the DXGI factory */
    402    IDXGIFactory_Release(pDXGIFactory);
    403    SDL_UnloadObject(pDXGIDLL);
    404
    405    if (*adapterIndex == -1) {
    406        return SDL_FALSE;
    407    } else {
    408        return SDL_TRUE;
    409    }
    410#endif
    411}
    412
    413#endif /* SDL_VIDEO_DRIVER_WINDOWS */
    414
    415/* vim: set ts=4 sw=4 expandtab: */