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