InputClass.c revision 1b5d61b8
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 36 37static const xf86ConfigSymTabRec InputClassTab[] = { 38 {ENDSECTION, "endsection"}, 39 {IDENTIFIER, "identifier"}, 40 {OPTION, "option"}, 41 {DRIVER, "driver"}, 42 {MATCH_PRODUCT, "matchproduct"}, 43 {MATCH_VENDOR, "matchvendor"}, 44 {MATCH_DEVICE_PATH, "matchdevicepath"}, 45 {MATCH_OS, "matchos"}, 46 {MATCH_PNPID, "matchpnpid"}, 47 {MATCH_USBID, "matchusbid"}, 48 {MATCH_DRIVER, "matchdriver"}, 49 {MATCH_TAG, "matchtag"}, 50 {MATCH_LAYOUT, "matchlayout"}, 51 {MATCH_IS_KEYBOARD, "matchiskeyboard"}, 52 {MATCH_IS_POINTER, "matchispointer"}, 53 {MATCH_IS_JOYSTICK, "matchisjoystick"}, 54 {MATCH_IS_TABLET, "matchistablet"}, 55 {MATCH_IS_TABLET_PAD, "matchistabletpad"}, 56 {MATCH_IS_TOUCHPAD, "matchistouchpad"}, 57 {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"}, 58 {NOMATCH_PRODUCT, "nomatchproduct"}, 59 {NOMATCH_VENDOR, "nomatchvendor"}, 60 {NOMATCH_DEVICE_PATH, "nomatchdevicepath"}, 61 {NOMATCH_OS, "nomatchos"}, 62 {NOMATCH_PNPID, "nomatchpnpid"}, 63 {NOMATCH_USBID, "nomatchusbid"}, 64 {NOMATCH_DRIVER, "nomatchdriver"}, 65 {NOMATCH_TAG, "nomatchtag"}, 66 {NOMATCH_LAYOUT, "nomatchlayout"}, 67 {-1, ""}, 68}; 69 70static void 71xf86freeInputClassList(XF86ConfInputClassPtr ptr) 72{ 73 XF86ConfInputClassPtr prev; 74 75 while (ptr) { 76 xf86MatchGroup *group, *next; 77 char **list; 78 79 TestFree(ptr->identifier); 80 TestFree(ptr->driver); 81 82 xorg_list_for_each_entry_safe(group, next, &ptr->match_product, entry) { 83 xorg_list_del(&group->entry); 84 for (list = group->values; *list; list++) 85 free(*list); 86 free(group); 87 } 88 xorg_list_for_each_entry_safe(group, next, &ptr->match_vendor, entry) { 89 xorg_list_del(&group->entry); 90 for (list = group->values; *list; list++) 91 free(*list); 92 free(group); 93 } 94 xorg_list_for_each_entry_safe(group, next, &ptr->match_device, entry) { 95 xorg_list_del(&group->entry); 96 for (list = group->values; *list; list++) 97 free(*list); 98 free(group); 99 } 100 xorg_list_for_each_entry_safe(group, next, &ptr->match_os, entry) { 101 xorg_list_del(&group->entry); 102 for (list = group->values; *list; list++) 103 free(*list); 104 free(group); 105 } 106 xorg_list_for_each_entry_safe(group, next, &ptr->match_pnpid, entry) { 107 xorg_list_del(&group->entry); 108 for (list = group->values; *list; list++) 109 free(*list); 110 free(group); 111 } 112 xorg_list_for_each_entry_safe(group, next, &ptr->match_usbid, entry) { 113 xorg_list_del(&group->entry); 114 for (list = group->values; *list; list++) 115 free(*list); 116 free(group); 117 } 118 xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) { 119 xorg_list_del(&group->entry); 120 for (list = group->values; *list; list++) 121 free(*list); 122 free(group); 123 } 124 xorg_list_for_each_entry_safe(group, next, &ptr->match_tag, entry) { 125 xorg_list_del(&group->entry); 126 for (list = group->values; *list; list++) 127 free(*list); 128 free(group); 129 } 130 xorg_list_for_each_entry_safe(group, next, &ptr->match_layout, entry) { 131 xorg_list_del(&group->entry); 132 for (list = group->values; *list; list++) 133 free(*list); 134 free(group); 135 } 136 137 TestFree(ptr->comment); 138 xf86optionListFree(ptr->option_lst); 139 140 prev = ptr; 141 ptr = ptr->list.next; 142 free(prev); 143 } 144} 145 146#define CLEANUP xf86freeInputClassList 147 148#define TOKEN_SEP "|" 149 150enum MatchType { 151 MATCH_NORMAL, 152 MATCH_NEGATED, 153}; 154 155static void 156add_group_entry(struct xorg_list *head, char **values, enum MatchType type) 157{ 158 xf86MatchGroup *group; 159 160 group = malloc(sizeof(*group)); 161 if (group) { 162 group->is_negated = (type == MATCH_NEGATED); 163 group->values = values; 164 xorg_list_add(&group->entry, head); 165 } 166} 167 168XF86ConfInputClassPtr 169xf86parseInputClassSection(void) 170{ 171 int has_ident = FALSE; 172 int token; 173 enum MatchType matchtype; 174 175 parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec) 176 177 /* Initialize MatchGroup lists */ 178 xorg_list_init(&ptr->match_product); 179 xorg_list_init(&ptr->match_vendor); 180 xorg_list_init(&ptr->match_device); 181 xorg_list_init(&ptr->match_os); 182 xorg_list_init(&ptr->match_pnpid); 183 xorg_list_init(&ptr->match_usbid); 184 xorg_list_init(&ptr->match_driver); 185 xorg_list_init(&ptr->match_tag); 186 xorg_list_init(&ptr->match_layout); 187 188 while ((token = xf86getToken(InputClassTab)) != ENDSECTION) { 189 matchtype = MATCH_NORMAL; 190 191 switch (token) { 192 case COMMENT: 193 ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str); 194 break; 195 case IDENTIFIER: 196 if (xf86getSubToken(&(ptr->comment)) != STRING) 197 Error(QUOTE_MSG, "Identifier"); 198 if (has_ident == TRUE) 199 Error(MULTIPLE_MSG, "Identifier"); 200 ptr->identifier = xf86_lex_val.str; 201 has_ident = TRUE; 202 break; 203 case DRIVER: 204 if (xf86getSubToken(&(ptr->comment)) != STRING) 205 Error(QUOTE_MSG, "Driver"); 206 if (strcmp(xf86_lex_val.str, "keyboard") == 0) { 207 ptr->driver = strdup("kbd"); 208 free(xf86_lex_val.str); 209 } 210 else 211 ptr->driver = xf86_lex_val.str; 212 break; 213 case OPTION: 214 ptr->option_lst = xf86parseOption(ptr->option_lst); 215 break; 216 case NOMATCH_PRODUCT: 217 matchtype = MATCH_NEGATED; 218 /* fallthrough */ 219 case MATCH_PRODUCT: 220 if (xf86getSubToken(&(ptr->comment)) != STRING) 221 Error(QUOTE_MSG, "MatchProduct"); 222 add_group_entry(&ptr->match_product, 223 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 224 matchtype); 225 free(xf86_lex_val.str); 226 break; 227 case NOMATCH_VENDOR: 228 matchtype = MATCH_NEGATED; 229 /* fallthrough */ 230 case MATCH_VENDOR: 231 if (xf86getSubToken(&(ptr->comment)) != STRING) 232 Error(QUOTE_MSG, "MatchVendor"); 233 add_group_entry(&ptr->match_vendor, 234 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 235 matchtype); 236 free(xf86_lex_val.str); 237 break; 238 case NOMATCH_DEVICE_PATH: 239 matchtype = MATCH_NEGATED; 240 /* fallthrough */ 241 case MATCH_DEVICE_PATH: 242 if (xf86getSubToken(&(ptr->comment)) != STRING) 243 Error(QUOTE_MSG, "MatchDevicePath"); 244 add_group_entry(&ptr->match_device, 245 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 246 matchtype); 247 free(xf86_lex_val.str); 248 break; 249 case NOMATCH_OS: 250 matchtype = MATCH_NEGATED; 251 /* fallthrough */ 252 case MATCH_OS: 253 if (xf86getSubToken(&(ptr->comment)) != STRING) 254 Error(QUOTE_MSG, "MatchOS"); 255 add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str, 256 TOKEN_SEP), 257 matchtype); 258 free(xf86_lex_val.str); 259 break; 260 case NOMATCH_PNPID: 261 matchtype = MATCH_NEGATED; 262 /* fallthrough */ 263 case MATCH_PNPID: 264 if (xf86getSubToken(&(ptr->comment)) != STRING) 265 Error(QUOTE_MSG, "MatchPnPID"); 266 add_group_entry(&ptr->match_pnpid, 267 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 268 matchtype); 269 free(xf86_lex_val.str); 270 break; 271 case NOMATCH_USBID: 272 matchtype = MATCH_NEGATED; 273 /* fallthrough */ 274 case MATCH_USBID: 275 if (xf86getSubToken(&(ptr->comment)) != STRING) 276 Error(QUOTE_MSG, "MatchUSBID"); 277 add_group_entry(&ptr->match_usbid, 278 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 279 matchtype); 280 free(xf86_lex_val.str); 281 break; 282 case NOMATCH_DRIVER: 283 matchtype = MATCH_NEGATED; 284 /* fallthrough */ 285 case MATCH_DRIVER: 286 if (xf86getSubToken(&(ptr->comment)) != STRING) 287 Error(QUOTE_MSG, "MatchDriver"); 288 add_group_entry(&ptr->match_driver, 289 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 290 matchtype); 291 free(xf86_lex_val.str); 292 break; 293 case NOMATCH_TAG: 294 matchtype = MATCH_NEGATED; 295 /* fallthrough */ 296 case MATCH_TAG: 297 if (xf86getSubToken(&(ptr->comment)) != STRING) 298 Error(QUOTE_MSG, "MatchTag"); 299 add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str, 300 TOKEN_SEP), 301 matchtype); 302 free(xf86_lex_val.str); 303 break; 304 case NOMATCH_LAYOUT: 305 matchtype = MATCH_NEGATED; 306 /* fallthrough */ 307 case MATCH_LAYOUT: 308 if (xf86getSubToken(&(ptr->comment)) != STRING) 309 Error(QUOTE_MSG, "MatchLayout"); 310 add_group_entry(&ptr->match_layout, 311 xstrtokenize(xf86_lex_val.str, TOKEN_SEP), 312 matchtype); 313 free(xf86_lex_val.str); 314 break; 315 case MATCH_IS_KEYBOARD: 316 if (xf86getSubToken(&(ptr->comment)) != STRING) 317 Error(QUOTE_MSG, "MatchIsKeyboard"); 318 ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val, 319 xf86_lex_val.str); 320 free(xf86_lex_val.str); 321 if (!ptr->is_keyboard.set) 322 Error(BOOL_MSG, "MatchIsKeyboard"); 323 break; 324 case MATCH_IS_POINTER: 325 if (xf86getSubToken(&(ptr->comment)) != STRING) 326 Error(QUOTE_MSG, "MatchIsPointer"); 327 ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val, 328 xf86_lex_val.str); 329 free(xf86_lex_val.str); 330 if (!ptr->is_pointer.set) 331 Error(BOOL_MSG, "MatchIsPointer"); 332 break; 333 case MATCH_IS_JOYSTICK: 334 if (xf86getSubToken(&(ptr->comment)) != STRING) 335 Error(QUOTE_MSG, "MatchIsJoystick"); 336 ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val, 337 xf86_lex_val.str); 338 free(xf86_lex_val.str); 339 if (!ptr->is_joystick.set) 340 Error(BOOL_MSG, "MatchIsJoystick"); 341 break; 342 case MATCH_IS_TABLET: 343 if (xf86getSubToken(&(ptr->comment)) != STRING) 344 Error(QUOTE_MSG, "MatchIsTablet"); 345 ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, xf86_lex_val.str); 346 free(xf86_lex_val.str); 347 if (!ptr->is_tablet.set) 348 Error(BOOL_MSG, "MatchIsTablet"); 349 break; 350 case MATCH_IS_TABLET_PAD: 351 if (xf86getSubToken(&(ptr->comment)) != STRING) 352 Error(QUOTE_MSG, "MatchIsTabletPad"); 353 ptr->is_tablet_pad.set = xf86getBoolValue(&ptr->is_tablet_pad.val, xf86_lex_val.str); 354 free(xf86_lex_val.str); 355 if (!ptr->is_tablet_pad.set) 356 Error(BOOL_MSG, "MatchIsTabletPad"); 357 break; 358 case MATCH_IS_TOUCHPAD: 359 if (xf86getSubToken(&(ptr->comment)) != STRING) 360 Error(QUOTE_MSG, "MatchIsTouchpad"); 361 ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val, 362 xf86_lex_val.str); 363 free(xf86_lex_val.str); 364 if (!ptr->is_touchpad.set) 365 Error(BOOL_MSG, "MatchIsTouchpad"); 366 break; 367 case MATCH_IS_TOUCHSCREEN: 368 if (xf86getSubToken(&(ptr->comment)) != STRING) 369 Error(QUOTE_MSG, "MatchIsTouchscreen"); 370 ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val, 371 xf86_lex_val.str); 372 free(xf86_lex_val.str); 373 if (!ptr->is_touchscreen.set) 374 Error(BOOL_MSG, "MatchIsTouchscreen"); 375 break; 376 case EOF_TOKEN: 377 Error(UNEXPECTED_EOF_MSG); 378 break; 379 default: 380 Error(INVALID_KEYWORD_MSG, xf86tokenString()); 381 break; 382 } 383 } 384 385 if (!has_ident) 386 Error(NO_IDENT_MSG); 387 388#ifdef DEBUG 389 printf("InputClass section parsed\n"); 390#endif 391 392 return ptr; 393} 394 395void 396xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr) 397{ 398 const xf86MatchGroup *group; 399 char *const *cur; 400 401 while (ptr) { 402 fprintf(cf, "Section \"InputClass\"\n"); 403 if (ptr->comment) 404 fprintf(cf, "%s", ptr->comment); 405 if (ptr->identifier) 406 fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier); 407 if (ptr->driver) 408 fprintf(cf, "\tDriver \"%s\"\n", ptr->driver); 409 410 xorg_list_for_each_entry(group, &ptr->match_product, entry) { 411 fprintf(cf, "\tMatchProduct \""); 412 for (cur = group->values; *cur; cur++) 413 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 414 *cur); 415 fprintf(cf, "\"\n"); 416 } 417 xorg_list_for_each_entry(group, &ptr->match_vendor, entry) { 418 fprintf(cf, "\tMatchVendor \""); 419 for (cur = group->values; *cur; cur++) 420 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 421 *cur); 422 fprintf(cf, "\"\n"); 423 } 424 xorg_list_for_each_entry(group, &ptr->match_device, entry) { 425 fprintf(cf, "\tMatchDevicePath \""); 426 for (cur = group->values; *cur; cur++) 427 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 428 *cur); 429 fprintf(cf, "\"\n"); 430 } 431 xorg_list_for_each_entry(group, &ptr->match_os, entry) { 432 fprintf(cf, "\tMatchOS \""); 433 for (cur = group->values; *cur; cur++) 434 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 435 *cur); 436 fprintf(cf, "\"\n"); 437 } 438 xorg_list_for_each_entry(group, &ptr->match_pnpid, entry) { 439 fprintf(cf, "\tMatchPnPID \""); 440 for (cur = group->values; *cur; cur++) 441 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 442 *cur); 443 fprintf(cf, "\"\n"); 444 } 445 xorg_list_for_each_entry(group, &ptr->match_usbid, entry) { 446 fprintf(cf, "\tMatchUSBID \""); 447 for (cur = group->values; *cur; cur++) 448 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 449 *cur); 450 fprintf(cf, "\"\n"); 451 } 452 xorg_list_for_each_entry(group, &ptr->match_driver, entry) { 453 fprintf(cf, "\tMatchDriver \""); 454 for (cur = group->values; *cur; cur++) 455 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 456 *cur); 457 fprintf(cf, "\"\n"); 458 } 459 xorg_list_for_each_entry(group, &ptr->match_tag, entry) { 460 fprintf(cf, "\tMatchTag \""); 461 for (cur = group->values; *cur; cur++) 462 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 463 *cur); 464 fprintf(cf, "\"\n"); 465 } 466 xorg_list_for_each_entry(group, &ptr->match_layout, entry) { 467 fprintf(cf, "\tMatchLayout \""); 468 for (cur = group->values; *cur; cur++) 469 fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP, 470 *cur); 471 fprintf(cf, "\"\n"); 472 } 473 474 if (ptr->is_keyboard.set) 475 fprintf(cf, "\tIsKeyboard \"%s\"\n", 476 ptr->is_keyboard.val ? "yes" : "no"); 477 if (ptr->is_pointer.set) 478 fprintf(cf, "\tIsPointer \"%s\"\n", 479 ptr->is_pointer.val ? "yes" : "no"); 480 if (ptr->is_joystick.set) 481 fprintf(cf, "\tIsJoystick \"%s\"\n", 482 ptr->is_joystick.val ? "yes" : "no"); 483 if (ptr->is_tablet.set) 484 fprintf(cf, "\tIsTablet \"%s\"\n", 485 ptr->is_tablet.val ? "yes" : "no"); 486 if (ptr->is_tablet_pad.set) 487 fprintf(cf, "\tIsTabletPad \"%s\"\n", 488 ptr->is_tablet_pad.val ? "yes" : "no"); 489 if (ptr->is_touchpad.set) 490 fprintf(cf, "\tIsTouchpad \"%s\"\n", 491 ptr->is_touchpad.val ? "yes" : "no"); 492 if (ptr->is_touchscreen.set) 493 fprintf(cf, "\tIsTouchscreen \"%s\"\n", 494 ptr->is_touchscreen.val ? "yes" : "no"); 495 xf86printOptionList(cf, ptr->option_lst, 1); 496 fprintf(cf, "EndSection\n\n"); 497 ptr = ptr->list.next; 498 } 499} 500