1 /* $NetBSD: rasops.h,v 1.51 2025/07/25 18:19:12 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _RASOPS_H_ 33 #define _RASOPS_H_ 1 34 35 #include <sys/param.h> 36 37 #include <dev/wscons/wsconsio.h> 38 #include <dev/wscons/wsdisplayvar.h> 39 #include <dev/wsfont/wsfont.h> 40 41 /* For rasops_info::ri_flg */ 42 #define RI_FULLCLEAR 0x01 /* eraserows() hack to clear full screen */ 43 #define RI_FORCEMONO 0x02 /* monochrome output even if we can do color */ 44 #define RI_BSWAP 0x04 /* framebuffer endianness doesn't match CPU */ 45 #define RI_CURSOR 0x08 /* cursor is switched on */ 46 #define RI_CLEAR 0x10 /* clear display on startup */ 47 #define RI_CENTER 0x20 /* center onscreen output */ 48 #define RI_CURSORCLIP 0x40 /* cursor is currently clipped */ 49 #define RI_CFGDONE 0x80 /* rasops_reconfig() completed successfully */ 50 #define RI_ROTATE_CW 0x100 /* display is rotated, quarter clockwise */ 51 #define RI_ROTATE_CCW 0x200 /* display is rotated, quarter counter-clockwise */ 52 #define RI_ROTATE_UD 0x400 /* display is rotated, upside-down */ 53 #define RI_ROTATE_MASK 0x700 54 /* 55 * if you call rasops_init() or rasops_reconfig() in a context where it is not 56 * safe to call kmem_alloc(), like early on during kernel startup, you MUST set 57 * RI_NO_AUTO to keep rasops from trying to allocate memory for autogenerated 58 * box drawing characters 59 */ 60 #define RI_NO_AUTO 0x800 /* do not generate box drawing characters */ 61 /* 62 * Set this if your driver's putchar() method supports anti-aliased fonts in 63 * the given video mode. Without this flag rasops_init() will only ever pick 64 * monochrome bitmap fonts. 65 */ 66 #define RI_ENABLE_ALPHA 0x1000 67 /* set this in order to use r3g3b2 'true' colour in 8 bit */ 68 #define RI_8BIT_IS_RGB 0x2000 69 /* 70 * drivers can set this to tell the font selection code that they'd rather 71 * use alpha fonts 72 */ 73 #define RI_PREFER_ALPHA 0x4000 74 /* 75 * Set this to prefer a wider font. 76 */ 77 #define RI_PREFER_WIDEFONT 0x8000 78 79 struct rasops_info { 80 /* These must be filled in by the caller */ 81 int ri_depth; /* depth in bits */ 82 uint8_t *ri_bits; /* ptr to bits */ 83 int ri_width; /* width (pels) */ 84 int ri_height; /* height (pels) */ 85 int ri_stride; /* stride in bytes */ 86 87 /* 88 * If you want shadow framebuffer support, point ri_hwbits 89 * to the real framebuffer, and ri_bits to the shadow framebuffer 90 */ 91 uint8_t *ri_hwbits; 92 93 /* 94 * These can optionally be left zeroed out. If you fill ri_font, 95 * but aren't using wsfont, set ri_wsfcookie to -1. 96 */ 97 struct wsdisplay_font *ri_font; 98 struct wsdisplay_font ri_optfont; 99 int ri_wsfcookie; /* wsfont cookie */ 100 void *ri_hw; /* driver private data; ignored by rasops */ 101 int ri_crow; /* cursor row */ 102 int ri_ccol; /* cursor column */ 103 int ri_flg; /* various operational flags */ 104 105 /* 106 * These are optional and will default if zero. Meaningless 107 * on depths other than 15, 16, 24 and 32 bits per pel. On 108 * 24 bit displays, ri_{r,g,b}num must be 8. 109 */ 110 uint8_t ri_rnum; /* number of bits for red */ 111 uint8_t ri_gnum; /* number of bits for green */ 112 uint8_t ri_bnum; /* number of bits for blue */ 113 uint8_t ri_rpos; /* which bit red starts at */ 114 uint8_t ri_gpos; /* which bit green starts at */ 115 uint8_t ri_bpos; /* which bit blue starts at */ 116 117 /* These are filled in by rasops_init() */ 118 int ri_emuwidth; /* width we actually care about */ 119 int ri_emuheight; /* height we actually care about */ 120 int ri_emustride; /* bytes per row we actually care about */ 121 int ri_rows; /* number of rows (characters, not pels) */ 122 int ri_cols; /* number of columns (characters, not pels) */ 123 #if __NetBSD_Prereq__(9, 99, 1) 124 struct { 125 int off; /* offset of underline from bottom */ 126 int height; /* height of underline */ 127 } ri_ul; 128 #else 129 /* 130 * XXX 131 * hack to keep ABI compatibility for netbsd-9, -8, and -7. 132 */ 133 // int ri_delta; /* obsoleted */ 134 struct { 135 short off; 136 short height; 137 } __packed ri_ul; 138 #endif 139 int ri_pelbytes; /* bytes per pel (may be zero) */ 140 int ri_fontscale; /* fontheight * fontstride */ 141 int ri_xscale; /* fontwidth * pelbytes */ 142 int ri_yscale; /* fontheight * stride */ 143 uint8_t *ri_origbits; /* where screen bits actually start */ 144 uint8_t *ri_hworigbits; /* where hw bits actually start */ 145 int ri_xorigin; /* where ri_bits begins (x) */ 146 int ri_yorigin; /* where ri_bits begins (y) */ 147 uint32_t 148 ri_devcmap[16]; /* color -> framebuffer data */ 149 150 /* The emulops you need to use, and the screen caps for wscons */ 151 struct wsdisplay_emulops ri_ops; 152 int ri_caps; 153 154 /* Callbacks so we can share some code */ 155 void (*ri_do_cursor)(struct rasops_info *); 156 157 /* Used to intercept putchar to permit display rotation */ 158 struct wsdisplay_emulops ri_real_ops; 159 }; 160 161 #define CHAR_IN_FONT(c, font) \ 162 ((c) >= (font)->firstchar && \ 163 (c) - (font)->firstchar < (font)->numchars) 164 165 #define PICK_FONT(ri, c) \ 166 ((((c) & WSFONT_FLAGS_MASK) == WSFONT_FLAG_OPT && \ 167 (ri)->ri_optfont.data != NULL) ? \ 168 &(ri)->ri_optfont : (ri)->ri_font) 169 170 /* 171 * rasops_init(). 172 * 173 * Integer parameters are the number of rows and columns we'd *like*. 174 * 175 * In terms of optimization, fonts that are a multiple of 8 pixels wide 176 * work the best. 177 * 178 * rasops_init() takes care of rasops_reconfig(). The parameters to both 179 * are the same. If calling rasops_reconfig() to change the font and 180 * ri_wsfcookie >= 0, you must call wsfont_unlock() on it, and reset it 181 * to -1 (or a new, valid cookie). 182 */ 183 184 /* rasops.c */ 185 int rasops_init(struct rasops_info *, int, int); 186 int rasops_reconfig(struct rasops_info *, int, int); 187 void rasops_unpack_attr(long, int *, int *, int *); 188 void rasops_eraserows(void *, int, int, long); 189 void rasops_erasecols(void *, int, int, int, long); 190 int rasops_get_cmap(struct rasops_info *, uint8_t *, size_t); 191 192 extern const uint8_t rasops_cmap[256 * 3]; 193 194 #ifdef _RASOPS_PRIVATE 195 /* 196 * Per-depth initialization functions. 197 */ 198 void rasops1_init(struct rasops_info *); 199 void rasops2_init(struct rasops_info *); 200 void rasops4_init(struct rasops_info *); 201 void rasops8_init(struct rasops_info *); 202 void rasops15_init(struct rasops_info *); 203 void rasops24_init(struct rasops_info *); 204 void rasops32_init(struct rasops_info *); 205 206 #define ATTR_BG(ri, attr) ((ri)->ri_devcmap[((uint32_t)(attr) >> 16) & 0xf]) 207 #define ATTR_FG(ri, attr) ((ri)->ri_devcmap[((uint32_t)(attr) >> 24) & 0xf]) 208 209 #define ATTR_MASK_BG __BITS(16, 19) 210 #define ATTR_MASK_FG __BITS(24, 27) 211 212 #define DELTA(p, d, cast) ((p) = (cast)((uint8_t *)(p) + (d))) 213 214 #define FBOFFSET(ri, row, col) \ 215 ((row) * (ri)->ri_yscale + (col) * (ri)->ri_xscale) 216 217 #define FONT_GLYPH(uc, font, ri) \ 218 ((uint8_t *)(font)->data + ((uc) - ((font)->firstchar)) * \ 219 (ri)->ri_fontscale) 220 221 static __inline void 222 rasops_memset32(void *p, uint32_t val, size_t bytes) 223 { 224 int slop1, slop2, full; 225 uint8_t *dp = (uint8_t *)p; 226 227 if (bytes == 1) { 228 *dp = val; 229 return; 230 } 231 232 slop1 = (4 - ((uintptr_t)dp & 3)) & 3; 233 slop2 = (bytes - slop1) & 3; 234 full = (bytes - slop1 /* - slop2 */) >> 2; 235 236 if (slop1 & 1) 237 *dp++ = val; 238 239 if (slop1 & 2) { 240 *(uint16_t *)dp = val; 241 dp += 2; 242 } 243 244 for (; full; full--) { 245 *(uint32_t *)dp = val; 246 dp += 4; 247 } 248 249 if (slop2 & 2) { 250 *(uint16_t *)dp = val; 251 dp += 2; 252 } 253 254 if (slop2 & 1) 255 *dp = val; 256 257 return; 258 } 259 260 static __inline uint32_t 261 rasops_be32uatoh(uint8_t *p) 262 { 263 uint32_t u; 264 265 u = p[0]; u <<= 8; 266 u |= p[1]; u <<= 8; 267 u |= p[2]; u <<= 8; 268 u |= p[3]; 269 return u; 270 } 271 #endif /* _RASOPS_PRIVATE */ 272 273 #endif /* _RASOPS_H_ */ 274