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