This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via 89f781e8da4907c3e34db57714777601227a3719 (commit) from 713e4f3f13172cb63b59ac501b54992a2309b314 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/89f781e8da4907c3e34db57714777601227a3...
commit 89f781e8da4907c3e34db57714777601227a3719 Author: Cyril Hrubis metan@ucw.cz Date: Sun Jan 15 17:40:47 2012 +0100
backends: Added support for overall backend API.
diff --git a/build/get_objs.sh b/build/get_objs.sh index 834fd77..3519b01 100755 --- a/build/get_objs.sh +++ b/build/get_objs.sh @@ -1,7 +1,7 @@ #!/bin/sh
TOPDIR=.. -LIBDIRS="core gfx text loaders filters backends input" +LIBDIRS="core gfx text loaders filters input"
for i in $LIBDIRS; do OBJECTS=`echo $TOPDIR/libs/$i/*.o`; diff --git a/demos/fbshow/Makefile b/demos/fbshow/Makefile index 08f9234..6b04464 100644 --- a/demos/fbshow/Makefile +++ b/demos/fbshow/Makefile @@ -5,7 +5,7 @@ CSOURCES=$(shell echo *.c) INCLUDE= CFLAGS+=-pthread LDFLAGS+=-pthread -LDLIBS+=-lGP -L$(TOPDIR)/build/ +LDLIBS+=-lGP -lGP_backends -lSDL -L$(TOPDIR)/build/
APPS=fbshow
diff --git a/demos/fbshow/fbshow.c b/demos/fbshow/fbshow.c index 3943ffc..fb3baeb 100644 --- a/demos/fbshow/fbshow.c +++ b/demos/fbshow/fbshow.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
@@ -32,13 +32,14 @@ #include <pthread.h>
#include <GP.h> -#include <backends/GP_Framebuffer.h> +#include <backends/GP_Backends.h> #include <input/GP_InputDriverLinux.h>
static GP_Pixel black_pixel; static GP_Pixel white_pixel;
-static GP_Framebuffer *fb = NULL; +static GP_Backend *backend; +static GP_Context *context;
/* image loader thread */ static int abort_flag = 0; @@ -60,7 +61,7 @@ static int image_loader_callback(GP_ProgressCallback *self) snprintf(buf, sizeof(buf), "%s ... %-3.1f%%", (const char*)self->priv, self->percentage);
- GP_Context *c = &fb->context; + GP_Context *c = context;
int align = GP_ALIGN_CENTER|GP_VALIGN_ABOVE;
@@ -118,8 +119,8 @@ static void *image_loader(void *ptr) callback.priv = "Loading image"; if (GP_LoadImage(params->img_path, &img, &callback) != 0) { - GP_Fill(&fb->context, black_pixel); - GP_Text(&fb->context, NULL, fb->context.w/2, fb->context.h/2, + GP_Fill(context, black_pixel); + GP_Text(context, NULL, context->w/2, context->h/2, GP_ALIGN_CENTER|GP_VALIGN_CENTER, black_pixel, white_pixel, "Failed to load image :("); return NULL; @@ -131,13 +132,13 @@ static void *image_loader(void *ptr) case 0: case 180: default: - w = fb->context.w; - h = fb->context.h; + w = context->w; + h = context->h; break; case 90: case 270: - w = fb->context.h; - h = fb->context.w; + w = context->h; + h = context->w; break; }
@@ -155,9 +156,9 @@ static void *image_loader(void *ptr) GP_Context *ret;
-// callback.priv = "Blurring Image"; -// if (GP_FilterGaussianBlur(img, img, 0.3/rat, 0.3/rat, &callback) == NULL) -// return NULL; + callback.priv = "Blurring Image"; + if (GP_FilterGaussianBlur(img, img, 0.5/rat, 0.5/rat, &callback) == NULL) + return NULL; callback.priv = "Resampling Image"; ret = GP_FilterResize(img, NULL, GP_INTERP_CUBIC_INT, img->w * rat, img->h * rat, &callback); @@ -191,39 +192,39 @@ static void *image_loader(void *ptr) if (img == NULL) return NULL;
- uint32_t cx = (fb->context.w - ret->w)/2; - uint32_t cy = (fb->context.h - ret->h)/2; + uint32_t cx = (context->w - ret->w)/2; + uint32_t cy = (context->h - ret->h)/2;
- GP_Blit(ret, 0, 0, ret->w, ret->h, &fb->context, cx, cy); + GP_Blit(ret, 0, 0, ret->w, ret->h, context, cx, cy); GP_ContextFree(ret);
/* clean up the rest of the display */ - GP_FillRectXYWH(&fb->context, 0, 0, cx, fb->context.h, black_pixel); - GP_FillRectXYWH(&fb->context, 0, 0, fb->context.w, cy, black_pixel); - GP_FillRectXYWH(&fb->context, ret->w+cx, 0, cx, fb->context.h, black_pixel); - GP_FillRectXYWH(&fb->context, 0, ret->h+cy, fb->context.w, cy, black_pixel); + GP_FillRectXYWH(context, 0, 0, cx, context->h, black_pixel); + GP_FillRectXYWH(context, 0, 0, context->w, cy, black_pixel); + GP_FillRectXYWH(context, ret->w+cx, 0, cx, context->h, black_pixel); + GP_FillRectXYWH(context, 0, ret->h+cy, context->w, cy, black_pixel);
if (!params->show_info) return NULL;
GP_Size th = GP_TextHeight(NULL); - GP_Print(&fb->context, NULL, 11, 11, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 11, 11, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, black_pixel, white_pixel, "%ux%u", w, h); - GP_Print(&fb->context, NULL, 10, 10, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 10, 10, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, white_pixel, black_pixel, "%ux%u", w, h); - GP_Print(&fb->context, NULL, 11, 13 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 11, 13 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, black_pixel, white_pixel, "1:%3.3f", rat); - GP_Print(&fb->context, NULL, 10, 12 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 10, 12 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, white_pixel, black_pixel, "1:%3.3f", rat); - GP_Print(&fb->context, NULL, 11, 15 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 11, 15 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, black_pixel, white_pixel, "%s", img_name(params->img_path)); - GP_Print(&fb->context, NULL, 10, 14 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 10, 14 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, white_pixel, black_pixel, "%s", img_name(params->img_path));
return NULL; @@ -247,15 +248,15 @@ static void show_image(struct loader_params *params)
if (ret) { fprintf(stderr, "Failed to start thread: %sn", strerror(ret)); - GP_FramebufferExit(fb); + GP_BackendExit(backend); exit(1); } }
static void sighandler(int signo __attribute__((unused))) { - if (fb != NULL) - GP_FramebufferExit(fb); + if (backend != NULL) + GP_BackendExit(backend);
exit(1); } @@ -313,19 +314,21 @@ int main(int argc, char *argv[]) signal(SIGBUS, sighandler); signal(SIGABRT, sighandler);
- fb = GP_FramebufferInit("/dev/fb0"); + backend = GP_BackendLinuxFBInit("/dev/fb0");
- if (fb == NULL) { + if (backend == NULL) { fprintf(stderr, "Failed to initalize framebuffern"); return 1; } + + context = backend->context; + + GP_EventSetScreenSize(context->w, context->h); - GP_EventSetScreenSize(fb->context.w, fb->context.h); - - black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, &fb->context); - white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, &fb->context); + black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context); + white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
- GP_Fill(&fb->context, black_pixel); + GP_Fill(context, black_pixel);
int argf = optind; int argn = argf; @@ -351,7 +354,7 @@ int main(int argc, char *argv[]) switch (ret) { case -1: - GP_FramebufferExit(fb); + GP_BackendExit(backend); return 0; break; case 0: @@ -411,7 +414,7 @@ int main(int argc, char *argv[]) case GP_KEY_ESC: case GP_KEY_ENTER: case GP_KEY_Q: - GP_FramebufferExit(fb); + GP_BackendExit(backend); return 0; break; case GP_KEY_RIGHT: @@ -443,7 +446,7 @@ int main(int argc, char *argv[]) } }
- GP_FramebufferExit(fb); + GP_BackendExit(backend);
return 0; } diff --git a/demos/grinder/Makefile b/demos/grinder/Makefile index 377d008..c77d449 100644 --- a/demos/grinder/Makefile +++ b/demos/grinder/Makefile @@ -2,7 +2,7 @@ TOPDIR=../..
CSOURCES=$(shell echo *.c)
-INCLUDE=core gfx SDL backends +INCLUDE=core gfx SDL LDLIBS+=-lGP -L$(TOPDIR)/build/
APPS=grinder diff --git a/include/backends/GP_Backend.h b/include/backends/GP_Backend.h index db771cd..2e36bb9 100644 --- a/include/backends/GP_Backend.h +++ b/include/backends/GP_Backend.h @@ -19,74 +19,134 @@ * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * * jiri.bluebear.dluhos@gmail.com * * * - * Copyright (C) 2009-2010 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-#ifndef GP_BACKEND_H -#define GP_BACKEND_H +/*
-#include "core/GP_Context.h" + The GP_Backend is overall structure for API for managing + connection/mmaped memory/... to xserver window/framebuffer/... . + + In contrast to other graphics libraries we do not try to create overall + initalization interface that would match specialities for every possible + backend. Rather than that we are trying to create API that is the same + for all backends, once initalization is done. + + So once you initalize, for example, framebuffer driver, the GP_Backend + structure is returned, which then could be used with generic code for + backend drawing.
-/* - * Types of events provided by the backend. */ -enum GP_BackendEventType { - GP_BACKEND_EVENT_NONE = 0, - GP_BACKEND_EVENT_UPDATE_VIDEO = 1, /* video redraw is needed */ - GP_BACKEND_EVENT_QUIT_REQUEST = 2, /* user requests quitting */ -}; + +#ifndef BACKENDS_GP_BACKEND_H +#define BACKENDS_GP_BACKEND_H + +#include "core/GP_Context.h" + +struct GP_Backend;
/* - * Structure describing an event reported by a backend. + * Linked list of file descriptors with callbacks. */ -struct GP_BackendEvent { - enum GP_BackendEventType type; -}; +typedef struct GP_BackendFD { + int fd; + void (*Callback)(struct GP_BackendFD *self, struct GP_Backend *backend); + struct GP_BackendFD *next; +} GP_BackendFD;
-/* Describes a backend and holds all its API functions. */ -struct GP_Backend { +typedef struct GP_Backend { + /* + * Backend name. + */ const char *name; - struct GP_Backend *(*init_fn)(void); - void (*shutdown_fn)(void); - GP_Context *(*open_video_fn)(int w, int h, int flags); - GP_Context *(*video_context_fn)(void); - void (*update_video_fn)(void); - int (*get_event_fn)(struct GP_BackendEvent *event); -};
-/* - * Attempts to initialize a backend. - * - * If name is specified, only that backend is tried; if name is NULL, - * all known backends are tried and the first usable one is picked. - * - * Returns the backend structure, or NULL on failure. - */ -struct GP_Backend *GP_InitBackend(const char *name); + /* + * Pointer to context app should draw to. + * + * This MAY change upon a flip operation. + */ + GP_Context *context; + + /* + * If display is buffered, this copies content + * of context onto display. + * + * If display is not buffered, this is no-op. + */ + void (*Flip)(struct GP_Backend *self); + + /* + * Updates display rectangle. + * + * In contrast to flip operation, the context + * must not change (this is intended for updating very small areas). + * + * If display is not buffered, this is no-op. + */ + void (*UpdateRect)(struct GP_Backend *self, + GP_Coord x1, GP_Coord y1, + GP_Coord x2, GP_Coord y2); + + /* + * Exits the backend. + */ + void (*Exit)(struct GP_Backend *self); + + /* + * Linked List of file descriptors with callbacks to poll. + * + * May be NULL. + */ + GP_BackendFD *fd_list; + + /* + * Some of the backends doesn't expose file descriptor + * (for example SDL is broken that way). + * + * In that case the fd_list is NULL and this function + * is non NULL. + */ + void (*Poll)(struct GP_Backend *self); + + /* Backed private data */ + char priv[]; +} GP_Backend; + +#define GP_BACKEND_PRIV(backend) ((void*)(backend)->priv)
/* - * Opens the backend video and returns its context. + * Calls backend->Flip(). */ -GP_Context *GP_OpenBackendVideo(int w, int h, int flags); +static inline void GP_BackendFlip(GP_Backend *backend) +{ + backend->Flip(backend); +}
/* - * Returns a pointer to context that represents the backend's video. + * Calls backend->UpdateRect(). */ -GP_Context *GP_GetBackendVideoContext(void); +static inline void GP_BackendUpdateRect(GP_Backend *backend, + GP_Coord x1, GP_Coord y1, + GP_Coord x2, GP_Coord y2) +{ + backend->UpdateRect(backend, x1, y1, x2, y2); +}
/* - * Calls the backend to update its video to reflect new changes. - * If the backend uses double buffering, this causes a buffer flip. - * If the backend uses direct-to-screen drawing, this call - * has no effect. + * Calls backend->Exit(). */ -void GP_UpdateBackendVideo(void); +static inline void GP_BackendExit(GP_Backend *backend) +{ + backend->Exit(backend); +}
/* - * Reads the first pending backend event. - * Returns 0 if no events were pending, 1 on success. + * Polls backend, the events are filled into event queue. */ -int GP_GetBackendEvent(struct GP_BackendEvent *event); +static inline void GP_BackendPoll(GP_Backend *backend) +{ + backend->Poll(backend); +}
-#endif /* GP_BACKEND_H */ +#endif /* BACKENDS_GP_BACKEND_H */ diff --git a/include/backends/GP_Framebuffer.h b/include/backends/GP_Backends.h similarity index 76% copy from include/backends/GP_Framebuffer.h copy to include/backends/GP_Backends.h index 010ed7f..284e2d7 100644 --- a/include/backends/GP_Framebuffer.h +++ b/include/backends/GP_Backends.h @@ -16,33 +16,28 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-#ifndef GP_FRAMEBUFFER_H -#define GP_FRAMEBUFFER_H +/* + + Catch all header for backends.
-#include "core/GP_Context.h" + */
-typedef struct GP_Framebuffer { - GP_Context context; - uint32_t bsize; - int con_fd; - int con_nr; - int last_con_nr; - int fb_fd; - char path[]; -} GP_Framebuffer; +#ifndef BACKENDS_GP_BACKENDS_H +#define BACKENDS_GP_BACKENDS_H
/* - * Initalize framebuffer. + * Base backend definitions. */ -GP_Framebuffer *GP_FramebufferInit(const char *path); +#include "GP_Backend.h"
/* - * Deinitalize framebuffer. + * Backends. */ -void GP_FramebufferExit(GP_Framebuffer *fb); +#include "GP_LinuxFB.h" +#include "GP_SDL.h"
-#endif /* GP_FRAMEBUFFER_H */ +#endif /* BACKENDS_GP_BACKENDS_H */ diff --git a/libs/backends/GP_Backend.c b/include/backends/GP_LinuxFB.h similarity index 52% rename from libs/backends/GP_Backend.c rename to include/backends/GP_LinuxFB.h index f705264..1fac9a4 100644 --- a/libs/backends/GP_Backend.c +++ b/include/backends/GP_LinuxFB.h @@ -16,72 +16,26 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * - * jiri.bluebear.dluhos@gmail.com * - * * - * Copyright (C) 2009-2010 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-#include "core/GP_Core.h" -#include "GP_Backend.h" -#include "../../config.h" +#ifndef BACKENDS_GP_FRAMEBUFFER_H +#define BACKENDS_GP_FRAMEBUFFER_H
-#include <string.h> +#include "GP_Backend.h"
/* - * The currently active backend (NULL if none). + * Initalize framebuffer. + * + * The path should point to framebuffer device eg. "/dev/fb0" for first + * framebuffer device. + * + * The GP_Backend structure is allocated and returned, the resources are + * deinitalized and the structure is freed by backed->Exit(backend); call. + * + * Upon failure NULL is returned. */ -static struct GP_Backend *current_backend = NULL; - -#ifdef HAVE_LIBSDL - -extern struct GP_Backend GP_SDL_backend; - -#endif - -struct GP_Backend *GP_InitBackend(const char *name) -{ - if (current_backend) - return current_backend; - -#ifdef HAVE_LIBSDL - - if (!name || strcasecmp(name, "sdl") == 0) { - current_backend = GP_SDL_backend.init_fn(); - return current_backend; - } - -#endif - - return NULL; -} - -struct GP_Backend *GP_GetCurrentBackend(void) -{ - return current_backend; -} - -GP_Context *GP_OpenBackendVideo(int w, int h, int flags) -{ - GP_CHECK(current_backend, "no current backend"); - return current_backend->open_video_fn(w, h, flags); -} - -struct GP_Context *GP_GetBackendVideoContext(void) -{ - GP_CHECK(current_backend, "no current backend"); - return current_backend->video_context_fn(); -} - -void GP_UpdateBackendVideo(void) -{ - GP_CHECK(current_backend, "no current backend"); - return current_backend->update_video_fn(); -} +GP_Backend *GP_BackendLinuxFBInit(const char *path);
-int GP_GetBackendEvent(struct GP_BackendEvent *event) -{ - GP_CHECK(current_backend, "no current backend"); - return current_backend->get_event_fn(event); -} +#endif /* BACKENDS_GP_FRAMEBUFFER_H */ diff --git a/include/backends/GP_Framebuffer.h b/include/backends/GP_SDL.h similarity index 76% rename from include/backends/GP_Framebuffer.h rename to include/backends/GP_SDL.h index 010ed7f..b6f0fab 100644 --- a/include/backends/GP_Framebuffer.h +++ b/include/backends/GP_SDL.h @@ -16,33 +16,21 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-#ifndef GP_FRAMEBUFFER_H -#define GP_FRAMEBUFFER_H +#ifndef BACKENDS_GP_SDL_H +#define BACKENDS_GP_SDL_H
-#include "core/GP_Context.h" - -typedef struct GP_Framebuffer { - GP_Context context; - uint32_t bsize; - int con_fd; - int con_nr; - int last_con_nr; - int fb_fd; - char path[]; -} GP_Framebuffer; - -/* - * Initalize framebuffer. - */ -GP_Framebuffer *GP_FramebufferInit(const char *path); +#include <stdint.h> +#include "GP_Backend.h"
/* - * Deinitalize framebuffer. + * Initalize SDL as drawing backend. + * + * Upon failure, or if SDL wasn't compiled in, NULL is returned. */ -void GP_FramebufferExit(GP_Framebuffer *fb); +GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h, uint16_t bpp);
-#endif /* GP_FRAMEBUFFER_H */ +#endif /* BACKENDS_GP_SDL_H */ diff --git a/libs/backends/GP_Framebuffer.c b/libs/backends/GP_LinuxFB.c similarity index 80% rename from libs/backends/GP_Framebuffer.c rename to libs/backends/GP_LinuxFB.c index 4eae632..d0ad3c7 100644 --- a/libs/backends/GP_Framebuffer.c +++ b/libs/backends/GP_LinuxFB.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
@@ -33,12 +33,22 @@ #include <linux/vt.h>
#include "core/GP_Debug.h" -#include "GP_Framebuffer.h" +#include "GP_LinuxFB.h" + +struct fb_priv { + GP_Context context; + uint32_t bsize; + int con_fd; + int con_nr; + int last_con_nr; + int fb_fd; + char path[]; +};
/* * Allocates and switches to newly allocated console. */ -static int allocate_console(struct GP_Framebuffer *fb) +static int allocate_console(struct fb_priv *fb) { struct vt_stat vts; int fd, nr; @@ -104,16 +114,57 @@ static int allocate_console(struct GP_Framebuffer *fb) return 0; }
-GP_Framebuffer *GP_FramebufferInit(const char *path) +/* Backend API callbacks */ + +static void fb_flip_noop(GP_Backend *self __attribute__((unused))) +{ + +} + +static void fb_update_rect_noop(GP_Backend *self __attribute__((unused)), + GP_Coord x1 __attribute__((unused)), + GP_Coord y1 __attribute__((unused)), + GP_Coord x2 __attribute__((unused)), + GP_Coord y2 __attribute__((unused))) +{ + +} + +static void fb_exit(GP_Backend *self) +{ + struct fb_priv *fb = GP_BACKEND_PRIV(self); + + /* unmap framebuffer */ + munmap(fb->context.pixels, fb->bsize); + close(fb->fb_fd); + + /* reset keyboard */ + ioctl(fb->con_fd, KDSETMODE, KD_TEXT); + + /* switch back console */ + if (fb->last_con_nr != -1) + ioctl(fb->con_fd, VT_ACTIVATE, fb->last_con_nr); + + close(fb->con_fd); + free(self); +} + +GP_Backend *GP_BackendLinuxFBInit(const char *path) { - GP_Framebuffer *fb = malloc(sizeof (GP_Framebuffer) + strlen(path) + 1); + GP_Backend *backend; + struct fb_priv *fb; struct fb_fix_screeninfo fscri; struct fb_var_screeninfo vscri; int fd; + + backend = malloc(sizeof(GP_Backend) + + sizeof(struct fb_priv) + strlen(path) + 1);
- if (fb == NULL) + if (backend == NULL) return NULL;
+ fb = GP_BACKEND_PRIV(backend); + if (allocate_console(fb)) goto err1;
@@ -181,7 +232,16 @@ GP_Framebuffer *GP_FramebufferInit(const char *path) fb->context.bytes_per_row = fscri.line_length; fb->context.pixel_type = pixel_type;
- return fb; + /* update API */ + backend->name = "Linux FB"; + backend->context = &fb->context; + backend->Flip = fb_flip_noop; + backend->UpdateRect = fb_update_rect_noop; + backend->Exit = fb_exit; + backend->fd_list = NULL; + backend->Poll = NULL; + + return backend; err3: close(fd); err2: @@ -194,23 +254,6 @@ err2: if (fb->last_con_nr != -1) ioctl(fb->con_fd, VT_ACTIVATE, fb->last_con_nr); err1: - free(fb); + free(backend); return NULL; } - -void GP_FramebufferExit(GP_Framebuffer *fb) -{ - /* unmap framebuffer */ - munmap(fb->context.pixels, fb->bsize); - close(fb->fb_fd); - - /* reset keyboard */ - ioctl(fb->con_fd, KDSETMODE, KD_TEXT); - - /* switch back console */ - if (fb->last_con_nr != -1) - ioctl(fb->con_fd, VT_ACTIVATE, fb->last_con_nr); - - close(fb->con_fd); - free(fb); -} diff --git a/libs/backends/GP_Backend_SDL.c b/libs/backends/GP_SDL.c similarity index 50% rename from libs/backends/GP_Backend_SDL.c rename to libs/backends/GP_SDL.c index 3b16d00..4083f09 100644 --- a/libs/backends/GP_Backend_SDL.c +++ b/libs/backends/GP_SDL.c @@ -19,42 +19,71 @@ * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * * jiri.bluebear.dluhos@gmail.com * * * - * Copyright (C) 2009-2010 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-#include "GP_Backend.h" #include "../../config.h"
+#include "core/GP_Debug.h" +#include "GP_Backend.h" + #ifdef HAVE_LIBSDL
-#include <dlfcn.h> #include <SDL/SDL.h>
-struct GP_Backend GP_SDL_backend; -static SDL_Surface *GP_SDL_display = NULL; -static GP_Context GP_SDL_context; +static SDL_Surface *sdl_surface; + +/* Backend API funcitons */ + +static void sdl_flip(struct GP_Backend *self __attribute__((unused))) +{ + SDL_Flip(sdl_surface); +}
-/* Functions from the SDL library, dynamically loaded in GP_SDL_InitFn(). */ -static void (*dyn_SDL_Quit)(void); -static int (*dyn_SDL_Init)(int); -static SDL_Surface *(*dyn_SDL_SetVideoMode)(int, int, int, uint32_t); -static void (*dyn_SDL_UpdateRect)(SDL_Surface *, int, int, int, int); -static int (*dyn_SDL_WaitEvent)(SDL_Event *); +static void sdl_update_rect(struct GP_Backend *self __attribute__((unused)), + GP_Coord x1, GP_Coord y1, GP_Coord x2, GP_Coord y2) +{ + SDL_UpdateRect(sdl_surface, x1, y1, x2, y2); +}
-/* User callbacks. */ -static void (*GP_SDL_update_video_callback)(void) = NULL; +static void sdl_exit(struct GP_Backend *self __attribute__((unused))) +{ + SDL_Quit(); +}
-inline GP_RetCode GP_SDL_ContextFromSurface( - GP_Context *context, SDL_Surface *surf) +static void sdl_poll(struct GP_Backend *self __attribute__((unused))) { - GP_CHECK(context, "context is NULL"); - GP_CHECK(surf, "surface is NULL"); + SDL_Event ev;
+ if (SDL_PollEvent(&ev)) { + printf("SDL EVENT!n"); + } +} + +static struct GP_Backend backend = { + .name = "SDL", + .context = NULL, + .Flip = sdl_flip, + .UpdateRect = sdl_update_rect, + .Exit = sdl_exit, + .fd_list = NULL, + .Poll = sdl_poll, +}; + +int context_from_surface(GP_Context *context, SDL_Surface *surf) +{ /* sanity checks on the SDL surface */ - if (surf->format->BytesPerPixel == 0 || surf->format->BytesPerPixel > 4) - return GP_ENOIMPL; - + if (surf->format->BytesPerPixel == 0) { + GP_DEBUG(1, "ERROR: Surface->BytesPerPixel == 0"); + return 1; + } + + if (surf->format->BytesPerPixel > 4) { + GP_DEBUG(1, "ERROR: Surface->BytesPerPixel > 4"); + return 1; + } + enum GP_PixelType pixeltype = GP_PixelRGBMatch(surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, @@ -62,7 +91,7 @@ inline GP_RetCode GP_SDL_ContextFromSurface( surf->format->BitsPerPixel);
if (pixeltype == GP_PIXEL_UNKNOWN) - return GP_ENOIMPL; + return 1;
/* basic structure and size */ context->pixels = surf->pixels; @@ -77,87 +106,41 @@ inline GP_RetCode GP_SDL_ContextFromSurface( context->x_swap = 0; context->y_swap = 0;
- return GP_ESUCCESS; -} - -static void GP_SDL_ShutdownFn(void) -{ - dyn_SDL_Quit(); -} - -static struct GP_Backend *GP_SDL_InitFn(void) -{ - void *library = dlopen("libSDL.so", RTLD_LAZY); - if (!library) - return NULL; - - dyn_SDL_Init = dlsym(library, "SDL_Init"); - dyn_SDL_Quit = dlsym(library, "SDL_Quit"); - dyn_SDL_UpdateRect = dlsym(library, "SDL_UpdateRect"); - dyn_SDL_SetVideoMode = dlsym(library, "SDL_SetVideoMode"); - dyn_SDL_WaitEvent = dlsym(library, "SDL_WaitEvent"); - - if (dyn_SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) - return NULL; - - return &GP_SDL_backend; + return 0; }
-static GP_Context *GP_SDL_OpenVideoFn(int w, int h, int flags) +GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h, uint16_t bpp) { - GP_SDL_display = dyn_SDL_SetVideoMode(w, h, 0, - SDL_SWSURFACE|SDL_DOUBLEBUF); - - if (GP_SDL_display == NULL) - return NULL; - - GP_RetCode retcode = GP_SDL_ContextFromSurface( - &GP_SDL_context, GP_SDL_display); - if (retcode != GP_ESUCCESS) - return NULL; - - return &GP_SDL_context; -} + /* SDL not yet initalized */ + if (backend.context != NULL) { + if (SDL_Init(SDL_INIT_VIDEO)) { + GP_DEBUG(1, "ERROR: SDL_Init: %s", SDL_GetError()); + return NULL; + } + + sdl_surface = SDL_SetVideoMode(w, h, bpp, SDL_SWSURFACE); + + if (sdl_surface == NULL) { + GP_DEBUG(1, "ERROR: SDL_SetVideoMode: %s", SDL_GetError()); + SDL_Quit(); + return NULL; + } + + if (context_from_surface(backend.context, sdl_surface)) { + GP_DEBUG(1, "ERROR: Failed to match pixel_type"); + SDL_Quit(); + return NULL; + } + }
-static GP_Context *GP_SDL_VideoContextFn(void) -{ - return &GP_SDL_context; + return &backend; }
-static void GP_SDL_UpdateVideoFn(void) -{ - dyn_SDL_UpdateRect(GP_SDL_display, 0, 0, - GP_SDL_display->w, GP_SDL_display->h); -} +#else
-static int GP_SDL_GetEventFn(struct GP_BackendEvent *event) +GP_Backend *GP_BackendSDLInit(void) { - SDL_Event sdl_event; - - if (dyn_SDL_WaitEvent(&sdl_event) == 0) - return 0; - - switch (sdl_event.type) { - case SDL_VIDEOEXPOSE: - event->type = GP_BACKEND_EVENT_UPDATE_VIDEO; - return 1; - case SDL_QUIT: - event->type = GP_BACKEND_EVENT_QUIT_REQUEST; - return 1; - } - - /* for the time being, unknown events are simply ignored */ - return 0; + return NULL; }
-struct GP_Backend GP_SDL_backend = { - .name = "SDL", - .init_fn = GP_SDL_InitFn, - .shutdown_fn = GP_SDL_ShutdownFn, - .open_video_fn = GP_SDL_OpenVideoFn, - .video_context_fn = GP_SDL_VideoContextFn, - .update_video_fn = GP_SDL_UpdateVideoFn, - .get_event_fn = GP_SDL_GetEventFn, -}; - #endif /* HAVE_LIBSDL */ diff --git a/libs/backends/Makefile b/libs/backends/Makefile index da08bb7..60bbdaf 100644 --- a/libs/backends/Makefile +++ b/libs/backends/Makefile @@ -1,5 +1,6 @@ TOPDIR=../.. CSOURCES=$(shell ls *.c) LIBNAME=backends +BUILDLIB=yes include $(TOPDIR)/include.mk include $(TOPDIR)/lib.mk diff --git a/tests/SDL/sierpinsky.c b/tests/SDL/sierpinsky.c index 04ad559..5d1e0f9 100644 --- a/tests/SDL/sierpinsky.c +++ b/tests/SDL/sierpinsky.c @@ -41,7 +41,7 @@ #define sgn(x) ((x)>0 ? 1 : -1)
SDL_Surface *display; -GP_Context *context; +GP_Context *context, ctx;
SDL_TimerID timer;
@@ -109,7 +109,7 @@ static void draw(int x, int y, int l, int iter) sierpinsky(x2, y2, x3, y3, iter/60%6); sierpinsky(x3, y3, x1, y1, iter/60%6);
- GP_UpdateBackendVideo(); + SDL_Flip(display); }
int paused = 0; @@ -137,16 +137,6 @@ int main(void) { SDL_Event ev;
- if (!GP_InitBackend("SDL")) { - fprintf(stderr, "error: could not initialize backendn"); - return 2; - } - if (!GP_OpenBackendVideo(DISPLAY_W, DISPLAY_H, 0)) { - fprintf(stderr, "error: could not open videon"); - return 2; - } - -/* if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) return -1;
@@ -157,11 +147,9 @@ int main(void) return -1; }
- GP_SDL_ContextFromSurface(&context, display); -*/ + GP_SDL_ContextFromSurface(&ctx, display);
- display = SDL_GetVideoSurface(); - context = GP_GetBackendVideoContext(); + context = &ctx;
black = GP_ColorToContextPixel(GP_COL_BLACK, context); blue = GP_ColorToContextPixel(GP_COL_BLUE, context); diff --git a/tests/core/Makefile b/tests/core/Makefile index 56955b9..9cef404 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -2,7 +2,7 @@ TOPDIR=../..
LIBNAME=core TESTSUITE=core_suite -LDLIBS+=-lGP -L$(TOPDIR)/build/ -lcheck -lm -ldl +LDLIBS+=-lGP -L$(TOPDIR)/build/ -lcheck -lm -lSDL GENSOURCES+=GP_Convert.test.gen.c GP_WritePixel.test.gen.c GP_MixPixels.test.gen.c
diff --git a/tests/drivers/Makefile b/tests/drivers/Makefile index afba820..dcf4129 100644 --- a/tests/drivers/Makefile +++ b/tests/drivers/Makefile @@ -2,7 +2,7 @@ TOPDIR=../..
CSOURCES=$(shell echo *.c)
-LDLIBS+=-lGP -lGP_SDL -lSDL -L$(TOPDIR)/build/ +LDLIBS+=-lGP -lGP_backends -lSDL -L$(TOPDIR)/build/
APPS=$(CSOURCES:.c=)
diff --git a/tests/drivers/framebuffer_test.c b/tests/drivers/framebuffer_test.c index c2595d2..29cdb3a 100644 --- a/tests/drivers/framebuffer_test.c +++ b/tests/drivers/framebuffer_test.c @@ -16,15 +16,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- Framebuffer test. - - 1. Draw to the framebuffer + Backend test. + + 1. Draw to the backend 2. Sleep 3. Exit
@@ -33,7 +33,7 @@ #include <math.h>
#include <GP.h> -#include <backends/GP_Framebuffer.h> +#include <backends/GP_Backends.h>
static void draw(GP_Context *context, int x, int y, int l) { @@ -57,18 +57,21 @@ static void draw(GP_Context *context, int x, int y, int l)
int main(void) { - GP_Framebuffer *fb; + GP_Backend *backend; + GP_Context *context; GP_TextStyle style;
GP_SetDebugLevel(10);
- fb = GP_FramebufferInit("/dev/fb0"); + backend = GP_BackendLinuxFBInit("/dev/fb0"); - if (fb == NULL) { + if (backend == NULL) { fprintf(stderr, "Failed to initalize framebuffern"); return 1; } + context = backend->context; + GP_DefaultTextStyle(&style);
style.pixel_xspace = 2; @@ -76,24 +79,26 @@ int main(void)
GP_Pixel gray, black;
- gray = GP_RGBToContextPixel(200, 200, 200, &fb->context); - black = GP_RGBToContextPixel(0, 0, 0, &fb->context); + gray = GP_RGBToContextPixel(200, 200, 200, context); + black = GP_RGBToContextPixel(0, 0, 0, context); const char *text = "Framebuffer test";
- GP_Fill(&fb->context, gray); - GP_Line(&fb->context, 0, 0, fb->context.w, fb->context.h, black); - GP_Line(&fb->context, 0, fb->context.h, fb->context.w, 0, black); - GP_Text(&fb->context, &style, - (fb->context.w - GP_TextWidth(&style, text))/2, + GP_Fill(context, gray); + GP_Line(context, 0, 0, context->w, context->h, black); + GP_Line(context, 0, context->h, context->w, 0, black); + GP_Text(context, &style, + (context->w - GP_TextWidth(&style, text))/2, 16, GP_ALIGN_RIGHT|GP_VALIGN_BELOW, black, gray, text);
- draw(&fb->context, fb->context.w / 2, 2.00 * fb->context.h / 3, 60); + draw(context, context->w / 2, 2.00 * context->h / 3, 60); + + GP_BackendFlip(backend);
sleep(10);
- GP_FramebufferExit(fb); + GP_BackendExit(backend);
return 0; } diff --git a/tests/drivers/sierpinsky.c b/tests/drivers/sierpinsky.c deleted file mode 100644 index c113e1e..0000000 --- a/tests/drivers/sierpinsky.c +++ /dev/null @@ -1,143 +0,0 @@ -/***************************************************************************** - * This file is part of gfxprim library. * - * * - * Gfxprim is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * Gfxprim is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with gfxprim; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, * - * Boston, MA 02110-1301 USA * - * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * - * * - *****************************************************************************/ - -/* - - Simple test for triangle drawing runtime. - - */ - -#include <GP.h> -#include <backends/GP_Framebuffer.h> - -#include <math.h> - -#define TIMER_TICK 50 -#define DISPLAY_W 640 -#define DISPLAY_H 480 -#define sqr(x) ((x)*(x)) -#define sgn(x) ((x)>0 ? 1 : -1) - -int iter, l, way = 1; - -GP_Pixel black, blue, gray; - -static void sierpinsky(GP_Context *context, GP_Pixel pixel, float x1, float y1, float x4, float y4, int iter) -{ - float x2, y2, x3, y3, x5, y5; - - if (iter <= 0) { - GP_Line(context, x1, y1, x4, y4, black); - return; - } - - x2 = floor((2*x1 + x4)/3); - y2 = floor((2*y1 + y4)/3); - - x3 = floor((2*x4 + x1)/3); - y3 = floor((2*y4 + y1)/3); - - x5 = (x1+x4)/2 + (y2 - y3)*sqrt(3.00/4); - y5 = (y1+y4)/2 + (x3 - x2)*sqrt(3.00/4); - - GP_FillTriangle(context, x2, y2, x3, y3, x5, y5, pixel); - - sierpinsky(context, pixel, x1, y1, x2, y2, iter - 1); - sierpinsky(context, pixel, x2, y2, x5, y5, iter - 1); - sierpinsky(context, pixel, x5, y5, x3, y3, iter - 1); - sierpinsky(context, pixel, x3, y3, x4, y4, iter - 1); -} - -static void draw(GP_Context *context, int x, int y, int l, int iter) -{ - float x1, y1, x2, y2, x3, y3; - int w = context->w; - int h = context->h; - - l = ((w < h ? w : h) - 20)/(5 - 1.00*iter/120); - - x1 = sin(1.00 * iter/57) * l + x; - y1 = cos(1.00 * iter/57) * l + y; - - x2 = sin(1.00 * (iter+120)/57) * l + x; - y2 = cos(1.00 * (iter+120)/57) * l + y; - - x3 = sin(1.00 * (iter+240)/57) * l + x; - y3 = cos(1.00 * (iter+240)/57) * l + y; - - GP_Fill(context, gray); - - GP_FillTriangle(context, x1, y1, x2, y2, x3, y3, blue); - - sierpinsky(context, blue, x1, y1, x2, y2, iter/60%6); - sierpinsky(context, blue, x2, y2, x3, y3, iter/60%6); - sierpinsky(context, blue, x3, y3, x1, y1, iter/60%6); -} - -static void redraw(GP_Context *context) -{ - iter += 2 * way; - - if (iter + 2 * way > 350) - way *= -1; - - if (iter < 2 * way) - way *= 1; - - - draw(context, context->w/2, context->h/2, l, iter); -} - -int main(void) -{ - GP_Framebuffer *fb; - GP_Context *context; - int i; - - GP_SetDebugLevel(10); - - fb = GP_FramebufferInit("/dev/fb0"); - - if (fb == NULL) { - fprintf(stderr, "failed to initalize framebuffern"); - return 1; - } - - context = &fb->context; - - gray = GP_ColorToContextPixel(GP_COL_GRAY_LIGHT, context); - blue = GP_ColorToContextPixel(GP_COL_BLUE, context); - black = GP_ColorToContextPixel(GP_COL_BLACK, context); - - iter = 0; - draw(context, context->w/2, context->h/2, l, iter); - - for (i = 0; i < 300; i++) { - redraw(context); - usleep(10000); - } - - GP_FramebufferExit(fb); - - return 0; -} -
-----------------------------------------------------------------------
Summary of changes: build/get_objs.sh | 2 +- demos/fbshow/Makefile | 2 +- demos/fbshow/fbshow.c | 81 +++++----- demos/grinder/Makefile | 2 +- include/backends/GP_Backend.h | 152 ++++++++++++----- .../GP_InputDriverSDL.h => backends/GP_Backends.h} | 20 ++- .../backends/{GP_Framebuffer.h => GP_LinuxFB.h} | 35 ++--- .../GP_InputDriverSDL.h => backends/GP_SDL.h} | 21 +-- libs/backends/GP_Backend.c | 87 ---------- libs/backends/{GP_Framebuffer.c => GP_LinuxFB.c} | 93 ++++++++--- libs/backends/{GP_Backend_SDL.c => GP_SDL.c} | 173 +++++++++----------- libs/backends/Makefile | 1 + tests/SDL/sierpinsky.c | 20 +-- tests/core/Makefile | 2 +- tests/drivers/Makefile | 2 +- tests/drivers/framebuffer_test.c | 39 +++-- tests/drivers/sierpinsky.c | 143 ---------------- 17 files changed, 361 insertions(+), 514 deletions(-) copy include/{input/GP_InputDriverSDL.h => backends/GP_Backends.h} (83%) rename include/backends/{GP_Framebuffer.h => GP_LinuxFB.h} (75%) copy include/{input/GP_InputDriverSDL.h => backends/GP_SDL.h} (82%) delete mode 100644 libs/backends/GP_Backend.c rename libs/backends/{GP_Framebuffer.c => GP_LinuxFB.c} (80%) rename libs/backends/{GP_Backend_SDL.c => GP_SDL.c} (50%) delete mode 100644 tests/drivers/sierpinsky.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.