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