Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: app/x11_util.cc

Issue 3175038: Allow overriding of X error functions (Closed)
Patch Set: Messed up #ifdef Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « app/x11_util.h ('k') | app/x11_util_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file defines utility functions for X11 (Linux only). This code has been 5 // This file defines utility functions for X11 (Linux only). This code has been
6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support
7 // remains woefully incomplete. 7 // remains woefully incomplete.
8 8
9 #include "app/x11_util.h" 9 #include "app/x11_util.h"
10 10
11 #include <gdk/gdk.h> 11 #include <gdk/gdk.h>
12 #include <gdk/gdkx.h> 12 #include <gdk/gdkx.h>
13 #include <gtk/gtk.h> 13 #include <gtk/gtk.h>
14 14
15 #include <sys/ipc.h> 15 #include <sys/ipc.h>
16 #include <sys/shm.h> 16 #include <sys/shm.h>
17 17
18 #include <list> 18 #include <list>
19 #include <set> 19 #include <set>
20 20
21 #include "base/command_line.h" 21 #include "base/command_line.h"
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/stringprintf.h"
23 #include "base/thread.h" 24 #include "base/thread.h"
24 #include "app/x11_util_internal.h" 25 #include "app/x11_util_internal.h"
25 #include "gfx/rect.h" 26 #include "gfx/rect.h"
26 #include "gfx/size.h" 27 #include "gfx/size.h"
27 28
28 namespace x11_util { 29 namespace x11_util {
29 30
30 namespace { 31 namespace {
31 32
32 // Used to cache the XRenderPictFormat for a visual/display pair. 33 // Used to cache the XRenderPictFormat for a visual/display pair.
(...skipping 13 matching lines...) Expand all
46 CachedPictFormats* get_cached_pict_formats() { 47 CachedPictFormats* get_cached_pict_formats() {
47 static CachedPictFormats* formats = NULL; 48 static CachedPictFormats* formats = NULL;
48 if (!formats) 49 if (!formats)
49 formats = new CachedPictFormats(); 50 formats = new CachedPictFormats();
50 return formats; 51 return formats;
51 } 52 }
52 53
53 // Maximum number of CachedPictFormats we keep around. 54 // Maximum number of CachedPictFormats we keep around.
54 const size_t kMaxCacheSize = 5; 55 const size_t kMaxCacheSize = 5;
55 56
56 int X11ErrorHandler(Display* d, XErrorEvent* e) { 57 int DefaultX11ErrorHandler(Display* d, XErrorEvent* e) {
57 LOG(FATAL) << "X Error detected: serial " << e->serial 58 LOG(FATAL) << GetErrorEventDescription(e);
58 << " error_code " << static_cast<unsigned int>(e->error_code)
59 << " request_code " << static_cast<unsigned int>(e->request_code)
60 << " minor_code " << static_cast<unsigned int>(e->minor_code);
61 return 0; 59 return 0;
62 } 60 }
63 61
64 int X11IOErrorHandler(Display* d) { 62 int DefaultX11IOErrorHandler(Display* d) {
63 // If there's an IO error it likely means the X server has gone away
65 LOG(FATAL) << "X IO Error detected"; 64 LOG(FATAL) << "X IO Error detected";
66 return 0; 65 return 0;
67 } 66 }
68 67
69 } // namespace 68 } // namespace
70 69
71 void SetX11ErrorHandlers() {
72 XSetErrorHandler(X11ErrorHandler);
73 XSetIOErrorHandler(X11IOErrorHandler);
74 }
75
76 bool XDisplayExists() { 70 bool XDisplayExists() {
77 return (gdk_display_get_default() != NULL); 71 return (gdk_display_get_default() != NULL);
78 } 72 }
79 73
80 Display* GetXDisplay() { 74 Display* GetXDisplay() {
81 static Display* display = NULL; 75 static Display* display = NULL;
82 76
83 if (!display) 77 if (!display)
84 display = gdk_x11_get_default_xdisplay(); 78 display = gdk_x11_get_default_xdisplay();
85 79
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 return result; 448 return result;
455 } 449 }
456 450
457 void RestackWindow(XID window, XID sibling, bool above) { 451 void RestackWindow(XID window, XID sibling, bool above) {
458 XWindowChanges changes; 452 XWindowChanges changes;
459 changes.sibling = sibling; 453 changes.sibling = sibling;
460 changes.stack_mode = above ? Above : Below; 454 changes.stack_mode = above ? Above : Below;
461 XConfigureWindow(GetXDisplay(), window, CWSibling | CWStackMode, &changes); 455 XConfigureWindow(GetXDisplay(), window, CWSibling | CWStackMode, &changes);
462 } 456 }
463 457
464 XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) {
465 DCHECK(QueryRenderSupport(dpy));
466
467 CachedPictFormats* formats = get_cached_pict_formats();
468
469 for (CachedPictFormats::const_iterator i = formats->begin();
470 i != formats->end(); ++i) {
471 if (i->equals(dpy, visual))
472 return i->format;
473 }
474
475 // Not cached, look up the value.
476 XRenderPictFormat* pictformat = XRenderFindVisualFormat(dpy, visual);
477 CHECK(pictformat) << "XRENDER does not support default visual";
478
479 // And store it in the cache.
480 CachedPictFormat cached_value;
481 cached_value.visual = visual;
482 cached_value.display = dpy;
483 cached_value.format = pictformat;
484 formats->push_front(cached_value);
485
486 if (formats->size() == kMaxCacheSize) {
487 formats->pop_back();
488 // We should really only have at most 2 display/visual combinations:
489 // one for normal browser windows, and possibly another for an argb window
490 // created to display a menu.
491 //
492 // If we get here it's not fatal, we just need to make sure we aren't
493 // always blowing away the cache. If we are, then we should figure out why
494 // and make it bigger.
495 NOTREACHED();
496 }
497
498 return pictformat;
499 }
500
501 XRenderPictFormat* GetRenderARGB32Format(Display* dpy) {
502 static XRenderPictFormat* pictformat = NULL;
503 if (pictformat)
504 return pictformat;
505
506 // First look for a 32-bit format which ignores the alpha value
507 XRenderPictFormat templ;
508 templ.depth = 32;
509 templ.type = PictTypeDirect;
510 templ.direct.red = 16;
511 templ.direct.green = 8;
512 templ.direct.blue = 0;
513 templ.direct.redMask = 0xff;
514 templ.direct.greenMask = 0xff;
515 templ.direct.blueMask = 0xff;
516 templ.direct.alphaMask = 0;
517
518 static const unsigned long kMask =
519 PictFormatType | PictFormatDepth |
520 PictFormatRed | PictFormatRedMask |
521 PictFormatGreen | PictFormatGreenMask |
522 PictFormatBlue | PictFormatBlueMask |
523 PictFormatAlphaMask;
524
525 pictformat = XRenderFindFormat(dpy, kMask, &templ, 0 /* first result */);
526
527 if (!pictformat) {
528 // Not all X servers support xRGB32 formats. However, the XRENDER spec says
529 // that they must support an ARGB32 format, so we can always return that.
530 pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32);
531 CHECK(pictformat) << "XRENDER ARGB32 not supported.";
532 }
533
534 return pictformat;
535 }
536
537 XSharedMemoryId AttachSharedMemory(Display* display, int shared_memory_key) { 458 XSharedMemoryId AttachSharedMemory(Display* display, int shared_memory_key) {
538 DCHECK(QuerySharedMemorySupport(display)); 459 DCHECK(QuerySharedMemorySupport(display));
539 460
540 XShmSegmentInfo shminfo; 461 XShmSegmentInfo shminfo;
541 memset(&shminfo, 0, sizeof(shminfo)); 462 memset(&shminfo, 0, sizeof(shminfo));
542 shminfo.shmid = shared_memory_key; 463 shminfo.shmid = shared_memory_key;
543 464
544 // This function is only called if QuerySharedMemorySupport returned true. In 465 // This function is only called if QuerySharedMemorySupport returned true. In
545 // which case we've already succeeded in having the X server attach to one of 466 // which case we've already succeeded in having the X server attach to one of
546 // our shared memory segments. 467 // our shared memory segments.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 gdk_display_get_default(), "_NET_WM_DESKTOP"); 740 gdk_display_get_default(), "_NET_WM_DESKTOP");
820 event.xclient.format = 32; 741 event.xclient.format = 32;
821 event.xclient.data.l[0] = desktop; 742 event.xclient.data.l[0] = desktop;
822 event.xclient.data.l[1] = 1; // source indication 743 event.xclient.data.l[1] = 1; // source indication
823 744
824 int result = XSendEvent(GetXDisplay(), GetX11RootWindow(), False, 745 int result = XSendEvent(GetXDisplay(), GetX11RootWindow(), False,
825 SubstructureNotifyMask, &event); 746 SubstructureNotifyMask, &event);
826 return result == Success; 747 return result == Success;
827 } 748 }
828 749
750 void SetDefaultX11ErrorHandlers() {
751 SetX11ErrorHandlers(NULL, NULL);
752 }
753
754 // ----------------------------------------------------------------------------
755 // These functions are declared in x11_util_internal.h because they require
756 // XLib.h to be included, and it conflicts with many other headers.
757 XRenderPictFormat* GetRenderARGB32Format(Display* dpy) {
758 static XRenderPictFormat* pictformat = NULL;
759 if (pictformat)
760 return pictformat;
761
762 // First look for a 32-bit format which ignores the alpha value
763 XRenderPictFormat templ;
764 templ.depth = 32;
765 templ.type = PictTypeDirect;
766 templ.direct.red = 16;
767 templ.direct.green = 8;
768 templ.direct.blue = 0;
769 templ.direct.redMask = 0xff;
770 templ.direct.greenMask = 0xff;
771 templ.direct.blueMask = 0xff;
772 templ.direct.alphaMask = 0;
773
774 static const unsigned long kMask =
775 PictFormatType | PictFormatDepth |
776 PictFormatRed | PictFormatRedMask |
777 PictFormatGreen | PictFormatGreenMask |
778 PictFormatBlue | PictFormatBlueMask |
779 PictFormatAlphaMask;
780
781 pictformat = XRenderFindFormat(dpy, kMask, &templ, 0 /* first result */);
782
783 if (!pictformat) {
784 // Not all X servers support xRGB32 formats. However, the XRENDER spec says
785 // that they must support an ARGB32 format, so we can always return that.
786 pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32);
787 CHECK(pictformat) << "XRENDER ARGB32 not supported.";
788 }
789
790 return pictformat;
791 }
792
793 XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) {
794 DCHECK(QueryRenderSupport(dpy));
795
796 CachedPictFormats* formats = get_cached_pict_formats();
797
798 for (CachedPictFormats::const_iterator i = formats->begin();
799 i != formats->end(); ++i) {
800 if (i->equals(dpy, visual))
801 return i->format;
802 }
803
804 // Not cached, look up the value.
805 XRenderPictFormat* pictformat = XRenderFindVisualFormat(dpy, visual);
806 CHECK(pictformat) << "XRENDER does not support default visual";
807
808 // And store it in the cache.
809 CachedPictFormat cached_value;
810 cached_value.visual = visual;
811 cached_value.display = dpy;
812 cached_value.format = pictformat;
813 formats->push_front(cached_value);
814
815 if (formats->size() == kMaxCacheSize) {
816 formats->pop_back();
817 // We should really only have at most 2 display/visual combinations:
818 // one for normal browser windows, and possibly another for an argb window
819 // created to display a menu.
820 //
821 // If we get here it's not fatal, we just need to make sure we aren't
822 // always blowing away the cache. If we are, then we should figure out why
823 // and make it bigger.
824 NOTREACHED();
825 }
826
827 return pictformat;
828 }
829
830 void SetX11ErrorHandlers(XErrorHandler error_handler,
831 XIOErrorHandler io_error_handler) {
832 XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler);
833 XSetIOErrorHandler(
834 io_error_handler ? io_error_handler : DefaultX11IOErrorHandler);
835 }
836
837 std::string GetErrorEventDescription(XErrorEvent* error_event) {
838 return base::StringPrintf(
839 "X Error detected: %lu error_code %u request_code %u minor_code %u",
840 error_event->serial,
841 error_event->error_code,
842 error_event->request_code,
843 error_event->minor_code);
844 }
845 // ----------------------------------------------------------------------------
846 // End of x11_util_internal.h
847
848
829 } // namespace x11_util 849 } // namespace x11_util
OLDNEW
« no previous file with comments | « app/x11_util.h ('k') | app/x11_util_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698