aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--host/Makefile4
-rw-r--r--host/font.c26
-rw-r--r--host/font.h6
-rw-r--r--host/main.c2
-rw-r--r--host/main.h2
-rw-r--r--host/matelight.py35
-rwxr-xr-xhost/server.py32
7 files changed, 90 insertions, 17 deletions
diff --git a/host/Makefile b/host/Makefile
index 345058b..a6b892f 100644
--- a/host/Makefile
+++ b/host/Makefile
@@ -1,6 +1,6 @@
-all: main.c font.c font.h color.c color.h gif.h gif.c
- gcc -shared -std=gnu11 -Wall -lm -o libbdf.so -g -O0 main.c font.c color.c
+all: main.c font.c font.h color.c color.h
+ gcc -shared -fPIC -std=gnu11 -Wall -lm -o libbdf.so -g -O0 main.c font.c color.c
clean:
rm libbdf.so
diff --git a/host/font.c b/host/font.c
index 494210d..85882ad 100644
--- a/host/font.c
+++ b/host/font.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
void render_glyph(glyph_t *g, color_t *buf, unsigned int bufwidth, unsigned int offx, unsigned int offy, color_t fg, color_t bg){
unsigned int bitmap_row_width = g->width/8;
@@ -30,7 +31,7 @@ glyphtable_t *read_bdf_file(char *filename){
goto error;
}
- glyphtable_t *glyph_table = read_bdf(fontfile, glyph_table, BLP_SIZE)
+ glyphtable_t *glyph_table = read_bdf(fontfile);
if(!glyph_table){
fprintf(stderr, "Error reading font file.\n");
goto error;
@@ -50,15 +51,16 @@ glyphtable_t *extend_glyphtable(glyphtable_t *glyph_table){
size_t newlen = oldlen + (oldlen<MAX_GLYPHTABLE_INCREMENT ? oldlen : MAX_GLYPHTABLE_INCREMENT);
if(oldlen == 0)
newlen = START_GLYPHTABLE_SIZE;
- glyph_t *newdata = realloc(glyph_table->data, newlen*sizeof(glyph_t));
+ glyph_t **newdata = realloc(glyph_table->data, newlen*sizeof(glyph_t*));
if(!newdata){
fprintf(stderr, "Cannot allocate bdf glyph buffer\n");
goto error;
}
glyph_table->data = newdata;
// Clear newly allocated memory area
- memset(glyph_table->data+oldlen, 0, (newlen-oldlen)*sizeof(glyph_t));
+ memset(glyph_table->data+oldlen, 0, (newlen-oldlen)*sizeof(glyph_t*));
glyph_table->size = newlen;
+ return glyph_table;
error:
free_glyphtable(glyph_table);
return NULL;
@@ -66,7 +68,7 @@ error:
void free_glyphtable(glyphtable_t *glyph_table){
if(glyph_table){
- for(unsigned int i=0; i<glyph_table->length; i++){
+ for(unsigned int i=0; i<glyph_table->size; i++){
free(glyph_table->data[i]);
}
free(glyph_table->data);
@@ -119,13 +121,6 @@ glyphtable_t *read_bdf(FILE *f){
fprintf(stderr, "Invalid ENCODING line: %s %s\n", line, args);
goto error;
}
- if(encoding > glyph_table->size){
- glyph_table = extend_glyphtable(glyph_table);
- if(!glyph_table){
- fprintf(stderr, "Cannot allocate glyph table.\n");
- goto error;
- }
- }
}else if(strcmp("BBX", line) == 0){
if(!args){
@@ -228,6 +223,15 @@ glyphtable_t *read_bdf(FILE *f){
}
i++;
}
+
+ if(encoding >= glyph_table->size){
+ glyph_table = extend_glyphtable(glyph_table);
+ if(!glyph_table){
+ fprintf(stderr, "Cannot extend glyph table.\n");
+ goto error;
+ }
+ }
+
memcpy(glyph_data, &current_glyph, sizeof(glyph_t));
glyph_table->data[encoding] = glyph_data;
diff --git a/host/font.h b/host/font.h
index 4a7fe63..e9fbb35 100644
--- a/host/font.h
+++ b/host/font.h
@@ -15,7 +15,7 @@ typedef struct {
} glyph_t;
typedef struct {
- glyph_t *t;
+ glyph_t **data;
size_t size;
} glyphtable_t;
@@ -25,7 +25,9 @@ typedef struct {
#define MAX_CSI_ELEMENTS 8
// We could also use some fancy hashtable here, but unifont includes about 57k glyphs so we would hardly save any memory.
-int read_bdf(FILE *f, glyph_t **glyph_table, unsigned int glyph_table_size);
+glyphtable_t *read_bdf(FILE *f);
+
+void free_glyphtable(glyphtable_t *glyph_table);
// Requires buf to point to a buffer at least of size glyph->width*glyph->height.
void render_glyph(glyph_t *glyph, color_t *buf, unsigned int bufwidth, unsigned int offx, unsigned int offy, color_t fg, color_t bg);
diff --git a/host/main.c b/host/main.c
index 0d5af6e..c6086e1 100644
--- a/host/main.c
+++ b/host/main.c
@@ -65,7 +65,7 @@ framebuffer_t *framebuffer_render_text(char *s, glyphtable_t *glyph_table){
p += inc;
if(c > glyph_table->size){
- fprintf(stderr, "Error rendering string: Codepoint 0x%lx out of valid range (0-%d).\n", (long int)c, glyph_table->size);
+ fprintf(stderr, "Error rendering string: Codepoint 0x%lx out of valid range (0-%ld).\n", (long int)c, glyph_table->size);
goto error;
}
diff --git a/host/main.h b/host/main.h
index 98c4ded..cf1dba7 100644
--- a/host/main.h
+++ b/host/main.h
@@ -4,7 +4,7 @@
#include "color.h"
#include "font.h"
-framebuffer_t *framebuffer_render_text(char *s, glyph_t **glyph_table, unsigned int glyph_table_size);
+framebuffer_t *framebuffer_render_text(char *s, glyphtable_t *glyph_table);
void console_render_buffer(framebuffer_t *fb);
#endif//__MAIN_H__
diff --git a/host/matelight.py b/host/matelight.py
new file mode 100644
index 0000000..f75ae80
--- /dev/null
+++ b/host/matelight.py
@@ -0,0 +1,35 @@
+import usb
+import colorsys
+import numpy as np
+import itertools
+
+CRATE_WIDTH = 5
+CRATE_HEIGHT = 4
+CRATES_X = 8
+CRATES_Y = 4
+
+DISPLAY_WIDTH = CRATES_X*CRATE_WIDTH
+DISPLAY_HEIGHT = CRATES_Y*CRATE_HEIGHT
+FRAME_SIZE = CRATE_WIDTH*CRATE_HEIGHT*3
+
+dev = usb.core.find(idVendor=0x1cbe, idProduct=0x0003)
+
+def sendframe(framedata):
+ """ Send a frame to the display
+
+ The argument contains a h * w array of 3-tuples of (r, g, b)-data or 4-tuples of (r, g, b, a)-data where the a
+ channel is ignored.
+ """
+ def chunks(l, n):
+ for i in xrange(0, len(l), n):
+ yield l[i:i+n]
+
+ for cx, cy in itertools.product(range(DISPLAY_WIDTH), range(DISPLAY_HEIGHT)):
+ data = [ v for x in range(CRATE_WIDTH) for y in range(CRATE_HEIGHT) for v in framedata[cy*CRATE_HEIGHT + y][cx*CRATE_WIDTH + x][:3] ]
+ if len(data) != FRAME_SIZE:
+ raise ValueError('Invalid frame data. Expected {} bytes, got {}.'.format(FRAME_SIZE, len(data)))
+ # Send framebuffer data
+ dev.write(0x01, bytes([0, x, y])+bytes(data))
+ # Send latch command
+ dev.write(0x01, b'\x01')
+
diff --git a/host/server.py b/host/server.py
new file mode 100755
index 0000000..c8e665a
--- /dev/null
+++ b/host/server.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+from ctypes import CDLL, POINTER, c_void_p, Structure, c_uint8, c_size_t, cast
+import numpy as np
+from matelight import sendframe
+
+class COLOR(Structure):
+ _fields_ = ('r', c_uint8), ('g', c_uint8), ('b', c_uint8), ('a', c_uint8)
+
+class FRAMEBUFFER(Structure):
+ _fields_ = ('data', POINTER(COLOR)), ('w', c_size_t), ('h', c_size_t)
+
+bdf = CDLL('./libbdf.so')
+bdf.read_bdf_file.restype = c_void_p
+bdf.framebuffer_render_text.restype = POINTER(FRAMEBUFFER)
+
+unifont = bdf.read_bdf_file('unifont.bdf')
+
+def render_text(text):
+ assert unifont
+ fb = bdf.framebuffer_render_text(str(text), unifont)
+ fbd = fb.contents
+ buf = np.ctypeslib.as_array(cast(fbd.data, POINTER(c_uint8)), shape=(fbd.h, fbd.w, 4))
+ # Set data pointer to NULL before freeing framebuffer struct to prevent free_framebuffer from also freeing the data
+ # buffer that is now used by numpy
+ fb.data = cast(c_void_p(), POINTER(COLOR))
+ bdf.free_framebuffer(fb)
+ return buf
+
+if __name__ == '__main__':
+ sendframe(render_text('test'));
+