summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
l---------Makefile1
-rw-r--r--Makefile.agl12
-rw-r--r--Makefile.glx12
-rw-r--r--bg.pngbin0 -> 191640 bytes
-rw-r--r--bg_surface.pngbin0 -> 67135 bytes
-rw-r--r--cairogears.c317
-rw-r--r--comp.c163
-rw-r--r--desktop-post.pngbin0 -> 67135 bytes
-rw-r--r--desktop.pngbin0 -> 59793 bytes
-rw-r--r--fakewin.pngbin0 -> 2557 bytes
-rw-r--r--fdface.c87
-rw-r--r--fdface.h32
-rw-r--r--fdhand.c136
-rw-r--r--fdhand.h33
-rw-r--r--fdlogo.c173
-rw-r--r--fdlogo.h33
-rw-r--r--fg.pngbin0 -> 71226 bytes
-rw-r--r--glider.pngbin0 -> 921 bytes
-rw-r--r--orion.pngbin0 -> 286253 bytes
-rw-r--r--shadow.c366
-rw-r--r--text.c179
-rw-r--r--text2.c130
-rw-r--r--trap.c263
23 files changed, 1937 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 120000
index 0000000..7bd461b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1 @@
+Makefile.glx \ No newline at end of file
diff --git a/Makefile.agl b/Makefile.agl
new file mode 100644
index 0000000..5e80968
--- /dev/null
+++ b/Makefile.agl
@@ -0,0 +1,12 @@
+CFLAGS=-g -Wall `pkg-config --cflags cairo` `pkg-config --cflags glitz-agl` -DGLITZ_AGL_BACKEND
+LDFLAGS=`pkg-config --libs cairo` `pkg-config --libs glitz-agl` -framework OpenGL -framework AGL -framework Carbon -lpng -lm
+
+PROGS=cairogears
+
+cairogears: trap.o comp.o text.o text2.o shadow.o read_png.o fdface.o fdhand.o fdlogo.o
+
+all: $(PROGS)
+
+clean:
+ rm -f $(PROGS) *.o
+
diff --git a/Makefile.glx b/Makefile.glx
new file mode 100644
index 0000000..674c6fe
--- /dev/null
+++ b/Makefile.glx
@@ -0,0 +1,12 @@
+CFLAGS=-O2 -g -Wall `pkg-config --cflags cairo`
+LDFLAGS=`pkg-config --libs cairo`
+
+PROGS=cairogears
+
+all: $(PROGS)
+
+cairogears: trap.o comp.o text.o text2.o shadow.o fdface.o fdhand.o fdlogo.o
+
+clean:
+ rm -f $(PROGS) *.o
+
diff --git a/bg.png b/bg.png
new file mode 100644
index 0000000..30b1902
--- /dev/null
+++ b/bg.png
Binary files differ
diff --git a/bg_surface.png b/bg_surface.png
new file mode 100644
index 0000000..090df6b
--- /dev/null
+++ b/bg_surface.png
Binary files differ
diff --git a/cairogears.c b/cairogears.c
new file mode 100644
index 0000000..f3a16f9
--- /dev/null
+++ b/cairogears.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <cairo.h>
+#include <cairo-xlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+#include <strings.h>
+
+#define PACKAGE "cairogears"
+
+#define WINDOW_WIDTH 512
+#define WINDOW_HEIGHT 512
+
+void trap_setup (cairo_surface_t *target, int w, int h);
+void trap_render (cairo_t *cr, int w, int h);
+
+void comp_setup (cairo_surface_t *target, int w, int h);
+void comp_render (cairo_t *cr, int w, int h);
+
+void text_setup (cairo_surface_t *target, int w, int h);
+void text_render (cairo_t *cr, int w, int h);
+
+void text2_setup (cairo_surface_t *target, int w, int h);
+void text2_render (cairo_t *cr, int w, int h);
+
+void shadow_setup (cairo_surface_t *target, int w, int h);
+void shadow_render (cairo_t *cr, int w, int h);
+
+static enum {
+ XRENDER_TYPE,
+ IMAGE_TYPE
+} output_type = XRENDER_TYPE;
+static const char *backend = "image";
+
+static enum {
+ NONE,
+ STROKE_AND_FILL_TYPE,
+ COMPOSITE_AND_TRANSFORM_TYPE,
+ TEXT_PATH_TYPE,
+ TEXT_BITMAP_TYPE,
+ SHADOW_TYPE
+} test_type = NONE;
+static const char *test = "gradient";
+
+static const char *program_name;
+
+static Display *dpy;
+static Window win;
+static XWMHints xwmh = {
+ (InputHint|StateHint),
+ False,
+ NormalState,
+ 0,
+ 0,
+ 0, 0,
+ 0,
+ 0,
+};
+
+static cairo_t *cr;
+static cairo_surface_t *win_surface;
+static cairo_surface_t *surface;
+
+static unsigned int frame_cnt = 0;
+
+int fast = 0;
+int fill_gradient = 0;
+int aa = -1;
+
+extern unsigned int glyph_cnt;
+
+void
+usage(void)
+{
+
+ printf ("Usage: %s [-image | -xrender] TEST\n\n"
+ "\tThe following tests are available:\n\n"
+ "\tTRAP Trapezoid fill test\n"
+ "\tGRAD Trapezoid gradient test\n"
+ "\tCOMP Composite and transform test\n"
+ "\tTEXT Text path test\n"
+ "\tTEXT2 Text bitmap test\n"
+ "\tSHADOW Composite with mask and convolution filter test\n\n",
+ program_name);
+}
+
+void alarmhandler (int sig) {
+ if (sig == SIGALRM) {
+ if (test_type == TEXT_BITMAP_TYPE) {
+ printf ("%s - %s: %d glyphs in 5.0 seconds = %.3f GPS\n",
+ backend, test,
+ glyph_cnt, glyph_cnt / 5.0);
+ glyph_cnt = 0;
+ }
+ printf ("%s - %s: %d frames in 5.0 seconds = %.3f FPS\n",
+ backend, test,
+ frame_cnt, frame_cnt / 5.0);
+ frame_cnt = 0;
+ }
+ signal (SIGALRM, alarmhandler);
+ alarm(5);
+}
+
+int
+main (int argc, char **argv) {
+
+ XEvent event;
+ XSizeHints xsh;
+ XSetWindowAttributes xswa;
+
+ unsigned int width, height, window_width, window_height;
+ int i;
+
+ program_name = argv[0];
+
+ for (i = 1; i < argc; i++) {
+ if (!strcasecmp ("-image", argv[i])) {
+ output_type = IMAGE_TYPE;
+ backend = "image";
+ } else if (!strcasecmp ("-xrender", argv[i])) {
+ output_type = XRENDER_TYPE;
+ backend = "xrender";
+ } else if (!strcasecmp ("TRAP", argv[i])) {
+ test_type = STROKE_AND_FILL_TYPE;
+ test = "trapezoids";
+ } else if (!strcasecmp ("GRAD", argv[i])) {
+ test_type = STROKE_AND_FILL_TYPE;
+ fill_gradient = 1;
+ test = "gradient";
+ } else if (!strcasecmp ("COMP", argv[i])) {
+ test_type = COMPOSITE_AND_TRANSFORM_TYPE;
+ test = "composite";
+ } else if (!strcasecmp ("TEXT", argv[i])) {
+ test_type = TEXT_PATH_TYPE;
+ test = "text";
+ } else if (!strcasecmp ("TEXT2", argv[i])) {
+ test_type = TEXT_BITMAP_TYPE;
+ test = "text2";
+ } else if (!strcasecmp ("SHADOW", argv[i])) {
+ test_type = SHADOW_TYPE;
+ test = "shadow";
+ } else {
+ fprintf (stderr, "%s: unrecognized option `%s'\n",
+ argv[0], argv[i]);
+ usage();
+ exit(1);
+ }
+ }
+
+ if (!test_type) {
+ usage();
+ exit(1);
+ }
+
+ window_width = width = WINDOW_WIDTH;
+ window_height = height = WINDOW_HEIGHT;
+
+ if ((dpy = XOpenDisplay (NULL)) == NULL) {
+ fprintf(stderr, "%s: can't open display: %s\n", argv[0],
+ XDisplayName (NULL));
+ exit(1);
+ }
+
+ xsh.flags = PSize;
+ xsh.width = width;
+ xsh.height = height;
+ xsh.x = 0;
+ xsh.y = 0;
+
+ win = XCreateWindow (dpy, RootWindow (dpy, DefaultScreen (dpy)),
+ xsh.x, xsh.y, xsh.width, xsh.height,
+ 0, CopyFromParent, CopyFromParent,
+ CopyFromParent, 0, &xswa);
+
+ XSetStandardProperties (dpy, win, PACKAGE, PACKAGE, None,
+ argv, argc, &xsh);
+ XSetWMHints (dpy, win, &xwmh);
+
+ XSelectInput (dpy, win, StructureNotifyMask);
+
+ win_surface = cairo_xlib_surface_create (dpy, win,
+ DefaultVisual (dpy, DefaultScreen (dpy)),
+ width, height);
+ switch (output_type) {
+ case XRENDER_TYPE:
+ surface = cairo_surface_create_similar (win_surface,
+ CAIRO_CONTENT_COLOR_ALPHA, width, height);
+ break;
+
+ case IMAGE_TYPE:
+ surface = cairo_image_surface_create (
+ CAIRO_FORMAT_ARGB32, width, height);
+ break;
+ }
+
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+
+ switch (test_type) {
+ case STROKE_AND_FILL_TYPE:
+ trap_setup (surface, width, height);
+ break;
+ case COMPOSITE_AND_TRANSFORM_TYPE:
+ comp_setup (surface, width, height);
+ break;
+ case TEXT_PATH_TYPE:
+ text_setup (surface, width, height);
+ break;
+ case TEXT_BITMAP_TYPE:
+ text2_setup (surface, width, height);
+ break;
+ case SHADOW_TYPE:
+ shadow_setup (surface, width, height);
+ break;
+ }
+
+ signal (SIGALRM, alarmhandler);
+ alarm (5);
+
+ XMapWindow (dpy, win);
+
+ if (test_type == TEXT_BITMAP_TYPE) {
+ XSync (dpy, False);
+ usleep (200000);
+ XSync (dpy, False);
+ }
+
+ for (;;) {
+ if (XPending (dpy)) {
+ XNextEvent (dpy, &event);
+ if (event.type == ConfigureNotify) {
+ width = event.xconfigure.width;
+ height = event.xconfigure.height;
+
+ cairo_xlib_surface_set_size (win_surface, width, height);
+ cairo_surface_destroy (surface);
+ switch (output_type) {
+ case XRENDER_TYPE:
+ surface = cairo_surface_create_similar (win_surface,
+ CAIRO_CONTENT_COLOR_ALPHA, width, height);
+
+
+ break;
+
+ case IMAGE_TYPE:
+ surface = cairo_image_surface_create (
+ CAIRO_FORMAT_ARGB32, width, height);
+ break;
+ }
+ }
+
+ cairo_destroy (cr);
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+ } else {
+ switch (test_type) {
+ case STROKE_AND_FILL_TYPE:
+ trap_render (cr, width, height);
+ break;
+ case COMPOSITE_AND_TRANSFORM_TYPE:
+ comp_render (cr, width, height);
+ break;
+ case TEXT_PATH_TYPE:
+ text_render (cr, width, height);
+ break;
+ case TEXT_BITMAP_TYPE:
+ text2_render (cr, width, height);
+ break;
+ case SHADOW_TYPE:
+ shadow_render (cr, width, height);
+ break;
+ }
+
+ {
+ cairo_t *cr2 = cairo_create (win_surface);
+ cairo_set_source_surface (cr2, surface, 0, 0);
+ cairo_paint (cr2);
+ cairo_destroy (cr2);
+ }
+
+ frame_cnt++;
+ }
+ }
+
+ exit (1);
+}
diff --git a/comp.c b/comp.c
new file mode 100644
index 0000000..05ea465
--- /dev/null
+++ b/comp.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <math.h>
+
+static cairo_surface_t *bg_surface;
+static cairo_surface_t *comp_surface;
+static int bg_width, bg_height;
+static int comp_width, comp_height;
+
+void
+comp_setup (cairo_surface_t *target, int w, int h)
+{
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ image = cairo_image_surface_create_from_png ("bg.png");
+ if (cairo_surface_status (image)) {
+ printf ("error reading bg.png: %s\n",
+ cairo_status_to_string (cairo_surface_status (image)));
+ exit(1);
+ }
+
+ bg_width = cairo_image_surface_get_width (image);
+ bg_height = cairo_image_surface_get_height (image);
+ bg_surface = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ bg_width, bg_height);
+
+ cr = cairo_create (bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+
+
+ image = cairo_image_surface_create_from_png ("fg.png");
+ if (cairo_surface_status (image)) {
+ printf ("error reading fg.png: %s\n",
+ cairo_status_to_string (cairo_surface_status (image)));
+ exit(1);
+ }
+
+ comp_width = cairo_image_surface_get_width (image);
+ comp_height = cairo_image_surface_get_height (image);
+ comp_surface = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ comp_width, comp_height);
+
+ cr = cairo_create (comp_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+}
+
+static double comp_x = 400 - 256 / 2;
+static double comp_y = 200 - 256 / 2;
+static double comp_x_dir = 5.0;
+static double comp_y_dir = 5.0;
+
+static double oversize = 1.0;
+static double oversize_dir = 0.001;
+
+void
+comp_render (cairo_t *cr, int w, int h)
+{
+ double scale_x, scale_y;
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_move_to (cr, 0, 0);
+
+ scale_x = ((double) w) / (double) bg_width;
+ scale_y = ((double) h) / (double) bg_height;
+
+ cairo_translate (cr,
+ -((oversize - 1.0) * (double) w) / 2.0,
+ -((oversize - 1.0) * (double) h) / 2.0);
+
+ cairo_scale (cr, scale_x * oversize, scale_y * oversize);
+
+ cairo_set_source_surface (cr, bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ oversize += oversize_dir;
+ if (oversize >= 1.2)
+ oversize_dir = -oversize_dir;
+ if (oversize <= 1.0)
+ oversize_dir = -oversize_dir;
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_move_to (cr, 0, 0);
+
+ if (comp_x_dir < 0) {
+ if (comp_x_dir < -1.0)
+ comp_x_dir += 10.0 / w;
+ } else {
+ if (comp_x_dir > 1.0)
+ comp_x_dir -= 10.0 / w;
+ }
+
+ if (comp_y_dir < 0) {
+ if (comp_y_dir < -1.0)
+ comp_y_dir += 10.0 / h;
+ } else {
+ if (comp_y_dir > 1.0)
+ comp_y_dir -= 10.0 / h;
+ }
+
+ comp_x += comp_x_dir;
+ comp_y += comp_y_dir;
+
+ if (comp_x >= (w - comp_width))
+ comp_x_dir = -(drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0);
+ else if (comp_x <= 0)
+ comp_x_dir = (drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0);
+
+ if (comp_y >= (h - comp_height))
+ comp_y_dir = -(drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0);
+ else if (comp_y <= 0)
+ comp_y_dir = drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0;
+
+ cairo_translate (cr, (int) comp_x, (int) comp_y);
+ cairo_move_to (cr, 0.0, 0.0);
+
+ cairo_set_source_surface (cr, comp_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+}
diff --git a/desktop-post.png b/desktop-post.png
new file mode 100644
index 0000000..090df6b
--- /dev/null
+++ b/desktop-post.png
Binary files differ
diff --git a/desktop.png b/desktop.png
new file mode 100644
index 0000000..3b2587d
--- /dev/null
+++ b/desktop.png
Binary files differ
diff --git a/fakewin.png b/fakewin.png
new file mode 100644
index 0000000..a21fd94
--- /dev/null
+++ b/fakewin.png
Binary files differ
diff --git a/fdface.c b/fdface.c
new file mode 100644
index 0000000..8536d1d
--- /dev/null
+++ b/fdface.c
@@ -0,0 +1,87 @@
+/*
+ * $Id: fdface.c,v 1.1 2003/12/02 03:04:46 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fdface.h"
+
+static void
+draw_fancy_tick (cairo_t *cr, double radius)
+{
+ cairo_save (cr);
+ cairo_arc (cr, 0, 0, radius, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0.73, 0.73, 0.73);
+ cairo_set_line_width (cr, radius * 2 / 3);
+ cairo_arc (cr, 0, 0, radius * 2, 0, 2 * M_PI);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+draw_plain_tick (cairo_t *cr, double radius)
+{
+ cairo_save (cr);
+ cairo_arc (cr, 0, 0, radius, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+void
+fdface_draw (cairo_t *cr, double width, double height)
+{
+ int minute;
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, width, height);
+ cairo_save (cr);
+ {
+ cairo_translate (cr, .15, .15);
+ cairo_scale (cr, .7, .7);
+ fdlogo_draw (cr, 1, 1);
+ }
+ cairo_restore (cr);
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_scale (cr, 0.93, 0.93);
+ for (minute = 0; minute < 60; minute++)
+ {
+ double degrees, radians;
+ cairo_save (cr);
+ degrees = minute * 6.0;
+ radians = degrees * M_PI / 180;
+ cairo_rotate (cr, radians);
+ cairo_translate (cr, 0, 0.5);
+ if (minute % 15 == 0)
+ draw_fancy_tick (cr, 0.015);
+ else if (minute % 5 == 0)
+ draw_fancy_tick (cr, 0.01);
+ else
+ draw_plain_tick (cr, 0.01);
+ cairo_restore (cr);
+ }
+ }
+ cairo_restore (cr);
+}
+
diff --git a/fdface.h b/fdface.h
new file mode 100644
index 0000000..1bc2bc9
--- /dev/null
+++ b/fdface.h
@@ -0,0 +1,32 @@
+/*
+ * $Id: fdface.h,v 1.1 2003/12/02 03:04:46 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FDFACE_H_
+#define _FDFACE_H_
+#include "fdlogo.h"
+
+void
+fdface_draw (cairo_t *cr, double width, double height);
+
+#endif /* _FDFACE_H_ */
diff --git a/fdhand.c b/fdhand.c
new file mode 100644
index 0000000..ece4ff6
--- /dev/null
+++ b/fdhand.c
@@ -0,0 +1,136 @@
+/*
+ * $Id: fdhand.c,v 1.3 2003/12/02 08:24:06 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fdhand.h"
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+
+#define PI_6 (M_PI/6.0)
+
+static void
+draw_hour (cairo_t *cr, double width, double length)
+{
+ double r = width / 2;
+ cairo_move_to (cr, length, -r);
+ cairo_arc (cr, length, 0, r, -M_PI_2, M_PI_2);
+ cairo_line_to (cr, width * M_SQRT2, r);
+ cairo_arc (cr, 0, 0, r*2, PI_6, - PI_6);
+ cairo_close_path (cr);
+}
+
+static void
+draw_minute (cairo_t *cr, double width, double length)
+{
+ double r = width / 2;
+ cairo_move_to (cr, length, -r);
+ cairo_arc (cr, length, 0, r, -M_PI_2, M_PI_2);
+ cairo_line_to (cr, 0, r);
+ cairo_line_to (cr, 0, -r);
+ cairo_close_path (cr);
+}
+
+static void
+draw_second (cairo_t *cr, double width, double length)
+{
+ double r = width / 2;
+ double thick = width;
+ double back = length / 3;
+ double back_thin = length / 10;
+
+ cairo_move_to (cr, length, -r);
+ cairo_arc (cr, length, 0, r, -M_PI_2, M_PI_2);
+ cairo_line_to (cr, -back_thin, r);
+ cairo_line_to (cr, -back_thin, thick);
+ cairo_line_to (cr, -back, thick);
+ cairo_line_to (cr, -back, -thick);
+ cairo_line_to (cr, -back_thin, -thick);
+ cairo_line_to (cr, -back_thin, -r);
+ cairo_close_path (cr);
+}
+
+static void
+draw_hand (cairo_t *cr, double angle, double width, double length, double alt,
+ void (*draw) (cairo_t *cr, double width, double length))
+{
+ /* Disabled shadow
+ cairo_save (cr);
+ {
+ cairo_translate (cr, alt/2, alt);
+ cairo_rotate (cr, angle);
+ (*draw) (cr, width, length);
+ cairo_set_rgb_color (cr, 0, 0, 0);
+ cairo_set_alpha (cr, 0.3);
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+ */
+
+ cairo_save (cr);
+ {
+ cairo_rotate (cr, angle);
+ (*draw) (cr, width, length);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+}
+
+static void
+draw_time (cairo_t *cr, double width, double height, struct timeval *tv, int seconds)
+{
+ double hour_angle, minute_angle, second_angle;
+ struct tm tm_ret;
+ struct tm *tm;
+
+ tm = localtime_r (&tv->tv_sec, &tm_ret);
+
+ second_angle = (tm->tm_sec + tv->tv_usec / 1000000.0) * 6.0;
+ minute_angle = tm->tm_min * 6.0 + second_angle / 60.0;
+ hour_angle = tm->tm_hour * 30.0 + minute_angle / 12.0;
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, width, height);
+ cairo_translate (cr, 0.5, 0.5);
+ draw_hand (cr, hour_angle * M_PI / 180.0 - M_PI_2,
+ 0.03, 0.25, 0.010, draw_hour);
+ draw_hand (cr, minute_angle * M_PI / 180.0 - M_PI_2,
+ 0.015, 0.39, 0.020, draw_minute);
+ if (seconds)
+ draw_hand (cr, second_angle * M_PI / 180.0 - M_PI_2,
+ 0.0075, 0.32, 0.026, draw_second);
+ }
+ cairo_restore (cr);
+}
+
+void
+fdhand_draw_now (cairo_t *cr, double width, double height, int seconds)
+{
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ draw_time (cr, width, height, &tv, seconds);
+}
+
diff --git a/fdhand.h b/fdhand.h
new file mode 100644
index 0000000..0eec9d7
--- /dev/null
+++ b/fdhand.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: fdhand.h,v 1.1 2003/12/02 03:04:47 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FDHAND_H_
+#define _FDHAND_H_
+
+#include <cairo.h>
+
+void
+fdhand_draw_now (cairo_t *cr, double width, double height, int seconds);
+
+#endif /* _FDHAND_H_ */
diff --git a/fdlogo.c b/fdlogo.c
new file mode 100644
index 0000000..a76b8bc
--- /dev/null
+++ b/fdlogo.c
@@ -0,0 +1,173 @@
+/*
+ * $Id: fdlogo.c,v 1.1 2003/12/02 03:04:47 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fdlogo.h"
+
+static void
+draw_boundary (cairo_t *cr)
+{
+ cairo_move_to (cr, 63.000, 36.000);
+
+ cairo_curve_to (cr, 63.000, 43.000,
+ 58.000, 47.000,
+ 51.000, 47.000);
+
+ cairo_line_to (cr, 13.000, 47.000);
+
+ cairo_curve_to (cr, 6.000, 47.000,
+ 1.000, 43.000,
+ 1.000, 36.000);
+
+ cairo_line_to (cr, 1.000, 12.000);
+
+ cairo_curve_to (cr, 1.000, 5.000,
+ 6.000, 1.000,
+ 13.000, 1.000);
+
+ cairo_line_to (cr, 51.000, 1.000);
+
+ cairo_curve_to (cr, 58.000, 1.000,
+ 63.000, 5.000,
+ 63.000, 12.000);
+ cairo_close_path (cr);
+}
+
+static void
+draw_outline (cairo_t *cr)
+{
+ /* cairo_set_rgb_color (cr, 0.73, 0.73, 0.73); */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_set_line_width (cr, 2);
+ draw_boundary (cr);
+ cairo_stroke (cr);
+}
+
+static void
+draw_background (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_translate (cr, 3.5, 3.5);
+ cairo_scale (cr, 0.887, 0.848);
+ draw_boundary (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+static void
+draw_window (cairo_t *cr)
+{
+ cairo_move_to (cr, -6.00, -7.125);
+
+ cairo_line_to (cr, 6.00, -7.125);
+
+ cairo_curve_to (cr, 8.00, -7.125,
+ 9.00, -6.125,
+ 9.00, -4.125);
+
+ cairo_line_to (cr, 9.00, 4.125);
+
+ cairo_curve_to (cr, 9.00, 6.125,
+ 8.00, 7.125,
+ 6.00, 7.125);
+
+ cairo_line_to (cr, -6.00, 7.125);
+
+ cairo_curve_to (cr, -8.00, 7.125,
+ -9.00, 6.125,
+ -9.00, 4.125);
+
+ cairo_line_to (cr, -9.00, -4.125);
+
+ cairo_curve_to (cr, -9.00, -6.125,
+ -8.00, -7.125,
+ -6.00, -7.125);
+ cairo_close_path (cr);
+}
+
+static void
+draw_window_at (cairo_t *cr, double x, double y, double scale)
+{
+ cairo_save (cr);
+ {
+ cairo_translate (cr, x, y);
+ cairo_scale (cr, scale, scale);
+ draw_window (cr);
+ cairo_save (cr);
+ {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_scale (cr, 1/scale, 1/scale);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+}
+
+void
+draw_windows (cairo_t *cr)
+{
+ cairo_save (cr);
+ {
+ cairo_move_to (cr, 18.00, 16.125);
+ cairo_line_to (cr, 48.25, 20.375);
+ cairo_line_to (cr, 30.25, 35.825);
+ cairo_close_path (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+ draw_window_at (cr, 18.00, 16.125, 1);
+ draw_window_at (cr, 48.25, 20.375, 0.8);
+ draw_window_at (cr, 30.25, 35.825, 0.5);
+}
+
+#define FDLOGO_ROT_X_FACTOR 1.086
+#define FDLOGO_ROT_Y_FACTOR 1.213
+#define FDLOGO_WIDTH (64 * FDLOGO_ROT_X_FACTOR)
+#define FDLOGO_HEIGHT (48 * FDLOGO_ROT_Y_FACTOR)
+
+void
+fdlogo_draw (cairo_t *cr, double width, double height)
+{
+ double x_scale, y_scale, scale, x_off, y_off;
+ cairo_save (cr);
+ x_scale = width / FDLOGO_WIDTH;
+ y_scale = height / FDLOGO_HEIGHT;
+ scale = x_scale < y_scale ? x_scale : y_scale;
+ x_off = (width - (scale * FDLOGO_WIDTH)) / 2;
+ y_off = (height - (scale * FDLOGO_HEIGHT)) / 2;
+ cairo_translate (cr, x_off, y_off);
+ cairo_scale (cr, scale, scale);
+
+ cairo_translate (cr, -2.5, 14.75);
+ cairo_rotate (cr, -0.274990703529840);
+
+ draw_outline (cr);
+ draw_background (cr);
+ draw_windows (cr);
+ cairo_restore (cr);
+}
diff --git a/fdlogo.h b/fdlogo.h
new file mode 100644
index 0000000..5349bc3
--- /dev/null
+++ b/fdlogo.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: fdlogo.h,v 1.1 2003/12/02 03:04:47 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FDLOGO_H_
+#define _FDLOGO_H_
+#include <cairo.h>
+#include <math.h>
+
+void
+fdlogo_draw (cairo_t *cr, double width, double height);
+
+#endif /* _FDLOGO_H_ */
diff --git a/fg.png b/fg.png
new file mode 100644
index 0000000..bc82a91
--- /dev/null
+++ b/fg.png
Binary files differ
diff --git a/glider.png b/glider.png
new file mode 100644
index 0000000..1569678
--- /dev/null
+++ b/glider.png
Binary files differ
diff --git a/orion.png b/orion.png
new file mode 100644
index 0000000..bce26c4
--- /dev/null
+++ b/orion.png
Binary files differ
diff --git a/shadow.c b/shadow.c
new file mode 100644
index 0000000..e16c7f7
--- /dev/null
+++ b/shadow.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <math.h>
+
+#include "fdface.h"
+#include "fdhand.h"
+
+#define PRECISION int /* int/float */
+#define TRUNC(x) ((PRECISION) (x))
+
+static cairo_surface_t *clock_bg_surface;
+static cairo_surface_t *clock_surface;
+static cairo_surface_t *glider_surface;
+static cairo_surface_t *fakewin_surface;
+static cairo_surface_t *bg_surface;
+static int bg_width, bg_height;
+
+#define CLOCK_W 256
+#define CLOCK_H 245
+
+static int fakewin_width;
+static int fakewin_height;
+
+static int glider_width;
+static int glider_height;
+
+static double glider_angle = 0;
+static double glider_pos_x = 80;
+static double glider_pos_y = 50;
+static double glider_dir_x = 1;
+static double glider_dir_y = 1;
+
+static void
+render_fakewin (void)
+{
+ cairo_t *cr;
+
+ cr = cairo_create (fakewin_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_move_to (cr, 0, 0);
+ cairo_rectangle (cr, 17, 34, fakewin_width - 32, fakewin_height - 50);
+ cairo_fill (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_translate (cr, TRUNC (glider_pos_x), TRUNC (glider_pos_y));
+
+ cairo_set_source_surface (cr, glider_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ glider_pos_x += glider_dir_x;
+ glider_pos_y += glider_dir_y;
+
+ if (glider_pos_x <= 18)
+ glider_dir_x = -glider_dir_x;
+
+ if (glider_pos_y <= 35)
+ glider_dir_y = -glider_dir_y;
+
+ if (glider_pos_x >= (fakewin_width - 16 - 37))
+ glider_dir_x = -glider_dir_x;
+
+ if (glider_pos_y >= (fakewin_height - 19 - 37))
+ glider_dir_y = -glider_dir_y;
+}
+
+static void
+render_clock (void)
+{
+ cairo_t *cr;
+
+ cr = cairo_create (clock_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_set_source_surface (cr, clock_bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+
+ fdhand_draw_now (cr, CLOCK_W, CLOCK_H, 1);
+ cairo_destroy (cr);
+}
+
+void
+shadow_setup (cairo_surface_t *target, int w, int h)
+{
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ clock_surface = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ CLOCK_W, CLOCK_H);
+
+ clock_bg_surface = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ CLOCK_W, CLOCK_H);
+ image = cairo_image_surface_create_from_png ("desktop.png");
+ if (cairo_surface_status (image)) {
+ printf ("error reading desktop.png: %s\n",
+ cairo_status_to_string (cairo_surface_status (image)));
+ exit(1);
+ }
+
+ bg_width = cairo_image_surface_get_width (image);
+ bg_height = cairo_image_surface_get_height (image);
+
+ bg_surface = cairo_surface_create_similar (target,
+ cairo_surface_get_content (image),
+ bg_width, bg_height);
+
+ cr = cairo_create (bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+
+ image = cairo_image_surface_create_from_png ("fakewin.png");
+ if (cairo_surface_status (image)) {
+ printf ("error reading fakewin.png: %s\n",
+ cairo_status_to_string (cairo_surface_status (image)));
+ exit(1);
+ }
+
+ fakewin_width = cairo_image_surface_get_width (image);
+ fakewin_height = cairo_image_surface_get_height (image);
+
+ fakewin_surface = cairo_surface_create_similar (target,
+ cairo_surface_get_content (image),
+ fakewin_width + 2,
+ fakewin_height + 2);
+
+ cr = cairo_create (fakewin_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ image = cairo_image_surface_create_from_png ("glider.png");
+ if (cairo_surface_status (image)) {
+ printf ("error reading glider.png: %s\n",
+ cairo_status_to_string (cairo_surface_status (image)));
+ exit(1);
+ }
+
+ glider_width = cairo_image_surface_get_width (image);
+ glider_height = cairo_image_surface_get_height (image);
+
+ glider_surface = cairo_surface_create_similar (target,
+ cairo_surface_get_content (image),
+ glider_width, glider_height);
+
+ cr = cairo_create (glider_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cr = cairo_create (clock_bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
+ cairo_rectangle (cr, 0, 0, CLOCK_W, CLOCK_H);
+ cairo_fill (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.25);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_scale (cr, CLOCK_W, CLOCK_H);
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_arc (cr, 0, 0, 0.5, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ fdface_draw (cr, CLOCK_W, CLOCK_H);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+
+ render_clock ();
+ render_fakewin ();
+}
+
+static long int shadow_cnt = 0;
+
+static double fw_x = 250.0, fw_y = 20.0;
+static double cl_x = 50.0, cl_y = 180.0;
+static double dst_x = 20.0, dst_y = 270.0;
+static double start_x = 250.0, start_y = 20.0;
+
+static int which = 1;
+
+static int
+shadow_move_towards_point (double *current_x, double *current_y)
+{
+ double to_go_x = dst_x - *current_x;
+ double to_go_y = dst_y - *current_y;
+ double done_x = *current_x - start_x;
+ double done_y = *current_y - start_y;
+
+ double dist_from_start = fabs (to_go_x) + fabs (to_go_y);
+ double dist_from_goal = fabs (done_x) + fabs (done_y);
+ double speed = (dist_from_start < dist_from_goal) ?
+ dist_from_start: dist_from_goal;
+ double speed_div;
+ double angle;
+
+ speed *= 10.0;
+
+ speed_div = fabs (dst_x - start_x) + fabs (dst_y - start_y);
+
+ speed /= (speed_div > 1.0)? speed_div: 1.0;
+ speed += 0.1;
+
+ angle = fabs (atan (to_go_y / to_go_x));
+
+ *current_x += speed * cos (angle) * ((dst_x > start_x)? 1.0: -1.0);
+ *current_y += speed * sin (angle) * ((dst_y > start_y)? 1.0: -1.0);
+
+ if (start_x <= dst_x) {
+ if (*current_x >= dst_x)
+ return 1;
+ } else {
+ if (*current_x <= dst_x)
+ return 1;
+ }
+
+ if (start_y <= dst_y) {
+ if (*current_y >= dst_y)
+ return 1;
+ } else {
+ if (*current_y <= dst_y)
+ return 1;
+ }
+
+ return 0;
+}
+
+static double shadow_alpha = 0.4;
+static double max_shadow_offset = 60.0;
+
+void
+shadow_render (cairo_t *cr, int w, int h)
+{
+ double scale_x, scale_y;
+ int move_done;
+ double shadow_offset_x, shadow_offset_y;
+ double light_x, light_y;
+
+ light_x = w / 2.0;
+ light_y = h / 2.0;
+
+ cairo_save (cr);
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ scale_x = ((double) w) / (double) bg_width;
+ scale_y = ((double) h) / (double) bg_height;
+
+ cairo_scale (cr, scale_x, scale_y);
+ cairo_set_source_surface (cr, bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ if (!(shadow_cnt % 10))
+ render_clock ();
+ else
+ if (!(shadow_cnt % 5))
+ render_fakewin ();
+
+ shadow_cnt++;
+
+ if (shadow_cnt >= 1000000)
+ shadow_cnt = 0;
+
+ shadow_offset_x = max_shadow_offset *
+ ((fw_x + fakewin_width / 2) - light_x) / (w / 2.0);
+ shadow_offset_y = max_shadow_offset *
+ ((fw_y + fakewin_height / 2) - light_y) / (h / 2.0);
+
+ /* hard shadow */
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, shadow_alpha);
+ cairo_mask_surface (cr, fakewin_surface,
+ TRUNC (fw_x + shadow_offset_x - 0.05 * fakewin_width),
+ TRUNC (fw_y + shadow_offset_y - 0.05 * fakewin_height));
+ cairo_paint (cr);
+
+ cairo_set_source_surface (cr, fakewin_surface, TRUNC (fw_x), TRUNC (fw_y));
+ cairo_paint (cr);
+
+ shadow_offset_x = max_shadow_offset *
+ ((cl_x + CLOCK_W / 2) - light_x) / (w / 2.0);
+ shadow_offset_y = max_shadow_offset *
+ ((cl_y + CLOCK_H / 2) - light_y) / (h / 2.0);
+
+ /* soft (translucent) shadow */
+ cairo_set_source_surface (cr, clock_surface,
+ TRUNC (cl_x + shadow_offset_x - 0.05 * CLOCK_W),
+ TRUNC (cl_y + shadow_offset_y - 0.05 * CLOCK_H));
+ cairo_paint_with_alpha (cr, shadow_alpha);
+
+ cairo_set_source_surface (cr, clock_surface, TRUNC (cl_x), TRUNC (cl_y));
+ cairo_paint (cr);
+
+
+ if (which) {
+ move_done = shadow_move_towards_point (&fw_x, &fw_y);
+ } else {
+ move_done = shadow_move_towards_point (&cl_x, &cl_y);
+ }
+
+ if (move_done) {
+ which = (int) (drand48 () + 0.5);
+
+ dst_x = drand48 () *
+ (w - ((which)? fakewin_width : CLOCK_W) -
+ max_shadow_offset);
+ dst_y = drand48 () *
+ (h - ((which)? fakewin_height: CLOCK_H) -
+ max_shadow_offset);
+
+ if (which) {
+ start_x = fw_x;
+ start_y = fw_y;
+ } else {
+ start_x = cl_x;
+ start_y = cl_y;
+ }
+ }
+
+ cairo_restore (cr);
+}
diff --git a/text.c b/text.c
new file mode 100644
index 0000000..1e512af
--- /dev/null
+++ b/text.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <cairo.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static float font_scale1, font_scale2,
+ font_rotate1, font_rotate2,
+ font_alpha1, font_alpha2,
+ font_speed1, font_speed2,
+ font_x1, font_y1,
+ font_x2, font_y2;
+
+static cairo_surface_t *bg_surface;
+static int bg_width, bg_height;
+
+void
+text_setup (cairo_surface_t *target, int w, int h)
+{
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ image = cairo_image_surface_create_from_png ("orion.png");
+ if (cairo_surface_status (image)) {
+ printf ("error reading orion.png: %s\n",
+ cairo_status_to_string (cairo_surface_status (image)));
+ exit(1);
+ }
+
+ bg_width = cairo_image_surface_get_width (image);
+ bg_height = cairo_image_surface_get_height (image);
+ bg_surface = cairo_surface_create_similar (target,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ bg_width, bg_height);
+
+ cr = cairo_create (bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+
+ drand48 ();
+ drand48 ();
+
+ font_rotate1 = (float) (drand48 () * 3.14);
+ font_rotate2 = (float) (drand48 () * 3.14);
+ font_scale1 = (float) (drand48 () * 250.0);
+ font_scale2 = (float) (drand48 () * 250.0);
+ font_speed1 = (float) (drand48 () + 0.5);
+ font_speed2 = (float) (drand48 () + 0.5);
+ font_alpha1 = 0.0;
+ font_alpha2 = 0.0;
+ font_x1 = 200.0 + (float) (drand48 () * (w - 200.0));
+ font_y1 = 100.0 + (float) (drand48 () * (h - 100.0));
+ font_x2 = 200.0 + (float) (drand48 () * (w - 200.0));
+ font_y2 = 100.0 + (float) (drand48 () * (h - 100.0));
+}
+
+static void
+text_path_render_text1 (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, font_alpha1);
+
+ cairo_set_font_size (cr, font_scale1);
+
+ cairo_move_to (cr, font_x1 - font_scale1, font_y1);
+ cairo_rotate(cr, font_rotate1);
+ cairo_text_path (cr, "CAIRO");
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, font_alpha1);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+text_path_render_text2 (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, font_alpha2);
+ cairo_set_font_size (cr, font_scale2);
+ cairo_move_to (cr, font_x2 - font_scale2, font_y2);
+ cairo_rotate(cr, font_rotate2);
+ cairo_text_path (cr, "GEARS");
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, font_alpha2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+void
+text_render (cairo_t *cr, int w, int h)
+{
+ double scale_x, scale_y;
+
+ cairo_select_font_face (cr,
+ "arial",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr, 1.0);
+
+ cairo_save (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_move_to (cr, 0, 0);
+
+ scale_x = ((double) w) / (double) bg_width;
+ scale_y = ((double) h) / (double) bg_height;
+
+ cairo_scale (cr, scale_x, scale_y);
+
+ cairo_set_source_surface (cr, bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ if (font_scale1 < font_scale2) {
+ text_path_render_text1 (cr);
+ text_path_render_text2 (cr);
+ } else {
+ text_path_render_text2 (cr);
+ text_path_render_text1 (cr);
+ }
+
+ if (font_scale1 > 250) {
+ font_scale1 = (float) (drand48 () * 50.0);
+ font_x1 = ((float) (drand48 () * (w - 400.0))) + 200.0;
+ font_y1 = ((float) (drand48 () * (h - 200.0))) + 100.0;
+ font_rotate1 = (float) (drand48 () * 3.14);
+ font_speed1 = (float) (drand48 () * 10.0);
+ font_alpha1 = 0;
+ }
+
+ if (font_scale2 > 250) {
+ font_scale2 = (float) (drand48 () * 50.0);
+ font_x2 = ((float) (drand48 () * (w - 400.0))) + 200.0;
+ font_y2 = ((float) (drand48 () * (h - 200.0))) + 100.0;
+ font_rotate2 = (float) (drand48 () * 3.14);
+ font_speed2 = (float) (drand48 () * 10.0);
+ font_alpha2 = 0;
+ }
+
+ font_scale1 > 150? font_scale1 += 2: font_scale1++;
+ font_scale2 > 150? font_scale2 += 2: font_scale2++;
+ font_scale1 < 175? (font_alpha1 += 0.01): (font_alpha1 -= 0.05);
+ font_scale2 < 175? (font_alpha2 += 0.01): (font_alpha2 -= 0.05);
+ font_scale1 += font_speed1;
+ font_scale2 += font_speed2;
+
+ cairo_restore (cr);
+}
diff --git a/text2.c b/text2.c
new file mode 100644
index 0000000..66360ba
--- /dev/null
+++ b/text2.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <cairo-ft.h>
+
+unsigned int glyph_cnt = 0;
+
+#define N_GLYPHS 2142
+
+static cairo_font_face_t *ft_face;
+
+static char *str = "CAIRO";
+
+void
+text2_setup (cairo_surface_t *surface, int w, int h)
+{
+ FcResult result;
+ FcPattern *pattern, *resolved;
+
+ pattern = FcPatternCreate ();
+ FcPatternAddString (pattern, FC_FAMILY, "Sans");
+ FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
+ FcPatternAddInteger (pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM);
+ FcPatternAddInteger (pattern, FC_PIXEL_SIZE, 10);
+
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+ FcDefaultSubstitute (pattern);
+
+ resolved = FcFontMatch (NULL, pattern, &result);
+ if (!resolved)
+ {
+ printf ("FcFontMatch: failed\n");
+ exit (1);
+ }
+
+ ft_face = cairo_ft_font_face_create_for_pattern (resolved);
+ if (!ft_face)
+ {
+ printf ("cairo_ft_font_face_create_for_pattern: failed\n");
+ exit (1);
+ }
+
+ FcPatternDestroy (resolved);
+ FcPatternDestroy (pattern);
+}
+
+void
+text2_render (cairo_t *cr, int w, int h)
+{
+ cairo_matrix_t scale, ctm;
+ cairo_scaled_font_t *ft_font;
+ cairo_font_options_t *options;
+ cairo_glyph_t glyphs[N_GLYPHS];
+ int ucs4[N_GLYPHS];
+ int x, y, i, slen;
+ FT_Face face;
+
+ options = cairo_font_options_create ();
+
+ cairo_matrix_init_scale (&scale, 10.0, 10.0);
+ cairo_set_font_face (cr, ft_face);
+ cairo_set_font_matrix (cr, &scale);
+ cairo_get_matrix (cr, &ctm);
+ ft_font = cairo_scaled_font_create (ft_face, &scale, &ctm, options);
+
+ cairo_font_options_destroy (options);
+
+ slen = strlen (str);
+ for (i = 0; i < N_GLYPHS; i++)
+ FcUtf8ToUcs4 (&str[i % slen], &ucs4[i], 1);
+
+ face = cairo_ft_scaled_font_lock_face (ft_font);
+
+ x = 4;
+ y = 14;
+ for (i = 0; i < N_GLYPHS; i++) {
+ glyphs[i].index = FT_Get_Char_Index (face, ucs4[i]);
+ glyphs[i].x = x;
+ glyphs[i].y = y;
+
+ x += 10;
+ if (x >= w) {
+ x = 4;
+ y += 12;
+ }
+ }
+
+ cairo_ft_scaled_font_unlock_face (ft_font);
+
+ if (glyph_cnt == 0)
+ {
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, w, h);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_fill (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.05);
+ }
+
+ glyph_cnt += N_GLYPHS;
+ cairo_show_glyphs (cr, glyphs, N_GLYPHS);
+}
diff --git a/trap.c b/trap.c
new file mode 100644
index 0000000..39ec155
--- /dev/null
+++ b/trap.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+ * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdlib.h>
+
+#include <cairo.h>
+#include <math.h>
+
+#define LINEWIDTH 3.0
+
+#define FILL_R 0.1
+#define FILL_G 0.1
+#define FILL_B 0.75
+#define FILL_OPACITY 0.5
+
+#define STROKE_R 0.1
+#define STROKE_G 0.75
+#define STROKE_B 0.1
+#define STROKE_OPACITY 1.0
+
+#define NUMPTS 6
+
+static double animpts[NUMPTS * 2];
+static double deltas[NUMPTS * 2];
+
+extern int fill_gradient;
+
+static void
+gear (cairo_t *cr,
+ double inner_radius,
+ double outer_radius,
+ int teeth,
+ double tooth_depth)
+{
+ int i;
+ double r0, r1, r2;
+ double angle, da;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0;
+ r2 = outer_radius + tooth_depth / 2.0;
+
+ da = 2.0 * M_PI / (double) teeth / 4.0;
+
+ cairo_new_path (cr);
+
+ angle = 0.0;
+ cairo_move_to (cr, r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da));
+
+ for (i = 1; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / (double) teeth;
+
+ cairo_line_to (cr, r1 * cos (angle), r1 * sin (angle));
+ cairo_line_to (cr, r2 * cos (angle + da), r2 * sin (angle + da));
+ cairo_line_to (cr, r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da));
+
+ if (i < teeth)
+ cairo_line_to (cr, r1 * cos (angle + 3 * da),
+ r1 * sin (angle + 3 * da));
+ }
+
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, r0 * cos (angle + 3 * da), r0 * sin (angle + 3 * da));
+
+ for (i = 1; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / (double) teeth;
+
+ cairo_line_to (cr, r0 * cos (angle), r0 * sin (angle));
+ }
+
+ cairo_close_path (cr);
+}
+
+void
+trap_setup (cairo_surface_t *target, int w, int h)
+{
+ int i;
+
+ //cairo_scale (cr, 3.0, 1.0);
+
+ for (i = 0; i < (NUMPTS * 2); i += 2) {
+ animpts[i + 0] = (float) (drand48 () * w);
+ animpts[i + 1] = (float) (drand48 () * h);
+ deltas[i + 0] = (float) (drand48 () * 6.0 + 4.0);
+ deltas[i + 1] = (float) (drand48 () * 6.0 + 4.0);
+ if (animpts[i + 0] > w / 2.0) {
+ deltas[i + 0] = -deltas[i + 0];
+ }
+ if (animpts[i + 1] > h / 2.0) {
+ deltas[i + 1] = -deltas[i + 1];
+ }
+ }
+}
+
+static void
+stroke_and_fill_animate (double *pts,
+ double *deltas,
+ int index,
+ int limit)
+{
+ double newpt = pts[index] + deltas[index];
+
+ if (newpt <= 0) {
+ newpt = -newpt;
+ deltas[index] = (double) (drand48 () * 4.0 + 2.0);
+ } else if (newpt >= (double) limit) {
+ newpt = 2.0 * limit - newpt;
+ deltas[index] = - (double) (drand48 () * 4.0 + 2.0);
+ }
+ pts[index] = newpt;
+}
+
+static void
+stroke_and_fill_step (int w, int h)
+{
+ int i;
+
+ for (i = 0; i < (NUMPTS * 2); i += 2) {
+ stroke_and_fill_animate (animpts, deltas, i + 0, w);
+ stroke_and_fill_animate (animpts, deltas, i + 1, h);
+ }
+}
+
+static double gear1_rotation = 0.35;
+static double gear2_rotation = 0.33;
+static double gear3_rotation = 0.50;
+
+void
+trap_render (cairo_t *cr, int w, int h)
+{
+ double *ctrlpts = animpts;
+ int len = (NUMPTS * 2);
+ double prevx = ctrlpts[len - 2];
+ double prevy = ctrlpts[len - 1];
+ double curx = ctrlpts[0];
+ double cury = ctrlpts[1];
+ double midx = (curx + prevx) / 2.0;
+ double midy = (cury + prevy) / 2.0;
+ int i;
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, w, h);
+ cairo_fill (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, 1.0);
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_save (cr);
+ cairo_scale (cr, (double) w / 512.0, (double) h / 512.0);
+
+ cairo_save (cr);
+ cairo_translate (cr, 170.0, 330.0);
+ cairo_rotate (cr, gear1_rotation);
+ gear (cr, 30.0, 120.0, 20, 20.0);
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 369.0, 330.0);
+ cairo_rotate (cr, gear2_rotation);
+ gear (cr, 15.0, 75.0, 12, 20.0);
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 170.0, 116.0);
+ cairo_rotate (cr, gear3_rotation);
+ gear (cr, 20.0, 90.0, 14, 20.0);
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_restore (cr);
+
+ gear1_rotation += 0.01;
+ gear2_rotation -= (0.01 * (20.0 / 12.0));
+ gear3_rotation -= (0.01 * (20.0 / 14.0));
+
+ stroke_and_fill_step (w, h);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, midx, midy);
+
+ for (i = 2; i <= (NUMPTS * 2); i += 2) {
+ double x2, x1 = (midx + curx) / 2.0;
+ double y2, y1 = (midy + cury) / 2.0;
+
+ prevx = curx;
+ prevy = cury;
+ if (i < (NUMPTS * 2)) {
+ curx = ctrlpts[i + 0];
+ cury = ctrlpts[i + 1];
+ } else {
+ curx = ctrlpts[0];
+ cury = ctrlpts[1];
+ }
+ midx = (curx + prevx) / 2.0;
+ midy = (cury + prevy) / 2.0;
+ x2 = (prevx + midx) / 2.0;
+ y2 = (prevy + midy) / 2.0;
+ cairo_curve_to (cr, x1, y1, x2, y2, midx, midy);
+ }
+ cairo_close_path (cr);
+
+ if (fill_gradient) {
+ double x1, y1, x2, y2;
+ cairo_pattern_t *pattern;
+
+ cairo_fill_extents (cr, &x1, &y1, &x2, &y2);
+
+ pattern = cairo_pattern_create_linear (x1, y1, x2, y2);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, 1.0, 0.0, 0.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, 0.0, 0.0, 1.0);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ } else {
+ cairo_set_source_rgba (cr, FILL_R, FILL_G, FILL_B, FILL_OPACITY);
+ }
+
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, STROKE_R, STROKE_G, STROKE_B, STROKE_OPACITY);
+ cairo_set_line_width (cr, LINEWIDTH);
+ cairo_stroke (cr);
+}