diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h index adb60c673ea9..84062864c57f 100644 --- a/stand/common/gfx_fb.h +++ b/stand/common/gfx_fb.h @@ -1,288 +1,290 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2020 Toomas Soome * Copyright 2020 RackTop Systems, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _GFX_FB_H #define _GFX_FB_H #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define EDID_MAGIC { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } struct edid_header { uint8_t header[8]; /* fixed header pattern */ uint16_t manufacturer_id; uint16_t product_code; uint32_t serial_number; uint8_t week_of_manufacture; uint8_t year_of_manufacture; uint8_t version; uint8_t revision; }; struct edid_basic_display_parameters { uint8_t video_input_parameters; uint8_t max_horizontal_image_size; uint8_t max_vertical_image_size; uint8_t display_gamma; uint8_t supported_features; }; struct edid_chromaticity_coordinates { uint8_t red_green_lo; uint8_t blue_white_lo; uint8_t red_x_hi; uint8_t red_y_hi; uint8_t green_x_hi; uint8_t green_y_hi; uint8_t blue_x_hi; uint8_t blue_y_hi; uint8_t white_x_hi; uint8_t white_y_hi; }; struct edid_detailed_timings { uint16_t pixel_clock; uint8_t horizontal_active_lo; uint8_t horizontal_blanking_lo; uint8_t horizontal_hi; uint8_t vertical_active_lo; uint8_t vertical_blanking_lo; uint8_t vertical_hi; uint8_t horizontal_sync_offset_lo; uint8_t horizontal_sync_pulse_width_lo; uint8_t vertical_sync_lo; uint8_t sync_hi; uint8_t horizontal_image_size_lo; uint8_t vertical_image_size_lo; uint8_t image_size_hi; uint8_t horizontal_border; uint8_t vertical_border; uint8_t features; }; struct vesa_edid_info { struct edid_header header; struct edid_basic_display_parameters display; #define EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1) struct edid_chromaticity_coordinates chromaticity; uint8_t established_timings_1; uint8_t established_timings_2; uint8_t manufacturer_reserved_timings; uint16_t standard_timings[8]; struct edid_detailed_timings detailed_timings[4]; uint8_t number_of_extensions; uint8_t checksum; } __packed; extern struct vesa_edid_info *edid_info; #define STD_TIMINGS 8 #define DET_TIMINGS 4 #define HSIZE(x) (((x & 0xff) + 31) * 8) #define RATIO(x) ((x & 0xC000) >> 14) #define RATIO1_1 0 /* EDID Ver. 1.3 redefined this */ #define RATIO16_10 RATIO1_1 #define RATIO4_3 1 #define RATIO5_4 2 #define RATIO16_9 3 /* * Number of pixels and lines is 12-bit int, valid values 0-4095. */ #define EDID_MAX_PIXELS 4095 #define EDID_MAX_LINES 4095 #define GET_EDID_INFO_WIDTH(edid_info, timings_num) \ ((edid_info)->detailed_timings[(timings_num)].horizontal_active_lo | \ (((uint32_t)(edid_info)->detailed_timings[(timings_num)].horizontal_hi & \ 0xf0) << 4)) #define GET_EDID_INFO_HEIGHT(edid_info, timings_num) \ ((edid_info)->detailed_timings[(timings_num)].vertical_active_lo | \ (((uint32_t)(edid_info)->detailed_timings[(timings_num)].vertical_hi & \ 0xf0) << 4)) struct resolution { uint32_t width; uint32_t height; TAILQ_ENTRY(resolution) next; }; typedef TAILQ_HEAD(edid_resolution, resolution) edid_res_list_t; struct vesa_flat_panel_info { uint16_t HSize; /* Horizontal Size in Pixels */ uint16_t VSize; /* Vertical Size in Lines */ uint16_t FPType; /* Flat Panel Type */ uint8_t RedBPP; /* Red Bits Per Primary */ uint8_t GreenBPP; /* Green Bits Per Primary */ uint8_t BlueBPP; /* Blue Bits Per Primary */ uint8_t ReservedBPP; /* Reserved Bits Per Primary */ uint32_t RsvdOffScrnMemSize; /* Size in KB of Offscreen Memory */ uint32_t RsvdOffScrnMemPtr; /* Pointer to reserved offscreen memory */ uint8_t Reserved[14]; /* remainder of FPInfo */ } __packed; #define COLOR_FORMAT_VGA 0 #define COLOR_FORMAT_RGB 1 #define NCOLORS 16 #define NCMAP 256 extern uint32_t cmap[NCMAP]; /* * VT_FB_MAX_WIDTH and VT_FB_MAX_HEIGHT are dimensions from where * we will not auto select smaller font than 8x16. * See also sys/dev/vt/vt.h */ #ifndef VT_FB_MAX_WIDTH #define VT_FB_MAX_WIDTH 4096 #endif #ifndef VT_FB_MAX_HEIGHT #define VT_FB_MAX_HEIGHT 2400 #endif enum FB_TYPE { FB_TEXT = -1, FB_GOP, FB_UGA, FB_VBE }; enum COLOR_TYPE { CT_INDEXED, CT_RGB }; struct gen_fb { uint64_t fb_addr; uint64_t fb_size; uint32_t fb_height; uint32_t fb_width; uint32_t fb_stride; uint32_t fb_mask_red; uint32_t fb_mask_green; uint32_t fb_mask_blue; uint32_t fb_mask_reserved; uint32_t fb_bpp; }; typedef struct teken_gfx { enum FB_TYPE tg_fb_type; enum COLOR_TYPE tg_ctype; unsigned tg_mode; teken_t tg_teken; /* Teken core */ teken_pos_t tg_cursor; /* Where cursor was drawn */ bool tg_cursor_visible; teken_pos_t tg_tp; /* Terminal dimensions */ teken_pos_t tg_origin; /* Point of origin in pixels */ uint8_t *tg_glyph; /* Memory for glyph */ size_t tg_glyph_size; struct vt_font tg_font; struct gen_fb tg_fb; uint32_t *tg_shadow_fb; /* units of 4 bytes */ size_t tg_shadow_sz; /* units of pages */ teken_funcs_t *tg_functions; void *tg_private; } teken_gfx_t; extern font_list_t fonts; extern teken_gfx_t gfx_state; typedef enum { GfxFbBltVideoFill, GfxFbBltVideoToBltBuffer, GfxFbBltBufferToVideo, GfxFbBltVideoToVideo, GfxFbBltOperationMax, } GFXFB_BLT_OPERATION; int gfxfb_blt(void *, GFXFB_BLT_OPERATION, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); int generate_cons_palette(uint32_t *, int, uint32_t, int, uint32_t, int, uint32_t, int); bool console_update_mode(bool); void setup_font(teken_gfx_t *, teken_unit_t, teken_unit_t); uint8_t *font_lookup(const struct vt_font *, teken_char_t, const teken_attr_t *); void bios_text_font(bool); /* teken callbacks. */ tf_cursor_t gfx_fb_cursor; tf_putchar_t gfx_fb_putchar; tf_fill_t gfx_fb_fill; tf_copy_t gfx_fb_copy; tf_param_t gfx_fb_param; /* Screen buffer element */ struct text_pixel { teken_char_t c; teken_attr_t a; }; extern const int cons_to_vga_colors[NCOLORS]; /* Screen buffer to track changes on the terminal screen. */ extern struct text_pixel *screen_buffer; bool is_same_pixel(struct text_pixel *, struct text_pixel *); bool gfx_get_edid_resolution(struct vesa_edid_info *, edid_res_list_t *); void gfx_framework_init(void); void gfx_fb_cons_display(uint32_t, uint32_t, uint32_t, uint32_t, void *); void gfx_fb_setpixel(uint32_t, uint32_t); void gfx_fb_drawrect(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); void gfx_term_drawrect(uint32_t, uint32_t, uint32_t, uint32_t); void gfx_fb_line(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); void gfx_fb_bezier(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); #define FL_PUTIMAGE_BORDER 0x1 #define FL_PUTIMAGE_NOSCROLL 0x2 #define FL_PUTIMAGE_DEBUG 0x80 int gfx_fb_putimage(png_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); bool gfx_parse_mode_str(char *, int *, int *, int *); void term_image_display(teken_gfx_t *, const teken_rect_t *); void reset_font_flags(void); +void gfx_interp_md(void); + #ifdef __cplusplus } #endif #endif /* _GFX_FB_H */ diff --git a/stand/common/interp_simple.c b/stand/common/interp_simple.c index fa021c796308..61ed724af9d0 100644 --- a/stand/common/interp_simple.c +++ b/stand/common/interp_simple.c @@ -1,200 +1,208 @@ /*- * Copyright (c) 1998 Michael Smith * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include /* * Simple commandline interpreter, toplevel and misc. */ #include #include #include "bootstrap.h" INTERP_DEFINE("simp"); void interp_init(void) { setenv("script.lang", "simple", 1); /* Read our default configuration. */ interp_include("/boot/loader.rc"); } int interp_run(const char *input) { int argc; char **argv; if (parse(&argc, &argv, input)) { printf("parse error\n"); return CMD_ERROR; } if (interp_builtin_cmd(argc, argv)) { printf("%s: %s\n", argv[0], command_errmsg); free(argv); return CMD_ERROR; } free(argv); return CMD_OK; } /* * Header prepended to each line. The text immediately follows the header. * We try to make this short in order to save memory -- the loader has * limited memory available, and some of the forth files are very long. */ struct includeline { struct includeline *next; int flags; int line; #define SL_QUIET (1<<0) #define SL_IGNOREERR (1<<1) char text[0]; }; int interp_include(const char *filename) { struct includeline *script, *se, *sp; char input[256]; /* big enough? */ int argc,res; char **argv, *cp; int fd, flags, line; if (((fd = open(filename, O_RDONLY)) == -1)) { snprintf(command_errbuf, sizeof(command_errbuf), "can't open '%s': %s", filename, strerror(errno)); return(CMD_ERROR); } #ifdef LOADER_VERIEXEC if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) { close(fd); sprintf(command_errbuf,"can't verify '%s'", filename); return(CMD_ERROR); } #endif /* * Read the script into memory. */ script = se = NULL; line = 0; while (fgetstr(input, sizeof(input), fd) >= 0) { line++; flags = 0; /* Discard comments */ if (strncmp(input+strspn(input, " "), "\\", 1) == 0) continue; cp = input; /* Echo? */ if (input[0] == '@') { cp++; flags |= SL_QUIET; } /* Error OK? */ if (input[0] == '-') { cp++; flags |= SL_IGNOREERR; } /* Allocate script line structure and copy line, flags */ if (*cp == '\0') continue; /* ignore empty line, save memory */ sp = malloc(sizeof(struct includeline) + strlen(cp) + 1); /* On malloc failure (it happens!), free as much as possible and exit */ if (sp == NULL) { while (script != NULL) { se = script; script = script->next; free(se); } snprintf(command_errbuf, sizeof(command_errbuf), "file '%s' line %d: memory allocation failure - aborting", filename, line); close(fd); return (CMD_ERROR); } strcpy(sp->text, cp); sp->flags = flags; sp->line = line; sp->next = NULL; if (script == NULL) { script = sp; } else { se->next = sp; } se = sp; } close(fd); /* * Execute the script */ argv = NULL; res = CMD_OK; for (sp = script; sp != NULL; sp = sp->next) { /* print if not being quiet */ if (!(sp->flags & SL_QUIET)) { interp_emit_prompt(); printf("%s\n", sp->text); } /* Parse the command */ if (!parse(&argc, &argv, sp->text)) { if ((argc > 0) && (interp_builtin_cmd(argc, argv) != 0)) { /* normal command */ printf("%s: %s\n", argv[0], command_errmsg); if (!(sp->flags & SL_IGNOREERR)) { res=CMD_ERROR; break; } } free(argv); argv = NULL; } else { printf("%s line %d: parse error\n", filename, sp->line); res=CMD_ERROR; break; } } if (argv != NULL) free(argv); while (script != NULL) { se = script; script = script->next; free(se); } return(res); } + +/* + * There's no graphics commands for the simple interpreter. + */ +void +gfx_interp_md(void) +{ +} diff --git a/stand/liblua/gfx_utils.c b/stand/liblua/gfx_utils.c index fe208dc990d8..d2d22738c929 100644 --- a/stand/liblua/gfx_utils.c +++ b/stand/liblua/gfx_utils.c @@ -1,242 +1,247 @@ /*- * Copyright (c) 2024 Netflix, Inc. * * SPDX-License-Identifier: BSD-2-Clause */ /* Copied from a file that likely shoulve have had this at the top */ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2020 Toomas Soome * Copyright 2020 RackTop Systems, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "lua.h" #include "lauxlib.h" #include "lutils.h" #include #include /* * put image using terminal coordinates. */ static int lua_term_putimage(lua_State *L) { const char *name; png_t png; uint32_t x1, y1, x2, y2, f; int nargs, ret = 0, error; nargs = lua_gettop(L); if (nargs != 6) { lua_pushboolean(L, 0); return 1; } name = luaL_checkstring(L, 1); x1 = luaL_checknumber(L, 2); y1 = luaL_checknumber(L, 3); x2 = luaL_checknumber(L, 4); y2 = luaL_checknumber(L, 5); f = luaL_checknumber(L, 6); x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; if (x2 != 0) { x2 = gfx_state.tg_origin.tp_col + x2 * gfx_state.tg_font.vf_width; } if (y2 != 0) { y2 = gfx_state.tg_origin.tp_row + y2 * gfx_state.tg_font.vf_height; } if ((error = png_open(&png, name)) != PNG_NO_ERROR) { if (f & FL_PUTIMAGE_DEBUG) printf("%s\n", png_error_string(error)); } else { if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) ret = 1; (void) png_close(&png); } lua_pushboolean(L, ret); return 1; } static int lua_fb_putimage(lua_State *L) { const char *name; png_t png; uint32_t x1, y1, x2, y2, f; int nargs, ret = 0, error; nargs = lua_gettop(L); if (nargs != 6) { lua_pushboolean(L, 0); return 1; } name = luaL_checkstring(L, 1); x1 = luaL_checknumber(L, 2); y1 = luaL_checknumber(L, 3); x2 = luaL_checknumber(L, 4); y2 = luaL_checknumber(L, 5); f = luaL_checknumber(L, 6); if ((error = png_open(&png, name)) != PNG_NO_ERROR) { if (f & FL_PUTIMAGE_DEBUG) printf("%s\n", png_error_string(error)); } else { if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) ret = 1; (void) png_close(&png); } lua_pushboolean(L, ret); return 1; } static int lua_fb_setpixel(lua_State *L) { uint32_t x, y; int nargs; nargs = lua_gettop(L); if (nargs != 2) { lua_pushnil(L); return 1; } x = luaL_checknumber(L, 1); y = luaL_checknumber(L, 2); gfx_fb_setpixel(x, y); return 0; } static int lua_fb_line(lua_State *L) { uint32_t x0, y0, x1, y1, wd; int nargs; nargs = lua_gettop(L); if (nargs != 5) { lua_pushnil(L); return 1; } x0 = luaL_checknumber(L, 1); y0 = luaL_checknumber(L, 2); x1 = luaL_checknumber(L, 3); y1 = luaL_checknumber(L, 4); wd = luaL_checknumber(L, 5); gfx_fb_line(x0, y0, x1, y1, wd); return 0; } static int lua_fb_bezier(lua_State *L) { uint32_t x0, y0, x1, y1, x2, y2, width; int nargs; nargs = lua_gettop(L); if (nargs != 7) { lua_pushnil(L); return 1; } x0 = luaL_checknumber(L, 1); y0 = luaL_checknumber(L, 2); x1 = luaL_checknumber(L, 3); y1 = luaL_checknumber(L, 4); x2 = luaL_checknumber(L, 5); y2 = luaL_checknumber(L, 6); width = luaL_checknumber(L, 7); gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); return 0; } static int lua_fb_drawrect(lua_State *L) { uint32_t x0, y0, x1, y1, fill; int nargs; nargs = lua_gettop(L); if (nargs != 5) { lua_pushnil(L); return 1; } x0 = luaL_checknumber(L, 1); y0 = luaL_checknumber(L, 2); x1 = luaL_checknumber(L, 3); y1 = luaL_checknumber(L, 4); fill = luaL_checknumber(L, 5); gfx_fb_drawrect(x0, y0, x1, y1, fill); return 0; } static int lua_term_drawrect(lua_State *L) { uint32_t x0, y0, x1, y1; int nargs; nargs = lua_gettop(L); if (nargs != 4) { lua_pushnil(L); return 1; } x0 = luaL_checknumber(L, 1); y0 = luaL_checknumber(L, 2); x1 = luaL_checknumber(L, 3); y1 = luaL_checknumber(L, 4); gfx_term_drawrect(x0, y0, x1, y1); return 0; } #define REG_SIMPLE(n) { #n, lua_ ## n } static const struct luaL_Reg gfxlib[] = { REG_SIMPLE(fb_bezier), REG_SIMPLE(fb_drawrect), REG_SIMPLE(fb_line), REG_SIMPLE(fb_putimage), REG_SIMPLE(fb_setpixel), REG_SIMPLE(term_drawrect), REG_SIMPLE(term_putimage), { NULL, NULL }, }; int luaopen_gfx(lua_State *L) { luaL_newlib(L, gfxlib); return 1; } + +void +gfx_interp_md(void) +{ +}