summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2004-10-02 03:07:26 +0000
committerKeith Packard <keithp@keithp.com>2004-10-02 03:07:26 +0000
commit1b7271c78065d6a1ab3396df916529fc7958b0e2 (patch)
tree82c60e56429615c34e52843feb215c510850bf9e
parent45152588227377efb4aac96710648d519ccd75dc (diff)
Add put_begin to screen structure so that the backend can batch updates.
Add twin_int_to_fixed. Inline twin_fixed_mul and twin_fixed_div using int64_t. Add twin_text_metrics_utf8. Hard-code the max number of vertices in a glyph. Set various ICCCM properties to make X wms happy. Use better approximation of ellipse major axis radius when drawing circles. Compiler warning. Delete duplicate twin_over definition Allow for multiple clocks, and add watermark. Note that text metrics are quite broken currently.
-rw-r--r--ChangeLog33
-rw-r--r--twin.h32
-rw-r--r--twin_fixed.c4
-rw-r--r--twin_font.c53
-rw-r--r--twin_path.c22
-rw-r--r--twin_poly.c2
-rw-r--r--twin_screen.c12
-rw-r--r--twin_x11.c68
-rw-r--r--twin_x11.h3
-rw-r--r--twinint.h8
-rw-r--r--xtwin.c178
11 files changed, 351 insertions, 64 deletions
diff --git a/ChangeLog b/ChangeLog
index 8fb013b..8a73635 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2004-10-01 Keith Packard <keithp@keithp.com>
+
+ * twin.h:
+ * twin_fixed.c:
+ * twin_font.c: (twin_text_metrics_ucs4), (twin_path_ucs4),
+ (twin_text_metrics_utf8):
+ * twin_screen.c: (twin_screen_create), (twin_screen_update):
+ * twin_x11.c: (_twin_x11_put_begin), (_twin_x11_put_span),
+ * twin_x11.h:
+ (twin_x11_create):
+ Add put_begin to screen structure so that the backend can batch
+ updates.
+ Add twin_int_to_fixed.
+ Inline twin_fixed_mul and twin_fixed_div using int64_t.
+ Add twin_text_metrics_utf8.
+ Hard-code the max number of vertices in a glyph.
+ Set various ICCCM properties to make X wms happy.
+
+ * twin_path.c: (_twin_matrix_max_radius), (twin_path_circle):
+ Use better approximation of ellipse major axis radius when
+ drawing circles.
+
+ * twin_poly.c: (_twin_edge_fill):
+ Compiler warning.
+
+ * twinint.h:
+ Delete duplicate twin_over definition
+
+ * xtwin.c: (twin_clock_hand), (twin_clock_face), (twin_clock),
+ (twin_app_thread), (twin_start_app), (twin_start_clock), (main):
+ Allow for multiple clocks, and add watermark. Note that
+ text metrics are quite broken currently.
+
2004-09-30 Keith Packard <keithp@keithp.com>
* Makefile.am:
diff --git a/twin.h b/twin.h
index b8f56e0..f91948d 100644
--- a/twin.h
+++ b/twin.h
@@ -106,8 +106,14 @@ typedef struct _twin_pixmap {
} twin_pixmap_t;
/*
- * A function that paints pixels to the screen
+ * twin_put_begin_t: called before data are drawn to the screen
+ * twin_put_span_t: called for each scanline drawn
*/
+typedef void (*twin_put_begin_t) (int x,
+ int y,
+ int width,
+ int height,
+ void *closure);
typedef void (*twin_put_span_t) (int x,
int y,
int width,
@@ -139,6 +145,7 @@ typedef struct _twin_screen {
/*
* Repaint function
*/
+ twin_put_begin_t put_begin;
twin_put_span_t put_span;
void *closure;
} twin_screen_t;
@@ -173,6 +180,8 @@ typedef int32_t twin_fixed_t; /* 16.16 format */
#define twin_double_to_fixed(d) ((twin_fixed_t) ((d) * 65536))
#define twin_fixed_to_double(f) ((double) (f) / 65536.0)
+#define twin_int_to_fixed(i) ((twin_fixed_t) (i) << 16)
+
/*
* Place matrices in structures so they can be easily copied
*/
@@ -241,14 +250,22 @@ twin_fill (twin_pixmap_t *dst,
* twin_fixed.c
*/
+#if 0
twin_fixed_t
twin_fixed_mul (twin_fixed_t af, twin_fixed_t bf);
+#else
+#define twin_fixed_mul(a,b) ((twin_fixed_t) (((int64_t) (a) * (b)) >> 16))
+#endif
twin_fixed_t
twin_fixed_sqrt (twin_fixed_t a);
+#if 0
twin_fixed_t
twin_fixed_div (twin_fixed_t a, twin_fixed_t b);
+#else
+#define twin_fixed_div(a,b) ((twin_fixed_t) ((((int64_t) (a)) << 16) / b))
+#endif
/*
* twin_font.c
@@ -282,6 +299,10 @@ twin_text_metrics_ucs4 (twin_path_t *path,
twin_ucs4_t ucs4,
twin_text_metrics_t *m);
+void
+twin_text_metrics_utf8 (twin_path_t *path,
+ const char *string,
+ twin_text_metrics_t *m);
/*
* twin_hull.c
*/
@@ -450,10 +471,11 @@ twin_fill_path (twin_pixmap_t *pixmap, twin_path_t *path, int dx, int dy);
*/
twin_screen_t *
-twin_screen_create (int width,
- int height,
- twin_put_span_t put_span,
- void *closure);
+twin_screen_create (int width,
+ int height,
+ twin_put_begin_t put_begin,
+ twin_put_span_t put_span,
+ void *closure);
void
twin_screen_destroy (twin_screen_t *screen);
diff --git a/twin_fixed.c b/twin_fixed.c
index cbdd1e1..b47e507 100644
--- a/twin_fixed.c
+++ b/twin_fixed.c
@@ -36,6 +36,7 @@
#define uint32_hi(i) ((i) >> 16)
#define uint32_carry16 ((1) << 16)
+#if 0
twin_fixed_t
twin_fixed_mul (twin_fixed_t af, twin_fixed_t bf)
{
@@ -88,7 +89,9 @@ twin_fixed_mul (twin_fixed_t af, twin_fixed_t bf)
twin_fixed_to_double (r)));
return r;
}
+#endif
+#if 0
twin_fixed_t
twin_fixed_div (twin_fixed_t a, twin_fixed_t b)
{
@@ -96,6 +99,7 @@ twin_fixed_div (twin_fixed_t a, twin_fixed_t b)
q = (twin_fixed_t) ((((int64_t) a) << 16) / b);
return q;
}
+#endif
twin_fixed_t
twin_fixed_sqrt (twin_fixed_t a)
diff --git a/twin_font.c b/twin_font.c
index 67d8ef2..9beaca5 100644
--- a/twin_font.c
+++ b/twin_font.c
@@ -209,7 +209,6 @@ twin_text_metrics_ucs4 (twin_path_t *path,
top = bottom = baseline;
right = Scale(p[0].y);
}
-
m->left_side_bearing = SNAPI(path, -left);
m->right_side_bearing = SNAPI(path,right);
m->width = m->left_side_bearing + m->right_side_bearing;
@@ -234,10 +233,10 @@ twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
twin_fixed_t pen_size;
twin_matrix_t pen_matrix;
twin_fixed_t pen_adjust;
- twin_gfixed_t *snap_x = 0, *snap_y = 0;
+ twin_gfixed_t snap_x[TWIN_GLYPH_MAX_POINTS];
+ twin_gfixed_t snap_y[TWIN_GLYPH_MAX_POINTS];
twin_text_metrics_t metrics;
int nsnap_x = 0, nsnap_y = 0;
- int npoints;
twin_text_metrics_ucs4 (path, ucs4, &metrics);
@@ -245,14 +244,6 @@ twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
if (Hint (path))
{
- for (i = 1; p[i].y != -64; i++)
- ;
-
- npoints = i - 1 + 3;
-
- snap_x = malloc ((npoints * 2) * sizeof (twin_gfixed_t));
- snap_y = snap_x + npoints;
-
nsnap_x = 0;
nsnap_y = 0;
@@ -336,9 +327,6 @@ twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
twin_path_destroy (stroke);
twin_path_destroy (pen);
- if (snap_x)
- free (snap_x);
-
w = metrics.width;
_twin_path_smove (path,
@@ -451,3 +439,40 @@ twin_width_utf8 (twin_path_t *path, const char *string)
return w;
}
+void
+twin_text_metrics_utf8 (twin_path_t *path,
+ const char *string,
+ twin_text_metrics_t *m)
+{
+ int len;
+ twin_ucs4_t ucs4;
+ twin_fixed_t w = 0;
+ twin_text_metrics_t c;
+ twin_bool_t first = TWIN_TRUE;
+
+ while ((len = _twin_utf8_to_ucs4(string, &ucs4)) > 0)
+ {
+ twin_text_metrics_ucs4 (path, ucs4, &c);
+ if (first)
+ *m = c;
+ else
+ {
+ c.left_side_bearing += w;
+ c.right_side_bearing += w;
+ c.width += w;
+
+ if (c.left_side_bearing > m->left_side_bearing)
+ m->left_side_bearing = c.left_side_bearing;
+ if (c.right_side_bearing > m->right_side_bearing)
+ m->right_side_bearing = c.right_side_bearing;
+ if (c.width > m->width)
+ m->width = c.width;
+ if (c.ascent < m->ascent)
+ m->ascent = c.ascent;
+ if (c.descent > m->descent)
+ m->descent = c.descent;
+ }
+ w = c.width;
+ string += len;
+ }
+}
diff --git a/twin_path.c b/twin_path.c
index 7fd6f16..b542a7d 100644
--- a/twin_path.c
+++ b/twin_path.c
@@ -154,6 +154,16 @@ twin_path_close (twin_path_t *path)
path->nsublen++;
}
+#define twin_fixed_abs(f) ((f) < 0 ? -(f) : (f))
+
+static twin_fixed_t
+_twin_matrix_max_radius (twin_matrix_t *m)
+{
+ return (twin_fixed_abs (m->m[0][0]) + twin_fixed_abs (m->m[0][1]) +
+ twin_fixed_abs (m->m[1][0]) + twin_fixed_abs (m->m[1][1]));
+}
+
+
void
twin_path_circle (twin_path_t *path, twin_fixed_t radius)
{
@@ -162,7 +172,7 @@ twin_path_circle (twin_path_t *path, twin_fixed_t radius)
twin_spoint_t center;
int i;
twin_matrix_t save;
- twin_fixed_t det;
+ twin_fixed_t max_radius;
save = twin_path_current_matrix (path);
@@ -172,14 +182,12 @@ twin_path_circle (twin_path_t *path, twin_fixed_t radius)
twin_path_close (path);
- /* The determinant represents the area expansion factor of the
- transform. In the worst case, this is entirely in one
- dimension, which is what we assume here. */
-
- det = _twin_matrix_determinant (&path->state.matrix);
+ max_radius = _twin_matrix_max_radius (&path->state.matrix);
- sides = (4 * det) / twin_sfixed_to_fixed (TWIN_SFIXED_TOLERANCE);
+ sides = max_radius / twin_sfixed_to_fixed (TWIN_SFIXED_TOLERANCE);
+ if (sides > 1024) sides = 1024;
+
n = 2;
while ((1 << n) < sides)
n++;
diff --git a/twin_poly.c b/twin_poly.c
index e8aa7f2..cacc327 100644
--- a/twin_poly.c
+++ b/twin_poly.c
@@ -272,7 +272,7 @@ _twin_edge_fill (twin_pixmap_t *pixmap, twin_edge_t *edges, int nedges)
twin_edge_t *active, *a, *n, **prev;
int e;
twin_sfixed_t y;
- twin_sfixed_t x0;
+ twin_sfixed_t x0 = 0;
int w;
qsort (edges, nedges, sizeof (twin_edge_t), _edge_compare_y);
diff --git a/twin_screen.c b/twin_screen.c
index 5510a52..cc69ab0 100644
--- a/twin_screen.c
+++ b/twin_screen.c
@@ -25,10 +25,11 @@
#include "twinint.h"
twin_screen_t *
-twin_screen_create (int width,
- int height,
- twin_put_span_t put_span,
- void *closure)
+twin_screen_create (int width,
+ int height,
+ twin_put_begin_t put_begin,
+ twin_put_span_t put_span,
+ void *closure)
{
twin_screen_t *screen = malloc (sizeof (twin_screen_t));
if (!screen)
@@ -44,6 +45,7 @@ twin_screen_create (int width,
#if HAVE_PTHREAD_H
pthread_mutex_init (&screen->screen_mutex, NULL);
#endif
+ screen->put_begin = put_begin;
screen->put_span = put_span;
screen->closure = closure;
return screen;
@@ -162,6 +164,8 @@ twin_screen_update (twin_screen_t *screen)
if (!span)
return;
+ if (screen->put_begin)
+ (*screen->put_begin) (x, y, width, height, screen->closure);
while (height--)
{
memset (span, 0xff, width * sizeof (twin_argb32_t));
diff --git a/twin_x11.c b/twin_x11.c
index b16bcc8..9630e63 100644
--- a/twin_x11.c
+++ b/twin_x11.c
@@ -26,6 +26,29 @@
#include "twinint.h"
static void
+_twin_x11_put_begin (int x,
+ int y,
+ int width,
+ int height,
+ void *closure)
+{
+ twin_x11_t *tx = closure;
+
+ tx->iy = 0;
+ tx->image = XCreateImage (tx->dpy, tx->visual, tx->depth, ZPixmap,
+ 0, 0, width, height, 32, 0);
+ if (tx->image)
+ {
+ tx->image->data = malloc (4 * width * height);
+ if (!tx->image->data)
+ {
+ XDestroyImage (tx->image);
+ tx->image = 0;
+ }
+ }
+}
+
+static void
_twin_x11_put_span (int x,
int y,
int width,
@@ -33,14 +56,11 @@ _twin_x11_put_span (int x,
void *closure)
{
twin_x11_t *tx = closure;
- XImage *image;
int ix = 0;
int iw = width;
- image = XCreateImage (tx->dpy, tx->visual, tx->depth, ZPixmap,
- 0, 0, width, 1, 32, 0);
-
- image->data = malloc (4 * width);
+ if (!tx->image)
+ return;
while (iw--)
{
@@ -48,11 +68,17 @@ _twin_x11_put_span (int x,
if (tx->depth == 16)
pixel = twin_argb32_to_rgb16 (pixel);
- XPutPixel (image, ix, 0, pixel);
+ XPutPixel (tx->image, ix, tx->iy, pixel);
ix++;
}
- XPutImage (tx->dpy, tx->win, tx->gc, image, 0, 0, x, y, width, 1);
- XDestroyImage (image);
+ tx->iy++;
+ if (tx->iy == tx->image->height)
+ {
+ XPutImage (tx->dpy, tx->win, tx->gc, tx->image, 0, 0,
+ x, y - tx->iy, width, tx->image->height);
+ XDestroyImage (tx->image);
+ tx->image = 0;
+ }
}
static void *
@@ -111,6 +137,13 @@ twin_x11_create (Display *dpy, int width, int height)
twin_x11_t *tx;
int scr = DefaultScreen (dpy);
XSetWindowAttributes wa;
+ XTextProperty wm_name, icon_name;
+ XSizeHints sizeHints;
+ XWMHints wmHints;
+ XClassHint classHints;
+ Atom wm_delete_window;
+ static char *argv[] = { "xtwin", 0 };
+ static int argc = 1;
tx = malloc (sizeof (twin_x11_t));
if (!tx)
@@ -128,12 +161,29 @@ twin_x11_create (Display *dpy, int width, int height)
ExposureMask|
StructureNotifyMask);
+ wm_name.value = (unsigned char *) argv[0];
+ wm_name.encoding = XA_STRING;
+ wm_name.format = 8;
+ wm_name.nitems = strlen (wm_name.value) + 1;
+ icon_name = wm_name;
+
tx->win = XCreateWindow (dpy, RootWindow (dpy, scr),
0, 0, width, height, 0,
tx->depth, InputOutput,
tx->visual, CWBackPixmap|CWEventMask, &wa);
+ sizeHints.flags = 0;
+ wmHints.flags = InputHint;
+ wmHints.input = True;
+ classHints.res_name = argv[0];
+ classHints.res_class = argv[0];
+ XSetWMProperties (dpy, tx->win,
+ &wm_name, &icon_name,
+ argv, argc,
+ &sizeHints, &wmHints, 0);
+ XSetWMProtocols (dpy, tx->win, &wm_delete_window, 1);
+
tx->gc = XCreateGC (dpy, tx->win, 0, 0);
- tx->screen = twin_screen_create (width, height,
+ tx->screen = twin_screen_create (width, height, _twin_x11_put_begin,
_twin_x11_put_span, tx);
twin_screen_register_damaged (tx->screen, twin_x11_screen_damaged, tx);
diff --git a/twin_x11.h b/twin_x11.h
index 5186f79..613fcf6 100644
--- a/twin_x11.h
+++ b/twin_x11.h
@@ -28,6 +28,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include <X11/Xatom.h>
#include <pthread.h>
typedef struct _twin_x11 {
@@ -40,6 +41,8 @@ typedef struct _twin_x11 {
pthread_t damage_thread;
pthread_cond_t damage_cond;
pthread_t event_thread;
+ XImage *image;
+ int iy;
} twin_x11_t;
/*
diff --git a/twinint.h b/twinint.h
index ebdefd2..7f930c1 100644
--- a/twinint.h
+++ b/twinint.h
@@ -79,11 +79,7 @@ typedef signed char twin_gfixed_t;
((twin_argb32_t) twin_int_mult (twin_get_8(s,i),(m),(t)) << (i))
#define twin_over(s,d,i,m,t) \
- ((t) = twin_int_mult(twin_get_8(d,i),(m),(t)) + twin_get_8(s,i),\
- (twin_argb32_t) twin_sat (t) << (i))
-
-#define twin_over(s,d,i,m,t) \
- ((t) = twin_int_mult(twin_get_8(d,i),(m),(t)) + twin_get_8(s,i),\
+ (((t) = twin_int_mult(twin_get_8(d,i),(m),(t)) + twin_get_8(s,i)),\
(twin_argb32_t) twin_sat (t) << (i))
#define twin_argb32_to_rgb16(s) ((((s) >> 3) & 0x001f) | \
@@ -344,4 +340,6 @@ _twin_path_sdraw (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y);
extern const twin_gpoint_t _twin_glyphs[];
extern const uint16_t _twin_glyph_offsets[];
+#define TWIN_GLYPH_MAX_POINTS 56
+
#endif /* _TWININT_H_ */
diff --git a/xtwin.c b/xtwin.c
index bc7b639..1db18f2 100644
--- a/xtwin.c
+++ b/xtwin.c
@@ -32,26 +32,81 @@
#define D(x) twin_double_to_fixed(x)
-#define CLOCK_SIZE 256
-
#define TWIN_CLOCK_BACKGROUND 0xff3b80ae
-#define TWIN_CLOCK_HOUR 0xffdedede
-#define TWIN_CLOCK_MINUTE 0xffdedede
+#define TWIN_CLOCK_HOUR 0x80808080
+#define TWIN_CLOCK_HOUR_OUT 0xffdedede
+#define TWIN_CLOCK_MINUTE 0x80808080
+#define TWIN_CLOCK_MINUTE_OUT 0xffdedede
#define TWIN_CLOCK_SECOND 0x80808080
#define TWIN_CLOCK_TIC 0xffbababa
#define TWIN_CLOCK_NUMBERS 0xffdedede
+#define TWIN_CLOCK_WATER 0x40404040
+#define TWIN_CLOCK_BORDER 0xffbababa
+#define TWIN_CLOCK_BORDER_WIDTH D(0.01)
+
+static void
+twin_clock_set_transform (twin_pixmap_t *clock,
+ twin_path_t *path)
+{
+ twin_fixed_t scale;
+
+ scale = D(1) / 2;
+ scale = twin_fixed_mul (scale, TWIN_FIXED_ONE - TWIN_CLOCK_BORDER_WIDTH * 3);
+ twin_path_scale (path,
+ clock->width * scale,
+ clock->height * scale);
+
+ twin_path_translate (path, D(1) + TWIN_CLOCK_BORDER_WIDTH * 3,
+ D(1) + TWIN_CLOCK_BORDER_WIDTH * 3);
+}
static void
twin_clock_hand (twin_pixmap_t *clock,
twin_angle_t angle,
twin_fixed_t len,
+ twin_fixed_t fill_width,
+ twin_fixed_t out_width,
+ twin_argb32_t fill_pixel,
+ twin_argb32_t out_pixel)
+{
+ twin_path_t *stroke = twin_path_create ();
+ twin_path_t *pen = twin_path_create ();
+ twin_path_t *path = twin_path_create ();
+ twin_matrix_t m;
+
+ twin_clock_set_transform (clock, stroke);
+
+ twin_path_rotate (stroke, angle);
+ twin_path_move (stroke, D(0), D(0));
+ twin_path_draw (stroke, len, D(0));
+
+ m = twin_path_current_matrix (stroke);
+ m.m[2][0] = 0;
+ m.m[2][1] = 0;
+ twin_path_set_matrix (pen, m);
+ twin_path_set_matrix (path, m);
+ twin_path_circle (pen, fill_width);
+ twin_path_convolve (path, stroke, pen);
+
+ twin_paint_path (clock, fill_pixel, path);
+
+ twin_paint_stroke (clock, out_pixel, path, out_width);
+
+ twin_path_destroy (path);
+ twin_path_destroy (pen);
+ twin_path_destroy (stroke);
+}
+
+static void
+twin_clock_sec (twin_pixmap_t *clock,
+ twin_angle_t angle,
+ twin_fixed_t len,
twin_fixed_t width,
twin_argb32_t pixel)
{
twin_path_t *stroke = twin_path_create ();
- twin_path_translate (stroke, D(CLOCK_SIZE) / 2, D(CLOCK_SIZE) / 2);
- twin_path_scale (stroke, D(CLOCK_SIZE) / 2, D(CLOCK_SIZE) / 2);
+ twin_clock_set_transform (clock, stroke);
twin_path_rotate (stroke, angle);
twin_path_move (stroke, D(0), D(0));
@@ -74,16 +129,37 @@ twin_clock_face (twin_pixmap_t *clock)
twin_path_t *path = twin_path_create ();
int m;
- twin_path_translate (path, D(CLOCK_SIZE) / 2, D(CLOCK_SIZE) / 2);
- twin_path_scale (path, D(CLOCK_SIZE) / 2, D(CLOCK_SIZE) / 2);
- twin_path_set_font_size (path, D(0.2));
- twin_path_set_font_style (path, TWIN_TEXT_UNHINTED);
+ twin_clock_set_transform (clock, path);
twin_path_move (path, 0, 0);
twin_path_circle (path, TWIN_FIXED_ONE);
twin_paint_path (clock, TWIN_CLOCK_BACKGROUND, path);
+ twin_paint_stroke (clock, TWIN_CLOCK_BORDER, path, TWIN_CLOCK_BORDER_WIDTH);
+
+ {
+ twin_state_t state = twin_path_save (path);
+ twin_text_metrics_t metrics;
+ twin_fixed_t height;
+ static char *label = "twin";
+
+ twin_path_empty (path);
+ twin_path_rotate (path, twin_degrees_to_angle (-11));
+ twin_path_set_font_size (path, D(0.5));
+ twin_path_set_font_style (path, TWIN_TEXT_UNHINTED|TWIN_TEXT_OBLIQUE);
+ twin_text_metrics_utf8 (path, label, &metrics);
+ height = metrics.ascent + metrics.descent;
+/* twin_path_move (path, -metrics.width / 2, height / 2 - metrics.ascent);*/
+ twin_path_move (path, -D(.4), -D(.16));
+ twin_path_utf8 (path, label);
+ twin_paint_path (clock, TWIN_CLOCK_WATER, path);
+ twin_path_restore (path, &state);
+ }
+
+ twin_path_set_font_size (path, D(0.2));
+ twin_path_set_font_style (path, TWIN_TEXT_UNHINTED);
+
for (m = 1; m <= 60; m++)
{
twin_state_t state = twin_path_save (path);
@@ -112,22 +188,32 @@ twin_clock_face (twin_pixmap_t *clock)
twin_path_destroy (path);
}
+int nclock;
+
static void
-twin_clock (twin_screen_t *screen)
+twin_clock (twin_screen_t *screen, int x, int y, int w, int h)
{
- twin_pixmap_t *clock = twin_pixmap_create (TWIN_ARGB32, CLOCK_SIZE, CLOCK_SIZE);
+ twin_pixmap_t *clock = twin_pixmap_create (TWIN_ARGB32, w, h);
struct timeval tv;
struct tm t;
twin_angle_t hour_angle, minute_angle, second_angle;
+#if 0
+ int i;
+#endif
printf ("twin clock\n");
- twin_pixmap_move (clock, 0, 0);
+ twin_pixmap_move (clock, x, y);
twin_pixmap_show (clock, screen, 0);
+
+#if 0
+ for (i = 0; i < 5; i++)
+#else
for (;;)
+#endif
{
twin_pixmap_disable_update (clock);
twin_fill (clock, 0x00000000, TWIN_SOURCE, 0, 0,
- CLOCK_SIZE, CLOCK_SIZE);
+ clock->width, clock->height);
gettimeofday (&tv, NULL);
@@ -139,13 +225,63 @@ twin_clock (twin_screen_t *screen)
hour_angle = t.tm_hour * TWIN_ANGLE_360 / 12 - TWIN_ANGLE_90 + minute_angle / 12;
twin_clock_face (clock);
- twin_clock_hand (clock, hour_angle, D(0.4), D(0.05), 0xffdedede);
- twin_clock_hand (clock, minute_angle, D(0.8), D(0.03), 0xffdedede);
- twin_clock_hand (clock, second_angle, D(0.6), D(0.01), 0x80808080);
+ twin_clock_hand (clock, hour_angle, D(0.4), D(0.07), D(0.01),
+ TWIN_CLOCK_HOUR, TWIN_CLOCK_HOUR_OUT);
+ twin_clock_hand (clock, minute_angle, D(0.8), D(0.05), D(0.01),
+ TWIN_CLOCK_MINUTE, TWIN_CLOCK_MINUTE_OUT);
+ twin_clock_sec (clock, second_angle, D(0.9), D(0.02),
+ TWIN_CLOCK_SECOND);
twin_pixmap_enable_update (clock);
+
+ gettimeofday (&tv, NULL);
+
usleep (1000000 - tv.tv_usec);
}
+ nclock--;
+}
+
+typedef void (*twin_app_func_t) (twin_screen_t *screen,
+ int x, int y, int w, int h);
+
+typedef struct _twin_app_args {
+ twin_app_func_t func;
+ twin_screen_t *screen;
+ int x, y, w, h;
+} twin_app_args_t;
+
+static void *
+twin_app_thread (void *closure)
+{
+ twin_app_args_t *a = closure;
+
+ (*a->func) (a->screen, a->x, a->y, a->w, a->h);
+ free (a);
+ return 0;
+}
+
+static void
+twin_start_app (twin_app_func_t func,
+ twin_screen_t *screen,
+ int x, int y, int w, int h)
+{
+ twin_app_args_t *a = malloc (sizeof (twin_app_args_t));
+ pthread_t thread;
+
+ a->func = func;
+ a->screen = screen;
+ a->x = x;
+ a->y = y;
+ a->w = w;
+ a->h = h;
+ pthread_create (&thread, NULL, twin_app_thread, a);
+}
+
+static void
+twin_start_clock (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ ++nclock;
+ twin_start_app (twin_clock, screen, x, y, w, h);
}
int styles[] = {
@@ -475,8 +611,12 @@ main (int argc, char **argv)
twin_pixmap_show (red, x11->screen, 0);
twin_pixmap_show (blue, x11->screen, 0);
#endif
- twin_clock (x11->screen);
- sleep (10000);
+ twin_start_clock (x11->screen, 0, 0, 512, 512);
+/* twin_start_clock (x11->screen, 256, 0, 256, 256);
+ twin_start_clock (x11->screen, 0, 256, 256, 256);
+ twin_start_clock (x11->screen, 256, 256, 256, 256); */
+ while (nclock)
+ sleep (1);
#if 0
had_motion = TWIN_FALSE;
for (;;)