diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-08-06 05:58:46 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-08-06 05:58:46 +0200 |
commit | 3a9de46457dbd877bf12712fe85f398043bb7920 (patch) | |
tree | 75a389c69239704017706e6e99bf36d23ab040f3 /src/framebuffer.c | |
parent | framebuffer.c: fb_count (diff) | |
download | crt-calibrator-3a9de46457dbd877bf12712fe85f398043bb7920.tar.gz crt-calibrator-3a9de46457dbd877bf12712fe85f398043bb7920.tar.bz2 crt-calibrator-3a9de46457dbd877bf12712fe85f398043bb7920.tar.xz |
drawing to the framebuffer
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/framebuffer.c')
-rw-r--r-- | src/framebuffer.c | 113 |
1 files changed, 112 insertions, 1 deletions
diff --git a/src/framebuffer.c b/src/framebuffer.c index 91a9b2a..6e5e1f4 100644 --- a/src/framebuffer.c +++ b/src/framebuffer.c @@ -19,6 +19,13 @@ #include <unistd.h> #include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <stropts.h> +#include <linux/fb.h> +#include <errno.h> /** @@ -30,13 +37,20 @@ /** + * The number of elements to allocates to a buffer for a framebuffer device pathname + */ +#define FB_DEVICE_MAX_LEN (sizeof(FB_DEVICE_PATTERN) / sizeof(char) + 3 * sizeof(size_t)) + + + +/** * Figure out how many framebuffers there are on the system * * @return The number of framebuffers on the system */ size_t fb_count(void) { - char buf[sizeof(FB_DEVICE_PATTERN) / sizeof(char) + 3 * sizeof(size_t)]; + char buf[FB_DEVICE_MAX_LEN]; size_t count = 0; for (;; count++) @@ -47,3 +61,100 @@ size_t fb_count(void) } } + +/** + * Open a framebuffer + * + * @param index The index of the framebuffer to open + * @param fb Framebuffer information to fill in + * @return Zero on success, -1 on error + */ +int fb_open(size_t index, framebuffer_t* restrict fb) +{ + char buf[FB_DEVICE_MAX_LEN]; + struct fb_fix_screeninfo fix_info; + struct fb_var_screeninfo var_info; + int old_errno; + + fb->fd = 0; + fb->mem = MAP_FAILED; + + sprintf(buf, FB_DEVICE_PATTERN, index); + fb->fd = open(buf, O_RDWR); + if (fb->fd == 0) + goto fail; + + if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fix_info) || + ioctl(fb->fd, FBIOGET_VSCREENINFO, &var_info)) + goto fail; + + fb->mem = mmap(NULL, fix_info.smem_len, PROT_WRITE, MAP_SHARED, fb->fd, 0); + if (fb->mem == MAP_FAILED) + goto fail; + + fb->mem += var_info.xoffset * (var_info.bits_per_pixel / 8); + fb->mem += var_info.yoffset * fix_info.line_length; + + fb->width = var_info.xres; + fb->height = var_info.yres; + fb->bytes_per_pixel = var_info.bits_per_pixel / 8; + fb->line_length = fix_info.line_length; + + return 0; + fail: + old_errno = errno; + fb_close(fb); + errno = old_errno; + return -1; +} + + +/** + * Close a framebuffer + * + * @param fb The framebuffer information + */ +void fb_close(framebuffer_t* restrict fb) +{ + if (fb->fd) + close(fb->fd); +} + + +uint32_t fb_colour(int red, int green, int blue) +{ + uint32_t rc = 0; + rc |= red, rc <<= 8; + rc |= green, rc <<= 8; + rc |= blue; + return rc; +} + + +void fb_fill_rectangle(framebuffer_t* restrict fb, uint32_t colour, + uint32_t x, uint32_t y, uint32_t width, uint32_t height) +{ + int8_t* mem = fb->mem + y * fb->line_length; + size_t x1 = x * fb->bytes_per_pixel; + size_t x2 = (x + width) * fb->bytes_per_pixel; + size_t y2 = y + height; + size_t x_, y_; + + for (y_ = y; y_ != y2; y_++, mem += fb->line_length) + for (x_ = x1; x_ != x2; x_ += fb->bytes_per_pixel) + { + int8_t* pixel = mem + x_; + *(uint32_t*)pixel = colour; + } +} + + +int main() +{ + framebuffer_t fb; + fb_open(0, &fb); + fb_fill_rectangle(&fb, fb_colour(36, 149, 190), 20, 20, fb.width - 40, fb.height - 40); + fb_close(&fb); + return 0; +} + |