llwindow.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:9k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llwindow.cpp
  3.  * @brief Basic graphical window class
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, 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. #include "llwindowheadless.h"
  34. #if LL_MESA_HEADLESS
  35. #include "llwindowmesaheadless.h"
  36. #elif LL_SDL
  37. #include "llwindowsdl.h"
  38. #elif LL_WINDOWS
  39. #include "llwindowwin32.h"
  40. #elif LL_DARWIN
  41. #include "llwindowmacosx.h"
  42. #endif
  43. #include "llerror.h"
  44. #include "llkeyboard.h"
  45. #include "linked_lists.h"
  46. #include "llwindowcallbacks.h"
  47. //
  48. // Globals
  49. //
  50. LLSplashScreen *gSplashScreenp = NULL;
  51. BOOL gDebugClicks = FALSE;
  52. BOOL gDebugWindowProc = FALSE;
  53. const S32 gURLProtocolWhitelistCount = 3;
  54. const std::string gURLProtocolWhitelist[] = { "file:", "http:", "https:" };
  55. // CP: added a handler list - this is what's used to open the protocol and is based on registry entry
  56. //    only meaningful difference currently is that file: protocols are opened using http:
  57. //    since no protocol handler exists in registry for file:
  58. //     Important - these lists should match - protocol to handler
  59. const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" };
  60. S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
  61. {
  62. // Properly hide the splash screen when displaying the message box
  63. BOOL was_visible = FALSE;
  64. if (LLSplashScreen::isVisible())
  65. {
  66. was_visible = TRUE;
  67. LLSplashScreen::hide();
  68. }
  69. S32 result = 0;
  70. #if LL_MESA_HEADLESS // !!! *FIX: (???)
  71. llwarns << "OSMessageBox: " << text << llendl;
  72. return OSBTN_OK;
  73. #elif LL_WINDOWS
  74. result = OSMessageBoxWin32(text, caption, type);
  75. #elif LL_DARWIN
  76. result = OSMessageBoxMacOSX(text, caption, type);
  77. #elif LL_SDL
  78. result = OSMessageBoxSDL(text, caption, type);
  79. #else
  80. #error("OSMessageBox not implemented for this platform!")
  81. #endif
  82. if (was_visible)
  83. {
  84. LLSplashScreen::show();
  85. }
  86. return result;
  87. }
  88. //
  89. // LLWindow
  90. //
  91. LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags)
  92. : mCallbacks(callbacks),
  93.   mPostQuit(TRUE),
  94.   mFullscreen(fullscreen),
  95.   mFullscreenWidth(0),
  96.   mFullscreenHeight(0),
  97.   mFullscreenBits(0),
  98.   mFullscreenRefresh(0),
  99.   mSupportedResolutions(NULL),
  100.   mNumSupportedResolutions(0),
  101.   mCurrentCursor(UI_CURSOR_ARROW),
  102.   mCursorHidden(FALSE),
  103.   mBusyCount(0),
  104.   mIsMouseClipping(FALSE),
  105.   mSwapMethod(SWAP_METHOD_UNDEFINED),
  106.   mHideCursorPermanent(FALSE),
  107.   mFlags(flags),
  108.   mHighSurrogate(0)
  109. { }
  110. LLWindow::~LLWindow()
  111. { }
  112. //virtual
  113. BOOL LLWindow::isValid()
  114. {
  115. return TRUE;
  116. }
  117. //virtual
  118. BOOL LLWindow::canDelete()
  119. {
  120. return TRUE;
  121. }
  122. // virtual
  123. void LLWindow::incBusyCount()
  124. {
  125. ++mBusyCount;
  126. }
  127. // virtual
  128. void LLWindow::decBusyCount()
  129. {
  130. if (mBusyCount > 0)
  131. {
  132. --mBusyCount;
  133. }
  134. }
  135. //virtual
  136. void LLWindow::resetBusyCount()
  137. {
  138. mBusyCount = 0;
  139. }
  140. //virtual
  141. S32 LLWindow::getBusyCount() const
  142. {
  143. return mBusyCount;
  144. }
  145. //virtual
  146. ECursorType LLWindow::getCursor() const
  147. {
  148. return mCurrentCursor;
  149. }
  150. //virtual
  151. BOOL LLWindow::dialogColorPicker(F32 *r, F32 *g, F32 *b)
  152. {
  153. return FALSE;
  154. }
  155. void *LLWindow::getMediaWindow()
  156. {
  157. // Default to returning the platform window.
  158. return getPlatformWindow();
  159. }
  160. //virtual
  161. void LLWindow::processMiscNativeEvents()
  162. {
  163. // do nothing unless subclassed
  164. }
  165. //virtual
  166. BOOL LLWindow::isPrimaryTextAvailable()
  167. {
  168. return FALSE; // no
  169. }
  170. //virtual
  171. BOOL LLWindow::pasteTextFromPrimary(LLWString &dst)
  172. {
  173. return FALSE; // fail
  174. }
  175. // virtual
  176. BOOL LLWindow::copyTextToPrimary(const LLWString &src)
  177. {
  178. return FALSE; // fail
  179. }
  180. // static
  181. std::vector<std::string> LLWindow::getDynamicFallbackFontList()
  182. {
  183. #if LL_WINDOWS
  184. return LLWindowWin32::getDynamicFallbackFontList();
  185. #elif LL_DARWIN
  186. return LLWindowMacOSX::getDynamicFallbackFontList();
  187. #elif LL_SDL
  188. return LLWindowSDL::getDynamicFallbackFontList();
  189. #else
  190. return std::vector<std::string>();
  191. #endif
  192. }
  193. #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
  194. #define UTF16_IS_LOW_SURROGATE(U)  ((U16)((U) - 0xDC00) < 0x0400)
  195. #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
  196. void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask)
  197. {
  198. // Note that we could discard unpaired surrogates, but I'm
  199. // following the Unicode Consortium's recommendation here;
  200. // that is, to preserve those unpaired surrogates in UTF-32
  201. // values.  _To_preserve_ means to pass to the callback in our
  202. // context.
  203. if (mHighSurrogate == 0)
  204. {
  205. if (UTF16_IS_HIGH_SURROGATE(utf16))
  206. {
  207. mHighSurrogate = utf16;
  208. }
  209. else
  210. {
  211. mCallbacks->handleUnicodeChar(utf16, mask);
  212. }
  213. }
  214. else
  215. {
  216. if (UTF16_IS_LOW_SURROGATE(utf16))
  217. {
  218. /* A legal surrogate pair.  */
  219. mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate, utf16), mask);
  220. mHighSurrogate = 0;
  221. }
  222. else if (UTF16_IS_HIGH_SURROGATE(utf16))
  223. {
  224. /* Two consecutive high surrogates.  */
  225. mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
  226. mHighSurrogate = utf16;
  227. }
  228. else
  229. {
  230. /* A non-low-surrogate preceeded by a high surrogate. */
  231. mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
  232. mHighSurrogate = 0;
  233. mCallbacks->handleUnicodeChar(utf16, mask);
  234. }
  235. }
  236. }
  237. //
  238. // LLSplashScreen
  239. //
  240. // static
  241. bool LLSplashScreen::isVisible()
  242. {
  243. return gSplashScreenp ? true: false;
  244. }
  245. // static
  246. LLSplashScreen *LLSplashScreen::create()
  247. {
  248. #if LL_MESA_HEADLESS || LL_SDL  // !!! *FIX: (???)
  249. return 0;
  250. #elif LL_WINDOWS
  251. return new LLSplashScreenWin32;
  252. #elif LL_DARWIN
  253. return new LLSplashScreenMacOSX;
  254. #else
  255. #error("LLSplashScreen not implemented on this platform!")
  256. #endif
  257. }
  258. //static
  259. void LLSplashScreen::show()
  260. {
  261. if (!gSplashScreenp)
  262. {
  263. #if LL_WINDOWS && !LL_MESA_HEADLESS
  264. gSplashScreenp = new LLSplashScreenWin32;
  265. #elif LL_DARWIN
  266. gSplashScreenp = new LLSplashScreenMacOSX;
  267. #endif
  268. if (gSplashScreenp)
  269. {
  270. gSplashScreenp->showImpl();
  271. }
  272. }
  273. }
  274. //static
  275. void LLSplashScreen::update(const std::string& str)
  276. {
  277. LLSplashScreen::show();
  278. if (gSplashScreenp)
  279. {
  280. gSplashScreenp->updateImpl(str);
  281. }
  282. }
  283. //static
  284. void LLSplashScreen::hide()
  285. {
  286. if (gSplashScreenp)
  287. {
  288. gSplashScreenp->hideImpl();
  289. }
  290. delete gSplashScreenp;
  291. gSplashScreenp = NULL;
  292. }
  293. //
  294. // LLWindowManager
  295. //
  296. // TODO: replace with std::set
  297. static std::set<LLWindow*> sWindowList;
  298. LLWindow* LLWindowManager::createWindow(
  299. LLWindowCallbacks* callbacks,
  300. const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
  301. BOOL fullscreen, 
  302. BOOL clearBg,
  303. BOOL disable_vsync,
  304. BOOL use_gl,
  305. BOOL ignore_pixel_depth,
  306. U32 fsaa_samples)
  307. {
  308. LLWindow* new_window;
  309. if (use_gl)
  310. {
  311. #if LL_MESA_HEADLESS
  312. new_window = new LLWindowMesaHeadless(callbacks,
  313. title, name, x, y, width, height, flags, 
  314. fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
  315. #elif LL_SDL
  316. new_window = new LLWindowSDL(callbacks,
  317. title, x, y, width, height, flags, 
  318. fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
  319. #elif LL_WINDOWS
  320. new_window = new LLWindowWin32(callbacks,
  321. title, name, x, y, width, height, flags, 
  322. fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
  323. #elif LL_DARWIN
  324. new_window = new LLWindowMacOSX(callbacks,
  325. title, name, x, y, width, height, flags, 
  326. fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
  327. #endif
  328. }
  329. else
  330. {
  331. new_window = new LLWindowHeadless(callbacks,
  332. title, name, x, y, width, height, flags, 
  333. fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
  334. }
  335. if (FALSE == new_window->isValid())
  336. {
  337. delete new_window;
  338. llwarns << "LLWindowManager::create() : Error creating window." << llendl;
  339. return NULL;
  340. }
  341. sWindowList.insert(new_window);
  342. return new_window;
  343. }
  344. BOOL LLWindowManager::destroyWindow(LLWindow* window)
  345. {
  346. if (sWindowList.find(window) == sWindowList.end())
  347. {
  348. llerrs << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!" 
  349. << llendl;
  350. return FALSE;
  351. }
  352. window->close();
  353. sWindowList.erase(window);
  354. delete window;
  355. return TRUE;
  356. }
  357. BOOL LLWindowManager::isWindowValid(LLWindow *window)
  358. {
  359. return sWindowList.find(window) != sWindowList.end();
  360. }