19c8bf69aSWarner Losh /*-
29c8bf69aSWarner Losh * Copyright (c) 2024 Netflix, Inc
39c8bf69aSWarner Losh *
49c8bf69aSWarner Losh * SPDX-License-Identifier: BSD-2-Clause
59c8bf69aSWarner Losh */
69c8bf69aSWarner Losh
79c8bf69aSWarner Losh /* Copied from a file that likely shoulve have had this at the top */
89c8bf69aSWarner Losh /*-
99c8bf69aSWarner Losh * SPDX-License-Identifier: BSD-2-Clause
109c8bf69aSWarner Losh *
119c8bf69aSWarner Losh * Copyright 2020 Toomas Soome
129c8bf69aSWarner Losh * Copyright 2020 RackTop Systems, Inc.
139c8bf69aSWarner Losh *
149c8bf69aSWarner Losh * Redistribution and use in source and binary forms, with or without
159c8bf69aSWarner Losh * modification, are permitted provided that the following conditions
169c8bf69aSWarner Losh * are met:
179c8bf69aSWarner Losh * 1. Redistributions of source code must retain the above copyright
189c8bf69aSWarner Losh * notice, this list of conditions and the following disclaimer.
199c8bf69aSWarner Losh * 2. Redistributions in binary form must reproduce the above copyright
209c8bf69aSWarner Losh * notice, this list of conditions and the following disclaimer in the
219c8bf69aSWarner Losh * documentation and/or other materials provided with the distribution.
229c8bf69aSWarner Losh *
239c8bf69aSWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
249c8bf69aSWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
259c8bf69aSWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
269c8bf69aSWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
279c8bf69aSWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
289c8bf69aSWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
299c8bf69aSWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
309c8bf69aSWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
319c8bf69aSWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
329c8bf69aSWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
339c8bf69aSWarner Losh * SUCH DAMAGE.
349c8bf69aSWarner Losh */
359c8bf69aSWarner Losh
369c8bf69aSWarner Losh /*******************************************************************
379c8bf69aSWarner Losh ** g f x _ l o a d e r . c
389c8bf69aSWarner Losh ** Additional FICL words designed for FreeBSD's loader
399c8bf69aSWarner Losh ** for graphics
409c8bf69aSWarner Losh *******************************************************************/
419c8bf69aSWarner Losh
429c8bf69aSWarner Losh #include <stand.h>
439c8bf69aSWarner Losh #include "bootstrap.h"
449c8bf69aSWarner Losh #include <gfx_fb.h>
459c8bf69aSWarner Losh #include <pnglite.h>
469c8bf69aSWarner Losh #include "ficl.h"
479c8bf69aSWarner Losh
489c8bf69aSWarner Losh /* FreeBSD's loader interaction words and extras
499c8bf69aSWarner Losh * for graphics
509c8bf69aSWarner Losh * fb-bezier ( x0 y0 x1 y1 x2 y2 wd -- )
519c8bf69aSWarner Losh * fb-drawrect ( x1 y1 x2 y2 fill -- )
529c8bf69aSWarner Losh * fb-line ( x0 y0 x1 y1 wd -- )
539c8bf69aSWarner Losh * fb-putimage ( flags x1 y1 x2 y2 -- flag )
549c8bf69aSWarner Losh * fb-setpixel ( x y -- )
559c8bf69aSWarner Losh * term-drawrect ( x1 y1 x2 y2 fill -- )
569c8bf69aSWarner Losh * term-putimage ( flags x1 y1 x2 y2 -- flag )
579c8bf69aSWarner Losh */
589c8bf69aSWarner Losh
599c8bf69aSWarner Losh /* ( flags x1 y1 x2 y2 -- flag ) */
609c8bf69aSWarner Losh void
ficl_term_putimage(FICL_VM * pVM)619c8bf69aSWarner Losh ficl_term_putimage(FICL_VM *pVM)
629c8bf69aSWarner Losh {
639c8bf69aSWarner Losh char *namep, *name;
649c8bf69aSWarner Losh int names;
659c8bf69aSWarner Losh unsigned long ret = FICL_FALSE;
669c8bf69aSWarner Losh uint32_t x1, y1, x2, y2, f;
679c8bf69aSWarner Losh png_t png;
689c8bf69aSWarner Losh int error;
699c8bf69aSWarner Losh
709c8bf69aSWarner Losh #if FICL_ROBUST > 1
719c8bf69aSWarner Losh vmCheckStack(pVM, 7, 1);
729c8bf69aSWarner Losh #endif
739c8bf69aSWarner Losh names = stackPopINT(pVM->pStack);
749c8bf69aSWarner Losh namep = (char *) stackPopPtr(pVM->pStack);
759c8bf69aSWarner Losh y2 = stackPopINT(pVM->pStack);
769c8bf69aSWarner Losh x2 = stackPopINT(pVM->pStack);
779c8bf69aSWarner Losh y1 = stackPopINT(pVM->pStack);
789c8bf69aSWarner Losh x1 = stackPopINT(pVM->pStack);
799c8bf69aSWarner Losh f = stackPopINT(pVM->pStack);
809c8bf69aSWarner Losh
819c8bf69aSWarner Losh x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width;
829c8bf69aSWarner Losh y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height;
839c8bf69aSWarner Losh if (x2 != 0) {
849c8bf69aSWarner Losh x2 = gfx_state.tg_origin.tp_col +
859c8bf69aSWarner Losh x2 * gfx_state.tg_font.vf_width;
869c8bf69aSWarner Losh }
879c8bf69aSWarner Losh if (y2 != 0) {
889c8bf69aSWarner Losh y2 = gfx_state.tg_origin.tp_row +
899c8bf69aSWarner Losh y2 * gfx_state.tg_font.vf_height;
909c8bf69aSWarner Losh }
919c8bf69aSWarner Losh
929c8bf69aSWarner Losh name = ficlMalloc(names + 1);
939c8bf69aSWarner Losh if (!name)
949c8bf69aSWarner Losh vmThrowErr(pVM, "Error: out of memory");
959c8bf69aSWarner Losh (void) strncpy(name, namep, names);
969c8bf69aSWarner Losh name[names] = '\0';
979c8bf69aSWarner Losh
989c8bf69aSWarner Losh if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
999c8bf69aSWarner Losh if (f & FL_PUTIMAGE_DEBUG)
1009c8bf69aSWarner Losh printf("%s\n", png_error_string(error));
1019c8bf69aSWarner Losh } else {
1029c8bf69aSWarner Losh if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
1039c8bf69aSWarner Losh ret = FICL_TRUE; /* success */
1049c8bf69aSWarner Losh (void) png_close(&png);
1059c8bf69aSWarner Losh }
1069c8bf69aSWarner Losh ficlFree(name);
1079c8bf69aSWarner Losh stackPushUNS(pVM->pStack, ret);
1089c8bf69aSWarner Losh }
1099c8bf69aSWarner Losh
1109c8bf69aSWarner Losh /* ( flags x1 y1 x2 y2 -- flag ) */
1119c8bf69aSWarner Losh void
ficl_fb_putimage(FICL_VM * pVM)1129c8bf69aSWarner Losh ficl_fb_putimage(FICL_VM *pVM)
1139c8bf69aSWarner Losh {
1149c8bf69aSWarner Losh char *namep, *name;
1159c8bf69aSWarner Losh int names;
1169c8bf69aSWarner Losh unsigned long ret = FICL_FALSE;
1179c8bf69aSWarner Losh uint32_t x1, y1, x2, y2, f;
1189c8bf69aSWarner Losh png_t png;
1199c8bf69aSWarner Losh int error;
1209c8bf69aSWarner Losh
1219c8bf69aSWarner Losh #if FICL_ROBUST > 1
1229c8bf69aSWarner Losh vmCheckStack(pVM, 7, 1);
1239c8bf69aSWarner Losh #endif
1249c8bf69aSWarner Losh names = stackPopINT(pVM->pStack);
1259c8bf69aSWarner Losh namep = (char *) stackPopPtr(pVM->pStack);
1269c8bf69aSWarner Losh y2 = stackPopINT(pVM->pStack);
1279c8bf69aSWarner Losh x2 = stackPopINT(pVM->pStack);
1289c8bf69aSWarner Losh y1 = stackPopINT(pVM->pStack);
1299c8bf69aSWarner Losh x1 = stackPopINT(pVM->pStack);
1309c8bf69aSWarner Losh f = stackPopINT(pVM->pStack);
1319c8bf69aSWarner Losh
1329c8bf69aSWarner Losh name = ficlMalloc(names + 1);
1339c8bf69aSWarner Losh if (!name)
1349c8bf69aSWarner Losh vmThrowErr(pVM, "Error: out of memory");
1359c8bf69aSWarner Losh (void) strncpy(name, namep, names);
1369c8bf69aSWarner Losh name[names] = '\0';
1379c8bf69aSWarner Losh
1389c8bf69aSWarner Losh if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
1399c8bf69aSWarner Losh if (f & FL_PUTIMAGE_DEBUG)
1409c8bf69aSWarner Losh printf("%s\n", png_error_string(error));
1419c8bf69aSWarner Losh } else {
1429c8bf69aSWarner Losh if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
1439c8bf69aSWarner Losh ret = FICL_TRUE; /* success */
1449c8bf69aSWarner Losh (void) png_close(&png);
1459c8bf69aSWarner Losh }
1469c8bf69aSWarner Losh ficlFree(name);
1479c8bf69aSWarner Losh stackPushUNS(pVM->pStack, ret);
1489c8bf69aSWarner Losh }
1499c8bf69aSWarner Losh
1509c8bf69aSWarner Losh void
ficl_fb_setpixel(FICL_VM * pVM)1519c8bf69aSWarner Losh ficl_fb_setpixel(FICL_VM *pVM)
1529c8bf69aSWarner Losh {
1539c8bf69aSWarner Losh FICL_UNS x, y;
1549c8bf69aSWarner Losh
1559c8bf69aSWarner Losh #if FICL_ROBUST > 1
1569c8bf69aSWarner Losh vmCheckStack(pVM, 2, 0);
1579c8bf69aSWarner Losh #endif
1589c8bf69aSWarner Losh
1599c8bf69aSWarner Losh y = stackPopUNS(pVM->pStack);
1609c8bf69aSWarner Losh x = stackPopUNS(pVM->pStack);
1619c8bf69aSWarner Losh gfx_fb_setpixel(x, y);
1629c8bf69aSWarner Losh }
1639c8bf69aSWarner Losh
1649c8bf69aSWarner Losh void
ficl_fb_line(FICL_VM * pVM)1659c8bf69aSWarner Losh ficl_fb_line(FICL_VM *pVM)
1669c8bf69aSWarner Losh {
1679c8bf69aSWarner Losh FICL_UNS x0, y0, x1, y1, wd;
1689c8bf69aSWarner Losh
1699c8bf69aSWarner Losh #if FICL_ROBUST > 1
1709c8bf69aSWarner Losh vmCheckStack(pVM, 5, 0);
1719c8bf69aSWarner Losh #endif
1729c8bf69aSWarner Losh
1739c8bf69aSWarner Losh wd = stackPopUNS(pVM->pStack);
1749c8bf69aSWarner Losh y1 = stackPopUNS(pVM->pStack);
1759c8bf69aSWarner Losh x1 = stackPopUNS(pVM->pStack);
1769c8bf69aSWarner Losh y0 = stackPopUNS(pVM->pStack);
1779c8bf69aSWarner Losh x0 = stackPopUNS(pVM->pStack);
1789c8bf69aSWarner Losh gfx_fb_line(x0, y0, x1, y1, wd);
1799c8bf69aSWarner Losh }
1809c8bf69aSWarner Losh
1819c8bf69aSWarner Losh void
ficl_fb_bezier(FICL_VM * pVM)1829c8bf69aSWarner Losh ficl_fb_bezier(FICL_VM *pVM)
1839c8bf69aSWarner Losh {
1849c8bf69aSWarner Losh FICL_UNS x0, y0, x1, y1, x2, y2, width;
1859c8bf69aSWarner Losh
1869c8bf69aSWarner Losh #if FICL_ROBUST > 1
1879c8bf69aSWarner Losh vmCheckStack(pVM, 7, 0);
1889c8bf69aSWarner Losh #endif
1899c8bf69aSWarner Losh
1909c8bf69aSWarner Losh width = stackPopUNS(pVM->pStack);
1919c8bf69aSWarner Losh y2 = stackPopUNS(pVM->pStack);
1929c8bf69aSWarner Losh x2 = stackPopUNS(pVM->pStack);
1939c8bf69aSWarner Losh y1 = stackPopUNS(pVM->pStack);
1949c8bf69aSWarner Losh x1 = stackPopUNS(pVM->pStack);
1959c8bf69aSWarner Losh y0 = stackPopUNS(pVM->pStack);
1969c8bf69aSWarner Losh x0 = stackPopUNS(pVM->pStack);
1979c8bf69aSWarner Losh gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width);
1989c8bf69aSWarner Losh }
1999c8bf69aSWarner Losh
2009c8bf69aSWarner Losh void
ficl_fb_drawrect(FICL_VM * pVM)2019c8bf69aSWarner Losh ficl_fb_drawrect(FICL_VM *pVM)
2029c8bf69aSWarner Losh {
2039c8bf69aSWarner Losh FICL_UNS x1, x2, y1, y2, fill;
2049c8bf69aSWarner Losh
2059c8bf69aSWarner Losh #if FICL_ROBUST > 1
2069c8bf69aSWarner Losh vmCheckStack(pVM, 5, 0);
2079c8bf69aSWarner Losh #endif
2089c8bf69aSWarner Losh
2099c8bf69aSWarner Losh fill = stackPopUNS(pVM->pStack);
2109c8bf69aSWarner Losh y2 = stackPopUNS(pVM->pStack);
2119c8bf69aSWarner Losh x2 = stackPopUNS(pVM->pStack);
2129c8bf69aSWarner Losh y1 = stackPopUNS(pVM->pStack);
2139c8bf69aSWarner Losh x1 = stackPopUNS(pVM->pStack);
2149c8bf69aSWarner Losh gfx_fb_drawrect(x1, y1, x2, y2, fill);
2159c8bf69aSWarner Losh }
2169c8bf69aSWarner Losh
2179c8bf69aSWarner Losh void
ficl_term_drawrect(FICL_VM * pVM)2189c8bf69aSWarner Losh ficl_term_drawrect(FICL_VM *pVM)
2199c8bf69aSWarner Losh {
2209c8bf69aSWarner Losh FICL_UNS x1, x2, y1, y2;
2219c8bf69aSWarner Losh
2229c8bf69aSWarner Losh #if FICL_ROBUST > 1
2239c8bf69aSWarner Losh vmCheckStack(pVM, 4, 0);
2249c8bf69aSWarner Losh #endif
2259c8bf69aSWarner Losh
2269c8bf69aSWarner Losh y2 = stackPopUNS(pVM->pStack);
2279c8bf69aSWarner Losh x2 = stackPopUNS(pVM->pStack);
2289c8bf69aSWarner Losh y1 = stackPopUNS(pVM->pStack);
2299c8bf69aSWarner Losh x1 = stackPopUNS(pVM->pStack);
2309c8bf69aSWarner Losh gfx_term_drawrect(x1, y1, x2, y2);
2319c8bf69aSWarner Losh }
2329c8bf69aSWarner Losh
2339c8bf69aSWarner Losh /**************************************************************************
2349c8bf69aSWarner Losh f i c l C o m p i l e G f x
2359c8bf69aSWarner Losh ** Build FreeBSD platform extensions into the system dictionary
2369c8bf69aSWarner Losh ** for gfx
2379c8bf69aSWarner Losh **************************************************************************/
ficlCompileGfx(FICL_SYSTEM * pSys)2389c8bf69aSWarner Losh static void ficlCompileGfx(FICL_SYSTEM *pSys)
2399c8bf69aSWarner Losh {
2409c8bf69aSWarner Losh ficlCompileFcn **fnpp;
2419c8bf69aSWarner Losh FICL_DICT *dp = pSys->dp;
2429c8bf69aSWarner Losh assert (dp);
2439c8bf69aSWarner Losh
2449c8bf69aSWarner Losh dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT);
2459c8bf69aSWarner Losh dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT);
2469c8bf69aSWarner Losh dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT);
2479c8bf69aSWarner Losh dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT);
2489c8bf69aSWarner Losh dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT);
2499c8bf69aSWarner Losh dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT);
2509c8bf69aSWarner Losh dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT);
2519c8bf69aSWarner Losh
2529c8bf69aSWarner Losh return;
2539c8bf69aSWarner Losh }
2549c8bf69aSWarner Losh FICL_COMPILE_SET(ficlCompileGfx);
2559c8bf69aSWarner Losh
2569c8bf69aSWarner Losh void
gfx_interp_ref(void)257*6faf55c8SWarner Losh gfx_interp_ref(void)
2589c8bf69aSWarner Losh {
2599c8bf69aSWarner Losh }
260