swk

static widget kit
git clone git://git.suckless.org/swk
Log | Files | Refs | README | LICENSE

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; }