1 /*- 2 * Copyright (c) 2024 Netflix, Inc. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 /* Copied from a file that likely shoulve have had this at the top */ 8 /*- 9 * SPDX-License-Identifier: BSD-2-Clause 10 * 11 * Copyright 2020 Toomas Soome 12 * Copyright 2020 RackTop Systems, Inc. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "lua.h" 37 #include "lauxlib.h" 38 #include "lutils.h" 39 #include <gfx_fb.h> 40 #include <pnglite.h> 41 42 /* 43 * put image using terminal coordinates. 44 */ 45 static int 46 lua_term_putimage(lua_State *L) 47 { 48 const char *name; 49 png_t png; 50 uint32_t x1, y1, x2, y2, f; 51 int nargs, ret = 0, error; 52 53 nargs = lua_gettop(L); 54 if (nargs != 6) { 55 lua_pushboolean(L, 0); 56 return 1; 57 } 58 59 name = luaL_checkstring(L, 1); 60 x1 = luaL_checknumber(L, 2); 61 y1 = luaL_checknumber(L, 3); 62 x2 = luaL_checknumber(L, 4); 63 y2 = luaL_checknumber(L, 5); 64 f = luaL_checknumber(L, 6); 65 66 x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; 67 y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; 68 if (x2 != 0) { 69 x2 = gfx_state.tg_origin.tp_col + 70 x2 * gfx_state.tg_font.vf_width; 71 } 72 if (y2 != 0) { 73 y2 = gfx_state.tg_origin.tp_row + 74 y2 * gfx_state.tg_font.vf_height; 75 } 76 77 if ((error = png_open(&png, name)) != PNG_NO_ERROR) { 78 if (f & FL_PUTIMAGE_DEBUG) 79 printf("%s\n", png_error_string(error)); 80 } else { 81 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) 82 ret = 1; 83 (void) png_close(&png); 84 } 85 lua_pushboolean(L, ret); 86 return 1; 87 } 88 89 static int 90 lua_fb_putimage(lua_State *L) 91 { 92 const char *name; 93 png_t png; 94 uint32_t x1, y1, x2, y2, f; 95 int nargs, ret = 0, error; 96 97 nargs = lua_gettop(L); 98 if (nargs != 6) { 99 lua_pushboolean(L, 0); 100 return 1; 101 } 102 103 name = luaL_checkstring(L, 1); 104 x1 = luaL_checknumber(L, 2); 105 y1 = luaL_checknumber(L, 3); 106 x2 = luaL_checknumber(L, 4); 107 y2 = luaL_checknumber(L, 5); 108 f = luaL_checknumber(L, 6); 109 110 if ((error = png_open(&png, name)) != PNG_NO_ERROR) { 111 if (f & FL_PUTIMAGE_DEBUG) 112 printf("%s\n", png_error_string(error)); 113 } else { 114 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) 115 ret = 1; 116 (void) png_close(&png); 117 } 118 lua_pushboolean(L, ret); 119 return 1; 120 } 121 122 static int 123 lua_fb_setpixel(lua_State *L) 124 { 125 uint32_t x, y; 126 int nargs; 127 128 nargs = lua_gettop(L); 129 if (nargs != 2) { 130 lua_pushnil(L); 131 return 1; 132 } 133 134 x = luaL_checknumber(L, 1); 135 y = luaL_checknumber(L, 2); 136 gfx_fb_setpixel(x, y); 137 gfx_fb_flush(); 138 return 0; 139 } 140 141 static int 142 lua_fb_line(lua_State *L) 143 { 144 uint32_t x0, y0, x1, y1, wd; 145 int nargs; 146 147 nargs = lua_gettop(L); 148 if (nargs != 5) { 149 lua_pushnil(L); 150 return 1; 151 } 152 153 x0 = luaL_checknumber(L, 1); 154 y0 = luaL_checknumber(L, 2); 155 x1 = luaL_checknumber(L, 3); 156 y1 = luaL_checknumber(L, 4); 157 wd = luaL_checknumber(L, 5); 158 gfx_fb_line(x0, y0, x1, y1, wd); 159 return 0; 160 } 161 162 static int 163 lua_fb_bezier(lua_State *L) 164 { 165 uint32_t x0, y0, x1, y1, x2, y2, width; 166 int nargs; 167 168 nargs = lua_gettop(L); 169 if (nargs != 7) { 170 lua_pushnil(L); 171 return 1; 172 } 173 174 x0 = luaL_checknumber(L, 1); 175 y0 = luaL_checknumber(L, 2); 176 x1 = luaL_checknumber(L, 3); 177 y1 = luaL_checknumber(L, 4); 178 x2 = luaL_checknumber(L, 5); 179 y2 = luaL_checknumber(L, 6); 180 width = luaL_checknumber(L, 7); 181 gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); 182 return 0; 183 } 184 185 static int 186 lua_fb_drawrect(lua_State *L) 187 { 188 uint32_t x0, y0, x1, y1, fill; 189 int nargs; 190 191 nargs = lua_gettop(L); 192 if (nargs != 5) { 193 lua_pushnil(L); 194 return 1; 195 } 196 197 x0 = luaL_checknumber(L, 1); 198 y0 = luaL_checknumber(L, 2); 199 x1 = luaL_checknumber(L, 3); 200 y1 = luaL_checknumber(L, 4); 201 fill = luaL_checknumber(L, 5); 202 gfx_fb_drawrect(x0, y0, x1, y1, fill); 203 return 0; 204 } 205 206 static int 207 lua_term_drawrect(lua_State *L) 208 { 209 uint32_t x0, y0, x1, y1; 210 int nargs; 211 212 nargs = lua_gettop(L); 213 if (nargs != 4) { 214 lua_pushnil(L); 215 return 1; 216 } 217 218 x0 = luaL_checknumber(L, 1); 219 y0 = luaL_checknumber(L, 2); 220 x1 = luaL_checknumber(L, 3); 221 y1 = luaL_checknumber(L, 4); 222 gfx_term_drawrect(x0, y0, x1, y1); 223 return 0; 224 } 225 226 #define REG_SIMPLE(n) { #n, lua_ ## n } 227 static const struct luaL_Reg gfxlib[] = { 228 REG_SIMPLE(fb_bezier), 229 REG_SIMPLE(fb_drawrect), 230 REG_SIMPLE(fb_line), 231 REG_SIMPLE(fb_putimage), 232 REG_SIMPLE(fb_setpixel), 233 REG_SIMPLE(term_drawrect), 234 REG_SIMPLE(term_putimage), 235 { NULL, NULL }, 236 }; 237 238 int 239 luaopen_gfx(lua_State *L) 240 { 241 luaL_newlib(L, gfxlib); 242 return 1; 243 } 244 245 void 246 gfx_interp_ref(void) 247 { 248 } 249 250 static void 251 gfx_init_md(lua_State *L) 252 { 253 luaL_requiref(L, "gfx", luaopen_gfx, 1); 254 lua_pop(L, 1); /* Remove lib */ 255 256 /* 257 * Add in the compatibility references in the loader table. Doing it with 258 * a pseudo-embedded script is easier than the raw calls. 259 */ 260 if (luaL_dostring(L, 261 "loader.fb_bezier = gfx.fb_bezier\n" 262 "loader.fb_drawrect = gfx.fb_drawrect\n" 263 "loader.fb_line = gfx.fb_line\n" 264 "loader.fb_putimage = gfx.fb_putimage\n" 265 "loader.fb_setpixel = gfx.fb_setpixel\n" 266 "loader.term_drawrect = gfx.term_drawrect\n" 267 "loader.term_putimage = gfx.term_putimage") != 0) { 268 lua_pop(L, 1); 269 const char *errstr = lua_tostring(L, -1); 270 errstr = errstr == NULL ? "unknown" : errstr; 271 printf("Error adding compat loader bindings: %s.\n", errstr); 272 } 273 } 274 275 LUA_COMPILE_SET(gfx_init_md); 276