⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zoom-region.c

📁 在Linux下实现magnification功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 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_CALLSstatic gboolean client_debug = FALSE;#define DBG(a) if (client_debug) { (a); }#else#define DBG(a) #endifstatic 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_CALLSgchar* 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"};#endiftypedef 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_CURSORstatic Cursor *x_cursors;static Window cursor_window = None;#endifstatic 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);voidreset_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) #endifstatic 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -