swk

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

commit fa5e9defd0b57e88fd8d2abbdf25448f8b86003a
parent c21b9fa32913daf46b34b7e72e2ca6567c4a1d14
Author: pancake <pancake@nopcode.org>
Date:   Tue, 20 Apr 2010 10:19:39 +0200

revert last commit
refactorize some code and remove draw.{c|h}
handle mouse events in sdl backend
extended example program
Diffstat:
Makefile | 2+-
app1.c | 40----------------------------------------
app2.c | 40----------------------------------------
draw.c | 35-----------------------------------
draw.h | 19-------------------
gi_sdl.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
swk.c | 40+++++++++++++++++++++++++++++++++++++---
swk.h | 23+++++++++++++++++------
test.c | 20+++++++++++++-------
9 files changed, 156 insertions(+), 177 deletions(-)

diff --git a/Makefile b/Makefile @@ -8,7 +8,7 @@ LIBDIR?=${PREFIX}/lib GI?=sdl GI_LIBS=-lSDL -GI_OBJS=gi_${GI}.o draw.o +GI_OBJS=gi_${GI}.o all: static test diff --git a/app1.c b/app1.c @@ -1,40 +0,0 @@ -void (*swkhandler)(SwkWidget *, SwkEvent *); - -void onclick(SwkWidget *w); - -SwkTextField t = { - SwkTypeTextField, - "enter some text", - NULL -}; -SwkButton b = { - SwkTypeButton, - "OK", - NULL -}; -SwkWin w = { - SwkTypeWin, - { &t, &b, NULL } -}; - -void onclick(SwkWidget *w) { - static int clicks = 0; - SwkButton *b = (SwkButton *)w; - fprintf(stdout, "onclick: %s\n", t.data); - if(++clicks == 10) - swk_exit(); -} - -static void myhandler(SwkWidget *w, SwkEvent *e) { - if(e->type == SWK_CLICK && w->type == SwkTypeButton) - onclick(w); - else /* fallback */ - swkhandler(w, e); -} - -int main() { - swk_init(&w); - swkhandler = swk_set_handler(myhandler); - swk_loop(NULL); // loops until swk_exit() is called - return 0; -} diff --git a/app2.c b/app2.c @@ -1,40 +0,0 @@ -void (*swkhandler)(SwkWidget *, SwkEvent *); - -void onclick(SwkWidget *w); - -SwkTextField t = { - SwkTypeTextField, - "enter some text", - NULL -}; -SwkButton b = { - SwkTypeButton, - "OK", - NULL -}; -SwkWin w = { - SwkTypeWin, - { &t, &b, NULL } -}; - -void onclick(SwkWidget *w) { - static int clicks = 0; - SwkButton *b = (SwkButton *)w; - fprintf(stdout, "onclick: %s\n", t.data); - if(++clicks == 10) - swk_exit(); -} - -static void myhandler(SwkWidget *w, SwkEvent *e) { - if(e->type == SWK_CLICK && w->type == SwkTypeButton) - onclick(w); - else /* fallback */ - swkhandler(w, e); -} - -int main() { - swk_init(&w); - swkhandler = swk_set_handler(myhandler); - swk_loop(NULL); // loops until swk_exit() is called - return 0; -} diff --git a/draw.c b/draw.c @@ -1,35 +0,0 @@ -#include <stdlib.h> -#include "draw.h" - -static DrawBuffer buf; - -int -draw_init(int w, int h) { - buf.pixels = malloc(sizeof(int)*w*h); - buf.w = w; - buf.h = h; - return swk_gi_init(w, h); -} - -void -swk_exit() { - free (buf.pixels); - swk_gi_exit(); -} - -/* TODO: move to gi_sdl.c */ -void -draw_line(int x, int y, int w, int h) { -} - -void -draw_box(int x, int y, int w, int h) { -} - -void -draw_rect(int x, int y, int w, int h) { -} - -void -draw_text(int x, int y, const char *text) { -} diff --git a/draw.h b/draw.h @@ -1,19 +0,0 @@ - -typedef struct { - int *pixels; - int w; - int h; -} DrawBuffer; - -int swk_gi_init(); -void swk_gi_exit(); -void swk_gi_flip(); - -int draw_init(int w, int h); -void draw_exit(); - -void draw_line(int x, int y, int w, int h); -void draw_box(int x, int y, int w, int h); -void draw_rect(int x, int y, int w, int h); -void draw_text(int x, int y, const char *text); -//void draw_pixmap(); diff --git a/gi_sdl.c b/gi_sdl.c @@ -1,18 +1,30 @@ #include <SDL/SDL.h> #include "swk.h" +static SDL_Surface *screen = NULL; + int -swk_gi_init(int w, int h) { +swk_gi_init(SwkWindow *w) { if (SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "Cannot initialize SDL\n"); return 0; } - SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE); + SDL_SetVideoMode(w->r.w, w->r.h, 32, SDL_DOUBLEBUF|SDL_RESIZABLE); + screen = SDL_GetVideoSurface(); SDL_EnableUNICODE(1); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); return 1; } +int +swk_gi_update(SwkWindow *w) { + /* nothing to do here */ + SDL_SetVideoMode(screen->w, screen->h, 32, SDL_DOUBLEBUF|SDL_RESIZABLE); + screen = SDL_GetVideoSurface(); + fprintf(stderr, "NEW(%d,%d)\n", screen->w, screen->h); + return 1; +} + void swk_gi_exit() { SDL_Quit(); @@ -21,38 +33,88 @@ swk_gi_exit() { static char sdlkeys[256] = { 0 }; // TODO SwkEvent * -swk_event() { +swk_gi_event(int dowait) { + int evret; SDL_Event event; static SwkEvent ev; SwkEvent *ret = NULL; - if(SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - ret = &ev; - ev.type = EKey; - ev.data.key.keycode = sdlkeys[event.key.keysym.sym]; - ev.data.key.modmask = 0; - if(event.key.keysym.mod & KMOD_LCTRL || - event.key.keysym.mod & KMOD_RCTRL) - ev.data.key.modmask |= Ctrl; - if(event.key.keysym.mod & KMOD_LSHIFT|| - event.key.keysym.mod & KMOD_RSHIFT) - ev.data.key.modmask |= Shift; - if(event.key.keysym.mod & KMOD_LMETA || - event.key.keysym.mod & KMOD_RMETA) - ev.data.key.modmask |= Meta; - break; - case SDL_QUIT: - ev.type = ev.type = EQuit; - ret = &ev; - break; - } + if (dowait) evret = SDL_WaitEvent(&event); + else evret = SDL_PollEvent(&event); + + if (evret) + switch (event.type) { + 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; + break; + case SDL_MOUSEMOTION: + ret = &ev; + ev.type = EMotion; + ev.data.motion.x = event.motion.x; + ev.data.motion.y = event.motion.y; + 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; + ev.data.click.point.y = event.button.y; + fprintf(stderr, "event: click %d\n", event.button.button); + break; + case SDL_KEYDOWN: + ret = &ev; + ev.type = EKey; + ev.data.key.keycode = sdlkeys[event.key.keysym.sym]; + ev.data.key.modmask = 0; + if(event.key.keysym.mod & KMOD_LCTRL || + event.key.keysym.mod & KMOD_RCTRL) + ev.data.key.modmask |= Ctrl; + if(event.key.keysym.mod & KMOD_LSHIFT|| + event.key.keysym.mod & KMOD_RSHIFT) + ev.data.key.modmask |= Shift; + if(event.key.keysym.mod & KMOD_LMETA || + event.key.keysym.mod & KMOD_RMETA) + ev.data.key.modmask |= Meta; + fprintf(stderr, "event: key %d %d\n", + ev.data.key.modmask, ev.data.key.keycode); + break; + case SDL_QUIT: + fprintf(stderr, "event: quit\n"); + ev.type = ev.type = EQuit; + ret = &ev; + break; } return ret; } void swk_gi_flip() { - /* TODO */ + fprintf(stderr, "flip\n"); + SDL_Flip(screen); +} + +/* -- drawing primitives -- */ +void +swk_gi_line(int x, int y, int w, int h) { +} + +void +swk_gi_box(int x, int y, int w, int h) { +} + +void +swk_gi_rect(int x, int y, int w, int h) { +} + +void +swk_gi_text(int x, int y, const char *text) { } diff --git a/swk.c b/swk.c @@ -2,16 +2,41 @@ #include <stdio.h> #include "swk.h" +static int running = 0; static SwkWindow *w = NULL; int swk_init(SwkWindow* window) { w = window; + w->box = w->boxes; if (w->r.w == 0 || w->r.h == 0) { w->r.w = 640; w->r.h = 480; } - return draw_init(w->r.w, w->r.h); + if (swk_gi_init(w)) + running = 1; + return running; +} + +void +swk_update() { + if (!swk_gi_update(w)) + running = 0; + else swk_gi_flip(); +} + +void +swk_exit() { + running = 0; +} + +void +swk_loop() { + SwkEvent *e; + do { + if ((e = swk_event(1))) + swk_event_handle(e); + } while (!e || e->type != EQuit); } void @@ -21,6 +46,15 @@ swk_fit() { printf("Handler: %p text: \"%s\"\n", b->cb, b->text); } +SwkEvent * +swk_event(int dowait) { + static SwkEvent ev; + if (running) + return swk_gi_event(); + ev.type = EQuit; + return &ev; +} + void swk_event_handle(SwkEvent *e) { switch(e->type) { @@ -31,10 +65,10 @@ swk_event_handle(SwkEvent *e) { break; case EExpose: swk_fit(); - //swk_gi_flip(); + swk_update(); break; case EQuit: - swk_exit(); + swk_gi_exit(); break; default: break; diff --git a/swk.h b/swk.h @@ -1,11 +1,8 @@ /* See LICENSE file for copyright and license details. */ -#include "draw.h" - #define SWK_NEWLINE .h=-1, .w=-1 typedef enum { EVoid, EClick, EMotion, EKey, EExpose, EQuit, ELast } SwkEventType; typedef enum { Ctrl=1, Meta=2, Shift=4 } SwkKeyMod; -typedef enum { Left=1, Middle=2, Right=3, WheelUp=4, WheelDown=5 } SwkClickButton; typedef struct SwkBox SwkBox; @@ -22,14 +19,14 @@ typedef struct { } Rect; typedef struct { - SwkClickButton button; - long modmask; + int button; + int modmask; Point point; } Click; typedef struct { int keycode; - long modmask; + int modmask; } Key; typedef struct { @@ -61,6 +58,7 @@ typedef struct { } SwkWindow; int swk_init(SwkWindow *w); +int swk_gi_update(SwkWindow *w); void swk_exit(); void swk_fit(); SwkEvent * swk_event(); @@ -73,3 +71,16 @@ void swk_button(SwkEvent *e); void swk_label(SwkEvent *e); void swk_entry(SwkEvent *e); void swk_filler(SwkEvent *e); + +/* graphic backend */ + +int swk_gi_init(SwkWindow *w); +void swk_gi_exit(); +SwkEvent * swk_gi_event(); + +void swk_gi_flip(); + +void swk_gi_line(int x, int y, int w, int h); +void swk_gi_box(int x, int y, int w, int h); +void swk_gi_rect(int x, int y, int w, int h); +void swk_gi_text(int x, int y, const char *text); diff --git a/test.c b/test.c @@ -1,17 +1,27 @@ #include <stdio.h> #include "swk.h" +static int count = 3; + +static int mybutton(SwkEvent *e) { + if (e->type == EClick) { + fprintf(stderr, "Button clicked %d\n", count); + if (count-- == 0) + swk_exit(); + } + return swk_button(e); +} + static SwkBox helloworld[] = { { .cb=swk_label, .text="Press this button", }, { SWK_NEWLINE }, { .cb=swk_filler, }, - { .cb=swk_button, .text="clickme" }, + { .cb=mybutton, .text="clickme" }, { .cb=NULL } }; int main() { - SwkEvent *e; SwkWindow w = { .title="Hello World", .boxes=helloworld @@ -19,10 +29,6 @@ main() { if (!swk_init(&w)) return 1; - do { - if ((e = swk_event())) - swk_event_handle(e); - } while (!e || e->type != EQuit); - swk_exit(); + swk_loop(); return 0; }