summaryrefslogtreecommitdiff
path: root/gdk/gdk.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@src.gnome.org>1998-11-06 22:05:02 +0000
committerOwen Taylor <otaylor@src.gnome.org>1998-11-06 22:05:02 +0000
commite2a521922085c8010028e227f61bba59ea6b8242 (patch)
tree2500d6aa6f63aab4b58c17546532ecce8fdcca37 /gdk/gdk.c
parent3c0df19a588bd96f328bda975db8eb9fa7f79e81 (diff)
downloadgtk+-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.c283
1 files changed, 211 insertions, 72 deletions
diff --git a/gdk/gdk.c b/gdk/gdk.c
index 449ad4add8..217724417c 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -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;
}