llwindow.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 #include "llwindowheadless.h"
00034 
00035 #if LL_MESA_HEADLESS
00036 #include "llwindowmesaheadless.h"
00037 #elif LL_SDL
00038 #include "llwindowsdl.h"
00039 #elif LL_WINDOWS
00040 #include "llwindowwin32.h"
00041 #elif LL_DARWIN
00042 #include "llwindowmacosx.h"
00043 #endif
00044 
00045 #include "llerror.h"
00046 #include "llkeyboard.h"
00047 #include "linked_lists.h"
00048 
00049 //static instance for default callbacks
00050 LLWindowCallbacks       LLWindow::sDefaultCallbacks;
00051 
00052 //
00053 // LLWindowCallbacks
00054 //
00055 
00056 LLSplashScreen *gSplashScreenp = NULL;
00057 BOOL gDebugClicks = FALSE;
00058 BOOL gDebugWindowProc = FALSE;
00059 
00060 const S32 gURLProtocolWhitelistCount = 3;
00061 const char* gURLProtocolWhitelist[] = { "file", "http", "https" };
00062 
00063 // CP: added a handler list - this is what's used to open the protocol and is based on registry entry
00064 //         only meaningful difference currently is that file: protocols are opened using http:
00065 //         since no protocol handler exists in registry for file:
00066 //     Important - these lists should match - protocol to handler
00067 const char* gURLProtocolWhitelistHandler[] = { "http", "http", "https" };       
00068 
00069 BOOL LLWindowCallbacks::handleTranslatedKeyDown(const KEY key, const MASK mask, BOOL repeated)
00070 {
00071         return FALSE;
00072 }
00073 
00074 
00075 BOOL LLWindowCallbacks::handleTranslatedKeyUp(const KEY key, const MASK mask)
00076 {
00077         return FALSE;
00078 }
00079 
00080 void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
00081 {
00082 }
00083 
00084 BOOL LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask)
00085 {
00086         return FALSE;
00087 }
00088 
00089 
00090 BOOL LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
00091 {
00092         return FALSE;
00093 }
00094 
00095 BOOL LLWindowCallbacks::handleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
00096 {
00097         return FALSE;
00098 }
00099 
00100 void LLWindowCallbacks::handleMouseLeave(LLWindow *window)
00101 {
00102         return;
00103 }
00104 
00105 BOOL LLWindowCallbacks::handleCloseRequest(LLWindow *window)
00106 {
00107         //allow the window to close
00108         return TRUE;
00109 }
00110 
00111 void LLWindowCallbacks::handleQuit(LLWindow *window)
00112 {
00113         if(LLWindowManager::destroyWindow(window) == FALSE)     
00114         {
00115                 llerrs << "LLWindowCallbacks::handleQuit() : Couldn't destroy window" << llendl;
00116         }
00117 }
00118 
00119 BOOL LLWindowCallbacks::handleRightMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
00120 {
00121         return FALSE;
00122 }
00123 
00124 BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
00125 {
00126         return FALSE;
00127 }
00128 
00129 BOOL LLWindowCallbacks::handleMiddleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
00130 {
00131         return FALSE;
00132 }
00133 
00134 BOOL LLWindowCallbacks::handleMiddleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
00135 {
00136         return FALSE;
00137 }
00138 
00139 BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated)
00140 {
00141         return FALSE;
00142 }
00143 
00144 BOOL LLWindowCallbacks::handleActivateApp(LLWindow *window, BOOL activating)
00145 {
00146         return FALSE;
00147 }
00148 
00149 void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, MASK mask)
00150 {
00151 }
00152 
00153 void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
00154 {
00155 }
00156 
00157 void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
00158 {
00159 }
00160 
00161 void LLWindowCallbacks::handleFocus(LLWindow *window)
00162 {
00163 }
00164 
00165 void LLWindowCallbacks::handleFocusLost(LLWindow *window)
00166 {
00167 }
00168 
00169 void LLWindowCallbacks::handleMenuSelect(LLWindow *window, const S32 menu_item)
00170 {
00171 }
00172 
00173 BOOL LLWindowCallbacks::handlePaint(LLWindow *window, const S32 x, const S32 y, 
00174                                                                         const S32 width, const S32 height)
00175 {
00176         return FALSE;
00177 }
00178 
00179 BOOL LLWindowCallbacks::handleDoubleClick(LLWindow *window, const LLCoordGL pos, MASK mask)
00180 {
00181         return FALSE;
00182 }
00183 
00184 void LLWindowCallbacks::handleWindowBlock(LLWindow *window)
00185 {
00186 }
00187 
00188 void LLWindowCallbacks::handleWindowUnblock(LLWindow *window)
00189 {
00190 }
00191 
00192 void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *data)
00193 {
00194 }
00195 
00196 BOOL LLWindowCallbacks::handleTimerEvent(LLWindow *window)
00197 {
00198         return FALSE;
00199 }
00200 
00201 BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window)
00202 {
00203         return FALSE;
00204 }
00205 
00206 S32 OSMessageBox(const char* text, const char* caption, U32 type)
00207 {
00208         // Properly hide the splash screen when displaying the message box
00209         BOOL was_visible = FALSE;
00210         if (LLSplashScreen::isVisible())
00211         {
00212                 was_visible = TRUE;
00213                 LLSplashScreen::hide();
00214         }
00215 
00216         S32 result = 0;
00217 #if LL_MESA_HEADLESS // !!! *FIX: (???)
00218         llwarns << "OSMessageBox: " << text << llendl;
00219         return OSBTN_OK;
00220 #elif LL_WINDOWS
00221         result = OSMessageBoxWin32(text, caption, type);
00222 #elif LL_DARWIN
00223         result = OSMessageBoxMacOSX(text, caption, type);
00224 #elif LL_SDL
00225         result = OSMessageBoxSDL(text, caption, type);
00226 #else
00227 #error("OSMessageBox not implemented for this platform!")
00228 #endif
00229 
00230         if (was_visible)
00231         {
00232                 LLSplashScreen::show();
00233         }
00234 
00235         return result;
00236 }
00237 
00238 
00239 //
00240 // LLWindow
00241 //
00242 
00243 LLWindow::LLWindow(BOOL fullscreen, U32 flags)
00244         : mCallbacks(&sDefaultCallbacks),
00245           mPostQuit(TRUE),
00246           mFullscreen(fullscreen),
00247           mFullscreenWidth(0),
00248           mFullscreenHeight(0),
00249           mFullscreenBits(0),
00250           mFullscreenRefresh(0),
00251           mSupportedResolutions(NULL),
00252           mNumSupportedResolutions(0),
00253           mCurrentCursor(UI_CURSOR_ARROW),
00254           mCursorHidden(FALSE),
00255           mBusyCount(0),
00256           mIsMouseClipping(FALSE),
00257           mSwapMethod(SWAP_METHOD_UNDEFINED),
00258           mHideCursorPermanent(FALSE),
00259           mFlags(flags),
00260           mHighSurrogate(0)
00261 {
00262 }
00263         
00264 // virtual
00265 void LLWindow::incBusyCount()
00266 {
00267         ++mBusyCount;
00268 }
00269 
00270 // virtual
00271 void LLWindow::decBusyCount()
00272 {
00273         if (mBusyCount > 0)
00274         {
00275                 --mBusyCount;
00276         }
00277 }
00278 
00279 void LLWindow::setCallbacks(LLWindowCallbacks *callbacks)
00280 {
00281         mCallbacks = callbacks;
00282         if (gKeyboard)
00283         {
00284                 gKeyboard->setCallbacks(callbacks);
00285         }
00286 }
00287 
00288 // static
00289 std::string LLWindow::getFontListSans()
00290 {
00291 #if LL_WINDOWS
00292         return LLWindowWin32::getFontListSans();
00293 #elif LL_DARWIN
00294         return LLWindowMacOSX::getFontListSans();
00295 #elif LL_SDL
00296         return LLWindowSDL::getFontListSans();
00297 #else
00298         return "";
00299 #endif
00300 }
00301 
00302 #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
00303 #define UTF16_IS_LOW_SURROGATE(U)  ((U16)((U) - 0xDC00) < 0x0400)
00304 #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
00305 
00306 void LLWindow::handleUnicodeUTF16(U16 utf16, MASK mask)
00307 {
00308         // Note that we could discard unpaired surrogates, but I'm
00309         // following the Unicode Consortium's recommendation here;
00310         // that is, to preserve those unpaired surrogates in UTF-32
00311         // values.  _To_preserve_ means to pass to the callback in our
00312         // context.
00313 
00314         if (mHighSurrogate == 0)
00315         {
00316                 if (UTF16_IS_HIGH_SURROGATE(utf16))
00317                 {
00318                         mHighSurrogate = utf16;
00319                 }
00320                 else
00321                 {
00322                         mCallbacks->handleUnicodeChar(utf16, mask);
00323                 }
00324         }
00325         else
00326         {
00327                 if (UTF16_IS_LOW_SURROGATE(utf16))
00328                 {
00329                         /* A legal surrogate pair.  */                  
00330                         mCallbacks->handleUnicodeChar(UTF16_SURROGATE_PAIR_TO_UTF32(mHighSurrogate, utf16), mask);
00331                         mHighSurrogate = 0;
00332                 }
00333                 else if (UTF16_IS_HIGH_SURROGATE(utf16))
00334                 {
00335                         /* Two consecutive high surrogates.  */
00336                         mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
00337                         mHighSurrogate = utf16;
00338                 }
00339                 else
00340                 {
00341                         /* A non-low-surrogate preceeded by a high surrogate. */
00342                         mCallbacks->handleUnicodeChar(mHighSurrogate, mask);
00343                         mHighSurrogate = 0;
00344                         mCallbacks->handleUnicodeChar(utf16, mask);
00345                 }
00346         }
00347 }
00348 
00349 //
00350 // LLSplashScreen
00351 //
00352 
00353 // static
00354 bool LLSplashScreen::isVisible()
00355 {
00356         return gSplashScreenp ? true: false;
00357 }
00358 
00359 // static
00360 LLSplashScreen *LLSplashScreen::create()
00361 {
00362 #if LL_MESA_HEADLESS || LL_SDL  // !!! *FIX: (???)
00363         return 0;
00364 #elif LL_WINDOWS
00365         return new LLSplashScreenWin32;
00366 #elif LL_DARWIN
00367         return new LLSplashScreenMacOSX;
00368 #else
00369 #error("LLSplashScreen not implemented on this platform!")
00370 #endif
00371 }
00372 
00373 
00374 //static
00375 void LLSplashScreen::show()
00376 {
00377         if (!gSplashScreenp)
00378         {
00379 #if LL_WINDOWS && !LL_MESA_HEADLESS
00380                 gSplashScreenp = new LLSplashScreenWin32;
00381 #elif LL_DARWIN
00382                 gSplashScreenp = new LLSplashScreenMacOSX;
00383 #endif
00384                 if (gSplashScreenp)
00385                 {
00386                         gSplashScreenp->showImpl();
00387                 }
00388         }
00389 }
00390 
00391 //static
00392 void LLSplashScreen::update(const char* str)
00393 {
00394         LLSplashScreen::show();
00395         if (gSplashScreenp)
00396         {
00397                 gSplashScreenp->updateImpl(str);
00398         }
00399 }
00400 
00401 //static
00402 void LLSplashScreen::hide()
00403 {
00404         if (gSplashScreenp)
00405         {
00406                 gSplashScreenp->hideImpl();
00407         }
00408         delete gSplashScreenp;
00409         gSplashScreenp = NULL;
00410 }
00411 
00412 //
00413 // LLWindowManager
00414 //
00415 
00416 // TODO: replace with std::set
00417 static std::set<LLWindow*> sWindowList;
00418 
00419 LLWindow* LLWindowManager::createWindow(
00420         char *title,
00421         char *name,
00422         LLCoordScreen upper_left,
00423         LLCoordScreen size,
00424         U32 flags,
00425         BOOL fullscreen, 
00426         BOOL clearBg,
00427         BOOL disable_vsync,
00428         BOOL use_gl,
00429         BOOL ignore_pixel_depth)
00430 {
00431         return createWindow(
00432                 title, name, upper_left.mX, upper_left.mY, size.mX, size.mY, flags, 
00433                 fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
00434 }
00435 
00436 LLWindow* LLWindowManager::createWindow(
00437         char *title, char *name, S32 x, S32 y, S32 width, S32 height, U32 flags,
00438         BOOL fullscreen, 
00439         BOOL clearBg,
00440         BOOL disable_vsync,
00441         BOOL use_gl,
00442         BOOL ignore_pixel_depth,
00443         U32 fsaa_samples)
00444 {
00445         LLWindow* new_window;
00446 
00447         if (use_gl)
00448         {
00449 #if LL_MESA_HEADLESS
00450                 new_window = new LLWindowMesaHeadless(
00451                         title, name, x, y, width, height, flags, 
00452                         fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
00453 #elif LL_SDL
00454                 new_window = new LLWindowSDL(
00455                         title, x, y, width, height, flags, 
00456                         fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
00457 #elif LL_WINDOWS
00458                 new_window = new LLWindowWin32(
00459                         title, name, x, y, width, height, flags, 
00460                         fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
00461 #elif LL_DARWIN
00462                 new_window = new LLWindowMacOSX(
00463                         title, name, x, y, width, height, flags, 
00464                         fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
00465 #endif
00466         }
00467         else
00468         {
00469                 new_window = new LLWindowHeadless(
00470                         title, name, x, y, width, height, flags, 
00471                         fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
00472         }
00473 
00474         if (FALSE == new_window->isValid())
00475         {
00476                 delete new_window;
00477                 llwarns << "LLWindowManager::create() : Error creating window." << llendl;
00478                 return NULL;
00479         }
00480         sWindowList.insert(new_window);
00481         return new_window;
00482 }
00483 
00484 BOOL LLWindowManager::destroyWindow(LLWindow* window)
00485 {
00486         if (sWindowList.find(window) == sWindowList.end())
00487         {
00488                 llerrs << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!" 
00489                         << llendl;
00490                 return FALSE;
00491         }
00492 
00493         window->close();
00494 
00495         sWindowList.erase(window);
00496 
00497         delete window;
00498 
00499         return TRUE;
00500 }
00501 
00502 BOOL LLWindowManager::isWindowValid(LLWindow *window)
00503 {
00504         return sWindowList.find(window) != sWindowList.end();
00505 }

Generated on Fri May 16 08:33:02 2008 for SecondLife by  doxygen 1.5.5