1 /*- 2 * (MPSAFE) 3 * 4 * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Sascha Wildner <saw@online.de> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer as 15 * the first lines of this file unmodified. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD: src/sys/dev/syscons/scvidctl.c,v 1.19.2.2 2000/05/05 09:16:08 nyan Exp $ 32 * $DragonFly: src/sys/dev/misc/syscons/scvidctl.c,v 1.16 2007/08/19 11:39:11 swildner Exp $ 33 */ 34 35 #include "opt_syscons.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/conf.h> 40 #include <sys/signalvar.h> 41 #include <sys/tty.h> 42 #include <sys/kernel.h> 43 #include <sys/thread2.h> 44 45 #include <machine/console.h> 46 47 #include <dev/video/fb/fbreg.h> 48 #include "syscons.h" 49 50 SET_DECLARE(scrndr_set, const sc_renderer_t); 51 52 int 53 sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, 54 int fontsize) 55 { 56 video_info_t info; 57 u_char *font; 58 int prev_ysize; 59 int new_ysize; 60 int error; 61 62 lwkt_gettoken(&tty_token); 63 if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info)) { 64 lwkt_reltoken(&tty_token); 65 return ENODEV; 66 } 67 lwkt_reltoken(&tty_token); 68 69 /* adjust argument values */ 70 if (fontsize <= 0) 71 fontsize = info.vi_cheight; 72 if (fontsize < 14) { 73 fontsize = 8; 74 #ifndef SC_NO_FONT_LOADING 75 if (!(scp->sc->fonts_loaded & FONT_8)) 76 return EINVAL; 77 font = scp->sc->font_8; 78 #else 79 font = NULL; 80 #endif 81 } else if (fontsize >= 16) { 82 fontsize = 16; 83 #ifndef SC_NO_FONT_LOADING 84 if (!(scp->sc->fonts_loaded & FONT_16)) 85 return EINVAL; 86 font = scp->sc->font_16; 87 #else 88 font = NULL; 89 #endif 90 } else { 91 fontsize = 14; 92 #ifndef SC_NO_FONT_LOADING 93 if (!(scp->sc->fonts_loaded & FONT_14)) 94 return EINVAL; 95 font = scp->sc->font_14; 96 #else 97 font = NULL; 98 #endif 99 } 100 if ((xsize <= 0) || (xsize > info.vi_width)) 101 xsize = info.vi_width; 102 if ((ysize <= 0) || (ysize > info.vi_height)) 103 ysize = info.vi_height; 104 105 /* stop screen saver, etc */ 106 crit_enter(); 107 if ((error = sc_clean_up(scp))) { 108 crit_exit(); 109 return error; 110 } 111 112 if (sc_render_match(scp, scp->sc->adp->va_name, V_INFO_MM_TEXT) == NULL) { 113 crit_exit(); 114 return ENODEV; 115 } 116 117 /* set up scp */ 118 new_ysize = 0; 119 #ifndef SC_NO_HISTORY 120 if (scp->history != NULL) { 121 sc_hist_save(scp); 122 new_ysize = sc_vtb_rows(scp->history); 123 } 124 #endif 125 prev_ysize = scp->ysize; 126 /* 127 * This is a kludge to fend off scrn_update() while we 128 * muck around with scp. XXX 129 */ 130 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 131 scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE | MOUSE_VISIBLE); 132 scp->mode = mode; 133 scp->model = V_INFO_MM_TEXT; 134 scp->xsize = xsize; 135 scp->ysize = ysize; 136 scp->xoff = 0; 137 scp->yoff = 0; 138 scp->xpixel = scp->xsize*8; 139 scp->ypixel = scp->ysize*fontsize; 140 scp->font = font; 141 scp->font_size = fontsize; 142 143 /* allocate buffers */ 144 sc_alloc_scr_buffer(scp, TRUE, TRUE); 145 sc_init_emulator(scp, NULL); 146 #ifndef SC_NO_CUTPASTE 147 sc_alloc_cut_buffer(scp, FALSE); 148 #endif 149 #ifndef SC_NO_HISTORY 150 sc_alloc_history_buffer(scp, new_ysize, prev_ysize, FALSE); 151 #endif 152 crit_exit(); 153 154 if (scp == scp->sc->cur_scp) 155 set_mode(scp); 156 scp->status &= ~UNKNOWN_MODE; 157 158 if (tp == NULL) 159 return 0; 160 DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n", 161 tp->t_winsize.ws_col, tp->t_winsize.ws_row, scp->xsize, scp->ysize)); 162 if (tp->t_winsize.ws_col != scp->xsize 163 || tp->t_winsize.ws_row != scp->ysize) { 164 tp->t_winsize.ws_col = scp->xsize; 165 tp->t_winsize.ws_row = scp->ysize; 166 pgsignal(tp->t_pgrp, SIGWINCH, 1); 167 } 168 169 return 0; 170 } 171 172 int 173 sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) 174 { 175 #ifdef SC_NO_MODE_CHANGE 176 return ENODEV; 177 #else 178 video_info_t info; 179 int error; 180 181 lwkt_gettoken(&tty_token); 182 if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info)) { 183 lwkt_reltoken(&tty_token); 184 return ENODEV; 185 } 186 lwkt_reltoken(&tty_token); 187 188 /* stop screen saver, etc */ 189 crit_enter(); 190 if ((error = sc_clean_up(scp))) { 191 crit_exit(); 192 return error; 193 } 194 195 if (sc_render_match(scp, scp->sc->adp->va_name, V_INFO_MM_OTHER) == NULL) { 196 crit_exit(); 197 return ENODEV; 198 } 199 200 /* set up scp */ 201 scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE | MOUSE_HIDDEN); 202 scp->status &= ~(PIXEL_MODE | MOUSE_VISIBLE); 203 scp->mode = mode; 204 scp->model = V_INFO_MM_OTHER; 205 /* 206 * Don't change xsize and ysize; preserve the previous vty 207 * and history buffers. 208 */ 209 scp->xoff = 0; 210 scp->yoff = 0; 211 scp->xpixel = info.vi_width; 212 scp->ypixel = info.vi_height; 213 scp->font = NULL; 214 scp->font_size = 0; 215 #ifndef SC_NO_SYSMOUSE 216 /* move the mouse cursor at the center of the screen */ 217 sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2); 218 #endif 219 sc_init_emulator(scp, NULL); 220 crit_exit(); 221 222 if (scp == scp->sc->cur_scp) 223 set_mode(scp); 224 /* clear_graphics();*/ 225 refresh_ega_palette(scp); 226 scp->status &= ~UNKNOWN_MODE; 227 228 if (tp == NULL) 229 return 0; 230 if (tp->t_winsize.ws_xpixel != scp->xpixel 231 || tp->t_winsize.ws_ypixel != scp->ypixel) { 232 tp->t_winsize.ws_xpixel = scp->xpixel; 233 tp->t_winsize.ws_ypixel = scp->ypixel; 234 pgsignal(tp->t_pgrp, SIGWINCH, 1); 235 } 236 237 return 0; 238 #endif /* SC_NO_MODE_CHANGE */ 239 } 240 241 int 242 sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, 243 int fontsize) 244 { 245 #ifndef SC_PIXEL_MODE 246 return ENODEV; 247 #else 248 video_info_t info; 249 u_char *font; 250 int prev_ysize; 251 int new_ysize; 252 int error; 253 254 lwkt_gettoken(&tty_token); 255 if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info)) { 256 lwkt_reltoken(&tty_token); 257 return ENODEV; /* this shouldn't happen */ 258 } 259 260 /* adjust argument values */ 261 if (fontsize <= 0) 262 fontsize = info.vi_cheight; 263 if (fontsize < 14) { 264 fontsize = 8; 265 #ifndef SC_NO_FONT_LOADING 266 if (!(scp->sc->fonts_loaded & FONT_8)) 267 return EINVAL; 268 font = scp->sc->font_8; 269 #else 270 font = NULL; 271 #endif 272 } else if (fontsize >= 16) { 273 fontsize = 16; 274 #ifndef SC_NO_FONT_LOADING 275 if (!(scp->sc->fonts_loaded & FONT_16)) 276 return EINVAL; 277 font = scp->sc->font_16; 278 #else 279 font = NULL; 280 #endif 281 } else { 282 fontsize = 14; 283 #ifndef SC_NO_FONT_LOADING 284 if (!(scp->sc->fonts_loaded & FONT_14)) 285 return EINVAL; 286 font = scp->sc->font_14; 287 #else 288 font = NULL; 289 #endif 290 } 291 if (xsize <= 0) 292 xsize = info.vi_width/8; 293 if (ysize <= 0) 294 ysize = info.vi_height/fontsize; 295 296 if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) 297 return EINVAL; 298 299 /* 300 * We currently support the following graphic modes: 301 * 302 * - 4 bpp planar modes whose memory size does not exceed 64K 303 * - 8 bbp packed pixel modes 304 * - 15, 16, 24 and 32 bpp direct modes with linear frame buffer 305 */ 306 307 if (info.vi_mem_model == V_INFO_MM_PLANAR) { 308 if (info.vi_planes != 4) 309 return ENODEV; 310 311 /* 312 * A memory size >64K requires bank switching to access the entire 313 * screen. XXX 314 */ 315 316 if (info.vi_width * info.vi_height / 8 > info.vi_window_size) 317 return ENODEV; 318 } else if (info.vi_mem_model == V_INFO_MM_PACKED) { 319 if (info.vi_depth != 8) 320 return ENODEV; 321 } else if (info.vi_mem_model == V_INFO_MM_DIRECT) { 322 if (!(info.vi_flags & V_INFO_LINEAR) && 323 (info.vi_depth != 15) && (info.vi_depth != 16) && 324 (info.vi_depth != 24) && (info.vi_depth != 32)) 325 return ENODEV; 326 } else 327 return ENODEV; 328 329 /* stop screen saver, etc */ 330 crit_enter(); 331 if ((error = sc_clean_up(scp))) { 332 crit_exit(); 333 return error; 334 } 335 336 if (sc_render_match(scp, scp->sc->adp->va_name, info.vi_mem_model) == NULL) { 337 crit_exit(); 338 return ENODEV; 339 } 340 341 #if 0 342 if (scp->tsw) 343 (*scp->tsw->te_term)(scp, scp->ts); 344 scp->tsw = NULL; 345 scp->ts = NULL; 346 #endif 347 348 /* set up scp */ 349 new_ysize = 0; 350 #ifndef SC_NO_HISTORY 351 if (scp->history != NULL) { 352 sc_hist_save(scp); 353 new_ysize = sc_vtb_rows(scp->history); 354 } 355 #endif 356 prev_ysize = scp->ysize; 357 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 358 scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE); 359 scp->model = info.vi_mem_model; 360 scp->xsize = xsize; 361 scp->ysize = ysize; 362 scp->xoff = (scp->xpixel/8 - xsize)/2; 363 scp->yoff = (scp->ypixel/fontsize - ysize)/2; 364 scp->font = font; 365 scp->font_size = fontsize; 366 367 /* allocate buffers */ 368 sc_alloc_scr_buffer(scp, TRUE, TRUE); 369 sc_init_emulator(scp, NULL); 370 #ifndef SC_NO_CUTPASTE 371 sc_alloc_cut_buffer(scp, FALSE); 372 #endif 373 #ifndef SC_NO_HISTORY 374 sc_alloc_history_buffer(scp, new_ysize, prev_ysize, FALSE); 375 #endif 376 crit_exit(); 377 378 if (scp == scp->sc->cur_scp) { 379 sc_set_border(scp, scp->border); 380 sc_set_cursor_image(scp); 381 } 382 383 scp->status &= ~UNKNOWN_MODE; 384 385 if (tp == NULL) 386 return 0; 387 if (tp->t_winsize.ws_col != scp->xsize 388 || tp->t_winsize.ws_row != scp->ysize) { 389 tp->t_winsize.ws_col = scp->xsize; 390 tp->t_winsize.ws_row = scp->ysize; 391 pgsignal(tp->t_pgrp, SIGWINCH, 1); 392 } 393 394 return 0; 395 #endif /* SC_PIXEL_MODE */ 396 } 397 398 #define fb_ioctl(a, c, d) \ 399 (((a) == NULL) ? ENODEV : \ 400 (*vidsw[(a)->va_index]->ioctl)((a), (c), (caddr_t)(d))) 401 402 int 403 sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag) 404 { 405 scr_stat *scp; 406 video_adapter_t *adp; 407 video_info_t info; 408 int error, ret; 409 410 KKASSERT(tp->t_dev); 411 412 scp = SC_STAT(tp->t_dev); 413 if (scp == NULL) /* tp == SC_MOUSE */ 414 return ENOIOCTL; 415 adp = scp->sc->adp; 416 if (adp == NULL) /* shouldn't happen??? */ 417 return ENODEV; 418 419 lwkt_gettoken(&tty_token); 420 switch (cmd) { 421 422 case CONS_CURRENTADP: /* get current adapter index */ 423 case FBIO_ADAPTER: 424 ret = fb_ioctl(adp, FBIO_ADAPTER, data); 425 lwkt_reltoken(&tty_token); 426 return ret; 427 428 case CONS_CURRENT: /* get current adapter type */ 429 case FBIO_ADPTYPE: 430 ret = fb_ioctl(adp, FBIO_ADPTYPE, data); 431 lwkt_reltoken(&tty_token); 432 return ret; 433 434 case CONS_ADPINFO: /* adapter information */ 435 case FBIO_ADPINFO: 436 if (((video_adapter_info_t *)data)->va_index >= 0) { 437 adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index); 438 if (adp == NULL) { 439 lwkt_reltoken(&tty_token); 440 return ENODEV; 441 } 442 } 443 ret = fb_ioctl(adp, FBIO_ADPINFO, data); 444 lwkt_reltoken(&tty_token); 445 return ret; 446 447 case CONS_GET: /* get current video mode */ 448 case FBIO_GETMODE: 449 *(int *)data = scp->mode; 450 lwkt_reltoken(&tty_token); 451 return 0; 452 453 #ifndef SC_NO_MODE_CHANGE 454 case CONS_SET: 455 case FBIO_SETMODE: /* set video mode */ 456 if (!(adp->va_flags & V_ADP_MODECHANGE)) { 457 lwkt_reltoken(&tty_token); 458 return ENODEV; 459 } 460 info.vi_mode = *(int *)data; 461 error = fb_ioctl(adp, FBIO_MODEINFO, &info); 462 if (error) { 463 lwkt_reltoken(&tty_token); 464 return error; 465 } 466 if (info.vi_flags & V_INFO_GRAPHICS) { 467 lwkt_reltoken(&tty_token); 468 return sc_set_graphics_mode(scp, tp, *(int *)data); 469 } else { 470 lwkt_reltoken(&tty_token); 471 return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0); 472 } 473 #endif /* SC_NO_MODE_CHANGE */ 474 475 case CONS_MODEINFO: /* get mode information */ 476 case FBIO_MODEINFO: 477 ret = fb_ioctl(adp, FBIO_MODEINFO, data); 478 lwkt_reltoken(&tty_token); 479 return ret; 480 481 case CONS_FINDMODE: /* find a matching video mode */ 482 case FBIO_FINDMODE: 483 ret = fb_ioctl(adp, FBIO_FINDMODE, data); 484 lwkt_reltoken(&tty_token); 485 return ret; 486 487 case CONS_SETWINORG: /* set frame buffer window origin */ 488 case FBIO_SETWINORG: 489 if (scp != scp->sc->cur_scp) { 490 lwkt_reltoken(&tty_token); 491 return ENODEV; /* XXX */ 492 } 493 ret = fb_ioctl(adp, FBIO_SETWINORG, data); 494 lwkt_reltoken(&tty_token); 495 return ret; 496 497 case FBIO_GETWINORG: /* get frame buffer window origin */ 498 if (scp != scp->sc->cur_scp) { 499 lwkt_reltoken(&tty_token); 500 return ENODEV; /* XXX */ 501 } 502 ret = fb_ioctl(adp, FBIO_GETWINORG, data); 503 lwkt_reltoken(&tty_token); 504 return ret; 505 506 case FBIO_GETDISPSTART: 507 case FBIO_SETDISPSTART: 508 case FBIO_GETLINEWIDTH: 509 case FBIO_SETLINEWIDTH: 510 if (scp != scp->sc->cur_scp) { 511 lwkt_reltoken(&tty_token); 512 return ENODEV; /* XXX */ 513 } 514 ret = fb_ioctl(adp, cmd, data); 515 lwkt_reltoken(&tty_token); 516 return ret; 517 518 case FBIO_GETPALETTE: 519 case FBIO_SETPALETTE: 520 case FBIOPUTCMAP: 521 case FBIOGETCMAP: 522 case FBIOGTYPE: 523 case FBIOGATTR: 524 case FBIOSVIDEO: 525 case FBIOGVIDEO: 526 case FBIOSCURSOR: 527 case FBIOGCURSOR: 528 case FBIOSCURPOS: 529 case FBIOGCURPOS: 530 case FBIOGCURMAX: 531 if (scp != scp->sc->cur_scp) { 532 lwkt_reltoken(&tty_token); 533 return ENODEV; /* XXX */ 534 } 535 ret = fb_ioctl(adp, cmd, data); 536 lwkt_reltoken(&tty_token); 537 return ret; 538 539 case KDSETMODE: /* set current mode of this (virtual) console */ 540 switch (*(int *)data) { 541 case KD_TEXT: /* switch to TEXT (known) mode */ 542 /* 543 * If scp->mode is of graphics modes, we don't know which 544 * text mode to switch back to... 545 */ 546 if (scp->status & GRAPHICS_MODE) { 547 lwkt_reltoken(&tty_token); 548 return EINVAL; 549 } 550 /* restore fonts & palette ! */ 551 #if 0 552 #ifndef SC_NO_FONT_LOADING 553 if (ISFONTAVAIL(adp->va_flags) 554 && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) 555 /* 556 * FONT KLUDGE 557 * Don't load fonts for now... XXX 558 */ 559 if (scp->sc->fonts_loaded & FONT_8) 560 sc_load_font(scp, 0, 8, scp->sc->font_8, 0, 256); 561 if (scp->sc->fonts_loaded & FONT_14) 562 sc_load_font(scp, 0, 14, scp->sc->font_14, 0, 256); 563 if (scp->sc->fonts_loaded & FONT_16) 564 sc_load_font(scp, 0, 16, scp->sc->font_16, 0, 256); 565 } 566 #endif /* SC_NO_FONT_LOADING */ 567 #endif 568 569 #ifndef SC_NO_PALETTE_LOADING 570 load_palette(adp, scp->sc->palette); 571 #endif 572 573 /* move hardware cursor out of the way */ 574 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); 575 /* FALL THROUGH */ 576 577 case KD_TEXT1: /* switch to TEXT (known) mode */ 578 /* 579 * If scp->mode is of graphics modes, we don't know which 580 * text/pixel mode to switch back to... 581 */ 582 if (scp->status & GRAPHICS_MODE) { 583 lwkt_reltoken(&tty_token); 584 return EINVAL; 585 } 586 crit_enter(); 587 if ((error = sc_clean_up(scp))) { 588 crit_exit(); 589 lwkt_reltoken(&tty_token); 590 return error; 591 } 592 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 593 crit_exit(); 594 /* no restore fonts & palette */ 595 if (scp == scp->sc->cur_scp) 596 set_mode(scp); 597 sc_clear_screen(scp); 598 scp->status &= ~UNKNOWN_MODE; 599 lwkt_reltoken(&tty_token); 600 return 0; 601 602 #ifdef SC_PIXEL_MODE 603 case KD_PIXEL: /* pixel (raster) display */ 604 if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) { 605 lwkt_reltoken(&tty_token); 606 return EINVAL; 607 } 608 if (scp->status & GRAPHICS_MODE) { 609 lwkt_reltoken(&tty_token); 610 return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, 611 scp->font_size); 612 } 613 crit_enter(); 614 if ((error = sc_clean_up(scp))) { 615 crit_exit(); 616 lwkt_reltoken(&tty_token); 617 return error; 618 } 619 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 620 crit_exit(); 621 if (scp == scp->sc->cur_scp) { 622 set_mode(scp); 623 #ifndef SC_NO_PALETTE_LOADING 624 load_palette(adp, scp->sc->palette); 625 #endif 626 } 627 sc_clear_screen(scp); 628 scp->status &= ~UNKNOWN_MODE; 629 lwkt_reltoken(&tty_token); 630 return 0; 631 #endif /* SC_PIXEL_MODE */ 632 633 case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ 634 crit_enter(); 635 if ((error = sc_clean_up(scp))) { 636 crit_exit(); 637 lwkt_reltoken(&tty_token); 638 return error; 639 } 640 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 641 crit_exit(); 642 lwkt_reltoken(&tty_token); 643 return 0; 644 645 default: 646 lwkt_reltoken(&tty_token); 647 return EINVAL; 648 } 649 /* NOT REACHED */ 650 651 #ifdef SC_PIXEL_MODE 652 case KDRASTER: /* set pixel (raster) display mode */ 653 if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) { 654 lwkt_reltoken(&tty_token); 655 return ENODEV; 656 } 657 lwkt_reltoken(&tty_token); 658 return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], 659 ((int *)data)[2]); 660 #endif /* SC_PIXEL_MODE */ 661 662 case KDGETMODE: /* get current mode of this (virtual) console */ 663 /* 664 * From the user program's point of view, KD_PIXEL is the same 665 * as KD_TEXT... 666 */ 667 *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; 668 lwkt_reltoken(&tty_token); 669 return 0; 670 671 case KDSBORDER: /* set border color of this (virtual) console */ 672 scp->border = *data; 673 if (scp == scp->sc->cur_scp) 674 sc_set_border(scp, scp->border); 675 lwkt_reltoken(&tty_token); 676 return 0; 677 } 678 679 lwkt_reltoken(&tty_token); 680 return ENOIOCTL; 681 } 682 683 static LIST_HEAD(, sc_renderer) sc_rndr_list = 684 LIST_HEAD_INITIALIZER(sc_rndr_list); 685 686 int 687 sc_render_add(sc_renderer_t *rndr) 688 { 689 LIST_INSERT_HEAD(&sc_rndr_list, rndr, link); 690 return 0; 691 } 692 693 int 694 sc_render_remove(sc_renderer_t *rndr) 695 { 696 /* 697 LIST_REMOVE(rndr, link); 698 */ 699 return EBUSY; /* XXX */ 700 } 701 702 sc_rndr_sw_t * 703 sc_render_match(scr_stat *scp, char *name, int model) 704 { 705 const sc_renderer_t **list; 706 const sc_renderer_t *p; 707 708 if (!LIST_EMPTY(&sc_rndr_list)) { 709 LIST_FOREACH(p, &sc_rndr_list, link) { 710 if ((strcmp(p->name, name) == 0) && 711 (model == p->model)) { 712 scp->status &= 713 ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 714 return p->rndrsw; 715 } 716 } 717 } else { 718 SET_FOREACH(list, scrndr_set) { 719 p = *list; 720 if ((strcmp(p->name, name) == 0) && 721 (model == p->model)) { 722 scp->status &= 723 ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 724 return p->rndrsw; 725 } 726 } 727 } 728 729 return NULL; 730 } 731