src/video/winrt/SDL_winrtvideo.cpp
author David Ludwig <dludwig@pobox.com>
Tue, 27 Aug 2013 11:44:43 -0400
changeset 8496 9f0a4fbc6452
parent 8494 5d165785918d
child 8497 103bb054aa7d
permissions -rw-r--r--
WinRT: renamed SDL_SYSWM_WINDOWSRT to SDL_SYSWM_WINRT
This is part of an overall effort to use the name, "WinRT", rather than "WindowsRT" (or "Windows RT"), as the shorthand name often seems to mean something different than the longhand name. (WinRT is an API, Windows RT is a product name)
dludwig@8327
     1
/*
dludwig@8327
     2
  Simple DirectMedia Layer
dludwig@8327
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
dludwig@8327
     4
dludwig@8327
     5
  This software is provided 'as-is', without any express or implied
dludwig@8327
     6
  warranty.  In no event will the authors be held liable for any damages
dludwig@8327
     7
  arising from the use of this software.
dludwig@8327
     8
dludwig@8327
     9
  Permission is granted to anyone to use this software for any purpose,
dludwig@8327
    10
  including commercial applications, and to alter it and redistribute it
dludwig@8327
    11
  freely, subject to the following restrictions:
dludwig@8327
    12
dludwig@8327
    13
  1. The origin of this software must not be misrepresented; you must not
dludwig@8327
    14
     claim that you wrote the original software. If you use this software
dludwig@8327
    15
     in a product, an acknowledgment in the product documentation would be
dludwig@8327
    16
     appreciated but is not required.
dludwig@8327
    17
  2. Altered source versions must be plainly marked as such, and must not be
dludwig@8327
    18
     misrepresented as being the original software.
dludwig@8327
    19
  3. This notice may not be removed or altered from any source distribution.
dludwig@8327
    20
*/
dludwig@8327
    21
#include "SDL_config.h"
dludwig@8327
    22
dludwig@8327
    23
#if SDL_VIDEO_DRIVER_WINRT
dludwig@8327
    24
dludwig@8327
    25
/* WinRT SDL video driver implementation
dludwig@8327
    26
dludwig@8327
    27
   Initial work on this was done by David Ludwig (dludwig@pobox.com), and
dludwig@8327
    28
   was based off of SDL's "dummy" video driver.
dludwig@8327
    29
 */
dludwig@8327
    30
dludwig@8494
    31
/* Windows includes */
dludwig@8494
    32
#include <agile.h>
dludwig@8494
    33
using namespace Windows::UI::Core;
dludwig@8494
    34
dludwig@8494
    35
dludwig@8494
    36
/* SDL includes */
dludwig@8329
    37
extern "C" {
dludwig@8327
    38
#include "SDL_video.h"
dludwig@8327
    39
#include "SDL_mouse.h"
dludwig@8327
    40
#include "../SDL_sysvideo.h"
dludwig@8327
    41
#include "../SDL_pixels_c.h"
dludwig@8327
    42
#include "../../events/SDL_events_c.h"
dludwig@8400
    43
#include "../../render/SDL_sysrender.h"
dludwig@8411
    44
#include "SDL_syswm.h"
dludwig@8329
    45
}
dludwig@8327
    46
dludwig@8483
    47
#include "../../core/winrt/SDL_winrtapp.h"
dludwig@8327
    48
#include "SDL_winrtevents_c.h"
dludwig@8374
    49
#include "SDL_winrtmouse.h"
dludwig@8327
    50
dludwig@8332
    51
extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
dludwig@8332
    52
dludwig@8327
    53
dludwig@8327
    54
/* Initialization/Query functions */
dludwig@8327
    55
static int WINRT_VideoInit(_THIS);
dludwig@8374
    56
static int WINRT_InitModes(_THIS);
dludwig@8327
    57
static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
dludwig@8327
    58
static void WINRT_VideoQuit(_THIS);
dludwig@8327
    59
dludwig@8494
    60
dludwig@8333
    61
/* Window functions */
dludwig@8333
    62
static int WINRT_CreateWindow(_THIS, SDL_Window * window);
dludwig@8333
    63
static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
dludwig@8411
    64
static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
dludwig@8333
    65
dludwig@8494
    66
dludwig@8494
    67
/* Internal window data */
dludwig@8494
    68
struct SDL_WindowData
dludwig@8494
    69
{
dludwig@8494
    70
    SDL_Window *sdlWindow;
dludwig@8494
    71
    Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow;
dludwig@8494
    72
};
dludwig@8494
    73
dludwig@8494
    74
dludwig@8327
    75
/* WinRT driver bootstrap functions */
dludwig@8327
    76
