/* Copyright (C) 1998-2010 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License or(at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
 */

_CONFIGINCLUDE(gdkmmconfig.h)

#include <glibmm/object.h>
#include <gdkmm/dragcontext.h>
#include <gdkmm/types.h>
#include <cairomm/region.h>
#include <cairomm/pattern.h>
#include <gdkmm/device.h>
#include <gdkmm/visual.h>
#include <gdkmm/rgba.h>
#include <cairomm/context.h>
#include <gdk/gdk.h>

_DEFS(gdkmm,gdk)
_PINCLUDE(glibmm/private/object_p.h)

namespace Gdk
{

_WRAP_ENUM(WindowState, GdkWindowState, decl_prefix GDKMM_API)
_WRAP_ENUM(WindowType, GdkWindowType, decl_prefix GDKMM_API)
_WRAP_ENUM(WindowAttributesType, GdkWindowAttributesType, decl_prefix GDKMM_API)
_WRAP_ENUM(WindowHints, GdkWindowHints, decl_prefix GDKMM_API)
_WRAP_ENUM(WindowTypeHint, GdkWindowTypeHint, decl_prefix GDKMM_API)
_WRAP_ENUM(WMDecoration, GdkWMDecoration, decl_prefix GDKMM_API)
_WRAP_ENUM(WMFunction, GdkWMFunction, decl_prefix GDKMM_API)
_WRAP_ENUM(WindowEdge, GdkWindowEdge, decl_prefix GDKMM_API)
_WRAP_ENUM(Gravity, GdkGravity, decl_prefix GDKMM_API)
_WRAP_ENUM(AnchorHints, GdkAnchorHints, decl_prefix GDKMM_API)
_WRAP_ENUM(FullscreenMode, GdkFullscreenMode, decl_prefix GDKMM_API)

class GDKMM_API Cursor;
class GDKMM_API Pixbuf;
class GDKMM_API GLContext;
class GDKMM_API DrawingContext;
class GDKMM_API FrameClock;

/** A Gdk::Window is a rectangular region on the screen. It's a low-level object, used to implement high-level objects such
 * as Gtk::Widget and Gtk::Window on the GTK+ level. A Gtk::Window is a toplevel window, the thing a user might think of as
 * a "window" with a titlebar and so on; a Gtk::Window may contain many Gdk::Windows. For example, each Gtk::Button has a
 * Gdk::Window associated with it.
 */
class GDKMM_API Window : public Glib::Object
{
  _CLASS_GOBJECT(Window, GdkWindow, GDK_WINDOW, Glib::Object, GObject, , , GDKMM_API)
  _STRUCT_NOT_HIDDEN
  _IGNORE(gdk_window_destroy, gdk_window_new, gdk_window_is_destroyed)

protected:
  Window(const Glib::RefPtr<Window>& parent, GdkWindowAttr* attributes, int attributes_mask);

public:
  _WRAP_CREATE(const Glib::RefPtr<Window>& parent, GdkWindowAttr* attributes, int attributes_mask)

  _WRAP_METHOD(WindowType get_window_type() const, gdk_window_get_window_type)

  _WRAP_METHOD(Glib::RefPtr<Visual> get_visual(), gdk_window_get_visual, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Visual> get_visual() const, gdk_window_get_visual, refreturn, constversion)

  _WRAP_METHOD(Glib::RefPtr<Screen> get_screen(), gdk_window_get_screen, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Screen> get_screen() const, gdk_window_get_screen, refreturn, constversion)

  _WRAP_METHOD(Glib::RefPtr<Display> get_display(), gdk_window_get_display, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Display> get_display() const, gdk_window_get_display, refreturn, constversion)

  _WRAP_METHOD(void show(), gdk_window_show)
  _WRAP_METHOD(void hide(), gdk_window_hide)
  _WRAP_METHOD(void withdraw(), gdk_window_withdraw)
  _WRAP_METHOD(void show_unraised(), gdk_window_show_unraised)
  _WRAP_METHOD(void move(int x, int y), gdk_window_move)
  _WRAP_METHOD(void resize(int width, int height), gdk_window_resize)
  _WRAP_METHOD(void move_resize(int x, int y, int width, int height), gdk_window_move_resize)
  _WRAP_METHOD(void reparent(const Glib::RefPtr<Window>& new_parent, int x, int y), gdk_window_reparent)
  _WRAP_METHOD(void raise(), gdk_window_raise)
  _WRAP_METHOD(void lower(), gdk_window_lower)

