[Commit] twin ChangeLog, 1.18, 1.19 Makefile.am, 1.7, 1.8 twin.h, 1.13, 1.14 twin_draw.c, 1.5, 1.6 twin_path.c, 1.10, 1.11 twin_pixmap.c, 1.3, 1.4 twin_screen.c, 1.5, 1.6 twin_thread.c, NONE, 1.1 twin_window.c, NONE, 1.1 twin_x11.c, 1.5, 1.6 twin_x11.h, 1.2, 1.3 xtwin.c, 1.17, 1.18

Keith Packard commit at keithp.com
Tue Oct 5 17:11:30 PDT 2004


Committed by: keithp

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

Modified Files:
	ChangeLog Makefile.am twin.h twin_draw.c twin_path.c 
	twin_pixmap.c twin_screen.c twin_x11.c twin_x11.h xtwin.c 
Added Files:
	twin_thread.c twin_window.c 
Log Message:
2004-10-05  Keith Packard  <keithp at 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.


Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/twin/ChangeLog,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- ChangeLog	5 Oct 2004 18:42:53 -0000	1.18
+++ ChangeLog	6 Oct 2004 00:11:27 -0000	1.19
@@ -1,5 +1,37 @@
 2004-10-05  Keith Packard  <keithp at 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 at keithp.com>
+
 	* twin.h:
 	* twin_draw.c: (twin_composite), (twin_fill):
 	* twin_matrix.c: (twin_matrix_multiply), (twin_matrix_translate),

Index: Makefile.am
===================================================================
RCS file: /local/src/CVS/twin/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.am	30 Sep 2004 17:23:07 -0000	1.7
+++ Makefile.am	6 Oct 2004 00:11:27 -0000	1.8
@@ -30,7 +30,9 @@
 	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

Index: twin.h
===================================================================
RCS file: /local/src/CVS/twin/twin.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- twin.h	5 Oct 2004 18:42:53 -0000	1.13
+++ twin.h	6 Oct 2004 00:11:27 -0000	1.14
@@ -44,6 +44,19 @@
 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 @@
     twin_argb32_t   *argb32;
 } twin_pointer_t;
 
+typedef struct _twin_window twin_window_t;
+
 /*
  * A rectangular array of pixels
  */
@@ -92,7 +107,7 @@
     /*
      * List of displayed pixmaps
      */
-    struct _twin_pixmap		*higher;
+    struct _twin_pixmap		*down, *up;
     /*
      * Screen position
      */
@@ -108,20 +123,25 @@
      * 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 @@
     /*
      * 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 @@
     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 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 @@
     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 @@
     } 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 @@
 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_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 @@
 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_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_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_ */

Index: twin_draw.c
===================================================================
RCS file: /local/src/CVS/twin/twin_draw.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- twin_draw.c	5 Oct 2004 18:42:53 -0000	1.5
+++ twin_draw.c	6 Oct 2004 00:11:27 -0000	1.6
@@ -370,32 +370,28 @@
 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);
 }

Index: twin_path.c
===================================================================
RCS file: /local/src/CVS/twin/twin_path.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- twin_path.c	5 Oct 2004 18:42:53 -0000	1.10
+++ twin_path.c	6 Oct 2004 00:11:27 -0000	1.11
@@ -443,7 +443,6 @@
 			       
     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;

Index: twin_pixmap.c
===================================================================
RCS file: /local/src/CVS/twin/twin_pixmap.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- twin_pixmap.c	5 Oct 2004 18:42:53 -0000	1.3
+++ twin_pixmap.c	6 Oct 2004 00:11:27 -0000	1.4
@@ -30,12 +30,14 @@
 		    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 @@
     pixmap->stride = stride;
     pixmap->disable = 0;
     pixmap->p.v = pixmap + 1;
+    memset (pixmap->p.v, '\0', space);
     return pixmap;
 }
 
@@ -59,23 +62,36 @@
 		  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 @@
 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_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;
+}
+

Index: twin_screen.c
===================================================================
RCS file: /local/src/CVS/twin/twin_screen.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- twin_screen.c	5 Oct 2004 18:42:53 -0000	1.5
+++ twin_screen.c	6 Oct 2004 00:11:27 -0000	1.6
@@ -34,6 +34,7 @@
     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 @@
     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 @@
     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 @@
 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;
+}

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

--- NEW FILE: twin_window.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.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- twin_x11.c	5 Oct 2004 18:42:53 -0000	1.5
+++ twin_x11.c	6 Oct 2004 00:11:27 -0000	1.6
@@ -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 @@
 }
 
 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_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 @@
 	    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 @@
 	    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_t	*tx = closure;
 
-    pthread_cond_broadcast (&tx->damage_cond);
+    twin_cond_broadcast (&tx->damage_cond);
 }
 
 twin_x11_t *
@@ -187,11 +204,11 @@
 
     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 @@
 {
     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);
 }
 

Index: twin_x11.h
===================================================================
RCS file: /local/src/CVS/twin/twin_x11.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- twin_x11.h	2 Oct 2004 03:07:26 -0000	1.2
+++ twin_x11.h	6 Oct 2004 00:11:27 -0000	1.3
@@ -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 @@
     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;
 
 /*

Index: xtwin.c
===================================================================
RCS file: /local/src/CVS/twin/xtwin.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- xtwin.c	5 Oct 2004 18:42:53 -0000	1.17
+++ xtwin.c	6 Oct 2004 00:11:27 -0000	1.18
@@ -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_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 @@
 }
 
 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_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_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_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 @@
 	    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 @@
 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_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_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 @@
     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_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 @@
 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 @@
     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 @@
     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 @@
 #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);




More information about the Commit mailing list