diff options
Diffstat (limited to 'gdk/x11/gdkevents-x11.c')
-rw-r--r-- | gdk/x11/gdkevents-x11.c | 296 |
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: |