Window.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /**
  2. * Copyright (c) 2006-2014 LOVE Development Team
  3. *
  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. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "common/config.h"
  22. #include "graphics/Graphics.h"
  23. #include "Window.h"
  24. // C++
  25. #include <iostream>
  26. #include <vector>
  27. #include <algorithm>
  28. namespace love
  29. {
  30. namespace window
  31. {
  32. namespace sdl
  33. {
  34. Window::Window()
  35. : windowTitle("")
  36. , created(false)
  37. , mouseGrabbed(false)
  38. , window(0)
  39. , context(0)
  40. {
  41. if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
  42. throw love::Exception("%s", SDL_GetError());
  43. }
  44. Window::~Window()
  45. {
  46. if (curMode.icon)
  47. curMode.icon->release();
  48. if (window)
  49. SDL_DestroyWindow(window);
  50. if (context)
  51. SDL_GL_DeleteContext(context);
  52. SDL_QuitSubSystem(SDL_INIT_VIDEO);
  53. }
  54. Window::_currentMode::_currentMode()
  55. : width(800)
  56. , height(600)
  57. , settings()
  58. , icon(0)
  59. {
  60. }
  61. bool Window::setWindow(int width, int height, WindowSettings *settings)
  62. {
  63. WindowSettings f;
  64. if (settings)
  65. f = *settings;
  66. f.minwidth = std::max(f.minwidth, 1);
  67. f.minheight = std::max(f.minheight, 1);
  68. f.display = std::min(std::max(f.display, 0), getDisplayCount() - 1);
  69. // Use the desktop resolution if a width or height of 0 is specified.
  70. if (width == 0 || height == 0)
  71. {
  72. SDL_DisplayMode mode = {};
  73. SDL_GetDesktopDisplayMode(f.display, &mode);
  74. width = mode.w;
  75. height = mode.h;
  76. }
  77. Uint32 sdlflags = SDL_WINDOW_OPENGL;
  78. if (f.fullscreen)
  79. {
  80. if (f.fstype == FULLSCREEN_TYPE_DESKTOP)
  81. sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
  82. else
  83. {
  84. sdlflags |= SDL_WINDOW_FULLSCREEN;
  85. // Fullscreen window creation will bug out if no mode can be used.
  86. SDL_DisplayMode mode = {0, width, height, 0, 0};
  87. if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == 0)
  88. return false;
  89. }
  90. }
  91. if (f.resizable)
  92. sdlflags |= SDL_WINDOW_RESIZABLE;
  93. if (f.borderless)
  94. sdlflags |= SDL_WINDOW_BORDERLESS;
  95. // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
  96. #if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
  97. if (f.highdpi)
  98. sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
  99. #endif
  100. graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
  101. if (gfx != nullptr)
  102. gfx->unSetMode();
  103. // Destroy and recreate the window if the dimensions or flags have changed.
  104. if (window)
  105. {
  106. int curdisplay = SDL_GetWindowDisplayIndex(window);
  107. Uint32 wflags = SDL_GetWindowFlags(window);
  108. Uint32 testflags = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP
  109. | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
  110. // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
  111. #if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
  112. testflags |= SDL_WINDOW_ALLOW_HIGHDPI;
  113. #endif
  114. wflags &= testflags;
  115. if (sdlflags != wflags || width != curMode.width || height != curMode.height
  116. || f.display != curdisplay || f.fsaa != curMode.settings.fsaa)
  117. {
  118. SDL_DestroyWindow(window);
  119. window = 0;
  120. // The old window may have generated pending events which are no
  121. // longer relevant. Destroy them all!
  122. SDL_FlushEvent(SDL_WINDOWEVENT);
  123. }
  124. }
  125. int centeredpos = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
  126. int uncenteredpos = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
  127. if (!window)
  128. {
  129. created = false;
  130. // In Windows and Linux, some GL attributes are set on window creation.
  131. setWindowGLAttributes(f.fsaa, f.sRGB);
  132. const char *title = windowTitle.c_str();
  133. int pos = f.centered ? centeredpos : uncenteredpos;
  134. window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
  135. if (!window && f.fsaa > 0)
  136. {
  137. // FSAA might have caused the failure, disable it and try again.
  138. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
  139. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
  140. window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
  141. f.fsaa = 0;
  142. }
  143. // Make sure the window keeps any previously set icon.
  144. if (window && curMode.icon)
  145. setIcon(curMode.icon);
  146. }
  147. if (!window)
  148. {
  149. std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
  150. return false;
  151. }
  152. // Enforce minimum window dimensions.
  153. SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
  154. if (f.centered && !f.fullscreen)
  155. SDL_SetWindowPosition(window, centeredpos, centeredpos);
  156. SDL_RaiseWindow(window);
  157. if (!setContext(f.fsaa, f.vsync, f.sRGB))
  158. return false;
  159. created = true;
  160. updateSettings(f);
  161. if (gfx != nullptr)
  162. {
  163. int width = curMode.width;
  164. int height = curMode.height;
  165. // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
  166. #if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
  167. SDL_GL_GetDrawableSize(window, &width, &height);
  168. #endif
  169. gfx->setMode(width, height, curMode.settings.sRGB);
  170. }
  171. // Make sure the mouse keeps its previous grab setting.
  172. setMouseGrab(mouseGrabbed);
  173. return true;
  174. }
  175. bool Window::onWindowResize(int width, int height)
  176. {
  177. if (!window)
  178. return false;
  179. curMode.width = width;
  180. curMode.height = height;
  181. return true;
  182. }
  183. bool Window::setContext(int fsaa, bool vsync, bool sRGB)
  184. {
  185. // We would normally only need to recreate the context if FSAA changes or
  186. // SDL_GL_MakeCurrent is unsuccessful, but in Windows MakeCurrent can
  187. // sometimes claim success but the context will actually be trashed.
  188. if (context)
  189. {
  190. SDL_GL_DeleteContext(context);
  191. context = 0;
  192. }
  193. // Make sure the proper attributes are set.
  194. setWindowGLAttributes(fsaa, sRGB);
  195. context = SDL_GL_CreateContext(window);
  196. if (!context && fsaa > 0)
  197. {
  198. // FSAA might have caused the failure, disable it and try again.
  199. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
  200. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
  201. context = SDL_GL_CreateContext(window);
  202. }
  203. if (!context)
  204. {
  205. int flags = 0;
  206. SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &flags);
  207. if (flags & SDL_GL_CONTEXT_DEBUG_FLAG)
  208. {
  209. SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
  210. SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
  211. context = SDL_GL_CreateContext(window);
  212. }
  213. }
  214. if (!context)
  215. {
  216. std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
  217. return false;
  218. }
  219. // Set vertical synchronization.
  220. SDL_GL_SetSwapInterval(vsync ? 1 : 0);
  221. // Verify FSAA setting.
  222. int buffers;
  223. int samples;
  224. SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
  225. SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
  226. // Don't fail because of this, but issue a warning.
  227. if ((!buffers && fsaa) || (samples != fsaa))
  228. {
  229. std::cerr << "Warning, FSAA setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
  230. fsaa = (buffers > 0) ? samples : 0;
  231. }
  232. curMode.settings.fsaa = fsaa;
  233. curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
  234. return true;
  235. }
  236. void Window::setWindowGLAttributes(int fsaa, bool /* sRGB */) const
  237. {
  238. // Set GL window attributes.
  239. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
  240. SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
  241. SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
  242. SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
  243. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  244. SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
  245. SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
  246. // FSAA.
  247. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
  248. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
  249. /* FIXME: Enable this code but make sure to try to re-create the window and
  250. * context with this disabled, if creation fails with it enabled.
  251. * We can leave this out for now because in practice the framebuffer will
  252. * already be sRGB-capable (on desktops at least.)
  253. #if SDL_VERSION_ATLEAST(2,0,1)
  254. SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0);
  255. #endif
  256. */
  257. // Do we want a debug context?
  258. const char *debugenv = SDL_GetHint("LOVE_GRAPHICS_DEBUG");
  259. if (debugenv && *debugenv == '1')
  260. {
  261. SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
  262. SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
  263. }
  264. else
  265. {
  266. SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
  267. SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
  268. }
  269. }
  270. void Window::updateSettings(const WindowSettings &newsettings)
  271. {
  272. Uint32 wflags = SDL_GetWindowFlags(window);
  273. // Set the new display mode as the current display mode.
  274. SDL_GetWindowSize(window, &curMode.width, &curMode.height);
  275. if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
  276. {
  277. curMode.settings.fullscreen = true;
  278. curMode.settings.fstype = FULLSCREEN_TYPE_DESKTOP;
  279. }
  280. else if ((wflags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)
  281. {
  282. curMode.settings.fullscreen = true;
  283. curMode.settings.fstype = FULLSCREEN_TYPE_NORMAL;
  284. }
  285. else
  286. {
  287. curMode.settings.fullscreen = false;
  288. curMode.settings.fstype = newsettings.fstype;
  289. }
  290. // The min width/height is set to 0 internally in SDL when in fullscreen.
  291. if (curMode.settings.fullscreen)
  292. {
  293. curMode.settings.minwidth = newsettings.minwidth;
  294. curMode.settings.minheight = newsettings.minheight;
  295. }
  296. else
  297. SDL_GetWindowMinimumSize(window, &curMode.settings.minwidth, &curMode.settings.minheight);
  298. curMode.settings.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
  299. curMode.settings.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
  300. curMode.settings.centered = newsettings.centered;
  301. curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
  302. #if SDL_VERSION_ATLEAST(2,0,1)
  303. curMode.settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
  304. #else
  305. curMode.settings.highdpi = false;
  306. #endif
  307. // Only minimize on focus loss if the window is in exclusive-fullscreen
  308. // mode.
  309. if (curMode.settings.fullscreen && curMode.settings.fstype == FULLSCREEN_TYPE_NORMAL)
  310. SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1");
  311. else
  312. SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
  313. curMode.settings.sRGB = newsettings.sRGB;
  314. }
  315. void Window::getWindow(int &width, int &height, WindowSettings &settings)
  316. {
  317. // The window might have been modified (moved, resized, etc.) by the user.
  318. if (window)
  319. updateSettings(curMode.settings);
  320. width = curMode.width;
  321. height = curMode.height;
  322. settings = curMode.settings;
  323. }
  324. bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
  325. {
  326. if (!window)
  327. return false;
  328. WindowSettings newsettings = curMode.settings;
  329. newsettings.fullscreen = fullscreen;
  330. newsettings.fstype = fstype;
  331. Uint32 sdlflags = 0;
  332. if (fullscreen)
  333. {
  334. if (fstype == FULLSCREEN_TYPE_DESKTOP)
  335. sdlflags = SDL_WINDOW_FULLSCREEN_DESKTOP;
  336. else
  337. {
  338. sdlflags = SDL_WINDOW_FULLSCREEN;
  339. SDL_DisplayMode mode = {};
  340. mode.w = curMode.width;
  341. mode.h = curMode.height;
  342. SDL_GetClosestDisplayMode(SDL_GetWindowDisplayIndex(window), &mode, &mode);
  343. SDL_SetWindowDisplayMode(window, &mode);
  344. }
  345. }
  346. if (SDL_SetWindowFullscreen(window, sdlflags) == 0)
  347. {
  348. SDL_GL_MakeCurrent(window, context);
  349. updateSettings(newsettings);
  350. // Update the viewport size now instead of waiting for event polling.
  351. graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
  352. if (gfx != nullptr)
  353. {
  354. int width = curMode.width;
  355. int height = curMode.height;
  356. // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
  357. #if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
  358. SDL_GL_GetDrawableSize(window, &width, &height);
  359. #endif
  360. gfx->setViewportSize(width, height);
  361. }
  362. return true;
  363. }
  364. return false;
  365. }
  366. bool Window::setFullscreen(bool fullscreen)
  367. {
  368. return setFullscreen(fullscreen, curMode.settings.fstype);
  369. }
  370. int Window::getDisplayCount() const
  371. {
  372. return SDL_GetNumVideoDisplays();
  373. }
  374. typedef Window::WindowSize WindowSize;
  375. std::vector<WindowSize> Window::getFullscreenSizes(int displayindex) const
  376. {
  377. std::vector<WindowSize> sizes;
  378. SDL_DisplayMode mode = {};
  379. std::vector<WindowSize>::const_iterator it;
  380. for (int i = 0; i < SDL_GetNumDisplayModes(displayindex); i++)
  381. {
  382. SDL_GetDisplayMode(displayindex, i, &mode);
  383. // SDL2's display mode list has multiple entries for modes of the same
  384. // size with different bits per pixel, so we need to filter those out.
  385. bool alreadyhassize = false;
  386. for (it = sizes.begin(); it != sizes.end(); ++it)
  387. {
  388. if (it->width == mode.w && it->height == mode.h)
  389. {
  390. alreadyhassize = true;
  391. break;
  392. }
  393. }
  394. if (!alreadyhassize)
  395. {
  396. WindowSize w = {mode.w, mode.h};
  397. sizes.push_back(w);
  398. }
  399. }
  400. return sizes;
  401. }
  402. void Window::getDesktopDimensions(int displayindex, int &width, int &height) const
  403. {
  404. if (displayindex >= 0 && displayindex < getDisplayCount())
  405. {
  406. SDL_DisplayMode mode = {};
  407. SDL_GetDesktopDisplayMode(displayindex, &mode);
  408. width = mode.w;
  409. height = mode.h;
  410. }
  411. else
  412. {
  413. width = 0;
  414. height = 0;
  415. }
  416. }
  417. bool Window::isCreated() const
  418. {
  419. return created;
  420. }
  421. void Window::setWindowTitle(const std::string &title)
  422. {
  423. windowTitle = title;
  424. if (window)
  425. SDL_SetWindowTitle(window, title.c_str());
  426. }
  427. const std::string &Window::getWindowTitle() const
  428. {
  429. return windowTitle;
  430. }
  431. bool Window::setIcon(love::image::ImageData *imgd)
  432. {
  433. if (!imgd)
  434. return false;
  435. imgd->retain();
  436. if (curMode.icon)
  437. curMode.icon->release();
  438. curMode.icon = imgd;
  439. if (!window)
  440. return false;
  441. Uint32 rmask, gmask, bmask, amask;
  442. #ifdef LOVE_BIG_ENDIAN
  443. rmask = 0xFF000000;
  444. gmask = 0x00FF0000;
  445. bmask = 0x0000FF00;
  446. amask = 0x000000FF;
  447. #else
  448. rmask = 0x000000FF;
  449. gmask = 0x0000FF00;
  450. bmask = 0x00FF0000;
  451. amask = 0xFF000000;
  452. #endif
  453. int w = imgd->getWidth();
  454. int h = imgd->getHeight();
  455. int pitch = imgd->getWidth() * 4;
  456. SDL_Surface *sdlicon = 0;
  457. {
  458. // We don't want another thread modifying the ImageData mid-copy.
  459. love::thread::Lock lock(imgd->getMutex());
  460. sdlicon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
  461. }
  462. if (!sdlicon)
  463. return false;
  464. SDL_SetWindowIcon(window, sdlicon);
  465. SDL_FreeSurface(sdlicon);
  466. return true;
  467. }
  468. love::image::ImageData *Window::getIcon()
  469. {
  470. return curMode.icon;
  471. }
  472. void Window::swapBuffers()
  473. {
  474. SDL_GL_SwapWindow(window);
  475. }
  476. bool Window::hasFocus() const
  477. {
  478. return (window && SDL_GetKeyboardFocus() == window);
  479. }
  480. bool Window::hasMouseFocus() const
  481. {
  482. return (window && SDL_GetMouseFocus() == window);
  483. }
  484. bool Window::isVisible() const
  485. {
  486. return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_SHOWN) != 0;
  487. }
  488. void Window::setMouseVisible(bool visible)
  489. {
  490. SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
  491. }
  492. bool Window::getMouseVisible() const
  493. {
  494. return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
  495. }
  496. void Window::setMouseGrab(bool grab)
  497. {
  498. mouseGrabbed = grab;
  499. if (window)
  500. SDL_SetWindowGrab(window, (SDL_bool) grab);
  501. }
  502. bool Window::isMouseGrabbed() const
  503. {
  504. if (window)
  505. return (bool) SDL_GetWindowGrab(window);
  506. else
  507. return mouseGrabbed;
  508. }
  509. double Window::getPixelScale() const
  510. {
  511. double scale = 1.0;
  512. // FIXME: disabled in Linux for runtime SDL 2.0.0 compatibility.
  513. #if SDL_VERSION_ATLEAST(2,0,1) && !defined(LOVE_LINUX)
  514. if (window)
  515. {
  516. int wheight;
  517. SDL_GetWindowSize(window, nullptr, &wheight);
  518. int dheight = wheight;
  519. SDL_GL_GetDrawableSize(window, nullptr, &dheight);
  520. scale = (double) dheight / wheight;
  521. }
  522. #endif
  523. return scale;
  524. }
  525. const void *Window::getHandle() const
  526. {
  527. return window;
  528. }
  529. void Window::showMessageBox(MessageBoxType type, const char *title, const char *message)
  530. {
  531. SDL_MessageBoxFlags sdlflags;
  532. switch (type)
  533. {
  534. case MESSAGEBOX_ERROR:
  535. sdlflags = SDL_MESSAGEBOX_ERROR;
  536. break;
  537. case MESSAGEBOX_WARNING:
  538. sdlflags = SDL_MESSAGEBOX_WARNING;
  539. break;
  540. case MESSAGEBOX_INFO:
  541. default:
  542. sdlflags = SDL_MESSAGEBOX_INFORMATION;
  543. break;
  544. }
  545. SDL_ShowSimpleMessageBox(sdlflags, title, message, window);
  546. }
  547. love::window::Window *Window::createSingleton()
  548. {
  549. if (!singleton)
  550. singleton = new Window();
  551. else
  552. singleton->retain();
  553. return singleton;
  554. }
  555. love::window::Window *Window::getSingleton()
  556. {
  557. return singleton;
  558. }
  559. const char *Window::getName() const
  560. {
  561. return "love.window.sdl";
  562. }
  563. } // sdl
  564. } // window
  565. } // love