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: src/sys/dev/syscons/scvidctl.c,v 1.19.2.2 2000/05/05 09:16:08 nyan Exp $ 27 * $DragonFly: src/sys/dev/misc/syscons/scvidctl.c,v 1.5 2003/11/10 06:12:06 dillon Exp $ 28 */ 29 30 #include "opt_syscons.h" 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/conf.h> 35 #include <sys/signalvar.h> 36 #include <sys/tty.h> 37 #include <sys/kernel.h> 38 39 #include <machine/console.h> 40 41 #include <dev/video/fb/fbreg.h> 42 #include "syscons.h" 43 44 SET_DECLARE(scrndr_set, const sc_renderer_t); 45 46 /* for compatibility with previous versions */ 47 /* 3.0-RELEASE used the following structure */ 48 typedef 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 */ 76 typedef 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 */ 101 typedef 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 126 int 127 sc_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 | MOUSE_HIDDEN; 198 scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE | MOUSE_VISIBLE); 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 238 int 239 sc_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 | MOUSE_HIDDEN); 265 scp->status &= ~(PIXEL_MODE | MOUSE_VISIBLE); 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 = 0; 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 302 int 303 sc_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) 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 | MOUSE_HIDDEN); 395 scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE); 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 438 int 439 sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread *td) 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 #ifdef PC98 626 /* PC98 GRAPHICS MODES */ 627 case SW_PC98_EGC640x400: case SW_PC98_PEGC640x400: 628 case SW_PC98_PEGC640x480: 629 #endif 630 if (!(adp->va_flags & V_ADP_MODECHANGE)) 631 return ENODEV; 632 return sc_set_graphics_mode(scp, tp, cmd & 0xff); 633 #endif /* SC_NO_MODE_CHANGE */ 634 635 case KDSETMODE: /* set current mode of this (virtual) console */ 636 switch (*(int *)data) { 637 case KD_TEXT: /* switch to TEXT (known) mode */ 638 /* 639 * If scp->mode is of graphics modes, we don't know which 640 * text mode to switch back to... 641 */ 642 if (scp->status & GRAPHICS_MODE) 643 return EINVAL; 644 /* restore fonts & palette ! */ 645 #if 0 646 #ifndef SC_NO_FONT_LOADING 647 if (ISFONTAVAIL(adp->va_flags) 648 && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) 649 /* 650 * FONT KLUDGE 651 * Don't load fonts for now... XXX 652 */ 653 if (scp->sc->fonts_loaded & FONT_8) 654 sc_load_font(scp, 0, 8, scp->sc->font_8, 0, 256); 655 if (scp->sc->fonts_loaded & FONT_14) 656 sc_load_font(scp, 0, 14, scp->sc->font_14, 0, 256); 657 if (scp->sc->fonts_loaded & FONT_16) 658 sc_load_font(scp, 0, 16, scp->sc->font_16, 0, 256); 659 } 660 #endif /* SC_NO_FONT_LOADING */ 661 #endif 662 663 #ifndef SC_NO_PALETTE_LOADING 664 load_palette(adp, scp->sc->palette); 665 #endif 666 667 #ifndef PC98 668 /* move hardware cursor out of the way */ 669 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); 670 #endif 671 672 /* FALL THROUGH */ 673 674 case KD_TEXT1: /* switch to TEXT (known) mode */ 675 /* 676 * If scp->mode is of graphics modes, we don't know which 677 * text/pixel mode to switch back to... 678 */ 679 if (scp->status & GRAPHICS_MODE) 680 return EINVAL; 681 s = spltty(); 682 if ((error = sc_clean_up(scp))) { 683 splx(s); 684 return error; 685 } 686 #ifndef PC98 687 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 688 splx(s); 689 /* no restore fonts & palette */ 690 if (scp == scp->sc->cur_scp) 691 set_mode(scp); 692 sc_clear_screen(scp); 693 scp->status &= ~UNKNOWN_MODE; 694 #else /* PC98 */ 695 scp->status &= ~UNKNOWN_MODE; 696 /* no restore fonts & palette */ 697 if (scp == scp->sc->cur_scp) 698 set_mode(scp); 699 sc_clear_screen(scp); 700 splx(s); 701 #endif /* PC98 */ 702 return 0; 703 704 #ifdef SC_PIXEL_MODE 705 case KD_PIXEL: /* pixel (raster) display */ 706 if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) 707 return EINVAL; 708 if (scp->status & GRAPHICS_MODE) 709 return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, 710 scp->font_size); 711 s = spltty(); 712 if ((error = sc_clean_up(scp))) { 713 splx(s); 714 return error; 715 } 716 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 717 splx(s); 718 if (scp == scp->sc->cur_scp) { 719 set_mode(scp); 720 #ifndef SC_NO_PALETTE_LOADING 721 load_palette(adp, scp->sc->palette); 722 #endif 723 } 724 sc_clear_screen(scp); 725 scp->status &= ~UNKNOWN_MODE; 726 return 0; 727 #endif /* SC_PIXEL_MODE */ 728 729 case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ 730 s = spltty(); 731 if ((error = sc_clean_up(scp))) { 732 splx(s); 733 return error; 734 } 735 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 736 splx(s); 737 #ifdef PC98 738 if (scp == scp->sc->cur_scp) 739 set_mode(scp); 740 #endif 741 return 0; 742 743 default: 744 return EINVAL; 745 } 746 /* NOT REACHED */ 747 748 #ifdef SC_PIXEL_MODE 749 case KDRASTER: /* set pixel (raster) display mode */ 750 if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) 751 return ENODEV; 752 return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], 753 ((int *)data)[2]); 754 #endif /* SC_PIXEL_MODE */ 755 756 case KDGETMODE: /* get current mode of this (virtual) console */ 757 /* 758 * From the user program's point of view, KD_PIXEL is the same 759 * as KD_TEXT... 760 */ 761 *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; 762 return 0; 763 764 case KDSBORDER: /* set border color of this (virtual) console */ 765 scp->border = *data; 766 if (scp == scp->sc->cur_scp) 767 sc_set_border(scp, scp->border); 768 return 0; 769 } 770 771 return ENOIOCTL; 772 } 773 774 static LIST_HEAD(, sc_renderer) sc_rndr_list = 775 LIST_HEAD_INITIALIZER(sc_rndr_list); 776 777 int 778 sc_render_add(sc_renderer_t *rndr) 779 { 780 LIST_INSERT_HEAD(&sc_rndr_list, rndr, link); 781 return 0; 782 } 783 784 int 785 sc_render_remove(sc_renderer_t *rndr) 786 { 787 /* 788 LIST_REMOVE(rndr, link); 789 */ 790 return EBUSY; /* XXX */ 791 } 792 793 sc_rndr_sw_t 794 *sc_render_match(scr_stat *scp, char *name, int mode) 795 { 796 const sc_renderer_t **list; 797 const sc_renderer_t *p; 798 799 if (!LIST_EMPTY(&sc_rndr_list)) { 800 LIST_FOREACH(p, &sc_rndr_list, link) { 801 if ((strcmp(p->name, name) == 0) 802 && (mode == p->mode)) { 803 scp->status &= 804 ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 805 return p->rndrsw; 806 } 807 } 808 } else { 809 SET_FOREACH(list, scrndr_set) { 810 p = *list; 811 if ((strcmp(p->name, name) == 0) 812 && (mode == p->mode)) { 813 scp->status &= 814 ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 815 return p->rndrsw; 816 } 817 } 818 } 819 820 return NULL; 821 } 822