[Commit] twin ChangeLog, 1.20, 1.21 Makefile.am, 1.9, 1.10 configure.ac, 1.3, 1.4 twin.h, 1.15, 1.16 twin_clock.c, NONE, 1.1 twin_clock.h, NONE, 1.1 twin_demo.c, NONE, 1.1 twin_demo.h, NONE, 1.1 twin_dispatch.c, NONE, 1.1 twin_draw.c, 1.6, 1.7 twin_file.c, NONE, 1.1 twin_icon.c, NONE, 1.1 twin_path.c, 1.11, 1.12 twin_pixmap.c, 1.5, 1.6 twin_poly.c, 1.8, 1.9 twin_queue.c, NONE, 1.1 twin_screen.c, 1.7, 1.8 twin_text.c, NONE, 1.1 twin_text.h, NONE, 1.1 twin_timeout.c, NONE, 1.1 twin_window.c, 1.2, 1.3 twin_work.c, NONE, 1.1 twin_x11.c, 1.6, 1.7 twin_x11.h, 1.3, 1.4 twinint.h, 1.12, 1.13 xtwin.c, 1.19, 1.20

Keith Packard commit at keithp.com
Mon Oct 25 12:09:41 PDT 2004


Committed by: keithp

Update of /local/src/CVS/twin
In directory home.keithp.com:/tmp/cvs-serv4796

Modified Files:
	ChangeLog Makefile.am configure.ac twin.h twin_draw.c 
	twin_path.c twin_pixmap.c twin_poly.c twin_screen.c 
	twin_window.c twin_x11.c twin_x11.h twinint.h xtwin.c 
Added Files:
	twin_clock.c twin_clock.h twin_demo.c twin_demo.h 
	twin_dispatch.c twin_file.c twin_icon.c twin_queue.c 
	twin_text.c twin_text.h twin_timeout.c twin_work.c 
Log Message:
2004-10-25  Keith Packard  <keithp at keithp.com>

	* Makefile.am:
	* configure.ac:
	* twin_dispatch.c: (twin_dispatch):
	* twin_file.c: (_twin_file_order), (_twin_run_file),
	(twin_set_file), (twin_clear_file):
	* twin_queue.c: (_twin_queue_insert), (_twin_queue_remove),
	(_twin_queue_delete), (_twin_queue_set_order),
	(_twin_queue_review_order):
	* twin_timeout.c: (_twin_timeout_order), (_twin_queue_timeout),
	(_twin_run_timeout), (twin_set_timeout), (twin_clear_timeout),
	(_twin_timeout_delay), (twin_now):
	* twin_work.c: (_twin_work_order), (_twin_queue_work),
	(_twin_run_work), (twin_set_work), (twin_clear_work):
	* twinint.h:
	Add dispatch stuff to manage timeouts, workprocs and files.
	Remove thread stuff
	
	* twin.h:
	* twin_clock.c: (twin_clock_set_transform), (twin_clock_hand),
	(twin_clock_minute_angle), (twin_clock_face), (twin_clock_timeout),
	(twin_clock_start):
	* twin_clock.h:
	* twin_demo.c: (twin_example_start), (twin_line_start),
	(twin_circletext_start), (twin_quickbrown_start),
	(twin_ascii_start), (twin_jelly_start), (twin_extents_start),
	(twin_demo_start):
	* twin_demo.h:
	* twin_text.c: (twin_text_start):
	* twin_text.h:
	* xtwin.c: (main):
	Split demos into separate files
	
	* twin_draw.c: (twin_composite), (twin_fill):
	Make drawing origin match clip rectangle.

	* twin_fedit
	Add glyph editor to CVS to preserve it
	
	* twin_icon.c: (twin_icon_draw):
	Add scalable icons

	* twin_path.c: (_twin_path_sfinish), (_twin_path_smove),
	(twin_path_close), (twin_path_circle), (twin_path_ellipse),
	(twin_path_append), (twin_composite_path):
	Separate 'closing' a subpath from 'finishing' a subpath; the
	former adds a point back to the start while the latter just
	leaves the path unclosed and prepares for a new subpath.
	
	* twin_pixmap.c: (twin_pixmap_create), (twin_pixmap_show),
	(twin_pixmap_hide), (twin_pixmap_clip), (twin_pixmap_current_clip),
	(twin_pixmap_restore_clip), (twin_pixmap_reset_clip),
	(twin_pixmap_damage), (twin_pixmap_move):
	* twin_poly.c: (_twin_edge_build), (_span_fill), (_twin_edge_fill),
	(twin_fill_path):
	* twin_screen.c: (twin_screen_create):
	Eliminate locking, add clipping.

	* twin_window.c: (twin_window_create), (twin_window_configure),
	(twin_window_frame):
	Clean up title drawing, use clipping
	
	* twin_x11.c: (twin_x11_read_events), (twin_x11_work),
	(twin_x11_create), (twin_x11_destroy), (twin_x11_damage):
	* twin_x11.h:
	Eliminate locking, use dispatch stuff


Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/twin/ChangeLog,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- ChangeLog	6 Oct 2004 06:40:57 -0000	1.20
+++ ChangeLog	25 Oct 2004 19:09:35 -0000	1.21
@@ -1,3 +1,71 @@
+2004-10-25  Keith Packard  <keithp at keithp.com>
+
+	* Makefile.am:
+	* configure.ac:
+	* twin_dispatch.c: (twin_dispatch):
+	* twin_file.c: (_twin_file_order), (_twin_run_file),
+	(twin_set_file), (twin_clear_file):
+	* twin_queue.c: (_twin_queue_insert), (_twin_queue_remove),
+	(_twin_queue_delete), (_twin_queue_set_order),
+	(_twin_queue_review_order):
+	* twin_timeout.c: (_twin_timeout_order), (_twin_queue_timeout),
+	(_twin_run_timeout), (twin_set_timeout), (twin_clear_timeout),
+	(_twin_timeout_delay), (twin_now):
+	* twin_work.c: (_twin_work_order), (_twin_queue_work),
+	(_twin_run_work), (twin_set_work), (twin_clear_work):
+	* twinint.h:
+	Add dispatch stuff to manage timeouts, workprocs and files.
+	Remove thread stuff
+	
+	* twin.h:
+	* twin_clock.c: (twin_clock_set_transform), (twin_clock_hand),
+	(twin_clock_minute_angle), (twin_clock_face), (twin_clock_timeout),
+	(twin_clock_start):
+	* twin_clock.h:
+	* twin_demo.c: (twin_example_start), (twin_line_start),
+	(twin_circletext_start), (twin_quickbrown_start),
+	(twin_ascii_start), (twin_jelly_start), (twin_extents_start),
+	(twin_demo_start):
+	* twin_demo.h:
+	* twin_text.c: (twin_text_start):
+	* twin_text.h:
+	* xtwin.c: (main):
+	Split demos into separate files
+	
+	* twin_draw.c: (twin_composite), (twin_fill):
+	Make drawing origin match clip rectangle.
+
+	* twin_fedit
+	Add glyph editor to CVS to preserve it
+	
+	* twin_icon.c: (twin_icon_draw):
+	Add scalable icons
+
+	* twin_path.c: (_twin_path_sfinish), (_twin_path_smove),
+	(twin_path_close), (twin_path_circle), (twin_path_ellipse),
+	(twin_path_append), (twin_composite_path):
+	Separate 'closing' a subpath from 'finishing' a subpath; the
+	former adds a point back to the start while the latter just
+	leaves the path unclosed and prepares for a new subpath.
+	
+	* twin_pixmap.c: (twin_pixmap_create), (twin_pixmap_show),
+	(twin_pixmap_hide), (twin_pixmap_clip), (twin_pixmap_current_clip),
+	(twin_pixmap_restore_clip), (twin_pixmap_reset_clip),
+	(twin_pixmap_damage), (twin_pixmap_move):
+	* twin_poly.c: (_twin_edge_build), (_span_fill), (_twin_edge_fill),
+	(twin_fill_path):
+	* twin_screen.c: (twin_screen_create):
+	Eliminate locking, add clipping.
+
+	* twin_window.c: (twin_window_create), (twin_window_configure),
+	(twin_window_frame):
+	Clean up title drawing, use clipping
+	
+	* twin_x11.c: (twin_x11_read_events), (twin_x11_work),
+	(twin_x11_create), (twin_x11_destroy), (twin_x11_damage):
+	* twin_x11.h:
+	Eliminate locking, use dispatch stuff
+
 2004-10-05  Keith Packard  <keithp at keithp.com>
 
 	* Makefile.am:

Index: Makefile.am
===================================================================
RCS file: /local/src/CVS/twin/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Makefile.am	6 Oct 2004 06:40:57 -0000	1.9
+++ Makefile.am	25 Oct 2004 19:09:35 -0000	1.10
@@ -1,4 +1,4 @@
-CFLAGS=-g
+AM_CFLAGS=-O0 -g
 INCLUDES= @X_CFLAGS@ @WARN_CFLAGS@
 
 #libtwin_la_SOURCES = \
