diff options
Diffstat (limited to 'magnifier/zoom-region.c')
-rw-r--r-- | magnifier/zoom-region.c | 3565 |
1 files changed, 0 insertions, 3565 deletions
diff --git a/magnifier/zoom-region.c b/magnifier/zoom-region.c deleted file mode 100644 index 4e096d5..0000000 --- a/magnifier/zoom-region.c +++ /dev/null @@ -1,3565 +0,0 @@ -/* - * AT-SPI - Assistive Technology Service Provider Interface - * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) - * - * Copyright 2001 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> -#include <popt.h> -#ifdef HAVE_COLORBLIND -#include <colorblind.h> -#endif /* HAVE_COLORBLIND */ -#include <gdk/gdkwindow.h> -#include <gtk/gtk.h> -#ifdef USE_GDKPIXBUF_RENDER_TO_DRAWABLE -#include <gdk/gdkpixbuf.h> -#else -#include <gdk/gdk.h> -#endif -#include <gdk/gdkx.h> -#include <gdk/gdkrgb.h> -#include <libbonobo.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/cursorfont.h> -#include <X11/extensions/XTest.h> -#include <math.h> - -#undef ZOOM_REGION_DEBUG - -#include "zoom-region.h" -#include "zoom-region-private.h" -#include "magnifier.h" /* needed to access parent data */ -#include "magnifier-private.h" /* needed to access parent data */ - -#define DEBUG_CLIENT_CALLS - -#ifdef DEBUG_CLIENT_CALLS -static gboolean client_debug = FALSE; -#define DBG(a) if (client_debug) { (a); } -#else -#define DBG(a) -#endif - -static GObjectClass *parent_class = NULL; - -enum { - ZOOM_REGION_MANAGED_PROP, - ZOOM_REGION_POLL_MOUSE_PROP, - ZOOM_REGION_SMOOTHSCROLL_PROP, - ZOOM_REGION_COLORBLIND_PROP, - ZOOM_REGION_INVERT_PROP, - ZOOM_REGION_SMOOTHING_PROP, - ZOOM_REGION_CONTRASTR_PROP, - ZOOM_REGION_CONTRASTG_PROP, - ZOOM_REGION_CONTRASTB_PROP, - ZOOM_REGION_BRIGHTR_PROP, - ZOOM_REGION_BRIGHTG_PROP, - ZOOM_REGION_BRIGHTB_PROP, - ZOOM_REGION_XSCALE_PROP, - ZOOM_REGION_YSCALE_PROP, - ZOOM_REGION_BORDERSIZE_PROP, - ZOOM_REGION_BORDERCOLOR_PROP, - ZOOM_REGION_XALIGN_PROP, - ZOOM_REGION_YALIGN_PROP, - ZOOM_REGION_VIEWPORT_PROP, - ZOOM_REGION_TESTPATTERN_PROP, - ZOOM_REGION_TIMING_TEST_PROP, - ZOOM_REGION_TIMING_OUTPUT_PROP, - ZOOM_REGION_TIMING_PAN_RATE_PROP, - ZOOM_REGION_EXIT_MAGNIFIER -} PropIdx; - -#ifdef DEBUG_CLIENT_CALLS -gchar* prop_names[ZOOM_REGION_EXIT_MAGNIFIER + 1] = -{ - "MANAGED", - "POLLMOUSE" - "SMOOTHSCROLL", - "INVERT", - "SMOOTHING", - "CONTRASTR", - "CONTRASTG", - "CONTRASTB", - "XSCALE", - "YSCALE", - "BORDERSIZE", - "BORDERCOLOR", - "XALIGN", - "YALIGN", - "VIEWPORT", - "TESTPATTERN", - "TIMING_TEST", - "TIMING_OUTPUT", - "TIMING_PAN_RATE", - "EXIT_MAGNIFIER" -}; -#endif - -typedef enum { - ZOOM_REGION_ERROR_NONE, - ZOOM_REGION_ERROR_NO_TARGET_DRAWABLE, - ZOOM_REGION_ERROR_TOO_BIG -} ZoomRegionPixmapCreationError; - -static float timing_scale_max = 0; -static float timing_idle_max = 0; -static float timing_frame_max = 0; -static float cps_max = 0; -static float nrr_max = 0; -static float update_nrr_max = 0; -static gboolean reset_timing = FALSE; -static gboolean timing_test = FALSE; - -static guint pending_idle_handler = 0; -static gboolean processing_updates = FALSE; -static gboolean timing_start = FALSE; - -#ifdef TEST_XTST_CURSOR -static Cursor *x_cursors; -static Window cursor_window = None; -#endif - -static gboolean can_coalesce = TRUE ; /* change this when event coalescing is working */ - -#define CLAMP_B_C(v) (t = (v), CLAMP (t, -1, 1)); - -static void zoom_region_sync (ZoomRegion *region); -static void zoom_region_finalize (GObject *object); -static void zoom_region_update (ZoomRegion *zoom_region, - const GdkRectangle rect); -static void zoom_region_queue_update (ZoomRegion *zoom_region, - const GdkRectangle rect); - -static int zoom_region_process_updates (gpointer data); -static void zoom_region_paint (ZoomRegion *zoom_region, GdkRectangle *rect); -static void zoom_region_paint_pixmap (ZoomRegion *zoom_region, GdkRectangle *rect); -static int zoom_region_update_pointer_timeout (gpointer data); -static GdkRectangle zoom_region_rect_from_bounds (ZoomRegion *zoom_region, - const GNOME_Magnifier_RectBounds *bounds); -static ZoomRegionPixmapCreationError zoom_region_create_pixmap (ZoomRegion *zoom_region); -static GdkRectangle zoom_region_update_pixmap (ZoomRegion *zoom_region, const GdkRectangle update_rect, GdkRectangle *paint_rect); - -void -reset_timing_stats() -{ - timing_scale_max = 0; - timing_idle_max = 0; - timing_frame_max = 0; - cps_max = 0; - nrr_max = 0; - update_nrr_max = 0; - mag_timing.num_scale_samples = 0; - mag_timing.num_idle_samples = 0; - mag_timing.num_frame_samples = 0; - mag_timing.num_line_samples = 0; - mag_timing.scale_total = 0; - mag_timing.idle_total = 0; - mag_timing.frame_total = 0; - mag_timing.update_pixels_total = 0; - mag_timing.update_pixels_total = 0; - mag_timing.dx_total = 0; - mag_timing.dy_total = 0; - mag_timing.last_frame_val = 0; - mag_timing.last_dy = 0; - g_timer_start (mag_timing.process); -} - -/** DEBUG STUFF **/ - -#undef DEBUG -#ifdef DEBUG -#define DEBUG_RECT(a, b) _debug_announce_rect (a, b) -#else -#define DEBUG_RECT(a, b) -#endif -static void -_debug_announce_rect (char *msg, GdkRectangle rect) -{ - fprintf (stderr, "%s: (%d,%d - %d,%d)\n", - msg, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); -} - -static gboolean -_diff_pixbufs (const GdkPixbuf *a, const GdkPixbuf *b) -{ - long i, j; - int bits_per_byte = 8; /* always true? */ - guchar *pa = gdk_pixbuf_get_pixels (a); - guchar *pb = gdk_pixbuf_get_pixels (b); - guchar *cpa, *cpb; - long rsa = gdk_pixbuf_get_rowstride (a); - long rsb = gdk_pixbuf_get_rowstride (b); - long rowbytes = gdk_pixbuf_get_width (a) * - gdk_pixbuf_get_bits_per_sample (a) * - gdk_pixbuf_get_n_channels (a)/ bits_per_byte; - long n_rows = gdk_pixbuf_get_height (a); - - if (gdk_pixbuf_get_height (b) != n_rows) - return TRUE; - if (gdk_pixbuf_get_width (b) != gdk_pixbuf_get_width (a)) - return TRUE; - for (j = 0; j < n_rows; ++j) - { - cpa = pa + j * rsa; - cpb = pb + j * rsb; - for (i = 0; i < rowbytes; ++i) - { - if (*cpa != *cpb) - { - return TRUE; - } - cpa++; - cpb++; - } - } - return FALSE; -} - -/** EVENT COALESCING **/ - -#ifdef BROKEN_COALESCE_STUFF_GETS_FIXED -/** - * _combine_rects: - * combines two GdkRectangles IFF the union of the two form - * a rectangle. - * a: the first GdkRectangle, which will be changed to the new bounds if - * coalesce operation can be performed, otherwise unchanged. - * b: the second GdkRectangle. - * returns: True if the two are coalesced, FALSE otherwise. - **/ -static gboolean -_combine_rects (GdkRectangle *a, GdkRectangle *b) -{ - gboolean can_combine = FALSE; - if ((a->x == b->x) && (a->x + a->width == b->x + b->width)) - { - can_combine = TRUE; - } - else if ((a->y == b->y) && (a->y + a->height == b->y + b->height)) - { - can_combine = TRUE; - } - if (can_combine) - { - GdkRectangle c; - /* TODO: check and fix this */ - if (gdk_rectangle_intersect (a, b, &c)) - { - gdk_rectangle_union (a, b, &c); - *a = c; - can_combine = TRUE; - } - else - { - can_combine = FALSE; - } - } - return can_combine; -} - -/** - * _refactor_rects: - * Refactor GdkRectangles whose union forms an 'L' shape, swapping - * the long and short elements. e.g. turns - * - * xxx xxx - * xxx xxx - * oooooo into oooxxx - * oooooo oooxxx - * - * returns: TRUE if the refactor was performed, FALSE if it could not be - * completed (i.e. if the rectangles did not form a suitable union). - **/ -static gboolean -_refactor_rects (GdkRectangle *p, GdkRectangle *n) -{ - gboolean refactored = FALSE; - GdkRectangle *a, *b; - if (p->x == n->x) - { - if (p->width < n->width) - { - a = p; - b = n; - } - else - { - a = n; - b = p; - } - if (a->y == b->y + b->height) - { - a->y -= b->height; - a->height += b->height; - b->x += a->width; - b->width -= a->width; - refactored = TRUE; - } - else if (a->y + a->height == b->y) - { - a->height += b->height; - b->x += a->width; - b->width -= a->width; - refactored = TRUE; - } - if (refactored) fprintf (stderr, "REFACTOR 1\n"); - } - else if (p->y == n->y) - { - if (p->height < n->height) - { - a = p; - b = n; - } - else - { - a = n; - b = p; - } - if (a->x == b->x + b->width) - { - a->x -= b->width; - a->width += b->width; - b->y += a->height; - b->height -= a->height; - refactored = TRUE; - } - else if (a->x + a->width == b->x) - { - a->width += b->width; - b->y += a->height; - b->height -= a->height; - refactored = TRUE; - } - if (refactored) fprintf (stderr, "REFACTOR 2\n"); - } - else if (p->x + p->width == n->x + n->width) - { - if (p->width < n->width) - { - a = p; - b = n; - } - else - { - a = n; - b = p; - } - if (a->y == b->y + b->height) - { - a->y -= b->height; - a->height += b->height; - b->width -= a->width; - refactored = TRUE; - } - else if (a->y + a->height == b->y) - { - a->height += b->height; - b->width -= a->width; - refactored = TRUE; - } - if (refactored) fprintf (stderr, "REFACTOR 3\n"); - } - else if (p->y + p->height == n->y + n->height) - { - if (p->height < n->height) - { - a = p; - b = n; - } - else - { - a = n; - b = p; - } - if (a->x == b->x + b->width) - { - a->x -= b->width; - a->width += b->width; - b->height -= a->height; - refactored = TRUE; - } - else if (a->x + a->width == b->x) - { - a->width += b->width; - b->height -= a->height; - refactored = TRUE; - } - if (refactored) fprintf (stderr, "REFACTOR 4\n"); - } - return refactored; -} - -static GList* -_combine_update_rects (GList *q, int lookahead_n) -{ - int i = 0; - GdkRectangle *a = q->data; - GList *p = q; - while (i < lookahead_n && p && p->next) - { - if (_combine_rects (a, q->next->data)) - { - q = g_list_delete_link (q, p->next); - } - else - { - p = p->next; - ++i; - } - } - return q; -} -#endif - -/*#define _is_horizontal_rect(r) (((2 * (r)->width / 3 * (r)->height)) > 1)*/ -/*#define _is_vertical_rect(r) (((2 * (r)->height / 3 * (r)->width)) > 1)*/ -#define _is_horizontal_rect(r) ((r)->width > (r)->height) -#define _is_vertical_rect(r) ((r)->height > (r)->width) - -/** - * _coalesce_update_rects : - * coalesces multiple "vertical" rects and "horizontal" - * rects into one of each. Can result in overlapping/larger - * update area for tiled rects, but reduces queue size dramatically. - **/ -static GList * -_coalesce_update_rects (GList *q, int min_coalesce_length) -{ - GdkRectangle *v = NULL, *h = NULL; - GList *compact_queue = NULL; -/* fprintf (stderr, "starting queue length = %d\n", g_list_length (q)); */ - if (g_list_length (q) < min_coalesce_length) - return g_list_copy (q); - while (q) - { - if (_is_vertical_rect ((GdkRectangle *) (q->data))) - { - if (v) gdk_rectangle_union (v, q->data, v); - else - { - v = g_new0 (GdkRectangle, 1); - *v = *(GdkRectangle *)q->data; - } - } - else if (_is_horizontal_rect ((GdkRectangle *) (q->data))) - { - if (h) gdk_rectangle_union (h, q->data, h); - else - { - h = g_new0 (GdkRectangle, 1); - *h = *(GdkRectangle *)q->data; - } - } - else - compact_queue = g_list_prepend (compact_queue, q->data); - q = q->next; - }; - if (v) - compact_queue = g_list_prepend (compact_queue, v); - if (h) - compact_queue = g_list_prepend (compact_queue, h); -/* fprintf (stderr, "ending queue length = %d\n", g_list_length (compact_queue));*/ - /* don't free the original queue, that's the caller's responsibility */ - return compact_queue; -} - -#ifdef BROKEN_COALESCE_STUFF_GETS_FIXED -static GList * -_smartbutbroken_coalesce_update_rects (GList *q, int lookahead_n) -{ - int i = 0, len; - fprintf (stderr, "starting queue length = %d\n", g_list_length (q)); - do { - GdkRectangle *a; - len = g_list_length (q); - q = _combine_update_rects (q, lookahead_n); - a = q->data; - while (i < lookahead_n && q && q->next) - { - if (_refactor_rects (a, q->next->data)) - break; - else - ++i; - } - q = _combine_update_rects (q, lookahead_n); - } while (g_list_length (q) < len); - fprintf (stderr, "ending queue length = %d\n", g_list_length (q)); - return q; -} -#endif - -/** COORDINATE CONVERSIONS **/ - -/** clip an area in source coords to the exposed target area **/ -static GdkRectangle -_rectangle_clip_to_rectangle (GdkRectangle area, - GdkRectangle clip_rect) -{ - GdkRectangle clipped; - clipped.x = MAX (area.x, clip_rect.x); - clipped.y = MAX (area.y, clip_rect.y); - clipped.width = MIN ((area.x + area.width), (clip_rect.x + clip_rect.width)) - clipped.x; - clipped.height = MIN ((area.y + area.height), (clip_rect.y + clip_rect.height)) - clipped.y; - return clipped; -} - -static GdkRectangle -_rectangle_clip_to_bounds (GdkRectangle area, - GNOME_Magnifier_RectBounds *clip_bounds) -{ - area.x = MAX (area.x, clip_bounds->x1); - area.x = MIN (area.x, clip_bounds->x2); - area.width = MIN (area.width, clip_bounds->x2 - area.x); - area.y = MAX (area.y, clip_bounds->y1); - area.y = MIN (area.y, clip_bounds->y2); - area.height = MIN (area.height, clip_bounds->y2 - area.y); - return area; -} - -static GdkRectangle -zoom_region_clip_to_source (ZoomRegion *zoom_region, - GdkRectangle area) -{ - GNOME_Magnifier_RectBounds *source_rect_ptr; - if (zoom_region && zoom_region->priv && zoom_region->priv->parent) - { - source_rect_ptr = &((Magnifier *)zoom_region->priv->parent)->source_bounds; - DEBUG_RECT ("clipping to source bounds", zoom_region_rect_from_bounds (zoom_region, source_rect_ptr)); - return _rectangle_clip_to_bounds (area, source_rect_ptr); - } - return area; -} - -static GdkRectangle -zoom_region_clip_to_exposed_target (ZoomRegion *zoom_region, - GdkRectangle area) -{ - GNOME_Magnifier_RectBounds onscreen_target, *source_area; - source_area = &zoom_region->priv->source_area; - - onscreen_target.x1 = MAX (floor (zoom_region->priv->exposed_bounds.x1 - / zoom_region->xscale), - source_area->x1); - onscreen_target.y1 = MAX (floor (zoom_region->priv->exposed_bounds.y1 - / zoom_region->yscale), - source_area->y1); - onscreen_target.x2 = MIN (ceil (zoom_region->priv->exposed_bounds.x2 - / zoom_region->xscale), - source_area->x2); - onscreen_target.y2 = MIN (ceil (zoom_region->priv->exposed_bounds.y2 - / zoom_region->yscale), - source_area->y2); - - return _rectangle_clip_to_bounds (area, &onscreen_target); -} - -static GdkRectangle -zoom_region_clip_to_scaled_pixmap (ZoomRegion *zoom_region, - GdkRectangle area) -{ - GdkRectangle pixmap_area = {0, 0, 0, 0}; - if (zoom_region->priv && zoom_region->priv->pixmap) - { - gdk_drawable_get_size (zoom_region->priv->pixmap, &pixmap_area.width, &pixmap_area.height); - return _rectangle_clip_to_rectangle (area, pixmap_area); - } - else - return area; -} - -static GdkRectangle -zoom_region_clip_to_window (ZoomRegion *zoom_region, - GdkRectangle area) -{ - GdkRectangle window_rect; - - /* we can just return ATM because _rectangle_clip_to_rectangle is unimplemented now */ - - return area; - - if (zoom_region->priv->w->window) - gdk_drawable_get_size (GDK_DRAWABLE (zoom_region->priv->w->window), - &window_rect.x, - &window_rect.y); - else - { - window_rect.x = 0; - window_rect.y = 0; - } - return _rectangle_clip_to_rectangle (area, window_rect); -} - -static const GdkRectangle -zoom_region_source_rect_from_view_bounds (ZoomRegion *zoom_region, - const GNOME_Magnifier_RectBounds *view_bounds) -{ - GdkRectangle source_rect; - source_rect.x = floor ((view_bounds->x1 + zoom_region->priv->exposed_bounds.x1) - / zoom_region->xscale); - source_rect.y = floor ((view_bounds->y1 + zoom_region->priv->exposed_bounds.y1) - / zoom_region->yscale); - source_rect.width = ceil ((view_bounds->x2 - view_bounds->x1) / zoom_region->xscale) + 1; - source_rect.height = ceil ((view_bounds->y2 - view_bounds->y1) / zoom_region->yscale) + 1; - return source_rect; -} - -static GdkRectangle -zoom_region_view_rect_from_source_rect (ZoomRegion *zoom_region, - const GdkRectangle source_rect) -{ - GdkRectangle view_rect; - view_rect.x = source_rect.x * zoom_region->xscale - zoom_region->priv->exposed_bounds.x1; - view_rect.y = source_rect.y * zoom_region->yscale - zoom_region->priv->exposed_bounds.y1; - view_rect.width = source_rect.width * zoom_region->xscale; - view_rect.height = source_rect.height * zoom_region->yscale; - DEBUG_RECT ("source", source_rect); - DEBUG_RECT ("converted to view-rect", view_rect); - return view_rect; -} - -static GdkRectangle -zoom_region_source_rect_from_view_rect (ZoomRegion *zoom_region, - const GdkRectangle view_rect) -{ - GdkRectangle source_rect; - source_rect.x = floor ((view_rect.x + zoom_region->priv->exposed_bounds.x1) - / zoom_region->xscale); - source_rect.y = floor ((view_rect.y + zoom_region->priv->exposed_bounds.y1) - / zoom_region->yscale); - source_rect.width = ceil (view_rect.width / zoom_region->xscale) + 1; - source_rect.height = ceil (view_rect.height / zoom_region->yscale) + 1; - return source_rect; -} - -static GdkRectangle -zoom_region_rect_from_bounds (ZoomRegion *zoom_region, - const GNOME_Magnifier_RectBounds *bounds) -{ - GdkRectangle rect; - rect.x = bounds->x1; - rect.y = bounds->y1; - rect.width = bounds->x2 - bounds->x1; - rect.height = bounds->y2 - bounds->y1; - return rect; -} - -/** ************** **/ - -static CORBA_boolean -zoom_region_update_scale (ZoomRegion *zoom_region, gdouble x, gdouble y) -{ - gdouble x_old = zoom_region->xscale; - gdouble y_old = zoom_region->yscale; - - zoom_region->xscale = x; - zoom_region->yscale = y; - - if (zoom_region->priv->scaled_pixbuf) - g_object_unref (zoom_region->priv->scaled_pixbuf); - zoom_region->priv->scaled_pixbuf = - gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, (zoom_region->priv->source_area.x2 - zoom_region->priv->source_area.x1) * zoom_region->xscale + 1, (zoom_region->priv->source_area.y2 - zoom_region->priv->source_area.y1) * zoom_region->yscale + 1); - - if (zoom_region->priv->pixmap) - g_object_unref (zoom_region->priv->pixmap); - - if (zoom_region_create_pixmap (zoom_region) == - ZOOM_REGION_ERROR_TOO_BIG) { - zoom_region->xscale = x_old; - zoom_region->yscale = y_old; - zoom_region_create_pixmap (zoom_region); - g_object_unref (zoom_region->priv->scaled_pixbuf); - - /* only create a scaled image big enough for the target - * display, for now */ - zoom_region->priv->scaled_pixbuf = gdk_pixbuf_new ( - GDK_COLORSPACE_RGB, FALSE, 8, (zoom_region->priv->source_area.x2 - zoom_region->priv->source_area.x1) * zoom_region->xscale + 1, (zoom_region->priv->source_area.y2 - zoom_region->priv->source_area.y1) * zoom_region->yscale + 1); - - return CORBA_FALSE; - } - return CORBA_TRUE; -} - -static void -zoom_region_queue_update (ZoomRegion *zoom_region, - const GdkRectangle update_rect) -{ - GdkRectangle *rect = - g_new0 (GdkRectangle, 1); - *rect = update_rect; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DEBUG_RECT ("queueing update", *rect); - - zoom_region->priv->q = - g_list_prepend (zoom_region->priv->q, rect); - if (zoom_region->priv && zoom_region->priv->update_handler_id == 0) - zoom_region->priv->update_handler_id = - g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - zoom_region_process_updates, - zoom_region, - NULL); -} - -static void -zoom_region_update_current (ZoomRegion *zoom_region) -{ -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (zoom_region->priv) - { - gboolean pixmap_valid = GDK_IS_DRAWABLE (zoom_region->priv->pixmap); - if (!pixmap_valid) - pixmap_valid = (zoom_region_create_pixmap (zoom_region) == ZOOM_REGION_ERROR_NONE); - if (pixmap_valid) - zoom_region_update (zoom_region, - zoom_region_source_rect_from_view_bounds ( - zoom_region, - &zoom_region->viewport)); - } -} - -static GdkRectangle -zoom_region_cursor_rect (ZoomRegion *zoom_region) -{ - GdkRectangle rect = {0, 0, 0, 0}; - Magnifier *magnifier = zoom_region->priv->parent; - GdkDrawable *cursor = NULL; - if (magnifier) - cursor = magnifier_get_cursor (magnifier); - if (cursor) - { - rect.x = zoom_region->priv->last_cursor_pos.x; - rect.y = zoom_region->priv->last_cursor_pos.y; - rect = zoom_region_view_rect_from_source_rect (zoom_region, rect); - rect.x -= magnifier->cursor_hotspot.x; - rect.y -= magnifier->cursor_hotspot.y; - gdk_drawable_get_size (cursor, &rect.width, &rect.height); - } - return rect; -} - -static void -zoom_region_unpaint_crosswire_cursor (ZoomRegion *zoom_region, - GdkRectangle *clip_rect) -{ - Magnifier *magnifier = zoom_region->priv->parent; - GdkRectangle vline_rect, hline_rect; - GdkPoint cursor_pos; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (!magnifier || magnifier->crosswire_size <= 0) return; - - cursor_pos = zoom_region->priv->last_drawn_crosswire_pos; - vline_rect.x = cursor_pos.x - magnifier->crosswire_size/2; - vline_rect.y = clip_rect ? clip_rect->y : 0; - vline_rect.width = MAX (magnifier->crosswire_size, 1); - vline_rect.height = clip_rect ? clip_rect->height : 4096; - hline_rect.x = clip_rect ? clip_rect->x : 0; - hline_rect.y = cursor_pos.y - magnifier->crosswire_size/2; - hline_rect.width = clip_rect ? clip_rect->width : 4096; - hline_rect.height = MAX (magnifier->crosswire_size, 1); - - zoom_region_paint_pixmap (zoom_region, &vline_rect); - zoom_region_paint_pixmap (zoom_region, &hline_rect); -} - -static void -zoom_region_paint_crosswire_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_rect) -{ - Magnifier *magnifier = zoom_region->priv->parent; - static GdkColormap *cmap; - static GdkColor last_color; - static gboolean last_color_init = FALSE; - GdkGCValues values; - GdkRectangle rect; - GdkDrawable *cursor; - GdkColor color = {0, 0, 0, 0}; - int x_left_clip = 0, x_right_clip = 0, y_top_clip = 0, y_bottom_clip = 0; - int csize = 0; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (!(magnifier && - zoom_region->priv->w->window && - GDK_IS_DRAWABLE (zoom_region->priv->w->window) && - magnifier->crosswire_size > 0)) return; - - if (zoom_region->priv->crosswire_gc == NULL) - { - zoom_region->priv->crosswire_gc = gdk_gc_new (zoom_region->priv->w->window); - cmap = gdk_gc_get_colormap(zoom_region->priv->crosswire_gc); - last_color_init = FALSE; - } - - if (magnifier->crosswire_color == 0) - { - color.red = 0xFFFF; - color.blue = 0xFFFF; - color.green = 0xFFFF; - values.function = GDK_INVERT; - } - else - { - color.red = (magnifier->crosswire_color & 0xFF0000) >> 8; - color.green = (magnifier->crosswire_color & 0xFF00); - color.blue = (magnifier->crosswire_color & 0xFF) << 8; - values.function = GDK_COPY; - } - - values.foreground = color; - - /* Only reset colors if they have changed */ - if (!last_color_init || color.red != last_color.red || - color.blue != last_color.blue || color.green != last_color.green) - { - if (cmap) - { - gdk_rgb_find_color (cmap, &(values.foreground)); - gdk_gc_set_values(zoom_region->priv->crosswire_gc, &values, GDK_GC_FUNCTION | GDK_GC_FOREGROUND); - } - else - { - gdk_gc_set_values(zoom_region->priv->crosswire_gc, &values, GDK_GC_FUNCTION); - } - - last_color.red = color.red; - last_color.blue = color.blue; - last_color.green = color.green; - last_color_init = TRUE; - } - - rect.x = zoom_region->priv->last_cursor_pos.x; - rect.y = zoom_region->priv->last_cursor_pos.y; - rect.width = 0; - rect.height = 0; - rect = zoom_region_view_rect_from_source_rect (zoom_region, rect); - if (clip_rect) gdk_gc_set_clip_rectangle (zoom_region->priv->crosswire_gc, clip_rect); - else gdk_gc_set_clip_rectangle (zoom_region->priv->crosswire_gc, NULL); - - if ((cursor = magnifier_get_cursor (magnifier))) { - gdk_drawable_get_size (cursor, &csize, &csize); - } - if (magnifier->crosswire_clip) - { - y_top_clip = rect.y - magnifier->cursor_hotspot.y - - magnifier->crosswire_size; - y_bottom_clip = rect.y + - (csize - magnifier->cursor_hotspot.y) + - magnifier->crosswire_size; - x_left_clip = rect.x - magnifier->cursor_hotspot.x - - magnifier->crosswire_size; - x_right_clip = rect.x + - (csize - magnifier->cursor_hotspot.x) + - magnifier->crosswire_size; - - } - if (magnifier->crosswire_size == 1) - { - if (magnifier->crosswire_clip) - { - gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, rect.x, 0, - rect.x, y_top_clip); - gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, 0, rect.y, - x_left_clip, rect.y); - } - gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, rect.x, - y_bottom_clip, rect.x, 4096); - gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, x_right_clip, - rect.y, 4096, rect.y); - } - else - { - if (magnifier->crosswire_clip ) - { - gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE, - rect.x - magnifier->crosswire_size / 2, - 0, magnifier->crosswire_size, y_top_clip); - gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE, 0, - rect.y - magnifier->crosswire_size / 2, - x_left_clip, magnifier->crosswire_size); - } - gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE, - rect.x - magnifier->crosswire_size / 2, - y_bottom_clip, magnifier->crosswire_size, 4096); - gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE, x_right_clip, - rect.y - magnifier->crosswire_size / 2, - 4096, magnifier->crosswire_size); - } -} - -static void -zoom_region_unpaint_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_rect) -{ -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - zoom_region_paint_pixmap (zoom_region, - &zoom_region->priv->cursor_backing_rect); -} - -static void -zoom_region_paint_cursor (ZoomRegion *zoom_region, - GdkRectangle *clip_rect) -{ - GdkGCValues values; - GdkRectangle rect, intersct; - GdkRectangle fullscreen; - Magnifier *magnifier = zoom_region->priv->parent; - rect = zoom_region_cursor_rect (zoom_region); -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (clip_rect == NULL) - { - fullscreen = zoom_region_rect_from_bounds (zoom_region, - &zoom_region->viewport); - clip_rect = &fullscreen; - } - /* save the unclipped cursor pos for 'undrawing' the crosswire, the clipped one is no good */ - zoom_region->priv->last_drawn_crosswire_pos.x = rect.x + magnifier->cursor_hotspot.x; - zoom_region->priv->last_drawn_crosswire_pos.y = rect.y + magnifier->cursor_hotspot.y; - - if (gdk_rectangle_intersect (clip_rect, &rect, &intersct)) - { - int width = 0, height = 0; - - GdkDrawable *cursor = magnifier_get_cursor (magnifier); - if (!cursor) - return; - else if (!GDK_IS_DRAWABLE (cursor)) g_message ("cursor isn't DRAWABLE!"); - zoom_region->priv->cursor_backing_rect = rect; - if (zoom_region->priv->cursor_backing_pixels) { - gdk_drawable_get_size (zoom_region->priv->cursor_backing_pixels, - &width, &height); - } - if (rect.width != width || rect.height != height) - { - if (zoom_region->priv->cursor_backing_pixels) { - g_object_unref (zoom_region->priv->cursor_backing_pixels); - } - zoom_region->priv->cursor_backing_pixels = - gdk_pixmap_new (zoom_region->priv->w->window, - rect.width, - rect.height, - -1); - } - if (zoom_region->priv->w->window != NULL) - { - if (zoom_region->priv->default_gc == NULL) - zoom_region->priv->default_gc = gdk_gc_new(zoom_region->priv->w->window); - gdk_draw_drawable (zoom_region->priv->cursor_backing_pixels, - zoom_region->priv->default_gc, - zoom_region->priv->w->window, - rect.x, - rect.y, - 0, 0, - rect.width, - rect.height); - } - DEBUG_RECT ("painting", rect); - if (cursor && zoom_region->priv->w && GDK_IS_DRAWABLE (zoom_region->priv->w->window)) - { - if (zoom_region->priv->paint_cursor_gc == NULL) - zoom_region->priv->paint_cursor_gc = gdk_gc_new (zoom_region->priv->w->window); - - gdk_gc_set_clip_rectangle (zoom_region->priv->paint_cursor_gc, clip_rect); - values.clip_x_origin = rect.x; - values.clip_y_origin = rect.y; - values.clip_mask = magnifier->priv->cursor_mask; - gdk_gc_set_values(zoom_region->priv->paint_cursor_gc, &values, GDK_GC_CLIP_X_ORIGIN | - GDK_GC_CLIP_Y_ORIGIN | GDK_GC_CLIP_MASK); - - gdk_draw_rectangle (zoom_region->priv->w->window, - zoom_region->priv->paint_cursor_gc, - TRUE, - rect.x, rect.y, rect.width, rect.height); - - gdk_draw_drawable (zoom_region->priv->w->window, - zoom_region->priv->paint_cursor_gc, - cursor, - 0, 0, - rect.x, - rect.y, - rect.width, - rect.height); - } - } -} - -/** - * zoom_region_coalesce_updates: - * - **/ -static void -zoom_region_coalesce_updates (ZoomRegion *zoom_region) -{ - /* TODO: lock the queue ? */ - GList *q; - int lookahead_n = 4; /* 'distance' to look ahead in queue */ - int max_qlen = 50; - - if (zoom_region->priv && zoom_region->priv->q && g_list_length (zoom_region->priv->q) > max_qlen) - { - g_list_free (zoom_region->priv->q); - zoom_region->priv->q = NULL; /* just discard and update everything */ - /* CAUTION: this can be an expensive operation! */ - zoom_region_queue_update (zoom_region, zoom_region_rect_from_bounds - (zoom_region, &zoom_region->priv->source_area)); - } - else - - if (zoom_region->priv && zoom_region->priv->q && - (g_list_length (zoom_region->priv->q) > 1) && can_coalesce) - { - q = g_list_reverse (g_list_copy (zoom_region->priv->q)); - if (q) - { - GList *coalesce_copy; - if (zoom_region->coalesce_func) - { - GList *new; - coalesce_copy = (*zoom_region->coalesce_func) (q, lookahead_n); - new = g_list_reverse (coalesce_copy); - g_list_free (zoom_region->priv->q); - zoom_region->priv->q = new; - } - g_list_free (q); - } - } -} - - -static void -zoom_region_paint_border (ZoomRegion *zoom_region) -{ - GdkColor color; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if ((zoom_region->border_size > 0) && - (zoom_region->priv->border->window)) { - color.red = (((zoom_region->border_color & 0xFF0000) >> 16) * - 65535) / 255; - color.green = (((zoom_region->border_color & 0xFF00) >> 8) * - 65535) / 255; - color.blue = ((zoom_region->border_color & 0xFF) * 65535) / - 255; - -#ifdef DEBUG_BORDER - fprintf (stderr, "border color triple RGB=%d|%d|%d\n", - color.red, color.green, color.blue); -#endif - - gtk_widget_modify_bg (zoom_region->priv->border, - GTK_STATE_NORMAL, &color); - } -} - -static void -zoom_region_paint_pixmap (ZoomRegion *zoom_region, - GdkRectangle *area) -{ -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - g_assert (zoom_region->priv); - g_assert (zoom_region->priv->w); - - if (!GDK_IS_DRAWABLE (zoom_region->priv->w->window)) return; - if (zoom_region->priv->default_gc == NULL) - zoom_region->priv->default_gc = gdk_gc_new (zoom_region->priv->w->window); - - if (zoom_region->priv->pixmap && GDK_IS_DRAWABLE (zoom_region->priv->w->window)) - { - gdk_draw_drawable (zoom_region->priv->w->window, - zoom_region->priv->default_gc, - zoom_region->priv->pixmap, - area->x + zoom_region->priv->exposed_bounds.x1 - zoom_region->priv->source_area.x1 * zoom_region->xscale, - area->y + zoom_region->priv->exposed_bounds.y1 - zoom_region->priv->source_area.y1 * zoom_region->yscale, - area->x, - area->y, - area->width, - area->height); - } -} - -/** - * Note: clips to region's current GdkWindow. - **/ -static void -zoom_region_paint (ZoomRegion *zoom_region, - GdkRectangle *area) -{ - GdkRectangle paint_area; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DEBUG_RECT ("painting (clipped)", *area); - paint_area = zoom_region_clip_to_window (zoom_region, *area); - zoom_region_paint_pixmap (zoom_region, &paint_area); - zoom_region_paint_cursor (zoom_region, &paint_area); - zoom_region_paint_crosswire_cursor (zoom_region, &paint_area); -} - -static ZoomRegionPixmapCreationError -zoom_region_create_pixmap (ZoomRegion *zoom_region) -{ -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (zoom_region->priv->w && GDK_IS_DRAWABLE (zoom_region->priv->w->window)) - { - long width = (zoom_region->priv->source_area.x2 - - zoom_region->priv->source_area.x1) * zoom_region->xscale; - long height = (zoom_region->priv->source_area.y2 - - zoom_region->priv->source_area.y1) * zoom_region->yscale; - zoom_region->priv->pixmap = - gdk_pixmap_new ( - zoom_region->priv->w->window, - width, - height, - gdk_drawable_get_depth ( - zoom_region->priv->w->window)); - - if (magnifier_error_check ()) { - zoom_region->priv->pixmap = NULL; - return ZOOM_REGION_ERROR_TOO_BIG; - } - - DEBUG_RECT("viewport", zoom_region_source_rect_from_view_bounds - (zoom_region, &zoom_region->viewport)); - DEBUG_RECT("source", zoom_region_rect_from_bounds - (zoom_region, &((Magnifier*)zoom_region->priv->parent)->source_bounds)); - - zoom_region_update (zoom_region, -/* zoom_region_source_rect_from_view_bounds ( - zoom_region, - &zoom_region->viewport)); -*/ - zoom_region_rect_from_bounds - (zoom_region, - &((Magnifier *)zoom_region->priv->parent)->source_bounds)); - return ZOOM_REGION_ERROR_NONE; - } - - return ZOOM_REGION_ERROR_NO_TARGET_DRAWABLE; -} - -static void -zoom_region_expose_handler (GtkWindow * w, - GdkEventExpose *event, - gpointer data) -{ - ZoomRegion *zoom_region = data; - DEBUG_RECT ("expose", event->area); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (zoom_region->priv->pixmap == NULL) - { - ZoomRegionPixmapCreationError ret; - /* TODO: scale down if this fails here */ - while ((ret = zoom_region_create_pixmap (zoom_region)) == - ZOOM_REGION_ERROR_TOO_BIG) { - zoom_region->xscale -= 1.0; - zoom_region->yscale -= 1.0; - zoom_region->priv->pixmap = NULL; - g_warning ("Scale factor too big to fit in memory; shrinking."); - } - if (ret == ZOOM_REGION_ERROR_NO_TARGET_DRAWABLE) - g_warning ("create-pixmap: no target drawable"); - } - zoom_region_paint (zoom_region, &event->area); -} - -static void -zoom_region_update_cursor (ZoomRegion *zoom_region, int dx, int dy, - GdkRectangle *clip_rect) -{ -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - zoom_region_unpaint_crosswire_cursor (zoom_region, clip_rect); - zoom_region_unpaint_cursor (zoom_region, clip_rect); - zoom_region->priv->cursor_backing_rect.x += dx; - zoom_region->priv->cursor_backing_rect.y += dy; - zoom_region->priv->last_drawn_crosswire_pos.x += dx; - zoom_region->priv->last_drawn_crosswire_pos.y += dy; - zoom_region_paint_cursor (zoom_region, clip_rect); - zoom_region_paint_crosswire_cursor (zoom_region, clip_rect); - if (GTK_IS_WIDGET (zoom_region->priv->w) && - GDK_IS_WINDOW (zoom_region->priv->w->window)) - gdk_display_sync (gdk_drawable_get_display ( - zoom_region->priv->w->window)); -} - -static gboolean -zoom_region_calculate_scroll_rects (ZoomRegion *zoom_region, - int dx, int dy, - GdkRectangle *scroll_rect, - GdkRectangle *expose_rect_h, - GdkRectangle *expose_rect_v) -{ - GdkWindow *window = NULL; - GdkRectangle rect = {0, 0, 0, 0}; - gboolean retval = TRUE; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - rect.x = 0; - rect.y = 0; - if (zoom_region && zoom_region->priv->w && - zoom_region->priv->w->window) - window = zoom_region->priv->w->window; - else - retval = FALSE; - if (!window) - retval = FALSE; - - if (window != NULL) - gdk_drawable_get_size (GDK_DRAWABLE (window), - &rect.width, - &rect.height); - - if ((ABS (dx) >= rect.width) || (ABS (dy) >= rect.height)) { - *scroll_rect = rect; - DBG(fprintf (stderr, "deltas too big to scroll\n")); - retval = FALSE; - } - else { - scroll_rect->x = MAX (0, dx); - scroll_rect->y = MAX (0, dy); - scroll_rect->width = MIN (rect.width + dx, rect.width - dx); - scroll_rect->height = MIN (rect.height + dy, rect.height - dy); - } - - expose_rect_h->x = 0; - expose_rect_h->y = (scroll_rect->y == 0) ? scroll_rect->height : 0; - expose_rect_h->width = rect.width; - expose_rect_h->height = rect.height - scroll_rect->height; - - expose_rect_v->x = (scroll_rect->x == 0) ? scroll_rect->width : 0; - expose_rect_v->y = scroll_rect->y; - expose_rect_v->width = rect.width - scroll_rect->width; - expose_rect_v->height = scroll_rect->height; - - return retval; -} - -static void -zoom_region_scroll_fast (ZoomRegion *zoom_region, int dx, int dy, - GdkRectangle *scroll_rect, - GdkRectangle *expose_rect_h, - GdkRectangle *expose_rect_v) -{ - GdkWindow *window; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (zoom_region->priv->w && zoom_region->priv->w->window) - window = zoom_region->priv->w->window; - else { - processing_updates = FALSE; - return; - } - zoom_region_unpaint_crosswire_cursor (zoom_region, scroll_rect); - zoom_region_unpaint_cursor (zoom_region, scroll_rect); - gdk_window_scroll (window, dx, dy); - zoom_region_paint_cursor (zoom_region, scroll_rect); - zoom_region_paint_crosswire_cursor (zoom_region, scroll_rect); - gdk_window_process_updates (window, FALSE); - /* sync reduces cursor flicker, but slows things down */ - if (zoom_region->smooth_scroll_policy > - GNOME_Magnifier_ZoomRegion_SCROLL_FASTEST) - gdk_display_sync (gdk_drawable_get_display (window)); -} - -static void -zoom_region_scroll_smooth (ZoomRegion *zoom_region, int dx, int dy, - GdkRectangle *scroll_rect, - GdkRectangle *expose_rect_h, - GdkRectangle *expose_rect_v) -{ - GdkWindow *window = NULL; - GdkRectangle window_rect; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (zoom_region->priv->w && GDK_IS_DRAWABLE (zoom_region->priv->w->window)) - window = zoom_region->priv->w->window; - else - return; - window_rect.x = 0; - window_rect.y = 0; - gdk_drawable_get_size (GDK_DRAWABLE (window), - &window_rect.width, &window_rect.height); - gdk_window_begin_paint_rect (window, &window_rect); - gdk_window_invalidate_rect (window, &window_rect, FALSE); - gdk_window_process_updates (window, FALSE); - gdk_window_end_paint (window); -} - -static void -zoom_region_scroll (ZoomRegion *zoom_region, int dx, int dy) -{ - GdkRectangle scroll_rect, expose_rect_h, expose_rect_v; - gboolean can_scroll; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (timing_test) { - mag_timing.num_line_samples++; - mag_timing.dx = abs(dx); - mag_timing.dy = abs(dy); - mag_timing.dx_total += mag_timing.dx; - mag_timing.dy_total += mag_timing.dy; - if (zoom_region->timing_output) { - fprintf(stderr, " Panning Increment (x) = %d (avg. %f) lines/frame\n", - mag_timing.dx, (float)mag_timing.dx_total / (float)mag_timing.num_line_samples); - fprintf(stderr, " Panning Increment (y) = %d (avg. %f) lines/frame\n", - mag_timing.dy, (float)mag_timing.dy_total / (float)mag_timing.num_line_samples); - } - } - - /* - * Currently processing a screen update. This flag used to disallow - * other updates to occur until this one finishes - */ - processing_updates = TRUE; - - can_scroll = zoom_region_calculate_scroll_rects (zoom_region, dx, dy, - &scroll_rect, - &expose_rect_h, - &expose_rect_v); - - if (can_scroll) { - zoom_region_update_pixmap (zoom_region, zoom_region_source_rect_from_view_rect (zoom_region, expose_rect_h), NULL); - zoom_region_update_pixmap (zoom_region, zoom_region_source_rect_from_view_rect (zoom_region, expose_rect_v), NULL); - - if (zoom_region->smooth_scroll_policy > GNOME_Magnifier_ZoomRegion_SCROLL_FAST) { - zoom_region_scroll_smooth (zoom_region, dx, dy, - &scroll_rect, - &expose_rect_h, - &expose_rect_v); - } else { - zoom_region_scroll_fast (zoom_region, dx, dy, - &scroll_rect, - &expose_rect_h, - &expose_rect_v); - } - } else { - zoom_region_queue_update (zoom_region, zoom_region_source_rect_from_view_rect (zoom_region, scroll_rect)); - } -} - -static void -zoom_region_recompute_exposed_bounds (ZoomRegion *zoom_region) -{ - zoom_region->priv->exposed_bounds.x2 = zoom_region->priv->exposed_bounds.x1 - + (zoom_region->viewport.x2 - zoom_region->viewport.x1); - zoom_region->priv->exposed_bounds.y2 = zoom_region->priv->exposed_bounds.y1 - + (zoom_region->viewport.y2 - zoom_region->viewport.y1); -} - -static void -zoom_region_set_cursor_pos (ZoomRegion *zoom_region, int x, int y) -{ - if (zoom_region->priv) - { - zoom_region->priv->last_cursor_pos.x = x; - zoom_region->priv->last_cursor_pos.y = y; - } -} - -static gboolean -zoom_region_update_pointer (ZoomRegion *zoom_region, gboolean draw_cursor) -{ - Magnifier *magnifier; - gint mouse_x_return, mouse_y_return; - guint mask_return; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (!zoom_region->priv || !zoom_region->priv->parent - || !zoom_region->poll_mouse) - return FALSE; - - magnifier = zoom_region->priv->parent; - - /* TODO: there's really no reason we should be using magnifier->priv->root here */ - if (magnifier && magnifier->priv && magnifier_get_root (magnifier)) - { - gdk_window_get_pointer ( - magnifier_get_root (magnifier), - &mouse_x_return, - &mouse_y_return, - &mask_return); - - if (zoom_region->priv->last_cursor_pos.x != mouse_x_return - || zoom_region->priv->last_cursor_pos.y != mouse_y_return) - { - zoom_region_set_cursor_pos (zoom_region, - mouse_x_return, mouse_y_return); - if (draw_cursor) - { - GdkRectangle paint_area, *clip = NULL; - - if (GTK_IS_WIDGET (zoom_region->priv->w) && - GDK_IS_DRAWABLE (zoom_region->priv->w->window)) - { - gdk_drawable_get_size (GDK_DRAWABLE (zoom_region->priv->w->window), &paint_area.width, &paint_area.height); - paint_area.x = 0; - paint_area.y = 0; - clip = &paint_area; - paint_area = - zoom_region_clip_to_source ( - zoom_region, - paint_area); - } - zoom_region_update_cursor (zoom_region, 0, 0, - clip); - } - return TRUE; - } - } - return FALSE; -} - -static int -zoom_region_update_pointer_idle (gpointer data) -{ - ZoomRegion *zoom_region = (ZoomRegion *) data; - - if (zoom_region_update_pointer (zoom_region, TRUE)) - return TRUE; - else { - if (zoom_region->priv) - zoom_region->priv->update_pointer_id = - g_timeout_add_full (G_PRIORITY_DEFAULT, - 100, - zoom_region_update_pointer_timeout, - zoom_region, - NULL); - return FALSE; - } -} - -static int -zoom_region_update_pointer_timeout (gpointer data) -{ - ZoomRegion *zoom_region = data; - - if (zoom_region->priv && zoom_region_update_pointer (zoom_region, TRUE)) { - zoom_region->priv->update_pointer_id = - g_idle_add_full (G_PRIORITY_HIGH_IDLE, - zoom_region_update_pointer_idle, - data, - NULL); - return FALSE; - } else - return TRUE; -} - -static void -zoom_region_moveto (ZoomRegion *zoom_region, - const long x, const long y) -{ - long dx = x * zoom_region->xscale - zoom_region->priv->exposed_bounds.x1; - long dy = y * zoom_region->yscale - zoom_region->priv->exposed_bounds.y1; -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif -/* fprintf (stderr, "moveto %ld %ld\n", x, y); */ - - mag_timing.dx = 0; - mag_timing.dy = 0; - - if ((dx != 0) || (dy != 0)) { - zoom_region_update_pointer (zoom_region, FALSE); - zoom_region->priv->exposed_bounds.x1 = x * zoom_region->xscale; - zoom_region->priv->exposed_bounds.y1 = y * zoom_region->yscale; - zoom_region_recompute_exposed_bounds (zoom_region); - zoom_region_scroll (zoom_region, - -dx, -dy); - } -} - -/* - * Process that must be made in-line in the current pixbuf. - */ -static void -zoom_region_process_pixbuf (ZoomRegion *zoom_region, GdkPixbuf *pixbuf) -{ - int rowstride = gdk_pixbuf_get_rowstride (pixbuf); - int i, j, t; - int w = gdk_pixbuf_get_width (pixbuf); - int h = gdk_pixbuf_get_height (pixbuf); - int n_channels = gdk_pixbuf_get_n_channels (pixbuf); - guchar *pixels = gdk_pixbuf_get_pixels (pixbuf); - guchar *pixels_row; -#ifdef HAVE_COLORBLIND - COLORBLIND_RUNTIME *cbr; - COLORBLIND_XCOLOR *color; -#endif /* HAVE_COLORBLIND */ - - gboolean manipulate_contrast = FALSE; - gboolean manipulate_brightness = FALSE; - gboolean color_blind_filter = FALSE; - - if (zoom_region->contrast_r != 0 || zoom_region->contrast_g != 0 || - zoom_region->contrast_b != 0) { - manipulate_contrast = TRUE; - } - - if (zoom_region->bright_r != 0 || zoom_region->bright_g != 0 || - zoom_region->bright_b != 0) { - manipulate_brightness = TRUE; - } - -#ifdef HAVE_COLORBLIND - if (zoom_region->color_blind_filter != - GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_NO_FILTER) { - color_blind_filter = TRUE; - cbr = colorblind_create (); - color = malloc (sizeof (COLORBLIND_XCOLOR)); - switch (zoom_region->color_blind_filter) { - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_NO_FILTER: - break; /* This entry is only to avoid a warning */ - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE_RED: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate_red); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE_GREEN: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate_green); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE_BLUE: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate_blue); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_RED: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate_red); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_GREEN: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate_green); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_BLUE: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate_blue); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_HUE_SHIFT_POSITIVE: - colorblind_set_filter_type (cbr, colorblind_filter_t_hue_shift_positive); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_HUE_SHIFT_NEGATIVE: - colorblind_set_filter_type (cbr, colorblind_filter_t_hue_shift_negative); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE: - colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate); - break; - case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_MONOCHRONE_OTHERS: - colorblind_set_filter_type (cbr, colorblind_filter_t_monochrome_others); - break; - } - } -#endif /* HAVE_COLORBLIND */ - - if (!manipulate_contrast && !zoom_region->invert && - !manipulate_brightness && !color_blind_filter) - return; - -#define CLAMP_UCHAR(v) (t = (v), CLAMP (t, 0, 255)) -#define CLAMP_LOW_MID(v) (t = (v), CLAMP (t, 0, 127)) -#define CLAMP_MID_HIGH(v) (t = (v), CLAMP (t, 127, 255)) - - for (j = 0; j < h; ++j) { - pixels_row = pixels; - for (i = 0; i < w; ++i) { - if (manipulate_contrast) { - /* Set the RED contrast */ - if (pixels_row[0] <= 127) - pixels_row[0] = CLAMP_LOW_MID (pixels_row[0] - zoom_region->contrast_r * 127); - else - pixels_row[0] = CLAMP_MID_HIGH (pixels_row[0] + zoom_region->contrast_r * 127); - - /* Set the GREEN contrast */ - if (pixels_row[1] <= 127) - pixels_row[1] = CLAMP_LOW_MID (pixels_row[1] - zoom_region->contrast_g * 127); - else - pixels_row[1] = CLAMP_MID_HIGH (pixels_row[1] + zoom_region->contrast_g * 127); - - /* Set the BLUE contrast */ - if (pixels_row[2] <= 127) - pixels_row[2] = CLAMP_LOW_MID (pixels_row[2] - zoom_region->contrast_b * 127); - else - pixels_row[2] = CLAMP_MID_HIGH (pixels_row[2] + zoom_region->contrast_b * 127); - } - - if (manipulate_brightness) { - /* Set the RED brightness */ - pixels_row[0] = CLAMP_UCHAR (pixels_row[0] + zoom_region->bright_r * 255); - - /* Set the GREEN brightness */ - pixels_row[1] = CLAMP_UCHAR (pixels_row[1] + zoom_region->bright_g * 255); - - /* Set the BLUE brightness */ - pixels_row[2] = CLAMP_UCHAR (pixels_row[2] + zoom_region->bright_b * 255); - } - - if (zoom_region->invert) { - pixels_row[0] = ~(pixels_row[0]); - pixels_row[1] = ~(pixels_row[1]); - pixels_row[2] = ~(pixels_row[2]); - } - -#ifdef HAVE_COLORBLIND - if (color_blind_filter) { - color->red = pixels_row[0]; - color->green = pixels_row[1]; - color->blue = pixels_row[2]; - if (colorblind_filter (cbr, color)) { - pixels_row[0] = color->red; - pixels_row[1] = color->green; - pixels_row[2] = color->blue; - } - } -#endif /* HAVE_COLORBLIND */ - - pixels_row += n_channels; - } - pixels += rowstride; - } -} - -static void -zoom_region_post_process_pixbuf (ZoomRegion *zoom_region, - GdkPixbuf *subimage, - GdkPixbuf *scaled_image) -{ - /* nothing yet */ - /** - * ADI: This is where your image smoothing code - * hooks into the magnifier. This routine can call others which - * post-process the GdkPixbuf before rendering to the screen. - * - * We can make this a two-stage process also, whereby the post-process code - * is only called in a lower-priority idle handler, and queues repaints - * when it is done. - **/ -} - -static GdkPixbuf * -zoom_region_get_source_subwindow (ZoomRegion *zoom_region, - const GdkRectangle bounds) -{ - int i, j, width, height; - Magnifier *magnifier = zoom_region->priv->parent; - GdkPixbuf *subimage = NULL; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - width = gdk_screen_get_width ( - gdk_display_get_screen (magnifier->source_display, - magnifier->source_screen_num)); - height = gdk_screen_get_height ( - gdk_display_get_screen (magnifier->source_display, - magnifier->source_screen_num)); - - if ((bounds.width <= 0) || (bounds.height <= 0)) - { - return NULL; - } - - if (!zoom_region->priv->source_drawable) - { - /* TESTING ONLY */ - if (zoom_region->priv->test) { - GdkImage *test_image = NULL; - - test_image = gdk_image_new (GDK_IMAGE_FASTEST, - gdk_visual_get_system (), - width, - height); - - for (i = 0; i < width; ++i) - for (j = 0; j < height; ++j) - gdk_image_put_pixel (test_image, i, j, i*j); - - zoom_region->priv->source_drawable = gdk_pixmap_new (zoom_region->priv->w->window, width, height, -1); - - if (zoom_region->priv->default_gc == NULL) - zoom_region->priv->default_gc = gdk_gc_new(zoom_region->priv->w->window); - - gdk_draw_image (zoom_region->priv->source_drawable, - zoom_region->priv->default_gc, - test_image, - 0, 0, - 0, 0, - width, height); - } - else - { - if (magnifier->priv->source_drawable) { - zoom_region->priv->source_drawable = - magnifier->priv->source_drawable; - } else - zoom_region->priv->source_drawable = gdk_screen_get_root_window (gdk_display_get_screen (magnifier->source_display, magnifier->source_screen_num)); - } - if (zoom_region->cache_source) - { - zoom_region->priv->source_pixbuf_cache = - gdk_pixbuf_new (GDK_COLORSPACE_RGB, - FALSE, - 8, /* FIXME: not always 8? */ - width, height); - } - } - DEBUG_RECT ("getting subimage from ", bounds); - - subimage = gdk_pixbuf_get_from_drawable (NULL, zoom_region->priv->source_drawable, - gdk_colormap_get_system (), - bounds.x, - bounds.y, - 0, - 0, - bounds.width, - bounds.height); - - /* TODO: blank the region overlapped by the target display if source == target */ - - if (!subimage) - _debug_announce_rect ("update of invalid subregion!\n", bounds); - - /* if this zoom-region keeps a cache, do a diff to see if update is necessary */ - if (zoom_region->cache_source && subimage) { - GdkPixbuf *cache_subpixbuf = - gdk_pixbuf_new_subpixbuf (zoom_region->priv->source_pixbuf_cache, - bounds.x, bounds.y, bounds.width, bounds.height); - if (_diff_pixbufs (subimage, cache_subpixbuf)) { - gdk_pixbuf_copy_area (subimage, 0, 0, bounds.width, bounds.height, - zoom_region->priv->source_pixbuf_cache, - bounds.x, bounds.y); - } - else - { - if (subimage) - g_object_unref (subimage); - subimage = NULL; - } - g_object_unref (cache_subpixbuf); - } - return subimage; -} - -static GdkRectangle -zoom_region_update_pixmap (ZoomRegion *zoom_region, - const GdkRectangle update_rect, - GdkRectangle *p_rect) -{ - GdkPixbuf *subimage; - GdkRectangle source_rect; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DEBUG_RECT ("unclipped update rect", update_rect); - source_rect = zoom_region_clip_to_source (zoom_region, update_rect); - DEBUG_RECT ("clipped to source", source_rect); - source_rect = zoom_region_clip_to_exposed_target (zoom_region, source_rect); - DEBUG_RECT ("update rect clipped to exposed target", source_rect); - - subimage = zoom_region_get_source_subwindow (zoom_region, source_rect); - - if (subimage) - { - GdkRectangle paint_rect; - g_timer_start (mag_timing.scale); - DEBUG_RECT ("source rect", source_rect); - paint_rect = zoom_region_view_rect_from_source_rect (zoom_region, source_rect); - if (p_rect) { - *p_rect = paint_rect; - } - /* paint_rect = zoom_region_clip_to_scaled_pixmap (zoom_region, paint_rect); */ - DEBUG_RECT ("paint rect", paint_rect); - - zoom_region_process_pixbuf (zoom_region, subimage); - - /** - * XXX: We seem to be breaking with the original intention - * here, which was to keep a fullscreen scaled pixbuf in-sync. - **/ - gdk_pixbuf_scale (subimage, - zoom_region->priv->scaled_pixbuf, - 0, - 0, - paint_rect.width, - paint_rect.height, - 0, - 0, - zoom_region->xscale, - zoom_region->yscale, - zoom_region->priv->gdk_interp_type); - - zoom_region_post_process_pixbuf (zoom_region, subimage, - zoom_region->priv->scaled_pixbuf); - if (zoom_region->priv->default_gc == NULL) - zoom_region->priv->default_gc = gdk_gc_new(zoom_region->priv->w->window); - -#ifndef USE_GDK_PIXBUF_RENDER_TO_DRAWABLE - if (GDK_IS_DRAWABLE (zoom_region->priv->pixmap)) - gdk_draw_pixbuf (zoom_region->priv->pixmap, - zoom_region->priv->default_gc, - zoom_region->priv->scaled_pixbuf, - 0, - 0, - paint_rect.x + zoom_region->priv->exposed_bounds.x1 - zoom_region->priv->source_area.x1 * zoom_region->xscale, - paint_rect.y + zoom_region->priv->exposed_bounds.y1 - zoom_region->priv->source_area.y1 * zoom_region->yscale, - paint_rect.width, - paint_rect.height, - GDK_RGB_DITHER_NONE, - 0, - 0); - else - g_warning ("updating non-drawable pixmap: region %p", zoom_region); -#else - gdk_pixbuf_render_to_drawable (zoom_region->priv->scaled_pixbuf, - zoom_region->priv->pixmap, - zoom_region->priv->default_gc, - 0, - 0, - paint_rect.x + zoom_region->priv->exposed_bounds.x1, - paint_rect.y + zoom_region->priv->exposed_bounds.y1, - paint_rect.width, - paint_rect.height, - GDK_RGB_DITHER_NONE, - 0, - 0); -#endif - if (magnifier_error_check ()) - g_warning ("Could not render scaled image to drawable; out of memory!\n"); - g_object_unref (subimage); - - g_timer_stop (mag_timing.scale); - } - return source_rect; -} - -/** - * zoom_region_update: - * - * @rect: a RectBounds structure indicating the source area to update, - * in the source coordinate system. - **/ -static void -zoom_region_update (ZoomRegion *zoom_region, - const GdkRectangle update_rect) -{ - GdkRectangle paint_rect = {0, 0, 0, 0}; - if (zoom_region->priv->w && zoom_region->priv->w->window) { - GdkRectangle source_rect = zoom_region_update_pixmap (zoom_region, update_rect, &paint_rect); - if (paint_rect.x != 0 || paint_rect.y != 0 || - paint_rect.width != 0 || paint_rect.height != 0) { - gdk_window_begin_paint_rect ( - zoom_region->priv->w->window, &paint_rect); - zoom_region_paint (zoom_region, &paint_rect); - gdk_window_end_paint (zoom_region->priv->w->window); - } - if (timing_test) { - mag_timing.num_scale_samples++; - - gulong microseconds; - - mag_timing.scale_val = - g_timer_elapsed (mag_timing.scale, - µseconds); - mag_timing.scale_total += mag_timing.scale_val; - - if (mag_timing.scale_val != 0 && (timing_scale_max == 0 || - (1.0/(float)mag_timing.scale_val) > (1.0/(float)timing_scale_max))) - timing_scale_max = mag_timing.scale_val; - if ((source_rect.height * source_rect.width / mag_timing.scale_val) > update_nrr_max) - update_nrr_max = source_rect.height * source_rect.width / mag_timing.scale_val; - - mag_timing.update_pixels_total += source_rect.height * source_rect.width; - - if (zoom_region->timing_output) { - fprintf(stderr, " Update Duration = %f (avg. %f) (max. %f) (tot. %f) seconds\n", - mag_timing.scale_val, (mag_timing.scale_total / - mag_timing.num_scale_samples), timing_scale_max, mag_timing.scale_total); - fprintf(stderr, " Update Pixels = %ld (avg. %ld) pixels/frame\n", - (long) source_rect.height * source_rect.width, - mag_timing.update_pixels_total / mag_timing.num_scale_samples); - fprintf(stderr, " Update Rate = (avg. %f) (max. %f) updates/second\n", - 1.0/(mag_timing.scale_total / mag_timing.num_scale_samples), 1.0/(float)timing_scale_max); - fprintf(stderr, " Net Update Rate = (avg. %f) (max. %f) Mpex/second\n", - ((float)mag_timing.update_pixels_total / (float)mag_timing.scale_total) / 1000000.0, - update_nrr_max / 1000000.0); - } - } - } else { - fprintf (stderr, "update on uninitialized zoom region!\n"); - } -} - -static void -zoom_region_init_window (ZoomRegion *zoom_region) -{ - GtkFixed *parent; - GtkWidget *zoomer, *border; - DBG(fprintf (stderr, "window not yet created...\n")); - parent = GTK_FIXED ( - ((Magnifier *)zoom_region->priv->parent)->priv->canvas); - zoomer = gtk_drawing_area_new (); - border = gtk_drawing_area_new (); - zoom_region->priv->border = border; - zoom_region->priv->w = zoomer; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - gtk_widget_set_size_request (GTK_WIDGET (border), - zoom_region->viewport.x2 - - zoom_region->viewport.x1, - zoom_region->viewport.y2 - - zoom_region->viewport.y1); - gtk_widget_set_size_request (GTK_WIDGET (zoomer), - zoom_region->viewport.x2 - - zoom_region->viewport.x1 - - zoom_region->border_size * 2, - zoom_region->viewport.y2 - - zoom_region->viewport.y1 - - zoom_region->border_size * 2); - gtk_fixed_put (parent, border, - zoom_region->viewport.x1, - zoom_region->viewport.y1); - gtk_fixed_put (parent, zoomer, - zoom_region->viewport.x1 + zoom_region->border_size, - zoom_region->viewport.y1 + zoom_region->border_size); - gtk_widget_show (GTK_WIDGET (border)); - gtk_widget_show (GTK_WIDGET (zoomer)); - gtk_widget_show (GTK_WIDGET (parent)); - zoom_region->priv->expose_handler_id = - g_signal_connect (G_OBJECT (zoom_region->priv->w), - "expose_event", - G_CALLBACK (zoom_region_expose_handler), - zoom_region); - DBG(fprintf (stderr, "New window created\n")); -} - -static int -zoom_region_process_updates (gpointer data) -{ - ZoomRegion *zoom_region = (ZoomRegion *) data; - - /* TODO: lock the queue when copying it? */ - zoom_region_coalesce_updates (zoom_region); - - if (zoom_region->priv->q != NULL) { - GList *last = g_list_last (zoom_region->priv->q); -#ifdef ZOOM_REGION_DEBUG - fprintf (stderr, "qlen=%d\n", g_list_length (zoom_region->priv->q)); -#endif - if (last) { - zoom_region->priv->q = g_list_remove_link (zoom_region->priv->q, - last); - zoom_region_update (zoom_region, - * (GdkRectangle *) last->data); - g_list_free (last); -#ifdef DEBUG - fputs (".\n", stderr); /* debug output, means we actually did something. */ -#endif - } - return TRUE; - } - else - { - if (zoom_region->priv) - zoom_region->priv->update_handler_id = 0; - return FALSE; - } -} - -void -timing_report(ZoomRegion *zoom_region) -{ - float frame_avg; - float x_scroll_incr, y_scroll_incr; - int width, height, x, y; - - if (timing_test) { - width = (zoom_region->viewport.x2 - - zoom_region->viewport.x1) / zoom_region->xscale; - height = (zoom_region->viewport.y2 - - zoom_region->viewport.y1) / zoom_region->yscale; - - frame_avg = mag_timing.frame_total / mag_timing.num_frame_samples; - - x_scroll_incr = (float)mag_timing.dx_total / (float)mag_timing.num_line_samples; - y_scroll_incr = (float)mag_timing.dy_total / (float)mag_timing.num_line_samples; - - gdk_drawable_get_size (GDK_DRAWABLE (zoom_region->priv->w->window), - &x, &y); - - fprintf(stderr, " Frames Processed = %ld\n", - mag_timing.num_frame_samples + 1); - fprintf(stderr, " Width/Height/Depth = %d/%d/%d\n", x, y, - gdk_drawable_get_depth (zoom_region->priv->w->window)); - fprintf(stderr, " Zoom Factor (x/y) = %f/%f\n", zoom_region->xscale, - zoom_region->yscale); - if (mag_timing.num_scale_samples != 0) { - fprintf(stderr, " Update Duration = (avg. %f) (max. %f) (tot. %f) seconds\n", - (mag_timing.scale_total / mag_timing.num_scale_samples), timing_scale_max, mag_timing.scale_total); - fprintf(stderr, " Update Pixels = (avg. %ld) pixels/frame\n", - mag_timing.update_pixels_total / mag_timing.num_scale_samples); - fprintf(stderr, " Update Rate = (avg. %f) (max. %f) updates/second\n", - 1.0/((float)mag_timing.scale_total / (float)mag_timing.num_scale_samples), - 1.0/(float)timing_scale_max); - fprintf(stderr, " Net Update Rate = (avg. %f) (max. %f) Mpex/second\n", - ((float)mag_timing.update_pixels_total / (float)mag_timing.scale_total) / 1000000.0, - update_nrr_max / 1000000.0); - } - fprintf(stderr, " Pan Latency = (avg. %f) (max. %f) seconds\n", - (mag_timing.idle_total / mag_timing.num_idle_samples), timing_idle_max); - fprintf(stderr, " Total Frame Duration = (avg. %f) (max. %f) (tot. %f) seconds\n", - frame_avg, timing_frame_max, mag_timing.frame_total); - fprintf(stderr, " Frame Rate = (avg. %f) (max. %f) frames/second\n", - 1.0 / (mag_timing.frame_total / mag_timing.num_frame_samples), cps_max); - fprintf(stderr, " Scroll Delta (x) = (avg. %f) (tot. %d) lines\n", - x_scroll_incr, mag_timing.dx_total); - fprintf(stderr, " Scroll Delta (y) = (avg. %f) (tot. %d) lines\n", - y_scroll_incr, mag_timing.dy_total); - fprintf(stderr, " Scroll Rate (x) = (avg. %f) lines/second\n", - x_scroll_incr / frame_avg); - fprintf(stderr, " Scroll Rate (y) = (avg. %f) lines/second\n", - y_scroll_incr / frame_avg); - - fprintf(stderr, " Net Render Rate = (avg. %f) (max. %f) Mpex/second\n\n", - (height * width * - ((float)mag_timing.num_frame_samples / (float)mag_timing.frame_total)) / 1000000.0, - nrr_max / 1000000.0); - } -} - -static void -zoom_region_time_frame(ZoomRegion *zoom_region, Magnifier *magnifier) -{ - float frame_avg; - float x_scroll_incr, y_scroll_incr; - int width = magnifier->target_bounds.x2 - magnifier->target_bounds.x1; - int height = magnifier->target_bounds.y2 - magnifier->target_bounds.y1; - - mag_timing.num_frame_samples++; - g_timer_stop (mag_timing.frame); - - gulong microseconds; - - mag_timing.frame_val = g_timer_elapsed (mag_timing.frame, - µseconds); - - mag_timing.frame_total += mag_timing.frame_val; - if (mag_timing.frame_val > timing_frame_max) - timing_frame_max = mag_timing.frame_val; - if (mag_timing.frame_val != 0 && 1.0/mag_timing.frame_val > cps_max) - cps_max = 1.0/mag_timing.frame_val; - - frame_avg = mag_timing.frame_total / mag_timing.num_frame_samples; - - x_scroll_incr = (float)mag_timing.dx_total / (float)mag_timing.num_line_samples; - y_scroll_incr = (float)mag_timing.dy_total / (float)mag_timing.num_line_samples; - - if ((height * width / mag_timing.frame_val) > nrr_max) - nrr_max = height * width / mag_timing.frame_val; - - if (zoom_region->timing_output) { - fprintf(stderr, " Total Frame Duration = %f (avg. %f) (max. %f) (tot. %f) seconds\n", - mag_timing.frame_val, frame_avg, timing_frame_max, mag_timing.frame_total); - fprintf(stderr, " Frame Rate = (avg. %f) (max. %f) frames/second\n", - 1.0 /frame_avg, cps_max); - fprintf(stderr, " Scroll Delta (x) = (avg. %f) (tot. %d) lines\n", - x_scroll_incr, mag_timing.dx_total); - fprintf(stderr, " Scroll Delta (y) = (avg. %f) (tot. %d) lines\n", - y_scroll_incr, mag_timing.dy_total); - fprintf(stderr, " Scroll Rate (x) = (avg. %f) lines/second\n", - x_scroll_incr / frame_avg); - fprintf(stderr, " Scroll Rate (y) = (avg. %f) lines/second\n", - y_scroll_incr / frame_avg); - - fprintf(stderr, " Net Render Rate = (avg. %f) (max. %f) Mpex/second\n", - (height * width * - ((float)mag_timing.num_frame_samples / (float)mag_timing.frame_total)) / 1000000.0, - nrr_max / 1000000.0); - } - - mag_timing.last_frame_val = mag_timing.frame_val; - mag_timing.last_dy = mag_timing.dy; - - if (reset_timing) { - fprintf(stderr, "\n### Updates summary:\n\n"); - timing_report (zoom_region); - fprintf(stderr, "\n### Updates finished, starting panning test\n"); - reset_timing_stats(); - reset_timing = FALSE; - } -} - -static void -zoom_region_sync (ZoomRegion *zoom_region) -{ - while (zoom_region->priv->q) - zoom_region_process_updates (zoom_region); -} - -static gboolean -gdk_timing_idle (gpointer data) -{ - ZoomRegion *zoom_region = data; - - /* Now update has finished, reset processing_updates */ - processing_updates = FALSE; - g_timer_stop (mag_timing.idle); - - if (timing_test) { - mag_timing.num_idle_samples++; - - gulong microseconds; - - mag_timing.idle_val = g_timer_elapsed (mag_timing.idle, - µseconds); - mag_timing.idle_total += mag_timing.idle_val; - - if (mag_timing.idle_val > timing_idle_max) - timing_idle_max = mag_timing.idle_val; - - if (zoom_region->timing_output) { - fprintf(stderr, " Pan Latency = %f (avg. %f) (max. %f) seconds\n", - mag_timing.idle_val, (mag_timing.idle_total / - mag_timing.num_idle_samples), timing_idle_max); - } - } - - return FALSE; -} - -static void -zoom_region_align (ZoomRegion *zoom_region) -{ - Magnifier *magnifier = zoom_region->priv->parent; - long x = 0, y = 0; - long width, height; - - if (timing_start) - zoom_region_time_frame(zoom_region, magnifier); - - if (timing_test) { - g_timer_start (mag_timing.frame); - - if (zoom_region->timing_output) { - gint x, y; - - gdk_drawable_get_size (GDK_DRAWABLE (zoom_region->priv->w->window), - &x, &y); - - fprintf(stderr, "\nTiming Information - ROI = (%d, %d) (%d, %d):\n", - zoom_region->roi.x1, zoom_region->roi.y1, zoom_region->roi.x2, - zoom_region->roi.y2); - fprintf(stderr, " Frame Number = %ld\n", - mag_timing.num_frame_samples + 1); - fprintf(stderr, " Width/Height/Depth = %d/%d/%d\n", x, y, - gdk_drawable_get_depth (zoom_region->priv->w->window)); - } - - /* - * The timing_start flag makes sure that we don't start displaying output - * until we have processed an entire frame. - */ - if (!timing_start) - g_timer_start (mag_timing.process); - - timing_start = TRUE; - } - - g_timer_start (mag_timing.idle); - - /* - * zoom_region_align calls - * zoom_region_moveto calls - * zoom_region_scroll calls - * zoom_region_scroll_fast or zoom_region_scroll_smooth calls - * gdk_window_scroll or gdk_window_invalidate_rect calls - * gdk_window_invalidate_region calls - * gdk_window_invalidate_maybe_recurse - * - * The last function in the stack will set up an idle handler of - * priority GDK_PRIORITY_REDRAW (gdk_window_update_idle) to be called - * to handle the work of updateing the screen. - * - * By setting up an idle handler of priority GDK_PRIORITY_REDRAW + 1, - * it will be called immediately after and we can determine when GTK+ - * is finished with the update. - */ - g_idle_add_full (GDK_PRIORITY_REDRAW + 1, - gdk_timing_idle, zoom_region, NULL); - - width = (zoom_region->viewport.x2 - - zoom_region->viewport.x1) / zoom_region->xscale; - height = (zoom_region->viewport.y2 - - zoom_region->viewport.y1) / zoom_region->yscale; - - switch (zoom_region->x_align_policy) { - case GNOME_Magnifier_ZoomRegion_ALIGN_MAX: - x = zoom_region->roi.x2 - width; - break; - case GNOME_Magnifier_ZoomRegion_ALIGN_MIN: - x = zoom_region->roi.x1; - break; - case GNOME_Magnifier_ZoomRegion_ALIGN_CENTER: - default: - x = ((zoom_region->roi.x1 + zoom_region->roi.x2) - width ) / 2; - } - - switch (zoom_region->y_align_policy) { - case GNOME_Magnifier_ZoomRegion_ALIGN_MAX: - y = zoom_region->roi.y2 - height; - break; - case GNOME_Magnifier_ZoomRegion_ALIGN_MIN: - y = zoom_region->roi.y1; - break; - case GNOME_Magnifier_ZoomRegion_ALIGN_CENTER: - default: - y = ((zoom_region->roi.y1 + zoom_region->roi.y2) - height ) / 2; - } - - zoom_region_moveto (zoom_region, x, y); -} - -static void -zoom_region_set_viewport (ZoomRegion *zoom_region, - const GNOME_Magnifier_RectBounds *viewport) -{ -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - if (zoom_region->viewport.x1 == viewport->x1 && - zoom_region->viewport.y1 == viewport->y1 && - zoom_region->viewport.x2 == viewport->x2 && - zoom_region->viewport.y2 == viewport->y2) { - return; - } - zoom_region->viewport = *viewport; -#ifdef DEBUG - fprintf (stderr, "Setting viewport %d,%d - %d,%d\n", - (int) viewport->x1, (int) viewport->y1, - (int) viewport->x2, (int) viewport->y2); -#endif - zoom_region_align (zoom_region); - if (!zoom_region->priv->w) { - zoom_region_init_window (zoom_region); - } else { - CORBA_any *any; - CORBA_Environment ev; - Bonobo_PropertyBag properties; - Magnifier *magnifier = (Magnifier *) zoom_region->priv->parent; - GtkFixed *fixed = GTK_FIXED (magnifier->priv->canvas); - gtk_fixed_move (fixed, - zoom_region->priv->border, - zoom_region->viewport.x1, - zoom_region->viewport.y1); - gtk_fixed_move (fixed, - zoom_region->priv->w, - zoom_region->viewport.x1 + - zoom_region->border_size, - zoom_region->viewport.y1 + - zoom_region->border_size); - gtk_widget_set_size_request ( - GTK_WIDGET (zoom_region->priv->border), - zoom_region->viewport.x2 - zoom_region->viewport.x1, - zoom_region->viewport.y2 - zoom_region->viewport.y1); - gtk_widget_set_size_request (GTK_WIDGET (zoom_region->priv->w), - zoom_region->viewport.x2 - - zoom_region->viewport.x1 - - zoom_region->border_size * 2, - zoom_region->viewport.y2 - - zoom_region->viewport.y1 - - zoom_region->border_size * 2); - CORBA_exception_init (&ev); - properties = - GNOME_Magnifier_Magnifier_getProperties( - BONOBO_OBJREF ( - (Magnifier *) zoom_region->priv->parent), &ev); - if (!BONOBO_EX (&ev)) - any = Bonobo_PropertyBag_getValue ( - properties, "source-display-bounds", &ev); - if (!BONOBO_EX (&ev)) - zoom_region->priv->source_area = - *((GNOME_Magnifier_RectBounds *) any->_value); - if (zoom_region->priv->pixmap) - g_object_unref (zoom_region->priv->pixmap); - zoom_region_create_pixmap (zoom_region); - if (zoom_region->priv->scaled_pixbuf) - g_object_unref (zoom_region->priv->scaled_pixbuf); - - zoom_region->priv->scaled_pixbuf = - gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, - (zoom_region->priv->source_area.x2 - - zoom_region->priv->source_area.x1) * zoom_region->xscale + 1, - (zoom_region->priv->source_area.y2 - - zoom_region->priv->source_area.y1) * zoom_region->yscale + 1); - } - zoom_region_queue_update (zoom_region, - zoom_region_source_rect_from_view_bounds ( - zoom_region, &zoom_region->viewport)); -} - -static void -zoom_region_get_property (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - ZoomRegion *zoom_region = user_data; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DBG (fprintf (stderr, "Get zoom-region property: %s\n", prop_names[arg_id])); - - switch (arg_id) { - case ZOOM_REGION_MANAGED_PROP: - BONOBO_ARG_SET_BOOLEAN (arg, zoom_region->is_managed); - break; - case ZOOM_REGION_POLL_MOUSE_PROP: - BONOBO_ARG_SET_BOOLEAN (arg, zoom_region->poll_mouse); - break; - case ZOOM_REGION_INVERT_PROP: - BONOBO_ARG_SET_BOOLEAN (arg, zoom_region->invert); - break; - case ZOOM_REGION_SMOOTHSCROLL_PROP: - BONOBO_ARG_SET_SHORT (arg, zoom_region->smooth_scroll_policy); - break; - case ZOOM_REGION_COLORBLIND_PROP: - BONOBO_ARG_SET_SHORT (arg, zoom_region->color_blind_filter); - break; - case ZOOM_REGION_TESTPATTERN_PROP: - BONOBO_ARG_SET_BOOLEAN (arg, zoom_region->priv->test); - break; - case ZOOM_REGION_SMOOTHING_PROP: - BONOBO_ARG_SET_STRING (arg, zoom_region->smoothing); - break; - case ZOOM_REGION_CONTRASTR_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->contrast_r); - break; - case ZOOM_REGION_CONTRASTG_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->contrast_g); - break; - case ZOOM_REGION_CONTRASTB_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->contrast_b); - break; - case ZOOM_REGION_BRIGHTR_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->bright_r); - break; - case ZOOM_REGION_BRIGHTG_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->bright_g); - break; - case ZOOM_REGION_BRIGHTB_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->bright_b); - break; - case ZOOM_REGION_XSCALE_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->xscale); - break; - case ZOOM_REGION_YSCALE_PROP: - BONOBO_ARG_SET_FLOAT (arg, zoom_region->yscale); - break; - case ZOOM_REGION_BORDERSIZE_PROP: - BONOBO_ARG_SET_LONG (arg, zoom_region->border_size); - break; - case ZOOM_REGION_XALIGN_PROP: - /* TODO: enums here */ - BONOBO_ARG_SET_INT (arg, zoom_region->x_align_policy); - break; - case ZOOM_REGION_YALIGN_PROP: - BONOBO_ARG_SET_INT (arg, zoom_region->y_align_policy); - break; - case ZOOM_REGION_BORDERCOLOR_PROP: - BONOBO_ARG_SET_LONG (arg, - zoom_region->border_color); - break; - case ZOOM_REGION_VIEWPORT_PROP: - BONOBO_ARG_SET_GENERAL (arg, zoom_region->viewport, - TC_GNOME_Magnifier_RectBounds, - GNOME_Magnifier_RectBounds, - NULL); - break; - case ZOOM_REGION_TIMING_TEST_PROP: - BONOBO_ARG_SET_INT (arg, zoom_region->timing_iterations); - break; - case ZOOM_REGION_TIMING_OUTPUT_PROP: - BONOBO_ARG_SET_BOOLEAN (arg, zoom_region->timing_output); - break; - case ZOOM_REGION_TIMING_PAN_RATE_PROP: - BONOBO_ARG_SET_INT (arg, zoom_region->timing_pan_rate); - break; - case ZOOM_REGION_EXIT_MAGNIFIER: - BONOBO_ARG_SET_BOOLEAN (arg, zoom_region->exit_magnifier); - break; - default: - bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound); - }; -} - -static void -zoom_region_set_property (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - ZoomRegion *zoom_region = user_data; - GNOME_Magnifier_RectBounds bounds; - gfloat t; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DBG (fprintf (stderr, "Set zoom-region property: %s\n", prop_names[arg_id])); - - switch (arg_id) { - case ZOOM_REGION_MANAGED_PROP: - zoom_region->is_managed = BONOBO_ARG_GET_BOOLEAN (arg); - break; - case ZOOM_REGION_POLL_MOUSE_PROP: - zoom_region->poll_mouse = BONOBO_ARG_GET_BOOLEAN (arg); - if (zoom_region->poll_mouse) - { - g_message ("Adding polling timer"); - zoom_region->priv->update_pointer_id = - g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, - 200, - zoom_region_update_pointer_timeout, - zoom_region, - NULL); - } - else if (zoom_region->priv->update_pointer_id) - { - g_message ("Removing polling timer"); - g_source_remove (zoom_region->priv->update_pointer_id); - zoom_region->priv->update_pointer_id = 0; - } - break; - case ZOOM_REGION_INVERT_PROP: - zoom_region->invert = BONOBO_ARG_GET_BOOLEAN (arg); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_SMOOTHSCROLL_PROP: - zoom_region->smooth_scroll_policy = BONOBO_ARG_GET_SHORT (arg); - break; - case ZOOM_REGION_COLORBLIND_PROP: - zoom_region->color_blind_filter = BONOBO_ARG_GET_SHORT (arg); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_SMOOTHING_PROP: - zoom_region->smoothing = BONOBO_ARG_GET_STRING (arg); - if (!strncmp (zoom_region->smoothing, "bilinear", 8)) - zoom_region->priv->gdk_interp_type = GDK_INTERP_BILINEAR; - else - zoom_region->priv->gdk_interp_type = GDK_INTERP_NEAREST; - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_TESTPATTERN_PROP: - zoom_region->priv->test = BONOBO_ARG_GET_BOOLEAN (arg); - if (zoom_region->priv->source_drawable) { - g_object_unref (zoom_region->priv->source_drawable); - zoom_region->priv->source_drawable = NULL; - } - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_CONTRASTR_PROP: - zoom_region->contrast_r = - CLAMP_B_C (BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_CONTRASTG_PROP: - zoom_region->contrast_g = - CLAMP_B_C (BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_CONTRASTB_PROP: - zoom_region->contrast_b = - CLAMP_B_C (BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_BRIGHTR_PROP: - zoom_region->bright_r = - CLAMP_B_C (BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_BRIGHTG_PROP: - zoom_region->bright_g = - CLAMP_B_C (BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_BRIGHTB_PROP: - zoom_region->bright_b = - CLAMP_B_C (BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_XSCALE_PROP: - (void) zoom_region_update_scale (zoom_region, - BONOBO_ARG_GET_FLOAT (arg), - zoom_region->yscale); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_YSCALE_PROP: - (void) zoom_region_update_scale (zoom_region, - zoom_region->xscale, - BONOBO_ARG_GET_FLOAT (arg)); - zoom_region_update_current (zoom_region); - break; - case ZOOM_REGION_BORDERSIZE_PROP: - zoom_region->border_size = BONOBO_ARG_GET_LONG (arg); - gtk_widget_set_size_request ( - GTK_WIDGET (zoom_region->priv->border), - zoom_region->viewport.x2 - - zoom_region->viewport.x1, - zoom_region->viewport.y2 - - zoom_region->viewport.y1); - gtk_widget_set_size_request (GTK_WIDGET (zoom_region->priv->w), - zoom_region->viewport.x2 - - zoom_region->viewport.x1 - - zoom_region->border_size * 2, - zoom_region->viewport.y2 - - zoom_region->viewport.y1 - - zoom_region->border_size * 2); - gtk_fixed_move (GTK_FIXED (((Magnifier *)zoom_region->priv->parent)->priv->canvas), zoom_region->priv->border, zoom_region->viewport.x1, zoom_region->viewport.y1); - gtk_fixed_move (GTK_FIXED (((Magnifier *)zoom_region->priv->parent)->priv->canvas), zoom_region->priv->w, zoom_region->viewport.x1 + zoom_region->border_size, zoom_region->viewport.y1 + zoom_region->border_size); - break; - case ZOOM_REGION_BORDERCOLOR_PROP: - zoom_region->border_color = - BONOBO_ARG_GET_LONG (arg); - zoom_region_paint_border (zoom_region); - break; - case ZOOM_REGION_XALIGN_PROP: - zoom_region->x_align_policy = BONOBO_ARG_GET_INT (arg); - zoom_region_align (zoom_region); - break; - case ZOOM_REGION_YALIGN_PROP: - /* TODO: enums here */ - zoom_region->y_align_policy = BONOBO_ARG_GET_INT (arg); - zoom_region_align (zoom_region); - break; - case ZOOM_REGION_VIEWPORT_PROP: - bounds = BONOBO_ARG_GET_GENERAL (arg, - TC_GNOME_Magnifier_RectBounds, - GNOME_Magnifier_RectBounds, - NULL); - zoom_region_set_viewport (zoom_region, &bounds); - break; - case ZOOM_REGION_TIMING_TEST_PROP: - zoom_region->timing_iterations = BONOBO_ARG_GET_INT (arg); - timing_test = TRUE; - break; - case ZOOM_REGION_TIMING_OUTPUT_PROP: - zoom_region->timing_output = BONOBO_ARG_GET_BOOLEAN (arg); - break; - case ZOOM_REGION_TIMING_PAN_RATE_PROP: - zoom_region->timing_pan_rate = BONOBO_ARG_GET_INT (arg); - timing_test = TRUE; - break; - case ZOOM_REGION_EXIT_MAGNIFIER: - zoom_region->exit_magnifier = BONOBO_ARG_GET_BOOLEAN (arg); - break; - default: - bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound); - }; -} - -static int -zoom_region_process_pending (gpointer data) -{ - ZoomRegion *zoom_region = (ZoomRegion *) data; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - zoom_region_align (zoom_region); - return FALSE; -} - -static int -zoom_region_pan_test (gpointer data) -{ - ZoomRegion *zoom_region = (ZoomRegion *) data; - Magnifier *magnifier = zoom_region->priv->parent; - GNOME_Magnifier_ZoomRegionList *zoom_regions; - GNOME_Magnifier_RectBounds roi; - CORBA_Environment ev; - static int counter = 0; - static gboolean finished_update = !TRUE; - static float last_pixels_at_speed = -1; - float pixels_at_speed; - float total_time; - int screen_height, height; - int pixel_position; - int pixel_direction; - - screen_height = gdk_screen_get_height ( - gdk_display_get_screen (magnifier->source_display, - magnifier->source_screen_num)); - - height = (zoom_region->viewport.y2 - - zoom_region->viewport.y1) / zoom_region->yscale; - - roi.x1 = zoom_region->roi.x1; - roi.x2 = zoom_region->roi.x2; - - g_timer_stop (mag_timing.process); - - gulong microseconds; - - total_time = g_timer_elapsed (mag_timing.process, µseconds); - - if (mag_timing.frame_total != 0.0) - pixels_at_speed = total_time * zoom_region->timing_pan_rate; - else - pixels_at_speed = 0.0; - - /* Wait until it is actually necessary to update the screen */ - if ((int)(last_pixels_at_speed) == (int)(pixels_at_speed)) - return TRUE; - - pixel_position = (int)(pixels_at_speed) % (screen_height - height); - counter = (int)(pixels_at_speed) / (screen_height - height); - pixel_direction = counter % 2; - - if (!finished_update) { - if ((int)(pixels_at_speed) > (zoom_region->roi.y1 + height)) - roi.y1 = zoom_region->roi.y1 + height; - else - roi.y1 = (int)(pixels_at_speed); - - if (roi.y1 >= screen_height - height) { - roi.y1 = screen_height - height; - } - } else { - if (pixel_direction == 0) - roi.y1 = screen_height - height - pixel_position; - else - roi.y1 = pixel_position; - } - - roi.y2 = roi.y1 + height; - magnifier->priv->cursor_x = (roi.x2 + roi.x1) / 2; - magnifier->priv->cursor_y = (roi.y2 + roi.y1) / 2; - - /* Add one since in first loop we call zoom_region_process_updates */ - if (counter > zoom_region->timing_iterations - 1) - zoom_region->exit_magnifier = TRUE; - - zoom_regions = GNOME_Magnifier_Magnifier_getZoomRegions ( - BONOBO_OBJREF (magnifier), &ev); - - if (zoom_regions && (zoom_regions->_length > 0)) { - GNOME_Magnifier_ZoomRegion_setROI ( - zoom_regions->_buffer[0], &roi, &ev); - } - - if (!finished_update) { - zoom_region_process_updates(zoom_region); - if (roi.y1 == screen_height - height) { - finished_update = TRUE; - reset_timing = TRUE; - } - } - - last_pixels_at_speed = pixels_at_speed; - - return FALSE; -} - -static void -impl_zoom_region_set_pointer_pos (PortableServer_Servant servant, - const CORBA_long mouse_x, - const CORBA_long mouse_y, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - GdkRectangle paint_area, *clip = NULL; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DBG (fprintf (stderr, "Set Pointer: \t%ld,%ld\n", - (long) mouse_x, (long) mouse_y)); - - fprintf (stderr, "Set Pointer: \t%ld,%ld\n", - (long) mouse_x, (long) mouse_y); - - zoom_region_set_cursor_pos (zoom_region, (int) mouse_x, (int) mouse_y); - - if (GTK_IS_WIDGET (zoom_region->priv->w) && - GDK_IS_DRAWABLE (zoom_region->priv->w->window)) - { - gdk_drawable_get_size ( - GDK_DRAWABLE ( - zoom_region->priv->w->window), - &paint_area.width, &paint_area.height); - paint_area.x = 0; - paint_area.y = 0; - clip = &paint_area; - paint_area = zoom_region_clip_to_source ( - zoom_region, paint_area); - } - /* - * if we update the cursor now, it causes flicker if the client - * subsequently calls setROI, so we wait for a redraw. - * Perhaps we should cue a redraw on idle instead? - */ -} - -static void -impl_zoom_region_set_contrast (PortableServer_Servant servant, - const CORBA_float R, - const CORBA_float G, - const CORBA_float B, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - gfloat t; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DBG (fprintf (stderr, "Set contrast: \t%f,%f %f\n", R, G, B)); - - /* if the contrast values are the same, this is a NOOP */ - if (zoom_region->contrast_r == R && - zoom_region->contrast_g == G && - zoom_region->contrast_b == B) - return; - - zoom_region->contrast_r = CLAMP_B_C (R); - zoom_region->contrast_g = CLAMP_B_C (G); - zoom_region->contrast_b = CLAMP_B_C (B); - - zoom_region_update_current (zoom_region); -} - -static void -impl_zoom_region_get_contrast (PortableServer_Servant servant, - CORBA_float *R, - CORBA_float *G, - CORBA_float *B, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - - *R = zoom_region->contrast_r; - *G = zoom_region->contrast_g; - *B = zoom_region->contrast_b; -} - -static void -impl_zoom_region_set_brightness (PortableServer_Servant servant, - const CORBA_float R, - const CORBA_float G, - const CORBA_float B, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - gfloat t; - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DBG (fprintf (stderr, "Set brightness: \t%f,%f %f\n", R, G, B)); - - /* if the contrast values are the same, this is a NOOP */ - if (zoom_region->bright_r == R && - zoom_region->bright_g == G && - zoom_region->bright_b == B) - return; - - zoom_region->bright_r = CLAMP_B_C (R); - zoom_region->bright_g = CLAMP_B_C (G); - zoom_region->bright_b = CLAMP_B_C (B); - - zoom_region_update_current (zoom_region); -} - -static void -impl_zoom_region_get_brightness (PortableServer_Servant servant, - CORBA_float *R, - CORBA_float *G, - CORBA_float *B, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - - *R = zoom_region->bright_r; - *G = zoom_region->bright_g; - *B = zoom_region->bright_b; -} - -static void -impl_zoom_region_set_roi (PortableServer_Servant servant, - const GNOME_Magnifier_RectBounds *bounds, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DBG (fprintf (stderr, "Set ROI: \t%d,%d %d,%d\n", - bounds->x1, bounds->y1, bounds->x2, bounds->y2)); - - if ((zoom_region->roi.x1 == bounds->x1) && - (zoom_region->roi.x2 == bounds->x2) && - (zoom_region->roi.y1 == bounds->y1) && - (zoom_region->roi.y2 == bounds->y2)) { - return; - } - - /* if these bounds are clearly bogus, warn and ignore */ - if (!bounds || (bounds->x2 <= bounds->x1) - || (bounds->y2 < bounds->y1) || - ((bounds->x1 + bounds->x2)/2 < 0) || - ((bounds->y1 + bounds->y2)/2 < 0)) - { - g_warning ("Bad bounds request (%d,%d to %d,%d), ignoring.\n", - bounds->x1, bounds->y1, bounds->x2, bounds->y2); - return; - } - - zoom_region->roi = *bounds; - - if (zoom_region->timing_pan_rate > 0) { - /* Set idle handler to do panning test */ - g_idle_add_full (GDK_PRIORITY_REDRAW + 3, - zoom_region_pan_test, zoom_region, NULL); - } - - if (zoom_region->exit_magnifier) { - if (timing_test) { - fprintf(stderr, "\n### Timing Summary:\n\n"); - if (zoom_region->timing_pan_rate) - fprintf(stderr, " Pan Rate = %d\n", zoom_region->timing_pan_rate); - timing_report(zoom_region); - } - exit(0); - } - - /* - * Do not bother trying to update the screen if the last - * screen update has not had time to complete. - */ - if (processing_updates) { - /* Remove any previous idle handler */ - if (pending_idle_handler != 0) { - g_source_remove(pending_idle_handler); - pending_idle_handler = 0; - } - - /* Set idle handler to process this pending update when possible */ - - pending_idle_handler = g_idle_add_full (GDK_PRIORITY_REDRAW + 2, - zoom_region_process_pending, zoom_region, NULL); - - if (zoom_region->timing_output) { - fprintf(stderr, - "\n [Last update not finished, pending - ROI=(%d, %d) (%d, %d)]\n\n", - zoom_region->roi.x1, zoom_region->roi.y1, zoom_region->roi.x2, - zoom_region->roi.y2); - } - } else { - zoom_region_align (zoom_region); - } -} - -static CORBA_boolean -impl_zoom_region_set_mag_factor (PortableServer_Servant servant, - const CORBA_float mag_factor_x, - const CORBA_float mag_factor_y, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - CORBA_any *any; - CORBA_boolean retval = CORBA_TRUE; - - if ((zoom_region->xscale == mag_factor_x) && - (zoom_region->yscale == mag_factor_y)) { - return retval; - } - - /* TODO: assert that parent is magnifier object */ - Bonobo_PropertyBag properties = - GNOME_Magnifier_Magnifier_getProperties( - BONOBO_OBJREF ( - (Magnifier *) zoom_region->priv->parent), ev); - any = Bonobo_PropertyBag_getValue ( - properties, "source-display-bounds", ev); - if (!BONOBO_EX (ev)) - zoom_region->priv->source_area = - *((GNOME_Magnifier_RectBounds *) any->_value); - else - retval = CORBA_FALSE; - - retval = zoom_region_update_scale (zoom_region, - mag_factor_x, mag_factor_y); - - zoom_region_update_current (zoom_region); - zoom_region_sync (zoom_region); - - bonobo_object_release_unref (properties, NULL); - return retval; -} - -static void -impl_zoom_region_get_mag_factor (PortableServer_Servant servant, - CORBA_float *mag_factor_x, - CORBA_float *mag_factor_y, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - *mag_factor_x = zoom_region->xscale; - *mag_factor_y = zoom_region->yscale; -} - -static Bonobo_PropertyBag -impl_zoom_region_get_properties (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - return bonobo_object_dup_ref ( - BONOBO_OBJREF (zoom_region->properties), ev); -} - -static void -impl_zoom_region_mark_dirty (PortableServer_Servant servant, - const GNOME_Magnifier_RectBounds *roi_dirty, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - DEBUG_RECT ("mark dirty", zoom_region_rect_from_bounds ( - zoom_region, roi_dirty) ); - - zoom_region_update_pointer (zoom_region, TRUE); - /* XXX ? should we clip here, or wait till process_updates? */ - zoom_region_queue_update (zoom_region, - zoom_region_clip_to_source (zoom_region, - zoom_region_rect_from_bounds (zoom_region, roi_dirty))); -} - -static GNOME_Magnifier_RectBounds -impl_zoom_region_get_roi (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - return zoom_region->roi; -} - -static void -impl_zoom_region_move_resize (PortableServer_Servant servant, - const GNOME_Magnifier_RectBounds *viewport_bounds, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - -#ifdef ZOOM_REGION_DEBUG - g_assert (zoom_region->alive); -#endif - zoom_region_set_viewport (zoom_region, viewport_bounds); -} - -/* could be called multiple times... */ -static void -zoom_region_do_dispose (ZoomRegion *zoom_region) -{ - DBG(g_message ("disposing region %p", zoom_region)); - if (zoom_region->priv && zoom_region->priv->expose_handler_id && - GTK_IS_WIDGET (zoom_region->priv->w)) { - g_signal_handler_disconnect ( - zoom_region->priv->w, - zoom_region->priv->expose_handler_id); - zoom_region->priv->expose_handler_id = 0; - } - if (zoom_region->priv && zoom_region->priv->update_pointer_id) - g_source_remove (zoom_region->priv->update_pointer_id); - if (zoom_region->priv && zoom_region->priv->update_handler_id) - g_source_remove (zoom_region->priv->update_handler_id); - g_idle_remove_by_data (zoom_region); - -#ifdef ZOOM_REGION_DEBUG - zoom_region->alive = FALSE; -#endif -} - -static void -impl_zoom_region_dispose (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - ZoomRegion *zoom_region = - ZOOM_REGION (bonobo_object_from_servant (servant)); - zoom_region_do_dispose (zoom_region); -} - - -/* could be called multiple times */ -static void -zoom_region_dispose (GObject *object) -{ - ZoomRegion *zoom_region = ZOOM_REGION (object); - - zoom_region_do_dispose (zoom_region); - - BONOBO_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); -} - -static void -zoom_region_class_init (ZoomRegionClass *klass) -{ - GObjectClass * object_class = (GObjectClass *) klass; - POA_GNOME_Magnifier_ZoomRegion__epv *epv = &klass->epv; - parent_class = g_type_class_peek (BONOBO_TYPE_OBJECT); /* needed by BONOBO_CALL_PARENT! */ - - object_class->dispose = zoom_region_dispose; - object_class->finalize = zoom_region_finalize; - - epv->setMagFactor = impl_zoom_region_set_mag_factor; - epv->getMagFactor = impl_zoom_region_get_mag_factor; - epv->getProperties = impl_zoom_region_get_properties; - epv->setROI = impl_zoom_region_set_roi; - epv->setPointerPos = impl_zoom_region_set_pointer_pos; - epv->markDirty = impl_zoom_region_mark_dirty; - epv->getROI = impl_zoom_region_get_roi; - epv->moveResize = impl_zoom_region_move_resize; - epv->dispose = impl_zoom_region_dispose; - epv->setContrast = impl_zoom_region_set_contrast; - epv->getContrast = impl_zoom_region_get_contrast; - epv->setBrightness = impl_zoom_region_set_brightness; - epv->getBrightness = impl_zoom_region_get_brightness; - - reset_timing_stats(); -#ifdef DEBUG_CLIENT_CALLS - client_debug = (g_getenv ("MAG_CLIENT_DEBUG") != NULL); -#endif -} - -static void -zoom_region_properties_init (ZoomRegion *zoom_region) -{ - BonoboArg *def; - - zoom_region->properties = - bonobo_property_bag_new_closure ( - g_cclosure_new_object ( - G_CALLBACK (zoom_region_get_property), - G_OBJECT (zoom_region)), - g_cclosure_new_object ( - G_CALLBACK (zoom_region_set_property), - G_OBJECT (zoom_region))); - - def = bonobo_arg_new (BONOBO_ARG_BOOLEAN); - BONOBO_ARG_SET_BOOLEAN (def, TRUE); - - bonobo_property_bag_add (zoom_region->properties, - "is-managed", - ZOOM_REGION_MANAGED_PROP, - BONOBO_ARG_BOOLEAN, - def, - "If false, zoom region does not auto-update, but is drawn into directly by the client", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_BOOLEAN); - BONOBO_ARG_SET_BOOLEAN (def, TRUE); - - bonobo_property_bag_add (zoom_region->properties, - "poll-mouse", - ZOOM_REGION_POLL_MOUSE_PROP, - BONOBO_ARG_BOOLEAN, - NULL, - "If false, zoom region does not poll for pointer location, but is (exclusively) given it by the client", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_SHORT); - BONOBO_ARG_SET_SHORT (def, GNOME_Magnifier_ZoomRegion_SCROLL_FASTEST); - - bonobo_property_bag_add (zoom_region->properties, - "smooth-scroll-policy", - ZOOM_REGION_SMOOTHSCROLL_PROP, - BONOBO_ARG_SHORT, - def, - "scrolling policy, slower versus faster", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_SHORT); - BONOBO_ARG_SET_SHORT ( - def, - GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_NO_FILTER); - - bonobo_property_bag_add (zoom_region->properties, - "color-blind-filter", - ZOOM_REGION_COLORBLIND_PROP, - BONOBO_ARG_SHORT, - def, - "color blind filter to apply in an image", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_BOOLEAN); - BONOBO_ARG_SET_BOOLEAN (def, FALSE); - - bonobo_property_bag_add (zoom_region->properties, - "use-test-pattern", - ZOOM_REGION_TESTPATTERN_PROP, - BONOBO_ARG_BOOLEAN, - def, - "use test pattern for source", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_BOOLEAN); - BONOBO_ARG_SET_BOOLEAN (def, TRUE); - - bonobo_property_bag_add (zoom_region->properties, - "inverse-video", - ZOOM_REGION_INVERT_PROP, - BONOBO_ARG_BOOLEAN, - def, - "inverse video display", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - - bonobo_property_bag_add (zoom_region->properties, - "smoothing-type", - ZOOM_REGION_SMOOTHING_PROP, - BONOBO_ARG_STRING, - NULL, - "image smoothing algorithm used", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 0.0); - - bonobo_property_bag_add (zoom_region->properties, - "red-contrast", - ZOOM_REGION_CONTRASTR_PROP, - BONOBO_ARG_FLOAT, - def, - "red image contrast ratio", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 0.0); - - bonobo_property_bag_add (zoom_region->properties, - "green-contrast", - ZOOM_REGION_CONTRASTG_PROP, - BONOBO_ARG_FLOAT, - def, - "green image contrast ratio", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 0.0); - - bonobo_property_bag_add (zoom_region->properties, - "blue-contrast", - ZOOM_REGION_CONTRASTB_PROP, - BONOBO_ARG_FLOAT, - def, - "blue image contrast ratio", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 0.0); - - bonobo_property_bag_add (zoom_region->properties, - "red-brightness", - ZOOM_REGION_BRIGHTR_PROP, - BONOBO_ARG_FLOAT, - def, - "red image brightness ratio", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 0.0); - - bonobo_property_bag_add (zoom_region->properties, - "green-brightness", - ZOOM_REGION_BRIGHTG_PROP, - BONOBO_ARG_FLOAT, - def, - "green image brightness ratio", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 0.0); - - bonobo_property_bag_add (zoom_region->properties, - "blue-brightness", - ZOOM_REGION_BRIGHTB_PROP, - BONOBO_ARG_FLOAT, - def, - "blue image brightness ratio", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 2.0); - - bonobo_property_bag_add (zoom_region->properties, - "mag-factor-x", - ZOOM_REGION_XSCALE_PROP, - BONOBO_ARG_FLOAT, - def, - "x scale factor", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_FLOAT); - BONOBO_ARG_SET_FLOAT (def, 2.0); - - bonobo_property_bag_add (zoom_region->properties, - "mag-factor-y", - ZOOM_REGION_YSCALE_PROP, - BONOBO_ARG_FLOAT, - def, - "y scale factor", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_LONG); - BONOBO_ARG_SET_LONG (def, 0); - - bonobo_property_bag_add (zoom_region->properties, - "border-size", - ZOOM_REGION_BORDERSIZE_PROP, - BONOBO_ARG_LONG, - def, - "size of zoom-region borders, in pixels", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_LONG); - BONOBO_ARG_SET_LONG (def, 0x00000000); - - bonobo_property_bag_add (zoom_region->properties, - "border-color", - ZOOM_REGION_BORDERCOLOR_PROP, - BONOBO_ARG_LONG, - def, - "border color, as RGBA32", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_INT); - BONOBO_ARG_SET_INT (def, 0); - - bonobo_property_bag_add (zoom_region->properties, - "x-alignment", - ZOOM_REGION_XALIGN_PROP, - BONOBO_ARG_INT, - def, - "x-alignment policy for this region", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - def = bonobo_arg_new (BONOBO_ARG_INT); - BONOBO_ARG_SET_INT (def, 0); - - bonobo_property_bag_add (zoom_region->properties, - "y-alignment", - ZOOM_REGION_YALIGN_PROP, - BONOBO_ARG_INT, - def, - "y-alignment policy for this region", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - bonobo_property_bag_add (zoom_region->properties, - "viewport", - ZOOM_REGION_VIEWPORT_PROP, - TC_GNOME_Magnifier_RectBounds, - NULL, - "viewport bounding box", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - def = bonobo_arg_new (BONOBO_ARG_INT); - BONOBO_ARG_SET_INT (def, 0); - - bonobo_property_bag_add (zoom_region->properties, - "timing-iterations", - ZOOM_REGION_TIMING_TEST_PROP, - BONOBO_ARG_INT, - def, - "timing iterations", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_BOOLEAN); - BONOBO_ARG_SET_BOOLEAN (def, FALSE); - - bonobo_property_bag_add (zoom_region->properties, - "timing-output", - ZOOM_REGION_TIMING_OUTPUT_PROP, - BONOBO_ARG_BOOLEAN, - def, - "timing output", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_INT); - BONOBO_ARG_SET_INT (def, 0); - - bonobo_property_bag_add (zoom_region->properties, - "timing-pan-rate", - ZOOM_REGION_TIMING_PAN_RATE_PROP, - BONOBO_ARG_INT, - def, - "timing pan rate", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - bonobo_arg_release (def); - - def = bonobo_arg_new (BONOBO_ARG_BOOLEAN); - BONOBO_ARG_SET_BOOLEAN (def, FALSE); - - bonobo_property_bag_add (zoom_region->properties, - "exit-magnifier", - ZOOM_REGION_EXIT_MAGNIFIER, - BONOBO_ARG_BOOLEAN, - def, - "timing output", - Bonobo_PROPERTY_READABLE | - Bonobo_PROPERTY_WRITEABLE); - - bonobo_arg_release (def); - -} - -static void -zoom_region_private_init (ZoomRegionPrivate *priv) -{ - GdkRectangle rect = {0, 0, 0, 0}; - GNOME_Magnifier_RectBounds rectbounds = {0, 0, 0, 0}; - priv->parent = NULL; - priv->w = NULL; - priv->default_gc = NULL; - priv->paint_cursor_gc = NULL; - priv->crosswire_gc = NULL; - priv->q = NULL; - priv->scaled_pixbuf = NULL; - priv->source_pixbuf_cache = NULL; - priv->source_drawable = NULL; - priv->pixmap = NULL; - priv->cursor_backing_rect = rect; - priv->cursor_backing_pixels = NULL; - priv->gdk_interp_type = GDK_INTERP_NEAREST; - priv->expose_handler_id = 0; - priv->test = FALSE; - priv->last_cursor_pos.x = 0; - priv->last_cursor_pos.y = 0; - priv->last_drawn_crosswire_pos.x = 0; - priv->last_drawn_crosswire_pos.y = 0; - priv->exposed_bounds = rectbounds; - priv->source_area = rectbounds; - priv->update_pointer_id = 0; - priv->update_handler_id = 0; -} - -static void -zoom_region_init (ZoomRegion *zoom_region) -{ - DBG(g_message ("initializing region %p", zoom_region)); - - zoom_region_properties_init (zoom_region); - zoom_region->smooth_scroll_policy = - GNOME_Magnifier_ZoomRegion_SCROLL_SMOOTH; - zoom_region->color_blind_filter = - GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_NO_FILTER; - zoom_region->contrast_r = 0.0; - zoom_region->contrast_g = 0.0; - zoom_region->contrast_b = 0.0; - zoom_region->bright_r = 0.0; - zoom_region->bright_g = 0.0; - zoom_region->bright_b = 0.0; - zoom_region->invert = FALSE; - zoom_region->cache_source = FALSE; - zoom_region->border_size = 0; - zoom_region->border_color = 0; - zoom_region->roi.x1 = 0; - zoom_region->roi.x1 = 0; - zoom_region->roi.x2 = 1; - zoom_region->roi.x2 = 1; - zoom_region->x_align_policy = GNOME_Magnifier_ZoomRegion_ALIGN_CENTER; - zoom_region->y_align_policy = GNOME_Magnifier_ZoomRegion_ALIGN_CENTER; - zoom_region->coalesce_func = _coalesce_update_rects; - zoom_region->poll_mouse = TRUE; - zoom_region->priv = g_malloc (sizeof (ZoomRegionPrivate)); - zoom_region_private_init (zoom_region->priv); - bonobo_object_add_interface (BONOBO_OBJECT (zoom_region), - BONOBO_OBJECT (zoom_region->properties)); - zoom_region->timing_output = FALSE; -#ifdef ZOOM_REGION_DEBUG - zoom_region->alive = TRUE; -#endif - zoom_region->priv->update_pointer_id = - g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, - 200, - zoom_region_update_pointer_timeout, - zoom_region, - NULL); -} - -ZoomRegion * -zoom_region_new (void) -{ - return g_object_new (zoom_region_get_type(), NULL); -} - -/* this one really shuts down the object - called once only */ -static void -zoom_region_finalize (GObject *region) -{ - ZoomRegion *zoom_region = (ZoomRegion *) region; - - DBG(g_message ("finalizing region %p", zoom_region)); - - if (zoom_region->priv && zoom_region->priv->q) - { - g_list_free (zoom_region->priv->q); - zoom_region->priv->q = NULL; - } - if (GTK_IS_WIDGET (zoom_region->priv->w)) - gtk_container_remove (GTK_CONTAINER (((Magnifier *) zoom_region->priv->parent)->priv->canvas), GTK_WIDGET (zoom_region->priv->w)); - if (GTK_IS_WIDGET (zoom_region->priv->border)) - gtk_container_remove (GTK_CONTAINER (((Magnifier *) zoom_region->priv->parent)->priv->canvas), GTK_WIDGET (zoom_region->priv->border)); - if (zoom_region->priv->source_pixbuf_cache) - g_object_unref (zoom_region->priv->source_pixbuf_cache); - if (zoom_region->priv->scaled_pixbuf) - g_object_unref (zoom_region->priv->scaled_pixbuf); - if (zoom_region->priv->pixmap) - g_object_unref (zoom_region->priv->pixmap); - zoom_region->priv->pixmap = NULL; - zoom_region->priv->parent = NULL; - if (zoom_region->priv->cursor_backing_pixels) - g_object_unref (zoom_region->priv->cursor_backing_pixels); - g_free (zoom_region->priv); - zoom_region->priv = NULL; -#ifdef ZOOM_REGION_DEBUG - zoom_region->alive = FALSE; -#endif - BONOBO_CALL_PARENT (G_OBJECT_CLASS, finalize, (region)); -} - -BONOBO_TYPE_FUNC_FULL (ZoomRegion, - GNOME_Magnifier_ZoomRegion, - BONOBO_TYPE_OBJECT, - zoom_region); |