Begin to support drawing backgrounds with Gtk+ 3

This commit is contained in:
Pierre Pronchery 2015-10-30 16:08:17 +01:00
parent f4deeb739e
commit d7154a53b5

View File

@ -127,6 +127,11 @@ struct _Desktop
GdkWindow * back; GdkWindow * back;
GtkIconTheme * theme; GtkIconTheme * theme;
GtkWidget * menu; GtkWidget * menu;
#if GTK_CHECK_VERSION(3, 0, 0)
cairo_t * cairo;
#else
GdkPixmap * pixmap;
#endif
}; };
struct _DesktopCategory struct _DesktopCategory
@ -1448,22 +1453,19 @@ static int _desktop_get_workarea(Desktop * desktop)
/* useful */ /* useful */
/* desktop_background */ /* desktop_background */
#if !GTK_CHECK_VERSION(3, 0, 0) static void _background_how_centered(Desktop * desktop, GdkRectangle * window,
static void _background_how_centered(GdkRectangle * window, GdkPixmap * pixmap,
char const * filename, GError ** error); char const * filename, GError ** error);
static void _background_how_scaled(GdkRectangle * window, GdkPixmap * pixmap, static void _background_how_scaled(Desktop * desktop, GdkRectangle * window,
char const * filename, GError ** error); char const * filename, GError ** error);
static void _background_how_scaled_ratio(GdkRectangle * window, static void _background_how_scaled_ratio(Desktop * desktop,
GdkPixmap * pixmap, char const * filename, GError ** error); GdkRectangle * window, char const * filename, GError ** error);
static void _background_how_tiled(GdkRectangle * window, GdkPixmap * pixmap, static void _background_how_tiled(Desktop * desktop, GdkRectangle * window,
char const * filename, GError ** error); char const * filename, GError ** error);
static void _background_monitor(Desktop * desktop, char const * filename, static void _background_monitor(Desktop * desktop, char const * filename,
DesktopHows how, gboolean extend, GdkPixmap * pixmap, DesktopHows how, gboolean extend, GdkRectangle * window,
GdkRectangle * window, int monitor); int monitor);
static void _background_monitors(Desktop * desktop, char const * filename, static void _background_monitors(Desktop * desktop, char const * filename,
DesktopHows how, gboolean extend, GdkPixmap * pixmap, DesktopHows how, gboolean extend, GdkRectangle * window);
GdkRectangle * window);
#endif
#if GTK_CHECK_VERSION(3, 0, 0) #if GTK_CHECK_VERSION(3, 0, 0)
static void _desktop_draw_background(Desktop * desktop, GdkRGBA * color, static void _desktop_draw_background(Desktop * desktop, GdkRGBA * color,
@ -1473,11 +1475,7 @@ static void _desktop_draw_background(Desktop * desktop, GdkColor * color,
char const * filename, DesktopHows how, gboolean extend) char const * filename, DesktopHows how, gboolean extend)
#endif #endif
{ {
GdkRectangle window = desktop->window; #if !GTK_CHECK_VERSION(3, 0, 0)
#if GTK_CHECK_VERSION(3, 0, 0)
cairo_t * cairo;
#else
GdkPixmap * pixmap;
GdkGC * gc; GdkGC * gc;
GtkStyle * style; GtkStyle * style;
#endif #endif
@ -1489,62 +1487,78 @@ static void _desktop_draw_background(Desktop * desktop, GdkColor * color,
if(how == DESKTOP_HOW_NONE) if(how == DESKTOP_HOW_NONE)
return; return;
#if GTK_CHECK_VERSION(3, 0, 0) #if GTK_CHECK_VERSION(3, 0, 0)
/* FIXME really implement */ desktop->cairo = gdk_cairo_create(desktop->root);
cairo = gdk_cairo_create(NULL); cairo_set_source_rgba(desktop->cairo, color->red, color->green,
cairo_set_source_rgba(cairo, color->red, color->green, color->blue, color->blue, 1.0);
1.0); gdk_cairo_rectangle(desktop->cairo, &desktop->window);
gdk_cairo_rectangle(cairo, &window);
cairo_destroy(cairo);
#else
/* draw default color */
pixmap = gdk_pixmap_new(desktop->back, window.width, window.height, -1);
gc = gdk_gc_new(pixmap);
gdk_gc_set_rgb_fg_color(gc, color);
gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, window.width, window.height);
if(filename != NULL) if(filename != NULL)
/* draw the background */ /* draw the background */
_background_monitors(desktop, filename, how, extend, pixmap, _background_monitors(desktop, filename, how, extend,
&window); &desktop->window);
cairo_paint(desktop->cairo);
cairo_destroy(desktop->cairo);
desktop->cairo = NULL;
#else
/* draw default color */
desktop->pixmap = gdk_pixmap_new(desktop->back, desktop->window.width,
desktop->window.height, -1);
gc = gdk_gc_new(desktop->pixmap);
gdk_gc_set_rgb_fg_color(gc, color);
gdk_draw_rectangle(desktop->pixmap, gc, TRUE, 0, 0,
desktop->window.width, desktop->window.height);
if(filename != NULL)
/* draw the background */
_background_monitors(desktop, filename, how, extend,
&desktop->window);
if(desktop->desktop != NULL) if(desktop->desktop != NULL)
{ {
style = gtk_style_new(); style = gtk_style_new();
style->bg_pixmap[GTK_STATE_NORMAL] = pixmap; style->bg_pixmap[GTK_STATE_NORMAL] = desktop->pixmap;
gtk_widget_set_style(desktop->desktop, style); gtk_widget_set_style(desktop->desktop, style);
} }
else else
{ {
gdk_window_set_back_pixmap(desktop->back, pixmap, FALSE); gdk_window_set_back_pixmap(desktop->back, desktop->pixmap,
FALSE);
gdk_window_clear(desktop->back); gdk_window_clear(desktop->back);
gdk_pixmap_unref(pixmap); gdk_pixmap_unref(desktop->pixmap);
} }
desktop->pixmap = NULL;
#endif #endif
} }
#if !GTK_CHECK_VERSION(3, 0, 0) static void _background_how_centered(Desktop * desktop, GdkRectangle * window,
static void _background_how_centered(GdkRectangle * window, GdkPixmap * pixmap,
char const * filename, GError ** error) char const * filename, GError ** error)
{ {
GdkPixbuf * background; GdkPixbuf * background;
gint w; gint w;
gint h; gint h;
gint x;
gint y;
if((background = gdk_pixbuf_new_from_file(filename, error)) == NULL) if((background = gdk_pixbuf_new_from_file(filename, error)) == NULL)
return; return;
w = gdk_pixbuf_get_width(background); w = gdk_pixbuf_get_width(background);
h = gdk_pixbuf_get_height(background); h = gdk_pixbuf_get_height(background);
gdk_draw_pixbuf(pixmap, NULL, background, 0, 0, x = (window->width - w) / 2 + window->x;
(window->width - w) / 2 + window->x, y = (window->height - h) / 2 + window->y;
(window->height - h) / 2 + window->y, w, h, #if GTK_CHECK_VERSION(3, 0, 0)
gdk_cairo_set_source_pixbuf(desktop->cairo, background, x, y);
#else
gdk_draw_pixbuf(desktop->pixmap, NULL, background, 0, 0, x, y, w, h,
GDK_RGB_DITHER_NONE, 0, 0); GDK_RGB_DITHER_NONE, 0, 0);
#endif
g_object_unref(background); g_object_unref(background);
} }
static void _background_how_scaled(GdkRectangle * window, GdkPixmap * pixmap, static void _background_how_scaled(Desktop * desktop, GdkRectangle * window,
char const * filename, GError ** error) char const * filename, GError ** error)
{ {
GdkPixbuf * background; GdkPixbuf * background;
gint w; gint w;
gint h; gint h;
gint x;
gint y;
#if GTK_CHECK_VERSION(2, 6, 0) #if GTK_CHECK_VERSION(2, 6, 0)
background = gdk_pixbuf_new_from_file_at_scale(filename, window->width, background = gdk_pixbuf_new_from_file_at_scale(filename, window->width,
@ -1559,20 +1573,26 @@ static void _background_how_scaled(GdkRectangle * window, GdkPixmap * pixmap,
return; return;
w = gdk_pixbuf_get_width(background); w = gdk_pixbuf_get_width(background);
h = gdk_pixbuf_get_height(background); h = gdk_pixbuf_get_height(background);
gdk_draw_pixbuf(pixmap, NULL, background, 0, 0, x = (window->width - w) / 2 + window->x;
(window->width - w) / 2 + window->x, y = (window->height - h) / 2 + window->y;
(window->height - h) / 2 + window->y, w, h, #if GTK_CHECK_VERSION(3, 0, 0)
gdk_cairo_set_source_pixbuf(desktop->cairo, background, x, y);
#else
gdk_draw_pixbuf(desktop->pixmap, NULL, background, 0, 0, x, y, w, h,
GDK_RGB_DITHER_NONE, 0, 0); GDK_RGB_DITHER_NONE, 0, 0);
#endif
g_object_unref(background); g_object_unref(background);
} }
static void _background_how_scaled_ratio(GdkRectangle * window, static void _background_how_scaled_ratio(Desktop * desktop,
GdkPixmap * pixmap, char const * filename, GError ** error) GdkRectangle * window, char const * filename, GError ** error)
{ {
#if GTK_CHECK_VERSION(2, 4, 0) #if GTK_CHECK_VERSION(2, 4, 0)
GdkPixbuf * background; GdkPixbuf * background;
gint w; gint w;
gint h; gint h;
gint x;
gint y;
background = gdk_pixbuf_new_from_file_at_size(filename, window->width, background = gdk_pixbuf_new_from_file_at_size(filename, window->width,
window->height, error); window->height, error);
@ -1580,17 +1600,21 @@ static void _background_how_scaled_ratio(GdkRectangle * window,
return; /* XXX report error */ return; /* XXX report error */
w = gdk_pixbuf_get_width(background); w = gdk_pixbuf_get_width(background);
h = gdk_pixbuf_get_height(background); h = gdk_pixbuf_get_height(background);
gdk_draw_pixbuf(pixmap, NULL, background, 0, 0, x =(window->width - w) / 2 + window->x;
(window->width - w) / 2 + window->x, y = (window->height - h) / 2 + window->y;
(window->height - h) / 2 + window->y, w, h, #if GTK_CHECK_VERSION(3, 0, 0)
gdk_cairo_set_source_pixbuf(desktop->cairo, background, x, y);
#else
gdk_draw_pixbuf(desktop->pixmap, NULL, background, 0, 0, x, y, w, h,
GDK_RGB_DITHER_NONE, 0, 0); GDK_RGB_DITHER_NONE, 0, 0);
#endif
g_object_unref(background); g_object_unref(background);
#else #else
_background_how_scaled(window, pixmap, filename, error); _background_how_scaled(desktop, window, filename, error);
#endif #endif
} }
static void _background_how_tiled(GdkRectangle * window, GdkPixmap * pixmap, static void _background_how_tiled(Desktop * desktop, GdkRectangle * window,
char const * filename, GError ** error) char const * filename, GError ** error)
{ {
GdkPixbuf * background; GdkPixbuf * background;
@ -1605,15 +1629,20 @@ static void _background_how_tiled(GdkRectangle * window, GdkPixmap * pixmap,
h = gdk_pixbuf_get_height(background); h = gdk_pixbuf_get_height(background);
for(j = 0; j < window->height; j += h) for(j = 0; j < window->height; j += h)
for(i = 0; i < window->width; i += w) for(i = 0; i < window->width; i += w)
gdk_draw_pixbuf(pixmap, NULL, background, 0, 0, #if GTK_CHECK_VERSION(3, 0, 0)
gdk_cairo_set_source_pixbuf(desktop->cairo, background,
i + window->x, j + window->y);
#else
gdk_draw_pixbuf(desktop->pixmap, NULL, background, 0, 0,
i + window->x, j + window->y, w, h, i + window->x, j + window->y, w, h,
GDK_RGB_DITHER_NONE, 0, 0); GDK_RGB_DITHER_NONE, 0, 0);
#endif
g_object_unref(background); g_object_unref(background);
} }
static void _background_monitor(Desktop * desktop, char const * filename, static void _background_monitor(Desktop * desktop, char const * filename,
DesktopHows how, gboolean extend, GdkPixmap * pixmap, DesktopHows how, gboolean extend, GdkRectangle * window,
GdkRectangle * window, int monitor) int monitor)
{ {
GError * error = NULL; GError * error = NULL;
@ -1625,18 +1654,19 @@ static void _background_monitor(Desktop * desktop, char const * filename,
case DESKTOP_HOW_NONE: case DESKTOP_HOW_NONE:
break; break;
case DESKTOP_HOW_CENTERED: case DESKTOP_HOW_CENTERED:
_background_how_centered(window, pixmap, filename, _background_how_centered(desktop, window, filename,
&error); &error);
break; break;
case DESKTOP_HOW_SCALED_RATIO: case DESKTOP_HOW_SCALED_RATIO:
_background_how_scaled_ratio(window, pixmap, filename, _background_how_scaled_ratio(desktop, window, filename,
&error); &error);
break; break;
case DESKTOP_HOW_TILED: case DESKTOP_HOW_TILED:
_background_how_tiled(window, pixmap, filename, &error); _background_how_tiled(desktop, window, filename,
&error);
break; break;
case DESKTOP_HOW_SCALED: case DESKTOP_HOW_SCALED:
_background_how_scaled(window, pixmap, filename, _background_how_scaled(desktop, window, filename,
&error); &error);
break; break;
} }
@ -1648,18 +1678,15 @@ static void _background_monitor(Desktop * desktop, char const * filename,
} }
static void _background_monitors(Desktop * desktop, char const * filename, static void _background_monitors(Desktop * desktop, char const * filename,
DesktopHows how, gboolean extend, GdkPixmap * pixmap, DesktopHows how, gboolean extend, GdkRectangle * window)
GdkRectangle * window)
{ {
gint n; gint n;
gint i; gint i;
n = (extend != TRUE) ? gdk_screen_get_n_monitors(desktop->screen) : 1; n = (extend != TRUE) ? gdk_screen_get_n_monitors(desktop->screen) : 1;
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
_background_monitor(desktop, filename, how, extend, pixmap, _background_monitor(desktop, filename, how, extend, window, i);
window, i);
} }
#endif
/* desktop_icon_add */ /* desktop_icon_add */