| 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 13 matching lines...) Expand all Loading... |
| 24 #include "base/string_number_conversions.h" | 24 #include "base/string_number_conversions.h" |
| 25 #include "base/string_util.h" | 25 #include "base/string_util.h" |
| 26 #include "base/stringprintf.h" | 26 #include "base/stringprintf.h" |
| 27 #include "base/threading/thread.h" | 27 #include "base/threading/thread.h" |
| 28 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 28 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 29 #include "ui/base/x/x11_util_internal.h" | 29 #include "ui/base/x/x11_util_internal.h" |
| 30 #include "ui/gfx/rect.h" | 30 #include "ui/gfx/rect.h" |
| 31 #include "ui/gfx/size.h" | 31 #include "ui/gfx/size.h" |
| 32 | 32 |
| 33 #if defined(OS_FREEBSD) | 33 #if defined(OS_FREEBSD) |
| 34 #include <sys/sysctl.h> |
| 34 #include <sys/types.h> | 35 #include <sys/types.h> |
| 35 #include <sys/sysctl.h> | 36 #endif |
| 37 |
| 38 #if defined(USE_AURA) |
| 39 #include <X11/Xcursor/Xcursor.h> |
| 36 #endif | 40 #endif |
| 37 | 41 |
| 38 #if defined(TOOLKIT_USES_GTK) | 42 #if defined(TOOLKIT_USES_GTK) |
| 39 #include <gdk/gdk.h> | 43 #include <gdk/gdk.h> |
| 40 #include <gdk/gdkx.h> | 44 #include <gdk/gdkx.h> |
| 41 #include <gtk/gtk.h> | 45 #include <gtk/gtk.h> |
| 46 #include "ui/base/gtk/gdk_x_compat.h" |
| 42 #include "ui/base/gtk/gtk_compat.h" | 47 #include "ui/base/gtk/gtk_compat.h" |
| 43 #include "ui/base/gtk/gdk_x_compat.h" | |
| 44 #else | 48 #else |
| 45 // TODO(sad): Use the new way of handling X errors when | 49 // TODO(sad): Use the new way of handling X errors when |
| 46 // http://codereview.chromium.org/7889040/ lands. | 50 // http://codereview.chromium.org/7889040/ lands. |
| 47 #define gdk_error_trap_push() | 51 #define gdk_error_trap_push() |
| 48 #define gdk_error_trap_pop() false | 52 #define gdk_error_trap_pop() false |
| 49 #define gdk_flush() | 53 #define gdk_flush() |
| 50 #endif | 54 #endif |
| 51 | 55 |
| 52 namespace ui { | 56 namespace ui { |
| 53 | 57 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 } | 157 } |
| 154 | 158 |
| 155 // A process wide singleton that manages the usage of X cursors. | 159 // A process wide singleton that manages the usage of X cursors. |
| 156 class XCursorCache { | 160 class XCursorCache { |
| 157 public: | 161 public: |
| 158 XCursorCache() {} | 162 XCursorCache() {} |
| 159 ~XCursorCache() { | 163 ~XCursorCache() { |
| 160 Clear(); | 164 Clear(); |
| 161 } | 165 } |
| 162 | 166 |
| 163 Cursor GetCursor(int cursor_shape) { | 167 ::Cursor GetCursor(int cursor_shape) { |
| 164 // Lookup cursor by attempting to insert a null value, which avoids | 168 // Lookup cursor by attempting to insert a null value, which avoids |
| 165 // a second pass through the map after a cache miss. | 169 // a second pass through the map after a cache miss. |
| 166 std::pair<std::map<int, Cursor>::iterator, bool> it = cache_.insert( | 170 std::pair<std::map<int, ::Cursor>::iterator, bool> it = cache_.insert( |
| 167 std::make_pair(cursor_shape, 0)); | 171 std::make_pair(cursor_shape, 0)); |
| 168 if (it.second) { | 172 if (it.second) { |
| 169 Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); | 173 Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 170 it.first->second = XCreateFontCursor(display, cursor_shape); | 174 it.first->second = XCreateFontCursor(display, cursor_shape); |
| 171 } | 175 } |
| 172 return it.first->second; | 176 return it.first->second; |
| 173 } | 177 } |
| 174 | 178 |
| 175 void Clear() { | 179 void Clear() { |
| 176 Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); | 180 Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 177 for (std::map<int, Cursor>::iterator it = | 181 for (std::map<int, ::Cursor>::iterator it = |
| 178 cache_.begin(); it != cache_.end(); ++it) { | 182 cache_.begin(); it != cache_.end(); ++it) { |
| 179 XFreeCursor(display, it->second); | 183 XFreeCursor(display, it->second); |
| 180 } | 184 } |
| 181 cache_.clear(); | 185 cache_.clear(); |
| 182 } | 186 } |
| 183 | 187 |
| 184 private: | 188 private: |
| 185 // Maps X11 font cursor shapes to Cursor IDs. | 189 // Maps X11 font cursor shapes to Cursor IDs. |
| 186 std::map<int, Cursor> cache_; | 190 std::map<int, ::Cursor> cache_; |
| 187 | 191 |
| 188 DISALLOW_COPY_AND_ASSIGN(XCursorCache); | 192 DISALLOW_COPY_AND_ASSIGN(XCursorCache); |
| 189 }; | 193 }; |
| 190 | 194 |
| 195 #if defined(USE_AURA) |
| 196 // A process wide singleton cache for custom X cursors. |
| 197 class XCustomCursorCache { |
| 198 public: |
| 199 static XCustomCursorCache* GetInstance() { |
| 200 return Singleton<XCustomCursorCache>::get(); |
| 201 } |
| 202 |
| 203 ::Cursor InstallCustomCursor(XcursorImage* image) { |
| 204 XCustomCursor* custom_cursor = new XCustomCursor(image); |
| 205 ::Cursor xcursor = custom_cursor->cursor(); |
| 206 cache_[xcursor] = custom_cursor; |
| 207 return xcursor; |
| 208 } |
| 209 |
| 210 void Ref(::Cursor cursor) { |
| 211 cache_[cursor]->Ref(); |
| 212 } |
| 213 |
| 214 void Unref(::Cursor cursor) { |
| 215 if (cache_[cursor]->Unref()) |
| 216 cache_.erase(cursor); |
| 217 } |
| 218 |
| 219 void Clear() { |
| 220 cache_.clear(); |
| 221 } |
| 222 |
| 223 private: |
| 224 friend struct DefaultSingletonTraits<XCustomCursorCache>; |
| 225 |
| 226 class XCustomCursor { |
| 227 public: |
| 228 // This takes ownership of the image. |
| 229 XCustomCursor(XcursorImage* image) |
| 230 : image_(image), |
| 231 ref_(1) { |
| 232 cursor_ = XcursorImageLoadCursor(GetXDisplay(), image); |
| 233 } |
| 234 |
| 235 ~XCustomCursor() { |
| 236 XcursorImageDestroy(image_); |
| 237 XFreeCursor(GetXDisplay(), cursor_); |
| 238 } |
| 239 |
| 240 ::Cursor cursor() const { return cursor_; } |
| 241 |
| 242 void Ref() { |
| 243 ++ref_; |
| 244 } |
| 245 |
| 246 // Returns true if the cursor was destroyed because of the unref. |
| 247 bool Unref() { |
| 248 if (--ref_ == 0) { |
| 249 delete this; |
| 250 return true; |
| 251 } |
| 252 return false; |
| 253 } |
| 254 |
| 255 private: |
| 256 XcursorImage* image_; |
| 257 int ref_; |
| 258 ::Cursor cursor_; |
| 259 |
| 260 DISALLOW_COPY_AND_ASSIGN(XCustomCursor); |
| 261 }; |
| 262 |
| 263 XCustomCursorCache() {} |
| 264 ~XCustomCursorCache() { |
| 265 Clear(); |
| 266 } |
| 267 |
| 268 std::map< ::Cursor, XCustomCursor*> cache_; |
| 269 DISALLOW_COPY_AND_ASSIGN(XCustomCursorCache); |
| 270 }; |
| 271 #endif // defined(USE_AURA) |
| 272 |
| 191 // A singleton object that remembers remappings of mouse buttons. | 273 // A singleton object that remembers remappings of mouse buttons. |
| 192 class XButtonMap { | 274 class XButtonMap { |
| 193 public: | 275 public: |
| 194 static XButtonMap* GetInstance() { | 276 static XButtonMap* GetInstance() { |
| 195 return Singleton<XButtonMap>::get(); | 277 return Singleton<XButtonMap>::get(); |
| 196 } | 278 } |
| 197 | 279 |
| 198 void UpdateMapping() { | 280 void UpdateMapping() { |
| 199 count_ = XGetPointerMapping(ui::GetXDisplay(), map_, arraysize(map_)); | 281 count_ = XGetPointerMapping(ui::GetXDisplay(), map_, arraysize(map_)); |
| 200 } | 282 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 render_supported = XRenderQueryExtension(dpy, &dummy, &dummy); | 381 render_supported = XRenderQueryExtension(dpy, &dummy, &dummy); |
| 300 render_supported_cached = true; | 382 render_supported_cached = true; |
| 301 | 383 |
| 302 return render_supported; | 384 return render_supported; |
| 303 } | 385 } |
| 304 | 386 |
| 305 int GetDefaultScreen(Display* display) { | 387 int GetDefaultScreen(Display* display) { |
| 306 return XDefaultScreen(display); | 388 return XDefaultScreen(display); |
| 307 } | 389 } |
| 308 | 390 |
| 309 Cursor GetXCursor(int cursor_shape) { | 391 ::Cursor GetXCursor(int cursor_shape) { |
| 310 CR_DEFINE_STATIC_LOCAL(XCursorCache, cache, ()); | 392 CR_DEFINE_STATIC_LOCAL(XCursorCache, cache, ()); |
| 311 | 393 |
| 312 if (cursor_shape == kCursorClearXCursorCache) { | 394 if (cursor_shape == kCursorClearXCursorCache) { |
| 313 cache.Clear(); | 395 cache.Clear(); |
| 314 return 0; | 396 return 0; |
| 315 } | 397 } |
| 316 | 398 |
| 317 return cache.GetCursor(cursor_shape); | 399 return cache.GetCursor(cursor_shape); |
| 318 } | 400 } |
| 319 | 401 |
| 402 #if defined(USE_AURA) |
| 403 ::Cursor CreateReffedCustomXCursor(XcursorImage* image) { |
| 404 return XCustomCursorCache::GetInstance()->InstallCustomCursor(image); |
| 405 } |
| 406 |
| 407 void RefCustomXCursor(::Cursor cursor) { |
| 408 XCustomCursorCache::GetInstance()->Ref(cursor); |
| 409 } |
| 410 |
| 411 void UnrefCustomXCursor(::Cursor cursor) { |
| 412 XCustomCursorCache::GetInstance()->Unref(cursor); |
| 413 } |
| 414 #endif |
| 415 |
| 320 XID GetX11RootWindow() { | 416 XID GetX11RootWindow() { |
| 321 return DefaultRootWindow(GetXDisplay()); | 417 return DefaultRootWindow(GetXDisplay()); |
| 322 } | 418 } |
| 323 | 419 |
| 324 bool GetCurrentDesktop(int* desktop) { | 420 bool GetCurrentDesktop(int* desktop) { |
| 325 return GetIntProperty(GetX11RootWindow(), "_NET_CURRENT_DESKTOP", desktop); | 421 return GetIntProperty(GetX11RootWindow(), "_NET_CURRENT_DESKTOP", desktop); |
| 326 } | 422 } |
| 327 | 423 |
| 328 #if defined(TOOLKIT_USES_GTK) | 424 #if defined(TOOLKIT_USES_GTK) |
| 329 XID GetX11WindowFromGtkWidget(GtkWidget* widget) { | 425 XID GetX11WindowFromGtkWidget(GtkWidget* widget) { |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 << "request_code " << static_cast<int>(error_event.request_code) << ", " | 1226 << "request_code " << static_cast<int>(error_event.request_code) << ", " |
| 1131 << "minor_code " << static_cast<int>(error_event.minor_code) | 1227 << "minor_code " << static_cast<int>(error_event.minor_code) |
| 1132 << " (" << request_str << ")"; | 1228 << " (" << request_str << ")"; |
| 1133 } | 1229 } |
| 1134 | 1230 |
| 1135 // ---------------------------------------------------------------------------- | 1231 // ---------------------------------------------------------------------------- |
| 1136 // End of x11_util_internal.h | 1232 // End of x11_util_internal.h |
| 1137 | 1233 |
| 1138 | 1234 |
| 1139 } // namespace ui | 1235 } // namespace ui |
| OLD | NEW |