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