swk

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

commit a59801efe90825ed51b87867f6cdb8406b707dd6
parent e90ffeeb671d5c93fba397f10cc041eb040471ec
Author: pancake <pancake@nopcode.org>
Date:   Tue, 20 Apr 2010 01:20:37 +0200

commit initial sdl backend
discussed design is partially implemented
Diffstat:
LICENSE | 22++++++++++++++++++++++
Makefile | 20++++++++++++++------
draw.c | 35+++++++++++++++++++++++++++++++++++
draw.h | 19+++++++++++++++++++
gi_sdl.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
swk.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
swk.h | 33+++++++++++++++++++++++----------
test.c | 23+++++++++++++++++++++++
8 files changed, 288 insertions(+), 16 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,22 @@ +MIT/X Consortium License + +© 2010 Anselm R Garbe <garbeam at gmail dot com> +© 2010 pancake <pancake at nopcode dot org> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile @@ -1,24 +1,32 @@ CC?=gcc +CFLAGS?=-Wall -g DESTDIR?= PREFIX?=${DESTDIR}/usr/local LIBDIR?=${PREFIX}/lib +# graphic backend +GI?=sdl +GI_LIBS=-lSDL + +GI_OBJS=gi_${GI}.o draw.o + all: static test test.o: ${CC} -I. test.c -c -o test.o -test: test.o - ${CC} test.o -o test libswk.a +test: test.o libswk.a + ${CC} test.o -o test libswk.a ${GI_LIBS} clean: - rm -f libswk.a test.o swk.o test + rm -f libswk.a test.o swk.o test ${GI_OBJS} install: - cp ${DESTDIR}/${LIBDIR} + cp libswk.a ${DESTDIR}/${LIBDIR} + # TODO: create pkgconfig? static: libswk.a -libswk.a: swk.o +libswk.a: swk.o ${GI_OBJS} rm -f libswk.a - ar qcvf libswk.a swk.o + ar qcvf libswk.a swk.o ${GI_OBJS} diff --git a/draw.c b/draw.c @@ -0,0 +1,35 @@ +#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 @@ -0,0 +1,19 @@ + +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 @@ -0,0 +1,66 @@ +#include <SDL/SDL.h> +#include "swk.h" + +int +swk_gi_init(int w, int h) { + if (SDL_Init(SDL_INIT_VIDEO)) { + fprintf(stderr, "Cannot initialize SDL\n"); + return 0; + } + SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE); + SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + return 1; +} + +void +swk_gi_exit() { + SDL_Quit(); +} + +static char sdlkeys[256] = { 0 }; // TODO + +SwkEvent * +swk_event(int lock) { + int evret; + SDL_Event event; + static SwkEvent ev; + SwkEvent *ret = NULL; + + if (lock) evret = SDL_WaitEvent(&event); + else evret = SDL_PollEvent(&event); + if (evret) { + 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_MOUSEBUTTONDOWN: + ret = &ev; + ev.type = EClick; + //ev.data.click.button = + break; + case SDL_QUIT: + ev.type = ev.type = EQuit; + ret = &ev; + break; + } + } + return ret; +} + +void +swk_gi_flip() { + /* TODO */ +} diff --git a/swk.c b/swk.c @@ -0,0 +1,86 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdio.h> +#include "swk.h" + +static SwkWindow *w = NULL; + +int +swk_init(SwkWindow* window) { + w = window; + 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); +} + +void +swk_fit() { + SwkBox *b; + for(b=w->boxes; b->cb; b++) + printf("Handler: %p text: \"%s\"\n", b->cb, b->text); +} + +void +swk_loop() { + SwkEvent *e; + do { + if ((e = swk_event(1))) + swk_event_handle(e); + } while (!e || e->type != EQuit); + swk_exit(); +} + +void +swk_event_handle(SwkEvent *e) { + switch(e->type) { + case EKey: + case EClick: + if (w->box && w->box->cb) + w->box->cb(e); + break; + case EExpose: + swk_fit(); + //swk_gi_flip(); + break; + case EQuit: + swk_exit(); + break; + default: + break; + } +} + +void +swk_focus_next() { + w->box++; + if (w->box->cb == NULL) + w->box = w->boxes; +} + +void +swk_focus_prev() { + if (w->box == w->boxes) { + while(w->box->cb) + w->box++; + w->box--; + } else w->box--; +} + +/* widgets */ +void +swk_label(SwkEvent *e) { +} + +void +swk_entry(SwkEvent *e) { +} + +void +swk_button(SwkEvent *e) { +} + +void +swk_filler(SwkEvent *e) { + /* empty widget */ +} diff --git a/swk.h b/swk.h @@ -1,4 +1,11 @@ -typedef enum { EVoid, EClick, EMotion, EKey, EExpose, ELast } SwkEventType; +/* 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; @@ -15,7 +22,7 @@ typedef struct { } Rect; typedef struct { - int button; + SwkClickButton button; long modmask; Point point; } Click; @@ -36,27 +43,33 @@ typedef struct { } data; } SwkEvent; -void (*SwkEventCallback)(SwkEvent *e); +typedef void (*SwkEventCallback)(SwkEvent *e); struct SwkBox { - Rect r; - SwkEventCallback *e; + int w; + int h; + SwkEventCallback cb; char *text; void *data; }; typedef struct { + char *title; Rect r; SwkBox *boxes; - char *title; + SwkBox *box; } SwkWindow; +int swk_init(SwkWindow *w); +void swk_exit(); +void swk_fit(); +SwkEvent * swk_event(int lock); +void swk_event_handle(SwkEvent *e); -void swk_init(); -void swk_deinit(); -int swk_loop(SwkWindow *w); -int swk_event(SwkWindow *w); +void swk_focus_next(); +void swk_focus_prev(); void swk_button(SwkEvent *e); void swk_label(SwkEvent *e); void swk_entry(SwkEvent *e); +void swk_filler(SwkEvent *e); diff --git a/test.c b/test.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include "swk.h" + +static SwkBox helloworld[] = { + { .cb=swk_label, .text="Press this button", }, + { SWK_NEWLINE }, + { .cb=swk_filler, }, + { .cb=swk_button, .text="clickme" }, + { .cb=NULL } +}; + +int +main() { + SwkWindow w = { + .title="Hello World", + .boxes=helloworld + }; + + if (!swk_init(&w)) + return 1; + swk_loop(); + return 0; +}