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