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/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 
     25 typedef unsigned long Atom;
     26 typedef unsigned long XID;
     27 typedef unsigned long XSharedMemoryId;  // ShmSeg in the X headers.
     28 typedef struct _XDisplay Display;
     29 typedef unsigned long Cursor;
     30 typedef struct _XcursorImage XcursorImage;
     31 typedef union _XEvent XEvent;
     32 typedef struct _XImage XImage;
     33 typedef struct _XGC *GC;
     34 
     35 #if defined(TOOLKIT_GTK)
     36 typedef struct _GdkDrawable GdkWindow;
     37 typedef struct _GtkWidget GtkWidget;
     38 typedef struct _GtkWindow GtkWindow;
     39 #endif
     40 
     41 namespace gfx {
     42 class Rect;
     43 }
     44 class SkBitmap;
     45 
     46 namespace 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.
     54 UI_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.
     60 UI_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.
     66 enum SharedMemorySupport {
     67   SHARED_MEMORY_NONE,
     68   SHARED_MEMORY_PUTIMAGE,
     69   SHARED_MEMORY_PIXMAP
     70 };
     71 // Return the shared memory type of our X connection.
     72 UI_EXPORT SharedMemorySupport QuerySharedMemorySupport(Display* dpy);
     73 
     74 // Return true iff the display supports Xrender
     75 UI_EXPORT bool QueryRenderSupport(Display* dpy);
     76 
     77 // Return the default screen number for the display
     78 int GetDefaultScreen(Display* display);
     79 
     80 // Returns an X11 Cursor, sharable across the process.
     81 // |cursor_shape| is an X font cursor shape, see XCreateFontCursor().
     82 UI_EXPORT ::Cursor GetXCursor(int cursor_shape);
     83 
     84 // Resets the cache used by GetXCursor(). Only useful for tests that may delete
     85 // the display.
     86 UI_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.
     92 UI_EXPORT ::Cursor CreateReffedCustomXCursor(XcursorImage* image);
     93 
     94 // Increases the refcount of the custom cursor.
     95 UI_EXPORT void RefCustomXCursor(::Cursor cursor);
     96 
     97 // Decreases the refcount of the custom cursor, and destroys it if it reaches 0.
     98 UI_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.
    102 UI_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|.
    108 UI_EXPORT int CoalescePendingMotionEvents(const XEvent* xev,
    109                                           XEvent* last_event);
    110 #endif
    111 
    112 // Hides the host cursor.
    113 UI_EXPORT void HideHostCursor();
    114 
    115 // Returns an invisible cursor.
    116 UI_EXPORT ::Cursor CreateInvisibleCursor();
    117 
    118 // These functions do not cache their results --------------------------
    119 
    120 // Get the X window id for the default root window
    121 UI_EXPORT XID GetX11RootWindow();
    122 
    123 // Returns the user's current desktop.
    124 bool GetCurrentDesktop(int* desktop);
    125 
    126 #if defined(TOOLKIT_GTK)
    127 // Get the X window id for the given GTK widget.
    128 UI_EXPORT XID GetX11WindowFromGtkWidget(GtkWidget* widget);
    129 XID 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.
    134 UI_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*.
    138 UI_EXPORT void* GetVisualFromGtkWidget(GtkWidget* widget);
    139 #endif  // defined(TOOLKIT_GTK)
    140 
    141 enum HideTitlebarWhenMaximized {
    142   SHOW_TITLEBAR_WHEN_MAXIMIZED = 0,
    143   HIDE_TITLEBAR_WHEN_MAXIMIZED = 1,
    144 };
    145 // Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|.
    146 UI_EXPORT void SetHideTitlebarWhenMaximizedProperty(
    147     XID window,
    148     HideTitlebarWhenMaximized property);
    149 
    150 // Clears all regions of X11's default root window by filling black pixels.
    151 UI_EXPORT void ClearX11DefaultRootWindow();
    152 
    153 // Return the number of bits-per-pixel for a pixmap of the given depth
    154 UI_EXPORT int BitsPerPixelForPixmapDepth(Display* display, int depth);
    155 
    156 // Returns true if |window| is visible.
    157 UI_EXPORT bool IsWindowVisible(XID window);
    158 
    159 // Returns the bounds of |window|.
    160 UI_EXPORT bool GetWindowRect(XID window, gfx::Rect* rect);
    161 
    162 // Returns true if |window| contains the point |screen_loc|.
    163 UI_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc);
    164 
    165 // Return true if |window| has any property with |property_name|.
    166 UI_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.
    170 UI_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.
    183 UI_EXPORT bool GetIntProperty(XID window, const std::string& property_name,
    184                               int* value);
    185 UI_EXPORT bool GetXIDProperty(XID window, const std::string& property_name,
    186                               XID* value);
    187 UI_EXPORT bool GetIntArrayProperty(XID window, const std::string& property_name,
    188                                    std::vector<int>* value);
    189 UI_EXPORT bool GetAtomArrayProperty(XID window,
    190                                     const std::string& property_name,
    191                                     std::vector<Atom>* value);
    192 UI_EXPORT bool GetStringProperty(
    193     XID window, const std::string& property_name, std::string* value);
    194 
    195 // These setters all make round trips.
    196 UI_EXPORT bool SetIntProperty(XID window,
    197                               const std::string& name,
    198                               const std::string& type,
    199                               int value);
    200 UI_EXPORT bool SetIntArrayProperty(XID window,
    201                                    const std::string& name,
    202                                    const std::string& type,
    203                                    const std::vector<int>& value);
    204 UI_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.
    210 Atom GetAtom(const char* atom_name);
    211 
    212 // Get |window|'s parent window, or None if |window| is the root window.
    213 UI_EXPORT XID GetParentWindow(XID window);
    214 
    215 // Walk up |window|'s hierarchy until we find a direct child of |root|.
    216 XID GetHighestAncestorWindow(XID window, XID root);
    217 
    218 static const int kAllDesktops = -1;
    219 // Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if
    220 // property not found.
    221 bool GetWindowDesktop(XID window, int* desktop);
    222 
    223 // Translates an X11 error code into a printable string.
    224 UI_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.
    228 class 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|.
    240 UI_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate,
    241                                    int max_depth);
    242 
    243 // Enumerates the top-level windows of the current display.
    244 UI_EXPORT void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate);
    245 
    246 // Returns all children windows of a given window in top-to-bottom stacking
    247 // order.
    248 UI_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.
    254 void 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.
    258 UI_EXPORT XSharedMemoryId AttachSharedMemory(Display* display,
    259                                              int shared_memory_support);
    260 UI_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.
    264 UI_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.
    270 UI_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
    280 UI_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 
    289 void FreePicture(Display* display, XID picture);
    290 void FreePixmap(Display* display, XID pixmap);
    291 
    292 enum 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.
    308 UI_EXPORT WindowManagerName GuessWindowManager();
    309 
    310 // Change desktop for |window| to the desktop of |destination| window.
    311 UI_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.
    316 UI_EXPORT void SetDefaultX11ErrorHandlers();
    317 
    318 // Return true if a given window is in full-screen mode.
    319 UI_EXPORT bool IsX11WindowFullScreen(XID window);
    320 
    321 // Return true if event type is MotionNotify.
    322 UI_EXPORT bool IsMotionEvent(XEvent* event);
    323 
    324 // Returns the mapped button.
    325 int GetMappedButton(int button);
    326 
    327 // Updates button mapping. This is usually called when a MappingNotify event is
    328 // received.
    329 UI_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>.
    333 UI_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.
    341 class 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.
    363 class 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.
    378 class 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.
    401 class 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