@@ -17,9 +17,12 @@
 xtwin_SOURCES = \
 	twin.h \
 	twin_convolve.c \
+	twin_dispatch.c \
 	twin_draw.c \
 	twin_glyphs.c \
 	twin_hull.c \
+	twin_icon.c \
+	twin_file.c \
 	twin_fixed.c \
 	twin_font.c \
 	twin_geom.c \
@@ -31,11 +34,17 @@
 	twin_primitive.c \
 	twin_screen.c \
 	twin_spline.c \
-	twin_thread.c \
 	twin_trig.c \
 	twin_window.c \
 	twin_x11.c \
 	twinint.h \
+	twin_queue.c \
+	twin_timeout.c \
+	twin_work.c \
+	twinint.h \
+	twin_clock.c \
+	twin_text.c \
+	twin_demo.c \
 	xtwin.c
 
 xtwin_LDADD = @X_LIBS@ -lm

Index: configure.ac
===================================================================
RCS file: /local/src/CVS/twin/configure.ac,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- configure.ac	30 Sep 2004 17:23:07 -0000	1.3
+++ configure.ac	25 Oct 2004 19:09:35 -0000	1.4
@@ -52,10 +52,6 @@
 AC_SUBST(X_CFLAGS)
 AC_SUBST(X_LIBS)
 
-AC_CHECK_LIB([pthread], [pthread_create])
-
-AC_CHECK_HEADERS([pthread.h])
-
 #
 #AC_ARG_WITH(freetype-config, [  --with-freetype-config=PROG   Use FreeType configuration program PROG], freetype_config=$withval, freetype_config=yes)
 #

Index: twin.h
===================================================================
RCS file: /local/src/CVS/twin/twin.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- twin.h	6 Oct 2004 06:40:57 -0000	1.15
+++ twin.h	25 Oct 2004 19:09:35 -0000	1.16
@@ -28,9 +28,6 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <twin_def.h>
-#if HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
 
 typedef uint8_t	    twin_a8_t;
 typedef uint16_t    twin_a16_t;
@@ -43,19 +40,7 @@
 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
+typedef int32_t	    twin_time_t;
 
 #define TWIN_FALSE  0
 #define TWIN_TRUE   1
@@ -120,6 +105,11 @@
     twin_coord_t		height;	    /* pixels */
     twin_coord_t		stride;	    /* bytes */
     /*
+     * Clipping - a single rectangle in pixmap coordinates.
+     * Drawing is done relative to this rectangle
+     */
+    twin_rect_t			clip;
+    /*
      * Pixels
      */
     twin_pointer_t		p;
@@ -176,7 +166,6 @@
     void		(*damaged) (void *);
     void		*damaged_closure;
     twin_count_t	disable;
-    twin_mutex_t	screen_mutex;
     /*
      * Repaint function
      */
@@ -220,6 +209,9 @@
 #define twin_fixed_to_double(f)    ((double) (f) / 65536.0)
 
 #define twin_int_to_fixed(i)	   ((twin_fixed_t) (i) << 16)
+#define twin_fixed_ceil(f)	   (((f) + 0xffff) & ~0xffff)
+#define twin_fixed_floor(f)	   ((f) & ~0xffff)
+#define twin_fixed_to_int(f)	   ((int) ((f) >> 16))
 
 typedef struct _twin_point {
     twin_fixed_t    x, y;
@@ -328,12 +320,23 @@
     TwinIconMinimize,
     TwinIconMaximize,
     TwinIconClose,
+    TwinIconResize,
 } twin_icon_t;
 
 /*
  * Widgets
  */
 
+typedef enum _twin_box_layout {
+    TwinLayoutHorz, TwinLayoutVert
+} twin_box_layout_t;
+
+typedef struct _twin_box {
+    twin_box_layout_t	layout;
+    twin_rect_t		geometry;
+    
+} twin_box_t;
+
 typedef struct {
     twin_rect_t		geometry;
 } twin_widget_t;
@@ -343,6 +346,36 @@
 } twin_button_t;
 
 /*
+ * Timeout and work procs return TWIN_TRUE to remain in the queue,
+ * timeout procs are called every 'delay' ms
+ */
+
+typedef twin_time_t (*twin_timeout_proc_t) (twin_time_t now,
+					    void	*closure);
+
+typedef twin_bool_t (*twin_work_proc_t) (void *closure);
+
+typedef enum _twin_file_op {
+    TWIN_READ = 1,
+    TWIN_WRITE = 2
+} twin_file_op_t;
+
+typedef twin_bool_t (*twin_file_proc_t) (int		file,
+					 twin_file_op_t	ops,
+					 void		*closure);
+					    
+typedef void	    (*twin_block_proc_t) (void *closure);
+typedef void	    (*twin_wakeup_proc_t) (void *closure);
+
+#define twin_time_compare(a,op,b)	(((a) - (b)) op 0)
+
+typedef struct _twin_timeout	twin_timeout_t;
+typedef struct _twin_work	twin_work_t;
+typedef struct _twin_file	twin_file_t;
+typedef struct _twin_block	twin_block_t;
+typedef struct _twin_wakeup	twin_wakeup_t;
+
+/*
  * twin_convolve.c
  */
 void
@@ -351,6 +384,12 @@
 		    twin_path_t	*pen);
 
 /*
+ * twin_dispatch.c
+ */
+void
+twin_dispatch (void);
+
+/*
  * twin_draw.c
  */
 
@@ -385,6 +424,19 @@
 twin_event_enqueue (const twin_event_t *event);
 
 /*
+ * twin_file.c
+ */
+ 
+twin_file_t *
+twin_set_file (twin_file_proc_t	    file_proc,
+	       int		    file,
+	       twin_file_op_t	    ops,
+	       void		    *closure);
+
+void
+twin_clear_file (twin_file_t *file);
+
+/*
  * twin_fixed.c
  */
 
@@ -620,9 +672,23 @@
 twin_pixmap_disable_update (twin_pixmap_t *pixmap);
 
 void
-twin_pixmap_damage (twin_pixmap_t *pixmap,
-		    twin_coord_t x1, twin_coord_t y1,
-		    twin_coord_t x2, twin_coord_t y2);
+twin_pixmap_clip (twin_pixmap_t *pixmap,
+		  twin_coord_t	left,	twin_coord_t top,
+		  twin_coord_t	right,	twin_coord_t bottom);
+
+twin_rect_t
+twin_pixmap_current_clip (twin_pixmap_t *pixmap);
+
+void
+twin_pixmap_restore_clip (twin_pixmap_t *pixmap, twin_rect_t rect);
+
+void
+twin_pixmap_reset_clip (twin_pixmap_t *pixmap);
+
+void
+twin_pixmap_damage (twin_pixmap_t   *pixmap,
+		    twin_coord_t    left,	twin_coord_t top,
+		    twin_coord_t    right,	twin_coord_t bottom);
 
 void
 twin_pixmap_lock (twin_pixmap_t *pixmap);
@@ -723,31 +789,21 @@
 		 twin_fixed_t	x3, twin_fixed_t y3);
 
 /*
- * twin_thread.c
+ * twin_timeout.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);
+#define twin_time_compare(a,op,b)	(((a) - (b)) op 0)
 
-void
-twin_cond_broadcast (twin_cond_t *cond);
+twin_timeout_t *
+twin_set_timeout (twin_timeout_proc_t timeout_proc,
+		     twin_time_t	    delay,
+		     void		    *closure);
 
 void
-twin_cond_wait (twin_cond_t *cond, twin_mutex_t *mutex);
-
-typedef void * (*twin_thread_func_t) (void *arg);
+twin_clear_timeout (twin_timeout_t *timeout);
 
-int
-twin_thread_create (twin_thread_t *thread, twin_thread_func_t func, void *arg);
+twin_time_t
+twin_now (void);
 
 /*
  * twin_trig.c
@@ -806,5 +862,18 @@
 twin_bool_t
 twin_window_dispatch (twin_window_t *window, twin_event_t *event);
 
-    
+/*
+ * twin_work.c
+ */
+
+#define TWIN_WORK_REDISPLAY  0
+
+twin_work_t *
+twin_set_work (twin_work_proc_t	    work_proc,
+		  int			    priority,
+		  void			    *closure);
+
+void
+twin_clear_work (twin_work_t *work);
+
 #endif /* _TWIN_H_ */

