summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@src.gnome.org>2001-03-29 21:17:45 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-03-29 21:17:45 +0000
commitc61a8f282fd3d3fe32efbdb1b41791447a2602da (patch)
treed478e8dc1b9a2c82361e00e2b411150e115a1309 /gdk
parent1c537e58537317be98ea0b7596b93a3acf143457 (diff)
downloadgtk+-c61a8f282fd3d3fe32efbdb1b41791447a2602da.tar.gz
*** empty log message ***
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkwindow.c128
-rw-r--r--gdk/gdkwindow.h32
-rw-r--r--gdk/x11/gdkevents-x11.c19
-rw-r--r--gdk/x11/gdkprivate-x11.h5
-rw-r--r--gdk/x11/gdkwindow-x11.c491
5 files changed, 670 insertions, 5 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index a9fd49c8b6..f64fab21a6 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2151,3 +2151,131 @@ gdk_window_set_debug_updates (gboolean setting)
debug_updates = setting;
}
+/**
+ * gdk_window_constrain_size:
+ * @geometry: a #GdkGeometry structure
+ * @flags: a mask indicating what portions of @geometry are set
+ * @width: desired width of window
+ * @height: desired height of the window
+ * @new_width: location to store resulting width
+ * @new_height: location to store resulting height
+ *
+ * Constrains a desired width and height according to a
+ * set of geometry hints (such as minimum and maximum size).
+ */
+void
+gdk_window_constrain_size (GdkGeometry *geometry,
+ guint flags,
+ gint width,
+ gint height,
+ gint *new_width,
+ gint *new_height)
+{
+ /* This routine is partially borrowed from fvwm.
+ *
+ * Copyright 1993, Robert Nation
+ * You may use this code for any purpose, as long as the original
+ * copyright remains in the source code and all documentation
+ *
+ * which in turn borrows parts of the algorithm from uwm
+ */
+ gint min_width = 0;
+ gint min_height = 0;
+ gint base_width = 0;
+ gint base_height = 0;
+ gint xinc = 1;
+ gint yinc = 1;
+ gint max_width = G_MAXINT;
+ gint max_height = G_MAXINT;
+
+#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
+
+ if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
+ {
+ base_width = geometry->base_width;
+ base_height = geometry->base_height;
+ min_width = geometry->min_width;
+ min_height = geometry->min_height;
+ }
+ else if (flags & GDK_HINT_BASE_SIZE)
+ {
+ base_width = geometry->base_width;
+ base_height = geometry->base_height;
+ min_width = geometry->base_width;
+ min_height = geometry->base_height;
+ }
+ else if (flags & GDK_HINT_MIN_SIZE)
+ {
+ base_width = geometry->min_width;
+ base_height = geometry->min_height;
+ min_width = geometry->min_width;
+ min_height = geometry->min_height;
+ }
+
+ if (flags & GDK_HINT_MAX_SIZE)
+ {
+ max_width = geometry->max_width ;
+ max_height = geometry->max_height;
+ }
+
+ if (flags & GDK_HINT_RESIZE_INC)
+ {
+ xinc = MAX (xinc, geometry->width_inc);
+ yinc = MAX (yinc, geometry->height_inc);
+ }
+
+ /* clamp width and height to min and max values
+ */
+ width = CLAMP (width, min_width, max_width);
+ height = CLAMP (height, min_height, max_height);
+
+ /* shrink to base + N * inc
+ */
+ width = base_width + FLOOR (width - base_width, xinc);
+ height = base_height + FLOOR (height - base_height, yinc);
+
+ /* constrain aspect ratio, according to:
+ *
+ * width
+ * min_aspect <= -------- <= max_aspect
+ * height
+ */
+
+ if (flags & GDK_HINT_ASPECT &&
+ geometry->min_aspect > 0 &&
+ geometry->max_aspect > 0)
+ {
+ gint delta;
+
+ if (geometry->min_aspect * height > width)
+ {
+ delta = FLOOR (height - width * geometry->min_aspect, yinc);
+ if (height - delta >= min_height)
+ height -= delta;
+ else
+ {
+ delta = FLOOR (height * geometry->min_aspect - width, xinc);
+ if (width + delta <= max_width)
+ width += delta;
+ }
+ }
+
+ if (geometry->max_aspect * height < width)
+ {
+ delta = FLOOR (width - height * geometry->max_aspect, xinc);
+ if (width - delta >= min_width)
+ width -= delta;
+ else
+ {
+ delta = FLOOR (width / geometry->max_aspect - height, yinc);
+ if (height + delta <= max_height)
+ height += delta;
+ }
+ }
+ }
+
+#undef FLOOR
+
+ *new_width = width;
+ *new_height = height;
+}
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 4d0e22b54c..dbb91da22f 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -150,6 +150,19 @@ typedef enum
GDK_GRAVITY_STATIC
} GdkGravity;
+
+typedef enum
+{
+ GDK_WINDOW_EDGE_NORTH_WEST,
+ GDK_WINDOW_EDGE_NORTH,
+ GDK_WINDOW_EDGE_NORTH_EAST,
+ GDK_WINDOW_EDGE_WEST,
+ GDK_WINDOW_EDGE_EAST,
+ GDK_WINDOW_EDGE_SOUTH_WEST,
+ GDK_WINDOW_EDGE_SOUTH,
+ GDK_WINDOW_EDGE_SOUTH_EAST
+} GdkWindowEdge;
+
struct _GdkWindowAttr
{
gchar *title;
@@ -443,6 +456,18 @@ void gdk_window_unmaximize (GdkWindow *window);
void gdk_window_register_dnd (GdkWindow *window);
+void gdk_window_begin_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp);
+void gdk_window_begin_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp);
+
/* Interface for dirty-region queueing */
void gdk_window_invalidate_rect (GdkWindow *window,
GdkRectangle *rect,
@@ -462,6 +487,13 @@ void gdk_window_process_updates (GdkWindow *window,
/* Enable/disable flicker, so you can tell if your code is inefficient. */
void gdk_window_set_debug_updates (gboolean setting);
+void gdk_window_constrain_size (GdkGeometry *geometry,
+ guint flags,
+ gint width,
+ gint height,
+ gint *new_width,
+ gint *new_height);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 90cbb60223..ccb50711a4 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -428,6 +428,15 @@ gdk_event_translate (GdkEvent *event,
if (window != NULL)
gdk_window_ref (window);
+ if (_gdk_moveresize_window &&
+ (xevent->xany.type == MotionNotify ||
+ xevent->xany.type == ButtonRelease))
+ {
+ _gdk_moveresize_handle_event (xevent);
+ gdk_window_unref (window);
+ return FALSE;
+ }
+
if (wmspec_check_window != None &&
xevent->xany.window == wmspec_check_window)
{
@@ -1130,8 +1139,14 @@ gdk_event_translate (GdkEvent *event,
window_private->y = event->configure.y;
GDK_WINDOW_IMPL_X11 (window_private->impl)->width = xevent->xconfigure.width;
GDK_WINDOW_IMPL_X11 (window_private->impl)->height = xevent->xconfigure.height;
- if (window_private->resize_count > 1)
- window_private->resize_count -= 1;
+ if (window_private->resize_count >= 1)
+ {
+ window_private->resize_count -= 1;
+
+ if (window_private->resize_count == 0 &&
+ window == _gdk_moveresize_window)
+ _gdk_moveresize_configure_done ();
+ }
}
break;
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index f864a6b0a5..7652f3d73f 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -92,6 +92,9 @@ void _gdk_region_get_xrectangles (GdkRegion *region,
XRectangle **rects,
gint *n_rects);
+void _gdk_moveresize_handle_event (XEvent *event);
+void _gdk_moveresize_configure_done (void);
+
extern GdkDrawableClass _gdk_x11_drawable_class;
extern gboolean gdk_use_xshm;
extern Atom gdk_wm_delete_window;
@@ -120,4 +123,6 @@ extern gboolean _gdk_have_xkb_autorepeat;
*/
extern gboolean _gdk_have_xkb_autorepeat;
+extern GdkWindow *_gdk_moveresize_window;
+
#endif /* __GDK_PRIVATE_X11_H__ */
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 9988235ae8..b53146f424 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -931,10 +931,14 @@ gdk_window_resize (GdkWindow *window,
width, height);
else
{
+ GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+ if (width != impl->width || height != impl->height)
+ private->resize_count += 1;
+
XResizeWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
width, height);
- private->resize_count += 1;
}
}
}
@@ -964,10 +968,14 @@ gdk_window_move_resize (GdkWindow *window,
_gdk_window_move_resize_child (window, x, y, width, height);
else
{
+ GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+ if (width != impl->width || height != impl->height)
+ private->resize_count += 1;
+
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
x, y, width, height);
- private->resize_count += 1;
}
}
}
@@ -1344,7 +1352,7 @@ gdk_window_set_geometry_hints (GdkWindow *window,
if (geom_mask & GDK_HINT_WIN_GRAVITY)
{
size_hints.flags |= PWinGravity;
- size_hints.width_inc = geometry->win_gravity;
+ size_hints.win_gravity = geometry->win_gravity;
}
/* FIXME: Would it be better to delete this property of
@@ -1355,6 +1363,65 @@ gdk_window_set_geometry_hints (GdkWindow *window,
&size_hints);
}
+static void
+gdk_window_get_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints *geom_mask)
+{
+ XSizeHints size_hints;
+ glong junk_size_mask = 0;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (geometry != NULL);
+ g_return_if_fail (geom_mask != NULL);
+
+ *geom_mask = 0;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &size_hints,
+ &junk_size_mask))
+ return;
+
+ if (size_hints.flags & PMinSize)
+ {
+ *geom_mask |= GDK_HINT_MIN_SIZE;
+ geometry->min_width = size_hints.min_width;
+ geometry->min_height = size_hints.min_height;
+ }
+
+ if (size_hints.flags & PMaxSize)
+ {
+ *geom_mask |= GDK_HINT_MAX_SIZE;
+ geometry->max_width = MAX (size_hints.max_width, 1);
+ geometry->max_height = MAX (size_hints.max_height, 1);
+ }
+
+ if (size_hints.flags & PResizeInc)
+ {
+ *geom_mask |= GDK_HINT_RESIZE_INC;
+ geometry->width_inc = size_hints.width_inc;
+ geometry->height_inc = size_hints.height_inc;
+ }
+
+ if (size_hints.flags & PAspect)
+ {
+ *geom_mask |= GDK_HINT_ASPECT;
+
+ geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
+ geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
+ }
+
+ if (size_hints.flags & PWinGravity)
+ {
+ *geom_mask |= GDK_HINT_WIN_GRAVITY;
+ geometry->win_gravity = size_hints.win_gravity;
+ }
+}
+
static gboolean
utf8_is_latin1 (const gchar *str)
{
@@ -3236,3 +3303,421 @@ gdk_window_xid_at_coords (gint x,
return root;
}
+static void
+wmspec_moveresize (GdkWindow *window,
+ gint direction,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ XEvent xev;
+
+ /* Release passive grab */
+ gdk_pointer_ungrab (timestamp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = gdk_display;
+ xev.xclient.window = GDK_WINDOW_XID (window);
+ xev.xclient.message_type = gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE);
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = root_x;
+ xev.xclient.data.l[1] = root_y;
+ xev.xclient.data.l[2] = direction;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (gdk_display, gdk_root_window, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+/* From the WM spec */
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
+#define _NET_WM_MOVERESIZE_MOVE 8
+
+static void
+wmspec_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ gint direction;
+
+ /* Let the compiler turn a switch into a table, instead
+ * of doing the table manually, this way is easier to verify.
+ */
+ switch (edge)
+ {
+ case GDK_WINDOW_EDGE_NORTH_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_NORTH:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOP;
+ break;
+
+ case GDK_WINDOW_EDGE_NORTH_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
+ break;
+
+ case GDK_WINDOW_EDGE_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
+ break;
+
+ default:
+ g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
+ edge);
+ return;
+ break;
+ }
+
+ wmspec_moveresize (window, direction, root_x, root_y, timestamp);
+}
+
+/* This is global for use in gdkevents-x11.c */
+GdkWindow *_gdk_moveresize_window;
+
+static GdkWindow *moveresize_emulation_window = NULL;
+static gboolean is_resize = FALSE;
+static GdkWindowEdge resize_edge;
+static gint moveresize_button;
+static gint moveresize_x;
+static gint moveresize_y;
+static gint moveresize_orig_x;
+static gint moveresize_orig_y;
+static gint moveresize_orig_width;
+static gint moveresize_orig_height;
+static GdkWindowHints moveresize_geom_mask = 0;
+static GdkGeometry moveresize_geometry;
+static Time moveresize_process_time;
+
+static XEvent *moveresize_pending_event;
+
+static void
+update_pos (gint new_root_x,
+ gint new_root_y)
+{
+ gint dx, dy;
+
+ dx = new_root_x - moveresize_x;
+ dy = new_root_y - moveresize_y;
+
+ if (is_resize)
+ {
+ gint w, h;
+
+ w = moveresize_orig_width;
+ h = moveresize_orig_height;
+
+ switch (resize_edge)
+ {
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ w += dx;
+ h += dy;
+ break;
+
+ }
+
+ w = MAX (w, 1);
+ h = MAX (h, 1);
+
+ if (moveresize_geom_mask)
+ {
+ gdk_window_constrain_size (&moveresize_geometry,
+ moveresize_geom_mask,
+ w, h,
+ &w, &h);
+ }
+
+ gdk_window_resize (_gdk_moveresize_window, w, h);
+ }
+ else
+ {
+ gint x, y;
+
+ x = moveresize_orig_x + dx;
+ y = moveresize_orig_y + dy;
+
+ gdk_window_move (_gdk_moveresize_window, x, y);
+ }
+}
+
+static void
+finish_drag (void)
+{
+ gdk_window_destroy (moveresize_emulation_window);
+ moveresize_emulation_window = NULL;
+ _gdk_moveresize_window = NULL;
+
+ if (moveresize_pending_event)
+ {
+ g_free (moveresize_pending_event);
+ moveresize_pending_event = NULL;
+ }
+}
+
+static int
+lookahead_motion_predicate (Display *display,
+ XEvent *event,
+ XPointer arg)
+{
+ gboolean *seen_release = (gboolean *)arg;
+
+ if (*seen_release)
+ return False;
+
+ switch (event->xany.type)
+ {
+ case ButtonRelease:
+ *seen_release = TRUE;
+ break;
+ case MotionNotify:
+ moveresize_process_time = event->xmotion.time;
+ break;
+ default:
+ break;
+ }
+
+ return False;
+}
+
+static gboolean
+moveresize_lookahead (XEvent *event)
+{
+ XEvent tmp_event;
+ gboolean seen_release = FALSE;
+
+ if (moveresize_process_time)
+ {
+ if (event->xmotion.time == moveresize_process_time)
+ {
+ moveresize_process_time = 0;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ XCheckIfEvent (gdk_display, &tmp_event,
+ lookahead_motion_predicate, (XPointer)&seen_release);
+
+ return moveresize_process_time == 0;
+}
+
+void
+_gdk_moveresize_handle_event (XEvent *event)
+{
+ guint button_mask = 0;
+ GdkWindowObject *window_private = (GdkWindowObject *) _gdk_moveresize_window;
+
+ button_mask = GDK_BUTTON1_MASK << (moveresize_button - 1);
+
+ switch (event->xany.type)
+ {
+ case MotionNotify:
+ if (window_private->resize_count > 0)
+ {
+ if (moveresize_pending_event)
+ *moveresize_pending_event = *event;
+ else
+ moveresize_pending_event = g_memdup (event, sizeof (XEvent));
+
+ break;
+ }
+ if (!moveresize_lookahead (event))
+ break;
+
+ update_pos (event->xmotion.x_root,
+ event->xmotion.y_root);
+
+ /* This should never be triggered in normal cases, but in the
+ * case where the drag started without an implicit grab being
+ * in effect, we could miss the release if it occurs before
+ * we grab the pointer; this ensures that we will never
+ * get a permanently stuck grab.
+ */
+ if ((event->xmotion.state & button_mask) == 0)
+ finish_drag ();
+ break;
+
+ case ButtonRelease:
+ update_pos (event->xbutton.x_root,
+ event->xbutton.y_root);
+
+ if (event->xbutton.button == moveresize_button)
+ finish_drag ();
+ break;
+ }
+}
+
+void
+_gdk_moveresize_configure_done (void)
+{
+ XEvent *tmp_event;
+
+ if (moveresize_pending_event)
+ {
+ tmp_event = moveresize_pending_event;
+ moveresize_pending_event = NULL;
+ _gdk_moveresize_handle_event (tmp_event);
+ g_free (tmp_event);
+ }
+}
+
+static void
+create_moveresize_window (guint32 timestamp)
+{
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ GdkGrabStatus status;
+
+ g_assert (moveresize_emulation_window == NULL);
+
+ attributes.x = -100;
+ attributes.y = -100;
+ attributes.width = 10;
+ attributes.height = 10;
+ attributes.window_type = GDK_WINDOW_TEMP;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.override_redirect = TRUE;
+ attributes.event_mask = 0;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
+
+ moveresize_emulation_window =
+ gdk_window_new (NULL, &attributes, attributes_mask);
+
+ gdk_window_show (moveresize_emulation_window);
+
+ status = gdk_pointer_grab (moveresize_emulation_window,
+ FALSE,
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ FALSE,
+ NULL,
+ timestamp);
+
+ if (status != GDK_GRAB_SUCCESS)
+ {
+ /* If this fails, some other client has grabbed the window
+ * already.
+ */
+ gdk_window_destroy (moveresize_emulation_window);
+ moveresize_emulation_window = NULL;
+ }
+
+ moveresize_process_time = 0;
+}
+
+static void
+emulate_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ is_resize = TRUE;
+ moveresize_button = button;
+ resize_edge = edge;
+ moveresize_x = root_x;
+ moveresize_y = root_y;
+ _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
+
+ gdk_window_get_size (window, &moveresize_orig_width, &moveresize_orig_height);
+
+ moveresize_geom_mask = 0;
+ gdk_window_get_geometry_hints (window,
+ &moveresize_geometry,
+ &moveresize_geom_mask);
+
+ create_moveresize_window (timestamp);
+}
+
+static void
+emulate_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ is_resize = FALSE;
+ moveresize_button = button;
+ moveresize_x = root_x;
+ moveresize_y = root_y;
+ _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
+
+ gdk_window_get_deskrelative_origin (_gdk_moveresize_window,
+ &moveresize_orig_x,
+ &moveresize_orig_y);
+
+ create_moveresize_window (timestamp);
+}
+
+void
+gdk_window_begin_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (moveresize_emulation_window == NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+ wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
+ else
+ emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
+}
+
+void
+gdk_window_begin_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (moveresize_emulation_window == NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+ wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE,
+ root_x, root_y, timestamp);
+ else
+ emulate_move_drag (window, button, root_x, root_y, timestamp);
+}
+