llwindow.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /**
  2. * @file llwindow.cpp
  3. * @brief Basic graphical window class
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #if LL_LINUX
  34. #include "llwindowsdl.h"
  35. #elif LL_WINDOWS
  36. #include "llwindowwin32.h"
  37. #elif LL_DARWIN
  38. #include "llwindowmacosx.h"
  39. #endif
  40. #include "llkeyboard.h"
  41. // Globals
  42. LLWindow* gWindowp = NULL;
  43. LLSplashScreen* gSplashScreenp = NULL;
  44. bool gDebugClicks = false;
  45. bool gDebugWindowProc = false;
  46. bool gHiDPISupport = false;
  47. const std::string gURLProtocolWhitelist[] =
  48. {
  49. "file:",
  50. "http:",
  51. "https:",
  52. "ftp:",
  53. "data:"
  54. };
  55. const S32 gURLProtocolWhitelistCount = LL_ARRAY_SIZE(gURLProtocolWhitelist);
  56. // Static instance for default callbacks
  57. LLWindowCallbacks LLWindow::sDefaultCallbacks;
  58. // Helper function
  59. S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
  60. {
  61. // Properly hide the splash screen when displaying the message box
  62. bool was_visible = LLSplashScreen::isVisible();
  63. if (was_visible)
  64. {
  65. LLSplashScreen::hide();
  66. }
  67. S32 result = 0;
  68. #if LL_DARWIN
  69. result = OSMessageBoxMacOSX(text, caption, type);
  70. #elif LL_LINUX
  71. result = OSMessageBoxSDL(text, caption, type);
  72. #elif LL_WINDOWS
  73. result = OSMessageBoxWin32(text, caption, type);
  74. #else
  75. # error("OSMessageBox not implemented for this platform !")
  76. #endif
  77. if (was_visible)
  78. {
  79. LLSplashScreen::show();
  80. }
  81. return result;
  82. }
  83. ///////////////////////////////////////////////////////////////////////////////
  84. // LLWindow class
  85. ///////////////////////////////////////////////////////////////////////////////
  86. //static
  87. void LLWindow::createWindow(const std::string& title, S32 x, S32 y,
  88. U32 width, U32 height, U32 flags, bool fullscreen,
  89. bool disable_vsync, U32 fsaa_samples)
  90. {
  91. llassert_always(gWindowp == NULL);
  92. #if LL_LINUX
  93. gWindowp = new LLWindowSDL(title, x, y, width, height, flags,
  94. fullscreen, disable_vsync, fsaa_samples);
  95. #elif LL_WINDOWS
  96. gWindowp = new LLWindowWin32(title, x, y, width, height, flags, fullscreen,
  97. disable_vsync, fsaa_samples);
  98. #elif LL_DARWIN
  99. gWindowp = new LLWindowMacOSX(title, flags, fullscreen, disable_vsync,
  100. fsaa_samples);
  101. #endif
  102. if (!gWindowp->isValid())
  103. {
  104. llwarns << "Invalid window. Destroying it." << llendl;
  105. delete gWindowp;
  106. gWindowp = NULL;
  107. }
  108. }
  109. //static
  110. void LLWindow::destroyWindow()
  111. {
  112. if (gWindowp)
  113. {
  114. gWindowp->close();
  115. delete gWindowp;
  116. gWindowp = NULL;
  117. }
  118. }
  119. LLWindow::LLWindow(bool fullscreen, U32 flags)
  120. : mCallbacks(&sDefaultCallbacks),
  121. mPostQuit(true),
  122. mFullscreen(fullscreen),
  123. mFullscreenWidth(0),
  124. mFullscreenHeight(0),
  125. mFullscreenBits(0),
  126. mFullscreenRefresh(0),
  127. mOverrideAspectRatio(0.f),
  128. mCurrentGamma(1.f),
  129. mSupportedResolutions(NULL),
  130. mNumSupportedResolutions(0),
  131. mCurrentCursor(UI_CURSOR_ARROW),
  132. mCursorFrozen(false),
  133. mCursorHidden(false),
  134. #if LL_DARWIN
  135. mNextCursor(UI_CURSOR_ARROW),
  136. #endif
  137. mBusyCount(0),
  138. mIsMouseClipping(false),
  139. mSwapMethod(SWAP_METHOD_UNDEFINED),
  140. mHideCursorPermanent(false),
  141. mFlags(flags),
  142. mHighSurrogate(0)
  143. {
  144. }
  145. void LLWindow::decBusyCount()
  146. {
  147. if (mBusyCount > 0)
  148. {
  149. --mBusyCount;
  150. }
  151. }
  152. void LLWindow::setCallbacks(LLWindowCallbacks* callbacks)
  153. {
  154. mCallbacks = callbacks;
  155. if (gKeyboardp)
  156. {
  157. gKeyboardp->setCallbacks(callbacks);
  158. }
  159. }
  160. //static
  161. std::vector<std::string> LLWindow::getDynamicFallbackFontList()
  162. {
  163. #if LL_WINDOWS
  164. return LLWindowWin32::getDynamicFallbackFontList();
  165. #elif LL_DARWIN
  166. return LLWindowMacOSX::getDynamicFallbackFontList();
  167. #elif LL_LINUX
  168. return LLWindowSDL::getDynamicFallbackFontList();
  169. #else
  170. return std::vector<std::string>();
  171. #endif
  172. }
  173. #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
  174. #define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400)
  175. #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
  176. void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask)
  177. {
  178. LL_DEBUGS("Window") << "UTF16 key = " << std::hex << (U32)utf16 << std::dec
  179. << " - mask = " << mask << LL_ENDL;
  180. // Note that we could discard unpaired surrogates, but I am following the
  181. // Unicode Consortium's recommendation here, that is, to preserve those
  182. // unpaired surrogates in UTF-32 values. _To_preserve_ means to pass to the
  183. // callback in our context.
  184. if (mHighSurrogate == 0)
  185. {
  186. if (UTF16_IS_HIGH_SURROGATE(utf16))
  187. {
  188. mHighSurrogate = utf16;
  189. }
  190. else
  191. {
  192. mCallbacks->handleUnicodeChar(utf16, mask);
  193. }
  194. }
  195. else if (UTF16_IS_LOW_SURROGATE(utf16))
  196. {
  197. // A legal surrogate pair.
  198. mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate,
  199. utf16),
  200. mask);
  201. mHighSurrogate = 0;
  202. }
  203. else if (UTF16_IS_HIGH_SURROGATE(utf16))
  204. {
  205. // Two consecutive high surrogates.
  206. mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
  207. mHighSurrogate = utf16;
  208. }
  209. else
  210. {
  211. // A non-low-surrogate preceeded by a high surrogate.
  212. mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
  213. mHighSurrogate = 0;
  214. mCallbacks->handleUnicodeChar(utf16, mask);
  215. }
  216. }
  217. ///////////////////////////////////////////////////////////////////////////////
  218. // LLSplashScreen class
  219. ///////////////////////////////////////////////////////////////////////////////
  220. //static
  221. bool LLSplashScreen::isVisible()
  222. {
  223. return gSplashScreenp != NULL;
  224. }
  225. //static
  226. void LLSplashScreen::show()
  227. {
  228. if (!gSplashScreenp)
  229. {
  230. #if LL_DARWIN
  231. gSplashScreenp = new LLSplashScreenMacOSX;
  232. #elif LL_LINUX
  233. gSplashScreenp = new LLSplashScreenSDL;
  234. #elif LL_WINDOWS
  235. gSplashScreenp = new LLSplashScreenWin32;
  236. #endif
  237. gSplashScreenp->showImpl();
  238. }
  239. }
  240. //static
  241. void LLSplashScreen::update(const std::string& str)
  242. {
  243. LLSplashScreen::show();
  244. if (gSplashScreenp)
  245. {
  246. gSplashScreenp->updateImpl(str);
  247. }
  248. }
  249. //static
  250. void LLSplashScreen::hide()
  251. {
  252. if (gSplashScreenp)
  253. {
  254. gSplashScreenp->hideImpl();
  255. }
  256. delete gSplashScreenp;
  257. gSplashScreenp = NULL;
  258. }
  259. ///////////////////////////////////////////////////////////////////////////////
  260. // LLWindowCallbacks class
  261. ///////////////////////////////////////////////////////////////////////////////
  262. //virtual
  263. bool LLWindowCallbacks::handleTranslatedKeyDown(KEY, MASK, bool)
  264. {
  265. return false;
  266. }
  267. //virtual
  268. bool LLWindowCallbacks::handleTranslatedKeyUp(KEY, MASK)
  269. {
  270. return false;
  271. }
  272. //virtual
  273. void LLWindowCallbacks::handleScanKey(KEY, bool, bool, bool)
  274. {
  275. }
  276. //virtual
  277. bool LLWindowCallbacks::handleUnicodeChar(llwchar, MASK)
  278. {
  279. return false;
  280. }
  281. //virtual
  282. bool LLWindowCallbacks::handleMouseDown(LLWindow*, const LLCoordGL, MASK)
  283. {
  284. return false;
  285. }
  286. //virtual
  287. bool LLWindowCallbacks::handleMouseUp(LLWindow*, const LLCoordGL, MASK)
  288. {
  289. return false;
  290. }
  291. //virtual
  292. void LLWindowCallbacks::handleMouseLeave(LLWindow*)
  293. {
  294. return;
  295. }
  296. //virtual
  297. bool LLWindowCallbacks::handleCloseRequest(LLWindow*)
  298. {
  299. // Allow the window to close
  300. return true;
  301. }
  302. //virtual
  303. void LLWindowCallbacks::handleQuit(LLWindow* window)
  304. {
  305. if (window == gWindowp)
  306. {
  307. LLWindow::destroyWindow();
  308. }
  309. else
  310. {
  311. llerrs << "Invalid window !" << llendl;
  312. }
  313. }
  314. //virtual
  315. bool LLWindowCallbacks::handleRightMouseDown(LLWindow*, const LLCoordGL, MASK)
  316. {
  317. return false;
  318. }
  319. //virtual
  320. bool LLWindowCallbacks::handleRightMouseUp(LLWindow*, const LLCoordGL, MASK)
  321. {
  322. return false;
  323. }
  324. //virtual
  325. bool LLWindowCallbacks::handleMiddleMouseDown(LLWindow*, const LLCoordGL, MASK)
  326. {
  327. return false;
  328. }
  329. //virtual
  330. bool LLWindowCallbacks::handleMiddleMouseUp(LLWindow*, const LLCoordGL, MASK)
  331. {
  332. return false;
  333. }
  334. //virtual
  335. bool LLWindowCallbacks::handleActivate(LLWindow*, bool)
  336. {
  337. return false;
  338. }
  339. //virtual
  340. bool LLWindowCallbacks::handleActivateApp(LLWindow*, bool)
  341. {
  342. return false;
  343. }
  344. //virtual
  345. void LLWindowCallbacks::handleMouseMove(LLWindow*, const LLCoordGL, MASK)
  346. {
  347. }
  348. #if LL_DARWIN
  349. //virtual
  350. void LLWindowCallbacks::handleMouseDragged(LLWindow*, const LLCoordGL, MASK)
  351. {
  352. }
  353. #endif
  354. //virtual
  355. void LLWindowCallbacks::handleScrollWheel(LLWindow*, S32)
  356. {
  357. }
  358. //virtual
  359. void LLWindowCallbacks::handleResize(LLWindow*, S32, S32)
  360. {
  361. }
  362. //virtual
  363. void LLWindowCallbacks::handleFocus(LLWindow*)
  364. {
  365. }
  366. //virtual
  367. void LLWindowCallbacks::handleFocusLost(LLWindow*)
  368. {
  369. }
  370. //virtual
  371. void LLWindowCallbacks::handleMenuSelect(LLWindow*, S32)
  372. {
  373. }
  374. //virtual
  375. bool LLWindowCallbacks::handlePaint(LLWindow*, S32, S32, S32, S32)
  376. {
  377. return false;
  378. }
  379. //virtual
  380. bool LLWindowCallbacks::handleDoubleClick(LLWindow*, const LLCoordGL, MASK)
  381. {
  382. return false;
  383. }
  384. //virtual
  385. void LLWindowCallbacks::handleWindowBlock(LLWindow*)
  386. {
  387. }
  388. //virtual
  389. void LLWindowCallbacks::handleWindowUnblock(LLWindow*)
  390. {
  391. }
  392. //virtual
  393. void LLWindowCallbacks::handleDataCopy(LLWindow*, S32, void*)
  394. {
  395. }
  396. //virtual
  397. bool LLWindowCallbacks::handleTimerEvent(LLWindow*)
  398. {
  399. return false;
  400. }
  401. //virtual
  402. bool LLWindowCallbacks::handleDeviceChange(LLWindow*)
  403. {
  404. return false;
  405. }
  406. //virtual
  407. bool LLWindowCallbacks::handleDPIChanged(LLWindow*, F32, S32, S32)
  408. {
  409. return false;
  410. }
  411. //virtual
  412. bool LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow*)
  413. {
  414. return false;
  415. }