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