// 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/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 Insets;
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 inner bounds of |window| (excluding the non-client area).
UI_BASE_EXPORT bool GetInnerWindowBounds(XID window, gfx::Rect* rect);

// Returns the non-client area extents of |window|. This is a negative inset; it
// represents the negative size of the window border on all sides.
// InnerWindowBounds.Inset(WindowExtents) = OuterWindowBounds.
// Returns false if the window manager does not provide extents information.
UI_BASE_EXPORT bool GetWindowExtents(XID window, gfx::Insets* extents);

// Returns the outer bounds of |window| (including the non-client area).
UI_BASE_EXPORT bool GetOuterWindowBounds(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_AWESOME,
  WM_BLACKBOX,
  WM_COMPIZ,
  WM_ENLIGHTENMENT,
  WM_I3,
  WM_ICE_WM,
  WM_ION3,
  WM_KWIN,
  WM_MATCHBOX,
  WM_METACITY,
  WM_MUFFIN,
  WM_MUTTER,
  WM_NOTION,
  WM_OPENBOX,
  WM_QTILE,
  WM_RATPOISON,
  WM_STUMPWM,
  WM_WMII,
  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();

// The same as GuessWindowManager(), but returns the raw string.  If we
// can't determine it, return "Unknown".
UI_BASE_EXPORT std::string GuessWindowManagerName();

// 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_
