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 3 // found in the LICENSE file. 4 5 #ifndef UI_BASE_X_X11_UTIL_H_ 6 #define UI_BASE_X_X11_UTIL_H_ 7 8 // This file declares utility functions for X11 (Linux only). 9 // 10 // These functions do not require the Xlib headers to be included (which is why 11 // we use a void* for Visual*). The Xlib headers are highly polluting so we try 12 // hard to limit their spread into the rest of the code. 13 14 #include <string> 15 #include <vector> 16 17 #include "base/basictypes.h" 18 #include "base/event_types.h" 19 #include "base/memory/ref_counted_memory.h" 20 #include "ui/base/ui_base_export.h" 21 #include "ui/events/event_constants.h" 22 #include "ui/events/keycodes/keyboard_codes.h" 23 #include "ui/gfx/point.h" 24 #include "ui/gfx/x/x11_types.h" 25 26 typedef unsigned long XSharedMemoryId; // ShmSeg in the X headers. 27 typedef unsigned long Cursor; 28 typedef struct _XcursorImage XcursorImage; 29 typedef union _XEvent XEvent; 30 31 namespace gfx { 32 class Canvas; 33 class Point; 34 class Rect; 35 } 36 class SkBitmap; 37 38 namespace ui { 39 40 // These functions use the default display and this /must/ be called from 41 // the UI thread. Thus, they don't support multiple displays. 42 43 // These functions cache their results --------------------------------- 44 45 // Returns true if the system supports XINPUT2. 46 UI_BASE_EXPORT bool IsXInput2Available(); 47 48 // X shared memory comes in three flavors: 49 // 1) No SHM support, 50 // 2) SHM putimage, 51 // 3) SHM pixmaps + putimage. 52 enum SharedMemorySupport { 53 SHARED_MEMORY_NONE, 54 SHARED_MEMORY_PUTIMAGE, 55 SHARED_MEMORY_PIXMAP 56 }; 57 // Return the shared memory type of our X connection. 58 UI_BASE_EXPORT SharedMemorySupport QuerySharedMemorySupport(XDisplay* dpy); 59 60 // Return true iff the display supports Xrender 61 UI_BASE_EXPORT bool QueryRenderSupport(XDisplay* dpy); 62 63 // Returns an X11 Cursor, sharable across the process. 64 // |cursor_shape| is an X font cursor shape, see XCreateFontCursor(). 65 UI_BASE_EXPORT ::Cursor GetXCursor(int cursor_shape); 66 67 // Creates a custom X cursor from the image. This takes ownership of image. The 68 // caller must not free/modify the image. The refcount of the newly created 69 // cursor is set to 1. 70 UI_BASE_EXPORT ::Cursor CreateReffedCustomXCursor(XcursorImage* image); 71 72 // Increases the refcount of the custom cursor. 73 UI_BASE_EXPORT void RefCustomXCursor(::Cursor cursor); 74 75 // Decreases the refcount of the custom cursor, and destroys it if it reaches 0. 76 UI_BASE_EXPORT void UnrefCustomXCursor(::Cursor cursor); 77 78 // Creates a XcursorImage and copies the SkBitmap |bitmap| on it. |bitmap| 79 // should be non-null. Caller owns the returned object. 80 UI_BASE_EXPORT XcursorImage* SkBitmapToXcursorImage(const SkBitmap* bitmap, 81 const gfx::Point& hotspot); 82 83 // Coalesce all pending motion events (touch or mouse) that are at the top of 84 // the queue, and return the number eliminated, storing the last one in 85 // |last_event|. 86 UI_BASE_EXPORT int CoalescePendingMotionEvents(const XEvent* xev, 87 XEvent* last_event); 88 89 // Hides the host cursor. 90 UI_BASE_EXPORT void HideHostCursor(); 91 92 // Returns an invisible cursor. 93 UI_BASE_EXPORT ::Cursor CreateInvisibleCursor(); 94 95 // Sets whether |window| should use the OS window frame. 96 UI_BASE_EXPORT void SetUseOSWindowFrame(XID window, bool use_os_window_frame); 97 98 // These functions do not cache their results -------------------------- 99 100 // Returns true if the shape extension is supported. 101 UI_BASE_EXPORT bool IsShapeExtensionAvailable(); 102 103 // Get the X window id for the default root window 104 UI_BASE_EXPORT XID GetX11RootWindow(); 105 106 // Returns the user's current desktop. 107 UI_BASE_EXPORT bool GetCurrentDesktop(int* desktop); 108 109 enum HideTitlebarWhenMaximized { 110 SHOW_TITLEBAR_WHEN_MAXIMIZED = 0, 111 HIDE_TITLEBAR_WHEN_MAXIMIZED = 1, 112 }; 113 // Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|. 114 UI_BASE_EXPORT void SetHideTitlebarWhenMaximizedProperty( 115 XID window, 116 HideTitlebarWhenMaximized property); 117 118 // Clears all regions of X11's default root window by filling black pixels. 119 UI_BASE_EXPORT void ClearX11DefaultRootWindow(); 120 121 // Returns true if |window| is visible. 122 UI_BASE_EXPORT bool IsWindowVisible(XID window); 123 124 // Returns the bounds of |window|. 125 UI_BASE_EXPORT bool GetWindowRect(XID window, gfx::Rect* rect); 126 127 // Returns true if |window| contains the point |screen_loc|. 128 UI_BASE_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc); 129 130 // Return true if |window| has any property with |property_name|. 131 UI_BASE_EXPORT bool PropertyExists(XID window, 132 const std::string& property_name); 133 134 // Returns the raw bytes from a property with minimal 135 // interpretation. |out_data| should be freed by XFree() after use. 136 UI_BASE_EXPORT bool GetRawBytesOfProperty( 137 XID window, 138 XAtom property, 139 scoped_refptr<base::RefCountedMemory>* out_data, 140 size_t* out_data_items, 141 XAtom* out_type); 142 143 // Get the value of an int, int array, atom array or string property. On 144 // success, true is returned and the value is stored in |value|. 145 // 146 // TODO(erg): Once we remove the gtk port and are 100% aura, all of these 147 // should accept an XAtom instead of a string. 148 UI_BASE_EXPORT bool GetIntProperty(XID window, 149 const std::string& property_name, 150 int* value); 151 UI_BASE_EXPORT bool GetXIDProperty(XID window, 152 const std::string& property_name, 153 XID* value); 154 UI_BASE_EXPORT bool GetIntArrayProperty(XID window, 155 const std::string& property_name, 156 std::vector<int>* value); 157 UI_BASE_EXPORT bool GetAtomArrayProperty(XID window, 158 const std::string& property_name, 159 std::vector<XAtom>* value); 160 UI_BASE_EXPORT bool GetStringProperty(XID window, 161 const std::string& property_name, 162 std::string* value); 163 164 // These setters all make round trips. 165 UI_BASE_EXPORT bool SetIntProperty(XID window, 166 const std::string& name, 167 const std::string& type, 168 int value); 169 UI_BASE_EXPORT bool SetIntArrayProperty(XID window, 170 const std::string& name, 171 const std::string& type, 172 const std::vector<int>& value); 173 UI_BASE_EXPORT bool SetAtomProperty(XID window, 174 const std::string& name, 175 const std::string& type, 176 XAtom value); 177 UI_BASE_EXPORT bool SetAtomArrayProperty(XID window, 178 const std::string& name, 179 const std::string& type, 180 const std::vector<XAtom>& value); 181 UI_BASE_EXPORT bool SetStringProperty(XID window, 182 XAtom property, 183 XAtom type, 184 const std::string& value); 185 186 // Gets the X atom for default display corresponding to atom_name. 187 UI_BASE_EXPORT XAtom GetAtom(const char* atom_name); 188 189 // Sets the WM_CLASS attribute for a given X11 window. 190 UI_BASE_EXPORT void SetWindowClassHint(XDisplay* display, 191 XID window, 192 const std::string& res_name, 193 const std::string& res_class); 194 195 // Sets the WM_WINDOW_ROLE attribute for a given X11 window. 196 UI_BASE_EXPORT void SetWindowRole(XDisplay* display, 197 XID window, 198 const std::string& role); 199 200 // Determine whether we should default to native decorations or the custom 201 // frame based on the currently-running window manager. 202 UI_BASE_EXPORT bool GetCustomFramePrefDefault(); 203 204 static const int kAllDesktops = -1; 205 // Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if 206 // property not found. 207 bool GetWindowDesktop(XID window, int* desktop); 208 209 // Translates an X11 error code into a printable string. 210 UI_BASE_EXPORT std::string GetX11ErrorString(XDisplay* display, int err); 211 212 // Implementers of this interface receive a notification for every X window of 213 // the main display. 214 class EnumerateWindowsDelegate { 215 public: 216 // |xid| is the X Window ID of the enumerated window. Return true to stop 217 // further iteration. 218 virtual bool ShouldStopIterating(XID xid) = 0; 219 220 protected: 221 virtual ~EnumerateWindowsDelegate() {} 222 }; 223 224 // Enumerates all windows in the current display. Will recurse into child 225 // windows up to a depth of |max_depth|. 226 UI_BASE_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate, 227 int max_depth); 228 229 // Enumerates the top-level windows of the current display. 230 UI_BASE_EXPORT void EnumerateTopLevelWindows( 231 ui::EnumerateWindowsDelegate* delegate); 232 233 // Returns all children windows of a given window in top-to-bottom stacking 234 // order. 235 UI_BASE_EXPORT bool GetXWindowStack(XID window, std::vector<XID>* windows); 236 237 // Copies |source_bounds| from |drawable| to |canvas| at offset |dest_offset|. 238 // |source_bounds| is in physical pixels, while |dest_offset| is relative to 239 // the canvas's scale. Note that this function is slow since it uses 240 // XGetImage() to copy the data from the X server to this process before 241 // copying it to |canvas|. 242 UI_BASE_EXPORT bool CopyAreaToCanvas(XID drawable, 243 gfx::Rect source_bounds, 244 gfx::Point dest_offset, 245 gfx::Canvas* canvas); 246 247 enum WindowManagerName { 248 WM_UNKNOWN, 249 250 WM_AWESOME, 251 WM_BLACKBOX, 252 WM_COMPIZ, 253 WM_ENLIGHTENMENT, 254 WM_I3, 255 WM_ICE_WM, 256 WM_ION3, 257 WM_KWIN, 258 WM_MATCHBOX, 259 WM_METACITY, 260 WM_MUFFIN, 261 WM_MUTTER, 262 WM_NOTION, 263 WM_OPENBOX, 264 WM_QTILE, 265 WM_RATPOISON, 266 WM_STUMPWM, 267 WM_XFWM4, 268 }; 269 // Attempts to guess the window maager. Returns WM_UNKNOWN if we can't 270 // determine it for one reason or another. 271 UI_BASE_EXPORT WindowManagerName GuessWindowManager(); 272 273 // The same as GuessWindowManager(), but returns the raw string. If we 274 // can't determine it, return "Unknown". 275 UI_BASE_EXPORT std::string GuessWindowManagerName(); 276 277 // Enable the default X error handlers. These will log the error and abort 278 // the process if called. Use SetX11ErrorHandlers() from x11_util_internal.h 279 // to set your own error handlers. 280 UI_BASE_EXPORT void SetDefaultX11ErrorHandlers(); 281 282 // Returns true if a given window is in full-screen mode. 283 UI_BASE_EXPORT bool IsX11WindowFullScreen(XID window); 284 285 // Returns true if the window manager supports the given hint. 286 UI_BASE_EXPORT bool WmSupportsHint(XAtom atom); 287 288 // Manages a piece of X11 allocated memory as a RefCountedMemory segment. This 289 // object takes ownership over the passed in memory and will free it with the 290 // X11 allocator when done. 291 class UI_BASE_EXPORT XRefcountedMemory : public base::RefCountedMemory { 292 public: 293 XRefcountedMemory(unsigned char* x11_data, size_t length) 294 : x11_data_(length ? x11_data : NULL), length_(length) {} 295 296 // Overridden from RefCountedMemory: 297 virtual const unsigned char* front() const OVERRIDE; 298 virtual size_t size() const OVERRIDE; 299 300 private: 301 virtual ~XRefcountedMemory(); 302 303 unsigned char* x11_data_; 304 size_t length_; 305 306 DISALLOW_COPY_AND_ASSIGN(XRefcountedMemory); 307 }; 308 309 // Keeps track of a string returned by an X function (e.g. XGetAtomName) and 310 // makes sure it's XFree'd. 311 class UI_BASE_EXPORT XScopedString { 312 public: 313 explicit XScopedString(char* str) : string_(str) {} 314 ~XScopedString(); 315 316 const char* string() const { return string_; } 317 318 private: 319 char* string_; 320 321 DISALLOW_COPY_AND_ASSIGN(XScopedString); 322 }; 323 324 // Keeps track of an image returned by an X function (e.g. XGetImage) and 325 // makes sure it's XDestroyImage'd. 326 class UI_BASE_EXPORT XScopedImage { 327 public: 328 explicit XScopedImage(XImage* image) : image_(image) {} 329 ~XScopedImage(); 330 331 XImage* get() const { return image_; } 332 333 XImage* operator->() const { return image_; } 334 335 void reset(XImage* image); 336 337 private: 338 XImage* image_; 339 340 DISALLOW_COPY_AND_ASSIGN(XScopedImage); 341 }; 342 343 // Keeps track of a cursor returned by an X function and makes sure it's 344 // XFreeCursor'd. 345 class UI_BASE_EXPORT XScopedCursor { 346 public: 347 // Keeps track of |cursor| created with |display|. 348 XScopedCursor(::Cursor cursor, XDisplay* display); 349 ~XScopedCursor(); 350 351 ::Cursor get() const; 352 void reset(::Cursor cursor); 353 354 private: 355 ::Cursor cursor_; 356 XDisplay* display_; 357 358 DISALLOW_COPY_AND_ASSIGN(XScopedCursor); 359 }; 360 361 namespace test { 362 // Resets the cache used by GetXCursor(). Only useful for tests that may delete 363 // the display. 364 UI_BASE_EXPORT void ResetXCursorCache(); 365 366 // Returns the cached XcursorImage for |cursor|. 367 UI_BASE_EXPORT const XcursorImage* GetCachedXcursorImage(::Cursor cursor); 368 369 } // namespace test 370 371 } // namespace ui 372 373 #endif // UI_BASE_X_X11_UTIL_H_ 374