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
28 * $FreeBSD: src/sys/dev/syscons/scgfbrndr.c,v 1.14.2.1 2001/11/01 08:33:15 obrien Exp $
29 * $DragonFly: src/sys/dev/misc/syscons/scgfbrndr.c,v 1.5 2006/02/19 09:16:26 swildner Exp $
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>
46 static vr_clear_t gfb_clear;
47 static vr_draw_border_t gfb_border;
48 static vr_draw_t gfb_draw;
49 static vr_set_cursor_t gfb_cursor_shape;
50 static vr_draw_cursor_t gfb_cursor;
51 static vr_blink_cursor_t gfb_blink;
52 #ifndef SC_NO_CUTPASTE
53 static vr_draw_mouse_t gfb_mouse;
55 #define gfb_mouse (vr_draw_mouse_t *)gfb_nop
58 static void gfb_nop(scr_stat *scp, ...);
60 sc_rndr_sw_t txtrndrsw = {
67 (vr_set_mouse_t *)gfb_nop,
72 sc_rndr_sw_t gfbrndrsw = {
79 (vr_set_mouse_t *)gfb_nop,
82 #endif /* SC_PIXEL_MODE */
84 #ifndef SC_NO_MODE_CHANGE
85 sc_rndr_sw_t grrndrsw = {
86 (vr_clear_t *)gfb_nop,
89 (vr_set_cursor_t *)gfb_nop,
90 (vr_draw_cursor_t *)gfb_nop,
91 (vr_blink_cursor_t *)gfb_nop,
92 (vr_set_mouse_t *)gfb_nop,
93 (vr_draw_mouse_t *)gfb_nop,
95 #endif /* SC_NO_MODE_CHANGE */
97 #ifndef SC_NO_CUTPASTE
99 static u_char mouse_pointer[16] = {
100 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
101 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
106 gfb_nop(scr_stat *scp, ...)
110 /* text mode renderer */
113 gfb_clear(scr_stat *scp, int c, int attr)
115 (*vidsw[scp->sc->adapter]->clear)(scp->sc->adp);
119 gfb_border(scr_stat *scp, int color)
121 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
125 gfb_draw(scr_stat *scp, int from, int count, int flip)
130 video_adapter_t *adp;
135 Determine if we need to scroll based on the offset
136 and the number of characters to be displayed...
138 if (from + count > scp->xsize*scp->ysize) {
141 Calculate the number of characters past the end of the
144 count = (from + count) -
145 (adp->va_info.vi_width * adp->va_info.vi_height);
148 Calculate the number of rows past the end of the visible
151 n = (count / adp->va_info.vi_width) + 1;
153 /* Scroll to make room for new text rows... */
154 (*vidsw[scp->sc->adapter]->copy)(adp, n, 0, n);
156 (*vidsw[scp->sc->adapter]->clear)(adp, n);
159 /* Display new text rows... */
160 (*vidsw[scp->sc->adapter]->puts)(adp, from,
161 scp->vtb.vtb_buffer + from, count);
165 We don't need to scroll, so we can just put the characters
171 Determine the method by which we are to display characters
172 (are we going to print forwards or backwards?
173 do we need to do a character-by-character copy, then?)...
176 for (i = count; i-- > 0; ++from) {
177 c = sc_vtb_getc(&scp->vtb, from);
178 a = sc_vtb_geta(&scp->vtb, from) >> 8;
179 (*vidsw[scp->sc->adapter]->putc)(adp, from, c,
183 (*vidsw[scp->sc->adapter]->puts)(adp, from,
184 scp->vtb.vtb_buffer + from, count);
190 gfb_cursor_shape(scr_stat *scp, int base, int height, int blink)
192 if (base < 0 || base >= scp->font_size)
194 /* the caller may set height <= 0 in order to disable the cursor */
196 scp->cursor_base = base;
197 scp->cursor_height = height;
199 (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
200 base, height, scp->font_size, blink);
203 static int pxlblinkrate = 0;
207 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
209 video_adapter_t *adp;
211 if (scp->cursor_height <= 0) /* the text cursor is disabled */
216 scp->status |= VR_CURSOR_BLINK;
218 scp->status |= VR_CURSOR_ON;
219 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
223 if (scp->status & VR_CURSOR_ON)
224 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1,
226 scp->status &= ~VR_CURSOR_ON;
229 scp->status &= ~VR_CURSOR_BLINK;
231 scp->status |= VR_CURSOR_ON;
232 scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at);
233 scp->cursor_saveunder_attr = sc_vtb_geta(&scp->scr, at);
234 (*vidsw[scp->sc->adapter]->putc)(scp->sc->adp, at,
235 scp->cursor_saveunder_char,
236 scp->cursor_saveunder_attr);
238 if (scp->status & VR_CURSOR_ON)
239 (*vidsw[scp->sc->adapter]->putc)(scp->sc->adp,
240 at, scp->cursor_saveunder_char,
241 scp->cursor_saveunder_attr);
242 scp->status &= ~VR_CURSOR_ON;
249 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
251 video_adapter_t *adp;
254 if (scp->cursor_height <= 0) /* the text cursor is disabled */
259 scp->status |= VR_CURSOR_ON;
260 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
261 at%scp->xsize, at/scp->xsize);
262 } else if (++pxlblinkrate & 4) {
264 scp->status ^= VR_CURSOR_ON;
265 if(scp->status & VR_CURSOR_ON)
266 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
267 at%scp->xsize, at/scp->xsize);
269 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1,
273 if (scp->status & VR_CURSOR_ON)
274 (*vidsw[adp->va_index]->set_hw_cursor)(adp,
275 at%scp->xsize, at/scp->xsize);
276 scp->status &= ~VR_CURSOR_ON;
279 scp->status |= VR_CURSOR_BLINK;
281 scp->status &= ~VR_CURSOR_BLINK;
285 gfb_blink(scr_stat *scp, int at, int flip)
287 if (!(scp->status & VR_CURSOR_BLINK))
289 if (!(++pxlblinkrate & 4))
292 scp->status ^= VR_CURSOR_ON;
293 gfb_cursor(scp, at, scp->status & VR_CURSOR_BLINK,
294 scp->status & VR_CURSOR_ON, flip);
297 #ifndef SC_NO_CUTPASTE
300 gfb_mouse(scr_stat *scp, int x, int y, int on)
306 /* Display the mouse pointer image... */
307 (*vidsw[scp->sc->adapter]->putm)(scp->sc->adp, x, y,
308 mouse_pointer, 0xffffffff, 16);
312 Erase the mouse cursor image by redrawing the text
316 pos = x*scp->xsize + y;
317 i = (y < scp->xsize - 1) ? 2 : 1;
318 (*scp->rndr->draw)(scp, pos, i, FALSE);
319 if (x < scp->ysize - 1)
320 (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
324 #endif /* SC_NO_CUTPASTE */