  _WRAP_METHOD(void restack(const Glib::RefPtr<Window>& sibling, bool above), gdk_window_restack)

  /** Changes the position of this window in the Z-order (stacking order). This
   * either raises (if @a above is true) or lowers the window.
   *
   * If this is a toplevel, the window manager may choose to deny the
   * request to move the window in the Z-order. restack() only
   * requests the restack but does not guarantee it.
   *
   * @param above Whether to raise or lower the window.
   *
   * @newin{2,18}
   */
  void restack(bool above);

  _WRAP_METHOD(void focus(guint32 timestamp), gdk_window_focus)
  _WRAP_METHOD(void set_user_data(gpointer user_data), gdk_window_set_user_data)
  _WRAP_METHOD(void set_override_redirect(bool override_redirect = true), gdk_window_set_override_redirect)

  //We could wrap these with a Slot instead of a C callback, but these methods are very low-level anyway.
  _WRAP_METHOD(void add_filter(GdkFilterFunc function, gpointer data), gdk_window_add_filter)
  _WRAP_METHOD(void remove_filter(GdkFilterFunc function, gpointer data), gdk_window_remove_filter)

  _WRAP_METHOD(void scroll(int dx, int dy), gdk_window_scroll)
  _WRAP_METHOD(void move_region(const ::Cairo::RefPtr< ::Cairo::Region>& region, int dx, int dy), gdk_window_move_region)
  _WRAP_METHOD(bool ensure_native(), gdk_window_ensure_native)

  _WRAP_METHOD(void shape_combine_region(const ::Cairo::RefPtr< ::Cairo::Region>& shape_region, int offset_x = 0, int offset_y = 0), gdk_window_shape_combine_region)
  _WRAP_METHOD(void set_child_shapes(), gdk_window_set_child_shapes)
  _WRAP_METHOD(bool get_composited() const, gdk_window_get_composited,
               deprecated "Compositing is an outdated technology that only ever worked on X11.")
  _WRAP_METHOD(void set_composited(bool composited = TRUE), gdk_window_set_composited,
               deprecated "Compositing is an outdated technology that only ever worked on X11.")
  _WRAP_METHOD(void merge_child_shapes(), gdk_window_merge_child_shapes)

  _WRAP_METHOD(void input_shape_combine_region(const ::Cairo::RefPtr< ::Cairo::Region>& shape_region, int offset_x, int offset_y), gdk_window_input_shape_combine_region)
  _WRAP_METHOD(void set_child_input_shapes(), gdk_window_set_child_input_shapes)
  _WRAP_METHOD(void merge_child_input_shapes(), gdk_window_merge_child_input_shapes)

  _WRAP_METHOD(void set_pass_through(bool pass_through = true), gdk_window_set_pass_through)
  _WRAP_METHOD(bool get_pass_through() const, gdk_window_get_pass_through)

