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