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