--- NEW FILE: twin_clock.c ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_clock.h ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_demo.c ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_demo.h ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_dispatch.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_draw.c
===================================================================
RCS file: /local/src/CVS/twin/twin_draw.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- twin_draw.c	6 Oct 2004 00:11:27 -0000	1.6
+++ twin_draw.c	25 Oct 2004 19:09:36 -0000	1.7
@@ -275,68 +275,73 @@
 {
     twin_coord_t    iy;
     twin_coord_t    left, right, top, bottom;
+    twin_coord_t    sdx, sdy;
+    twin_source_u   s;
 
+    dst_x += dst->clip.left;
+    dst_y += dst->clip.top;
     left = dst_x;
     right = dst_x + width;
     top = dst_y;
     bottom = dst_y + height;
-    if (left < 0)
-	left = 0;
-    if (right > dst->width)
-	right = dst->width;
-    if (top < 0)
-	top = 0;
-    if (bottom > dst->height)
-	bottom = dst->height;
+    /* clip */
+    if (left < dst->clip.left)
+	left = dst->clip.left;
+    if (right > dst->clip.right)
+	right = dst->clip.right;
+    if (top < dst->clip.top)
+	top = dst->clip.top;
+    if (bottom > dst->clip.bottom)
+	bottom = dst->clip.bottom;
+
     if (left >= right || top >= bottom)
 	return;
 
-    twin_pixmap_lock (dst);
+    if (src->source_kind == TWIN_PIXMAP)
+    {
+	src_x += src->u.pixmap->clip.left;
+	src_y += src->u.pixmap->clip.top;
+    }
+    else
+        s.c = src->u.argb;
+    
+    sdx = src_x - dst_x;
+    sdy = src_y - dst_y;
+
     if (msk)
     {
 	twin_src_msk_op	op;
-	twin_source_u   s, m;
-	twin_coord_t	sdx, sdy, mdx, mdy;
+	twin_source_u   m;
+	twin_coord_t	mdx, mdy;
+	
+	if (msk->source_kind == TWIN_PIXMAP)
+	{
+	    msk_x += msk->u.pixmap->clip.left;
+	    msk_y += msk->u.pixmap->clip.top;
+	}
+	else
+	    s.c = msk->u.argb;
 	
-	sdx = src_x - dst_x;
-	sdy = src_y - dst_y;
 	mdx = msk_x - dst_x;
 	mdy = msk_y - dst_y;
-	
 
 	op = comp3[operator][operand_index(src)][operand_index(msk)][dst->format];
-	if (op)
-	{
-	    if (src->source_kind == TWIN_SOLID)
-		s.c = src->u.argb;
-	    if (msk->source_kind == TWIN_SOLID)
-		s.c = msk->u.argb;
-	    for (iy = top; iy < bottom; iy++)
-	    {
-		if (src->source_kind == TWIN_PIXMAP)
-		    s.p = twin_pixmap_pointer (src->u.pixmap, left+sdx, iy+sdy);
-		if (msk->source_kind == TWIN_PIXMAP)
-		    m.p = twin_pixmap_pointer (msk->u.pixmap, left+mdx, iy+mdy);
-		(*op) (twin_pixmap_pointer (dst, left, iy),
-		       s, m, right - left);
-	    }
-	}
-	else
+	for (iy = top; iy < bottom; iy++)
 	{
+	    if (src->source_kind == TWIN_PIXMAP)
+		s.p = twin_pixmap_pointer (src->u.pixmap, left+sdx, iy+sdy);
+	    if (msk->source_kind == TWIN_PIXMAP)
+		m.p = twin_pixmap_pointer (msk->u.pixmap, left+mdx, iy+mdy);
+	    (*op) (twin_pixmap_pointer (dst, left, iy),
+		   s, m, right - left);
 	}
     }
     else
     {
 	twin_src_op	op;
-	twin_source_u   s;
-	twin_coord_t	sdx, sdy;
-	
-	sdx = src_x - dst_x;
-	sdy = src_y - dst_y;
 	
 	op = comp2[operator][operand_index(src)][dst->format];
-        if (src->source_kind == TWIN_SOLID)
-	    s.c = src->u.argb;
+	
 	for (iy = top; iy < bottom; iy++)
 	{
 	    if (src->source_kind == TWIN_PIXMAP)
@@ -346,7 +351,6 @@
 	}
     }
     twin_pixmap_damage (dst, left, top, right, bottom);
-    twin_pixmap_unlock (dst);
 }
 	     
 /*
@@ -379,19 +383,24 @@
     twin_source_u   src;
     twin_coord_t    iy;
     
-    twin_pixmap_lock (dst);
+    left += dst->clip.left;
+    right += dst->clip.left;
+    top += dst->clip.top;
+    bottom += dst->clip.top;
+    /* clip */
+    if (left < dst->clip.left)
+	left = dst->clip.left;
+    if (right > dst->clip.right)
+	right = dst->clip.right;
+    if (top < dst->clip.top)
+	top = dst->clip.top;
+    if (bottom > dst->clip.bottom)
+	bottom = dst->clip.bottom;
+    if (left >= right || top >= bottom)
+	return;
     src.c = pixel;
-    if (left < 0)
-	left = 0;
-    if (right > dst->width)
-	right = dst->width;
-    if (top < 0)
-	top = 0;
-    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);
 }

--- NEW FILE: twin_file.c ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_icon.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_path.c
===================================================================
RCS file: /local/src/CVS/twin/twin_path.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- twin_path.c	6 Oct 2004 00:11:27 -0000	1.11
+++ twin_path.c	25 Oct 2004 19:09:36 -0000	1.12
@@ -60,12 +60,44 @@
     return path->points[start];
 }
 
+void
+_twin_path_sfinish (twin_path_t *path)
+{
+    switch (_twin_current_subpath_len(path)) {
+    case 1:
+	path->npoints--;
+    case 0:
+	return;
+    }
+    
+    if (path->nsublen == path->size_sublen)
+    {
+	int	size_sublen;
+	int	*sublen;
+	
+	if (path->size_sublen > 0)
+	    size_sublen = path->size_sublen * 2;
+	else
+	    size_sublen = 1;
+	if (path->sublen)
+	    sublen = realloc (path->sublen, size_sublen * sizeof (int));
+	else
+	    sublen = malloc (size_sublen * sizeof (int));
+	if (!sublen)
+	    return;
+	path->sublen = sublen;
+	path->size_sublen = size_sublen;
+    }
+    path->sublen[path->nsublen] = path->npoints;
+    path->nsublen++;
+}
+
 void 
 _twin_path_smove (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y)
 {
     switch (_twin_current_subpath_len (path)) {
     default:
-	twin_path_close (path);
+	_twin_path_sfinish (path);
     case 0:
 	_twin_path_sdraw (path, x, y);
 	break;
@@ -147,33 +179,17 @@
 void
 twin_path_close (twin_path_t *path)
 {
+    twin_spoint_t   f;
+    
     switch (_twin_current_subpath_len(path)) {
-    case 1:
-	path->npoints--;
     case 0:
-	return;
-    }
-    
-    if (path->nsublen == path->size_sublen)
-    {
-	int	size_sublen;
-	int	*sublen;
-	
-	if (path->size_sublen > 0)
-	    size_sublen = path->size_sublen * 2;
-	else
-	    size_sublen = 1;
-	if (path->sublen)
-	    sublen = realloc (path->sublen, size_sublen * sizeof (int));
-	else
-	    sublen = malloc (size_sublen * sizeof (int));
-	if (!sublen)
-	    return;
-	path->sublen = sublen;
-	path->size_sublen = size_sublen;
+    case 1:
+	break;
+    default:
+	f = _twin_path_subpath_first_spoint (path);
+	_twin_path_sdraw (path, f.x, f.y);
+	break;
     }
-    path->sublen[path->nsublen] = path->npoints;
-    path->nsublen++;
 }
 
 #define twin_fixed_abs(f)   ((f) < 0 ? -(f) : (f))
@@ -201,7 +217,7 @@
 
     center = _twin_path_current_spoint (path);
 
-    twin_path_close (path);
+    _twin_path_sfinish (path);
     
     max_radius = _twin_matrix_max_radius (&path->state.matrix);
     
@@ -224,7 +240,7 @@
 			  center.y + _twin_matrix_dy (&path->state.matrix, x, y));
     }
     
-    twin_path_close (path);
+    _twin_path_sfinish (path);
     twin_path_set_matrix (path, save);
 }
 
@@ -246,7 +262,7 @@
 
     center = _twin_path_current_spoint (path);
 
-    twin_path_close (path);
+    _twin_path_sfinish (path);
     
     max_radius = _twin_matrix_max_radius (&path->state.matrix);
     
@@ -269,7 +285,7 @@
 			  center.y + _twin_matrix_dy (&path->state.matrix, x, y));
     }
     
-    twin_path_close (path);
+    _twin_path_sfinish (path);
     twin_path_set_matrix (path, save);
 }
 
