[gnome-mag/cairo-port: 6/8] Convert cursor drawing to Cairo
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-mag/cairo-port: 6/8] Convert cursor drawing to Cairo
- Date: Fri, 13 Aug 2010 02:29:59 +0000 (UTC)
commit 548f6aef172920fa22badc9585e34120b3bf0c6e
Author: Benjamin Otte <otte redhat com>
Date: Fri Aug 13 03:33:45 2010 +0200
Convert cursor drawing to Cairo
NB: This removes the cursor coloring property. From looking at the code,
it didn't seem to work anyway.
magnifier/magnifier-main.c | 8 +-
magnifier/magnifier-private.h | 7 +-
magnifier/magnifier.c | 329 ++++++++++++++++-------------------------
magnifier/magnifier.h | 17 +-
magnifier/x11/gmag-cursor.c | 92 +++++-------
magnifier/x11/gmag-cursor.h | 12 +-
magnifier/zoom-region.c | 123 +++++++---------
7 files changed, 233 insertions(+), 355 deletions(-)
---
diff --git a/magnifier/magnifier-main.c b/magnifier/magnifier-main.c
index f09e3c7..bc5f2bc 100644
--- a/magnifier/magnifier-main.c
+++ b/magnifier/magnifier-main.c
@@ -42,8 +42,8 @@
ZoomRegion *zoom_region;
typedef struct {
- gchar *target_display;
- gchar *source_display;
+ const gchar *target_display;
+ const gchar *source_display;
gchar *cursor_set;
gchar *smoothing_type;
gdouble zoom_factor;
@@ -53,7 +53,6 @@ typedef struct {
gint mouse_poll_time;
gint cursor_size;
gdouble cursor_scale_factor;
- gint64 cursor_color;
gboolean vertical_split;
gboolean horizontal_split;
gboolean fullscreen;
@@ -90,7 +89,6 @@ static MagnifierOptions global_options = { NULL, /* target_display */
50, /* mouse_poll_time */
0, /* cursor_size */
0.0F, /* cursor_scale_factor */
- 0xFF000000,/* cursor_color */
0, /* vertical_split */
0, /* horizontal_split */
0, /* fullscreen */
@@ -122,7 +120,6 @@ static GOptionEntry magnifier_options [] = {
{"cursor-set", 0, 0, G_OPTION_ARG_STRING, &global_options.cursor_set, "cursor set to use in target display", NULL},
{"cursor-size", 0, 0, G_OPTION_ARG_INT, &global_options.cursor_size, "cursor size to use (overrides cursor-scale-factor)", NULL},
{"cursor-scale-factor", 0, 0, G_OPTION_ARG_DOUBLE, &global_options.cursor_scale_factor, "cursor scale factor", NULL},
- {"cursor-color", 0, 0, G_OPTION_ARG_INT64, &global_options.cursor_color, "cursor color (applied to \'black\' pixels)", NULL},
{"vertical", 'v', 0, G_OPTION_ARG_NONE, &global_options.vertical_split, "split screen vertically (if target display = source display)", NULL},
{"horizontal", 'h', 0, G_OPTION_ARG_NONE, &global_options.horizontal_split, "split screen horizontally (if target display = source display)", NULL},
{"mouse-follow", 'm', 0, G_OPTION_ARG_NONE, &global_options.mouse_follow, "track mouse movements", NULL},
@@ -383,7 +380,6 @@ main (int argc, char** argv)
"cursor-size", global_options.cursor_size,
"cursor-scale-factor", global_options.cursor_scale_factor != 0.0F ?
global_options.cursor_scale_factor : global_options.zoom_factor,
- "cursor-color", global_options.cursor_color,
NULL);
if (!global_options.show_crosswires)
diff --git a/magnifier/magnifier-private.h b/magnifier/magnifier-private.h
index 621beef..86e8f58 100644
--- a/magnifier/magnifier-private.h
+++ b/magnifier/magnifier-private.h
@@ -32,15 +32,10 @@ struct _MagnifierPrivate {
GdkWindow *root;
GdkWindow *overlay;
GdkPixmap *source_drawable;
- GdkDrawable *cursor;
- int cursor_default_size_x;
- int cursor_default_size_y;
+ cairo_surface_t *cursor;
gboolean crosswire;
- GdkBitmap *cursor_mask;
int cursor_x;
int cursor_y;
- int cursor_hotspot_x;
- int cursor_hotspot_y;
gboolean use_source_cursor;
GHashTable *cursorlist;
guint dbus_object_id;
diff --git a/magnifier/magnifier.c b/magnifier/magnifier.c
index efca61e..515a288 100644
--- a/magnifier/magnifier.c
+++ b/magnifier/magnifier.c
@@ -53,7 +53,6 @@ enum {
MAGNIFIER_CURSOR_SET_PROP,
MAGNIFIER_CURSOR_SIZE_PROP,
MAGNIFIER_CURSOR_ZOOM_PROP,
- MAGNIFIER_CURSOR_HOTSPOT_PROP,
MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP,
MAGNIFIER_CROSSWIRE_SIZE_PROP,
MAGNIFIER_CROSSWIRE_LENGTH_PROP,
@@ -172,90 +171,53 @@ magnifier_zoom_regions_mark_dirty (Magnifier *magnifier, RectBounds rect_bounds)
}
void
-magnifier_set_cursor_from_pixbuf (Magnifier *magnifier,
- GdkPixbuf *cursor_pixbuf)
+magnifier_set_cursor_from_surface (Magnifier *magnifier,
+ cairo_surface_t *cursor_surface)
{
- GdkPixmap *pixmap, *mask;
- gint width, height;
- GdkGC *gc;
- GdkDrawable *drawable = gtk_widget_get_window (GTK_WIDGET (magnifier));
-
if (magnifier->priv->cursor) {
- g_object_unref (magnifier->priv->cursor);
+ cairo_surface_destroy (magnifier->priv->cursor);
magnifier->priv->cursor = NULL;
}
- if (drawable && cursor_pixbuf) {
- const gchar *xhot_string = NULL, *yhot_string = NULL;
- width = gdk_pixbuf_get_width (cursor_pixbuf);
- height = gdk_pixbuf_get_height (cursor_pixbuf);
- pixmap = gdk_pixmap_new (drawable, width, height, -1);
- gc = gdk_gc_new (pixmap);
- if (GDK_IS_DRAWABLE (pixmap))
- gdk_draw_pixbuf (pixmap, gc, cursor_pixbuf, 0, 0, 0, 0,
- width, height, GDK_RGB_DITHER_NONE,
- 0, 0);
- else
- DBG (g_warning ("empty cursor pixmap created."));
- mask = gdk_pixmap_new (drawable, width, height, 1);
- gdk_pixbuf_render_threshold_alpha (cursor_pixbuf, mask,
- 0, 0, 0, 0,
- width, height,
- 200);
- g_object_unref (gc);
- magnifier->priv->cursor = pixmap;
- magnifier->priv->cursor_mask = mask;
-
- xhot_string = g_object_get_data (G_OBJECT(cursor_pixbuf), "x_hot");
- yhot_string = g_object_get_data (G_OBJECT(cursor_pixbuf), "y_hot");
-
- if (xhot_string)
- magnifier->cursor_hotspot.x = atoi (xhot_string);
- if (yhot_string)
- magnifier->cursor_hotspot.y = atoi (yhot_string);
- if (pixmap) {
- gdk_drawable_get_size (
- pixmap,
- &magnifier->priv->cursor_default_size_x,
- &magnifier->priv->cursor_default_size_y);
- magnifier->priv->cursor_hotspot_x =
- magnifier->cursor_hotspot.x;
- magnifier->priv->cursor_hotspot_y =
- magnifier->cursor_hotspot.y;
- }
+ if (cursor_surface) {
+ magnifier->priv->cursor = cairo_surface_reference (cursor_surface);
}
}
-GdkPixbuf *
-magnifier_get_pixbuf_for_name (Magnifier *magnifier, const gchar *cursor_name)
+static cairo_surface_t *
+magnifier_get_surface_for_name (Magnifier *magnifier, const gchar *cursor_name)
{
- GdkPixbuf *retval = NULL;
+ cairo_surface_t *retval = NULL;
if (magnifier->priv->cursorlist)
retval = g_hash_table_lookup (magnifier->priv->cursorlist, cursor_name);
if (retval)
- g_object_ref (retval);
+ cairo_surface_reference (retval);
return retval;
}
void
-magnifier_set_cursor_pixmap_by_name (Magnifier *magnifier,
- const gchar *cursor_name,
- gboolean source_fallback)
+magnifier_set_cursor_by_name (Magnifier *magnifier,
+ const gchar *cursor_name,
+ gboolean source_fallback)
{
- GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
+
/* search local table; if not found, use source screen's cursor if source_fallback is TRUE */
- if ((pixbuf = magnifier_get_pixbuf_for_name (magnifier, cursor_name)) == NULL) {
+ surface = magnifier_get_surface_for_name (magnifier, cursor_name);
+ if (surface == NULL) {
if (source_fallback == TRUE)
{
- pixbuf = gmag_cursor_get_source_pixbuf (magnifier);
+ surface = gmag_cursor_get_source_surface (magnifier);
}
else
{
- pixbuf = magnifier_get_pixbuf_for_name (magnifier, "default");
+ surface = magnifier_get_surface_for_name (magnifier, "default");
}
}
- magnifier_set_cursor_from_pixbuf (magnifier, pixbuf);
- if (pixbuf) g_object_unref (pixbuf);
+
+ magnifier_set_cursor_from_surface (magnifier, surface);
+ if (surface)
+ cairo_surface_destroy (surface);
}
void
@@ -585,98 +547,6 @@ magnifier_exit (GtkObject *object)
}
#endif
-void
-magnifier_transform_cursor (Magnifier *magnifier)
-{
- if (magnifier->priv->cursor) /* don't do this if cursor isn't intialized yet */
- {
- int width, height;
- int size_x, size_y;
- GdkPixbuf *scaled_cursor_pixbuf;
- GdkPixbuf *scaled_mask_pixbuf;
- GdkPixbuf *scaled_mask_pixbuf_alpha;
- GdkPixbuf *cursor_pixbuf;
- GdkPixbuf *mask_pixbuf;
- GdkPixmap *cursor_pixmap = magnifier->priv->cursor;
- GdkPixmap *mask_pixmap = magnifier->priv->cursor_mask;
- GdkGC *cgc;
- GdkGC *mgc;
-
- if (magnifier->cursor_size_x)
- {
- size_x = magnifier->cursor_size_x;
- size_y = magnifier->cursor_size_y;
- }
- else
- {
- size_x = magnifier->priv->cursor_default_size_x *
- magnifier->cursor_scale_factor;
- size_y = magnifier->priv->cursor_default_size_y *
- magnifier->cursor_scale_factor;
- }
- gdk_drawable_get_size (magnifier->priv->cursor, &width, &height);
- if ((size_x == width) && (size_y == height)) {
- return; /* nothing changes */
- }
- cgc = gdk_gc_new (cursor_pixmap);
- mgc = gdk_gc_new (mask_pixmap);
- cursor_pixbuf = gdk_pixbuf_get_from_drawable (NULL, cursor_pixmap,
- NULL, 0, 0, 0, 0,
- width, height);
- mask_pixbuf = gdk_pixbuf_get_from_drawable (NULL,
- mask_pixmap,
- NULL, 0, 0, 0, 0,
- width, height);
- scaled_cursor_pixbuf = gdk_pixbuf_scale_simple (
- cursor_pixbuf, size_x, size_y, GDK_INTERP_NEAREST);
-
- magnifier->cursor_hotspot.x = magnifier->priv->cursor_hotspot_x * size_x
- / magnifier->priv->cursor_default_size_x;
- magnifier->cursor_hotspot.y = magnifier->priv->cursor_hotspot_y * size_y
- / magnifier->priv->cursor_default_size_y;
-
- scaled_mask_pixbuf = gdk_pixbuf_scale_simple (
- mask_pixbuf, size_x, size_y, GDK_INTERP_NEAREST);
- g_object_unref (cursor_pixbuf);
- g_object_unref (mask_pixbuf);
- g_object_unref (cursor_pixmap);
- g_object_unref (mask_pixmap);
- magnifier->priv->cursor = gdk_pixmap_new (
- gtk_widget_get_window (GTK_WIDGET (magnifier)),
- size_x, size_y,
- -1);
- if (!GDK_IS_DRAWABLE (magnifier->priv->cursor))
- {
- DBG (g_warning ("NULL magnifier cursor pixmap."));
- return;
- }
- magnifier->priv->cursor_mask = gdk_pixmap_new (
- gtk_widget_get_window (GTK_WIDGET (magnifier)),
- size_x, size_y,
- 1);
- if (GDK_IS_DRAWABLE (magnifier->priv->cursor)) {
- gdk_draw_pixbuf (magnifier->priv->cursor,
- cgc,
- scaled_cursor_pixbuf,
- 0, 0, 0, 0, size_x, size_y,
- GDK_RGB_DITHER_NONE, 0, 0 );
- }
- else
- DBG (g_warning ("cursor pixmap is non-drawable."));
- scaled_mask_pixbuf_alpha = gdk_pixbuf_add_alpha (
- scaled_mask_pixbuf, True, 0, 0, 0);
- gdk_pixbuf_render_threshold_alpha (scaled_mask_pixbuf_alpha,
- magnifier->priv->cursor_mask,
- 0, 0, 0, 0, size_x, size_y,
- 0x80);
- g_object_unref (scaled_mask_pixbuf_alpha);
- g_object_unref (scaled_cursor_pixbuf);
- g_object_unref (scaled_mask_pixbuf);
- g_object_unref (mgc);
- g_object_unref (cgc);
- }
-}
-
static void
magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set)
{
@@ -705,7 +575,8 @@ magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set)
g_hash_table_destroy (magnifier->priv->cursorlist);
}
magnifier->priv->cursorlist = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
+ g_free,
+ (GDestroyNotify) cairo_surface_destroy);
cursor_dirname = g_strconcat (CURSORSDIR, "/", magnifier->cursor_set, NULL);
cursor_dir = g_dir_open (cursor_dirname, 0, NULL);
@@ -719,14 +590,26 @@ magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set)
if (pixbuf)
{
/* add this pixbuf and its name to our list */
+ cairo_surface_t *surface;
+ cairo_t *cr;
gchar **sv, *cname;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ cr = cairo_create (surface);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
cname = g_path_get_basename (filename);
sv = g_strsplit (cname, ".", 2);
g_hash_table_insert (magnifier->priv->cursorlist,
g_strdup (sv[0]),
- pixbuf);
+ surface);
g_free (cname);
g_strfreev (sv);
+ g_object_unref (pixbuf);
}
g_free (path);
}
@@ -735,8 +618,7 @@ magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set)
if (cursor_dir) g_dir_close (cursor_dir);
}
/* don't fallover to source cursor here, we haven't initialized X yet */
- magnifier_set_cursor_pixmap_by_name (magnifier, "default", FALSE);
- magnifier_transform_cursor (magnifier);
+ magnifier_set_cursor_by_name (magnifier, "default", FALSE);
}
static gboolean
@@ -964,17 +846,11 @@ get_property_cb (GDBusConnection *connection,
retval = g_variant_new_array (G_VARIANT_TYPE_INT32, children, 2);
} else if (g_strcmp0 (property_name, "CursorZoom") == 0) {
retval = g_variant_new_double (magnifier->cursor_scale_factor);
- } else if (g_strcmp0 (property_name, "CursorHotspot") == 0) {
- GVariant *children[2];
-
- children[0] = g_variant_new_int32 (magnifier->cursor_hotspot.x);
- children[1] = g_variant_new_int32 (magnifier->cursor_hotspot.y);
- retval = g_variant_new_array (G_VARIANT_TYPE_INT32, children, 2);
} else if (g_strcmp0 (property_name, "CursorDefaultSize") == 0) {
gint32 csize = 0;
if (magnifier->priv->cursor) {
- gdk_drawable_get_size (magnifier->priv->cursor, &csize, &csize);
+ csize = cairo_image_surface_get_width (magnifier->priv->cursor);
}
retval = g_variant_new_int32 (csize);
} else if (g_strcmp0 (property_name, "CrosswireSize") == 0) {
@@ -1042,10 +918,6 @@ set_property_cb (GDBusConnection *connection,
g_object_set (magnifier,
"cursor-scale-factor", g_variant_get_double (value),
NULL);
- } else if (g_strcmp0 (property_name, "CursorColor") == 0) {
- g_object_set (magnifier,
- "cursor-color", g_variant_get_uint32 (value),
- NULL);
} else if (g_strcmp0 (property_name, "CursorHotspot") == 0) {
const int *items;
gsize n_items;
@@ -1205,19 +1077,11 @@ magnifier_gobject_get_property (GObject *object,
case MAGNIFIER_CURSOR_ZOOM_PROP:
g_value_set_float (value, magnifier->cursor_scale_factor);
break;
- case MAGNIFIER_CURSOR_HOTSPOT_PROP: {
- Point *point = g_new (Point, 1);
-
- *point = magnifier->cursor_hotspot;
- g_value_set_pointer (value, point);
- }
- break;
case MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP: {
int csize = 0;
if (magnifier->priv->cursor)
- gdk_drawable_get_size (magnifier->priv->cursor,
- &csize, &csize);
+ csize = cairo_image_surface_get_width (magnifier->priv->cursor);
g_value_set_uint (value, csize);
}
break;
@@ -1421,22 +1285,11 @@ magnifier_gobject_set_property (GObject *object,
case MAGNIFIER_CURSOR_SIZE_PROP:
magnifier->cursor_size_x = g_value_get_int (value);
magnifier->cursor_size_y = magnifier->cursor_size_x;
- magnifier_transform_cursor (magnifier);
DBG (fprintf (stderr, "Setting cursor size: \t%d\n", magnifier->cursor_size_x));
break;
case MAGNIFIER_CURSOR_ZOOM_PROP:
magnifier->cursor_scale_factor = g_value_get_float (value);
DBG (fprintf (stderr, "Setting cursor scale factor: \t%f\n", (float) magnifier->cursor_scale_factor));
- magnifier_transform_cursor (magnifier);
- break;
- case MAGNIFIER_CURSOR_HOTSPOT_PROP: {
- Point *point = g_value_get_pointer (value);
-
- magnifier->cursor_hotspot = *point;
- /* TODO: notify zoomers */
- /* FIXME: don't call init_cursor, it overwrites this property! */
- magnifier_transform_cursor (magnifier);
- }
break;
case MAGNIFIER_CROSSWIRE_SIZE_PROP:
magnifier->crosswire_size = g_value_get_int (value);
@@ -1576,12 +1429,6 @@ magnifier_class_init (MagnifierClass *klass)
0, G_MAXFLOAT, 1.0F,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
- MAGNIFIER_CURSOR_HOTSPOT_PROP,
- g_param_spec_pointer ("cursor-hotspot",
- "CursorHotspot",
- "hotspot relative to cursor's upper-left-corner, at default resolition",
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP,
g_param_spec_int ("cursor-default-size",
"CursorDefaultSize",
@@ -1717,8 +1564,8 @@ magnifier_new (gboolean override_redirect,
return mag;
}
-GdkDrawable *
-magnifier_get_cursor (Magnifier *magnifier)
+static void
+magnifier_ensure_cursor (Magnifier *magnifier)
{
if (magnifier->priv->cursor == NULL) {
if ((fixes_event_base == 0) &&
@@ -1730,18 +1577,96 @@ magnifier_get_cursor (Magnifier *magnifier)
pixbuf = gdk_pixbuf_new_from_file (default_cursor_filename, NULL);
if (pixbuf)
{
- magnifier_set_cursor_from_pixbuf (magnifier, pixbuf);
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ cr = cairo_create (surface);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ magnifier_set_cursor_from_surface (magnifier, surface);
g_object_unref (pixbuf);
- magnifier_transform_cursor (magnifier);
+ cairo_surface_destroy (surface);
}
g_free (default_cursor_filename);
} else {
- GdkPixbuf *cursor_pixbuf = gmag_cursor_get_source_pixbuf (
+ cairo_surface_t *surface = gmag_cursor_get_source_surface (
magnifier);
- magnifier_set_cursor_from_pixbuf (magnifier, cursor_pixbuf);
- if (cursor_pixbuf) g_object_unref (cursor_pixbuf);
- magnifier_transform_cursor (magnifier);
+ magnifier_set_cursor_from_surface (magnifier, surface);
+ if (surface) cairo_surface_destroy (surface);
}
}
- return magnifier->priv->cursor;
+}
+
+cairo_pattern_t *
+magnifier_get_cursor (Magnifier *magnifier)
+{
+ cairo_matrix_t matrix;
+ cairo_pattern_t *pattern;
+
+ magnifier_ensure_cursor (magnifier);
+ if (magnifier->priv->cursor == NULL)
+ return NULL;
+
+ pattern = cairo_pattern_create_for_surface (magnifier->priv->cursor);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+
+ if (magnifier->cursor_size_x)
+ {
+ double xscale, yscale;
+
+ xscale = (double) cairo_image_surface_get_width (magnifier->priv->cursor) / magnifier->cursor_size_x;
+ yscale = (double) cairo_image_surface_get_height (magnifier->priv->cursor) / magnifier->cursor_size_y;
+
+ cairo_matrix_init_scale (&matrix, xscale, yscale);
+ }
+ else
+ {
+ cairo_matrix_init_scale (&matrix,
+ 1.0 / magnifier->cursor_scale_factor,
+ 1.0 / magnifier->cursor_scale_factor);
+ }
+
+ cairo_pattern_set_matrix (pattern, &matrix);
+
+ return pattern;
+}
+
+void
+magnifier_get_cursor_size (Magnifier * magnifier,
+ GdkRectangle * rect)
+{
+ double x_hot, y_hot;
+ int width, height;
+
+ magnifier_ensure_cursor (magnifier);
+ if (magnifier->priv->cursor == NULL)
+ {
+ memset (rect, 0, sizeof (GdkRectangle));
+ return;
+ }
+
+ cairo_surface_get_device_offset (magnifier->priv->cursor, &x_hot, &y_hot);
+
+ width = cairo_image_surface_get_width (magnifier->priv->cursor);
+ height = cairo_image_surface_get_height (magnifier->priv->cursor);
+
+ if (magnifier->cursor_size_x)
+ {
+ rect->x = - x_hot * magnifier->cursor_size_x / width;
+ rect->y = - y_hot * magnifier->cursor_size_y / height;
+ rect->width = magnifier->cursor_size_x;
+ rect->height = magnifier->cursor_size_y;
+ }
+ else
+ {
+ rect->x = - x_hot * magnifier->cursor_scale_factor;
+ rect->y = - y_hot * magnifier->cursor_scale_factor;
+ rect->width = magnifier->cursor_scale_factor * width;
+ rect->height = magnifier->cursor_scale_factor * height;
+ }
}
diff --git a/magnifier/magnifier.h b/magnifier/magnifier.h
index 6885462..cfd640e 100644
--- a/magnifier/magnifier.h
+++ b/magnifier/magnifier.h
@@ -62,7 +62,6 @@ typedef struct {
float cursor_scale_factor;
RectBounds source_bounds;
RectBounds target_bounds;
- Point cursor_hotspot;
MagnifierPrivate *priv;
} Magnifier;
@@ -145,7 +144,10 @@ typedef struct timing {
TimingStruct mag_timing;
-GdkDrawable *magnifier_get_cursor (Magnifier *magnifier);
+cairo_pattern_t * magnifier_get_cursor (Magnifier * magnifier);
+void magnifier_get_cursor_size (Magnifier * magnifier,
+ GdkRectangle * size);
+
GType magnifier_get_type (void) G_GNUC_CONST;
GdkWindow *magnifier_get_root (Magnifier *magnifier);
Magnifier *magnifier_new (gboolean override_redirect,
@@ -160,12 +162,11 @@ void magnifier_add_zoom_region (Magnifier *magnifier,
ZoomRegion *zoom_region);
void magnifier_notify_damage (Magnifier *magnifier,
GdkRectangle *rect);
-void magnifier_set_cursor_from_pixbuf (Magnifier *magnifier,
- GdkPixbuf *pointer_pixbuf);
-void magnifier_set_cursor_pixmap_by_name (Magnifier *magnifier,
- const gchar *cursor_name,
- gboolean source_fallback);
-void magnifier_transform_cursor (Magnifier *magnifier);
+void magnifier_set_cursor_from_surface (Magnifier *magnifier,
+ cairo_surface_t *surface);
+void magnifier_set_cursor_by_name (Magnifier *magnifier,
+ const gchar *cursor_name,
+ gboolean source_fallback);
void magnifier_zoom_regions_update_pointer (Magnifier *magnifier);
gboolean magnifier_full_screen_capable (Magnifier *magnifier);
diff --git a/magnifier/x11/gmag-cursor.c b/magnifier/x11/gmag-cursor.c
index 89c1a62..217afbc 100644
--- a/magnifier/x11/gmag-cursor.c
+++ b/magnifier/x11/gmag-cursor.c
@@ -41,50 +41,41 @@ static Window root_window;
static gint fixes_error_base;
-static void
-gmag_cursor_cursor_convert_to_rgba (Magnifier *magnifier,
- XFixesCursorImage *cursor_image)
-{
- int i, count = cursor_image->width * cursor_image->height;
- for (i = 0; i < count; ++i) {
- guint32 pixval = GUINT_TO_LE (cursor_image->pixels[i]);
- cursor_image->pixels[i] = pixval;
- }
-}
-
-static void
-gmag_cursor_free_cursor_pixels (guchar *pixels, gpointer data)
-{
- XFree (data);
-}
-
-GdkPixbuf *
-gmag_cursor_get_source_pixbuf (Magnifier *magnifier)
+cairo_surface_t *
+gmag_cursor_get_source_surface (Magnifier *magnifier)
{
XFixesCursorImage *cursor_image = XFixesGetCursorImage (dpy);
- GdkPixbuf *cursor_pixbuf = NULL;
- gchar *s1, *s2;
+ gulong *cursor_pixels = cursor_image->pixels;
+ cairo_surface_t *surface = NULL;
+ int x, y, stride;
+ guint32 *pixels;
if (cursor_image) {
- s1 = (char *) malloc (sizeof (char) * 6);
- s2 = (char *) malloc (sizeof (char) * 6);
- gmag_cursor_cursor_convert_to_rgba (magnifier, cursor_image);
- cursor_pixbuf = gdk_pixbuf_new_from_data (
- (guchar *) cursor_image->pixels, GDK_COLORSPACE_RGB,
- TRUE, 8, cursor_image->width, cursor_image->height,
- cursor_image->width * 4,
- gmag_cursor_free_cursor_pixels, cursor_image);
- g_object_set_data (G_OBJECT (cursor_pixbuf), "x_hot",
- g_ascii_dtostr (
- s1, 6,
- (gdouble) cursor_image->xhot));
- g_object_set_data (G_OBJECT (cursor_pixbuf), "y_hot",
- g_ascii_dtostr (
- s2, 6,
- (gdouble) cursor_image->yhot));
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cursor_image->width,
+ cursor_image->height);
+
+ pixels = (guint32 *) cairo_image_surface_get_data (surface);
+ stride = cairo_image_surface_get_stride (surface);
+ stride /= 4; /* we're using guint32 */
+ for (y = 0; y < cursor_image->height; y++) {
+ for (x = 0; x < cursor_image->width; x++) {
+ pixels[x] = *cursor_pixels;
+ cursor_pixels++;
+ }
+ pixels += stride;
+ }
+
+ cairo_surface_mark_dirty (surface);
+
+ /* We offset the surface so 0,0 of the surface ends up being
+ * at the cursor's hot point */
+ cairo_surface_set_device_offset (surface,
+ cursor_image->xhot,
+ cursor_image->yhot);
}
- return cursor_pixbuf;
+ return surface;
}
void
@@ -129,35 +120,24 @@ void
gmag_cursor_events_handler (Magnifier *magnifier, XEvent *ev)
{
XFixesCursorNotifyEvent *cev = (XFixesCursorNotifyEvent *) ev;
- gchar *s1, *s2;
if (magnifier->priv->use_source_cursor) {
- GdkPixbuf *cursor_pixbuf =
- gmag_cursor_get_source_pixbuf (magnifier);
- magnifier_set_cursor_from_pixbuf (magnifier,
- cursor_pixbuf);
- s1 = g_object_get_data (G_OBJECT (cursor_pixbuf),
- "x_hot");
- s2 = g_object_get_data (G_OBJECT (cursor_pixbuf),
- "y_hot");
- if (s1) {
- g_free (s1);
- g_free (s2);
- }
- if (cursor_pixbuf)
- g_object_unref (cursor_pixbuf);
+ cairo_surface_t *surface = gmag_cursor_get_source_surface (magnifier);
+
+ magnifier_set_cursor_from_surface (magnifier, surface);
+ if (surface)
+ cairo_surface_destroy (surface);
} else {
if (cev)
- magnifier_set_cursor_pixmap_by_name (
+ magnifier_set_cursor_by_name (
magnifier,
gdk_x11_get_xatom_name (cev->cursor_name),
TRUE);
else
- magnifier_set_cursor_pixmap_by_name (
+ magnifier_set_cursor_by_name (
magnifier, "default", TRUE);
}
- magnifier_transform_cursor (magnifier);
magnifier_zoom_regions_update_pointer (magnifier);
#ifdef CURSOR_DEBUG
if (cev)
diff --git a/magnifier/x11/gmag-cursor.h b/magnifier/x11/gmag-cursor.h
index b50e935..6dd9a96 100644
--- a/magnifier/x11/gmag-cursor.h
+++ b/magnifier/x11/gmag-cursor.h
@@ -28,12 +28,12 @@
#include <X11/Xlib.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <cairo.h>
-gint gmag_cursor_init (Magnifier *magnifier, Display *dpy_conn);
-GdkPixbuf *gmag_cursor_get_source_pixbuf (Magnifier *magnifier);
-void gmag_cursor_events_handler (Magnifier *magnifier, XEvent *ev);
-void gmag_cursor_hide (Magnifier *magnifier);
-void gmag_cursor_show (Magnifier *magnifier);
+gint gmag_cursor_init (Magnifier *magnifier, Display *dpy_conn);
+cairo_surface_t *gmag_cursor_get_source_surface (Magnifier *magnifier);
+void gmag_cursor_events_handler (Magnifier *magnifier, XEvent *ev);
+void gmag_cursor_hide (Magnifier *magnifier);
+void gmag_cursor_show (Magnifier *magnifier);
#endif /* GMAG_CURSOR_H_ */
diff --git a/magnifier/zoom-region.c b/magnifier/zoom-region.c
index ea28a0b..5a60699 100644
--- a/magnifier/zoom-region.c
+++ b/magnifier/zoom-region.c
@@ -742,24 +742,27 @@ zoom_region_update_current (ZoomRegion *zoom_region)
}
}
-static GdkRectangle
-zoom_region_cursor_rect (ZoomRegion *zoom_region)
+static void
+zoom_region_cursor_rect (ZoomRegion *zoom_region, GdkRectangle *rect, int *x, int *y)
{
- GdkRectangle rect = {0, 0, 0, 0};
+ GdkRectangle tmp;
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;
+ magnifier_get_cursor_size (magnifier, rect);
+ else
+ memset (rect, 0, sizeof (GdkRectangle));
+
+ if (rect->width <= 0 || rect->height <= 0)
+ return;
+
+ tmp.x = zoom_region->priv->last_cursor_pos.x;
+ tmp.y = zoom_region->priv->last_cursor_pos.y;
+ tmp.width = tmp.height = 0;
+ tmp = zoom_region_view_rect_from_source_rect (zoom_region, tmp);
+ rect->x += tmp.x;
+ rect->y += tmp.y;
+ *x = tmp.x;
+ *y = tmp.y;
}
static void
@@ -797,12 +800,10 @@ zoom_region_paint_crosswire_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_
static GdkColor last_color;
static gboolean last_color_init = FALSE;
GdkGCValues values;
- GdkRectangle rect;
- GdkDrawable *cursor;
+ GdkRectangle rect, crect;
GdkColor color = {0, 0, 0, 0};
int x_start = 0, y_start = 0, x_end = 4096, y_end = 4096;
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);
@@ -864,22 +865,16 @@ zoom_region_paint_crosswire_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_
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);
- }
+ magnifier_get_cursor_size (magnifier, &crect);
+ crect.x += rect.x;
+ crect.y += rect.y;
if (magnifier->crosswire_length) {
if (magnifier->crosswire_clip) {
- x_start = rect.x - magnifier->cursor_hotspot.x -
- magnifier->crosswire_length;
- x_end = rect.x +
- (csize - magnifier->cursor_hotspot.x) +
- magnifier->crosswire_length;
- y_start = rect.y - magnifier->cursor_hotspot.y -
- magnifier->crosswire_length;
- y_end = rect.y +
- (csize - magnifier->cursor_hotspot.y) +
- magnifier->crosswire_length;
+ x_start = crect.x - magnifier->crosswire_length;
+ x_end = crect.x + crect.width + magnifier->crosswire_length;
+ y_start = crect.y - magnifier->crosswire_length;
+ y_end = crect.y + crect.height + magnifier->crosswire_length;
} else {
x_start = rect.x - magnifier->crosswire_length;
x_end = rect.x + magnifier->crosswire_length;
@@ -890,16 +885,10 @@ zoom_region_paint_crosswire_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_
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;
+ y_top_clip = crect.y - magnifier->crosswire_size;
+ y_bottom_clip = crect.y + crect.height + magnifier->crosswire_size;
+ x_left_clip = rect.x - magnifier->crosswire_size;
+ x_right_clip = crect.x + crect.width + magnifier->crosswire_size;
}
if (magnifier->crosswire_size == 1) {
@@ -964,17 +953,19 @@ 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);
+ int x, y;
+
#ifdef ZOOM_REGION_DEBUG
g_assert (zoom_region->alive);
#endif
if (!zoom_region->draw_cursor)
return;
+ zoom_region_cursor_rect (zoom_region, &rect, &x, &y);
+
if (clip_rect == NULL)
{
fullscreen = zoom_region_rect_from_bounds (zoom_region,
@@ -982,17 +973,18 @@ zoom_region_paint_cursor (ZoomRegion *zoom_region,
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;
+ zoom_region->priv->last_drawn_crosswire_pos.x = rect.x;
+ zoom_region->priv->last_drawn_crosswire_pos.y = rect.y;
if (gdk_rectangle_intersect (clip_rect, &rect, &intersct))
{
+ cairo_pattern_t *cursor;
int width = 0, height = 0;
- GdkDrawable *cursor = magnifier_get_cursor (magnifier);
+ 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,
@@ -1023,32 +1015,21 @@ zoom_region_paint_cursor (ZoomRegion *zoom_region,
rect.height);
}
DEBUG_RECT ("painting", rect);
- if (cursor && GDK_IS_DRAWABLE (gtk_widget_get_window (GTK_WIDGET (zoom_region))))
+ if (GDK_IS_DRAWABLE (gtk_widget_get_window (GTK_WIDGET (zoom_region))))
{
- if (zoom_region->priv->paint_cursor_gc == NULL)
- zoom_region->priv->paint_cursor_gc = gdk_gc_new (gtk_widget_get_window (GTK_WIDGET (zoom_region)));
-
- 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 (gtk_widget_get_window (GTK_WIDGET (zoom_region)),
- zoom_region->priv->paint_cursor_gc,
- TRUE,
- rect.x, rect.y, rect.width, rect.height);
-
- gdk_draw_drawable (gtk_widget_get_window (GTK_WIDGET (zoom_region)),
- zoom_region->priv->paint_cursor_gc,
- cursor,
- 0, 0,
- rect.x,
- rect.y,
- rect.width,
- rect.height);
+ cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (GTK_WIDGET (zoom_region)));
+
+ gdk_cairo_rectangle (cr, clip_rect);
+ cairo_clip (cr);
+
+ cairo_translate (cr, x, y);
+ cairo_set_source (cr, cursor);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
}
+
+ cairo_pattern_destroy (cursor);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]