scvidctl.c revision 204281
153642Sguido/*-
2255332Scy * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
353642Sguido * All rights reserved.
480482Sdarrenr *
553642Sguido * This code is derived from software contributed to The DragonFly Project
653642Sguido * by Sascha Wildner <saw@online.de>
757126Sguido *
8172776Sdarrenr * Redistribution and use in source and binary forms, with or without
953642Sguido * modification, are permitted provided that the following conditions
1053642Sguido * are met:
1153642Sguido * 1. Redistributions of source code must retain the above copyright
1253642Sguido *    notice, this list of conditions and the following disclaimer as
1353642Sguido *    the first lines of this file unmodified.
14145562Sdarrenr * 2. Redistributions in binary form must reproduce the above copyright
15255332Scy *    notice, this list of conditions and the following disclaimer in the
16255332Scy *    documentation and/or other materials provided with the distribution.
17255332Scy *
18255332Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19255332Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20255332Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21255332Scy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22255332Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23255332Scy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24255332Scy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25255332Scy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26145562Sdarrenr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27255332Scy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28255332Scy */
29255332Scy
30255332Scy#include <sys/cdefs.h>
3153642Sguido__FBSDID("$FreeBSD: head/sys/dev/syscons/scvidctl.c 204281 2010-02-24 20:13:34Z jkim $");
3253642Sguido
3353642Sguido#include "opt_compat.h"
3453642Sguido#include "opt_syscons.h"
3553642Sguido
3653642Sguido#include <sys/param.h>
3753642Sguido#include <sys/systm.h>
3853642Sguido#include <sys/conf.h>
3953642Sguido#include <sys/signalvar.h>
4053642Sguido#include <sys/tty.h>
4153642Sguido#include <sys/kernel.h>
4253642Sguido#include <sys/fbio.h>
43153876Sguido#include <sys/consio.h>
44145522Sdarrenr#include <sys/filedesc.h>
45145522Sdarrenr#include <sys/lock.h>
4653642Sguido#include <sys/sx.h>
4753642Sguido#include <sys/mutex.h>
48145522Sdarrenr#include <sys/proc.h>
4953642Sguido
5053642Sguido#include <dev/fb/fbreg.h>
51145522Sdarrenr#include <dev/syscons/syscons.h>
52145522Sdarrenr
5353642SguidoSET_DECLARE(scrndr_set, const sc_renderer_t);
54145522Sdarrenr
55145522Sdarrenr/* for compatibility with previous versions */
5653642Sguido/* 3.0-RELEASE used the following structure */
5753642Sguidotypedef struct old_video_adapter {
58145522Sdarrenr    int			va_index;
59145522Sdarrenr    int			va_type;
60145522Sdarrenr    int			va_flags;
61145522Sdarrenr/* flag bits are the same as the -CURRENT
62170268Sdarrenr#define V_ADP_COLOR	(1<<0)
6360851Sdarrenr#define V_ADP_MODECHANGE (1<<1)
64145522Sdarrenr#define V_ADP_STATESAVE	(1<<2)
65145522Sdarrenr#define V_ADP_STATELOAD	(1<<3)
66145522Sdarrenr#define V_ADP_FONT	(1<<4)
67170268Sdarrenr#define V_ADP_PALETTE	(1<<5)
68145522Sdarrenr#define V_ADP_BORDER	(1<<6)
69145522Sdarrenr#define V_ADP_VESA	(1<<7)
70145522Sdarrenr*/
71145522Sdarrenr    int			va_crtc_addr;
72145522Sdarrenr    u_int		va_window;	/* virtual address */
73145522Sdarrenr    size_t		va_window_size;
74145522Sdarrenr    size_t		va_window_gran;
75170268Sdarrenr    u_int		va_buffer;	/* virtual address */
76170268Sdarrenr    size_t		va_buffer_size;
77170268Sdarrenr    int			va_initial_mode;
78170268Sdarrenr    int			va_initial_bios_mode;
79170268Sdarrenr    int			va_mode;
80170268Sdarrenr} old_video_adapter_t;
81255332Scy
82255332Scy#define OLD_CONS_ADPINFO _IOWR('c', 101, old_video_adapter_t)
8353642Sguido
84145522Sdarrenr/* 3.1-RELEASE used the following structure */
85145522Sdarrenrtypedef struct old_video_adapter_info {
8653642Sguido    int			va_index;
8753642Sguido    int			va_type;
88145522Sdarrenr    char		va_name[16];
8953642Sguido    int			va_unit;
9053642Sguido    int			va_flags;
91145522Sdarrenr    int			va_io_base;
92145522Sdarrenr    int			va_io_size;
9353642Sguido    int			va_crtc_addr;
94145522Sdarrenr    int			va_mem_base;
95145522Sdarrenr    int			va_mem_size;
9653642Sguido    u_int		va_window;	/* virtual address */
9753642Sguido    size_t		va_window_size;
98145522Sdarrenr    size_t		va_window_gran;
99145522Sdarrenr    u_int		va_buffer;
100145522Sdarrenr    size_t		va_buffer_size;
101145522Sdarrenr    int			va_initial_mode;
102170268Sdarrenr    int			va_initial_bios_mode;
10360851Sdarrenr    int			va_mode;
104145522Sdarrenr    int			va_line_width;
105145522Sdarrenr} old_video_adapter_info_t;
106145522Sdarrenr
107170268Sdarrenr#define OLD_CONS_ADPINFO2 _IOWR('c', 101, old_video_adapter_info_t)
108145522Sdarrenr
109145522Sdarrenr/* 3.0-RELEASE and 3.1-RELEASE used the following structure */
110145522Sdarrenrtypedef struct old_video_info {
111145522Sdarrenr    int			vi_mode;
112145522Sdarrenr    int			vi_flags;
113145522Sdarrenr/* flag bits are the same as the -CURRENT
114145522Sdarrenr#define V_INFO_COLOR	(1<<0)
115170268Sdarrenr#define V_INFO_GRAPHICS	(1<<1)
116170268Sdarrenr#define V_INFO_LINEAR	(1<<2)
117170268Sdarrenr#define V_INFO_VESA	(1<<3)
118170268Sdarrenr*/
119170268Sdarrenr    int			vi_width;
120170268Sdarrenr    int			vi_height;
121255332Scy    int			vi_cwidth;
122255332Scy    int			vi_cheight;
12353642Sguido    int			vi_depth;
12453642Sguido    int			vi_planes;
12553642Sguido    u_int		vi_window;	/* physical address */
12653642Sguido    size_t		vi_window_size;
127170268Sdarrenr    size_t		vi_window_gran;
128170268Sdarrenr    u_int		vi_buffer;	/* physical address */
12953642Sguido    size_t		vi_buffer_size;
13060851Sdarrenr} old_video_info_t;
131145522Sdarrenr
132145522Sdarrenr#define OLD_CONS_MODEINFO _IOWR('c', 102, old_video_info_t)
133255332Scy#define OLD_CONS_FINDMODE _IOWR('c', 103, old_video_info_t)
134145522Sdarrenr
135255332Scyint
136255332Scysc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
137145522Sdarrenr		 int fontsize, int fontwidth)
138145522Sdarrenr{
139145522Sdarrenr    video_info_t info;
140145522Sdarrenr    u_char *font;
141145522Sdarrenr    int prev_ysize;
142145522Sdarrenr    int error;
143145522Sdarrenr    int s;
144145522Sdarrenr
145145522Sdarrenr    if (vidd_get_info(scp->sc->adp, mode, &info))
146145522Sdarrenr	return ENODEV;
147145522Sdarrenr
148145522Sdarrenr    /* adjust argument values */
149170268Sdarrenr    if (fontwidth <= 0)
150170268Sdarrenr	fontwidth = info.vi_cwidth;
151170268Sdarrenr    if (fontsize <= 0)
152255332Scy	fontsize = info.vi_cheight;
153170268Sdarrenr    if (fontsize < 14) {
154145522Sdarrenr	fontsize = 8;
155145522Sdarrenr#ifndef SC_NO_FONT_LOADING
156145522Sdarrenr	if (!(scp->sc->fonts_loaded & FONT_8))
157145522Sdarrenr	    return EINVAL;
158145522Sdarrenr	font = scp->sc->font_8;
159145522Sdarrenr#else
160145522Sdarrenr	font = NULL;
161170268Sdarrenr#endif
162170268Sdarrenr    } else if (fontsize >= 16) {
163170268Sdarrenr	fontsize = 16;
164255332Scy#ifndef SC_NO_FONT_LOADING
165170268Sdarrenr	if (!(scp->sc->fonts_loaded & FONT_16))
166145522Sdarrenr	    return EINVAL;
167145522Sdarrenr	font = scp->sc->font_16;
168145522Sdarrenr#else
169145522Sdarrenr	font = NULL;
170170268Sdarrenr#endif
171255332Scy    } else {
172170268Sdarrenr	fontsize = 14;
173170268Sdarrenr#ifndef SC_NO_FONT_LOADING
174145522Sdarrenr	if (!(scp->sc->fonts_loaded & FONT_14))
175145522Sdarrenr	    return EINVAL;
176145522Sdarrenr	font = scp->sc->font_14;
177145522Sdarrenr#else
178145522Sdarrenr	font = NULL;
179145522Sdarrenr#endif
180172776Sdarrenr    }
181172776Sdarrenr    if ((xsize <= 0) || (xsize > info.vi_width))
182172776Sdarrenr	xsize = info.vi_width;
183172776Sdarrenr    if ((ysize <= 0) || (ysize > info.vi_height))
184172776Sdarrenr	ysize = info.vi_height;
185172776Sdarrenr
186172776Sdarrenr    /* stop screen saver, etc */
187172776Sdarrenr    s = spltty();
188145522Sdarrenr    if ((error = sc_clean_up(scp))) {
189145522Sdarrenr	splx(s);
190145522Sdarrenr	return error;
191145522Sdarrenr    }
192145522Sdarrenr
193145522Sdarrenr    if (sc_render_match(scp, scp->sc->adp->va_name, 0) == NULL) {
194145522Sdarrenr	splx(s);
195255332Scy	return ENODEV;
196255332Scy    }
197255332Scy
198255332Scy    /* set up scp */
199255332Scy#ifndef SC_NO_HISTORY
200255332Scy    if (scp->history != NULL)
201255332Scy	sc_hist_save(scp);
202255332Scy#endif
203255332Scy    prev_ysize = scp->ysize;
204255332Scy    /*
205255332Scy     * This is a kludge to fend off scrn_update() while we
206255332Scy     * muck around with scp. XXX
207255332Scy     */
208255332Scy    scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
209255332Scy    scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE | MOUSE_VISIBLE);
210255332Scy    scp->mode = mode;
211145522Sdarrenr    scp->xsize = xsize;
212145522Sdarrenr    scp->ysize = ysize;
213255332Scy    scp->xoff = 0;
214172776Sdarrenr    scp->yoff = 0;
215172776Sdarrenr    scp->xpixel = scp->xsize*8;
216172776Sdarrenr    scp->ypixel = scp->ysize*fontsize;
217172776Sdarrenr    scp->font = font;
218172776Sdarrenr    scp->font_size = fontsize;
219172776Sdarrenr    scp->font_width = fontwidth;
220172776Sdarrenr
221145522Sdarrenr    /* allocate buffers */
222145522Sdarrenr    sc_alloc_scr_buffer(scp, TRUE, TRUE);
223145522Sdarrenr    sc_init_emulator(scp, NULL);
224255332Scy#ifndef SC_NO_CUTPASTE
225145522Sdarrenr    sc_alloc_cut_buffer(scp, FALSE);
226255332Scy#endif
227145522Sdarrenr#ifndef SC_NO_HISTORY
228145522Sdarrenr    sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
229145522Sdarrenr#endif
230145522Sdarrenr    splx(s);
231145522Sdarrenr
232145522Sdarrenr    if (scp == scp->sc->cur_scp)
233145522Sdarrenr	set_mode(scp);
234145522Sdarrenr    scp->status &= ~UNKNOWN_MODE;
235145522Sdarrenr
236145522Sdarrenr    if (tp == NULL)
237145522Sdarrenr	return 0;
238255332Scy    DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n",
239255332Scy	tp->t_winsize.ws_col, tp->t_winsize.ws_row, scp->xsize, scp->ysize));
240255332Scy    if (tp->t_winsize.ws_col != scp->xsize
241145522Sdarrenr	|| tp->t_winsize.ws_row != scp->ysize) {
242145522Sdarrenr	tp->t_winsize.ws_col = scp->xsize;
243145522Sdarrenr	tp->t_winsize.ws_row = scp->ysize;
244145522Sdarrenr
245145522Sdarrenr	tty_signal_pgrp(tp, SIGWINCH);
246255332Scy    }
247255332Scy
248255332Scy    return 0;
249255332Scy}
250255332Scy
251255332Scyint
252255332Scysc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
253255332Scy{
254255332Scy#ifdef SC_NO_MODE_CHANGE
255255332Scy    return ENODEV;
256255332Scy#else
257255332Scy    video_info_t info;
258255332Scy    int error;
259255332Scy    int s;
260255332Scy
261255332Scy    if (vidd_get_info(scp->sc->adp, mode, &info))
262255332Scy	return ENODEV;
263255332Scy
264255332Scy    /* stop screen saver, etc */
265145522Sdarrenr    s = spltty();
266255332Scy    if ((error = sc_clean_up(scp))) {
267145522Sdarrenr	splx(s);
268145522Sdarrenr	return error;
269145522Sdarrenr    }
270145522Sdarrenr
271145522Sdarrenr    if (sc_render_match(scp, scp->sc->adp->va_name, GRAPHICS_MODE) == NULL) {
272145522Sdarrenr	splx(s);
273255332Scy	return ENODEV;
274255332Scy    }
275255332Scy
276255332Scy    /* set up scp */
277255332Scy    scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE | MOUSE_HIDDEN);
278255332Scy    scp->status &= ~(PIXEL_MODE | MOUSE_VISIBLE);
279255332Scy    scp->mode = mode;
280255332Scy    /*
281255332Scy     * Don't change xsize and ysize; preserve the previous vty
282255332Scy     * and history buffers.
283255332Scy     */
284255332Scy    scp->xoff = 0;
285255332Scy    scp->yoff = 0;
286255332Scy    scp->xpixel = info.vi_width;
287255332Scy    scp->ypixel = info.vi_height;
288255332Scy    scp->font = NULL;
289255332Scy    scp->font_size = 0;
290255332Scy#ifndef SC_NO_SYSMOUSE
291255332Scy    /* move the mouse cursor at the center of the screen */
292145522Sdarrenr    sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
293255332Scy#endif
294255332Scy    sc_init_emulator(scp, NULL);
295255332Scy    splx(s);
296255332Scy
297145522Sdarrenr    if (scp == scp->sc->cur_scp)
29853642Sguido	set_mode(scp);
29960851Sdarrenr    /* clear_graphics();*/
300145522Sdarrenr    scp->status &= ~UNKNOWN_MODE;
30160851Sdarrenr
30260851Sdarrenr    if (tp == NULL)
30360851Sdarrenr	return 0;
30453642Sguido    if (tp->t_winsize.ws_xpixel != scp->xpixel
305145522Sdarrenr	|| tp->t_winsize.ws_ypixel != scp->ypixel) {
306145522Sdarrenr	tp->t_winsize.ws_xpixel = scp->xpixel;
307255332Scy	tp->t_winsize.ws_ypixel = scp->ypixel;
308145522Sdarrenr
309145522Sdarrenr	tty_signal_pgrp(tp, SIGWINCH);
310255332Scy    }
311255332Scy
312255332Scy    return 0;
313255332Scy#endif /* SC_NO_MODE_CHANGE */
31453642Sguido}
31553642Sguido
316145522Sdarrenrint
317145522Sdarrenrsc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
318145522Sdarrenr		  int fontsize, int fontwidth)
319145522Sdarrenr{
320145522Sdarrenr#ifndef SC_PIXEL_MODE
321145522Sdarrenr    return ENODEV;
322145522Sdarrenr#else
323145522Sdarrenr    video_info_t info;
324145522Sdarrenr    ksiginfo_t ksi;
325145522Sdarrenr    u_char *font;
326145522Sdarrenr    int prev_ysize;
327145522Sdarrenr    int error;
328145522Sdarrenr    int s;
329145522Sdarrenr
330145522Sdarrenr    if (vidd_get_info(scp->sc->adp, scp->mode, &info))
331145522Sdarrenr	return ENODEV;		/* this shouldn't happen */
332145522Sdarrenr
333145522Sdarrenr    /* adjust argument values */
334145522Sdarrenr    if (fontsize <= 0)
335255332Scy	fontsize = info.vi_cheight;
336145522Sdarrenr    if (fontsize < 14) {
337255332Scy	fontsize = 8;
338145522Sdarrenr#ifndef SC_NO_FONT_LOADING
339145522Sdarrenr	if (!(scp->sc->fonts_loaded & FONT_8))
340172776Sdarrenr	    return EINVAL;
341255332Scy	font = scp->sc->font_8;
342255332Scy#else
343255332Scy	font = NULL;
344255332Scy#endif
345145522Sdarrenr    } else if (fontsize >= 16) {
346255332Scy	fontsize = 16;
347145522Sdarrenr#ifndef SC_NO_FONT_LOADING
34853642Sguido	if (!(scp->sc->fonts_loaded & FONT_16))
349255332Scy	    return EINVAL;
350255332Scy	font = scp->sc->font_16;
351255332Scy#else
35260851Sdarrenr	font = NULL;
35360851Sdarrenr#endif
354145522Sdarrenr    } else {
355145522Sdarrenr	fontsize = 14;
356170268Sdarrenr#ifndef SC_NO_FONT_LOADING
357170268Sdarrenr	if (!(scp->sc->fonts_loaded & FONT_14))
358145522Sdarrenr	    return EINVAL;
359145522Sdarrenr	font = scp->sc->font_14;
360170268Sdarrenr#else
361170268Sdarrenr	font = NULL;
362145522Sdarrenr#endif
363145522Sdarrenr    }
364145522Sdarrenr    if (xsize <= 0)
365145522Sdarrenr	xsize = info.vi_width/8;
36660851Sdarrenr    if (ysize <= 0)
36760851Sdarrenr	ysize = info.vi_height/fontsize;
36853642Sguido
36953642Sguido    if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
37053642Sguido	return EINVAL;
371145522Sdarrenr
37253642Sguido    if (!sc_support_pixel_mode(&info))
373145522Sdarrenr	return ENODEV;
374145522Sdarrenr
375145522Sdarrenr    /* stop screen saver, etc */
376145522Sdarrenr    s = spltty();
377145522Sdarrenr    if ((error = sc_clean_up(scp))) {
378145522Sdarrenr	splx(s);
379145522Sdarrenr	return error;
380145522Sdarrenr    }
381145522Sdarrenr
382255332Scy    if (sc_render_match(scp, scp->sc->adp->va_name, PIXEL_MODE) == NULL) {
38353642Sguido	splx(s);
384255332Scy	return ENODEV;
385255332Scy    }
386255332Scy
387255332Scy#if 0
388145522Sdarrenr    if (scp->tsw)
389255332Scy	(*scp->tsw->te_term)(scp, scp->ts);
390255332Scy    scp->tsw = NULL;
391255332Scy    scp->ts = NULL;
392255332Scy#endif
393255332Scy
394255332Scy    /* set up scp */
395255332Scy#ifndef SC_NO_HISTORY
396255332Scy    if (scp->history != NULL)
397255332Scy	sc_hist_save(scp);
398255332Scy#endif
399255332Scy    prev_ysize = scp->ysize;
400255332Scy    scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
401255332Scy    scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
402255332Scy    scp->xsize = xsize;
403255332Scy    scp->ysize = ysize;
404255332Scy    scp->xoff = (scp->xpixel/8 - xsize)/2;
405255332Scy    scp->yoff = (scp->ypixel/fontsize - ysize)/2;
406255332Scy    scp->font = font;
407255332Scy    scp->font_size = fontsize;
408255332Scy    scp->font_width = fontwidth;
409255332Scy
410255332Scy    /* allocate buffers */
411255332Scy    sc_alloc_scr_buffer(scp, TRUE, TRUE);
412255332Scy    sc_init_emulator(scp, NULL);
413255332Scy#ifndef SC_NO_CUTPASTE
414255332Scy    sc_alloc_cut_buffer(scp, FALSE);
415255332Scy#endif
416255332Scy#ifndef SC_NO_HISTORY
417255332Scy    sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
418255332Scy#endif
41953642Sguido    splx(s);
420255332Scy
42153642Sguido    if (scp == scp->sc->cur_scp) {
422255332Scy	sc_set_border(scp, scp->border);
423145522Sdarrenr	sc_set_cursor_image(scp);
424255332Scy    }
425255332Scy
426255332Scy    scp->status &= ~UNKNOWN_MODE;
427255332Scy
428255332Scy    if (tp == NULL)
42995418Sdarrenr	return 0;
430145522Sdarrenr    if (tp->t_winsize.ws_col != scp->xsize
431145522Sdarrenr	|| tp->t_winsize.ws_row != scp->ysize) {
432255332Scy	tp->t_winsize.ws_col = scp->xsize;
433255332Scy	tp->t_winsize.ws_row = scp->ysize;
434255332Scy	if (tp->t_pgrp != NULL) {
435255332Scy	    ksiginfo_init(&ksi);
436255332Scy	    ksi.ksi_signo = SIGWINCH;
437255332Scy	    ksi.ksi_code = SI_KERNEL;
438255332Scy	    PGRP_LOCK(tp->t_pgrp);
439255332Scy	    pgsignal(tp->t_pgrp, SIGWINCH, 1, &ksi);
440255332Scy	    PGRP_UNLOCK(tp->t_pgrp);
441255332Scy	}
442255332Scy    }
443255332Scy
444255332Scy    return 0;
445145522Sdarrenr#endif /* SC_PIXEL_MODE */
446255332Scy}
447255332Scy
44892685Sdarrenrint
449145522Sdarrenrsc_support_pixel_mode(void *arg)
450145522Sdarrenr{
451255332Scy#ifdef SC_PIXEL_MODE
452255332Scy	video_info_t *info = arg;
453255332Scy
454145522Sdarrenr	if ((info->vi_flags & V_INFO_GRAPHICS) == 0)
455255332Scy		return (0);
456255332Scy
457255332Scy	/*
458255332Scy	 * We currently support the following graphic modes:
459255332Scy	 *
460255332Scy	 * - 4 bpp planar modes whose memory size does not exceed 64K
461255332Scy	 * - 15, 16, 24 and 32 bpp linear modes
462255332Scy	 */
463130886Sdarrenr	switch (info->vi_mem_model) {
464145522Sdarrenr	case V_INFO_MM_PLANAR:
465145522Sdarrenr		if (info->vi_planes != 4)
466145522Sdarrenr			break;
467145522Sdarrenr		/*
468161356Sguido		 * A memory size >64K requires bank switching to access
46953642Sguido		 * the entire screen. XXX
470145522Sdarrenr		 */
471145522Sdarrenr		if (info->vi_width * info->vi_height / 8 > info->vi_window_size)
472145522Sdarrenr			break;
473255332Scy		return (1);
47453642Sguido	case V_INFO_MM_DIRECT:
47553642Sguido		if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
476255332Scy		    info->vi_depth != 15 && info->vi_depth != 16 &&
477255332Scy		    info->vi_depth != 24 && info->vi_depth != 32)
47880482Sdarrenr			break;
47992685Sdarrenr		return (1);
480145522Sdarrenr	case V_INFO_MM_PACKED:
481145522Sdarrenr		if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
482145522Sdarrenr		    info->vi_depth != 8)
483255332Scy			break;
484145522Sdarrenr		return (1);
485145522Sdarrenr	}
48680482Sdarrenr#endif
487145522Sdarrenr	return (0);
48880482Sdarrenr}
489255332Scy
490255332Scy#define fb_ioctl(a, c, d)		\
491255332Scy	(((a) == NULL) ? ENODEV : 	\
492255332Scy			 vidd_ioctl((a), (c), (caddr_t)(d)))
493255332Scy
494255332Scyint
495255332Scysc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
496255332Scy{
49760851Sdarrenr    scr_stat *scp;
498170268Sdarrenr    video_adapter_t *adp;
499170268Sdarrenr    video_info_t info;
500145522Sdarrenr    video_adapter_info_t adp_info;
501145522Sdarrenr    int error;
502255332Scy    int s;
503145522Sdarrenr#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
504145522Sdarrenr    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
505145522Sdarrenr    int ival;
506145522Sdarrenr#endif
507145522Sdarrenr
508255332Scy    scp = SC_STAT(tp);
509145522Sdarrenr    if (scp == NULL)		/* tp == SC_MOUSE */
510145522Sdarrenr	return ENOIOCTL;
51153642Sguido    adp = scp->sc->adp;
51253642Sguido    if (adp == NULL)		/* shouldn't happen??? */
51353642Sguido	return ENODEV;
51453642Sguido
51592685Sdarrenr    switch (cmd) {
51653642Sguido
51753642Sguido    case CONS_CURRENTADP:	/* get current adapter index */
518145522Sdarrenr    case FBIO_ADAPTER:
51995418Sdarrenr	return fb_ioctl(adp, FBIO_ADAPTER, data);
520145522Sdarrenr
52195418Sdarrenr    case CONS_CURRENT:  	/* get current adapter type */
52295418Sdarrenr    case FBIO_ADPTYPE:
523145522Sdarrenr	return fb_ioctl(adp, FBIO_ADPTYPE, data);
52453642Sguido
525145522Sdarrenr    case OLD_CONS_ADPINFO:	/* adapter information (old interface) */
526145522Sdarrenr	if (((old_video_adapter_t *)data)->va_index >= 0) {
527145522Sdarrenr	    adp = vid_get_adapter(((old_video_adapter_t *)data)->va_index);
528145522Sdarrenr	    if (adp == NULL)
529145522Sdarrenr		return ENODEV;
530145522Sdarrenr	}
531145522Sdarrenr	((old_video_adapter_t *)data)->va_index = adp->va_index;
532145522Sdarrenr	((old_video_adapter_t *)data)->va_type = adp->va_type;
53353642Sguido	((old_video_adapter_t *)data)->va_flags = adp->va_flags;
534145522Sdarrenr	((old_video_adapter_t *)data)->va_crtc_addr = adp->va_crtc_addr;
535145522Sdarrenr	((old_video_adapter_t *)data)->va_window = adp->va_window;
536145522Sdarrenr	((old_video_adapter_t *)data)->va_window_size = adp->va_window_size;
537255332Scy	((old_video_adapter_t *)data)->va_window_gran = adp->va_window_gran;
538255332Scy	((old_video_adapter_t *)data)->va_buffer = adp->va_buffer;
539255332Scy	((old_video_adapter_t *)data)->va_buffer_size = adp->va_buffer_size;
540255332Scy	((old_video_adapter_t *)data)->va_mode = adp->va_mode;
541255332Scy	((old_video_adapter_t *)data)->va_initial_mode = adp->va_initial_mode;
542255332Scy	((old_video_adapter_t *)data)->va_initial_bios_mode
543255332Scy	    = adp->va_initial_bios_mode;
544255332Scy	return 0;
545255332Scy
546145522Sdarrenr    case OLD_CONS_ADPINFO2:	/* adapter information (yet another old I/F) */
547255332Scy	adp_info.va_index = ((old_video_adapter_info_t *)data)->va_index;
548255332Scy	if (adp_info.va_index >= 0) {
549255332Scy	    adp = vid_get_adapter(adp_info.va_index);
550255332Scy	    if (adp == NULL)
551255332Scy		return ENODEV;
552255332Scy	}
553255332Scy	error = fb_ioctl(adp, FBIO_ADPINFO, &adp_info);
554255332Scy	if (error == 0)
555255332Scy	    bcopy(&adp_info, data, sizeof(old_video_adapter_info_t));
556255332Scy	return error;
557255332Scy
558255332Scy    case CONS_ADPINFO:		/* adapter information */
559255332Scy    case FBIO_ADPINFO:
560255332Scy	if (((video_adapter_info_t *)data)->va_index >= 0) {
561255332Scy	    adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index);
562255332Scy	    if (adp == NULL)
563255332Scy		return ENODEV;
564255332Scy	}
565255332Scy	return fb_ioctl(adp, FBIO_ADPINFO, data);
566255332Scy
567255332Scy    case CONS_GET:      	/* get current video mode */
568255332Scy    case FBIO_GETMODE:
569255332Scy	*(int *)data = scp->mode;
570255332Scy	return 0;
571145522Sdarrenr
572145522Sdarrenr#ifndef SC_NO_MODE_CHANGE
573145522Sdarrenr    case FBIO_SETMODE:		/* set video mode */
574145522Sdarrenr	if (!(adp->va_flags & V_ADP_MODECHANGE))
57553642Sguido 	    return ENODEV;
576255332Scy	info.vi_mode = *(int *)data;
577255332Scy	error = fb_ioctl(adp, FBIO_MODEINFO, &info);
578255332Scy	if (error)
579255332Scy	    return error;
580255332Scy	if (info.vi_flags & V_INFO_GRAPHICS)
58153642Sguido	    return sc_set_graphics_mode(scp, tp, *(int *)data);
58253642Sguido	else
583255332Scy	    return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0, 0);
58492685Sdarrenr#endif /* SC_NO_MODE_CHANGE */
58592685Sdarrenr
58692685Sdarrenr    case OLD_CONS_MODEINFO:	/* get mode information (old infterface) */
587255332Scy	info.vi_mode = ((old_video_info_t *)data)->vi_mode;
588255332Scy	error = fb_ioctl(adp, FBIO_MODEINFO, &info);
589255332Scy	if (error == 0)
590255332Scy	    bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t));
591255332Scy	return error;
592255332Scy
593255332Scy    case CONS_MODEINFO:		/* get mode information */
594255332Scy    case FBIO_MODEINFO:
595255332Scy	return fb_ioctl(adp, FBIO_MODEINFO, data);
596255332Scy
597255332Scy    case OLD_CONS_FINDMODE:	/* find a matching video mode (old interface) */
598255332Scy	bzero(&info, sizeof(info));
599255332Scy	bcopy((old_video_info_t *)data, &info, sizeof(old_video_info_t));
600145522Sdarrenr	error = fb_ioctl(adp, FBIO_FINDMODE, &info);
601145522Sdarrenr	if (error == 0)
602145522Sdarrenr	    bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t));
60360851Sdarrenr	return error;
604255332Scy
605255332Scy    case CONS_FINDMODE:		/* find a matching video mode */
606255332Scy    case FBIO_FINDMODE:
60760851Sdarrenr	return fb_ioctl(adp, FBIO_FINDMODE, data);
60860851Sdarrenr
609145522Sdarrenr#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
610145522Sdarrenr    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
611145522Sdarrenr    case _IO('c', 104):
612145522Sdarrenr	ival = IOCPARM_IVAL(data);
613145522Sdarrenr	data = (caddr_t)&ival;
61460851Sdarrenr	/* FALLTHROUGH */
615145522Sdarrenr#endif
616145522Sdarrenr    case CONS_SETWINORG:	/* set frame buffer window origin */
61760851Sdarrenr    case FBIO_SETWINORG:
61860851Sdarrenr	if (scp != scp->sc->cur_scp)
61960851Sdarrenr	    return ENODEV;	/* XXX */
62060851Sdarrenr	return fb_ioctl(adp, FBIO_SETWINORG, data);
62160851Sdarrenr
62260851Sdarrenr    case FBIO_GETWINORG:	/* get frame buffer window origin */
62360851Sdarrenr	if (scp != scp->sc->cur_scp)
62460851Sdarrenr	    return ENODEV;	/* XXX */
62560851Sdarrenr	return fb_ioctl(adp, FBIO_GETWINORG, data);
62660851Sdarrenr
62760851Sdarrenr    case FBIO_GETDISPSTART:
628145522Sdarrenr    case FBIO_SETDISPSTART:
629145522Sdarrenr    case FBIO_GETLINEWIDTH:
630255332Scy    case FBIO_SETLINEWIDTH:
631255332Scy	if (scp != scp->sc->cur_scp)
632255332Scy	    return ENODEV;	/* XXX */
633255332Scy	return fb_ioctl(adp, cmd, data);
634255332Scy
635255332Scy    case FBIO_GETPALETTE:
636255332Scy    case FBIO_SETPALETTE:
637255332Scy    case FBIOPUTCMAP:
638255332Scy    case FBIOGETCMAP:
639255332Scy    case FBIOGTYPE:
640255332Scy    case FBIOGATTR:
641255332Scy    case FBIOSVIDEO:
642255332Scy    case FBIOGVIDEO:
643255332Scy    case FBIOSCURSOR:
644145522Sdarrenr    case FBIOGCURSOR:
645145522Sdarrenr    case FBIOSCURPOS:
646145522Sdarrenr    case FBIOGCURPOS:
647145522Sdarrenr    case FBIOGCURMAX:
648145522Sdarrenr	if (scp != scp->sc->cur_scp)
649145522Sdarrenr	    return ENODEV;	/* XXX */
650255332Scy	return fb_ioctl(adp, cmd, data);
651255332Scy
652145522Sdarrenr    case FBIO_BLANK:
653255332Scy	if (scp != scp->sc->cur_scp)
654255332Scy	    return ENODEV;	/* XXX */
655145522Sdarrenr	return fb_ioctl(adp, cmd, data);
656255332Scy
657255332Scy#ifndef SC_NO_MODE_CHANGE
658255332Scy    /* generic text modes */
659255332Scy    case SW_TEXT_80x25:	case SW_TEXT_80x30:
660255332Scy    case SW_TEXT_80x43: case SW_TEXT_80x50:
661145522Sdarrenr    case SW_TEXT_80x60:
662145522Sdarrenr	/* FALLTHROUGH */
663170268Sdarrenr
664170268Sdarrenr    /* VGA TEXT MODES */
665170268Sdarrenr    case SW_VGA_C40x25:
666145522Sdarrenr    case SW_VGA_C80x25: case SW_VGA_M80x25:
667170268Sdarrenr    case SW_VGA_C80x30: case SW_VGA_M80x30:
668170268Sdarrenr    case SW_VGA_C80x50: case SW_VGA_M80x50:
669170268Sdarrenr    case SW_VGA_C80x60: case SW_VGA_M80x60:
670145522Sdarrenr    case SW_VGA_C90x25: case SW_VGA_M90x25:
671145522Sdarrenr    case SW_VGA_C90x30: case SW_VGA_M90x30:
672145522Sdarrenr    case SW_VGA_C90x43: case SW_VGA_M90x43:
673255332Scy    case SW_VGA_C90x50: case SW_VGA_M90x50:
674255332Scy    case SW_VGA_C90x60: case SW_VGA_M90x60:
675255332Scy    case SW_B40x25:     case SW_C40x25:
676255332Scy    case SW_B80x25:     case SW_C80x25:
677255332Scy    case SW_ENH_B40x25: case SW_ENH_C40x25:
678255332Scy    case SW_ENH_B80x25: case SW_ENH_C80x25:
679255332Scy    case SW_ENH_B80x43: case SW_ENH_C80x43:
680255332Scy    case SW_EGAMONO80x25:
681255332Scy
682255332Scy#ifdef PC98
683255332Scy    /* PC98 TEXT MODES */
684255332Scy    case SW_PC98_80x25:
685255332Scy    case SW_PC98_80x30:
686255332Scy#endif
687145522Sdarrenr	if (!(adp->va_flags & V_ADP_MODECHANGE))
688145522Sdarrenr 	    return ENODEV;
689145522Sdarrenr	return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0, 0);
69053642Sguido
691145522Sdarrenr    /* GRAPHICS MODES */
69253642Sguido    case SW_BG320:     case SW_BG640:
693255332Scy    case SW_CG320:     case SW_CG320_D:   case SW_CG640_E:
694255332Scy    case SW_CG640x350: case SW_ENH_CG640:
695255332Scy    case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
696255332Scy    case SW_VGA_MODEX:
697145522Sdarrenr#ifdef PC98
698255332Scy    /* PC98 GRAPHICS MODES */
699255332Scy    case SW_PC98_EGC640x400:	case SW_PC98_PEGC640x400:
700145522Sdarrenr    case SW_PC98_PEGC640x480:
701145522Sdarrenr#endif
702255332Scy	if (!(adp->va_flags & V_ADP_MODECHANGE))
703255332Scy	    return ENODEV;
704255332Scy	return sc_set_graphics_mode(scp, tp, cmd & 0xff);
705145522Sdarrenr#endif /* SC_NO_MODE_CHANGE */
706255332Scy
707255332Scy#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
70853642Sguido    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
709170268Sdarrenr    case _IO('K', 10):
710170268Sdarrenr	ival = IOCPARM_IVAL(data);
711170268Sdarrenr	data = (caddr_t)&ival;
712170268Sdarrenr	/* FALLTHROUGH */
713170268Sdarrenr#endif
714170268Sdarrenr    case KDSETMODE:     	/* set current mode of this (virtual) console */
715170268Sdarrenr	switch (*(int *)data) {
71653642Sguido	case KD_TEXT:   	/* switch to TEXT (known) mode */
71753642Sguido	    /*
71853642Sguido	     * If scp->mode is of graphics modes, we don't know which
71953642Sguido	     * text mode to switch back to...
72053642Sguido	     */
721145522Sdarrenr	    if (scp->status & GRAPHICS_MODE)
72253642Sguido		return EINVAL;
723145522Sdarrenr	    /* restore fonts & palette ! */
724255332Scy#if 0
725255332Scy#ifndef SC_NO_FONT_LOADING
72653642Sguido	    if (ISFONTAVAIL(adp->va_flags)
727255332Scy		&& !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
728255332Scy		/*
729255332Scy		 * FONT KLUDGE
730255332Scy		 * Don't load fonts for now... XXX
731145522Sdarrenr		 */
73253642Sguido		if (scp->sc->fonts_loaded & FONT_8)
733145522Sdarrenr		    sc_load_font(scp, 0, 8, 8, scp->sc->font_8, 0, 256);
734145522Sdarrenr		if (scp->sc->fonts_loaded & FONT_14)
735255332Scy		    sc_load_font(scp, 0, 14, 8, scp->sc->font_14, 0, 256);
736145522Sdarrenr		if (scp->sc->fonts_loaded & FONT_16)
737145522Sdarrenr		    sc_load_font(scp, 0, 16, 8, scp->sc->font_16, 0, 256);
738145522Sdarrenr	    }
73953642Sguido#endif /* SC_NO_FONT_LOADING */
740145522Sdarrenr#endif
741145522Sdarrenr
742145522Sdarrenr#ifndef SC_NO_PALETTE_LOADING
743145522Sdarrenr#ifdef SC_PIXEL_MODE
744145522Sdarrenr	    if ((adp->va_flags & V_ADP_DAC8) != 0)
745145522Sdarrenr		vidd_load_palette(adp, scp->sc->palette2);
746255332Scy	    else
74753642Sguido#endif
748145522Sdarrenr	    vidd_load_palette(adp, scp->sc->palette);
749145522Sdarrenr#endif
750255332Scy
75160851Sdarrenr#ifndef PC98
752255332Scy	    /* move hardware cursor out of the way */
75360851Sdarrenr	    vidd_set_hw_cursor(adp, -1, -1);
754255332Scy#endif
755255332Scy
756255332Scy	    /* FALLTHROUGH */
757255332Scy
758255332Scy	case KD_TEXT1:  	/* switch to TEXT (known) mode */
759145522Sdarrenr	    /*
760145522Sdarrenr	     * If scp->mode is of graphics modes, we don't know which
761145522Sdarrenr	     * text/pixel mode to switch back to...
762145522Sdarrenr	     */
763255332Scy	    if (scp->status & GRAPHICS_MODE)
764145522Sdarrenr		return EINVAL;
765255332Scy	    s = spltty();
766255332Scy	    if ((error = sc_clean_up(scp))) {
767255332Scy		splx(s);
768255332Scy		return error;
769255332Scy	    }
770255332Scy#ifndef PC98
771255332Scy	    scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
772255332Scy	    splx(s);
773255332Scy	    /* no restore fonts & palette */
774255332Scy	    if (scp == scp->sc->cur_scp)
77553642Sguido		set_mode(scp);
77653642Sguido	    sc_clear_screen(scp);
777255332Scy	    scp->status &= ~UNKNOWN_MODE;
778145522Sdarrenr#else /* PC98 */
779145522Sdarrenr	    scp->status &= ~UNKNOWN_MODE;
780145522Sdarrenr	    /* no restore fonts & palette */
781145522Sdarrenr	    if (scp == scp->sc->cur_scp)
782145522Sdarrenr		set_mode(scp);
783145522Sdarrenr	    sc_clear_screen(scp);
784145522Sdarrenr	    splx(s);
785145522Sdarrenr#endif /* PC98 */
786145522Sdarrenr	    return 0;
787145522Sdarrenr
788145522Sdarrenr#ifdef SC_PIXEL_MODE
789145522Sdarrenr	case KD_PIXEL:		/* pixel (raster) display */
790145522Sdarrenr	    if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
79153642Sguido		return EINVAL;
792145522Sdarrenr	    if (scp->status & GRAPHICS_MODE)
79353642Sguido		return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
794145522Sdarrenr					 scp->font_size, scp->font_width);
79553642Sguido	    s = spltty();
796145522Sdarrenr	    if ((error = sc_clean_up(scp))) {
79760851Sdarrenr		splx(s);
79860851Sdarrenr		return error;
79960851Sdarrenr	    }
80060851Sdarrenr	    scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
80160851Sdarrenr	    splx(s);
80260851Sdarrenr	    if (scp == scp->sc->cur_scp) {
80360851Sdarrenr		set_mode(scp);
80460851Sdarrenr#ifndef SC_NO_PALETTE_LOADING
80560851Sdarrenr		if ((adp->va_flags & V_ADP_DAC8) != 0)
806255332Scy		    vidd_load_palette(adp, scp->sc->palette2);
807145522Sdarrenr		else
80860851Sdarrenr		    vidd_load_palette(adp, scp->sc->palette);
809255332Scy#endif
810145522Sdarrenr	    }
81160851Sdarrenr	    sc_clear_screen(scp);
812255332Scy	    scp->status &= ~UNKNOWN_MODE;
813145522Sdarrenr	    return 0;
81460851Sdarrenr#endif /* SC_PIXEL_MODE */
815255332Scy
816145522Sdarrenr	case KD_GRAPHICS:	/* switch to GRAPHICS (unknown) mode */
817145522Sdarrenr	    s = spltty();
818145522Sdarrenr	    if ((error = sc_clean_up(scp))) {
819170268Sdarrenr		splx(s);
820170268Sdarrenr		return error;
821170268Sdarrenr	    }
822170268Sdarrenr	    scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
823145522Sdarrenr	    splx(s);
824145522Sdarrenr#ifdef PC98
825170268Sdarrenr	    if (scp == scp->sc->cur_scp)
826170268Sdarrenr		set_mode(scp);
827145522Sdarrenr#endif
828145522Sdarrenr	    return 0;
829145522Sdarrenr
830145522Sdarrenr	default:
831145522Sdarrenr	    return EINVAL;
832145522Sdarrenr	}
833145522Sdarrenr	/* NOT REACHED */
834145522Sdarrenr
835145522Sdarrenr#ifdef SC_PIXEL_MODE
836145522Sdarrenr    case KDRASTER:		/* set pixel (raster) display mode */
837255332Scy	if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
838255332Scy	    return ENODEV;
839145522Sdarrenr	return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
840145522Sdarrenr				 ((int *)data)[2], 8);
84192685Sdarrenr#endif /* SC_PIXEL_MODE */
84292685Sdarrenr
843145522Sdarrenr    case KDGETMODE:     	/* get current mode of this (virtual) console */
844145522Sdarrenr	/*
84553642Sguido	 * From the user program's point of view, KD_PIXEL is the same
846145522Sdarrenr	 * as KD_TEXT...
84753642Sguido	 */
848145522Sdarrenr	*data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
849145522Sdarrenr	return 0;
850255332Scy
851145522Sdarrenr#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
852145522Sdarrenr    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
853145522Sdarrenr    case _IO('K', 13):
85453642Sguido	ival = IOCPARM_IVAL(data);
85553642Sguido	data = (caddr_t)&ival;
85653642Sguido	/* FALLTHROUGH */
85753642Sguido#endif
858145522Sdarrenr    case KDSBORDER:     	/* set border color of this (virtual) console */
859145522Sdarrenr	scp->border = *(int *)data;
860145522Sdarrenr	if (scp == scp->sc->cur_scp)
861145522Sdarrenr	    sc_set_border(scp, scp->border);
862255332Scy	return 0;
863255332Scy    }
864145522Sdarrenr
86553642Sguido    return ENOIOCTL;
86653642Sguido}
86753642Sguido
868145522Sdarrenrstatic LIST_HEAD(, sc_renderer) sc_rndr_list =
869145522Sdarrenr	LIST_HEAD_INITIALIZER(sc_rndr_list);
870145522Sdarrenr
871145522Sdarrenrint
872145522Sdarrenrsc_render_add(sc_renderer_t *rndr)
873145522Sdarrenr{
874145522Sdarrenr	LIST_INSERT_HEAD(&sc_rndr_list, rndr, link);
875145522Sdarrenr	return 0;
876145522Sdarrenr}
877145522Sdarrenr
878145522Sdarrenrint
879145522Sdarrenrsc_render_remove(sc_renderer_t *rndr)
880145522Sdarrenr{
881145522Sdarrenr	/*
882145522Sdarrenr	LIST_REMOVE(rndr, link);
88353642Sguido	*/
884255332Scy	return EBUSY;	/* XXX */
885145522Sdarrenr}
886145522Sdarrenr
887145522Sdarrenrsc_rndr_sw_t
888145522Sdarrenr*sc_render_match(scr_stat *scp, char *name, int mode)
889145522Sdarrenr{
890255332Scy	const sc_renderer_t **list;
891255332Scy	const sc_renderer_t *p;
892145522Sdarrenr
893145522Sdarrenr	if (!LIST_EMPTY(&sc_rndr_list)) {
894145522Sdarrenr		LIST_FOREACH(p, &sc_rndr_list, link) {
895145522Sdarrenr			if ((strcmp(p->name, name) == 0)
896145522Sdarrenr				&& (mode == p->mode)) {
89753642Sguido				scp->status &=
89853642Sguido				    ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
899145522Sdarrenr				return p->rndrsw;
900145522Sdarrenr			}
901145522Sdarrenr		}
902145522Sdarrenr	} else {
903145522Sdarrenr		SET_FOREACH(list, scrndr_set) {
904145522Sdarrenr			p = *list;
905255332Scy			if ((strcmp(p->name, name) == 0)
906145522Sdarrenr				&& (mode == p->mode)) {
907145522Sdarrenr				scp->status &=
90853642Sguido				    ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
90953642Sguido				return p->rndrsw;
91053642Sguido			}
91153642Sguido		}
91253642Sguido	}
91353642Sguido
91453642Sguido	return NULL;
91553642Sguido}
91653642Sguido