aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2004-10-06 00:11:27 +0000
committerKeith Packard <keithp@keithp.com>2004-10-06 00:11:27 +0000
commitdc7477b9826f7cb6e95d591698daaf5251e65bf4 (patch)
tree37bb92d430656e47d9d307cd25cea9822f1a48e4
parenta8611583a5e0e2539be9841c8d5a6e37b7cff7a6 (diff)
downloadlibtwin-dc7477b9826f7cb6e95d591698daaf5251e65bf4.tar.gz
Add the beginings of event dispatch and a bit of window management
including titles. Default event dispatcher does restacking and motion.
-rw-r--r--ChangeLog32
-rw-r--r--Makefile.am2
-rw-r--r--twin.h213
-rw-r--r--twin_draw.c18
-rw-r--r--twin_path.c1
-rw-r--r--twin_pixmap.c95
-rw-r--r--twin_screen.c140
-rw-r--r--twin_thread.c83
-rw-r--r--twin_window.c251
-rw-r--r--twin_x11.c73
-rw-r--r--twin_x11.h9
-rw-r--r--xtwin.c92
12 files changed, 851 insertions, 158 deletions
diff --git a/ChangeLog b/ChangeLog
index 851b365..67d0388 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,37 @@
2004-10-05 Keith Packard <keithp@keithp.com>
+ * Makefile.am:
+ * twin.h:
+ * twin_draw.c: (twin_fill):
+ * twin_path.c: (twin_composite_path):
+ * twin_pixmap.c: (twin_pixmap_create), (twin_pixmap_show),
+ (twin_pixmap_hide), (_twin_pixmap_fetch),
+ (twin_pixmap_transparent), (twin_pixmap_move),
+ (twin_pixmap_dispatch):
+ * twin_screen.c: (twin_screen_create), (twin_screen_lock),
+ (twin_screen_unlock), (twin_screen_update),
+ (twin_screen_set_active), (twin_screen_get_active),
+ (twin_screen_dispatch):
+ * twin_thread.c: (twin_mutex_init), (twin_mutex_lock),
+ (twin_mutex_unlock), (twin_cond_init), (twin_cond_broadcast),
+ (twin_cond_wait), (twin_thread_create):
+ * twin_window.c: (twin_window_create), (twin_window_destroy),
+ (twin_window_show), (twin_window_hide), (twin_window_configure),
+ (twin_window_style_size), (twin_window_set_name),
+ (twin_window_frame), (twin_window_draw), (twin_window_dispatch):
+ * twin_x11.c: (_twin_x11_put_begin), (_twin_x11_put_span),
+ (twin_x11_damage_thread), (twin_x11_event_thread),
+ (twin_x11_screen_damaged), (twin_x11_create), (twin_x11_destroy):
+ * twin_x11.h:
+ * xtwin.c: (twin_clock_set_transform), (twin_clock_hand),
+ (twin_clock_face), (twin_clock), (twin_app_thread),
+ (twin_start_app), (twin_start_clock), (main):
+ Add the beginings of event dispatch and a bit of
+ window management including titles. Default event dispatcher
+ does restacking and motion.
+
+2004-10-05 Keith Packard <keithp@keithp.com>
+
* twin.h:
* twin_draw.c: (twin_composite), (twin_fill):
* twin_matrix.c: (twin_matrix_multiply), (twin_matrix_translate),
diff --git a/Makefile.am b/Makefile.am
index 4b7f8d7..999deae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,7 +30,9 @@ xtwin_SOURCES = \
twin_primitive.c \
twin_screen.c \
twin_spline.c \
+ twin_thread.c \
twin_trig.c \
+ twin_window.c \
twin_x11.c \
twinint.h \
xtwin.c
diff --git a/twin.h b/twin.h
index 642fff3..a9e956f 100644
--- a/twin.h
+++ b/twin.h
@@ -44,6 +44,19 @@ typedef int16_t twin_count_t;
typedef int16_t twin_keysym_t;
typedef int32_t twin_area_t;
+/*
+ * Mutexes
+ */
+#if HAVE_PTHREAD_H
+typedef pthread_mutex_t twin_mutex_t;
+typedef pthread_cond_t twin_cond_t;
+typedef pthread_t twin_thread_t;
+#else
+typedef int twin_mutext_t;
+typedef int twin_cond_t;
+typedef int twin_thread_t;
+#endif
+
#define TWIN_FALSE 0
#define TWIN_TRUE 1
@@ -80,6 +93,8 @@ typedef union _twin_pointer {
twin_argb32_t *argb32;
} twin_pointer_t;
+typedef struct _twin_window twin_window_t;
+
/*
* A rectangular array of pixels
*/
@@ -92,7 +107,7 @@ typedef struct _twin_pixmap {
/*
* List of displayed pixmaps
*/
- struct _twin_pixmap *higher;
+ struct _twin_pixmap *down, *up;
/*
* Screen position
*/
@@ -108,20 +123,25 @@ typedef struct _twin_pixmap {
* Pixels
*/
twin_pointer_t p;
+ /*
+ * When representing a window, this point
+ * refers to the window object
+ */
+ twin_window_t *window;
} twin_pixmap_t;
/*
* 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) (twin_coord_t x,
- twin_coord_t y,
- twin_coord_t width,
- twin_coord_t height,
+typedef void (*twin_put_begin_t) (twin_coord_t left,
+ twin_coord_t top,
+ twin_coord_t right,
+ twin_coord_t bottom,
void *closure);
-typedef void (*twin_put_span_t) (twin_coord_t x,
- twin_coord_t y,
- twin_coord_t width,
+typedef void (*twin_put_span_t) (twin_coord_t left,
+ twin_coord_t top,
+ twin_coord_t right,
twin_argb32_t *pixels,
void *closure);
@@ -132,7 +152,15 @@ typedef struct _twin_screen {
/*
* List of displayed pixmaps
*/
- twin_pixmap_t *bottom;
+ twin_pixmap_t *top, *bottom;
+ /*
+ * One of them receives all key events
+ */
+ twin_pixmap_t *active;
+ /*
+ * pointer down for this window
+ */
+ twin_pixmap_t *pointer;
/*
* Output size
*/
@@ -144,15 +172,17 @@ typedef struct _twin_screen {
void (*damaged) (void *);
void *damaged_closure;
twin_count_t disable;
-#if HAVE_PTHREAD_H
- pthread_mutex_t screen_mutex;
-#endif
+ twin_mutex_t screen_mutex;
/*
* Repaint function
*/
twin_put_begin_t put_begin;
twin_put_span_t put_span;
void *closure;
+ /*
+ * Window manager stuff
+ */
+ twin_coord_t button_x, button_y;
} twin_screen_t;
/*
@@ -226,7 +256,8 @@ typedef struct _twin_text_metrics {
typedef enum _twin_event_kind {
EventButtonDown, EventButtonUp, EventMotion,
- EventKeyDown, EventKeyUp, EventUcs4
+ EventKeyDown, EventKeyUp, EventUcs4,
+ EventActivate, EventDeactivate,
} twin_event_kind_t;
typedef struct _twin_event {
@@ -234,11 +265,9 @@ typedef struct _twin_event {
union {
struct {
twin_coord_t x, y;
+ twin_coord_t screen_x, screen_y;
twin_count_t button;
- } button;
- struct {
- twin_coord_t x, y;
- } motion;
+ } pointer;
struct {
twin_keysym_t key;
} key;
@@ -248,6 +277,53 @@ typedef struct _twin_event {
} u;
} twin_event_t;
+typedef struct _twin_event_queue {
+ struct _twin_event_queue *next;
+ twin_event_t event;
+} twin_event_queue_t;
+
+/*
+ * Windows
+ */
+
+typedef enum _twin_window_style {
+ WindowPlain,
+ WindowApplication,
+} twin_window_style_t;
+
+typedef void (*twin_draw_func_t) (twin_window_t *window);
+
+typedef twin_bool_t (*twin_event_func_t) (twin_window_t *window,
+ twin_event_t *event);
+
+typedef void (*twin_destroy_func_t) (twin_window_t *window);
+
+struct _twin_window {
+ twin_screen_t *screen;
+ twin_pixmap_t *pixmap;
+ twin_window_style_t style;
+ twin_rect_t client;
+ twin_rect_t damage;
+ void *client_data;
+ char *name;
+
+ twin_draw_func_t draw;
+ twin_event_func_t event;
+ twin_destroy_func_t destroy;
+};
+
+/*
+ * Widgets
+ */
+
+typedef struct {
+ twin_rect_t geometry;
+} twin_widget_t;
+
+typedef struct {
+ twin_widget_t core;
+} twin_button_t;
+
/*
* twin_convolve.c
*/
@@ -278,10 +354,17 @@ void
twin_fill (twin_pixmap_t *dst,
twin_argb32_t pixel,
twin_operator_t operator,
- twin_coord_t x,
- twin_coord_t y,
- twin_coord_t width,
- twin_coord_t height);
+ twin_coord_t left,
+ twin_coord_t top,
+ twin_coord_t right,
+ twin_coord_t bottom);
+
+/*
+ * twin_event.c
+ */
+
+void
+twin_event_enqueue (const twin_event_t *event);
/*
* twin_fixed.c
@@ -515,6 +598,12 @@ twin_pixmap_move (twin_pixmap_t *pixmap, twin_coord_t x, twin_coord_t y);
twin_pointer_t
twin_pixmap_pointer (twin_pixmap_t *pixmap, twin_coord_t x, twin_coord_t y);
+twin_bool_t
+twin_pixmap_transparent (twin_pixmap_t *pixmap, twin_coord_t x, twin_coord_t y);
+
+twin_bool_t
+twin_pixmap_dispatch (twin_pixmap_t *pixmap, twin_event_t *event);
+
/*
* twin_poly.c
*/
@@ -563,6 +652,16 @@ void
twin_screen_update (twin_screen_t *screen);
void
+twin_screen_set_active (twin_screen_t *screen, twin_pixmap_t *pixmap);
+
+twin_pixmap_t *
+twin_screen_get_active (twin_screen_t *screen);
+
+twin_bool_t
+twin_screen_dispatch (twin_screen_t *screen,
+ twin_event_t *event);
+
+void
twin_screen_lock (twin_screen_t *screen);
void
@@ -580,6 +679,33 @@ twin_path_curve (twin_path_t *path,
twin_fixed_t x3, twin_fixed_t y3);
/*
+ * twin_thread.c
+ */
+
+void
+twin_mutex_init (twin_mutex_t *mutex);
+
+void
+twin_mutex_lock (twin_mutex_t *mutex);
+
+void
+twin_mutex_unlock (twin_mutex_t *mutex);
+
+void
+twin_cond_init (twin_cond_t *cond);
+
+void
+twin_cond_broadcast (twin_cond_t *cond);
+
+void
+twin_cond_wait (twin_cond_t *cond, twin_mutex_t *mutex);
+
+typedef void * (*twin_thread_func_t) (void *arg);
+
+int
+twin_thread_create (twin_thread_t *thread, twin_thread_func_t func, void *arg);
+
+/*
* twin_trig.c
*/
@@ -592,4 +718,49 @@ twin_cos (twin_angle_t a);
twin_fixed_t
twin_tan (twin_angle_t a);
+/*
+ * twin_window.c
+ */
+
+twin_window_t *
+twin_window_create (twin_screen_t *screen,
+ twin_format_t format,
+ twin_window_style_t style,
+ twin_coord_t x,
+ twin_coord_t y,
+ twin_coord_t width,
+ twin_coord_t height);
+
+void
+twin_window_destroy (twin_window_t *window);
+
+void
+twin_window_show (twin_window_t *window);
+
+void
+twin_window_hide (twin_window_t *window);
+
+void
+twin_window_configure (twin_window_t *window,
+ twin_window_style_t style,
+ twin_coord_t x,
+ twin_coord_t y,
+ twin_coord_t width,
+ twin_coord_t height);
+
+void
+twin_window_set_name (twin_window_t *window,
+ const char *name);
+
+void
+twin_window_style_size (twin_window_style_t style,
+ twin_rect_t *size);
+
+void
+twin_window_draw (twin_window_t *window);
+
+twin_bool_t
+twin_window_dispatch (twin_window_t *window, twin_event_t *event);
+
+
#endif /* _TWIN_H_ */
diff --git a/twin_draw.c b/twin_draw.c
index 505eed7..9a8a2c6 100644
--- a/twin_draw.c
+++ b/twin_draw.c
@@ -370,32 +370,28 @@ void
twin_fill (twin_pixmap_t *dst,
twin_argb32_t pixel,
twin_operator_t operator,
- twin_coord_t x,
- twin_coord_t y,
- twin_coord_t width,
- twin_coord_t height)
+ twin_coord_t left,
+ twin_coord_t top,
+ twin_coord_t right,
+ twin_coord_t bottom)
{
twin_src_op op;
twin_source_u src;
twin_coord_t iy;
- twin_coord_t left, right, top, bottom;
twin_pixmap_lock (dst);
src.c = pixel;
- left = x;
- right = x + width;
- top = y;
- bottom = y + height;
if (left < 0)
left = 0;
if (right > dst->width)
right = dst->width;
if (top < 0)
top = 0;
- if (top > dst->height)
- top = dst->height;
+ if (bottom > dst->height)
+ bottom = dst->height;
op = fill[operator][dst->format];
for (iy = top; iy < bottom; iy++)
(*op) (twin_pixmap_pointer (dst, left, iy), src, right - left);
+ twin_pixmap_damage (dst, left, right, top, bottom);
twin_pixmap_unlock (dst);
}
diff --git a/twin_path.c b/twin_path.c
index 468e22e..74d527a 100644
--- a/twin_path.c
+++ b/twin_path.c
@@ -443,7 +443,6 @@ twin_composite_path (twin_pixmap_t *dst,
if (!mask)
return;
- twin_fill (mask, 0x00000000, TWIN_SOURCE, 0, 0, width, height);
twin_fill_path (mask, path, -bounds.left, -bounds.top);
msk.source_kind = TWIN_PIXMAP;
msk.u.pixmap = mask;
diff --git a/twin_pixmap.c b/twin_pixmap.c
index 5882bfe..ad0abe5 100644
--- a/twin_pixmap.c
+++ b/twin_pixmap.c
@@ -30,12 +30,14 @@ twin_pixmap_create (twin_format_t format,
twin_coord_t height)
{
twin_coord_t stride = twin_bytes_per_pixel (format) * width;
- twin_area_t size = sizeof (twin_pixmap_t) + (twin_area_t) stride * height;
+ twin_area_t space = (twin_area_t) stride * height;
+ twin_area_t size = sizeof (twin_pixmap_t) + space;
twin_pixmap_t *pixmap = malloc (size);
if (!pixmap)
return 0;
pixmap->screen = 0;
- pixmap->higher = 0;
+ pixmap->up = 0;
+ pixmap->down = 0;
pixmap->x = pixmap->y = 0;
pixmap->format = format;
pixmap->width = width;
@@ -43,6 +45,7 @@ twin_pixmap_create (twin_format_t format,
pixmap->stride = stride;
pixmap->disable = 0;
pixmap->p.v = pixmap + 1;
+ memset (pixmap->p.v, '\0', space);
return pixmap;
}
@@ -59,23 +62,36 @@ twin_pixmap_show (twin_pixmap_t *pixmap,
twin_screen_t *screen,
twin_pixmap_t *lower)
{
- twin_pixmap_t **higherp;
-
- twin_screen_lock (screen);
-
if (pixmap->disable)
twin_screen_disable_update (screen);
+ if (lower == pixmap)
+ lower = pixmap->down;
+
if (pixmap->screen)
twin_pixmap_hide (pixmap);
+ twin_screen_lock (screen);
+
pixmap->screen = screen;
+
if (lower)
- higherp = &lower->higher;
+ {
+ pixmap->down = lower;
+ pixmap->up = lower->up;
+ lower->up = pixmap;
+ if (!pixmap->up)
+ screen->top = pixmap;
+ }
else
- higherp = &screen->bottom;
- pixmap->higher = *higherp;
- *higherp = pixmap;
+ {
+ pixmap->down = NULL;
+ pixmap->up = screen->bottom;
+ screen->bottom = pixmap;
+ if (!pixmap->up)
+ screen->top = pixmap;
+ }
+
twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height);
twin_screen_unlock (screen);
}
@@ -84,17 +100,29 @@ void
twin_pixmap_hide (twin_pixmap_t *pixmap)
{
twin_screen_t *screen = pixmap->screen;
- twin_pixmap_t **higherp;
+ twin_pixmap_t **up, **down;
if (!screen)
return;
twin_screen_lock (screen);
twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height);
- for (higherp = &screen->bottom; *higherp != pixmap; higherp = &(*higherp)->higher)
- ;
- *higherp = pixmap->higher;
+
+ if (pixmap->up)
+ down = &pixmap->up->down;
+ else
+ down = &screen->top;
+
+ if (pixmap->down)
+ up = &pixmap->down->up;
+ else
+ up = &screen->bottom;
+
+ *down = pixmap->down;
+ *up = pixmap->up;
+
pixmap->screen = 0;
- pixmap->higher = 0;
+ pixmap->up = 0;
+ pixmap->down = 0;
if (pixmap->disable)
twin_screen_enable_update (screen);
twin_screen_unlock (screen);
@@ -158,11 +186,48 @@ twin_pixmap_unlock (twin_pixmap_t *pixmap)
twin_screen_unlock (pixmap->screen);
}
+static twin_argb32_t
+_twin_pixmap_fetch (twin_pixmap_t *pixmap, twin_coord_t x, twin_coord_t y)
+{
+ twin_pointer_t p = twin_pixmap_pointer (pixmap, x - pixmap->x, y - pixmap->y);
+
+ if (pixmap->x <= x && x < pixmap->x + pixmap->width &&
+ pixmap->y <= y && y < pixmap->y + pixmap->height)
+ {
+ switch (pixmap->format) {
+ case TWIN_A8:
+ return *p.a8 << 24;
+ case TWIN_RGB16:
+ return twin_rgb16_to_argb32 (*p.rgb16);
+ case TWIN_ARGB32:
+ return *p.argb32;
+ }
+ }
+ return 0;
+}
+
+twin_bool_t
+twin_pixmap_transparent (twin_pixmap_t *pixmap, twin_coord_t x, twin_coord_t y)
+{
+ return (_twin_pixmap_fetch (pixmap, x, y) >> 24) == 0;
+}
+
void
twin_pixmap_move (twin_pixmap_t *pixmap, twin_coord_t x, twin_coord_t y)
{
+ twin_pixmap_lock (pixmap);
twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height);
pixmap->x = x;
pixmap->y = y;
twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height);
+ twin_pixmap_unlock (pixmap);
}
+
+twin_bool_t
+twin_pixmap_dispatch (twin_pixmap_t *pixmap, twin_event_t *event)
+{
+ if (pixmap->window)
+ return twin_window_dispatch (pixmap->window, event);
+ return TWIN_FALSE;
+}
+
diff --git a/twin_screen.c b/twin_screen.c
index 1821cc6..bb031e3 100644
--- a/twin_screen.c
+++ b/twin_screen.c
@@ -34,6 +34,7 @@ twin_screen_create (twin_coord_t width,
twin_screen_t *screen = malloc (sizeof (twin_screen_t));
if (!screen)
return 0;
+ screen->top = 0;
screen->bottom = 0;
screen->width = width;
screen->height = height;
@@ -42,29 +43,25 @@ twin_screen_create (twin_coord_t width,
screen->damaged = NULL;
screen->damaged_closure = NULL;
screen->disable = 0;
-#if HAVE_PTHREAD_H
- pthread_mutex_init (&screen->screen_mutex, NULL);
-#endif
+ twin_mutex_init (&screen->screen_mutex);
screen->put_begin = put_begin;
screen->put_span = put_span;
screen->closure = closure;
+
+ screen->button_x = screen->button_y = -1;
return screen;
}
void
twin_screen_lock (twin_screen_t *screen)
{
-#if HAVE_PTHREAD_H
- pthread_mutex_lock (&screen->screen_mutex);
-#endif
+ twin_mutex_lock (&screen->screen_mutex);
}
void
twin_screen_unlock (twin_screen_t *screen)
{
-#if HAVE_PTHREAD_H
- pthread_mutex_unlock (&screen->screen_mutex);
-#endif
+ twin_mutex_unlock (&screen->screen_mutex);
}
void
@@ -104,6 +101,8 @@ twin_screen_disable_update (twin_screen_t *screen)
screen->disable++;
}
+#include <stdio.h>
+
void
twin_screen_damage (twin_screen_t *screen,
twin_coord_t left, twin_coord_t top,
@@ -150,59 +149,128 @@ twin_screen_damaged (twin_screen_t *screen)
void
twin_screen_update (twin_screen_t *screen)
{
- if (!screen->disable &&
- screen->damage.left < screen->damage.right &&
- screen->damage.top < screen->damage.bottom)
+ twin_coord_t left = screen->damage.left;
+ twin_coord_t top = screen->damage.top;
+ twin_coord_t right = screen->damage.right;
+ twin_coord_t bottom = screen->damage.bottom;
+
+ if (!screen->disable && left < right && top < bottom)
{
- twin_coord_t x = screen->damage.left;
- twin_coord_t y = screen->damage.top;
- twin_coord_t width = screen->damage.right - screen->damage.left;
- twin_coord_t height = screen->damage.bottom - screen->damage.top;
twin_argb32_t *span;
twin_pixmap_t *p;
+ twin_coord_t y;
+ twin_coord_t width = right - left;
+ screen->damage.left = screen->damage.right = 0;
+ screen->damage.top = screen->damage.bottom = 0;
/* XXX what is the maximum number of lines? */
span = malloc (width * sizeof (twin_argb32_t));
if (!span)
return;
if (screen->put_begin)
- (*screen->put_begin) (x, y, width, height, screen->closure);
- while (height--)
+ (*screen->put_begin) (left, top, right, bottom, screen->closure);
+ for (y = top; y < bottom; y++)
{
memset (span, 0xff, width * sizeof (twin_argb32_t));
- for (p = screen->bottom; p; p = p->higher)
+ for (p = screen->bottom; p; p = p->up)
{
twin_pointer_t dst;
twin_source_u src;
-
- int left, right;
+ twin_coord_t p_left, p_right;
+
/* bounds check in y */
if (y < p->y)
continue;
if (p->y + p->height <= y)
continue;
/* bounds check in x*/
- left = x;
- if (left < p->x)
- left = p->x;
- right = x + width;
- if (right > p->x + p->width)
- right = p->x + p->width;
- if (left >= right)
+ p_left = left;
+ if (p_left < p->x)
+ p_left = p->x;
+ p_right = right;
+ if (p_right > p->x + p->width)
+ p_right = p->x + p->width;
+ if (p_left >= p_right)
continue;
- dst.argb32 = span + (left - x);
- src.p = twin_pixmap_pointer (p, left - p->x, y - p->y);
+ dst.argb32 = span + (p_left - left);
+ src.p = twin_pixmap_pointer (p, p_left - p->x, y - p->y);
if (p->format == TWIN_RGB16)
- _twin_rgb16_source_argb32 (dst, src, right - left);
+ _twin_rgb16_source_argb32 (dst, src, p_right - p_left);
else
- _twin_argb32_over_argb32 (dst, src, right - left);
+ _twin_argb32_over_argb32 (dst, src, p_right - p_left);
}
- (*screen->put_span) (x, y, width, span, screen->closure);
- y++;
+ (*screen->put_span) (left, y, right, span, screen->closure);
}
free (span);
- screen->damage.left = screen->damage.right = 0;
- screen->damage.top = screen->damage.bottom = 0;
}
}
+
+void
+twin_screen_set_active (twin_screen_t *screen, twin_pixmap_t *pixmap)
+{
+ twin_event_t ev;
+ twin_pixmap_t *old = screen->active;
+ screen->active = pixmap;
+ if (old)
+ {
+ ev.kind = EventDeactivate;
+ twin_pixmap_dispatch (old, &ev);
+ }
+ if (pixmap)
+ {
+ ev.kind = EventActivate;
+ twin_pixmap_dispatch (pixmap, &ev);
+ }
+}
+
+twin_pixmap_t *
+twin_screen_get_active (twin_screen_t *screen)
+{
+ return screen->active;
+}
+
+twin_bool_t
+twin_screen_dispatch (twin_screen_t *screen,
+ twin_event_t *event)
+{
+ twin_pixmap_t *pixmap;
+
+ switch (event->kind) {
+ case EventMotion:
+ case EventButtonDown:
+ case EventButtonUp:
+ pixmap = screen->pointer;
+ if (!pixmap)
+ {
+ for (pixmap = screen->top; pixmap; pixmap = pixmap->down)
+ if (!twin_pixmap_transparent (pixmap,
+ event->u.pointer.screen_x,
+ event->u.pointer.screen_y))
+ {
+ break;
+ }
+ if (event->kind == EventButtonDown)
+ screen->pointer = pixmap;
+ }
+ if (event->kind == EventButtonUp)
+ screen->pointer = NULL;
+ if (pixmap)
+ {
+ event->u.pointer.x = event->u.pointer.screen_x - pixmap->x;
+ event->u.pointer.y = event->u.pointer.screen_y - pixmap->y;
+ }
+ break;
+ case EventKeyDown:
+ case EventKeyUp:
+ case EventUcs4:
+ pixmap = screen->active;
+ break;
+ default:
+ pixmap = NULL;
+ break;
+ }
+ if (pixmap)
+ return twin_pixmap_dispatch (pixmap, event);
+ return TWIN_FALSE;
+}
diff --git a/twin_thread.c b/twin_thread.c
new file mode 100644
index 0000000..1faddc0
--- /dev/null
+++ b/twin_thread.c
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2004 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 "twinint.h"
+
+void
+twin_mutex_init (twin_mutex_t *mutex)
+{
+#if HAVE_PTHREAD_H
+ pthread_mutex_init (mutex, NULL);
+#endif
+}
+
+void
+twin_mutex_lock (twin_mutex_t *mutex)
+{
+#if HAVE_PTHREAD_H
+ pthread_mutex_lock (mutex);
+#endif
+}
+
+void
+twin_mutex_unlock (twin_mutex_t *mutex)
+{
+#if HAVE_PTHREAD_H
+ pthread_mutex_unlock (mutex);
+#endif
+}
+
+void
+twin_cond_init (twin_cond_t *cond)
+{
+#if HAVE_PTHREAD_H
+ pthread_cond_init (cond, NULL);
+#endif
+}
+
+void
+twin_cond_broadcast (twin_cond_t *cond)
+{
+#if HAVE_PTHREAD_H
+ pthread_cond_broadcast (cond);
+#else
+ OOPS - need some synchronization mechanism
+#endif
+}
+
+void
+twin_cond_wait (twin_cond_t *cond, twin_mutex_t *mutex)
+{
+#if HAVE_PTHREAD_H
+ pthread_cond_wait (cond, mutex);
+#else
+ OOPS - need some synchronization mechanism
+#endif
+}
+
+int
+twin_thread_create (twin_thread_t *thread, twin_thread_func_t func, void *arg)
+{
+ return pthread_create (thread, NULL, func, arg);
+}
diff --git a/twin_window.c b/twin_window.c
new file mode 100644
index 0000000..6071877
--- /dev/null
+++ b/twin_window.c
@@ -0,0 +1,251 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2004 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 "twinint.h"
+
+#define TWIN_ACTIVE_BG 0xff3b80ae
+#define TWIN_INACTIVE_BG 0xff808080
+#define TWIN_FRAME_TEXT 0xffffffff
+#define TWIN_ACTIVE_BORDER 0xff000000
+#define TWIN_BW 3
+#define TWIN_TITLE_HEIGHT 18
+
+twin_window_t *
+twin_window_create (twin_screen_t *screen,
+ twin_format_t format,
+ twin_window_style_t style,
+ twin_coord_t x,
+ twin_coord_t y,
+ twin_coord_t width,
+ twin_coord_t height)
+{
+ twin_window_t *window = malloc (sizeof (twin_window_t));
+
+ if (!window) return NULL;
+ window->screen = screen;
+ window->pixmap = twin_pixmap_create (format, width, height);
+ window->pixmap->window = window;
+ twin_pixmap_move (window->pixmap, x, y);
+ window->style = style;
+ window->client.left = TWIN_BW;
+ window->client.top = TWIN_BW + TWIN_TITLE_HEIGHT + TWIN_BW;
+ window->client.right = width - TWIN_BW;
+ window->client.bottom = height - TWIN_BW;
+ window->damage.left = window->damage.right = 0;
+ window->damage.top = window->damage.bottom = 0;
+ window->client_data = 0;
+ window->name = 0;
+
+ window->draw = 0;
+ window->event = 0;
+ window->destroy = 0;
+ return window;
+}
+
+void
+twin_window_destroy (twin_window_t *window)
+{
+ twin_window_hide (window);
+ twin_pixmap_destroy (window->pixmap);
+ if (window->name) free (window->name);
+ free (window);
+}
+
+void
+twin_window_show (twin_window_t *window)
+{
+ if (window->pixmap != window->screen->top)
+ twin_pixmap_show (window->pixmap, window->screen, window->screen->top);
+}
+
+void
+twin_window_hide (twin_window_t *window)
+{
+ twin_pixmap_hide (window->pixmap);
+}
+
+void
+twin_window_configure (twin_window_t *window,
+ twin_window_style_t style,
+ twin_coord_t x,
+ twin_coord_t y,
+ twin_coord_t width,
+ twin_coord_t height)
+{
+ twin_bool_t need_repaint = TWIN_FALSE;
+
+ twin_pixmap_disable_update (window->pixmap);
+ if (style != window->style)
+ {
+ window->style = style;
+ need_repaint = TWIN_TRUE;
+ }
+ if (width != window->pixmap->width || height != window->pixmap->height)
+ {
+ twin_pixmap_t *old = window->pixmap;
+ int i;
+
+ window->pixmap = twin_pixmap_create (old->format, width, height);
+ window->pixmap->window = window;
+ twin_pixmap_move (window->pixmap, x, y);
+ if (old->screen)
+ twin_pixmap_show (window->pixmap, window->screen, old);
+ for (i = 0; i < old->disable; i++)
+ twin_pixmap_disable_update (window->pixmap);
+ twin_pixmap_destroy (old);
+ }
+ if (x != window->pixmap->x || y != window->pixmap->y)
+ twin_pixmap_move (window->pixmap, x, y);
+ if (need_repaint)
+ twin_window_draw (window);
+ twin_pixmap_enable_update (window->pixmap);
+}
+
+void
+twin_window_style_size (twin_window_style_t style,
+ twin_rect_t *size)
+{
+ switch (style) {
+ case WindowPlain:
+ size->left = size->right = size->top = size->bottom = 0;
+ break;
+ case WindowApplication:
+ size->left = TWIN_BW;
+ size->right = TWIN_BW;
+ size->top = TWIN_BW + TWIN_TITLE_HEIGHT + TWIN_BW;
+ size->bottom = TWIN_BW;
+ break;
+ }
+}
+
+void
+twin_window_set_name (twin_window_t *window,
+ const char *name)
+{
+ if (window->name) free (window->name);
+ window->name = malloc (strlen (name) + 1);
+ if (window->name) strcpy (window->name, name);
+ twin_window_draw (window);
+}
+
+static void
+twin_window_frame (twin_window_t *window)
+{
+ twin_coord_t bw = window->client.left;
+ twin_path_t *path;
+ twin_coord_t name_height;
+ twin_text_metrics_t m;
+ twin_pixmap_t *pixmap = window->pixmap;
+
+ /* border */
+
+ twin_fill (pixmap, TWIN_ACTIVE_BORDER,
+ TWIN_SOURCE,
+ 0, 0, pixmap->width, bw);
+ twin_fill (pixmap, TWIN_ACTIVE_BORDER,
+ TWIN_SOURCE,
+ 0, bw, bw, pixmap->height - bw);
+ twin_fill (pixmap, TWIN_ACTIVE_BORDER,
+ TWIN_SOURCE,
+ window->client.right, bw, pixmap->width, pixmap->height - bw);
+ twin_fill (pixmap, TWIN_ACTIVE_BORDER,
+ TWIN_SOURCE,
+ window->client.left, window->client.top - bw,
+ window->client.right, window->client.top);
+ twin_fill (pixmap, TWIN_ACTIVE_BORDER,
+ TWIN_SOURCE,
+ 0, window->client.bottom,
+ pixmap->width, pixmap->height);
+
+ /* name background */
+ twin_fill (pixmap, TWIN_ACTIVE_BG,
+ TWIN_SOURCE,
+ bw, bw, pixmap->width - bw, window->client.top - bw);
+
+ /* name */
+ if (window->name)
+ {
+ path = twin_path_create ();
+ name_height = window->client.top - bw * 4;
+ if (name_height < 1)
+ name_height = 1;
+ twin_path_translate (path, twin_int_to_fixed (bw*2),
+ twin_int_to_fixed (bw*2));
+ twin_path_set_font_size (path, twin_int_to_fixed (name_height));
+ twin_path_set_font_style (path, TWIN_TEXT_OBLIQUE);
+ twin_text_metrics_utf8 (path, window->name, &m);
+ twin_path_move (path, 0, m.font_ascent);
+ twin_path_utf8 (path, window->name);
+ twin_paint_path (pixmap, TWIN_FRAME_TEXT, path);
+ twin_path_destroy (path);
+ }
+}
+
+void
+twin_window_draw (twin_window_t *window)
+{
+ switch (window->style) {
+ case WindowPlain:
+ break;
+ case WindowApplication:
+ twin_window_frame (window);
+ break;
+ }
+ if (window->draw)
+ (*window->draw) (window);
+}
+
+twin_bool_t
+twin_window_dispatch (twin_window_t *window, twin_event_t *event)
+{
+ if (window->event && (*window->event) (window, event))
+ return TWIN_TRUE;
+ switch (event->kind) {
+ case EventButtonDown:
+ twin_window_show (window);
+ window->screen->button_x = event->u.pointer.x;
+ window->screen->button_y = event->u.pointer.y;
+ return TWIN_TRUE;
+ case EventButtonUp:
+ window->screen->button_x = -1;
+ window->screen->button_y = -1;
+ case EventMotion:
+ if (window->screen->button_x >= 0)
+ {
+ twin_coord_t x, y;
+
+ x = event->u.pointer.screen_x - window->screen->button_x;
+ y = event->u.pointer.screen_y - window->screen->button_y;
+ twin_window_configure (window,
+ window->style,
+ x, y,
+ window->pixmap->width,
+ window->pixmap->height);
+ }
+ return TWIN_TRUE;
+ default:
+ break;
+ }
+ return TWIN_FALSE;
+}
diff --git a/twin_x11.c b/twin_x11.c
index 95346a3..495c728 100644
--- a/twin_x11.c
+++ b/twin_x11.c
@@ -26,15 +26,17 @@
#include "twinint.h"
static void
-_twin_x11_put_begin (twin_coord_t x,
- twin_coord_t y,
- twin_coord_t width,
- twin_coord_t height,
+_twin_x11_put_begin (twin_coord_t left,
+ twin_coord_t top,
+ twin_coord_t right,
+ twin_coord_t bottom,
void *closure)
{
- twin_x11_t *tx = closure;
+ twin_x11_t *tx = closure;
+ twin_coord_t width = right - left;
+ twin_coord_t height = bottom - top;
- tx->iy = 0;
+ tx->image_y = top;
tx->image = XCreateImage (tx->dpy, tx->visual, tx->depth, ZPixmap,
0, 0, width, height, 32, 0);
if (tx->image)
@@ -49,33 +51,32 @@ _twin_x11_put_begin (twin_coord_t x,
}
static void
-_twin_x11_put_span (twin_coord_t x,
- twin_coord_t y,
- twin_coord_t width,
+_twin_x11_put_span (twin_coord_t left,
+ twin_coord_t top,
+ twin_coord_t right,
twin_argb32_t *pixels,
void *closure)
{
- twin_x11_t *tx = closure;
- twin_coord_t ix = 0;
- twin_coord_t iw = width;
+ twin_x11_t *tx = closure;
+ twin_coord_t width = right - left;
+ twin_coord_t ix;
+ twin_coord_t iy = top - tx->image_y;
if (!tx->image)
return;
- while (iw--)
+ for (ix = 0; ix < width; ix++)
{
twin_argb32_t pixel = *pixels++;
if (tx->depth == 16)
pixel = twin_argb32_to_rgb16 (pixel);
- XPutPixel (tx->image, ix, tx->iy, pixel);
- ix++;
+ XPutPixel (tx->image, ix, iy, pixel);
}
- tx->iy++;
- if (tx->iy == tx->image->height)
+ if ((top + 1 - tx->image_y) == tx->image->height)
{
XPutImage (tx->dpy, tx->win, tx->gc, tx->image, 0, 0,
- x, (y + 1) - tx->iy, width, tx->image->height);
+ left, tx->image_y, tx->image->width, tx->image->height);
XDestroyImage (tx->image);
tx->image = 0;
}
@@ -86,10 +87,10 @@ twin_x11_damage_thread (void *arg)
{
twin_x11_t *tx = arg;
- pthread_mutex_lock (&tx->screen->screen_mutex);
+ twin_mutex_lock (&tx->screen->screen_mutex);
for (;;)
{
- pthread_cond_wait (&tx->damage_cond, &tx->screen->screen_mutex);
+ twin_cond_wait (&tx->damage_cond, &tx->screen->screen_mutex);
if (!tx->win)
break;
if (twin_screen_damaged (tx->screen))
@@ -98,15 +99,16 @@ twin_x11_damage_thread (void *arg)
XFlush (tx->dpy);
}
}
- pthread_mutex_unlock (&tx->screen->screen_mutex);
+ twin_mutex_unlock (&tx->screen->screen_mutex);
return 0;
}
static void *
twin_x11_event_thread (void *arg)
{
- twin_x11_t *tx = arg;
- XEvent ev;
+ twin_x11_t *tx = arg;
+ XEvent ev;
+ twin_event_t tev;
for (;;)
{
@@ -117,6 +119,21 @@ twin_x11_event_thread (void *arg)
break;
case DestroyNotify:
return 0;
+ case ButtonPress:
+ case ButtonRelease:
+ tev.u.pointer.screen_x = ev.xbutton.x;
+ tev.u.pointer.screen_y = ev.xbutton.y;
+ tev.kind = ((ev.type == ButtonPress) ?
+ EventButtonDown : EventButtonUp);
+ twin_screen_dispatch (tx->screen, &tev);
+ break;
+ case MotionNotify:
+ tev.u.pointer.screen_x = ev.xmotion.x;
+ tev.u.pointer.screen_y = ev.xmotion.y;
+ tev.kind = EventMotion;
+ tev.u.pointer.button = ev.xmotion.state;
+ twin_screen_dispatch (tx->screen, &tev);
+ break;
}
}
}
@@ -126,7 +143,7 @@ twin_x11_screen_damaged (void *closure)
{
twin_x11_t *tx = closure;
- pthread_cond_broadcast (&tx->damage_cond);
+ twin_cond_broadcast (&tx->damage_cond);
}
twin_x11_t *
@@ -187,11 +204,11 @@ twin_x11_create (Display *dpy, int width, int height)
XMapWindow (dpy, tx->win);
- pthread_cond_init (&tx->damage_cond, NULL);
+ twin_cond_init (&tx->damage_cond);
- pthread_create (&tx->damage_thread, NULL, twin_x11_damage_thread, tx);
+ twin_thread_create (&tx->damage_thread, twin_x11_damage_thread, tx);
- pthread_create (&tx->event_thread, NULL, twin_x11_event_thread, tx);
+ twin_thread_create (&tx->event_thread, twin_x11_event_thread, tx);
return tx;
}
@@ -201,7 +218,7 @@ twin_x11_destroy (twin_x11_t *tx)
{
XDestroyWindow (tx->dpy, tx->win);
tx->win = 0;
- pthread_cond_broadcast (&tx->damage_cond);
+ twin_cond_broadcast (&tx->damage_cond);
twin_screen_destroy (tx->screen);
}
diff --git a/twin_x11.h b/twin_x11.h
index 613fcf6..b6a55be 100644
--- a/twin_x11.h
+++ b/twin_x11.h
@@ -29,7 +29,6 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
-#include <pthread.h>
typedef struct _twin_x11 {
twin_screen_t *screen;
@@ -38,11 +37,11 @@ typedef struct _twin_x11 {
GC gc;
Visual *visual;
int depth;
- pthread_t damage_thread;
- pthread_cond_t damage_cond;
- pthread_t event_thread;
+ twin_thread_t damage_thread;
+ twin_cond_t damage_cond;
+ twin_thread_t event_thread;
XImage *image;
- int iy;
+ int image_y;
} twin_x11_t;
/*
diff --git a/xtwin.c b/xtwin.c
index 9903511..be112b6 100644
--- a/xtwin.c
+++ b/xtwin.c
@@ -48,24 +48,28 @@
#define TWIN_CLOCK_BORDER_WIDTH D(0.01)
static void
-twin_clock_set_transform (twin_pixmap_t *clock,
+twin_clock_set_transform (twin_window_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);
+ scale = (TWIN_FIXED_ONE - TWIN_CLOCK_BORDER_WIDTH * 3) / 2;
+ twin_path_translate (path,
+ twin_int_to_fixed (clock->client.left),
+ twin_int_to_fixed (clock->client.top));
twin_path_scale (path,
- clock->width * scale,
- clock->height * scale);
+ (clock->client.right - clock->client.left) * scale,
+ (clock->client.bottom - clock->client.top) * scale);
- twin_path_translate (path, D(1) + TWIN_CLOCK_BORDER_WIDTH * 3,
- D(1) + TWIN_CLOCK_BORDER_WIDTH * 3);
+ twin_path_translate (path,
+ TWIN_FIXED_ONE + TWIN_CLOCK_BORDER_WIDTH * 3,
+ TWIN_FIXED_ONE + TWIN_CLOCK_BORDER_WIDTH * 3);
+
twin_path_rotate (path, -TWIN_ANGLE_90);
}
static void
-twin_clock_hand (twin_pixmap_t *clock,
+twin_clock_hand (twin_window_t *clock,
twin_angle_t angle,
twin_fixed_t len,
twin_fixed_t fill_width,
@@ -92,9 +96,9 @@ twin_clock_hand (twin_pixmap_t *clock,
twin_path_circle (pen, fill_width);
twin_path_convolve (path, stroke, pen);
- twin_paint_path (clock, fill_pixel, path);
+ twin_paint_path (clock->pixmap, fill_pixel, path);
- twin_paint_stroke (clock, out_pixel, path, out_width);
+ twin_paint_stroke (clock->pixmap, out_pixel, path, out_width);
twin_path_destroy (path);
twin_path_destroy (pen);
@@ -108,7 +112,7 @@ twin_clock_minute_angle (int min)
}
static void
-twin_clock_face (twin_pixmap_t *clock)
+twin_clock_face (twin_window_t *clock)
{
twin_path_t *path = twin_path_create ();
int m;
@@ -118,9 +122,9 @@ twin_clock_face (twin_pixmap_t *clock)
twin_path_move (path, 0, 0);
twin_path_circle (path, TWIN_FIXED_ONE);
- twin_paint_path (clock, TWIN_CLOCK_BACKGROUND, path);
+ twin_paint_path (clock->pixmap, TWIN_CLOCK_BACKGROUND, path);
- twin_paint_stroke (clock, TWIN_CLOCK_BORDER, path, TWIN_CLOCK_BORDER_WIDTH);
+ twin_paint_stroke (clock->pixmap, TWIN_CLOCK_BORDER, path, TWIN_CLOCK_BORDER_WIDTH);
{
twin_state_t state = twin_path_save (path);
@@ -138,12 +142,12 @@ twin_clock_face (twin_pixmap_t *clock)
twin_path_move (path, -width / 2, metrics.ascent - height/2 + D(0.01));
twin_path_draw (path, width / 2, metrics.ascent - height/2 + D(0.01));
- twin_paint_stroke (clock, TWIN_CLOCK_WATER_UNDER, path, D(0.02));
+ twin_paint_stroke (clock->pixmap, TWIN_CLOCK_WATER_UNDER, path, D(0.02));
twin_path_empty (path);
twin_path_move (path, -width / 2 - metrics.left_side_bearing, metrics.ascent - height/2);
twin_path_utf8 (path, label);
- twin_paint_path (clock, TWIN_CLOCK_WATER, path);
+ twin_paint_path (clock->pixmap, TWIN_CLOCK_WATER, path);
twin_path_restore (path, &state);
}
@@ -159,7 +163,7 @@ twin_clock_face (twin_pixmap_t *clock)
{
twin_path_move (path, 0, -TWIN_FIXED_ONE);
twin_path_draw (path, 0, -D(0.9));
- twin_paint_stroke (clock, TWIN_CLOCK_TIC, path, D(0.01));
+ twin_paint_stroke (clock->pixmap, TWIN_CLOCK_TIC, path, D(0.01));
}
else
{
@@ -174,7 +178,7 @@ twin_clock_face (twin_pixmap_t *clock)
left = -width / 2 - metrics.left_side_bearing;
twin_path_move (path, left, -D(0.98) + metrics.ascent);
twin_path_utf8 (path, hour);
- twin_paint_path (clock, TWIN_CLOCK_NUMBERS, path);
+ twin_paint_path (clock->pixmap, TWIN_CLOCK_NUMBERS, path);
}
twin_path_restore (path, &state);
}
@@ -185,21 +189,27 @@ twin_clock_face (twin_pixmap_t *clock)
int nclock;
static void
-twin_clock (twin_screen_t *screen, int x, int y, int w, int h)
+twin_clock (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
{
- twin_pixmap_t *clock = twin_pixmap_create (TWIN_ARGB32, w, h);
+ twin_window_t *clock = twin_window_create (screen, TWIN_ARGB32,
+ WindowApplication,
+ x, y, w, h);
struct timeval tv;
struct tm t;
twin_angle_t hour_angle, minute_angle, second_angle;
- twin_pixmap_move (clock, x, y);
- twin_pixmap_show (clock, screen, 0);
+ twin_window_set_name (clock, name);
+ twin_window_show (clock);
for (;;)
{
- twin_pixmap_disable_update (clock);
- twin_fill (clock, 0x00000000, TWIN_SOURCE, 0, 0,
- clock->width, clock->height);
+ twin_pixmap_disable_update (clock->pixmap);
+ twin_window_draw (clock);
+ twin_fill (clock->pixmap, 0x00000000, TWIN_SOURCE,
+ clock->client.left, clock->client.top,
+ clock->client.right, clock->client.bottom);
+
+ twin_clock_face (clock);
gettimeofday (&tv, NULL);
@@ -209,7 +219,6 @@ twin_clock (twin_screen_t *screen, int x, int y, int w, int h)
TWIN_ANGLE_360) / 6000;
minute_angle = twin_clock_minute_angle (t.tm_min) + second_angle / 60;
hour_angle = (t.tm_hour * TWIN_ANGLE_360 + minute_angle) / 12;
- twin_clock_face (clock);
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),
@@ -217,7 +226,7 @@ twin_clock (twin_screen_t *screen, int x, int y, int w, int h)
twin_clock_hand (clock, second_angle, D(0.9), D(0.01), D(0.01),
TWIN_CLOCK_SECOND, TWIN_CLOCK_SECOND_OUT);
- twin_pixmap_enable_update (clock);
+ twin_pixmap_enable_update (clock->pixmap);
gettimeofday (&tv, NULL);
@@ -228,12 +237,13 @@ twin_clock (twin_screen_t *screen, int x, int y, int w, int h)
nclock--;
}
-typedef void (*twin_app_func_t) (twin_screen_t *screen,
+typedef void (*twin_app_func_t) (twin_screen_t *screen, const char *name,
int x, int y, int w, int h);
typedef struct _twin_app_args {
twin_app_func_t func;
twin_screen_t *screen;
+ char *name;
int x, y, w, h;
} twin_app_args_t;
@@ -242,7 +252,7 @@ twin_app_thread (void *closure)
{
twin_app_args_t *a = closure;
- (*a->func) (a->screen, a->x, a->y, a->w, a->h);
+ (*a->func) (a->screen, a->name, a->x, a->y, a->w, a->h);
free (a);
return 0;
}
@@ -250,25 +260,28 @@ twin_app_thread (void *closure)
static void
twin_start_app (twin_app_func_t func,
twin_screen_t *screen,
+ const char *name,
int x, int y, int w, int h)
{
- twin_app_args_t *a = malloc (sizeof (twin_app_args_t));
+ twin_app_args_t *a = malloc (sizeof (twin_app_args_t) + strlen (name) + 1);
pthread_t thread;
a->func = func;
a->screen = screen;
+ a->name = (char *) (a + 1);
a->x = x;
a->y = y;
a->w = w;
a->h = h;
+ strcpy (a->name, name);
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)
+twin_start_clock (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
{
++nclock;
- twin_start_app (twin_clock, screen, x, y, w, h);
+ twin_start_app (twin_clock, screen, name, x, y, w, h);
}
int styles[] = {
@@ -328,9 +341,6 @@ main (int argc, char **argv)
pen = twin_path_create ();
twin_path_circle (pen, D (1));
- twin_fill (red, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
- twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
-
path = twin_path_create ();
#if 0
twin_path_move (path, D(3), D(0));
@@ -494,8 +504,6 @@ main (int argc, char **argv)
twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
WIDTH, HEIGHT);
- twin_fill (blue, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-
#if 0
path = twin_path_create ();
@@ -636,12 +644,14 @@ main (int argc, char **argv)
#endif
if (!nclock)
- twin_start_clock (x11->screen, 0, 0, WIDTH, HEIGHT);
+ twin_start_clock (x11->screen, "small clock", 10, 10, 200, 200);
+#if 1
+ twin_start_clock (x11->screen, "ul clock", 0, 0, 256, 256);
+#endif
#if 0
- twin_start_clock (x11->screen, 0, 0, 256, 256);
- 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);
+ twin_start_clock (x11->screen, "ur clock", 256, 0, 256, 256);
+ twin_start_clock (x11->screen, "ll clock", 0, 256, 256, 256);
+ twin_start_clock (x11->screen, "lr clock", 256, 256, 256, 256);
#endif
while (nclock)
sleep (1);