xserver

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

registry.c (8843B)


      1 /************************************************************
      2 
      3 Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 this permission notice appear in supporting documentation.  This permission
      8 notice shall be included in all copies or substantial portions of the
      9 Software.
     10 
     11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     12 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     14 AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     15 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     16 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     17 
     18 ********************************************************/
     19 
     20 #ifdef HAVE_DIX_CONFIG_H
     21 #include <dix-config.h>
     22 #endif
     23 
     24 #include <stdlib.h>
     25 #include <string.h>
     26 #include <X11/X.h>
     27 #include <X11/Xproto.h>
     28 #include "resource.h"
     29 #include "registry.h"
     30 
     31 #define BASE_SIZE 16
     32 
     33 #ifdef X_REGISTRY_REQUEST
     34 #define CORE "X11"
     35 #define FILENAME SERVER_MISC_CONFIG_PATH "/protocol.txt"
     36 
     37 #define PROT_COMMENT '#'
     38 #define PROT_REQUEST 'R'
     39 #define PROT_EVENT 'V'
     40 #define PROT_ERROR 'E'
     41 
     42 static FILE *fh;
     43 
     44 static char ***requests, **events, **errors;
     45 static unsigned nmajor, *nminor, nevent, nerror;
     46 #endif
     47 
     48 #ifdef X_REGISTRY_RESOURCE
     49 static const char **resources;
     50 static unsigned nresource;
     51 #endif
     52 
     53 #if defined(X_REGISTRY_RESOURCE) || defined(X_REGISTRY_REQUEST)
     54 /*
     55  * File parsing routines
     56  */
     57 static int
     58 double_size(void *p, unsigned n, unsigned size)
     59 {
     60     char **ptr = (char **) p;
     61     unsigned s, f;
     62 
     63     if (n) {
     64         s = n * size;
     65         n *= 2 * size;
     66         f = n;
     67     }
     68     else {
     69         s = 0;
     70         n = f = BASE_SIZE * size;
     71     }
     72 
     73     *ptr = realloc(*ptr, n);
     74     if (!*ptr) {
     75         dixResetRegistry();
     76         return FALSE;
     77     }
     78     memset(*ptr + s, 0, f - s);
     79     return TRUE;
     80 }
     81 #endif
     82 
     83 #ifdef X_REGISTRY_REQUEST
     84 /*
     85  * Request/event/error registry functions
     86  */
     87 static void
     88 RegisterRequestName(unsigned major, unsigned minor, char *name)
     89 {
     90     while (major >= nmajor) {
     91         if (!double_size(&requests, nmajor, sizeof(char **)))
     92             return;
     93         if (!double_size(&nminor, nmajor, sizeof(unsigned)))
     94             return;
     95         nmajor = nmajor ? nmajor * 2 : BASE_SIZE;
     96     }
     97     while (minor >= nminor[major]) {
     98         if (!double_size(requests + major, nminor[major], sizeof(char *)))
     99             return;
    100         nminor[major] = nminor[major] ? nminor[major] * 2 : BASE_SIZE;
    101     }
    102 
    103     free(requests[major][minor]);
    104     requests[major][minor] = name;
    105 }
    106 
    107 static void
    108 RegisterEventName(unsigned event, char *name)
    109 {
    110     while (event >= nevent) {
    111         if (!double_size(&events, nevent, sizeof(char *)))
    112             return;
    113         nevent = nevent ? nevent * 2 : BASE_SIZE;
    114     }
    115 
    116     free(events[event]);
    117     events[event] = name;
    118 }
    119 
    120 static void
    121 RegisterErrorName(unsigned error, char *name)
    122 {
    123     while (error >= nerror) {
    124         if (!double_size(&errors, nerror, sizeof(char *)))
    125             return;
    126         nerror = nerror ? nerror * 2 : BASE_SIZE;
    127     }
    128 
    129     free(errors[error]);
    130     errors[error] = name;
    131 }
    132 
    133 void
    134 RegisterExtensionNames(ExtensionEntry * extEntry)
    135 {
    136     char buf[256], *lineobj, *ptr;
    137     unsigned offset;
    138 
    139     if (fh == NULL)
    140         return;
    141 
    142     rewind(fh);
    143 
    144     while (fgets(buf, sizeof(buf), fh)) {
    145         lineobj = NULL;
    146         ptr = strchr(buf, '\n');
    147         if (ptr)
    148             *ptr = 0;
    149 
    150         /* Check for comments or empty lines */
    151         switch (buf[0]) {
    152         case PROT_REQUEST:
    153         case PROT_EVENT:
    154         case PROT_ERROR:
    155             break;
    156         case PROT_COMMENT:
    157         case '\0':
    158             continue;
    159         default:
    160             goto invalid;
    161         }
    162 
    163         /* Check for space character in the fifth position */
    164         ptr = strchr(buf, ' ');
    165         if (!ptr || ptr != buf + 4)
    166             goto invalid;
    167 
    168         /* Duplicate the string after the space */
    169         lineobj = strdup(ptr + 1);
    170         if (!lineobj)
    171             continue;
    172 
    173         /* Check for a colon somewhere on the line */
    174         ptr = strchr(buf, ':');
    175         if (!ptr)
    176             goto invalid;
    177 
    178         /* Compare the part before colon with the target extension name */
    179         *ptr = 0;
    180         if (strcmp(buf + 5, extEntry->name))
    181             goto skip;
    182 
    183         /* Get the opcode for the request, event, or error */
    184         offset = strtol(buf + 1, &ptr, 10);
    185         if (offset == 0 && ptr == buf + 1)
    186             goto invalid;
    187 
    188         /* Save the strdup result in the registry */
    189         switch (buf[0]) {
    190         case PROT_REQUEST:
    191             if (extEntry->base)
    192                 RegisterRequestName(extEntry->base, offset, lineobj);
    193             else
    194                 RegisterRequestName(offset, 0, lineobj);
    195             continue;
    196         case PROT_EVENT:
    197             RegisterEventName(extEntry->eventBase + offset, lineobj);
    198             continue;
    199         case PROT_ERROR:
    200             RegisterErrorName(extEntry->errorBase + offset, lineobj);
    201             continue;
    202         }
    203 
    204  invalid:
    205         LogMessage(X_WARNING, "Invalid line in " FILENAME ", skipping\n");
    206  skip:
    207         free(lineobj);
    208     }
    209 }
    210 
    211 const char *
    212 LookupRequestName(int major, int minor)
    213 {
    214     if (major >= nmajor)
    215         return XREGISTRY_UNKNOWN;
    216     if (minor >= nminor[major])
    217         return XREGISTRY_UNKNOWN;
    218 
    219     return requests[major][minor] ? requests[major][minor] : XREGISTRY_UNKNOWN;
    220 }
    221 
    222 const char *
    223 LookupMajorName(int major)
    224 {
    225     if (major < 128) {
    226         const char *retval;
    227 
    228         if (major >= nmajor)
    229             return XREGISTRY_UNKNOWN;
    230         if (0 >= nminor[major])
    231             return XREGISTRY_UNKNOWN;
    232 
    233         retval = requests[major][0];
    234         return retval ? retval + sizeof(CORE) : XREGISTRY_UNKNOWN;
    235     }
    236     else {
    237         ExtensionEntry *extEntry = GetExtensionEntry(major);
    238 
    239         return extEntry ? extEntry->name : XREGISTRY_UNKNOWN;
    240     }
    241 }
    242 
    243 const char *
    244 LookupEventName(int event)
    245 {
    246     event &= 127;
    247     if (event >= nevent)
    248         return XREGISTRY_UNKNOWN;
    249 
    250     return events[event] ? events[event] : XREGISTRY_UNKNOWN;
    251 }
    252 
    253 const char *
    254 LookupErrorName(int error)
    255 {
    256     if (error >= nerror)
    257         return XREGISTRY_UNKNOWN;
    258 
    259     return errors[error] ? errors[error] : XREGISTRY_UNKNOWN;
    260 }
    261 #endif /* X_REGISTRY_REQUEST */
    262 
    263 #ifdef X_REGISTRY_RESOURCE
    264 /*
    265  * Resource registry functions
    266  */
    267 
    268 void
    269 RegisterResourceName(RESTYPE resource, const char *name)
    270 {
    271     resource &= TypeMask;
    272 
    273     while (resource >= nresource) {
    274         if (!double_size(&resources, nresource, sizeof(char *)))
    275             return;
    276         nresource = nresource ? nresource * 2 : BASE_SIZE;
    277     }
    278 
    279     resources[resource] = name;
    280 }
    281 
    282 const char *
    283 LookupResourceName(RESTYPE resource)
    284 {
    285     resource &= TypeMask;
    286     if (resource >= nresource)
    287         return XREGISTRY_UNKNOWN;
    288 
    289     return resources[resource] ? resources[resource] : XREGISTRY_UNKNOWN;
    290 }
    291 #endif /* X_REGISTRY_RESOURCE */
    292 
    293 void
    294 dixFreeRegistry(void)
    295 {
    296 #ifdef X_REGISTRY_REQUEST
    297     /* Free all memory */
    298     while (nmajor--) {
    299         while (nminor[nmajor])
    300             free(requests[nmajor][--nminor[nmajor]]);
    301         free(requests[nmajor]);
    302     }
    303     free(requests);
    304     free(nminor);
    305 
    306     while (nevent--)
    307         free(events[nevent]);
    308     free(events);
    309 
    310     while (nerror--)
    311         free(errors[nerror]);
    312     free(errors);
    313     requests = NULL;
    314     nminor = NULL;
    315     events = NULL;
    316     errors = NULL;
    317     nmajor = nevent = nerror = 0;
    318 #endif
    319 
    320 #ifdef X_REGISTRY_RESOURCE
    321     free(resources);
    322 
    323     resources = NULL;
    324     nresource = 0;
    325 #endif
    326 }
    327 
    328 void
    329 dixCloseRegistry(void)
    330 {
    331 #ifdef X_REGISTRY_REQUEST
    332     if (fh) {
    333 	fclose(fh);
    334         fh = NULL;
    335     }
    336 #endif
    337 }
    338 
    339 /*
    340  * Setup and teardown
    341  */
    342 void
    343 dixResetRegistry(void)
    344 {
    345 #ifdef X_REGISTRY_REQUEST
    346     ExtensionEntry extEntry = { .name = CORE };
    347 #endif
    348 
    349     dixFreeRegistry();
    350 
    351 #ifdef X_REGISTRY_REQUEST
    352     /* Open the protocol file */
    353     fh = fopen(FILENAME, "r");
    354     if (!fh)
    355         LogMessage(X_WARNING,
    356                    "Failed to open protocol names file " FILENAME "\n");
    357 
    358     /* Add the core protocol */
    359     RegisterExtensionNames(&extEntry);
    360 #endif
    361 
    362 #ifdef X_REGISTRY_RESOURCE
    363     /* Add built-in resources */
    364     RegisterResourceName(RT_NONE, "NONE");
    365     RegisterResourceName(RT_WINDOW, "WINDOW");
    366     RegisterResourceName(RT_PIXMAP, "PIXMAP");
    367     RegisterResourceName(RT_GC, "GC");
    368     RegisterResourceName(RT_FONT, "FONT");
    369     RegisterResourceName(RT_CURSOR, "CURSOR");
    370     RegisterResourceName(RT_COLORMAP, "COLORMAP");
    371     RegisterResourceName(RT_CMAPENTRY, "COLORMAP ENTRY");
    372     RegisterResourceName(RT_OTHERCLIENT, "OTHER CLIENT");
    373     RegisterResourceName(RT_PASSIVEGRAB, "PASSIVE GRAB");
    374 #endif
    375 }