Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / parser / InputClass.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright (c) 2009 Dan Nicholson
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifdef HAVE_XORG_CONFIG_H
27#include <xorg-config.h>
28#endif
29
30#include <string.h>
31#include "os.h"
32#include "xf86Parser.h"
33#include "xf86tokens.h"
34#include "Configint.h"
35
36extern LexRec val;
37
38static
39xf86ConfigSymTabRec InputClassTab[] = {
40 {ENDSECTION, "endsection"},
41 {IDENTIFIER, "identifier"},
42 {OPTION, "option"},
43 {DRIVER, "driver"},
44 {MATCH_PRODUCT, "matchproduct"},
45 {MATCH_VENDOR, "matchvendor"},
46 {MATCH_DEVICE_PATH, "matchdevicepath"},
47 {MATCH_OS, "matchos"},
48 {MATCH_PNPID, "matchpnpid"},
49 {MATCH_USBID, "matchusbid"},
50 {MATCH_DRIVER, "matchdriver"},
51 {MATCH_TAG, "matchtag"},
52 {MATCH_LAYOUT, "matchlayout"},
53 {MATCH_IS_KEYBOARD, "matchiskeyboard"},
54 {MATCH_IS_POINTER, "matchispointer"},
55 {MATCH_IS_JOYSTICK, "matchisjoystick"},
56 {MATCH_IS_TABLET, "matchistablet"},
57 {MATCH_IS_TOUCHPAD, "matchistouchpad"},
58 {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"},
59 {-1, ""},
60};
61
62#define CLEANUP xf86freeInputClassList
63
64#define TOKEN_SEP "|"
65
66static void
67add_group_entry(struct xorg_list *head, char **values)
68{
69 xf86MatchGroup *group;
70
71 group = malloc(sizeof(*group));
72 if (group) {
73 group->values = values;
74 xorg_list_add(&group->entry, head);
75 }
76}
77
78XF86ConfInputClassPtr
79xf86parseInputClassSection(void)
80{
81 int has_ident = FALSE;
82 int token;
83
84 parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
85
86 /* Initialize MatchGroup lists */
87 xorg_list_init(&ptr->match_product);
88 xorg_list_init(&ptr->match_vendor);
89 xorg_list_init(&ptr->match_device);
90 xorg_list_init(&ptr->match_os);
91 xorg_list_init(&ptr->match_pnpid);
92 xorg_list_init(&ptr->match_usbid);
93 xorg_list_init(&ptr->match_driver);
94 xorg_list_init(&ptr->match_tag);
95 xorg_list_init(&ptr->match_layout);
96
97 while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
98 switch (token) {
99 case COMMENT:
100 ptr->comment = xf86addComment(ptr->comment, val.str);
101 break;
102 case IDENTIFIER:
103 if (xf86getSubToken(&(ptr->comment)) != STRING)
104 Error(QUOTE_MSG, "Identifier");
105 if (has_ident == TRUE)
106 Error(MULTIPLE_MSG, "Identifier");
107 ptr->identifier = val.str;
108 has_ident = TRUE;
109 break;
110 case DRIVER:
111 if (xf86getSubToken(&(ptr->comment)) != STRING)
112 Error(QUOTE_MSG, "Driver");
113 if (strcmp(val.str, "keyboard") == 0) {
114 ptr->driver = strdup("kbd");
115 free(val.str);
116 }
117 else
118 ptr->driver = val.str;
119 break;
120 case OPTION:
121 ptr->option_lst = xf86parseOption(ptr->option_lst);
122 break;
123 case MATCH_PRODUCT:
124 if (xf86getSubToken(&(ptr->comment)) != STRING)
125 Error(QUOTE_MSG, "MatchProduct");
126 add_group_entry(&ptr->match_product,
127 xstrtokenize(val.str, TOKEN_SEP));
128 free(val.str);
129 break;
130 case MATCH_VENDOR:
131 if (xf86getSubToken(&(ptr->comment)) != STRING)
132 Error(QUOTE_MSG, "MatchVendor");
133 add_group_entry(&ptr->match_vendor,
134 xstrtokenize(val.str, TOKEN_SEP));
135 free(val.str);
136 break;
137 case MATCH_DEVICE_PATH:
138 if (xf86getSubToken(&(ptr->comment)) != STRING)
139 Error(QUOTE_MSG, "MatchDevicePath");
140 add_group_entry(&ptr->match_device,
141 xstrtokenize(val.str, TOKEN_SEP));
142 free(val.str);
143 break;
144 case MATCH_OS:
145 if (xf86getSubToken(&(ptr->comment)) != STRING)
146 Error(QUOTE_MSG, "MatchOS");
147 add_group_entry(&ptr->match_os, xstrtokenize(val.str, TOKEN_SEP));
148 free(val.str);
149 break;
150 case MATCH_PNPID:
151 if (xf86getSubToken(&(ptr->comment)) != STRING)
152 Error(QUOTE_MSG, "MatchPnPID");
153 add_group_entry(&ptr->match_pnpid,
154 xstrtokenize(val.str, TOKEN_SEP));
155 free(val.str);
156 break;
157 case MATCH_USBID:
158 if (xf86getSubToken(&(ptr->comment)) != STRING)
159 Error(QUOTE_MSG, "MatchUSBID");
160 add_group_entry(&ptr->match_usbid,
161 xstrtokenize(val.str, TOKEN_SEP));
162 free(val.str);
163 break;
164 case MATCH_DRIVER:
165 if (xf86getSubToken(&(ptr->comment)) != STRING)
166 Error(QUOTE_MSG, "MatchDriver");
167 add_group_entry(&ptr->match_driver,
168 xstrtokenize(val.str, TOKEN_SEP));
169 free(val.str);
170 break;
171 case MATCH_TAG:
172 if (xf86getSubToken(&(ptr->comment)) != STRING)
173 Error(QUOTE_MSG, "MatchTag");
174 add_group_entry(&ptr->match_tag, xstrtokenize(val.str, TOKEN_SEP));
175 free(val.str);
176 break;
177 case MATCH_LAYOUT:
178 if (xf86getSubToken(&(ptr->comment)) != STRING)
179 Error(QUOTE_MSG, "MatchLayout");
180 add_group_entry(&ptr->match_layout,
181 xstrtokenize(val.str, TOKEN_SEP));
182 free(val.str);
183 break;
184 case MATCH_IS_KEYBOARD:
185 if (xf86getSubToken(&(ptr->comment)) != STRING)
186 Error(QUOTE_MSG, "MatchIsKeyboard");
187 ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val,
188 val.str);
189 free(val.str);
190 if (!ptr->is_keyboard.set)
191 Error(BOOL_MSG, "MatchIsKeyboard");
192 break;
193 case MATCH_IS_POINTER:
194 if (xf86getSubToken(&(ptr->comment)) != STRING)
195 Error(QUOTE_MSG, "MatchIsPointer");
196 ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val,
197 val.str);
198 free(val.str);
199 if (!ptr->is_pointer.set)
200 Error(BOOL_MSG, "MatchIsPointer");
201 break;
202 case MATCH_IS_JOYSTICK:
203 if (xf86getSubToken(&(ptr->comment)) != STRING)
204 Error(QUOTE_MSG, "MatchIsJoystick");
205 ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val,
206 val.str);
207 free(val.str);
208 if (!ptr->is_joystick.set)
209 Error(BOOL_MSG, "MatchIsJoystick");
210 break;
211 case MATCH_IS_TABLET:
212 if (xf86getSubToken(&(ptr->comment)) != STRING)
213 Error(QUOTE_MSG, "MatchIsTablet");
214 ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, val.str);
215 free(val.str);
216 if (!ptr->is_tablet.set)
217 Error(BOOL_MSG, "MatchIsTablet");
218 break;
219 case MATCH_IS_TOUCHPAD:
220 if (xf86getSubToken(&(ptr->comment)) != STRING)
221 Error(QUOTE_MSG, "MatchIsTouchpad");
222 ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val,
223 val.str);
224 free(val.str);
225 if (!ptr->is_touchpad.set)
226 Error(BOOL_MSG, "MatchIsTouchpad");
227 break;
228 case MATCH_IS_TOUCHSCREEN:
229 if (xf86getSubToken(&(ptr->comment)) != STRING)
230 Error(QUOTE_MSG, "MatchIsTouchscreen");
231 ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val,
232 val.str);
233 free(val.str);
234 if (!ptr->is_touchscreen.set)
235 Error(BOOL_MSG, "MatchIsTouchscreen");
236 break;
237 case EOF_TOKEN:
238 Error(UNEXPECTED_EOF_MSG);
239 break;
240 default:
241 Error(INVALID_KEYWORD_MSG, xf86tokenString());
242 break;
243 }
244 }
245
246 if (!has_ident)
247 Error(NO_IDENT_MSG);
248
249#ifdef DEBUG
250 printf("InputClass section parsed\n");
251#endif
252
253 return ptr;
254}
255
256void
257xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
258{
259 const xf86MatchGroup *group;
260 char *const *cur;
261
262 while (ptr) {
263 fprintf(cf, "Section \"InputClass\"\n");
264 if (ptr->comment)
265 fprintf(cf, "%s", ptr->comment);
266 if (ptr->identifier)
267 fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier);
268 if (ptr->driver)
269 fprintf(cf, "\tDriver \"%s\"\n", ptr->driver);
270
271 xorg_list_for_each_entry(group, &ptr->match_product, entry) {
272 fprintf(cf, "\tMatchProduct \"");
273 for (cur = group->values; *cur; cur++)
274 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
275 *cur);
276 fprintf(cf, "\"\n");
277 }
278 xorg_list_for_each_entry(group, &ptr->match_vendor, entry) {
279 fprintf(cf, "\tMatchVendor \"");
280 for (cur = group->values; *cur; cur++)
281 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
282 *cur);
283 fprintf(cf, "\"\n");
284 }
285 xorg_list_for_each_entry(group, &ptr->match_device, entry) {
286 fprintf(cf, "\tMatchDevicePath \"");
287 for (cur = group->values; *cur; cur++)
288 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
289 *cur);
290 fprintf(cf, "\"\n");
291 }
292 xorg_list_for_each_entry(group, &ptr->match_os, entry) {
293 fprintf(cf, "\tMatchOS \"");
294 for (cur = group->values; *cur; cur++)
295 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
296 *cur);
297 fprintf(cf, "\"\n");
298 }
299 xorg_list_for_each_entry(group, &ptr->match_pnpid, entry) {
300 fprintf(cf, "\tMatchPnPID \"");
301 for (cur = group->values; *cur; cur++)
302 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
303 *cur);
304 fprintf(cf, "\"\n");
305 }
306 xorg_list_for_each_entry(group, &ptr->match_usbid, entry) {
307 fprintf(cf, "\tMatchUSBID \"");
308 for (cur = group->values; *cur; cur++)
309 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
310 *cur);
311 fprintf(cf, "\"\n");
312 }
313 xorg_list_for_each_entry(group, &ptr->match_driver, entry) {
314 fprintf(cf, "\tMatchDriver \"");
315 for (cur = group->values; *cur; cur++)
316 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
317 *cur);
318 fprintf(cf, "\"\n");
319 }
320 xorg_list_for_each_entry(group, &ptr->match_tag, entry) {
321 fprintf(cf, "\tMatchTag \"");
322 for (cur = group->values; *cur; cur++)
323 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
324 *cur);
325 fprintf(cf, "\"\n");
326 }
327 xorg_list_for_each_entry(group, &ptr->match_layout, entry) {
328 fprintf(cf, "\tMatchLayout \"");
329 for (cur = group->values; *cur; cur++)
330 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
331 *cur);
332 fprintf(cf, "\"\n");
333 }
334
335 if (ptr->is_keyboard.set)
336 fprintf(cf, "\tIsKeyboard \"%s\"\n",
337 ptr->is_keyboard.val ? "yes" : "no");
338 if (ptr->is_pointer.set)
339 fprintf(cf, "\tIsPointer \"%s\"\n",
340 ptr->is_pointer.val ? "yes" : "no");
341 if (ptr->is_joystick.set)
342 fprintf(cf, "\tIsJoystick \"%s\"\n",
343 ptr->is_joystick.val ? "yes" : "no");
344 if (ptr->is_tablet.set)
345 fprintf(cf, "\tIsTablet \"%s\"\n",
346 ptr->is_tablet.val ? "yes" : "no");
347 if (ptr->is_touchpad.set)
348 fprintf(cf, "\tIsTouchpad \"%s\"\n",
349 ptr->is_touchpad.val ? "yes" : "no");
350 if (ptr->is_touchscreen.set)
351 fprintf(cf, "\tIsTouchscreen \"%s\"\n",
352 ptr->is_touchscreen.val ? "yes" : "no");
353 xf86printOptionList(cf, ptr->option_lst, 1);
354 fprintf(cf, "EndSection\n\n");
355 ptr = ptr->list.next;
356 }
357}
358
359void
360xf86freeInputClassList(XF86ConfInputClassPtr ptr)
361{
362 XF86ConfInputClassPtr prev;
363
364 while (ptr) {
365 xf86MatchGroup *group, *next;
366 char **list;
367
368 TestFree(ptr->identifier);
369 TestFree(ptr->driver);
370
371 xorg_list_for_each_entry_safe(group, next, &ptr->match_product, entry) {
372 xorg_list_del(&group->entry);
373 for (list = group->values; *list; list++)
374 free(*list);
375 free(group);
376 }
377 xorg_list_for_each_entry_safe(group, next, &ptr->match_vendor, entry) {
378 xorg_list_del(&group->entry);
379 for (list = group->values; *list; list++)
380 free(*list);
381 free(group);
382 }
383 xorg_list_for_each_entry_safe(group, next, &ptr->match_device, entry) {
384 xorg_list_del(&group->entry);
385 for (list = group->values; *list; list++)
386 free(*list);
387 free(group);
388 }
389 xorg_list_for_each_entry_safe(group, next, &ptr->match_os, entry) {
390 xorg_list_del(&group->entry);
391 for (list = group->values; *list; list++)
392 free(*list);
393 free(group);
394 }
395 xorg_list_for_each_entry_safe(group, next, &ptr->match_pnpid, entry) {
396 xorg_list_del(&group->entry);
397 for (list = group->values; *list; list++)
398 free(*list);
399 free(group);
400 }
401 xorg_list_for_each_entry_safe(group, next, &ptr->match_usbid, entry) {
402 xorg_list_del(&group->entry);
403 for (list = group->values; *list; list++)
404 free(*list);
405 free(group);
406 }
407 xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) {
408 xorg_list_del(&group->entry);
409 for (list = group->values; *list; list++)
410 free(*list);
411 free(group);
412 }
413 xorg_list_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
414 xorg_list_del(&group->entry);
415 for (list = group->values; *list; list++)
416 free(*list);
417 free(group);
418 }
419 xorg_list_for_each_entry_safe(group, next, &ptr->match_layout, entry) {
420 xorg_list_del(&group->entry);
421 for (list = group->values; *list; list++)
422 free(*list);
423 free(group);
424 }
425
426 TestFree(ptr->comment);
427 xf86optionListFree(ptr->option_lst);
428
429 prev = ptr;
430 ptr = ptr->list.next;
431 free(prev);
432 }
433}