xref: /freebsd/sys/dev/syscons/scvidctl.c (revision 95bafc8f5ad947ec29c2dfbabadd20c3f67a1e5a)
1a8445737SSøren Schmidt /*-
2a8445737SSøren Schmidt  * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
3a8445737SSøren Schmidt  * All rights reserved.
4a8445737SSøren Schmidt  *
5a8445737SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
6a8445737SSøren Schmidt  * modification, are permitted provided that the following conditions
7a8445737SSøren Schmidt  * are met:
8a8445737SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
9a8445737SSøren Schmidt  *    notice, this list of conditions and the following disclaimer.
10a8445737SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
11a8445737SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
12a8445737SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
13a8445737SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote
14a8445737SSøren Schmidt  *    products derived from this software without specific prior written
15a8445737SSøren Schmidt  *    permission.
16a8445737SSøren Schmidt  *
17a8445737SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18a8445737SSøren Schmidt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19a8445737SSøren Schmidt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20a8445737SSøren Schmidt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21a8445737SSøren Schmidt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22a8445737SSøren Schmidt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23a8445737SSøren Schmidt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24a8445737SSøren Schmidt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25a8445737SSøren Schmidt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26a8445737SSøren Schmidt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27a8445737SSøren Schmidt  * SUCH DAMAGE.
28a8445737SSøren Schmidt  *
2995bafc8fSKazutaka YOKOTA  * $Id: scvidctl.c,v 1.1 1998/09/15 18:16:37 sos Exp $
30a8445737SSøren Schmidt  */
31a8445737SSøren Schmidt 
32a8445737SSøren Schmidt #include "sc.h"
33a8445737SSøren Schmidt #include "opt_syscons.h"
34a8445737SSøren Schmidt 
35a8445737SSøren Schmidt #if NSC > 0
36a8445737SSøren Schmidt 
37a8445737SSøren Schmidt #include <sys/param.h>
38a8445737SSøren Schmidt #include <sys/systm.h>
39a8445737SSøren Schmidt #include <sys/signalvar.h>
40a8445737SSøren Schmidt #include <sys/tty.h>
41a8445737SSøren Schmidt #include <sys/kernel.h>
42a8445737SSøren Schmidt 
43a8445737SSøren Schmidt #include <machine/apm_bios.h>
44a8445737SSøren Schmidt #include <machine/console.h>
45a8445737SSøren Schmidt 
46a8445737SSøren Schmidt #include <i386/isa/videoio.h>
47a8445737SSøren Schmidt #include <i386/isa/syscons.h>
48a8445737SSøren Schmidt 
49a8445737SSøren Schmidt /* video ioctl */
50a8445737SSøren Schmidt 
51a8445737SSøren Schmidt extern scr_stat *cur_console;
52a8445737SSøren Schmidt extern int fonts_loaded;
53a8445737SSøren Schmidt extern int sc_history_size;
54a8445737SSøren Schmidt extern u_char palette[];
55a8445737SSøren Schmidt 
56a8445737SSøren Schmidt int
57a8445737SSøren Schmidt sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
58a8445737SSøren Schmidt 		 int fontsize)
59a8445737SSøren Schmidt {
60a8445737SSøren Schmidt     video_adapter_t *adp;
61a8445737SSøren Schmidt     video_info_t info;
62a8445737SSøren Schmidt     int error;
63a8445737SSøren Schmidt     int s;
64a8445737SSøren Schmidt     int i;
65a8445737SSøren Schmidt 
66a8445737SSøren Schmidt     if ((*biosvidsw.get_info)(scp->adp, mode, &info))
67a8445737SSøren Schmidt 	return ENODEV;
68a8445737SSøren Schmidt     adp = get_adapter(scp);
69a8445737SSøren Schmidt 
70a8445737SSøren Schmidt     /* adjust argument values */
71a8445737SSøren Schmidt     if (fontsize <= 0)
72a8445737SSøren Schmidt 	fontsize = info.vi_cheight;
73a8445737SSøren Schmidt     if (fontsize < 14) {
74a8445737SSøren Schmidt 	fontsize = 8;
75a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_8))
76a8445737SSøren Schmidt 	    return EINVAL;
77a8445737SSøren Schmidt     } else if (fontsize >= 16) {
78a8445737SSøren Schmidt 	fontsize = 16;
79a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_16))
80a8445737SSøren Schmidt 	    return EINVAL;
81a8445737SSøren Schmidt     } else {
82a8445737SSøren Schmidt 	fontsize = 14;
83a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_14))
84a8445737SSøren Schmidt 	    return EINVAL;
85a8445737SSøren Schmidt     }
86a8445737SSøren Schmidt     if ((xsize <= 0) || (xsize > info.vi_width))
87a8445737SSøren Schmidt 	xsize = info.vi_width;
88a8445737SSøren Schmidt     if ((ysize <= 0) || (ysize > info.vi_height))
89a8445737SSøren Schmidt 	ysize = info.vi_height;
90a8445737SSøren Schmidt 
91a8445737SSøren Schmidt     /* stop screen saver, etc */
92a8445737SSøren Schmidt     s = spltty();
93a8445737SSøren Schmidt     if ((error = sc_clean_up(scp))) {
94a8445737SSøren Schmidt 	splx(s);
95a8445737SSøren Schmidt 	return error;
96a8445737SSøren Schmidt     }
97a8445737SSøren Schmidt 
98a8445737SSøren Schmidt     /* set up scp */
99a8445737SSøren Schmidt     if (scp->history != NULL)
100a8445737SSøren Schmidt 	i = imax(scp->history_size / scp->xsize
101a8445737SSøren Schmidt 		 - imax(sc_history_size, scp->ysize), 0);
102a8445737SSøren Schmidt     else
103a8445737SSøren Schmidt 	i = 0;
104a8445737SSøren Schmidt     /*
105a8445737SSøren Schmidt      * This is a kludge to fend off scrn_update() while we
106a8445737SSøren Schmidt      * muck around with scp. XXX
107a8445737SSøren Schmidt      */
108a8445737SSøren Schmidt     scp->status |= UNKNOWN_MODE;
109a8445737SSøren Schmidt     scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
110a8445737SSøren Schmidt     scp->mode = mode;
111a8445737SSøren Schmidt     scp->font_size = fontsize;
112a8445737SSøren Schmidt     scp->xsize = xsize;
113a8445737SSøren Schmidt     scp->ysize = ysize;
114a8445737SSøren Schmidt     scp->xpixel = scp->xsize*8;
115a8445737SSøren Schmidt     scp->ypixel = scp->ysize*fontsize;
116a8445737SSøren Schmidt 
117a8445737SSøren Schmidt     /* allocate buffers */
118a8445737SSøren Schmidt     sc_alloc_scr_buffer(scp, TRUE, TRUE);
119a8445737SSøren Schmidt     if (ISMOUSEAVAIL(adp->va_flags))
120a8445737SSøren Schmidt 	sc_alloc_cut_buffer(scp, FALSE);
121a8445737SSøren Schmidt     sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
122a8445737SSøren Schmidt     splx(s);
123a8445737SSøren Schmidt 
124a8445737SSøren Schmidt     if (scp == cur_console)
125a8445737SSøren Schmidt 	set_mode(scp);
126a8445737SSøren Schmidt     scp->status &= ~UNKNOWN_MODE;
127a8445737SSøren Schmidt 
128a8445737SSøren Schmidt     if (tp == NULL)
129a8445737SSøren Schmidt 	return 0;
130a8445737SSøren Schmidt     if (tp->t_winsize.ws_col != scp->xsize
131a8445737SSøren Schmidt 	|| tp->t_winsize.ws_row != scp->ysize) {
132a8445737SSøren Schmidt 	tp->t_winsize.ws_col = scp->xsize;
133a8445737SSøren Schmidt 	tp->t_winsize.ws_row = scp->ysize;
134a8445737SSøren Schmidt 	pgsignal(tp->t_pgrp, SIGWINCH, 1);
135a8445737SSøren Schmidt     }
136a8445737SSøren Schmidt 
137a8445737SSøren Schmidt     return 0;
138a8445737SSøren Schmidt }
139a8445737SSøren Schmidt 
140a8445737SSøren Schmidt int
141a8445737SSøren Schmidt sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
142a8445737SSøren Schmidt {
143a8445737SSøren Schmidt     video_adapter_t *adp;
144a8445737SSøren Schmidt     video_info_t info;
145a8445737SSøren Schmidt     int error;
146a8445737SSøren Schmidt     int s;
147a8445737SSøren Schmidt 
148a8445737SSøren Schmidt     if ((*biosvidsw.get_info)(scp->adp, mode, &info))
149a8445737SSøren Schmidt 	return ENODEV;
150a8445737SSøren Schmidt     adp = get_adapter(scp);
151a8445737SSøren Schmidt 
152a8445737SSøren Schmidt     /* stop screen saver, etc */
153a8445737SSøren Schmidt     s = spltty();
154a8445737SSøren Schmidt     if ((error = sc_clean_up(scp))) {
155a8445737SSøren Schmidt 	splx(s);
156a8445737SSøren Schmidt 	return error;
157a8445737SSøren Schmidt     }
158a8445737SSøren Schmidt 
159a8445737SSøren Schmidt     /* set up scp */
160a8445737SSøren Schmidt     scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
161a8445737SSøren Schmidt     scp->status &= ~PIXEL_MODE;
162a8445737SSøren Schmidt     scp->mode = mode;
163a8445737SSøren Schmidt     scp->xpixel = info.vi_width;
164a8445737SSøren Schmidt     scp->ypixel = info.vi_height;
165a8445737SSøren Schmidt     scp->xsize = info.vi_width/8;
166a8445737SSøren Schmidt     scp->ysize = info.vi_height/info.vi_cheight;
167a8445737SSøren Schmidt     scp->font_size = FONT_NONE;
168a8445737SSøren Schmidt     /* move the mouse cursor at the center of the screen */
169a8445737SSøren Schmidt     sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
170a8445737SSøren Schmidt     splx(s);
171a8445737SSøren Schmidt 
172a8445737SSøren Schmidt     if (scp == cur_console)
173a8445737SSøren Schmidt 	set_mode(scp);
174a8445737SSøren Schmidt     /* clear_graphics();*/
175a8445737SSøren Schmidt     scp->status &= ~UNKNOWN_MODE;
176a8445737SSøren Schmidt 
177a8445737SSøren Schmidt     if (tp == NULL)
178a8445737SSøren Schmidt 	return 0;
179a8445737SSøren Schmidt     if (tp->t_winsize.ws_xpixel != scp->xpixel
180a8445737SSøren Schmidt 	|| tp->t_winsize.ws_ypixel != scp->ypixel) {
181a8445737SSøren Schmidt 	tp->t_winsize.ws_xpixel = scp->xpixel;
182a8445737SSøren Schmidt 	tp->t_winsize.ws_ypixel = scp->ypixel;
183a8445737SSøren Schmidt 	pgsignal(tp->t_pgrp, SIGWINCH, 1);
184a8445737SSøren Schmidt     }
185a8445737SSøren Schmidt 
186a8445737SSøren Schmidt     return 0;
187a8445737SSøren Schmidt }
188a8445737SSøren Schmidt 
189a8445737SSøren Schmidt int
190a8445737SSøren Schmidt sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
191a8445737SSøren Schmidt 		  int fontsize)
192a8445737SSøren Schmidt {
193a8445737SSøren Schmidt     video_adapter_t *adp;
194a8445737SSøren Schmidt     video_info_t info;
195a8445737SSøren Schmidt     int error;
196a8445737SSøren Schmidt     int s;
197a8445737SSøren Schmidt     int i;
198a8445737SSøren Schmidt 
199a8445737SSøren Schmidt     if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
200a8445737SSøren Schmidt 	return ENODEV;		/* this shouldn't happen */
201a8445737SSøren Schmidt     adp = get_adapter(scp);
202a8445737SSøren Schmidt 
203a8445737SSøren Schmidt #ifdef SC_VIDEO_DEBUG
204a8445737SSøren Schmidt     if (scp->scr_buf != NULL) {
205a8445737SSøren Schmidt 	printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
206a8445737SSøren Schmidt 	       scp->mode, xsize, ysize, fontsize);
207a8445737SSøren Schmidt     }
208a8445737SSøren Schmidt #endif
209a8445737SSøren Schmidt 
210a8445737SSøren Schmidt     /* adjust argument values */
211a8445737SSøren Schmidt     if ((fontsize <= 0) || (fontsize == FONT_NONE))
212a8445737SSøren Schmidt 	fontsize = info.vi_cheight;
213a8445737SSøren Schmidt     if (fontsize < 14) {
214a8445737SSøren Schmidt 	fontsize = 8;
215a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_8))
216a8445737SSøren Schmidt 	    return EINVAL;
217a8445737SSøren Schmidt     } else if (fontsize >= 16) {
218a8445737SSøren Schmidt 	fontsize = 16;
219a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_16))
220a8445737SSøren Schmidt 	    return EINVAL;
221a8445737SSøren Schmidt     } else {
222a8445737SSøren Schmidt 	fontsize = 14;
223a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_14))
224a8445737SSøren Schmidt 	    return EINVAL;
225a8445737SSøren Schmidt     }
226a8445737SSøren Schmidt     if (xsize <= 0)
227a8445737SSøren Schmidt 	xsize = info.vi_width/8;
228a8445737SSøren Schmidt     if (ysize <= 0)
229a8445737SSøren Schmidt 	ysize = info.vi_height/fontsize;
230a8445737SSøren Schmidt 
231a8445737SSøren Schmidt #ifdef SC_VIDEO_DEBUG
232a8445737SSøren Schmidt     if (scp->scr_buf != NULL) {
233a8445737SSøren Schmidt 	printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
234a8445737SSøren Schmidt 	       scp->mode, xsize, ysize, fontsize);
23595bafc8fSKazutaka YOKOTA 	printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n",
23695bafc8fSKazutaka YOKOTA 	       adp->va_window, info.vi_width, info.vi_height,
237a8445737SSøren Schmidt 	       (info.vi_width/8 - xsize)/2,
238a8445737SSøren Schmidt 	       (info.vi_height/fontsize - ysize)/2);
239a8445737SSøren Schmidt     }
240a8445737SSøren Schmidt #endif
241a8445737SSøren Schmidt 
24295bafc8fSKazutaka YOKOTA     if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
24395bafc8fSKazutaka YOKOTA 	return EINVAL;
24495bafc8fSKazutaka YOKOTA 
24595bafc8fSKazutaka YOKOTA     /* only 16 color, 4 plane modes are supported XXX */
24695bafc8fSKazutaka YOKOTA     if ((info.vi_depth != 4) || (info.vi_planes != 4))
24795bafc8fSKazutaka YOKOTA 	return ENODEV;
24895bafc8fSKazutaka YOKOTA 
24995bafc8fSKazutaka YOKOTA     /*
25095bafc8fSKazutaka YOKOTA      * set_pixel_mode() currently does not support video modes whose
25195bafc8fSKazutaka YOKOTA      * memory size is larger than 64K. Because such modes require
25295bafc8fSKazutaka YOKOTA      * bank switching to access the entire screen. XXX
25395bafc8fSKazutaka YOKOTA      */
25495bafc8fSKazutaka YOKOTA     if (info.vi_width*info.vi_height/8 > info.vi_window_size*1024)
25595bafc8fSKazutaka YOKOTA 	return ENODEV;
25695bafc8fSKazutaka YOKOTA 
257a8445737SSøren Schmidt     /* stop screen saver, etc */
258a8445737SSøren Schmidt     s = spltty();
259a8445737SSøren Schmidt     if ((error = sc_clean_up(scp))) {
260a8445737SSøren Schmidt 	splx(s);
261a8445737SSøren Schmidt 	return error;
262a8445737SSøren Schmidt     }
263a8445737SSøren Schmidt 
264a8445737SSøren Schmidt     /* set up scp */
265a8445737SSøren Schmidt     if (scp->history != NULL)
266a8445737SSøren Schmidt 	i = imax(scp->history_size / scp->xsize
267a8445737SSøren Schmidt 		 - imax(sc_history_size, scp->ysize), 0);
268a8445737SSøren Schmidt     else
269a8445737SSøren Schmidt 	i = 0;
270a8445737SSøren Schmidt     scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
271a8445737SSøren Schmidt     scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED);
272a8445737SSøren Schmidt     scp->xsize = xsize;
273a8445737SSøren Schmidt     scp->ysize = ysize;
274a8445737SSøren Schmidt     scp->font_size = fontsize;
275a8445737SSøren Schmidt     scp->xoff = (scp->xpixel/8 - xsize)/2;
276a8445737SSøren Schmidt     scp->yoff = (scp->ypixel/fontsize - ysize)/2;
277a8445737SSøren Schmidt 
278a8445737SSøren Schmidt     /* allocate buffers */
279a8445737SSøren Schmidt     sc_alloc_scr_buffer(scp, TRUE, TRUE);
280a8445737SSøren Schmidt     if (ISMOUSEAVAIL(adp->va_flags))
281a8445737SSøren Schmidt 	sc_alloc_cut_buffer(scp, FALSE);
282a8445737SSøren Schmidt     sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
283a8445737SSøren Schmidt     splx(s);
284a8445737SSøren Schmidt 
285a8445737SSøren Schmidt     if (scp == cur_console)
28695bafc8fSKazutaka YOKOTA 	set_border(scp, scp->border);
287a8445737SSøren Schmidt 
288a8445737SSøren Schmidt     scp->status &= ~UNKNOWN_MODE;
289a8445737SSøren Schmidt 
290a8445737SSøren Schmidt #ifdef SC_VIDEO_DEBUG
291a8445737SSøren Schmidt     printf("set_pixel_mode(): status:%x\n", scp->status);
292a8445737SSøren Schmidt #endif
293a8445737SSøren Schmidt 
294a8445737SSøren Schmidt     if (tp == NULL)
295a8445737SSøren Schmidt 	return 0;
296a8445737SSøren Schmidt     if (tp->t_winsize.ws_col != scp->xsize
297a8445737SSøren Schmidt 	|| tp->t_winsize.ws_row != scp->ysize) {
298a8445737SSøren Schmidt 	tp->t_winsize.ws_col = scp->xsize;
299a8445737SSøren Schmidt 	tp->t_winsize.ws_row = scp->ysize;
300a8445737SSøren Schmidt 	pgsignal(tp->t_pgrp, SIGWINCH, 1);
301a8445737SSøren Schmidt     }
302a8445737SSøren Schmidt 
303a8445737SSøren Schmidt     return 0;
304a8445737SSøren Schmidt }
305a8445737SSøren Schmidt 
306a8445737SSøren Schmidt int
307a8445737SSøren Schmidt sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
308a8445737SSøren Schmidt {
309a8445737SSøren Schmidt     scr_stat *scp;
310a8445737SSøren Schmidt     video_adapter_t *adp;
311a8445737SSøren Schmidt     int error;
312a8445737SSøren Schmidt     int s;
313a8445737SSøren Schmidt 
314a8445737SSøren Schmidt     scp = sc_get_scr_stat(tp->t_dev);
315a8445737SSøren Schmidt 
316a8445737SSøren Schmidt     switch (cmd) {
317a8445737SSøren Schmidt 
318a8445737SSøren Schmidt     case CONS_CURRENT:  	/* get current adapter type */
319a8445737SSøren Schmidt 	adp = get_adapter(scp);
320a8445737SSøren Schmidt 	*(int *)data = adp->va_type;
321a8445737SSøren Schmidt 	return 0;
322a8445737SSøren Schmidt 
323a8445737SSøren Schmidt     case CONS_CURRENTADP:	/* get current adapter index */
324a8445737SSøren Schmidt 	*(int *)data = scp->adp;
325a8445737SSøren Schmidt 	return 0;
326a8445737SSøren Schmidt 
327a8445737SSøren Schmidt     case CONS_ADPINFO:		/* adapter information */
328a8445737SSøren Schmidt 	adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index);
329a8445737SSøren Schmidt 	if (adp == NULL)
330a8445737SSøren Schmidt 	    return ENODEV;
331a8445737SSøren Schmidt 	bcopy(adp, data, sizeof(*adp));
332a8445737SSøren Schmidt 	return 0;
333a8445737SSøren Schmidt 
334a8445737SSøren Schmidt     case CONS_GET:      	/* get current video mode */
335a8445737SSøren Schmidt 	*(int *)data = scp->mode;
336a8445737SSøren Schmidt 	return 0;
337a8445737SSøren Schmidt 
338a8445737SSøren Schmidt     case CONS_MODEINFO:		/* get mode information */
339a8445737SSøren Schmidt 	return ((*biosvidsw.get_info)(scp->adp,
340a8445737SSøren Schmidt 		    ((video_info_t *)data)->vi_mode, (video_info_t *)data)
341a8445737SSøren Schmidt 		? ENODEV : 0);
342a8445737SSøren Schmidt 
343a8445737SSøren Schmidt     case CONS_FINDMODE:		/* find a matching video mode */
344a8445737SSøren Schmidt 	return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data)
345a8445737SSøren Schmidt 		? ENODEV : 0);
346a8445737SSøren Schmidt 
347a8445737SSøren Schmidt     case CONS_SETWINORG:
348a8445737SSøren Schmidt 	return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
349a8445737SSøren Schmidt 		   ? ENODEV : 0);
350a8445737SSøren Schmidt 
35195bafc8fSKazutaka YOKOTA     /* generic text modes */
35295bafc8fSKazutaka YOKOTA     case SW_TEXT_80x25:	case SW_TEXT_80x30:
35395bafc8fSKazutaka YOKOTA     case SW_TEXT_80x43: case SW_TEXT_80x50:
35495bafc8fSKazutaka YOKOTA     case SW_TEXT_80x60:
35595bafc8fSKazutaka YOKOTA 	/* FALL THROUGH */
35695bafc8fSKazutaka YOKOTA 
357a8445737SSøren Schmidt     /* VGA TEXT MODES */
358a8445737SSøren Schmidt     case SW_VGA_C40x25:
359a8445737SSøren Schmidt     case SW_VGA_C80x25: case SW_VGA_M80x25:
360a8445737SSøren Schmidt     case SW_VGA_C80x30: case SW_VGA_M80x30:
361a8445737SSøren Schmidt     case SW_VGA_C80x50: case SW_VGA_M80x50:
362a8445737SSøren Schmidt     case SW_VGA_C80x60: case SW_VGA_M80x60:
363a8445737SSøren Schmidt     case SW_B40x25:     case SW_C40x25:
364a8445737SSøren Schmidt     case SW_B80x25:     case SW_C80x25:
365a8445737SSøren Schmidt     case SW_ENH_B40x25: case SW_ENH_C40x25:
366a8445737SSøren Schmidt     case SW_ENH_B80x25: case SW_ENH_C80x25:
367a8445737SSøren Schmidt     case SW_ENH_B80x43: case SW_ENH_C80x43:
368a8445737SSøren Schmidt     case SW_EGAMONO80x25:
369a8445737SSøren Schmidt 	adp = get_adapter(scp);
370a8445737SSøren Schmidt 	if (!(adp->va_flags & V_ADP_MODECHANGE))
371a8445737SSøren Schmidt  	    return ENODEV;
372a8445737SSøren Schmidt 	return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
373a8445737SSøren Schmidt 
374a8445737SSøren Schmidt     /* GRAPHICS MODES */
375a8445737SSøren Schmidt     case SW_BG320:     case SW_BG640:
376a8445737SSøren Schmidt     case SW_CG320:     case SW_CG320_D:   case SW_CG640_E:
377a8445737SSøren Schmidt     case SW_CG640x350: case SW_ENH_CG640:
378a8445737SSøren Schmidt     case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
379a8445737SSøren Schmidt     case SW_VGA_MODEX:
380a8445737SSøren Schmidt 	adp = get_adapter(scp);
381a8445737SSøren Schmidt 	if (!(adp->va_flags & V_ADP_MODECHANGE))
382a8445737SSøren Schmidt 	    return ENODEV;
383a8445737SSøren Schmidt 	return sc_set_graphics_mode(scp, tp, cmd & 0xff);
384a8445737SSøren Schmidt 
385a8445737SSøren Schmidt     case KDSETMODE:     	/* set current mode of this (virtual) console */
386a8445737SSøren Schmidt 	switch (*data) {
387a8445737SSøren Schmidt 	case KD_TEXT:   	/* switch to TEXT (known) mode */
388a8445737SSøren Schmidt 	    /*
389a8445737SSøren Schmidt 	     * If scp->mode is of graphics modes, we don't know which
390a8445737SSøren Schmidt 	     * text mode to switch back to...
391a8445737SSøren Schmidt 	     */
392a8445737SSøren Schmidt 	    if (scp->status & GRAPHICS_MODE)
393a8445737SSøren Schmidt 		return EINVAL;
394a8445737SSøren Schmidt 	    /* restore fonts & palette ! */
395a8445737SSøren Schmidt #if 0
396a8445737SSøren Schmidt 	    adp = get_adapter(scp);
397a8445737SSøren Schmidt 	    if (ISFONTAVAIL(adp->va_flags)
398a8445737SSøren Schmidt 		&& !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
399a8445737SSøren Schmidt 		/*
400a8445737SSøren Schmidt 		 * FONT KLUDGE
401a8445737SSøren Schmidt 		 * Don't load fonts for now... XXX
402a8445737SSøren Schmidt 		 */
403a8445737SSøren Schmidt 		if (fonts_loaded & FONT_8)
404a8445737SSøren Schmidt 		    copy_font(scp, LOAD, 8, font_8);
405a8445737SSøren Schmidt 		if (fonts_loaded & FONT_14)
406a8445737SSøren Schmidt 		    copy_font(scp, LOAD, 14, font_14);
407a8445737SSøren Schmidt 		if (fonts_loaded & FONT_16)
408a8445737SSøren Schmidt 		    copy_font(scp, LOAD, 16, font_16);
409a8445737SSøren Schmidt 	    }
410a8445737SSøren Schmidt #endif
411a8445737SSøren Schmidt 	    load_palette(scp, palette);
412a8445737SSøren Schmidt 
413a8445737SSøren Schmidt 	    /* move hardware cursor out of the way */
414a8445737SSøren Schmidt 	    (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
415a8445737SSøren Schmidt 
416a8445737SSøren Schmidt 	    /* FALL THROUGH */
417a8445737SSøren Schmidt 
418a8445737SSøren Schmidt 	case KD_TEXT1:  	/* switch to TEXT (known) mode */
419a8445737SSøren Schmidt 	    /*
420a8445737SSøren Schmidt 	     * If scp->mode is of graphics modes, we don't know which
421a8445737SSøren Schmidt 	     * text/pixel mode to switch back to...
422a8445737SSøren Schmidt 	     */
423a8445737SSøren Schmidt 	    if (scp->status & GRAPHICS_MODE)
424a8445737SSøren Schmidt 		return EINVAL;
425a8445737SSøren Schmidt 	    s = spltty();
426a8445737SSøren Schmidt 	    if ((error = sc_clean_up(scp))) {
427a8445737SSøren Schmidt 		splx(s);
428a8445737SSøren Schmidt 		return error;
429a8445737SSøren Schmidt 	    }
430a8445737SSøren Schmidt 	    scp->status |= UNKNOWN_MODE;
431a8445737SSøren Schmidt 	    splx(s);
432a8445737SSøren Schmidt 	    /* no restore fonts & palette */
43395bafc8fSKazutaka YOKOTA 	    if (scp == cur_console)
434a8445737SSøren Schmidt 		set_mode(scp);
435a8445737SSøren Schmidt 	    sc_clear_screen(scp);
436a8445737SSøren Schmidt 	    scp->status &= ~UNKNOWN_MODE;
437a8445737SSøren Schmidt 	    return 0;
438a8445737SSøren Schmidt 
439a8445737SSøren Schmidt 	case KD_PIXEL:		/* pixel (raster) display */
440a8445737SSøren Schmidt 	    if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
441a8445737SSøren Schmidt 		return EINVAL;
44295bafc8fSKazutaka YOKOTA 	    if (scp->status & GRAPHICS_MODE)
443a8445737SSøren Schmidt 		return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
444a8445737SSøren Schmidt 					 scp->font_size);
445a8445737SSøren Schmidt 	    s = spltty();
446a8445737SSøren Schmidt 	    if ((error = sc_clean_up(scp))) {
447a8445737SSøren Schmidt 		splx(s);
448a8445737SSøren Schmidt 		return error;
449a8445737SSøren Schmidt 	    }
450a8445737SSøren Schmidt 	    scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
451a8445737SSøren Schmidt 	    splx(s);
452a8445737SSøren Schmidt 	    if (scp == cur_console) {
453a8445737SSøren Schmidt 		set_mode(scp);
454a8445737SSøren Schmidt 		load_palette(scp, palette);
455a8445737SSøren Schmidt 	    }
456a8445737SSøren Schmidt 	    sc_clear_screen(scp);
457a8445737SSøren Schmidt 	    scp->status &= ~UNKNOWN_MODE;
458a8445737SSøren Schmidt 	    return 0;
459a8445737SSøren Schmidt 
460a8445737SSøren Schmidt 	case KD_GRAPHICS:	/* switch to GRAPHICS (unknown) mode */
461a8445737SSøren Schmidt 	    s = spltty();
462a8445737SSøren Schmidt 	    if ((error = sc_clean_up(scp))) {
463a8445737SSøren Schmidt 		splx(s);
464a8445737SSøren Schmidt 		return error;
465a8445737SSøren Schmidt 	    }
466a8445737SSøren Schmidt 	    scp->status |= UNKNOWN_MODE;
467a8445737SSøren Schmidt 	    splx(s);
468a8445737SSøren Schmidt 	    return 0;
469a8445737SSøren Schmidt 
470a8445737SSøren Schmidt 	default:
471a8445737SSøren Schmidt 	    return EINVAL;
472a8445737SSøren Schmidt 	}
473a8445737SSøren Schmidt 	/* NOT REACHED */
474a8445737SSøren Schmidt 
475a8445737SSøren Schmidt     case KDRASTER:		/* set pixel (raster) display mode */
476a8445737SSøren Schmidt 	if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
477a8445737SSøren Schmidt 	    return ENODEV;
478a8445737SSøren Schmidt 	return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
479a8445737SSøren Schmidt 				 ((int *)data)[2]);
480a8445737SSøren Schmidt 
481a8445737SSøren Schmidt     case KDGETMODE:     	/* get current mode of this (virtual) console */
482a8445737SSøren Schmidt 	/*
483a8445737SSøren Schmidt 	 * From the user program's point of view, KD_PIXEL is the same
484a8445737SSøren Schmidt 	 * as KD_TEXT...
485a8445737SSøren Schmidt 	 */
486a8445737SSøren Schmidt 	*data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
487a8445737SSøren Schmidt 	return 0;
488a8445737SSøren Schmidt 
489a8445737SSøren Schmidt     case KDSBORDER:     	/* set border color of this (virtual) console */
490a8445737SSøren Schmidt 	scp->border = *data;
491a8445737SSøren Schmidt 	if (scp == cur_console)
492a8445737SSøren Schmidt 	    set_border(cur_console, scp->border);
493a8445737SSøren Schmidt 	return 0;
494a8445737SSøren Schmidt     }
495a8445737SSøren Schmidt 
496a8445737SSøren Schmidt     return ENOIOCTL;
497a8445737SSøren Schmidt }
498a8445737SSøren Schmidt 
499a8445737SSøren Schmidt #endif /* NSC > 0 */
500