| 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 |
| 11 #include <ctype.h> | 11 #include <ctype.h> |
| 12 #include <sys/ipc.h> | 12 #include <sys/ipc.h> |
| 13 #include <sys/shm.h> | 13 #include <sys/shm.h> |
| 14 | 14 |
| 15 #include <list> | 15 #include <list> |
| 16 #include <map> | 16 #include <map> |
| 17 #include <utility> |
| 17 #include <vector> | 18 #include <vector> |
| 18 | 19 |
| 19 #include <X11/extensions/Xrandr.h> | 20 #include <X11/extensions/Xrandr.h> |
| 20 #include <X11/extensions/randr.h> | 21 #include <X11/extensions/randr.h> |
| 21 | 22 |
| 22 #include "base/bind.h" | 23 #include "base/bind.h" |
| 23 #include "base/command_line.h" | 24 #include "base/command_line.h" |
| 24 #include "base/logging.h" | 25 #include "base/logging.h" |
| 25 #include "base/memory/scoped_ptr.h" | 26 #include "base/memory/scoped_ptr.h" |
| 26 #include "base/memory/singleton.h" | 27 #include "base/memory/singleton.h" |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 flags & ui::EF_SHIFT_DOWN); | 160 flags & ui::EF_SHIFT_DOWN); |
| 160 // Tests assume the keycode for XK_less is equal to the one of XK_comma, | 161 // Tests assume the keycode for XK_less is equal to the one of XK_comma, |
| 161 // but XKeysymToKeycode returns 94 for XK_less while it returns 59 for | 162 // but XKeysymToKeycode returns 94 for XK_less while it returns 59 for |
| 162 // XK_comma. Here we convert the value for XK_less to the value for XK_comma. | 163 // XK_comma. Here we convert the value for XK_less to the value for XK_comma. |
| 163 return (keysym == XK_less) ? 59 : XKeysymToKeycode(display, keysym); | 164 return (keysym == XK_less) ? 59 : XKeysymToKeycode(display, keysym); |
| 164 } | 165 } |
| 165 | 166 |
| 166 // A process wide singleton that manages the usage of X cursors. | 167 // A process wide singleton that manages the usage of X cursors. |
| 167 class XCursorCache { | 168 class XCursorCache { |
| 168 public: | 169 public: |
| 169 XCursorCache() {} | 170 XCursorCache() {} |
| 170 ~XCursorCache() { | 171 ~XCursorCache() { |
| 171 Clear(); | 172 Clear(); |
| 172 } | 173 } |
| 173 | 174 |
| 174 ::Cursor GetCursor(int cursor_shape) { | 175 ::Cursor GetCursor(int cursor_shape) { |
| 175 // Lookup cursor by attempting to insert a null value, which avoids | 176 // Lookup cursor by attempting to insert a null value, which avoids |
| 176 // a second pass through the map after a cache miss. | 177 // a second pass through the map after a cache miss. |
| 177 std::pair<std::map<int, ::Cursor>::iterator, bool> it = cache_.insert( | 178 std::pair<std::map<int, ::Cursor>::iterator, bool> it = cache_.insert( |
| 178 std::make_pair(cursor_shape, 0)); | 179 std::make_pair(cursor_shape, 0)); |
| 179 if (it.second) { | 180 if (it.second) { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 int allow_removed; | 346 int allow_removed; |
| 346 size_t length = sizeof(allow_removed); | 347 size_t length = sizeof(allow_removed); |
| 347 | 348 |
| 348 if ((sysctlbyname("kern.ipc.shm_allow_removed", &allow_removed, &length, | 349 if ((sysctlbyname("kern.ipc.shm_allow_removed", &allow_removed, &length, |
| 349 NULL, 0) < 0) || allow_removed < 1) { | 350 NULL, 0) < 0) || allow_removed < 1) { |
| 350 return SHARED_MEMORY_NONE; | 351 return SHARED_MEMORY_NONE; |
| 351 } | 352 } |
| 352 #endif | 353 #endif |
| 353 | 354 |
| 354 // Next we probe to see if shared memory will really work | 355 // Next we probe to see if shared memory will really work |
| 355 int shmkey = shmget(IPC_PRIVATE, 1, 0666); | 356 int shmkey = shmget(IPC_PRIVATE, 1, 0600); |
| 356 if (shmkey == -1) | 357 if (shmkey == -1) { |
| 358 LOG(WARNING) << "Failed to get shared memory segment."; |
| 357 return SHARED_MEMORY_NONE; | 359 return SHARED_MEMORY_NONE; |
| 360 } else { |
| 361 VLOG(1) << "Got shared memory segment " << shmkey; |
| 362 } |
| 363 |
| 358 void* address = shmat(shmkey, NULL, 0); | 364 void* address = shmat(shmkey, NULL, 0); |
| 359 // Mark the shared memory region for deletion | 365 // Mark the shared memory region for deletion |
| 360 shmctl(shmkey, IPC_RMID, NULL); | 366 shmctl(shmkey, IPC_RMID, NULL); |
| 361 | 367 |
| 362 XShmSegmentInfo shminfo; | 368 XShmSegmentInfo shminfo; |
| 363 memset(&shminfo, 0, sizeof(shminfo)); | 369 memset(&shminfo, 0, sizeof(shminfo)); |
| 364 shminfo.shmid = shmkey; | 370 shminfo.shmid = shmkey; |
| 365 | 371 |
| 366 gdk_error_trap_push(); | 372 gdk_error_trap_push(); |
| 367 bool result = XShmAttach(dpy, &shminfo); | 373 bool result = XShmAttach(dpy, &shminfo); |
| 374 if (result) |
| 375 VLOG(1) << "X got shared memory segment " << shmkey; |
| 376 else |
| 377 LOG(WARNING) << "X failed to attach to shared memory segment " << shmkey; |
| 368 XSync(dpy, False); | 378 XSync(dpy, False); |
| 369 if (gdk_error_trap_pop()) | 379 if (gdk_error_trap_pop()) |
| 370 result = false; | 380 result = false; |
| 371 shmdt(address); | 381 shmdt(address); |
| 372 if (!result) | 382 if (!result) { |
| 383 LOG(WARNING) << "X failed to attach to shared memory segment " << shmkey; |
| 373 return SHARED_MEMORY_NONE; | 384 return SHARED_MEMORY_NONE; |
| 385 } |
| 386 |
| 387 VLOG(1) << "X attached to shared memory segment " << shmkey; |
| 374 | 388 |
| 375 XShmDetach(dpy, &shminfo); | 389 XShmDetach(dpy, &shminfo); |
| 376 return pixmaps_supported ? SHARED_MEMORY_PIXMAP : SHARED_MEMORY_PUTIMAGE; | 390 return pixmaps_supported ? SHARED_MEMORY_PIXMAP : SHARED_MEMORY_PUTIMAGE; |
| 377 } | 391 } |
| 378 | 392 |
| 379 SharedMemorySupport QuerySharedMemorySupport(Display* dpy) { | 393 SharedMemorySupport QuerySharedMemorySupport(Display* dpy) { |
| 380 static SharedMemorySupport shared_memory_support = SHARED_MEMORY_NONE; | 394 static SharedMemorySupport shared_memory_support = SHARED_MEMORY_NONE; |
| 381 static bool shared_memory_support_cached = false; | 395 static bool shared_memory_support_cached = false; |
| 382 | 396 |
| 383 if (shared_memory_support_cached) | 397 if (shared_memory_support_cached) |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 XSharedMemoryId AttachSharedMemory(Display* display, int shared_memory_key) { | 863 XSharedMemoryId AttachSharedMemory(Display* display, int shared_memory_key) { |
| 850 DCHECK(QuerySharedMemorySupport(display)); | 864 DCHECK(QuerySharedMemorySupport(display)); |
| 851 | 865 |
| 852 XShmSegmentInfo shminfo; | 866 XShmSegmentInfo shminfo; |
| 853 memset(&shminfo, 0, sizeof(shminfo)); | 867 memset(&shminfo, 0, sizeof(shminfo)); |
| 854 shminfo.shmid = shared_memory_key; | 868 shminfo.shmid = shared_memory_key; |
| 855 | 869 |
| 856 // This function is only called if QuerySharedMemorySupport returned true. In | 870 // This function is only called if QuerySharedMemorySupport returned true. In |
| 857 // which case we've already succeeded in having the X server attach to one of | 871 // which case we've already succeeded in having the X server attach to one of |
| 858 // our shared memory segments. | 872 // our shared memory segments. |
| 859 if (!XShmAttach(display, &shminfo)) | 873 if (!XShmAttach(display, &shminfo)) { |
| 874 LOG(WARNING) << "X failed to attach to shared memory segment " |
| 875 << shminfo.shmid; |
| 860 NOTREACHED(); | 876 NOTREACHED(); |
| 877 } else { |
| 878 VLOG(1) << "X attached to shared memory segment " << shminfo.shmid; |
| 879 } |
| 861 | 880 |
| 862 return shminfo.shmseg; | 881 return shminfo.shmseg; |
| 863 } | 882 } |
| 864 | 883 |
| 865 void DetachSharedMemory(Display* display, XSharedMemoryId shmseg) { | 884 void DetachSharedMemory(Display* display, XSharedMemoryId shmseg) { |
| 866 DCHECK(QuerySharedMemorySupport(display)); | 885 DCHECK(QuerySharedMemorySupport(display)); |
| 867 | 886 |
| 868 XShmSegmentInfo shminfo; | 887 XShmSegmentInfo shminfo; |
| 869 memset(&shminfo, 0, sizeof(shminfo)); | 888 memset(&shminfo, 0, sizeof(shminfo)); |
| 870 shminfo.shmseg = shmseg; | 889 shminfo.shmseg = shmseg; |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1444 "%s.%d", ext_list[i], error_event.minor_code); | 1463 "%s.%d", ext_list[i], error_event.minor_code); |
| 1445 XGetErrorDatabaseText( | 1464 XGetErrorDatabaseText( |
| 1446 dpy, "XRequest", msg.c_str(), "Unknown", request_str, | 1465 dpy, "XRequest", msg.c_str(), "Unknown", request_str, |
| 1447 sizeof(request_str)); | 1466 sizeof(request_str)); |
| 1448 break; | 1467 break; |
| 1449 } | 1468 } |
| 1450 } | 1469 } |
| 1451 XFreeExtensionList(ext_list); | 1470 XFreeExtensionList(ext_list); |
| 1452 } | 1471 } |
| 1453 | 1472 |
| 1454 LOG(ERROR) | 1473 LOG(ERROR) |
| 1455 << "X Error detected: " | 1474 << "X Error detected: " |
| 1456 << "serial " << error_event.serial << ", " | 1475 << "serial " << error_event.serial << ", " |
| 1457 << "error_code " << static_cast<int>(error_event.error_code) | 1476 << "error_code " << static_cast<int>(error_event.error_code) |
| 1458 << " (" << error_str << "), " | 1477 << " (" << error_str << "), " |
| 1459 << "request_code " << static_cast<int>(error_event.request_code) << ", " | 1478 << "request_code " << static_cast<int>(error_event.request_code) << ", " |
| 1460 << "minor_code " << static_cast<int>(error_event.minor_code) | 1479 << "minor_code " << static_cast<int>(error_event.minor_code) |
| 1461 << " (" << request_str << ")"; | 1480 << " (" << request_str << ")"; |
| 1462 } | 1481 } |
| 1463 | 1482 |
| 1464 // ---------------------------------------------------------------------------- | 1483 // ---------------------------------------------------------------------------- |
| 1465 // End of x11_util_internal.h | 1484 // End of x11_util_internal.h |
| 1466 | 1485 |
| 1467 | 1486 |
| 1468 } // namespace ui | 1487 } // namespace ui |
| OLD | NEW |