2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 * Copyright (c) 2000 Andrew Miklic
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include "opt_syscons.h"
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
39 #include <sys/consio.h>
41 #include <machine/bus.h>
43 #include <dev/fb/fbreg.h>
44 #include <dev/syscons/syscons.h>
46 #ifndef SC_RENDER_DEBUG
47 #define SC_RENDER_DEBUG 0
50 static vr_clear_t gfb_clear;
51 static vr_draw_border_t gfb_border;
52 static vr_draw_t gfb_draw;
53 static vr_set_cursor_t gfb_cursor_shape;
54 static vr_draw_cursor_t gfb_cursor;
55 static vr_blink_cursor_t gfb_blink;
56 #ifndef SC_NO_CUTPASTE
57 static vr_draw_mouse_t gfb_mouse;
59 #define gfb_mouse (vr_draw_mouse_t *)gfb_nop
62 static void gfb_nop(scr_stat *scp, ...);
64 sc_rndr_sw_t txtrndrsw = {
71 (vr_set_mouse_t *)gfb_nop,
76 sc_rndr_sw_t gfbrndrsw = {
83 (vr_set_mouse_t *)gfb_nop,
86 #endif /* SC_PIXEL_MODE */
88 #ifndef SC_NO_MODE_CHANGE
89 sc_rndr_sw_t grrndrsw = {
90 (vr_clear_t *)gfb_nop,
93 (vr_set_cursor_t *)gfb_nop,
94 (vr_draw_cursor_t *)gfb_nop,
95 (vr_blink_cursor_t *)gfb_nop,
96 (vr_set_mouse_t *)gfb_nop,
97 (vr_draw_mouse_t *)gfb_nop,
99 #endif /* SC_NO_MODE_CHANGE */
101 #ifndef SC_NO_CUTPASTE
103 static u_char mouse_pointer[16] = {
104 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
105 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
110 gfb_nop(scr_stat *scp, ...)
114 /* text mode renderer */
117 gfb_clear(scr_stat *scp, int c, int attr)
119 (*vidsw[scp->sc->adapter]->clear)(scp->sc->adp);
123 gfb_border(scr_stat *scp, int color)
125 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
129 gfb_draw(scr_stat *scp, int from, int count, int flip)
134 video_adapter_t *adp;
139 Determine if we need to scroll based on the offset
140 and the number of characters to be displayed...
142 if (from + count > scp->xsize*scp->ysize) {
145 Calculate the number of characters past the end of the
148 count = (from + count) -
149 (adp->va_info.vi_width * adp->va_info.vi_height);
152 Calculate the number of rows past the end of the visible
155 n = (count / adp->va_info.vi_width) + 1;
157 /* Scroll to make room for new text rows... */
158 (*vidsw[scp->sc->adapter]->copy)(adp, n, 0, n);
160 (*vidsw[scp->sc->adapter]->clear)(adp, n);
163 /* Display new text rows... */
164 (*vidsw[scp->sc->adapter]->puts)(adp, from,
165 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from), count);
169 We don't need to scroll, so we can just put the characters
175 Determine the method by which we are to display characters
176 (are we going to print forwards or backwards?
177 do we need to do a character-by-character copy, then?)...
180 for (i = count; i-- > 0; ++from) {
181 c = sc_vtb_getc(&scp->vtb, from);
182 a = sc_vtb_geta(&scp->vtb, from) >> 8;
183 (*vidsw[scp->sc->adapter]->putc)(adp, from, c,
187 (*vidsw[scp->sc->adapter]->puts)(adp, from,
188 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from),
195 gfb_cursor_shape(scr_stat *scp, int base, int height, int blink)
197 if (base < 0 || base >= scp->font_size)
199 /* the caller may set height <= 0 in order to disable the cursor */
201 scp->cursor_base = base;
202 scp->cursor_height = height;
204 (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
205 base, height, scp->font_size, blink);
208 static int pxlblinkrate = 0;
212 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
214 video_adapter_t *adp;
216 if (scp->cursor_height <= 0) /* the text cursor is disabled */
221 scp->status |= VR_CURSOR_BLINK;
223 scp->status |= VR_CURSOR_ON;
224 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
228 if (scp->status & VR_CURSOR_ON)
229 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1,
231 scp->status &= ~VR_CURSOR_ON;
234 scp->status &= ~VR_CURSOR_BLINK;
236 scp->status |= VR_CURSOR_ON;
237 scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at);
238 scp->cursor_saveunder_attr = sc_vtb_geta(&scp->scr, at);
239 (*vidsw[scp->sc->adapter]->putc)(scp->sc->adp, at,
240 scp->cursor_saveunder_char,
241 scp->cursor_saveunder_attr);
243 if (scp->status & VR_CURSOR_ON)
244 (*vidsw[scp->sc->adapter]->putc)(scp->sc->adp,
245 at, scp->cursor_saveunder_char,
246 scp->cursor_saveunder_attr);
247 scp->status &= ~VR_CURSOR_ON;
254 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
256 video_adapter_t *adp;
259 if (scp->curs_attr.height <= 0)
260 /* the text cursor is disabled */
265 scp->status |= VR_CURSOR_ON;
266 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
267 at%scp->xsize, at/scp->xsize);
268 } else if (++pxlblinkrate & 4) {
270 scp->status ^= VR_CURSOR_ON;
271 if(scp->status & VR_CURSOR_ON)
272 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
273 at%scp->xsize, at/scp->xsize);
275 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1,
279 if (scp->status & VR_CURSOR_ON)
280 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
281 at%scp->xsize, at/scp->xsize);
282 scp->status &= ~VR_CURSOR_ON;
285 scp->status |= VR_CURSOR_BLINK;
287 scp->status &= ~VR_CURSOR_BLINK;
291 gfb_blink(scr_stat *scp, int at, int flip)
293 if (!(scp->status & VR_CURSOR_BLINK))
295 if (!(++pxlblinkrate & 4))
298 scp->status ^= VR_CURSOR_ON;
299 gfb_cursor(scp, at, scp->status & VR_CURSOR_BLINK,
300 scp->status & VR_CURSOR_ON, flip);
303 #ifndef SC_NO_CUTPASTE
306 gfb_mouse(scr_stat *scp, int x, int y, int on)
312 /* Display the mouse pointer image... */
313 (*vidsw[scp->sc->adapter]->putm)(scp->sc->adp, x, y,
314 mouse_pointer, 0xffffffff, 16);
318 Erase the mouse cursor image by redrawing the text
322 pos = x*scp->xsize + y;
323 i = (y < scp->xsize - 1) ? 2 : 1;
324 (*scp->rndr->draw)(scp, pos, i, FALSE);
325 if (x < scp->ysize - 1)
326 (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
330 #endif /* SC_NO_CUTPASTE */