mutter/mutter-gdk-cairo.patch

1115 lines
36 KiB
Diff

From 08cfdcd802c762b04351798e8a03524e11db637e Mon Sep 17 00:00:00 2001
From: Florian Müllner <fmuellner@gnome.org>
Date: Mon, 19 Jul 2010 15:55:00 +0000
Subject: Replace GDK drawing API with cairo
The GDK drawing API was deprecated/removed.
https://bugzilla.gnome.org/show_bug.cgi?id=626583
---
Index: mutter-2.31.5/src/ui/draw-workspace.c
===================================================================
--- mutter-2.31.5.orig/src/ui/draw-workspace.c
+++ mutter-2.31.5/src/ui/draw-workspace.c
@@ -180,6 +180,7 @@ wnck_draw_workspace (GtkWidget
GdkRectangle workspace_rect;
GtkStateType state;
GtkStyle *style;
+ cairo_t *cr;
workspace_rect.x = x;
workspace_rect.y = y;
@@ -194,28 +195,21 @@ wnck_draw_workspace (GtkWidget
state = GTK_STATE_NORMAL;
style = gtk_widget_get_style (widget);
+ cr = gdk_cairo_create (drawable);
if (workspace_background)
{
- gdk_draw_pixbuf (drawable,
- style->dark_gc[state],
- workspace_background,
- 0, 0,
- x, y,
- -1, -1,
- GDK_RGB_DITHER_MAX,
- 0, 0);
+ gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y);
+ cairo_paint (cr);
}
else
{
- cairo_t *cr;
-
- cr = gdk_cairo_create (gtk_widget_get_window (widget));
gdk_cairo_set_source_color (cr, &style->dark[state]);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr);
- cairo_destroy (cr);
}
+
+ cairo_destroy (cr);
i = 0;
while (i < n_windows)
Index: mutter-2.31.5/src/ui/frames.c
===================================================================
--- mutter-2.31.5.orig/src/ui/frames.c
+++ mutter-2.31.5/src/ui/frames.c
@@ -2004,46 +2004,64 @@ meta_frames_destroy_event (Gtk
return TRUE;
}
-/* Cut and paste from GDK */
-static GdkGC *
-get_bg_gc (GdkWindow *window, int x_offset, int y_offset)
+#if !GTK_CHECK_VERSION(2,21,6)
+/* Copied from GDK */
+static cairo_pattern_t *
+gdk_window_get_background_pattern (GdkWindow *window)
+{
+ GdkWindowObject *private = (GdkWindowObject *) window;
+ cairo_pattern_t *pattern;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+ if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG)
+ pattern = NULL;
+ else if (private->bg_pixmap != GDK_NO_BG &&
+ private->bg_pixmap != NULL)
+ {
+ static cairo_user_data_key_t key;
+ cairo_surface_t *surface;
+
+ surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_pattern_set_user_data (pattern,
+ &key,
+ g_object_ref (private->bg_pixmap),
+ g_object_unref);
+ }
+ else
+ pattern =
+ cairo_pattern_create_rgb (private->bg_color.red / 65535.,
+ private->bg_color.green / 65535.,
+ private->bg_color.blue / 65535.);
+ }
+
+ return pattern;
+}
+#endif
+
+static void
+setup_bg_cr (cairo_t *cr, GdkWindow *window, int x_offset, int y_offset)
{
GdkWindow *parent = gdk_window_get_parent (window);
- GdkPixmap *back_pixmap;
- gboolean parent_relative;
- guint gc_mask = 0;
- GdkGCValues gc_values;
+ cairo_pattern_t *bg_pattern;
- gdk_window_get_back_pixmap (window, &back_pixmap, &parent_relative);
- if (parent_relative && parent)
+ bg_pattern = gdk_window_get_background_pattern (window);
+ if (bg_pattern == NULL && parent)
{
gint window_x, window_y;
gdk_window_get_position (window, &window_x, &window_y);
- return get_bg_gc (parent,
- x_offset + window_x,
- y_offset + window_y);
- }
- else if (back_pixmap)
- {
- gc_values.fill = GDK_TILED;
- gc_values.tile = back_pixmap;
- gc_values.ts_x_origin = x_offset;
- gc_values.ts_y_origin = y_offset;
-
- gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
-
- return gdk_gc_new_with_values (window, &gc_values, gc_mask);
+ setup_bg_cr (cr, parent, x_offset + window_x, y_offset + window_y);
}
- else
+ else if (bg_pattern)
{
- GdkColor bg_color;
- GdkGC *gc = gdk_gc_new (window);
-
- gdk_window_get_background (window, &bg_color);
- gdk_gc_set_foreground (gc, &bg_color);
-
- return gc;
+ cairo_translate (cr, - x_offset, - y_offset);
+ cairo_set_source (cr, bg_pattern);
+ cairo_translate (cr, x_offset, y_offset);
}
}
@@ -2052,12 +2070,16 @@ clear_backing (GdkPixmap *pixmap,
GdkWindow *window,
int xoffset, int yoffset)
{
- GdkGC *tmp_gc = get_bg_gc (window, xoffset, yoffset);
+ int width, height;
+ cairo_t *cr = gdk_cairo_create (pixmap);
+
+ setup_bg_cr (cr, window, xoffset, yoffset);
- gdk_draw_rectangle (pixmap, tmp_gc, TRUE,
- 0, 0, -1, -1);
+ gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
- g_object_unref (tmp_gc);
+ cairo_destroy (cr);
}
/* Returns a pixmap with a piece of the windows frame painted on it.
@@ -2220,10 +2242,10 @@ cached_pixels_draw (CachedPixels *pixels
GdkWindow *window,
MetaRegion *region)
{
- GdkGC *gc;
+ cairo_t *cr;
int i;
- gc = gdk_gc_new (window);
+ cr = gdk_cairo_create (window);
for (i = 0; i < 4; i++)
{
@@ -2232,16 +2254,15 @@ cached_pixels_draw (CachedPixels *pixels
if (piece->pixmap)
{
- gdk_draw_drawable (window, gc, piece->pixmap,
- 0, 0,
- piece->rect.x, piece->rect.y,
- -1, -1);
+ gdk_cairo_set_source_pixmap (cr, piece->pixmap,
+ piece->rect.x, piece->rect.y);
+ cairo_paint (cr);
subtract_from_region (region, piece->pixmap,
piece->rect.x, piece->rect.y);
}
}
- g_object_unref (gc);
+ cairo_destroy (cr);
}
static gboolean
@@ -2550,11 +2571,6 @@ meta_frames_set_window_background (MetaF
GTK_WIDGET (frames),
&color);
- /* Fill in color.pixel */
-
- gdk_rgb_find_color (gtk_widget_get_colormap (GTK_WIDGET (frames)),
- &color);
-
/* Set A in ARGB to window_background_alpha, if we have ARGB */
visual = gtk_widget_get_visual (GTK_WIDGET (frames));
Index: mutter-2.31.5/src/ui/tabpopup.c
===================================================================
--- mutter-2.31.5.orig/src/ui/tabpopup.c
+++ mutter-2.31.5/src/ui/tabpopup.c
@@ -83,6 +83,7 @@ outline_window_expose (GtkWidget *w
TabEntry *te;
GtkStyle *style;
GdkWindow *window;
+ cairo_t *cr;
popup = data;
@@ -92,20 +93,24 @@ outline_window_expose (GtkWidget *w
te = popup->current_selected_entry;
window = gtk_widget_get_window (widget);
style = gtk_widget_get_style (widget);
-
- gdk_draw_rectangle (window,
- style->white_gc,
- FALSE,
- 0, 0,
- te->rect.width - 1,
- te->rect.height - 1);
-
- gdk_draw_rectangle (window,
- style->white_gc,
- FALSE,
- te->inner_rect.x - 1, te->inner_rect.y - 1,
- te->inner_rect.width + 1,
- te->inner_rect.height + 1);
+ cr = gdk_cairo_create (window);
+
+ cairo_set_line_width (cr, 1.0);
+ gdk_cairo_set_source_color (cr, &style->white);
+
+ cairo_rectangle (cr,
+ 0.5, 0.5,
+ te->rect.width - 1,
+ te->rect.height - 1);
+ cairo_stroke (cr);
+
+ cairo_rectangle (cr,
+ te->inner_rect.x - 0.5, te->inner_rect.y - 0.5,
+ te->inner_rect.width + 1,
+ te->inner_rect.height + 1);
+ cairo_stroke (cr);
+
+ cairo_destroy (cr);
return FALSE;
}
@@ -710,6 +715,7 @@ meta_select_image_expose_event (GtkWidge
int x, y, w, h;
gint xpad, ypad;
gfloat xalign, yalign;
+ cairo_t *cr;
misc = GTK_MISC (widget);
@@ -734,27 +740,28 @@ meta_select_image_expose_event (GtkWidge
window = gtk_widget_get_window (widget);
style = gtk_widget_get_style (widget);
state = gtk_widget_get_state (widget);
+ cr = gdk_cairo_create (window);
- gdk_draw_rectangle (window,
- style->fg_gc[state],
- FALSE,
- x, y, w, h);
- gdk_draw_rectangle (window,
- style->fg_gc[state],
- FALSE,
- x - 1, y - 1, w + 2, h + 2);
-
+ cairo_set_line_width (cr, 2.0);
+ gdk_cairo_set_source_color (cr, &style->fg[state]);
+
+ cairo_rectangle (cr, x, y, w + 1, h + 1);
+ cairo_stroke (cr);
+
+ cairo_set_line_width (cr, 1.0);
#if 0
- gdk_draw_rectangle (widget->window,
- widget->style->bg_gc[GTK_STATE_SELECTED],
- TRUE,
- x, y, w, h);
+ gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_SELECTED]);
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_fill (cr);
#endif
+
#if 0
gtk_paint_focus (widget->style, widget->window,
&event->area, widget, "meta-tab-image",
x, y, w, h);
#endif
+
+ cairo_destroy (cr);
}
return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
@@ -906,6 +913,7 @@ meta_select_workspace_expose_event (GtkW
GtkAllocation allocation;
GtkStyle *style;
GdkWindow *window;
+ cairo_t *cr;
int i, n_windows;
GList *tmp, *list;
@@ -965,20 +973,19 @@ meta_select_workspace_expose_event (GtkW
if (META_SELECT_WORKSPACE (widget)->selected)
{
style = gtk_widget_get_style (widget);
- i = SELECT_OUTLINE_WIDTH - 1;
+ cr = gdk_cairo_create (window);
- while (i >= 0)
- {
- gdk_draw_rectangle (window,
- style->fg_gc[gtk_widget_get_state (widget)],
- FALSE,
- i,
- i,
- allocation.width - i * 2 - 1,
- allocation.height - i * 2 - 1);
+ gdk_cairo_set_source_color (cr,
+ &style->fg[gtk_widget_get_state (widget)]);
+ cairo_set_line_width (cr, SELECT_OUTLINE_WIDTH);
+
+ cairo_rectangle (cr,
+ SELECT_OUTLINE_WIDTH / 2.0, SELECT_OUTLINE_WIDTH / 2.0,
+ allocation.width - SELECT_OUTLINE_WIDTH,
+ allocation.height - SELECT_OUTLINE_WIDTH);
+ cairo_stroke (cr);
- --i;
- }
+ cairo_destroy (cr);
}
return TRUE;
Index: mutter-2.31.5/src/ui/testgradient.c
===================================================================
--- mutter-2.31.5.orig/src/ui/testgradient.c
+++ mutter-2.31.5/src/ui/testgradient.c
@@ -24,7 +24,7 @@
#include <gtk/gtk.h>
typedef void (* RenderGradientFunc) (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width,
int height);
@@ -34,28 +34,22 @@ draw_checkerboard (GdkDrawable *drawable
int height)
{
gint i, j, xcount, ycount;
- GdkGC *gc1, *gc2;
- GdkColor color;
+ GdkColor color1, color2;
+ cairo_t *cr;
#define CHECK_SIZE 10
#define SPACING 2
- /* It would be a bit more efficient to keep these
- * GC's around instead of recreating on each expose, but
- * this is the lazy/slow way.
- */
- gc1 = gdk_gc_new (drawable);
- color.red = 30000;
- color.green = 30000;
- color.blue = 30000;
- gdk_gc_set_rgb_fg_color (gc1, &color);
-
- gc2 = gdk_gc_new (drawable);
- color.red = 50000;
- color.green = 50000;
- color.blue = 50000;
- gdk_gc_set_rgb_fg_color (gc2, &color);
-
+ color1.red = 30000;
+ color1.green = 30000;
+ color1.blue = 30000;
+
+ color2.red = 50000;
+ color2.green = 50000;
+ color2.blue = 50000;
+
+ cr = gdk_cairo_create (drawable);
+
xcount = 0;
i = SPACING;
while (i < width)
@@ -64,23 +58,17 @@ draw_checkerboard (GdkDrawable *drawable
ycount = xcount % 2; /* start with even/odd depending on row */
while (j < height)
{
- GdkGC *gc;
-
if (ycount % 2)
- gc = gc1;
+ gdk_cairo_set_source_color (cr, &color1);
else
- gc = gc2;
+ gdk_cairo_set_source_color (cr, &color2);
/* If we're outside event->area, this will do nothing.
* It might be mildly more efficient if we handled
* the clipping ourselves, but again we're feeling lazy.
*/
- gdk_draw_rectangle (drawable,
- gc,
- TRUE,
- i, j,
- CHECK_SIZE,
- CHECK_SIZE);
+ cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
+ cairo_fill (cr);
j += CHECK_SIZE + SPACING;
++ycount;
@@ -90,13 +78,12 @@ draw_checkerboard (GdkDrawable *drawable
++xcount;
}
- g_object_unref (G_OBJECT (gc1));
- g_object_unref (G_OBJECT (gc2));
+ cairo_destroy (cr);
}
static void
render_simple (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height,
MetaGradientType type,
gboolean with_alpha)
@@ -131,52 +118,48 @@ render_simple (GdkDrawable *drawable,
draw_checkerboard (drawable, width, height);
}
- gdk_draw_pixbuf (drawable,
- gc,
- pixbuf,
- 0, 0,
- 0, 0, width, height,
- GDK_RGB_DITHER_MAX,
- 0, 0);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
g_object_unref (G_OBJECT (pixbuf));
}
static void
render_vertical_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_simple (drawable, gc, width, height, META_GRADIENT_VERTICAL, FALSE);
+ render_simple (drawable, cr, width, height, META_GRADIENT_VERTICAL, FALSE);
}
static void
render_horizontal_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_simple (drawable, gc, width, height, META_GRADIENT_HORIZONTAL, FALSE);
+ render_simple (drawable, cr, width, height, META_GRADIENT_HORIZONTAL, FALSE);
}
static void
render_diagonal_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL, FALSE);
+ render_simple (drawable, cr, width, height, META_GRADIENT_DIAGONAL, FALSE);
}
static void
render_diagonal_alpha_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL, TRUE);
+ render_simple (drawable, cr, width, height, META_GRADIENT_DIAGONAL, TRUE);
}
static void
render_multi (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height,
MetaGradientType type)
{
@@ -194,14 +177,9 @@ render_multi (GdkDrawable *drawable,
colors, N_COLORS,
type);
- gdk_draw_pixbuf (drawable,
- gc,
- pixbuf,
- 0, 0,
- 0, 0,
- width, height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
g_object_unref (G_OBJECT (pixbuf));
#undef N_COLORS
@@ -209,31 +187,31 @@ render_multi (GdkDrawable *drawable,
static void
render_vertical_multi_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_multi (drawable, gc, width, height, META_GRADIENT_VERTICAL);
+ render_multi (drawable, cr, width, height, META_GRADIENT_VERTICAL);
}
static void
render_horizontal_multi_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_multi (drawable, gc, width, height, META_GRADIENT_HORIZONTAL);
+ render_multi (drawable, cr, width, height, META_GRADIENT_HORIZONTAL);
}
static void
render_diagonal_multi_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
- render_multi (drawable, gc, width, height, META_GRADIENT_DIAGONAL);
+ render_multi (drawable, cr, width, height, META_GRADIENT_DIAGONAL);
}
static void
render_interwoven_func (GdkDrawable *drawable,
- GdkGC *gc,
+ cairo_t *cr,
int width, int height)
{
GdkPixbuf *pixbuf;
@@ -249,14 +227,9 @@ render_interwoven_func (GdkDrawable *dra
colors, height / 10,
colors + 2, height / 14);
- gdk_draw_pixbuf (drawable,
- gc,
- pixbuf,
- 0, 0,
- 0, 0,
- width, height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
g_object_unref (G_OBJECT (pixbuf));
}
@@ -267,17 +240,25 @@ expose_callback (GtkWidget *widget,
gpointer data)
{
RenderGradientFunc func = data;
+ GdkWindow *window;
GtkAllocation allocation;
GtkStyle *style;
+ cairo_t *cr;
style = gtk_widget_get_style (widget);
gtk_widget_get_allocation (widget, &allocation);
+ window = gtk_widget_get_window (widget);
+ cr = gdk_cairo_create (window);
+ gdk_cairo_set_source_color (cr, &style->fg[gtk_widget_get_state (widget)]);
+
(* func) (gtk_widget_get_window (widget),
- style->fg_gc[gtk_widget_get_state (widget)],
+ cr,
allocation.width,
allocation.height);
+ cairo_destroy (cr);
+
return TRUE;
}
Index: mutter-2.31.5/src/ui/theme.c
===================================================================
--- mutter-2.31.5.orig/src/ui/theme.c
+++ mutter-2.31.5/src/ui/theme.c
@@ -2922,36 +2922,6 @@ meta_draw_op_free (MetaDrawOp *op)
g_free (op);
}
-static GdkGC*
-get_gc_for_primitive (GtkWidget *widget,
- GdkDrawable *drawable,
- MetaColorSpec *color_spec,
- const GdkRectangle *clip,
- int line_width)
-{
- GdkGC *gc;
- GdkGCValues values;
- GdkColor color;
-
- meta_color_spec_render (color_spec, widget, &color);
-
- values.foreground = color;
-
- gdk_rgb_find_color (gdk_drawable_get_colormap (drawable),
- &values.foreground);
-
- values.line_width = line_width;
-
- gc = gdk_gc_new_with_values (drawable, &values,
- GDK_GC_FOREGROUND | GDK_GC_LINE_WIDTH);
-
- if (clip)
- gdk_gc_set_clip_rectangle (gc,
- (GdkRectangle*) clip); /* const cast */
-
- return gc;
-}
-
static GdkPixbuf*
apply_alpha (GdkPixbuf *pixbuf,
MetaAlphaGradientSpec *spec,
@@ -2988,54 +2958,6 @@ apply_alpha (GdkPixbuf *pixb
return pixbuf;
}
-static void
-render_pixbuf (GdkDrawable *drawable,
- const GdkRectangle *clip,
- GdkPixbuf *pixbuf,
- int x,
- int y)
-{
- /* grumble, render_to_drawable_alpha does not accept a clip
- * mask, so we have to go through some BS
- */
- /* FIXME once GTK 1.3.13 has been out a while we can use
- * render_to_drawable() which now does alpha with clip.
- *
- * Though the gdk_rectangle_intersect() check may be a useful
- * optimization anyway.
- */
- GdkRectangle pixbuf_rect;
- GdkRectangle draw_rect;
-
- pixbuf_rect.x = x;
- pixbuf_rect.y = y;
- pixbuf_rect.width = gdk_pixbuf_get_width (pixbuf);
- pixbuf_rect.height = gdk_pixbuf_get_height (pixbuf);
-
- if (clip)
- {
- if (!gdk_rectangle_intersect ((GdkRectangle*)clip,
- &pixbuf_rect, &draw_rect))
- return;
- }
- else
- {
- draw_rect = pixbuf_rect;
- }
-
- gdk_draw_pixbuf (drawable,
- NULL,
- pixbuf,
- draw_rect.x - pixbuf_rect.x,
- draw_rect.y - pixbuf_rect.y,
- draw_rect.x, draw_rect.y,
- draw_rect.width,
- draw_rect.height,
- GDK_RGB_DITHER_NORMAL,
- draw_rect.x - pixbuf_rect.x,
- draw_rect.y - pixbuf_rect.y);
-}
-
static GdkPixbuf*
pixbuf_tile (GdkPixbuf *tile,
int width,
@@ -3476,6 +3398,17 @@ fill_env (MetaPositionExprEnv *env,
env->theme = meta_current_theme;
}
+/* This code was originally rendering anti-aliased using X primitives, and
+ * now has been switched to draw anti-aliased using cairo. In general, the
+ * closest correspondence between X rendering and cairo rendering is given
+ * by offsetting the geometry by 0.5 pixels in both directions before rendering
+ * with cairo. This is because X samples at the upper left corner of the
+ * pixel while cairo averages over the entire pixel. However, in the cases
+ * where the X rendering was an exact rectangle with no "jaggies"
+ * we need to be a bit careful about applying the offset. We want to produce
+ * the exact same pixel-aligned rectangle, rather than a rectangle with
+ * fuzz around the edges.
+ */
static void
meta_draw_op_draw_with_env (const MetaDrawOp *op,
GtkStyle *style_gtk,
@@ -3486,7 +3419,18 @@ meta_draw_op_draw_with_env (const MetaDr
MetaRectangle rect,
MetaPositionExprEnv *env)
{
- GdkGC *gc;
+ GdkColor color;
+ cairo_t *cr;
+
+ cr = gdk_cairo_create (drawable);
+
+ cairo_set_line_width (cr, 1.0);
+
+ if (clip)
+ {
+ gdk_cairo_rectangle (cr, clip);
+ cairo_clip (cr);
+ }
switch (op->type)
{
@@ -3494,18 +3438,19 @@ meta_draw_op_draw_with_env (const MetaDr
{
int x1, x2, y1, y2;
- gc = get_gc_for_primitive (widget, drawable,
- op->data.line.color_spec,
- clip,
- op->data.line.width);
+ meta_color_spec_render (op->data.line.color_spec, widget, &color);
+ gdk_cairo_set_source_color (cr, &color);
+
+ if (op->data.line.width > 0)
+ cairo_set_line_width (cr, op->data.line.width);
if (op->data.line.dash_on_length > 0 &&
op->data.line.dash_off_length > 0)
{
- gint8 dash_list[2];
+ double dash_list[2];
dash_list[0] = op->data.line.dash_on_length;
dash_list[1] = op->data.line.dash_off_length;
- gdk_gc_set_dashes (gc, 0, dash_list, 2);
+ cairo_set_dash (cr, dash_list, 2, 0);
}
x1 = parse_x_position_unchecked (op->data.line.x1, env);
@@ -3514,7 +3459,10 @@ meta_draw_op_draw_with_env (const MetaDr
if (!op->data.line.x2 &&
!op->data.line.y2 &&
op->data.line.width==0)
- gdk_draw_point (drawable, gc, x1, y1);
+ {
+ cairo_rectangle (cr, x1, y1, 1, 1);
+ cairo_fill (cr);
+ }
else
{
if (op->data.line.x2)
@@ -3527,10 +3475,34 @@ meta_draw_op_draw_with_env (const MetaDr
else
y2 = y1;
- gdk_draw_line (drawable, gc, x1, y1, x2, y2);
- }
+ /* This is one of the cases where we are matching the exact
+ * pixel aligned rectangle produced by X.
+ */
+ if (y1 == y2 || x1 == x2)
+ {
+ double offset = (op->data.line.width == 0 ||
+ op->data.line.width % 2) ? .5 : 0;
+ /* X includes end points for lines of width 0 */
+ double line_extend = op->data.line.width == 0 ? 1. : 0.;
- g_object_unref (G_OBJECT (gc));
+ if (y1 == y2)
+ {
+ cairo_move_to (cr, x1, y1 + offset);
+ cairo_line_to (cr, x2 + line_extend, y2 + offset);
+ }
+ else
+ {
+ cairo_move_to (cr, x1 + offset, y1);
+ cairo_line_to (cr, x2 + offset, y2 + line_extend);
+ }
+ }
+ else
+ {
+ cairo_move_to (cr, x1 + .5, y1 + .5);
+ cairo_line_to (cr, x2 + .5, y2 + .5);
+ }
+ cairo_stroke (cr);
+ }
}
break;
@@ -3538,45 +3510,69 @@ meta_draw_op_draw_with_env (const MetaDr
{
int rx, ry, rwidth, rheight;
- gc = get_gc_for_primitive (widget, drawable,
- op->data.rectangle.color_spec,
- clip, 0);
+ meta_color_spec_render (op->data.rectangle.color_spec, widget, &color);
+ gdk_cairo_set_source_color (cr, &color);
rx = parse_x_position_unchecked (op->data.rectangle.x, env);
ry = parse_y_position_unchecked (op->data.rectangle.y, env);
rwidth = parse_size_unchecked (op->data.rectangle.width, env);
rheight = parse_size_unchecked (op->data.rectangle.height, env);
- gdk_draw_rectangle (drawable, gc,
- op->data.rectangle.filled,
- rx, ry, rwidth, rheight);
-
- g_object_unref (G_OBJECT (gc));
+ /* Filled and stroked rectangles are the other cases
+ * we pixel-align to X rasterization
+ */
+ if (op->data.rectangle.filled)
+ {
+ cairo_rectangle (cr, rx, ry, rwidth, rheight);
+ cairo_fill (cr);
+ }
+ else
+ {
+ cairo_rectangle (cr, rx + .5, ry + .5, rwidth, rheight);
+ cairo_stroke (cr);
+ }
}
break;
case META_DRAW_ARC:
{
int rx, ry, rwidth, rheight;
+ double start_angle, end_angle;
+ double center_x, center_y;
- gc = get_gc_for_primitive (widget, drawable,
- op->data.arc.color_spec,
- clip, 0);
+ meta_color_spec_render (op->data.arc.color_spec, widget, &color);
+ gdk_cairo_set_source_color (cr, &color);
rx = parse_x_position_unchecked (op->data.arc.x, env);
ry = parse_y_position_unchecked (op->data.arc.y, env);
rwidth = parse_size_unchecked (op->data.arc.width, env);
rheight = parse_size_unchecked (op->data.arc.height, env);
- gdk_draw_arc (drawable,
- gc,
- op->data.arc.filled,
- rx, ry, rwidth, rheight,
- op->data.arc.start_angle * (360.0 * 64.0) -
- (90.0 * 64.0), /* start at 12 instead of 3 oclock */
- op->data.arc.extent_angle * (360.0 * 64.0));
+ start_angle = op->data.arc.start_angle * (M_PI / 180.)
+ - (.25 * M_PI); /* start at 12 instead of 3 oclock */
+ end_angle = start_angle + op->data.arc.extent_angle * (M_PI / 180.);
+ center_x = rx + (double)rwidth / 2. + .5;
+ center_y = ry + (double)rheight / 2. + .5;
+
+ cairo_save (cr);
+
+ cairo_translate (cr, center_x, center_y);
+ cairo_scale (cr, (double)rwidth / 2., (double)rheight / 2.);
- g_object_unref (G_OBJECT (gc));
+ if (op->data.arc.extent_angle >= 0)
+ cairo_arc (cr, 0, 0, 1, start_angle, end_angle);
+ else
+ cairo_arc_negative (cr, 0, 0, 1, start_angle, end_angle);
+
+ cairo_restore (cr);
+
+ if (op->data.arc.filled)
+ {
+ cairo_line_to (cr, center_x, center_y);
+ cairo_fill (cr);
+ }
+ else
+ cairo_stroke (cr);
}
break;
@@ -3599,15 +3595,11 @@ meta_draw_op_draw_with_env (const MetaDr
if (!needs_alpha)
{
- gc = get_gc_for_primitive (widget, drawable,
- op->data.tint.color_spec,
- clip, 0);
-
- gdk_draw_rectangle (drawable, gc,
- TRUE,
- rx, ry, rwidth, rheight);
+ meta_color_spec_render (op->data.tint.color_spec, widget, &color);
+ gdk_cairo_set_source_color (cr, &color);
- g_object_unref (G_OBJECT (gc));
+ cairo_rectangle (cr, rx + .5, ry + .5, rwidth, rheight);
+ cairo_fill (cr);
}
else
{
@@ -3618,7 +3610,8 @@ meta_draw_op_draw_with_env (const MetaDr
if (pixbuf)
{
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
+ cairo_paint (cr);
g_object_unref (G_OBJECT (pixbuf));
}
@@ -3641,7 +3634,8 @@ meta_draw_op_draw_with_env (const MetaDr
if (pixbuf)
{
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
+ cairo_paint (cr);
g_object_unref (G_OBJECT (pixbuf));
}
@@ -3670,7 +3664,8 @@ meta_draw_op_draw_with_env (const MetaDr
rx = parse_x_position_unchecked (op->data.image.x, env);
ry = parse_y_position_unchecked (op->data.image.y, env);
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
+ cairo_paint (cr);
g_object_unref (G_OBJECT (pixbuf));
}
@@ -3753,7 +3748,8 @@ meta_draw_op_draw_with_env (const MetaDr
rx = parse_x_position_unchecked (op->data.icon.x, env);
ry = parse_y_position_unchecked (op->data.icon.y, env);
- render_pixbuf (drawable, clip, pixbuf, rx, ry);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
+ cairo_paint (cr);
g_object_unref (G_OBJECT (pixbuf));
}
@@ -3766,9 +3762,8 @@ meta_draw_op_draw_with_env (const MetaDr
int rx, ry;
PangoRectangle ink_rect, logical_rect;
- gc = get_gc_for_primitive (widget, drawable,
- op->data.title.color_spec,
- clip, 0);
+ meta_color_spec_render (op->data.title.color_spec, widget, &color);
+ gdk_cairo_set_source_color (cr, &color);
rx = parse_x_position_unchecked (op->data.title.x, env);
ry = parse_y_position_unchecked (op->data.title.y, env);
@@ -3790,7 +3785,7 @@ meta_draw_op_draw_with_env (const MetaDr
* correct for this, by reducing the ellipsization width by the overflow
* of the un-ellipsized text on the right... it's always the visual
* right we want regardless of bidi, since since the X we pass in to
- * gdk_draw_layout() is always the left edge of the line.
+ * cairo_move_to() is always the left edge of the line.
*/
right_bearing = (ink_rect.x + ink_rect.width) - (logical_rect.x + logical_rect.width);
right_bearing = MAX (right_bearing, 0);
@@ -3806,15 +3801,12 @@ meta_draw_op_draw_with_env (const MetaDr
pango_layout_set_width (info->title_layout, PANGO_SCALE * ellipsize_width);
}
- gdk_draw_layout (drawable, gc,
- rx, ry,
- info->title_layout);
+ cairo_move_to (cr, rx, ry);
+ pango_cairo_show_layout (cr, info->title_layout);
/* Remove any ellipsization we might have set; will short-circuit
* if the width is already -1 */
pango_layout_set_width (info->title_layout, -1);
-
- g_object_unref (G_OBJECT (gc));
}
break;
@@ -3882,6 +3874,8 @@ meta_draw_op_draw_with_env (const MetaDr
}
break;
}
+
+ cairo_destroy (cr);
}
void
@@ -6637,7 +6631,8 @@ draw_bg_gradient_composite (const MetaTe
GDK_INTERP_BILINEAR,
255 * alpha);
- render_pixbuf (drawable, clip, composited, x, y);
+ gdk_cairo_set_source_pixbuf (cr, composited, x, y);
+ cairo_paint (cr);
g_object_unref (G_OBJECT (bg_pixbuf));
g_object_unref (G_OBJECT (fg_pixbuf));
Index: mutter-2.31.5/src/ui/ui.c
===================================================================
--- mutter-2.31.5.orig/src/ui/ui.c
+++ mutter-2.31.5/src/ui/ui.c
@@ -419,21 +419,17 @@ meta_image_window_set (MetaImageWindow *
int y)
{
GdkWindow *window;
+ cairo_t *cr;
/* We use a back pixmap to avoid having to handle exposes, because
* it's really too slow for large clients being minimized, etc.
* and this way flicker is genuinely zero.
*/
- gdk_draw_pixbuf (iw->pixmap,
- gtk_widget_get_style (iw->window)->black_gc,
- pixbuf,
- 0, 0,
- 0, 0,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
+ cr = gdk_cairo_create (iw->pixmap);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
window = gtk_widget_get_window (iw->window);
@@ -1001,7 +997,7 @@ meta_ui_get_pixbuf_from_pixmap (Pixmap
depth = gdk_drawable_get_depth (GDK_DRAWABLE (gpmap));
if (depth <= 24)
- cmap = gdk_screen_get_rgb_colormap (screen);
+ cmap = gdk_screen_get_system_colormap (screen);
else
cmap = gdk_screen_get_rgba_colormap (screen);
Index: mutter-2.31.5/src/gdk-compat.h
===================================================================
--- mutter-2.31.5.orig/src/gdk-compat.h
+++ mutter-2.31.5/src/gdk-compat.h
@@ -11,24 +11,7 @@
#if !GTK_CHECK_VERSION (2, 21, 1)
-#define gdk_window_get_background(w,c) *c = GDK_WINDOW_OBJECT (w)->bg_color
#define gdk_visual_get_depth(v) GDK_VISUAL(v)->depth
-#define gdk_window_get_back_pixmap(w,p,r) \
- G_STMT_START { \
- GdkWindowObject *priv = GDK_WINDOW_OBJECT (w); \
- \
- if (p != NULL) \
- { \
- if (priv->bg_pixmap == GDK_PARENT_RELATIVE_BG || \
- priv->bg_pixmap == GDK_NO_BG) \
- *p = NULL; \
- else \
- *p = priv->bg_pixmap; \
- } \
- \
- if (r != NULL) \
- *r = (priv->bg_pixmap == GDK_PARENT_RELATIVE_BG); \
- } G_STMT_END
#endif /*GTK_CHECK_VERSION */