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