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 25typedef unsigned long Atom; 26typedef unsigned long XID; 27typedef unsigned long XSharedMemoryId; // ShmSeg in the X headers. 28typedef struct _XDisplay Display; 29typedef unsigned long Cursor; 30typedef struct _XcursorImage XcursorImage; 31typedef union _XEvent XEvent; 32typedef struct _XImage XImage; 33typedef struct _XGC *GC; 34 35#if defined(TOOLKIT_GTK) 36typedef struct _GdkDrawable GdkWindow; 37typedef struct _GtkWidget GtkWidget; 38typedef struct _GtkWindow GtkWindow; 39#endif 40 41namespace gfx { 42class Rect; 43} 44class SkBitmap; 45 46namespace 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. 54UI_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. 60UI_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. 66enum SharedMemorySupport { 67 SHARED_MEMORY_NONE, 68 SHARED_MEMORY_PUTIMAGE, 69 SHARED_MEMORY_PIXMAP 70}; 71// Return the shared memory type of our X connection. 72UI_EXPORT SharedMemorySupport QuerySharedMemorySupport(Display* dpy); 73 74// Return true iff the display supports Xrender 75UI_EXPORT bool QueryRenderSupport(Display* dpy); 76 77// Return the default screen number for the display 78int GetDefaultScreen(Display* display); 79 80// Returns an X11 Cursor, sharable across the process. 81// |cursor_shape| is an X font cursor shape, see XCreateFontCursor(). 82UI_EXPORT ::Cursor GetXCursor(int cursor_shape); 83 84// Resets the cache used by GetXCursor(). Only useful for tests that may delete 85// the display. 86UI_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. 92UI_EXPORT ::Cursor CreateReffedCustomXCursor(XcursorImage* image); 93 94// Increases the refcount of the custom cursor. 95UI_EXPORT void RefCustomXCursor(::Cursor cursor); 96 97// Decreases the refcount of the custom cursor, and destroys it if it reaches 0. 98UI_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. 102UI_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|. 108UI_EXPORT int CoalescePendingMotionEvents(const XEvent* xev, 109 XEvent* last_event); 110#endif 111 112// Hides the host cursor. 113UI_EXPORT void HideHostCursor(); 114 115// Returns an invisible cursor. 116UI_EXPORT ::Cursor CreateInvisibleCursor(); 117 118// These functions do not cache their results -------------------------- 119 120// Get the X window id for the default root window 121UI_EXPORT XID GetX11RootWindow(); 122 123// Returns the user's current desktop. 124bool GetCurrentDesktop(int* desktop); 125 126#if defined(TOOLKIT_GTK) 127// Get the X window id for the given GTK widget. 128UI_EXPORT XID GetX11WindowFromGtkWidget(GtkWidget* widget); 129XID 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. 134UI_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*. 138UI_EXPORT void* GetVisualFromGtkWidget(GtkWidget* widget); 139#endif // defined(TOOLKIT_GTK) 140 141enum HideTitlebarWhenMaximized { 142 SHOW_TITLEBAR_WHEN_MAXIMIZED = 0, 143 HIDE_TITLEBAR_WHEN_MAXIMIZED = 1, 144}; 145// Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|. 146UI_EXPORT void SetHideTitlebarWhenMaximizedProperty( 147 XID window, 148 HideTitlebarWhenMaximized property); 149 150// Clears all regions of X11's default root window by filling black pixels. 151UI_EXPORT void ClearX11DefaultRootWindow(); 152 153// Return the number of bits-per-pixel for a pixmap of the given depth 154UI_EXPORT int BitsPerPixelForPixmapDepth(Display* display, int depth); 155 156// Returns true if |window| is visible. 157UI_EXPORT bool IsWindowVisible(XID window); 158 159// Returns the bounds of |window|. 160UI_EXPORT bool GetWindowRect(XID window, gfx::Rect* rect); 161 162// Returns true if |window| contains the point |screen_loc|. 163UI_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc); 164 165// Return true if |window| has any property with |property_name|. 166UI_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. 170UI_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. 183UI_EXPORT bool GetIntProperty(XID window, const std::string& property_name, 184 int* value); 185UI_EXPORT bool GetXIDProperty(XID window, const std::string& property_name, 186 XID* value); 187UI_EXPORT bool GetIntArrayProperty(XID window, const std::string& property_name, 188 std::vector<int>* value); 189UI_EXPORT bool GetAtomArrayProperty(XID window, 190 const std::string& property_name, 191 std::vector<Atom>* value); 192UI_EXPORT bool GetStringProperty( 193 XID window, const std::string& property_name, std::string* value); 194 195// These setters all make round trips. 196UI_EXPORT bool SetIntProperty(XID window, 197 const std::string& name, 198 const std::string& type, 199 int value); 200UI_EXPORT bool SetIntArrayProperty(XID window, 201 const std::string& name, 202 const std::string& type, 203 const std::vector<int>& value); 204UI_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. 210Atom GetAtom(const char* atom_name); 211 212// Get |window|'s parent window, or None if |window| is the root window. 213UI_EXPORT XID GetParentWindow(XID window); 214 215// Walk up |window|'s hierarchy until we find a direct child of |root|. 216XID GetHighestAncestorWindow(XID window, XID root); 217 218static const int kAllDesktops = -1; 219// Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if 220// property not found. 221bool GetWindowDesktop(XID window, int* desktop); 222 223// Translates an X11 error code into a printable string. 224UI_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. 228class 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|. 240UI_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate, 241 int max_depth); 242 243// Enumerates the top-level windows of the current display. 244UI_EXPORT void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate); 245 246// Returns all children windows of a given window in top-to-bottom stacking 247// order. 248UI_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. 254void 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. 258UI_EXPORT XSharedMemoryId AttachSharedMemory(Display* display, 259 int shared_memory_support); 260UI_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. 264UI_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. 270UI_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 280UI_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 289void FreePicture(Display* display, XID picture); 290void FreePixmap(Display* display, XID pixmap); 291 292enum 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. 308UI_EXPORT WindowManagerName GuessWindowManager(); 309 310// Change desktop for |window| to the desktop of |destination| window. 311UI_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. 316UI_EXPORT void SetDefaultX11ErrorHandlers(); 317 318// Return true if a given window is in full-screen mode. 319UI_EXPORT bool IsX11WindowFullScreen(XID window); 320 321// Return true if event type is MotionNotify. 322UI_EXPORT bool IsMotionEvent(XEvent* event); 323 324// Returns the mapped button. 325int GetMappedButton(int button); 326 327// Updates button mapping. This is usually called when a MappingNotify event is 328// received. 329UI_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>. 333UI_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. 341class 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. 363class 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. 378class 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. 401class 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