summaryrefslogtreecommitdiff
path: root/gdk/x11/gdkevents-x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/x11/gdkevents-x11.c')
-rw-r--r--gdk/x11/gdkevents-x11.c296
1 files changed, 54 insertions, 242 deletions
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index e2056add0e..9f29453178 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -25,7 +25,8 @@
*/
#include "gdk.h"
-#include "gdkprivate.h"
+#include "gdkprivate-x11.h"
+#include "gdkinternals.h"
#include "gdkx.h"
#include "gdkkeysyms.h"
@@ -215,214 +216,6 @@ 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;
-};
-
-static Bool
-expose_predicate (Display *display,
- XEvent *xevent,
- XPointer arg)
-{
- GdkExposeInfo *info = (GdkExposeInfo*) arg;
-
- /* Compressing across GravityNotify events is safe, because
- * we completely ignore them, so they can't change what
- * we are going to draw. Compressing across GravityNotify
- * events is necessay because during window-unshading animation
- * we'll get a whole bunch of them interspersed with
- * expose events.
- */
- if (xevent->xany.type != Expose &&
- xevent->xany.type != GravityNotify)
- {
- info->seen_nonmatching = TRUE;
- }
-
- if (info->seen_nonmatching ||
- xevent->xany.type != Expose ||
- 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;
-
- event.any.type = GDK_EXPOSE;
- event.any.window = None;
- event.any.send_event = FALSE;
-
- 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);
-
- event.any.window = window;
-
- /* 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;
-}
-
static gint
gdk_event_apply_filters (XEvent *xevent,
GdkEvent *event,
@@ -477,6 +270,7 @@ gdk_event_translate (GdkEvent *event,
char buf[16];
#endif
gint return_val;
+ gint xoffset, yoffset;
return_val = FALSE;
@@ -571,6 +365,16 @@ gdk_event_translate (GdkEvent *event,
return_val = TRUE;
+ if (window)
+ {
+ _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
+ }
+ else
+ {
+ xoffset = 0;
+ yoffset = 0;
+ }
+
switch (xevent->type)
{
case KeyPress:
@@ -709,8 +513,8 @@ gdk_event_translate (GdkEvent *event,
GDK_SCROLL_UP : GDK_SCROLL_DOWN;
event->scroll.window = window;
event->scroll.time = xevent->xbutton.x;
- event->scroll.x = xevent->xbutton.x;
- event->scroll.y = xevent->xbutton.y;
+ event->scroll.x = xevent->xbutton.x + xoffset;
+ event->scroll.y = xevent->xbutton.y + yoffset;
event->scroll.x_root = (gfloat)xevent->xbutton.x_root;
event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
event->scroll.pressure = 0.5;
@@ -725,8 +529,8 @@ gdk_event_translate (GdkEvent *event,
event->button.type = GDK_BUTTON_PRESS;
event->button.window = window;
event->button.time = xevent->xbutton.time;
- event->button.x = xevent->xbutton.x;
- event->button.y = xevent->xbutton.y;
+ event->button.x = xevent->xbutton.x + xoffset;
+ event->button.y = xevent->xbutton.y + yoffset;
event->button.x_root = (gfloat)xevent->xbutton.x_root;
event->button.y_root = (gfloat)xevent->xbutton.y_root;
event->button.pressure = 0.5;
@@ -769,8 +573,8 @@ gdk_event_translate (GdkEvent *event,
event->button.type = GDK_BUTTON_RELEASE;
event->button.window = window;
event->button.time = xevent->xbutton.time;
- event->button.x = xevent->xbutton.x;
- event->button.y = xevent->xbutton.y;
+ event->button.x = xevent->xbutton.x + xoffset;
+ event->button.y = xevent->xbutton.y + yoffset;
event->button.x_root = (gfloat)xevent->xbutton.x_root;
event->button.y_root = (gfloat)xevent->xbutton.y_root;
event->button.pressure = 0.5;
@@ -803,8 +607,8 @@ gdk_event_translate (GdkEvent *event,
event->motion.type = GDK_MOTION_NOTIFY;
event->motion.window = window;
event->motion.time = xevent->xmotion.time;
- event->motion.x = xevent->xmotion.x;
- event->motion.y = xevent->xmotion.y;
+ event->motion.x = xevent->xmotion.x + xoffset;
+ event->motion.y = xevent->xmotion.y + yoffset;
event->motion.x_root = (gfloat)xevent->xmotion.x_root;
event->motion.y_root = (gfloat)xevent->xmotion.y_root;
event->motion.pressure = 0.5;
@@ -845,8 +649,8 @@ gdk_event_translate (GdkEvent *event,
event->crossing.subwindow = NULL;
event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = xevent->xcrossing.x;
- event->crossing.y = xevent->xcrossing.y;
+ event->crossing.x = xevent->xcrossing.x + xoffset;
+ event->crossing.y = xevent->xcrossing.y + yoffset;
event->crossing.x_root = xevent->xcrossing.x_root;
event->crossing.y_root = xevent->xcrossing.y_root;
@@ -914,8 +718,8 @@ gdk_event_translate (GdkEvent *event,
event->crossing.subwindow = NULL;
event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = xevent->xcrossing.x;
- event->crossing.y = xevent->xcrossing.y;
+ event->crossing.x = xevent->xcrossing.x + xoffset;
+ event->crossing.y = xevent->xcrossing.y + yoffset;
event->crossing.x_root = xevent->xcrossing.x_root;
event->crossing.y_root = xevent->xcrossing.y_root;
@@ -1016,33 +820,41 @@ gdk_event_translate (GdkEvent *event,
xevent->xexpose.x, xevent->xexpose.y,
xevent->xexpose.width, xevent->xexpose.height,
event->any.send_event ? " (send)" : ""));
- gdk_compress_exposures (xevent, window);
-
- event->expose.type = GDK_EXPOSE;
- event->expose.window = window;
- event->expose.area.x = xevent->xexpose.x;
- event->expose.area.y = xevent->xexpose.y;
- event->expose.area.width = xevent->xexpose.width;
- event->expose.area.height = xevent->xexpose.height;
- event->expose.count = xevent->xexpose.count;
-
+ {
+ GdkRectangle expose_rect;
+
+ expose_rect.x = xevent->xexpose.x + xoffset;
+ expose_rect.y = xevent->xexpose.y + yoffset;
+ expose_rect.width = xevent->xexpose.width;
+ expose_rect.height = xevent->xexpose.height;
+
+ _gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
+
+ return_val = FALSE;
+ }
+
break;
case GraphicsExpose:
/* Print debugging info.
*/
- GDK_NOTE (EVENTS,
- g_message ("graphics expose:\tdrawable: %ld",
- xevent->xgraphicsexpose.drawable));
-
- event->expose.type = GDK_EXPOSE;
- event->expose.window = window;
- event->expose.area.x = xevent->xgraphicsexpose.x;
- event->expose.area.y = xevent->xgraphicsexpose.y;
- event->expose.area.width = xevent->xgraphicsexpose.width;
- event->expose.area.height = xevent->xgraphicsexpose.height;
- event->expose.count = xevent->xexpose.count;
+ {
+ GdkRectangle expose_rect;
+
+ GDK_NOTE (EVENTS,
+ g_message ("graphics expose:\tdrawable: %ld",
+ xevent->xgraphicsexpose.drawable));
+
+ expose_rect.x = xevent->xgraphicsexpose.x + xoffset;
+ expose_rect.y = xevent->xgraphicsexpose.y + yoffset;
+ expose_rect.width = xevent->xgraphicsexpose.width;
+ expose_rect.height = xevent->xgraphicsexpose.height;
+
+ _gdk_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
+
+ return_val = FALSE;
+ }
break;
case NoExpose: