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
;
45 static const char **resources
;
46 static unsigned nmajor
, *nminor
, nevent
, nerror
, nresource
;
49 * File parsing routines
52 double_size(void *p
, unsigned n
, unsigned size
)
54 char **ptr
= (char **) p
;
64 n
= f
= BASE_SIZE
* size
;
67 *ptr
= realloc(*ptr
, n
);
72 memset(*ptr
+ s
, 0, f
- s
);
77 RegisterRequestName(unsigned major
, unsigned minor
, char *name
)
79 while (major
>= nmajor
) {
80 if (!double_size(&requests
, nmajor
, sizeof(char **)))
82 if (!double_size(&nminor
, nmajor
, sizeof(unsigned)))
84 nmajor
= nmajor
? nmajor
* 2 : BASE_SIZE
;
86 while (minor
>= nminor
[major
]) {
87 if (!double_size(requests
+ major
, nminor
[major
], sizeof(char *)))
89 nminor
[major
] = nminor
[major
] ? nminor
[major
] * 2 : BASE_SIZE
;
92 free(requests
[major
][minor
]);
93 requests
[major
][minor
] = name
;
97 RegisterEventName(unsigned event
, char *name
)
99 while (event
>= nevent
) {
100 if (!double_size(&events
, nevent
, sizeof(char *)))
102 nevent
= nevent
? nevent
* 2 : BASE_SIZE
;
106 events
[event
] = name
;
110 RegisterErrorName(unsigned error
, char *name
)
112 while (error
>= nerror
) {
113 if (!double_size(&errors
, nerror
, sizeof(char *)))
115 nerror
= nerror
? nerror
* 2 : BASE_SIZE
;
119 errors
[error
] = name
;
123 RegisterExtensionNames(ExtensionEntry
* extEntry
)
125 char buf
[256], *lineobj
, *ptr
;
133 while (fgets(buf
, sizeof(buf
), fh
)) {
135 ptr
= strchr(buf
, '\n');
139 /* Check for comments or empty lines */
152 /* Check for space character in the fifth position */
153 ptr
= strchr(buf
, ' ');
154 if (!ptr
|| ptr
!= buf
+ 4)
157 /* Duplicate the string after the space */
158 lineobj
= strdup(ptr
+ 1);
162 /* Check for a colon somewhere on the line */
163 ptr
= strchr(buf
, ':');
167 /* Compare the part before colon with the target extension name */
169 if (strcmp(buf
+ 5, extEntry
->name
))
172 /* Get the opcode for the request, event, or error */
173 offset
= strtol(buf
+ 1, &ptr
, 10);
174 if (offset
== 0 && ptr
== buf
+ 1)
177 /* Save the strdup result in the registry */
181 RegisterRequestName(extEntry
->base
, offset
, lineobj
);
183 RegisterRequestName(offset
, 0, lineobj
);
186 RegisterEventName(extEntry
->eventBase
+ offset
, lineobj
);
189 RegisterErrorName(extEntry
->errorBase
+ offset
, lineobj
);
194 LogMessage(X_WARNING
, "Invalid line in " FILENAME
", skipping\n");
201 * Registration functions
205 RegisterResourceName(RESTYPE resource
, const char *name
)
207 resource
&= TypeMask
;
209 while (resource
>= nresource
) {
210 if (!double_size(&resources
, nresource
, sizeof(char *)))
212 nresource
= nresource
? nresource
* 2 : BASE_SIZE
;
215 resources
[resource
] = name
;
223 LookupRequestName(int major
, int minor
)
226 return XREGISTRY_UNKNOWN
;
227 if (minor
>= nminor
[major
])
228 return XREGISTRY_UNKNOWN
;
230 return requests
[major
][minor
] ? requests
[major
][minor
] : XREGISTRY_UNKNOWN
;
234 LookupMajorName(int major
)
240 return XREGISTRY_UNKNOWN
;
241 if (0 >= nminor
[major
])
242 return XREGISTRY_UNKNOWN
;
244 retval
= requests
[major
][0];
245 return retval
? retval
+ sizeof(CORE
) : XREGISTRY_UNKNOWN
;
248 ExtensionEntry
*extEntry
= GetExtensionEntry(major
);
250 return extEntry
? extEntry
->name
: XREGISTRY_UNKNOWN
;
255 LookupEventName(int event
)
259 return XREGISTRY_UNKNOWN
;
261 return events
[event
] ? events
[event
] : XREGISTRY_UNKNOWN
;
265 LookupErrorName(int error
)
268 return XREGISTRY_UNKNOWN
;
270 return errors
[error
] ? errors
[error
] : XREGISTRY_UNKNOWN
;
274 LookupResourceName(RESTYPE resource
)
276 resource
&= TypeMask
;
277 if (resource
>= nresource
)
278 return XREGISTRY_UNKNOWN
;
280 return resources
[resource
] ? resources
[resource
] : XREGISTRY_UNKNOWN
;
284 dixFreeRegistry(void)
286 /* Free all memory */
288 while (nminor
[nmajor
])
289 free(requests
[nmajor
][--nminor
[nmajor
]]);
290 free(requests
[nmajor
]);
296 free(events
[nevent
]);
300 free(errors
[nerror
]);
311 nmajor
= nevent
= nerror
= nresource
= 0;
323 dixResetRegistry(void)
325 ExtensionEntry extEntry
= { .name
= CORE
};
329 /* Open the protocol file */
330 fh
= fopen(FILENAME
, "r");
332 LogMessage(X_WARNING
,
333 "Failed to open protocol names file " FILENAME
"\n");
335 /* Add built-in resources */
336 RegisterResourceName(RT_NONE
, "NONE");
337 RegisterResourceName(RT_WINDOW
, "WINDOW");
338 RegisterResourceName(RT_PIXMAP
, "PIXMAP");
339 RegisterResourceName(RT_GC
, "GC");
340 RegisterResourceName(RT_FONT
, "FONT");
341 RegisterResourceName(RT_CURSOR
, "CURSOR");
342 RegisterResourceName(RT_COLORMAP
, "COLORMAP");
343 RegisterResourceName(RT_CMAPENTRY
, "COLORMAP ENTRY");
344 RegisterResourceName(RT_OTHERCLIENT
, "OTHER CLIENT");
345 RegisterResourceName(RT_PASSIVEGRAB
, "PASSIVE GRAB");
347 /* Add the core protocol */
348 RegisterExtensionNames(&extEntry
);
351 #endif /* XREGISTRY */