1/*- 2 * Copyright (c) 1999 FreeBSD(98) Porting Team. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer as 10 * the first lines of this file unmodified. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#include "opt_syscons.h" 30#include "opt_gdc.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/kernel.h> 35#include <sys/module.h> 36#include <sys/fbio.h> 37#include <sys/consio.h> 38 39#include <dev/fb/fbreg.h> 40#include <dev/syscons/syscons.h> 41 42#ifndef SC_RENDER_DEBUG 43#define SC_RENDER_DEBUG 0 44#endif 45 46static vr_clear_t gdc_txtclear; 47static vr_draw_border_t gdc_txtborder; 48static vr_draw_t gdc_txtdraw; 49static vr_set_cursor_t gdc_txtcursor_shape; 50static vr_draw_cursor_t gdc_txtcursor; 51#ifndef SC_NO_CUTPASTE 52static vr_draw_mouse_t gdc_txtmouse; 53#else 54#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop 55#endif 56 57#ifndef SC_NO_MODE_CHANGE 58static vr_draw_border_t gdc_grborder; 59#endif 60 61static void gdc_nop(scr_stat *scp, ...); 62 63static sc_rndr_sw_t txtrndrsw = { 64 (vr_init_t *)gdc_nop, 65 gdc_txtclear, 66 gdc_txtborder, 67 gdc_txtdraw, 68 gdc_txtcursor_shape, 69 gdc_txtcursor, 70 (vr_blink_cursor_t *)gdc_nop, 71 (vr_set_mouse_t *)gdc_nop, 72 gdc_txtmouse, 73}; 74RENDERER(gdc, 0, txtrndrsw, gdc_set); 75 76#ifndef SC_NO_MODE_CHANGE 77static sc_rndr_sw_t grrndrsw = { 78 (vr_init_t *)gdc_nop, 79 (vr_clear_t *)gdc_nop, 80 gdc_grborder, 81 (vr_draw_t *)gdc_nop, 82 (vr_set_cursor_t *)gdc_nop, 83 (vr_draw_cursor_t *)gdc_nop, 84 (vr_blink_cursor_t *)gdc_nop, 85 (vr_set_mouse_t *)gdc_nop, 86 (vr_draw_mouse_t *)gdc_nop, 87}; 88RENDERER(gdc, GRAPHICS_MODE, grrndrsw, gdc_set); 89#endif /* SC_NO_MODE_CHANGE */ 90 91RENDERER_MODULE(gdc, gdc_set); 92 93static void 94gdc_nop(scr_stat *scp, ...) 95{ 96} 97 98/* text mode renderer */ 99 100static void 101gdc_txtclear(scr_stat *scp, int c, int attr) 102{ 103 sc_vtb_clear(&scp->scr, c, attr); 104} 105 106static void 107gdc_txtborder(scr_stat *scp, int color) 108{ 109 vidd_set_border(scp->sc->adp, color); 110} 111 112static void 113gdc_txtdraw(scr_stat *scp, int from, int count, int flip) 114{ 115 vm_offset_t p; 116 int c; 117 int a; 118 119 if (from + count > scp->xsize*scp->ysize) 120 count = scp->xsize*scp->ysize - from; 121 122 if (flip) { 123 for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { 124 c = sc_vtb_getc(&scp->vtb, from); 125 a = sc_vtb_geta(&scp->vtb, from); 126#if 0 127 a ^= 0x0800; 128#else 129 a = (a & 0x8800) | ((a & 0x7000) >> 4) 130 | ((a & 0x0700) << 4); 131#endif 132 p = sc_vtb_putchar(&scp->scr, p, c, a); 133 } 134 } else { 135 sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count); 136 } 137} 138 139static void 140gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink) 141{ 142 if (base < 0 || base >= scp->font_size) 143 return; 144 /* the caller may set height <= 0 in order to disable the cursor */ 145 vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size, 146 blink); 147} 148 149static void 150gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) 151{ 152 if (on) { 153 scp->status |= VR_CURSOR_ON; 154 vidd_set_hw_cursor(scp->sc->adp, at%scp->xsize, 155 at/scp->xsize); 156 } else { 157 if (scp->status & VR_CURSOR_ON) 158 vidd_set_hw_cursor(scp->sc->adp, -1, -1); 159 scp->status &= ~VR_CURSOR_ON; 160 } 161} 162 163#ifndef SC_NO_CUTPASTE 164 165static void 166draw_txtmouse(scr_stat *scp, int x, int y) 167{ 168 int at; 169 int a; 170 171 at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; 172 a = sc_vtb_geta(&scp->vtb, at); 173#if 0 174 a ^= 0x0800; 175#else 176 a = (a & 0x8800) | ((a & 0x7000) >> 4) 177 | ((a & 0x0700) << 4); 178#endif 179 sc_vtb_putc(&scp->scr, at, sc_vtb_getc(&scp->scr, at), a); 180} 181 182static void 183remove_txtmouse(scr_stat *scp, int x, int y) 184{ 185} 186 187static void 188gdc_txtmouse(scr_stat *scp, int x, int y, int on) 189{ 190 if (on) 191 draw_txtmouse(scp, x, y); 192 else 193 remove_txtmouse(scp, x, y); 194} 195 196#endif /* SC_NO_CUTPASTE */ 197 198#ifndef SC_NO_MODE_CHANGE 199 200/* graphics mode renderer */ 201 202static void 203gdc_grborder(scr_stat *scp, int color) 204{ 205 vidd_set_border(scp->sc->adp, color); 206} 207 208#endif /* SC_NO_MODE_CHANGE */ 209