  _WRAP_METHOD(bool is_visible() const, gdk_window_is_visible)
  _WRAP_METHOD(bool is_viewable() const, gdk_window_is_viewable)
  _WRAP_METHOD(bool is_input_only() const, gdk_window_is_input_only)
  _WRAP_METHOD(bool is_shaped() const, gdk_window_is_shaped)
  _WRAP_METHOD(WindowState get_state() const, gdk_window_get_state)
  _WRAP_METHOD(bool set_static_gravities(bool use_static = true), gdk_window_set_static_gravities,
               deprecated "Static gravities haven't worked on anything but X11 for a long time.")
  _WRAP_METHOD(bool has_native() const, gdk_window_has_native)
  _WRAP_METHOD(void set_type_hint(WindowTypeHint hint), gdk_window_set_type_hint)
  _WRAP_METHOD(WindowTypeHint get_type_hint(), gdk_window_get_type_hint)
  _WRAP_METHOD(bool get_modal_hint() const, gdk_window_get_modal_hint)
  _WRAP_METHOD(void set_modal_hint(bool modal = true), gdk_window_set_modal_hint)
  _WRAP_METHOD(void set_geometry_hints(const Geometry& geometry, WindowHints geom_mask), gdk_window_set_geometry_hints)
  _WRAP_METHOD(void begin_paint_rect(const Rectangle& rectangle), gdk_window_begin_paint_rect,
    deprecated "Use begin_draw_frame() instead.")
  _WRAP_METHOD(void begin_paint_region(const ::Cairo::RefPtr< ::Cairo::Region>& region), gdk_window_begin_paint_region,
    deprecated "Use begin_draw_frame() instead.")
  _WRAP_METHOD(void end_paint(), gdk_window_end_paint, deprecated "Use end_draw_frame() instead.")
  _WRAP_METHOD(void flush(), gdk_window_flush, deprecated "This method does nothing.")
  _WRAP_METHOD(void set_title(const Glib::ustring& title), gdk_window_set_title)
  _WRAP_METHOD(void set_role(const Glib::ustring& role), gdk_window_set_role)
  _WRAP_METHOD(void set_startup_id(const Glib::ustring& startup_id), gdk_window_set_startup_id)
  _WRAP_METHOD(void set_transient_for(const Glib::RefPtr<Window>& parent), gdk_window_set_transient_for)
  _WRAP_METHOD(void set_background(const Color& color), gdk_window_set_background,
    deprecated "Don't use this function.")
  _WRAP_METHOD(void set_background(const RGBA& rgba), gdk_window_set_background_rgba,
    deprecated "Don't use this function.")

#m4 _CONVERSION(`const ::Cairo::RefPtr< ::Cairo::Pattern>&',`cairo_pattern_t*',`($3)->cobj()')
  _WRAP_METHOD(void set_background(const ::Cairo::RefPtr< ::Cairo::Pattern>& pattern), gdk_window_set_background_pattern,
    deprecated "Don't use this function.")

  #m4 _CONVERSION(`cairo_pattern_t*',`::Cairo::RefPtr< ::Cairo::Pattern>',`::Cairo::RefPtr< ::Cairo::Pattern>(new ::Cairo::Pattern($3, false /* take reference */))')
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Pattern> get_background_pattern(), gdk_window_get_background_pattern,
    deprecated "Don't use this function.")
  #m4 _CONVERSION(`cairo_pattern_t*',`::Cairo::RefPtr<const ::Cairo::Pattern>',`::Cairo::RefPtr<const ::Cairo::Pattern>(new ::Cairo::Pattern($3, false /* take reference */))')
  _WRAP_METHOD(::Cairo::RefPtr<const ::Cairo::Pattern> get_background_pattern() const, gdk_window_get_background_pattern,
    deprecated "Don't use this function.")

  _WRAP_METHOD(void set_cursor(const Glib::RefPtr<Cursor>& cursor), gdk_window_set_cursor)

  /** Use the parent window's cursor.
   * For top-level windows this means that it will use the default cursor for the ROOT window.
   */
  void set_cursor();

  _WRAP_METHOD(void set_device_cursor(const Glib::RefPtr<Device>& device, const Glib::RefPtr<Cursor>& cursor), gdk_window_set_device_cursor)

  /** Use the parent window's cursor.
   * For top-level windows this means that it will use the default cursor for the ROOT window.
   */
  void set_device_cursor(const Glib::RefPtr<Device>& device);

  _WRAP_METHOD(Glib::RefPtr<Cursor> get_device_cursor(const Glib::RefPtr<Device>& device), gdk_window_get_device_cursor, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Cursor> get_device_cursor(const Glib::RefPtr<const Device>& device) const, gdk_window_get_device_cursor, refreturn)


  _WRAP_METHOD(Glib::RefPtr<Cursor> get_cursor(), gdk_window_get_cursor, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Cursor> get_cursor() const, gdk_window_get_cursor, refreturn, constversion)

  _WRAP_METHOD(void get_user_data(gpointer* data), gdk_window_get_user_data)
  _WRAP_METHOD(void get_geometry(int& x, int& y, int& width, int& height) const, gdk_window_get_geometry)
  _WRAP_METHOD(int get_width() const, gdk_window_get_width)
  _WRAP_METHOD(int get_height() const, gdk_window_get_height)

