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/ui_base_export.h"
21#include "ui/events/event_constants.h"
22#include "ui/events/keycodes/keyboard_codes.h"
23#include "ui/gfx/point.h"
24#include "ui/gfx/x/x11_types.h"
25
26typedef unsigned long XSharedMemoryId;  // ShmSeg in the X headers.
27typedef unsigned long Cursor;
28typedef struct _XcursorImage XcursorImage;
29typedef union _XEvent XEvent;
30
31namespace gfx {
32class Canvas;
33class Point;
34class Rect;
35}
36class SkBitmap;
37
38namespace ui {
39
40// These functions use the default display and this /must/ be called from
41// the UI thread. Thus, they don't support multiple displays.
42
43// These functions cache their results ---------------------------------
44
45// Returns true if the system supports XINPUT2.
46UI_BASE_EXPORT bool IsXInput2Available();
47
48// X shared memory comes in three flavors:
49// 1) No SHM support,
50// 2) SHM putimage,
51// 3) SHM pixmaps + putimage.
52enum SharedMemorySupport {
53  SHARED_MEMORY_NONE,
54  SHARED_MEMORY_PUTIMAGE,
55  SHARED_MEMORY_PIXMAP
56};
57// Return the shared memory type of our X connection.
58UI_BASE_EXPORT SharedMemorySupport QuerySharedMemorySupport(XDisplay* dpy);
59
60// Return true iff the display supports Xrender
61UI_BASE_EXPORT bool QueryRenderSupport(XDisplay* dpy);
62
63// Returns an X11 Cursor, sharable across the process.
64// |cursor_shape| is an X font cursor shape, see XCreateFontCursor().
65UI_BASE_EXPORT ::Cursor GetXCursor(int cursor_shape);
66
67// Creates a custom X cursor from the image. This takes ownership of image. The
68// caller must not free/modify the image. The refcount of the newly created
69// cursor is set to 1.
70UI_BASE_EXPORT ::Cursor CreateReffedCustomXCursor(XcursorImage* image);
71
72// Increases the refcount of the custom cursor.
73UI_BASE_EXPORT void RefCustomXCursor(::Cursor cursor);
74
75// Decreases the refcount of the custom cursor, and destroys it if it reaches 0.
76UI_BASE_EXPORT void UnrefCustomXCursor(::Cursor cursor);
77
78// Creates a XcursorImage and copies the SkBitmap |bitmap| on it. |bitmap|
79// should be non-null. Caller owns the returned object.
80UI_BASE_EXPORT XcursorImage* SkBitmapToXcursorImage(const SkBitmap* bitmap,
81                                                    const gfx::Point& hotspot);
82
83// Coalesce all pending motion events (touch or mouse) that are at the top of
84// the queue, and return the number eliminated, storing the last one in
85// |last_event|.
86UI_BASE_EXPORT int CoalescePendingMotionEvents(const XEvent* xev,
87                                               XEvent* last_event);
88
89// Hides the host cursor.
90UI_BASE_EXPORT void HideHostCursor();
91
92// Returns an invisible cursor.
93UI_BASE_EXPORT ::Cursor CreateInvisibleCursor();
94
95// Sets whether |window| should use the OS window frame.
96UI_BASE_EXPORT void SetUseOSWindowFrame(XID window, bool use_os_window_frame);
97
98// These functions do not cache their results --------------------------
99
100// Returns true if the shape extension is supported.
101UI_BASE_EXPORT bool IsShapeExtensionAvailable();
102
103// Get the X window id for the default root window
104UI_BASE_EXPORT XID GetX11RootWindow();
105
106// Returns the user's current desktop.
107UI_BASE_EXPORT bool GetCurrentDesktop(int* desktop);
108
109enum HideTitlebarWhenMaximized {
110  SHOW_TITLEBAR_WHEN_MAXIMIZED = 0,
111  HIDE_TITLEBAR_WHEN_MAXIMIZED = 1,
112};
113// Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|.
114UI_BASE_EXPORT void SetHideTitlebarWhenMaximizedProperty(
115    XID window,
116    HideTitlebarWhenMaximized property);
117
118// Clears all regions of X11's default root window by filling black pixels.
119UI_BASE_EXPORT void ClearX11DefaultRootWindow();
120
121// Returns true if |window| is visible.
122UI_BASE_EXPORT bool IsWindowVisible(XID window);
123
124// Returns the bounds of |window|.
125UI_BASE_EXPORT bool GetWindowRect(XID window, gfx::Rect* rect);
126
127// Returns true if |window| contains the point |screen_loc|.
128UI_BASE_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc);
129
130// Return true if |window| has any property with |property_name|.
131UI_BASE_EXPORT bool PropertyExists(XID window,
132                                   const std::string& property_name);
133
134// Returns the raw bytes from a property with minimal
135// interpretation. |out_data| should be freed by XFree() after use.
136UI_BASE_EXPORT bool GetRawBytesOfProperty(
137    XID window,
138    XAtom property,
139    scoped_refptr<base::RefCountedMemory>* out_data,
140    size_t* out_data_items,
141    XAtom* out_type);
142
143// Get the value of an int, int array, atom array or string property.  On
144// success, true is returned and the value is stored in |value|.
145//
146// TODO(erg): Once we remove the gtk port and are 100% aura, all of these
147// should accept an XAtom instead of a string.
148UI_BASE_EXPORT bool GetIntProperty(XID window,
149                                   const std::string& property_name,
150                                   int* value);
151UI_BASE_EXPORT bool GetXIDProperty(XID window,
152                                   const std::string& property_name,
153                                   XID* value);
154UI_BASE_EXPORT bool GetIntArrayProperty(XID window,
155                                        const std::string& property_name,
156                                        std::vector<int>* value);
157UI_BASE_EXPORT bool GetAtomArrayProperty(XID window,
158                                         const std::string& property_name,
159                                         std::vector<XAtom>* value);
160UI_BASE_EXPORT bool GetStringProperty(XID window,
161                                      const std::string& property_name,
162                                      std::string* value);
163
164// These setters all make round trips.
165UI_BASE_EXPORT bool SetIntProperty(XID window,
166                                   const std::string& name,
167                                   const std::string& type,
168                                   int value);
169UI_BASE_EXPORT bool SetIntArrayProperty(XID window,
170                                        const std::string& name,
171                                        const std::string& type,
172                                        const std::vector<int>& value);
173UI_BASE_EXPORT bool SetAtomProperty(XID window,
174                                    const std::string& name,
175                                    const std::string& type,
176                                    XAtom value);
177UI_BASE_EXPORT bool SetAtomArrayProperty(XID window,
178                                         const std::string& name,
179                                         const std::string& type,
180                                         const std::vector<XAtom>& value);
181UI_BASE_EXPORT bool SetStringProperty(XID window,
182                                      XAtom property,
183                                      XAtom type,
184                                      const std::string& value);
185
186// Gets the X atom for default display corresponding to atom_name.
187UI_BASE_EXPORT XAtom GetAtom(const char* atom_name);
188
189// Sets the WM_CLASS attribute for a given X11 window.
190UI_BASE_EXPORT void SetWindowClassHint(XDisplay* display,
191                                       XID window,
192                                       const std::string& res_name,
193                                       const std::string& res_class);
194
195// Sets the WM_WINDOW_ROLE attribute for a given X11 window.
196UI_BASE_EXPORT void SetWindowRole(XDisplay* display,
197                                  XID window,
198                                  const std::string& role);
199
200// Determine whether we should default to native decorations or the custom
201// frame based on the currently-running window manager.
202UI_BASE_EXPORT bool GetCustomFramePrefDefault();
203
204static const int kAllDesktops = -1;
205// Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if
206// property not found.
207bool GetWindowDesktop(XID window, int* desktop);
208
209// Translates an X11 error code into a printable string.
210UI_BASE_EXPORT std::string GetX11ErrorString(XDisplay* display, int err);
211
212// Implementers of this interface receive a notification for every X window of
213// the main display.
214class EnumerateWindowsDelegate {
215 public:
216  // |xid| is the X Window ID of the enumerated window.  Return true to stop
217  // further iteration.
218  virtual bool ShouldStopIterating(XID xid) = 0;
219
220 protected:
221  virtual ~EnumerateWindowsDelegate() {}
222};
223
224// Enumerates all windows in the current display.  Will recurse into child
225// windows up to a depth of |max_depth|.
226UI_BASE_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate,
227                                        int max_depth);
228
229// Enumerates the top-level windows of the current display.
230UI_BASE_EXPORT void EnumerateTopLevelWindows(
231    ui::EnumerateWindowsDelegate* delegate);
232
233// Returns all children windows of a given window in top-to-bottom stacking
234// order.
235UI_BASE_EXPORT bool GetXWindowStack(XID window, std::vector<XID>* windows);
236
237// Copies |source_bounds| from |drawable| to |canvas| at offset |dest_offset|.
238// |source_bounds| is in physical pixels, while |dest_offset| is relative to
239// the canvas's scale. Note that this function is slow since it uses
240// XGetImage() to copy the data from the X server to this process before
241// copying it to |canvas|.
242UI_BASE_EXPORT bool CopyAreaToCanvas(XID drawable,
243                                     gfx::Rect source_bounds,
244                                     gfx::Point dest_offset,
245                                     gfx::Canvas* canvas);
246
247enum WindowManagerName {
248  WM_UNKNOWN,
249
250  WM_AWESOME,
251  WM_BLACKBOX,
252  WM_COMPIZ,
253  WM_ENLIGHTENMENT,
254  WM_I3,
255  WM_ICE_WM,
256  WM_ION3,
257  WM_KWIN,
258  WM_MATCHBOX,
259  WM_METACITY,
260  WM_MUFFIN,
261  WM_MUTTER,
262  WM_NOTION,
263  WM_OPENBOX,
264  WM_QTILE,
265  WM_RATPOISON,
266  WM_STUMPWM,
267  WM_XFWM4,
268};
269// Attempts to guess the window maager. Returns WM_UNKNOWN if we can't
270// determine it for one reason or another.
271UI_BASE_EXPORT WindowManagerName GuessWindowManager();
272
273// The same as GuessWindowManager(), but returns the raw string.  If we
274// can't determine it, return "Unknown".
275UI_BASE_EXPORT std::string GuessWindowManagerName();
276
277// Enable the default X error handlers. These will log the error and abort
278// the process if called. Use SetX11ErrorHandlers() from x11_util_internal.h
279// to set your own error handlers.
280UI_BASE_EXPORT void SetDefaultX11ErrorHandlers();
281
282// Returns true if a given window is in full-screen mode.
283UI_BASE_EXPORT bool IsX11WindowFullScreen(XID window);
284
285// Returns true if the window manager supports the given hint.
286UI_BASE_EXPORT bool WmSupportsHint(XAtom atom);
287
288// Manages a piece of X11 allocated memory as a RefCountedMemory segment. This
289// object takes ownership over the passed in memory and will free it with the
290// X11 allocator when done.
291class UI_BASE_EXPORT XRefcountedMemory : public base::RefCountedMemory {
292 public:
293  XRefcountedMemory(unsigned char* x11_data, size_t length)
294      : x11_data_(length ? x11_data : NULL), length_(length) {}
295
296  // Overridden from RefCountedMemory:
297  virtual const unsigned char* front() const OVERRIDE;
298  virtual size_t size() const OVERRIDE;
299
300 private:
301  virtual ~XRefcountedMemory();
302
303  unsigned char* x11_data_;
304  size_t length_;
305
306  DISALLOW_COPY_AND_ASSIGN(XRefcountedMemory);
307};
308
309// Keeps track of a string returned by an X function (e.g. XGetAtomName) and
310// makes sure it's XFree'd.
311class UI_BASE_EXPORT XScopedString {
312 public:
313  explicit XScopedString(char* str) : string_(str) {}
314  ~XScopedString();
315
316  const char* string() const { return string_; }
317
318 private:
319  char* string_;
320
321  DISALLOW_COPY_AND_ASSIGN(XScopedString);
322};
323
324// Keeps track of an image returned by an X function (e.g. XGetImage) and
325// makes sure it's XDestroyImage'd.
326class UI_BASE_EXPORT XScopedImage {
327 public:
328  explicit XScopedImage(XImage* image) : image_(image) {}
329  ~XScopedImage();
330
331  XImage* get() const { return image_; }
332
333  XImage* operator->() const { return image_; }
334
335  void reset(XImage* image);
336
337 private:
338  XImage* image_;
339
340  DISALLOW_COPY_AND_ASSIGN(XScopedImage);
341};
342
343// Keeps track of a cursor returned by an X function and makes sure it's
344// XFreeCursor'd.
345class UI_BASE_EXPORT XScopedCursor {
346 public:
347  // Keeps track of |cursor| created with |display|.
348  XScopedCursor(::Cursor cursor, XDisplay* display);
349  ~XScopedCursor();
350
351  ::Cursor get() const;
352  void reset(::Cursor cursor);
353
354 private:
355  ::Cursor cursor_;
356  XDisplay* display_;
357
358  DISALLOW_COPY_AND_ASSIGN(XScopedCursor);
359};
360
361namespace test {
362// Resets the cache used by GetXCursor(). Only useful for tests that may delete
363// the display.
364UI_BASE_EXPORT void ResetXCursorCache();
365
366// Returns the cached XcursorImage for |cursor|.
367UI_BASE_EXPORT const XcursorImage* GetCachedXcursorImage(::Cursor cursor);
368
369}  // namespace test
370
371}  // namespace ui
372
373#endif  // UI_BASE_X_X11_UTIL_H_
374