aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/framebuffer.c113
-rw-r--r--src/framebuffer.h60
2 files changed, 172 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;
+}
+
diff --git a/src/framebuffer.h b/src/framebuffer.h
index d3f170e..1dffb82 100644
--- a/src/framebuffer.h
+++ b/src/framebuffer.h
@@ -20,6 +20,45 @@
#include <stddef.h>
+#include <stdint.h>
+
+
+/**
+ * Framebuffer information
+ */
+typedef struct framebuffer
+{
+ /**
+ * The file descriptor used to access the framebuffer, 0 if not opened
+ */
+ int fd;
+
+ /**
+ * The width of the display in pixels
+ */
+ uint32_t width;
+
+ /**
+ * The height of the display in pixels
+ */
+ uint32_t height;
+
+ /**
+ * Increment for `mem` to move to next pixel on the line
+ */
+ uint32_t bytes_per_pixel;
+
+ /**
+ * Increment for `mem` to move down one line but stay in the same column
+ */
+ uint32_t line_length;
+
+ /**
+ * Framebuffer pointer, `MAP_FAILED` (from <sys/mman.h>) if not mapped
+ */
+ int8_t* mem;
+
+} framebuffer_t;
/**
@@ -29,6 +68,27 @@
*/
size_t fb_count(void);
+/**
+ * Open a framebuffer
+ *
+ * @param index The index of the framebuffer to open
+ * @param fb Framevuffer information to fill in
+ * @return Zero on success, -1 on error
+ */
+int fb_open(size_t index, framebuffer_t* restrict fb);
+
+/**
+ * Close a framebuffer
+ *
+ * @param fb The framebuffer information
+ */
+void fb_close(framebuffer_t* restrict fb);
+
+uint32_t fb_colour(int red, int green, int blue);
+
+void fb_fill_rectangle(framebuffer_t* restrict fb, uint32_t colour,
+ uint32_t x, uint32_t y, uint32_t width, uint32_t height);
+
#endif