@@ -376,7 +392,7 @@
     {
 	if (s < src->nsublen && p == src->sublen[s])
 	{
-	    twin_path_close (dst);
+	    _twin_path_sfinish (dst);
 	    s++;
 	}
 	_twin_path_sdraw (dst, src->points[p].x, src->points[p].y);
@@ -435,7 +451,7 @@
     twin_coord_t    width, height;
 
     twin_path_bounds (path, &bounds);
-    if (bounds.left == bounds.right)
+    if (bounds.left >= bounds.right || bounds.top >= bounds.bottom)
 	return;
     width = bounds.right - bounds.left;
     height = bounds.bottom - bounds.top;

Index: twin_pixmap.c
===================================================================
RCS file: /local/src/CVS/twin/twin_pixmap.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- twin_pixmap.c	6 Oct 2004 06:40:57 -0000	1.5
+++ twin_pixmap.c	25 Oct 2004 19:09:36 -0000	1.6
@@ -42,6 +42,9 @@
     pixmap->format = format;
     pixmap->width = width;
     pixmap->height = height;
+    pixmap->clip.left = pixmap->clip.top = 0;
+    pixmap->clip.right = pixmap->width;
+    pixmap->clip.bottom = pixmap->height;
     pixmap->stride = stride;
     pixmap->disable = 0;
     pixmap->p.v = pixmap + 1;
@@ -94,8 +97,6 @@
     if (pixmap->screen)
 	twin_pixmap_hide (pixmap);
     
-    twin_screen_lock (screen);
-
     pixmap->screen = screen;
     
     if (lower)
@@ -116,7 +117,6 @@
     }
 
     twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height);
-    twin_screen_unlock (screen);
 }
 
 void
@@ -127,7 +127,7 @@
 
     if (!screen)
 	return;
-    twin_screen_lock (screen);
+
     twin_pixmap_damage (pixmap, 0, 0, pixmap->width, pixmap->height);
 
     if (pixmap->up)
@@ -148,7 +148,6 @@
     pixmap->down = 0;
     if (pixmap->disable)
 	twin_screen_enable_update (screen);
-    twin_screen_unlock (screen);
 }
 
 twin_pointer_t
@@ -183,30 +182,50 @@
 }
 
 void
-twin_pixmap_damage (twin_pixmap_t *pixmap,
-		    twin_coord_t x1, twin_coord_t y1,
-		    twin_coord_t x2, twin_coord_t y2)
+twin_pixmap_clip (twin_pixmap_t *pixmap,
+		  twin_coord_t	left,	twin_coord_t top,
+		  twin_coord_t	right,	twin_coord_t bottom)
 {
-    if (pixmap->screen)
-	twin_screen_damage (pixmap->screen,
-			    x1 + pixmap->x,
-			    y1 + pixmap->y,
-			    x2 + pixmap->x,
-			    y2 + pixmap->y);
+    if (left > pixmap->clip.left)	pixmap->clip.left = left;
+    if (top > pixmap->clip.top)		pixmap->clip.top = top;
+    if (right < pixmap->clip.right)	pixmap->clip.right = right;
+    if (bottom < pixmap->clip.bottom)	pixmap->clip.bottom = bottom;
+    if (pixmap->clip.left >= pixmap->clip.right)
+	pixmap->clip.right = pixmap->clip.left = 0;
+    if (pixmap->clip.top >= pixmap->clip.bottom)
+	pixmap->clip.bottom = pixmap->clip.top = 0;
+}
+
+twin_rect_t
+twin_pixmap_current_clip (twin_pixmap_t *pixmap)
+{
+    return pixmap->clip;
 }
 
 void
-twin_pixmap_lock (twin_pixmap_t *pixmap)
+twin_pixmap_restore_clip (twin_pixmap_t *pixmap, twin_rect_t rect)
 {
-    if (pixmap->screen)
-	twin_screen_lock (pixmap->screen);
+    pixmap->clip = rect;
 }
 
 void
-twin_pixmap_unlock (twin_pixmap_t *pixmap)
+twin_pixmap_reset_clip (twin_pixmap_t *pixmap)
+{
+    pixmap->clip.left = 0;		pixmap->clip.top = 0;
+    pixmap->clip.right = pixmap->width;	pixmap->clip.bottom = pixmap->height;
+}
+
+void
+twin_pixmap_damage (twin_pixmap_t *pixmap,
+		    twin_coord_t x1, twin_coord_t y1,
+		    twin_coord_t x2, twin_coord_t y2)
 {
     if (pixmap->screen)
-	twin_screen_unlock (pixmap->screen);
+	twin_screen_damage (pixmap->screen,
+			    x1 + pixmap->x,
+			    y1 + pixmap->y,
+			    x2 + pixmap->x,
+			    y2 + pixmap->y);
 }
 
 static twin_argb32_t
@@ -238,12 +257,10 @@
 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

Index: twin_poly.c
===================================================================
RCS file: /local/src/CVS/twin/twin_poly.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- twin_poly.c	5 Oct 2004 18:42:53 -0000	1.8
+++ twin_poly.c	25 Oct 2004 19:09:36 -0000	1.9
@@ -85,7 +85,7 @@
 
 static int
 _twin_edge_build (twin_spoint_t *vertices, int nvertices, twin_edge_t *edges,
-		  twin_sfixed_t dx, twin_sfixed_t dy)
+		  twin_sfixed_t dx, twin_sfixed_t dy, twin_sfixed_t top_y)
 {
     int		    v, nv;
     int		    tv, bv;
@@ -120,8 +120,8 @@
 
 	/* snap top to first grid point in pixmap */
 	y = _twin_sfixed_grid_ceil (vertices[tv].y + dy);
-	if (y < TWIN_POLY_START)
-	    y = TWIN_POLY_START;
+	if (y < TWIN_POLY_START + top_y)
+	    y = TWIN_POLY_START + top_y;
 	
 	/* skip vertices which don't span a sample row */
 	if (y >= vertices[bv].y + dy)
@@ -206,8 +206,8 @@
     int		    col;
     
     /* clip to pixmap */
-    if (left < 0)
-	left = 0;
+    if (left < twin_int_to_sfixed (pixmap->clip.left))
+	left = twin_int_to_sfixed (pixmap->clip.left);
     
     if (right > twin_int_to_sfixed (pixmap->width))
 	right = twin_int_to_sfixed (pixmap->width);
@@ -311,7 +311,7 @@
 	/* step down, clipping to pixmap */
 	y += TWIN_POLY_STEP;
 
-	if (twin_sfixed_trunc (y) >= pixmap->height)
+	if (twin_sfixed_trunc (y) >= pixmap->clip.bottom)
 	    break;
 	
 	/* strip out dead edges */
@@ -363,6 +363,8 @@
     edges = malloc (sizeof (twin_edge_t) * nalloc);
     p = 0;
     nedges = 0;
+    dx += twin_int_to_sfixed (pixmap->clip.left);
+    dy += twin_int_to_sfixed (pixmap->clip.top);
     for (s = 0; s <= path->nsublen; s++)
     {
 	int sublen;
@@ -376,7 +378,7 @@
 	if (npoints > 1)
 	{
 	    n = _twin_edge_build (path->points + p, npoints, edges + nedges,
-				  sdx, sdy);
+				  sdx, sdy, twin_int_to_sfixed (pixmap->clip.top));
 	    p = sublen;
 	    nedges += n;
 	}

--- NEW FILE: twin_queue.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_screen.c
===================================================================
RCS file: /local/src/CVS/twin/twin_screen.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- twin_screen.c	6 Oct 2004 06:40:57 -0000	1.7
+++ twin_screen.c	25 Oct 2004 19:09:36 -0000	1.8
@@ -44,7 +44,6 @@
     screen->damaged_closure = NULL;
     screen->disable = 0;
     screen->background = 0;
-    twin_mutex_init (&screen->screen_mutex);
     screen->put_begin = put_begin;
     screen->put_span = put_span;
     screen->closure = closure;
@@ -54,18 +53,6 @@
 }
 
 void
