summaryrefslogtreecommitdiff
path: root/twin_demos
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2006-11-29 19:38:10 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-11-29 19:51:28 +1100
commitd575e2b4fd8249e0ae584b0b6401ff6b8dd7d2c4 (patch)
tree440cfbf14d2dce9c374296a3d078e0ce523b5207 /twin_demos
parent2f714ca431d6e592c91d55f2c5619afdb4a3b8a1 (diff)
Move demo applications to twin_demos subdirectory
This change moves the twin demo applications to a new subdirectory (twin_demos), and updates the auto{conf,make} setup to suit. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'twin_demos')
-rw-r--r--twin_demos/Makefile.am13
-rw-r--r--twin_demos/twin_calc.c239
-rw-r--r--twin_demos/twin_calc.h32
-rw-r--r--twin_demos/twin_clock.c270
-rw-r--r--twin_demos/twin_clock.h49
-rw-r--r--twin_demos/twin_demo.c453
-rw-r--r--twin_demos/twin_demo.h30
-rw-r--r--twin_demos/twin_demoline.c154
-rw-r--r--twin_demos/twin_demoline.h52
-rw-r--r--twin_demos/twin_demospline.c166
-rw-r--r--twin_demos/twin_demospline.h54
-rw-r--r--twin_demos/twin_hello.c72
-rw-r--r--twin_demos/twin_hello.h30
-rw-r--r--twin_demos/twin_text.c83
-rw-r--r--twin_demos/twin_text.h30
15 files changed, 1727 insertions, 0 deletions
diff --git a/twin_demos/Makefile.am b/twin_demos/Makefile.am
new file mode 100644
index 0000000..b4020c9
--- /dev/null
+++ b/twin_demos/Makefile.am
@@ -0,0 +1,13 @@
+
+noinst_LIBRARIES = libtwin_demos.a
+
+libtwin_demos_a_CFLAGS = @WARN_CFLAGS@
+libtwin_demos_a_CPPFLAGS = -I$(top_srcdir)
+libtwin_demos_a_SOURCES = twin_calc.c twin_calc.h \
+ twin_clock.c twin_clock.h \
+ twin_demo.c twin_demo.h \
+ twin_demoline.c twin_demoline.h \
+ twin_demospline.c twin_demospline.h \
+ twin_hello.c twin_hello.h \
+ twin_text.c twin_text.h
+
diff --git a/twin_demos/twin_calc.c b/twin_demos/twin_calc.c
new file mode 100644
index 0000000..6b49621
--- /dev/null
+++ b/twin_demos/twin_calc.c
@@ -0,0 +1,239 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "twin_calc.h"
+#include <stdio.h>
+
+#define TWIN_CALC_STACK 5
+#define TWIN_CALC_ZERO 0
+#define TWIN_CALC_ONE 1
+#define TWIN_CALC_TWO 2
+#define TWIN_CALC_THREE 3
+#define TWIN_CALC_FOUR 4
+#define TWIN_CALC_FIVE 5
+#define TWIN_CALC_SIX 6
+#define TWIN_CALC_SEVEN 7
+#define TWIN_CALC_EIGHT 8
+#define TWIN_CALC_NINE 9
+#define TWIN_CALC_PLUS 10
+#define TWIN_CALC_MINUS 11
+#define TWIN_CALC_TIMES 12
+#define TWIN_CALC_DIVIDE 13
+#define TWIN_CALC_EQUAL 14
+#define TWIN_CALC_CLEAR 15
+#define TWIN_CALC_NBUTTON 16
+
+/*
+ * Layout:
+ *
+ * display
+ *
+ * 7 8 9 +
+ * 4 5 6 -
+ * 1 2 3 *
+ * 0 clr = ÷
+ */
+#define TWIN_CALC_COLS 4
+#define TWIN_CALC_ROWS 4
+
+const static int calc_layout[TWIN_CALC_ROWS][TWIN_CALC_COLS] = {
+ { TWIN_CALC_SEVEN, TWIN_CALC_EIGHT, TWIN_CALC_NINE, TWIN_CALC_PLUS },
+ { TWIN_CALC_FOUR, TWIN_CALC_FIVE, TWIN_CALC_SIX, TWIN_CALC_MINUS },
+ { TWIN_CALC_ONE, TWIN_CALC_TWO, TWIN_CALC_THREE, TWIN_CALC_TIMES },
+ { TWIN_CALC_ZERO, TWIN_CALC_CLEAR, TWIN_CALC_EQUAL, TWIN_CALC_DIVIDE },
+};
+
+typedef struct _twin_calc {
+ int stack[TWIN_CALC_STACK];
+ int pending_op;
+ twin_bool_t pending_delete;
+ twin_window_t *window;
+ twin_toplevel_t *toplevel;
+ twin_box_t *keys;
+ twin_box_t *cols[4];
+ twin_label_t *display;
+ twin_button_t *buttons[TWIN_CALC_NBUTTON];
+} twin_calc_t;
+
+static const char *twin_calc_labels[] = {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "+", "-", "*", "/", "=", "CLR"
+};
+
+#define TWIN_CALC_VALUE_SIZE twin_int_to_fixed(29)
+#define TWIN_CALC_VALUE_STYLE TWIN_TEXT_ROMAN
+#define TWIN_CALC_VALUE_FG 0xff000000
+#define TWIN_CALC_VALUE_BG 0x80808080
+#define TWIN_CALC_BUTTON_SIZE twin_int_to_fixed(15)
+#define TWIN_CALC_BUTTON_STYLE TWIN_TEXT_BOLD
+#define TWIN_CALC_BUTTON_FG 0xff000000
+#define TWIN_CALC_BUTTON_BG 0xc0808080
+
+static int
+_twin_calc_button_to_id (twin_calc_t *calc, twin_button_t *button)
+{
+ int i;
+
+ for (i = 0; i < TWIN_CALC_NBUTTON; i++)
+ if (calc->buttons[i] == button)
+ return i;
+ return -1;
+}
+
+static void
+_twin_calc_update_value (twin_calc_t *calc)
+{
+ char v[20];
+
+ sprintf (v, "%d", calc->stack[0]);
+ twin_label_set (calc->display, v, TWIN_CALC_VALUE_FG,
+ TWIN_CALC_VALUE_SIZE, TWIN_CALC_VALUE_STYLE);
+}
+
+static void
+_twin_calc_push (twin_calc_t *calc)
+{
+ int i;
+
+ for (i = 0; i < TWIN_CALC_STACK - 1; i++)
+ calc->stack[i+1] = calc->stack[i];
+ calc->pending_delete = TWIN_TRUE;
+}
+
+static int
+_twin_calc_pop (twin_calc_t *calc)
+{
+ int i;
+ int v = calc->stack[0];
+ for (i = 0; i < TWIN_CALC_STACK - 1; i++)
+ calc->stack[i] = calc->stack[i+1];
+ return v;
+}
+
+static void
+_twin_calc_digit (twin_calc_t *calc, int digit)
+{
+ if (calc->pending_delete)
+ {
+ calc->stack[0] = 0;
+ calc->pending_delete = TWIN_FALSE;
+ }
+ calc->stack[0] = calc->stack[0] * 10 + digit;
+ _twin_calc_update_value (calc);
+}
+
+static void
+_twin_calc_button_signal (twin_button_t *button,
+ twin_button_signal_t signal,
+ void *closure)
+{
+ twin_calc_t *calc = closure;
+ int i;
+ int a, b;
+
+ if (signal != TwinButtonSignalDown) return;
+ i = _twin_calc_button_to_id (calc, button);
+ if (i < 0) return;
+ switch (i) {
+ case TWIN_CALC_PLUS:
+ case TWIN_CALC_MINUS:
+ case TWIN_CALC_TIMES:
+ case TWIN_CALC_DIVIDE:
+ calc->pending_op = i;
+ _twin_calc_push (calc);
+ break;
+ case TWIN_CALC_EQUAL:
+ if (calc->pending_op != 0)
+ {
+ b = _twin_calc_pop (calc);
+ a = _twin_calc_pop (calc);
+ switch (calc->pending_op) {
+ case TWIN_CALC_PLUS: a = a + b; break;
+ case TWIN_CALC_MINUS: a = a - b; break;
+ case TWIN_CALC_TIMES: a = a * b; break;
+ case TWIN_CALC_DIVIDE: if (!b) a = 0; else a = a / b; break;
+ }
+ _twin_calc_push (calc);
+ calc->stack[0] = a;
+ _twin_calc_update_value (calc);
+ calc->pending_op = 0;
+ }
+ calc->pending_delete = TWIN_TRUE;
+ break;
+ case TWIN_CALC_CLEAR:
+ for (i = 0; i < TWIN_CALC_STACK; i++)
+ calc->stack[i] = 0;
+ calc->pending_op = 0;
+ calc->pending_delete = TWIN_TRUE;
+ _twin_calc_update_value (calc);
+ break;
+ default:
+ _twin_calc_digit (calc, i);
+ break;
+ }
+}
+
+void
+twin_calc_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+ twin_calc_t *calc = malloc (sizeof (twin_calc_t));
+ int i, j;
+
+ calc->toplevel = twin_toplevel_create (screen,
+ TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h, name);
+ calc->display = twin_label_create (&calc->toplevel->box,
+ "0",
+ TWIN_CALC_VALUE_FG,
+ TWIN_CALC_VALUE_SIZE,
+ TWIN_CALC_VALUE_STYLE);
+ twin_widget_set (&calc->display->widget, TWIN_CALC_VALUE_BG);
+ calc->display->align = TwinAlignRight;
+ calc->display->widget.shape = TwinShapeLozenge;
+ calc->keys = twin_box_create (&calc->toplevel->box, TwinBoxHorz);
+ for (i = 0; i < TWIN_CALC_COLS; i++)
+ {
+ calc->cols[i] = twin_box_create (calc->keys, TwinBoxVert);
+ for (j = 0; j < TWIN_CALC_ROWS; j++)
+ {
+ int b = calc_layout[j][i];
+ calc->buttons[b] = twin_button_create (calc->cols[i],
+ twin_calc_labels[b],
+ TWIN_CALC_BUTTON_FG,
+ TWIN_CALC_BUTTON_SIZE,
+ TWIN_CALC_BUTTON_STYLE);
+ twin_widget_set (&calc->buttons[b]->label.widget,
+ TWIN_CALC_BUTTON_BG);
+ calc->buttons[b]->signal = _twin_calc_button_signal;
+ calc->buttons[b]->closure = calc;
+/* calc->buttons[b]->label.widget.shape = TwinShapeLozenge; */
+ if (i || j)
+ calc->buttons[b]->label.widget.copy_geom = &calc->buttons[calc_layout[0][0]]->label.widget;
+ }
+ }
+
+ for (i = 0; i < TWIN_CALC_STACK; i++)
+ calc->stack[i] = 0;
+ calc->pending_delete = TWIN_TRUE;
+ calc->pending_op = 0;
+ twin_toplevel_show (calc->toplevel);
+}
diff --git a/twin_demos/twin_calc.h b/twin_demos/twin_calc.h
new file mode 100644
index 0000000..6fbb2f1
--- /dev/null
+++ b/twin_demos/twin_calc.h
@@ -0,0 +1,32 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <twin.h>
+
+#ifndef _TWIN_CALC_H_
+#define _TWIN_CALC_H_
+
+#include <twin.h>
+
+void
+twin_calc_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_CALC_H_ */
diff --git a/twin_demos/twin_clock.c b/twin_demos/twin_clock.c
new file mode 100644
index 0000000..039ae05
--- /dev/null
+++ b/twin_demos/twin_clock.c
@@ -0,0 +1,270 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <twin_clock.h>
+#include <twinint.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.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)
+
+#define _twin_clock_pixmap(clock) ((clock)->widget.window->pixmap)
+
+static void
+twin_clock_set_transform (twin_clock_t *clock,
+ twin_path_t *path)
+{
+ twin_fixed_t scale;
+
+ scale = (TWIN_FIXED_ONE - TWIN_CLOCK_BORDER_WIDTH * 3) / 2;
+ twin_path_scale (path, _twin_widget_width (clock) * scale,
+ _twin_widget_height (clock) * 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_clock_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, 0, 0, fill_width);
+ twin_path_convolve (path, stroke, pen);
+
+ twin_paint_path (_twin_clock_pixmap(clock), fill_pixel, path);
+
+ twin_paint_stroke (_twin_clock_pixmap(clock), 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_clock_t *clock)
+{
+ twin_path_t *path = twin_path_create ();
+ int m;
+
+ twin_clock_set_transform (clock, path);
+
+ twin_path_circle (path, 0, 0, TWIN_FIXED_ONE);
+
+ twin_paint_path (_twin_clock_pixmap(clock), TWIN_CLOCK_BACKGROUND, path);
+
+ twin_paint_stroke (_twin_clock_pixmap(clock), TWIN_CLOCK_BORDER, path, TWIN_CLOCK_BORDER_WIDTH);
+
+ {
+ twin_state_t state = twin_path_save (path);
+ twin_text_metrics_t metrics;
+ twin_fixed_t height, 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 (_twin_clock_pixmap(clock), 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 (_twin_clock_pixmap(clock), TWIN_CLOCK_WATER, path);
+ twin_path_restore (path, &state);
+ }
+
+ twin_path_set_font_size (path, D(0.2));
+ twin_path_set_font_style (path, TWIN_TEXT_UNHINTED);
+
+ for (m = 1; m <= 60; m++)
+ {
+ twin_state_t state = twin_path_save (path);
+ 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 (_twin_clock_pixmap(clock), 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 (_twin_clock_pixmap(clock), TWIN_CLOCK_NUMBERS, path);
+ }
+ twin_path_restore (path, &state);
+ }
+
+ twin_path_destroy (path);
+}
+
+static twin_time_t
+_twin_clock_interval (void)
+{
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ return 1000 - (tv.tv_usec / 1000);
+}
+
+void
+_twin_clock_paint (twin_clock_t *clock)
+{
+ struct timeval tv;
+ twin_angle_t second_angle, minute_angle, hour_angle;
+ struct tm t;
+
+ gettimeofday (&tv, NULL);
+
+ localtime_r(&tv.tv_sec, &t);
+
+ _twin_clock_face (clock);
+
+ 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);
+}
+
+static twin_time_t
+_twin_clock_timeout (twin_time_t now, void *closure)
+{
+ twin_clock_t *clock = closure;
+ _twin_widget_queue_paint (&clock->widget);
+ return _twin_clock_interval ();
+}
+
+twin_dispatch_result_t
+_twin_clock_dispatch (twin_widget_t *widget, twin_event_t *event)
+{
+ twin_clock_t *clock = (twin_clock_t *) widget;
+
+ if (_twin_widget_dispatch (widget, event) == TwinDispatchDone)
+ return TwinDispatchDone;
+ switch (event->kind) {
+ case TwinEventPaint:
+ _twin_clock_paint (clock);
+ break;
+ default:
+ break;
+ }
+ return TwinDispatchContinue;
+}
+
+void
+_twin_clock_init (twin_clock_t *clock,
+ twin_box_t *parent,
+ twin_dispatch_proc_t dispatch)
+{
+ static const twin_widget_layout_t preferred = { 0, 0, 1, 1 };
+ _twin_widget_init (&clock->widget, parent, 0, preferred, dispatch);
+ clock->timeout = twin_set_timeout (_twin_clock_timeout,
+ _twin_clock_interval(),
+ clock);
+}
+
+twin_clock_t *
+twin_clock_create (twin_box_t *parent)
+{
+ twin_clock_t *clock = malloc (sizeof (twin_clock_t));
+
+ _twin_clock_init(clock, parent, _twin_clock_dispatch);
+ return clock;
+}
+
+void
+twin_clock_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+ twin_toplevel_t *toplevel = twin_toplevel_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h, name);
+ twin_clock_t *clock = twin_clock_create (&toplevel->box);
+ (void) clock;
+ twin_toplevel_show (toplevel);
+}
diff --git a/twin_demos/twin_clock.h b/twin_demos/twin_clock.h
new file mode 100644
index 0000000..2259c29
--- /dev/null
+++ b/twin_demos/twin_clock.h
@@ -0,0 +1,49 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TWIN_CLOCK_H_
+#define _TWIN_CLOCK_H_
+
+#include <twin.h>
+
+typedef struct _twin_clock {
+ twin_widget_t widget;
+ twin_timeout_t *timeout;
+} twin_clock_t;
+
+void
+_twin_clock_paint (twin_clock_t *clock);
+
+twin_dispatch_result_t
+_twin_clock_dispatch (twin_widget_t *widget, twin_event_t *event);
+
+void
+_twin_clock_init (twin_clock_t *clock,
+ twin_box_t *parent,
+ twin_dispatch_proc_t dispatch);
+
+twin_clock_t *
+twin_clock_create (twin_box_t *parent);
+
+void
+twin_clock_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_CLOCK_H_ */
diff --git a/twin_demos/twin_demo.c b/twin_demos/twin_demo.c
new file mode 100644
index 0000000..f93e9f4
--- /dev/null
+++ b/twin_demos/twin_demo.c
@@ -0,0 +1,453 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <twin_demo.h>
+
+#define D(x) twin_double_to_fixed(x)
+
+#if 0
+static int styles[] = {
+ TWIN_TEXT_ROMAN,
+ TWIN_TEXT_OBLIQUE,
+ TWIN_TEXT_BOLD,
+ TWIN_TEXT_BOLD|TWIN_TEXT_OBLIQUE
+};
+#endif
+
+#if 0
+static void
+twin_example_start (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ twin_window_t *window = twin_window_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h);
+ int wid = window->client.right - window->client.left;
+ int hei = window->client.bottom - window->client.top;
+ twin_pixmap_t *pixmap = window->pixmap;
+ twin_path_t *path = twin_path_create ();
+ twin_path_t *pen = twin_path_create ();
+ twin_pixmap_t *alpha = twin_pixmap_create (TWIN_A8, w, h);
+ twin_operand_t source, mask;
+
+ twin_fill (pixmap, 0xffffffff, TWIN_SOURCE, 0, 0, wid, hei);
+
+ twin_window_set_name (window, "example");
+
+ twin_path_circle (pen, D (1));
+
+ /* graphics here in path */
+
+ twin_fill_path (alpha, path, 0, 0);
+ twin_path_destroy (path);
+ twin_path_destroy (pen);
+ source.source_kind = TWIN_SOLID;
+ source.u.argb = 0xff000000;
+ mask.source_kind = TWIN_PIXMAP;
+ mask.u.pixmap = alpha;
+ twin_composite (pixmap, 0, 0,
+ &source, 0, 0, &mask, 0, 0, TWIN_OVER, w, h);
+ twin_pixmap_destroy (alpha);
+ twin_window_show (window);
+}
+#endif
+
+static void
+twin_line_start (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ twin_window_t *window = twin_window_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h);
+ twin_pixmap_t *pixmap = window->pixmap;
+ twin_path_t *stroke = twin_path_create ();
+ twin_fixed_t fy;
+
+ twin_path_translate (stroke, D(200), D(200));
+ twin_fill (pixmap, 0xffffffff, TWIN_SOURCE,
+ 0, 0, w, h);
+
+ twin_window_set_name (window, "line");
+
+ for (fy = 0; fy < 150; fy += 40)
+ {
+ twin_path_move (stroke, D(-150), -D(fy));
+ twin_path_draw (stroke, D(150), D(fy));
+ }
+ twin_path_set_cap_style (stroke, TwinCapProjecting);
+ twin_paint_stroke (pixmap, 0xff000000, stroke, D(10));
+ twin_path_destroy (stroke);
+ twin_window_show (window);
+}
+
+static void
+twin_circletext_start (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ twin_window_t *window = twin_window_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h);
+ int wid = window->client.right - window->client.left;
+ int hei = window->client.bottom - window->client.top;
+ twin_pixmap_t *pixmap = window->pixmap;
+ twin_path_t *path = twin_path_create ();
+ twin_path_t *pen = twin_path_create ();
+ twin_pixmap_t *alpha = twin_pixmap_create (TWIN_A8, wid, hei);
+ int s;
+ twin_operand_t source, mask;
+
+ twin_fill (pixmap, 0xffffffff, TWIN_SOURCE,
+ 0, 0, wid, hei);
+ twin_window_set_name (window, "circletext");
+
+ twin_path_set_font_style (path, TWIN_TEXT_UNHINTED);
+ twin_path_circle (pen, 0, 0, D (1));
+
+ twin_path_translate (path, D(200), D(200));
+ 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_fill_path (alpha, path, 0, 0);
+ twin_path_destroy (path);
+ twin_path_destroy (pen);
+ source.source_kind = TWIN_SOLID;
+ source.u.argb = 0xff000000;
+ mask.source_kind = TWIN_PIXMAP;
+ mask.u.pixmap = alpha;
+ twin_composite (pixmap, 0, 0,
+ &source, 0, 0, &mask, 0, 0, TWIN_OVER, wid, hei);
+ twin_pixmap_destroy (alpha);
+ twin_window_show (window);
+}
+
+static void
+twin_quickbrown_start (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ twin_window_t *window = twin_window_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h);
+ int wid = window->client.right - window->client.left;
+ int hei = window->client.bottom - window->client.top;
+ twin_pixmap_t *pixmap = window->pixmap;
+ twin_path_t *path = twin_path_create ();
+ twin_path_t *pen = twin_path_create ();
+ twin_pixmap_t *alpha = twin_pixmap_create (TWIN_A8, wid, hei);
+ twin_operand_t source, mask;
+ twin_fixed_t fx, fy;
+ int s;
+
+ twin_window_set_name (window, "Quick Brown");
+
+ twin_fill (pixmap, 0xffffffff, TWIN_SOURCE,
+ 0, 0, wid, hei);
+
+ twin_path_circle (pen, 0, 0, D (1));
+
+ fx = D(3);
+ fy = D(8);
+ for (s = 6; s < 36; s++)
+ {
+ twin_path_move (path, fx, fy);
+ twin_path_set_font_size (path, D(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.");
+ fy += D(s);
+ }
+
+ twin_fill_path (alpha, path, 0, 0);
+ twin_path_destroy (path);
+ twin_path_destroy (pen);
+ source.source_kind = TWIN_SOLID;
+ source.u.argb = 0xff000000;
+ mask.source_kind = TWIN_PIXMAP;
+ mask.u.pixmap = alpha;
+ twin_composite (pixmap, 0, 0,
+ &source, 0, 0, &mask, 0, 0, TWIN_OVER, wid, hei);
+ twin_pixmap_destroy (alpha);
+ twin_window_show (window);
+}
+
+static void
+twin_ascii_start (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ twin_window_t *window = twin_window_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h);
+ int wid = window->client.right - window->client.left;
+ int hei = window->client.bottom - window->client.top;
+ twin_pixmap_t *pixmap = window->pixmap;
+ twin_path_t *path = twin_path_create ();
+ twin_path_t *pen = twin_path_create ();
+ twin_pixmap_t *alpha = twin_pixmap_create (TWIN_A8, wid, hei);
+ twin_operand_t source, mask;
+ twin_fixed_t fx, fy;
+ int s;
+
+ twin_window_set_name (window, "ASCII");
+
+ twin_fill (pixmap, 0xffffffff, TWIN_SOURCE, 0, 0, wid, hei);
+ twin_path_circle (pen, 0, 0, D (1));
+
+ fx = D(3);
+ fy = D(8);
+ for (s = 6; s < 36; s += 6)
+ {
+ twin_path_set_font_size (path, D(s));
+ fy += D(s+2);
+ twin_path_move (path, fx, fy);
+ twin_path_utf8 (path,
+ " !\"#$%&'()*+,-./0123456789:;<=>?");
+ fy += D(s+2);
+ twin_path_move (path, fx, fy);
+ twin_path_utf8 (path,
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_");
+ fy += D(s+2);
+ twin_path_move (path, fx, fy);
+ twin_path_utf8 (path,
+ "`abcdefghijklmnopqrstuvwxyz{|}~");
+ fy += D(s+2);
+ }
+
+ twin_fill_path (alpha, path, 0, 0);
+ twin_path_destroy (path);
+ twin_path_destroy (pen);
+ source.source_kind = TWIN_SOLID;
+ source.u.argb = 0xff000000;
+ mask.source_kind = TWIN_PIXMAP;
+ mask.u.pixmap = alpha;
+ twin_composite (pixmap, 0, 0,
+ &source, 0, 0, &mask, 0, 0, TWIN_OVER, wid, hei);
+ twin_pixmap_destroy (alpha);
+ twin_window_show (window);
+}
+
+static void
+twin_jelly_start (twin_screen_t *screen, int x, int y, int w, int h)
+{
+ twin_window_t *window = twin_window_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h);
+ int wid = window->client.right - window->client.left;
+ int hei = window->client.bottom - window->client.top;
+ twin_pixmap_t *pixmap = window->pixmap;
+ twin_path_t *path = twin_path_create ();
+ twin_fixed_t fx, fy;
+ int s;
+
+ twin_window_set_name (window, "Jelly");
+
+ twin_fill (pixmap, 0xffffffff, TWIN_SOURCE,
+ 0, 0, wid, hei);
+
+ fx = D(3);
+ fy = D(8);
+ for (s = 6; s < 36; s += 2)
+ {
+ twin_path_set_font_size (path, D(s));
+ fy += D(s + 2);
+ twin_path_move (path, fx, fy);
+#define TEXT "jelly text"
+/* twin_path_set_font_style (path, TWIN_TEXT_UNHINTED); */
+ twin_path_utf8 (path, TEXT);
+ twin_paint_path (pixmap, 0xff000000, path);
+ twin_path_empty (path);
+ {
+ twin_text_metrics_t m;
+ twin_path_t *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 (pixmap, 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 (pixmap, 0xff00ff00, stroke, D(1));
+ twin_path_destroy (stroke);
+ }
+ }
+ twin_window_show (window);
+}
+
+void
+twin_demo_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+#if 0
+ twin_circletext_start (screen, x, y, w, h);
+#endif
+ twin_line_start (screen, x += 20, y += 20, w, h);
+#if 0
+ twin_quickbrown_start (screen, x += 20, y += 20, w, h);
+ twin_ascii_start (screen, x += 20, y += 20, w, h);
+ twin_jelly_start (screen, x += 20, y += 20, w, h);
+#endif
+#if 0
+
+#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, w, h);
+ 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,
+ w, h);
+#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, w, h);
+ 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,
+ w, h);
+#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, w, h);
+ 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,
+ w, h);
+#endif
+
+#if 1
+ 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, w, h);
+ twin_fill_path (alpha, path, 0, 0);
+ 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, w, h);
+ twin_fill_path (alpha, stroke, 0, 0);
+
+ 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, w, h);
+ twin_fill_path (alpha, path, 0, 0);
+
+ 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_window_show (redw);
+ twin_window_show (bluew);
+#endif
+}
diff --git a/twin_demos/twin_demo.h b/twin_demos/twin_demo.h
new file mode 100644
index 0000000..ee4d03c
--- /dev/null
+++ b/twin_demos/twin_demo.h
@@ -0,0 +1,30 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TWIN_DEMO_H_
+#define _TWIN_DEMO_H_
+
+#include <twin.h>
+
+void
+twin_demo_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_DEMO_H_ */
diff --git a/twin_demos/twin_demoline.c b/twin_demos/twin_demoline.c
new file mode 100644
index 0000000..245caa7
--- /dev/null
+++ b/twin_demos/twin_demoline.c
@@ -0,0 +1,154 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <twin_demoline.h>
+#include <twinint.h>
+#include <stdio.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)
+
+#define _twin_demoline_pixmap(demoline) ((demoline)->widget.window->pixmap)
+
+void
+_twin_demoline_paint (twin_demoline_t *demoline)
+{
+ twin_path_t *path;
+
+ path = twin_path_create ();
+ twin_path_set_cap_style (path, demoline->cap_style);
+ twin_path_move (path, demoline->points[0].x, demoline->points[0].y);
+ twin_path_draw (path, demoline->points[1].x, demoline->points[1].y);
+ twin_paint_stroke (_twin_demoline_pixmap(demoline), 0xff000000, path,
+ demoline->line_width);
+ twin_path_set_cap_style (path, TwinCapButt);
+ twin_paint_stroke (_twin_demoline_pixmap(demoline), 0xffff0000, path,
+ twin_int_to_fixed (2));
+ twin_path_destroy (path);
+}
+
+static twin_dispatch_result_t
+_twin_demoline_update_pos (twin_demoline_t *demoline, twin_event_t *event)
+{
+ if (demoline->which < 0)
+ return TwinDispatchContinue;
+ demoline->points[demoline->which].x = twin_int_to_fixed (event->u.pointer.x);
+ demoline->points[demoline->which].y = twin_int_to_fixed (event->u.pointer.y);
+ _twin_widget_queue_paint (&demoline->widget);
+ return TwinDispatchDone;
+}
+
+#define twin_fixed_abs(f) ((f) < 0 ? -(f) : (f))
+
+static int
+_twin_demoline_hit (twin_demoline_t *demoline, twin_fixed_t x, twin_fixed_t y)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ if (twin_fixed_abs (x - demoline->points[i].x) < demoline->line_width / 2 &&
+ twin_fixed_abs (y - demoline->points[i].y) < demoline->line_width / 2)
+ return i;
+ return -1;
+}
+
+twin_dispatch_result_t
+_twin_demoline_dispatch (twin_widget_t *widget, twin_event_t *event)
+{
+ twin_demoline_t *demoline = (twin_demoline_t *) widget;
+
+ if (_twin_widget_dispatch (widget, event) == TwinDispatchDone)
+ return TwinDispatchDone;
+ switch (event->kind) {
+ case TwinEventPaint:
+ _twin_demoline_paint (demoline);
+ break;
+ case TwinEventButtonDown:
+ demoline->which = _twin_demoline_hit (demoline,
+ twin_int_to_fixed (event->u.pointer.x),
+ twin_int_to_fixed (event->u.pointer.y));
+ return _twin_demoline_update_pos (demoline, event);
+ break;
+ case TwinEventMotion:
+ return _twin_demoline_update_pos (demoline, event);
+ break;
+ case TwinEventButtonUp:
+ if (demoline->which < 0)
+ return TwinDispatchContinue;
+ _twin_demoline_update_pos (demoline, event);
+ demoline->which = -1;
+ return TwinDispatchDone;
+ break;
+ default:
+ break;
+ }
+ return TwinDispatchContinue;
+}
+
+void
+_twin_demoline_init (twin_demoline_t *demoline,
+ twin_box_t *parent,
+ twin_dispatch_proc_t dispatch)
+{
+ static const twin_widget_layout_t preferred = { 0, 0, 1, 1 };
+ _twin_widget_init (&demoline->widget, parent, 0, preferred, dispatch);
+ twin_widget_set (&demoline->widget, 0xffffffff);
+ demoline->line_width = twin_int_to_fixed (30);
+ demoline->cap_style = TwinCapProjecting;
+ demoline->points[0].x = twin_int_to_fixed (50);
+ demoline->points[0].y = twin_int_to_fixed (50);
+ demoline->points[1].x = twin_int_to_fixed (100);
+ demoline->points[1].y = twin_int_to_fixed (100);
+}
+
+twin_demoline_t *
+twin_demoline_create (twin_box_t *parent)
+{
+ twin_demoline_t *demoline = malloc (sizeof (twin_demoline_t));
+
+ _twin_demoline_init(demoline, parent, _twin_demoline_dispatch);
+ return demoline;
+}
+
+void
+twin_demoline_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+ twin_toplevel_t *toplevel = twin_toplevel_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h, name);
+ twin_demoline_t *demoline = twin_demoline_create (&toplevel->box);
+ (void) demoline;
+ twin_toplevel_show (toplevel);
+}
diff --git a/twin_demos/twin_demoline.h b/twin_demos/twin_demoline.h
new file mode 100644
index 0000000..10dee67
--- /dev/null
+++ b/twin_demos/twin_demoline.h
@@ -0,0 +1,52 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TWIN_DEMOLINE_H_
+#define _TWIN_DEMOLINE_H_
+
+#include <twin.h>
+
+typedef struct _twin_demoline {
+ twin_widget_t widget;
+ twin_point_t points[2];
+ int which;
+ twin_fixed_t line_width;
+ twin_cap_t cap_style;
+} twin_demoline_t;
+
+void
+_twin_demoline_paint (twin_demoline_t *demoline);
+
+twin_dispatch_result_t
+_twin_demoline_dispatch (twin_widget_t *widget, twin_event_t *event);
+
+void
+_twin_demoline_init (twin_demoline_t *demoline,
+ twin_box_t *parent,
+ twin_dispatch_proc_t dispatch);
+
+twin_demoline_t *
+twin_demoline_create (twin_box_t *parent);
+
+void
+twin_demoline_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_DEMOLINE_H_ */
diff --git a/twin_demos/twin_demospline.c b/twin_demos/twin_demospline.c
new file mode 100644
index 0000000..d425fab
--- /dev/null
+++ b/twin_demos/twin_demospline.c
@@ -0,0 +1,166 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <twin_demospline.h>
+#include <twinint.h>
+#include <stdio.h>
+
+#define D(x) twin_double_to_fixed(x)
+
+#define _twin_demospline_pixmap(demospline) ((demospline)->widget.window->pixmap)
+
+void
+_twin_demospline_paint (twin_demospline_t *demospline)
+{
+ twin_path_t *path;
+ int i;
+
+ path = twin_path_create ();
+ twin_path_set_cap_style (path, demospline->cap_style);
+ twin_path_move (path, demospline->points[0].x, demospline->points[0].y);
+ twin_path_curve (path,
+ demospline->points[1].x, demospline->points[1].y,
+ demospline->points[2].x, demospline->points[2].y,
+ demospline->points[3].x, demospline->points[3].y);
+ twin_paint_stroke (_twin_demospline_pixmap(demospline), 0xff404040, path,
+ demospline->line_width);
+ twin_path_set_cap_style (path, TwinCapButt);
+ twin_paint_stroke (_twin_demospline_pixmap(demospline), 0xffffff00, path,
+ twin_int_to_fixed (2));
+
+ twin_path_empty (path);
+ twin_path_move (path, demospline->points[0].x, demospline->points[0].y);
+ twin_path_draw (path, demospline->points[1].x, demospline->points[1].y);
+ twin_paint_stroke (_twin_demospline_pixmap(demospline), 0xc08000c0, path,
+ twin_int_to_fixed (2));
+ twin_path_empty (path);
+ twin_path_move (path, demospline->points[3].x, demospline->points[3].y);
+ twin_path_draw (path, demospline->points[2].x, demospline->points[2].y);
+ twin_paint_stroke (_twin_demospline_pixmap(demospline), 0xc08000c0, path,
+ twin_int_to_fixed (2));
+ twin_path_empty (path);
+ for (i = 0; i < NPT; i++)
+ {
+ twin_path_empty (path);
+ twin_path_circle (path, demospline->points[i].x, demospline->points[i].y,
+ twin_int_to_fixed (10));
+ twin_paint_path (_twin_demospline_pixmap(demospline), 0x40004020, path);
+ }
+ twin_path_destroy (path);
+}
+
+static twin_dispatch_result_t
+_twin_demospline_update_pos (twin_demospline_t *demospline, twin_event_t *event)
+{
+ if (demospline->which < 0)
+ return TwinDispatchContinue;
+ demospline->points[demospline->which].x = twin_int_to_fixed (event->u.pointer.x);
+ demospline->points[demospline->which].y = twin_int_to_fixed (event->u.pointer.y);
+ _twin_widget_queue_paint (&demospline->widget);
+ return TwinDispatchDone;
+}
+
+#define twin_fixed_abs(f) ((f) < 0 ? -(f) : (f))
+
+static int
+_twin_demospline_hit (twin_demospline_t *demospline, twin_fixed_t x, twin_fixed_t y)
+{
+ int i;
+
+ for (i = 0; i < NPT; i++)
+ if (twin_fixed_abs (x - demospline->points[i].x) < demospline->line_width / 2 &&
+ twin_fixed_abs (y - demospline->points[i].y) < demospline->line_width / 2)
+ return i;
+ return -1;
+}
+
+twin_dispatch_result_t
+_twin_demospline_dispatch (twin_widget_t *widget, twin_event_t *event)
+{
+ twin_demospline_t *demospline = (twin_demospline_t *) widget;
+
+ if (_twin_widget_dispatch (widget, event) == TwinDispatchDone)
+ return TwinDispatchDone;
+ switch (event->kind) {
+ case TwinEventPaint:
+ _twin_demospline_paint (demospline);
+ break;
+ case TwinEventButtonDown:
+ demospline->which = _twin_demospline_hit (demospline,
+ twin_int_to_fixed (event->u.pointer.x),
+ twin_int_to_fixed (event->u.pointer.y));
+ return _twin_demospline_update_pos (demospline, event);
+ break;
+ case TwinEventMotion:
+ return _twin_demospline_update_pos (demospline, event);
+ break;
+ case TwinEventButtonUp:
+ if (demospline->which < 0)
+ return TwinDispatchContinue;
+ _twin_demospline_update_pos (demospline, event);
+ demospline->which = -1;
+ return TwinDispatchDone;
+ break;
+ default:
+ break;
+ }
+ return TwinDispatchContinue;
+}
+
+void
+_twin_demospline_init (twin_demospline_t *demospline,
+ twin_box_t *parent,
+ twin_dispatch_proc_t dispatch)
+{
+ static const twin_widget_layout_t preferred = { 0, 0, 1, 1 };
+ _twin_widget_init (&demospline->widget, parent, 0, preferred, dispatch);
+ twin_widget_set (&demospline->widget, 0xffffffff);
+ demospline->line_width = twin_int_to_fixed (100);
+ demospline->cap_style = TwinCapButt;
+ demospline->points[0].x = twin_int_to_fixed (100);
+ demospline->points[0].y = twin_int_to_fixed (100);
+ demospline->points[1].x = twin_int_to_fixed (300);
+ demospline->points[1].y = twin_int_to_fixed (300);
+ demospline->points[2].x = twin_int_to_fixed (100);
+ demospline->points[2].y = twin_int_to_fixed (300);
+ demospline->points[3].x = twin_int_to_fixed (300);
+ demospline->points[3].y = twin_int_to_fixed (100);
+}
+
+twin_demospline_t *
+twin_demospline_create (twin_box_t *parent)
+{
+ twin_demospline_t *demospline = malloc (sizeof (twin_demospline_t));
+
+ _twin_demospline_init(demospline, parent, _twin_demospline_dispatch);
+ return demospline;
+}
+
+void
+twin_demospline_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+ twin_toplevel_t *toplevel = twin_toplevel_create (screen, TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h, name);
+ twin_demospline_t *demospline = twin_demospline_create (&toplevel->box);
+ (void) demospline;
+ twin_toplevel_show (toplevel);
+}
diff --git a/twin_demos/twin_demospline.h b/twin_demos/twin_demospline.h
new file mode 100644
index 0000000..8b72455
--- /dev/null
+++ b/twin_demos/twin_demospline.h
@@ -0,0 +1,54 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TWIN_DEMOSPLINE_H_
+#define _TWIN_DEMOSPLINE_H_
+
+#include <twin.h>
+
+#define NPT 4
+
+typedef struct _twin_demospline {
+ twin_widget_t widget;
+ twin_point_t points[NPT];
+ int which;
+ twin_fixed_t line_width;
+ twin_cap_t cap_style;
+} twin_demospline_t;
+
+void
+_twin_demospline_paint (twin_demospline_t *demospline);
+
+twin_dispatch_result_t
+_twin_demospline_dispatch (twin_widget_t *widget, twin_event_t *event);
+
+void
+_twin_demospline_init (twin_demospline_t *demospline,
+ twin_box_t *parent,
+ twin_dispatch_proc_t dispatch);
+
+twin_demospline_t *
+twin_demospline_create (twin_box_t *parent);
+
+void
+twin_demospline_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_DEMOLINE_H_ */
diff --git a/twin_demos/twin_hello.c b/twin_demos/twin_hello.c
new file mode 100644
index 0000000..09cff8d
--- /dev/null
+++ b/twin_demos/twin_hello.c
@@ -0,0 +1,72 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "twin_hello.h"
+#include <time.h>
+#include <string.h>
+
+static twin_time_t
+_twin_hello_timeout (twin_time_t now, void *closure)
+{
+ twin_label_t *labelb = closure;
+ time_t secs = time (0);
+ char *t = ctime(&secs);
+
+ *strchr(t, '\n') = '\0';
+ twin_label_set (labelb, t,
+ 0xff008000,
+ twin_int_to_fixed (12),
+ TWIN_TEXT_OBLIQUE);
+ return 1000;
+}
+
+void
+twin_hello_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+ twin_toplevel_t *top = twin_toplevel_create (screen,
+ TWIN_ARGB32,
+ TwinWindowApplication,
+ x, y, w, h, name);
+ twin_label_t *labela = twin_label_create (&top->box,
+ name,
+ 0xff000080,
+ twin_int_to_fixed (12),
+ TWIN_TEXT_ROMAN);
+ twin_widget_t *widget = twin_widget_create (&top->box,
+ 0xff800000,
+ 1, 2, 0, 0);
+ twin_label_t *labelb = twin_label_create (&top->box,
+ name,
+ 0xff008000,
+ twin_int_to_fixed (12),
+ TWIN_TEXT_OBLIQUE);
+ twin_button_t *button = twin_button_create (&top->box,
+ "Button",
+ 0xff800000,
+ twin_int_to_fixed (18),
+ TWIN_TEXT_BOLD|TWIN_TEXT_OBLIQUE);
+ twin_widget_set (&labela->widget, 0xc0c0c0c0);
+ (void) widget;
+ twin_widget_set (&labelb->widget, 0xc0c0c0c0);
+ twin_widget_set (&button->label.widget, 0xc0808080);
+ twin_toplevel_show (top);
+ twin_set_timeout (_twin_hello_timeout, 1000, labelb);
+}
diff --git a/twin_demos/twin_hello.h b/twin_demos/twin_hello.h
new file mode 100644
index 0000000..a4b92aa
--- /dev/null
+++ b/twin_demos/twin_hello.h
@@ -0,0 +1,30 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TWIN_HELLO_H_
+#define _TWIN_HELLO_H_
+
+#include <twin.h>
+
+void
+twin_hello_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_HELLO_H_ */
diff --git a/twin_demos/twin_text.c b/twin_demos/twin_text.c
new file mode 100644
index 0000000..93efdb4
--- /dev/null
+++ b/twin_demos/twin_text.c
@@ -0,0 +1,83 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <twin_text.h>
+
+#define D(x) twin_double_to_fixed(x)
+
+void
+twin_text_start (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,
+ TwinWindowApplication,
+ 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 ();
+#define TEXT_SIZE 9
+ twin_path_set_font_size (path, D(TEXT_SIZE));
+ fx = D(3);
+ fy = D(10);
+ twin_fill (text->pixmap, 0xc0c0c0c0, TWIN_SOURCE,
+ 0, 0,
+ text->client.right - text->client.left,
+ text->client.bottom - text->client.top);
+ 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);
+}
+
diff --git a/twin_demos/twin_text.h b/twin_demos/twin_text.h
new file mode 100644
index 0000000..fe9c482
--- /dev/null
+++ b/twin_demos/twin_text.h
@@ -0,0 +1,30 @@
+/*
+ * Twin - A Tiny Window System
+ * Copyright © 2004 Keith Packard <keithp@keithp.com>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Twin Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TWIN_TEXT_H_
+#define _TWIN_TEXT_H_
+
+#include <twin.h>
+
+void
+twin_text_start (twin_screen_t *screen, const char *name, int x, int y, int w, int h);
+
+#endif /* _TWIN_TEXT_H_ */