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 |