-twin_screen_lock (twin_screen_t *screen)
-{
-    twin_mutex_lock (&screen->screen_mutex);
-}
-
-void
-twin_screen_unlock (twin_screen_t *screen)
-{
-    twin_mutex_unlock (&screen->screen_mutex);
-}
-
-void
 twin_screen_destroy (twin_screen_t *screen)
 {
     while (screen->bottom)

--- NEW FILE: twin_text.c ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_text.h ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: twin_timeout.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_window.c
===================================================================
RCS file: /local/src/CVS/twin/twin_window.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- twin_window.c	6 Oct 2004 06:40:57 -0000	1.2
+++ twin_window.c	25 Oct 2004 19:09:36 -0000	1.3
@@ -29,7 +29,9 @@
 #define TWIN_FRAME_TEXT	    0xffffffff
 #define TWIN_ACTIVE_BORDER  0xff606060
 #define TWIN_BW		    0
-#define TWIN_TITLE_HEIGHT   22
+#define TWIN_TITLE_HEIGHT   20
+#define TWIN_RESIZE_SIZE    ((TWIN_TITLE_HEIGHT + 4) / 5)
+#define TWIN_TITLE_BW	    ((TWIN_TITLE_HEIGHT + 11) / 12)
 
 twin_window_t *
 twin_window_create (twin_screen_t	*screen,
@@ -50,8 +52,8 @@
     case WindowApplication:
 	left = TWIN_BW;
 	top = TWIN_BW + TWIN_TITLE_HEIGHT + TWIN_BW;
-	right = TWIN_BW;
-	bottom = TWIN_BW;
+	right = TWIN_BW + TWIN_RESIZE_SIZE;
+	bottom = TWIN_BW + TWIN_RESIZE_SIZE;
 	break;
     case WindowPlain:
     default:
@@ -68,6 +70,9 @@
     window->client.top = top;
     window->client.bottom = height - bottom;
     window->pixmap = twin_pixmap_create (format, width, height);
+    twin_pixmap_clip (window->pixmap,
+		      window->client.left, window->client.top,
+		      window->client.right, window->client.bottom);
     window->pixmap->window = window;
     twin_pixmap_move (window->pixmap, x, y);
     window->damage.left = window->damage.right = 0;
@@ -132,6 +137,9 @@
 	for (i = 0; i < old->disable; i++)
 	    twin_pixmap_disable_update (window->pixmap);
 	twin_pixmap_destroy (old);
+	twin_pixmap_clip (window->pixmap,
+			  window->client.left, window->client.top,
+			  window->client.right, window->client.bottom);
     }
     if (x != window->pixmap->x || y != window->pixmap->y)
 	twin_pixmap_move (window->pixmap, x, y);
@@ -171,25 +179,68 @@
 static void
 twin_window_frame (twin_window_t *window)
 {
-    twin_coord_t	bw = 2;
+    twin_fixed_t	bw = twin_int_to_fixed (TWIN_TITLE_BW);
     twin_path_t		*path;
-    twin_coord_t	name_height;
-    twin_text_metrics_t	m;
+    twin_fixed_t	bw_2 = bw / 2;
     twin_pixmap_t	*pixmap = window->pixmap;
-    twin_fixed_t	bw_2 = twin_int_to_fixed (bw) / 2;
     twin_fixed_t	w_top = bw_2;
     twin_fixed_t	c_left = bw_2;
-    twin_fixed_t	t_h = twin_int_to_fixed (window->client.top - bw);
+    twin_fixed_t	t_h = twin_int_to_fixed (window->client.top) - bw;
     twin_fixed_t	t_arc_1 = t_h / 3;
-    twin_fixed_t	c_right = twin_int_to_fixed (pixmap->width) - bw_2;
+    twin_fixed_t	t_arc_2 = t_h * 2 / 3;
+    twin_fixed_t	c_right = twin_int_to_fixed (window->client.right) - bw_2;
     twin_fixed_t	c_top = twin_int_to_fixed (window->client.top) - bw_2;
-
+    
+    twin_fixed_t	name_height = t_h - bw - bw_2;
+    twin_fixed_t	icon_size = name_height * 8 / 10;
+    twin_fixed_t	icon_y = (twin_int_to_fixed (window->client.top) - 
+				  icon_size) / 2;
+    twin_fixed_t	menu_x = t_arc_2;
+    twin_fixed_t	text_x = menu_x + icon_size + bw;
+    twin_fixed_t	text_y = icon_y + icon_size;
+    twin_fixed_t	text_width;
+    twin_fixed_t	title_right;
+    twin_fixed_t	close_x;
+    twin_fixed_t	max_x;
+    twin_fixed_t	min_x;
+    twin_fixed_t	resize_x;
+    twin_fixed_t	resize_y;
+    const char		*name;
+    
+    twin_pixmap_reset_clip (pixmap);
+    
     twin_fill (pixmap, 0x00000000, TWIN_SOURCE, 
 	       0, 0, pixmap->width, window->client.top);
 
+    path = twin_path_create ();
+
+		      
+    /* name */
+    name = window->name;
+    if (!name)
+	name = "Sans un nom!";
+    twin_path_set_font_size (path, name_height);
+    twin_path_set_font_style (path, TWIN_TEXT_OBLIQUE | TWIN_TEXT_UNHINTED);
+    text_width = twin_width_utf8 (path, name);
+	
+    title_right = (text_x + text_width + 
+		   bw + icon_size +
+		   bw + icon_size +
+		   bw + icon_size + 
+		   t_arc_2);
+    
+    if (title_right < c_right)
+	c_right = title_right;
+    
+							  
+    close_x = c_right - t_arc_2 - icon_size;
+    max_x = close_x - bw - icon_size;
+    min_x = max_x - bw - icon_size;
+    resize_x = twin_int_to_fixed (window->client.right);
+    resize_y = twin_int_to_fixed (window->client.bottom);
+
     /* border */
      
-    path = twin_path_create ();
     twin_path_move (path, c_left, c_top);
     twin_path_draw (path, c_right, c_top);
     twin_path_curve (path,
@@ -209,23 +260,54 @@
 
     twin_path_empty (path);
     
-    /* name */
-    if (window->name)
+    twin_pixmap_clip (pixmap, 
+		      twin_fixed_to_int (twin_fixed_floor (menu_x)),
+		      0,
+		      twin_fixed_to_int (twin_fixed_ceil (c_right - t_arc_2)),
+		      window->client.top);
+    
+    twin_path_move (path, text_x - twin_fixed_floor (menu_x), text_y);
+    twin_path_utf8 (path, window->name);
+    twin_paint_path (pixmap, TWIN_FRAME_TEXT, path);
+
+    twin_pixmap_reset_clip (pixmap);
+	
+    /* widgets */
+
     {
-	twin_point_t	t;
-	name_height = window->client.top - bw * 2;
-	if (name_height < 1) 
-	    name_height = 1;
-	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);
-	t.x = ((c_right - c_left) - 
-	       (m.right_side_bearing - m.left_side_bearing)) / 2;
-	t.y = c_top - bw_2 * 4;
-	twin_path_move (path, t.x, t.y);
-	twin_path_utf8 (path, window->name);
-	twin_paint_path (pixmap, TWIN_FRAME_TEXT, path);
+	twin_matrix_t	m;
+	
+	twin_matrix_identity (&m);
+	twin_matrix_translate (&m, menu_x, icon_y);
+	twin_matrix_scale (&m, icon_size, icon_size);
+	twin_icon_draw (pixmap, TwinIconMenu, m);
+	
+	twin_matrix_identity (&m);
+	twin_matrix_translate (&m, min_x, icon_y);
+	twin_matrix_scale (&m, icon_size, icon_size);
+	twin_icon_draw (pixmap, TwinIconMinimize, m);
+	
+	twin_matrix_identity (&m);
+	twin_matrix_translate (&m, max_x, icon_y);
+	twin_matrix_scale (&m, icon_size, icon_size);
+	twin_icon_draw (pixmap, TwinIconMaximize, m);
+
+	twin_matrix_identity (&m);
+	twin_matrix_translate (&m, close_x, icon_y);
+	twin_matrix_scale (&m, icon_size, icon_size);
+	twin_icon_draw (pixmap, TwinIconClose, m);
+	
+	twin_matrix_identity (&m);
+	twin_matrix_translate (&m, resize_x, resize_y);
+	twin_matrix_scale (&m, 
+			   twin_int_to_fixed (TWIN_TITLE_HEIGHT),
+			   twin_int_to_fixed (TWIN_TITLE_HEIGHT));
+	twin_icon_draw (pixmap, TwinIconResize, m);
     }
+
+    twin_pixmap_clip (pixmap,
+		      window->client.left, window->client.top,
+		      window->client.right, window->client.bottom);
     twin_path_destroy (path);
 }
 

--- NEW FILE: twin_work.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_x11.c
===================================================================
RCS file: /local/src/CVS/twin/twin_x11.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- twin_x11.c	6 Oct 2004 00:11:27 -0000	1.6
+++ twin_x11.c	25 Oct 2004 19:09:36 -0000	1.7
@@ -82,36 +82,18 @@
     }
 }
 
