diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-10 20:40:34 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-10 20:40:34 +0000 |
commit | e66d704b2fb60846d399cc45cee04d26573725ec (patch) | |
tree | b49c9dcae3598793e373ee9923c6fcade700a625 /app/x11_util.cc | |
parent | c36a87afc467a1fd2eb4bb2309051bc8e45e4393 (diff) | |
download | chromium_src-e66d704b2fb60846d399cc45cee04d26573725ec.zip chromium_src-e66d704b2fb60846d399cc45cee04d26573725ec.tar.gz chromium_src-e66d704b2fb60846d399cc45cee04d26573725ec.tar.bz2 |
Allow overriding of X error functions
BUG=50006 (and various other reports)
TEST=Run chrome under nested window manager using Xephyr (see
http://code.google.com/p/chromium/wiki/LayoutTestsLinux)
use --enable-logging=stderr --log-level=0
kill xephyr
examine log. You should see
X IO Error detected
followed (not necessarily immediately) by
successfully saved /tmp/tx/Default/Preferences
successfully saved /tmp/tx/Local State
successfully saved /tmp/tx/Local State
successfully saved /tmp/tx/Default/Preferences
along with no crash.
There is a high ranking crash report on both linux and chromeos that happens whenever X sends an error to chrome. This change causes us to log and continue when we get a regular error from X. When we get an IO error, indicating X is gone, we attempt to shut down gracefully.
Review URL: http://codereview.chromium.org/3175038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59147 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app/x11_util.cc')
-rw-r--r-- | app/x11_util.cc | 188 |
1 files changed, 104 insertions, 84 deletions
diff --git a/app/x11_util.cc b/app/x11_util.cc index ba014dc..558fd67 100644 --- a/app/x11_util.cc +++ b/app/x11_util.cc @@ -20,6 +20,7 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/stringprintf.h" #include "base/thread.h" #include "app/x11_util_internal.h" #include "gfx/rect.h" @@ -53,26 +54,19 @@ CachedPictFormats* get_cached_pict_formats() { // Maximum number of CachedPictFormats we keep around. const size_t kMaxCacheSize = 5; -int X11ErrorHandler(Display* d, XErrorEvent* e) { - LOG(FATAL) << "X Error detected: serial " << e->serial - << " error_code " << static_cast<unsigned int>(e->error_code) - << " request_code " << static_cast<unsigned int>(e->request_code) - << " minor_code " << static_cast<unsigned int>(e->minor_code); +int DefaultX11ErrorHandler(Display* d, XErrorEvent* e) { + LOG(FATAL) << GetErrorEventDescription(e); return 0; } -int X11IOErrorHandler(Display* d) { +int DefaultX11IOErrorHandler(Display* d) { + // If there's an IO error it likely means the X server has gone away LOG(FATAL) << "X IO Error detected"; return 0; } } // namespace -void SetX11ErrorHandlers() { - XSetErrorHandler(X11ErrorHandler); - XSetIOErrorHandler(X11IOErrorHandler); -} - bool XDisplayExists() { return (gdk_display_get_default() != NULL); } @@ -461,79 +455,6 @@ void RestackWindow(XID window, XID sibling, bool above) { XConfigureWindow(GetXDisplay(), window, CWSibling | CWStackMode, &changes); } -XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) { - DCHECK(QueryRenderSupport(dpy)); - - CachedPictFormats* formats = get_cached_pict_formats(); - - for (CachedPictFormats::const_iterator i = formats->begin(); - i != formats->end(); ++i) { - if (i->equals(dpy, visual)) - return i->format; - } - - // Not cached, look up the value. - XRenderPictFormat* pictformat = XRenderFindVisualFormat(dpy, visual); - CHECK(pictformat) << "XRENDER does not support default visual"; - - // And store it in the cache. - CachedPictFormat cached_value; - cached_value.visual = visual; - cached_value.display = dpy; - cached_value.format = pictformat; - formats->push_front(cached_value); - - if (formats->size() == kMaxCacheSize) { - formats->pop_back(); - // We should really only have at most 2 display/visual combinations: - // one for normal browser windows, and possibly another for an argb window - // created to display a menu. - // - // If we get here it's not fatal, we just need to make sure we aren't - // always blowing away the cache. If we are, then we should figure out why - // and make it bigger. - NOTREACHED(); - } - - return pictformat; -} - -XRenderPictFormat* GetRenderARGB32Format(Display* dpy) { - static XRenderPictFormat* pictformat = NULL; - if (pictformat) - return pictformat; - - // First look for a 32-bit format which ignores the alpha value - XRenderPictFormat templ; - templ.depth = 32; - templ.type = PictTypeDirect; - templ.direct.red = 16; - templ.direct.green = 8; - templ.direct.blue = 0; - templ.direct.redMask = 0xff; - templ.direct.greenMask = 0xff; - templ.direct.blueMask = 0xff; - templ.direct.alphaMask = 0; - - static const unsigned long kMask = - PictFormatType | PictFormatDepth | - PictFormatRed | PictFormatRedMask | - PictFormatGreen | PictFormatGreenMask | - PictFormatBlue | PictFormatBlueMask | - PictFormatAlphaMask; - - pictformat = XRenderFindFormat(dpy, kMask, &templ, 0 /* first result */); - - if (!pictformat) { - // Not all X servers support xRGB32 formats. However, the XRENDER spec says - // that they must support an ARGB32 format, so we can always return that. - pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32); - CHECK(pictformat) << "XRENDER ARGB32 not supported."; - } - - return pictformat; -} - XSharedMemoryId AttachSharedMemory(Display* display, int shared_memory_key) { DCHECK(QuerySharedMemorySupport(display)); @@ -826,4 +747,103 @@ bool ChangeWindowDesktop(XID window, XID destination) { return result == Success; } +void SetDefaultX11ErrorHandlers() { + SetX11ErrorHandlers(NULL, NULL); +} + +// ---------------------------------------------------------------------------- +// These functions are declared in x11_util_internal.h because they require +// XLib.h to be included, and it conflicts with many other headers. +XRenderPictFormat* GetRenderARGB32Format(Display* dpy) { + static XRenderPictFormat* pictformat = NULL; + if (pictformat) + return pictformat; + + // First look for a 32-bit format which ignores the alpha value + XRenderPictFormat templ; + templ.depth = 32; + templ.type = PictTypeDirect; + templ.direct.red = 16; + templ.direct.green = 8; + templ.direct.blue = 0; + templ.direct.redMask = 0xff; + templ.direct.greenMask = 0xff; + templ.direct.blueMask = 0xff; + templ.direct.alphaMask = 0; + + static const unsigned long kMask = + PictFormatType | PictFormatDepth | + PictFormatRed | PictFormatRedMask | + PictFormatGreen | PictFormatGreenMask | + PictFormatBlue | PictFormatBlueMask | + PictFormatAlphaMask; + + pictformat = XRenderFindFormat(dpy, kMask, &templ, 0 /* first result */); + + if (!pictformat) { + // Not all X servers support xRGB32 formats. However, the XRENDER spec says + // that they must support an ARGB32 format, so we can always return that. + pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32); + CHECK(pictformat) << "XRENDER ARGB32 not supported."; + } + + return pictformat; +} + +XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) { + DCHECK(QueryRenderSupport(dpy)); + + CachedPictFormats* formats = get_cached_pict_formats(); + + for (CachedPictFormats::const_iterator i = formats->begin(); + i != formats->end(); ++i) { + if (i->equals(dpy, visual)) + return i->format; + } + + // Not cached, look up the value. + XRenderPictFormat* pictformat = XRenderFindVisualFormat(dpy, visual); + CHECK(pictformat) << "XRENDER does not support default visual"; + + // And store it in the cache. + CachedPictFormat cached_value; + cached_value.visual = visual; + cached_value.display = dpy; + cached_value.format = pictformat; + formats->push_front(cached_value); + + if (formats->size() == kMaxCacheSize) { + formats->pop_back(); + // We should really only have at most 2 display/visual combinations: + // one for normal browser windows, and possibly another for an argb window + // created to display a menu. + // + // If we get here it's not fatal, we just need to make sure we aren't + // always blowing away the cache. If we are, then we should figure out why + // and make it bigger. + NOTREACHED(); + } + + return pictformat; +} + +void SetX11ErrorHandlers(XErrorHandler error_handler, + XIOErrorHandler io_error_handler) { + XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler); + XSetIOErrorHandler( + io_error_handler ? io_error_handler : DefaultX11IOErrorHandler); +} + +std::string GetErrorEventDescription(XErrorEvent* error_event) { + return base::StringPrintf( + "X Error detected: %lu error_code %u request_code %u minor_code %u", + error_event->serial, + error_event->error_code, + error_event->request_code, + error_event->minor_code); +} +// ---------------------------------------------------------------------------- +// End of x11_util_internal.h + + } // namespace x11_util |