1 /************************************************************
3 Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
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
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.
18 ********************************************************/
20 #ifdef HAVE_DIX_CONFIG_H
21 #include <dix-config.h>
29 #include <X11/Xproto.h>
35 #define FILENAME SERVER_MISC_CONFIG_PATH "/protocol.txt"
37 #define PROT_COMMENT '#'
38 #define PROT_REQUEST 'R'
39 #define PROT_EVENT 'V'
40 #define PROT_ERROR 'E'
44 static char ***requests, **events, **errors, **resources;
45 static unsigned nmajor, *nminor, nevent, nerror, nresource;
48 * File parsing routines
50 static int double_size(void *p, unsigned n, unsigned size)
52 char **ptr = (char **)p;
61 n = f = BASE_SIZE * size;
64 *ptr = realloc(*ptr, n);
69 memset(*ptr + s, 0, f - s);
74 RegisterRequestName(unsigned major, unsigned minor, char *name)
76 while (major >= nmajor) {
77 if (!double_size(&requests, nmajor, sizeof(char **)))
79 if (!double_size(&nminor, nmajor, sizeof(unsigned)))
81 nmajor = nmajor ? nmajor * 2 : BASE_SIZE;
83 while (minor >= nminor[major]) {
84 if (!double_size(requests+major, nminor[major], sizeof(char *)))
86 nminor[major] = nminor[major] ? nminor[major] * 2 : BASE_SIZE;
89 free(requests[major][minor]);
90 requests[major][minor] = name;
94 RegisterEventName(unsigned event, char *name) {
95 while (event >= nevent) {
96 if (!double_size(&events, nevent, sizeof(char *)))
98 nevent = nevent ? nevent * 2 : BASE_SIZE;
102 events[event] = name;
106 RegisterErrorName(unsigned error, char *name) {
107 while (error >= nerror) {
108 if (!double_size(&errors, nerror, sizeof(char *)))
110 nerror = nerror ? nerror * 2 : BASE_SIZE;
114 errors[error] = name;
118 RegisterExtensionNames(ExtensionEntry *extEntry)
120 char buf[256], *lineobj, *ptr;
128 while (fgets(buf, sizeof(buf), fh)) {
130 ptr = strchr(buf, '\n');
134 /* Check for comments or empty lines */
147 /* Check for space character in the fifth position */
148 ptr = strchr(buf, ' ');
149 if (!ptr || ptr != buf + 4)
152 /* Duplicate the string after the space */
153 lineobj = strdup(ptr + 1);
157 /* Check for a colon somewhere on the line */
158 ptr = strchr(buf, ':');
162 /* Compare the part before colon with the target extension name */
164 if (strcmp(buf + 5, extEntry->name))
167 /* Get the opcode for the request, event, or error */
168 offset = strtol(buf + 1, &ptr, 10);
169 if (offset == 0 && ptr == buf + 1)
172 /* Save the strdup result in the registry */
176 RegisterRequestName(extEntry->base, offset, lineobj);
178 RegisterRequestName(offset, 0, lineobj);
181 RegisterEventName(extEntry->eventBase + offset, lineobj);
184 RegisterErrorName(extEntry->errorBase + offset, lineobj);
189 LogMessage(X_WARNING, "Invalid line in " FILENAME ", skipping\n");
196 * Registration functions
200 RegisterResourceName(RESTYPE resource, char *name)
202 resource &= TypeMask;
204 while (resource >= nresource) {
205 if (!double_size(&resources, nresource, sizeof(char *)))
207 nresource = nresource ? nresource * 2 : BASE_SIZE;
210 resources[resource] = name;
218 LookupRequestName(int major, int minor)
221 return XREGISTRY_UNKNOWN;
222 if (minor >= nminor[major])
223 return XREGISTRY_UNKNOWN;
225 return requests[major][minor] ? requests[major][minor] : XREGISTRY_UNKNOWN;
229 LookupMajorName(int major)
235 return XREGISTRY_UNKNOWN;
236 if (0 >= nminor[major])
237 return XREGISTRY_UNKNOWN;
239 retval = requests[major][0];
240 return retval ? retval + sizeof(CORE) : XREGISTRY_UNKNOWN;
242 ExtensionEntry *extEntry = GetExtensionEntry(major);
243 return extEntry ? extEntry->name : XREGISTRY_UNKNOWN;
248 LookupEventName(int event)
252 return XREGISTRY_UNKNOWN;
254 return events[event] ? events[event] : XREGISTRY_UNKNOWN;
258 LookupErrorName(int error)
261 return XREGISTRY_UNKNOWN;
263 return errors[error] ? errors[error] : XREGISTRY_UNKNOWN;
267 LookupResourceName(RESTYPE resource)
269 resource &= TypeMask;
270 if (resource >= nresource)
271 return XREGISTRY_UNKNOWN;
273 return resources[resource] ? resources[resource] : XREGISTRY_UNKNOWN;
280 dixResetRegistry(void)
282 ExtensionEntry extEntry;
284 /* Free all memory */
286 while (nminor[nmajor])
287 free(requests[nmajor][--nminor[nmajor]]);
288 free(requests[nmajor]);
294 free(events[nevent]);
298 free(errors[nerror]);
309 nmajor = nevent = nerror = nresource = 0;
311 /* Open the protocol file */
314 fh = fopen(FILENAME, "r");
316 LogMessage(X_WARNING, "Failed to open protocol names file " FILENAME "\n");
318 /* Add built-in resources */
319 RegisterResourceName(RT_NONE, "NONE");
320 RegisterResourceName(RT_WINDOW, "WINDOW");
321 RegisterResourceName(RT_PIXMAP, "PIXMAP");
322 RegisterResourceName(RT_GC, "GC");
323 RegisterResourceName(RT_FONT, "FONT");
324 RegisterResourceName(RT_CURSOR, "CURSOR");
325 RegisterResourceName(RT_COLORMAP, "COLORMAP");
326 RegisterResourceName(RT_CMAPENTRY, "COLORMAP ENTRY");
327 RegisterResourceName(RT_OTHERCLIENT, "OTHER CLIENT");
328 RegisterResourceName(RT_PASSIVEGRAB, "PASSIVE GRAB");
330 /* Add the core protocol */
331 memset(&extEntry, 0, sizeof(extEntry));
332 extEntry.name = CORE;
333 RegisterExtensionNames(&extEntry);
336 #endif /* XREGISTRY */