X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fgdkwindow.c;h=3164b8ecfc19fb3b9696a5c7bc50aa787177950b;hb=1f149b3a8d4180024df25f700307406520159bec;hp=7f8a38ccd7f176c5596c6238406c6034516dd361;hpb=566a13a6c0a22b71dfa6fc3bdfc4a69649f0a55f;p=~andy%2Fgtk diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 7f8a38ccd..3164b8ecf 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -12,1040 +12,171 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include -#include -#include "gdk.h" -#include "../config.h" -#include "gdkinput.h" -#include "gdkprivate.h" -#include "MwmUtil.h" -#include -#include - -int nevent_masks = 17; -int event_mask_table[19] = -{ - ExposureMask, - PointerMotionMask, - PointerMotionHintMask, - ButtonMotionMask, - Button1MotionMask, - Button2MotionMask, - Button3MotionMask, - ButtonPressMask | OwnerGrabButtonMask, - ButtonReleaseMask | OwnerGrabButtonMask, - KeyPressMask, - KeyReleaseMask, - EnterWindowMask, - LeaveWindowMask, - FocusChangeMask, - StructureNotifyMask, - PropertyChangeMask, - VisibilityChangeMask, - 0, /* PROXIMITY_IN */ - 0 /* PROXIMTY_OUT */ -}; - - -/* internal function created for and used by gdk_window_xid_at_coords */ -Window -gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y, - GList *excludes, gboolean excl_child) -{ - GdkWindow *window; - GdkWindowPrivate *private; - Display *disp; - Window *list=NULL; - Window child=0,parent_win=0,root_win=0; - unsigned int num,i,ww,wh,wb,wd; - int wx,wy; - - window=(GdkWindow*)&gdk_root_parent; - private=(GdkWindowPrivate*)window; - disp=private->xdisplay; - if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd)) - return 0; - wx+=bx;wy+=by; - if (!((x>=wx)&&(y>=wy)&&(x<(wx+ww))&&(y<(wy+wh)))) - return 0; - if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num)) - return base; - if (list) - { - for (i=num-1;;i--) - { - if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i]))) - { - if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0) - { - XFree(list); - return child; - } - } - if (!i) break; - } - XFree(list); - } - return base; -} -/* - * The following fucntion by The Rasterman - * This function returns the X Window ID in which the x y location is in - * (x and y being relative to the root window), excluding any windows listed - * in the GList excludes (this is a list of X Window ID's - gpointer being - * the Window ID). - * - * This is primarily designed for internal gdk use - for DND for example - * when using a shaped icon window as the drag object - you exclude the - * X Window ID of the "icon" (perhaps more if excludes may be needed) and - * You can get back an X Window ID as to what X Window ID is infact under - * those X,Y co-ordinates. +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -Window -gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child) -{ - GdkWindow *window; - GdkWindowPrivate *private; - Display *disp; - Window *list=NULL; - Window root,child=0,parent_win=0,root_win=0; - unsigned int num,i; - GList *gl; - - window=(GdkWindow*)&gdk_root_parent; - private=(GdkWindowPrivate*)window; - disp=private->xdisplay; - root=private->xwindow; - XGrabServer(disp); - num=g_list_length(excludes); - if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num)) - return root; - if (list) - { - for (i=num-1;;i--) - { - if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i]))) - { - if ((child=gdk_window_xid_at(list[i],0,0,x,y,excludes,excl_child))!=0) - { - if (excludes) - { - if (!g_list_find(excludes,(gpointer *)child)) - { - XFree(list); - XUngrabServer(disp); - return child; - } - } - else - { - XFree(list); - XUngrabServer(disp); - return child; - } - } - } - if (!i) break; - } - XFree(list); - } - XUngrabServer(disp); - return root; -} - -void -gdk_window_init () -{ - XWindowAttributes xattributes; - unsigned int width; - unsigned int height; - unsigned int border_width; - unsigned int depth; - int x, y; - - XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window, - &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes); - - gdk_root_parent.xdisplay = gdk_display; - gdk_root_parent.xwindow = gdk_root_window; - gdk_root_parent.window_type = GDK_WINDOW_ROOT; - gdk_root_parent.window.user_data = NULL; - gdk_root_parent.width = width; - gdk_root_parent.height = height; -} - -GdkWindow* -gdk_window_new (GdkWindow *parent, - GdkWindowAttr *attributes, - gint attributes_mask) -{ - GdkWindow *window; - GdkWindowPrivate *private; - GdkWindowPrivate *parent_private; - GdkVisual *visual; - GdkColormap *colormap; - Display *parent_display; - Window xparent; - Visual *xvisual; - XSetWindowAttributes xattributes; - long xattributes_mask; - XSizeHints size_hints; - XWMHints wm_hints; - XClassHint *class_hint; - int x, y, depth; - unsigned int class; - char *title; - int i; - - g_return_val_if_fail (attributes != NULL, NULL); - - if (!parent) - parent = (GdkWindow*) &gdk_root_parent; - - parent_private = (GdkWindowPrivate*) parent; - if (parent_private->destroyed) - return NULL; - - xparent = parent_private->xwindow; - parent_display = parent_private->xdisplay; - - private = g_new (GdkWindowPrivate, 1); - window = (GdkWindow*) private; - - private->parent = parent; - private->xdisplay = parent_display; - private->destroyed = FALSE; - private->resize_count = 0; - private->ref_count = 1; - xattributes_mask = 0; - - if (attributes_mask & GDK_WA_X) - x = attributes->x; - else - x = 0; - - if (attributes_mask & GDK_WA_Y) - y = attributes->y; - else - y = 0; - - private->x = x; - private->y = y; - private->width = (attributes->width > 1) ? (attributes->width) : (1); - private->height = (attributes->height > 1) ? (attributes->height) : (1); - private->window_type = attributes->window_type; - private->extension_events = FALSE; - private->dnd_drag_data_type = None; - private->dnd_drag_data_typesavail = - private->dnd_drop_data_typesavail = NULL; - private->dnd_drop_enabled = private->dnd_drag_enabled = - private->dnd_drag_accepted = private->dnd_drag_datashow = - private->dnd_drop_data_numtypesavail = - private->dnd_drag_data_numtypesavail = 0; - private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0; - - private->filters = NULL; - - window->user_data = NULL; - - if (attributes_mask & GDK_WA_VISUAL) - visual = attributes->visual; - else - visual = gdk_visual_get_system (); - xvisual = ((GdkVisualPrivate*) visual)->xvisual; - - xattributes.event_mask = StructureNotifyMask; - for (i = 0; i < nevent_masks; i++) - { - if (attributes->event_mask & (1 << (i + 1))) - xattributes.event_mask |= event_mask_table[i]; - } - - if (xattributes.event_mask) - xattributes_mask |= CWEventMask; - - if(attributes_mask & GDK_WA_NOREDIR) { - xattributes.override_redirect = - (attributes->override_redirect == FALSE)?False:True; - xattributes_mask |= CWOverrideRedirect; - } else - xattributes.override_redirect = False; - - if (attributes->wclass == GDK_INPUT_OUTPUT) - { - class = InputOutput; - depth = visual->depth; - - if (attributes_mask & GDK_WA_COLORMAP) - colormap = attributes->colormap; - else - colormap = gdk_colormap_get_system (); - - xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen); - xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen); - xattributes_mask |= CWBorderPixel | CWBackPixel; - - switch (private->window_type) - { - case GDK_WINDOW_TOPLEVEL: - xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap; - xattributes_mask |= CWColormap; - - xparent = gdk_root_window; - break; - - case GDK_WINDOW_CHILD: - xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap; - xattributes_mask |= CWColormap; - break; - - case GDK_WINDOW_DIALOG: - xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap; - xattributes_mask |= CWColormap; - - xparent = gdk_root_window; - break; - - case GDK_WINDOW_TEMP: - xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap; - xattributes_mask |= CWColormap; - - xparent = gdk_root_window; - - xattributes.save_under = True; - xattributes.override_redirect = True; - xattributes.cursor = None; - xattributes_mask |= CWSaveUnder | CWOverrideRedirect; - break; - case GDK_WINDOW_ROOT: - g_error ("cannot make windows of type GDK_WINDOW_ROOT"); - break; - case GDK_WINDOW_PIXMAP: - g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)"); - break; - } - } - else - { - depth = 0; - class = InputOnly; - colormap = NULL; - } - - private->xwindow = XCreateWindow (private->xdisplay, xparent, - x, y, private->width, private->height, - 0, depth, class, xvisual, - xattributes_mask, &xattributes); - gdk_window_ref (window); - gdk_xid_table_insert (&private->xwindow, window); - - switch (private->window_type) - { - case GDK_WINDOW_DIALOG: - XSetTransientForHint (private->xdisplay, private->xwindow, xparent); - case GDK_WINDOW_TOPLEVEL: - case GDK_WINDOW_TEMP: - XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2); - break; - case GDK_WINDOW_CHILD: - if ((attributes->wclass == GDK_INPUT_OUTPUT) && - (colormap != gdk_colormap_get_system ()) && - (colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window)))) - { - g_print ("adding colormap window\n"); - gdk_window_add_colormap_windows (window); - } - break; - default: - break; - } - - size_hints.flags = PSize | PBaseSize; - size_hints.width = private->width; - size_hints.height = private->height; - size_hints.base_width = private->width; - size_hints.base_height = private->height; - - wm_hints.flags = InputHint | StateHint | WindowGroupHint; - wm_hints.window_group = gdk_leader_window; - wm_hints.input = True; - wm_hints.initial_state = NormalState; - - XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints); - XSetWMHints (private->xdisplay, private->xwindow, &wm_hints); - - if (attributes_mask & GDK_WA_TITLE) - title = attributes->title; - else - title = gdk_progname; - - XmbSetWMProperties (private->xdisplay, private->xwindow, - title, title, - NULL, 0, - NULL, NULL, NULL); - - if (attributes_mask & GDK_WA_WMCLASS) - { - class_hint = XAllocClassHint (); - class_hint->res_name = attributes->wmclass_name; - class_hint->res_class = attributes->wmclass_class; - XSetClassHint (private->xdisplay, private->xwindow, class_hint); - XFree (class_hint); - } - - gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? - (attributes->cursor) : - NULL)); - - return window; -} - -GdkWindow * -gdk_window_foreign_new (guint32 anid) -{ - GdkWindow *window; - GdkWindowPrivate *private; - XWindowAttributes attrs; - Window root, parent; - Window *children; - guint nchildren; - - private = g_new (GdkWindowPrivate, 1); - window = (GdkWindow*) private; - - XGetWindowAttributes (gdk_display, anid, &attrs); - - /* FIXME: This is pretty expensive. Maybe the caller should supply - * the parent */ - XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren); - XFree (children); - private->parent = gdk_xid_table_lookup (parent); - - private->xwindow = anid; - private->xdisplay = gdk_display; - private->x = attrs.x; - private->y = attrs.y; - private->width = attrs.width; - private->height = attrs.height; - private->resize_count = 0; - private->ref_count = 1; - private->window_type = GDK_WINDOW_FOREIGN; - private->destroyed = FALSE; - private->extension_events = 0; - - - private->dnd_drag_data_type = None; - private->dnd_drag_data_typesavail = - private->dnd_drop_data_typesavail = NULL; - private->dnd_drop_enabled = private->dnd_drag_enabled = - private->dnd_drag_accepted = private->dnd_drag_datashow = - private->dnd_drop_data_numtypesavail = - private->dnd_drag_data_numtypesavail = 0; - private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0; - - private->filters = NULL; - - window->user_data = NULL; - - gdk_window_ref (window); - gdk_xid_table_insert (&private->xwindow, window); - - return window; -} - -/* Call this function when you want a window and all its children to - disappear. When xdestroy is true, a request to destroy the XWindow - is sent out. When it is false, it is assumed that the XWindow has - been or will be destroyed by destroying some ancestor of this - window. */ - -static void -gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy, - gboolean our_destroy) -{ - GdkWindowPrivate *private; - GdkWindowPrivate *temp_private; - GdkWindow *temp_window; - GList *children; - GList *tmp; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - - switch (private->window_type) - { - case GDK_WINDOW_TOPLEVEL: - case GDK_WINDOW_CHILD: - case GDK_WINDOW_DIALOG: - case GDK_WINDOW_TEMP: - case GDK_WINDOW_FOREIGN: - if (!private->destroyed) - { - if (private->window_type != GDK_WINDOW_FOREIGN) - { - children = gdk_window_get_children (window); - tmp = children; - - while (tmp) - { - temp_window = tmp->data; - tmp = tmp->next; - - temp_private = (GdkWindowPrivate*) temp_window; - if (temp_private) - gdk_window_internal_destroy (temp_window, FALSE, - our_destroy); - } - - g_list_free (children); - } - - if (private->extension_events != 0) - gdk_input_window_destroy (window); - - if(private->dnd_drag_data_numtypesavail > 0) - { - g_free (private->dnd_drag_data_typesavail); - private->dnd_drag_data_typesavail = NULL; - } - if(private->dnd_drop_data_numtypesavail > 0) - { - g_free (private->dnd_drop_data_typesavail); - private->dnd_drop_data_typesavail = NULL; - } - - if (private->filters) - { - tmp = private->filters; - - while (tmp) - { - g_free (tmp->data); - tmp = tmp->next; - } - - g_list_free (private->filters); - private->filters = NULL; - } - - if (private->window_type == GDK_WINDOW_FOREIGN) - { - if (our_destroy && (private->parent != NULL)) - { - /* It's somebody elses window, but in our heirarchy, - * so reparent it to the root window, and then send - * it a delete event, as if we were a WM - */ - XClientMessageEvent xevent; - - gdk_window_hide (window); - gdk_window_reparent (window, NULL, 0, 0); - - xevent.type = ClientMessage; - xevent.window = private->xwindow; - xevent.message_type = gdk_wm_protocols; - xevent.format = 32; - xevent.data.l[0] = gdk_wm_delete_window; - xevent.data.l[1] = CurrentTime; - - XSendEvent (private->xdisplay, private->xwindow, - False, 0, (XEvent *)&xevent); - } - } - else if (xdestroy) - XDestroyWindow (private->xdisplay, private->xwindow); - - private->destroyed = TRUE; - } - break; - - case GDK_WINDOW_ROOT: - g_error ("attempted to destroy root window"); - break; - - case GDK_WINDOW_PIXMAP: - g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)"); - break; - } -} - -/* Like internal_destroy, but also destroys the reference created by - gdk_window_new. */ - -void -gdk_window_destroy (GdkWindow *window) -{ - gdk_window_internal_destroy (window, TRUE, TRUE); - gdk_window_unref (window); -} - -/* This function is called when the XWindow is really gone. */ - -void -gdk_window_destroy_notify (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - { - if (private->window_type == GDK_WINDOW_FOREIGN) - gdk_window_internal_destroy (window, FALSE, FALSE); - else - g_warning ("Window %#lx unexpectedly destroyed", private->xwindow); - } - - gdk_xid_table_remove (private->xwindow); - gdk_window_unref (window); -} - -GdkWindow* -gdk_window_ref (GdkWindow *window) -{ - GdkWindowPrivate *private = (GdkWindowPrivate *)window; - g_return_val_if_fail (window != NULL, NULL); - - private->ref_count += 1; - return window; -} +#include "gdkwindow.h" +#include "gdkinternals.h" +#include "gdk.h" /* For gdk_rectangle_union() */ +#include "gdkpixmap.h" -void -gdk_window_unref (GdkWindow *window) -{ - GdkWindowPrivate *private = (GdkWindowPrivate *)window; - g_return_if_fail (window != NULL); - - private->ref_count -= 1; - if (private->ref_count == 0) - { - if (!private->destroyed) - g_warning ("losing last reference to undestroyed window\n"); - g_free (window); - } -} - -void -gdk_window_show (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - { - XRaiseWindow (private->xdisplay, private->xwindow); - XMapWindow (private->xdisplay, private->xwindow); - } -} - -void -gdk_window_hide (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - XUnmapWindow (private->xdisplay, private->xwindow); -} - -void -gdk_window_withdraw (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - XWithdrawWindow (private->xdisplay, private->xwindow, 0); -} - -void -gdk_window_move (GdkWindow *window, - gint x, - gint y) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - { - XMoveWindow (private->xdisplay, private->xwindow, x, y); - - if (private->window_type == GDK_WINDOW_CHILD) - { - private->x = x; - private->y = y; - } - } -} - -void -gdk_window_resize (GdkWindow *window, - gint width, - gint height) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - if (width < 1) - width = 1; - if (height < 1) - height = 1; - - private = (GdkWindowPrivate*) window; - - if (!private->destroyed && - ((private->resize_count > 0) || - (private->width != (guint16) width) || - (private->height != (guint16) height))) - { - XResizeWindow (private->xdisplay, private->xwindow, width, height); - private->resize_count += 1; - - if (private->window_type == GDK_WINDOW_CHILD) - { - private->width = width; - private->height = height; - } - } -} - -void -gdk_window_move_resize (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - if (width < 1) - width = 1; - if (height < 1) - height = 1; - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - { - XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height); - - if (private->window_type == GDK_WINDOW_CHILD) - { - private->x = x; - private->y = y; - private->width = width; - private->height = height; - } - } -} - -void -gdk_window_reparent (GdkWindow *window, - GdkWindow *new_parent, - gint x, - gint y) -{ - GdkWindowPrivate *window_private; - GdkWindowPrivate *parent_private; - - g_return_if_fail (window != NULL); - - if (!new_parent) - new_parent = (GdkWindow*) &gdk_root_parent; - - window_private = (GdkWindowPrivate*) window; - parent_private = (GdkWindowPrivate*) new_parent; - - if (!window_private->destroyed && !parent_private->destroyed) - XReparentWindow (window_private->xdisplay, - window_private->xwindow, - parent_private->xwindow, - x, y); -} - -void -gdk_window_clear (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - - if (!private->destroyed) - XClearWindow (private->xdisplay, private->xwindow); -} - -void -gdk_window_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - - if (!private->destroyed) - XClearArea (private->xdisplay, private->xwindow, - x, y, width, height, False); -} - -void -gdk_window_clear_area_e (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - - if (!private->destroyed) - XClearArea (private->xdisplay, private->xwindow, - x, y, width, height, True); -} - -void -gdk_window_copy_area (GdkWindow *window, - GdkGC *gc, - gint x, - gint y, - GdkWindow *source_window, - gint source_x, - gint source_y, - gint width, - gint height) -{ - GdkWindowPrivate *src_private; - GdkWindowPrivate *dest_private; - GdkGCPrivate *gc_private; - - g_return_if_fail (window != NULL); - g_return_if_fail (gc != NULL); - - if (source_window == NULL) - source_window = window; - - src_private = (GdkWindowPrivate*) source_window; - dest_private = (GdkWindowPrivate*) window; - gc_private = (GdkGCPrivate*) gc; - - if (!src_private->destroyed && !dest_private->destroyed) - { - XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow, - gc_private->xgc, - source_x, source_y, - width, height, - x, y); - } -} - -void -gdk_window_raise (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - - if (!private->destroyed) - XRaiseWindow (private->xdisplay, private->xwindow); -} - -void -gdk_window_lower (GdkWindow *window) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - - if (!private->destroyed) - XLowerWindow (private->xdisplay, private->xwindow); -} +#ifndef USE_BACKING_STORE +#ifndef GDK_WINDOWING_WIN32 +#define USE_BACKING_STORE /* Doesn't work yet on Win32 */ +#endif +#endif -void -gdk_window_set_user_data (GdkWindow *window, - gpointer user_data) -{ - g_return_if_fail (window != NULL); - - window->user_data = user_data; -} +typedef struct _GdkWindowPaint GdkWindowPaint; -void -gdk_window_set_hints (GdkWindow *window, - gint x, - gint y, - gint min_width, - gint min_height, - gint max_width, - gint max_height, - gint flags) +struct _GdkWindowPaint { - GdkWindowPrivate *private; - XSizeHints size_hints; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (private->destroyed) - return; - - size_hints.flags = 0; - - if (flags & GDK_HINT_POS) - { - size_hints.flags |= PPosition; - size_hints.x = x; - size_hints.y = y; - } - - if (flags & GDK_HINT_MIN_SIZE) - { - size_hints.flags |= PMinSize; - size_hints.min_width = min_width; - size_hints.min_height = min_height; - } - - if (flags & GDK_HINT_MAX_SIZE) - { - size_hints.flags |= PMaxSize; - size_hints.max_width = max_width; - size_hints.max_height = max_height; - } - - if (flags) - XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints); -} + GdkRegion *region; + GdkPixmap *pixmap; + gint x_offset; + gint y_offset; +}; -void -gdk_window_set_title (GdkWindow *window, - const gchar *title) -{ - GdkWindowPrivate *private; - - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - XmbSetWMProperties (private->xdisplay, private->xwindow, - title, title, NULL, 0, NULL, NULL, NULL); -} +static void gdk_window_draw_destroy (GdkDrawable *drawable); +static GdkGC *gdk_window_draw_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask); +static void gdk_window_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height); +static void gdk_window_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +static void gdk_window_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints); +static void gdk_window_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); +static void gdk_window_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length); +static void gdk_window_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); +static void gdk_window_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +static void gdk_window_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs); +static void gdk_window_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); + + +/* All drawing operations on windows are forwarded through the following + * class to enable the automatic-backing-store feature. + */ +GdkDrawableClass _gdk_window_class = { + gdk_window_draw_destroy, + gdk_window_draw_create_gc, + gdk_window_draw_rectangle, + gdk_window_draw_arc, + gdk_window_draw_polygon, + gdk_window_draw_text, + gdk_window_draw_text_wc, + gdk_window_draw_drawable, + gdk_window_draw_points, + gdk_window_draw_segments, + gdk_window_draw_lines +}; -void -gdk_window_set_background (GdkWindow *window, - GdkColor *color) +GdkWindow * +_gdk_window_alloc (void) { - GdkWindowPrivate *private; + GdkWindowPrivate *private = g_new (GdkWindowPrivate, 1); + GdkWindow *window = (GdkWindow*) private; - g_return_if_fail (window != NULL); - - private = (GdkWindowPrivate*) window; - if (!private->destroyed) - XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel); -} + window->user_data = NULL; -void -gdk_window_set_back_pixmap (GdkWindow *window, - GdkPixmap *pixmap, - gint parent_relative) -{ - GdkWindowPrivate *window_private; - GdkPixmapPrivate *pixmap_private; - Pixmap xpixmap; - - g_return_if_fail (window != NULL); - - window_private = (GdkWindowPrivate*) window; - pixmap_private = (GdkPixmapPrivate*) pixmap; - - if (pixmap) - xpixmap = pixmap_private->xwindow; - else - xpixmap = None; - - if (parent_relative) - xpixmap = ParentRelative; - - if (!window_private->destroyed) - XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap); -} + private->drawable.ref_count = 1; + private->drawable.destroyed = FALSE; + private->drawable.klass = NULL; + private->drawable.klass_data = NULL; + private->drawable.window_type = GDK_WINDOW_CHILD; -void -gdk_window_set_cursor (GdkWindow *window, - GdkCursor *cursor) -{ - GdkWindowPrivate *window_private; - GdkCursorPrivate *cursor_private; - Cursor xcursor; - - g_return_if_fail (window != NULL); - - window_private = (GdkWindowPrivate*) window; - cursor_private = (GdkCursorPrivate*) cursor; + private->drawable.width = 1; + private->drawable.height = 1; + + private->drawable.colormap = NULL; + + private->parent = NULL; + private->x = 0; + private->y = 0; + private->resize_count = 0; + + private->mapped = FALSE; + private->guffaw_gravity = FALSE; + private->extension_events = FALSE; - if (!cursor) - xcursor = None; - else - xcursor = cursor_private->xcursor; + private->filters = NULL; + private->children = NULL; + + private->bg_color.pixel = 0; + private->bg_color.red = 0; + private->bg_color.green = 0; + private->bg_color.blue = 0; + + private->bg_pixmap = NULL; + + private->paint_stack = NULL; + + private->update_area = NULL; + private->update_freeze_count = 0; - if (!window_private->destroyed) - XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor); + return window; } void -gdk_window_set_colormap (GdkWindow *window, - GdkColormap *colormap) +gdk_window_set_user_data (GdkWindow *window, + gpointer user_data) { - GdkWindowPrivate *window_private; - GdkColormapPrivate *colormap_private; - g_return_if_fail (window != NULL); - g_return_if_fail (colormap != NULL); - window_private = (GdkWindowPrivate*) window; - colormap_private = (GdkColormapPrivate*) colormap; - - if (!window_private->destroyed) - { - XSetWindowColormap (window_private->xdisplay, - window_private->xwindow, - colormap_private->xcolormap); - - if (window_private->window_type != GDK_WINDOW_TOPLEVEL) - gdk_window_add_colormap_windows (window); - } + window->user_data = user_data; } void @@ -1057,46 +188,6 @@ gdk_window_get_user_data (GdkWindow *window, *data = window->user_data; } -void -gdk_window_get_geometry (GdkWindow *window, - gint *x, - gint *y, - gint *width, - gint *height, - gint *depth) -{ - GdkWindowPrivate *window_private; - Window root; - gint tx; - gint ty; - guint twidth; - guint theight; - guint tborder_width; - guint tdepth; - - if (!window) - window = (GdkWindow*) &gdk_root_parent; - - window_private = (GdkWindowPrivate*) window; - - if (!window_private->destroyed) - { - XGetGeometry (window_private->xdisplay, window_private->xwindow, - &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth); - - if (x) - *x = tx; - if (y) - *y = ty; - if (width) - *width = twidth; - if (height) - *height = theight; - if (depth) - *depth = tdepth; - } -} - void gdk_window_get_position (GdkWindow *window, gint *x, @@ -1105,6 +196,7 @@ gdk_window_get_position (GdkWindow *window, GdkWindowPrivate *window_private; g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); window_private = (GdkWindowPrivate*) window; @@ -1114,787 +206,1076 @@ gdk_window_get_position (GdkWindow *window, *y = window_private->y; } -void -gdk_window_get_size (GdkWindow *window, - gint *width, - gint *height) +GdkWindow* +gdk_window_get_parent (GdkWindow *window) { - GdkWindowPrivate *window_private; + g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + return ((GdkWindowPrivate*) window)->parent; +} + +GdkWindow* +gdk_window_get_toplevel (GdkWindow *window) +{ + GdkWindowPrivate *private; + + g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + private = (GdkWindowPrivate *)window; + while (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD) + private = (GdkWindowPrivate *)private->parent; + + return (GdkWindow *)window; +} + +void +gdk_window_add_filter (GdkWindow *window, + GdkFilterFunc function, + gpointer data) +{ + GdkWindowPrivate *private; + GList *tmp_list; + GdkEventFilter *filter; g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowPrivate*) window; + if (private && GDK_DRAWABLE_DESTROYED (window)) + return; - window_private = (GdkWindowPrivate*) window; + if (private) + tmp_list = private->filters; + else + tmp_list = gdk_default_filters; + + while (tmp_list) + { + filter = (GdkEventFilter *)tmp_list->data; + if ((filter->function == function) && (filter->data == data)) + return; + tmp_list = tmp_list->next; + } + + filter = g_new (GdkEventFilter, 1); + filter->function = function; + filter->data = data; - if (width) - *width = window_private->width; - if (height) - *height = window_private->height; + if (private) + private->filters = g_list_append (private->filters, filter); + else + gdk_default_filters = g_list_append (gdk_default_filters, filter); } -GdkVisual* -gdk_window_get_visual (GdkWindow *window) +void +gdk_window_remove_filter (GdkWindow *window, + GdkFilterFunc function, + gpointer data) { - GdkWindowPrivate *window_private; - XWindowAttributes window_attributes; + GdkWindowPrivate *private; + GList *tmp_list, *node; + GdkEventFilter *filter; - g_return_val_if_fail (window != NULL, NULL); + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowPrivate*) window; - window_private = (GdkWindowPrivate*) window; - while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP)) - window_private = (GdkWindowPrivate*) window_private->parent; + if (private) + tmp_list = private->filters; + else + tmp_list = gdk_default_filters; - if (window_private && !window_private->destroyed) + while (tmp_list) { - XGetWindowAttributes (window_private->xdisplay, - window_private->xwindow, - &window_attributes); + filter = (GdkEventFilter *)tmp_list->data; + node = tmp_list; + tmp_list = tmp_list->next; - return gdk_visual_lookup (window_attributes.visual); + if ((filter->function == function) && (filter->data == data)) + { + if (private) + private->filters = g_list_remove_link (private->filters, node); + else + gdk_default_filters = g_list_remove_link (gdk_default_filters, node); + g_list_free_1 (node); + g_free (filter); + + return; + } + } +} + +GList * +gdk_window_get_toplevels (void) +{ + GList *new_list = NULL; + GList *tmp_list; + + tmp_list = ((GdkWindowPrivate *)gdk_parent_root)->children; + while (tmp_list) + { + new_list = g_list_prepend (new_list, tmp_list->data); + tmp_list = tmp_list->next; } - return NULL; + return new_list; } -GdkColormap* -gdk_window_get_colormap (GdkWindow *window) +/************************************************************* + * gdk_window_is_visible: + * Check if the given window is mapped. + * arguments: + * window: + * results: + * is the window mapped + *************************************************************/ + +gboolean +gdk_window_is_visible (GdkWindow *window) { - GdkWindowPrivate *window_private; - XWindowAttributes window_attributes; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; - g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - window_private = (GdkWindowPrivate*) window; + return private->mapped; +} + +/************************************************************* + * gdk_window_is_viewable: + * Check if the window and all ancestors of the window + * are mapped. (This is not necessarily "viewable" in + * the X sense, since we only check as far as we have + * GDK window parents, not to the root window) + * arguments: + * window: + * results: + * is the window viewable + *************************************************************/ + +gboolean +gdk_window_is_viewable (GdkWindow *window) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; - if (!window_private->destroyed) + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + while (private && + (private != (GdkWindowPrivate *)gdk_parent_root) && + (private->drawable.window_type != GDK_WINDOW_FOREIGN)) { - XGetWindowAttributes (window_private->xdisplay, - window_private->xwindow, - &window_attributes); + if (!private->mapped) + return FALSE; - return gdk_colormap_lookup (window_attributes.colormap); + private = (GdkWindowPrivate *)private->parent; } - return NULL; + return TRUE; } -GdkWindowType -gdk_window_get_type (GdkWindow *window) +void +gdk_window_begin_paint_rect (GdkWindow *window, + GdkRectangle *rectangle) { - GdkWindowPrivate *window_private; + GdkRegion *region; - g_return_val_if_fail (window != NULL, (GdkWindowType) -1); + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); - window_private = (GdkWindowPrivate*) window; - return window_private->window_type; + region = gdk_region_rectangle (rectangle); + gdk_window_begin_paint_region (window, region); + gdk_region_destroy (region); } -gint -gdk_window_get_origin (GdkWindow *window, - gint *x, - gint *y) +static GdkGC * +gdk_window_get_bg_gc (GdkWindow *window, GdkWindowPaint *paint) { - GdkWindowPrivate *private; - gint return_val; - Window child; - gint tx, ty; - - g_return_val_if_fail (window != NULL, 0); + GdkWindowPrivate *private = (GdkWindowPrivate *)window; - private = (GdkWindowPrivate*) window; + guint gc_mask = 0; + GdkGCValues gc_values; - if (!private->destroyed) + if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) + { + GdkWindowPaint tmp_paint = *paint; + tmp_paint.x_offset += private->x; + tmp_paint.y_offset += private->y; + + return gdk_window_get_bg_gc (private->parent, &tmp_paint); + } + else if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG) { - return_val = XTranslateCoordinates (private->xdisplay, - private->xwindow, - gdk_root_window, - 0, 0, &tx, &ty, - &child); + gc_values.fill = GDK_TILED; + gc_values.tile = private->bg_pixmap; + gc_values.ts_x_origin = - paint->x_offset; + gc_values.ts_y_origin = - paint->y_offset; - if (x) - *x = tx; - if (y) - *y = ty; + gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; } else - return_val = 0; - - return return_val; + { + gc_values.foreground = private->bg_color; + gc_mask = GDK_GC_FOREGROUND; + } + + return gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask); } -GdkWindow* -gdk_window_get_pointer (GdkWindow *window, - gint *x, - gint *y, - GdkModifierType *mask) +static void +gdk_window_paint_init_bg (GdkWindow *window, + GdkWindowPaint *paint, + GdkRegion *init_region) { - GdkWindowPrivate *private; - GdkWindow *return_val; - Window root; - Window child; - int rootx, rooty; - int winx, winy; - unsigned int xmask; + GdkGC *tmp_gc; + + tmp_gc = gdk_window_get_bg_gc (window, paint); + gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE, 0, 0, -1, -1); + gdk_gc_unref (tmp_gc); +} + +void +gdk_window_begin_paint_region (GdkWindow *window, + GdkRegion *region) +{ +#ifdef USE_BACKING_STORE + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + GdkRectangle clip_box; + GdkWindowPaint *paint; + GdkRegion *init_region; + GdkGC *tmp_gc; + + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); - if (!window) - window = (GdkWindow*) &gdk_root_parent; + paint = g_new (GdkWindowPaint, 1); - private = (GdkWindowPrivate*) window; + paint->region = gdk_region_copy (region); + + init_region = gdk_region_copy (region); + gdk_region_get_clipbox (paint->region, &clip_box); - return_val = NULL; - if (!private->destroyed && - XQueryPointer (private->xdisplay, private->xwindow, &root, &child, - &rootx, &rooty, &winx, &winy, &xmask)) + if (private->paint_stack) { - if (x) *x = winx; - if (y) *y = winy; - if (mask) *mask = xmask; - - if (child) - return_val = gdk_window_lookup (child); + gint old_width, old_height; + GdkWindowPaint *tmp_paint = private->paint_stack->data; + GdkRectangle old_rect, new_rect; + GSList *tmp_list; + + gdk_drawable_get_size (tmp_paint->pixmap, &old_width, &old_height); + old_rect.x = tmp_paint->x_offset; + old_rect.y = tmp_paint->y_offset; + old_rect.width = old_width; + old_rect.height = old_height; + + gdk_rectangle_union (&clip_box, &old_rect, &new_rect); + + if (new_rect.width > old_rect.width || new_rect.height > old_rect.height) + { + paint->pixmap = gdk_pixmap_new (window, new_rect.width, new_rect.height, -1); + tmp_gc = gdk_gc_new (paint->pixmap); + gdk_draw_drawable (paint->pixmap, tmp_gc, tmp_paint->pixmap, + 0, 0, old_rect.width, old_rect.height, + old_rect.x - new_rect.x, old_rect.y - new_rect.y); + gdk_gc_unref (tmp_gc); + gdk_drawable_unref (tmp_paint->pixmap); + + paint->x_offset = new_rect.x; + paint->y_offset = new_rect.y; + + tmp_list = private->paint_stack; + while (tmp_list) + { + tmp_paint = private->paint_stack->data; + gdk_region_subtract (init_region, tmp_paint->region); + + tmp_paint->pixmap = paint->pixmap; + tmp_paint->x_offset = paint->x_offset; + tmp_paint->y_offset = paint->x_offset; + + tmp_list = tmp_list->next; + } + } + else + { + paint->x_offset = tmp_paint->x_offset; + paint->y_offset = tmp_paint->y_offset; + paint->pixmap = tmp_paint->pixmap; + + tmp_list = private->paint_stack; + while (tmp_list) + { + tmp_paint = private->paint_stack->data; + gdk_region_subtract (init_region, tmp_paint->region); + + tmp_list = tmp_list->next; + } + } + } + else + { + paint->x_offset = clip_box.x; + paint->y_offset = clip_box.y; + paint->pixmap = gdk_pixmap_new (window, clip_box.width, clip_box.height, -1); } + + if (!gdk_region_empty (init_region)) + gdk_window_paint_init_bg (window, paint, init_region); + gdk_region_destroy (init_region); - return return_val; + private->paint_stack = g_slist_prepend (private->paint_stack, paint); +#endif /* USE_BACKING_STORE */ } -GdkWindow* -gdk_window_get_parent (GdkWindow *window) +void +gdk_window_end_paint (GdkWindow *window) { - g_return_val_if_fail (window != NULL, NULL); +#ifdef USE_BACKING_STORE + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + GdkWindowPaint *paint; + GdkGC *tmp_gc; + GdkRectangle clip_box; + gint x_offset, y_offset; - return ((GdkWindowPrivate*) window)->parent; -} + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (private->paint_stack != NULL); -GdkWindow* -gdk_window_get_toplevel (GdkWindow *window) -{ - GdkWindowPrivate *private; + paint = private->paint_stack->data; + private->paint_stack = g_slist_delete_link (private->paint_stack, private->paint_stack); - g_return_val_if_fail (window != NULL, NULL); + gdk_region_get_clipbox (paint->region, &clip_box); - private = (GdkWindowPrivate*) window; + tmp_gc = gdk_gc_new (window); - while (private->window_type == GDK_WINDOW_CHILD) + _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset); + + gdk_gc_set_clip_region (tmp_gc, paint->region); + gdk_gc_set_clip_origin (tmp_gc, -x_offset, -y_offset); + + _gdk_windowing_window_class.draw_drawable (window, tmp_gc, paint->pixmap, + clip_box.x - paint->x_offset, + clip_box.y - paint->y_offset, + clip_box.x - x_offset, clip_box.y - y_offset, + clip_box.width, clip_box.height); + gdk_gc_unref (tmp_gc); + + if (private->paint_stack) { - window = ((GdkWindowPrivate*) window)->parent; - private = (GdkWindowPrivate*) window; + GSList *tmp_list = private->paint_stack; + while (tmp_list) + { + GdkWindowPaint *tmp_paint = tmp_list->data; + gdk_region_subtract (tmp_paint->region, paint->region); + + tmp_list = tmp_list->next; + } } + else + gdk_drawable_unref (paint->pixmap); - return window; + gdk_region_destroy (paint->region); + g_free (paint); +#endif /* USE_BACKING_STORE */ } -GList* -gdk_window_get_children (GdkWindow *window) +static void +gdk_window_get_offsets (GdkWindow *window, + gint *x_offset, + gint *y_offset) { - GdkWindowPrivate *private; - GdkWindow *child; - GList *children; - Window root; - Window parent; - Window *xchildren; - unsigned int nchildren; - unsigned int i; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + *x_offset = paint->x_offset; + *y_offset = paint->y_offset; + } + else + _gdk_windowing_window_get_offsets (window, x_offset, y_offset); +} - g_return_val_if_fail (window != NULL, NULL); +#define OFFSET_GC(gc) \ + gint x_offset, y_offset; \ + gint old_clip_x = ((GdkGCPrivate *)gc)->clip_x_origin; \ + gint old_clip_y = ((GdkGCPrivate *)gc)->clip_y_origin; \ + gint old_ts_x = ((GdkGCPrivate *)gc)->ts_x_origin; \ + gint old_ts_y = ((GdkGCPrivate *)gc)->ts_y_origin; \ + gdk_window_get_offsets (drawable, &x_offset, &y_offset); \ + if (x_offset != 0 || y_offset != 0) \ + { \ + gdk_gc_set_clip_origin (gc, old_clip_x - x_offset, \ + old_clip_y - y_offset); \ + gdk_gc_set_ts_origin (gc, old_ts_x - x_offset, \ + old_ts_y - y_offset); \ + } + +#define RESTORE_GC(gc) \ + if (x_offset != 0 || y_offset != 0) \ + { \ + gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \ + gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \ + } - private = (GdkWindowPrivate*) window; - if (private->destroyed) - return NULL; +static void +gdk_window_draw_destroy (GdkDrawable *drawable) +{ + _gdk_windowing_window_class.destroy (drawable); +} + +static GdkGC * +gdk_window_draw_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask) +{ + return _gdk_windowing_window_class.create_gc (drawable, values, mask); +} + +static void +gdk_window_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + OFFSET_GC (gc); + + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_rectangle (paint->pixmap, gc, filled, + x - x_offset, y - y_offset, width, height); + } + else + _gdk_windowing_window_class.draw_rectangle (drawable, gc, filled, + x - x_offset, y - y_offset, width, height); + + RESTORE_GC (gc); +} + +static void +gdk_window_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + OFFSET_GC (gc); - XQueryTree (private->xdisplay, private->xwindow, - &root, &parent, &xchildren, &nchildren); + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_arc (paint->pixmap, gc, filled, + x - x_offset, y_offset, + width, height, angle1, angle2); + } + else + _gdk_windowing_window_class.draw_arc (drawable, gc, filled, + x - x_offset, y - y_offset, + width, height, angle1, angle2); + RESTORE_GC (gc); +} - children = NULL; +static void +gdk_window_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + GdkPoint *new_points; + + OFFSET_GC (gc); - if (nchildren > 0) + if (x_offset != 0 || y_offset != 0) { - for (i = 0; i < nchildren; i++) + int i; + + new_points = g_new (GdkPoint, npoints); + for (i=0; ipaint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints); - XFree (xchildren); } + else + _gdk_windowing_window_class.draw_polygon (drawable, gc, filled, new_points, npoints); + + if (new_points != points) + g_free (new_points); - return children; + RESTORE_GC (gc); } -GdkEventMask -gdk_window_get_events (GdkWindow *window) +static void +gdk_window_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) { - GdkWindowPrivate *private; - XWindowAttributes attrs; - GdkEventMask event_mask; - int i; + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + OFFSET_GC (gc); - g_return_val_if_fail (window != NULL, 0); + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_text (paint->pixmap, font, gc, + x - x_offset, y - y_offset, text, text_length); - private = (GdkWindowPrivate*) window; - if (private->destroyed) - return 0; + } + else + _gdk_windowing_window_class.draw_text (drawable, font, gc, + x - x_offset, y - y_offset, text, text_length); + + RESTORE_GC (gc); +} - XGetWindowAttributes (gdk_display, private->xwindow, - &attrs); +static void +gdk_window_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + OFFSET_GC (gc); - event_mask = 0; - for (i = 0; i < nevent_masks; i++) + if (private->paint_stack) { - if (attrs.your_event_mask & event_mask_table[i]) - event_mask |= 1 << (i + 1); + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_text_wc (paint->pixmap, font, gc, + x - x_offset, y - y_offset, text, text_length); } + else + _gdk_windowing_window_class.draw_text_wc (drawable, font, gc, + x - x_offset, y - y_offset, text, text_length); + + RESTORE_GC (gc); +} + +static void +gdk_window_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + OFFSET_GC (gc); - return event_mask; + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_drawable (paint->pixmap, gc, src, xsrc, ysrc, + xdest - x_offset, ydest - y_offset, width, height); + + } + else + _gdk_windowing_window_class.draw_drawable (drawable, gc, src, xsrc, ysrc, + xdest - x_offset, ydest - y_offset, + width, height); + RESTORE_GC (gc); } -void -gdk_window_set_events (GdkWindow *window, - GdkEventMask event_mask) +static void +gdk_window_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) { - GdkWindowPrivate *private; - long xevent_mask; - int i; + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + GdkPoint *new_points; + + OFFSET_GC (gc); - g_return_if_fail (window != NULL); + if (x_offset != 0 || y_offset != 0) + { + gint i; - private = (GdkWindowPrivate*) window; - if (private->destroyed) - return; + new_points = g_new (GdkPoint, npoints); + for (i=0; ipaint_stack) { - if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_points (paint->pixmap, gc, new_points, npoints); } - - XSelectInput (gdk_display, private->xwindow, - xevent_mask); + else + _gdk_windowing_window_class.draw_points (drawable, gc, points, npoints); + + if (new_points != points) + g_free (new_points); + + RESTORE_GC (gc); } -void -gdk_window_add_colormap_windows (GdkWindow *window) +static void +gdk_window_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) { - GdkWindow *toplevel; - GdkWindowPrivate *toplevel_private; - GdkWindowPrivate *window_private; - Window *old_windows; - Window *new_windows; - int i, count; - - g_return_if_fail (window != NULL); + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + GdkSegment *new_segs; - toplevel = gdk_window_get_toplevel (window); - toplevel_private = (GdkWindowPrivate*) toplevel; - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return; + OFFSET_GC (gc); - if (!XGetWMColormapWindows (toplevel_private->xdisplay, - toplevel_private->xwindow, - &old_windows, &count)) + if (x_offset != 0 || y_offset != 0) { - old_windows = NULL; - count = 0; - } + gint i; - for (i = 0; i < count; i++) - if (old_windows[i] == window_private->xwindow) - return; - - new_windows = g_new (Window, count + 1); + new_segs = g_new (GdkSegment, nsegs); + for (i=0; ixwindow; + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs); + } + else + _gdk_windowing_window_class.draw_segments (drawable, gc, new_segs, nsegs); - XSetWMColormapWindows (toplevel_private->xdisplay, - toplevel_private->xwindow, - new_windows, count + 1); + if (new_segs != segs) + g_free (new_segs); - g_free (new_windows); - if (old_windows) - XFree (old_windows); + RESTORE_GC (gc); } -/* - * This needs the X11 shape extension. - * If not available, simply remove the call to - * XShapeCombineMask. Shaped windows will look - * ugly, but programs still work. Stefan Wille - */ -void -gdk_window_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, gint y) +static void +gdk_window_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) { - GdkWindowPrivate *window_private; - Pixmap pixmap; - - g_return_if_fail (window != NULL); - - /* This is needed, according to raster */ - gdk_window_set_override_redirect(window, TRUE); + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + GdkPoint *new_points; - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return; + OFFSET_GC (gc); - if (mask) + if (x_offset != 0 || y_offset != 0) { - GdkWindowPrivate *pixmap_private; + gint i; - pixmap_private = (GdkWindowPrivate*) mask; - pixmap = (Pixmap) pixmap_private->xwindow; + new_points = g_new (GdkPoint, npoints); + for (i=0; ipaint_stack) { - x = 0; - y = 0; - pixmap = None; + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_lines (paint->pixmap, gc, new_points, npoints); } + else + _gdk_windowing_window_class.draw_lines (drawable, gc, new_points, npoints); + + if (new_points != points) + g_free (new_points); + + RESTORE_GC (gc); +} + +/* Fixme - this is just like gdk_window_paint_init_bg */ +static void +gdk_window_clear_backing_rect (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + GdkWindowPaint *paint = private->paint_stack->data; + GdkGC *tmp_gc; - XShapeCombineMask (window_private->xdisplay, - window_private->xwindow, - ShapeBounding, - x, y, - pixmap, - ShapeSet); + tmp_gc = gdk_window_get_bg_gc (window, paint); + gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE, + x - paint->x_offset, y - paint->y_offset, width, height); + gdk_gc_unref (tmp_gc); } void -gdk_dnd_drag_addwindow (GdkWindow *window) +gdk_window_clear_area (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) { - GdkWindowPrivate *window_private; - + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); - window_private = (GdkWindowPrivate *) window; - if (window_private->destroyed) - return; - - if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0) - { - gdk_dnd.drag_numwindows++; - gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows, - gdk_dnd.drag_numwindows - * sizeof(GdkWindow *)); - gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window; - window_private->dnd_drag_accepted = 0; - } + if (private->paint_stack) + gdk_window_clear_backing_rect (window, x, y, width, height); else - g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n"); + _gdk_windowing_window_clear_area (window, x, y, width, height); } void -gdk_window_dnd_drag_set (GdkWindow *window, - guint8 drag_enable, - gchar **typelist, - guint numtypes) +gdk_window_clear_area_e (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) { - GdkWindowPrivate *window_private; - int i, wasset = 0; - + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + g_return_if_fail (window != NULL); - window_private = (GdkWindowPrivate *) window; - if (window_private->destroyed) - return; - - window_private->dnd_drag_enabled = drag_enable ? 1 : 0; + g_return_if_fail (GDK_IS_WINDOW (window)); - if (drag_enable) - { - g_return_if_fail(typelist != NULL); - - if (window_private->dnd_drag_data_numtypesavail > 3) - wasset = 1; - window_private->dnd_drag_data_numtypesavail = numtypes; - - window_private->dnd_drag_data_typesavail = - g_realloc (window_private->dnd_drag_data_typesavail, - (numtypes + 1) * sizeof (GdkAtom)); - - for (i = 0; i < numtypes; i++) - { - /* Allow blanket use of ALL to get anything... */ - if (strcmp (typelist[i], "ALL")) - window_private->dnd_drag_data_typesavail[i] = - gdk_atom_intern (typelist[i], FALSE); - else - window_private->dnd_drag_data_typesavail[i] = None; - } - - /* - * set our extended type list if we need to - */ - if (numtypes > 3) - gdk_property_change(window, gdk_dnd.gdk_XdeTypelist, - XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE, - (guchar *)(window_private->dnd_drag_data_typesavail - + (sizeof(GdkAtom) * 3)), - (numtypes - 3) * sizeof(GdkAtom)); - else if (wasset) - gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist); - } - else - { - g_free (window_private->dnd_drag_data_typesavail); - window_private->dnd_drag_data_typesavail = NULL; - window_private->dnd_drag_data_numtypesavail = 0; - } + if (private->paint_stack) + gdk_window_clear_backing_rect (window, x, y, width, height); + + _gdk_windowing_window_clear_area_e (window, x, y, width, height); } void -gdk_window_dnd_drop_set (GdkWindow *window, - guint8 drop_enable, - gchar **typelist, - guint numtypes, - guint8 destructive_op) +_gdk_window_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) { - GdkWindowPrivate *window_private; - int i; - - g_return_if_fail (window != NULL); - window_private = (GdkWindowPrivate *) window; - if (window_private->destroyed) - return; + GdkImagePrivate *image_private = (GdkImagePrivate*) image; + GdkWindowPrivate *private = (GdkWindowPrivate *)drawable; + + OFFSET_GC (gc); - window_private->dnd_drop_enabled = drop_enable ? 1 : 0; - if (drop_enable) + if (private->paint_stack) { - g_return_if_fail(typelist != NULL); - - window_private->dnd_drop_data_numtypesavail = numtypes; - - window_private->dnd_drop_data_typesavail = - g_realloc (window_private->dnd_drop_data_typesavail, - (numtypes + 1) * sizeof (GdkAtom)); - - for (i = 0; i < numtypes; i++) - window_private->dnd_drop_data_typesavail[i] = - gdk_atom_intern (typelist[i], FALSE); - - window_private->dnd_drop_destructive_op = destructive_op; + GdkWindowPaint *paint = private->paint_stack->data; + image_private->klass->image_put (image, paint->pixmap, gc, xsrc, ysrc, + xdest - x_offset, ydest - y_offset, + width, height); + } + else + image_private->klass->image_put (image, drawable, gc, xsrc, ysrc, + xdest - x_offset, ydest - y_offset, + width, height); + + RESTORE_GC (gc); } -/* - * This is used to reply to a GDK_DRAG_REQUEST event - * (which may be generated by XdeRequest or a confirmed drop... +/* Code for dirty-region queueing */ -void -gdk_window_dnd_data_set (GdkWindow *window, - GdkEvent *event, - gpointer data, - gulong data_numbytes) + +static GSList *update_windows = NULL; +static guint update_idle = 0; + +#define GDK_PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 20) + +static void +gdk_window_process_updates_internal (GdkWindow *window) { - GdkWindowPrivate *window_private; - XEvent sev; - GdkEventDropDataAvailable tmp_ev; - gchar *tmp; - - g_return_if_fail (window != NULL); - g_return_if_fail (event != NULL); - g_return_if_fail (data != NULL); - g_return_if_fail (data_numbytes > 0); - g_return_if_fail (event->type == GDK_DRAG_REQUEST); - - window_private = (GdkWindowPrivate *) window; - g_return_if_fail (window_private->dnd_drag_accepted != 0); - if (window_private->destroyed) - return; - - /* We set the property on our window... */ - gdk_property_change (window, window_private->dnd_drag_data_type, - XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data, - data_numbytes); - tmp = gdk_atom_name(window_private->dnd_drag_data_type); -#ifdef DEBUG_DND - g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow); -#endif - g_free(tmp); - - /* - * Then we send the event to tell the receiving window that the - * drop has happened - */ - tmp_ev.u.allflags = 0; - tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION; - tmp_ev.u.flags.isdrop = event->dragrequest.isdrop; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + gboolean save_region = FALSE; - sev.xclient.type = ClientMessage; - sev.xclient.format = 32; - sev.xclient.window = event->dragrequest.requestor; - sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable; - sev.xclient.data.l[0] = window_private->xwindow; - sev.xclient.data.l[1] = tmp_ev.u.allflags; - sev.xclient.data.l[2] = window_private->dnd_drag_data_type; - - if (event->dragrequest.isdrop) - sev.xclient.data.l[3] = event->dragrequest.drop_coords.x + - (event->dragrequest.drop_coords.y << 16); - else - sev.xclient.data.l[3] = 0; - - sev.xclient.data.l[4] = event->dragrequest.timestamp; + if (gdk_event_func) + { + GdkEvent event; + GdkRectangle window_rect; - if (!gdk_send_xevent (event->dragrequest.requestor, False, - NoEventMask, &sev)) - GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n", - event->dragrequest.requestor)); + window_rect.x = 0; + window_rect.y = 0; + window_rect.width = private->drawable.width; + window_rect.height = private->drawable.height; + save_region = _gdk_windowing_window_queue_antiexpose (window, private->update_area); + + event.expose.type = GDK_EXPOSE; + event.expose.window = gdk_window_ref ((GdkWindow *)private); + event.expose.count = 0; + + gdk_region_get_clipbox (private->update_area, &event.expose.area); + if (gdk_rectangle_intersect (&event.expose.area, &window_rect, &event.expose.area)) + { + (*gdk_event_func) (&event, gdk_event_data); + } + } + + if (!save_region) + gdk_region_destroy (private->update_area); + private->update_area = NULL; } -void -gdk_window_add_filter (GdkWindow *window, - GdkFilterFunc function, - gpointer data) +void +gdk_window_process_all_updates (void) { - GdkWindowPrivate *private; - GList *tmp_list; - GdkEventFilter *filter; + GSList *old_update_windows = update_windows; + GSList *tmp_list = update_windows; - private = (GdkWindowPrivate*) window; - if (private && private->destroyed) - return; - - if(private) - tmp_list = private->filters; - else - tmp_list = gdk_default_filters; + if (update_idle) + g_source_remove (update_idle); + + update_windows = NULL; + update_idle = 0; while (tmp_list) { - filter = (GdkEventFilter *)tmp_list->data; - if ((filter->function == function) && (filter->data == data)) - return; + gdk_window_process_updates_internal (tmp_list->data); tmp_list = tmp_list->next; } - filter = g_new (GdkEventFilter, 1); - filter->function = function; - filter->data = data; + g_slist_free (old_update_windows); - if(private) - private->filters = g_list_append (private->filters, filter); - else - gdk_default_filters = g_list_append (gdk_default_filters, filter); + gdk_flush(); } -void -gdk_window_remove_filter (GdkWindow *window, - GdkFilterFunc function, - gpointer data) +static gboolean +gdk_window_update_idle (gpointer data) { - GdkWindowPrivate *private; - GList *tmp_list; - GdkEventFilter *filter; + gdk_window_process_all_updates (); + + return FALSE; +} - private = (GdkWindowPrivate*) window; +void +gdk_window_process_updates (GdkWindow *window, + gboolean update_children) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; - if(private) - tmp_list = private->filters; - else - tmp_list = gdk_default_filters; + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); - while (tmp_list) + if (private->update_area) { - filter = (GdkEventFilter *)tmp_list->data; - tmp_list = tmp_list->next; + gdk_window_process_updates_internal (window); + update_windows = g_slist_remove (update_windows, window); + } - if ((filter->function == function) && (filter->data == data)) + if (update_children) + { + GList *tmp_list = private->children; + while (tmp_list) { - if(private) - private->filters = g_list_remove_link (private->filters, tmp_list); - else - gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list); - g_list_free_1 (tmp_list); - g_free (filter); - - return; + gdk_window_process_updates (tmp_list->data, TRUE); + tmp_list = tmp_list->next; } } } void -gdk_window_set_override_redirect(GdkWindow *window, - gboolean override_redirect) -{ - GdkWindowPrivate *private; - XSetWindowAttributes attr; - - g_return_if_fail (window != NULL); - private = (GdkWindowPrivate*) window; - if (private->destroyed) - return; - - attr.override_redirect = (override_redirect == FALSE)?False:True; - XChangeWindowAttributes(gdk_display, - ((GdkWindowPrivate *)window)->xwindow, - CWOverrideRedirect, - &attr); -} - -void -gdk_window_set_icon (GdkWindow *window, - GdkWindow *icon_window, - GdkPixmap *pixmap, - GdkBitmap *mask) +gdk_window_invalidate_rect (GdkWindow *window, + GdkRectangle *rect, + gboolean invalidate_children) { - XWMHints wm_hints; - GdkWindowPrivate *window_private; - GdkWindowPrivate *private; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; g_return_if_fail (window != NULL); - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return; + g_return_if_fail (GDK_IS_WINDOW (window)); - wm_hints.flags = 0; - - if (icon_window != NULL) + if (private->update_area) { - private = (GdkWindowPrivate *)icon_window; - wm_hints.flags |= IconWindowHint; - wm_hints.icon_window = private->xwindow; + gdk_region_union_with_rect (private->update_area, rect); } - - if (pixmap != NULL) + else { - private = (GdkWindowPrivate *)pixmap; - wm_hints.flags |= IconPixmapHint; - wm_hints.icon_pixmap = private->xwindow; + update_windows = g_slist_prepend (update_windows, window); + private->update_area = gdk_region_rectangle (rect); + + if (!private->update_freeze_count && !update_idle) + update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, NULL, NULL); } - if (mask != NULL) + + if (invalidate_children) { - private = (GdkWindowPrivate *)mask; - wm_hints.flags |= IconMaskHint; - wm_hints.icon_mask = private->xwindow; - } + GList *tmp_list; + GdkRectangle child_rect, new_rect; + + tmp_list = private->children; + while (tmp_list) + { + GdkWindowPrivate *child = tmp_list->data; + tmp_list = tmp_list->next; - XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints); + /* FIXME: this is a HACK to figure out if the child is + * input-only. + */ + if (child->drawable.colormap) + { + child_rect.x = child->x; + child_rect.y = child->y; + child_rect.width = child->drawable.width; + child_rect.height = child->drawable.height; + + if (gdk_rectangle_intersect (rect, &child_rect, &new_rect)) + { + new_rect.x -= child_rect.x; + new_rect.y -= child_rect.y; + + gdk_window_invalidate_rect ((GdkWindow *)child, &new_rect, TRUE); + } + } + } + } } -void -gdk_window_set_icon_name (GdkWindow *window, - gchar * name) +void +gdk_window_invalidate_region (GdkWindow *window, + GdkRegion *region, + gboolean invalidate_children) { - GdkWindowPrivate *window_private; - XTextProperty property; - gint res; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; g_return_if_fail (window != NULL); - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (private->input_only) return; - res = XmbTextListToTextProperty (window_private->xdisplay, - &name, 1, XStdICCTextStyle, - &property); - if (res < 0) + + if (private->update_area) { - g_warning("Error converting icon name to text property: %d\n", res); - return; + gdk_region_union (private->update_area, region); } + else + { + update_windows = g_slist_prepend (update_windows, window); + private->update_area = gdk_region_copy (region); - XSetWMIconName (window_private->xdisplay, window_private->xwindow, - &property); - - XFree(property.value); -} - -void -gdk_window_set_group (GdkWindow *window, - GdkWindow *leader) -{ - XWMHints wm_hints; - GdkWindowPrivate *window_private; - GdkWindowPrivate *private; + if (!private->update_freeze_count && !update_idle) + update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, NULL, NULL); + } - g_return_if_fail (window != NULL); - g_return_if_fail (leader != NULL); - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return; + if (invalidate_children) + { + GList *tmp_list; + GdkRectangle child_rect; + GdkRegion *child_region; - private = (GdkWindowPrivate *)leader; - wm_hints.flags = WindowGroupHint; - wm_hints.window_group = private->xwindow; + tmp_list = private->children; + while (tmp_list) + { + GdkWindowPrivate *child = tmp_list->data; + tmp_list = tmp_list->next; - XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints); + if (child->input_only) + { + child_rect.x = child->x; + child_rect.y = child->y; + child_rect.width = child->drawable.width; + child_rect.height = child->drawable.height; + + child_region = gdk_region_rectangle (&child_rect); + gdk_region_intersect (child_region, region); + + if (!gdk_region_empty (child_region)) + { + gdk_region_offset (child_region, - child_rect.x, - child_rect.y); + gdk_window_invalidate_region ((GdkWindow *)child, child_region, TRUE); + } + + gdk_region_destroy (child_region); + } + } + } } -static void -gdk_window_set_mwm_hints (GdkWindow *window, - MotifWmHints *new_hints) +GdkRegion * +gdk_window_get_update_area (GdkWindow *window) { - static Atom hints_atom = None; - MotifWmHints *hints; - Atom type; - gint format; - gulong nitems; - gulong bytes_after; - - GdkWindowPrivate *window_private; - - g_return_if_fail (window != NULL); - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + GdkRegion *tmp_region; - if (!hints_atom) - hints_atom = XInternAtom (window_private->xdisplay, - _XA_MOTIF_WM_HINTS, FALSE); - - XGetWindowProperty (window_private->xdisplay, window_private->xwindow, - hints_atom, 0, sizeof(MotifWmHints)/4, - False, AnyPropertyType, &type, &format, &nitems, - &bytes_after, (guchar **)&hints); + g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); - if (type == None) - hints = new_hints; - else + if (private->update_area) { - if (new_hints->flags & MWM_HINTS_FUNCTIONS) - { - hints->flags |= MWM_HINTS_FUNCTIONS; - hints->functions = new_hints->functions; - } - if (new_hints->flags & MWM_HINTS_DECORATIONS) - { - hints->flags |= MWM_HINTS_DECORATIONS; - hints->decorations = new_hints->decorations; - } - } + tmp_region = private->update_area; + private->update_area = NULL; - XChangeProperty (window_private->xdisplay, window_private->xwindow, - hints_atom, hints_atom, 32, PropModeReplace, - (guchar *)hints, sizeof(MotifWmHints)/4); - - if (hints != new_hints) - XFree (hints); + update_windows = g_slist_remove (update_windows, window); + + return tmp_region; + } + else + return NULL; } void -gdk_window_set_decorations (GdkWindow *window, - GdkWMDecoration decorations) +gdk_window_freeze_updates (GdkWindow *window) { - MotifWmHints hints; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; - hints.flags = MWM_HINTS_DECORATIONS; - hints.decorations = decorations; + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); - gdk_window_set_mwm_hints (window, &hints); + private->update_freeze_count++; } void -gdk_window_set_functions (GdkWindow *window, - GdkWMFunction functions) +gdk_window_thaw_updates (GdkWindow *window) { - MotifWmHints hints; + GdkWindowPrivate *private = (GdkWindowPrivate *)window; - hints.flags = MWM_HINTS_FUNCTIONS; - hints.functions = functions; + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (private->update_freeze_count > 0); - gdk_window_set_mwm_hints (window, &hints); + private->update_freeze_count--; + if (!private->update_freeze_count && private->update_area && !update_idle) + update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, NULL, NULL); } +