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