diff options
author | Keith Packard <keithp@keithp.com> | 2004-10-02 03:07:26 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2004-10-02 03:07:26 +0000 |
commit | 1b7271c78065d6a1ab3396df916529fc7958b0e2 (patch) | |
tree | 82c60e56429615c34e52843feb215c510850bf9e | |
parent | 45152588227377efb4aac96710648d519ccd75dc (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-- | ChangeLog | 33 | ||||
-rw-r--r-- | twin.h | 32 | ||||
-rw-r--r-- | twin_fixed.c | 4 | ||||
-rw-r--r-- | twin_font.c | 53 | ||||
-rw-r--r-- | twin_path.c | 22 | ||||
-rw-r--r-- | twin_poly.c | 2 | ||||
-rw-r--r-- | twin_screen.c | 12 | ||||
-rw-r--r-- | twin_x11.c | 68 | ||||
-rw-r--r-- | twin_x11.h | 3 | ||||
-rw-r--r-- | twinint.h | 8 | ||||
-rw-r--r-- | xtwin.c | 178 |
11 files changed, 351 insertions, 64 deletions
@@ -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: @@ -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)); @@ -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); @@ -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; /* @@ -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_ */ @@ -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 (;;) |