sdlWindowMgr.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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 "gfx/gfxDevice.h"
  24. #include "core/util/journal/process.h"
  25. #include "core/strings/unicode.h"
  26. #include "SDL.h"
  27. // ------------------------------------------------------------------------
  28. void sdl_CloseSplashWindow(void* hinst);
  29. #ifdef TORQUE_SDL
  30. PlatformWindowManager * CreatePlatformWindowManager()
  31. {
  32. return new PlatformWindowManagerSDL();
  33. }
  34. #endif
  35. // ------------------------------------------------------------------------
  36. PlatformWindowManagerSDL::PlatformWindowManagerSDL()
  37. {
  38. // Register in the process list.
  39. mOnProcessSignalSlot.setDelegate( this, &PlatformWindowManagerSDL::_process );
  40. Process::notify( mOnProcessSignalSlot, PROCESS_INPUT_ORDER );
  41. // Init our list of allocated windows.
  42. mWindowListHead = NULL;
  43. // By default, we have no parent window.
  44. mParentWindow = NULL;
  45. mCurtainWindow = NULL;
  46. mDisplayWindow = true;
  47. mOffscreenRender = false;
  48. mInputState = KeyboardInputState::NONE;
  49. buildMonitorsList();
  50. }
  51. PlatformWindowManagerSDL::~PlatformWindowManagerSDL()
  52. {
  53. // Kill all our windows first.
  54. while(mWindowListHead)
  55. // The destructors update the list, so this works just fine.
  56. delete mWindowListHead;
  57. }
  58. RectI PlatformWindowManagerSDL::getPrimaryDesktopArea()
  59. {
  60. // TODO SDL
  61. AssertFatal(0, "");
  62. return RectI(0,0,0,0);
  63. }
  64. Point2I PlatformWindowManagerSDL::getDesktopResolution()
  65. {
  66. SDL_DisplayMode mode;
  67. SDL_GetDesktopDisplayMode(0, &mode);
  68. // Return Resolution
  69. return Point2I(mode.w, mode.h);
  70. }
  71. S32 PlatformWindowManagerSDL::getDesktopBitDepth()
  72. {
  73. // Return Bits per Pixel
  74. SDL_DisplayMode mode;
  75. SDL_GetDesktopDisplayMode(0, &mode);
  76. int bbp;
  77. unsigned int r,g,b,a;
  78. SDL_PixelFormatEnumToMasks(mode.format, &bbp, &r, &g, &b, &a);
  79. return bbp;
  80. }
  81. void PlatformWindowManagerSDL::buildMonitorsList()
  82. {
  83. // TODO SDL
  84. }
  85. S32 PlatformWindowManagerSDL::findFirstMatchingMonitor(const char* name)
  86. {
  87. /// TODO SDL
  88. AssertFatal(0, "");
  89. return 0;
  90. }
  91. U32 PlatformWindowManagerSDL::getMonitorCount()
  92. {
  93. // TODO SDL
  94. AssertFatal(0, "");
  95. return 1;
  96. }
  97. const char* PlatformWindowManagerSDL::getMonitorName(U32 index)
  98. {
  99. // TODO SDL
  100. AssertFatal(0, "");
  101. return "Monitor";
  102. }
  103. RectI PlatformWindowManagerSDL::getMonitorRect(U32 index)
  104. {
  105. // TODO SDL
  106. AssertFatal(0, "");
  107. return RectI(0, 0, 0,0 );
  108. }
  109. void PlatformWindowManagerSDL::getMonitorRegions(Vector<RectI> &regions)
  110. {
  111. // TODO SDL
  112. AssertFatal(0, "");
  113. }
  114. void PlatformWindowManagerSDL::getWindows(VectorPtr<PlatformWindow*> &windows)
  115. {
  116. PlatformWindowSDL *win = mWindowListHead;
  117. while(win)
  118. {
  119. windows.push_back(win);
  120. win = win->mNextWindow;
  121. }
  122. }
  123. PlatformWindow *PlatformWindowManagerSDL::createWindow(GFXDevice *device, const GFXVideoMode &mode)
  124. {
  125. // Do the allocation.
  126. PlatformWindowSDL *window = new PlatformWindowSDL();
  127. U32 windowFlags = /*SDL_WINDOW_SHOWN |*/ SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
  128. if(GFX->getAdapterType() == OpenGL)
  129. windowFlags |= SDL_WINDOW_OPENGL;
  130. window->mWindowHandle = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, mode.resolution.x, mode.resolution.y, windowFlags );
  131. window->mWindowId = SDL_GetWindowID( window->mWindowHandle );
  132. window->mOwningManager = this;
  133. mWindowMap[ window->mWindowId ] = window;
  134. if(device)
  135. {
  136. window->mDevice = device;
  137. window->mTarget = device->allocWindowTarget(window);
  138. AssertISV(window->mTarget, "PlatformWindowManagerSDL::createWindow - failed to get a window target back from the device.");
  139. }
  140. else
  141. {
  142. Con::warnf("PlatformWindowManagerSDL::createWindow - created a window with no device!");
  143. }
  144. linkWindow(window);
  145. return window;
  146. }
  147. void PlatformWindowManagerSDL::setParentWindow(void* newParent)
  148. {
  149. }
  150. void* PlatformWindowManagerSDL::getParentWindow()
  151. {
  152. return NULL;
  153. }
  154. void PlatformWindowManagerSDL::_process()
  155. {
  156. SDL_Event evt;
  157. while( SDL_PollEvent(&evt) )
  158. {
  159. switch(evt.type)
  160. {
  161. case SDL_QUIT:
  162. {
  163. PlatformWindowSDL *window = static_cast<PlatformWindowSDL*>( getFirstWindow() );
  164. if(window)
  165. window->appEvent.trigger( window->getWindowId(), WindowClose );
  166. break;
  167. }
  168. case SDL_KEYDOWN:
  169. case SDL_KEYUP:
  170. {
  171. PlatformWindowSDL *window = mWindowMap[evt.key.windowID];
  172. if(window)
  173. window->_processSDLEvent(evt);
  174. break;
  175. }
  176. case SDL_MOUSEWHEEL:
  177. {
  178. PlatformWindowSDL *window = mWindowMap[evt.wheel.windowID];
  179. if (window)
  180. window->_processSDLEvent(evt);
  181. break;
  182. }
  183. case SDL_MOUSEMOTION:
  184. {
  185. PlatformWindowSDL *window = mWindowMap[evt.motion.windowID];
  186. if(window)
  187. window->_processSDLEvent(evt);
  188. break;
  189. }
  190. case SDL_MOUSEBUTTONDOWN:
  191. case SDL_MOUSEBUTTONUP:
  192. {
  193. PlatformWindowSDL *window = mWindowMap[evt.button.windowID];
  194. if(window)
  195. window->_processSDLEvent(evt);
  196. break;
  197. }
  198. case SDL_TEXTINPUT:
  199. {
  200. PlatformWindowSDL *window = mWindowMap[evt.text.windowID];
  201. if(window)
  202. window->_processSDLEvent(evt);
  203. break;
  204. }
  205. case SDL_WINDOWEVENT:
  206. {
  207. PlatformWindowSDL *window = mWindowMap[evt.window.windowID];
  208. if(window)
  209. window->_processSDLEvent(evt);
  210. break;
  211. }
  212. default:
  213. {
  214. //Con::printf("Event: %d", evt.type);
  215. }
  216. }
  217. }
  218. // After the event loop is processed, we can now see if we have to notify
  219. // SDL that we want text based events. This fixes a bug where text based
  220. // events would be generated while key presses would still be happening.
  221. // See KeyboardInputState for further documentation.
  222. if (mInputState != KeyboardInputState::NONE)
  223. {
  224. // Update text mode toggling.
  225. if (mInputState == KeyboardInputState::TEXT_INPUT)
  226. SDL_StartTextInput();
  227. else
  228. SDL_StopTextInput();
  229. // Done until we need to update it again.
  230. mInputState = KeyboardInputState::NONE;
  231. }
  232. }
  233. PlatformWindow * PlatformWindowManagerSDL::getWindowById( WindowId id )
  234. {
  235. // Walk the list and find the matching id, if any.
  236. PlatformWindowSDL *win = mWindowListHead;
  237. while(win)
  238. {
  239. if(win->getWindowId() == id)
  240. return win;
  241. win = win->mNextWindow;
  242. }
  243. return NULL;
  244. }
  245. PlatformWindow * PlatformWindowManagerSDL::getFirstWindow()
  246. {
  247. return mWindowListHead != NULL ? mWindowListHead : NULL;
  248. }
  249. PlatformWindow* PlatformWindowManagerSDL::getFocusedWindow()
  250. {
  251. PlatformWindowSDL* window = mWindowListHead;
  252. while( window )
  253. {
  254. if( window->isFocused() )
  255. return window;
  256. window = window->mNextWindow;
  257. }
  258. return NULL;
  259. }
  260. void PlatformWindowManagerSDL::linkWindow( PlatformWindowSDL *w )
  261. {
  262. w->mNextWindow = mWindowListHead;
  263. mWindowListHead = w;
  264. }
  265. void PlatformWindowManagerSDL::unlinkWindow( PlatformWindowSDL *w )
  266. {
  267. PlatformWindowSDL **walk = &mWindowListHead;
  268. while(*walk)
  269. {
  270. if(*walk != w)
  271. {
  272. // Advance to next item in list.
  273. walk = &(*walk)->mNextWindow;
  274. continue;
  275. }
  276. // Got a match - unlink and return.
  277. *walk = (*walk)->mNextWindow;
  278. return;
  279. }
  280. }
  281. void PlatformWindowManagerSDL::_processCmdLineArgs( const S32 argc, const char **argv )
  282. {
  283. // TODO SDL
  284. }
  285. void PlatformWindowManagerSDL::lowerCurtain()
  286. {
  287. if(mCurtainWindow)
  288. return;
  289. // TODO SDL
  290. }
  291. void PlatformWindowManagerSDL::raiseCurtain()
  292. {
  293. if(!mCurtainWindow)
  294. return;
  295. // TODO SDL
  296. }
  297. void PlatformWindowManagerSDL::updateSDLTextInputState(KeyboardInputState state)
  298. {
  299. // Force update state. This will respond at the end of the event loop.
  300. mInputState = state;
  301. }
  302. void Platform::openFolder(const char* path )
  303. {
  304. AssertFatal(0, "Not Implemented");
  305. }
  306. void Platform::openFile(const char* path )
  307. {
  308. AssertFatal(0, "Not Implemented");
  309. }
  310. //------------------------------------------------------------------------------
  311. namespace GL
  312. {
  313. void gglPerformBinds();
  314. }
  315. void InitWindowingSystem()
  316. {
  317. }
  318. AFTER_MODULE_INIT(gfx)
  319. {
  320. int res = SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_NOPARACHUTE );
  321. AssertFatal(res != -1, "SDL init error");
  322. // By default, SDL enables text input. We disable it on initialization, and
  323. // we will enable it whenever the time is right.
  324. SDL_StopTextInput();
  325. }