sdlWindowMgr.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "windowManager/sdl/sdlWindowMgr.h"
  23. #include "platformSDL/sdlInputManager.h"
  24. #include "platform/platformVolume.h"
  25. #include "core/util/path.h"
  26. #include "gfx/gfxDevice.h"
  27. #include "core/util/journal/process.h"
  28. #include "core/strings/unicode.h"
  29. #include "gfx/bitmap/gBitmap.h"
  30. #include "SDL.h"
  31. // ------------------------------------------------------------------------
  32. void sdl_CloseSplashWindow(void* hinst);
  33. #ifdef TORQUE_SDL
  34. #ifdef TORQUE_SECURE_VFS
  35. PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo()
  36. {
  37. }
  38. PlatformWindowManagerSDL::DragAndDropFSInfo::DragAndDropFSInfo(String rootName, Torque::FS::FileSystemRef fileSystem) : mRootName(rootName), mDragAndDropFS(fileSystem)
  39. {
  40. if (!Torque::FS::Mount(rootName, fileSystem))
  41. {
  42. Con::errorf("Could not mount drag and drop FS!");
  43. }
  44. }
  45. PlatformWindowManagerSDL::DragAndDropFSInfo::~DragAndDropFSInfo()
  46. {
  47. }
  48. #endif
  49. PlatformWindowManager * CreatePlatformWindowManager()
  50. {
  51. return new PlatformWindowManagerSDL();
  52. }
  53. #endif
  54. // ------------------------------------------------------------------------
  55. PlatformWindowManagerSDL::PlatformWindowManagerSDL()
  56. {
  57. // Register in the process list.
  58. mOnProcessSignalSlot.setDelegate( this, &PlatformWindowManagerSDL::_process );
  59. Process::notify( mOnProcessSignalSlot, PROCESS_INPUT_ORDER );
  60. // Init our list of allocated windows.
  61. mWindowListHead = NULL;
  62. // By default, we have no parent window.
  63. mParentWindow = NULL;
  64. mCurtainWindow = NULL;
  65. mDisplayWindow = true;
  66. mOffscreenRender = false;
  67. mInputState = KeyboardInputState::NONE;
  68. }
  69. PlatformWindowManagerSDL::~PlatformWindowManagerSDL()
  70. {
  71. // Unmount all drag and drop FS mounts
  72. for (auto iteration = mActiveDragAndDropFSByPath.begin(); iteration != mActiveDragAndDropFSByPath.end(); ++iteration)
  73. {
  74. auto&& mapping = *iteration;
  75. Torque::FS::Unmount(mapping.value.mDragAndDropFS);
  76. }
  77. mActiveDragAndDropByRoot.clear();
  78. mActiveDragAndDropFSByPath.clear();
  79. // Kill all our windows first.
  80. while(mWindowListHead)
  81. // The destructors update the list, so this works just fine.
  82. delete mWindowListHead;
  83. }
  84. RectI PlatformWindowManagerSDL::getPrimaryDesktopArea()
  85. {
  86. // Primary is monitor 0
  87. return getMonitorRect(0);
  88. }
  89. Point2I PlatformWindowManagerSDL::getDesktopResolution()
  90. {
  91. SDL_DisplayMode mode;
  92. SDL_GetDesktopDisplayMode(0, &mode);
  93. // Return Resolution
  94. return Point2I(mode.w, mode.h);
  95. }
  96. S32 PlatformWindowManagerSDL::getDesktopBitDepth()
  97. {
  98. // Return Bits per Pixel
  99. SDL_DisplayMode mode;
  100. SDL_GetDesktopDisplayMode(0, &mode);
  101. int bbp;
  102. unsigned int r,g,b,a;
  103. SDL_PixelFormatEnumToMasks(mode.format, &bbp, &r, &g, &b, &a);
  104. return bbp;
  105. }
  106. S32 PlatformWindowManagerSDL::findFirstMatchingMonitor(const char* name)
  107. {
  108. S32 count = SDL_GetNumVideoDisplays();
  109. for (U32 index = 0; index < count; ++index)
  110. {
  111. if (dStrstr(name, SDL_GetDisplayName(index)) == name)
  112. return index;
  113. }
  114. return 0;
  115. }
  116. U32 PlatformWindowManagerSDL::getMonitorCount()
  117. {
  118. S32 monitorCount = SDL_GetNumVideoDisplays();
  119. if (monitorCount < 0)
  120. {
  121. Con::errorf("SDL_GetNumVideoDisplays() failed: %s", SDL_GetError());
  122. monitorCount = 0;
  123. }
  124. return (U32)monitorCount;
  125. }
  126. const char* PlatformWindowManagerSDL::getMonitorName(U32 index)
  127. {
  128. const char* monitorName = SDL_GetDisplayName(index);
  129. if (monitorName == NULL)
  130. Con::errorf("SDL_GetDisplayName() failed: %s", SDL_GetError());
  131. return monitorName;
  132. }
  133. RectI PlatformWindowManagerSDL::getMonitorRect(U32 index)
  134. {
  135. SDL_Rect sdlRect;
  136. if (0 != SDL_GetDisplayBounds(index, &sdlRect))
  137. {
  138. Con::errorf("SDL_GetDisplayBounds() failed: %s", SDL_GetError());
  139. return RectI(0, 0, 0, 0);
  140. }
  141. return RectI(sdlRect.x, sdlRect.y, sdlRect.w, sdlRect.h);
  142. }
  143. RectI PlatformWindowManagerSDL::getMonitorUsableRect(U32 index)
  144. {
  145. SDL_Rect sdlRect;
  146. if (0 != SDL_GetDisplayUsableBounds(index, &sdlRect))
  147. {
  148. Con::errorf("SDL_GetDisplayUsableBounds() failed: %s", SDL_GetError());
  149. return RectI(0, 0, 0, 0);
  150. }
  151. return RectI(sdlRect.x, sdlRect.y, sdlRect.w, sdlRect.h);
  152. }
  153. U32 PlatformWindowManagerSDL::getMonitorModeCount(U32 monitorIndex)
  154. {
  155. S32 modeCount = SDL_GetNumDisplayModes(monitorIndex);
  156. if (modeCount < 0)
  157. {
  158. Con::errorf("SDL_GetNumDisplayModes(%d) failed: %s", monitorIndex, SDL_GetError());
  159. modeCount = 0;
  160. }
  161. return (U32)modeCount;
  162. }
  163. const String PlatformWindowManagerSDL::getMonitorMode(U32 monitorIndex, U32 modeIndex)
  164. {
  165. SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
  166. if (SDL_GetDisplayMode(monitorIndex, modeIndex, &mode) != 0)
  167. {
  168. Con::errorf("SDL_GetDisplayMode(%d, %d) failed: %s", monitorIndex, modeIndex, SDL_GetError());
  169. return String::EmptyString;
  170. }
  171. GFXVideoMode vm;
  172. vm.resolution.set(mode.w, mode.h);
  173. vm.refreshRate = mode.refresh_rate;
  174. vm.bitDepth = 32;
  175. vm.antialiasLevel = 0;
  176. vm.fullScreen = false;
  177. vm.wideScreen = false;
  178. return vm.toString();
  179. }
  180. const String PlatformWindowManagerSDL::getMonitorDesktopMode(U32 monitorIndex)
  181. {
  182. SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
  183. if (SDL_GetDesktopDisplayMode(monitorIndex, &mode) != 0)
  184. {
  185. Con::errorf("SDL_GetDesktopDisplayMode(%d) failed: %s", monitorIndex, SDL_GetError());
  186. return String::EmptyString;
  187. }
  188. GFXVideoMode vm;
  189. vm.resolution.set(mode.w, mode.h);
  190. vm.refreshRate = mode.refresh_rate;
  191. int bbp;
  192. unsigned int r, g, b, a;
  193. SDL_PixelFormatEnumToMasks(mode.format, &bbp, &r, &g, &b, &a);
  194. vm.bitDepth = bbp;
  195. vm.antialiasLevel = 0;
  196. vm.fullScreen = false;
  197. vm.wideScreen = ((mode.w / 16) * 9) == mode.h;
  198. return vm.toString();
  199. }
  200. void PlatformWindowManagerSDL::getMonitorRegions(Vector<RectI> &regions)
  201. {
  202. SDL_Rect sdlRect;
  203. S32 monitorCount = SDL_GetNumVideoDisplays();
  204. for (S32 index = 0; index < monitorCount; ++index)
  205. {
  206. if (0 == SDL_GetDisplayBounds(index, &sdlRect))
  207. regions.push_back(RectI(sdlRect.x, sdlRect.y, sdlRect.w, sdlRect.h));
  208. }
  209. }
  210. void PlatformWindowManagerSDL::getWindows(VectorPtr<PlatformWindow*> &windows)
  211. {
  212. PlatformWindowSDL *win = mWindowListHead;
  213. while(win)
  214. {
  215. windows.push_back(win);
  216. win = win->mNextWindow;
  217. }
  218. }
  219. PlatformWindow *PlatformWindowManagerSDL::createWindow(GFXDevice *device, const GFXVideoMode &mode)
  220. {
  221. // Do the allocation.
  222. PlatformWindowSDL *window = new PlatformWindowSDL();
  223. U32 windowFlags = /*SDL_WINDOW_SHOWN |*/ SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
  224. if(GFX->getAdapterType() == OpenGL)
  225. windowFlags |= SDL_WINDOW_OPENGL;
  226. window->mWindowHandle = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, mode.resolution.x, mode.resolution.y, windowFlags );
  227. window->mWindowId = SDL_GetWindowID( window->mWindowHandle );
  228. window->mOwningManager = this;
  229. mWindowMap[ window->mWindowId ] = window;
  230. //Now, fetch our window icon, if any
  231. Torque::Path iconPath = Torque::Path(Con::getVariable( "$Core::windowIcon" ));
  232. if (iconPath.getExtension() == String("bmp"))
  233. {
  234. Con::errorf("Unable to use bmp format images for the window icon. Please use a different format.");
  235. }
  236. else
  237. {
  238. Resource<GBitmap> img = GBitmap::load(iconPath);
  239. if (img != NULL)
  240. {
  241. U32 pitch;
  242. U32 width = img->getWidth();
  243. bool hasAlpha = img->getHasTransparency();
  244. U32 depth;
  245. if (hasAlpha)
  246. {
  247. pitch = 4 * width;
  248. depth = 32;
  249. }
  250. else
  251. {
  252. pitch = 3 * width;
  253. depth = 24;
  254. }
  255. Uint32 rmask, gmask, bmask, amask;
  256. if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
  257. {
  258. S32 shift = hasAlpha ? 8 : 0;
  259. rmask = 0xff000000 >> shift;
  260. gmask = 0x00ff0000 >> shift;
  261. bmask = 0x0000ff00 >> shift;
  262. amask = 0x000000ff >> shift;
  263. }
  264. else
  265. {
  266. rmask = 0x000000ff;
  267. gmask = 0x0000ff00;
  268. bmask = 0x00ff0000;
  269. amask = hasAlpha ? 0xff000000 : 0;
  270. }
  271. SDL_Surface* iconSurface = SDL_CreateRGBSurfaceFrom(img->getAddress(0, 0), img->getWidth(), img->getHeight(), depth, pitch, rmask, gmask, bmask, amask);
  272. SDL_SetWindowIcon(window->mWindowHandle, iconSurface);
  273. SDL_FreeSurface(iconSurface);
  274. }
  275. }
  276. if(device)
  277. {
  278. window->mDevice = device;
  279. window->mTarget = device->allocWindowTarget(window);
  280. AssertISV(window->mTarget, "PlatformWindowManagerSDL::createWindow - failed to get a window target back from the device.");
  281. }
  282. else
  283. {
  284. Con::warnf("PlatformWindowManagerSDL::createWindow - created a window with no device!");
  285. }
  286. //Set it up for drag-n-drop events
  287. #ifdef TORQUE_TOOLS
  288. SDL_EventState(SDL_DROPBEGIN, SDL_ENABLE);
  289. SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
  290. SDL_EventState(SDL_DROPCOMPLETE, SDL_ENABLE);
  291. #endif
  292. linkWindow(window);
  293. SDL_SetWindowMinimumSize(window->mWindowHandle, Con::getIntVariable("$Video::minimumXResolution", 1024),
  294. Con::getIntVariable("$Video::minimumYResolution", 720));
  295. return window;
  296. }
  297. void PlatformWindowManagerSDL::setParentWindow(void* newParent)
  298. {
  299. }
  300. void* PlatformWindowManagerSDL::getParentWindow()
  301. {
  302. return NULL;
  303. }
  304. void PlatformWindowManagerSDL::_process()
  305. {
  306. SDL_Event evt;
  307. while( SDL_PollEvent(&evt) )
  308. {
  309. if (evt.type >= SDL_JOYAXISMOTION && evt.type <= SDL_CONTROLLERDEVICEREMAPPED)
  310. {
  311. SDLInputManager* mgr = static_cast<SDLInputManager*>(Input::getManager());
  312. if (mgr)
  313. mgr->processEvent(evt);
  314. continue;
  315. }
  316. switch(evt.type)
  317. {
  318. case SDL_QUIT:
  319. {
  320. PlatformWindowSDL *window = static_cast<PlatformWindowSDL*>( getFirstWindow() );
  321. if(window)
  322. window->appEvent.trigger( window->getWindowId(), WindowClose );
  323. break;
  324. }
  325. case SDL_KEYDOWN:
  326. case SDL_KEYUP:
  327. {
  328. PlatformWindowSDL *window = mWindowMap[evt.key.windowID];
  329. if(window)
  330. window->_processSDLEvent(evt);
  331. break;
  332. }
  333. case SDL_MOUSEWHEEL:
  334. {
  335. PlatformWindowSDL *window = mWindowMap[evt.wheel.windowID];
  336. if (window)
  337. window->_processSDLEvent(evt);
  338. break;
  339. }
  340. case SDL_MOUSEMOTION:
  341. {
  342. PlatformWindowSDL *window = mWindowMap[evt.motion.windowID];
  343. if(window)
  344. window->_processSDLEvent(evt);
  345. break;
  346. }
  347. case SDL_MOUSEBUTTONDOWN:
  348. case SDL_MOUSEBUTTONUP:
  349. {
  350. PlatformWindowSDL *window = mWindowMap[evt.button.windowID];
  351. if(window)
  352. window->_processSDLEvent(evt);
  353. break;
  354. }
  355. case SDL_TEXTINPUT:
  356. {
  357. PlatformWindowSDL *window = mWindowMap[evt.text.windowID];
  358. if(window)
  359. window->_processSDLEvent(evt);
  360. break;
  361. }
  362. case SDL_WINDOWEVENT:
  363. {
  364. PlatformWindowSDL *window = mWindowMap[evt.window.windowID];
  365. if(window)
  366. window->_processSDLEvent(evt);
  367. break;
  368. }
  369. case(SDL_DROPBEGIN):
  370. {
  371. if (!Con::isFunction("onDropBegin"))
  372. break;
  373. Con::executef("onDropBegin");
  374. }
  375. case (SDL_DROPFILE):
  376. {
  377. // In case if dropped file
  378. if (!Con::isFunction("onDropFile"))
  379. break;
  380. char* fileName = evt.drop.file;
  381. if (!Platform::isDirectory(fileName) && !Platform::isFile(fileName))
  382. break;
  383. #ifdef TORQUE_SECURE_VFS
  384. // Determine what the directory is so we can mount it
  385. Torque::Path targetDirectory = Torque::Path(fileName);
  386. // If we're dropping a file, strip off file information - otherwise if a directory mount it directly
  387. if (Platform::isFile(fileName))
  388. {
  389. targetDirectory.setExtension("");
  390. targetDirectory.setFileName("");
  391. }
  392. const String directoryName = targetDirectory.getDirectory(targetDirectory.getDirectoryCount() - 1);
  393. auto dropFSMount = mActiveDragAndDropFSByPath.find(targetDirectory);
  394. if (dropFSMount == mActiveDragAndDropFSByPath.end())
  395. {
  396. Torque::FS::FileSystemRef newMount = Platform::FS::createNativeFS(targetDirectory.getFullPath());
  397. // Search for an unused root in case we have duplicate names
  398. U32 rootCounter = 1;
  399. String chosenRootName = directoryName;
  400. auto search = mActiveDragAndDropByRoot.find(chosenRootName);
  401. while (search != mActiveDragAndDropByRoot.end())
  402. {
  403. char buffer[32];
  404. dSprintf(buffer, sizeof(buffer), "%u", rootCounter);
  405. chosenRootName = directoryName + buffer;
  406. search = mActiveDragAndDropByRoot.find(chosenRootName);
  407. }
  408. mActiveDragAndDropFSByPath[targetDirectory] = DragAndDropFSInfo(directoryName, newMount);
  409. mActiveDragAndDropFSByPath[chosenRootName] = mActiveDragAndDropFSByPath[targetDirectory];
  410. }
  411. DragAndDropFSInfo& filesystemInformation = mActiveDragAndDropFSByPath[targetDirectory];
  412. // Load source file information
  413. Torque::Path sourceFile = fileName;
  414. // Build a reference to the file in VFS
  415. Torque::Path targetFile;
  416. targetFile.setRoot(filesystemInformation.mRootName);
  417. targetFile.setPath("/");
  418. // Only copy file & extension information if we're dropping a file
  419. if (Platform::isFile(fileName))
  420. {
  421. targetFile.setFileName(sourceFile.getFileName());
  422. targetFile.setExtension(sourceFile.getExtension());
  423. }
  424. Con::executef("onDropFile", StringTable->insert(targetFile.getFullPath()));
  425. #else
  426. Con::executef("onDropFile", StringTable->insert(fileName));
  427. #endif
  428. SDL_free(fileName); // Free dropped_filedir memory
  429. break;
  430. }
  431. case(SDL_DROPCOMPLETE):
  432. {
  433. if (Con::isFunction("onDropEnd"))
  434. Con::executef("onDropEnd");
  435. break;
  436. }
  437. default:
  438. {
  439. #ifdef TORQUE_DEBUG
  440. Con::warnf("Unhandled SDL input event: 0x%04x", evt.type);
  441. #endif
  442. }
  443. }
  444. }
  445. // After the event loop is processed, we can now see if we have to notify
  446. // SDL that we want text based events. This fixes a bug where text based
  447. // events would be generated while key presses would still be happening.
  448. // See KeyboardInputState for further documentation.
  449. if (mInputState != KeyboardInputState::NONE)
  450. {
  451. // Update text mode toggling.
  452. if (mInputState == KeyboardInputState::TEXT_INPUT)
  453. SDL_StartTextInput();
  454. else
  455. SDL_StopTextInput();
  456. // Done until we need to update it again.
  457. mInputState = KeyboardInputState::NONE;
  458. }
  459. }
  460. PlatformWindow * PlatformWindowManagerSDL::getWindowById( WindowId id )
  461. {
  462. // Walk the list and find the matching id, if any.
  463. PlatformWindowSDL *win = mWindowListHead;
  464. while(win)
  465. {
  466. if(win->getWindowId() == id)
  467. return win;
  468. win = win->mNextWindow;
  469. }
  470. return NULL;
  471. }
  472. PlatformWindow * PlatformWindowManagerSDL::getFirstWindow()
  473. {
  474. return mWindowListHead != NULL ? mWindowListHead : NULL;
  475. }
  476. PlatformWindow* PlatformWindowManagerSDL::getFocusedWindow()
  477. {
  478. PlatformWindowSDL* window = mWindowListHead;
  479. while( window )
  480. {
  481. if( window->isFocused() )
  482. return window;
  483. window = window->mNextWindow;
  484. }
  485. return NULL;
  486. }
  487. void PlatformWindowManagerSDL::linkWindow( PlatformWindowSDL *w )
  488. {
  489. w->mNextWindow = mWindowListHead;
  490. mWindowListHead = w;
  491. }
  492. void PlatformWindowManagerSDL::unlinkWindow( PlatformWindowSDL *w )
  493. {
  494. PlatformWindowSDL **walk = &mWindowListHead;
  495. while(*walk)
  496. {
  497. if(*walk != w)
  498. {
  499. // Advance to next item in list.
  500. walk = &(*walk)->mNextWindow;
  501. continue;
  502. }
  503. // Got a match - unlink and return.
  504. *walk = (*walk)->mNextWindow;
  505. return;
  506. }
  507. }
  508. void PlatformWindowManagerSDL::_processCmdLineArgs( const S32 argc, const char **argv )
  509. {
  510. // TODO SDL
  511. }
  512. void PlatformWindowManagerSDL::lowerCurtain()
  513. {
  514. if(mCurtainWindow)
  515. return;
  516. // TODO SDL
  517. }
  518. void PlatformWindowManagerSDL::raiseCurtain()
  519. {
  520. if(!mCurtainWindow)
  521. return;
  522. // TODO SDL
  523. }
  524. void PlatformWindowManagerSDL::updateSDLTextInputState(KeyboardInputState state)
  525. {
  526. // Force update state. This will respond at the end of the event loop.
  527. mInputState = state;
  528. }
  529. void Platform::openFolder(const char* path )
  530. {
  531. AssertFatal(0, "Not Implemented");
  532. }
  533. void Platform::openFile(const char* path )
  534. {
  535. AssertFatal(0, "Not Implemented");
  536. }
  537. //------------------------------------------------------------------------------
  538. namespace GL
  539. {
  540. void gglPerformBinds();
  541. }
  542. void InitWindowingSystem()
  543. {
  544. }
  545. AFTER_MODULE_INIT(gfx)
  546. {
  547. #if !defined(TORQUE_DEDICATED)
  548. int res = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_NOPARACHUTE);
  549. AssertFatal(res != -1, avar("SDL error:%s", SDL_GetError()));
  550. // By default, SDL enables text input. We disable it on initialization, and
  551. // we will enable it whenever the time is right.
  552. SDL_StopTextInput();
  553. #endif
  554. }