123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- /**
- * @file llwindow.cpp
- * @brief Basic graphical window class
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #if LL_LINUX
- #include "llwindowsdl.h"
- #elif LL_WINDOWS
- #include "llwindowwin32.h"
- #elif LL_DARWIN
- #include "llwindowmacosx.h"
- #endif
- #include "llkeyboard.h"
- // Globals
- LLWindow* gWindowp = NULL;
- LLSplashScreen* gSplashScreenp = NULL;
- bool gDebugClicks = false;
- bool gDebugWindowProc = false;
- bool gHiDPISupport = false;
- const std::string gURLProtocolWhitelist[] =
- {
- "file:",
- "http:",
- "https:",
- "ftp:",
- "data:"
- };
- const S32 gURLProtocolWhitelistCount = LL_ARRAY_SIZE(gURLProtocolWhitelist);
- // Static instance for default callbacks
- LLWindowCallbacks LLWindow::sDefaultCallbacks;
- // Helper function
- S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
- {
- // Properly hide the splash screen when displaying the message box
- bool was_visible = LLSplashScreen::isVisible();
- if (was_visible)
- {
- LLSplashScreen::hide();
- }
- S32 result = 0;
- #if LL_DARWIN
- result = OSMessageBoxMacOSX(text, caption, type);
- #elif LL_LINUX
- result = OSMessageBoxSDL(text, caption, type);
- #elif LL_WINDOWS
- result = OSMessageBoxWin32(text, caption, type);
- #else
- # error("OSMessageBox not implemented for this platform !")
- #endif
- if (was_visible)
- {
- LLSplashScreen::show();
- }
- return result;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLWindow class
- ///////////////////////////////////////////////////////////////////////////////
- //static
- void LLWindow::createWindow(const std::string& title, S32 x, S32 y,
- U32 width, U32 height, U32 flags, bool fullscreen,
- bool disable_vsync, U32 fsaa_samples)
- {
- llassert_always(gWindowp == NULL);
- #if LL_LINUX
- gWindowp = new LLWindowSDL(title, x, y, width, height, flags,
- fullscreen, disable_vsync, fsaa_samples);
- #elif LL_WINDOWS
- gWindowp = new LLWindowWin32(title, x, y, width, height, flags, fullscreen,
- disable_vsync, fsaa_samples);
- #elif LL_DARWIN
- gWindowp = new LLWindowMacOSX(title, flags, fullscreen, disable_vsync,
- fsaa_samples);
- #endif
- if (!gWindowp->isValid())
- {
- llwarns << "Invalid window. Destroying it." << llendl;
- delete gWindowp;
- gWindowp = NULL;
- }
- }
- //static
- void LLWindow::destroyWindow()
- {
- if (gWindowp)
- {
- gWindowp->close();
- delete gWindowp;
- gWindowp = NULL;
- }
- }
- LLWindow::LLWindow(bool fullscreen, U32 flags)
- : mCallbacks(&sDefaultCallbacks),
- mPostQuit(true),
- mFullscreen(fullscreen),
- mFullscreenWidth(0),
- mFullscreenHeight(0),
- mFullscreenBits(0),
- mFullscreenRefresh(0),
- mOverrideAspectRatio(0.f),
- mCurrentGamma(1.f),
- mSupportedResolutions(NULL),
- mNumSupportedResolutions(0),
- mCurrentCursor(UI_CURSOR_ARROW),
- mCursorFrozen(false),
- mCursorHidden(false),
- #if LL_DARWIN
- mNextCursor(UI_CURSOR_ARROW),
- #endif
- mBusyCount(0),
- mIsMouseClipping(false),
- mSwapMethod(SWAP_METHOD_UNDEFINED),
- mHideCursorPermanent(false),
- mFlags(flags),
- mHighSurrogate(0)
- {
- }
- void LLWindow::decBusyCount()
- {
- if (mBusyCount > 0)
- {
- --mBusyCount;
- }
- }
- void LLWindow::setCallbacks(LLWindowCallbacks* callbacks)
- {
- mCallbacks = callbacks;
- if (gKeyboardp)
- {
- gKeyboardp->setCallbacks(callbacks);
- }
- }
- //static
- std::vector<std::string> LLWindow::getDynamicFallbackFontList()
- {
- #if LL_WINDOWS
- return LLWindowWin32::getDynamicFallbackFontList();
- #elif LL_DARWIN
- return LLWindowMacOSX::getDynamicFallbackFontList();
- #elif LL_LINUX
- return LLWindowSDL::getDynamicFallbackFontList();
- #else
- return std::vector<std::string>();
- #endif
- }
- #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
- #define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400)
- #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
- void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask)
- {
- LL_DEBUGS("Window") << "UTF16 key = " << std::hex << (U32)utf16 << std::dec
- << " - mask = " << mask << LL_ENDL;
- // Note that we could discard unpaired surrogates, but I am following the
- // Unicode Consortium's recommendation here, that is, to preserve those
- // unpaired surrogates in UTF-32 values. _To_preserve_ means to pass to the
- // callback in our context.
- if (mHighSurrogate == 0)
- {
- if (UTF16_IS_HIGH_SURROGATE(utf16))
- {
- mHighSurrogate = utf16;
- }
- else
- {
- mCallbacks->handleUnicodeChar(utf16, mask);
- }
- }
- else if (UTF16_IS_LOW_SURROGATE(utf16))
- {
- // A legal surrogate pair.
- mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate,
- utf16),
- mask);
- mHighSurrogate = 0;
- }
- else if (UTF16_IS_HIGH_SURROGATE(utf16))
- {
- // Two consecutive high surrogates.
- mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
- mHighSurrogate = utf16;
- }
- else
- {
- // A non-low-surrogate preceeded by a high surrogate.
- mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
- mHighSurrogate = 0;
- mCallbacks->handleUnicodeChar(utf16, mask);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLSplashScreen class
- ///////////////////////////////////////////////////////////////////////////////
- //static
- bool LLSplashScreen::isVisible()
- {
- return gSplashScreenp != NULL;
- }
- //static
- void LLSplashScreen::show()
- {
- if (!gSplashScreenp)
- {
- #if LL_DARWIN
- gSplashScreenp = new LLSplashScreenMacOSX;
- #elif LL_LINUX
- gSplashScreenp = new LLSplashScreenSDL;
- #elif LL_WINDOWS
- gSplashScreenp = new LLSplashScreenWin32;
- #endif
- gSplashScreenp->showImpl();
- }
- }
- //static
- void LLSplashScreen::update(const std::string& str)
- {
- LLSplashScreen::show();
- if (gSplashScreenp)
- {
- gSplashScreenp->updateImpl(str);
- }
- }
- //static
- void LLSplashScreen::hide()
- {
- if (gSplashScreenp)
- {
- gSplashScreenp->hideImpl();
- }
- delete gSplashScreenp;
- gSplashScreenp = NULL;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // LLWindowCallbacks class
- ///////////////////////////////////////////////////////////////////////////////
- //virtual
- bool LLWindowCallbacks::handleTranslatedKeyDown(KEY, MASK, bool)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleTranslatedKeyUp(KEY, MASK)
- {
- return false;
- }
- //virtual
- void LLWindowCallbacks::handleScanKey(KEY, bool, bool, bool)
- {
- }
- //virtual
- bool LLWindowCallbacks::handleUnicodeChar(llwchar, MASK)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleMouseDown(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleMouseUp(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- void LLWindowCallbacks::handleMouseLeave(LLWindow*)
- {
- return;
- }
- //virtual
- bool LLWindowCallbacks::handleCloseRequest(LLWindow*)
- {
- // Allow the window to close
- return true;
- }
- //virtual
- void LLWindowCallbacks::handleQuit(LLWindow* window)
- {
- if (window == gWindowp)
- {
- LLWindow::destroyWindow();
- }
- else
- {
- llerrs << "Invalid window !" << llendl;
- }
- }
- //virtual
- bool LLWindowCallbacks::handleRightMouseDown(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleRightMouseUp(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleMiddleMouseDown(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleMiddleMouseUp(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleActivate(LLWindow*, bool)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleActivateApp(LLWindow*, bool)
- {
- return false;
- }
- //virtual
- void LLWindowCallbacks::handleMouseMove(LLWindow*, const LLCoordGL, MASK)
- {
- }
- #if LL_DARWIN
- //virtual
- void LLWindowCallbacks::handleMouseDragged(LLWindow*, const LLCoordGL, MASK)
- {
- }
- #endif
- //virtual
- void LLWindowCallbacks::handleScrollWheel(LLWindow*, S32)
- {
- }
- //virtual
- void LLWindowCallbacks::handleResize(LLWindow*, S32, S32)
- {
- }
- //virtual
- void LLWindowCallbacks::handleFocus(LLWindow*)
- {
- }
- //virtual
- void LLWindowCallbacks::handleFocusLost(LLWindow*)
- {
- }
- //virtual
- void LLWindowCallbacks::handleMenuSelect(LLWindow*, S32)
- {
- }
- //virtual
- bool LLWindowCallbacks::handlePaint(LLWindow*, S32, S32, S32, S32)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleDoubleClick(LLWindow*, const LLCoordGL, MASK)
- {
- return false;
- }
- //virtual
- void LLWindowCallbacks::handleWindowBlock(LLWindow*)
- {
- }
- //virtual
- void LLWindowCallbacks::handleWindowUnblock(LLWindow*)
- {
- }
- //virtual
- void LLWindowCallbacks::handleDataCopy(LLWindow*, S32, void*)
- {
- }
- //virtual
- bool LLWindowCallbacks::handleTimerEvent(LLWindow*)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleDeviceChange(LLWindow*)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleDPIChanged(LLWindow*, F32, S32, S32)
- {
- return false;
- }
- //virtual
- bool LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow*)
- {
- return false;
- }
|