Scrap PC98 support.
[dragonfly.git] / sys / dev / misc / syscons / scvidctl.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3 * All rights reserved.
4 *
2a85d763
MD
5 * This code is derived from software contributed to The DragonFly Project
6 * by Sascha Wildner <saw@online.de>
7 *
984263bc
MD
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer as
13 * the first lines of this file unmodified.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $FreeBSD: src/sys/dev/syscons/scvidctl.c,v 1.19.2.2 2000/05/05 09:16:08 nyan Exp $
7aa7bdf5 30 * $DragonFly: src/sys/dev/misc/syscons/scvidctl.c,v 1.8 2005/02/13 03:02:25 swildner Exp $
984263bc
MD
31 */
32
33#include "opt_syscons.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/signalvar.h>
39#include <sys/tty.h>
40#include <sys/kernel.h>
41
42#include <machine/console.h>
43
1f2de5d4
MD
44#include <dev/video/fb/fbreg.h>
45#include "syscons.h"
984263bc 46
dc62b251
MD
47SET_DECLARE(scrndr_set, const sc_renderer_t);
48
984263bc
MD
49int
50sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
51 int fontsize)
52{
53 video_info_t info;
54 u_char *font;
55 int prev_ysize;
56 int error;
57 int s;
58
59 if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info))
60 return ENODEV;
61
62 /* adjust argument values */
63 if (fontsize <= 0)
64 fontsize = info.vi_cheight;
65 if (fontsize < 14) {
66 fontsize = 8;
67#ifndef SC_NO_FONT_LOADING
68 if (!(scp->sc->fonts_loaded & FONT_8))
69 return EINVAL;
70 font = scp->sc->font_8;
71#else
72 font = NULL;
73#endif
74 } else if (fontsize >= 16) {
75 fontsize = 16;
76#ifndef SC_NO_FONT_LOADING
77 if (!(scp->sc->fonts_loaded & FONT_16))
78 return EINVAL;
79 font = scp->sc->font_16;
80#else
81 font = NULL;
82#endif
83 } else {
84 fontsize = 14;
85#ifndef SC_NO_FONT_LOADING
86 if (!(scp->sc->fonts_loaded & FONT_14))
87 return EINVAL;
88 font = scp->sc->font_14;
89#else
90 font = NULL;
91#endif
92 }
93 if ((xsize <= 0) || (xsize > info.vi_width))
94 xsize = info.vi_width;
95 if ((ysize <= 0) || (ysize > info.vi_height))
96 ysize = info.vi_height;
97
98 /* stop screen saver, etc */
99 s = spltty();
100 if ((error = sc_clean_up(scp))) {
101 splx(s);
102 return error;
103 }
104
105 if (sc_render_match(scp, scp->sc->adp->va_name, 0) == NULL) {
106 splx(s);
107 return ENODEV;
108 }
109
110 /* set up scp */
111#ifndef SC_NO_HISTORY
112 if (scp->history != NULL)
113 sc_hist_save(scp);
114#endif
115 prev_ysize = scp->ysize;
116 /*
117 * This is a kludge to fend off scrn_update() while we
118 * muck around with scp. XXX
119 */
120 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
121 scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE | MOUSE_VISIBLE);
122 scp->mode = mode;
123 scp->xsize = xsize;
124 scp->ysize = ysize;
125 scp->xoff = 0;
126 scp->yoff = 0;
127 scp->xpixel = scp->xsize*8;
128 scp->ypixel = scp->ysize*fontsize;
129 scp->font = font;
130 scp->font_size = fontsize;
131
132 /* allocate buffers */
133 sc_alloc_scr_buffer(scp, TRUE, TRUE);
134 sc_init_emulator(scp, NULL);
135#ifndef SC_NO_CUTPASTE
136 sc_alloc_cut_buffer(scp, FALSE);
137#endif
138#ifndef SC_NO_HISTORY
139 sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
140#endif
141 splx(s);
142
143 if (scp == scp->sc->cur_scp)
144 set_mode(scp);
145 scp->status &= ~UNKNOWN_MODE;
146
147 if (tp == NULL)
148 return 0;
149 DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n",
150 tp->t_winsize.ws_col, tp->t_winsize.ws_row, scp->xsize, scp->ysize));
151 if (tp->t_winsize.ws_col != scp->xsize
152 || tp->t_winsize.ws_row != scp->ysize) {
153 tp->t_winsize.ws_col = scp->xsize;
154 tp->t_winsize.ws_row = scp->ysize;
155 pgsignal(tp->t_pgrp, SIGWINCH, 1);
156 }
157
158 return 0;
159}
160
161int
162sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
163{
164#ifdef SC_NO_MODE_CHANGE
165 return ENODEV;
166#else
167 video_info_t info;
168 int error;
169 int s;
170
171 if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info))
172 return ENODEV;
173
174 /* stop screen saver, etc */
175 s = spltty();
176 if ((error = sc_clean_up(scp))) {
177 splx(s);
178 return error;
179 }
180
181 if (sc_render_match(scp, scp->sc->adp->va_name, GRAPHICS_MODE) == NULL) {
182 splx(s);
183 return ENODEV;
184 }
185
186 /* set up scp */
187 scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE | MOUSE_HIDDEN);
188 scp->status &= ~(PIXEL_MODE | MOUSE_VISIBLE);
189 scp->mode = mode;
190 /*
191 * Don't change xsize and ysize; preserve the previous vty
192 * and history buffers.
193 */
194 scp->xoff = 0;
195 scp->yoff = 0;
196 scp->xpixel = info.vi_width;
197 scp->ypixel = info.vi_height;
198 scp->font = NULL;
199 scp->font_size = 0;
200#ifndef SC_NO_SYSMOUSE
201 /* move the mouse cursor at the center of the screen */
202 sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
203#endif
204 sc_init_emulator(scp, NULL);
205 splx(s);
206
207 if (scp == scp->sc->cur_scp)
208 set_mode(scp);
209 /* clear_graphics();*/
210 scp->status &= ~UNKNOWN_MODE;
211
212 if (tp == NULL)
213 return 0;
214 if (tp->t_winsize.ws_xpixel != scp->xpixel
215 || tp->t_winsize.ws_ypixel != scp->ypixel) {
216 tp->t_winsize.ws_xpixel = scp->xpixel;
217 tp->t_winsize.ws_ypixel = scp->ypixel;
218 pgsignal(tp->t_pgrp, SIGWINCH, 1);
219 }
220
221 return 0;
222#endif /* SC_NO_MODE_CHANGE */
223}
224
225int
226sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
227 int fontsize)
228{
229#ifndef SC_PIXEL_MODE
230 return ENODEV;
231#else
232 video_info_t info;
233 u_char *font;
234 int prev_ysize;
235 int error;
236 int s;
237
238 if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info))
239 return ENODEV; /* this shouldn't happen */
240
241 /* adjust argument values */
242 if (fontsize <= 0)
243 fontsize = info.vi_cheight;
244 if (fontsize < 14) {
245 fontsize = 8;
246#ifndef SC_NO_FONT_LOADING
247 if (!(scp->sc->fonts_loaded & FONT_8))
248 return EINVAL;
249 font = scp->sc->font_8;
250#else
251 font = NULL;
252#endif
253 } else if (fontsize >= 16) {
254 fontsize = 16;
255#ifndef SC_NO_FONT_LOADING
256 if (!(scp->sc->fonts_loaded & FONT_16))
257 return EINVAL;
258 font = scp->sc->font_16;
259#else
260 font = NULL;
261#endif
262 } else {
263 fontsize = 14;
264#ifndef SC_NO_FONT_LOADING
265 if (!(scp->sc->fonts_loaded & FONT_14))
266 return EINVAL;
267 font = scp->sc->font_14;
268#else
269 font = NULL;
270#endif
271 }
272 if (xsize <= 0)
273 xsize = info.vi_width/8;
274 if (ysize <= 0)
275 ysize = info.vi_height/fontsize;
276
277 if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
278 return EINVAL;
279
984263bc 280 /*
2a85d763
MD
281 * We currently support the following graphic modes:
282 *
283 * - 4 bpp planar modes whose memory size does not exceed 64K
284 * - 15, 16, 24 and 32 bpp linear modes
984263bc 285 */
2a85d763
MD
286
287 if (info.vi_mem_model == V_INFO_MM_PLANAR) {
288 if (info.vi_planes != 4)
289 return ENODEV;
290
291 /*
292 * A memory size >64K requires bank switching to access the entire
293 * screen. XXX
294 */
295
296 if (info.vi_width * info.vi_height / 8 > info.vi_window_size)
297 return ENODEV;
298 } else if (info.vi_mem_model == V_INFO_MM_DIRECT) {
299 if ((info.vi_depth != 15) && (info.vi_depth != 16) &&
300 (info.vi_depth != 24) && (info.vi_depth != 32))
301 return ENODEV;
302 } else
984263bc
MD
303 return ENODEV;
304
305 /* stop screen saver, etc */
306 s = spltty();
307 if ((error = sc_clean_up(scp))) {
308 splx(s);
309 return error;
310 }
311
312 if (sc_render_match(scp, scp->sc->adp->va_name, PIXEL_MODE) == NULL) {
313 splx(s);
314 return ENODEV;
315 }
316
317#if 0
318 if (scp->tsw)
319 (*scp->tsw->te_term)(scp, scp->ts);
320 scp->tsw = NULL;
321 scp->ts = NULL;
322#endif
323
324 /* set up scp */
325#ifndef SC_NO_HISTORY
326 if (scp->history != NULL)
327 sc_hist_save(scp);
328#endif
329 prev_ysize = scp->ysize;
330 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
331 scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
332 scp->xsize = xsize;
333 scp->ysize = ysize;
334 scp->xoff = (scp->xpixel/8 - xsize)/2;
335 scp->yoff = (scp->ypixel/fontsize - ysize)/2;
336 scp->font = font;
337 scp->font_size = fontsize;
338
339 /* allocate buffers */
340 sc_alloc_scr_buffer(scp, TRUE, TRUE);
341 sc_init_emulator(scp, NULL);
342#ifndef SC_NO_CUTPASTE
343 sc_alloc_cut_buffer(scp, FALSE);
344#endif
345#ifndef SC_NO_HISTORY
346 sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
347#endif
348 splx(s);
349
350 if (scp == scp->sc->cur_scp) {
351 sc_set_border(scp, scp->border);
352 sc_set_cursor_image(scp);
353 }
354
355 scp->status &= ~UNKNOWN_MODE;
356
357 if (tp == NULL)
358 return 0;
359 if (tp->t_winsize.ws_col != scp->xsize
360 || tp->t_winsize.ws_row != scp->ysize) {
361 tp->t_winsize.ws_col = scp->xsize;
362 tp->t_winsize.ws_row = scp->ysize;
363 pgsignal(tp->t_pgrp, SIGWINCH, 1);
364 }
365
366 return 0;
367#endif /* SC_PIXEL_MODE */
368}
369
370#define fb_ioctl(a, c, d) \
371 (((a) == NULL) ? ENODEV : \
372 (*vidsw[(a)->va_index]->ioctl)((a), (c), (caddr_t)(d)))
373
374int
41c20dac 375sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread *td)
984263bc
MD
376{
377 scr_stat *scp;
378 video_adapter_t *adp;
379 video_info_t info;
984263bc
MD
380 int error;
381 int s;
382
383 scp = SC_STAT(tp->t_dev);
384 if (scp == NULL) /* tp == SC_MOUSE */
385 return ENOIOCTL;
386 adp = scp->sc->adp;
387 if (adp == NULL) /* shouldn't happen??? */
388 return ENODEV;
389
390 switch (cmd) {
391
392 case CONS_CURRENTADP: /* get current adapter index */
393 case FBIO_ADAPTER:
394 return fb_ioctl(adp, FBIO_ADAPTER, data);
395
396 case CONS_CURRENT: /* get current adapter type */
397 case FBIO_ADPTYPE:
398 return fb_ioctl(adp, FBIO_ADPTYPE, data);
399
984263bc
MD
400 case CONS_ADPINFO: /* adapter information */
401 case FBIO_ADPINFO:
402 if (((video_adapter_info_t *)data)->va_index >= 0) {
403 adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index);
404 if (adp == NULL)
405 return ENODEV;
406 }
407 return fb_ioctl(adp, FBIO_ADPINFO, data);
408
409 case CONS_GET: /* get current video mode */
410 case FBIO_GETMODE:
411 *(int *)data = scp->mode;
412 return 0;
413
414#ifndef SC_NO_MODE_CHANGE
415 case FBIO_SETMODE: /* set video mode */
416 if (!(adp->va_flags & V_ADP_MODECHANGE))
417 return ENODEV;
418 info.vi_mode = *(int *)data;
419 error = fb_ioctl(adp, FBIO_MODEINFO, &info);
420 if (error)
421 return error;
422 if (info.vi_flags & V_INFO_GRAPHICS)
423 return sc_set_graphics_mode(scp, tp, *(int *)data);
424 else
425 return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0);
426#endif /* SC_NO_MODE_CHANGE */
427
984263bc
MD
428 case CONS_MODEINFO: /* get mode information */
429 case FBIO_MODEINFO:
430 return fb_ioctl(adp, FBIO_MODEINFO, data);
431
984263bc
MD
432 case CONS_FINDMODE: /* find a matching video mode */
433 case FBIO_FINDMODE:
434 return fb_ioctl(adp, FBIO_FINDMODE, data);
435
436 case CONS_SETWINORG: /* set frame buffer window origin */
437 case FBIO_SETWINORG:
438 if (scp != scp->sc->cur_scp)
439 return ENODEV; /* XXX */
440 return fb_ioctl(adp, FBIO_SETWINORG, data);
441
442 case FBIO_GETWINORG: /* get frame buffer window origin */
443 if (scp != scp->sc->cur_scp)
444 return ENODEV; /* XXX */
445 return fb_ioctl(adp, FBIO_GETWINORG, data);
446
447 case FBIO_GETDISPSTART:
448 case FBIO_SETDISPSTART:
449 case FBIO_GETLINEWIDTH:
450 case FBIO_SETLINEWIDTH:
451 if (scp != scp->sc->cur_scp)
452 return ENODEV; /* XXX */
453 return fb_ioctl(adp, cmd, data);
454
455 case FBIO_GETPALETTE:
456 case FBIO_SETPALETTE:
457 case FBIOPUTCMAP:
458 case FBIOGETCMAP:
459 case FBIOGTYPE:
460 case FBIOGATTR:
461 case FBIOSVIDEO:
462 case FBIOGVIDEO:
463 case FBIOSCURSOR:
464 case FBIOGCURSOR:
465 case FBIOSCURPOS:
466 case FBIOGCURPOS:
467 case FBIOGCURMAX:
468 if (scp != scp->sc->cur_scp)
469 return ENODEV; /* XXX */
470 return fb_ioctl(adp, cmd, data);
471
472#ifndef SC_NO_MODE_CHANGE
473 /* generic text modes */
474 case SW_TEXT_80x25: case SW_TEXT_80x30:
475 case SW_TEXT_80x43: case SW_TEXT_80x50:
476 case SW_TEXT_80x60:
477 /* FALL THROUGH */
478
479 /* VGA TEXT MODES */
480 case SW_VGA_C40x25:
481 case SW_VGA_C80x25: case SW_VGA_M80x25:
482 case SW_VGA_C80x30: case SW_VGA_M80x30:
483 case SW_VGA_C80x50: case SW_VGA_M80x50:
484 case SW_VGA_C80x60: case SW_VGA_M80x60:
485 case SW_VGA_C90x25: case SW_VGA_M90x25:
486 case SW_VGA_C90x30: case SW_VGA_M90x30:
487 case SW_VGA_C90x43: case SW_VGA_M90x43:
488 case SW_VGA_C90x50: case SW_VGA_M90x50:
489 case SW_VGA_C90x60: case SW_VGA_M90x60:
490 case SW_B40x25: case SW_C40x25:
491 case SW_B80x25: case SW_C80x25:
492 case SW_ENH_B40x25: case SW_ENH_C40x25:
493 case SW_ENH_B80x25: case SW_ENH_C80x25:
494 case SW_ENH_B80x43: case SW_ENH_C80x43:
495 case SW_EGAMONO80x25:
984263bc
MD
496 if (!(adp->va_flags & V_ADP_MODECHANGE))
497 return ENODEV;
498 return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
499
500 /* GRAPHICS MODES */
501 case SW_BG320: case SW_BG640:
502 case SW_CG320: case SW_CG320_D: case SW_CG640_E:
503 case SW_CG640x350: case SW_ENH_CG640:
504 case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
505 case SW_VGA_MODEX:
984263bc
MD
506 if (!(adp->va_flags & V_ADP_MODECHANGE))
507 return ENODEV;
508 return sc_set_graphics_mode(scp, tp, cmd & 0xff);
509#endif /* SC_NO_MODE_CHANGE */
510
511 case KDSETMODE: /* set current mode of this (virtual) console */
512 switch (*(int *)data) {
513 case KD_TEXT: /* switch to TEXT (known) mode */
514 /*
515 * If scp->mode is of graphics modes, we don't know which
516 * text mode to switch back to...
517 */
518 if (scp->status & GRAPHICS_MODE)
519 return EINVAL;
520 /* restore fonts & palette ! */
521#if 0
522#ifndef SC_NO_FONT_LOADING
523 if (ISFONTAVAIL(adp->va_flags)
524 && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
525 /*
526 * FONT KLUDGE
527 * Don't load fonts for now... XXX
528 */
529 if (scp->sc->fonts_loaded & FONT_8)
530 sc_load_font(scp, 0, 8, scp->sc->font_8, 0, 256);
531 if (scp->sc->fonts_loaded & FONT_14)
532 sc_load_font(scp, 0, 14, scp->sc->font_14, 0, 256);
533 if (scp->sc->fonts_loaded & FONT_16)
534 sc_load_font(scp, 0, 16, scp->sc->font_16, 0, 256);
535 }
536#endif /* SC_NO_FONT_LOADING */
537#endif
538
539#ifndef SC_NO_PALETTE_LOADING
540 load_palette(adp, scp->sc->palette);
541#endif
542
984263bc
MD
543 /* move hardware cursor out of the way */
544 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
984263bc
MD
545 /* FALL THROUGH */
546
547 case KD_TEXT1: /* switch to TEXT (known) mode */
548 /*
549 * If scp->mode is of graphics modes, we don't know which
550 * text/pixel mode to switch back to...
551 */
552 if (scp->status & GRAPHICS_MODE)
553 return EINVAL;
554 s = spltty();
555 if ((error = sc_clean_up(scp))) {
556 splx(s);
557 return error;
558 }
984263bc
MD
559 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
560 splx(s);
561 /* no restore fonts & palette */
562 if (scp == scp->sc->cur_scp)
563 set_mode(scp);
564 sc_clear_screen(scp);
565 scp->status &= ~UNKNOWN_MODE;
984263bc
MD
566 return 0;
567
568#ifdef SC_PIXEL_MODE
569 case KD_PIXEL: /* pixel (raster) display */
570 if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
571 return EINVAL;
572 if (scp->status & GRAPHICS_MODE)
573 return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
574 scp->font_size);
575 s = spltty();
576 if ((error = sc_clean_up(scp))) {
577 splx(s);
578 return error;
579 }
580 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
581 splx(s);
582 if (scp == scp->sc->cur_scp) {
583 set_mode(scp);
584#ifndef SC_NO_PALETTE_LOADING
585 load_palette(adp, scp->sc->palette);
586#endif
587 }
588 sc_clear_screen(scp);
589 scp->status &= ~UNKNOWN_MODE;
590 return 0;
591#endif /* SC_PIXEL_MODE */
592
593 case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
594 s = spltty();
595 if ((error = sc_clean_up(scp))) {
596 splx(s);
597 return error;
598 }
599 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
600 splx(s);
984263bc
MD
601 return 0;
602
603 default:
604 return EINVAL;
605 }
606 /* NOT REACHED */
607
608#ifdef SC_PIXEL_MODE
609 case KDRASTER: /* set pixel (raster) display mode */
610 if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
611 return ENODEV;
612 return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
613 ((int *)data)[2]);
614#endif /* SC_PIXEL_MODE */
615
616 case KDGETMODE: /* get current mode of this (virtual) console */
617 /*
618 * From the user program's point of view, KD_PIXEL is the same
619 * as KD_TEXT...
620 */
621 *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
622 return 0;
623
624 case KDSBORDER: /* set border color of this (virtual) console */
625 scp->border = *data;
626 if (scp == scp->sc->cur_scp)
627 sc_set_border(scp, scp->border);
628 return 0;
629 }
630
631 return ENOIOCTL;
632}
633
634static LIST_HEAD(, sc_renderer) sc_rndr_list =
635 LIST_HEAD_INITIALIZER(sc_rndr_list);
636
637int
638sc_render_add(sc_renderer_t *rndr)
639{
640 LIST_INSERT_HEAD(&sc_rndr_list, rndr, link);
641 return 0;
642}
643
644int
645sc_render_remove(sc_renderer_t *rndr)
646{
647 /*
648 LIST_REMOVE(rndr, link);
649 */
650 return EBUSY; /* XXX */
651}
652
653sc_rndr_sw_t
654*sc_render_match(scr_stat *scp, char *name, int mode)
655{
656 const sc_renderer_t **list;
657 const sc_renderer_t *p;
658
659 if (!LIST_EMPTY(&sc_rndr_list)) {
660 LIST_FOREACH(p, &sc_rndr_list, link) {
661 if ((strcmp(p->name, name) == 0)
662 && (mode == p->mode)) {
663 scp->status &=
664 ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
665 return p->rndrsw;
666 }
667 }
668 } else {
dc62b251
MD
669 SET_FOREACH(list, scrndr_set) {
670 p = *list;
984263bc
MD
671 if ((strcmp(p->name, name) == 0)
672 && (mode == p->mode)) {
673 scp->status &=
674 ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
675 return p->rndrsw;
676 }
677 }
678 }
679
680 return NULL;
681}