kdrive.c (27754B)
1 /* 2 * Copyright © 1999 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Keith Packard not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Keith Packard makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 #ifdef HAVE_DIX_CONFIG_H 24 #include <dix-config.h> 25 #endif 26 #include "kdrive.h" 27 #include <mivalidate.h> 28 #include <dixstruct.h> 29 #include "privates.h" 30 #ifdef RANDR 31 #include <randrstr.h> 32 #endif 33 #include "glx_extinit.h" 34 35 #ifdef XV 36 #include "kxv.h" 37 #endif 38 39 #ifdef DPMSExtension 40 #include "dpmsproc.h" 41 #endif 42 43 #ifdef HAVE_EXECINFO_H 44 #include <execinfo.h> 45 #endif 46 47 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 48 #include <hotplug.h> 49 #endif 50 51 /* This stub can be safely removed once we can 52 * split input and GPU parts in hotplug.h et al. */ 53 #include <systemd-logind.h> 54 55 typedef struct _kdDepths { 56 CARD8 depth; 57 CARD8 bpp; 58 } KdDepths; 59 60 KdDepths kdDepths[] = { 61 {1, 1}, 62 {4, 4}, 63 {8, 8}, 64 {15, 16}, 65 {16, 16}, 66 {24, 32}, 67 {32, 32} 68 }; 69 70 #define KD_DEFAULT_BUTTONS 5 71 72 DevPrivateKeyRec kdScreenPrivateKeyRec; 73 static unsigned long kdGeneration; 74 75 Bool kdEmulateMiddleButton; 76 Bool kdRawPointerCoordinates; 77 Bool kdDisableZaphod; 78 static Bool kdEnabled; 79 static int kdSubpixelOrder; 80 static char *kdSwitchCmd; 81 static DDXPointRec kdOrigin; 82 Bool kdHasPointer = FALSE; 83 Bool kdHasKbd = FALSE; 84 const char *kdGlobalXkbRules = NULL; 85 const char *kdGlobalXkbModel = NULL; 86 const char *kdGlobalXkbLayout = NULL; 87 const char *kdGlobalXkbVariant = NULL; 88 const char *kdGlobalXkbOptions = NULL; 89 90 void 91 KdDisableScreen(ScreenPtr pScreen) 92 { 93 KdScreenPriv(pScreen); 94 95 if (!pScreenPriv->enabled) 96 return; 97 if (!pScreenPriv->closed) 98 SetRootClip(pScreen, ROOT_CLIP_NONE); 99 KdDisableColormap(pScreen); 100 if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel) 101 (*pScreenPriv->card->cfuncs->disableAccel) (pScreen); 102 pScreenPriv->enabled = FALSE; 103 } 104 105 static void 106 KdDoSwitchCmd(const char *reason) 107 { 108 if (kdSwitchCmd) { 109 char *command; 110 int ret; 111 112 if (asprintf(&command, "%s %s", kdSwitchCmd, reason) == -1) 113 return; 114 115 /* Ignore the return value from system; I'm not sure 116 * there's anything more useful to be done when 117 * it fails 118 */ 119 ret = system(command); 120 (void) ret; 121 free(command); 122 } 123 } 124 125 static void 126 KdSuspend(void) 127 { 128 KdCardInfo *card; 129 KdScreenInfo *screen; 130 131 if (kdEnabled) { 132 for (card = kdCardInfo; card; card = card->next) { 133 for (screen = card->screenList; screen; screen = screen->next) 134 if (screen->mynum == card->selected && screen->pScreen) 135 KdDisableScreen(screen->pScreen); 136 } 137 KdDisableInput(); 138 KdDoSwitchCmd("suspend"); 139 } 140 } 141 142 static void 143 KdDisableScreens(void) 144 { 145 KdSuspend(); 146 kdEnabled = FALSE; 147 } 148 149 Bool 150 KdEnableScreen(ScreenPtr pScreen) 151 { 152 KdScreenPriv(pScreen); 153 154 if (pScreenPriv->enabled) 155 return TRUE; 156 pScreenPriv->enabled = TRUE; 157 pScreenPriv->dpmsState = KD_DPMS_NORMAL; 158 pScreenPriv->card->selected = pScreenPriv->screen->mynum; 159 if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel) 160 (*pScreenPriv->card->cfuncs->enableAccel) (pScreen); 161 KdEnableColormap(pScreen); 162 SetRootClip(pScreen, ROOT_CLIP_FULL); 163 return TRUE; 164 } 165 166 void 167 ddxGiveUp(enum ExitCode error) 168 { 169 KdDisableScreens(); 170 } 171 172 static Bool kdDumbDriver; 173 static Bool kdSoftCursor; 174 175 const char * 176 KdParseFindNext(const char *cur, const char *delim, char *save, char *last) 177 { 178 while (*cur && !strchr(delim, *cur)) { 179 *save++ = *cur++; 180 } 181 *save = 0; 182 *last = *cur; 183 if (*cur) 184 cur++; 185 return cur; 186 } 187 188 Rotation 189 KdAddRotation(Rotation a, Rotation b) 190 { 191 Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All); 192 Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); 193 194 if (rotate > RR_Rotate_270) 195 rotate /= (RR_Rotate_270 * RR_Rotate_90); 196 return reflect | rotate; 197 } 198 199 Rotation 200 KdSubRotation(Rotation a, Rotation b) 201 { 202 Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All); 203 Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); 204 205 if (rotate > RR_Rotate_270) 206 rotate /= (RR_Rotate_270 * RR_Rotate_90); 207 return reflect | rotate; 208 } 209 210 void 211 KdParseScreen(KdScreenInfo * screen, const char *arg) 212 { 213 char delim; 214 char save[1024]; 215 int i; 216 int pixels, mm; 217 218 screen->dumb = kdDumbDriver; 219 screen->softCursor = kdSoftCursor; 220 screen->origin = kdOrigin; 221 screen->randr = RR_Rotate_0; 222 screen->x = 0; 223 screen->y = 0; 224 screen->width = 0; 225 screen->height = 0; 226 screen->width_mm = 0; 227 screen->height_mm = 0; 228 screen->subpixel_order = kdSubpixelOrder; 229 screen->rate = 0; 230 screen->fb.depth = 0; 231 if (!arg) 232 return; 233 if (strlen(arg) >= sizeof(save)) 234 return; 235 236 for (i = 0; i < 2; i++) { 237 arg = KdParseFindNext(arg, "x/+@XY", save, &delim); 238 if (!save[0]) 239 return; 240 241 pixels = atoi(save); 242 mm = 0; 243 244 if (delim == '/') { 245 arg = KdParseFindNext(arg, "x+@XY", save, &delim); 246 if (!save[0]) 247 return; 248 mm = atoi(save); 249 } 250 251 if (i == 0) { 252 screen->width = pixels; 253 screen->width_mm = mm; 254 } 255 else { 256 screen->height = pixels; 257 screen->height_mm = mm; 258 } 259 if (delim != 'x' && delim != '+' && delim != '@' && 260 delim != 'X' && delim != 'Y' && 261 (delim != '\0' || i == 0)) 262 return; 263 } 264 265 kdOrigin.x += screen->width; 266 kdOrigin.y = 0; 267 kdDumbDriver = FALSE; 268 kdSoftCursor = FALSE; 269 kdSubpixelOrder = SubPixelUnknown; 270 271 if (delim == '+') { 272 arg = KdParseFindNext(arg, "+@xXY", save, &delim); 273 if (save[0]) 274 screen->x = atoi(save); 275 } 276 277 if (delim == '+') { 278 arg = KdParseFindNext(arg, "@xXY", save, &delim); 279 if (save[0]) 280 screen->y = atoi(save); 281 } 282 283 if (delim == '@') { 284 arg = KdParseFindNext(arg, "xXY", save, &delim); 285 if (save[0]) { 286 int rotate = atoi(save); 287 288 if (rotate < 45) 289 screen->randr = RR_Rotate_0; 290 else if (rotate < 135) 291 screen->randr = RR_Rotate_90; 292 else if (rotate < 225) 293 screen->randr = RR_Rotate_180; 294 else if (rotate < 315) 295 screen->randr = RR_Rotate_270; 296 else 297 screen->randr = RR_Rotate_0; 298 } 299 } 300 if (delim == 'X') { 301 arg = KdParseFindNext(arg, "xY", save, &delim); 302 screen->randr |= RR_Reflect_X; 303 } 304 305 if (delim == 'Y') { 306 arg = KdParseFindNext(arg, "xY", save, &delim); 307 screen->randr |= RR_Reflect_Y; 308 } 309 310 arg = KdParseFindNext(arg, "x/,", save, &delim); 311 if (save[0]) { 312 screen->fb.depth = atoi(save); 313 if (delim == '/') { 314 arg = KdParseFindNext(arg, "x,", save, &delim); 315 if (save[0]) 316 screen->fb.bitsPerPixel = atoi(save); 317 } 318 else 319 screen->fb.bitsPerPixel = 0; 320 } 321 322 if (delim == 'x') { 323 arg = KdParseFindNext(arg, "x", save, &delim); 324 if (save[0]) 325 screen->rate = atoi(save); 326 } 327 } 328 329 static void 330 KdParseRgba(char *rgba) 331 { 332 if (!strcmp(rgba, "rgb")) 333 kdSubpixelOrder = SubPixelHorizontalRGB; 334 else if (!strcmp(rgba, "bgr")) 335 kdSubpixelOrder = SubPixelHorizontalBGR; 336 else if (!strcmp(rgba, "vrgb")) 337 kdSubpixelOrder = SubPixelVerticalRGB; 338 else if (!strcmp(rgba, "vbgr")) 339 kdSubpixelOrder = SubPixelVerticalBGR; 340 else if (!strcmp(rgba, "none")) 341 kdSubpixelOrder = SubPixelNone; 342 else 343 kdSubpixelOrder = SubPixelUnknown; 344 } 345 346 void 347 KdUseMsg(void) 348 { 349 ErrorF("\nTinyX Device Dependent Usage:\n"); 350 ErrorF 351 ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][+[-]XOFFSET][+[-]YOFFSET][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n"); 352 ErrorF 353 ("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n"); 354 ErrorF 355 ("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n"); 356 ErrorF 357 ("-keybd driver [,,options] Specify the keyboard driver and its options\n"); 358 ErrorF("-xkb-rules Set default XkbRules value (can be overridden by -keybd options)\n"); 359 ErrorF("-xkb-model Set default XkbModel value (can be overridden by -keybd options)\n"); 360 ErrorF("-xkb-layout Set default XkbLayout value (can be overridden by -keybd options)\n"); 361 ErrorF("-xkb-variant Set default XkbVariant value (can be overridden by -keybd options)\n"); 362 ErrorF("-xkb-options Set default XkbOptions value (can be overridden by -keybd options)\n"); 363 ErrorF("-zaphod Disable cursor screen switching\n"); 364 ErrorF("-2button Emulate 3 button mouse\n"); 365 ErrorF("-3button Disable 3 button mouse emulation\n"); 366 ErrorF 367 ("-rawcoord Don't transform pointer coordinates on rotation\n"); 368 ErrorF("-dumb Disable hardware acceleration\n"); 369 ErrorF("-softCursor Force software cursor\n"); 370 ErrorF("-videoTest Start the server, pause momentarily and exit\n"); 371 ErrorF 372 ("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n"); 373 ErrorF("-switchCmd Command to execute on vt switch\n"); 374 ErrorF 375 ("vtxx Use virtual terminal xx instead of the next available\n"); 376 } 377 378 int 379 KdProcessArgument(int argc, char **argv, int i) 380 { 381 KdCardInfo *card; 382 KdScreenInfo *screen; 383 384 if (!strcmp(argv[i], "-screen")) { 385 if ((i + 1) < argc) { 386 card = KdCardInfoLast(); 387 if (!card) { 388 InitCard(0); 389 card = KdCardInfoLast(); 390 } 391 if (card) { 392 screen = KdScreenInfoAdd(card); 393 KdParseScreen(screen, argv[i + 1]); 394 } 395 else 396 ErrorF("No matching card found!\n"); 397 } 398 else 399 UseMsg(); 400 return 2; 401 } 402 if (!strcmp(argv[i], "-zaphod")) { 403 kdDisableZaphod = TRUE; 404 return 1; 405 } 406 if (!strcmp(argv[i], "-3button")) { 407 kdEmulateMiddleButton = FALSE; 408 return 1; 409 } 410 if (!strcmp(argv[i], "-2button")) { 411 kdEmulateMiddleButton = TRUE; 412 return 1; 413 } 414 if (!strcmp(argv[i], "-rawcoord")) { 415 kdRawPointerCoordinates = 1; 416 return 1; 417 } 418 if (!strcmp(argv[i], "-dumb")) { 419 kdDumbDriver = TRUE; 420 return 1; 421 } 422 if (!strcmp(argv[i], "-softCursor")) { 423 kdSoftCursor = TRUE; 424 return 1; 425 } 426 if (!strcmp(argv[i], "-origin")) { 427 if ((i + 1) < argc) { 428 char *x = argv[i + 1]; 429 char *y = strchr(x, ','); 430 431 if (x) 432 kdOrigin.x = atoi(x); 433 else 434 kdOrigin.x = 0; 435 if (y) 436 kdOrigin.y = atoi(y + 1); 437 else 438 kdOrigin.y = 0; 439 } 440 else 441 UseMsg(); 442 return 2; 443 } 444 if (!strcmp(argv[i], "-rgba")) { 445 if ((i + 1) < argc) 446 KdParseRgba(argv[i + 1]); 447 else 448 UseMsg(); 449 return 2; 450 } 451 if (!strcmp(argv[i], "-switchCmd")) { 452 if ((i + 1) < argc) 453 kdSwitchCmd = argv[i + 1]; 454 else 455 UseMsg(); 456 return 2; 457 } 458 if (!strcmp(argv[i], "-xkb-rules")) { 459 if (i + 1 >= argc) { 460 UseMsg(); 461 FatalError("Missing argument for option -xkb-rules.\n"); 462 } 463 kdGlobalXkbRules = argv[i + 1]; 464 return 2; 465 } 466 if (!strcmp(argv[i], "-xkb-model")) { 467 if (i + 1 >= argc) { 468 UseMsg(); 469 FatalError("Missing argument for option -xkb-model.\n"); 470 } 471 kdGlobalXkbModel = argv[i + 1]; 472 return 2; 473 } 474 if (!strcmp(argv[i], "-xkb-layout")) { 475 if (i + 1 >= argc) { 476 UseMsg(); 477 FatalError("Missing argument for option -xkb-layout.\n"); 478 } 479 kdGlobalXkbLayout = argv[i + 1]; 480 return 2; 481 } 482 if (!strcmp(argv[i], "-xkb-variant")) { 483 if (i + 1 >= argc) { 484 UseMsg(); 485 FatalError("Missing argument for option -xkb-variant.\n"); 486 } 487 kdGlobalXkbVariant = argv[i + 1]; 488 return 2; 489 } 490 if (!strcmp(argv[i], "-xkb-options")) { 491 if (i + 1 >= argc) { 492 UseMsg(); 493 FatalError("Missing argument for option -xkb-options.\n"); 494 } 495 kdGlobalXkbOptions = argv[i + 1]; 496 return 2; 497 } 498 if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) { 499 if (i + 1 >= argc) 500 UseMsg(); 501 KdAddConfigPointer(argv[i + 1]); 502 kdHasPointer = TRUE; 503 return 2; 504 } 505 if (!strcmp(argv[i], "-keybd")) { 506 if (i + 1 >= argc) 507 UseMsg(); 508 KdAddConfigKeyboard(argv[i + 1]); 509 kdHasKbd = TRUE; 510 return 2; 511 } 512 513 return 0; 514 } 515 516 static Bool 517 KdAllocatePrivates(ScreenPtr pScreen) 518 { 519 KdPrivScreenPtr pScreenPriv; 520 521 if (kdGeneration != serverGeneration) 522 kdGeneration = serverGeneration; 523 524 if (!dixRegisterPrivateKey(&kdScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 525 return FALSE; 526 527 pScreenPriv = calloc(1, sizeof(*pScreenPriv)); 528 if (!pScreenPriv) 529 return FALSE; 530 KdSetScreenPriv(pScreen, pScreenPriv); 531 return TRUE; 532 } 533 534 static Bool 535 KdCreateScreenResources(ScreenPtr pScreen) 536 { 537 KdScreenPriv(pScreen); 538 KdCardInfo *card = pScreenPriv->card; 539 Bool ret; 540 541 pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources; 542 if (pScreen->CreateScreenResources) 543 ret = (*pScreen->CreateScreenResources) (pScreen); 544 else 545 ret = -1; 546 pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; 547 pScreen->CreateScreenResources = KdCreateScreenResources; 548 if (ret && card->cfuncs->createRes) 549 ret = (*card->cfuncs->createRes) (pScreen); 550 return ret; 551 } 552 553 static Bool 554 KdCloseScreen(ScreenPtr pScreen) 555 { 556 KdScreenPriv(pScreen); 557 KdScreenInfo *screen = pScreenPriv->screen; 558 KdCardInfo *card = pScreenPriv->card; 559 Bool ret; 560 561 if (card->cfuncs->closeScreen) 562 (*card->cfuncs->closeScreen)(pScreen); 563 564 pScreenPriv->closed = TRUE; 565 pScreen->CloseScreen = pScreenPriv->CloseScreen; 566 567 if (pScreen->CloseScreen) 568 ret = (*pScreen->CloseScreen) (pScreen); 569 else 570 ret = TRUE; 571 572 if (screen->mynum == card->selected) 573 KdDisableScreen(pScreen); 574 575 if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel) 576 (*card->cfuncs->finiAccel) (pScreen); 577 578 if (card->cfuncs->scrfini) 579 (*card->cfuncs->scrfini) (screen); 580 581 /* 582 * Clean up card when last screen is closed, DIX closes them in 583 * reverse order, thus we check for when the first in the list is closed 584 */ 585 if (screen == card->screenList) { 586 if (card->cfuncs->cardfini) 587 (*card->cfuncs->cardfini) (card); 588 /* 589 * Clean up OS when last card is closed 590 */ 591 if (card == kdCardInfo) { 592 kdEnabled = FALSE; 593 } 594 } 595 596 pScreenPriv->screen->pScreen = 0; 597 598 free((void *) pScreenPriv); 599 return ret; 600 } 601 602 static Bool 603 KdSaveScreen(ScreenPtr pScreen, int on) 604 { 605 return FALSE; 606 } 607 608 static Bool 609 KdCreateWindow(WindowPtr pWin) 610 { 611 #ifndef PHOENIX 612 if (!pWin->parent) { 613 KdScreenPriv(pWin->drawable.pScreen); 614 615 if (!pScreenPriv->enabled) { 616 RegionEmpty(&pWin->borderClip); 617 RegionBreak(&pWin->clipList); 618 } 619 } 620 #endif 621 return fbCreateWindow(pWin); 622 } 623 624 void 625 KdSetSubpixelOrder(ScreenPtr pScreen, Rotation randr) 626 { 627 KdScreenPriv(pScreen); 628 KdScreenInfo *screen = pScreenPriv->screen; 629 int subpixel_order = screen->subpixel_order; 630 Rotation subpixel_dir; 631 int i; 632 633 static struct { 634 int subpixel_order; 635 Rotation direction; 636 } orders[] = { 637 {SubPixelHorizontalRGB, RR_Rotate_0}, 638 {SubPixelHorizontalBGR, RR_Rotate_180}, 639 {SubPixelVerticalRGB, RR_Rotate_270}, 640 {SubPixelVerticalBGR, RR_Rotate_90}, 641 }; 642 643 static struct { 644 int bit; 645 int normal; 646 int reflect; 647 } reflects[] = { 648 {RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR}, 649 {RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB}, 650 {RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR}, 651 {RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB}, 652 }; 653 654 /* map subpixel to direction */ 655 for (i = 0; i < 4; i++) 656 if (orders[i].subpixel_order == subpixel_order) 657 break; 658 if (i < 4) { 659 subpixel_dir = 660 KdAddRotation(randr & RR_Rotate_All, orders[i].direction); 661 662 /* map back to subpixel order */ 663 for (i = 0; i < 4; i++) 664 if (orders[i].direction & subpixel_dir) { 665 subpixel_order = orders[i].subpixel_order; 666 break; 667 } 668 /* reflect */ 669 for (i = 0; i < 4; i++) 670 if ((randr & reflects[i].bit) && 671 reflects[i].normal == subpixel_order) { 672 subpixel_order = reflects[i].reflect; 673 break; 674 } 675 } 676 PictureSetSubpixelOrder(pScreen, subpixel_order); 677 } 678 679 /* Pass through AddScreen, which doesn't take any closure */ 680 static KdScreenInfo *kdCurrentScreen; 681 682 static Bool 683 KdScreenInit(ScreenPtr pScreen, int argc, char **argv) 684 { 685 KdScreenInfo *screen = kdCurrentScreen; 686 KdCardInfo *card = screen->card; 687 KdPrivScreenPtr pScreenPriv; 688 689 /* 690 * note that screen->fb is set up for the nominal orientation 691 * of the screen; that means if randr is rotated, the values 692 * there should reflect a rotated frame buffer (or shadow). 693 */ 694 Bool rotated = (screen->randr & (RR_Rotate_90 | RR_Rotate_270)) != 0; 695 int width, height, *width_mmp, *height_mmp; 696 697 KdAllocatePrivates(pScreen); 698 699 pScreenPriv = KdGetScreenPriv(pScreen); 700 701 if (!rotated) { 702 width = screen->width; 703 height = screen->height; 704 width_mmp = &screen->width_mm; 705 height_mmp = &screen->height_mm; 706 } 707 else { 708 width = screen->height; 709 height = screen->width; 710 width_mmp = &screen->height_mm; 711 height_mmp = &screen->width_mm; 712 } 713 screen->pScreen = pScreen; 714 pScreenPriv->screen = screen; 715 pScreenPriv->card = card; 716 pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3; 717 pScreenPriv->dpmsState = KD_DPMS_NORMAL; 718 pScreen->x = screen->origin.x; 719 pScreen->y = screen->origin.y; 720 721 if (!monitorResolution) 722 monitorResolution = 75; 723 /* 724 * This is done in this order so that backing store wraps 725 * our GC functions; fbFinishScreenInit initializes MI 726 * backing store 727 */ 728 if (!fbSetupScreen(pScreen, 729 screen->fb.frameBuffer, 730 width, height, 731 monitorResolution, monitorResolution, 732 screen->fb.pixelStride, screen->fb.bitsPerPixel)) { 733 return FALSE; 734 } 735 736 /* 737 * Set colormap functions 738 */ 739 pScreen->InstallColormap = KdInstallColormap; 740 pScreen->UninstallColormap = KdUninstallColormap; 741 pScreen->ListInstalledColormaps = KdListInstalledColormaps; 742 pScreen->StoreColors = KdStoreColors; 743 744 pScreen->SaveScreen = KdSaveScreen; 745 pScreen->CreateWindow = KdCreateWindow; 746 747 if (!fbFinishScreenInit(pScreen, 748 screen->fb.frameBuffer, 749 width, height, 750 monitorResolution, monitorResolution, 751 screen->fb.pixelStride, screen->fb.bitsPerPixel)) { 752 return FALSE; 753 } 754 755 /* 756 * Fix screen sizes; for some reason mi takes dpi instead of mm. 757 * Rounding errors are annoying 758 */ 759 if (*width_mmp) 760 pScreen->mmWidth = *width_mmp; 761 else 762 *width_mmp = pScreen->mmWidth; 763 if (*height_mmp) 764 pScreen->mmHeight = *height_mmp; 765 else 766 *height_mmp = pScreen->mmHeight; 767 768 /* 769 * Plug in our own block/wakeup handlers. 770 * miScreenInit installs NoopDDA in both places 771 */ 772 pScreen->BlockHandler = KdBlockHandler; 773 pScreen->WakeupHandler = KdWakeupHandler; 774 775 if (!fbPictureInit(pScreen, 0, 0)) 776 return FALSE; 777 if (card->cfuncs->initScreen) 778 if (!(*card->cfuncs->initScreen) (pScreen)) 779 return FALSE; 780 781 if (!screen->dumb && card->cfuncs->initAccel) 782 if (!(*card->cfuncs->initAccel) (pScreen)) 783 screen->dumb = TRUE; 784 785 if (card->cfuncs->finishInitScreen) 786 if (!(*card->cfuncs->finishInitScreen) (pScreen)) 787 return FALSE; 788 789 /* 790 * Wrap CloseScreen, the order now is: 791 * KdCloseScreen 792 * fbCloseScreen 793 */ 794 pScreenPriv->CloseScreen = pScreen->CloseScreen; 795 pScreen->CloseScreen = KdCloseScreen; 796 797 pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; 798 pScreen->CreateScreenResources = KdCreateScreenResources; 799 800 if (screen->softCursor || 801 !card->cfuncs->initCursor || !(*card->cfuncs->initCursor) (pScreen)) { 802 /* Use MI for cursor display and event queueing. */ 803 screen->softCursor = TRUE; 804 miDCInitialize(pScreen, &kdPointerScreenFuncs); 805 } 806 807 if (!fbCreateDefColormap(pScreen)) { 808 return FALSE; 809 } 810 811 KdSetSubpixelOrder(pScreen, screen->randr); 812 813 /* 814 * Enable the hardware 815 */ 816 kdEnabled = TRUE; 817 818 if (screen->mynum == card->selected) { 819 pScreenPriv->enabled = TRUE; 820 KdEnableColormap(pScreen); 821 if (!screen->dumb && card->cfuncs->enableAccel) 822 (*card->cfuncs->enableAccel) (pScreen); 823 } 824 825 return TRUE; 826 } 827 828 static void 829 KdInitScreen(ScreenInfo * pScreenInfo, 830 KdScreenInfo * screen, int argc, char **argv) 831 { 832 KdCardInfo *card = screen->card; 833 834 if (!(*card->cfuncs->scrinit) (screen)) 835 FatalError("Screen initialization failed!\n"); 836 837 if (!card->cfuncs->initAccel) 838 screen->dumb = TRUE; 839 if (!card->cfuncs->initCursor) 840 screen->softCursor = TRUE; 841 } 842 843 static Bool 844 KdSetPixmapFormats(ScreenInfo * pScreenInfo) 845 { 846 CARD8 depthToBpp[33]; /* depth -> bpp map */ 847 KdCardInfo *card; 848 KdScreenInfo *screen; 849 int i; 850 int bpp; 851 PixmapFormatRec *format; 852 853 for (i = 1; i <= 32; i++) 854 depthToBpp[i] = 0; 855 856 /* 857 * Generate mappings between bitsPerPixel and depth, 858 * also ensure that all screens comply with protocol 859 * restrictions on equivalent formats for the same 860 * depth on different screens 861 */ 862 for (card = kdCardInfo; card; card = card->next) { 863 for (screen = card->screenList; screen; screen = screen->next) { 864 bpp = screen->fb.bitsPerPixel; 865 if (bpp == 24) 866 bpp = 32; 867 if (!depthToBpp[screen->fb.depth]) 868 depthToBpp[screen->fb.depth] = bpp; 869 else if (depthToBpp[screen->fb.depth] != bpp) 870 return FALSE; 871 } 872 } 873 874 /* 875 * Fill in additional formats 876 */ 877 for (i = 0; i < ARRAY_SIZE(kdDepths); i++) 878 if (!depthToBpp[kdDepths[i].depth]) 879 depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp; 880 881 pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; 882 pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; 883 pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; 884 pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; 885 886 pScreenInfo->numPixmapFormats = 0; 887 888 for (i = 1; i <= 32; i++) { 889 if (depthToBpp[i]) { 890 format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++]; 891 format->depth = i; 892 format->bitsPerPixel = depthToBpp[i]; 893 format->scanlinePad = BITMAP_SCANLINE_PAD; 894 } 895 } 896 897 return TRUE; 898 } 899 900 static void 901 KdAddScreen(ScreenInfo * pScreenInfo, 902 KdScreenInfo * screen, int argc, char **argv) 903 { 904 int i; 905 906 /* 907 * Fill in fb visual type masks for this screen 908 */ 909 for (i = 0; i < pScreenInfo->numPixmapFormats; i++) { 910 unsigned long visuals; 911 Pixel rm, gm, bm; 912 913 visuals = 0; 914 rm = gm = bm = 0; 915 if (pScreenInfo->formats[i].depth == screen->fb.depth) { 916 visuals = screen->fb.visuals; 917 rm = screen->fb.redMask; 918 gm = screen->fb.greenMask; 919 bm = screen->fb.blueMask; 920 } 921 fbSetVisualTypesAndMasks(pScreenInfo->formats[i].depth, 922 visuals, 8, rm, gm, bm); 923 } 924 925 kdCurrentScreen = screen; 926 927 AddScreen(KdScreenInit, argc, argv); 928 } 929 930 void 931 KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) 932 { 933 KdCardInfo *card; 934 KdScreenInfo *screen; 935 936 if (!kdCardInfo) { 937 InitCard(0); 938 if (!(card = KdCardInfoLast())) 939 FatalError("No matching cards found!\n"); 940 screen = KdScreenInfoAdd(card); 941 KdParseScreen(screen, 0); 942 } 943 /* 944 * Initialize all of the screens for all of the cards 945 */ 946 for (card = kdCardInfo; card; card = card->next) { 947 int ret = 1; 948 949 if (card->cfuncs->cardinit) 950 ret = (*card->cfuncs->cardinit) (card); 951 if (ret) { 952 for (screen = card->screenList; screen; screen = screen->next) 953 KdInitScreen(pScreenInfo, screen, argc, argv); 954 } 955 } 956 957 /* 958 * Merge the various pixmap formats together, this can fail 959 * when two screens share depth but not bitsPerPixel 960 */ 961 if (!KdSetPixmapFormats(pScreenInfo)) 962 return; 963 964 /* 965 * Add all of the screens 966 */ 967 for (card = kdCardInfo; card; card = card->next) 968 for (screen = card->screenList; screen; screen = screen->next) 969 KdAddScreen(pScreenInfo, screen, argc, argv); 970 971 xorgGlxCreateVendor(); 972 973 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 974 if (SeatId) /* Enable input hot-plugging */ 975 config_pre_init(); 976 #endif 977 } 978 979 void 980 OsVendorFatalError(const char *f, va_list args) 981 { 982 } 983 984 /* These stubs can be safely removed once we can 985 * split input and GPU parts in hotplug.h et al. */ 986 #ifdef CONFIG_UDEV_KMS 987 void 988 NewGPUDeviceRequest(struct OdevAttributes *attribs) 989 { 990 } 991 992 void 993 DeleteGPUDeviceRequest(struct OdevAttributes *attribs) 994 { 995 } 996 #endif 997 998 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 999 struct xf86_platform_device * 1000 xf86_find_platform_device_by_devnum(int major, int minor) 1001 { 1002 return NULL; 1003 } 1004 #endif 1005 1006 #ifdef SYSTEMD_LOGIND 1007 void 1008 systemd_logind_vtenter(void) 1009 { 1010 } 1011 1012 void 1013 systemd_logind_release_fd(int major, int minor, int fd) 1014 { 1015 close(fd); 1016 } 1017 #endif