From fd46865a502036b9e4414e7ec4950faf551b1f14 Mon Sep 17 00:00:00 2001 From: Adam Moss Date: Tue, 2 Dec 2008 20:35:40 +0000 Subject: QAR-1040 maint-viewer-11 + OpenAL combo mergeme svn merge -c104451 svn+ssh://svn.lindenlab.com/svn/linden/branches/moss/openal-maint-viewer-11-combo-r104448 --- indra/llwindow/llwindowsdl.cpp | 626 ++++++----------------------------------- indra/llwindow/llwindowsdl.h | 12 - 2 files changed, 81 insertions(+), 557 deletions(-) (limited to 'indra/llwindow') diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 6a0ef141f5..5240bb62fd 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1,6 +1,7 @@ /** * @file llwindowsdl.cpp * @brief SDL implementation of LLWindow class + * @author This module has many fathers, and it shows. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -156,6 +157,8 @@ bool LLWindowSDL::ll_try_gtk_init(void) llwarns << "- GTK COMPATIBILITY WARNING: " << gtk_warning << llendl; gtk_is_good = FALSE; + } else { + llinfos << "- GTK version is good." << llendl; } done_gtk_diag = TRUE; @@ -188,11 +191,12 @@ Display* LLWindowSDL::get_SDL_Display(void) LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width, - S32 height, U32 flags, - BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth, U32 fsaa_samples) - : LLWindow(fullscreen, flags), mGamma(1.0f) + S32 height, U32 flags, + BOOL fullscreen, BOOL clearBg, + BOOL disable_vsync, BOOL use_gl, + BOOL ignore_pixel_depth, U32 fsaa_samples) + : LLWindow(fullscreen, flags), Lock_Display(NULL), + Unlock_Display(NULL), mGamma(1.0f) { // Initialize the keyboard gKeyboard = new LLKeyboardSDL(); @@ -200,10 +204,6 @@ LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width, // Ignore use_gl for now, only used for drones on PC mWindow = NULL; - mCursorDecoupled = FALSE; - mCursorLastEventDeltaX = 0; - mCursorLastEventDeltaY = 0; - mCursorIgnoreNextDelta = FALSE; mNeedsResize = FALSE; mOverrideAspectRatio = 0.f; mGrabbyKeyFlags = 0; @@ -717,9 +717,33 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B #endif #if LL_X11 - init_x11clipboard(); + /* Grab the window manager specific information */ + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if ( SDL_GetWMInfo(&info) ) + { + /* Save the information for later use */ + if ( info.subsystem == SDL_SYSWM_X11 ) + { + mSDL_Display = info.info.x11.display; + mSDL_XWindowID = info.info.x11.wmwindow; + Lock_Display = info.info.x11.lock_func; + Unlock_Display = info.info.x11.unlock_func; + } + else + { + llwarns << "We're not running under X11? Wild." + << llendl; + } + } + else + { + llwarns << "We're not running under any known WM. Wild." + << llendl; + } #endif // LL_X11 + //make sure multisampling is disabled by default glDisable(GL_MULTISAMPLE_ARB); @@ -763,8 +787,12 @@ BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL void LLWindowSDL::destroyContext() { llinfos << "destroyContext begins" << llendl; + #if LL_X11 - quit_x11clipboard(); + mSDL_Display = NULL; + mSDL_XWindowID = None; + Lock_Display = NULL; + Unlock_Display = NULL; #endif // LL_X11 // Clean up remaining GL state before blowing away window @@ -984,11 +1012,7 @@ BOOL LLWindowSDL::isCursorHidden() // Constrains the mouse to the window. void LLWindowSDL::setMouseClipping( BOOL b ) { - //llinfos << "LLWindowSDL::setMouseClipping " << b << llendl; - // Just stash the requested state. We'll simulate this when the cursor is hidden by decoupling. - mIsMouseClipping = b; //SDL_WM_GrabInput(b ? SDL_GRAB_ON : SDL_GRAB_OFF); - adjustCursorDecouple(); } BOOL LLWindowSDL::setCursorPosition(const LLCoordWindow position) @@ -1003,10 +1027,10 @@ BOOL LLWindowSDL::setCursorPosition(const LLCoordWindow position) //llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl; - SDL_WarpMouse(screen_pos.mX, screen_pos.mY); - - // Under certain circumstances, this will trigger us to decouple the cursor. - adjustCursorDecouple(true); + // do the actual forced cursor move. + SDL_WarpMouse(screen_pos.mX, screen_pos.mY); + + //llinfos << llformat("llcw %d,%d -> scr %d,%d", position.mX, position.mY, screen_pos.mX, screen_pos.mY) << llendl; return result; } @@ -1026,33 +1050,6 @@ BOOL LLWindowSDL::getCursorPosition(LLCoordWindow *position) return convertCoords(screen_pos, position); } -void LLWindowSDL::adjustCursorDecouple(bool warpingMouse) -{ - if(mIsMouseClipping && mCursorHidden) - { - if(warpingMouse) - { - // The cursor should be decoupled. Make sure it is. - if(!mCursorDecoupled) - { - // llinfos << "adjustCursorDecouple: decoupling cursor" << llendl; - //CGAssociateMouseAndMouseCursorPosition(false); - mCursorDecoupled = true; - mCursorIgnoreNextDelta = TRUE; - } - } - } - else - { - // The cursor should not be decoupled. Make sure it isn't. - if(mCursorDecoupled) - { - // llinfos << "adjustCursorDecouple: recoupling cursor" << llendl; - //CGAssociateMouseAndMouseCursorPosition(true); - mCursorDecoupled = false; - } - } -} F32 LLWindowSDL::getNativeAspectRatio() { @@ -1212,506 +1209,50 @@ void LLWindowSDL::flashIcon(F32 seconds) #endif // LL_X11 } -#if LL_X11 -/* Lots of low-level X11 stuff to handle X11 copy-and-paste */ - -/* Our X11 clipboard support is a bit bizarre in various - organically-grown ways. Ideally it should be fixed to do - real string-type negotiation (this would make pasting to - xterm faster and pasting to UTF-8 emacs work properly), but - right now it has the rare and desirable trait of being - generally stable and working. */ - -typedef Atom x11clipboard_type; - -/* PRIMARY and CLIPBOARD are the two main kinds of - X11 clipboard. A third are the CUT_BUFFERs which an - obsolete holdover from X10 days and use a quite orthogonal - mechanism. CLIPBOARD is the type whose design most - closely matches SL's own win32-alike explicit copy-and-paste - paradigm. - - Pragmatically we support all three to varying degrees. When - we paste into SL, it is strictly from CLIPBOARD. When we copy, - we support (to as full an extent as the clipboard content type - allows) CLIPBOARD, PRIMARY, and CUT_BUFFER0. - */ -static x11clipboard_type get_x11_readwrite_clipboard_type(void) -{ - return XInternAtom(LLWindowSDL::get_SDL_Display(), "CLIPBOARD", False); -} - -static x11clipboard_type get_x11_write_clipboard_type(void) -{ - return XA_PRIMARY; -} - -/* This is where our own private cutbuffer goes - we don't use - a regular cutbuffer (XA_CUT_BUFFER0 etc) for intermediate - storage because their use isn't really defined for holding UTF8. */ -static x11clipboard_type get_x11_cutbuffer_clipboard_type(void) -{ - return XInternAtom(LLWindowSDL::get_SDL_Display(), "SECONDLIFE_CUTBUFFER", False); -} - -/* Some X11 atom-generators */ -static Atom get_x11_targets_atom(void) -{ - return XInternAtom(LLWindowSDL::get_SDL_Display(), "TARGETS", False); -} - -static Atom get_x11_text_atom(void) -{ - return XInternAtom(LLWindowSDL::get_SDL_Display(), "TEXT", False); -} - -/* These defines, and convert_data/convert_x11clipboard, - mostly exist to support non-text or unusually-encoded - clipboard data, which we don't really have a need for at - the moment. */ -#define SDLCLIPTYPE(A, B, C, D) (int)(((A)<<24)|((B)<<16)|((C)<<8)|((D)<<0)) -#define FORMAT_PREFIX "SECONDLIFE_x11clipboard_0x" -static -x11clipboard_type convert_format(int type) -{ - if (!gWindowImplementation) - { - llwarns << "!gWindowImplementation in convert_format()" - << llendl; - return XA_STRING; - } - - switch (type) - { - case SDLCLIPTYPE('T', 'E', 'X', 'T'): - // old-style X11 clipboard, strictly only ISO 8859-1 encoding - return XA_STRING; - case SDLCLIPTYPE('U', 'T', 'F', '8'): - // newer de-facto UTF8 clipboard atom - return XInternAtom(gWindowImplementation->mSDL_Display, - "UTF8_STRING", False); - default: - { - /* completely arbitrary clipboard types... we don't actually use - these right now, and support is skeletal. */ - char format[sizeof(FORMAT_PREFIX)+8+1]; /* Flawfinder: ignore */ - - snprintf(format, sizeof(format), "%s%08lx", FORMAT_PREFIX, (unsigned long)type); - return XInternAtom(gWindowImplementation->mSDL_Display, - format, False); - } - } -} - -/* convert platform string to x11 clipboard format. for our - purposes this is pretty trivial right now. */ -static int -convert_data(int type, char *dst, const char *src, int srclen) -{ - int dstlen; - - dstlen = 0; - switch (type) - { - case SDLCLIPTYPE('T', 'E', 'X', 'T'): - case SDLCLIPTYPE('U', 'T', 'F', '8'): - if (src == NULL) - { - break; - } - if ( srclen == 0 ) - srclen = strlen(src); /* Flawfinder: ignore */ - - dstlen = srclen + 1; - - if ( dst ) // assume caller made it big enough by asking us - { - memcpy(dst, src, srclen); /* Flawfinder: ignore */ - dst[srclen] = '\0'; - } - break; - - default: - llwarns << "convert_data: Unknown medium type" << llendl; - break; - } - return(dstlen); -} - -/* Convert x11clipboard data to platform string. This too is - pretty trivial for our needs right now, and just about identical - to above. */ -static int -convert_x11clipboard(int type, char *dst, const char *src, int srclen) -{ - int dstlen; - - dstlen = 0; - switch (type) - { - case SDLCLIPTYPE('U', 'T', 'F', '8'): - case SDLCLIPTYPE('T', 'E', 'X', 'T'): - if (src == NULL) - { - break; - } - if ( srclen == 0 ) - srclen = strlen(src); /* Flawfinder: ignore */ - - dstlen = srclen + 1; - - if ( dst ) // assume caller made it big enough by asking us - { - memcpy(dst, src, srclen); /* Flawfinder: ignore */ - dst[srclen] = '\0'; - } - break; - - default: - llwarns << "convert_x11clipboard: Unknown medium type" << llendl; - break; - } - return dstlen; -} - -int -LLWindowSDL::is_empty_x11clipboard(void) -{ - int retval; - - maybe_lock_display(); - retval = ( XGetSelectionOwner(mSDL_Display, get_x11_readwrite_clipboard_type()) == None ); - maybe_unlock_display(); - - return(retval); -} - -void -LLWindowSDL::put_x11clipboard(int type, int srclen, const char *src) +#if LL_GTK +BOOL LLWindowSDL::isClipboardTextAvailable() { - x11clipboard_type format; - int dstlen; - char *dst; - - format = convert_format(type); - dstlen = convert_data(type, NULL, src, srclen); - - dst = (char *)malloc(dstlen); - if ( dst != NULL ) + if (ll_try_gtk_init()) { - maybe_lock_display(); - Window root = DefaultRootWindow(mSDL_Display); - convert_data(type, dst, src, srclen); - // Cutbuffers are only allowed to have STRING atom types, - // but Emacs puts UTF8 inside them anyway. We cautiously - // don't. - if (type == SDLCLIPTYPE('T','E','X','T')) - { - // dstlen-1 so we don't include the trailing \0 - llinfos << "X11: Populating cutbuffer." <event.xevent; - - if ( (xevent.type == SelectionNotify)&& - (xevent.xselection.requestor == owner) ) - selection_response = 1; - } - } else { - llinfos << "X11: Waiting for SYSWM event..." << llendl; - } - } - llinfos << "X11: Clipboard arrived." <type != SDL_SYSWMEVENT ) - { - return(1); - } - - /* Handle window-manager specific clipboard events */ - switch (event->syswm.msg->event.xevent.type) { - /* Copy the selection from SECONDLIFE_CUTBUFFER to the requested property */ - case SelectionRequest: { - XSelectionRequestEvent *req; - XEvent sevent; - int seln_format; - unsigned long nbytes; - unsigned long overflow; - unsigned char *seln_data; - - req = &event->syswm.msg->event.xevent.xselectionrequest; - sevent.xselection.type = SelectionNotify; - sevent.xselection.display = req->display; - sevent.xselection.selection = req->selection; - sevent.xselection.target = None; - sevent.xselection.property = None; - sevent.xselection.requestor = req->requestor; - sevent.xselection.time = req->time; - if ( XGetWindowProperty(LLWindowSDL::get_SDL_Display(), DefaultRootWindow(LLWindowSDL::get_SDL_Display()), - get_x11_cutbuffer_clipboard_type(), 0, INT_MAX/4, False, req->target, - &sevent.xselection.target, &seln_format, - &nbytes, &overflow, &seln_data) == Success ) - { - if ( sevent.xselection.target == req->target) - { - if ( sevent.xselection.target == XA_STRING || - sevent.xselection.target == - convert_format(SDLCLIPTYPE('U','T','F','8')) ) - { - if ( seln_data[nbytes-1] == '\0' ) - --nbytes; - } - XChangeProperty(LLWindowSDL::get_SDL_Display(), req->requestor, req->property, - req->target, seln_format, PropModeReplace, - seln_data, nbytes); - sevent.xselection.property = req->property; - } else if (get_x11_targets_atom() == req->target) { - /* only advertise what we currently support */ - const int num_supported = 3; - Atom supported[num_supported] = { - XA_STRING, // will be over-written below - get_x11_text_atom(), - get_x11_targets_atom() - }; - supported[0] = sevent.xselection.target; - XChangeProperty(LLWindowSDL::get_SDL_Display(), req->requestor, - req->property, XA_ATOM, 32, PropModeReplace, - (unsigned char*)supported, - num_supported); - sevent.xselection.property = req->property; - llinfos << "Clipboard: An app asked us what selections format we offer." << llendl; - } else { - llinfos << "Clipboard: An app requested an unsupported selection format " << req->target << ", we have " << sevent.xselection.target << llendl; - sevent.xselection.target = None; - } - XFree(seln_data); + text = LLWString(utf8str_to_wstring(data)); + g_free(data); + return TRUE; } - int sendret = - XSendEvent(LLWindowSDL::get_SDL_Display(),req->requestor,False,0,&sevent); - if ((sendret==BadValue) || (sendret==BadWindow)) - llwarns << "Clipboard SendEvent failed" << llendl; - XSync(LLWindowSDL::get_SDL_Display(), False); } - break; - } - - /* Post the event for X11 clipboard reading above */ - return(1); + return FALSE; // failure } -int -LLWindowSDL::init_x11clipboard(void) +BOOL LLWindowSDL::copyTextToClipboard(const LLWString &text) { - SDL_SysWMinfo info; - int retval; - - /* Grab the window manager specific information */ - retval = -1; - SDL_SetError("SDL is not running on known window manager"); - - SDL_VERSION(&info.version); - if ( SDL_GetWMInfo(&info) ) + if (ll_try_gtk_init()) { - /* Save the information for later use */ - if ( info.subsystem == SDL_SYSWM_X11 ) - { - mSDL_Display = info.info.x11.display; - mSDL_XWindowID = info.info.x11.wmwindow; - Lock_Display = info.info.x11.lock_func; - Unlock_Display = info.info.x11.unlock_func; - - /* Enable the special window hook events */ - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - SDL_SetEventFilter(clipboard_filter_callback); - - retval = 0; - } - else - { - SDL_SetError("SDL is not running on X11"); - } - } - return(retval); -} - -void -LLWindowSDL::quit_x11clipboard(void) -{ - mSDL_Display = NULL; - mSDL_XWindowID = None; - Lock_Display = NULL; - Unlock_Display = NULL; - - SDL_SetEventFilter(NULL); // Stop custom event filtering -} - -/************************************************/ - -BOOL LLWindowSDL::isClipboardTextAvailable() -{ - return !is_empty_x11clipboard(); -} - -BOOL LLWindowSDL::pasteTextFromClipboard(LLWString &dst) -{ - int cliplen; // seems 1 or 2 bytes longer than expected - char *cliptext = NULL; - get_x11clipboard(SDLCLIPTYPE('U','T','F','8'), &cliplen, &cliptext); - if (cliptext) - { - llinfos << "X11: Got UTF8 clipboard text." << llendl; - // at some future time we can use cliplen instead of relying on \0, - // if we ever grok non-ascii, non-utf8 encodings on the clipboard. - std::string clip_str(cliptext); - // we can't necessarily trust the incoming text to be valid UTF-8, - // but utf8str_to_wstring() seems to do an appropriate level of - // validation for avoiding over-reads. - dst = utf8str_to_wstring(clip_str); - /*llinfos << "X11 pasteTextFromClipboard: cliplen=" << cliplen << - " strlen(cliptext)=" << strlen(cliptext) << - " clip_str.length()=" << clip_str.length() << - " dst.length()=" << dst.length() << - llendl;*/ - free(cliptext); - return TRUE; // success - } - get_x11clipboard(SDLCLIPTYPE('T','E','X','T'), &cliplen, &cliptext); - if (cliptext) - { - llinfos << "X11: Got ISO 8859-1 clipboard text." << llendl; - std::string clip_str(cliptext); - std::string utf8_str = rawstr_to_utf8(clip_str); - dst = utf8str_to_wstring(utf8_str); - free(cliptext); + const std::string utf8 = wstring_to_utf8str(text); + GtkClipboard * const clipboard = + gtk_clipboard_get(GDK_NONE); + gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); + return TRUE; } return FALSE; // failure } -BOOL LLWindowSDL::copyTextToClipboard(const LLWString &s) -{ - std::string utf8text = wstring_to_utf8str(s); - const char* cstr = utf8text.c_str(); - if (cstr == NULL) - { - return FALSE; - } - int cstrlen = strlen(cstr); /* Flawfinder: ignore */ - int i; - for (i=0; ihandleMouseDown(this, openGlCoord, mask); } - else if (event.button.button == SDL_BUTTON_RIGHT) // right ... yes, it's 3, not 2, in SDL... + else if (event.button.button == SDL_BUTTON_RIGHT) // right { - // right double click isn't handled right now in Second Life ... if (isDoubleClick) - mCallbacks->handleRightMouseDown(this, openGlCoord, mask); + mCallbacks->handleRightMouseDown(this, openGlCoord, mask); } else if (event.button.button == SDL_BUTTON_MIDDLE) // middle @@ -2112,13 +1654,11 @@ void LLWindowSDL::gatherInput() MASK mask = gKeyboard->currentMask(TRUE); if (event.button.button == SDL_BUTTON_LEFT) // left - mCallbacks->handleMouseUp(this, openGlCoord, mask); - else if (event.button.button == SDL_BUTTON_RIGHT) // right ... yes, it's 3, not 2, in SDL... - mCallbacks->handleRightMouseUp(this, openGlCoord, mask); + mCallbacks->handleMouseUp(this, openGlCoord, mask); + else if (event.button.button == SDL_BUTTON_RIGHT) // right + mCallbacks->handleRightMouseUp(this, openGlCoord, mask); else if (event.button.button == SDL_BUTTON_MIDDLE) // middle - { mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); - } // don't handle mousewheel here... break; @@ -2426,8 +1966,6 @@ void LLWindowSDL::hideCursor() { // llinfos << "hideCursor: already hidden" << llendl; } - - adjustCursorDecouple(); } void LLWindowSDL::showCursor() @@ -2443,8 +1981,6 @@ void LLWindowSDL::showCursor() { // llinfos << "showCursor: already visible" << llendl; } - - adjustCursorDecouple(); } void LLWindowSDL::showCursorFromMouseMove() diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 091b0de1e0..52afea71ae 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -123,7 +123,6 @@ public: // Not great that these are public, but they have to be accessible // by non-class code and it's better than making them global. #if LL_X11 - // These are set up by the X11 clipboard initialization code Window mSDL_XWindowID; Display *mSDL_Display; #endif @@ -173,7 +172,6 @@ protected: BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); - void adjustCursorDecouple(bool warpingMouse = false); void fixWindowSize(void); U32 SDLCheckGrabbyKeys(SDLKey keysym, BOOL gain); BOOL SDLReallyCaptureInput(BOOL capture); @@ -186,10 +184,6 @@ protected: SDL_Surface * mWindow; std::string mWindowTitle; double mOriginalAspectRatio; - BOOL mCursorDecoupled; - S32 mCursorLastEventDeltaX; - S32 mCursorLastEventDeltaY; - BOOL mCursorIgnoreNextDelta; BOOL mNeedsResize; // Constructor figured out the window is too big, it needs a resize. LLCoordScreen mNeedsResizeSize; F32 mOverrideAspectRatio; @@ -206,12 +200,6 @@ protected: #if LL_X11 private: - // more X11 clipboard stuff - int init_x11clipboard(void); - void quit_x11clipboard(void); - int is_empty_x11clipboard(void); - void put_x11clipboard(int type, int srclen, const char *src); - void get_x11clipboard(int type, int *dstlen, char **dst); void x11_set_urgent(BOOL urgent); BOOL mFlashing; LLTimer mFlashTimer; -- cgit v1.2.3