testWinMgr.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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 "console/console.h"
  23. #include "windowManager/platformWindowMgr.h"
  24. #include "unit/test.h"
  25. #include "core/util/tVector.h"
  26. #include "gfx/gfxStructs.h"
  27. #include "core/util/journal/process.h"
  28. #include "gfx/gfxInit.h"
  29. using namespace UnitTesting;
  30. CreateUnitTest(TestWinMgrQueries, "WindowManager/BasicQueries")
  31. {
  32. void run()
  33. {
  34. PlatformWindowManager *pwm = CreatePlatformWindowManager();
  35. // Check out the primary desktop area...
  36. RectI primary = pwm->getPrimaryDesktopArea();
  37. Con::printf("Primary desktop area is (%d,%d) (%d,%d)",
  38. primary.point.x, primary.point.y, primary.extent.x, primary.extent.y);
  39. test(primary.isValidRect(), "Got some sort of invalid rect from the window manager!");
  40. // Now try to get info about all the monitors.
  41. Vector<RectI> monitorRects;
  42. pwm->getMonitorRegions(monitorRects);
  43. test(monitorRects.size() > 0, "Should get at least one monitor rect back from getMonitorRegions!");
  44. // This test is here just to detect overflow/runaway situations. -- BJG
  45. test(monitorRects.size() < 64, "Either something's wrong, or you have a lot of monitors...");
  46. for(S32 i=0; i<monitorRects.size(); i++)
  47. {
  48. Con::printf(" Monitor #%d region is (%d,%d) (%d,%d)", i,
  49. monitorRects[i].point.x, monitorRects[i].point.y, monitorRects[i].extent.x, monitorRects[i].extent.y);
  50. test(monitorRects[i].isValidRect(), "Got an invalid rect for this monitor - no good.");
  51. }
  52. }
  53. };
  54. CreateInteractiveTest(TestWinMgrCreate, "WindowManager/CreateAWindow")
  55. {
  56. void handleMouseEvent(WindowId,U32,S32 x,S32 y, bool isRelative)
  57. {
  58. Con::printf("Mouse at %d, %d %s", x, y, isRelative ? "(relative)" : "(absolute)");
  59. }
  60. void handleAppEvent(WindowId, S32 event)
  61. {
  62. if(event == WindowClose)
  63. Process::requestShutdown();
  64. }
  65. void run()
  66. {
  67. PlatformWindowManager *pwm = CreatePlatformWindowManager();
  68. GFXVideoMode vm;
  69. vm.resolution.x = 800;
  70. vm.resolution.y = 600;
  71. PlatformWindow *pw = pwm->createWindow(NULL, vm);
  72. test(pw, "Didn't get a window back from the window manager, no good.");
  73. if(!pw)
  74. return;
  75. // Setup our events.
  76. pw->mouseEvent.notify(this, &TestWinMgrCreate::handleMouseEvent);
  77. pw->appEvent.notify(this, &TestWinMgrCreate::handleAppEvent);
  78. // And, go on our way.
  79. while(Process::processEvents())
  80. ;
  81. SAFE_DELETE(pw);
  82. }
  83. };
  84. CreateInteractiveTest(TestWinMgrGFXInit, "WindowManager/SimpleGFX")
  85. {
  86. PlatformWindow *mWindow;
  87. GFXDevice *mDevice;
  88. void handleDrawEvent(WindowId id)
  89. {
  90. mDevice->beginScene();
  91. mDevice->setActiveRenderTarget(mWindow->getGFXTarget());
  92. mDevice->clear( GFXClearZBuffer | GFXClearStencil | GFXClearTarget, ColorI( 255, 255, 0 ), 1.0f, 0 );
  93. mDevice->endScene();
  94. mWindow->getGFXTarget()->present();
  95. }
  96. void forceDraw()
  97. {
  98. handleDrawEvent(0);
  99. }
  100. void handleAppEvent(WindowId, S32 event)
  101. {
  102. if(event == WindowClose)
  103. Process::requestShutdown();
  104. }
  105. void run()
  106. {
  107. PlatformWindowManager *pwm = CreatePlatformWindowManager();
  108. // Create a device.
  109. GFXAdapter a;
  110. a.mType = Direct3D9;
  111. a.mIndex = 0;
  112. mDevice = GFXInit::createDevice(&a);
  113. test(mDevice, "Unable to create d3d9 device #0.");
  114. // Initialize the window...
  115. GFXVideoMode vm;
  116. vm.resolution.x = 400;
  117. vm.resolution.y = 400;
  118. mWindow = pwm->createWindow(mDevice, vm);
  119. test(mWindow, "Didn't get a window back from the window manager, no good.");
  120. if(!mWindow)
  121. return;
  122. // Setup our events.
  123. mWindow->displayEvent.notify(this, &TestWinMgrGFXInit::handleDrawEvent);
  124. mWindow->idleEvent.notify(this, &TestWinMgrGFXInit::forceDraw);
  125. mWindow->appEvent.notify(this, &TestWinMgrGFXInit::handleAppEvent);
  126. // And, go on our way.
  127. while(Process::processEvents())
  128. ;
  129. mWindow->displayEvent.remove(this, &TestWinMgrGFXInit::handleDrawEvent);
  130. mWindow->idleEvent.remove(this, &TestWinMgrGFXInit::forceDraw);
  131. mWindow->appEvent.remove(this, &TestWinMgrGFXInit::handleAppEvent);
  132. // Clean up!
  133. SAFE_DELETE(mDevice);
  134. SAFE_DELETE(mWindow);
  135. }
  136. };
  137. CreateInteractiveTest(TestWinMgrGFXInitMultiWindow, "WindowManager/GFXMultiWindow")
  138. {
  139. enum {
  140. NumWindows = 4,
  141. };
  142. PlatformWindowManager *mWindowManager;
  143. PlatformWindow *mWindows[NumWindows];
  144. GFXDevice *mDevice;
  145. void handleDrawEvent(WindowId id)
  146. {
  147. // Which window are we getting this event on?
  148. PlatformWindow *w = mWindowManager->getWindowById(id);
  149. mDevice->beginScene();
  150. mDevice->setActiveRenderTarget(w->getGFXTarget());
  151. // Vary clear color by window to discern which window is which.
  152. mDevice->clear( GFXClearTarget,
  153. ColorI( 255 - (id * 50), 255, id * 100 ), 1.0f, 0 );
  154. mDevice->endScene();
  155. // Call swap on the window's render target.
  156. ((GFXWindowTarget*)w->getGFXTarget())->present();
  157. }
  158. void handleAppEvent(WindowId, S32 event)
  159. {
  160. if(event == WindowClose)
  161. Process::requestShutdown();
  162. }
  163. void handleIdleEvent()
  164. {
  165. for(S32 i=0; i<NumWindows; i++)
  166. handleDrawEvent(mWindows[i]->getWindowId());
  167. }
  168. void run()
  169. {
  170. mWindowManager = CreatePlatformWindowManager();
  171. // Create a device.
  172. GFXAdapter a;
  173. a.mType = Direct3D9;
  174. a.mIndex = 0;
  175. mDevice = GFXInit::createDevice(&a);
  176. test(mDevice, "Unable to create d3d9 device #0.");
  177. // Initialize the windows...
  178. GFXVideoMode vm;
  179. vm.resolution.x = 400;
  180. vm.resolution.y = 400;
  181. for(S32 i=0; i<NumWindows; i++)
  182. {
  183. mWindows[i] = mWindowManager->createWindow(mDevice, vm);
  184. test(mWindows[i], "Didn't get a window back from the window manager, no good.");
  185. if(!mWindows[i])
  186. continue;
  187. // Setup our events.
  188. mWindows[i]->displayEvent.notify(this, &TestWinMgrGFXInitMultiWindow::handleDrawEvent);
  189. mWindows[i]->appEvent.notify(this, &TestWinMgrGFXInitMultiWindow::handleAppEvent);
  190. mWindows[i]->idleEvent.notify(this, &TestWinMgrGFXInitMultiWindow::handleIdleEvent);
  191. }
  192. // And, go on our way.
  193. while(Process::processEvents())
  194. ;
  195. SAFE_DELETE(mWindowManager);
  196. SAFE_DELETE(mDevice);
  197. }
  198. };
  199. CreateInteractiveTest(TestJournaledMultiWindowGFX, "WindowManager/GFXJournaledMultiWindow")
  200. {
  201. enum {
  202. NumWindows = 2,
  203. };
  204. PlatformWindowManager *mWindowManager;
  205. PlatformWindow *mWindows[NumWindows];
  206. GFXDevice *mDevice;
  207. S32 mNumDraws;
  208. S32 mNumResize;
  209. void drawToWindow(PlatformWindow *win)
  210. {
  211. // Do some simple checks to make sure we draw the same number of times
  212. // on both runs.
  213. if(Journal::IsPlaying())
  214. mNumDraws--;
  215. else
  216. mNumDraws++;
  217. // Render!
  218. mDevice->beginScene();
  219. mDevice->setActiveRenderTarget(win->getGFXTarget());
  220. // Vary clear color by window to discern which window is which.
  221. static S32 timeVariance = 0;
  222. mDevice->clear( GFXClearTarget,
  223. ColorI( 0xFF - (++timeVariance * 5), 0xFF, win->getWindowId() * 0x0F ), 1.0f, 0 );
  224. mDevice->endScene();
  225. // Call swap on the window's render target.
  226. win->getGFXTarget()->present();
  227. }
  228. void handleDrawEvent(WindowId id)
  229. {
  230. // Which window are we getting this event on?
  231. PlatformWindow *w = mWindowManager->getWindowById(id);
  232. drawToWindow(w);
  233. }
  234. void handleAppEvent(WindowId, S32 event)
  235. {
  236. if(event == WindowClose)
  237. Process::requestShutdown();
  238. }
  239. void handleIdleEvent()
  240. {
  241. for(S32 i=0; i<NumWindows; i++)
  242. drawToWindow(mWindows[i]);
  243. }
  244. void handleResizeEvent(WindowId id, S32 width, S32 height)
  245. {
  246. // Do some simple checks to make sure we resize the same number of times
  247. // on both runs.
  248. if(Journal::IsPlaying())
  249. {
  250. // If we're playing back, APPLY the resize event...
  251. mWindowManager->getWindowById(id)->setSize(Point2I(width, height));
  252. mNumResize--;
  253. }
  254. else
  255. {
  256. // If we're not playing back, do nothing except note it.
  257. mNumResize++;
  258. }
  259. // Which window are we getting this event on?
  260. PlatformWindow *w = mWindowManager->getWindowById(id);
  261. drawToWindow(w);
  262. }
  263. /// The mainloop of our app - we'll run this twice, once to create
  264. /// a journal and again to play it back.
  265. void mainLoop()
  266. {
  267. mWindowManager = CreatePlatformWindowManager();
  268. // Create a device.
  269. GFXAdapter a;
  270. a.mType = Direct3D9;
  271. a.mIndex = 0;
  272. mDevice = GFXInit::createDevice(&a);
  273. test(mDevice, "Unable to create ogl device #0.");
  274. // Initialize the windows...
  275. GFXVideoMode vm;
  276. vm.resolution.x = 400;
  277. vm.resolution.y = 400;
  278. for(S32 i=0; i<NumWindows; i++)
  279. {
  280. mWindows[i] = mWindowManager->createWindow(mDevice, vm);
  281. test(mWindows[i], "Didn't get a window back from the window manager, no good.");
  282. if(!mWindows[i])
  283. continue;
  284. // Setup our events.
  285. mWindows[i]->displayEvent.notify(this, &TestJournaledMultiWindowGFX::handleDrawEvent);
  286. mWindows[i]->appEvent.notify(this, &TestJournaledMultiWindowGFX::handleAppEvent);
  287. mWindows[i]->resizeEvent.notify(this, &TestJournaledMultiWindowGFX::handleResizeEvent);
  288. // Only subscribe to the first idle event.
  289. if(i==0)
  290. mWindows[i]->idleEvent.notify(this, &TestJournaledMultiWindowGFX::handleIdleEvent);
  291. }
  292. // And, go on our way.
  293. while(Process::processEvents())
  294. ;
  295. // Finally, clean up.
  296. for(S32 i=0; i<NumWindows; i++)
  297. SAFE_DELETE(mWindows[i]);
  298. SAFE_DELETE(mDevice);
  299. SAFE_DELETE(mWindowManager);
  300. }
  301. void run()
  302. {
  303. return;
  304. // CodeReview: this should be deleted or enabled.
  305. #if 0
  306. mNumDraws = 0;
  307. mNumResize = 0;
  308. // Record a run of the main loop.
  309. Journal::Record("multiwindow.jrn");
  310. mainLoop();
  311. Journal::Stop();
  312. test(mNumDraws > 0, "No draws occurred!");
  313. test(mNumResize > 0, "No resizes occurred!");
  314. // And play it back.
  315. Journal::Play("multiwindow.jrn");
  316. mainLoop();
  317. Journal::Stop();
  318. test(mNumDraws == 0, "Failed to play journal back with same number of draws.");
  319. test(mNumResize == 0, "Failed to play journal back with same number of resizes.");
  320. #endif
  321. }
  322. };
  323. CreateInteractiveTest(GFXTestFullscreenToggle, "GFX/TestFullscreenToggle")
  324. {
  325. enum Constants
  326. {
  327. NumWindows = 1,
  328. };
  329. PlatformWindowManager *mWindowManager;
  330. PlatformWindow *mWindows[NumWindows];
  331. GFXDevice *mDevice;
  332. void drawToWindow(PlatformWindow *win)
  333. {
  334. // Render!
  335. mDevice->beginScene();
  336. mDevice->setActiveRenderTarget(win->getGFXTarget());
  337. // Vary clear color by window to discern which window is which.
  338. static S32 timeVariance = 0;
  339. mDevice->clear( GFXClearZBuffer | GFXClearStencil | GFXClearTarget,
  340. ColorI( 0xFF - (++timeVariance * 5), 0xFF, win->getWindowId() * 0x40 ), 1.0f, 0 );
  341. mDevice->endScene();
  342. // Call swap on the window's render target.
  343. win->getGFXTarget()->present();
  344. }
  345. void handleDrawEvent(WindowId id)
  346. {
  347. // Which window are we getting this event on?
  348. PlatformWindow *w = mWindowManager->getWindowById(id);
  349. drawToWindow(w);
  350. }
  351. void handleAppEvent(WindowId, S32 event)
  352. {
  353. if(event == WindowClose)
  354. Process::requestShutdown();
  355. }
  356. void handleIdleEvent()
  357. {
  358. // Redraw everything.
  359. for(S32 i=0; i<NumWindows; i++)
  360. drawToWindow(mWindows[i]);
  361. // Don't monopolize the CPU.
  362. Platform::sleep(10);
  363. }
  364. void handleButtonEvent(WindowId did,U32 modifier,U32 action,U16 button)
  365. {
  366. // Only respond to button down
  367. if(action != IA_MAKE)
  368. return;
  369. // Get the window...
  370. PlatformWindow *win = mWindowManager->getWindowById(did);
  371. GFXVideoMode winVm = win->getVideoMode();
  372. // If the window is not full screen, make it full screen 800x600x32
  373. if(winVm.fullScreen == false)
  374. {
  375. winVm.fullScreen = true;
  376. winVm.resolution.set(800,600);
  377. }
  378. else
  379. {
  380. // If the window is full screen, then bump it to 400x400x32
  381. winVm.fullScreen = false;
  382. winVm.resolution.set(400,400);
  383. }
  384. win->setVideoMode(winVm);
  385. }
  386. void run()
  387. {
  388. mWindowManager = CreatePlatformWindowManager();
  389. // Create a device.
  390. GFXAdapter a;
  391. a.mType = Direct3D9;
  392. a.mIndex = 0;
  393. mDevice = GFXInit::createDevice(&a);
  394. test(mDevice, "Unable to create d3d9 device #0.");
  395. // Initialize the windows...
  396. GFXVideoMode vm;
  397. vm.resolution.x = 400;
  398. vm.resolution.y = 400;
  399. for(S32 i=0; i<NumWindows; i++)
  400. {
  401. mWindows[i] = mWindowManager->createWindow(mDevice, vm);
  402. test(mWindows[i], "Didn't get a window back from the window manager, no good.");
  403. if(!mWindows[i])
  404. continue;
  405. // Setup our events.
  406. mWindows[i]->appEvent.notify(this, &GFXTestFullscreenToggle::handleAppEvent);
  407. mWindows[i]->buttonEvent.notify(this, &GFXTestFullscreenToggle::handleButtonEvent);
  408. mWindows[i]->displayEvent.notify(this, &GFXTestFullscreenToggle::handleDrawEvent);
  409. // Only subscribe to the first idle event.
  410. if(i==0)
  411. mWindows[i]->idleEvent.notify(this, &GFXTestFullscreenToggle::handleIdleEvent);
  412. }
  413. // And, go on our way.
  414. while(Process::processEvents())
  415. ;
  416. // Finally, clean up.
  417. for(S32 i=0; i<NumWindows; i++)
  418. SAFE_DELETE(mWindows[i]);
  419. mDevice->preDestroy();
  420. SAFE_DELETE(mDevice);
  421. SAFE_DELETE(mWindowManager);
  422. }
  423. };