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, generate has been updated via 37c452a809960d666b96c68e30349aa8e17041a7 (commit) from 711ed658bc24822ac5d4d08a8eb435352f08036f (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/37c452a809960d666b96c68e30349aa8e1704...
commit 37c452a809960d666b96c68e30349aa8e17041a7 Author: Cyril Hrubis metan@ucw.cz Date: Thu Oct 13 22:34:48 2011 +0200
Started to work on framebuffer driver (again).
diff --git a/include/backends/GP_Framebuffer.h b/include/backends/GP_Framebuffer.h new file mode 100644 index 0000000..010ed7f --- /dev/null +++ b/include/backends/GP_Framebuffer.h @@ -0,0 +1,48 @@ +/***************************************************************************** + * 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 * + * * + *****************************************************************************/ + +#ifndef GP_FRAMEBUFFER_H +#define GP_FRAMEBUFFER_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); + +/* + * Deinitalize framebuffer. + */ +void GP_FramebufferExit(GP_Framebuffer *fb); + +#endif /* GP_FRAMEBUFFER_H */ diff --git a/include/core/GP_Pixel.h b/include/core/GP_Pixel.h index fb38acb..2b06cee 100644 --- a/include/core/GP_Pixel.h +++ b/include/core/GP_Pixel.h @@ -158,13 +158,23 @@ static inline void GP_PixelPrint(GP_Pixel pixel, GP_PixelType type) }
/* - * Match pixel type to known pixel types, pixel_size is in bits. + * Match pixel type to known pixel types. * * Returns either valid PixelType or GP_PIXEL_UNKNOWN */ GP_PixelType GP_PixelRGBMatch(GP_Pixel rmask, GP_Pixel gmask, GP_Pixel bmask, GP_Pixel amask, - uint8_t pixel_size); + uint8_t bits_per_pixel);
+/* + * Similar to GP_PixelRGBMatch but works with offsets and sizes + * + * Returns either valid PixelType or GP_PIXEL_UNKNOWN + */ +GP_PixelType GP_PixelRGBLookup(uint32_t rsize, uint32_t roff, + uint32_t gsize, uint32_t goff, + uint32_t bsize, uint32_t boff, + uint32_t asize, uint32_t aoff, + uint8_t bits_per_pixel);
#endif /* GP_PIXEL_H */ diff --git a/libs/backends/GP_Framebuffer.c b/libs/backends/GP_Framebuffer.c new file mode 100644 index 0000000..4eae632 --- /dev/null +++ b/libs/backends/GP_Framebuffer.c @@ -0,0 +1,216 @@ +/***************************************************************************** + * 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 * + * * + *****************************************************************************/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> + +#include <linux/fb.h> +#include <linux/kd.h> +#include <linux/vt.h> + +#include "core/GP_Debug.h" +#include "GP_Framebuffer.h" + +/* + * Allocates and switches to newly allocated console. + */ +static int allocate_console(struct GP_Framebuffer *fb) +{ + struct vt_stat vts; + int fd, nr; + char buf[255]; + + /* allocate and switch to new console */ + fd = open("/dev/tty1", O_WRONLY); + + if (fd < 0) { + GP_DEBUG(1, "Opening console /dev/tty1 failed: %s", + strerror(errno)); + return -1; + } + + if (ioctl(fd, VT_OPENQRY, &nr) < 0) { + GP_DEBUG(1, "Failed to ioctl VT_OPENQRY /dev/tty1: %s", + strerror(errno)); + close(fd); + return -1; + } + + close(fd); + + snprintf(buf, sizeof(buf), "/dev/tty%i", nr); + fd = open(buf, O_RDWR); + + if (fd < 0) { + GP_DEBUG(1, "Opening console %s failed: %s", + buf, strerror(errno)); + close(fd); + return -1; + } + + if (ioctl(fd, VT_GETSTATE, &vts) == 0) + fb->last_con_nr = vts.v_active; + else + fb->last_con_nr = -1; + + if (ioctl(fd, VT_ACTIVATE, nr) < 0) { + GP_DEBUG(1, "Failed to ioctl VT_ACTIVATE %s: %s", + buf, strerror(errno)); + close(fd); + return -1; + } + + if (ioctl(fd, VT_WAITACTIVE, nr) < 0) { + GP_DEBUG(1, "Failed to ioctl VT_WAITACTIVE %s: %s", + buf, strerror(errno)); + close(fd); + return -1; + } + + /* turn off blinking cursor */ + if (ioctl(fd, KDSETMODE, KD_GRAPHICS) < 0) { + GP_DEBUG(1, "Failed to ioctl KDSETMODE %s: %s", + buf, strerror(errno)); + close(fd); + } + + fb->con_nr = nr; + fb->con_fd = fd; + + return 0; +} + +GP_Framebuffer *GP_FramebufferInit(const char *path) +{ + GP_Framebuffer *fb = malloc(sizeof (GP_Framebuffer) + strlen(path) + 1); + struct fb_fix_screeninfo fscri; + struct fb_var_screeninfo vscri; + int fd; + + if (fb == NULL) + return NULL; + + if (allocate_console(fb)) + goto err1; + + /* open and mmap framebuffer */ + fd = open(path, O_RDWR); + + if (fd < 0) { + GP_DEBUG(1, "Opening framebuffer failed: %s", strerror(errno)); + goto err2; + } + + if (ioctl(fd, FBIOGET_FSCREENINFO, &fscri) < 0) { + GP_DEBUG(1, "Failed to ioctl FBIOGET_FSCREENINFO: %s", + strerror(errno)); + goto err3; + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &vscri) < 0) { + GP_DEBUG(1, "Failed to ioctl FBIOGET_VSCREENINFO: %s", + strerror(errno)); + goto err3; + } + + /* + * Framebuffer is grayscale. + */ + if (vscri.grayscale) { + //TODO + goto err3; + } + + enum GP_PixelType pixel_type; + pixel_type = GP_PixelRGBLookup(vscri.red.length, vscri.red.offset, + vscri.green.length, vscri.green.offset, + vscri.blue.length, vscri.blue.offset, + vscri.transp.length, vscri.transp.offset, + vscri.bits_per_pixel); + + if (pixel_type == GP_PIXEL_UNKNOWN) { + GP_DEBUG(1, "Unknown pixel typen"); + goto err3; + } + + fb->context.pixels = mmap(NULL, fscri.smem_len, + PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, + fd, 0); + + if (fb->context.pixels == MAP_FAILED) { + GP_DEBUG(1, "mmaping framebuffer failed: %s", strerror(errno)); + goto err3; + } + + fb->fb_fd = fd; + fb->bsize = fscri.smem_len; + strcpy(fb->path, path); + + fb->context.w = vscri.xres; + fb->context.h = vscri.yres; + + fb->context.axes_swap = 0; + fb->context.x_swap = 0; + fb->context.y_swap = 0; + + fb->context.bpp = vscri.bits_per_pixel; + fb->context.bytes_per_row = fscri.line_length; + fb->context.pixel_type = pixel_type; + + return fb; +err3: + close(fd); +err2: + close(fb->con_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); +err1: + free(fb); + 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/core/GP_Pixel.c b/libs/core/GP_Pixel.c index bd9f463..98dc0d0 100644 --- a/libs/core/GP_Pixel.c +++ b/libs/core/GP_Pixel.c @@ -58,19 +58,19 @@ static int match(const GP_PixelTypeChannel *channel, GP_Pixel mask)
GP_PixelType GP_PixelRGBMatch(GP_Pixel rmask, GP_Pixel gmask, GP_Pixel bmask, GP_Pixel amask, - uint8_t pixel_size) + uint8_t bits_per_pixel) { unsigned int i;
GP_DEBUG(1, "Matching Pixel R %08x G %08x B %08x A %08x size %u", - rmask, gmask, bmask, amask, pixel_size); + rmask, gmask, bmask, amask, bits_per_pixel);
for (i = 0; i < GP_PIXEL_MAX; i++) { int res;
const GP_PixelTypeChannel *r, *g, *b, *a;
- if (GP_PixelTypes[i].size != pixel_size) + if (GP_PixelTypes[i].size != bits_per_pixel) continue;
r = get_channel(&GP_PixelTypes[i], "R"); @@ -79,7 +79,7 @@ GP_PixelType GP_PixelRGBMatch(GP_Pixel rmask, GP_Pixel gmask, a = get_channel(&GP_PixelTypes[i], "A");
GP_DEBUG(2, "Trying Pixel %s %u", - GP_PixelTypes[i].name, pixel_size); + GP_PixelTypes[i].name, bits_per_pixel);
if (r) GP_DEBUG(3, "Matching R %i %i", r->size, r->offset); @@ -105,3 +105,48 @@ GP_PixelType GP_PixelRGBMatch(GP_Pixel rmask, GP_Pixel gmask,
return GP_PIXEL_UNKNOWN; } + + +GP_PixelType GP_PixelRGBLookup(uint32_t rsize, uint32_t roff, + uint32_t gsize, uint32_t goff, + uint32_t bsize, uint32_t boff, + uint32_t asize, uint32_t aoff, + uint8_t bits_per_pixel) +{ + unsigned int i; + + GP_DEBUG(1, "Looking up Pixel R %08x %08x G %08x %08x B %08x %08x size %u", + rsize, roff, gsize, goff, bsize, boff, bits_per_pixel); + + for (i = 0; i < GP_PIXEL_MAX; i++) { + const GP_PixelTypeChannel *r, *g, *b, *a; + + if (GP_PixelTypes[i].size != bits_per_pixel) + continue; + + GP_DEBUG(2, "Trying Pixel %s %u", + GP_PixelTypes[i].name, bits_per_pixel); + + r = get_channel(&GP_PixelTypes[i], "R"); + g = get_channel(&GP_PixelTypes[i], "G"); + b = get_channel(&GP_PixelTypes[i], "B"); + a = get_channel(&GP_PixelTypes[i], "A"); + + if (a == NULL && asize != 0) + continue; + + if (a != NULL && (a->offset != aoff || a->size != asize)) + continue; + + if (r->offset == roff && r->size == rsize && + g->offset == goff && g->size == gsize && + b->offset == boff && b->size == bsize) { + GP_DEBUG(1, "Pixel found type id %u name '%s'", + GP_PixelTypes[i].type, GP_PixelTypes[i].name); + + return GP_PixelTypes[i].type; + } + } + + return GP_PIXEL_UNKNOWN; +}
-----------------------------------------------------------------------
Summary of changes: .../drivers => include/backends}/GP_Framebuffer.h | 7 +-- include/core/GP_Pixel.h | 14 +++- {tests/drivers => libs/backends}/GP_Framebuffer.c | 73 +++++++++++++------- libs/core/GP_Pixel.c | 53 +++++++++++++- 4 files changed, 112 insertions(+), 35 deletions(-) copy {tests/drivers => include/backends}/GP_Framebuffer.h (86%) copy {tests/drivers => libs/backends}/GP_Framebuffer.c (70%)
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.