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