  _WRAP_METHOD(void get_position(int& x, int& y) const, gdk_window_get_position)
  _WRAP_METHOD(int get_origin(int& x, int& y) const, gdk_window_get_origin)
  _WRAP_METHOD(void get_root_coords(int x, int y, int& root_x, int& root_y), gdk_window_get_root_coords)
  _WRAP_METHOD(void coords_to_parent(double x,  double y, double& parent_x, double& parent_y), gdk_window_coords_to_parent)
  _WRAP_METHOD(void coords_from_parent(double parent_x, double parent_y, double& x, double& y), gdk_window_coords_from_parent)

  _WRAP_METHOD(void get_root_origin(int& x, int& y) const, gdk_window_get_root_origin)

  _WRAP_METHOD(void get_frame_extents(Rectangle& rect), gdk_window_get_frame_extents, deprecated "Use the const method instead.")
  _WRAP_METHOD(void get_frame_extents(Rectangle& rect) const, gdk_window_get_frame_extents)

  _WRAP_METHOD(int get_scale_factor() const, gdk_window_get_scale_factor)
  _WRAP_METHOD(Glib::RefPtr<Window> get_pointer(int& x, int& y, ModifierType& mask), gdk_window_get_pointer, refreturn, deprecated "Use get_device_position() instead")
  _WRAP_METHOD(Glib::RefPtr<Window> get_parent(), gdk_window_get_parent, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_parent() const, gdk_window_get_parent, refreturn, constversion)
  _WRAP_METHOD(Glib::RefPtr<Window> get_toplevel(), gdk_window_get_toplevel, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_toplevel() const, gdk_window_get_toplevel, refreturn, constversion)

  _WRAP_METHOD(Glib::RefPtr<Window> get_device_position(const Glib::RefPtr<const Device>& device, int& x, int& y, ModifierType& mask) const, gdk_window_get_device_position, refreturn)

    _WRAP_METHOD(Glib::RefPtr<Window> get_device_position(const Glib::RefPtr<const Device>& device, double& x, double& y, ModifierType& mask) const, gdk_window_get_device_position_double, refreturn)

  _WRAP_METHOD(Glib::RefPtr<Window> get_effective_parent(), gdk_window_get_effective_parent, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_effective_parent() const, gdk_window_get_effective_parent, refreturn, constversion)
  _WRAP_METHOD(Glib::RefPtr<Window> get_effective_toplevel(), gdk_window_get_effective_toplevel, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_effective_toplevel() const, gdk_window_get_effective_toplevel, refreturn, constversion)

#m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<Window> >',`Glib::ListHandler<Glib::RefPtr<Window> >::list_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
  _WRAP_METHOD(std::vector< Glib::RefPtr<Window> > get_children(), gdk_window_get_children)
#m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<const Window> >',`Glib::ListHandler<Glib::RefPtr<const Window> >::list_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
  _WRAP_METHOD(std::vector< Glib::RefPtr<const Window> > get_children() const, gdk_window_get_children)
  _IGNORE(gdk_window_peek_children) //gdk_window_peek_children() is the same as gdk_window_get_children() with different memory mangement of the list.

  _WRAP_METHOD(EventMask get_events() const, gdk_window_get_events)
  _WRAP_METHOD(void set_events(EventMask event_mask), gdk_window_set_events)

  _WRAP_METHOD(EventMask get_device_events(const Glib::RefPtr<const Device>& device) const, gdk_window_get_device_events)
  _WRAP_METHOD(void set_device_events(const Glib::RefPtr<Device>& device, EventMask event_mask), gdk_window_set_device_events)

  _WRAP_METHOD(EventMask get_source_events(InputSource source) const, gdk_window_get_source_events)
  _WRAP_METHOD(void set_source_events(InputSource source, EventMask event_mask), gdk_window_set_source_events)

#m4 _CONVERSION(`const std::vector< Glib::RefPtr<Gdk::Pixbuf> >&',`GList*',`Glib::ListHandler<Glib::RefPtr<Gdk::Pixbuf> >::vector_to_list($3).data ()')
  _WRAP_METHOD(void set_icon_list(const std::vector< Glib::RefPtr<Gdk::Pixbuf> >& pixbufs), gdk_window_set_icon_list)
  void unset_icon();
  _WRAP_METHOD(void set_icon_name(const Glib::ustring& name), gdk_window_set_icon_name)

