| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 #include "ui/gfx/gdk_compat.h" | 65 #include "ui/gfx/gdk_compat.h" |
| 66 #include "ui/gfx/gtk_compat.h" | 66 #include "ui/gfx/gtk_compat.h" |
| 67 #endif | 67 #endif |
| 68 | 68 |
| 69 namespace ui { | 69 namespace ui { |
| 70 | 70 |
| 71 namespace { | 71 namespace { |
| 72 | 72 |
| 73 // Used to cache the XRenderPictFormat for a visual/display pair. | 73 // Used to cache the XRenderPictFormat for a visual/display pair. |
| 74 struct CachedPictFormat { | 74 struct CachedPictFormat { |
| 75 bool equals(Display* display, Visual* visual) const { | 75 bool equals(XDisplay* display, Visual* visual) const { |
| 76 return display == this->display && visual == this->visual; | 76 return display == this->display && visual == this->visual; |
| 77 } | 77 } |
| 78 | 78 |
| 79 Display* display; | 79 XDisplay* display; |
| 80 Visual* visual; | 80 Visual* visual; |
| 81 XRenderPictFormat* format; | 81 XRenderPictFormat* format; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 typedef std::list<CachedPictFormat> CachedPictFormats; | 84 typedef std::list<CachedPictFormat> CachedPictFormats; |
| 85 | 85 |
| 86 // Returns the cache of pict formats. | 86 // Returns the cache of pict formats. |
| 87 CachedPictFormats* get_cached_pict_formats() { | 87 CachedPictFormats* get_cached_pict_formats() { |
| 88 static CachedPictFormats* formats = NULL; | 88 static CachedPictFormats* formats = NULL; |
| 89 if (!formats) | 89 if (!formats) |
| 90 formats = new CachedPictFormats(); | 90 formats = new CachedPictFormats(); |
| 91 return formats; | 91 return formats; |
| 92 } | 92 } |
| 93 | 93 |
| 94 // Maximum number of CachedPictFormats we keep around. | 94 // Maximum number of CachedPictFormats we keep around. |
| 95 const size_t kMaxCacheSize = 5; | 95 const size_t kMaxCacheSize = 5; |
| 96 | 96 |
| 97 int DefaultX11ErrorHandler(Display* d, XErrorEvent* e) { | 97 int DefaultX11ErrorHandler(XDisplay* d, XErrorEvent* e) { |
| 98 if (base::MessageLoop::current()) { | 98 if (base::MessageLoop::current()) { |
| 99 base::MessageLoop::current()->PostTask( | 99 base::MessageLoop::current()->PostTask( |
| 100 FROM_HERE, base::Bind(&LogErrorEventDescription, d, *e)); | 100 FROM_HERE, base::Bind(&LogErrorEventDescription, d, *e)); |
| 101 } else { | 101 } else { |
| 102 LOG(ERROR) | 102 LOG(ERROR) |
| 103 << "X error received: " | 103 << "X error received: " |
| 104 << "serial " << e->serial << ", " | 104 << "serial " << e->serial << ", " |
| 105 << "error_code " << static_cast<int>(e->error_code) << ", " | 105 << "error_code " << static_cast<int>(e->error_code) << ", " |
| 106 << "request_code " << static_cast<int>(e->request_code) << ", " | 106 << "request_code " << static_cast<int>(e->request_code) << ", " |
| 107 << "minor_code " << static_cast<int>(e->minor_code); | 107 << "minor_code " << static_cast<int>(e->minor_code); |
| 108 } | 108 } |
| 109 return 0; | 109 return 0; |
| 110 } | 110 } |
| 111 | 111 |
| 112 int DefaultX11IOErrorHandler(Display* d) { | 112 int DefaultX11IOErrorHandler(XDisplay* d) { |
| 113 // If there's an IO error it likely means the X server has gone away | 113 // If there's an IO error it likely means the X server has gone away |
| 114 LOG(ERROR) << "X IO error received (X server probably went away)"; | 114 LOG(ERROR) << "X IO error received (X server probably went away)"; |
| 115 _exit(1); | 115 _exit(1); |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Note: The caller should free the resulting value data. | 118 // Note: The caller should free the resulting value data. |
| 119 bool GetProperty(XID window, const std::string& property_name, long max_length, | 119 bool GetProperty(XID window, const std::string& property_name, long max_length, |
| 120 Atom* type, int* format, unsigned long* num_items, | 120 Atom* type, int* format, unsigned long* num_items, |
| 121 unsigned char** property) { | 121 unsigned char** property) { |
| 122 Atom property_atom = GetAtom(property_name.c_str()); | 122 Atom property_atom = GetAtom(property_name.c_str()); |
| 123 unsigned long remaining_bytes = 0; | 123 unsigned long remaining_bytes = 0; |
| 124 return XGetWindowProperty(GetXDisplay(), | 124 return XGetWindowProperty(gfx::GetXDisplay(), |
| 125 window, | 125 window, |
| 126 property_atom, | 126 property_atom, |
| 127 0, // offset into property data to read | 127 0, // offset into property data to read |
| 128 max_length, // max length to get | 128 max_length, // max length to get |
| 129 False, // deleted | 129 False, // deleted |
| 130 AnyPropertyType, | 130 AnyPropertyType, |
| 131 type, | 131 type, |
| 132 format, | 132 format, |
| 133 num_items, | 133 num_items, |
| 134 &remaining_bytes, | 134 &remaining_bytes, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 152 case ui::ET_KEY_RELEASED: | 152 case ui::ET_KEY_RELEASED: |
| 153 return KeyRelease; | 153 return KeyRelease; |
| 154 default: | 154 default: |
| 155 return 0; | 155 return 0; |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 // Converts KeyboardCode to XKeyEvent keycode. | 159 // Converts KeyboardCode to XKeyEvent keycode. |
| 160 unsigned int XKeyEventKeyCode(ui::KeyboardCode key_code, | 160 unsigned int XKeyEventKeyCode(ui::KeyboardCode key_code, |
| 161 int flags, | 161 int flags, |
| 162 Display* display) { | 162 XDisplay* display) { |
| 163 const int keysym = XKeysymForWindowsKeyCode(key_code, | 163 const int keysym = XKeysymForWindowsKeyCode(key_code, |
| 164 flags & ui::EF_SHIFT_DOWN); | 164 flags & ui::EF_SHIFT_DOWN); |
| 165 // Tests assume the keycode for XK_less is equal to the one of XK_comma, | 165 // Tests assume the keycode for XK_less is equal to the one of XK_comma, |
| 166 // but XKeysymToKeycode returns 94 for XK_less while it returns 59 for | 166 // but XKeysymToKeycode returns 94 for XK_less while it returns 59 for |
| 167 // XK_comma. Here we convert the value for XK_less to the value for XK_comma. | 167 // XK_comma. Here we convert the value for XK_less to the value for XK_comma. |
| 168 return (keysym == XK_less) ? 59 : XKeysymToKeycode(display, keysym); | 168 return (keysym == XK_less) ? 59 : XKeysymToKeycode(display, keysym); |
| 169 } | 169 } |
| 170 | 170 |
| 171 // A process wide singleton that manages the usage of X cursors. | 171 // A process wide singleton that manages the usage of X cursors. |
| 172 class XCursorCache { | 172 class XCursorCache { |
| 173 public: | 173 public: |
| 174 XCursorCache() {} | 174 XCursorCache() {} |
| 175 ~XCursorCache() { | 175 ~XCursorCache() { |
| 176 Clear(); | 176 Clear(); |
| 177 } | 177 } |
| 178 | 178 |
| 179 ::Cursor GetCursor(int cursor_shape) { | 179 ::Cursor GetCursor(int cursor_shape) { |
| 180 // Lookup cursor by attempting to insert a null value, which avoids | 180 // Lookup cursor by attempting to insert a null value, which avoids |
| 181 // a second pass through the map after a cache miss. | 181 // a second pass through the map after a cache miss. |
| 182 std::pair<std::map<int, ::Cursor>::iterator, bool> it = cache_.insert( | 182 std::pair<std::map<int, ::Cursor>::iterator, bool> it = cache_.insert( |
| 183 std::make_pair(cursor_shape, 0)); | 183 std::make_pair(cursor_shape, 0)); |
| 184 if (it.second) { | 184 if (it.second) { |
| 185 Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); | 185 XDisplay* display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 186 it.first->second = XCreateFontCursor(display, cursor_shape); | 186 it.first->second = XCreateFontCursor(display, cursor_shape); |
| 187 } | 187 } |
| 188 return it.first->second; | 188 return it.first->second; |
| 189 } | 189 } |
| 190 | 190 |
| 191 void Clear() { | 191 void Clear() { |
| 192 Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); | 192 XDisplay* display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 193 for (std::map<int, ::Cursor>::iterator it = | 193 for (std::map<int, ::Cursor>::iterator it = |
| 194 cache_.begin(); it != cache_.end(); ++it) { | 194 cache_.begin(); it != cache_.end(); ++it) { |
| 195 XFreeCursor(display, it->second); | 195 XFreeCursor(display, it->second); |
| 196 } | 196 } |
| 197 cache_.clear(); | 197 cache_.clear(); |
| 198 } | 198 } |
| 199 | 199 |
| 200 private: | 200 private: |
| 201 // Maps X11 font cursor shapes to Cursor IDs. | 201 // Maps X11 font cursor shapes to Cursor IDs. |
| 202 std::map<int, ::Cursor> cache_; | 202 std::map<int, ::Cursor> cache_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 236 |
| 237 private: | 237 private: |
| 238 friend struct DefaultSingletonTraits<XCustomCursorCache>; | 238 friend struct DefaultSingletonTraits<XCustomCursorCache>; |
| 239 | 239 |
| 240 class XCustomCursor { | 240 class XCustomCursor { |
| 241 public: | 241 public: |
| 242 // This takes ownership of the image. | 242 // This takes ownership of the image. |
| 243 XCustomCursor(XcursorImage* image) | 243 XCustomCursor(XcursorImage* image) |
| 244 : image_(image), | 244 : image_(image), |
| 245 ref_(1) { | 245 ref_(1) { |
| 246 cursor_ = XcursorImageLoadCursor(GetXDisplay(), image); | 246 cursor_ = XcursorImageLoadCursor(gfx::GetXDisplay(), image); |
| 247 } | 247 } |
| 248 | 248 |
| 249 ~XCustomCursor() { | 249 ~XCustomCursor() { |
| 250 XcursorImageDestroy(image_); | 250 XcursorImageDestroy(image_); |
| 251 XFreeCursor(GetXDisplay(), cursor_); | 251 XFreeCursor(gfx::GetXDisplay(), cursor_); |
| 252 } | 252 } |
| 253 | 253 |
| 254 ::Cursor cursor() const { return cursor_; } | 254 ::Cursor cursor() const { return cursor_; } |
| 255 | 255 |
| 256 void Ref() { | 256 void Ref() { |
| 257 ++ref_; | 257 ++ref_; |
| 258 } | 258 } |
| 259 | 259 |
| 260 // Returns true if the cursor was destroyed because of the unref. | 260 // Returns true if the cursor was destroyed because of the unref. |
| 261 bool Unref() { | 261 bool Unref() { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 285 #endif // defined(USE_AURA) | 285 #endif // defined(USE_AURA) |
| 286 | 286 |
| 287 // A singleton object that remembers remappings of mouse buttons. | 287 // A singleton object that remembers remappings of mouse buttons. |
| 288 class XButtonMap { | 288 class XButtonMap { |
| 289 public: | 289 public: |
| 290 static XButtonMap* GetInstance() { | 290 static XButtonMap* GetInstance() { |
| 291 return Singleton<XButtonMap>::get(); | 291 return Singleton<XButtonMap>::get(); |
| 292 } | 292 } |
| 293 | 293 |
| 294 void UpdateMapping() { | 294 void UpdateMapping() { |
| 295 count_ = XGetPointerMapping(ui::GetXDisplay(), map_, arraysize(map_)); | 295 count_ = XGetPointerMapping(gfx::GetXDisplay(), map_, arraysize(map_)); |
| 296 } | 296 } |
| 297 | 297 |
| 298 int GetMappedButton(int button) { | 298 int GetMappedButton(int button) { |
| 299 return button > 0 && button <= count_ ? map_[button - 1] : button; | 299 return button > 0 && button <= count_ ? map_[button - 1] : button; |
| 300 } | 300 } |
| 301 | 301 |
| 302 private: | 302 private: |
| 303 friend struct DefaultSingletonTraits<XButtonMap>; | 303 friend struct DefaultSingletonTraits<XButtonMap>; |
| 304 | 304 |
| 305 XButtonMap() { | 305 XButtonMap() { |
| 306 UpdateMapping(); | 306 UpdateMapping(); |
| 307 } | 307 } |
| 308 | 308 |
| 309 ~XButtonMap() {} | 309 ~XButtonMap() {} |
| 310 | 310 |
| 311 unsigned char map_[256]; | 311 unsigned char map_[256]; |
| 312 int count_; | 312 int count_; |
| 313 | 313 |
| 314 DISALLOW_COPY_AND_ASSIGN(XButtonMap); | 314 DISALLOW_COPY_AND_ASSIGN(XButtonMap); |
| 315 }; | 315 }; |
| 316 | 316 |
| 317 bool IsShapeAvailable() { | 317 bool IsShapeAvailable() { |
| 318 int dummy; | 318 int dummy; |
| 319 static bool is_shape_available = | 319 static bool is_shape_available = |
| 320 XShapeQueryExtension(ui::GetXDisplay(), &dummy, &dummy); | 320 XShapeQueryExtension(gfx::GetXDisplay(), &dummy, &dummy); |
| 321 return is_shape_available; | 321 return is_shape_available; |
| 322 | 322 |
| 323 } | 323 } |
| 324 | 324 |
| 325 } // namespace | 325 } // namespace |
| 326 | 326 |
| 327 bool XDisplayExists() { | 327 bool XDisplayExists() { |
| 328 return (GetXDisplay() != NULL); | 328 return (gfx::GetXDisplay() != NULL); |
| 329 } | 329 } |
| 330 | 330 |
| 331 Display* GetXDisplay() { | 331 static SharedMemorySupport DoQuerySharedMemorySupport(XDisplay* dpy) { |
| 332 return base::MessagePumpForUI::GetDefaultXDisplay(); | |
| 333 } | |
| 334 | |
| 335 static SharedMemorySupport DoQuerySharedMemorySupport(Display* dpy) { | |
| 336 int dummy; | 332 int dummy; |
| 337 Bool pixmaps_supported; | 333 Bool pixmaps_supported; |
| 338 // Query the server's support for XSHM. | 334 // Query the server's support for XSHM. |
| 339 if (!XShmQueryVersion(dpy, &dummy, &dummy, &pixmaps_supported)) | 335 if (!XShmQueryVersion(dpy, &dummy, &dummy, &pixmaps_supported)) |
| 340 return SHARED_MEMORY_NONE; | 336 return SHARED_MEMORY_NONE; |
| 341 | 337 |
| 342 #if defined(OS_FREEBSD) | 338 #if defined(OS_FREEBSD) |
| 343 // On FreeBSD we can't access the shared memory after it was marked for | 339 // On FreeBSD we can't access the shared memory after it was marked for |
| 344 // deletion, unless this behaviour is explicitly enabled by the user. | 340 // deletion, unless this behaviour is explicitly enabled by the user. |
| 345 // In case it's not enabled disable shared memory support. | 341 // In case it's not enabled disable shared memory support. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 LOG(WARNING) << "X failed to attach to shared memory segment " << shmkey; | 378 LOG(WARNING) << "X failed to attach to shared memory segment " << shmkey; |
| 383 return SHARED_MEMORY_NONE; | 379 return SHARED_MEMORY_NONE; |
| 384 } | 380 } |
| 385 | 381 |
| 386 VLOG(1) << "X attached to shared memory segment " << shmkey; | 382 VLOG(1) << "X attached to shared memory segment " << shmkey; |
| 387 | 383 |
| 388 XShmDetach(dpy, &shminfo); | 384 XShmDetach(dpy, &shminfo); |
| 389 return pixmaps_supported ? SHARED_MEMORY_PIXMAP : SHARED_MEMORY_PUTIMAGE; | 385 return pixmaps_supported ? SHARED_MEMORY_PIXMAP : SHARED_MEMORY_PUTIMAGE; |
| 390 } | 386 } |
| 391 | 387 |
| 392 SharedMemorySupport QuerySharedMemorySupport(Display* dpy) { | 388 SharedMemorySupport QuerySharedMemorySupport(XDisplay* dpy) { |
| 393 static SharedMemorySupport shared_memory_support = SHARED_MEMORY_NONE; | 389 static SharedMemorySupport shared_memory_support = SHARED_MEMORY_NONE; |
| 394 static bool shared_memory_support_cached = false; | 390 static bool shared_memory_support_cached = false; |
| 395 | 391 |
| 396 if (shared_memory_support_cached) | 392 if (shared_memory_support_cached) |
| 397 return shared_memory_support; | 393 return shared_memory_support; |
| 398 | 394 |
| 399 shared_memory_support = DoQuerySharedMemorySupport(dpy); | 395 shared_memory_support = DoQuerySharedMemorySupport(dpy); |
| 400 shared_memory_support_cached = true; | 396 shared_memory_support_cached = true; |
| 401 | 397 |
| 402 return shared_memory_support; | 398 return shared_memory_support; |
| 403 } | 399 } |
| 404 | 400 |
| 405 bool QueryRenderSupport(Display* dpy) { | 401 bool QueryRenderSupport(XDisplay* dpy) { |
| 406 static bool render_supported = false; | 402 static bool render_supported = false; |
| 407 static bool render_supported_cached = false; | 403 static bool render_supported_cached = false; |
| 408 | 404 |
| 409 if (render_supported_cached) | 405 if (render_supported_cached) |
| 410 return render_supported; | 406 return render_supported; |
| 411 | 407 |
| 412 // We don't care about the version of Xrender since all the features which | 408 // We don't care about the version of Xrender since all the features which |
| 413 // we use are included in every version. | 409 // we use are included in every version. |
| 414 int dummy; | 410 int dummy; |
| 415 render_supported = XRenderQueryExtension(dpy, &dummy, &dummy); | 411 render_supported = XRenderQueryExtension(dpy, &dummy, &dummy); |
| 416 render_supported_cached = true; | 412 render_supported_cached = true; |
| 417 | 413 |
| 418 return render_supported; | 414 return render_supported; |
| 419 } | 415 } |
| 420 | 416 |
| 421 int GetDefaultScreen(Display* display) { | 417 int GetDefaultScreen(XDisplay* display) { |
| 422 return XDefaultScreen(display); | 418 return XDefaultScreen(display); |
| 423 } | 419 } |
| 424 | 420 |
| 425 ::Cursor GetXCursor(int cursor_shape) { | 421 ::Cursor GetXCursor(int cursor_shape) { |
| 426 if (!cursor_cache) | 422 if (!cursor_cache) |
| 427 cursor_cache = new XCursorCache; | 423 cursor_cache = new XCursorCache; |
| 428 return cursor_cache->GetCursor(cursor_shape); | 424 return cursor_cache->GetCursor(cursor_shape); |
| 429 } | 425 } |
| 430 | 426 |
| 431 void ResetXCursorCache() { | 427 void ResetXCursorCache() { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 } | 482 } |
| 487 | 483 |
| 488 return image; | 484 return image; |
| 489 } | 485 } |
| 490 | 486 |
| 491 | 487 |
| 492 int CoalescePendingMotionEvents(const XEvent* xev, | 488 int CoalescePendingMotionEvents(const XEvent* xev, |
| 493 XEvent* last_event) { | 489 XEvent* last_event) { |
| 494 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 490 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 495 int num_coalesced = 0; | 491 int num_coalesced = 0; |
| 496 Display* display = xev->xany.display; | 492 XDisplay* display = xev->xany.display; |
| 497 int event_type = xev->xgeneric.evtype; | 493 int event_type = xev->xgeneric.evtype; |
| 498 | 494 |
| 499 DCHECK_EQ(event_type, XI_Motion); | 495 DCHECK_EQ(event_type, XI_Motion); |
| 500 | 496 |
| 501 while (XPending(display)) { | 497 while (XPending(display)) { |
| 502 XEvent next_event; | 498 XEvent next_event; |
| 503 XPeekEvent(display, &next_event); | 499 XPeekEvent(display, &next_event); |
| 504 | 500 |
| 505 // If we can't get the cookie, abort the check. | 501 // If we can't get the cookie, abort the check. |
| 506 if (!XGetEventData(next_event.xgeneric.display, &next_event.xcookie)) | 502 if (!XGetEventData(next_event.xgeneric.display, &next_event.xcookie)) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 ui::EventTimeFromNative(const_cast<XEvent*>(xev)); | 552 ui::EventTimeFromNative(const_cast<XEvent*>(xev)); |
| 557 UMA_HISTOGRAM_COUNTS_10000("Event.CoalescedCount.Mouse", num_coalesced); | 553 UMA_HISTOGRAM_COUNTS_10000("Event.CoalescedCount.Mouse", num_coalesced); |
| 558 UMA_HISTOGRAM_TIMES("Event.CoalescedLatency.Mouse", delta); | 554 UMA_HISTOGRAM_TIMES("Event.CoalescedLatency.Mouse", delta); |
| 559 } | 555 } |
| 560 return num_coalesced; | 556 return num_coalesced; |
| 561 } | 557 } |
| 562 #endif | 558 #endif |
| 563 | 559 |
| 564 void HideHostCursor() { | 560 void HideHostCursor() { |
| 565 CR_DEFINE_STATIC_LOCAL(XScopedCursor, invisible_cursor, | 561 CR_DEFINE_STATIC_LOCAL(XScopedCursor, invisible_cursor, |
| 566 (CreateInvisibleCursor(), ui::GetXDisplay())); | 562 (CreateInvisibleCursor(), gfx::GetXDisplay())); |
| 567 XDefineCursor(ui::GetXDisplay(), DefaultRootWindow(ui::GetXDisplay()), | 563 XDefineCursor(gfx::GetXDisplay(), DefaultRootWindow(gfx::GetXDisplay()), |
| 568 invisible_cursor.get()); | 564 invisible_cursor.get()); |
| 569 } | 565 } |
| 570 | 566 |
| 571 ::Cursor CreateInvisibleCursor() { | 567 ::Cursor CreateInvisibleCursor() { |
| 572 Display* xdisplay = ui::GetXDisplay(); | 568 XDisplay* xdisplay = gfx::GetXDisplay(); |
| 573 ::Cursor invisible_cursor; | 569 ::Cursor invisible_cursor; |
| 574 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 570 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 575 XColor black; | 571 XColor black; |
| 576 black.red = black.green = black.blue = 0; | 572 black.red = black.green = black.blue = 0; |
| 577 Pixmap blank = XCreateBitmapFromData(xdisplay, | 573 Pixmap blank = XCreateBitmapFromData(xdisplay, |
| 578 DefaultRootWindow(xdisplay), | 574 DefaultRootWindow(xdisplay), |
| 579 nodata, 8, 8); | 575 nodata, 8, 8); |
| 580 invisible_cursor = XCreatePixmapCursor(xdisplay, blank, blank, | 576 invisible_cursor = XCreatePixmapCursor(xdisplay, blank, blank, |
| 581 &black, &black, 0, 0); | 577 &black, &black, 0, 0); |
| 582 XFreePixmap(xdisplay, blank); | 578 XFreePixmap(xdisplay, blank); |
| 583 return invisible_cursor; | 579 return invisible_cursor; |
| 584 } | 580 } |
| 585 | 581 |
| 586 XID GetX11RootWindow() { | 582 XID GetX11RootWindow() { |
| 587 return DefaultRootWindow(GetXDisplay()); | 583 return DefaultRootWindow(gfx::GetXDisplay()); |
| 588 } | 584 } |
| 589 | 585 |
| 590 bool GetCurrentDesktop(int* desktop) { | 586 bool GetCurrentDesktop(int* desktop) { |
| 591 return GetIntProperty(GetX11RootWindow(), "_NET_CURRENT_DESKTOP", desktop); | 587 return GetIntProperty(GetX11RootWindow(), "_NET_CURRENT_DESKTOP", desktop); |
| 592 } | 588 } |
| 593 | 589 |
| 594 #if defined(TOOLKIT_GTK) | 590 #if defined(TOOLKIT_GTK) |
| 595 XID GetX11WindowFromGtkWidget(GtkWidget* widget) { | 591 XID GetX11WindowFromGtkWidget(GtkWidget* widget) { |
| 596 return GDK_WINDOW_XID(gtk_widget_get_window(widget)); | 592 return GDK_WINDOW_XID(gtk_widget_get_window(widget)); |
| 597 } | 593 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 614 } | 610 } |
| 615 | 611 |
| 616 void* GetVisualFromGtkWidget(GtkWidget* widget) { | 612 void* GetVisualFromGtkWidget(GtkWidget* widget) { |
| 617 return GDK_VISUAL_XVISUAL(gtk_widget_get_visual(widget)); | 613 return GDK_VISUAL_XVISUAL(gtk_widget_get_visual(widget)); |
| 618 } | 614 } |
| 619 #endif // defined(TOOLKIT_GTK) | 615 #endif // defined(TOOLKIT_GTK) |
| 620 | 616 |
| 621 void SetHideTitlebarWhenMaximizedProperty(XID window, | 617 void SetHideTitlebarWhenMaximizedProperty(XID window, |
| 622 HideTitlebarWhenMaximized property) { | 618 HideTitlebarWhenMaximized property) { |
| 623 uint32 hide = property; | 619 uint32 hide = property; |
| 624 XChangeProperty(GetXDisplay(), | 620 XChangeProperty(gfx::GetXDisplay(), |
| 625 window, | 621 window, |
| 626 GetAtom("_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"), | 622 GetAtom("_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"), |
| 627 XA_CARDINAL, | 623 XA_CARDINAL, |
| 628 32, // size in bits | 624 32, // size in bits |
| 629 PropModeReplace, | 625 PropModeReplace, |
| 630 reinterpret_cast<unsigned char*>(&hide), | 626 reinterpret_cast<unsigned char*>(&hide), |
| 631 1); | 627 1); |
| 632 } | 628 } |
| 633 | 629 |
| 634 void ClearX11DefaultRootWindow() { | 630 void ClearX11DefaultRootWindow() { |
| 635 Display* display = GetXDisplay(); | 631 XDisplay* display = gfx::GetXDisplay(); |
| 636 XID root_window = GetX11RootWindow(); | 632 XID root_window = GetX11RootWindow(); |
| 637 gfx::Rect root_bounds; | 633 gfx::Rect root_bounds; |
| 638 if (!GetWindowRect(root_window, &root_bounds)) { | 634 if (!GetWindowRect(root_window, &root_bounds)) { |
| 639 LOG(ERROR) << "Failed to get the bounds of the X11 root window"; | 635 LOG(ERROR) << "Failed to get the bounds of the X11 root window"; |
| 640 return; | 636 return; |
| 641 } | 637 } |
| 642 | 638 |
| 643 XGCValues gc_values = {0}; | 639 XGCValues gc_values = {0}; |
| 644 gc_values.foreground = BlackPixel(display, DefaultScreen(display)); | 640 gc_values.foreground = BlackPixel(display, DefaultScreen(display)); |
| 645 GC gc = XCreateGC(display, root_window, GCForeground, &gc_values); | 641 GC gc = XCreateGC(display, root_window, GCForeground, &gc_values); |
| 646 XFillRectangle(display, root_window, gc, | 642 XFillRectangle(display, root_window, gc, |
| 647 root_bounds.x(), | 643 root_bounds.x(), |
| 648 root_bounds.y(), | 644 root_bounds.y(), |
| 649 root_bounds.width(), | 645 root_bounds.width(), |
| 650 root_bounds.height()); | 646 root_bounds.height()); |
| 651 XFreeGC(display, gc); | 647 XFreeGC(display, gc); |
| 652 } | 648 } |
| 653 | 649 |
| 654 int BitsPerPixelForPixmapDepth(Display* dpy, int depth) { | 650 int BitsPerPixelForPixmapDepth(XDisplay* dpy, int depth) { |
| 655 int count; | 651 int count; |
| 656 XPixmapFormatValues* formats = XListPixmapFormats(dpy, &count); | 652 XPixmapFormatValues* formats = XListPixmapFormats(dpy, &count); |
| 657 if (!formats) | 653 if (!formats) |
| 658 return -1; | 654 return -1; |
| 659 | 655 |
| 660 int bits_per_pixel = -1; | 656 int bits_per_pixel = -1; |
| 661 for (int i = 0; i < count; ++i) { | 657 for (int i = 0; i < count; ++i) { |
| 662 if (formats[i].depth == depth) { | 658 if (formats[i].depth == depth) { |
| 663 bits_per_pixel = formats[i].bits_per_pixel; | 659 bits_per_pixel = formats[i].bits_per_pixel; |
| 664 break; | 660 break; |
| 665 } | 661 } |
| 666 } | 662 } |
| 667 | 663 |
| 668 XFree(formats); | 664 XFree(formats); |
| 669 return bits_per_pixel; | 665 return bits_per_pixel; |
| 670 } | 666 } |
| 671 | 667 |
| 672 bool IsWindowVisible(XID window) { | 668 bool IsWindowVisible(XID window) { |
| 673 XWindowAttributes win_attributes; | 669 XWindowAttributes win_attributes; |
| 674 if (!XGetWindowAttributes(GetXDisplay(), window, &win_attributes)) | 670 if (!XGetWindowAttributes(gfx::GetXDisplay(), window, &win_attributes)) |
| 675 return false; | 671 return false; |
| 676 if (win_attributes.map_state != IsViewable) | 672 if (win_attributes.map_state != IsViewable) |
| 677 return false; | 673 return false; |
| 678 // Some compositing window managers (notably kwin) do not actually unmap | 674 // Some compositing window managers (notably kwin) do not actually unmap |
| 679 // windows on desktop switch, so we also must check the current desktop. | 675 // windows on desktop switch, so we also must check the current desktop. |
| 680 int window_desktop, current_desktop; | 676 int window_desktop, current_desktop; |
| 681 return (!GetWindowDesktop(window, &window_desktop) || | 677 return (!GetWindowDesktop(window, &window_desktop) || |
| 682 !GetCurrentDesktop(¤t_desktop) || | 678 !GetCurrentDesktop(¤t_desktop) || |
| 683 window_desktop == kAllDesktops || | 679 window_desktop == kAllDesktops || |
| 684 window_desktop == current_desktop); | 680 window_desktop == current_desktop); |
| 685 } | 681 } |
| 686 | 682 |
| 687 bool GetWindowRect(XID window, gfx::Rect* rect) { | 683 bool GetWindowRect(XID window, gfx::Rect* rect) { |
| 688 Window root, child; | 684 Window root, child; |
| 689 int x, y; | 685 int x, y; |
| 690 unsigned int width, height; | 686 unsigned int width, height; |
| 691 unsigned int border_width, depth; | 687 unsigned int border_width, depth; |
| 692 | 688 |
| 693 if (!XGetGeometry(GetXDisplay(), window, &root, &x, &y, | 689 if (!XGetGeometry(gfx::GetXDisplay(), window, &root, &x, &y, |
| 694 &width, &height, &border_width, &depth)) | 690 &width, &height, &border_width, &depth)) |
| 695 return false; | 691 return false; |
| 696 | 692 |
| 697 if (!XTranslateCoordinates(GetXDisplay(), window, root, | 693 if (!XTranslateCoordinates(gfx::GetXDisplay(), window, root, |
| 698 0, 0, &x, &y, &child)) | 694 0, 0, &x, &y, &child)) |
| 699 return false; | 695 return false; |
| 700 | 696 |
| 701 *rect = gfx::Rect(x, y, width, height); | 697 *rect = gfx::Rect(x, y, width, height); |
| 702 return true; | 698 return true; |
| 703 } | 699 } |
| 704 | 700 |
| 705 | 701 |
| 706 bool WindowContainsPoint(XID window, gfx::Point screen_loc) { | 702 bool WindowContainsPoint(XID window, gfx::Point screen_loc) { |
| 707 gfx::Rect window_rect; | 703 gfx::Rect window_rect; |
| 708 if (!GetWindowRect(window, &window_rect)) | 704 if (!GetWindowRect(window, &window_rect)) |
| 709 return false; | 705 return false; |
| 710 | 706 |
| 711 if (!window_rect.Contains(screen_loc)) | 707 if (!window_rect.Contains(screen_loc)) |
| 712 return false; | 708 return false; |
| 713 | 709 |
| 714 if (!IsShapeAvailable()) | 710 if (!IsShapeAvailable()) |
| 715 return true; | 711 return true; |
| 716 | 712 |
| 717 // According to http://www.x.org/releases/X11R7.6/doc/libXext/shapelib.html, | 713 // According to http://www.x.org/releases/X11R7.6/doc/libXext/shapelib.html, |
| 718 // if an X display supports the shape extension the bounds of a window are | 714 // if an X display supports the shape extension the bounds of a window are |
| 719 // defined as the intersection of the window bounds and the interior | 715 // defined as the intersection of the window bounds and the interior |
| 720 // rectangles. This means to determine if a point is inside a window for the | 716 // rectangles. This means to determine if a point is inside a window for the |
| 721 // purpose of input handling we have to check the rectangles in the ShapeInput | 717 // purpose of input handling we have to check the rectangles in the ShapeInput |
| 722 // list. | 718 // list. |
| 723 int dummy; | 719 int dummy; |
| 724 int input_rects_size = 0; | 720 int input_rects_size = 0; |
| 725 XRectangle* input_rects = XShapeGetRectangles( | 721 XRectangle* input_rects = XShapeGetRectangles( |
| 726 ui::GetXDisplay(), window, ShapeInput, &input_rects_size, &dummy); | 722 gfx::GetXDisplay(), window, ShapeInput, &input_rects_size, &dummy); |
| 727 if (!input_rects) | 723 if (!input_rects) |
| 728 return true; | 724 return true; |
| 729 bool is_in_input_rects = false; | 725 bool is_in_input_rects = false; |
| 730 for (int i = 0; i < input_rects_size; ++i) { | 726 for (int i = 0; i < input_rects_size; ++i) { |
| 731 // The ShapeInput rects appear to be in window space, so we have to | 727 // The ShapeInput rects appear to be in window space, so we have to |
| 732 // translate by the window_rect's offset to map to screen space. | 728 // translate by the window_rect's offset to map to screen space. |
| 733 gfx::Rect input_rect = | 729 gfx::Rect input_rect = |
| 734 gfx::Rect(input_rects[i].x + window_rect.x(), | 730 gfx::Rect(input_rects[i].x + window_rect.x(), |
| 735 input_rects[i].y + window_rect.y(), | 731 input_rects[i].y + window_rect.y(), |
| 736 input_rects[i].width, input_rects[i].height); | 732 input_rects[i].width, input_rects[i].height); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 764 scoped_refptr<base::RefCountedMemory>* out_data, | 760 scoped_refptr<base::RefCountedMemory>* out_data, |
| 765 size_t* out_data_bytes, | 761 size_t* out_data_bytes, |
| 766 size_t* out_data_items, | 762 size_t* out_data_items, |
| 767 Atom* out_type) { | 763 Atom* out_type) { |
| 768 // Retrieve the data from our window. | 764 // Retrieve the data from our window. |
| 769 unsigned long nitems = 0; | 765 unsigned long nitems = 0; |
| 770 unsigned long nbytes = 0; | 766 unsigned long nbytes = 0; |
| 771 Atom prop_type = None; | 767 Atom prop_type = None; |
| 772 int prop_format = 0; | 768 int prop_format = 0; |
| 773 unsigned char* property_data = NULL; | 769 unsigned char* property_data = NULL; |
| 774 if (XGetWindowProperty(GetXDisplay(), window, property, | 770 if (XGetWindowProperty(gfx::GetXDisplay(), window, property, |
| 775 0, 0x1FFFFFFF /* MAXINT32 / 4 */, False, | 771 0, 0x1FFFFFFF /* MAXINT32 / 4 */, False, |
| 776 AnyPropertyType, &prop_type, &prop_format, | 772 AnyPropertyType, &prop_type, &prop_format, |
| 777 &nitems, &nbytes, &property_data) != Success) { | 773 &nitems, &nbytes, &property_data) != Success) { |
| 778 return false; | 774 return false; |
| 779 } | 775 } |
| 780 | 776 |
| 781 if (prop_type == None) | 777 if (prop_type == None) |
| 782 return false; | 778 return false; |
| 783 | 779 |
| 784 size_t bytes = 0; | 780 size_t bytes = 0; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 DCHECK(!value.empty()); | 946 DCHECK(!value.empty()); |
| 951 Atom name_atom = GetAtom(name.c_str()); | 947 Atom name_atom = GetAtom(name.c_str()); |
| 952 Atom type_atom = GetAtom(type.c_str()); | 948 Atom type_atom = GetAtom(type.c_str()); |
| 953 | 949 |
| 954 // XChangeProperty() expects values of type 32 to be longs. | 950 // XChangeProperty() expects values of type 32 to be longs. |
| 955 scoped_ptr<long[]> data(new long[value.size()]); | 951 scoped_ptr<long[]> data(new long[value.size()]); |
| 956 for (size_t i = 0; i < value.size(); ++i) | 952 for (size_t i = 0; i < value.size(); ++i) |
| 957 data[i] = value[i]; | 953 data[i] = value[i]; |
| 958 | 954 |
| 959 X11ErrorTracker err_tracker; | 955 X11ErrorTracker err_tracker; |
| 960 XChangeProperty(ui::GetXDisplay(), | 956 XChangeProperty(gfx::GetXDisplay(), |
| 961 window, | 957 window, |
| 962 name_atom, | 958 name_atom, |
| 963 type_atom, | 959 type_atom, |
| 964 32, // size in bits of items in 'value' | 960 32, // size in bits of items in 'value' |
| 965 PropModeReplace, | 961 PropModeReplace, |
| 966 reinterpret_cast<const unsigned char*>(data.get()), | 962 reinterpret_cast<const unsigned char*>(data.get()), |
| 967 value.size()); // num items | 963 value.size()); // num items |
| 968 return !err_tracker.FoundNewError(); | 964 return !err_tracker.FoundNewError(); |
| 969 } | 965 } |
| 970 | 966 |
| 971 bool SetAtomArrayProperty(XID window, | 967 bool SetAtomArrayProperty(XID window, |
| 972 const std::string& name, | 968 const std::string& name, |
| 973 const std::string& type, | 969 const std::string& type, |
| 974 const std::vector<Atom>& value) { | 970 const std::vector<Atom>& value) { |
| 975 DCHECK(!value.empty()); | 971 DCHECK(!value.empty()); |
| 976 Atom name_atom = GetAtom(name.c_str()); | 972 Atom name_atom = GetAtom(name.c_str()); |
| 977 Atom type_atom = GetAtom(type.c_str()); | 973 Atom type_atom = GetAtom(type.c_str()); |
| 978 | 974 |
| 979 // XChangeProperty() expects values of type 32 to be longs. | 975 // XChangeProperty() expects values of type 32 to be longs. |
| 980 scoped_ptr<Atom[]> data(new Atom[value.size()]); | 976 scoped_ptr<Atom[]> data(new Atom[value.size()]); |
| 981 for (size_t i = 0; i < value.size(); ++i) | 977 for (size_t i = 0; i < value.size(); ++i) |
| 982 data[i] = value[i]; | 978 data[i] = value[i]; |
| 983 | 979 |
| 984 X11ErrorTracker err_tracker; | 980 X11ErrorTracker err_tracker; |
| 985 XChangeProperty(ui::GetXDisplay(), | 981 XChangeProperty(gfx::GetXDisplay(), |
| 986 window, | 982 window, |
| 987 name_atom, | 983 name_atom, |
| 988 type_atom, | 984 type_atom, |
| 989 32, // size in bits of items in 'value' | 985 32, // size in bits of items in 'value' |
| 990 PropModeReplace, | 986 PropModeReplace, |
| 991 reinterpret_cast<const unsigned char*>(data.get()), | 987 reinterpret_cast<const unsigned char*>(data.get()), |
| 992 value.size()); // num items | 988 value.size()); // num items |
| 993 return !err_tracker.FoundNewError(); | 989 return !err_tracker.FoundNewError(); |
| 994 } | 990 } |
| 995 | 991 |
| 996 Atom GetAtom(const char* name) { | 992 Atom GetAtom(const char* name) { |
| 997 #if defined(TOOLKIT_GTK) | 993 #if defined(TOOLKIT_GTK) |
| 998 return gdk_x11_get_xatom_by_name_for_display( | 994 return gdk_x11_get_xatom_by_name_for_display( |
| 999 gdk_display_get_default(), name); | 995 gdk_display_get_default(), name); |
| 1000 #else | 996 #else |
| 1001 // TODO(derat): Cache atoms to avoid round-trips to the server. | 997 // TODO(derat): Cache atoms to avoid round-trips to the server. |
| 1002 return XInternAtom(GetXDisplay(), name, false); | 998 return XInternAtom(gfx::GetXDisplay(), name, false); |
| 1003 #endif | 999 #endif |
| 1004 } | 1000 } |
| 1005 | 1001 |
| 1006 void SetWindowClassHint(Display* display, | 1002 void SetWindowClassHint(XDisplay* display, |
| 1007 XID window, | 1003 XID window, |
| 1008 std::string res_name, | 1004 std::string res_name, |
| 1009 std::string res_class) { | 1005 std::string res_class) { |
| 1010 XClassHint class_hints; | 1006 XClassHint class_hints; |
| 1011 // const_cast is safe because XSetClassHint does not modify the strings. | 1007 // const_cast is safe because XSetClassHint does not modify the strings. |
| 1012 // Just to be safe, the res_name and res_class parameters are local copies, | 1008 // Just to be safe, the res_name and res_class parameters are local copies, |
| 1013 // not const references. | 1009 // not const references. |
| 1014 class_hints.res_name = const_cast<char*>(res_name.c_str()); | 1010 class_hints.res_name = const_cast<char*>(res_name.c_str()); |
| 1015 class_hints.res_class = const_cast<char*>(res_class.c_str()); | 1011 class_hints.res_class = const_cast<char*>(res_class.c_str()); |
| 1016 XSetClassHint(display, window, &class_hints); | 1012 XSetClassHint(display, window, &class_hints); |
| 1017 } | 1013 } |
| 1018 | 1014 |
| 1019 XID GetParentWindow(XID window) { | 1015 XID GetParentWindow(XID window) { |
| 1020 XID root = None; | 1016 XID root = None; |
| 1021 XID parent = None; | 1017 XID parent = None; |
| 1022 XID* children = NULL; | 1018 XID* children = NULL; |
| 1023 unsigned int num_children = 0; | 1019 unsigned int num_children = 0; |
| 1024 XQueryTree(GetXDisplay(), window, &root, &parent, &children, &num_children); | 1020 XQueryTree(gfx::GetXDisplay(), window, &root, &parent, &children, &num_childre
n); |
| 1025 if (children) | 1021 if (children) |
| 1026 XFree(children); | 1022 XFree(children); |
| 1027 return parent; | 1023 return parent; |
| 1028 } | 1024 } |
| 1029 | 1025 |
| 1030 XID GetHighestAncestorWindow(XID window, XID root) { | 1026 XID GetHighestAncestorWindow(XID window, XID root) { |
| 1031 while (true) { | 1027 while (true) { |
| 1032 XID parent = GetParentWindow(window); | 1028 XID parent = GetParentWindow(window); |
| 1033 if (parent == None) | 1029 if (parent == None) |
| 1034 return None; | 1030 return None; |
| 1035 if (parent == root) | 1031 if (parent == root) |
| 1036 return window; | 1032 return window; |
| 1037 window = parent; | 1033 window = parent; |
| 1038 } | 1034 } |
| 1039 } | 1035 } |
| 1040 | 1036 |
| 1041 bool GetWindowDesktop(XID window, int* desktop) { | 1037 bool GetWindowDesktop(XID window, int* desktop) { |
| 1042 return GetIntProperty(window, "_NET_WM_DESKTOP", desktop); | 1038 return GetIntProperty(window, "_NET_WM_DESKTOP", desktop); |
| 1043 } | 1039 } |
| 1044 | 1040 |
| 1045 std::string GetX11ErrorString(Display* display, int err) { | 1041 std::string GetX11ErrorString(XDisplay* display, int err) { |
| 1046 char buffer[256]; | 1042 char buffer[256]; |
| 1047 XGetErrorText(display, err, buffer, arraysize(buffer)); | 1043 XGetErrorText(display, err, buffer, arraysize(buffer)); |
| 1048 return buffer; | 1044 return buffer; |
| 1049 } | 1045 } |
| 1050 | 1046 |
| 1051 // Returns true if |window| is a named window. | 1047 // Returns true if |window| is a named window. |
| 1052 bool IsWindowNamed(XID window) { | 1048 bool IsWindowNamed(XID window) { |
| 1053 XTextProperty prop; | 1049 XTextProperty prop; |
| 1054 if (!XGetWMName(GetXDisplay(), window, &prop) || !prop.value) | 1050 if (!XGetWMName(gfx::GetXDisplay(), window, &prop) || !prop.value) |
| 1055 return false; | 1051 return false; |
| 1056 | 1052 |
| 1057 XFree(prop.value); | 1053 XFree(prop.value); |
| 1058 return true; | 1054 return true; |
| 1059 } | 1055 } |
| 1060 | 1056 |
| 1061 bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, | 1057 bool EnumerateChildren(EnumerateWindowsDelegate* delegate, XID window, |
| 1062 const int max_depth, int depth) { | 1058 const int max_depth, int depth) { |
| 1063 if (depth > max_depth) | 1059 if (depth > max_depth) |
| 1064 return false; | 1060 return false; |
| 1065 | 1061 |
| 1066 XID root, parent, *children; | 1062 XID root, parent, *children; |
| 1067 unsigned int num_children; | 1063 unsigned int num_children; |
| 1068 int status = XQueryTree(GetXDisplay(), window, &root, &parent, &children, | 1064 int status = XQueryTree(gfx::GetXDisplay(), window, &root, &parent, &children, |
| 1069 &num_children); | 1065 &num_children); |
| 1070 if (status == 0) | 1066 if (status == 0) |
| 1071 return false; | 1067 return false; |
| 1072 | 1068 |
| 1073 std::vector<XID> windows; | 1069 std::vector<XID> windows; |
| 1074 for (int i = static_cast<int>(num_children) - 1; i >= 0; i--) | 1070 for (int i = static_cast<int>(num_children) - 1; i >= 0; i--) |
| 1075 windows.push_back(children[i]); | 1071 windows.push_back(children[i]); |
| 1076 | 1072 |
| 1077 XFree(children); | 1073 XFree(children); |
| 1078 | 1074 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 if (data) | 1146 if (data) |
| 1151 XFree(data); | 1147 XFree(data); |
| 1152 | 1148 |
| 1153 return result; | 1149 return result; |
| 1154 } | 1150 } |
| 1155 | 1151 |
| 1156 void RestackWindow(XID window, XID sibling, bool above) { | 1152 void RestackWindow(XID window, XID sibling, bool above) { |
| 1157 XWindowChanges changes; | 1153 XWindowChanges changes; |
| 1158 changes.sibling = sibling; | 1154 changes.sibling = sibling; |
| 1159 changes.stack_mode = above ? Above : Below; | 1155 changes.stack_mode = above ? Above : Below; |
| 1160 XConfigureWindow(GetXDisplay(), window, CWSibling | CWStackMode, &changes); | 1156 XConfigureWindow(gfx::GetXDisplay(), window, CWSibling | CWStackMode, &changes
); |
| 1161 } | 1157 } |
| 1162 | 1158 |
| 1163 XSharedMemoryId AttachSharedMemory(Display* display, int shared_memory_key) { | 1159 XSharedMemoryId AttachSharedMemory(XDisplay* display, int shared_memory_key) { |
| 1164 DCHECK(QuerySharedMemorySupport(display)); | 1160 DCHECK(QuerySharedMemorySupport(display)); |
| 1165 | 1161 |
| 1166 XShmSegmentInfo shminfo; | 1162 XShmSegmentInfo shminfo; |
| 1167 memset(&shminfo, 0, sizeof(shminfo)); | 1163 memset(&shminfo, 0, sizeof(shminfo)); |
| 1168 shminfo.shmid = shared_memory_key; | 1164 shminfo.shmid = shared_memory_key; |
| 1169 | 1165 |
| 1170 // This function is only called if QuerySharedMemorySupport returned true. In | 1166 // This function is only called if QuerySharedMemorySupport returned true. In |
| 1171 // which case we've already succeeded in having the X server attach to one of | 1167 // which case we've already succeeded in having the X server attach to one of |
| 1172 // our shared memory segments. | 1168 // our shared memory segments. |
| 1173 if (!XShmAttach(display, &shminfo)) { | 1169 if (!XShmAttach(display, &shminfo)) { |
| 1174 LOG(WARNING) << "X failed to attach to shared memory segment " | 1170 LOG(WARNING) << "X failed to attach to shared memory segment " |
| 1175 << shminfo.shmid; | 1171 << shminfo.shmid; |
| 1176 NOTREACHED(); | 1172 NOTREACHED(); |
| 1177 } else { | 1173 } else { |
| 1178 VLOG(1) << "X attached to shared memory segment " << shminfo.shmid; | 1174 VLOG(1) << "X attached to shared memory segment " << shminfo.shmid; |
| 1179 } | 1175 } |
| 1180 | 1176 |
| 1181 return shminfo.shmseg; | 1177 return shminfo.shmseg; |
| 1182 } | 1178 } |
| 1183 | 1179 |
| 1184 void DetachSharedMemory(Display* display, XSharedMemoryId shmseg) { | 1180 void DetachSharedMemory(XDisplay* display, XSharedMemoryId shmseg) { |
| 1185 DCHECK(QuerySharedMemorySupport(display)); | 1181 DCHECK(QuerySharedMemorySupport(display)); |
| 1186 | 1182 |
| 1187 XShmSegmentInfo shminfo; | 1183 XShmSegmentInfo shminfo; |
| 1188 memset(&shminfo, 0, sizeof(shminfo)); | 1184 memset(&shminfo, 0, sizeof(shminfo)); |
| 1189 shminfo.shmseg = shmseg; | 1185 shminfo.shmseg = shmseg; |
| 1190 | 1186 |
| 1191 if (!XShmDetach(display, &shminfo)) | 1187 if (!XShmDetach(display, &shminfo)) |
| 1192 NOTREACHED(); | 1188 NOTREACHED(); |
| 1193 } | 1189 } |
| 1194 | 1190 |
| 1195 bool CopyAreaToCanvas(XID drawable, | 1191 bool CopyAreaToCanvas(XID drawable, |
| 1196 gfx::Rect source_bounds, | 1192 gfx::Rect source_bounds, |
| 1197 gfx::Point dest_offset, | 1193 gfx::Point dest_offset, |
| 1198 gfx::Canvas* canvas) { | 1194 gfx::Canvas* canvas) { |
| 1199 ui::XScopedImage scoped_image( | 1195 ui::XScopedImage scoped_image( |
| 1200 XGetImage(GetXDisplay(), drawable, | 1196 XGetImage(gfx::GetXDisplay(), drawable, |
| 1201 source_bounds.x(), source_bounds.y(), | 1197 source_bounds.x(), source_bounds.y(), |
| 1202 source_bounds.width(), source_bounds.height(), | 1198 source_bounds.width(), source_bounds.height(), |
| 1203 AllPlanes, ZPixmap)); | 1199 AllPlanes, ZPixmap)); |
| 1204 XImage* image = scoped_image.get(); | 1200 XImage* image = scoped_image.get(); |
| 1205 if (!image) { | 1201 if (!image) { |
| 1206 LOG(ERROR) << "XGetImage failed"; | 1202 LOG(ERROR) << "XGetImage failed"; |
| 1207 return false; | 1203 return false; |
| 1208 } | 1204 } |
| 1209 | 1205 |
| 1210 if (image->bits_per_pixel == 32) { | 1206 if (image->bits_per_pixel == 32) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1234 image_skia.AddRepresentation(image_rep); | 1230 image_skia.AddRepresentation(image_rep); |
| 1235 canvas->DrawImageInt(image_skia, dest_offset.x(), dest_offset.y()); | 1231 canvas->DrawImageInt(image_skia, dest_offset.x(), dest_offset.y()); |
| 1236 } else { | 1232 } else { |
| 1237 NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; | 1233 NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; |
| 1238 return false; | 1234 return false; |
| 1239 } | 1235 } |
| 1240 | 1236 |
| 1241 return true; | 1237 return true; |
| 1242 } | 1238 } |
| 1243 | 1239 |
| 1244 XID CreatePictureFromSkiaPixmap(Display* display, XID pixmap) { | 1240 XID CreatePictureFromSkiaPixmap(XDisplay* display, XID pixmap) { |
| 1245 XID picture = XRenderCreatePicture( | 1241 XID picture = XRenderCreatePicture( |
| 1246 display, pixmap, GetRenderARGB32Format(display), 0, NULL); | 1242 display, pixmap, GetRenderARGB32Format(display), 0, NULL); |
| 1247 | 1243 |
| 1248 return picture; | 1244 return picture; |
| 1249 } | 1245 } |
| 1250 | 1246 |
| 1251 void PutARGBImage(Display* display, | 1247 void PutARGBImage(XDisplay* display, |
| 1252 void* visual, int depth, | 1248 void* visual, int depth, |
| 1253 XID pixmap, void* pixmap_gc, | 1249 XID pixmap, void* pixmap_gc, |
| 1254 const uint8* data, | 1250 const uint8* data, |
| 1255 int width, int height) { | 1251 int width, int height) { |
| 1256 PutARGBImage(display, | 1252 PutARGBImage(display, |
| 1257 visual, depth, | 1253 visual, depth, |
| 1258 pixmap, pixmap_gc, | 1254 pixmap, pixmap_gc, |
| 1259 data, width, height, | 1255 data, width, height, |
| 1260 0, 0, // src_x, src_y | 1256 0, 0, // src_x, src_y |
| 1261 0, 0, // dst_x, dst_y | 1257 0, 0, // dst_x, dst_y |
| 1262 width, height); | 1258 width, height); |
| 1263 } | 1259 } |
| 1264 | 1260 |
| 1265 void PutARGBImage(Display* display, | 1261 void PutARGBImage(XDisplay* display, |
| 1266 void* visual, int depth, | 1262 void* visual, int depth, |
| 1267 XID pixmap, void* pixmap_gc, | 1263 XID pixmap, void* pixmap_gc, |
| 1268 const uint8* data, | 1264 const uint8* data, |
| 1269 int data_width, int data_height, | 1265 int data_width, int data_height, |
| 1270 int src_x, int src_y, | 1266 int src_x, int src_y, |
| 1271 int dst_x, int dst_y, | 1267 int dst_x, int dst_y, |
| 1272 int copy_width, int copy_height) { | 1268 int copy_width, int copy_height) { |
| 1273 // TODO(scherkus): potential performance impact... consider passing in as a | 1269 // TODO(scherkus): potential performance impact... consider passing in as a |
| 1274 // parameter. | 1270 // parameter. |
| 1275 int pixmap_bpp = BitsPerPixelForPixmapDepth(display, depth); | 1271 int pixmap_bpp = BitsPerPixelForPixmapDepth(display, depth); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 src_x, src_y, dst_x, dst_y, | 1356 src_x, src_y, dst_x, dst_y, |
| 1361 copy_width, copy_height); | 1357 copy_width, copy_height); |
| 1362 free(orig_bitmap16); | 1358 free(orig_bitmap16); |
| 1363 } else { | 1359 } else { |
| 1364 LOG(FATAL) << "Sorry, we don't support your visual depth without " | 1360 LOG(FATAL) << "Sorry, we don't support your visual depth without " |
| 1365 "Xrender support (depth:" << depth | 1361 "Xrender support (depth:" << depth |
| 1366 << " bpp:" << pixmap_bpp << ")"; | 1362 << " bpp:" << pixmap_bpp << ")"; |
| 1367 } | 1363 } |
| 1368 } | 1364 } |
| 1369 | 1365 |
| 1370 void FreePicture(Display* display, XID picture) { | 1366 void FreePicture(XDisplay* display, XID picture) { |
| 1371 XRenderFreePicture(display, picture); | 1367 XRenderFreePicture(display, picture); |
| 1372 } | 1368 } |
| 1373 | 1369 |
| 1374 void FreePixmap(Display* display, XID pixmap) { | 1370 void FreePixmap(XDisplay* display, XID pixmap) { |
| 1375 XFreePixmap(display, pixmap); | 1371 XFreePixmap(display, pixmap); |
| 1376 } | 1372 } |
| 1377 | 1373 |
| 1378 bool GetWindowManagerName(std::string* wm_name) { | 1374 bool GetWindowManagerName(std::string* wm_name) { |
| 1379 DCHECK(wm_name); | 1375 DCHECK(wm_name); |
| 1380 int wm_window = 0; | 1376 int wm_window = 0; |
| 1381 if (!GetIntProperty(GetX11RootWindow(), | 1377 if (!GetIntProperty(GetX11RootWindow(), |
| 1382 "_NET_SUPPORTING_WM_CHECK", | 1378 "_NET_SUPPORTING_WM_CHECK", |
| 1383 &wm_window)) { | 1379 &wm_window)) { |
| 1384 return false; | 1380 return false; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 return false; | 1446 return false; |
| 1451 | 1447 |
| 1452 XEvent event; | 1448 XEvent event; |
| 1453 event.xclient.type = ClientMessage; | 1449 event.xclient.type = ClientMessage; |
| 1454 event.xclient.window = window; | 1450 event.xclient.window = window; |
| 1455 event.xclient.message_type = GetAtom("_NET_WM_DESKTOP"); | 1451 event.xclient.message_type = GetAtom("_NET_WM_DESKTOP"); |
| 1456 event.xclient.format = 32; | 1452 event.xclient.format = 32; |
| 1457 event.xclient.data.l[0] = desktop; | 1453 event.xclient.data.l[0] = desktop; |
| 1458 event.xclient.data.l[1] = 1; // source indication | 1454 event.xclient.data.l[1] = 1; // source indication |
| 1459 | 1455 |
| 1460 int result = XSendEvent(GetXDisplay(), GetX11RootWindow(), False, | 1456 int result = XSendEvent(gfx::GetXDisplay(), GetX11RootWindow(), False, |
| 1461 SubstructureNotifyMask, &event); | 1457 SubstructureNotifyMask, &event); |
| 1462 return result == Success; | 1458 return result == Success; |
| 1463 } | 1459 } |
| 1464 | 1460 |
| 1465 void SetDefaultX11ErrorHandlers() { | 1461 void SetDefaultX11ErrorHandlers() { |
| 1466 SetX11ErrorHandlers(NULL, NULL); | 1462 SetX11ErrorHandlers(NULL, NULL); |
| 1467 } | 1463 } |
| 1468 | 1464 |
| 1469 bool IsX11WindowFullScreen(XID window) { | 1465 bool IsX11WindowFullScreen(XID window) { |
| 1470 // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or | 1466 // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1501 return monitor_rect.x == window_rect.x() && | 1497 return monitor_rect.x == window_rect.x() && |
| 1502 monitor_rect.y == window_rect.y() && | 1498 monitor_rect.y == window_rect.y() && |
| 1503 monitor_rect.width == window_rect.width() && | 1499 monitor_rect.width == window_rect.width() && |
| 1504 monitor_rect.height == window_rect.height(); | 1500 monitor_rect.height == window_rect.height(); |
| 1505 #else | 1501 #else |
| 1506 // We can't use gfx::Screen here because we don't have an aura::Window. So | 1502 // We can't use gfx::Screen here because we don't have an aura::Window. So |
| 1507 // instead just look at the size of the default display. | 1503 // instead just look at the size of the default display. |
| 1508 // | 1504 // |
| 1509 // TODO(erg): Actually doing this correctly would require pulling out xrandr, | 1505 // TODO(erg): Actually doing this correctly would require pulling out xrandr, |
| 1510 // which we don't even do in the desktop screen yet. | 1506 // which we don't even do in the desktop screen yet. |
| 1511 ::Display* display = ui::GetXDisplay(); | 1507 ::XDisplay* display = gfx::GetXDisplay(); |
| 1512 ::Screen* screen = DefaultScreenOfDisplay(display); | 1508 ::Screen* screen = DefaultScreenOfDisplay(display); |
| 1513 int width = WidthOfScreen(screen); | 1509 int width = WidthOfScreen(screen); |
| 1514 int height = HeightOfScreen(screen); | 1510 int height = HeightOfScreen(screen); |
| 1515 return window_rect.size() == gfx::Size(width, height); | 1511 return window_rect.size() == gfx::Size(width, height); |
| 1516 #endif | 1512 #endif |
| 1517 } | 1513 } |
| 1518 | 1514 |
| 1519 bool IsMotionEvent(XEvent* event) { | 1515 bool IsMotionEvent(XEvent* event) { |
| 1520 int type = event->type; | 1516 int type = event->type; |
| 1521 if (type == GenericEvent) | 1517 if (type == GenericEvent) |
| 1522 type = event->xgeneric.evtype; | 1518 type = event->xgeneric.evtype; |
| 1523 return type == MotionNotify; | 1519 return type == MotionNotify; |
| 1524 } | 1520 } |
| 1525 | 1521 |
| 1526 int GetMappedButton(int button) { | 1522 int GetMappedButton(int button) { |
| 1527 return XButtonMap::GetInstance()->GetMappedButton(button); | 1523 return XButtonMap::GetInstance()->GetMappedButton(button); |
| 1528 } | 1524 } |
| 1529 | 1525 |
| 1530 void UpdateButtonMap() { | 1526 void UpdateButtonMap() { |
| 1531 XButtonMap::GetInstance()->UpdateMapping(); | 1527 XButtonMap::GetInstance()->UpdateMapping(); |
| 1532 } | 1528 } |
| 1533 | 1529 |
| 1534 void InitXKeyEventForTesting(EventType type, | 1530 void InitXKeyEventForTesting(EventType type, |
| 1535 KeyboardCode key_code, | 1531 KeyboardCode key_code, |
| 1536 int flags, | 1532 int flags, |
| 1537 XEvent* event) { | 1533 XEvent* event) { |
| 1538 CHECK(event); | 1534 CHECK(event); |
| 1539 Display* display = GetXDisplay(); | 1535 XDisplay* display = gfx::GetXDisplay(); |
| 1540 XKeyEvent key_event; | 1536 XKeyEvent key_event; |
| 1541 key_event.type = XKeyEventType(type); | 1537 key_event.type = XKeyEventType(type); |
| 1542 CHECK_NE(0, key_event.type); | 1538 CHECK_NE(0, key_event.type); |
| 1543 key_event.serial = 0; | 1539 key_event.serial = 0; |
| 1544 key_event.send_event = 0; | 1540 key_event.send_event = 0; |
| 1545 key_event.display = display; | 1541 key_event.display = display; |
| 1546 key_event.time = 0; | 1542 key_event.time = 0; |
| 1547 key_event.window = 0; | 1543 key_event.window = 0; |
| 1548 key_event.root = 0; | 1544 key_event.root = 0; |
| 1549 key_event.subwindow = 0; | 1545 key_event.subwindow = 0; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1579 } | 1575 } |
| 1580 | 1576 |
| 1581 void XScopedImage::reset(XImage* image) { | 1577 void XScopedImage::reset(XImage* image) { |
| 1582 if (image_ == image) | 1578 if (image_ == image) |
| 1583 return; | 1579 return; |
| 1584 if (image_) | 1580 if (image_) |
| 1585 XDestroyImage(image_); | 1581 XDestroyImage(image_); |
| 1586 image_ = image; | 1582 image_ = image; |
| 1587 } | 1583 } |
| 1588 | 1584 |
| 1589 XScopedCursor::XScopedCursor(::Cursor cursor, Display* display) | 1585 XScopedCursor::XScopedCursor(::Cursor cursor, XDisplay* display) |
| 1590 : cursor_(cursor), | 1586 : cursor_(cursor), |
| 1591 display_(display) { | 1587 display_(display) { |
| 1592 } | 1588 } |
| 1593 | 1589 |
| 1594 XScopedCursor::~XScopedCursor() { | 1590 XScopedCursor::~XScopedCursor() { |
| 1595 reset(0U); | 1591 reset(0U); |
| 1596 } | 1592 } |
| 1597 | 1593 |
| 1598 ::Cursor XScopedCursor::get() const { | 1594 ::Cursor XScopedCursor::get() const { |
| 1599 return cursor_; | 1595 return cursor_; |
| 1600 } | 1596 } |
| 1601 | 1597 |
| 1602 void XScopedCursor::reset(::Cursor cursor) { | 1598 void XScopedCursor::reset(::Cursor cursor) { |
| 1603 if (cursor_) | 1599 if (cursor_) |
| 1604 XFreeCursor(display_, cursor_); | 1600 XFreeCursor(display_, cursor_); |
| 1605 cursor_ = cursor; | 1601 cursor_ = cursor; |
| 1606 } | 1602 } |
| 1607 | 1603 |
| 1608 // ---------------------------------------------------------------------------- | 1604 // ---------------------------------------------------------------------------- |
| 1609 // These functions are declared in x11_util_internal.h because they require | 1605 // These functions are declared in x11_util_internal.h because they require |
| 1610 // XLib.h to be included, and it conflicts with many other headers. | 1606 // XLib.h to be included, and it conflicts with many other headers. |
| 1611 XRenderPictFormat* GetRenderARGB32Format(Display* dpy) { | 1607 XRenderPictFormat* GetRenderARGB32Format(XDisplay* dpy) { |
| 1612 static XRenderPictFormat* pictformat = NULL; | 1608 static XRenderPictFormat* pictformat = NULL; |
| 1613 if (pictformat) | 1609 if (pictformat) |
| 1614 return pictformat; | 1610 return pictformat; |
| 1615 | 1611 |
| 1616 // First look for a 32-bit format which ignores the alpha value | 1612 // First look for a 32-bit format which ignores the alpha value |
| 1617 XRenderPictFormat templ; | 1613 XRenderPictFormat templ; |
| 1618 templ.depth = 32; | 1614 templ.depth = 32; |
| 1619 templ.type = PictTypeDirect; | 1615 templ.type = PictTypeDirect; |
| 1620 templ.direct.red = 16; | 1616 templ.direct.red = 16; |
| 1621 templ.direct.green = 8; | 1617 templ.direct.green = 8; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1637 if (!pictformat) { | 1633 if (!pictformat) { |
| 1638 // Not all X servers support xRGB32 formats. However, the XRENDER spec says | 1634 // Not all X servers support xRGB32 formats. However, the XRENDER spec says |
| 1639 // that they must support an ARGB32 format, so we can always return that. | 1635 // that they must support an ARGB32 format, so we can always return that. |
| 1640 pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32); | 1636 pictformat = XRenderFindStandardFormat(dpy, PictStandardARGB32); |
| 1641 CHECK(pictformat) << "XRENDER ARGB32 not supported."; | 1637 CHECK(pictformat) << "XRENDER ARGB32 not supported."; |
| 1642 } | 1638 } |
| 1643 | 1639 |
| 1644 return pictformat; | 1640 return pictformat; |
| 1645 } | 1641 } |
| 1646 | 1642 |
| 1647 XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) { | 1643 XRenderPictFormat* GetRenderVisualFormat(XDisplay* dpy, Visual* visual) { |
| 1648 DCHECK(QueryRenderSupport(dpy)); | 1644 DCHECK(QueryRenderSupport(dpy)); |
| 1649 | 1645 |
| 1650 CachedPictFormats* formats = get_cached_pict_formats(); | 1646 CachedPictFormats* formats = get_cached_pict_formats(); |
| 1651 | 1647 |
| 1652 for (CachedPictFormats::const_iterator i = formats->begin(); | 1648 for (CachedPictFormats::const_iterator i = formats->begin(); |
| 1653 i != formats->end(); ++i) { | 1649 i != formats->end(); ++i) { |
| 1654 if (i->equals(dpy, visual)) | 1650 if (i->equals(dpy, visual)) |
| 1655 return i->format; | 1651 return i->format; |
| 1656 } | 1652 } |
| 1657 | 1653 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1681 return pictformat; | 1677 return pictformat; |
| 1682 } | 1678 } |
| 1683 | 1679 |
| 1684 void SetX11ErrorHandlers(XErrorHandler error_handler, | 1680 void SetX11ErrorHandlers(XErrorHandler error_handler, |
| 1685 XIOErrorHandler io_error_handler) { | 1681 XIOErrorHandler io_error_handler) { |
| 1686 XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler); | 1682 XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler); |
| 1687 XSetIOErrorHandler( | 1683 XSetIOErrorHandler( |
| 1688 io_error_handler ? io_error_handler : DefaultX11IOErrorHandler); | 1684 io_error_handler ? io_error_handler : DefaultX11IOErrorHandler); |
| 1689 } | 1685 } |
| 1690 | 1686 |
| 1691 void LogErrorEventDescription(Display* dpy, | 1687 void LogErrorEventDescription(XDisplay* dpy, |
| 1692 const XErrorEvent& error_event) { | 1688 const XErrorEvent& error_event) { |
| 1693 char error_str[256]; | 1689 char error_str[256]; |
| 1694 char request_str[256]; | 1690 char request_str[256]; |
| 1695 | 1691 |
| 1696 XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str)); | 1692 XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str)); |
| 1697 | 1693 |
| 1698 strncpy(request_str, "Unknown", sizeof(request_str)); | 1694 strncpy(request_str, "Unknown", sizeof(request_str)); |
| 1699 if (error_event.request_code < 128) { | 1695 if (error_event.request_code < 128) { |
| 1700 std::string num = base::UintToString(error_event.request_code); | 1696 std::string num = base::UintToString(error_event.request_code); |
| 1701 XGetErrorDatabaseText( | 1697 XGetErrorDatabaseText( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1728 << "request_code " << static_cast<int>(error_event.request_code) << ", " | 1724 << "request_code " << static_cast<int>(error_event.request_code) << ", " |
| 1729 << "minor_code " << static_cast<int>(error_event.minor_code) | 1725 << "minor_code " << static_cast<int>(error_event.minor_code) |
| 1730 << " (" << request_str << ")"; | 1726 << " (" << request_str << ")"; |
| 1731 } | 1727 } |
| 1732 | 1728 |
| 1733 // ---------------------------------------------------------------------------- | 1729 // ---------------------------------------------------------------------------- |
| 1734 // End of x11_util_internal.h | 1730 // End of x11_util_internal.h |
| 1735 | 1731 |
| 1736 | 1732 |
| 1737 } // namespace ui | 1733 } // namespace ui |
| OLD | NEW |