dludwig@8327
    77
static int
dludwig@8327
    78
WINRT_Available(void)
dludwig@8327
    79
{
dludwig@8328
    80
    return (1);
dludwig@8327
    81
}
dludwig@8327
    82
dludwig@8327
    83
static void
dludwig@8327
    84
WINRT_DeleteDevice(SDL_VideoDevice * device)
dludwig@8327
    85
{
dludwig@8433
    86
    SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL);
dludwig@8327
    87
    SDL_free(device);
dludwig@8327
    88
}
dludwig@8327
    89
dludwig@8327
    90
static SDL_VideoDevice *
dludwig@8327
    91
WINRT_CreateDevice(int devindex)
dludwig@8327
    92
{
dludwig@8327
    93
    SDL_VideoDevice *device;
dludwig@8327
    94
dludwig@8327
    95
    /* Initialize all variables that we clean on shutdown */
dludwig@8327
    96
    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
dludwig@8327
    97
    if (!device) {
dludwig@8327
    98
        SDL_OutOfMemory();
dludwig@8327
    99
        if (device) {
dludwig@8327
   100
            SDL_free(device);
dludwig@8327
   101
        }
dludwig@8327
   102
        return (0);
dludwig@8327
   103
    }
dludwig@8327
   104
dludwig@8327
   105
    /* Set the function pointers */
dludwig@8327
   106
    device->VideoInit = WINRT_VideoInit;
dludwig@8327
   107
    device->VideoQuit = WINRT_VideoQuit;
dludwig@8333
   108
    device->CreateWindow = WINRT_CreateWindow;
dludwig@8333
   109
    device->DestroyWindow = WINRT_DestroyWindow;
dludwig@8327
   110
    device->SetDisplayMode = WINRT_SetDisplayMode;
dludwig@8327
   111
    device->PumpEvents = WINRT_PumpEvents;
dludwig@8411
   112
    device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
dludwig@8433
   113
    device->free = WINRT_DeleteDevice;
dludwig@8433
   114
    SDL_WinRTGlobalApp->SetSDLVideoDevice(device);
dludwig@8327
   115
dludwig@8327
   116
    return device;
dludwig@8327
   117
}
dludwig@8327
   118
dludwig@8494
   119
#define WINRTVID_DRIVER_NAME "winrt"
dludwig@8327
   120
VideoBootStrap WINRT_bootstrap = {
dludwig@8327
   121
    WINRTVID_DRIVER_NAME, "SDL Windows RT video driver",
dludwig@8327
   122
    WINRT_Available, WINRT_CreateDevice
dludwig@8327
   123
};
dludwig@8327
   124
dludwig@8327
   125
int
dludwig@8327
   126
WINRT_VideoInit(_THIS)
dludwig@8327
   127
{
dludwig@8476
   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)
dludwig@8475
   129
dludwig@8374
   130
    if (WINRT_InitModes(_this) < 0) {
dludwig@8374
   131
        return -1;
dludwig@8374
   132
    }
dludwig@8374
   133
    WINRT_InitMouse(_this);
dludwig@8374
   134
dludwig@8374
   135
    return 0;
dludwig@8374
   136
}
dludwig@8374
   137
dludwig@8374
   138
static int
dludwig@8374
   139
WINRT_InitModes(_THIS)
dludwig@8374
   140
{
dludwig@8492
   141
    SDL_DisplayMode mode = SDL_WinRTGlobalApp->CalcCurrentDisplayMode();
dludwig@8329
   142
    if (SDL_AddBasicVideoDisplay(&mode) < 0) {
dludwig@8329
   143
        return -1;
dludwig@8374
   144
    }
dludwig@8374
   145
dludwig@8374
   146
    SDL_AddDisplayMode(&_this->displays[0], &mode);
dludwig@8327
   147
    return 0;
dludwig@8327
   148
}
dludwig@8327
   149
dludwig@8327
   150
static int
dludwig@8327
   151
WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
dludwig@8327
   152
{
dludwig@8327
   153
    return 0;
dludwig@8327
   154
}
dludwig@8327
   155
dludwig@8327
   156
void
dludwig@8327
   157
WINRT_VideoQuit(_THIS)
dludwig@8327
   158
{
dludwig@8374
   159
    WINRT_QuitMouse(_this);
dludwig@8327
   160
}
dludwig@8327
   161
dludwig@8333
   162
int
dludwig@8333
   163