  _WRAP_METHOD(void set_group(const Glib::RefPtr<Window>& leader), gdk_window_set_group)
  _WRAP_METHOD(Glib::RefPtr<Window> get_group(), gdk_window_get_group)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_group() const, gdk_window_get_group, constversion)

  _WRAP_METHOD(void set_decorations(WMDecoration decorations), gdk_window_set_decorations)
  _WRAP_METHOD(bool get_decorations(WMDecoration& decorations) const, gdk_window_get_decorations)
  _WRAP_METHOD(void set_functions(WMFunction functions), gdk_window_set_functions)

  #m4 _CONVERSION(`cairo_surface_t*',`::Cairo::RefPtr< ::Cairo::Surface>',`::Cairo::RefPtr< ::Cairo::Surface>(new ::Cairo::Surface($3, true /* do not take ref */))')
  #m4 _CONVERSION(`::Cairo::Content',`cairo_content_t',`(cairo_content_t)($3)')
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Surface> create_similar_surface(::Cairo::Content content, int width,  int height), gdk_window_create_similar_surface )

  #m4 _CONVERSION(`::Cairo::Format',`cairo_format_t',`(cairo_format_t)($3)')
    _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Surface> create_similar_image_surface(::Cairo::Format format, int width, int height, int scale), gdk_window_create_similar_image_surface )

  _WRAP_METHOD(void beep(), gdk_window_beep)

  _WRAP_METHOD(void iconify(), gdk_window_iconify)
  _WRAP_METHOD(void deiconify(), gdk_window_deiconify)
  _WRAP_METHOD(void stick(), gdk_window_stick)
  _WRAP_METHOD(void unstick(), gdk_window_unstick)
  _WRAP_METHOD(void maximize(), gdk_window_maximize)
  _WRAP_METHOD(void unmaximize(), gdk_window_unmaximize)
  _WRAP_METHOD(void register_dnd(), gdk_window_register_dnd)

  _WRAP_METHOD_DOCS_ONLY(gdk_window_get_drag_protocol)
  DragProtocol get_drag_protocol(Glib::RefPtr<Window>& target) const;

  /** Finds out the DND protocol supported by a window.
   *
   * @newin{3,0}
   *
   * @return The supported DND protocol.
   */
  DragProtocol get_drag_protocol() const;

  _IGNORE(gdk_window_get_drag_protocol)

  _WRAP_METHOD(void begin_resize_drag(WindowEdge edge, int button, int root_x, int root_y, guint32 timestamp), gdk_window_begin_resize_drag)

  _WRAP_METHOD(void resize_drag(WindowEdge edge, const Glib::RefPtr<Device>& device, int button, int root_x, int root_y, guint32 timestamp), gdk_window_begin_resize_drag_for_device)

  _WRAP_METHOD(void begin_move_drag(int button, int root_x, int root_y, guint32 timestamp), gdk_window_begin_move_drag)

  _WRAP_METHOD(void begin_move_drag(const Glib::RefPtr<Device>& device, int button, int root_x, int root_y, guint32 timestamp), gdk_window_begin_move_drag_for_device)

  /** Starts a drag and creates a new drag context for it.
   *
   * This method is called by the drag source.
   * @param targets A list of the offered targets names.
   * @return A newly created Gdk::DragContext.
   *
   * @newin{2,24}
   */
  Glib::RefPtr<DragContext> drag_begin(const std::vector<Glib::ustring>& targets);
  _IGNORE(gdk_drag_begin)

  _WRAP_METHOD(void invalidate_rect(const Rectangle& rect, bool invalidate_children), gdk_window_invalidate_rect)

  /** A convenience wrapper around invalidate_region() which
   * invalidates the whole region. See invalidate_region() for details.
   * @param invalidate_children Whether to also invalidate child windows.
   */
  void invalidate(bool invalidate_children);

  _WRAP_METHOD(void invalidate_region(const ::Cairo::RefPtr< ::Cairo::Region>& region, bool invalidate_children = true), gdk_window_invalidate_region)

  //TODO:
  /*
  void       gdk_window_invalidate_maybe_recurse  (GdkWindow          *window,
						 const cairo_region_t    *region,
						 gboolean (*child_func) (GdkWindow *, gpointer),
						 gpointer   user_data);
	*/

