diff options
author | Owen Taylor <otaylor@src.gnome.org> | 1998-11-06 22:05:02 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 1998-11-06 22:05:02 +0000 |
commit | e2a521922085c8010028e227f61bba59ea6b8242 (patch) | |
tree | 2500d6aa6f63aab4b58c17546532ecce8fdcca37 /gdk/gdk.c | |
parent | 3c0df19a588bd96f328bda975db8eb9fa7f79e81 (diff) | |
download | gtk+-e2a521922085c8010028e227f61bba59ea6b8242.tar.gz |
Merge from themes-2. See the ChangeLog for a somewhat detailed
history of the evolution of the changes involved. Most of this
is actually minor painting tweaks.
Diffstat (limited to 'gdk/gdk.c')
-rw-r--r-- | gdk/gdk.c | 283 |
1 files changed, 211 insertions, 72 deletions
@@ -116,10 +116,6 @@ static Bool gdk_event_get_type (Display *display, static void gdk_synthesize_click (GdkEvent *event, gint nclicks); -#ifdef DEBUG_DND -static void gdk_print_atom (GdkAtom anatom); -#endif - #ifndef HAVE_XCONVERTCASE static void gdkx_XConvertCase (KeySym symbol, KeySym *lower, @@ -156,12 +152,12 @@ static gint gdk_im_open (XrmDatabase db, static void gdk_im_close (void); static void gdk_ic_cleanup (void); +#endif /* USE_XIM */ + GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev, GdkEvent *event, gpointer data); -#endif /* USE_XIM */ - /* Private variable declarations */ static int gdk_initialized = 0; /* 1 if the library is initialized, @@ -743,6 +739,194 @@ gdk_event_get_graphics_expose (GdkWindow *window) return NULL; } +/************************ + * Exposure compression * + ************************/ + +/* + * The following implements simple exposure compression. It is + * modelled after the way Xt does exposure compression - in + * particular compress_expose = XtExposeCompressMultiple. + * It compress consecutive sequences of exposure events, + * but not sequences that cross other events. (This is because + * if it crosses a ConfigureNotify, we could screw up and + * mistakenly compress the exposures generated for the new + * size - could we just check for ConfigureNotify?) + * + * Xt compresses to a region / bounding rectangle, we compress + * to two rectangles, and try find the two rectangles of minimal + * area for this - this is supposed to handle the typical + * L-shaped regions generated by OpaqueMove. + */ + +/* Given three rectangles, find the two rectangles that cover + * them with the smallest area. + */ +static void +gdk_add_rect_to_rects (GdkRectangle *rect1, + GdkRectangle *rect2, + GdkRectangle *new_rect) +{ + GdkRectangle t1, t2, t3; + gint size1, size2, size3; + + gdk_rectangle_union (rect1, rect2, &t1); + gdk_rectangle_union (rect1, new_rect, &t2); + gdk_rectangle_union (rect2, new_rect, &t3); + + size1 = t1.width * t1.height + new_rect->width * new_rect->height; + size2 = t2.width * t2.height + rect2->width * rect2->height; + size3 = t1.width * t1.height + rect1->width * rect1->height; + + if (size1 < size2) + { + if (size1 < size3) + { + *rect1 = t1; + *rect2 = *new_rect; + } + else + *rect2 = t3; + } + else + { + if (size2 < size3) + *rect1 = t2; + else + *rect2 = t3; + } +} + +typedef struct _GdkExposeInfo GdkExposeInfo; + +struct _GdkExposeInfo { + Window window; + gboolean seen_nonmatching; +}; + +Bool +expose_predicate (Display *display, XEvent *xevent, XPointer arg) +{ + GdkExposeInfo *info = (GdkExposeInfo *)arg; + + if (xevent->xany.type != Expose) + { + info->seen_nonmatching = TRUE; + } + + if (info->seen_nonmatching || (xevent->xany.window != info->window)) + return FALSE; + else + return TRUE; +} + +void +gdk_compress_exposures (XEvent *xevent, GdkWindow *window) +{ + gint nrects = 1; + gint count = 0; + GdkRectangle rect1; + GdkRectangle rect2; + GdkRectangle tmp_rect; + XEvent tmp_event; + GdkFilterReturn result; + GdkExposeInfo info; + GdkEvent event; + + info.window = xevent->xany.window; + info.seen_nonmatching = FALSE; + + rect1.x = xevent->xexpose.x; + rect1.y = xevent->xexpose.y; + rect1.width = xevent->xexpose.width; + rect1.height = xevent->xexpose.height; + + while (1) + { + if (count == 0) + { + if (!XCheckIfEvent (gdk_display, + &tmp_event, + expose_predicate, + (XPointer)&info)) + break; + } + else + XIfEvent (gdk_display, + &tmp_event, + expose_predicate, + (XPointer)&info); + + /* We apply filters here, and if it was filtered, completely + * ignore the return + */ + result = gdk_event_apply_filters (xevent, &event, + window ? + ((GdkWindowPrivate *)window)->filters + : gdk_default_filters); + + if (result != GDK_FILTER_CONTINUE) + { + if (result == GDK_FILTER_TRANSLATE) + gdk_event_put (&event); + continue; + } + + if (nrects == 1) + { + rect2.x = tmp_event.xexpose.x; + rect2.y = tmp_event.xexpose.y; + rect2.width = tmp_event.xexpose.width; + rect2.height = tmp_event.xexpose.height; + + nrects++; + } + else + { + tmp_rect.x = tmp_event.xexpose.x; + tmp_rect.y = tmp_event.xexpose.y; + tmp_rect.width = tmp_event.xexpose.width; + tmp_rect.height = tmp_event.xexpose.height; + + gdk_add_rect_to_rects (&rect1, &rect2, &tmp_rect); + } + + count = tmp_event.xexpose.count; + } + + if (nrects == 2) + { + gdk_rectangle_union (&rect1, &rect2, &tmp_rect); + + if ((tmp_rect.width * tmp_rect.height) < + 2 * (rect1.height * rect1.width + + rect2.height * rect2.width)) + { + rect1 = tmp_rect; + nrects = 1; + } + } + + if (nrects == 2) + { + event.expose.type = GDK_EXPOSE; + event.expose.window = window; + event.expose.area.x = rect2.x; + event.expose.area.y = rect2.y; + event.expose.area.width = rect2.width; + event.expose.area.height = rect2.height; + event.expose.count = 0; + + gdk_event_put (&event); + } + + xevent->xexpose.count = nrects - 1; + xevent->xexpose.x = rect1.x; + xevent->xexpose.y = rect1.y; + xevent->xexpose.width = rect1.width; + xevent->xexpose.height = rect1.height; +} + /* *-------------------------------------------------------------- * gdk_event_get @@ -834,6 +1018,7 @@ gdk_event_get (void) #else XNextEvent (gdk_display, &xevent); #endif + event = gdk_event_new (); event->any.type = GDK_NOTHING; @@ -2005,6 +2190,13 @@ gdk_event_translate (GdkEvent *event, case KeyRelease: /* Lookup the string corresponding to the given keysym. */ +#ifdef USE_XIM + if (buf_len == 0) + { + buf_len = 128; + buf = g_new (gchar, buf_len); + } +#endif keysym = GDK_VoidSymbol; charcount = XLookupString (&xevent->xkey, buf, 16, &keysym, &compose); @@ -2031,8 +2223,7 @@ gdk_event_translate (GdkEvent *event, /* Print debugging info. */ GDK_NOTE (EVENTS, - g_message ("button press[%d]:\t\twindow: %ld x,y: %d %d button: %d", - window_private?window_private->dnd_drag_enabled:0, + g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window - base_id, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); @@ -2102,8 +2293,7 @@ gdk_event_translate (GdkEvent *event, /* Print debugging info. */ GDK_NOTE (EVENTS, - g_message ("button release[%d]:\twindow: %ld x,y: %d %d button: %d", - window_private?window_private->dnd_drag_enabled:0, + g_message ("button release:\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window - base_id, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); @@ -2178,6 +2368,7 @@ gdk_event_translate (GdkEvent *event, /* Tell XInput stuff about it if appropriate */ if (window_private && + !window_private->destroyed && (window_private->extension_events != 0) && gdk_input_vtable.enter_event) gdk_input_vtable.enter_event (&xevent->xcrossing, window); @@ -2357,6 +2548,7 @@ gdk_event_translate (GdkEvent *event, xevent->xexpose.window - base_id, xevent->xexpose.count, xevent->xexpose.x, xevent->xexpose.y, xevent->xexpose.width, xevent->xexpose.height)); + gdk_compress_exposures (xevent, window); event->expose.type = GDK_EXPOSE; event->expose.window = window; @@ -2539,10 +2731,11 @@ gdk_event_translate (GdkEvent *event, xevent->xconfigure.above - base_id, xevent->xconfigure.override_redirect)); - if ((window_private->extension_events != 0) && + if (!window_private->destroyed && + (window_private->extension_events != 0) && gdk_input_vtable.configure_event) gdk_input_vtable.configure_event (&xevent->xconfigure, window); - + if (window_private->window_type == GDK_WINDOW_CHILD) return_val = FALSE; else @@ -2714,6 +2907,7 @@ gdk_event_translate (GdkEvent *event, /* something else - (e.g., a Xinput event) */ if (window_private && + !window_private->destroyed && (window_private->extension_events != 0) && gdk_input_vtable.other_event) return_val = gdk_input_vtable.other_event(event, xevent, window); @@ -3638,61 +3832,6 @@ _g_mbtowc (wchar_t *wstr, const char *str, size_t len) #endif /* X_LOCALE */ -/* - * used for debugging only - */ -#ifdef DEBUG_DND -static void -gdk_print_atom (GdkAtom anatom) -{ - gchar *tmpstr = NULL; - tmpstr = (anatom!=None)?gdk_atom_name(anatom):"(none)"; - g_message("Atom %lu has name %s", anatom, tmpstr); - if(tmpstr) - g_free(tmpstr); -} -#endif - -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * -gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y) -{ - GdkWindow *retval = w; - GdkWindowPrivate *awin; - GList *children; - gint16 myx = *x, myy = *y; - - g_return_val_if_fail (w != NULL && x != NULL && y != NULL, NULL); - - myx = *x; - myy = *y; - - descend: - for (children = gdk_window_get_children(retval); - children && children->next; - children = children->next) - { - awin = (GdkWindowPrivate *) children->data; - if ((myx >= awin->x) && (myy >= awin->y) - && (myx < (awin->x + awin->width)) - && (myy < (awin->y + awin->height))) - { - retval = (GdkWindow *) awin; - myx -= awin->x; - myy -= awin->y; - goto descend; - } - } - - *x = myx; - *y = myy; - - return retval; -} -#endif - /* Sends a ClientMessage to all toplevel client windows */ gboolean gdk_event_send_client_message (GdkEvent *event, guint32 xid) @@ -3716,7 +3855,7 @@ gdk_event_send_client_message (GdkEvent *event, guint32 xid) gboolean gdk_event_send_client_message_to_all_recurse (XEvent *xev, guint32 xid, - gboolean send_anyways) + guint level) { static GdkAtom wm_state_atom = GDK_NONE; @@ -3729,7 +3868,7 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev, unsigned int ret_nchildren; int i; - gboolean send = TRUE; + gboolean send = FALSE; gboolean found = FALSE; if (!wm_state_atom) @@ -3761,13 +3900,13 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev, return FALSE; for(i = 0; i < ret_nchildren; i++) - if (gdk_event_send_client_message_to_all_recurse(xev, ret_children[i], FALSE)) + if (gdk_event_send_client_message_to_all_recurse(xev, ret_children[i], level + 1)) found = TRUE; XFree(ret_children); } - if (send || (!found && send_anyways)) + if (send || (!found && (level == 1))) { xev->xclient.window = xid; gdk_send_xevent (xid, False, NoEventMask, xev); @@ -3791,7 +3930,7 @@ gdk_event_send_clientmessage_toall (GdkEvent *event) memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); sev.xclient.message_type = event->client.message_type; - gdk_event_send_client_message_to_all_recurse(&sev, gdk_root_window, TRUE); + gdk_event_send_client_message_to_all_recurse(&sev, gdk_root_window, 0); gdk_error_warnings = old_warnings; } |