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