1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer as
12 * the first lines of this file unmodified.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Copyright (c) 2000 Andrew Miklic
29 */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include "opt_syscons.h"
35 #ifdef __powerpc__
36 #include "opt_ofwfb.h"
37 #endif
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/fbio.h>
43 #include <sys/consio.h>
44
45 #include <machine/bus.h>
46
47 #include <dev/fb/fbreg.h>
48 #include <dev/syscons/syscons.h>
49
50 #ifndef SC_RENDER_DEBUG
51 #define SC_RENDER_DEBUG 0
52 #endif
53
54 static vr_clear_t gfb_clear;
55 static vr_draw_border_t gfb_border;
56 static vr_draw_t gfb_draw;
57 static vr_set_cursor_t gfb_cursor_shape;
58 static vr_draw_cursor_t gfb_cursor;
59 static vr_blink_cursor_t gfb_blink;
60 #ifndef SC_NO_CUTPASTE
61 static vr_draw_mouse_t gfb_mouse;
62 #else
63 #define gfb_mouse (vr_draw_mouse_t *)gfb_nop
64 #endif
65
66 static void gfb_nop(scr_stat *scp);
67
68 sc_rndr_sw_t txtrndrsw = {
69 (vr_init_t *)gfb_nop,
70 gfb_clear,
71 gfb_border,
72 gfb_draw,
73 gfb_cursor_shape,
74 gfb_cursor,
75 gfb_blink,
76 (vr_set_mouse_t *)gfb_nop,
77 gfb_mouse,
78 };
79
80 #ifdef SC_PIXEL_MODE
81 sc_rndr_sw_t gfbrndrsw = {
82 (vr_init_t *)gfb_nop,
83 gfb_clear,
84 gfb_border,
85 gfb_draw,
86 gfb_cursor_shape,
87 gfb_cursor,
88 gfb_blink,
89 (vr_set_mouse_t *)gfb_nop,
90 gfb_mouse,
91 };
92 #endif /* SC_PIXEL_MODE */
93
94 #ifndef SC_NO_MODE_CHANGE
95 sc_rndr_sw_t grrndrsw = {
96 (vr_init_t *)gfb_nop,
97 (vr_clear_t *)gfb_nop,
98 gfb_border,
99 (vr_draw_t *)gfb_nop,
100 (vr_set_cursor_t *)gfb_nop,
101 (vr_draw_cursor_t *)gfb_nop,
102 (vr_blink_cursor_t *)gfb_nop,
103 (vr_set_mouse_t *)gfb_nop,
104 (vr_draw_mouse_t *)gfb_nop,
105 };
106 #endif /* SC_NO_MODE_CHANGE */
107
108 #ifndef SC_NO_CUTPASTE
109 static u_char mouse_pointer[16] = {
110 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
111 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
112 };
113 #endif
114
115 static void
116 gfb_nop(scr_stat *scp)
117 {
118 }
119
120 /* text mode renderer */
121
122 static void
123 gfb_clear(scr_stat *scp, int c, int attr)
124 {
125 vidd_clear(scp->sc->adp);
126 }
127
128 static void
129 gfb_border(scr_stat *scp, int color)
130 {
131 vidd_set_border(scp->sc->adp, color);
132 }
133
134 static void
135 gfb_draw(scr_stat *scp, int from, int count, int flip)
136 {
137 int c;
138 int a;
139 int i, n;
140 video_adapter_t *adp;
141
142 adp = scp->sc->adp;
143
144 /*
145 Determine if we need to scroll based on the offset
146 and the number of characters to be displayed...
147 */
148 if (from + count > scp->xsize*scp->ysize) {
149 /*
150 Calculate the number of characters past the end of the
151 visible screen...
152 */
153 count = (from + count) -
154 (adp->va_info.vi_width * adp->va_info.vi_height);
155
156 /*
157 Calculate the number of rows past the end of the visible
158 screen...
159 */
160 n = (count / adp->va_info.vi_width) + 1;
161
162 /* Scroll to make room for new text rows... */
163 vidd_copy(adp, n, 0, n);
164 #if 0
165 vidd_clear(adp, n);
166 #endif
167
168 /* Display new text rows... */
169 vidd_puts(adp, from,
170 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from), count);
171 }
172
173 /*
174 We don't need to scroll, so we can just put the characters
175 all-at-once...
176 */
177 else {
178 /*
179 Determine the method by which we are to display characters
180 (are we going to print forwards or backwards?
181 do we need to do a character-by-character copy, then?)...
182 */
183 if (flip)
184 for (i = count; i-- > 0; ++from) {
185 c = sc_vtb_getc(&scp->vtb, from);
186 a = sc_vtb_geta(&scp->vtb, from) >> 8;
187 vidd_putc(adp, from, c,
188 (a >> 4) | ((a & 0xf) << 4));
189 }
190 else {
191 vidd_puts(adp, from,
192 (u_int16_t *)sc_vtb_pointer(&scp->vtb, from),
193 count);
194 }
195 }
196 }
197
198 static void
199 gfb_cursor_shape(scr_stat *scp, int base, int height, int blink)
200 {
201 if (base < 0 || base >= scp->font_size)
202 return;
203 /* the caller may set height <= 0 in order to disable the cursor */
204 #if 0
205 scp->cursor_base = base;
206 scp->cursor_height = height;
207 #endif
208 vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size,
209 blink);
210 }
211
212 static int pxlblinkrate = 0;
213
214 #if defined(SC_OFWFB)
215 static void
216 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
217 {
218 video_adapter_t *adp;
219 int a, c;
220
221 if (scp->curs_attr.height <= 0) /* the text cursor is disabled */
222 return;
223
224 adp = scp->sc->adp;
225 if(blink) {
226 scp->status |= VR_CURSOR_BLINK;
227 if (on) {
228 scp->status |= VR_CURSOR_ON;
229 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
230 } else {
231 if (scp->status & VR_CURSOR_ON)
232 vidd_set_hw_cursor(adp, -1, -1);
233 scp->status &= ~VR_CURSOR_ON;
234 }
235 } else {
236 scp->status &= ~VR_CURSOR_BLINK;
237 if(on) {
238 scp->status |= VR_CURSOR_ON;
239 vidd_putc(scp->sc->adp, scp->cursor_oldpos,
240 sc_vtb_getc(&scp->vtb, scp->cursor_oldpos),
241 sc_vtb_geta(&scp->vtb, scp->cursor_oldpos) >> 8);
242 a = sc_vtb_geta(&scp->vtb, at) >> 8;
243 c = sc_vtb_getc(&scp->vtb, at);
244 vidd_putc(scp->sc->adp, at, c,
245 (a >> 4) | ((a & 0xf) << 4));
246 } else {
247 if (scp->status & VR_CURSOR_ON)
248 vidd_putc(scp->sc->adp, at,
249 sc_vtb_getc(&scp->vtb, at),
250 sc_vtb_geta(&scp->vtb, at) >> 8);
251 scp->status &= ~VR_CURSOR_ON;
252 }
253 }
254 }
255 #else
256 static void
257 gfb_cursor(scr_stat *scp, int at, int blink, int on, int flip)
258 {
259 video_adapter_t *adp;
260
261 adp = scp->sc->adp;
262 if (scp->curs_attr.height <= 0)
263 /* the text cursor is disabled */
264 return;
265
266 if (on) {
267 if (!blink) {
268 scp->status |= VR_CURSOR_ON;
269 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
270 } else if (++pxlblinkrate & 4) {
271 pxlblinkrate = 0;
272 scp->status ^= VR_CURSOR_ON;
273 if(scp->status & VR_CURSOR_ON)
274 vidd_set_hw_cursor(adp, at%scp->xsize,
275 at/scp->xsize);
276 else
277 vidd_set_hw_cursor(adp, -1, -1);
278 }
279 } else {
280 if (scp->status & VR_CURSOR_ON)
281 vidd_set_hw_cursor(adp, at%scp->xsize, at/scp->xsize);
282 scp->status &= ~VR_CURSOR_ON;
283 }
284 if (blink)
285 scp->status |= VR_CURSOR_BLINK;
286 else
287 scp->status &= ~VR_CURSOR_BLINK;
288 }
289 #endif
290
291 static void
292 gfb_blink(scr_stat *scp, int at, int flip)
293 {
294 if (!(scp->status & VR_CURSOR_BLINK))
295 return;
296 if (!(++pxlblinkrate & 4))
297 return;
298 pxlblinkrate = 0;
299 scp->status ^= VR_CURSOR_ON;
300 gfb_cursor(scp, at, scp->status & VR_CURSOR_BLINK,
301 scp->status & VR_CURSOR_ON, flip);
302 }
303
304 #ifndef SC_NO_CUTPASTE
305
306 static void
307 gfb_mouse(scr_stat *scp, int x, int y, int on)
308 {
309 if (on) {
310 vidd_putm(scp->sc->adp, x, y, mouse_pointer,
311 0xffffffff, 16, 8);
312 } else {
313 /* XXX: removal is incomplete for h/w cursors and borders. */
314 }
315 }
316
317 #endif /* SC_NO_CUTPASTE */
Cache object: 01cb1b19ea498c17108c62850f847671
|