SDL_winrtvideo.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "SDL_config.h"
  19. #if SDL_VIDEO_DRIVER_WINRT
  20. /* WinRT SDL video driver implementation
  21. Initial work on this was done by David Ludwig (dludwig@pobox.com), and
  22. was based off of SDL's "dummy" video driver.
  23. */
  24. extern "C" {
  25. #include "SDL_video.h"
  26. #include "SDL_mouse.h"
  27. #include "../SDL_sysvideo.h"
  28. #include "../SDL_pixels_c.h"
  29. #include "../../events/SDL_events_c.h"
  30. #include "../../render/SDL_sysrender.h"
  31. #include "SDL_syswm.h"
  32. }
  33. #include "SDL_WinRTApp.h"
  34. #include "SDL_winrtvideo.h"
  35. #include "SDL_winrtevents_c.h"
  36. #include "SDL_winrtmouse.h"
  37. using namespace Windows::UI::Core;
  38. /* On Windows, windows.h defines CreateWindow */
  39. #ifdef CreateWindow
  40. #undef CreateWindow
  41. #endif
  42. extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
  43. #define WINRTVID_DRIVER_NAME "winrt"
  44. /* Initialization/Query functions */
  45. static int WINRT_VideoInit(_THIS);
  46. static int WINRT_InitModes(_THIS);
  47. static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
  48. static void WINRT_VideoQuit(_THIS);
  49. /* Window functions */
  50. static int WINRT_CreateWindow(_THIS, SDL_Window * window);
  51. static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
  52. static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
  53. /* WinRT driver bootstrap functions */
  54. static int
  55. WINRT_Available(void)
  56. {
  57. return (1);
  58. }
  59. static void
  60. WINRT_DeleteDevice(SDL_VideoDevice * device)
  61. {
  62. SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL);
  63. SDL_free(device);
  64. }
  65. static SDL_VideoDevice *
  66. WINRT_CreateDevice(int devindex)
  67. {
  68. SDL_VideoDevice *device;
  69. /* Initialize all variables that we clean on shutdown */
  70. device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
  71. if (!device) {
  72. SDL_OutOfMemory();
  73. if (device) {
  74. SDL_free(device);
  75. }
  76. return (0);
  77. }
  78. /* Set the function pointers */
  79. device->VideoInit = WINRT_VideoInit;
  80. device->VideoQuit = WINRT_VideoQuit;
  81. device->CreateWindow = WINRT_CreateWindow;
  82. device->DestroyWindow = WINRT_DestroyWindow;
  83. device->SetDisplayMode = WINRT_SetDisplayMode;
  84. device->PumpEvents = WINRT_PumpEvents;
  85. //device->CreateWindowFramebuffer = SDL_WINRT_CreateWindowFramebuffer;
  86. //device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer;
  87. //device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer;
  88. device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
  89. device->free = WINRT_DeleteDevice;
  90. SDL_WinRTGlobalApp->SetSDLVideoDevice(device);
  91. return device;
  92. }
  93. VideoBootStrap WINRT_bootstrap = {
  94. WINRTVID_DRIVER_NAME, "SDL Windows RT video driver",
  95. WINRT_Available, WINRT_CreateDevice
  96. };
  97. int
  98. WINRT_VideoInit(_THIS)
  99. {
  100. // 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)
  101. if (WINRT_InitModes(_this) < 0) {
  102. return -1;
  103. }
  104. WINRT_InitMouse(_this);
  105. return 0;
  106. }
  107. static int
  108. WINRT_InitModes(_THIS)
  109. {
  110. SDL_DisplayMode mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
  111. if (SDL_AddBasicVideoDisplay(&mode) < 0) {
  112. return -1;
  113. }
  114. SDL_AddDisplayMode(&_this->displays[0], &mode);
  115. return 0;
  116. }
  117. static int
  118. WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
  119. {
  120. return 0;
  121. }
  122. void
  123. WINRT_VideoQuit(_THIS)
  124. {
  125. WINRT_QuitMouse(_this);
  126. }
  127. int
  128. WINRT_CreateWindow(_THIS, SDL_Window * window)
  129. {
  130. // Make sure that only one window gets created, at least until multimonitor
  131. // support is added.
  132. if (SDL_WinRTGlobalApp->HasSDLWindowData())
  133. {
  134. SDL_SetError("WinRT only supports one window");
  135. return -1;
  136. }
  137. SDL_WindowData *data = new SDL_WindowData;
  138. if (!data) {
  139. SDL_OutOfMemory();
  140. return -1;
  141. }
  142. window->driverdata = data;
  143. data->sdlWindow = window;
  144. data->coreWindow = CoreWindow::GetForCurrentThread();
  145. /* Make sure the window is considered to be positioned at {0,0},
  146. and is considered fullscreen, shown, and the like.
  147. */
  148. window->x = 0;
  149. window->y = 0;
  150. window->flags =
  151. SDL_WINDOW_FULLSCREEN |
  152. SDL_WINDOW_SHOWN |
  153. SDL_WINDOW_BORDERLESS |
  154. SDL_WINDOW_MAXIMIZED |
  155. SDL_WINDOW_INPUT_GRABBED;
  156. /* HACK from DLudwig: The following line of code prevents
  157. SDL_CreateWindow and SDL_UpdateFullscreenMode from trying to resize
  158. the window after the call to WINRT_CreateWindow returns.
  159. This hack should allow a window to be created in virtually any size,
  160. and more importantly, it allows a window's framebuffer, as created and
  161. retrieved via SDL_GetWindowSurface, to be in any size. This can be
  162. utilized by apps centered around software rendering, such as ports
  163. of older apps. The app can have SDL create a framebuffer in any size
  164. it chooses. SDL will scale the framebuffer to the native
  165. screen size on the GPU (via SDL_UpdateWindowSurface).
  166. */
  167. _this->displays[0].fullscreen_window = window;
  168. /* Further prevent any display resizing, and make sure SDL_GetWindowDisplayMode
  169. can report the correct size of windows, by creating a new display
  170. mode in the requested size. To note, if the window is being created in
  171. the device's native screen size, SDL_AddDisplayMode will do nothing.
  172. */
  173. window->fullscreen_mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
  174. window->fullscreen_mode.w = window->w;
  175. window->fullscreen_mode.h = window->h;
  176. SDL_AddDisplayMode(&_this->displays[0], &window->fullscreen_mode);
  177. /* TODO: Consider removing custom display modes in WINRT_DestroyWindow. */
  178. /* Make sure the WinRT app's IFramworkView can post events on
  179. behalf of SDL:
  180. */
  181. SDL_WinRTGlobalApp->SetSDLWindowData(data);
  182. /* All done! */
  183. return 0;
  184. }
  185. void
  186. WINRT_DestroyWindow(_THIS, SDL_Window * window)
  187. {
  188. SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
  189. if (SDL_WinRTGlobalApp->HasSDLWindowData() &&
  190. SDL_WinRTGlobalApp->GetSDLWindowData()->sdlWindow == window)
  191. {
  192. SDL_WinRTGlobalApp->SetSDLWindowData(NULL);
  193. }
  194. if (data) {
  195. // Delete the internal window data:
  196. delete data;
  197. data = NULL;
  198. }
  199. }
  200. SDL_bool
  201. WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
  202. {
  203. SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
  204. if (info->version.major <= SDL_MAJOR_VERSION) {
  205. info->subsystem = SDL_SYSWM_WINDOWSRT;
  206. info->info.winrt.window = reinterpret_cast<IUnknown *>(data->coreWindow.Get());
  207. return SDL_TRUE;
  208. } else {
  209. SDL_SetError("Application not compiled with SDL %d.%d\n",
  210. SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
  211. return SDL_FALSE;
  212. }
  213. return SDL_FALSE;
  214. }
  215. #endif /* SDL_VIDEO_DRIVER_WINRT */
  216. /* vi: set ts=4 sw=4 expandtab: */