1 /*-
2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
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 * Copyright (c) 2000 Andrew Miklic
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: releng/9.0/sys/dev/syscons/scgfbrndr.c 174985 2007-12-29 23:26:59Z wkoszek $");
31
32 #include "opt_syscons.h"
33 #include "opt_gfb.h"
34 #ifdef __powerpc__
35 #include "opt_ofwfb.h"
36 #endif
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/fbio.h>
42 #include <sys/consio.h>
43
44 #include <machine/bus.h>
45
46 #include <dev/fb/fbreg.h>
47 #include <dev/syscons/syscons.h>
48
49 #ifndef SC_RENDER_DEBUG
50 #define SC_RENDER_DEBUG 0
51 #endif
52
53 static vr_clear_t gfb_clear;
54 static vr_draw_border_t gfb_border;
55 static vr_draw_t gfb_draw;
56 static vr_set_cursor_t gfb_cursor_shape;
57 static vr_draw_cursor_t gfb_cursor;
58 static vr_blink_cursor_t gfb_blink;
59 #ifndef SC_NO_CUTPASTE
60 static vr_draw_mouse_t gfb_mouse;
61 #else
62 #define gfb_mouse (vr_draw_mouse_t *)gfb_nop
63 #endif
64
65 static void gfb_nop(scr_stat *scp);
66
67 sc_rndr_sw_t txtrndrsw = {
68 (vr_init_t *)gfb_nop,
69 gfb_clear,
70 gfb_border,
71 gfb_draw,
72 gfb_cursor_shape,
73 gfb_cursor,
74 gfb_blink,
75 (vr_set_mouse_t *)gfb_nop,
76 gfb_mouse,
77 };
78
79 #ifdef SC_PIXEL_MODE
80 sc_rndr_sw_t gfbrndrsw = {
81 (vr_init_t *)gfb_nop,
82 gfb_clear,
83 gfb_border,
84 gfb_draw,
85 gfb_cursor_shape,
86 gfb_cursor,
87 gfb_blink,
88 (vr_set_mouse_t *)gfb_nop,
89 gfb_mouse,
90 };
91 #endif /* SC_PIXEL_MODE */
92
93 #ifndef SC_NO_MODE_CHANGE
94 sc_rndr_sw_t grrndrsw = {
95 (vr_init_t *)gfb_nop,
96 (vr_clear_t *)gfb_nop,
97 gfb_border,
98 (vr_draw_t *)gfb_nop,
99 (vr_set_cursor_t *)gfb_nop,
100 (vr_draw_cursor_t *)gfb_nop,
101 (vr_blink_cursor_t *)gfb_nop,
102 (vr_set_mouse_t *)gfb_nop,
103 (vr_draw_mouse_t *)gfb_nop,
104 };
105 #endif /* SC_NO_MODE_CHANGE */
106
107 #ifndef SC_NO_CUTPASTE
108 #ifdef __sparc64__
109 static u_char mouse_pointer[22 * 2] = {
110 0x00, 0x00, /* ............ */
111 0x80, 0x00, /* *........... */
112 0xc0, 0x00, /* **.......... */
113 0xe0, 0x00, /* ***......... */
114 0xf0, 0x00, /* ****........ */
115 0xf8, 0x00, /* *****....... */
116 0xfc, 0x00, /* ******...... */
117 0xfe, 0x00, /* *******..... */
118 0xff, 0x00, /* ********.... */
119 0xff, 0x80, /* *********... */
120 0xfc, 0xc0, /* ******..**.. */
121 0xdc, 0x00, /* **.***...... */
122 0x8e, 0x00, /* *...***..... */
123 0x0e, 0x00, /* ....***..... */
124 0x07, 0x00, /* .....***.... */
125 0x04, 0x00, /* .....*...... */
126 0x00, 0x00, /* ............ */
127 0x00, 0x00, /* ............ */
128 0x00, 0x00, /* ............ */
129 0x00, 0x00, /* ............ */
130 0x00, 0x00, /* ............ */
131 0x00, 0x00 /* ............ */
132 };
133 #else
134 static u_char mouse_pointer[16] = {
135 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
136 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
137 };
138 #endif
139 #endif
140
141 static void
142 gfb_nop(scr_stat *scp)
143 {
144 }
145
146 /* text mode renderer */
147
148 static void
149 gfb_clear(scr_stat *scp, int c, int attr)
150 {
151 vidd_clear(scp->sc->adp);
152 }
153
154 static void
155 gfb_border(scr_stat *scp, int color)
156 {
157 vidd_set_border(scp->sc->adp, color);
158 }
159
160 static void
161 gfb_draw(scr_stat *scp, int from, int count, int flip)
162 {
163 int c;
164 int a;
165 int i, n;
166 video_adapter_t *adp;
167
168 adp = scp->sc->adp;
169
170 /*
171 Determine if we need to scroll based on the offset
172 and the number of characters to be displayed...
173 */
174 if (from + count > scp->xsize*scp->ysize) {
175
176 /*
177 Calculate the number of characters past the end of the
178 visible screen...
179 */
180 count = (from + count) -
181 (adp->va_info.vi_width * adp->va_info.vi_height);
182
183 /*
184 Calculate the number of rows past the end of the visible
185 screen...
186 */
187 n = (count / adp->va_info.vi_width) + 1;
188
189 /* Scroll to make room for new text rows... */
190 vidd_copy(adp, n, 0, n);
191 #if 0
192 vidd_clear(adp, n);
193 #endif
194
195 /* Display new text rows... */
196 vidd_puts(adp, from,
197 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from), count);
198 }
199
200 /*
201 We don't need to scroll, so we can just put the characters
202 all-at-once...
203 */
204 else {
205
206 /*
207 Determine the method by which we are to display characters
208 (are we going to print forwards or backwards?
209 do we need to do a character-by-character copy, then?)...
210 */
211 if (flip)
212 for (i = count; i-- > 0; ++from) {
213 c = sc_vtb_getc(&scp->vtb, from);
214 a = sc_vtb_geta(&scp->vtb, from) >> 8;
215 vidd_putc(adp, from, c,
216 (a >> 4) | ((a & 0xf) << 4));
217 }
218 else {
219 vidd_puts(adp, from,
220 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from),
221 count);
222 }
223 }
224 }
225
226 static void
227 gfb_cursor_shape(scr_stat *scp, int base, int height, int blink)
228 {
229 if (base < 0 || base >= scp->font_size)
230 return;
231 /* the caller may set height <= 0 in order to disable the cursor */
232 #if 0
233 scp->cursor_base = base;
234 scp->cursor_height = height;
235 #endif
236 vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size,
237 blink);
238 }
239
240 static int pxlblinkrate = 0;
241
242 #if defined(__sparc64__) || defined(SC_OFWFB)
243 static void
244 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
245 {
246 video_adapter_t *adp;
247 int a, c;
248
249 if (scp->curs_attr.height <= 0) /* the text cursor is disabled */
250 return;
251
252 adp = scp->sc->adp;
253 if(blink) {
254 scp->status |= VR_CURSOR_BLINK;
255 if (on) {
256 scp->status |= VR_CURSOR_ON;
257 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
258 } else {
259 if (scp->status & VR_CURSOR_ON)
260 vidd_set_hw_cursor(adp, -1, -1);
261 scp->status &= ~VR_CURSOR_ON;
262 }
263 } else {
264 scp->status &= ~VR_CURSOR_BLINK;
265 if(on) {
266 scp->status |= VR_CURSOR_ON;
267 vidd_putc(scp->sc->adp, scp->cursor_oldpos,
268 sc_vtb_getc(&scp->vtb, scp->cursor_oldpos),
269 sc_vtb_geta(&scp->vtb, scp->cursor_oldpos) >> 8);
270 a = sc_vtb_geta(&scp->vtb, at) >> 8;
271 c = sc_vtb_getc(&scp->vtb, at);
272 vidd_putc(scp->sc->adp, at, c,
273 (a >> 4) | ((a & 0xf) << 4));
274 scp->cursor_saveunder_attr = a;
275 scp->cursor_saveunder_char = c;
276 } else {
277 if (scp->status & VR_CURSOR_ON)
278 vidd_putc(scp->sc->adp, at,
279 scp->cursor_saveunder_char,
280 scp->cursor_saveunder_attr);
281 scp->status &= ~VR_CURSOR_ON;
282 }
283 }
284 }
285 #else
286 static void
287 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
288 {
289 video_adapter_t *adp;
290
291 adp = scp->sc->adp;
292 if (scp->curs_attr.height <= 0)
293 /* the text cursor is disabled */
294 return;
295
296 if (on) {
297 if (!blink) {
298 scp->status |= VR_CURSOR_ON;
299 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
300 } else if (++pxlblinkrate & 4) {
301 pxlblinkrate = 0;
302 scp->status ^= VR_CURSOR_ON;
303 if(scp->status & VR_CURSOR_ON)
304 vidd_set_hw_cursor(adp, at%scp->xsize,
305 at/scp->xsize);
306 else
307 vidd_set_hw_cursor(adp, -1, -1);
308 }
309 } else {
310 if (scp->status & VR_CURSOR_ON)
311 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
312 scp->status &= ~VR_CURSOR_ON;
313 }
314 if (blink)
315 scp->status |= VR_CURSOR_BLINK;
316 else
317 scp->status &= ~VR_CURSOR_BLINK;
318 }
319 #endif
320
321 static void
322 gfb_blink(scr_stat *scp, int at, int flip)
323 {
324 if (!(scp->status & VR_CURSOR_BLINK))
325 return;
326 if (!(++pxlblinkrate & 4))
327 return;
328 pxlblinkrate = 0;
329 scp->status ^= VR_CURSOR_ON;
330 gfb_cursor(scp, at, scp->status & VR_CURSOR_BLINK,
331 scp->status & VR_CURSOR_ON, flip);
332 }
333
334 #ifndef SC_NO_CUTPASTE
335
336 static void
337 gfb_mouse(scr_stat *scp, int x, int y, int on)
338 {
339 #ifdef __sparc64__
340 vidd_putm(scp->sc->adp, x, y, mouse_pointer,
341 on ? 0xffffffff : 0x0, 22, 12);
342 #else
343 int i, pos;
344
345 if (on) {
346
347 /* Display the mouse pointer image... */
348 vidd_putm(scp->sc->adp, x, y, mouse_pointer,
349 0xffffffff, 16, 8);
350 } else {
351
352 /*
353 Erase the mouse cursor image by redrawing the text
354 underneath it...
355 */
356 return;
357 pos = x*scp->xsize + y;
358 i = (y < scp->xsize - 1) ? 2 : 1;
359 (*scp->rndr->draw)(scp, pos, i, FALSE);
360 if (x < scp->ysize - 1)
361 (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
362 }
363 #endif
364 }
365
366 #endif /* SC_NO_CUTPASTE */
Cache object: 27ee0f08f58a1a4310dd7f38e0de66c1
|