xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

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