summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2018-10-27 06:24:27 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2018-10-30 04:16:23 +0100
commitdf8233e4abbd0d626158abc5388957cc28b06c50 (patch)
tree3b6c151b8dba5201673dd8ae2842350822243cde /apps
parent80352c2c2d7ff005e0ad63e1b56d1f6ff9af81d8 (diff)
Lua expand multiple screen support
Some of the lcd functions had support for multiple screens but this wasn't very safe since the screen number wasn't bounded within the screens[] array This adds support for all the lcd functions along with checking that screen# is bounded properly, adds around 600 bytes to devices with a remote screen devices without a remote screen lock to SCREEN_MAIN Change-Id: I618bbc7b3919c7b0ff375fb2d71949d7cab43c87
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/lua/rocklib.c87
-rwxr-xr-xapps/plugins/lua/rocklib_aux.pl8
-rw-r--r--apps/plugins/lua/rocklib_img.c309
3 files changed, 303 insertions, 101 deletions
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c
index 80124d2165..c9242d99bd 100644
--- a/apps/plugins/lua/rocklib.c
+++ b/apps/plugins/lua/rocklib.c
@@ -56,66 +56,6 @@
#define RB_WRAP(func) static int rock_##func(lua_State UNUSED_ATTR *L)
#define SIMPLE_VOID_WRAPPER(func) RB_WRAP(func) { (void)L; func(); return 0; }
-/* Helper function for opt_viewport */
-static void check_tablevalue(lua_State *L,
- const char* key,
- int tablepos,
- void* res,
- bool is_unsigned)
-{
- lua_getfield(L, tablepos, key); /* Find table[key] */
-
- int val = lua_tointeger(L, -1);
-
- if(is_unsigned)
- *(unsigned*)res = (unsigned) val;
- else
- *(int*)res = val;
-
- lua_pop(L, 1); /* Pop the value off the stack */
-}
-
-static inline struct viewport* opt_viewport(lua_State *L,
- int narg,
- struct viewport* vp,
- struct viewport* alt)
-{
- if(lua_isnoneornil(L, narg))
- return alt;
-
- luaL_checktype(L, narg, LUA_TTABLE);
-
- check_tablevalue(L, "x", narg, &vp->x, false);
- check_tablevalue(L, "y", narg, &vp->y, false);
- check_tablevalue(L, "width", narg, &vp->width, false);
- check_tablevalue(L, "height", narg, &vp->height, false);
-#ifdef HAVE_LCD_BITMAP
- check_tablevalue(L, "font", narg, &vp->font, false);
- check_tablevalue(L, "drawmode", narg, &vp->drawmode, false);
-#endif
-#if LCD_DEPTH > 1
- check_tablevalue(L, "fg_pattern", narg, &vp->fg_pattern, true);
- check_tablevalue(L, "bg_pattern", narg, &vp->bg_pattern, true);
-#endif
-
- return vp;
-}
-
-RB_WRAP(set_viewport)
-{
- static struct viewport vp;
- int screen = luaL_optint(L, 2, SCREEN_MAIN);
- rb->screens[screen]->set_viewport(opt_viewport(L, 1, &vp, NULL));
- return 0;
-}
-
-RB_WRAP(clear_viewport)
-{
- int screen = luaL_optint(L, 1, SCREEN_MAIN);
- rb->screens[screen]->clear_viewport();
- return 0;
-}
-
RB_WRAP(current_tick)
{
lua_pushinteger(L, *rb->current_tick);
@@ -172,25 +112,6 @@ RB_WRAP(touchscreen_get_mode)
}
#endif
-RB_WRAP(font_getstringsize)
-{
- const unsigned char* str = luaL_checkstring(L, 1);
- int fontnumber = luaL_checkint(L, 2);
- int w, h;
-
- if (fontnumber == FONT_UI)
- fontnumber = rb->global_status->font_id[SCREEN_MAIN];
- else
- fontnumber = FONT_SYSFIXED;
-
- int result = rb->font_getstringsize(str, &w, &h, fontnumber);
- lua_pushinteger(L, result);
- lua_pushinteger(L, w);
- lua_pushinteger(L, h);
-
- return 3;
-}
-
RB_WRAP(current_path)
{
return get_current_path(L, 1);
@@ -507,9 +428,6 @@ static const luaL_Reg rocklib[] =
RB_FUNC(kbd_input),
- RB_FUNC(font_getstringsize),
- RB_FUNC(set_viewport),
- RB_FUNC(clear_viewport),
RB_FUNC(current_path),
RB_FUNC(gui_syncyesno_run),
RB_FUNC(do_menu),
@@ -563,6 +481,11 @@ LUALIB_API int luaopen_rock(lua_State *L)
RB_CONSTANT(LCD_DEPTH),
RB_CONSTANT(LCD_HEIGHT),
RB_CONSTANT(LCD_WIDTH),
+#ifdef HAVE_REMOTE_LCD
+ RB_CONSTANT(LCD_REMOTE_DEPTH),
+ RB_CONSTANT(LCD_REMOTE_HEIGHT),
+ RB_CONSTANT(LCD_REMOTE_WIDTH),
+#endif
RB_CONSTANT(FONT_SYSFIXED),
RB_CONSTANT(FONT_UI),
diff --git a/apps/plugins/lua/rocklib_aux.pl b/apps/plugins/lua/rocklib_aux.pl
index 5114e7b6f7..8ad59317d6 100755
--- a/apps/plugins/lua/rocklib_aux.pl
+++ b/apps/plugins/lua/rocklib_aux.pl
@@ -73,6 +73,14 @@ my @forbidden_functions = ('^open$',
'^codec_',
'^timer_',
'^lcd_(mono_)?+bitmap',
+ '^lcd_(draw|fill|update_)rect$',
+ '^lcd_draw(line|pixel)$',
+ '^lcd_(h|v)line$',
+ '^lcd_(update|clear_display|set_drawmode)$',
+ '^lcd_setfont$',
+ '^lcd_(set|get)_(fore|back)ground$',
+ '^lcd_put(s|sxy|s_scroll)$',
+ '^lcd_scroll_stop$',
'^__.+$',
'^.+_(un)?cached$',
'^audio_.+$',
diff --git a/apps/plugins/lua/rocklib_img.c b/apps/plugins/lua/rocklib_img.c
index 6cece9c836..9d9fb120f8 100644
--- a/apps/plugins/lua/rocklib_img.c
+++ b/apps/plugins/lua/rocklib_img.c
@@ -1217,21 +1217,180 @@ static const struct luaL_reg rli_lib [] =
*/
#define RB_WRAP(func) static int rock_##func(lua_State UNUSED_ATTR *L)
+
+#if defined NB_SCREENS && (NB_SCREENS > 1)
+#define RB_SCREENS(luastate, narg, func, ...) \
+ rb->screens[get_screen(luastate, narg)]->func(__VA_ARGS__)
+
+static int get_screen(lua_State *L, int narg)
+{
+ int screen = luaL_optint(L, narg, SCREEN_MAIN);
+
+ if(screen < SCREEN_MAIN)
+ screen = SCREEN_MAIN;
+ else if(screen > NB_SCREENS)
+ screen = NB_SCREENS;
+
+ return screen;
+}
+#else /* only SCREEN_MAIN exists */
+#define RB_SCREENS(luastate, narg, func, ...) \
+ rb->screens[SCREEN_MAIN]->func(__VA_ARGS__)
+#endif
+
+RB_WRAP(lcd_update)
+{
+ RB_SCREENS(L, 1, update);
+ return 0;
+}
+
+RB_WRAP(lcd_clear_display)
+{
+ RB_SCREENS(L, 1, clear_display);
+ return 0;
+}
+
+RB_WRAP(lcd_set_drawmode)
+{
+ int mode = (int) luaL_checkint(L, 1);
+ RB_SCREENS(L, 2, set_drawmode, mode);
+ return 0;
+}
+
+/* helper function for lcd_puts functions */
+static const unsigned char * lcd_putshelper(lua_State *L, int *x, int *y)
+{
+ *x = (int) luaL_checkint(L, 1);
+ *y = (int) luaL_checkint(L, 2);
+ return luaL_checkstring(L, 3);
+}
+
+RB_WRAP(lcd_putsxy)
+{
+ int x, y;
+ const unsigned char *string = lcd_putshelper(L, &x, &y);
+ RB_SCREENS(L, 4, putsxy, x, y, string);
+ return 0;
+}
+
+RB_WRAP(lcd_puts)
+{
+ int x, y;
+ const unsigned char * string = lcd_putshelper(L, &x, &y);
+ RB_SCREENS(L, 4, puts, x, y, string);
+ return 0;
+}
+
+RB_WRAP(lcd_puts_scroll)
+{
+ int x, y;
+ const unsigned char * string = lcd_putshelper(L, &x, &y);
+ bool result = RB_SCREENS(L, 4, puts_scroll, x, y, string);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+RB_WRAP(lcd_scroll_stop)
+{
+ RB_SCREENS(L, 1, scroll_stop);
+ return 0;
+}
+
+/* Helper function for opt_viewport */
+static int check_tablevalue(lua_State *L, const char* key, int tablepos)
+{
+ lua_getfield(L, tablepos, key); /* Find table[key] */
+
+ int val = lua_tointeger(L, -1);
+
+ lua_pop(L, 1); /* Pop the value off the stack */
+ return val;
+}
+
+static inline struct viewport* opt_viewport(lua_State *L,
+ int narg,
+ struct viewport* vp,
+ struct viewport* alt)
+{
+ if(lua_isnoneornil(L, narg))
+ return alt;
+
+ luaL_checktype(L, narg, LUA_TTABLE);
+
+ vp->x = check_tablevalue(L, "x", narg);
+ vp->y = check_tablevalue(L, "y", narg);
+ vp->width = check_tablevalue(L, "width", narg);
+ vp->height = check_tablevalue(L, "height", narg);
#ifdef HAVE_LCD_BITMAP
+ vp->font = check_tablevalue(L, "font", narg);
+ vp->drawmode = check_tablevalue(L, "drawmode", narg);
+#endif
+#if LCD_DEPTH > 1
+ vp->fg_pattern = (unsigned int) check_tablevalue(L, "fg_pattern", narg);
+ vp->bg_pattern = (unsigned int) check_tablevalue(L, "bg_pattern", narg);
+#endif
+
+ return vp;
+}
+
+RB_WRAP(set_viewport)
+{
+ static struct viewport vp;
+ RB_SCREENS(L, 2, set_viewport, opt_viewport(L, 1, &vp, NULL));
+ return 0;
+}
+
+RB_WRAP(clear_viewport)
+{
+ RB_SCREENS(L, 1, clear_viewport);
+ return 0;
+}
+
+RB_WRAP(font_getstringsize)
+{
+ const unsigned char* str = luaL_checkstring(L, 1);
+ int fontnumber = lua_tointeger(L, 2);
+ int w, h, result;
+
+ if (fontnumber == FONT_UI)
+ fontnumber = rb->global_status->font_id[SCREEN_MAIN];
+ else
+ fontnumber = FONT_SYSFIXED;
+
+ if lua_isnil(L, 2)
+ result = RB_SCREENS(L, 3, getstringsize, str, &w, &h);
+ else
+ result = rb->font_getstringsize(str, &w, &h, fontnumber);
+
+ lua_pushinteger(L, result);
+ lua_pushinteger(L, w);
+ lua_pushinteger(L, h);
+
+ return 3;
+}
+
+#ifdef HAVE_LCD_BITMAP
+
RB_WRAP(lcd_framebuffer)
{
rli_wrap(L, rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT);
return 1;
}
-/* helper function for lcd_xxx_bitmap functions */
-static int get_bmp_bounds(lua_State *L, int npos, int *x, int *y, int *w, int* h)
+RB_WRAP(lcd_setfont)
+{
+ int font = (int) luaL_checkint(L, 1);
+ RB_SCREENS(L, 2, setfont, font);
+ return 0;
+}
+
+/* helper function for lcd_xxx_bitmap/rect functions */
+static void get_rect_bounds(lua_State *L, int narg, int *x, int *y, int *w, int* h)
{
- *x = luaL_checkint(L, npos);
- *y = luaL_checkint(L, npos + 1);
- *w = luaL_checkint(L, npos + 2);
- *h = luaL_checkint(L, npos + 3);
- return luaL_optint(L, npos + 4, SCREEN_MAIN);
+ *x = luaL_checkint(L, narg);
+ *y = luaL_checkint(L, narg + 1);
+ *w = luaL_checkint(L, narg + 2);
+ *h = luaL_checkint(L, narg + 3);
}
RB_WRAP(lcd_mono_bitmap_part)
@@ -1241,9 +1400,10 @@ RB_WRAP(lcd_mono_bitmap_part)
int src_y = luaL_checkint(L, 3);
int stride = luaL_checkint(L, 4);
int x, y, width, height;
- int screen = get_bmp_bounds(L, 5, &x, &y, &width, &height);
+ get_rect_bounds(L, 5, &x, &y, &width, &height);
- rb->screens[screen]->mono_bitmap_part((const unsigned char *)src->data, src_x, src_y, stride, x, y, width, height);
+ RB_SCREENS(L, 9, mono_bitmap_part, (const unsigned char *)src->data,
+ src_x, src_y, stride, x, y, width, height);
return 0;
}
@@ -1251,9 +1411,9 @@ RB_WRAP(lcd_mono_bitmap)
{
struct rocklua_image *src = rli_checktype(L, 1);
int x, y, width, height;
- int screen = get_bmp_bounds(L, 2, &x, &y, &width, &height);
+ get_rect_bounds(L, 2, &x, &y, &width, &height);
- rb->screens[screen]->mono_bitmap((const unsigned char *)src->data, x, y, width, height);
+ RB_SCREENS(L, 6, mono_bitmap, (const unsigned char *)src->data, x, y, width, height);
return 0;
}
@@ -1265,9 +1425,9 @@ RB_WRAP(lcd_bitmap_part)
int src_y = luaL_checkint(L, 3);
int stride = luaL_checkint(L, 4);
int x, y, width, height;
- int screen = get_bmp_bounds(L, 5, &x, &y, &width, &height);
+ get_rect_bounds(L, 5, &x, &y, &width, &height);
- rb->screens[screen]->bitmap_part(src->data, src_x, src_y, stride, x, y, width, height);
+ RB_SCREENS(L, 9, bitmap_part, src->data, src_x, src_y, stride, x, y, width, height);
return 0;
}
@@ -1275,9 +1435,9 @@ RB_WRAP(lcd_bitmap)
{
struct rocklua_image *src = rli_checktype(L, 1);
int x, y, width, height;
- int screen = get_bmp_bounds(L, 2, &x, &y, &width, &height);
+ get_rect_bounds(L, 2, &x, &y, &width, &height);
- rb->screens[screen]->bitmap(src->data, x, y, width, height);
+ RB_SCREENS(L, 6, bitmap, src->data, x, y, width, height);
return 0;
}
@@ -1291,6 +1451,35 @@ RB_WRAP(lcd_get_backdrop)
return 1;
}
+
+RB_WRAP(lcd_set_foreground)
+{
+ unsigned foreground = (unsigned) luaL_checkint(L, 1);
+ RB_SCREENS(L, 2, set_foreground, foreground);
+ return 0;
+}
+
+RB_WRAP(lcd_get_foreground)
+{
+ unsigned result = RB_SCREENS(L, 1, get_foreground);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+RB_WRAP(lcd_set_background)
+{
+ unsigned background = (unsigned) luaL_checkint(L, 1);
+ RB_SCREENS(L, 2, set_background, background);
+ return 0;
+}
+
+RB_WRAP(lcd_get_background)
+{
+ unsigned result = RB_SCREENS(L, 1, get_background);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
#endif /* LCD_DEPTH > 1 */
#if LCD_DEPTH == 16
@@ -1301,9 +1490,10 @@ RB_WRAP(lcd_bitmap_transparent_part)
int src_y = luaL_checkint(L, 3);
int stride = luaL_checkint(L, 4);
int x, y, width, height;
- int screen = get_bmp_bounds(L, 5, &x, &y, &width, &height);
+ get_rect_bounds(L, 5, &x, &y, &width, &height);
- rb->screens[screen]->transparent_bitmap_part(src->data, src_x, src_y, stride, x, y, width, height);
+ RB_SCREENS(L, 9, transparent_bitmap_part, src->data, src_x,
+ src_y, stride, x, y, width, height);
return 0;
}
@@ -1311,13 +1501,71 @@ RB_WRAP(lcd_bitmap_transparent)
{
struct rocklua_image *src = rli_checktype(L, 1);
int x, y, width, height;
- int screen = get_bmp_bounds(L, 2, &x, &y, &width, &height);
+ get_rect_bounds(L, 2, &x, &y, &width, &height);
- rb->screens[screen]->transparent_bitmap(src->data, x, y, width, height);
+ RB_SCREENS(L, 6, transparent_bitmap, src->data, x, y, width, height);
return 0;
}
#endif /* LCD_DEPTH == 16 */
+RB_WRAP(lcd_update_rect)
+{
+ int x, y, width, height;
+ get_rect_bounds(L, 1, &x, &y, &width, &height);
+ RB_SCREENS(L, 5, update_rect, x, y, width, height);
+ return 0;
+}
+
+RB_WRAP(lcd_drawrect)
+{
+ int x, y, width, height;
+ get_rect_bounds(L, 1, &x, &y, &width, &height);
+ RB_SCREENS(L, 5, drawrect, x, y, width, height);
+ return 0;
+}
+
+RB_WRAP(lcd_fillrect)
+{
+ int x, y, width, height;
+ get_rect_bounds(L, 1, &x, &y, &width, &height);
+ RB_SCREENS(L, 5, fillrect, x, y, width, height);
+ return 0;
+}
+
+RB_WRAP(lcd_drawline)
+{
+ int x1, y1, x2, y2;
+ get_rect_bounds(L, 1, &x1, &y1, &x2, &y2);
+ RB_SCREENS(L, 5, drawline, x1, y1, x2, y2);
+ return 0;
+}
+
+RB_WRAP(lcd_hline)
+{
+ int x1 = (int) luaL_checkint(L, 1);
+ int x2 = (int) luaL_checkint(L, 2);
+ int y = (int) luaL_checkint(L, 3);
+ RB_SCREENS(L, 4, hline, x1, x2, y);
+ return 0;
+}
+
+RB_WRAP(lcd_vline)
+{
+ int x = (int) luaL_checkint(L, 1);
+ int y1 = (int) luaL_checkint(L, 2);
+ int y2 = (int) luaL_checkint(L, 3);
+ RB_SCREENS(L, 4, vline, x, y1, y2);
+ return 0;
+}
+
+RB_WRAP(lcd_drawpixel)
+{
+ int x = (int) luaL_checkint(L, 1);
+ int y = (int) luaL_checkint(L, 2);
+ RB_SCREENS(L, 3, drawpixel, x, y);
+ return 0;
+}
+
#endif /* defined(LCD_BITMAP) */
#ifdef HAVE_LCD_COLOR
@@ -1377,19 +1625,42 @@ RB_WRAP(read_bmp_file)
static const luaL_Reg rocklib_img[] =
{
/* Graphics */
+ R(lcd_update),
+ R(lcd_clear_display),
+ R(lcd_set_drawmode),
+ R(lcd_putsxy),
+ R(lcd_puts),
+ R(lcd_puts_scroll),
+ R(lcd_scroll_stop),
+ R(set_viewport),
+ R(clear_viewport),
+ R(font_getstringsize),
#ifdef HAVE_LCD_BITMAP
R(lcd_framebuffer),
+ R(lcd_setfont),
R(lcd_mono_bitmap_part),
R(lcd_mono_bitmap),
#if LCD_DEPTH > 1
R(lcd_get_backdrop),
R(lcd_bitmap_part),
R(lcd_bitmap),
+ R(lcd_set_foreground),
+ R(lcd_get_foreground),
+ R(lcd_set_background),
+ R(lcd_get_background),
#endif
#if LCD_DEPTH == 16
R(lcd_bitmap_transparent_part),
R(lcd_bitmap_transparent),
#endif
+ R(lcd_update_rect),
+ R(lcd_drawrect),
+ R(lcd_fillrect),
+ R(lcd_drawline),
+ R(lcd_hline),
+ R(lcd_vline),
+ R(lcd_drawpixel),
+
#endif /*HAVE_LCD_BITMAP*/
#ifdef HAVE_LCD_COLOR
R(lcd_rgbpack),