#m4 _CONVERSION(`cairo_region_t*',`::Cairo::RefPtr< ::Cairo::Region>',`::Cairo::RefPtr< ::Cairo::Region>(new ::Cairo::Region(($3), true /* do not take ref */))')

  //This method should not have a const version - see the docs
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Region> get_update_area(), gdk_window_get_update_area)

  _WRAP_METHOD(void freeze_updates(), gdk_window_freeze_updates)
  _WRAP_METHOD(void thaw_updates(), gdk_window_thaw_updates)
  _WRAP_METHOD(static void process_all_updates(), gdk_window_process_all_updates,
    deprecated "Don't use this function now that we have a frame clock.")
  _WRAP_METHOD(void process_updates(bool update_children), gdk_window_process_updates,
    deprecated "Don't use this function now that we have a frame clock.")
  _WRAP_METHOD(static void set_debug_updates(bool setting = true), gdk_window_set_debug_updates,
    deprecated "No replacement available.")
  _IGNORE(gdk_window_thaw_toplevel_updates_libgtk_only,
          gdk_window_freeze_toplevel_updates_libgtk_only)dnl// deprecated

  //TODO: flags is now an enum. See
  // https://git.gnome.org/browse/gtk+/commit/gdk/gdkwindow.c?id=4b42526e1f33b0ceb9231cee5e15861b97c05726
  // Change it here too?
  #m4 _CONVERSION(`guint',`GdkWindowHints',`(GdkWindowHints)($3)')
  _WRAP_METHOD(static void constrain_size(const Geometry& geometry, guint flags, int width, int height, int& new_width, int& new_height), gdk_window_constrain_size)

  _WRAP_METHOD(void enable_synchronized_configure(), gdk_window_enable_synchronized_configure, deprecated "This function is no longer needed.")
  _WRAP_METHOD(void configure_finished(), gdk_window_configure_finished, deprecated "This function is no longer needed.")

  _WRAP_METHOD(void set_skip_taskbar_hint(bool skips_taskbar = true), gdk_window_set_skip_taskbar_hint)
  _WRAP_METHOD(void set_skip_pager_hint(bool skips_pager = true), gdk_window_set_skip_pager_hint)

  _WRAP_METHOD(void set_urgency_hint(bool urgent = true), gdk_window_set_urgency_hint)

  _WRAP_METHOD(void fullscreen(), gdk_window_fullscreen)
  _WRAP_METHOD(void set_fullscreen_mode(FullscreenMode mode), gdk_window_set_fullscreen_mode)
  _WRAP_METHOD(FullscreenMode get_fullscreen_mode() const, gdk_window_get_fullscreen_mode)
  _WRAP_METHOD(void unfullscreen(), gdk_window_unfullscreen)

  _IGNORE(gdk_pointer_grab, gdk_pointer_ungrab, gdk_keyboard_grab, gdk_keyboard_ungrab) //deprecated

  _WRAP_METHOD(void set_keep_above(bool setting = true), gdk_window_set_keep_above)
  _WRAP_METHOD(void set_keep_below(bool setting = true), gdk_window_set_keep_below)

  _WRAP_METHOD(void set_opacity(double opacity), gdk_window_set_opacity)

  _WRAP_METHOD(bool get_accept_focus() const, gdk_window_get_accept_focus)
  _WRAP_METHOD(void set_accept_focus(bool accept_focus = true), gdk_window_set_accept_focus)

  _WRAP_METHOD(bool get_focus_on_map() const, gdk_window_get_focus_on_map)
  _WRAP_METHOD(void set_focus_on_map(bool focus_on_map), gdk_window_set_focus_on_map)

  _WRAP_METHOD(static Glib::RefPtr<Window> get_default_root_window(), gdk_get_default_root_window, refreturn)

  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Surface> get_offscreen_surface(), gdk_offscreen_window_get_surface, refreturn)
  _WRAP_METHOD(::Cairo::RefPtr<const ::Cairo::Surface> get_offscreen_surface() const, gdk_offscreen_window_get_surface, constversion, refreturn)

  _WRAP_METHOD(Glib::RefPtr<Window> get_offscreen_embedder(), gdk_offscreen_window_get_embedder, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_offscreen_embedder() const, gdk_offscreen_window_get_embedder, constversion, refreturn)

  _WRAP_METHOD(void set_offscreen_embedder(const Glib::RefPtr<Window>& embedder), gdk_offscreen_window_set_embedder)

  _WRAP_METHOD(void geometry_changed(), gdk_window_geometry_changed)

  _WRAP_METHOD(void set_support_multidevice(bool support_multidevice = true), gdk_window_set_support_multidevice)
  _WRAP_METHOD(bool get_support_multidevice(), gdk_window_get_support_multidevice)

  _WRAP_METHOD(Glib::RefPtr<FrameClock> get_frame_clock(), gdk_window_get_frame_clock, refreturn, newin "3,24")
  _WRAP_METHOD(Glib::RefPtr<const FrameClock> get_frame_clock() const, gdk_window_get_frame_clock, refreturn, constversion, newin "3,24")

