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