src/video/winrt/SDL_winrtvideo.cpp
author David Ludwig <dludwig@pobox.com>
Tue, 27 Aug 2013 11:39:44 -0400
changeset 8494 5d165785918d
parent 8492 1bcacb98366e
child 8496 9f0a4fbc6452
permissions -rw-r--r--
WinRT: misc code cleanups
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 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_config.h"
    22 
    23 #if SDL_VIDEO_DRIVER_WINRT
    24 
    25 /* WinRT SDL video driver implementation
    26 
    27    Initial work on this was done by David Ludwig (dludwig@pobox.com), and
    28    was based off of SDL's "dummy" video driver.
    29  */
    30 
    31 /* Windows includes */
    32 #include <agile.h>
    33 using namespace Windows::UI::Core;
    34 
    35 
    36 /* SDL includes */
    37 extern "C" {
    38 #include "SDL_video.h"
    39 #include "SDL_mouse.h"
    40 #include "../SDL_sysvideo.h"
    41 #include "../SDL_pixels_c.h"
    42 #include "../../events/SDL_events_c.h"
    43 #include "../../render/SDL_sysrender.h"
    44 #include "SDL_syswm.h"
    45 }
    46 
    47 #include "../../core/winrt/SDL_winrtapp.h"
    48 #include "SDL_winrtevents_c.h"
    49 #include "SDL_winrtmouse.h"
    50 
    51 extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
    52 
    53 
    54 /* Initialization/Query functions */
    55 static int WINRT_VideoInit(_THIS);
    56 static int WINRT_InitModes(_THIS);
    57 static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
    58 static void WINRT_VideoQuit(_THIS);
    59 
    60 
    61 /* Window functions */
    62 static int WINRT_CreateWindow(_THIS, SDL_Window * window);
    63 static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
    64 static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
    65 
    66 
    67 /* Internal window data */
    68 struct SDL_WindowData
    69 {
    70     SDL_Window *sdlWindow;
    71     Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow;
    72 };
    73 
    74 
    75 /* WinRT driver bootstrap functions */
    76 
    77 static int
    78 WINRT_Available(void)
    79 {
    80     return (1);
    81 }
    82 
    83 static void
    84 WINRT_DeleteDevice(SDL_VideoDevice * device)
    85 {
    86     SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL);
    87     SDL_free(device);
    88 }
    89 
    90 static SDL_VideoDevice *
    91 WINRT_CreateDevice(int devindex)
    92 {
    93     SDL_VideoDevice *device;
    94 
    95     /* Initialize all variables that we clean on shutdown */
    96     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    97     if (!device) {
    98         SDL_OutOfMemory();
    99         if (device) {
   100             SDL_free(device);
   101         }
   102         return (0);
   103     }
   104 
   105     /* Set the function pointers */
   106     device->VideoInit = WINRT_VideoInit;
   107     device->VideoQuit = WINRT_VideoQuit;
   108     device->CreateWindow = WINRT_CreateWindow;
   109     device->DestroyWindow = WINRT_DestroyWindow;
   110     device->SetDisplayMode = WINRT_SetDisplayMode;
   111     device->PumpEvents = WINRT_PumpEvents;
   112     device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
   113     device->free = WINRT_DeleteDevice;
   114     SDL_WinRTGlobalApp->SetSDLVideoDevice(device);
   115 
   116     return device;
   117 }
   118 
   119 #define WINRTVID_DRIVER_NAME "winrt"
   120 VideoBootStrap WINRT_bootstrap = {
   121     WINRTVID_DRIVER_NAME, "SDL Windows RT video driver",
   122     WINRT_Available, WINRT_CreateDevice
   123 };
   124 
   125 int
   126 WINRT_VideoInit(_THIS)
   127 {
   128     // TODO, WinRT: consider adding a hack to wait (here) for the app's orientation to finish getting set (before the initial display mode is set up)
   129 
   130     if (WINRT_InitModes(_this) < 0) {
   131         return -1;
   132     }
   133     WINRT_InitMouse(_this);
   134 
   135     return 0;
   136 }
   137 
   138 static int
   139 WINRT_InitModes(_THIS)
   140 {
   141     SDL_DisplayMode mode = SDL_WinRTGlobalApp->CalcCurrentDisplayMode();
   142     if (SDL_AddBasicVideoDisplay(&mode) < 0) {
   143         return -1;
   144     }
   145 
   146     SDL_AddDisplayMode(&_this->displays[0], &mode);
   147     return 0;
   148 }
   149 
   150 static int
   151 WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
   152 {
   153     return 0;
   154 }
   155 
   156 void
   157 WINRT_VideoQuit(_THIS)
   158 {
   159     WINRT_QuitMouse(_this);
   160 }
   161 
   162 int
   163 WINRT_CreateWindow(_THIS, SDL_Window * window)
   164 {
   165     // Make sure that only one window gets created, at least until multimonitor
   166     // support is added.
   167     if (SDL_WinRTGlobalApp->GetSDLWindow() != NULL) {
   168         SDL_SetError("WinRT only supports one window");
   169         return -1;
   170     }
   171 
   172     SDL_WindowData *data = new SDL_WindowData;
   173     if (!data) {
   174         SDL_OutOfMemory();
   175         return -1;
   176     }
   177     window->driverdata = data;
   178     data->sdlWindow = window;
   179     data->coreWindow = CoreWindow::GetForCurrentThread();
   180 
   181     /* Make sure the window is considered to be positioned at {0,0},
   182        and is considered fullscreen, shown, and the like.
   183     */
   184     window->x = 0;
   185     window->y = 0;
   186     window->flags =
   187         SDL_WINDOW_FULLSCREEN |
   188         SDL_WINDOW_SHOWN |
   189         SDL_WINDOW_BORDERLESS |
   190         SDL_WINDOW_MAXIMIZED |
   191         SDL_WINDOW_INPUT_GRABBED;
   192 
   193     /* WinRT does not, as of this writing, appear to support app-adjustable
   194        window sizes.  Set the window size to whatever the native WinRT
   195        CoreWindow is set at.
   196 
   197        TODO, WinRT: if and when non-fullscreen XAML control support is added to SDL, consider making those resizable via SDL_Window's interfaces.
   198     */
   199     window->w = _this->displays[0].current_mode.w;
   200     window->h = _this->displays[0].current_mode.h;
   201  
   202     /* Make sure the WinRT app's IFramworkView can post events on
   203        behalf of SDL:
   204     */
   205     SDL_WinRTGlobalApp->SetSDLWindow(window);
   206 
   207     /* All done! */
   208     return 0;
   209 }
   210 
   211 void
   212 WINRT_DestroyWindow(_THIS, SDL_Window * window)
   213 {
   214     SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
   215 
   216     if (SDL_WinRTGlobalApp->GetSDLWindow() == window) {
   217         SDL_WinRTGlobalApp->SetSDLWindow(NULL);
   218     }
   219 
   220     if (data) {
   221         // Delete the internal window data:
   222         delete data;
   223         data = NULL;
   224     }
   225 }
   226 
   227 SDL_bool
   228 WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
   229 {
   230     SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
   231 
   232     if (info->version.major <= SDL_MAJOR_VERSION) {
   233         info->subsystem = SDL_SYSWM_WINDOWSRT;
   234         info->info.winrt.window = reinterpret_cast<IUnknown *>(data->coreWindow.Get());
   235         return SDL_TRUE;
   236     } else {
   237         SDL_SetError("Application not compiled with SDL %d.%d\n",
   238                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   239         return SDL_FALSE;
   240     }
   241     return SDL_FALSE;
   242 }
   243 
   244 #endif /* SDL_VIDEO_DRIVER_WINRT */
   245 
   246 /* vi: set ts=4 sw=4 expandtab: */