aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2004-10-06 06:40:57 +0000
committerKeith Packard <keithp@keithp.com>2004-10-06 06:40:57 +0000
commitc905d1c40ad88707f549a56e631c4eaff756378b (patch)
treed0fb88cc0092666bece5f2516888ab29d58378b9
parentdc7477b9826f7cb6e95d591698daaf5251e65bf4 (diff)
downloadlibtwin-c905d1c40ad88707f549a56e631c4eaff756378b.tar.gz
Add patterns.
Add screen backgrounds Eliminate spurious border bits Add text display applet
-rw-r--r--ChangeLog20
-rw-r--r--Makefile.am1
-rw-r--r--twin.h44
-rw-r--r--twin_pattern.c41
-rw-r--r--twin_pixmap.c23
-rw-r--r--twin_screen.c41
-rw-r--r--twin_window.c104
-rw-r--r--xtwin.c81
8 files changed, 308 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 67d0388..f9340d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,26 @@
* Makefile.am:
* twin.h:
+ * twin_pattern.c: (twin_make_pattern):
+ * twin_pixmap.c: (twin_pixmap_create_const):
+ Add patterns.
+
+ * twin_screen.c: (twin_screen_create), (twin_screen_update),
+ (twin_screen_set_background), (twin_screen_get_background):
+ Add screen backgrounds
+
+ * twin_window.c: (twin_window_create), (twin_window_style_size),
+ (twin_window_frame), (twin_window_draw):
+ Eliminate spurious border bits
+
+ * xtwin.c: (twin_clock), (twin_text_app), (twin_start_clock),
+ (main):
+ Add text display applet
+
+2004-10-05 Keith Packard <keithp@keithp.com>
+
+ * Makefile.am:
+ * twin.h:
* twin_draw.c: (twin_fill):
* twin_path.c: (twin_composite_path):
* twin_pixmap.c: (twin_pixmap_create), (twin_pixmap_show),
diff --git a/Makefile.am b/Makefile.am
index 999deae..af5f217 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,6 +25,7 @@ xtwin_SOURCES = \
twin_geom.c \
twin_matrix.c \
twin_path.c \
+ twin_pattern.c \
twin_pixmap.c \
twin_poly.c \
twin_primitive.c \
diff --git a/twin.h b/twin.h
index a9e956f..4cf2848 100644
--- a/twin.h
+++ b/twin.h
@@ -166,6 +166,10 @@ typedef struct _twin_screen {
*/
twin_coord_t width, height;
/*
+ * Background pattern
+ */
+ twin_pixmap_t *background;
+ /*
* Damage
*/
twin_rect_t damage;
@@ -289,6 +293,9 @@ typedef struct _twin_event_queue {
typedef enum _twin_window_style {
WindowPlain,
WindowApplication,
+ WindowFullScreen,
+ WindowDialog,
+ WindowAlert,
} twin_window_style_t;
typedef void (*twin_draw_func_t) (twin_window_t *window);
@@ -313,6 +320,17 @@ struct _twin_window {
};
/*
+ * Icons
+ */
+
+typedef enum _twin_icon {
+ TwinIconMenu,
+ TwinIconMinimize,
+ TwinIconMaximize,
+ TwinIconClose,
+} twin_icon_t;
+
+/*
* Widgets
*/
@@ -431,6 +449,13 @@ twin_path_t *
twin_path_convex_hull (twin_path_t *path);
/*
+ * twin_icon.c
+ */
+
+void
+twin_icon_draw (twin_pixmap_t *pixmap, twin_icon_t icon, twin_matrix_t matrix);
+
+/*
* twin_matrix.c
*/
@@ -556,6 +581,12 @@ twin_paint_stroke (twin_pixmap_t *dst,
twin_fixed_t pen_width);
/*
+ * twin_pattern.c
+ */
+twin_pixmap_t *
+twin_make_pattern (void);
+
+/*
* twin_pixmap.c
*/
@@ -564,6 +595,13 @@ twin_pixmap_create (twin_format_t format,
twin_coord_t width,
twin_coord_t height);
+twin_pixmap_t *
+twin_pixmap_create_const (twin_format_t format,
+ twin_coord_t width,
+ twin_coord_t height,
+ twin_coord_t stride,
+ twin_pointer_t pixels);
+
void
twin_pixmap_destroy (twin_pixmap_t *pixmap);
@@ -657,6 +695,12 @@ twin_screen_set_active (twin_screen_t *screen, twin_pixmap_t *pixmap);
twin_pixmap_t *
twin_screen_get_active (twin_screen_t *screen);
+void
+twin_screen_set_background (twin_screen_t *screen, twin_pixmap_t *pixmap);
+
+twin_pixmap_t *
+twin_screen_get_background (twin_screen_t *screen);
+
twin_bool_t
twin_screen_dispatch (twin_screen_t *screen,
twin_event_t *event);
diff --git a/twin_pattern.c b/twin_pattern.c
new file mode 100644
index 0000000..3ba43cf
--- /dev/null
+++ b/twin_pattern.c
@@ -0,0 +1,41 @@
+/* GIMP RGBA C-Source image dump (cork.c) */
+
+#include "twinint.h"
+
+static const struct {
+ unsigned int width;
+ unsigned int height;
+ unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
+ char *comment;
+ unsigned char pixel_data[8 * 8 * 4];
+} cork_image = {
+ 8, 8, 4,
+ "cork",
+ "{\265\357\377\214\275\357\377{\265\357\377{\265\357\377\214\275\357\377{\265"
+ "\336\377{\265\357\377\234\316\377\377{\265\357\377Z\214\316\377{\265\357\377"
+ "k\234\336\377Z\214\326\377Z\224\336\377{\265\357\377{\265\336\377\214\275"
+ "\357\377Z\214\326\377{\265\357\377\214\275\357\377{\255\336\377{\265\357\377"
+ "{\265\336\377{\255\357\377{\265\336\377{\265\357\377Z\214\316\377{\263\353"
+ "\377{\265\357\377\234\316\377\377{\265\357\377{\265\336\377\214\275\357\377{"
+ "\255\336\377{\265\357\377{\265\336\377{\265\357\377k\245\357\377\234\316\377"
+ "\377{\265\357\377{\265\336\377\214\306\377\377{\255\336\377k\245\357\377{"
+ "\265\336\377{\265\357\377\234\316\377\377Z\214\316\377Z\214\326\377{\265\357"
+ "\377k\245\357\377{\265\336\377\214\275\357\377{\255\357\377\214\275\357\377a"
+ "\223\321\377\207\270\354\377[\215\326\377{\265\357\377Z\214\316\377\214\306"
+ "\377\377{\255\336\377{\255\357\377Z\224"
+ "\336\377"
+};
+
+twin_pixmap_t *
+twin_make_pattern (void)
+{
+ twin_pointer_t pixels;
+
+ pixels.v = (void *) cork_image.pixel_data;
+
+ return twin_pixmap_create_const (TWIN_ARGB32,
+ cork_image.width,
+ cork_image.height,
+ cork_image.width * cork_image.bytes_per_pixel,
+ pixels);
+}
diff --git a/twin_pixmap.c b/twin_pixmap.c
index ad0abe5..74704b7 100644
--- a/twin_pixmap.c
+++ b/twin_pixmap.c
@@ -49,6 +49,29 @@ twin_pixmap_create (twin_format_t format,
return pixmap;
}
+twin_pixmap_t *
+twin_pixmap_create_const (twin_format_t format,
+ twin_coord_t width,
+ twin_coord_t height,
+ twin_coord_t stride,
+ twin_pointer_t pixels)
+{
+ twin_pixmap_t *pixmap = malloc (sizeof (twin_pixmap_t));
+ if (!pixmap)
+ return 0;
+ pixmap->screen = 0;
+ pixmap->up = 0;
+ pixmap->down = 0;
+ pixmap->x = pixmap->y = 0;
+ pixmap->format = format;
+ pixmap->width = width;
+ pixmap->height = height;
+ pixmap->stride = stride;
+ pixmap->disable = 0;
+ pixmap->p = pixels;
+ return pixmap;
+}
+
void
twin_pixmap_destroy (twin_pixmap_t *pixmap)
{
diff --git a/twin_screen.c b/twin_screen.c
index bb031e3..8a6f8b8 100644
--- a/twin_screen.c
+++ b/twin_screen.c
@@ -43,6 +43,7 @@ twin_screen_create (twin_coord_t width,
screen->damaged = NULL;
screen->damaged_closure = NULL;
screen->disable = 0;
+ screen->background = 0;
twin_mutex_init (&screen->screen_mutex);
screen->put_begin = put_begin;
screen->put_span = put_span;
@@ -172,7 +173,30 @@ twin_screen_update (twin_screen_t *screen)
(*screen->put_begin) (left, top, right, bottom, screen->closure);
for (y = top; y < bottom; y++)
{
- memset (span, 0xff, width * sizeof (twin_argb32_t));
+ if (screen->background)
+ {
+ twin_pointer_t dst;
+ twin_source_u src;
+ twin_coord_t p_left;
+ twin_coord_t m_left;
+ twin_coord_t p_this;
+ twin_coord_t p_width = screen->background->width;
+ twin_coord_t p_y = y % screen->background->height;
+
+ for (p_left = left; p_left < right; p_left += p_this)
+ {
+ dst.argb32 = span + (p_left - left);
+ m_left = p_left % p_width;
+ p_this = p_width - m_left;
+ if (p_left + p_this > right)
+ p_this = right - p_left;
+ src.p = twin_pixmap_pointer (screen->background,
+ m_left, p_y);
+ _twin_argb32_source_argb32 (dst, src, p_this);
+ }
+ }
+ else
+ memset (span, 0xff, width * sizeof (twin_argb32_t));
for (p = screen->bottom; p; p = p->up)
{
twin_pointer_t dst;
@@ -230,6 +254,21 @@ twin_screen_get_active (twin_screen_t *screen)
return screen->active;
}
+void
+twin_screen_set_background (twin_screen_t *screen, twin_pixmap_t *pixmap)
+{
+ if (screen->background)
+ twin_pixmap_destroy (screen->background);
+ screen->background = pixmap;
+ twin_screen_damage (screen, 0, 0, screen->width, screen->height);
+}
+
+twin_pixmap_t *
+twin_screen_get_background (twin_screen_t *screen)
+{
+ return screen->background;
+}
+
twin_bool_t
twin_screen_dispatch (twin_screen_t *screen,
twin_event_t *event)
diff --git a/twin_window.c b/twin_window.c
index 6071877..b348572 100644
--- a/twin_window.c
+++ b/twin_window.c
@@ -24,12 +24,12 @@
#include "twinint.h"
-#define TWIN_ACTIVE_BG 0xff3b80ae
+#define TWIN_ACTIVE_BG 0xd03b80ae
#define TWIN_INACTIVE_BG 0xff808080
#define TWIN_FRAME_TEXT 0xffffffff
-#define TWIN_ACTIVE_BORDER 0xff000000
-#define TWIN_BW 3
-#define TWIN_TITLE_HEIGHT 18
+#define TWIN_ACTIVE_BORDER 0xff606060
+#define TWIN_BW 0
+#define TWIN_TITLE_HEIGHT 22
twin_window_t *
twin_window_create (twin_screen_t *screen,
@@ -41,17 +41,35 @@ twin_window_create (twin_screen_t *screen,
twin_coord_t height)
{
twin_window_t *window = malloc (sizeof (twin_window_t));
+ twin_coord_t left, right, top, bottom;
if (!window) return NULL;
window->screen = screen;
+ window->style = style;
+ switch (window->style) {
+ case WindowApplication:
+ left = TWIN_BW;
+ top = TWIN_BW + TWIN_TITLE_HEIGHT + TWIN_BW;
+ right = TWIN_BW;
+ bottom = TWIN_BW;
+ break;
+ case WindowPlain:
+ default:
+ left = 0;
+ top = 0;
+ right = 0;
+ bottom = 0;
+ break;
+ }
+ width += left + right;
+ height += top + bottom;
+ window->client.left = left;
+ window->client.right = width - right;
+ window->client.top = top;
+ window->client.bottom = height - bottom;
window->pixmap = twin_pixmap_create (format, width, height);
window->pixmap->window = window;
twin_pixmap_move (window->pixmap, x, y);
- window->style = style;
- window->client.left = TWIN_BW;
- window->client.top = TWIN_BW + TWIN_TITLE_HEIGHT + TWIN_BW;
- window->client.right = width - TWIN_BW;
- window->client.bottom = height - TWIN_BW;
window->damage.left = window->damage.right = 0;
window->damage.top = window->damage.bottom = 0;
window->client_data = 0;
@@ -128,6 +146,7 @@ twin_window_style_size (twin_window_style_t style,
{
switch (style) {
case WindowPlain:
+ default:
size->left = size->right = size->top = size->bottom = 0;
break;
case WindowApplication:
@@ -152,54 +171,62 @@ twin_window_set_name (twin_window_t *window,
static void
twin_window_frame (twin_window_t *window)
{
- twin_coord_t bw = window->client.left;
+ twin_coord_t bw = 2;
twin_path_t *path;
twin_coord_t name_height;
twin_text_metrics_t m;
twin_pixmap_t *pixmap = window->pixmap;
+ twin_fixed_t bw_2 = twin_int_to_fixed (bw) / 2;
+ twin_fixed_t w_top = bw_2;
+ twin_fixed_t c_left = bw_2;
+ twin_fixed_t t_h = twin_int_to_fixed (window->client.top - bw);
+ twin_fixed_t t_arc_1 = t_h / 3;
+ twin_fixed_t c_right = twin_int_to_fixed (pixmap->width) - bw_2;
+ twin_fixed_t c_top = twin_int_to_fixed (window->client.top) - bw_2;
+
+ twin_fill (pixmap, 0x00000000, TWIN_SOURCE,
+ 0, 0, pixmap->width, window->client.top);
/* border */
- twin_fill (pixmap, TWIN_ACTIVE_BORDER,
- TWIN_SOURCE,
- 0, 0, pixmap->width, bw);
- twin_fill (pixmap, TWIN_ACTIVE_BORDER,
- TWIN_SOURCE,
- 0, bw, bw, pixmap->height - bw);
- twin_fill (pixmap, TWIN_ACTIVE_BORDER,
- TWIN_SOURCE,
- window->client.right, bw, pixmap->width, pixmap->height - bw);
- twin_fill (pixmap, TWIN_ACTIVE_BORDER,
- TWIN_SOURCE,
- window->client.left, window->client.top - bw,
- window->client.right, window->client.top);
- twin_fill (pixmap, TWIN_ACTIVE_BORDER,
- TWIN_SOURCE,
- 0, window->client.bottom,
- pixmap->width, pixmap->height);
+ path = twin_path_create ();
+ twin_path_move (path, c_left, c_top);
+ twin_path_draw (path, c_right, c_top);
+ twin_path_curve (path,
+ c_right, w_top + t_arc_1,
+ c_right - t_arc_1, w_top,
+ c_right - t_h, w_top);
+ twin_path_draw (path, c_left + t_h, w_top);
+ twin_path_curve (path,
+ c_left + t_arc_1, w_top,
+ c_left, w_top + t_arc_1,
+ c_left, c_top);
+ twin_path_close (path);
+
+ twin_paint_path (pixmap, TWIN_ACTIVE_BG, path);
+
+ twin_paint_stroke (pixmap, TWIN_ACTIVE_BORDER, path, bw_2 * 2);
+
+ twin_path_empty (path);
- /* name background */
- twin_fill (pixmap, TWIN_ACTIVE_BG,
- TWIN_SOURCE,
- bw, bw, pixmap->width - bw, window->client.top - bw);
-
/* name */
if (window->name)
{
- path = twin_path_create ();
- name_height = window->client.top - bw * 4;
+ twin_point_t t;
+ name_height = window->client.top - bw * 2;
if (name_height < 1)
name_height = 1;
- twin_path_translate (path, twin_int_to_fixed (bw*2),
- twin_int_to_fixed (bw*2));
twin_path_set_font_size (path, twin_int_to_fixed (name_height));
twin_path_set_font_style (path, TWIN_TEXT_OBLIQUE);
twin_text_metrics_utf8 (path, window->name, &m);
- twin_path_move (path, 0, m.font_ascent);
+ t.x = ((c_right - c_left) -
+ (m.right_side_bearing - m.left_side_bearing)) / 2;
+ t.y = c_top - bw_2 * 4;
+ twin_path_move (path, t.x, t.y);
twin_path_utf8 (path, window->name);
twin_paint_path (pixmap, TWIN_FRAME_TEXT, path);
- twin_path_destroy (path);
}
+ twin_path_destroy (path);
}
void
@@ -207,6 +234,7 @@ twin_window_draw (twin_window_t *window)
{
switch (window->style) {
case WindowPlain:
+ default:
break;
case WindowApplication:
twin_window_frame (window);
diff --git a/xtwin.c b/xtwin.c
index be112b6..366b134 100644
--- a/xtwin.c
+++ b/xtwin.c
@@ -186,7 +186,7 @@ twin_clock_face (twin_window_t *clock)
twin_path_destroy (path);
}
-int nclock;
+int napp;
static void
twin_clock (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
@@ -234,7 +234,67 @@ twin_clock (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
usleep (INTERVAL - (tv.tv_usec % INTERVAL));
}
- nclock--;
+ napp--;
+}
+
+static void
+twin_text_app (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
+{
+ twin_window_t *text = twin_window_create (screen, TWIN_ARGB32,
+ WindowApplication,
+ x,y,w,h);
+ twin_fixed_t fx, fy;
+ static const char *lines[] = {
+ "Fourscore and seven years ago our fathers brought forth on",
+ "this continent a new nation, conceived in liberty and",
+ "dedicated to the proposition that all men are created equal.",
+ "",
+ "Now we are engaged in a great civil war, testing whether that",
+ "nation or any nation so conceived and so dedicated can long",
+ "endure. We are met on a great battlefield of that war. We",
+ "have come to dedicate a portion of it as a final resting",
+ "place for those who died here that the nation might live.",
+ "This we may, in all propriety do. But in a larger sense, we",
+ "cannot dedicate, we cannot consecrate, we cannot hallow this",
+ "ground. The brave men, living and dead who struggled here",
+ "have hallowed it far above our poor power to add or detract.",
+ "The world will little note nor long remember what we say here,",
+ "but it can never forget what they did here.",
+ "",
+ "It is rather for us the living, we here be dedicated to the",
+ "great task remaining before us--that from these honored",
+ "dead we take increased devotion to that cause for which they",
+ "here gave the last full measure of devotion--that we here",
+ "highly resolve that these dead shall not have died in vain, that",
+ "this nation shall have a new birth of freedom, and that",
+ "government of the people, by the people, for the people shall",
+ "not perish from the earth.",
+ 0
+ };
+ const char **l;
+ twin_path_t *path;
+
+ twin_window_set_name(text, name);
+ path = twin_path_create ();
+ twin_path_translate (path,
+ twin_int_to_fixed (text->client.left),
+ twin_int_to_fixed (text->client.top));
+#define TEXT_SIZE 10
+ twin_path_set_font_size (path, D(TEXT_SIZE));
+ fx = D(3);
+ fy = D(10);
+ twin_fill (text->pixmap, 0xc0c0c0c0, TWIN_SOURCE,
+ text->client.left, text->client.top,
+ text->client.right, text->client.bottom);
+ for (l = lines; *l; l++)
+ {
+ twin_path_move (path, fx, fy);
+ twin_path_utf8 (path, *l);
+ twin_paint_path (text->pixmap, 0xff000000, path);
+ twin_path_empty (path);
+ fy += D(TEXT_SIZE);
+ }
+ twin_window_show (text);
}
typedef void (*twin_app_func_t) (twin_screen_t *screen, const char *name,
@@ -280,7 +340,7 @@ twin_start_app (twin_app_func_t func,
static void
twin_start_clock (twin_screen_t *screen, const char *name, int x, int y, int w, int h)
{
- ++nclock;
+ ++napp;
twin_start_app (twin_clock, screen, name, x, y, w, h);
}
@@ -315,6 +375,7 @@ main (int argc, char **argv)
twin_fixed_t fx, fy;
int g;
+ twin_screen_set_background (x11->screen, twin_make_pattern ());
(void) ev;
(void) motion;
(void) had_motion;
@@ -640,20 +701,24 @@ main (int argc, char **argv)
twin_pixmap_move (blue, 100, 100);
twin_pixmap_show (red, x11->screen, 0);
twin_pixmap_show (blue, x11->screen, 0);
- ++nclock;
+ ++napp;
#endif
- if (!nclock)
- twin_start_clock (x11->screen, "small clock", 10, 10, 200, 200);
+ if (!napp)
+ twin_start_clock (x11->screen, "Clock", 10, 10, 200, 200);
+#if 0
+ twin_start_clock (x11->screen, "Large clock", 0, 100, 256, 256);
+#endif
#if 1
- twin_start_clock (x11->screen, "ul clock", 0, 0, 256, 256);
+ twin_start_app (twin_text_app, x11->screen, "Gettysburg Address",
+ 100, 100, 318, 250);
#endif
#if 0
twin_start_clock (x11->screen, "ur clock", 256, 0, 256, 256);
twin_start_clock (x11->screen, "ll clock", 0, 256, 256, 256);
twin_start_clock (x11->screen, "lr clock", 256, 256, 256, 256);
#endif
- while (nclock)
+ while (napp)
sleep (1);
return 0;
}