summaryrefslogtreecommitdiff
path: root/typing-break/drw-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'typing-break/drw-utils.c')
-rw-r--r--typing-break/drw-utils.c250
1 files changed, 250 insertions, 0 deletions
diff --git a/typing-break/drw-utils.c b/typing-break/drw-utils.c
new file mode 100644
index 00000000..ff19f74f
--- /dev/null
+++ b/typing-break/drw-utils.c
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2003 Richard Hult <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include "drw-utils.h"
+
+static GdkPixbuf *
+create_tile_pixbuf (GdkPixbuf *dest_pixbuf,
+ GdkPixbuf *src_pixbuf,
+ GdkRectangle *field_geom,
+ guint alpha,
+ GdkColor *bg_color)
+{
+ gboolean need_composite;
+ gboolean use_simple;
+ gdouble cx, cy;
+ gdouble colorv;
+ gint pwidth, pheight;
+
+ need_composite = (alpha < 255 || gdk_pixbuf_get_has_alpha (src_pixbuf));
+ use_simple = (dest_pixbuf == NULL);
+
+ if (dest_pixbuf == NULL)
+ dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ FALSE, 8,
+ field_geom->width, field_geom->height);
+
+ if (need_composite && use_simple)
+ colorv = ((bg_color->red & 0xff00) << 8) |
+ (bg_color->green & 0xff00) |
+ ((bg_color->blue & 0xff00) >> 8);
+ else
+ colorv = 0;
+
+ pwidth = gdk_pixbuf_get_width (src_pixbuf);
+ pheight = gdk_pixbuf_get_height (src_pixbuf);
+
+ for (cy = 0; cy < field_geom->height; cy += pheight) {
+ for (cx = 0; cx < field_geom->width; cx += pwidth) {
+ if (need_composite && !use_simple)
+ gdk_pixbuf_composite (src_pixbuf, dest_pixbuf,
+ cx, cy,
+ MIN (pwidth, field_geom->width - cx),
+ MIN (pheight, field_geom->height - cy),
+ cx, cy,
+ 1.0, 1.0,
+ GDK_INTERP_BILINEAR,
+ alpha);
+ else if (need_composite && use_simple)
+ gdk_pixbuf_composite_color (src_pixbuf, dest_pixbuf,
+ cx, cy,
+ MIN (pwidth, field_geom->width - cx),
+ MIN (pheight, field_geom->height - cy),
+ cx, cy,
+ 1.0, 1.0,
+ GDK_INTERP_BILINEAR,
+ alpha,
+ 65536, 65536, 65536,
+ colorv, colorv);
+ else
+ gdk_pixbuf_copy_area (src_pixbuf,
+ 0, 0,
+ MIN (pwidth, field_geom->width - cx),
+ MIN (pheight, field_geom->height - cy),
+ dest_pixbuf,
+ cx, cy);
+ }
+ }
+
+ return dest_pixbuf;
+}
+
+static gboolean
+window_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ cairo_t *context;
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ int width;
+ int height;
+
+ context = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ cairo_set_operator (context, CAIRO_OPERATOR_SOURCE);
+ gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
+
+ surface = cairo_surface_create_similar (cairo_get_target (context),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width,
+ height);
+
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
+ goto done;
+ }
+
+ cr = cairo_create (surface);
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
+ goto done;
+ }
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+
+ /* draw a box */
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_set_source_rgba (cr, 0.2, 0.2, 0.2, 0.5);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+
+ cairo_set_source_surface (context, surface, 0, 0);
+ cairo_paint (context);
+
+ done:
+ if (surface != NULL) {
+ cairo_surface_destroy (surface);
+ }
+ cairo_destroy (context);
+
+ return FALSE;
+}
+
+static void
+set_pixmap_background (GtkWidget *window)
+{
+ GdkScreen *screen;
+ GdkPixbuf *tmp_pixbuf, *pixbuf, *tile_pixbuf;
+ GdkPixmap *pixmap;
+ GdkRectangle rect;
+ GdkColor color;
+ gint width, height;
+
+ gtk_widget_realize (window);
+
+ screen = gtk_widget_get_screen (window);
+ width = gdk_screen_get_width (screen);
+ height = gdk_screen_get_height (screen);
+
+ tmp_pixbuf = gdk_pixbuf_get_from_drawable (NULL,
+ gdk_screen_get_root_window (screen),
+ gdk_screen_get_system_colormap (screen),
+ 0,
+ 0,
+ 0,
+ 0,
+ width, height);
+
+ pixbuf = gdk_pixbuf_new_from_file (IMAGEDIR "/ocean-stripes.png", NULL);
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+
+ color.red = 0;
+ color.blue = 0;
+ color.green = 0;
+
+ tile_pixbuf = create_tile_pixbuf (NULL,
+ pixbuf,
+ &rect,
+ 155,
+ &color);
+
+ g_object_unref (pixbuf);
+
+ gdk_pixbuf_composite (tile_pixbuf,
+ tmp_pixbuf,
+ 0,
+ 0,
+ width,
+ height,
+ 0,
+ 0,
+ 1,
+ 1,
+ GDK_INTERP_NEAREST,
+ 225);
+
+ g_object_unref (tile_pixbuf);
+
+ pixmap = gdk_pixmap_new (gtk_widget_get_window (window),
+ width,
+ height,
+ -1);
+
+ gdk_draw_pixbuf (pixmap,
+ NULL,
+ tmp_pixbuf,
+ 0,
+ 0,
+ 0,
+ 0,
+ width,
+ height,
+ GDK_RGB_DITHER_NONE,
+ 0,
+ 0);
+
+ g_object_unref (tmp_pixbuf);
+
+ gdk_window_set_back_pixmap (gtk_widget_get_window (window), pixmap, FALSE);
+ g_object_unref (pixmap);
+}
+
+void
+drw_setup_background (GtkWidget *window)
+{
+ GdkScreen *screen;
+ GdkColormap *colormap;
+ gboolean is_composited;
+
+ screen = gtk_widget_get_screen (window);
+ colormap = gdk_screen_get_rgba_colormap (screen);
+
+ if (colormap != NULL && gdk_screen_is_composited (screen)) {
+ gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
+ is_composited = TRUE;
+ } else {
+ is_composited = FALSE;
+ }
+
+ if (is_composited) {
+ g_signal_connect (window, "expose-event", G_CALLBACK (window_expose_event), window);
+ } else {
+ set_pixmap_background (window);
+ }
+}
+