|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef UI_BASE_X_X11_UTIL_H_ | 
|  | #define UI_BASE_X_X11_UTIL_H_ | 
|  |  | 
|  | // This file declares utility functions for X11 (Linux only). | 
|  | // | 
|  | // These functions do not require the Xlib headers to be included (which is why | 
|  | // we use a void* for Visual*). The Xlib headers are highly polluting so we try | 
|  | // hard to limit their spread into the rest of the code. | 
|  |  | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/basictypes.h" | 
|  | #include "base/event_types.h" | 
|  | #include "base/memory/ref_counted_memory.h" | 
|  | #include "ui/base/ui_base_export.h" | 
|  | #include "ui/events/event_constants.h" | 
|  | #include "ui/events/keycodes/keyboard_codes.h" | 
|  | #include "ui/gfx/point.h" | 
|  | #include "ui/gfx/x/x11_types.h" | 
|  |  | 
|  | typedef unsigned long XSharedMemoryId;  // ShmSeg in the X headers. | 
|  | typedef unsigned long Cursor; | 
|  | typedef struct _XcursorImage XcursorImage; | 
|  | typedef union _XEvent XEvent; | 
|  |  | 
|  | namespace gfx { | 
|  | class Canvas; | 
|  | class Point; | 
|  | class Rect; | 
|  | } | 
|  | class SkBitmap; | 
|  |  | 
|  | namespace ui { | 
|  |  | 
|  | // These functions use the default display and this /must/ be called from | 
|  | // the UI thread. Thus, they don't support multiple displays. | 
|  |  | 
|  | // These functions cache their results --------------------------------- | 
|  |  | 
|  | // Returns true if the system supports XINPUT2. | 
|  | UI_BASE_EXPORT bool IsXInput2Available(); | 
|  |  | 
|  | // X shared memory comes in three flavors: | 
|  | // 1) No SHM support, | 
|  | // 2) SHM putimage, | 
|  | // 3) SHM pixmaps + putimage. | 
|  | enum SharedMemorySupport { | 
|  | SHARED_MEMORY_NONE, | 
|  | SHARED_MEMORY_PUTIMAGE, | 
|  | SHARED_MEMORY_PIXMAP | 
|  | }; | 
|  | // Return the shared memory type of our X connection. | 
|  | UI_BASE_EXPORT SharedMemorySupport QuerySharedMemorySupport(XDisplay* dpy); | 
|  |  | 
|  | // Return true iff the display supports Xrender | 
|  | UI_BASE_EXPORT bool QueryRenderSupport(XDisplay* dpy); | 
|  |  | 
|  | // Returns an X11 Cursor, sharable across the process. | 
|  | // |cursor_shape| is an X font cursor shape, see XCreateFontCursor(). | 
|  | UI_BASE_EXPORT ::Cursor GetXCursor(int cursor_shape); | 
|  |  | 
|  | // Creates a custom X cursor from the image. This takes ownership of image. The | 
|  | // caller must not free/modify the image. The refcount of the newly created | 
|  | // cursor is set to 1. | 
|  | UI_BASE_EXPORT ::Cursor CreateReffedCustomXCursor(XcursorImage* image); | 
|  |  | 
|  | // Increases the refcount of the custom cursor. | 
|  | UI_BASE_EXPORT void RefCustomXCursor(::Cursor cursor); | 
|  |  | 
|  | // Decreases the refcount of the custom cursor, and destroys it if it reaches 0. | 
|  | UI_BASE_EXPORT void UnrefCustomXCursor(::Cursor cursor); | 
|  |  | 
|  | // Creates a XcursorImage and copies the SkBitmap |bitmap| on it. |bitmap| | 
|  | // should be non-null. Caller owns the returned object. | 
|  | UI_BASE_EXPORT XcursorImage* SkBitmapToXcursorImage(const SkBitmap* bitmap, | 
|  | const gfx::Point& hotspot); | 
|  |  | 
|  | // Coalesce all pending motion events (touch or mouse) that are at the top of | 
|  | // the queue, and return the number eliminated, storing the last one in | 
|  | // |last_event|. | 
|  | UI_BASE_EXPORT int CoalescePendingMotionEvents(const XEvent* xev, | 
|  | XEvent* last_event); | 
|  |  | 
|  | // Hides the host cursor. | 
|  | UI_BASE_EXPORT void HideHostCursor(); | 
|  |  | 
|  | // Returns an invisible cursor. | 
|  | UI_BASE_EXPORT ::Cursor CreateInvisibleCursor(); | 
|  |  | 
|  | // Sets whether |window| should use the OS window frame. | 
|  | UI_BASE_EXPORT void SetUseOSWindowFrame(XID window, bool use_os_window_frame); | 
|  |  | 
|  | // These functions do not cache their results -------------------------- | 
|  |  | 
|  | // Returns true if the shape extension is supported. | 
|  | UI_BASE_EXPORT bool IsShapeExtensionAvailable(); | 
|  |  | 
|  | // Get the X window id for the default root window | 
|  | UI_BASE_EXPORT XID GetX11RootWindow(); | 
|  |  | 
|  | // Returns the user's current desktop. | 
|  | UI_BASE_EXPORT bool GetCurrentDesktop(int* desktop); | 
|  |  | 
|  | enum HideTitlebarWhenMaximized { | 
|  | SHOW_TITLEBAR_WHEN_MAXIMIZED = 0, | 
|  | HIDE_TITLEBAR_WHEN_MAXIMIZED = 1, | 
|  | }; | 
|  | // Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|. | 
|  | UI_BASE_EXPORT void SetHideTitlebarWhenMaximizedProperty( | 
|  | XID window, | 
|  | HideTitlebarWhenMaximized property); | 
|  |  | 
|  | // Clears all regions of X11's default root window by filling black pixels. | 
|  | UI_BASE_EXPORT void ClearX11DefaultRootWindow(); | 
|  |  | 
|  | // Returns true if |window| is visible. | 
|  | UI_BASE_EXPORT bool IsWindowVisible(XID window); | 
|  |  | 
|  | // Returns the bounds of |window|. | 
|  | UI_BASE_EXPORT bool GetWindowRect(XID window, gfx::Rect* rect); | 
|  |  | 
|  | // Returns true if |window| contains the point |screen_loc|. | 
|  | UI_BASE_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc); | 
|  |  | 
|  | // Return true if |window| has any property with |property_name|. | 
|  | UI_BASE_EXPORT bool PropertyExists(XID window, | 
|  | const std::string& property_name); | 
|  |  | 
|  | // Returns the raw bytes from a property with minimal | 
|  | // interpretation. |out_data| should be freed by XFree() after use. | 
|  | UI_BASE_EXPORT bool GetRawBytesOfProperty( | 
|  | XID window, | 
|  | XAtom property, | 
|  | scoped_refptr<base::RefCountedMemory>* out_data, | 
|  | size_t* out_data_items, | 
|  | XAtom* out_type); | 
|  |  | 
|  | // Get the value of an int, int array, atom array or string property.  On | 
|  | // success, true is returned and the value is stored in |value|. | 
|  | // | 
|  | // TODO(erg): Once we remove the gtk port and are 100% aura, all of these | 
|  | // should accept an XAtom instead of a string. | 
|  | UI_BASE_EXPORT bool GetIntProperty(XID window, | 
|  | const std::string& property_name, | 
|  | int* value); | 
|  | UI_BASE_EXPORT bool GetXIDProperty(XID window, | 
|  | const std::string& property_name, | 
|  | XID* value); | 
|  | UI_BASE_EXPORT bool GetIntArrayProperty(XID window, | 
|  | const std::string& property_name, | 
|  | std::vector<int>* value); | 
|  | UI_BASE_EXPORT bool GetAtomArrayProperty(XID window, | 
|  | const std::string& property_name, | 
|  | std::vector<XAtom>* value); | 
|  | UI_BASE_EXPORT bool GetStringProperty(XID window, | 
|  | const std::string& property_name, | 
|  | std::string* value); | 
|  |  | 
|  | // These setters all make round trips. | 
|  | UI_BASE_EXPORT bool SetIntProperty(XID window, | 
|  | const std::string& name, | 
|  | const std::string& type, | 
|  | int value); | 
|  | UI_BASE_EXPORT bool SetIntArrayProperty(XID window, | 
|  | const std::string& name, | 
|  | const std::string& type, | 
|  | const std::vector<int>& value); | 
|  | UI_BASE_EXPORT bool SetAtomProperty(XID window, | 
|  | const std::string& name, | 
|  | const std::string& type, | 
|  | XAtom value); | 
|  | UI_BASE_EXPORT bool SetAtomArrayProperty(XID window, | 
|  | const std::string& name, | 
|  | const std::string& type, | 
|  | const std::vector<XAtom>& value); | 
|  | UI_BASE_EXPORT bool SetStringProperty(XID window, | 
|  | XAtom property, | 
|  | XAtom type, | 
|  | const std::string& value); | 
|  |  | 
|  | // Gets the X atom for default display corresponding to atom_name. | 
|  | UI_BASE_EXPORT XAtom GetAtom(const char* atom_name); | 
|  |  | 
|  | // Sets the WM_CLASS attribute for a given X11 window. | 
|  | UI_BASE_EXPORT void SetWindowClassHint(XDisplay* display, | 
|  | XID window, | 
|  | const std::string& res_name, | 
|  | const std::string& res_class); | 
|  |  | 
|  | // Sets the WM_WINDOW_ROLE attribute for a given X11 window. | 
|  | UI_BASE_EXPORT void SetWindowRole(XDisplay* display, | 
|  | XID window, | 
|  | const std::string& role); | 
|  |  | 
|  | // Determine whether we should default to native decorations or the custom | 
|  | // frame based on the currently-running window manager. | 
|  | UI_BASE_EXPORT bool GetCustomFramePrefDefault(); | 
|  |  | 
|  | static const int kAllDesktops = -1; | 
|  | // Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if | 
|  | // property not found. | 
|  | bool GetWindowDesktop(XID window, int* desktop); | 
|  |  | 
|  | // Translates an X11 error code into a printable string. | 
|  | UI_BASE_EXPORT std::string GetX11ErrorString(XDisplay* display, int err); | 
|  |  | 
|  | // Implementers of this interface receive a notification for every X window of | 
|  | // the main display. | 
|  | class EnumerateWindowsDelegate { | 
|  | public: | 
|  | // |xid| is the X Window ID of the enumerated window.  Return true to stop | 
|  | // further iteration. | 
|  | virtual bool ShouldStopIterating(XID xid) = 0; | 
|  |  | 
|  | protected: | 
|  | virtual ~EnumerateWindowsDelegate() {} | 
|  | }; | 
|  |  | 
|  | // Enumerates all windows in the current display.  Will recurse into child | 
|  | // windows up to a depth of |max_depth|. | 
|  | UI_BASE_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate, | 
|  | int max_depth); | 
|  |  | 
|  | // Enumerates the top-level windows of the current display. | 
|  | UI_BASE_EXPORT void EnumerateTopLevelWindows( | 
|  | ui::EnumerateWindowsDelegate* delegate); | 
|  |  | 
|  | // Returns all children windows of a given window in top-to-bottom stacking | 
|  | // order. | 
|  | UI_BASE_EXPORT bool GetXWindowStack(XID window, std::vector<XID>* windows); | 
|  |  | 
|  | // Copies |source_bounds| from |drawable| to |canvas| at offset |dest_offset|. | 
|  | // |source_bounds| is in physical pixels, while |dest_offset| is relative to | 
|  | // the canvas's scale. Note that this function is slow since it uses | 
|  | // XGetImage() to copy the data from the X server to this process before | 
|  | // copying it to |canvas|. | 
|  | UI_BASE_EXPORT bool CopyAreaToCanvas(XID drawable, | 
|  | gfx::Rect source_bounds, | 
|  | gfx::Point dest_offset, | 
|  | gfx::Canvas* canvas); | 
|  |  | 
|  | enum WindowManagerName { | 
|  | WM_UNKNOWN, | 
|  | WM_BLACKBOX, | 
|  | WM_CHROME_OS, | 
|  | WM_COMPIZ, | 
|  | WM_ENLIGHTENMENT, | 
|  | WM_ICE_WM, | 
|  | WM_KWIN, | 
|  | WM_METACITY, | 
|  | WM_MUFFIN, | 
|  | WM_MUTTER, | 
|  | WM_OPENBOX, | 
|  | WM_XFWM4, | 
|  | }; | 
|  | // Attempts to guess the window maager. Returns WM_UNKNOWN if we can't | 
|  | // determine it for one reason or another. | 
|  | UI_BASE_EXPORT WindowManagerName GuessWindowManager(); | 
|  |  | 
|  | // Enable the default X error handlers. These will log the error and abort | 
|  | // the process if called. Use SetX11ErrorHandlers() from x11_util_internal.h | 
|  | // to set your own error handlers. | 
|  | UI_BASE_EXPORT void SetDefaultX11ErrorHandlers(); | 
|  |  | 
|  | // Returns true if a given window is in full-screen mode. | 
|  | UI_BASE_EXPORT bool IsX11WindowFullScreen(XID window); | 
|  |  | 
|  | // Returns true if the window manager supports the given hint. | 
|  | UI_BASE_EXPORT bool WmSupportsHint(XAtom atom); | 
|  |  | 
|  | // Manages a piece of X11 allocated memory as a RefCountedMemory segment. This | 
|  | // object takes ownership over the passed in memory and will free it with the | 
|  | // X11 allocator when done. | 
|  | class UI_BASE_EXPORT XRefcountedMemory : public base::RefCountedMemory { | 
|  | public: | 
|  | XRefcountedMemory(unsigned char* x11_data, size_t length) | 
|  | : x11_data_(length ? x11_data : NULL), length_(length) {} | 
|  |  | 
|  | // Overridden from RefCountedMemory: | 
|  | virtual const unsigned char* front() const OVERRIDE; | 
|  | virtual size_t size() const OVERRIDE; | 
|  |  | 
|  | private: | 
|  | virtual ~XRefcountedMemory(); | 
|  |  | 
|  | unsigned char* x11_data_; | 
|  | size_t length_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(XRefcountedMemory); | 
|  | }; | 
|  |  | 
|  | // Keeps track of a string returned by an X function (e.g. XGetAtomName) and | 
|  | // makes sure it's XFree'd. | 
|  | class UI_BASE_EXPORT XScopedString { | 
|  | public: | 
|  | explicit XScopedString(char* str) : string_(str) {} | 
|  | ~XScopedString(); | 
|  |  | 
|  | const char* string() const { return string_; } | 
|  |  | 
|  | private: | 
|  | char* string_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(XScopedString); | 
|  | }; | 
|  |  | 
|  | // Keeps track of an image returned by an X function (e.g. XGetImage) and | 
|  | // makes sure it's XDestroyImage'd. | 
|  | class UI_BASE_EXPORT XScopedImage { | 
|  | public: | 
|  | explicit XScopedImage(XImage* image) : image_(image) {} | 
|  | ~XScopedImage(); | 
|  |  | 
|  | XImage* get() const { return image_; } | 
|  |  | 
|  | XImage* operator->() const { return image_; } | 
|  |  | 
|  | void reset(XImage* image); | 
|  |  | 
|  | private: | 
|  | XImage* image_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(XScopedImage); | 
|  | }; | 
|  |  | 
|  | // Keeps track of a cursor returned by an X function and makes sure it's | 
|  | // XFreeCursor'd. | 
|  | class UI_BASE_EXPORT XScopedCursor { | 
|  | public: | 
|  | // Keeps track of |cursor| created with |display|. | 
|  | XScopedCursor(::Cursor cursor, XDisplay* display); | 
|  | ~XScopedCursor(); | 
|  |  | 
|  | ::Cursor get() const; | 
|  | void reset(::Cursor cursor); | 
|  |  | 
|  | private: | 
|  | ::Cursor cursor_; | 
|  | XDisplay* display_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(XScopedCursor); | 
|  | }; | 
|  |  | 
|  | namespace test { | 
|  | // Resets the cache used by GetXCursor(). Only useful for tests that may delete | 
|  | // the display. | 
|  | UI_BASE_EXPORT void ResetXCursorCache(); | 
|  |  | 
|  | // Returns the cached XcursorImage for |cursor|. | 
|  | UI_BASE_EXPORT const XcursorImage* GetCachedXcursorImage(::Cursor cursor); | 
|  |  | 
|  | }  // namespace test | 
|  |  | 
|  | }  // namespace ui | 
|  |  | 
|  | #endif  // UI_BASE_X_X11_UTIL_H_ |