-static void *
-twin_x11_damage_thread (void *arg)
+static twin_bool_t
+twin_x11_read_events (int		file,
+		      twin_file_op_t	ops,
+		      void		*closure)
 {
-    twin_x11_t	*tx = arg;
+    twin_x11_t		    *tx = closure;
 
-    twin_mutex_lock (&tx->screen->screen_mutex);
-    for (;;)
+    while (XEventsQueued (tx->dpy, QueuedAfterReading))
     {
-	twin_cond_wait (&tx->damage_cond, &tx->screen->screen_mutex);
-	if (!tx->win)
-	    break;
-	if (twin_screen_damaged (tx->screen))
-	{
-	    twin_x11_update (tx);
-	    XFlush (tx->dpy);
-	}
-    }
-    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_event_t    tev;
+	XEvent		ev;
+	twin_event_t    tev;
 
-    for (;;)
-    {
 	XNextEvent (tx->dpy, &ev);
 	switch (ev.type) {
 	case Expose:
@@ -136,14 +118,20 @@
 	    break;
 	}
     }
+    return TWIN_TRUE;
 }
 
-static void
-twin_x11_screen_damaged (void *closure)
+static twin_bool_t
+twin_x11_work (void *closure)
 {
-    twin_x11_t	*tx = closure;
-
-    twin_cond_broadcast (&tx->damage_cond);
+    twin_x11_t		    *tx = closure;
+    
+    if (twin_screen_damaged (tx->screen))
+    {
+	twin_x11_update (tx);
+	XFlush (tx->dpy);
+    }
+    return TWIN_TRUE;
 }
 
 twin_x11_t *
@@ -167,6 +155,13 @@
     tx->visual = DefaultVisual (dpy, scr);
     tx->depth = DefaultDepth (dpy, scr);
 
+    twin_set_file (twin_x11_read_events,
+		      ConnectionNumber (dpy),
+		      TWIN_READ,
+		      tx);
+    
+    twin_set_work (twin_x11_work, TWIN_WORK_REDISPLAY, tx);
+
     wa.background_pixmap = None;
     wa.event_mask = (KeyPressMask|
 		     KeyReleaseMask|
@@ -200,16 +195,9 @@
     tx->gc = XCreateGC (dpy, tx->win, 0, 0);
     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);
 
     XMapWindow (dpy, tx->win);
 
-    twin_cond_init (&tx->damage_cond);
-
-    twin_thread_create (&tx->damage_thread, twin_x11_damage_thread, tx);
-
-    twin_thread_create (&tx->event_thread, twin_x11_event_thread, tx);
-    
     return tx;
 }
 
@@ -218,17 +206,14 @@
 {
     XDestroyWindow (tx->dpy, tx->win);
     tx->win = 0;
-    twin_cond_broadcast (&tx->damage_cond);
     twin_screen_destroy (tx->screen);
 }
 
 void
 twin_x11_damage (twin_x11_t *tx, XExposeEvent *ev)
 {
-    twin_screen_lock (tx->screen);
     twin_screen_damage (tx->screen, 
 			ev->x, ev->y, ev->x + ev->width, ev->y + ev->height);
-    twin_screen_unlock (tx->screen);
 }
 
 void

Index: twin_x11.h
===================================================================
RCS file: /local/src/CVS/twin/twin_x11.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- twin_x11.h	6 Oct 2004 00:11:27 -0000	1.3
+++ twin_x11.h	25 Oct 2004 19:09:36 -0000	1.4
@@ -37,9 +37,6 @@
     GC		    gc;
     Visual	    *visual;
     int		    depth;
-    twin_thread_t   damage_thread;
-    twin_cond_t	    damage_cond;
-    twin_thread_t   event_thread;
     XImage	    *image;
     int		    image_y;
 } twin_x11_t;

Index: twinint.h
===================================================================
RCS file: /local/src/CVS/twin/twinint.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- twinint.h	5 Oct 2004 18:42:53 -0000	1.12
+++ twinint.h	25 Oct 2004 19:09:36 -0000	1.13
@@ -345,6 +345,9 @@
 		   twin_sfixed_t    x2, twin_sfixed_t y2,
 		   twin_sfixed_t    x3, twin_sfixed_t y3);
 
+void
+_twin_path_sfinish (twin_path_t *path);
+
 /*
  * Glyph stuff.  Coordinates are stored in 2.6 fixed point format
  */
@@ -375,4 +378,89 @@
 #define twin_glyph_snap_y(g)	(twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g))
 #define twin_glyph_draw(g)	(twin_glyph_snap_y(g) + twin_glyph_n_snap_y(g))
 
+/*
+ * dispatch stuff
+ */
+
+typedef struct _twin_queue {
+    struct _twin_queue  *next;
+    struct _twin_queue	*order;
+    twin_bool_t		walking;
+    twin_bool_t		deleted;
+} twin_queue_t;
+
+struct _twin_timeout {
+    twin_queue_t	queue;
+    twin_time_t		time;
+    twin_time_t		delay;
+    twin_timeout_proc_t proc;
+    void		*closure;
+};
+
+struct _twin_work {
+    twin_queue_t	queue;
+    int			priority;
+    twin_work_proc_t	proc;
+    void		*closure;
+};
+
+struct _twin_file {
+    twin_queue_t	queue;
+    int			file;
+    twin_file_op_t	ops;
+    twin_file_proc_t	proc;
+    void		*closure;
+};
+
+struct _twin_block {
+    twin_queue_t	queue;
+    twin_block_proc_t   proc;
+    void		*closure;
+};
+
+struct _twin_wakeup {
+    twin_queue_t	queue;
+    twin_wakeup_proc_t  proc;
+    void		*closure;
+};
+
+typedef enum _twin_order {
+    TWIN_BEFORE = -1,
+    TWIN_AT = 0,
+    TWIN_AFTER = 1
+} twin_order_t;
+
+typedef twin_order_t (*twin_queue_proc_t) (twin_queue_t *a, twin_queue_t *b);
+
+void
+_twin_queue_insert (twin_queue_t	**head,
+		    twin_queue_proc_t	proc,
+		    twin_queue_t	*new);
+
+void
+_twin_queue_remove (twin_queue_t	**head,
+		    twin_queue_t	*old);
+
+void
+_twin_queue_delete (twin_queue_t	**head,
+		    twin_queue_t	*old);
+
+twin_queue_t *
+_twin_queue_set_order (twin_queue_t	**head);
+
+void
+_twin_queue_review_order (twin_queue_t	*first);
+
+void
+_twin_run_file (twin_time_t delay);
+
+void
+_twin_run_timeout (void);
+    
+twin_time_t
+_twin_timeout_delay (void);
+
+void
+_twin_run_work (void);
+
 #endif /* _TWININT_H_ */

Index: xtwin.c
===================================================================
RCS file: /local/src/CVS/twin/xtwin.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- xtwin.c	6 Oct 2004 06:40:57 -0000	1.19
+++ xtwin.c	25 Oct 2004 19:09:36 -0000	1.20
@@ -29,327 +29,9 @@
 #include <sys/time.h>
 #include <time.h>
 #include <assert.h>
