1*9593dc34Smglocker /* $OpenBSD: fb.c,v 1.31 2024/09/04 07:54:52 mglocker Exp $ */ 270d3ea64Smiod /* $NetBSD: fb.c,v 1.23 1997/07/07 23:30:22 pk Exp $ */ 370d3ea64Smiod 470d3ea64Smiod /* 5607827a8Smiod * Copyright (c) 2002, 2004, 2008 Miodrag Vallat. 670d3ea64Smiod * All rights reserved. 770d3ea64Smiod * 870d3ea64Smiod * Redistribution and use in source and binary forms, with or without 970d3ea64Smiod * modification, are permitted provided that the following conditions 1070d3ea64Smiod * are met: 1170d3ea64Smiod * 1. Redistributions of source code must retain the above copyright 1270d3ea64Smiod * notice, this list of conditions and the following disclaimer. 1370d3ea64Smiod * 2. Redistributions in binary form must reproduce the above copyright 1470d3ea64Smiod * notice, this list of conditions and the following disclaimer in the 1570d3ea64Smiod * documentation and/or other materials provided with the distribution. 1670d3ea64Smiod * 1770d3ea64Smiod * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1870d3ea64Smiod * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1970d3ea64Smiod * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2070d3ea64Smiod * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 2170d3ea64Smiod * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2270d3ea64Smiod * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2370d3ea64Smiod * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2470d3ea64Smiod * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2570d3ea64Smiod * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 2670d3ea64Smiod * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2770d3ea64Smiod * POSSIBILITY OF SUCH DAMAGE. 2870d3ea64Smiod * 2970d3ea64Smiod * 3070d3ea64Smiod * Copyright (c) 1992, 1993 3170d3ea64Smiod * The Regents of the University of California. All rights reserved. 3270d3ea64Smiod * 3370d3ea64Smiod * This software was developed by the Computer Systems Engineering group 3470d3ea64Smiod * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 3570d3ea64Smiod * contributed to Berkeley. 3670d3ea64Smiod * 3770d3ea64Smiod * All advertising materials mentioning features or use of this software 3870d3ea64Smiod * must display the following acknowledgement: 3970d3ea64Smiod * This product includes software developed by the University of 4070d3ea64Smiod * California, Lawrence Berkeley Laboratory. 4170d3ea64Smiod * 4270d3ea64Smiod * Redistribution and use in source and binary forms, with or without 4370d3ea64Smiod * modification, are permitted provided that the following conditions 4470d3ea64Smiod * are met: 4570d3ea64Smiod * 1. Redistributions of source code must retain the above copyright 4670d3ea64Smiod * notice, this list of conditions and the following disclaimer. 4770d3ea64Smiod * 2. Redistributions in binary form must reproduce the above copyright 4870d3ea64Smiod * notice, this list of conditions and the following disclaimer in the 4970d3ea64Smiod * documentation and/or other materials provided with the distribution. 5070d3ea64Smiod * 3. Neither the name of the University nor the names of its contributors 5170d3ea64Smiod * may be used to endorse or promote products derived from this software 5270d3ea64Smiod * without specific prior written permission. 5370d3ea64Smiod * 5470d3ea64Smiod * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 5570d3ea64Smiod * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5670d3ea64Smiod * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5770d3ea64Smiod * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 5870d3ea64Smiod * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5970d3ea64Smiod * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 6070d3ea64Smiod * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 6170d3ea64Smiod * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 6270d3ea64Smiod * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 6370d3ea64Smiod * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 6470d3ea64Smiod * SUCH DAMAGE. 6570d3ea64Smiod * 6670d3ea64Smiod * @(#)fb.c 8.1 (Berkeley) 6/11/93 6770d3ea64Smiod */ 6870d3ea64Smiod 6970d3ea64Smiod /* 7070d3ea64Smiod * Common wsdisplay framebuffer drivers helpers. 7170d3ea64Smiod */ 7270d3ea64Smiod 7370d3ea64Smiod #include <sys/param.h> 7470d3ea64Smiod #include <sys/systm.h> 7570d3ea64Smiod #include <sys/device.h> 7670d3ea64Smiod #include <sys/proc.h> 7770d3ea64Smiod #include <sys/conf.h> 7870d3ea64Smiod 7970d3ea64Smiod #include <machine/autoconf.h> 8070d3ea64Smiod #include <machine/conf.h> 81607827a8Smiod #include <machine/openfirm.h> 8270d3ea64Smiod 8370d3ea64Smiod #include <dev/wscons/wsdisplayvar.h> 8470d3ea64Smiod #include <dev/rasops/rasops.h> 8570d3ea64Smiod #include <machine/fbvar.h> 8670d3ea64Smiod 8770d3ea64Smiod #include "wsdisplay.h" 8870d3ea64Smiod 8970d3ea64Smiod /* 903238630cSmiod * Sun specific color indexes. 913238630cSmiod * Black is not really 7, but rather ~0; to fit within the 8 ANSI color 923238630cSmiod * palette we are using on console, we pick (~0) & 0x07 instead. 933238630cSmiod * This essentially swaps WSCOL_BLACK and WSCOL_WHITE. 943238630cSmiod */ 953238630cSmiod #define WSCOL_SUN_WHITE 0 963238630cSmiod #define WSCOL_SUN_BLACK 7 973238630cSmiod 983238630cSmiod /* 9970d3ea64Smiod * emergency unblank code 10070d3ea64Smiod * XXX should be somewhat moved to wscons MI code 10170d3ea64Smiod */ 10270d3ea64Smiod 10370d3ea64Smiod void (*fb_burner)(void *, u_int, u_int); 10470d3ea64Smiod void *fb_cookie; 10570d3ea64Smiod 10670d3ea64Smiod void 1070aac5001Snaddy fb_unblank(void) 10870d3ea64Smiod { 10970d3ea64Smiod if (fb_burner != NULL) 11070d3ea64Smiod (*fb_burner)(fb_cookie, 1, 0); 11170d3ea64Smiod } 11270d3ea64Smiod 11370d3ea64Smiod #if NWSDISPLAY > 0 11470d3ea64Smiod 1152f3b6a47Smiod static int a2int(char *, int); 116607827a8Smiod int fb_get_console_metrics(int *, int *, int *, int *); 117607827a8Smiod void fb_initwsd(struct sunfb *); 118607827a8Smiod void fb_updatecursor(struct rasops_info *); 119607827a8Smiod 120607827a8Smiod int fb_alloc_screen(void *, const struct wsscreen_descr *, void **, 121e0c3e559Sjsg int *, int *, uint32_t *); 122607827a8Smiod void fb_free_screen(void *, void *); 123607827a8Smiod int fb_show_screen(void *, void *, int, void (*)(void *, int, int), 124607827a8Smiod void *); 12583275742Smiod int fb_load_font(void *, void *, struct wsdisplay_font *); 12683275742Smiod int fb_list_font(void *, struct wsdisplay_font *); 1272f3b6a47Smiod 12870d3ea64Smiod void 12970d3ea64Smiod fb_setsize(struct sunfb *sf, int def_depth, int def_width, int def_height, 13070d3ea64Smiod int node, int unused) 13170d3ea64Smiod { 13270d3ea64Smiod int def_linebytes; 13370d3ea64Smiod 1349f777a6aSkettenis /* 1359f777a6aSkettenis * Some PCI devices lack the `depth' property, but have a `depth ' 1369f777a6aSkettenis * property (with a trailing space) instead. 1379f777a6aSkettenis */ 1389f777a6aSkettenis sf->sf_depth = getpropint(node, "depth", 1399f777a6aSkettenis getpropint(node, "depth ", def_depth)); 14070d3ea64Smiod sf->sf_width = getpropint(node, "width", def_width); 14170d3ea64Smiod sf->sf_height = getpropint(node, "height", def_height); 14270d3ea64Smiod 14370d3ea64Smiod def_linebytes = 14470d3ea64Smiod roundup(sf->sf_width, sf->sf_depth) * sf->sf_depth / 8; 14570d3ea64Smiod sf->sf_linebytes = getpropint(node, "linebytes", def_linebytes); 146607827a8Smiod 14770d3ea64Smiod /* 14870d3ea64Smiod * XXX If we are configuring a board in a wider depth level 14970d3ea64Smiod * than the mode it is currently operating in, the PROM will 15070d3ea64Smiod * return a linebytes property tied to the current depth value, 15170d3ea64Smiod * which is NOT what we are relying upon! 15270d3ea64Smiod */ 153607827a8Smiod if (sf->sf_linebytes < (sf->sf_width * sf->sf_depth) / 8) 15470d3ea64Smiod sf->sf_linebytes = def_linebytes; 15570d3ea64Smiod 15670d3ea64Smiod sf->sf_fbsize = sf->sf_height * sf->sf_linebytes; 15770d3ea64Smiod } 15870d3ea64Smiod 159de9ae89dSmiod static int 16070d3ea64Smiod a2int(char *cp, int deflt) 16170d3ea64Smiod { 16270d3ea64Smiod int i = 0; 16370d3ea64Smiod 16470d3ea64Smiod if (*cp == '\0') 16570d3ea64Smiod return (deflt); 16670d3ea64Smiod while (*cp != '\0') 16770d3ea64Smiod i = i * 10 + *cp++ - '0'; 16870d3ea64Smiod return (i); 16970d3ea64Smiod } 17070d3ea64Smiod 171de9ae89dSmiod /* setup the embedded wsscreen_descr structure from rasops settings */ 172607827a8Smiod void 173de9ae89dSmiod fb_initwsd(struct sunfb *sf) 174de9ae89dSmiod { 175de9ae89dSmiod strlcpy(sf->sf_wsd.name, "std", sizeof(sf->sf_wsd.name)); 176de9ae89dSmiod sf->sf_wsd.capabilities = sf->sf_ro.ri_caps; 177de9ae89dSmiod sf->sf_wsd.nrows = sf->sf_ro.ri_rows; 178de9ae89dSmiod sf->sf_wsd.ncols = sf->sf_ro.ri_cols; 179de9ae89dSmiod sf->sf_wsd.textops = &sf->sf_ro.ri_ops; 180de9ae89dSmiod } 181de9ae89dSmiod 182607827a8Smiod void 1832f3b6a47Smiod fb_updatecursor(struct rasops_info *ri) 1842f3b6a47Smiod { 1852f3b6a47Smiod struct sunfb *sf = (struct sunfb *)ri->ri_hw; 1862f3b6a47Smiod 1872f3b6a47Smiod if (sf->sf_crowp != NULL) 1882f3b6a47Smiod *sf->sf_crowp = ri->ri_crow; 1892f3b6a47Smiod if (sf->sf_ccolp != NULL) 1902f3b6a47Smiod *sf->sf_ccolp = ri->ri_ccol; 1912f3b6a47Smiod } 1922f3b6a47Smiod 19370d3ea64Smiod void 194607827a8Smiod fbwscons_init(struct sunfb *sf, int flags, int isconsole) 19570d3ea64Smiod { 1960c14c0f0Smiod struct rasops_info *ri = &sf->sf_ro; 197607827a8Smiod int cols, rows, fw, fh, wt, wl; 19870d3ea64Smiod 19970d3ea64Smiod /* ri_hw and ri_bits must have already been setup by caller */ 200607827a8Smiod ri->ri_flg = RI_FULLCLEAR | flags; 2010c14c0f0Smiod ri->ri_depth = sf->sf_depth; 2020c14c0f0Smiod ri->ri_stride = sf->sf_linebytes; 2030c14c0f0Smiod ri->ri_width = sf->sf_width; 2040c14c0f0Smiod ri->ri_height = sf->sf_height; 20570d3ea64Smiod 20670d3ea64Smiod rows = a2int(getpropstring(optionsnode, "screen-#rows"), 34); 20770d3ea64Smiod cols = a2int(getpropstring(optionsnode, "screen-#columns"), 80); 20870d3ea64Smiod 209607827a8Smiod /* 210607827a8Smiod * If the framebuffer width is under 960 pixels, rasops will 211607827a8Smiod * switch from the 12x22 font to the more adequate 8x16 font 212607827a8Smiod * here. 213607827a8Smiod * If we are the console device, we need to adjust two things: 214*9593dc34Smglocker * - the display row should be overridden from the current PROM 215607827a8Smiod * metrics, since it will not match the PROM reality anymore. 216607827a8Smiod * - the screen needs to be cleared. 217607827a8Smiod * 21834a62e53Skrw * However, to accommodate laptops with specific small fonts, 219607827a8Smiod * it is necessary to compare the resolution with the actual 220607827a8Smiod * font metrics. 221607827a8Smiod */ 222607827a8Smiod 223607827a8Smiod if (isconsole) { 224607827a8Smiod if (fb_get_console_metrics(&fw, &fh, &wt, &wl) != 0) { 225607827a8Smiod /* 226607827a8Smiod * Assume a 12x22 prom font and a centered 227607827a8Smiod * 80x34 console window. 228607827a8Smiod */ 229607827a8Smiod fw = 12; fh = 22; 230095b369dSmiod wt = wl = 0; 231095b369dSmiod } else { 232095b369dSmiod /* 233095b369dSmiod * Make sure window-top and window-left 234095b369dSmiod * values are consistent with the font metrics. 235095b369dSmiod */ 2362dd06ba7Skettenis if (wt <= 0 || wt > sf->sf_height - rows * fh || 2372dd06ba7Skettenis wl <= 0 || wl > sf->sf_width - cols * fw) 238095b369dSmiod wt = wl = 0; 23930afeea5Smiod } 240095b369dSmiod if (wt == 0 /* || wl == 0 */) { 241607827a8Smiod ri->ri_flg |= RI_CENTER; 242607827a8Smiod 243607827a8Smiod /* 244607827a8Smiod * Since the console window might not be 245607827a8Smiod * centered (e.g. on a 1280x1024 vigra 246607827a8Smiod * VS-12 frame buffer), have rasops 247607827a8Smiod * clear the margins even if the screen is 248607827a8Smiod * not cleared. 249607827a8Smiod */ 250607827a8Smiod ri->ri_flg |= RI_CLEARMARGINS; 251607827a8Smiod } 252607827a8Smiod 253607827a8Smiod if (ri->ri_wsfcookie != 0) { 254607827a8Smiod /* driver handles font issues. do nothing. */ 255607827a8Smiod } else { 256607827a8Smiod /* 257607827a8Smiod * If the PROM uses a different font than the 258607827a8Smiod * one we are expecting it to use, or if the 259607827a8Smiod * display is shorter than 960 pixels wide, 260607827a8Smiod * we'll force a screen clear. 261607827a8Smiod */ 262607827a8Smiod if (fw != 12 || sf->sf_width < 12 * 80) 263607827a8Smiod ri->ri_flg |= RI_CLEAR | RI_CENTER; 264607827a8Smiod } 265607827a8Smiod } else { 266607827a8Smiod ri->ri_flg |= RI_CLEAR | RI_CENTER; 267607827a8Smiod } 268607827a8Smiod 269607827a8Smiod /* ifb(4) doesn't set ri_bits at the moment */ 270607827a8Smiod if (ri->ri_bits == NULL) 2719c2c4db2Smiod ri->ri_flg &= ~(RI_CLEAR | RI_CLEARMARGINS); 272607827a8Smiod 2730c14c0f0Smiod rasops_init(ri, rows, cols); 2743049e847Smiod 275607827a8Smiod /* 276607827a8Smiod * If this is the console display and there is no font change, 277607827a8Smiod * adjust our terminal window to the position of the PROM 278607827a8Smiod * window - in case it is not exactly centered. 279607827a8Smiod */ 280607827a8Smiod if ((ri->ri_flg & RI_CENTER) == 0) { 281607827a8Smiod /* code above made sure wt and wl are initialized */ 282607827a8Smiod ri->ri_bits += wt * ri->ri_stride; 283607827a8Smiod if (ri->ri_depth >= 8) /* for 15bpp to compute ok */ 284607827a8Smiod ri->ri_bits += wl * ri->ri_pelbytes; 285607827a8Smiod else 286607827a8Smiod ri->ri_bits += (wl * ri->ri_depth) >> 3; 287607827a8Smiod 288607827a8Smiod ri->ri_xorigin = wl; 289607827a8Smiod ri->ri_yorigin = wt; 290607827a8Smiod } 291607827a8Smiod 2923049e847Smiod if (sf->sf_depth == 8) { 2933049e847Smiod /* 2943049e847Smiod * If we are running with an indexed palette, compensate 2953049e847Smiod * the swap of black and white through ri_devcmap. 2963049e847Smiod */ 2973049e847Smiod ri->ri_devcmap[WSCOL_SUN_BLACK] = 0; 2983049e847Smiod ri->ri_devcmap[WSCOL_SUN_WHITE] = 0xffffffff; 2993049e847Smiod } else if (sf->sf_depth > 8) { 3003049e847Smiod /* 3013049e847Smiod * If we are running on a direct color frame buffer, 3023049e847Smiod * make the ``normal'' white the same as the highlighted 3033049e847Smiod * white. 3043049e847Smiod */ 3053049e847Smiod ri->ri_devcmap[WSCOL_WHITE] = ri->ri_devcmap[WSCOL_WHITE + 8]; 3063049e847Smiod } 30770d3ea64Smiod } 30870d3ea64Smiod 30970d3ea64Smiod void 310aca70fa6Smiod fbwscons_console_init(struct sunfb *sf, int row) 31170d3ea64Smiod { 3122008d283Smiod struct rasops_info *ri = &sf->sf_ro; 3133df54b20Skettenis void *cookie; 314e0c3e559Sjsg uint32_t defattr; 31570d3ea64Smiod 3162628683eSmiod if (romgetcursoraddr(&sf->sf_crowp, &sf->sf_ccolp)) 3172628683eSmiod sf->sf_ccolp = sf->sf_crowp = NULL; 3182628683eSmiod if (sf->sf_ccolp != NULL) 3192008d283Smiod ri->ri_ccol = *sf->sf_ccolp; 32070d3ea64Smiod 321607827a8Smiod if (ri->ri_flg & RI_CLEAR) { 322607827a8Smiod /* 323607827a8Smiod * If we have cleared the screen, this is because either 324607827a8Smiod * we are not the console display, or the font has been 325607827a8Smiod * changed. 326607827a8Smiod * In this case, choose not to keep pointers to the PROM 327607827a8Smiod * cursor position, as the values are likely to be inaccurate 328607827a8Smiod * upon shutdown... 329607827a8Smiod */ 330607827a8Smiod sf->sf_crowp = sf->sf_ccolp = NULL; 331607827a8Smiod row = 0; 332607827a8Smiod } 333607827a8Smiod 334607827a8Smiod if (row < 0) /* no override */ { 3352628683eSmiod if (sf->sf_crowp != NULL) 3362008d283Smiod ri->ri_crow = *sf->sf_crowp; 33770d3ea64Smiod else 33870d3ea64Smiod /* assume last row */ 3392008d283Smiod ri->ri_crow = ri->ri_rows - 1; 3402628683eSmiod } else { 3412008d283Smiod ri->ri_crow = row; 3422628683eSmiod } 34370d3ea64Smiod 34470d3ea64Smiod /* 34570d3ea64Smiod * Scale back rows and columns if the font would not otherwise 34670d3ea64Smiod * fit on this display. Without this we would panic later. 34770d3ea64Smiod */ 3482008d283Smiod if (ri->ri_crow >= ri->ri_rows) 3492008d283Smiod ri->ri_crow = ri->ri_rows - 1; 3502008d283Smiod if (ri->ri_ccol >= ri->ri_cols) 3512008d283Smiod ri->ri_ccol = ri->ri_cols - 1; 35270d3ea64Smiod 35370d3ea64Smiod /* 354a0c83eadSjsing * Take care of updating the PROM cursor position as well if we can. 3552f3b6a47Smiod */ 3562008d283Smiod if (ri->ri_updatecursor != NULL && 3572f3b6a47Smiod (sf->sf_ccolp != NULL || sf->sf_crowp != NULL)) 3582008d283Smiod ri->ri_updatecursor = fb_updatecursor; 3592f3b6a47Smiod 3603df54b20Skettenis if (ri->ri_flg & RI_VCONS) 3613df54b20Skettenis cookie = ri->ri_active; 3623df54b20Skettenis else 3633df54b20Skettenis cookie = ri; 3643df54b20Skettenis 3652008d283Smiod if (ISSET(ri->ri_caps, WSSCREEN_WSCOLORS)) 366fc223b23Sjsg ri->ri_ops.pack_attr(cookie, 36770d3ea64Smiod WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, &defattr); 3682008d283Smiod else 369fc223b23Sjsg ri->ri_ops.pack_attr(cookie, 0, 0, 0, &defattr); 37070d3ea64Smiod 371de9ae89dSmiod fb_initwsd(sf); 3723df54b20Skettenis wsdisplay_cnattach(&sf->sf_wsd, cookie, 3733df54b20Skettenis ri->ri_ccol, ri->ri_crow, defattr); 37470d3ea64Smiod } 37570d3ea64Smiod 37670d3ea64Smiod void 37770d3ea64Smiod fbwscons_setcolormap(struct sunfb *sf, 37870d3ea64Smiod void (*setcolor)(void *, u_int, u_int8_t, u_int8_t, u_int8_t)) 37970d3ea64Smiod { 38070d3ea64Smiod int i; 3813238630cSmiod const u_char *color; 38270d3ea64Smiod 38370d3ea64Smiod if (sf->sf_depth <= 8 && setcolor != NULL) { 38470d3ea64Smiod for (i = 0; i < 16; i++) { 3853238630cSmiod color = &rasops_cmap[i * 3]; 38670d3ea64Smiod setcolor(sf, i, color[0], color[1], color[2]); 38770d3ea64Smiod } 388ce0365c9Smiod for (i = 240; i < 256; i++) { 3893238630cSmiod color = &rasops_cmap[i * 3]; 390ce0365c9Smiod setcolor(sf, i, color[0], color[1], color[2]); 391ce0365c9Smiod } 3923238630cSmiod /* 3933238630cSmiod * Compensate for BoW default hardware palette: existing 3943238630cSmiod * output (which we do not want to affect) is black on 3953238630cSmiod * white with color index 0 being white and 0xff being 3963238630cSmiod * black. 3973238630cSmiod */ 3983238630cSmiod setcolor(sf, WSCOL_SUN_WHITE, 0xff, 0xff, 0xff); 3993238630cSmiod setcolor(sf, 0xff ^ WSCOL_SUN_WHITE, 0, 0, 0); 4003238630cSmiod setcolor(sf, WSCOL_SUN_BLACK, 0, 0, 0); 4013238630cSmiod setcolor(sf, 0xff ^ (WSCOL_SUN_BLACK), 0xff, 0xff, 0xff); 40270d3ea64Smiod } 40370d3ea64Smiod } 40470d3ea64Smiod 405de9ae89dSmiod void 406de9ae89dSmiod fbwscons_attach(struct sunfb *sf, struct wsdisplay_accessops *op, int isconsole) 407de9ae89dSmiod { 408de9ae89dSmiod struct wsemuldisplaydev_attach_args waa; 409de9ae89dSmiod 410de9ae89dSmiod if (isconsole == 0) { 411de9ae89dSmiod /* done in wsdisplay_cnattach() earlier if console */ 412de9ae89dSmiod fb_initwsd(sf); 413aca70fa6Smiod } else { 414aca70fa6Smiod /* remember screen burner routine */ 415aca70fa6Smiod fb_burner = op->burn_screen; 416aca70fa6Smiod fb_cookie = sf; 417de9ae89dSmiod } 418de9ae89dSmiod 419607827a8Smiod /* plug common wsdisplay_accessops if necessary */ 420607827a8Smiod if (op->alloc_screen == NULL) { 421607827a8Smiod op->alloc_screen = fb_alloc_screen; 422607827a8Smiod op->free_screen = fb_free_screen; 423607827a8Smiod op->show_screen = fb_show_screen; 424607827a8Smiod } 42583275742Smiod if (op->load_font == NULL) { 42683275742Smiod op->load_font = fb_load_font; 42783275742Smiod op->list_font = fb_list_font; 42883275742Smiod } 429607827a8Smiod 430ece7a61fSmiod sf->sf_scrlist[0] = &sf->sf_wsd; 431cffcb173Smiod sf->sf_wsl.nscreens = 1; 432ece7a61fSmiod sf->sf_wsl.screens = (const struct wsscreen_descr **)sf->sf_scrlist; 433de9ae89dSmiod 434de9ae89dSmiod waa.console = isconsole; 435cffcb173Smiod waa.scrdata = &sf->sf_wsl; 436de9ae89dSmiod waa.accessops = op; 437de9ae89dSmiod waa.accesscookie = sf; 4382281f83fSmiod waa.defaultscreens = 0; 439de9ae89dSmiod config_found(&sf->sf_dev, &waa, wsemuldisplaydevprint); 440de9ae89dSmiod } 441de9ae89dSmiod 442607827a8Smiod /* 443607827a8Smiod * Common wsdisplay_accessops routines. 444607827a8Smiod */ 445607827a8Smiod int 446607827a8Smiod fb_alloc_screen(void *v, const struct wsscreen_descr *type, 447e0c3e559Sjsg void **cookiep, int *curxp, int *curyp, uint32_t *attrp) 448607827a8Smiod { 449607827a8Smiod struct sunfb *sf = v; 450607827a8Smiod struct rasops_info *ri = &sf->sf_ro; 4513df54b20Skettenis void *cookie; 452607827a8Smiod 453607827a8Smiod if (sf->sf_nscreens > 0) 454607827a8Smiod return (ENOMEM); 455607827a8Smiod 4563df54b20Skettenis if (ri->ri_flg & RI_VCONS) 4573df54b20Skettenis cookie = ri->ri_active; 4583df54b20Skettenis else 4593df54b20Skettenis cookie = ri; 4603df54b20Skettenis 4613df54b20Skettenis *cookiep = cookie; 462607827a8Smiod *curyp = 0; 463607827a8Smiod *curxp = 0; 464607827a8Smiod if (ISSET(ri->ri_caps, WSSCREEN_WSCOLORS)) 465fc223b23Sjsg ri->ri_ops.pack_attr(cookie, 466607827a8Smiod WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp); 467607827a8Smiod else 468fc223b23Sjsg ri->ri_ops.pack_attr(cookie, 0, 0, 0, attrp); 469607827a8Smiod sf->sf_nscreens++; 470607827a8Smiod return (0); 471607827a8Smiod } 472607827a8Smiod 473607827a8Smiod void 474607827a8Smiod fb_free_screen(void *v, void *cookie) 475607827a8Smiod { 476607827a8Smiod struct sunfb *sf = v; 477607827a8Smiod 478607827a8Smiod sf->sf_nscreens--; 479607827a8Smiod } 480607827a8Smiod 481607827a8Smiod int 482607827a8Smiod fb_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), 483607827a8Smiod void *cbarg) 484607827a8Smiod { 485607827a8Smiod return (0); 486607827a8Smiod } 487607827a8Smiod 488607827a8Smiod int 48983275742Smiod fb_load_font(void *v, void *emulcookie, struct wsdisplay_font *font) 49083275742Smiod { 49183275742Smiod struct sunfb *sf = v; 49283275742Smiod struct rasops_info *ri = &sf->sf_ro; 49383275742Smiod 49483275742Smiod return rasops_load_font(ri, emulcookie, font); 49583275742Smiod } 49683275742Smiod 49783275742Smiod int 49883275742Smiod fb_list_font(void *v, struct wsdisplay_font *font) 49983275742Smiod { 50083275742Smiod struct sunfb *sf = v; 50183275742Smiod struct rasops_info *ri = &sf->sf_ro; 50283275742Smiod 50383275742Smiod return rasops_list_font(ri, font); 50483275742Smiod } 50583275742Smiod 50683275742Smiod int 507607827a8Smiod fb_get_console_metrics(int *fontwidth, int *fontheight, int *wtop, int *wleft) 508607827a8Smiod { 509607827a8Smiod cell_t romheight, romwidth, windowtop, windowleft; 510607827a8Smiod 511607827a8Smiod /* 512607827a8Smiod * Get the PROM font metrics and address 513607827a8Smiod */ 514607827a8Smiod OF_interpret("stdout @ is my-self " 515607827a8Smiod "addr char-height addr char-width " 516607827a8Smiod "addr window-top addr window-left", 517607827a8Smiod 4, &windowleft, &windowtop, &romwidth, &romheight); 518607827a8Smiod 51988ee6abdSmiod if (romheight == 0 || romwidth == 0 || 52088ee6abdSmiod windowtop == 0 || windowleft == 0) 521607827a8Smiod return (1); 522607827a8Smiod 523607827a8Smiod *fontwidth = (int)*(uint64_t *)romwidth; 524607827a8Smiod *fontheight = (int)*(uint64_t *)romheight; 525607827a8Smiod *wtop = (int)*(uint64_t *)windowtop; 526607827a8Smiod *wleft = (int)*(uint64_t *)windowleft; 527607827a8Smiod 528607827a8Smiod return (0); 529607827a8Smiod } 530607827a8Smiod 53170d3ea64Smiod #endif /* NWSDISPLAY */ 532