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