-
-#define D(x) twin_double_to_fixed(x)
-
-#define TWIN_CLOCK_BACKGROUND	0xff3b80ae
-#define TWIN_CLOCK_HOUR		0x80808080
-#define TWIN_CLOCK_HOUR_OUT	0x30000000
-#define TWIN_CLOCK_MINUTE	0x80808080
-#define TWIN_CLOCK_MINUTE_OUT	0x30000000
-#define TWIN_CLOCK_SECOND	0x80808080
-#define TWIN_CLOCK_SECOND_OUT	0x30000000
-#define TWIN_CLOCK_TIC		0xffbababa
-#define TWIN_CLOCK_NUMBERS	0xffdedede
-#define TWIN_CLOCK_WATER	0x60200000
-#define TWIN_CLOCK_WATER_OUT	0x40404040
-#define TWIN_CLOCK_WATER_UNDER	0x60400000
-#define TWIN_CLOCK_BORDER	0xffbababa
-#define TWIN_CLOCK_BORDER_WIDTH	D(0.01)
-
-static void
-twin_clock_set_transform (twin_window_t	*clock,
-			  twin_path_t	*path)
-{
-    twin_fixed_t    scale;
-
-    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->client.right - clock->client.left) * scale,
-		     (clock->client.bottom - clock->client.top) * scale);
-
-    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_window_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->pixmap, fill_pixel, path);
-
-    twin_paint_stroke (clock->pixmap, out_pixel, path, out_width);
-    
-    twin_path_destroy (path);
-    twin_path_destroy (pen);
-    twin_path_destroy (stroke);
-}
-
-static twin_angle_t
-twin_clock_minute_angle (int min)
-{
-    return min * TWIN_ANGLE_360 / 60;
-}
-
-static void
-twin_clock_face (twin_window_t *clock)
-{
-    twin_path_t	    *path = twin_path_create ();
-    int		    m;
-
-    twin_clock_set_transform (clock, path);
-
-    twin_path_move (path, 0, 0);
-    twin_path_circle (path, TWIN_FIXED_ONE);
-    
-    twin_paint_path (clock->pixmap, TWIN_CLOCK_BACKGROUND, path);
-
-    twin_paint_stroke (clock->pixmap, 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, width;
-	static char	    *label = "twin";
-
-	twin_path_empty (path);
-	twin_path_rotate (path, twin_degrees_to_angle (-11) + TWIN_ANGLE_90);
-	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;
-	width = metrics.right_side_bearing - metrics.left_side_bearing;
-	
-	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->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->pixmap, 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);
-	twin_path_rotate (path, twin_clock_minute_angle (m) + TWIN_ANGLE_90);
-        twin_path_empty (path);
-	if (m % 5 != 0)
-	{
-	    twin_path_move (path, 0, -TWIN_FIXED_ONE);
-	    twin_path_draw (path, 0, -D(0.9));
-	    twin_paint_stroke (clock->pixmap, TWIN_CLOCK_TIC, path, D(0.01));
-	}
-	else
-	{
-	    char		hour[3];
-	    twin_text_metrics_t	metrics;
-	    twin_fixed_t	width;
-	    twin_fixed_t	left;
-	    
-	    sprintf (hour, "%d", m / 5);
-	    twin_text_metrics_utf8 (path, hour, &metrics);
-	    width = metrics.right_side_bearing - metrics.left_side_bearing;
-	    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->pixmap, TWIN_CLOCK_NUMBERS, path);
-	}
-        twin_path_restore (path, &state);
-    }
-    
-    twin_path_destroy (path);
-}
-
-int napp;
-
-static void
-twin_clock (twin_screen_t *screen, const char *name, int x, int y, int w, int 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_window_set_name (clock, name);
-    twin_window_show (clock);
-    
-    for (;;)
-    {
-	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);
-
-	localtime_r(&tv.tv_sec, &t);
-
-	second_angle = ((t.tm_sec * 100 + tv.tv_usec / 10000) * 
-			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_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_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->pixmap);
-	
-	gettimeofday (&tv, NULL);
-	
-#define INTERVAL    1000000
-	
-	usleep (INTERVAL - (tv.tv_usec % INTERVAL));
-    }
-    napp--;
-}
-
-static void
-twin_text_app (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
-{
-    twin_window_t   *text = twin_window_create (screen, TWIN_ARGB32,
-						WindowApplication,
-						x,y,w,h);
-    twin_fixed_t    fx, fy;
-    static const char	*lines[] = {
-	"Fourscore and seven years ago our fathers brought forth on",
-	"this continent a new nation, conceived in liberty and",
-	"dedicated to the proposition that all men are created equal.",
-	"",
-	"Now we are engaged in a great civil war, testing whether that",
-	"nation or any nation so conceived and so dedicated can long",
-	"endure. We are met on a great battlefield of that war. We",
-	"have come to dedicate a portion of it as a final resting",
-	"place for those who died here that the nation might live.",
-	"This we may, in all propriety do. But in a larger sense, we",
-	"cannot dedicate, we cannot consecrate, we cannot hallow this",
-	"ground. The brave men, living and dead who struggled here",
-	"have hallowed it far above our poor power to add or detract.",
-	"The world will little note nor long remember what we say here,",
-	"but it can never forget what they did here.",
-	"",
-	"It is rather for us the living, we here be dedicated to the",
-	"great task remaining before us--that from these honored",
-	"dead we take increased devotion to that cause for which they",
-	"here gave the last full measure of devotion--that we here",
-	"highly resolve that these dead shall not have died in vain, that",
-	"this nation shall have a new birth of freedom, and that",
-	"government of the people, by the people, for the people shall",
-	"not perish from the earth.",
-	0
-    };
-    const char **l;
-    twin_path_t	*path;
-    
-    twin_window_set_name(text, name);
-    path = twin_path_create ();
-    twin_path_translate (path, 
-			 twin_int_to_fixed (text->client.left),
-			 twin_int_to_fixed (text->client.top));
-#define TEXT_SIZE   10
-    twin_path_set_font_size (path, D(TEXT_SIZE));
-    fx = D(3);
-    fy = D(10);
-    twin_fill (text->pixmap, 0xc0c0c0c0, TWIN_SOURCE,
-	       text->client.left, text->client.top,
-	       text->client.right, text->client.bottom);
-    for (l = lines; *l; l++) 
-    {
-	twin_path_move (path, fx, fy);
-	twin_path_utf8 (path, *l);
-	twin_paint_path (text->pixmap, 0xff000000, path);
-	twin_path_empty (path);
-	fy += D(TEXT_SIZE);
-    }
-    twin_window_show (text);
-}
-
-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;
-
-static void *
-twin_app_thread (void *closure)
-{
-    twin_app_args_t *a = closure;
-
-    (*a->func) (a->screen, a->name, 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, 
-		const char *name,
-		int x, int y, int w, int h)
-{
-    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, const char *name, int x, int y, int w, int h)
-{
-    ++napp;
-    twin_start_app (twin_clock, screen, name, x, y, w, h);
-}
-
-int styles[] = {
-    TWIN_TEXT_ROMAN,
-    TWIN_TEXT_OBLIQUE,
-    TWIN_TEXT_BOLD,
-    TWIN_TEXT_BOLD|TWIN_TEXT_OBLIQUE
-};
+#include <twin_clock.h>
+#include <twin_text.h>
+#include <twin_demo.h>
 
 #define WIDTH	512
 #define HEIGHT	512
@@ -357,368 +39,14 @@
 int
 main (int argc, char **argv)
 {
-    Status	    status = XInitThreads ();
     Display	    *dpy = XOpenDisplay (0);
     twin_x11_t	    *x11 = twin_x11_create (dpy, WIDTH, HEIGHT);
-    twin_pixmap_t   *red = twin_pixmap_create (TWIN_ARGB32, WIDTH, HEIGHT);
-    twin_pixmap_t   *blue = twin_pixmap_create (TWIN_ARGB32, 100, 100);
-    twin_pixmap_t   *alpha = twin_pixmap_create (TWIN_A8, WIDTH, HEIGHT);
-    twin_operand_t  source, mask;
-    twin_path_t	    *path;
-    XEvent	    ev, motion;
-    twin_bool_t	    had_motion;
-    int		    x, y;
-    twin_path_t	    *pen;
-    twin_path_t	    *stroke;
-    twin_path_t	    *extra;
-    int		    s;
-    twin_fixed_t    fx, fy;
-    int		    g;
 
     twin_screen_set_background (x11->screen, twin_make_pattern ());
-    (void) ev;
-    (void) motion;
-    (void) had_motion;
-    (void) x;
-    (void) y;
-    (void) red;
-    (void) blue;
-    (void) status;
-    (void) alpha;
-    (void) source;
-    (void) mask;
-    (void) source;
-    (void) path;
-    
-    extra = 0;
-    stroke = 0;
-    pen = 0;
-    s = 0;
-    fx = 0;
-    fy = 0;
-    g = 0 ;
-
-#if 0
-    pen = twin_path_create ();
-    twin_path_circle (pen, D (1));
-    
-    path = twin_path_create ();
-#if 0
-    twin_path_move (path, D(3), D(0));
-    for (g = 0; g < 4326; g++)
-    {
-	int glyph = g;
-	if (!twin_has_glyph (glyph)) glyph = 0;
-	twin_path_cur_point (path, &fx, &fy);
-	if (fx + twin_glyph_width (glyph, D(10)) >= D(WIDTH) || g % 50 == 0)
-	    twin_path_move (path, D(3), fy + D(10));
-	twin_path_glyph (path, D(10), D(10), TWIN_TEXT_ROMAN,
-			 glyph);
-    }
-#endif
-#if 0
-    stroke = twin_path_create ();
-    twin_path_move (stroke, D(30), D(400));
-    twin_path_set_font_size (stroke, D(100));
-    twin_path_utf8 (stroke, "jelly HEzt/[].");
-    twin_path_convolve (path, stroke, pen);
-/*    twin_path_append (path, stroke); */
-    twin_path_destroy (stroke);
-    stroke = twin_path_create ();
-    twin_path_move (stroke, D(30), D(400));
-    twin_path_draw (stroke, D(1000), D(400));
-    twin_path_convolve (path, stroke, pen);
-#endif
-    
-#if 0
-    stroke = twin_path_create ();
-    pen = twin_path_create ();
-    twin_path_translate (stroke, D(100), D(100));
-/*    twin_path_rotate (stroke, twin_degrees_to_angle (270)); */
-    twin_path_rotate (stroke, twin_degrees_to_angle (270));
-    twin_path_move (stroke, D(0), D(0));
-    twin_path_draw (stroke, D(100), D(0));
-    twin_path_set_matrix (pen, twin_path_current_matrix (stroke));
-    twin_path_circle (pen, D(20));
-    twin_path_convolve (path, stroke, pen);
-#endif
-    
-#if 0
-    stroke = twin_path_create ();
-    twin_path_translate (stroke, D(250), D(250));
-    twin_path_circle (stroke, 0x42aaa);
-    extra = twin_path_convex_hull (stroke);
-    twin_path_convolve (path, extra, pen);
-#endif
-    
-#if 0
-    {
-	twin_state_t	state = twin_path_save (path);
-    twin_path_translate (path, D(300), D(300));
-    twin_path_set_font_size (path, D(15));
-    for (s = 0; s < 41; s++)
-    {
-	twin_state_t	state = twin_path_save (path);
-	twin_path_rotate (path, twin_degrees_to_angle (9 * s));
-	twin_path_move (path, D(100), D(0));
-	twin_path_utf8 (path, "Hello, world!");
-	twin_path_restore (path, &state);
-    }
-	twin_path_restore (path, &state);
-    }
-#endif
-#if 1
-    fx = D(15);
-    fy = 0;
-    twin_path_translate (path, 0, D(HEIGHT));
-    twin_path_rotate (path, -twin_degrees_to_angle (90));
-    twin_path_scale (path, D(1), D(0.5));
-    twin_path_set_font_style (path, TWIN_TEXT_OBLIQUE);
-    for (g = 40; g <= 60; g += 4)
-    {
-        twin_path_set_font_size (path, D(g));
-#if 0
-        fy += D(g+2);
-	twin_path_move (path, fx, fy);
-	twin_path_utf8 (path, "H");
-#endif
-#if 0
-        fy += D(g+2);
-	twin_path_move (path, fx, fy);
-	twin_path_utf8 (path,
-			  " !\"#$%&'()*+,-./0123456789:;<=>?");
-        fy += D(g+2);
-	twin_path_move (path, fx, fy);
-	twin_path_utf8 (path,
-			  "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_");
-        fy += D(g+2);
-	twin_path_move (path, fx, fy);
-	twin_path_utf8 (path,
-			  "`abcdefghijklmnopqrstuvwxyz{|}~");
-#endif
-#if 0
-	for (s = 0; s < 4; s++)
-	{
-	    fy += D(g+2);
-	    twin_path_move (path, fx, fy);
-	    twin_path_set_font_style (path, styles[s]);
-	    twin_path_utf8 (path,
-			    "the quick brown fox jumps over the lazy dog.");
-	    twin_path_utf8 (path,
-			    "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.");
-	}
-#endif
-#if 1
-	fy += D(g + 2);
-	twin_path_move (path, fx, fy);
-#define TEXT	"jelly HEzt/[]."
-/*	twin_path_set_font_style (path, TWIN_TEXT_UNHINTED); */
-	twin_path_utf8 (path, TEXT);
-	{
-	    twin_text_metrics_t	m;
-	    
-	    stroke = twin_path_create ();
-	    twin_path_set_matrix (stroke, twin_path_current_matrix (path));
-	    twin_text_metrics_utf8 (path, TEXT, &m);
-	    twin_path_translate (stroke, TWIN_FIXED_HALF, TWIN_FIXED_HALF);
-	    twin_path_move (stroke, fx, fy);
-	    twin_path_draw (stroke, fx + m.width, fy);
-	    twin_paint_stroke (red, 0xffff0000, stroke, D(1));
-	    twin_path_empty (stroke);
-	    twin_path_move (stroke, 
-			    fx + m.left_side_bearing, fy - m.ascent);
-	    twin_path_draw (stroke,
-			    fx + m.right_side_bearing, fy - m.ascent);
-	    twin_path_draw (stroke,
-			    fx + m.right_side_bearing, fy + m.descent);
-	    twin_path_draw (stroke,
-			    fx + m.left_side_bearing, fy + m.descent);
-	    twin_path_draw (stroke, 
-			    fx + m.left_side_bearing, fy - m.ascent);
-	    twin_paint_stroke (red, 0xff00ff00, stroke, D(1));
-	}
-#endif
-    }
-#endif
-#if 0
-    fx = D(3);
-    fy = D(8);
-    for (g = 6; g < 36; g++)
-    {
-	twin_path_move (path, fx, fy);
-	twin_path_set_font_size (path, D(g));
-	twin_path_utf8 (path,
-			"the quick brown fox jumps over the lazy dog.");
-	twin_path_utf8 (path,
-			"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.");
-	fy += D(g);
-    }
-#endif
-    twin_fill_path (alpha, path, 0, 0);
-    
-    twin_path_destroy (path);
-    
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xff000000;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    WIDTH, HEIGHT);
-
-#if 0
-    path = twin_path_create ();
-
-    twin_path_rotate (path, -TWIN_ANGLE_45);
-    twin_path_translate (path, D(10), D(2));
-    for (s = 0; s < 40; s++)
-    {
-	twin_path_rotate (path, TWIN_ANGLE_11_25 / 16);
-	twin_path_scale (path, D(1.125), D(1.125));
-	twin_path_move (path, D(0), D(0));
-	twin_path_draw (path, D(1), D(0));
-	twin_path_draw (path, D(1), D(1));
-	twin_path_draw (path, D(0), D(1));
-    }
-    
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
-    twin_fill_path (alpha, path);
-    
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xffff0000;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    WIDTH, HEIGHT);
-#endif
-
-#if 0
-    path = twin_path_create ();
-    stroke = twin_path_create ();
-
-    twin_path_translate (stroke, D(62), D(62));
-    twin_path_scale (stroke,D(60),D(60));
-    for (s = 0; s < 60; s++)
-    {
-        twin_state_t    save = twin_path_save (stroke);
-	twin_angle_t    a = s * TWIN_ANGLE_90 / 15;
-	    
-	twin_path_rotate (stroke, a);
-        twin_path_move (stroke, D(1), 0);
-	if (s % 5 == 0)
-	    twin_path_draw (stroke, D(0.85), 0);
-	else
-	    twin_path_draw (stroke, D(.98), 0);
-        twin_path_restore (stroke, &save);
-    }
-    twin_path_convolve (path, stroke, pen);
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
-    twin_fill_path (alpha, path);
-    
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xffff0000;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    WIDTH, HEIGHT);
-#endif
-
-#if 0
-    path = twin_path_create ();
-    stroke = twin_path_create ();
-
-    twin_path_translate (stroke, D(100), D(100));
-    twin_path_scale (stroke, D(10), D(10));
-    twin_path_move (stroke, D(0), D(0));
-    twin_path_draw (stroke, D(10), D(0));
-    twin_path_convolve (path, stroke, pen);
-    
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
-    twin_fill_path (alpha, path);
-    
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xffff0000;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    WIDTH, HEIGHT);
-#endif
-    
-#if 0
-    path = twin_path_create ();
-
-    stroke = twin_path_create ();
-    
-    twin_path_move (stroke, D (10), D (40));
-    twin_path_draw (stroke, D (40), D (40));
-    twin_path_draw (stroke, D (10), D (10));
-    twin_path_move (stroke, D (10), D (50));
-    twin_path_draw (stroke, D (40), D (50));
-
-    twin_path_convolve (path, stroke, pen);
-    twin_path_destroy (stroke);
-
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-    twin_fill_path (alpha, path);
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xff00ff00;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (blue, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    100, 100);
-    
-    twin_path_destroy (path);
-
-    path = twin_path_create ();
-    stroke = twin_path_create ();
-
-    twin_path_move (stroke, D (50), D (50));
-    twin_path_curve (stroke, D (70), D (70), D (80), D (70), D (100), D (50));
-
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-    twin_fill_path (alpha, stroke);
-    
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xffff0000;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (blue, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    100, 100);
-    
-    twin_path_convolve (path, stroke, pen);
-    
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-    twin_fill_path (alpha, path);
-
-    source.source_kind = TWIN_SOLID;
-    source.u.argb = 0xff0000ff;
-    mask.source_kind = TWIN_PIXMAP;
-    mask.u.pixmap = alpha;
-    twin_composite (blue, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    100, 100);
-#endif
-
-    twin_pixmap_move (red, 0, 0);
-    twin_pixmap_move (blue, 100, 100);
-    twin_pixmap_show (red, x11->screen, 0);
-    twin_pixmap_show (blue, x11->screen, 0);
-    ++napp;
-#endif
-
-    if (!napp)
-	twin_start_clock (x11->screen, "Clock", 10, 10, 200, 200);
-#if 0
-    twin_start_clock (x11->screen, "Large clock", 0, 100, 256, 256);
-#endif
-#if 1
-    twin_start_app (twin_text_app, x11->screen, "Gettysburg Address",
-		    100, 100, 318, 250);
-#endif
-#if 0
-    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 (napp)
-	sleep (1);
+    twin_demo_start (x11->screen, "Demo", 100, 100, 400, 400);
+    twin_clock_start (x11->screen, "Clock", 10, 10, 200, 200);
+    twin_text_start (x11->screen,  "Gettysburg Address",
+		     0, 0, 300, 300);
+    twin_dispatch ();
     return 0;
 }




More information about the Commit mailing list