diff --git a/native/framebuffers.c b/native/framebuffers.c index ce2601d..ae04a25 100644 --- a/native/framebuffers.c +++ b/native/framebuffers.c @@ -19,10 +19,8 @@ void pyfb_init(void) { framebuffers[i].users = 0; framebuffers[i].fb_info.fb_size_b = 0; framebuffers[i].u32_buffer = NULL; - - atomic_flag flag = ATOMIC_FLAG_INIT; - - framebuffers[i].fb_lock = flag; + atomic_flag flag = ATOMIC_FLAG_INIT; + framebuffers[i].fb_lock = flag; } } @@ -110,9 +108,6 @@ int pyfb_open(uint8_t fbnum) { if(buffer == NULL) { // got out of memory for the offscreen buffers - if(buffer != NULL) { - free(buffer); - } // free up all other resources for the new buffer close(fb_fd); @@ -234,10 +229,10 @@ void pyfb_vinfo(uint8_t fbnum, struct pyfb_videomode_info* info_ptr) { unlock(framebuffers[fbnum].fb_lock); } -void pyfb_flushBuffer(uint8_t fbnum) { +int pyfb_flushBuffer(uint8_t fbnum) { // first test if this device number is valid if(fbnum >= MAX_FRAMEBUFFERS) { - return; + return -1; } lock(framebuffers[fbnum].fb_lock); @@ -246,19 +241,27 @@ void pyfb_flushBuffer(uint8_t fbnum) { if(framebuffers[fbnum].fb_fd == -1) { // this framebuffer is not in use, so ignore unlock(framebuffers[fbnum].fb_lock); - return; + return -1; } // if we get here, flush the offscreen buffer to the framebuffer - lseek(framebuffers[fbnum].fb_fd, 0L, SEEK_SET); + if(lseek(framebuffers[fbnum].fb_fd, 0L, SEEK_SET) == -1) { + unlock(framebuffers[fbnum].fb_lock); + return -1; + } + + size_t buf_len = (size_t)framebuffers[fbnum].fb_info.fb_size_b; + unsigned long int exitcode = 0; + if(framebuffers[fbnum].fb_info.vinfo.bits_per_pixel == 32) { - write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u32_buffer, (size_t)framebuffers[fbnum].fb_info.fb_size_b); + exitcode = (unsigned int)write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u32_buffer, buf_len); } else { - write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u16_buffer, (size_t)framebuffers[fbnum].fb_info.fb_size_b); + exitcode = (unsigned int)write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u16_buffer, buf_len); } // okay, ready flushed unlock(framebuffers[fbnum].fb_lock); + return buf_len == exitcode ? 0 : -1; } /** @@ -308,6 +311,7 @@ void __APISTATUS_internal pyfb_setPixel(uint8_t fbnum, // do unsigned int xres = framebuffers[fbnum].fb_info.vinfo.xres; unsigned int width = framebuffers[fbnum].fb_info.vinfo.bits_per_pixel; + if(width == 16) { pyfb_pixel16(fbnum, x, y, color, xres); } else { @@ -343,6 +347,7 @@ void pyfb_ssetPixel(uint8_t fbnum, unsigned long int x, unsigned long int y, con // else all is okay and we can continue unsigned int width = framebuffers[fbnum].fb_info.vinfo.bits_per_pixel; + if(width == 16) { pyfb_pixel16(fbnum, x, y, color, xres); } else { @@ -388,6 +393,7 @@ void pyfb_sdrawHorizontalLine(uint8_t fbnum, // Now test if the ranges are okay unsigned long int xres = framebuffers[fbnum].fb_info.vinfo.xres; unsigned long int yres = framebuffers[fbnum].fb_info.vinfo.yres; + if(y >= yres) { unlock(framebuffers[fbnum].fb_lock); return; @@ -440,6 +446,7 @@ void pyfb_sdrawVerticalLine(uint8_t fbnum, // Now test if the ranges are okay unsigned long int xres = framebuffers[fbnum].fb_info.vinfo.xres; unsigned long int yres = framebuffers[fbnum].fb_info.vinfo.yres; + if(y >= yres || (y + len - 1) >= yres) { unlock(framebuffers[fbnum].fb_lock); return; diff --git a/native/module_pyfb.c b/native/module_pyfb.c index ace5ba7..0a25226 100644 --- a/native/module_pyfb.c +++ b/native/module_pyfb.c @@ -140,6 +140,27 @@ static PyObject* pyfunc_pyfb_sdrawVerticalLine(PyObject* self, PyObject* args) { return PyLong_FromLong(exitcode); } +/** + * Python wrapper for the pyfb_flushBuffer function. + * + * @param self The function + * @param args The arguments, expecting long of the fbnum + * + * @return The exitstatus + */ +static PyObject* pyfunc_pyfb_flushBuffer(PyObject* self, PyObject* args) { + unsigned char fbnum_c; + + if(!PyArg_ParseTuple(args, "b", &fbnum_c)) { + PyErr_SetString(PyExc_TypeError, "Expecting arguments of type (byte)"); + return NULL; + } + + // Now invoke the function + int exitcode = pyfb_flushBuffer((uint8_t)fbnum_c); + return PyLong_FromLong(exitcode); +} + // The module def /** @@ -151,6 +172,7 @@ static PyMethodDef pyfb_methods[] = { {"pyfb_setPixel", pyfunc_pyfb_ssetPixel, METH_VARARGS, "Draw a pixel on the framebuffer"}, {"pyfb_drawHorizontalLine", pyfunc_pyfb_sdrawHorizontalLine, METH_VARARGS, "Draw a horizontal line on the framebuffer"}, {"pyfb_drawVerticalLine", pyfunc_pyfb_sdrawVerticalLine, METH_VARARGS, "Draw a vertical line on the framebuffer"}, + {"pyfb_flushBuffer", pyfunc_pyfb_flushBuffer, METH_VARARGS, "Flush the offscreen buffer to the framebuffer"}, {NULL, NULL, 0, NULL}}; static struct PyModuleDef module__pyfb = {PyModuleDef_HEAD_INIT, diff --git a/native/pyframebuffer.h b/native/pyframebuffer.h index 70912e9..7136d84 100644 --- a/native/pyframebuffer.h +++ b/native/pyframebuffer.h @@ -360,7 +360,9 @@ extern void __APISTATUS_internal pyfb_drawVerticalLine(uint8_t fbnum, * it says that it can take something between 20 and 100 milliseconds. * * @param fbnum The framebuffer number of which to flush all buffers + * + * @return If succeeded 0, else -1 */ -extern void pyfb_flushBuffer(uint8_t fbnum); +extern int pyfb_flushBuffer(uint8_t fbnum); #endif \ No newline at end of file