diff options
author | Keith Packard <keithp@keithp.com> | 2003-12-02 03:04:47 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2003-12-02 03:04:47 +0000 |
commit | 9dff31a23a918ce48fba1501feb0a98a2e5361e1 (patch) | |
tree | 5099a768eb65a3d6c93164c8d97dc416b6bb6355 | |
parent | d992b971a08bcc5fcfdab73324c1f24babfed373 (diff) |
Add fdfacepng program, split clock into many files. make background
generation a bit more efficient for opaque case. Add translucent disc
for translucent case. Add options to fdclock program
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | fdclock.c | 545 | ||||
-rw-r--r-- | fdface.c | 89 | ||||
-rw-r--r-- | fdface.h | 32 | ||||
-rw-r--r-- | fdfacepng.c | 57 | ||||
-rw-r--r-- | fdhand.c | 104 | ||||
-rw-r--r-- | fdhand.h | 33 | ||||
-rw-r--r-- | fdlogo.c | 173 | ||||
-rw-r--r-- | fdlogo.h | 33 | ||||
-rw-r--r-- | findargb.c | 61 | ||||
-rw-r--r-- | findargb.h | 33 |
12 files changed, 793 insertions, 405 deletions
@@ -1,5 +1,25 @@ 2003-12-01 Keith Packard <keithp@keithp.com> + * Makefile: + * fdclock.c: (clear), (make_background), (main_x), (main): + * fdface.c: (draw_fancy_tick), (draw_plain_tick), (fdface_draw): + * fdface.h: + * fdfacepng.c: (dump_png), (main): + * fdhand.c: (draw_hand_helper), (draw_hand), (draw_time), + (fdhand_draw_now): + * fdhand.h: + * fdlogo.c: (draw_boundary), (draw_outline), (draw_background), + (draw_window), (draw_window_at), (draw_windows), (fdlogo_draw): + * fdlogo.h: + * findargb.c: (find_argb_visual): + * findargb.h: + Add fdfacepng program, split clock into many files. + make background generation a bit more efficient for + opaque case. Add translucent disc for translucent case. + Add options to fdclock program + +2003-12-01 Keith Packard <keithp@keithp.com> + * fdclock.c: (draw_time), (main_x): Shrink default size to 150x150. Fix hour adjustment for minute angle. @@ -1,13 +1,21 @@ -OBJS = fdclock.o write_png.o +COMMON = fdlogo.o fdface.o +CLOCKOBJS = fdclock.o fdhand.o findargb.o $(COMMON) +PNGOBJS = fdfacepng.o write_png.o $(COMMON) INCLUDES=`pkg-config --cflags cairo` -LIBS= `pkg-config --libs cairo` -lpng +CLOCKLIBS= `pkg-config --libs cairo` +PNGLIBS=`pkg-config --libs cairo` -lpng CFLAGS=-g .c.o: $(CC) -c $(CFLAGS) $(INCLUDES) $*.c - -fdclock: $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) + +all: fdclock fdfacepng + +fdclock: $(CLOCKOBJS) + $(CC) $(CFLAGS) -o $@ $(CLOCKOBJS) $(CLOCKLIBS) + +fdfacepng: $(PNGOBJS) + $(CC) $(CFLAGS) -o $@ $(PNGOBJS) $(PNGLIBS) clean: rm -f fdclock $(OBJS) @@ -24,358 +24,134 @@ #include <cairo.h> #include <cairo-xlib.h> -#include <math.h> #include <X11/Xlib.h> #include <X11/extensions/Xrender.h> -#include <sys/time.h> -#include <time.h> #include <sys/poll.h> +#include <unistd.h> +#include "fdface.h" +#include "fdhand.h" +#include "findargb.h" -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); -} - -void -draw_outline (cairo_t *cr) -{ - cairo_set_rgb_color (cr, 0.73, 0.73, 0.73); - cairo_set_line_width (cr, 2); - draw_boundary (cr); - cairo_stroke (cr); -} +#define CLOCK_WIDTH 150 +#define CLOCK_HEIGHT 150 -void -draw_background (cairo_t *cr) +static void +clear (cairo_t *cr, double width, double height, double alpha) { cairo_save (cr); - cairo_set_rgb_color (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_set_rgb_color (cr, 1, 1, 1); + cairo_set_alpha (cr, alpha); + cairo_set_operator (cr, CAIRO_OPERATOR_SRC); + cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); cairo_restore (cr); } - -void -draw_window (cairo_t *cr) -{ - cairo_move_to (cr, -6.00, -7.125); - cairo_line_to (cr, 6.00, -7.125); +Pixmap +make_background (Display *dpy, Window root, int width, int height, int depth, + Visual *visual, Colormap cmap) +{ + cairo_t *cr = cairo_create (); + cairo_surface_t *back_surface; + cairo_surface_t *temp_surface = 0; + Pixmap background; + + /* + * Background pixmap + */ + background = XCreatePixmap (dpy, root, width, height, depth); + back_surface = cairo_xlib_surface_create (dpy, background, visual, 0, cmap); + + if (depth == 32) + { + temp_surface = cairo_surface_create_similar (back_surface, + CAIRO_FORMAT_ARGB32, + width, height); + /* + * draw the background to the temporary surface + */ - 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_set_target_surface (cr, temp_surface); + } + else + cairo_set_target_surface (cr, back_surface); - cairo_curve_to (cr, -9.00, -6.125, - -8.00, -7.125, - -6.00, -7.125); - cairo_close_path (cr); -} + clear (cr, width, height, temp_surface ? 0 : 1); -void -draw_window_at (cairo_t *cr, double x, double y, double scale) -{ - cairo_save (cr); + if (temp_surface) { - cairo_translate (cr, x, y); - cairo_scale (cr, scale, scale); - draw_window (cr); cairo_save (cr); { cairo_set_rgb_color (cr, 1, 1, 1); + cairo_set_alpha (cr, 0.5); + cairo_scale (cr, width, height); + 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_rgb_color (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_rgb_color (cr, 1, 1, 1); - cairo_set_alpha (cr, 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 ROT_X_FACTOR 1.086 -#define ROT_Y_FACTOR 1.213 -#define NWIDTH (64 * ROT_X_FACTOR) -#define NHEIGHT (48 * ROT_Y_FACTOR) -#define CLOCK_WIDTH 150 -#define CLOCK_HEIGHT 150 - -void -draw_logo (cairo_t *cr, double width, double height) -{ - double x_scale, y_scale, scale, x_off, y_off; - cairo_save (cr); - x_scale = width / NWIDTH; - y_scale = height / NHEIGHT; - scale = x_scale < y_scale ? x_scale : y_scale; - x_off = (width - (scale * NWIDTH)) / 2; - y_off = (height - (scale * NHEIGHT)) / 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); -} - -void -draw_fancy_tick (cairo_t *cr, double radius) -{ - cairo_save (cr); - cairo_arc (cr, 0, 0, radius, 0, 2 * M_PI); - cairo_set_rgb_color (cr, 0.231, 0.502, 0.682); - cairo_fill (cr); - cairo_set_rgb_color (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); -} - -void -draw_plain_tick (cairo_t *cr, double radius) -{ - cairo_save (cr); - cairo_arc (cr, 0, 0, radius, 0, 2 * M_PI); - cairo_set_rgb_color (cr, 0.231, 0.502, 0.682); - cairo_fill (cr); - cairo_restore (cr); -} - -#define PI_6 (M_PI/6.0) - -void -draw_hand_helper (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, M_PI - PI_6); - cairo_line_to (cr, -length / 10, r); - cairo_arc (cr, -length / 10, 0, r, M_PI_2, -M_PI_2); - cairo_line_to (cr, -width * M_SQRT2, -r); - cairo_arc (cr, 0, 0, r*2, M_PI + PI_6, -PI_6); - cairo_close_path (cr); -} + fdface_draw (cr, width, height); -void -draw_hand (cairo_t *cr, double angle, double width, double length, double alt) -{ - cairo_save (cr); - { - cairo_translate (cr, alt, alt); - cairo_rotate (cr, angle); - draw_hand_helper (cr, width, length); - cairo_set_rgb_color (cr, 0, 0, 0); - cairo_set_alpha (cr, 0.5); - cairo_fill (cr); - } - cairo_restore (cr); - cairo_save (cr); + if (temp_surface) { - cairo_rotate (cr, angle); - cairo_set_rgb_color (cr, 0, 0, 0); - draw_hand_helper (cr, width, length); - cairo_fill (cr); - } - cairo_restore (cr); -} + cairo_set_target_surface (cr, back_surface); -void -draw_time (cairo_t *cr, double width, double height, struct timeval *tv) -{ - double hour_angle, minute_angle, second_angle; - struct tm tm_ret; - struct tm *tm; + clear (cr, width, height, 0); - 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_set_alpha (cr, 0.8); - 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.02, 0.25, 0.005); - draw_hand (cr, minute_angle * M_PI / 180.0 - M_PI_2, 0.01, 0.4, 0.010); - draw_hand (cr, second_angle * M_PI / 180.0 - M_PI_2, 0.005, 0.3, 0.015); + cairo_show_surface (cr, temp_surface, width, height); + cairo_surface_destroy (temp_surface); } - cairo_restore (cr); -} - -void -draw_now (cairo_t *cr, double width, double height) -{ - struct timeval tv; - struct timezone tz; - gettimeofday (&tv, &tz); - - draw_time (cr, width, height, &tv); + cairo_surface_destroy (back_surface); + cairo_destroy (cr); + return background; } void -draw_clock (cairo_t *cr, double width, double height) +main_x (char *dpy_name, char *geom, Bool seconds, Bool translucent) { - double x_off, y_off; - double size; - int minute; - - cairo_save (cr); + Display *dpy; + int scr; + int x = 0, y = 0; + int width = CLOCK_WIDTH, height = CLOCK_HEIGHT; + Window root; + Visual *visual; + XWMHints *wmhints; + XSizeHints *normalhints; + XClassHint *classhint; + char *name; + XSetWindowAttributes wattr; + unsigned long wmask; + int depth; + Colormap cmap; + Window w; + GC gc; + XGCValues gcv; + Pixmap background = None, buffer; + XEvent ev; + Bool paint = False; + int timeout; + + dpy = XOpenDisplay (dpy_name); + if (!dpy) { - cairo_scale (cr, width, height); - cairo_save (cr); - { - cairo_translate (cr, .15, .15); - cairo_scale (cr, .7, .7); - draw_logo (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); - } + fprintf (stderr, "Cannot open display\n"); + return; } - cairo_restore (cr); -} - -static Visual * -find_argb_visual (Display *dpy, int scr) -{ - XVisualInfo *xvi; - XVisualInfo template; - int nvi; - int i; - XRenderPictFormat *format; - Visual *visual; - - template.screen = scr; - template.depth = 32; - template.class = TrueColor; - xvi = XGetVisualInfo (dpy, - VisualScreenMask | - VisualDepthMask | - VisualClassMask, - &template, - &nvi); - if (!xvi) - return 0; - visual = 0; - for (i = 0; i < nvi; i++) - { - format = XRenderFindVisualFormat (dpy, xvi[i].visual); - if (format->type == PictTypeDirect && format->direct.alphaMask) - { - visual = xvi[i].visual; - break; - } - } - - XFree (xvi); - return visual; -} + + if (geom) + XParseGeometry (geom, &x, &y, &width, &height); -void -main_x (int width, int height) -{ - cairo_t *cr = cairo_create (); - Display *dpy = XOpenDisplay (0); - int scr = DefaultScreen (dpy); - Window root = RootWindow (dpy, scr); - Visual *visual = find_argb_visual (dpy, scr); - XWMHints *wmhints; - XSizeHints *normalhints; - XClassHint *classhint; - char *name; - XSetWindowAttributes wattr; - unsigned long wmask; - int depth; - Colormap cmap; - Window w; - GC gc; - XGCValues gcv; - Pixmap background = None, buffer; - XEvent ev; - Bool paint = False; + scr = DefaultScreen (dpy); + root = RootWindow (dpy, scr); + if (translucent) + visual = find_argb_visual (dpy, scr); + else + visual = 0; wattr.event_mask = (ExposureMask | StructureNotifyMask); if (visual) @@ -394,15 +170,15 @@ main_x (int width, int height) wattr.border_pixel = BlackPixel (dpy, scr); } wmask = CWEventMask | CWBackPixel | CWBorderPixel | CWColormap; - w = XCreateWindow (dpy, root, 0, 0, width, height, 0, + w = XCreateWindow (dpy, root, x, y, width, height, 0, depth, InputOutput, visual, wmask, &wattr); name = "fdclock"; normalhints = XAllocSizeHints (); normalhints->flags = 0; - normalhints->x = 0; - normalhints->y = 0; + normalhints->x = x; + normalhints->y = y; normalhints->width = width; normalhints->height = height; @@ -423,6 +199,10 @@ main_x (int width, int height) XMapWindow (dpy, w); gcv.graphics_exposures = False; gc = XCreateGC (dpy, w, GCGraphicsExposures, &gcv); + if (seconds) + timeout = 100; + else + timeout = 1000; for (;;) { struct pollfd a; @@ -430,7 +210,7 @@ main_x (int width, int height) XFlush (dpy); a.fd = ConnectionNumber (dpy); a.events = POLLIN; - if (poll (&a, 1, 100) > 0) + if (poll (&a, 1, timeout) > 0) { do { XNextEvent (dpy, &ev); @@ -459,102 +239,67 @@ main_x (int width, int height) paint = True; if (paint) { - cairo_surface_t *surface; - - if (!background) - { - cairo_surface_t *temp; - - background = XCreatePixmap (dpy, root, - width, height, depth); - surface = cairo_xlib_surface_create (dpy, background, - visual, 0, cmap); - temp = cairo_surface_create_similar (surface, - CAIRO_FORMAT_ARGB32, - width, height); - cairo_save (cr); - cairo_set_target_surface (cr, temp); - if (depth == 32) - { - cairo_set_rgb_color (cr, 0, 0, 0); - cairo_set_alpha (cr, 0); - } - else - cairo_set_rgb_color (cr, 1, 1, 1); - - cairo_set_operator (cr, CAIRO_OPERATOR_SRC); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_set_alpha (cr, 1); - draw_clock (cr, width, height); - cairo_set_target_surface (cr, surface); - if (depth == 32) - { - cairo_set_rgb_color (cr, 0, 0, 0); - cairo_set_alpha (cr, 0); - } - else - cairo_set_rgb_color (cr, 1, 1, 1); - - cairo_set_operator (cr, CAIRO_OPERATOR_SRC); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_surface_t *buffer_surface; + cairo_t *cr = cairo_create (); - cairo_set_alpha (cr, 0.8); - cairo_show_surface (cr, temp, width, height); - cairo_surface_destroy (temp); - cairo_surface_destroy (surface); - cairo_restore (cr); - } + /* + * Create a pixmap holding the background clock image + * so it doesn't have to be painted every tick + */ + if (!background) + background = make_background (dpy, root, width, height, depth, + visual, cmap); + buffer = XCreatePixmap (dpy, root, width, height, depth); - surface = cairo_xlib_surface_create (dpy, buffer, - visual, 0, cmap); - cairo_set_target_surface (cr, surface); - cairo_surface_destroy (surface); + buffer_surface = cairo_xlib_surface_create (dpy, buffer, + visual, 0, cmap); + cairo_set_target_surface (cr, buffer_surface); XCopyArea (dpy, background, buffer, gc, 0, 0, width, height, 0, 0); - draw_now (cr, width, height); + fdhand_draw_now (cr, width, height, seconds); XCopyArea (dpy, buffer, w, gc, 0, 0, width, height, 0, 0); + cairo_surface_destroy (buffer_surface); XFreePixmap (dpy, buffer); paint = False; + cairo_destroy (cr); } } } - -int -main_png (int width, int height) -{ - int stride = width * 4; - cairo_t *cr = cairo_create ();; - char *image = calloc (stride * height, 1); - char out[1024]; - - cairo_set_target_image (cr, image, CAIRO_FORMAT_ARGB32, - width, height, stride); - cairo_move_to (cr, 0, 0); - cairo_line_to (cr, width, 0); - cairo_line_to (cr, width, height); - cairo_line_to (cr, 0, height); - cairo_close_path (cr); - cairo_set_rgb_color (cr, 1, 1, 1); - cairo_fill (cr); - draw_clock (cr, width, height); - sprintf (out, "freedesktop-clock-%d.png", width); - write_png_argb32 (image, out, width, height, stride); - - cairo_destroy (cr); - return 0; -} +extern char *optarg; +extern int optind, opterr, optopt; int main (int argc, char **argv) { - main_x (CLOCK_WIDTH, CLOCK_HEIGHT); -/* main_png (2400, 2400); */ + char *dpy_name = 0; + char *geom = 0; + Bool seconds = False, translucent = False; + int c; + + while ((c = getopt (argc, argv, "std:g:")) > 0) + { + switch (c) { + case 'd': + dpy_name = optarg; + break; + case 'g': + geom = optarg; + break; + case 's': + seconds = True; + break; + case 't': + translucent = True; + break; + default: + fprintf (stderr, "usage: %s -st -d <dpy> -g <geom>\n", argv[0]); + exit (1); + break; + } + } + + main_x (dpy_name, geom, seconds, translucent); return 0; } diff --git a/fdface.c b/fdface.c new file mode 100644 index 0000000..72c0664 --- /dev/null +++ b/fdface.c @@ -0,0 +1,89 @@ +/* + * $Id$ + * + * 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_rgb_color (cr, 0.231, 0.502, 0.682); + cairo_fill (cr); + cairo_set_rgb_color (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_rgb_color (cr, 0.231, 0.502, 0.682); + cairo_fill (cr); + cairo_restore (cr); +} + +void +fdface_draw (cairo_t *cr, double width, double height) +{ + double x_off, y_off; + double size; + 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..9ebaaa5 --- /dev/null +++ b/fdface.h @@ -0,0 +1,32 @@ +/* + * $Id$ + * + * 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/fdfacepng.c b/fdfacepng.c new file mode 100644 index 0000000..da72cf9 --- /dev/null +++ b/fdfacepng.c @@ -0,0 +1,57 @@ +/* + * $Id$ + * + * 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 <cairo.h> +#include "fdface.h" + +static int +dump_png (int width, int height) +{ + int stride = width * 4; + cairo_t *cr = cairo_create ();; + char *image = calloc (stride * height, 1); + char out[1024]; + + cairo_set_target_image (cr, image, CAIRO_FORMAT_ARGB32, + width, height, stride); + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, width, 0); + cairo_line_to (cr, width, height); + cairo_line_to (cr, 0, height); + cairo_close_path (cr); + cairo_set_rgb_color (cr, 1, 1, 1); + cairo_fill (cr); + fdface_draw (cr, width, height); + sprintf (out, "freedesktop-clock-%d.png", width); + write_png_argb32 (image, out, width, height, stride); + + cairo_destroy (cr); + return 0; +} + +int +main (int argc, char **argv) +{ + return dump_png (2400, 2400); +} diff --git a/fdhand.c b/fdhand.c new file mode 100644 index 0000000..eab2f2d --- /dev/null +++ b/fdhand.c @@ -0,0 +1,104 @@ +/* + * $Id$ + * + * 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_hand_helper (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, M_PI - PI_6); + cairo_line_to (cr, -length / 10, r); + cairo_arc (cr, -length / 10, 0, r, M_PI_2, -M_PI_2); + cairo_line_to (cr, -width * M_SQRT2, -r); + cairo_arc (cr, 0, 0, r*2, M_PI + PI_6, -PI_6); + cairo_close_path (cr); +} + +static void +draw_hand (cairo_t *cr, double angle, double width, double length, double alt) +{ + cairo_save (cr); + { + cairo_translate (cr, alt, alt); + cairo_rotate (cr, angle); + draw_hand_helper (cr, width, length); + cairo_set_rgb_color (cr, 0, 0, 0); + cairo_set_alpha (cr, 0.5); + cairo_fill (cr); + } + cairo_restore (cr); + cairo_save (cr); + { + cairo_rotate (cr, angle); + cairo_set_rgb_color (cr, 0, 0, 0); + draw_hand_helper (cr, width, length); + 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.02, 0.25, 0.005); + draw_hand (cr, minute_angle * M_PI / 180.0 - M_PI_2, 0.01, 0.4, 0.010); + if (seconds) + draw_hand (cr, second_angle * M_PI / 180.0 - M_PI_2, 0.005, 0.3, 0.015); + } + cairo_restore (cr); +} + +void +fdhand_draw_now (cairo_t *cr, double width, double height, int seconds) +{ + struct timeval tv; + struct timezone tz; + gettimeofday (&tv, &tz); + + draw_time (cr, width, height, &tv, seconds); +} + diff --git a/fdhand.h b/fdhand.h new file mode 100644 index 0000000..da01079 --- /dev/null +++ b/fdhand.h @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * 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..d758376 --- /dev/null +++ b/fdlogo.c @@ -0,0 +1,173 @@ +/* + * $Id$ + * + * 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_line_width (cr, 2); + draw_boundary (cr); + cairo_stroke (cr); +} + +static void +draw_background (cairo_t *cr) +{ + cairo_save (cr); + cairo_set_rgb_color (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_rgb_color (cr, 1, 1, 1); + cairo_fill (cr); + } + cairo_restore (cr); + cairo_set_rgb_color (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_rgb_color (cr, 1, 1, 1); + cairo_set_alpha (cr, 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..c268a3f --- /dev/null +++ b/fdlogo.h @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * 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/findargb.c b/findargb.c new file mode 100644 index 0000000..fe54c8e --- /dev/null +++ b/findargb.c @@ -0,0 +1,61 @@ +/* + * $Id$ + * + * 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 "findargb.h" + +Visual * +find_argb_visual (Display *dpy, int scr) +{ + XVisualInfo *xvi; + XVisualInfo template; + int nvi; + int i; + XRenderPictFormat *format; + Visual *visual; + + template.screen = scr; + template.depth = 32; + template.class = TrueColor; + xvi = XGetVisualInfo (dpy, + VisualScreenMask | + VisualDepthMask | + VisualClassMask, + &template, + &nvi); + if (!xvi) + return 0; + visual = 0; + for (i = 0; i < nvi; i++) + { + format = XRenderFindVisualFormat (dpy, xvi[i].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) + { + visual = xvi[i].visual; + break; + } + } + + XFree (xvi); + return visual; +} diff --git a/findargb.h b/findargb.h new file mode 100644 index 0000000..a877470 --- /dev/null +++ b/findargb.h @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * 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 _FINDARGB_H_ +#define _FINDARGB_H_ +#include <X11/Xlib.h> +#include <X11/extensions/Xrender.h> + +Visual * +find_argb_visual (Display *dpy, int scr); + +#endif |