xserver

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

xf86AutoConfig.c (12900B)


      1 /*
      2  * Copyright 2003 by David H. Dawes.
      3  * Copyright 2003 by X-Oz Technologies.
      4  * All rights reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Except as contained in this notice, the name of the copyright holder(s)
     25  * and author(s) shall not be used in advertising or otherwise to promote
     26  * the sale, use or other dealings in this Software without prior written
     27  * authorization from the copyright holder(s) and author(s).
     28  *
     29  * Author: David Dawes <dawes@XFree86.Org>.
     30  */
     31 
     32 #ifdef HAVE_XORG_CONFIG_H
     33 #include <xorg-config.h>
     34 #endif
     35 
     36 #include "xf86.h"
     37 #include "xf86Parser.h"
     38 #include "xf86tokens.h"
     39 #include "xf86Config.h"
     40 #include "xf86MatchDrivers.h"
     41 #include "xf86Priv.h"
     42 #include "xf86_OSlib.h"
     43 #include "xf86platformBus.h"
     44 #include "xf86pciBus.h"
     45 #ifdef __sparc__
     46 #include "xf86sbusBus.h"
     47 #endif
     48 
     49 #ifdef __sun
     50 #include <sys/visual_io.h>
     51 #include <ctype.h>
     52 #endif
     53 
     54 /* Sections for the default built-in configuration. */
     55 
     56 #define BUILTIN_DEVICE_NAME \
     57 	"\"Builtin Default %s Device %d\""
     58 
     59 #define BUILTIN_DEVICE_SECTION_PRE \
     60 	"Section \"Device\"\n" \
     61 	"\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
     62 	"\tDriver\t\"%s\"\n"
     63 
     64 #define BUILTIN_DEVICE_SECTION_POST \
     65 	"EndSection\n\n"
     66 
     67 #define BUILTIN_DEVICE_SECTION \
     68 	BUILTIN_DEVICE_SECTION_PRE \
     69 	BUILTIN_DEVICE_SECTION_POST
     70 
     71 #define BUILTIN_SCREEN_NAME \
     72 	"\"Builtin Default %s Screen %d\""
     73 
     74 #define BUILTIN_SCREEN_SECTION \
     75 	"Section \"Screen\"\n" \
     76 	"\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
     77 	"\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
     78 	"EndSection\n\n"
     79 
     80 #define BUILTIN_LAYOUT_SECTION_PRE \
     81 	"Section \"ServerLayout\"\n" \
     82 	"\tIdentifier\t\"Builtin Default Layout\"\n"
     83 
     84 #define BUILTIN_LAYOUT_SCREEN_LINE \
     85 	"\tScreen\t" BUILTIN_SCREEN_NAME "\n"
     86 
     87 #define BUILTIN_LAYOUT_SECTION_POST \
     88 	"EndSection\n\n"
     89 
     90 static const char **builtinConfig = NULL;
     91 static int builtinLines = 0;
     92 
     93 static void listPossibleVideoDrivers(XF86MatchedDrivers *md);
     94 
     95 /*
     96  * A built-in config file is stored as an array of strings, with each string
     97  * representing a single line.  AppendToConfig() breaks up the string "s"
     98  * into lines, and appends those lines it to builtinConfig.
     99  */
    100 
    101 static void
    102 AppendToList(const char *s, const char ***list, int *lines)
    103 {
    104     char *str, *newstr, *p;
    105 
    106     str = xnfstrdup(s);
    107     for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
    108         (*lines)++;
    109         *list = xnfreallocarray(*list, *lines + 1, sizeof(**list));
    110         newstr = xnfalloc(strlen(p) + 2);
    111         strcpy(newstr, p);
    112         strcat(newstr, "\n");
    113         (*list)[*lines - 1] = newstr;
    114         (*list)[*lines] = NULL;
    115     }
    116     free(str);
    117 }
    118 
    119 static void
    120 FreeList(const char ***list, int *lines)
    121 {
    122     int i;
    123 
    124     for (i = 0; i < *lines; i++) {
    125         free((char *) ((*list)[i]));
    126     }
    127     free(*list);
    128     *list = NULL;
    129     *lines = 0;
    130 }
    131 
    132 static void
    133 FreeConfig(void)
    134 {
    135     FreeList(&builtinConfig, &builtinLines);
    136 }
    137 
    138 static void
    139 AppendToConfig(const char *s)
    140 {
    141     AppendToList(s, &builtinConfig, &builtinLines);
    142 }
    143 
    144 void
    145 xf86AddMatchedDriver(XF86MatchedDrivers *md, const char *driver)
    146 {
    147     int j;
    148     int nmatches = md->nmatches;
    149 
    150     for (j = 0; j < nmatches; ++j) {
    151         if (xf86NameCmp(md->matches[j], driver) == 0) {
    152             // Driver already in matched drivers
    153             return;
    154         }
    155     }
    156 
    157     if (nmatches < MATCH_DRIVERS_LIMIT) {
    158         md->matches[nmatches] = xnfstrdup(driver);
    159         md->nmatches++;
    160     }
    161     else {
    162         xf86Msg(X_WARNING, "Too many drivers registered, can't add %s\n", driver);
    163     }
    164 }
    165 
    166 Bool
    167 xf86AutoConfig(void)
    168 {
    169     XF86MatchedDrivers md;
    170     int i;
    171     const char **cp;
    172     char buf[1024];
    173     ConfigStatus ret;
    174 
    175     /* Make sure config rec is there */
    176     if (xf86allocateConfig() != NULL) {
    177         ret = CONFIG_OK;    /* OK so far */
    178     }
    179     else {
    180         xf86Msg(X_ERROR, "Couldn't allocate Config record.\n");
    181         return FALSE;
    182     }
    183 
    184     listPossibleVideoDrivers(&md);
    185 
    186     for (i = 0; i < md.nmatches; i++) {
    187         snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION,
    188                 md.matches[i], 0, md.matches[i]);
    189         AppendToConfig(buf);
    190         snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION,
    191                 md.matches[i], 0, md.matches[i], 0);
    192         AppendToConfig(buf);
    193     }
    194 
    195     AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
    196     for (i = 0; i < md.nmatches; i++) {
    197         snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE,
    198                 md.matches[i], 0);
    199         AppendToConfig(buf);
    200     }
    201     AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
    202 
    203     for (i = 0; i < md.nmatches; i++) {
    204         free(md.matches[i]);
    205     }
    206 
    207     xf86MsgVerb(X_DEFAULT, 0,
    208                 "Using default built-in configuration (%d lines)\n",
    209                 builtinLines);
    210 
    211     xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
    212     for (cp = builtinConfig; *cp; cp++)
    213         xf86ErrorFVerb(3, "\t%s", *cp);
    214     xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
    215 
    216     xf86initConfigFiles();
    217     xf86setBuiltinConfig(builtinConfig);
    218     ret = xf86HandleConfigFile(TRUE);
    219     FreeConfig();
    220 
    221     if (ret != CONFIG_OK)
    222         xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
    223 
    224     return ret == CONFIG_OK;
    225 }
    226 
    227 static void
    228 listPossibleVideoDrivers(XF86MatchedDrivers *md)
    229 {
    230     md->nmatches = 0;
    231 
    232 #ifdef XSERVER_PLATFORM_BUS
    233     xf86PlatformMatchDriver(md);
    234 #endif
    235 #ifdef __sun
    236     /* Check for driver type based on /dev/fb type and if valid, use
    237        it instead of PCI bus probe results */
    238     if (xf86Info.consoleFd >= 0) {
    239         struct vis_identifier visid;
    240         const char *cp;
    241         int iret;
    242 
    243         SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
    244         if (iret < 0) {
    245             int fbfd;
    246 
    247             fbfd = open(xf86SolarisFbDev, O_RDONLY);
    248             if (fbfd >= 0) {
    249                 SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
    250                 close(fbfd);
    251             }
    252         }
    253 
    254         if (iret < 0) {
    255             xf86Msg(X_WARNING,
    256                     "could not get frame buffer identifier from %s\n",
    257                     xf86SolarisFbDev);
    258         }
    259         else {
    260             xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
    261 
    262             /* Special case from before the general case was set */
    263             if (strcmp(visid.name, "NVDAnvda") == 0) {
    264                 xf86AddMatchedDriver(md, "nvidia");
    265             }
    266 
    267             /* General case - split into vendor name (initial all-caps
    268                prefix) & driver name (rest of the string). */
    269             if (strcmp(visid.name, "SUNWtext") != 0) {
    270                 for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
    271                     /* find end of all uppercase vendor section */
    272                 }
    273                 if ((cp != visid.name) && (*cp != '\0')) {
    274                     char *vendorName = xnfstrdup(visid.name);
    275 
    276                     vendorName[cp - visid.name] = '\0';
    277 
    278                     xf86AddMatchedDriver(md, vendorName);
    279                     xf86AddMatchedDriver(md, cp);
    280 
    281                     free(vendorName);
    282                 }
    283             }
    284         }
    285     }
    286 #endif
    287 #ifdef __sparc__
    288     char *sbusDriver = sparcDriverName();
    289 
    290     if (sbusDriver)
    291         xf86AddMatchedDriver(md, sbusDriver);
    292 #endif
    293 #ifdef XSERVER_LIBPCIACCESS
    294     xf86PciMatchDriver(md);
    295 #endif
    296 
    297 #if defined(__linux__)
    298     xf86AddMatchedDriver(md, "modesetting");
    299 #endif
    300 
    301 #if !defined(__sun)
    302     /* Fallback to platform default frame buffer driver */
    303 #if !defined(__linux__) && defined(__sparc__)
    304     xf86AddMatchedDriver(md, "wsfb");
    305 #else
    306     xf86AddMatchedDriver(md, "fbdev");
    307 #endif
    308 #endif                          /* !__sun */
    309 
    310     /* Fallback to platform default hardware */
    311 #if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
    312     xf86AddMatchedDriver(md, "vesa");
    313 #elif defined(__sparc__) && !defined(__sun)
    314     xf86AddMatchedDriver(md, "sunffb");
    315 #endif
    316 }
    317 
    318 /* copy a screen section and enter the desired driver
    319  * and insert it at i in the list of screens */
    320 static Bool
    321 copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
    322 {
    323     confScreenPtr nscreen;
    324     GDevPtr cptr = NULL;
    325     char *identifier;
    326 
    327     nscreen = malloc(sizeof(confScreenRec));
    328     if (!nscreen)
    329         return FALSE;
    330     memcpy(nscreen, oscreen, sizeof(confScreenRec));
    331 
    332     cptr = malloc(sizeof(GDevRec));
    333     if (!cptr) {
    334         free(nscreen);
    335         return FALSE;
    336     }
    337     memcpy(cptr, odev, sizeof(GDevRec));
    338 
    339     if (asprintf(&identifier, "Autoconfigured Video Device %s", driver)
    340         == -1) {
    341         free(cptr);
    342         free(nscreen);
    343         return FALSE;
    344     }
    345     cptr->driver = driver;
    346     cptr->identifier = identifier;
    347 
    348     xf86ConfigLayout.screens[i].screen = nscreen;
    349 
    350     /* now associate the new driver entry with the new screen entry */
    351     xf86ConfigLayout.screens[i].screen->device = cptr;
    352     cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
    353 
    354     return TRUE;
    355 }
    356 
    357 GDevPtr
    358 autoConfigDevice(GDevPtr preconf_device)
    359 {
    360     GDevPtr ptr = NULL;
    361     XF86MatchedDrivers md;
    362     int num_screens = 0, i;
    363     screenLayoutPtr slp;
    364 
    365     if (!xf86configptr) {
    366         return NULL;
    367     }
    368 
    369     /* If there's a configured section with no driver chosen, use it */
    370     if (preconf_device) {
    371         ptr = preconf_device;
    372     }
    373     else {
    374         ptr = calloc(1, sizeof(GDevRec));
    375         if (!ptr) {
    376             return NULL;
    377         }
    378         ptr->chipID = -1;
    379         ptr->chipRev = -1;
    380         ptr->irq = -1;
    381 
    382         ptr->active = TRUE;
    383         ptr->claimed = FALSE;
    384         ptr->identifier = "Autoconfigured Video Device";
    385         ptr->driver = NULL;
    386     }
    387     if (!ptr->driver) {
    388         /* get all possible video drivers and count them */
    389         listPossibleVideoDrivers(&md);
    390         for (i = 0; i < md.nmatches; i++) {
    391             xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
    392                     md.matches[i], i);
    393         }
    394 
    395         slp = xf86ConfigLayout.screens;
    396         if (slp) {
    397             /* count the number of screens and make space for
    398              * a new screen for each additional possible driver
    399              * minus one for the already existing first one
    400              * plus one for the terminating NULL */
    401             for (; slp[num_screens].screen; num_screens++);
    402             xf86ConfigLayout.screens = xnfcalloc(num_screens + md.nmatches,
    403                                                  sizeof(screenLayoutRec));
    404             xf86ConfigLayout.screens[0] = slp[0];
    405 
    406             /* do the first match and set that for the original first screen */
    407             ptr->driver = md.matches[0];
    408             if (!xf86ConfigLayout.screens[0].screen->device) {
    409                 xf86ConfigLayout.screens[0].screen->device = ptr;
    410                 ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
    411             }
    412 
    413             /* for each other driver found, copy the first screen, insert it
    414              * into the list of screens and set the driver */
    415             for (i = 1; i < md.nmatches; i++) {
    416                 if (!copyScreen(slp[0].screen, ptr, i, md.matches[i]))
    417                     return NULL;
    418             }
    419 
    420             /* shift the rest of the original screen list
    421              * to the end of the current screen list
    422              *
    423              * TODO Handle rest of multiple screen sections */
    424             for (i = 1; i < num_screens; i++) {
    425                 xf86ConfigLayout.screens[i + md.nmatches] = slp[i];
    426             }
    427             xf86ConfigLayout.screens[num_screens + md.nmatches - 1].screen =
    428                 NULL;
    429             free(slp);
    430         }
    431         else {
    432             /* layout does not have any screens, not much to do */
    433             ptr->driver = md.matches[0];
    434             for (i = 1; i < md.nmatches; i++) {
    435                 free(md.matches[i]);
    436             }
    437         }
    438     }
    439 
    440     xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
    441 
    442     return ptr;
    443 }