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