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 lwkt_reltoken(&tty_token); 260 261 /* adjust argument values */ 262 if (fontsize <= 0) 263 fontsize = info.vi_cheight; 264 if (fontsize < 14) { 265 fontsize = 8; 266 #ifndef SC_NO_FONT_LOADING 267 if (!(scp->sc->fonts_loaded & FONT_8)) 268 return EINVAL; 269 font = scp->sc->font_8; 270 #else 271 font = NULL; 272 #endif 273 } else if (fontsize >= 16) { 274 fontsize = 16; 275 #ifndef SC_NO_FONT_LOADING 276 if (!(scp->sc->fonts_loaded & FONT_16)) 277 return EINVAL; 278 font = scp->sc->font_16; 279 #else 280 font = NULL; 281 #endif 282 } else { 283 fontsize = 14; 284 #ifndef SC_NO_FONT_LOADING 285 if (!(scp->sc->fonts_loaded & FONT_14)) 286 return EINVAL; 287 font = scp->sc->font_14; 288 #else 289 font = NULL; 290 #endif 291 } 292 if (xsize <= 0) 293 xsize = info.vi_width/8; 294 if (ysize <= 0) 295 ysize = info.vi_height/fontsize; 296 297 if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) 298 return EINVAL; 299 300 /* 301 * We currently support the following graphic modes: 302 * 303 * - 4 bpp planar modes whose memory size does not exceed 64K 304 * - 8 bbp packed pixel modes 305 * - 15, 16, 24 and 32 bpp direct modes with linear frame buffer 306 */ 307 308 if (info.vi_mem_model == V_INFO_MM_PLANAR) { 309 if (info.vi_planes != 4) 310 return ENODEV; 311 312 /* 313 * A memory size >64K requires bank switching to access the entire 314 * screen. XXX 315 */ 316 317 if (info.vi_width * info.vi_height / 8 > info.vi_window_size) 318 return ENODEV; 319 } else if (info.vi_mem_model == V_INFO_MM_PACKED) { 320 if (info.vi_depth != 8) 321 return ENODEV; 322 } else if (info.vi_mem_model == V_INFO_MM_DIRECT) { 323 if (!(info.vi_flags & V_INFO_LINEAR) && 324 (info.vi_depth != 15) && (info.vi_depth != 16) && 325 (info.vi_depth != 24) && (info.vi_depth != 32)) 326 return ENODEV; 327 } else 328 return ENODEV; 329 330 /* stop screen saver, etc */ 331 crit_enter(); 332 if ((error = sc_clean_up(scp))) { 333 crit_exit(); 334 return error; 335 } 336 337 if (sc_render_match(scp, scp->sc->adp->va_name, info.vi_mem_model) == NULL) { 338 crit_exit(); 339 return ENODEV; 340 } 341 342 #if 0 343 if (scp->tsw) 344 (*scp->tsw->te_term)(scp, scp->ts); 345 scp->tsw = NULL; 346 scp->ts = NULL; 347 #endif 348 349 /* set up scp */ 350 new_ysize = 0; 351 #ifndef SC_NO_HISTORY 352 if (scp->history != NULL) { 353 sc_hist_save(scp); 354 new_ysize = sc_vtb_rows(scp->history); 355 } 356 #endif 357 prev_ysize = scp->ysize; 358 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 359 scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE); 360 scp->model = info.vi_mem_model; 361 scp->xsize = xsize; 362 scp->ysize = ysize; 363 scp->xoff = (scp->xpixel/8 - xsize)/2; 364 scp->yoff = (scp->ypixel/fontsize - ysize)/2; 365 scp->font = font; 366 scp->font_size = fontsize; 367 368 /* allocate buffers */ 369 sc_alloc_scr_buffer(scp, TRUE, TRUE); 370 sc_init_emulator(scp, NULL); 371 #ifndef SC_NO_CUTPASTE 372 sc_alloc_cut_buffer(scp, FALSE); 373 #endif 374 #ifndef SC_NO_HISTORY 375 sc_alloc_history_buffer(scp, new_ysize, prev_ysize, FALSE); 376 #endif 377 crit_exit(); 378 379 if (scp == scp->sc->cur_scp) { 380 sc_set_border(scp, scp->border); 381 sc_set_cursor_image(scp); 382 } 383 384 scp->status &= ~UNKNOWN_MODE; 385 386 if (tp == NULL) 387 return 0; 388 if (tp->t_winsize.ws_col != scp->xsize 389 || tp->t_winsize.ws_row != scp->ysize) { 390 tp->t_winsize.ws_col = scp->xsize; 391 tp->t_winsize.ws_row = scp->ysize; 392 pgsignal(tp->t_pgrp, SIGWINCH, 1); 393 } 394 395 return 0; 396 #endif /* SC_PIXEL_MODE */ 397 } 398 399 #define fb_ioctl(a, c, d) \ 400 (((a) == NULL) ? ENODEV : \ 401 (*vidsw[(a)->va_index]->ioctl)((a), (c), (caddr_t)(d))) 402 403 int 404 sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag) 405 { 406 scr_stat *scp; 407 video_adapter_t *adp; 408 video_info_t info; 409 int error, ret; 410 411 KKASSERT(tp->t_dev); 412 413 scp = SC_STAT(tp->t_dev); 414 if (scp == NULL) /* tp == SC_MOUSE */ 415 return ENOIOCTL; 416 adp = scp->sc->adp; 417 if (adp == NULL) /* shouldn't happen??? */ 418 return ENODEV; 419 420 lwkt_gettoken(&tty_token); 421 switch (cmd) { 422 423 case CONS_CURRENTADP: /* get current adapter index */ 424 case FBIO_ADAPTER: 425 ret = fb_ioctl(adp, FBIO_ADAPTER, data); 426 lwkt_reltoken(&tty_token); 427 return ret; 428 429 case CONS_CURRENT: /* get current adapter type */ 430 case FBIO_ADPTYPE: 431 ret = fb_ioctl(adp, FBIO_ADPTYPE, data); 432 lwkt_reltoken(&tty_token); 433 return ret; 434 435 case CONS_ADPINFO: /* adapter information */ 436 case FBIO_ADPINFO: 437 if (((video_adapter_info_t *)data)->va_index >= 0) { 438 adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index); 439 if (adp == NULL) { 440 lwkt_reltoken(&tty_token); 441 return ENODEV; 442 } 443 } 444 ret = fb_ioctl(adp, FBIO_ADPINFO, data); 445 lwkt_reltoken(&tty_token); 446 return ret; 447 448 case CONS_GET: /* get current video mode */ 449 case FBIO_GETMODE: 450 *(int *)data = scp->mode; 451 lwkt_reltoken(&tty_token); 452 return 0; 453 454 #ifndef SC_NO_MODE_CHANGE 455 case CONS_SET: 456 case FBIO_SETMODE: /* set video mode */ 457 if (!(adp->va_flags & V_ADP_MODECHANGE)) { 458 lwkt_reltoken(&tty_token); 459 return ENODEV; 460 } 461 info.vi_mode = *(int *)data; 462 error = fb_ioctl(adp, FBIO_MODEINFO, &info); 463 if (error) { 464 lwkt_reltoken(&tty_token); 465 return error; 466 } 467 if (info.vi_flags & V_INFO_GRAPHICS) { 468 lwkt_reltoken(&tty_token); 469 return sc_set_graphics_mode(scp, tp, *(int *)data); 470 } else { 471 lwkt_reltoken(&tty_token); 472 return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0); 473 } 474 #endif /* SC_NO_MODE_CHANGE */ 475 476 case CONS_MODEINFO: /* get mode information */ 477 case FBIO_MODEINFO: 478 ret = fb_ioctl(adp, FBIO_MODEINFO, data); 479 lwkt_reltoken(&tty_token); 480 return ret; 481 482 case CONS_FINDMODE: /* find a matching video mode */ 483 case FBIO_FINDMODE: 484 ret = fb_ioctl(adp, FBIO_FINDMODE, data); 485 lwkt_reltoken(&tty_token); 486 return ret; 487 488 case CONS_SETWINORG: /* set frame buffer window origin */ 489 case FBIO_SETWINORG: 490 if (scp != scp->sc->cur_scp) { 491 lwkt_reltoken(&tty_token); 492 return ENODEV; /* XXX */ 493 } 494 ret = fb_ioctl(adp, FBIO_SETWINORG, data); 495 lwkt_reltoken(&tty_token); 496 return ret; 497 498 case FBIO_GETWINORG: /* get frame buffer window origin */ 499 if (scp != scp->sc->cur_scp) { 500 lwkt_reltoken(&tty_token); 501 return ENODEV; /* XXX */ 502 } 503 ret = fb_ioctl(adp, FBIO_GETWINORG, data); 504 lwkt_reltoken(&tty_token); 505 return ret; 506 507 case FBIO_GETDISPSTART: 508 case FBIO_SETDISPSTART: 509 case FBIO_GETLINEWIDTH: 510 case FBIO_SETLINEWIDTH: 511 if (scp != scp->sc->cur_scp) { 512 lwkt_reltoken(&tty_token); 513 return ENODEV; /* XXX */ 514 } 515 ret = fb_ioctl(adp, cmd, data); 516 lwkt_reltoken(&tty_token); 517 return ret; 518 519 case FBIO_GETPALETTE: 520 case FBIO_SETPALETTE: 521 case FBIOPUTCMAP: 522 case FBIOGETCMAP: 523 case FBIOGTYPE: 524 case FBIOGATTR: 525 case FBIOSVIDEO: 526 case FBIOGVIDEO: 527 case FBIOSCURSOR: 528 case FBIOGCURSOR: 529 case FBIOSCURPOS: 530 case FBIOGCURPOS: 531 case FBIOGCURMAX: 532 if (scp != scp->sc->cur_scp) { 533 lwkt_reltoken(&tty_token); 534 return ENODEV; /* XXX */ 535 } 536 ret = fb_ioctl(adp, cmd, data); 537 lwkt_reltoken(&tty_token); 538 return ret; 539 540 case KDSETMODE: /* set current mode of this (virtual) console */ 541 switch (*(int *)data) { 542 case KD_TEXT: /* switch to TEXT (known) mode */ 543 /* 544 * If scp->mode is of graphics modes, we don't know which 545 * text mode to switch back to... 546 */ 547 if (scp->status & GRAPHICS_MODE) { 548 lwkt_reltoken(&tty_token); 549 return EINVAL; 550 } 551 /* restore fonts & palette ! */ 552 #if 0 553 #ifndef SC_NO_FONT_LOADING 554 if (ISFONTAVAIL(adp->va_flags) 555 && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) 556 /* 557 * FONT KLUDGE 558 * Don't load fonts for now... XXX 559 */ 560 if (scp->sc->fonts_loaded & FONT_8) 561 sc_load_font(scp, 0, 8, scp->sc->font_8, 0, 256); 562 if (scp->sc->fonts_loaded & FONT_14) 563 sc_load_font(scp, 0, 14, scp->sc->font_14, 0, 256); 564 if (scp->sc->fonts_loaded & FONT_16) 565 sc_load_font(scp, 0, 16, scp->sc->font_16, 0, 256); 566 } 567 #endif /* SC_NO_FONT_LOADING */ 568 #endif 569 570 #ifndef SC_NO_PALETTE_LOADING 571 load_palette(adp, scp->sc->palette); 572 #endif 573 574 /* move hardware cursor out of the way */ 575 (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); 576 /* FALL THROUGH */ 577 578 case KD_TEXT1: /* switch to TEXT (known) mode */ 579 /* 580 * If scp->mode is of graphics modes, we don't know which 581 * text/pixel mode to switch back to... 582 */ 583 if (scp->status & GRAPHICS_MODE) { 584 lwkt_reltoken(&tty_token); 585 return EINVAL; 586 } 587 crit_enter(); 588 if ((error = sc_clean_up(scp))) { 589 crit_exit(); 590 lwkt_reltoken(&tty_token); 591 return error; 592 } 593 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 594 crit_exit(); 595 /* no restore fonts & palette */ 596 if (scp == scp->sc->cur_scp) 597 set_mode(scp); 598 sc_clear_screen(scp); 599 scp->status &= ~UNKNOWN_MODE; 600 lwkt_reltoken(&tty_token); 601 return 0; 602 603 #ifdef SC_PIXEL_MODE 604 case KD_PIXEL: /* pixel (raster) display */ 605 if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) { 606 lwkt_reltoken(&tty_token); 607 return EINVAL; 608 } 609 if (scp->status & GRAPHICS_MODE) { 610 lwkt_reltoken(&tty_token); 611 return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, 612 scp->font_size); 613 } 614 crit_enter(); 615 if ((error = sc_clean_up(scp))) { 616 crit_exit(); 617 lwkt_reltoken(&tty_token); 618 return error; 619 } 620 scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 621 crit_exit(); 622 if (scp == scp->sc->cur_scp) { 623 set_mode(scp); 624 #ifndef SC_NO_PALETTE_LOADING 625 load_palette(adp, scp->sc->palette); 626 #endif 627 } 628 sc_clear_screen(scp); 629 scp->status &= ~UNKNOWN_MODE; 630 lwkt_reltoken(&tty_token); 631 return 0; 632 #endif /* SC_PIXEL_MODE */ 633 634 case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ 635 crit_enter(); 636 if ((error = sc_clean_up(scp))) { 637 crit_exit(); 638 lwkt_reltoken(&tty_token); 639 return error; 640 } 641 scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 642 crit_exit(); 643 lwkt_reltoken(&tty_token); 644 return 0; 645 646 default: 647 lwkt_reltoken(&tty_token); 648 return EINVAL; 649 } 650 /* NOT REACHED */ 651 652 #ifdef SC_PIXEL_MODE 653 case KDRASTER: /* set pixel (raster) display mode */ 654 if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) { 655 lwkt_reltoken(&tty_token); 656 return ENODEV; 657 } 658 lwkt_reltoken(&tty_token); 659 return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], 660 ((int *)data)[2]); 661 #endif /* SC_PIXEL_MODE */ 662 663 case KDGETMODE: /* get current mode of this (virtual) console */ 664 /* 665 * From the user program's point of view, KD_PIXEL is the same 666 * as KD_TEXT... 667 */ 668 *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; 669 lwkt_reltoken(&tty_token); 670 return 0; 671 672 case KDSBORDER: /* set border color of this (virtual) console */ 673 scp->border = *data; 674 if (scp == scp->sc->cur_scp) 675 sc_set_border(scp, scp->border); 676 lwkt_reltoken(&tty_token); 677 return 0; 678 } 679 680 lwkt_reltoken(&tty_token); 681 return ENOIOCTL; 682 } 683 684 static LIST_HEAD(, sc_renderer) sc_rndr_list = 685 LIST_HEAD_INITIALIZER(sc_rndr_list); 686 687 int 688 sc_render_add(sc_renderer_t *rndr) 689 { 690 LIST_INSERT_HEAD(&sc_rndr_list, rndr, link); 691 return 0; 692 } 693 694 int 695 sc_render_remove(sc_renderer_t *rndr) 696 { 697 /* 698 LIST_REMOVE(rndr, link); 699 */ 700 return EBUSY; /* XXX */ 701 } 702 703 sc_rndr_sw_t * 704 sc_render_match(scr_stat *scp, char *name, int model) 705 { 706 const sc_renderer_t **list; 707 const sc_renderer_t *p; 708 709 if (!LIST_EMPTY(&sc_rndr_list)) { 710 LIST_FOREACH(p, &sc_rndr_list, link) { 711 if ((strcmp(p->name, name) == 0) && 712 (model == p->model)) { 713 scp->status &= 714 ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 715 return p->rndrsw; 716 } 717 } 718 } else { 719 SET_FOREACH(list, scrndr_set) { 720 p = *list; 721 if ((strcmp(p->name, name) == 0) && 722 (model == p->model)) { 723 scp->status &= 724 ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 725 return p->rndrsw; 726 } 727 } 728 } 729 730 return NULL; 731 } 732