xref: /freebsd/sys/dev/syscons/scvidctl.c (revision a8445737e740901f5f2c8d24c12ef7fc8b00134e)
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  *
29a8445737SSøren Schmidt  * $Id$
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 u_short *Crtat;
53a8445737SSøren Schmidt extern int fonts_loaded;
54a8445737SSøren Schmidt extern int sc_history_size;
55a8445737SSøren Schmidt extern u_char palette[];
56a8445737SSøren Schmidt 
57a8445737SSøren Schmidt int
58a8445737SSøren Schmidt sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
59a8445737SSøren Schmidt 		 int fontsize)
60a8445737SSøren Schmidt {
61a8445737SSøren Schmidt     video_adapter_t *adp;
62a8445737SSøren Schmidt     video_info_t info;
63a8445737SSøren Schmidt     int error;
64a8445737SSøren Schmidt     int s;
65a8445737SSøren Schmidt     int i;
66a8445737SSøren Schmidt 
67a8445737SSøren Schmidt     if ((*biosvidsw.get_info)(scp->adp, mode, &info))
68a8445737SSøren Schmidt 	return ENODEV;
69a8445737SSøren Schmidt     adp = get_adapter(scp);
70a8445737SSøren Schmidt 
71a8445737SSøren Schmidt     /* adjust argument values */
72a8445737SSøren Schmidt     if (fontsize <= 0)
73a8445737SSøren Schmidt 	fontsize = info.vi_cheight;
74a8445737SSøren Schmidt     if (fontsize < 14) {
75a8445737SSøren Schmidt 	fontsize = 8;
76a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_8))
77a8445737SSøren Schmidt 	    return EINVAL;
78a8445737SSøren Schmidt     } else if (fontsize >= 16) {
79a8445737SSøren Schmidt 	fontsize = 16;
80a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_16))
81a8445737SSøren Schmidt 	    return EINVAL;
82a8445737SSøren Schmidt     } else {
83a8445737SSøren Schmidt 	fontsize = 14;
84a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_14))
85a8445737SSøren Schmidt 	    return EINVAL;
86a8445737SSøren Schmidt     }
87a8445737SSøren Schmidt     if ((xsize <= 0) || (xsize > info.vi_width))
88a8445737SSøren Schmidt 	xsize = info.vi_width;
89a8445737SSøren Schmidt     if ((ysize <= 0) || (ysize > info.vi_height))
90a8445737SSøren Schmidt 	ysize = info.vi_height;
91a8445737SSøren Schmidt 
92a8445737SSøren Schmidt     /* stop screen saver, etc */
93a8445737SSøren Schmidt     s = spltty();
94a8445737SSøren Schmidt     if ((error = sc_clean_up(scp))) {
95a8445737SSøren Schmidt 	splx(s);
96a8445737SSøren Schmidt 	return error;
97a8445737SSøren Schmidt     }
98a8445737SSøren Schmidt 
99a8445737SSøren Schmidt     /* set up scp */
100a8445737SSøren Schmidt     if (scp->history != NULL)
101a8445737SSøren Schmidt 	i = imax(scp->history_size / scp->xsize
102a8445737SSøren Schmidt 		 - imax(sc_history_size, scp->ysize), 0);
103a8445737SSøren Schmidt     else
104a8445737SSøren Schmidt 	i = 0;
105a8445737SSøren Schmidt     /*
106a8445737SSøren Schmidt      * This is a kludge to fend off scrn_update() while we
107a8445737SSøren Schmidt      * muck around with scp. XXX
108a8445737SSøren Schmidt      */
109a8445737SSøren Schmidt     scp->status |= UNKNOWN_MODE;
110a8445737SSøren Schmidt     scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
111a8445737SSøren Schmidt     scp->mode = mode;
112a8445737SSøren Schmidt     scp->font_size = fontsize;
113a8445737SSøren Schmidt     scp->xsize = xsize;
114a8445737SSøren Schmidt     scp->ysize = ysize;
115a8445737SSøren Schmidt     scp->xpixel = scp->xsize*8;
116a8445737SSøren Schmidt     scp->ypixel = scp->ysize*fontsize;
117a8445737SSøren Schmidt 
118a8445737SSøren Schmidt     /* allocate buffers */
119a8445737SSøren Schmidt     sc_alloc_scr_buffer(scp, TRUE, TRUE);
120a8445737SSøren Schmidt     if (ISMOUSEAVAIL(adp->va_flags))
121a8445737SSøren Schmidt 	sc_alloc_cut_buffer(scp, FALSE);
122a8445737SSøren Schmidt     sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
123a8445737SSøren Schmidt     splx(s);
124a8445737SSøren Schmidt 
125a8445737SSøren Schmidt     if (scp == cur_console)
126a8445737SSøren Schmidt 	set_mode(scp);
127a8445737SSøren Schmidt     scp->status &= ~UNKNOWN_MODE;
128a8445737SSøren Schmidt 
129a8445737SSøren Schmidt     if (tp == NULL)
130a8445737SSøren Schmidt 	return 0;
131a8445737SSøren Schmidt     if (tp->t_winsize.ws_col != scp->xsize
132a8445737SSøren Schmidt 	|| tp->t_winsize.ws_row != scp->ysize) {
133a8445737SSøren Schmidt 	tp->t_winsize.ws_col = scp->xsize;
134a8445737SSøren Schmidt 	tp->t_winsize.ws_row = scp->ysize;
135a8445737SSøren Schmidt 	pgsignal(tp->t_pgrp, SIGWINCH, 1);
136a8445737SSøren Schmidt     }
137a8445737SSøren Schmidt 
138a8445737SSøren Schmidt     return 0;
139a8445737SSøren Schmidt }
140a8445737SSøren Schmidt 
141a8445737SSøren Schmidt int
142a8445737SSøren Schmidt sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
143a8445737SSøren Schmidt {
144a8445737SSøren Schmidt     video_adapter_t *adp;
145a8445737SSøren Schmidt     video_info_t info;
146a8445737SSøren Schmidt     int error;
147a8445737SSøren Schmidt     int s;
148a8445737SSøren Schmidt 
149a8445737SSøren Schmidt     if ((*biosvidsw.get_info)(scp->adp, mode, &info))
150a8445737SSøren Schmidt 	return ENODEV;
151a8445737SSøren Schmidt     adp = get_adapter(scp);
152a8445737SSøren Schmidt 
153a8445737SSøren Schmidt     /* stop screen saver, etc */
154a8445737SSøren Schmidt     s = spltty();
155a8445737SSøren Schmidt     if ((error = sc_clean_up(scp))) {
156a8445737SSøren Schmidt 	splx(s);
157a8445737SSøren Schmidt 	return error;
158a8445737SSøren Schmidt     }
159a8445737SSøren Schmidt 
160a8445737SSøren Schmidt     /* set up scp */
161a8445737SSøren Schmidt     scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
162a8445737SSøren Schmidt     scp->status &= ~PIXEL_MODE;
163a8445737SSøren Schmidt     scp->mode = mode;
164a8445737SSøren Schmidt     scp->xpixel = info.vi_width;
165a8445737SSøren Schmidt     scp->ypixel = info.vi_height;
166a8445737SSøren Schmidt     scp->xsize = info.vi_width/8;
167a8445737SSøren Schmidt     scp->ysize = info.vi_height/info.vi_cheight;
168a8445737SSøren Schmidt     scp->font_size = FONT_NONE;
169a8445737SSøren Schmidt     /* move the mouse cursor at the center of the screen */
170a8445737SSøren Schmidt     sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
171a8445737SSøren Schmidt     splx(s);
172a8445737SSøren Schmidt 
173a8445737SSøren Schmidt     if (scp == cur_console)
174a8445737SSøren Schmidt 	set_mode(scp);
175a8445737SSøren Schmidt     /* clear_graphics();*/
176a8445737SSøren Schmidt     scp->status &= ~UNKNOWN_MODE;
177a8445737SSøren Schmidt 
178a8445737SSøren Schmidt     if (tp == NULL)
179a8445737SSøren Schmidt 	return 0;
180a8445737SSøren Schmidt     if (tp->t_winsize.ws_xpixel != scp->xpixel
181a8445737SSøren Schmidt 	|| tp->t_winsize.ws_ypixel != scp->ypixel) {
182a8445737SSøren Schmidt 	tp->t_winsize.ws_xpixel = scp->xpixel;
183a8445737SSøren Schmidt 	tp->t_winsize.ws_ypixel = scp->ypixel;
184a8445737SSøren Schmidt 	pgsignal(tp->t_pgrp, SIGWINCH, 1);
185a8445737SSøren Schmidt     }
186a8445737SSøren Schmidt 
187a8445737SSøren Schmidt     return 0;
188a8445737SSøren Schmidt }
189a8445737SSøren Schmidt 
190a8445737SSøren Schmidt int
191a8445737SSøren Schmidt sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
192a8445737SSøren Schmidt 		  int fontsize)
193a8445737SSøren Schmidt {
194a8445737SSøren Schmidt     video_adapter_t *adp;
195a8445737SSøren Schmidt     video_info_t info;
196a8445737SSøren Schmidt     int error;
197a8445737SSøren Schmidt     int s;
198a8445737SSøren Schmidt     int i;
199a8445737SSøren Schmidt 
200a8445737SSøren Schmidt     if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
201a8445737SSøren Schmidt 	return ENODEV;		/* this shouldn't happen */
202a8445737SSøren Schmidt     adp = get_adapter(scp);
203a8445737SSøren Schmidt 
204a8445737SSøren Schmidt #ifdef SC_VIDEO_DEBUG
205a8445737SSøren Schmidt     if (scp->scr_buf != NULL) {
206a8445737SSøren Schmidt 	printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
207a8445737SSøren Schmidt 	       scp->mode, xsize, ysize, fontsize);
208a8445737SSøren Schmidt     }
209a8445737SSøren Schmidt #endif
210a8445737SSøren Schmidt 
211a8445737SSøren Schmidt     /* adjust argument values */
212a8445737SSøren Schmidt     if ((fontsize <= 0) || (fontsize == FONT_NONE))
213a8445737SSøren Schmidt 	fontsize = info.vi_cheight;
214a8445737SSøren Schmidt     if (fontsize < 14) {
215a8445737SSøren Schmidt 	fontsize = 8;
216a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_8))
217a8445737SSøren Schmidt 	    return EINVAL;
218a8445737SSøren Schmidt     } else if (fontsize >= 16) {
219a8445737SSøren Schmidt 	fontsize = 16;
220a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_16))
221a8445737SSøren Schmidt 	    return EINVAL;
222a8445737SSøren Schmidt     } else {
223a8445737SSøren Schmidt 	fontsize = 14;
224a8445737SSøren Schmidt 	if (!(fonts_loaded & FONT_14))
225a8445737SSøren Schmidt 	    return EINVAL;
226a8445737SSøren Schmidt     }
227a8445737SSøren Schmidt     if (xsize <= 0)
228a8445737SSøren Schmidt 	xsize = info.vi_width/8;
229a8445737SSøren Schmidt     if (ysize <= 0)
230a8445737SSøren Schmidt 	ysize = info.vi_height/fontsize;
231a8445737SSøren Schmidt 
232a8445737SSøren Schmidt #ifdef SC_VIDEO_DEBUG
233a8445737SSøren Schmidt     if (scp->scr_buf != NULL) {
234a8445737SSøren Schmidt 	printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
235a8445737SSøren Schmidt 	       scp->mode, xsize, ysize, fontsize);
236a8445737SSøren Schmidt 	printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n",
237a8445737SSøren Schmidt 	       Crtat, info.vi_width, info.vi_height,
238a8445737SSøren Schmidt 	       (info.vi_width/8 - xsize)/2,
239a8445737SSøren Schmidt 	       (info.vi_height/fontsize - ysize)/2);
240a8445737SSøren Schmidt     }
241a8445737SSøren Schmidt #endif
242a8445737SSøren Schmidt 
243a8445737SSøren Schmidt     /* stop screen saver, etc */
244a8445737SSøren Schmidt     s = spltty();
245a8445737SSøren Schmidt     if ((error = sc_clean_up(scp))) {
246a8445737SSøren Schmidt 	splx(s);
247a8445737SSøren Schmidt 	return error;
248a8445737SSøren Schmidt     }
249a8445737SSøren Schmidt 
250a8445737SSøren Schmidt     /* set up scp */
251a8445737SSøren Schmidt     if (scp->history != NULL)
252a8445737SSøren Schmidt 	i = imax(scp->history_size / scp->xsize
253a8445737SSøren Schmidt 		 - imax(sc_history_size, scp->ysize), 0);
254a8445737SSøren Schmidt     else
255a8445737SSøren Schmidt 	i = 0;
256a8445737SSøren Schmidt     scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
257a8445737SSøren Schmidt     scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED);
258a8445737SSøren Schmidt     scp->xsize = xsize;
259a8445737SSøren Schmidt     scp->ysize = ysize;
260a8445737SSøren Schmidt     scp->font_size = fontsize;
261a8445737SSøren Schmidt     scp->xoff = (scp->xpixel/8 - xsize)/2;
262a8445737SSøren Schmidt     scp->yoff = (scp->ypixel/fontsize - ysize)/2;
263a8445737SSøren Schmidt 
264a8445737SSøren Schmidt     /* allocate buffers */
265a8445737SSøren Schmidt     sc_alloc_scr_buffer(scp, TRUE, TRUE);
266a8445737SSøren Schmidt     if (ISMOUSEAVAIL(adp->va_flags))
267a8445737SSøren Schmidt 	sc_alloc_cut_buffer(scp, FALSE);
268a8445737SSøren Schmidt     sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
269a8445737SSøren Schmidt     splx(s);
270a8445737SSøren Schmidt 
271a8445737SSøren Schmidt     /* FIXME */
272a8445737SSøren Schmidt     if (scp == cur_console)
273a8445737SSøren Schmidt 	bzero(Crtat, scp->xpixel*scp->ypixel/8);
274a8445737SSøren Schmidt 
275a8445737SSøren Schmidt     scp->status &= ~UNKNOWN_MODE;
276a8445737SSøren Schmidt 
277a8445737SSøren Schmidt #ifdef SC_VIDEO_DEBUG
278a8445737SSøren Schmidt     printf("set_pixel_mode(): status:%x\n", scp->status);
279a8445737SSøren Schmidt #endif
280a8445737SSøren Schmidt 
281a8445737SSøren Schmidt     if (tp == NULL)
282a8445737SSøren Schmidt 	return 0;
283a8445737SSøren Schmidt     if (tp->t_winsize.ws_col != scp->xsize
284a8445737SSøren Schmidt 	|| tp->t_winsize.ws_row != scp->ysize) {
285a8445737SSøren Schmidt 	tp->t_winsize.ws_col = scp->xsize;
286a8445737SSøren Schmidt 	tp->t_winsize.ws_row = scp->ysize;
287a8445737SSøren Schmidt 	pgsignal(tp->t_pgrp, SIGWINCH, 1);
288a8445737SSøren Schmidt     }
289a8445737SSøren Schmidt 
290a8445737SSøren Schmidt     return 0;
291a8445737SSøren Schmidt }
292a8445737SSøren Schmidt 
293a8445737SSøren Schmidt int
294a8445737SSøren Schmidt sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
295a8445737SSøren Schmidt {
296a8445737SSøren Schmidt     scr_stat *scp;
297a8445737SSøren Schmidt     video_adapter_t *adp;
298a8445737SSøren Schmidt     int error;
299a8445737SSøren Schmidt     int s;
300a8445737SSøren Schmidt 
301a8445737SSøren Schmidt     scp = sc_get_scr_stat(tp->t_dev);
302a8445737SSøren Schmidt 
303a8445737SSøren Schmidt     switch (cmd) {
304a8445737SSøren Schmidt 
305a8445737SSøren Schmidt     case CONS_CURRENT:  	/* get current adapter type */
306a8445737SSøren Schmidt 	adp = get_adapter(scp);
307a8445737SSøren Schmidt 	*(int *)data = adp->va_type;
308a8445737SSøren Schmidt 	return 0;
309a8445737SSøren Schmidt 
310a8445737SSøren Schmidt     case CONS_CURRENTADP:	/* get current adapter index */
311a8445737SSøren Schmidt 	*(int *)data = scp->adp;
312a8445737SSøren Schmidt 	return 0;
313a8445737SSøren Schmidt 
314a8445737SSøren Schmidt     case CONS_ADPINFO:		/* adapter information */
315a8445737SSøren Schmidt 	adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index);
316a8445737SSøren Schmidt 	if (adp == NULL)
317a8445737SSøren Schmidt 	    return ENODEV;
318a8445737SSøren Schmidt 	bcopy(adp, data, sizeof(*adp));
319a8445737SSøren Schmidt 	return 0;
320a8445737SSøren Schmidt 
321a8445737SSøren Schmidt     case CONS_GET:      	/* get current video mode */
322a8445737SSøren Schmidt 	*(int *)data = scp->mode;
323a8445737SSøren Schmidt 	return 0;
324a8445737SSøren Schmidt 
325a8445737SSøren Schmidt     case CONS_MODEINFO:		/* get mode information */
326a8445737SSøren Schmidt 	return ((*biosvidsw.get_info)(scp->adp,
327a8445737SSøren Schmidt 		    ((video_info_t *)data)->vi_mode, (video_info_t *)data)
328a8445737SSøren Schmidt 		? ENODEV : 0);
329a8445737SSøren Schmidt 
330a8445737SSøren Schmidt     case CONS_FINDMODE:		/* find a matching video mode */
331a8445737SSøren Schmidt 	return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data)
332a8445737SSøren Schmidt 		? ENODEV : 0);
333a8445737SSøren Schmidt 
334a8445737SSøren Schmidt     case CONS_SETWINORG:
335a8445737SSøren Schmidt 	return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
336a8445737SSøren Schmidt 		   ? ENODEV : 0);
337a8445737SSøren Schmidt 
338a8445737SSøren Schmidt     /* VGA TEXT MODES */
339a8445737SSøren Schmidt     case SW_VGA_C40x25:
340a8445737SSøren Schmidt     case SW_VGA_C80x25: case SW_VGA_M80x25:
341a8445737SSøren Schmidt     case SW_VGA_C80x30: case SW_VGA_M80x30:
342a8445737SSøren Schmidt     case SW_VGA_C80x50: case SW_VGA_M80x50:
343a8445737SSøren Schmidt     case SW_VGA_C80x60: case SW_VGA_M80x60:
344a8445737SSøren Schmidt     case SW_B40x25:     case SW_C40x25:
345a8445737SSøren Schmidt     case SW_B80x25:     case SW_C80x25:
346a8445737SSøren Schmidt     case SW_ENH_B40x25: case SW_ENH_C40x25:
347a8445737SSøren Schmidt     case SW_ENH_B80x25: case SW_ENH_C80x25:
348a8445737SSøren Schmidt     case SW_ENH_B80x43: case SW_ENH_C80x43:
349a8445737SSøren Schmidt     case SW_EGAMONO80x25:
350a8445737SSøren Schmidt 	adp = get_adapter(scp);
351a8445737SSøren Schmidt 	if (!(adp->va_flags & V_ADP_MODECHANGE))
352a8445737SSøren Schmidt  	    return ENODEV;
353a8445737SSøren Schmidt 	return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
354a8445737SSøren Schmidt 
355a8445737SSøren Schmidt     /* GRAPHICS MODES */
356a8445737SSøren Schmidt     case SW_BG320:     case SW_BG640:
357a8445737SSøren Schmidt     case SW_CG320:     case SW_CG320_D:   case SW_CG640_E:
358a8445737SSøren Schmidt     case SW_CG640x350: case SW_ENH_CG640:
359a8445737SSøren Schmidt     case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
360a8445737SSøren Schmidt     case SW_VGA_MODEX:
361a8445737SSøren Schmidt 	adp = get_adapter(scp);
362a8445737SSøren Schmidt 	if (!(adp->va_flags & V_ADP_MODECHANGE))
363a8445737SSøren Schmidt 	    return ENODEV;
364a8445737SSøren Schmidt 	return sc_set_graphics_mode(scp, tp, cmd & 0xff);
365a8445737SSøren Schmidt 
366a8445737SSøren Schmidt     case KDSETMODE:     	/* set current mode of this (virtual) console */
367a8445737SSøren Schmidt 	switch (*data) {
368a8445737SSøren Schmidt 	case KD_TEXT:   	/* switch to TEXT (known) mode */
369a8445737SSøren Schmidt 	    /*
370a8445737SSøren Schmidt 	     * If scp->mode is of graphics modes, we don't know which
371a8445737SSøren Schmidt 	     * text mode to switch back to...
372a8445737SSøren Schmidt 	     */
373a8445737SSøren Schmidt 	    if (scp->status & GRAPHICS_MODE)
374a8445737SSøren Schmidt 		return EINVAL;
375a8445737SSøren Schmidt 	    /* restore fonts & palette ! */
376a8445737SSøren Schmidt #if 0
377a8445737SSøren Schmidt 	    adp = get_adapter(scp);
378a8445737SSøren Schmidt 	    if (ISFONTAVAIL(adp->va_flags)
379a8445737SSøren Schmidt 		&& !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
380a8445737SSøren Schmidt 		/*
381a8445737SSøren Schmidt 		 * FONT KLUDGE
382a8445737SSøren Schmidt 		 * Don't load fonts for now... XXX
383a8445737SSøren Schmidt 		 */
384a8445737SSøren Schmidt 		if (fonts_loaded & FONT_8)
385a8445737SSøren Schmidt 		    copy_font(scp, LOAD, 8, font_8);
386a8445737SSøren Schmidt 		if (fonts_loaded & FONT_14)
387a8445737SSøren Schmidt 		    copy_font(scp, LOAD, 14, font_14);
388a8445737SSøren Schmidt 		if (fonts_loaded & FONT_16)
389a8445737SSøren Schmidt 		    copy_font(scp, LOAD, 16, font_16);
390a8445737SSøren Schmidt 	    }
391a8445737SSøren Schmidt #endif
392a8445737SSøren Schmidt 	    load_palette(scp, palette);
393a8445737SSøren Schmidt 
394a8445737SSøren Schmidt 	    /* move hardware cursor out of the way */
395a8445737SSøren Schmidt 	    (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
396a8445737SSøren Schmidt 
397a8445737SSøren Schmidt 	    /* FALL THROUGH */
398a8445737SSøren Schmidt 
399a8445737SSøren Schmidt 	case KD_TEXT1:  	/* switch to TEXT (known) mode */
400a8445737SSøren Schmidt 	    /*
401a8445737SSøren Schmidt 	     * If scp->mode is of graphics modes, we don't know which
402a8445737SSøren Schmidt 	     * text/pixel mode to switch back to...
403a8445737SSøren Schmidt 	     */
404a8445737SSøren Schmidt 	    if (scp->status & GRAPHICS_MODE)
405a8445737SSøren Schmidt 		return EINVAL;
406a8445737SSøren Schmidt 	    s = spltty();
407a8445737SSøren Schmidt 	    if ((error = sc_clean_up(scp))) {
408a8445737SSøren Schmidt 		splx(s);
409a8445737SSøren Schmidt 		return error;
410a8445737SSøren Schmidt 	    }
411a8445737SSøren Schmidt 	    scp->status |= UNKNOWN_MODE;
412a8445737SSøren Schmidt 	    splx(s);
413a8445737SSøren Schmidt 	    /* no restore fonts & palette */
414a8445737SSøren Schmidt 	    if (scp == cur_console) {
415a8445737SSøren Schmidt 		set_mode(scp);
416a8445737SSøren Schmidt 		/* FIXME */
417a8445737SSøren Schmidt 		if (scp->status & PIXEL_MODE)
418a8445737SSøren Schmidt 		    bzero(Crtat, scp->xpixel*scp->ypixel/8);
419a8445737SSøren Schmidt 	    }
420a8445737SSøren Schmidt 	    sc_clear_screen(scp);
421a8445737SSøren Schmidt 	    scp->status &= ~UNKNOWN_MODE;
422a8445737SSøren Schmidt 	    return 0;
423a8445737SSøren Schmidt 
424a8445737SSøren Schmidt 	case KD_PIXEL:		/* pixel (raster) display */
425a8445737SSøren Schmidt 	    if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
426a8445737SSøren Schmidt 		return EINVAL;
427a8445737SSøren Schmidt 	    if (!(scp->status & PIXEL_MODE))
428a8445737SSøren Schmidt 		return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
429a8445737SSøren Schmidt 					 scp->font_size);
430a8445737SSøren Schmidt 	    s = spltty();
431a8445737SSøren Schmidt 	    if ((error = sc_clean_up(scp))) {
432a8445737SSøren Schmidt 		splx(s);
433a8445737SSøren Schmidt 		return error;
434a8445737SSøren Schmidt 	    }
435a8445737SSøren Schmidt 	    scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
436a8445737SSøren Schmidt 	    splx(s);
437a8445737SSøren Schmidt 	    if (scp == cur_console) {
438a8445737SSøren Schmidt 		set_mode(scp);
439a8445737SSøren Schmidt 		load_palette(scp, palette);
440a8445737SSøren Schmidt 		/* FIXME */
441a8445737SSøren Schmidt 		bzero(Crtat, scp->xpixel*scp->ypixel/8);
442a8445737SSøren Schmidt 	    }
443a8445737SSøren Schmidt 	    sc_clear_screen(scp);
444a8445737SSøren Schmidt 	    scp->status &= ~UNKNOWN_MODE;
445a8445737SSøren Schmidt 	    return 0;
446a8445737SSøren Schmidt 
447a8445737SSøren Schmidt 	case KD_GRAPHICS:	/* switch to GRAPHICS (unknown) mode */
448a8445737SSøren Schmidt 	    s = spltty();
449a8445737SSøren Schmidt 	    if ((error = sc_clean_up(scp))) {
450a8445737SSøren Schmidt 		splx(s);
451a8445737SSøren Schmidt 		return error;
452a8445737SSøren Schmidt 	    }
453a8445737SSøren Schmidt 	    scp->status |= UNKNOWN_MODE;
454a8445737SSøren Schmidt 	    splx(s);
455a8445737SSøren Schmidt 	    return 0;
456a8445737SSøren Schmidt 
457a8445737SSøren Schmidt 	default:
458a8445737SSøren Schmidt 	    return EINVAL;
459a8445737SSøren Schmidt 	}
460a8445737SSøren Schmidt 	/* NOT REACHED */
461a8445737SSøren Schmidt 
462a8445737SSøren Schmidt     case KDRASTER:		/* set pixel (raster) display mode */
463a8445737SSøren Schmidt 	if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
464a8445737SSøren Schmidt 	    return ENODEV;
465a8445737SSøren Schmidt 	return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
466a8445737SSøren Schmidt 				 ((int *)data)[2]);
467a8445737SSøren Schmidt 
468a8445737SSøren Schmidt     case KDGETMODE:     	/* get current mode of this (virtual) console */
469a8445737SSøren Schmidt 	/*
470a8445737SSøren Schmidt 	 * From the user program's point of view, KD_PIXEL is the same
471a8445737SSøren Schmidt 	 * as KD_TEXT...
472a8445737SSøren Schmidt 	 */
473a8445737SSøren Schmidt 	*data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
474a8445737SSøren Schmidt 	return 0;
475a8445737SSøren Schmidt 
476a8445737SSøren Schmidt     case KDSBORDER:     	/* set border color of this (virtual) console */
477a8445737SSøren Schmidt 	scp->border = *data;
478a8445737SSøren Schmidt 	if (scp == cur_console)
479a8445737SSøren Schmidt 	    set_border(cur_console, scp->border);
480a8445737SSøren Schmidt 	return 0;
481a8445737SSøren Schmidt     }
482a8445737SSøren Schmidt 
483a8445737SSøren Schmidt     return ENOIOCTL;
484a8445737SSøren Schmidt }
485a8445737SSøren Schmidt 
486a8445737SSøren Schmidt #endif /* NSC > 0 */
487