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.6 2006/10/25 22:55:55 dillon 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>
42 #include <dev/fb/fbreg.h>
45 static vr_clear_t gfb_clear
;
46 static vr_draw_border_t gfb_border
;
47 static vr_draw_t gfb_draw
;
48 static vr_set_cursor_t gfb_cursor_shape
;
49 static vr_draw_cursor_t gfb_cursor
;
50 static vr_blink_cursor_t gfb_blink
;
51 #ifndef SC_NO_CUTPASTE
52 static vr_draw_mouse_t gfb_mouse
;
54 #define gfb_mouse (vr_draw_mouse_t *)gfb_nop
57 static void gfb_nop(scr_stat
*scp
, ...);
59 sc_rndr_sw_t txtrndrsw
= {
66 (vr_set_mouse_t
*)gfb_nop
,
71 sc_rndr_sw_t gfbrndrsw
= {
78 (vr_set_mouse_t
*)gfb_nop
,
81 #endif /* SC_PIXEL_MODE */
83 #ifndef SC_NO_MODE_CHANGE
84 sc_rndr_sw_t grrndrsw
= {
85 (vr_clear_t
*)gfb_nop
,
88 (vr_set_cursor_t
*)gfb_nop
,
89 (vr_draw_cursor_t
*)gfb_nop
,
90 (vr_blink_cursor_t
*)gfb_nop
,
91 (vr_set_mouse_t
*)gfb_nop
,
92 (vr_draw_mouse_t
*)gfb_nop
,
94 #endif /* SC_NO_MODE_CHANGE */
96 #ifndef SC_NO_CUTPASTE
98 static u_char mouse_pointer
[16] = {
99 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
100 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
105 gfb_nop(scr_stat
*scp
, ...)
109 /* text mode renderer */
112 gfb_clear(scr_stat
*scp
, int c
, int attr
)
114 (*vidsw
[scp
->sc
->adapter
]->clear
)(scp
->sc
->adp
);
118 gfb_border(scr_stat
*scp
, int color
)
120 (*vidsw
[scp
->sc
->adapter
]->set_border
)(scp
->sc
->adp
, color
);
124 gfb_draw(scr_stat
*scp
, int from
, int count
, int flip
)
129 video_adapter_t
*adp
;
134 Determine if we need to scroll based on the offset
135 and the number of characters to be displayed...
137 if (from
+ count
> scp
->xsize
*scp
->ysize
) {
140 Calculate the number of characters past the end of the
143 count
= (from
+ count
) -
144 (adp
->va_info
.vi_width
* adp
->va_info
.vi_height
);
147 Calculate the number of rows past the end of the visible
150 n
= (count
/ adp
->va_info
.vi_width
) + 1;
152 /* Scroll to make room for new text rows... */
153 (*vidsw
[scp
->sc
->adapter
]->copy
)(adp
, n
, 0, n
);
155 (*vidsw
[scp
->sc
->adapter
]->clear
)(adp
, n
);
158 /* Display new text rows... */
159 (*vidsw
[scp
->sc
->adapter
]->puts
)(adp
, from
,
160 scp
->vtb
.vtb_buffer
+ from
, count
);
164 We don't need to scroll, so we can just put the characters
170 Determine the method by which we are to display characters
171 (are we going to print forwards or backwards?
172 do we need to do a character-by-character copy, then?)...
175 for (i
= count
; i
-- > 0; ++from
) {
176 c
= sc_vtb_getc(&scp
->vtb
, from
);
177 a
= sc_vtb_geta(&scp
->vtb
, from
) >> 8;
178 (*vidsw
[scp
->sc
->adapter
]->putc
)(adp
, from
, c
,
182 (*vidsw
[scp
->sc
->adapter
]->puts
)(adp
, from
,
183 scp
->vtb
.vtb_buffer
+ from
, count
);
189 gfb_cursor_shape(scr_stat
*scp
, int base
, int height
, int blink
)
191 if (base
< 0 || base
>= scp
->font_size
)
193 /* the caller may set height <= 0 in order to disable the cursor */
195 scp
->cursor_base
= base
;
196 scp
->cursor_height
= height
;
198 (*vidsw
[scp
->sc
->adapter
]->set_hw_cursor_shape
)(scp
->sc
->adp
,
199 base
, height
, scp
->font_size
, blink
);
202 static int pxlblinkrate
= 0;
206 gfb_cursor(scr_stat
*scp
, int at
, int blink
, int on
, int flip
)
208 video_adapter_t
*adp
;
210 if (scp
->cursor_height
<= 0) /* the text cursor is disabled */
215 scp
->status
|= VR_CURSOR_BLINK
;
217 scp
->status
|= VR_CURSOR_ON
;
218 (*vidsw
[adp
->va_index
]->set_hw_cursor
)(adp
,
222 if (scp
->status
& VR_CURSOR_ON
)
223 (*vidsw
[adp
->va_index
]->set_hw_cursor
)(adp
, -1,
225 scp
->status
&= ~VR_CURSOR_ON
;
228 scp
->status
&= ~VR_CURSOR_BLINK
;
230 scp
->status
|= VR_CURSOR_ON
;
231 scp
->cursor_saveunder_char
= sc_vtb_getc(&scp
->scr
, at
);
232 scp
->cursor_saveunder_attr
= sc_vtb_geta(&scp
->scr
, at
);
233 (*vidsw
[scp
->sc
->adapter
]->putc
)(scp
->sc
->adp
, at
,
234 scp
->cursor_saveunder_char
,
235 scp
->cursor_saveunder_attr
);
237 if (scp
->status
& VR_CURSOR_ON
)
238 (*vidsw
[scp
->sc
->adapter
]->putc
)(scp
->sc
->adp
,
239 at
, scp
->cursor_saveunder_char
,
240 scp
->cursor_saveunder_attr
);
241 scp
->status
&= ~VR_CURSOR_ON
;
248 gfb_cursor(scr_stat
*scp
, int at
, int blink
, int on
, int flip
)
250 video_adapter_t
*adp
;
253 if (scp
->cursor_height
<= 0) /* the text cursor is disabled */
258 scp
->status
|= VR_CURSOR_ON
;
259 (*vidsw
[adp
->va_index
]->set_hw_cursor
)(adp
,
260 at
%scp
->xsize
, at
/scp
->xsize
);
261 } else if (++pxlblinkrate
& 4) {
263 scp
->status
^= VR_CURSOR_ON
;
264 if(scp
->status
& VR_CURSOR_ON
)
265 (*vidsw
[adp
->va_index
]->set_hw_cursor
)(adp
,
266 at
%scp
->xsize
, at
/scp
->xsize
);
268 (*vidsw
[adp
->va_index
]->set_hw_cursor
)(adp
, -1,
272 if (scp
->status
& VR_CURSOR_ON
)
273 (*vidsw
[adp
->va_index
]->set_hw_cursor
)(adp
,
274 at
%scp
->xsize
, at
/scp
->xsize
);
275 scp
->status
&= ~VR_CURSOR_ON
;
278 scp
->status
|= VR_CURSOR_BLINK
;
280 scp
->status
&= ~VR_CURSOR_BLINK
;
284 gfb_blink(scr_stat
*scp
, int at
, int flip
)
286 if (!(scp
->status
& VR_CURSOR_BLINK
))
288 if (!(++pxlblinkrate
& 4))
291 scp
->status
^= VR_CURSOR_ON
;
292 gfb_cursor(scp
, at
, scp
->status
& VR_CURSOR_BLINK
,
293 scp
->status
& VR_CURSOR_ON
, flip
);
296 #ifndef SC_NO_CUTPASTE
299 gfb_mouse(scr_stat
*scp
, int x
, int y
, int on
)
305 /* Display the mouse pointer image... */
306 (*vidsw
[scp
->sc
->adapter
]->putm
)(scp
->sc
->adp
, x
, y
,
307 mouse_pointer
, 0xffffffff, 16);
311 Erase the mouse cursor image by redrawing the text
315 pos
= x
*scp
->xsize
+ y
;
316 i
= (y
< scp
->xsize
- 1) ? 2 : 1;
317 (*scp
->rndr
->draw
)(scp
, pos
, i
, FALSE
);
318 if (x
< scp
->ysize
- 1)
319 (*scp
->rndr
->draw
)(scp
, pos
+ scp
->xsize
, i
, FALSE
);
323 #endif /* SC_NO_CUTPASTE */