WINRT_CreateWindow(_THIS, SDL_Window * window)
dludwig@8333
   164
{
dludwig@8334
   165
    // Make sure that only one window gets created, at least until multimonitor
dludwig@8334
   166
    // support is added.
dludwig@8494
   167
    if (SDL_WinRTGlobalApp->GetSDLWindow() != NULL) {
dludwig@8334
   168
        SDL_SetError("WinRT only supports one window");
dludwig@8334
   169
        return -1;
dludwig@8334
   170
    }
dludwig@8333
   171
dludwig@8411
   172
    SDL_WindowData *data = new SDL_WindowData;
dludwig@8333
   173
    if (!data) {
dludwig@8333
   174
        SDL_OutOfMemory();
dludwig@8333
   175
        return -1;
dludwig@8333
   176
    }
dludwig@8417
   177
    window->driverdata = data;
dludwig@8333
   178
    data->sdlWindow = window;
dludwig@8463
   179
    data->coreWindow = CoreWindow::GetForCurrentThread();
dludwig@8333
   180
dludwig@8367
   181
    /* Make sure the window is considered to be positioned at {0,0},
dludwig@8367
   182
       and is considered fullscreen, shown, and the like.
dludwig@8367
   183
    */
dludwig@8333
   184
    window->x = 0;
dludwig@8333
   185
    window->y = 0;
dludwig@8367
   186
    window->flags =
dludwig@8367
   187
        SDL_WINDOW_FULLSCREEN |
dludwig@8367
   188
        SDL_WINDOW_SHOWN |
dludwig@8367
   189
        SDL_WINDOW_BORDERLESS |
dludwig@8367
   190
        SDL_WINDOW_MAXIMIZED |
dludwig@8367
   191
        SDL_WINDOW_INPUT_GRABBED;
dludwig@8333
   192
dludwig@8491
   193
    /* WinRT does not, as of this writing, appear to support app-adjustable
dludwig@8491
   194
       window sizes.  Set the window size to whatever the native WinRT
dludwig@8491
   195
       CoreWindow is set at.
dludwig@8491
   196
dludwig@8491
   197
       TODO, WinRT: if and when non-fullscreen XAML control support is added to SDL, consider making those resizable via SDL_Window's interfaces.
dludwig@8367
   198
    */
dludwig@8491
   199
    window->w = _this->displays[0].current_mode.w;
dludwig@8491
   200
    window->h = _this->displays[0].current_mode.h;
dludwig@8367
   201
 
dludwig@8367
   202
    /* Make sure the WinRT app's IFramworkView can post events on
dludwig@8367
   203
       behalf of SDL:
dludwig@8367
   204
    */
dludwig@8494
   205
    SDL_WinRTGlobalApp->SetSDLWindow(window);
dludwig@8333
   206
dludwig@8367
   207
    /* All done! */
dludwig@8333
   208
    return 0;
dludwig@8333
   209
}
dludwig@8333
   210
dludwig@8333
   211
void
dludwig@8333
   212
WINRT_DestroyWindow(_THIS, SDL_Window * window)
dludwig@8333
   213
{
dludwig@8411
   214
    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
dludwig@8411
   215
dludwig@8494
   216
    if (SDL_WinRTGlobalApp->GetSDLWindow() == window) {
dludwig@8494
   217
        SDL_WinRTGlobalApp->SetSDLWindow(NULL);
dludwig@8424
   218
    }
dludwig@8424
   219
dludwig@8411
   220
    if (data) {
dludwig@8411
   221
        // Delete the internal window data:
dludwig@8411
   222
        delete data;
dludwig@8411
   223
        data = NULL;
dludwig@8411
   224
    }
dludwig@8333
   225
}
dludwig@8333
   226
dludwig@8411
   227
SDL_bool
dludwig@8411
   228
WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
dludwig@8411
   229
{
dludwig@8411
   230
    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
dludwig@8411
   231
dludwig@8411
   232
    if (info->version.major <= SDL_MAJOR_VERSION) {
dludwig@8496
   233
        info->subsystem = SDL_SYSWM_WINRT;
dludwig@8463
   234
        info->info.winrt.window = reinterpret_cast<IUnknown *>(data->coreWindow.Get());
dludwig@8411
   235
        return SDL_TRUE;
dludwig@8411
   236
    } else {
dludwig@8411
   237
        SDL_SetError("Application not compiled with SDL %d.%d\n",
dludwig@8411
   238
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
dludwig@8411
   239
        return SDL_FALSE;
dludwig@8411
   240
    }
dludwig@8411
   241
    return SDL_FALSE;
dludwig@8411
   242
}
dludwig@8333
   243
dludwig@8327
   244
#endif /* SDL_VIDEO_DRIVER_WINRT */
dludwig@8327
   245
dludwig@8327
   246
/* vi: set ts=4 sw=4 expandtab: */