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

Side by Side Diff: ui/base/x/x11_util.cc

Issue 7889040: Change X11 error handler override to allow easy X11 error checking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/base/x/x11_util.h" 9 #include "ui/base/x/x11_util.h"
10 10
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 static CachedPictFormats* formats = NULL; 58 static CachedPictFormats* formats = NULL;
59 if (!formats) 59 if (!formats)
60 formats = new CachedPictFormats(); 60 formats = new CachedPictFormats();
61 return formats; 61 return formats;
62 } 62 }
63 63
64 // Maximum number of CachedPictFormats we keep around. 64 // Maximum number of CachedPictFormats we keep around.
65 const size_t kMaxCacheSize = 5; 65 const size_t kMaxCacheSize = 5;
66 66
67 int DefaultX11ErrorHandler(Display* d, XErrorEvent* e) { 67 int DefaultX11ErrorHandler(Display* d, XErrorEvent* e) {
68 DCHECK(!MessageLoop::current() ||
69 MessageLoop::current()->type() == MessageLoop::TYPE_UI);
68 MessageLoop::current()->PostTask( 70 MessageLoop::current()->PostTask(
69 FROM_HERE, NewRunnableFunction(LogErrorEventDescription, d, *e)); 71 FROM_HERE, NewRunnableFunction(LogErrorEventDescription, d, *e));
70 return 0; 72 return 0;
71 } 73 }
72 74
73 int DefaultX11IOErrorHandler(Display* d) { 75 int DefaultX11IOErrorHandler(Display* d) {
74 // If there's an IO error it likely means the X server has gone away 76 // If there's an IO error it likely means the X server has gone away
75 LOG(ERROR) << "X IO Error detected"; 77 LOG(ERROR) << "X IO Error detected";
76 _exit(1); 78 _exit(1);
77 } 79 }
78 80
81 XErrorHandler current_error_handler = DefaultX11ErrorHandler;
82 XErrorEvent last_error_event = {0, NULL, 0, 0, 0, 0, 0 };
83
84 int BaseX11ErrorHandler(Display* d, XErrorEvent* e) {
85 last_error_event = *e;
86 return current_error_handler(d, e);
87 }
88
79 Atom GetAtom(const char* name) { 89 Atom GetAtom(const char* name) {
80 #if defined(TOOLKIT_USES_GTK) 90 #if defined(TOOLKIT_USES_GTK)
81 return gdk_x11_get_xatom_by_name_for_display( 91 return gdk_x11_get_xatom_by_name_for_display(
82 gdk_display_get_default(), name); 92 gdk_display_get_default(), name);
83 #else 93 #else
84 return XInternAtom(GetXDisplay(), name, false); 94 return XInternAtom(GetXDisplay(), name, false);
85 #endif 95 #endif
86 } 96 }
87 97
88 // Note: The caller should free the resulting value data. 98 // Note: The caller should free the resulting value data.
89 bool GetProperty(XID window, const std::string& property_name, long max_length, 99 bool GetProperty(XID window, const std::string& property_name, long max_length,
90 Atom* type, int* format, unsigned long* num_items, 100 Atom* type, int* format, unsigned long* num_items,
91 unsigned char** property) { 101 unsigned char** property) {
92 Atom property_atom = GetAtom(property_name.c_str()); 102 Atom property_atom = GetAtom(property_name.c_str());
93 unsigned long remaining_bytes = 0; 103 unsigned long remaining_bytes = 0;
94 return XGetWindowProperty(GetXDisplay(), 104 return XGetWindowProperty(GetXDisplay(),
95 window, 105 window,
96 property_atom, 106 property_atom,
97 0, // offset into property data to read 107 0, // offset into property data to read
98 max_length, // max length to get 108 max_length, // max length to get
99 False, // deleted 109 False, // deleted
100 AnyPropertyType, 110 AnyPropertyType,
101 type, 111 type,
102 format, 112 format,
103 num_items, 113 num_items,
104 &remaining_bytes, 114 &remaining_bytes,
105 property); 115 property);
106 } 116 }
107 117
118 std::string BuildX11ErrorString(const XErrorEvent& error_event) {
119 char error_str[256];
120 char request_str[256];
121
122 XGetErrorText(error_event.display, error_event.error_code, error_str,
123 sizeof(error_str));
124
125 strncpy(request_str, "Unknown", sizeof(request_str));
126 if (error_event.request_code < 128) {
127 std::string num = base::UintToString(error_event.request_code);
128 XGetErrorDatabaseText(error_event.display, "XRequest", num.c_str(),
129 "Unknown", request_str, sizeof(request_str));
130 } else {
131 int num_ext;
132 char** ext_list = XListExtensions(error_event.display, &num_ext);
133
134 for (int i = 0; i < num_ext; i++) {
135 int ext_code, first_event, first_error;
136 XQueryExtension(error_event.display, ext_list[i], &ext_code, &first_event,
137 &first_error);
138 if (error_event.request_code == ext_code) {
139 std::string msg = StringPrintf(
140 "%s.%d", ext_list[i], error_event.minor_code);
141 XGetErrorDatabaseText(error_event.display, "XRequest", msg.c_str(),
142 "Unknown", request_str, sizeof(request_str));
143 break;
144 }
145 }
146 XFreeExtensionList(ext_list);
147 }
148
149 std::ostringstream error_ss;
150 error_ss << "X Error detected: "
151 << "serial " << error_event.serial << ", "
152 << "error_code " << static_cast<int>(error_event.error_code)
153 << " (" << error_str << "), "
154 << "request_code " << static_cast<int>(error_event.request_code)
155 << ", "
156 << "minor_code " << static_cast<int>(error_event.minor_code)
157 << " (" << request_str << ")";
158 return error_ss.str();
159 }
160
108 } // namespace 161 } // namespace
109 162
110 bool XDisplayExists() { 163 bool XDisplayExists() {
111 return (GetXDisplay() != NULL); 164 return (GetXDisplay() != NULL);
112 } 165 }
113 166
114 Display* GetXDisplay() { 167 Display* GetXDisplay() {
115 return base::MessagePumpForUI::GetDefaultXDisplay(); 168 return base::MessagePumpForUI::GetDefaultXDisplay();
116 } 169 }
117 170
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 event.xclient.format = 32; 741 event.xclient.format = 32;
689 event.xclient.data.l[0] = desktop; 742 event.xclient.data.l[0] = desktop;
690 event.xclient.data.l[1] = 1; // source indication 743 event.xclient.data.l[1] = 1; // source indication
691 744
692 int result = XSendEvent(GetXDisplay(), GetX11RootWindow(), False, 745 int result = XSendEvent(GetXDisplay(), GetX11RootWindow(), False,
693 SubstructureNotifyMask, &event); 746 SubstructureNotifyMask, &event);
694 return result == Success; 747 return result == Success;
695 } 748 }
696 749
697 void SetDefaultX11ErrorHandlers() { 750 void SetDefaultX11ErrorHandlers() {
751 XSetErrorHandler(BaseX11ErrorHandler);
698 SetX11ErrorHandlers(NULL, NULL); 752 SetX11ErrorHandlers(NULL, NULL);
699 } 753 }
700 754
701 bool IsX11WindowFullScreen(XID window) { 755 bool IsX11WindowFullScreen(XID window) {
702 // First check if _NET_WM_STATE property contains _NET_WM_STATE_FULLSCREEN. 756 // First check if _NET_WM_STATE property contains _NET_WM_STATE_FULLSCREEN.
703 static Atom atom = GetAtom("_NET_WM_STATE_FULLSCREEN"); 757 static Atom atom = GetAtom("_NET_WM_STATE_FULLSCREEN");
704 758
705 std::vector<Atom> atom_properties; 759 std::vector<Atom> atom_properties;
706 if (GetAtomArrayProperty(window, 760 if (GetAtomArrayProperty(window,
707 "_NET_WM_STATE", 761 "_NET_WM_STATE",
(...skipping 15 matching lines...) Expand all
723 return monitor_rect.x == window_rect.x() && 777 return monitor_rect.x == window_rect.x() &&
724 monitor_rect.y == window_rect.y() && 778 monitor_rect.y == window_rect.y() &&
725 monitor_rect.width == window_rect.width() && 779 monitor_rect.width == window_rect.width() &&
726 monitor_rect.height == window_rect.height(); 780 monitor_rect.height == window_rect.height();
727 #else 781 #else
728 NOTIMPLEMENTED(); 782 NOTIMPLEMENTED();
729 return false; 783 return false;
730 #endif 784 #endif
731 } 785 }
732 786
787 void CheckForReportedX11Error() {
788 DCHECK(!MessageLoop::current() ||
789 MessageLoop::current()->type() == MessageLoop::TYPE_UI);
790 if (!last_error_event.display)
791 return;
792 XSync(last_error_event.display, False);
793 LOG(FATAL) << BuildX11ErrorString(last_error_event);
794 }
795
733 // ---------------------------------------------------------------------------- 796 // ----------------------------------------------------------------------------
734 // These functions are declared in x11_util_internal.h because they require 797 // These functions are declared in x11_util_internal.h because they require
735 // XLib.h to be included, and it conflicts with many other headers. 798 // XLib.h to be included, and it conflicts with many other headers.
736 XRenderPictFormat* GetRenderARGB32Format(Display* dpy) { 799 XRenderPictFormat* GetRenderARGB32Format(Display* dpy) {
737 static XRenderPictFormat* pictformat = NULL; 800 static XRenderPictFormat* pictformat = NULL;
738 if (pictformat) 801 if (pictformat)
739 return pictformat; 802 return pictformat;
740 803
741 // First look for a 32-bit format which ignores the alpha value 804 // First look for a 32-bit format which ignores the alpha value
742 XRenderPictFormat templ; 805 XRenderPictFormat templ;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 // always blowing away the cache. If we are, then we should figure out why 864 // always blowing away the cache. If we are, then we should figure out why
802 // and make it bigger. 865 // and make it bigger.
803 NOTREACHED(); 866 NOTREACHED();
804 } 867 }
805 868
806 return pictformat; 869 return pictformat;
807 } 870 }
808 871
809 void SetX11ErrorHandlers(XErrorHandler error_handler, 872 void SetX11ErrorHandlers(XErrorHandler error_handler,
810 XIOErrorHandler io_error_handler) { 873 XIOErrorHandler io_error_handler) {
811 XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler); 874 DCHECK(!MessageLoop::current() ||
812 XSetIOErrorHandler( 875 MessageLoop::current()->type() == MessageLoop::TYPE_UI);
813 io_error_handler ? io_error_handler : DefaultX11IOErrorHandler); 876 current_error_handler = error_handler ?
877 error_handler : DefaultX11ErrorHandler;
878 XSetIOErrorHandler(io_error_handler ?
879 io_error_handler : DefaultX11IOErrorHandler);
814 } 880 }
815 881
816 void LogErrorEventDescription(Display* dpy, 882 void LogErrorEventDescription(Display* dpy,
817 const XErrorEvent& error_event) { 883 const XErrorEvent& error_event) {
818 char error_str[256]; 884 DCHECK(!MessageLoop::current() ||
819 char request_str[256]; 885 MessageLoop::current()->type() == MessageLoop::TYPE_UI);
820 886 DCHECK_EQ(dpy, error_event.display)
821 XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str)); 887 << "Attempt to log error for mismatching X11 display.";
822 888 LOG(ERROR) << BuildX11ErrorString(error_event);
823 strncpy(request_str, "Unknown", sizeof(request_str));
824 if (error_event.request_code < 128) {
825 std::string num = base::UintToString(error_event.request_code);
826 XGetErrorDatabaseText(
827 dpy, "XRequest", num.c_str(), "Unknown", request_str,
828 sizeof(request_str));
829 } else {
830 int num_ext;
831 char** ext_list = XListExtensions(dpy, &num_ext);
832
833 for (int i = 0; i < num_ext; i++) {
834 int ext_code, first_event, first_error;
835 XQueryExtension(dpy, ext_list[i], &ext_code, &first_event, &first_error);
836 if (error_event.request_code == ext_code) {
837 std::string msg = StringPrintf(
838 "%s.%d", ext_list[i], error_event.minor_code);
839 XGetErrorDatabaseText(
840 dpy, "XRequest", msg.c_str(), "Unknown", request_str,
841 sizeof(request_str));
842 break;
843 }
844 }
845 XFreeExtensionList(ext_list);
846 }
847
848 LOG(ERROR)
849 << "X Error detected: "
850 << "serial " << error_event.serial << ", "
851 << "error_code " << static_cast<int>(error_event.error_code)
852 << " (" << error_str << "), "
853 << "request_code " << static_cast<int>(error_event.request_code) << ", "
854 << "minor_code " << static_cast<int>(error_event.minor_code)
855 << " (" << request_str << ")";
856 } 889 }
857 890
858 // ---------------------------------------------------------------------------- 891 // ----------------------------------------------------------------------------
859 // End of x11_util_internal.h 892 // End of x11_util_internal.h
860 893
861 894
862 } // namespace ui 895 } // namespace ui
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/vertex_attrib_manager_unittest.cc ('k') | ui/base/x/x11_util_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698