#m4 _CONVERSION(`cairo_region_t*',`::Cairo::RefPtr< ::Cairo::Region>',`::Cairo::RefPtr< ::Cairo::Region>(new ::Cairo::Region($3, true /* do not take ref */))')

  //This is const because it returns a copy (though that is not very clear from the C documentation)
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Region> get_clip_region() const, gdk_window_get_clip_region)

  //This is const because it returns a copy (though that is not very clear from the C documentation)
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Region> get_visible_region() const, gdk_window_get_visible_region)

#m4 _CONVERSION(`cairo_t*',`::Cairo::RefPtr< ::Cairo::Context>',`::Cairo::RefPtr< ::Cairo::Context>(new ::Cairo::Context($3, true /* has_reference */))')
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Context> create_cairo_context(), gdk_cairo_create,
    deprecated "Use begin_draw_frame() and Gdk::DrawingContext::get_cairo_context() instead.")

  //TODO: Wrap these? Find out when they are emitted and if they are useful outside of GTK+, and improve the C docs.
  //_WRAP_SIGNAL(Glib::RefPtr<Gdk::Window> pick_embedded_child(double x, double y), pick-embedded-child, no_default_handler)
  //_WRAP_SIGNAL(Glib::RefPtr<Gdk::Window> to_embedder(double offscreen_x, double offscreen_y, double& embedder_x, double& embedder_y), to-embedder, no_default_handler)
  //_WRAP_SIGNAL(Glib::RefPtr<Gdk::Window> from_embedder(double embedder_x, double embedder_y, double& offscreen_x, double& offscreen_y), from-embedder, no_default_handler)

  _WRAP_METHOD(void set_opaque_region(const ::Cairo::RefPtr<const ::Cairo::Region>& region), gdk_window_set_opaque_region)

  _WRAP_METHOD(void set_event_compression(bool event_compression = true), gdk_window_set_event_compression)
  _WRAP_METHOD(bool get_event_compression() const, gdk_window_get_event_compression)

  _WRAP_METHOD(void set_shadow_width(int left, int right, int top, int bottom), gdk_window_set_shadow_width)

  //TODO: Use Gdk::Event when we use it elsewhere - See also, for instance, Gdk::Display::put_event().
  _WRAP_METHOD(bool show_window_menu(GdkEvent* event), gdk_window_show_window_menu)

  /** Creates a new GLContext matching the framebuffer format to the visual of the
   * Window. The context is disconnected from any particular window or surface.
   *
   * If the creation of the GLContext failed an error will be thrown.
   *
   * Before using the returned GLContext, you will need to call
   * GLContext::make_current() or GLContext::realize().
   *
   * @newin{3,18}
   *
   * @return GLContext The newly created context.
   *
   * @throws GLError On missing GL implementation or extension required for context creation.
   */
  _WRAP_METHOD(Glib::RefPtr<Gdk::GLContext> create_gl_context(), gdk_window_create_gl_context, errthrow)

  _WRAP_METHOD(Glib::RefPtr<DrawingContext> begin_draw_frame(const ::Cairo::RefPtr<const ::Cairo::Region>& region), gdk_window_begin_draw_frame, refreturn)
  _WRAP_METHOD(void end_draw_frame(const Glib::RefPtr<DrawingContext>& context), gdk_window_end_draw_frame)

  _WRAP_PROPERTY("cursor", Glib::RefPtr<Cursor>)
};

} // namespace Gdk
