commit de43db41e02a8de24fc6060855a50e9d3a9842f7
parent 29d3b902c839e1690d05e9bd2757315178dbfa28
Author: anselm@garbe.us <unknown>
Date: Wed, 21 Apr 2010 16:24:12 +0100
Some cleanups and remarks
Diffstat:
Makefile | | | 2 | +- |
gi_sdl.c | | | 84 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
swk.c | | | 98 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
swk.h | | | 40 | +++++++++++++++++++++++----------------- |
test.c | | | 12 | ++++++------ |
5 files changed, 121 insertions(+), 115 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
CC?=gcc
-CFLAGS?=-Wall -g
+CFLAGS?=-Wall -g -std=c99
VERSION=0.1
DESTDIR?=
PREFIX?=${DESTDIR}/usr/local
diff --git a/gi_sdl.c b/gi_sdl.c
@@ -80,76 +80,71 @@ swk_gi_exit() {
SDL_Quit();
}
-
+/* FIXME: put ugly statics into void *aux of SwkWindow */
static int has_event = 0;
static SDL_Event lastev = {.type=-1};
int
-swk_gi_has_event() {
+swk_gi_has_event(SwkWindow *w) {
if (!has_event)
has_event = SDL_PollEvent(&lastev);
return has_event;
}
SwkEvent *
-swk_gi_event(int dowait) {
+swk_gi_event(SwkWindow *w, int dowait) {
SDL_Event event;
- static SwkEvent ev;
- SwkEvent *ret = NULL;
+ SwkEvent *ret = &w->_e;
if(has_event) event = lastev;
else has_event = SDL_WaitEvent(&event);
if (has_event);
switch(event.type) {
+ default: ret = NULL; break;
case SDL_VIDEORESIZE:
fprintf(stderr, "resize %d %d\n", event.resize.w, event.resize.h);
SDL_SetVideoMode(event.resize.w, event.resize.h,
32, SDL_DOUBLEBUF|SDL_RESIZABLE);
case SDL_VIDEOEXPOSE:
- ret = &ev;
- ev.type = EExpose;
- ev.data.expose.x = ev.data.expose.y = \
- ev.data.expose.w = ev.data.expose.h = 0;
+ ret->type = EExpose;
+ ret->data.expose.x = ret->data.expose.y = \
+ ret->data.expose.w = ret->data.expose.h = 0;
break;
case SDL_MOUSEMOTION:
- ret = &ev;
- ev.type = EMotion;
- ev.data.motion.x = event.motion.x / FS;
- ev.data.motion.y = event.motion.y / FS;
+ ret->type = EMotion;
+ ret->data.motion.x = event.motion.x / FS;
+ ret->data.motion.y = event.motion.y / FS;
// fprintf(stderr, "event: motion %d %d\n",
// event.motion.x, event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
- ret = &ev;
- ev.type = EClick;
- ev.data.click.button = event.button.button;
- ev.data.click.point.x = event.button.x / FS;
- ev.data.click.point.y = event.button.y / FS;
+ ret->type = EClick;
+ ret->data.click.button = event.button.button;
+ ret->data.click.point.x = event.button.x / FS;
+ ret->data.click.point.y = event.button.y / FS;
fprintf(stderr, "event: click %d\n", event.button.button);
break;
case SDL_KEYDOWN:
- if (ev.data.key.keycode != 0 && event.key.keysym.unicode != 0) {
- ret = &ev;
- ev.type = EKey;
- ev.data.key.keycode = event.key.keysym.unicode;
- ev.data.key.modmask = 0;
+ if (ret->data.key.keycode != 0 && event.key.keysym.unicode != 0) {
+ ret->type = EKey;
+ ret->data.key.keycode = event.key.keysym.unicode;
+ ret->data.key.modmask = 0;
if(event.key.keysym.mod & KMOD_CTRL)
- ev.data.key.modmask |= Ctrl;
+ ret->data.key.modmask |= Ctrl;
if(event.key.keysym.mod & KMOD_SHIFT)
- ev.data.key.modmask |= Shift;
+ ret->data.key.modmask |= Shift;
if(event.key.keysym.mod & KMOD_ALT)
- ev.data.key.modmask |= Alt;
+ ret->data.key.modmask |= Alt;
if(event.key.keysym.mod & KMOD_META)
- ev.data.key.modmask |= Meta;
+ ret->data.key.modmask |= Meta;
fprintf(stderr, "event: key %d %d\n",
- ev.data.key.modmask, ev.data.key.keycode);
+ ret->data.key.modmask, ret->data.key.keycode);
}
break;
case SDL_QUIT:
fprintf(stderr, "event: quit\n");
- ev.type = ev.type = EQuit;
- ret = &ev;
+ ret->type = ret->type = EQuit;
break;
}
has_event = 0;
@@ -168,37 +163,38 @@ swk_gi_flip() {
}
/* -- drawing primitives -- */
+
void
-swk_gi_line(int x, int y, int w, int h, int color) {
+swk_gi_line(int x1, int y1, int x2, int y2, int color) {
int i;
- x *= FS; y *= FS;
- w *= FS; h *= FS;
+ x1 *= FS; y1 *= FS;
+ x2 *= FS; y2 *= FS;
- if (w==0) for(i=0;i<h;i++) putpixel(x, y+i, pal[color]);
+ if (x2==0) for(i=0;i<y2;i++) putpixel(x1, y1+i, pal[color]);
else
- if (h==0) for(i=0;i<w;i++) putpixel(x+i, y, pal[color]);
+ if (y2==0) for(i=0;i<x2;i++) putpixel(x1+i, y1, pal[color]);
}
void
-swk_gi_fill(int x, int y, int w, int h, int color) {
- SDL_Rect area = { x*FS, y*FS, w*FS, h*FS };
+swk_gi_fill(Rect r, int color) {
+ SDL_Rect area = { r.x*FS, r.y*FS, r.w*FS, r.h*FS };
SDL_FillRect(screen, &area, pal[color]);
}
void
-swk_gi_rect(int x, int y, int w, int h, int color) {
- swk_gi_line(x, y, w, 0, color);
- swk_gi_line(x, y+h, w, 0, color);
- swk_gi_line(x, y, 0, h, color);
- swk_gi_line(x+w, y, 0, h, color);
+swk_gi_rect(Rect r, int color) {
+ swk_gi_line(r.x, r.y, r.w, 0, color);
+ swk_gi_line(r.x, r.y+r.h, r.w, 0, color);
+ swk_gi_line(r.x, r.y, 0, r.h, color);
+ swk_gi_line(r.x+r.w, r.y, 0, r.h, color);
}
void
-swk_gi_text(int x, int y, const char *text) {
+swk_gi_text(Rect r, const char *text) {
if (*text) {
SDL_Surface *ts = TTF_RenderText_Solid(font, text, fontcolor);
if (ts) {
- SDL_Rect to = { x*FS, y*FS, ts->w, ts->h };
+ SDL_Rect to = { (r.x+1)*FS, r.y*FS, ts->w, ts->h };
SDL_BlitSurface(ts, NULL, screen, &to);
SDL_FreeSurface(ts);
} else fprintf(stderr, "Cannot render string (%s)\n", text);
diff --git a/swk.c b/swk.c
@@ -5,11 +5,10 @@
#include "swk.h"
static int running = 0;
-static SwkWindow *w = NULL;
int
-swk_init(SwkWindow* window) {
- w = window;
+swk_init(SwkWindow *w) {
+ w->_e.win = w;
w->box = w->boxes;
if(w->r.w == 0 || w->r.h == 0) {
w->r.w = 640;
@@ -17,41 +16,41 @@ swk_init(SwkWindow* window) {
}
if(swk_gi_init(w)) {
running = 1;
- swk_update();
+ swk_update(w);
}
return running;
}
void
-swk_update() {
- SwkEvent ev = { .type = EExpose };
+swk_update(SwkWindow *w) {
+ w->_e.type = EExpose;
if(swk_gi_update(w)) {
SwkBox *b = w->boxes;
- swk_fit();
+ swk_fit(w);
swk_gi_clear();
for(;b->cb; b++) {
- ev.box = b;
- b->cb(&ev);
+ w->_e.box = b;
+ b->cb(&w->_e);
}
swk_gi_flip();
} else running = 0;
}
void
-swk_exit() {
+swk_exit(void) {
running = 0;
}
void
-swk_loop() {
+swk_loop(SwkWindow *w) {
SwkEvent *e;
do {
- if((e = swk_event(1)))
- swk_event_handle(e);
+ if((e = swk_next_event(w)))
+ swk_handle_event(e);
} while (!e || e->type != EQuit);
}
-static void swk_fit_row(SwkBox *a, SwkBox *b, int y) {
+static void swk_fit_row(SwkWindow *w, SwkBox *a, SwkBox *b, int y) {
int count, x = 0;
SwkBox *btmp;
count = 0;
@@ -70,71 +69,76 @@ static void swk_fit_row(SwkBox *a, SwkBox *b, int y) {
}
void
-swk_fit() {
+swk_fit(SwkWindow *w) {
int y = 0;
SwkBox *b, *b2;
for(b=b2=w->boxes; b->cb; b++) {
if(b->r.w==-1 && b->r.h==-1) {
- swk_fit_row(b2, b, y);
+ swk_fit_row(w, b2, b, y);
y += (int)(size_t)b->data;
b2 = b+1;
}
}
- swk_fit_row(b2, b, y);
+ swk_fit_row(w, b2, b, y);
+}
+
+int
+swk_has_event(SwkWindow *w) {
+ return swk_gi_has_event(w);
}
SwkEvent *
-swk_event(int dowait) {
- static SwkEvent ev;
+swk_next_event(SwkWindow *w) {
if(running)
- return swk_gi_event();
- ev.type = EQuit;
- return &ev;
+ return swk_gi_event(w, 1);
+ w->_e.type = EQuit;
+ w->_e.win = w;
+ return &w->_e;
}
void
-swk_event_handle(SwkEvent *e) {
+swk_handle_event(SwkEvent *e) {
SwkBox *b;
switch(e->type) {
case EKey:
// TODO: handle ^Y and ^P to copypasta box->text
if(e->data.key.keycode == 9) { // TAB
if(e->data.key.modmask)
- swk_focus_prev();
- else swk_focus_next();
- swk_update();
+ swk_focus_prev(e->win);
+ else swk_focus_next(e->win);
+ swk_update(e->win);
} else
if(e->data.key.keycode == 13) { // ENTER
- e->box = w->box;
+ e->box = e->win->box;
e->type = EClick;
}
// send key to focused box
- e->box = w->box;
- if(w->box)
- w->box->cb(e);
- swk_update();
+ e->box = e->win->box;
+ if(e->win->box)
+ e->win->box->cb(e);
+ swk_update(e->win);
break;
case EMotion:
- for(b=w->boxes; b->cb; b++) {
+ for(b=e->win->boxes; b->cb; b++) {
if(SWK_HIT(b->r, e->data.motion)) {
- w->box = e->box = b;
+ e->win->box = e->box = b;
b->cb(e);
- swk_update();
+ swk_update(e->win);
break;
}
}
break;
case EClick:
- for(b=w->boxes; b->cb; b++) {
+ for(b=e->win->boxes; b->cb; b++) {
if(SWK_HIT(b->r, e->data.click.point)) {
- e->box = w->box = b;
+ e->box = e->win->box = b;
e->box->cb(e);
- swk_update();
+ swk_update(e->win);
}
}
break;
case EExpose:
- swk_update();
+ swk_update(e->win);
break;
case EQuit:
swk_gi_exit();
@@ -145,7 +149,7 @@ swk_event_handle(SwkEvent *e) {
}
void
-swk_focus_next() {
+swk_focus_next(SwkWindow *w) {
w->box++;
if(w->box->cb == NULL)
w->box = w->boxes;
@@ -156,7 +160,7 @@ swk_focus_next() {
}
void
-swk_focus_prev() {
+swk_focus_prev(SwkWindow *w) {
if(w->box == w->boxes) {
while(w->box->cb)
w->box++;
@@ -167,7 +171,7 @@ swk_focus_prev() {
w->box--;
if(w->box < w->boxes) {
w->box = w->boxes;
- swk_focus_prev();
+ swk_focus_prev(w);
return;
}
}
@@ -181,9 +185,9 @@ swk_label(SwkEvent *e) {
switch(e->type) {
case EExpose:
r = e->box->r;
- if(w->box == e->box)
+ if(e->win->box == e->box)
swk_gi_line(r.x, r.y+1, r.w, 0, ColorHI);
- swk_gi_text(r.x, r.y, e->box->text);
+ swk_gi_text(r, e->box->text);
break;
default:
break;
@@ -224,10 +228,10 @@ swk_button(SwkEvent *e) {
switch(e->type) {
case EExpose:
r = e->box->r;
- if(w->box == e->box)
- swk_gi_rect(r.x, r.y, r.w, r.h, ColorHI);
- else swk_gi_rect(r.x, r.y, r.w, r.h, ColorFG);
- swk_gi_text(r.x+1, r.y, e->box->text);
+ if(e->win->box == e->box)
+ swk_gi_rect(r, ColorHI);
+ else swk_gi_rect(r, ColorFG);
+ swk_gi_text(r, e->box->text);
break;
default:
break;
diff --git a/swk.h b/swk.h
@@ -1,6 +1,6 @@
/* See LICENSE file for copyright and license details. */
-#define SWK_NEWLINE(x) .data=(void*)(size_t)x, .r.w=-1, .r.h=-1, .cb = swk_filler
+#define SWK_BOX_NEWLINE(x) { .data=(void*)(size_t)x, .r.w=-1, .r.h=-1, .cb = swk_filler }
#define SWK_HIT(r,p) (p.x>=r.x && p.x<(r.x+r.w) && p.y>=r.y && p.y<(r.y+r.h))
typedef enum { EVoid, EClick, EMotion, EKey, EExpose, EQuit, ELast } SwkEventType;
@@ -8,6 +8,7 @@ typedef enum { Shift=1, Ctrl=2, Alt=4, Meta=8 } SwkKeyMod;
typedef enum { ColorFG, ColorBG, ColorHI, ColorLast } Palete;
typedef struct SwkBox SwkBox;
+typedef struct SwkWindow SwkWindow;
typedef struct {
int x;
@@ -35,6 +36,7 @@ typedef struct {
typedef struct {
SwkEventType type;
SwkBox *box;
+ SwkWindow *win;
union {
Click click;
Point motion;
@@ -53,23 +55,26 @@ struct SwkBox {
void *data;
};
-typedef struct {
+struct SwkWindow {
char *title;
Rect r;
SwkBox *boxes;
+ /* internal use */
SwkBox *box;
-} SwkWindow;
+ SwkEvent _e;
+};
int swk_init(SwkWindow *w);
-void swk_update();
-void swk_exit();
-void swk_fit();
-void swk_loop();
-SwkEvent * swk_event();
-void swk_event_handle(SwkEvent *e);
+void swk_update(SwkWindow *w);
+void swk_exit(void);
+void swk_fit(SwkWindow *w);
+void swk_loop(SwkWindow *w);
+SwkEvent *swk_next_event(SwkWindow *w);
+int swk_has_event(SwkWindow *w);
+void swk_handle_event(SwkEvent *e);
-void swk_focus_next();
-void swk_focus_prev();
+void swk_focus_next(SwkWindow *w);
+void swk_focus_prev(SwkWindow *w);
void swk_button(SwkEvent *e);
void swk_label(SwkEvent *e);
@@ -80,14 +85,15 @@ void swk_filler(SwkEvent *e);
int swk_gi_init(SwkWindow *w);
void swk_gi_exit();
-SwkEvent * swk_gi_event();
+SwkEvent *swk_gi_event(SwkWindow *w, int dowait);
int swk_gi_update(SwkWindow *w);
-int swk_gi_has_event();
+int swk_gi_has_event(SwkWindow *w);
+/* FIXME: don't these need SwkWindow *w state, to avoid static'ness? */
void swk_gi_clear();
void swk_gi_flip();
-void swk_gi_line(int x, int y, int w, int h, int color);
-void swk_gi_fill(int x, int y, int w, int h, int color);
-void swk_gi_rect(int x, int y, int w, int h, int color);
-void swk_gi_text(int x, int y, const char *text);
+void swk_gi_line(int x1, int y1, int x2, int y2, int color);
+void swk_gi_fill(Rect r, int color);
+void swk_gi_rect(Rect r, int color);
+void swk_gi_text(Rect r, const char *text);
diff --git a/test.c b/test.c
@@ -17,21 +17,21 @@ static void mybutton(SwkEvent *e) {
static SwkBox helloworld[] = {
- { SWK_NEWLINE(1) },
+ SWK_BOX_NEWLINE(1),
{ .cb=swk_label, .text="Press a button", },
- { SWK_NEWLINE(2) },
+ SWK_BOX_NEWLINE(2),
{ .cb=swk_label, .text="Username:", },
{ .cb=swk_entry, .text="____", },
{ .cb=swk_filler, },
- { SWK_NEWLINE(1) },
+ SWK_BOX_NEWLINE(1),
{ .cb=swk_label, .text="Password:", },
{ .cb=swk_entry, .text="****", },
{ .cb=swk_filler, },
- { SWK_NEWLINE(2) },
+ SWK_BOX_NEWLINE(2),
{ .cb=mybutton, .text="yes" },
{ .cb=mybutton, .text="no" },
{ .cb=swk_filler, },
- { SWK_NEWLINE(5) },
+ SWK_BOX_NEWLINE(5),
{ .cb=swk_label, .text="--swktest", },
{ .cb=NULL }
};
@@ -44,6 +44,6 @@ main() {
};
if (!swk_init(&w))
return 1;
- swk_loop();
+ swk_loop(&w);
return 0;
}