Example #1
0
/**
 * uni_image_view_fast_scroll:
 *
 * Actually scroll the views window using gdk_draw_drawable().
 * GTK_WIDGET (view)->window is guaranteed to be non-NULL in this
 * function.
 **/
static void
uni_image_view_fast_scroll (UniImageView * view, int delta_x, int delta_y)
{
    GdkDrawable *drawable = GTK_WIDGET (view)->window;

    int src_x, src_y;
    int dest_x, dest_y;
    if (delta_x < 0)
    {
        src_x = 0;
        dest_x = -delta_x;
    }
    else
    {
        src_x = delta_x;
        dest_x = 0;
    }
    if (delta_y < 0)
    {
        src_y = 0;
        dest_y = -delta_y;
    }
    else
    {
        src_y = delta_y;
        dest_y = 0;
    }

    /* First move the part of the image that did not become hidden or
       shown by this operation. gdk_draw_drawable is probably very
       fast because it does not involve sending any data to the X11
       server.

       Remember that X11 is weird shit. It does not remember how
       windows beneath other windows look like. So if another window
       overlaps this window, it will temporarily look corrupted. We
       fix that later by turning on "exposures." See below. */

    GdkGC *gc = gdk_gc_new (drawable);
    Size alloc = uni_image_view_get_allocated_size (view);

    gdk_gc_set_exposures (gc, TRUE);
    gdk_draw_drawable (drawable,
                       gc,
                       drawable,
                       src_x, src_y,
                       dest_x, dest_y,
                       alloc.width - abs (delta_x),
                       alloc.height - abs (delta_y));
    g_object_unref (gc);

    /* If we moved in both the x and y directions, two "strips" of the
       image becomes visible. One horizontal strip and one vertical
       strip. */
    GdkRectangle horiz_strip = {
        0,
        (delta_y < 0) ? 0 : alloc.height - abs (delta_y),
        alloc.width,
        abs (delta_y)
    };
    uni_image_view_repaint_area (view, &horiz_strip);

    GdkRectangle vert_strip = {
        (delta_x < 0) ? 0 : alloc.width - abs (delta_x),
        0,
        abs (delta_x),
        alloc.height
    };
    uni_image_view_repaint_area (view, &vert_strip);

    /* Here is where we fix the weirdness mentioned above. I do not
     * really know why it works, but it does! */
    GdkEvent *ev;
    while ((ev = gdk_event_get_graphics_expose (drawable)) != NULL)
    {
        GdkEventExpose *expose = (GdkEventExpose *) ev;
        int exp_count = expose->count;
        uni_image_view_repaint_area (view, &expose->area);
        gdk_event_free (ev);
        if (exp_count == 0)
            break;
    }
}
Example #2
0
static VALUE
gdkevent_s_get_graphics_expose(G_GNUC_UNUSED VALUE self, VALUE window)
{
    return make_gdkevent(gdk_event_get_graphics_expose(GDK_WINDOW(RVAL2GOBJ(window))));
}