16747b715Smrg/*
26747b715Smrg * Copyright (c) 2009 Dan Nicholson
36747b715Smrg *
46747b715Smrg * Permission is hereby granted, free of charge, to any person
56747b715Smrg * obtaining a copy of this software and associated documentation
66747b715Smrg * files (the "Software"), to deal in the Software without
76747b715Smrg * restriction, including without limitation the rights to use,
86747b715Smrg * copy, modify, merge, publish, distribute, sublicense, and/or sell
96747b715Smrg * copies of the Software, and to permit persons to whom the
106747b715Smrg * Software is furnished to do so, subject to the following
116747b715Smrg * conditions:
126747b715Smrg *
136747b715Smrg * The above copyright notice and this permission notice shall be
146747b715Smrg * included in all copies or substantial portions of the Software.
156747b715Smrg *
166747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
176747b715Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
186747b715Smrg * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
196747b715Smrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
206747b715Smrg * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
216747b715Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
226747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
236747b715Smrg * OTHER DEALINGS IN THE SOFTWARE.
246747b715Smrg */
256747b715Smrg
266747b715Smrg#ifdef HAVE_XORG_CONFIG_H
276747b715Smrg#include <xorg-config.h>
286747b715Smrg#endif
296747b715Smrg
306747b715Smrg#include <string.h>
316747b715Smrg#include "os.h"
326747b715Smrg#include "xf86Parser.h"
336747b715Smrg#include "xf86tokens.h"
346747b715Smrg#include "Configint.h"
356747b715Smrg
366747b715Smrg
371b5d61b8Smrgstatic const xf86ConfigSymTabRec InputClassTab[] = {
386747b715Smrg    {ENDSECTION, "endsection"},
396747b715Smrg    {IDENTIFIER, "identifier"},
406747b715Smrg    {OPTION, "option"},
416747b715Smrg    {DRIVER, "driver"},
426747b715Smrg    {MATCH_PRODUCT, "matchproduct"},
436747b715Smrg    {MATCH_VENDOR, "matchvendor"},
446747b715Smrg    {MATCH_DEVICE_PATH, "matchdevicepath"},
456747b715Smrg    {MATCH_OS, "matchos"},
466747b715Smrg    {MATCH_PNPID, "matchpnpid"},
476747b715Smrg    {MATCH_USBID, "matchusbid"},
486747b715Smrg    {MATCH_DRIVER, "matchdriver"},
496747b715Smrg    {MATCH_TAG, "matchtag"},
5035c4bbdfSmrg    {MATCH_LAYOUT, "matchlayout"},
516747b715Smrg    {MATCH_IS_KEYBOARD, "matchiskeyboard"},
526747b715Smrg    {MATCH_IS_POINTER, "matchispointer"},
536747b715Smrg    {MATCH_IS_JOYSTICK, "matchisjoystick"},
546747b715Smrg    {MATCH_IS_TABLET, "matchistablet"},
551b5d61b8Smrg    {MATCH_IS_TABLET_PAD, "matchistabletpad"},
566747b715Smrg    {MATCH_IS_TOUCHPAD, "matchistouchpad"},
576747b715Smrg    {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"},
581b5d61b8Smrg    {NOMATCH_PRODUCT, "nomatchproduct"},
591b5d61b8Smrg    {NOMATCH_VENDOR, "nomatchvendor"},
601b5d61b8Smrg    {NOMATCH_DEVICE_PATH, "nomatchdevicepath"},
611b5d61b8Smrg    {NOMATCH_OS, "nomatchos"},
621b5d61b8Smrg    {NOMATCH_PNPID, "nomatchpnpid"},
631b5d61b8Smrg    {NOMATCH_USBID, "nomatchusbid"},
641b5d61b8Smrg    {NOMATCH_DRIVER, "nomatchdriver"},
651b5d61b8Smrg    {NOMATCH_TAG, "nomatchtag"},
661b5d61b8Smrg    {NOMATCH_LAYOUT, "nomatchlayout"},
676747b715Smrg    {-1, ""},
686747b715Smrg};
696747b715Smrg
7035c4bbdfSmrgstatic void
7135c4bbdfSmrgxf86freeInputClassList(XF86ConfInputClassPtr ptr)
7235c4bbdfSmrg{
7335c4bbdfSmrg    XF86ConfInputClassPtr prev;
7435c4bbdfSmrg
7535c4bbdfSmrg    while (ptr) {
7635c4bbdfSmrg        xf86MatchGroup *group, *next;
7735c4bbdfSmrg        char **list;
7835c4bbdfSmrg
7935c4bbdfSmrg        TestFree(ptr->identifier);
8035c4bbdfSmrg        TestFree(ptr->driver);
8135c4bbdfSmrg
8235c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_product, entry) {
8335c4bbdfSmrg            xorg_list_del(&group->entry);
8435c4bbdfSmrg            for (list = group->values; *list; list++)
8535c4bbdfSmrg                free(*list);
8635c4bbdfSmrg            free(group);
8735c4bbdfSmrg        }
8835c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_vendor, entry) {
8935c4bbdfSmrg            xorg_list_del(&group->entry);
9035c4bbdfSmrg            for (list = group->values; *list; list++)
9135c4bbdfSmrg                free(*list);
9235c4bbdfSmrg            free(group);
9335c4bbdfSmrg        }
9435c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_device, entry) {
9535c4bbdfSmrg            xorg_list_del(&group->entry);
9635c4bbdfSmrg            for (list = group->values; *list; list++)
9735c4bbdfSmrg                free(*list);
9835c4bbdfSmrg            free(group);
9935c4bbdfSmrg        }
10035c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_os, entry) {
10135c4bbdfSmrg            xorg_list_del(&group->entry);
10235c4bbdfSmrg            for (list = group->values; *list; list++)
10335c4bbdfSmrg                free(*list);
10435c4bbdfSmrg            free(group);
10535c4bbdfSmrg        }
10635c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_pnpid, entry) {
10735c4bbdfSmrg            xorg_list_del(&group->entry);
10835c4bbdfSmrg            for (list = group->values; *list; list++)
10935c4bbdfSmrg                free(*list);
11035c4bbdfSmrg            free(group);
11135c4bbdfSmrg        }
11235c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_usbid, entry) {
11335c4bbdfSmrg            xorg_list_del(&group->entry);
11435c4bbdfSmrg            for (list = group->values; *list; list++)
11535c4bbdfSmrg                free(*list);
11635c4bbdfSmrg            free(group);
11735c4bbdfSmrg        }
11835c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) {
11935c4bbdfSmrg            xorg_list_del(&group->entry);
12035c4bbdfSmrg            for (list = group->values; *list; list++)
12135c4bbdfSmrg                free(*list);
12235c4bbdfSmrg            free(group);
12335c4bbdfSmrg        }
12435c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
12535c4bbdfSmrg            xorg_list_del(&group->entry);
12635c4bbdfSmrg            for (list = group->values; *list; list++)
12735c4bbdfSmrg                free(*list);
12835c4bbdfSmrg            free(group);
12935c4bbdfSmrg        }
13035c4bbdfSmrg        xorg_list_for_each_entry_safe(group, next, &ptr->match_layout, entry) {
13135c4bbdfSmrg            xorg_list_del(&group->entry);
13235c4bbdfSmrg            for (list = group->values; *list; list++)
13335c4bbdfSmrg                free(*list);
13435c4bbdfSmrg            free(group);
13535c4bbdfSmrg        }
13635c4bbdfSmrg
13735c4bbdfSmrg        TestFree(ptr->comment);
13835c4bbdfSmrg        xf86optionListFree(ptr->option_lst);
13935c4bbdfSmrg
14035c4bbdfSmrg        prev = ptr;
14135c4bbdfSmrg        ptr = ptr->list.next;
14235c4bbdfSmrg        free(prev);
14335c4bbdfSmrg    }
14435c4bbdfSmrg}
14535c4bbdfSmrg
1466747b715Smrg#define CLEANUP xf86freeInputClassList
1476747b715Smrg
1486747b715Smrg#define TOKEN_SEP "|"
1496747b715Smrg
1501b5d61b8Smrgenum MatchType {
1511b5d61b8Smrg    MATCH_NORMAL,
1521b5d61b8Smrg    MATCH_NEGATED,
1531b5d61b8Smrg};
1541b5d61b8Smrg
1556747b715Smrgstatic void
1561b5d61b8Smrgadd_group_entry(struct xorg_list *head, char **values, enum MatchType type)
1576747b715Smrg{
1586747b715Smrg    xf86MatchGroup *group;
1596747b715Smrg
1606747b715Smrg    group = malloc(sizeof(*group));
1616747b715Smrg    if (group) {
1621b5d61b8Smrg        group->is_negated = (type == MATCH_NEGATED);
1636747b715Smrg        group->values = values;
16435c4bbdfSmrg        xorg_list_add(&group->entry, head);
1656747b715Smrg    }
1666747b715Smrg}
1676747b715Smrg
1686747b715SmrgXF86ConfInputClassPtr
1696747b715Smrgxf86parseInputClassSection(void)
1706747b715Smrg{
1716747b715Smrg    int has_ident = FALSE;
1726747b715Smrg    int token;
1731b5d61b8Smrg    enum MatchType matchtype;
1746747b715Smrg
1756747b715Smrg    parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
1766747b715Smrg
1771b5d61b8Smrg    /* Initialize MatchGroup lists */
1781b5d61b8Smrg    xorg_list_init(&ptr->match_product);
17935c4bbdfSmrg    xorg_list_init(&ptr->match_vendor);
18035c4bbdfSmrg    xorg_list_init(&ptr->match_device);
18135c4bbdfSmrg    xorg_list_init(&ptr->match_os);
18235c4bbdfSmrg    xorg_list_init(&ptr->match_pnpid);
18335c4bbdfSmrg    xorg_list_init(&ptr->match_usbid);
18435c4bbdfSmrg    xorg_list_init(&ptr->match_driver);
18535c4bbdfSmrg    xorg_list_init(&ptr->match_tag);
18635c4bbdfSmrg    xorg_list_init(&ptr->match_layout);
1876747b715Smrg
1886747b715Smrg    while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
1891b5d61b8Smrg        matchtype = MATCH_NORMAL;
1901b5d61b8Smrg
1916747b715Smrg        switch (token) {
1926747b715Smrg        case COMMENT:
19335c4bbdfSmrg            ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str);
19458cf2af7Smrg            free(xf86_lex_val.str);
19558cf2af7Smrg            xf86_lex_val.str = NULL;
1966747b715Smrg            break;
1976747b715Smrg        case IDENTIFIER:
1986747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
1996747b715Smrg                Error(QUOTE_MSG, "Identifier");
2006747b715Smrg            if (has_ident == TRUE)
2016747b715Smrg                Error(MULTIPLE_MSG, "Identifier");
20235c4bbdfSmrg            ptr->identifier = xf86_lex_val.str;
2036747b715Smrg            has_ident = TRUE;
2046747b715Smrg            break;
2056747b715Smrg        case DRIVER:
2066747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2076747b715Smrg                Error(QUOTE_MSG, "Driver");
20835c4bbdfSmrg            if (strcmp(xf86_lex_val.str, "keyboard") == 0) {
2096747b715Smrg                ptr->driver = strdup("kbd");
21035c4bbdfSmrg                free(xf86_lex_val.str);
2116747b715Smrg            }
2126747b715Smrg            else
21335c4bbdfSmrg                ptr->driver = xf86_lex_val.str;
2146747b715Smrg            break;
2156747b715Smrg        case OPTION:
2166747b715Smrg            ptr->option_lst = xf86parseOption(ptr->option_lst);
2176747b715Smrg            break;
2181b5d61b8Smrg        case NOMATCH_PRODUCT:
2191b5d61b8Smrg            matchtype = MATCH_NEGATED;
2201b5d61b8Smrg            /* fallthrough */
2216747b715Smrg        case MATCH_PRODUCT:
2226747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2236747b715Smrg                Error(QUOTE_MSG, "MatchProduct");
2246747b715Smrg            add_group_entry(&ptr->match_product,
2251b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
2261b5d61b8Smrg                            matchtype);
22735c4bbdfSmrg            free(xf86_lex_val.str);
2286747b715Smrg            break;
2291b5d61b8Smrg        case NOMATCH_VENDOR:
2301b5d61b8Smrg            matchtype = MATCH_NEGATED;
2311b5d61b8Smrg            /* fallthrough */
2326747b715Smrg        case MATCH_VENDOR:
2336747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2346747b715Smrg                Error(QUOTE_MSG, "MatchVendor");
2356747b715Smrg            add_group_entry(&ptr->match_vendor,
2361b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
2371b5d61b8Smrg                            matchtype);
23835c4bbdfSmrg            free(xf86_lex_val.str);
2396747b715Smrg            break;
2401b5d61b8Smrg        case NOMATCH_DEVICE_PATH:
2411b5d61b8Smrg            matchtype = MATCH_NEGATED;
2421b5d61b8Smrg            /* fallthrough */
2436747b715Smrg        case MATCH_DEVICE_PATH:
2446747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2456747b715Smrg                Error(QUOTE_MSG, "MatchDevicePath");
2466747b715Smrg            add_group_entry(&ptr->match_device,
2471b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
2481b5d61b8Smrg                            matchtype);
24935c4bbdfSmrg            free(xf86_lex_val.str);
2506747b715Smrg            break;
2511b5d61b8Smrg        case NOMATCH_OS:
2521b5d61b8Smrg            matchtype = MATCH_NEGATED;
2531b5d61b8Smrg            /* fallthrough */
2546747b715Smrg        case MATCH_OS:
2556747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2566747b715Smrg                Error(QUOTE_MSG, "MatchOS");
2571b5d61b8Smrg            add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str,
2581b5d61b8Smrg                                                         TOKEN_SEP),
2591b5d61b8Smrg                            matchtype);
26035c4bbdfSmrg            free(xf86_lex_val.str);
2616747b715Smrg            break;
2621b5d61b8Smrg        case NOMATCH_PNPID:
2631b5d61b8Smrg            matchtype = MATCH_NEGATED;
2641b5d61b8Smrg            /* fallthrough */
2656747b715Smrg        case MATCH_PNPID:
2666747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2676747b715Smrg                Error(QUOTE_MSG, "MatchPnPID");
2686747b715Smrg            add_group_entry(&ptr->match_pnpid,
2691b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
2701b5d61b8Smrg                            matchtype);
27135c4bbdfSmrg            free(xf86_lex_val.str);
2726747b715Smrg            break;
2731b5d61b8Smrg        case NOMATCH_USBID:
2741b5d61b8Smrg            matchtype = MATCH_NEGATED;
2751b5d61b8Smrg            /* fallthrough */
2766747b715Smrg        case MATCH_USBID:
2776747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2786747b715Smrg                Error(QUOTE_MSG, "MatchUSBID");
2796747b715Smrg            add_group_entry(&ptr->match_usbid,
2801b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
2811b5d61b8Smrg                            matchtype);
28235c4bbdfSmrg            free(xf86_lex_val.str);
2836747b715Smrg            break;
2841b5d61b8Smrg        case NOMATCH_DRIVER:
2851b5d61b8Smrg            matchtype = MATCH_NEGATED;
2861b5d61b8Smrg            /* fallthrough */
2876747b715Smrg        case MATCH_DRIVER:
2886747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
2896747b715Smrg                Error(QUOTE_MSG, "MatchDriver");
2906747b715Smrg            add_group_entry(&ptr->match_driver,
2911b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
2921b5d61b8Smrg                            matchtype);
29335c4bbdfSmrg            free(xf86_lex_val.str);
2946747b715Smrg            break;
2951b5d61b8Smrg        case NOMATCH_TAG:
2961b5d61b8Smrg            matchtype = MATCH_NEGATED;
2971b5d61b8Smrg            /* fallthrough */
2986747b715Smrg        case MATCH_TAG:
2996747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3006747b715Smrg                Error(QUOTE_MSG, "MatchTag");
3011b5d61b8Smrg            add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str,
3021b5d61b8Smrg                                                          TOKEN_SEP),
3031b5d61b8Smrg                            matchtype);
30435c4bbdfSmrg            free(xf86_lex_val.str);
30535c4bbdfSmrg            break;
3061b5d61b8Smrg        case NOMATCH_LAYOUT:
3071b5d61b8Smrg            matchtype = MATCH_NEGATED;
3081b5d61b8Smrg            /* fallthrough */
30935c4bbdfSmrg        case MATCH_LAYOUT:
31035c4bbdfSmrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
31135c4bbdfSmrg                Error(QUOTE_MSG, "MatchLayout");
31235c4bbdfSmrg            add_group_entry(&ptr->match_layout,
3131b5d61b8Smrg                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
3141b5d61b8Smrg                            matchtype);
31535c4bbdfSmrg            free(xf86_lex_val.str);
3166747b715Smrg            break;
3176747b715Smrg        case MATCH_IS_KEYBOARD:
3186747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3196747b715Smrg                Error(QUOTE_MSG, "MatchIsKeyboard");
3206747b715Smrg            ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val,
32135c4bbdfSmrg                                                    xf86_lex_val.str);
32235c4bbdfSmrg            free(xf86_lex_val.str);
3236747b715Smrg            if (!ptr->is_keyboard.set)
3246747b715Smrg                Error(BOOL_MSG, "MatchIsKeyboard");
3256747b715Smrg            break;
3266747b715Smrg        case MATCH_IS_POINTER:
3276747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3286747b715Smrg                Error(QUOTE_MSG, "MatchIsPointer");
3296747b715Smrg            ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val,
33035c4bbdfSmrg                                                   xf86_lex_val.str);
33135c4bbdfSmrg            free(xf86_lex_val.str);
3326747b715Smrg            if (!ptr->is_pointer.set)
3336747b715Smrg                Error(BOOL_MSG, "MatchIsPointer");
3346747b715Smrg            break;
3356747b715Smrg        case MATCH_IS_JOYSTICK:
3366747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3376747b715Smrg                Error(QUOTE_MSG, "MatchIsJoystick");
3386747b715Smrg            ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val,
33935c4bbdfSmrg                                                    xf86_lex_val.str);
34035c4bbdfSmrg            free(xf86_lex_val.str);
3416747b715Smrg            if (!ptr->is_joystick.set)
3426747b715Smrg                Error(BOOL_MSG, "MatchIsJoystick");
3436747b715Smrg            break;
3446747b715Smrg        case MATCH_IS_TABLET:
3456747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3466747b715Smrg                Error(QUOTE_MSG, "MatchIsTablet");
34735c4bbdfSmrg            ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, xf86_lex_val.str);
34835c4bbdfSmrg            free(xf86_lex_val.str);
3496747b715Smrg            if (!ptr->is_tablet.set)
3506747b715Smrg                Error(BOOL_MSG, "MatchIsTablet");
3516747b715Smrg            break;
3521b5d61b8Smrg        case MATCH_IS_TABLET_PAD:
3531b5d61b8Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3541b5d61b8Smrg                Error(QUOTE_MSG, "MatchIsTabletPad");
3551b5d61b8Smrg            ptr->is_tablet_pad.set = xf86getBoolValue(&ptr->is_tablet_pad.val, xf86_lex_val.str);
3561b5d61b8Smrg            free(xf86_lex_val.str);
3571b5d61b8Smrg            if (!ptr->is_tablet_pad.set)
3581b5d61b8Smrg                Error(BOOL_MSG, "MatchIsTabletPad");
3591b5d61b8Smrg            break;
3606747b715Smrg        case MATCH_IS_TOUCHPAD:
3616747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3626747b715Smrg                Error(QUOTE_MSG, "MatchIsTouchpad");
3636747b715Smrg            ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val,
36435c4bbdfSmrg                                                    xf86_lex_val.str);
36535c4bbdfSmrg            free(xf86_lex_val.str);
3666747b715Smrg            if (!ptr->is_touchpad.set)
3676747b715Smrg                Error(BOOL_MSG, "MatchIsTouchpad");
3686747b715Smrg            break;
3696747b715Smrg        case MATCH_IS_TOUCHSCREEN:
3706747b715Smrg            if (xf86getSubToken(&(ptr->comment)) != STRING)
3716747b715Smrg                Error(QUOTE_MSG, "MatchIsTouchscreen");
3726747b715Smrg            ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val,
37335c4bbdfSmrg                                                       xf86_lex_val.str);
37435c4bbdfSmrg            free(xf86_lex_val.str);
3756747b715Smrg            if (!ptr->is_touchscreen.set)
3766747b715Smrg                Error(BOOL_MSG, "MatchIsTouchscreen");
3776747b715Smrg            break;
3786747b715Smrg        case EOF_TOKEN:
37935c4bbdfSmrg            Error(UNEXPECTED_EOF_MSG);
3806747b715Smrg            break;
3816747b715Smrg        default:
38235c4bbdfSmrg            Error(INVALID_KEYWORD_MSG, xf86tokenString());
3836747b715Smrg            break;
3846747b715Smrg        }
3856747b715Smrg    }
3866747b715Smrg
3876747b715Smrg    if (!has_ident)
38835c4bbdfSmrg        Error(NO_IDENT_MSG);
3896747b715Smrg
3906747b715Smrg#ifdef DEBUG
3916747b715Smrg    printf("InputClass section parsed\n");
3926747b715Smrg#endif
3936747b715Smrg
3946747b715Smrg    return ptr;
3956747b715Smrg}
3966747b715Smrg
3976747b715Smrgvoid
39835c4bbdfSmrgxf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
3996747b715Smrg{
4006747b715Smrg    const xf86MatchGroup *group;
40135c4bbdfSmrg    char *const *cur;
4026747b715Smrg
4036747b715Smrg    while (ptr) {
4046747b715Smrg        fprintf(cf, "Section \"InputClass\"\n");
4056747b715Smrg        if (ptr->comment)
4066747b715Smrg            fprintf(cf, "%s", ptr->comment);
4076747b715Smrg        if (ptr->identifier)
4086747b715Smrg            fprintf(cf, "\tIdentifier      \"%s\"\n", ptr->identifier);
4096747b715Smrg        if (ptr->driver)
4106747b715Smrg            fprintf(cf, "\tDriver          \"%s\"\n", ptr->driver);
4116747b715Smrg
41235c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_product, entry) {
4136747b715Smrg            fprintf(cf, "\tMatchProduct    \"");
4146747b715Smrg            for (cur = group->values; *cur; cur++)
4156747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4166747b715Smrg                        *cur);
4176747b715Smrg            fprintf(cf, "\"\n");
4186747b715Smrg        }
41935c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_vendor, entry) {
4206747b715Smrg            fprintf(cf, "\tMatchVendor     \"");
4216747b715Smrg            for (cur = group->values; *cur; cur++)
4226747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4236747b715Smrg                        *cur);
4246747b715Smrg            fprintf(cf, "\"\n");
4256747b715Smrg        }
42635c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_device, entry) {
4276747b715Smrg            fprintf(cf, "\tMatchDevicePath \"");
4286747b715Smrg            for (cur = group->values; *cur; cur++)
4296747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4306747b715Smrg                        *cur);
4316747b715Smrg            fprintf(cf, "\"\n");
4326747b715Smrg        }
43335c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_os, entry) {
4346747b715Smrg            fprintf(cf, "\tMatchOS         \"");
4356747b715Smrg            for (cur = group->values; *cur; cur++)
4366747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4376747b715Smrg                        *cur);
4386747b715Smrg            fprintf(cf, "\"\n");
4396747b715Smrg        }
44035c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_pnpid, entry) {
4416747b715Smrg            fprintf(cf, "\tMatchPnPID      \"");
4426747b715Smrg            for (cur = group->values; *cur; cur++)
4436747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4446747b715Smrg                        *cur);
4456747b715Smrg            fprintf(cf, "\"\n");
4466747b715Smrg        }
44735c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_usbid, entry) {
4486747b715Smrg            fprintf(cf, "\tMatchUSBID      \"");
4496747b715Smrg            for (cur = group->values; *cur; cur++)
4506747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4516747b715Smrg                        *cur);
4526747b715Smrg            fprintf(cf, "\"\n");
4536747b715Smrg        }
45435c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_driver, entry) {
4556747b715Smrg            fprintf(cf, "\tMatchDriver     \"");
4566747b715Smrg            for (cur = group->values; *cur; cur++)
4576747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4586747b715Smrg                        *cur);
4596747b715Smrg            fprintf(cf, "\"\n");
4606747b715Smrg        }
46135c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_tag, entry) {
4626747b715Smrg            fprintf(cf, "\tMatchTag        \"");
4636747b715Smrg            for (cur = group->values; *cur; cur++)
4646747b715Smrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
4656747b715Smrg                        *cur);
4666747b715Smrg            fprintf(cf, "\"\n");
4676747b715Smrg        }
46835c4bbdfSmrg        xorg_list_for_each_entry(group, &ptr->match_layout, entry) {
46935c4bbdfSmrg            fprintf(cf, "\tMatchLayout     \"");
47035c4bbdfSmrg            for (cur = group->values; *cur; cur++)
47135c4bbdfSmrg                fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
47235c4bbdfSmrg                        *cur);
47335c4bbdfSmrg            fprintf(cf, "\"\n");
47435c4bbdfSmrg        }
4756747b715Smrg
4766747b715Smrg        if (ptr->is_keyboard.set)
4776747b715Smrg            fprintf(cf, "\tIsKeyboard      \"%s\"\n",
4786747b715Smrg                    ptr->is_keyboard.val ? "yes" : "no");
4796747b715Smrg        if (ptr->is_pointer.set)
4806747b715Smrg            fprintf(cf, "\tIsPointer       \"%s\"\n",
4816747b715Smrg                    ptr->is_pointer.val ? "yes" : "no");
4826747b715Smrg        if (ptr->is_joystick.set)
4836747b715Smrg            fprintf(cf, "\tIsJoystick      \"%s\"\n",
4846747b715Smrg                    ptr->is_joystick.val ? "yes" : "no");
4856747b715Smrg        if (ptr->is_tablet.set)
4866747b715Smrg            fprintf(cf, "\tIsTablet        \"%s\"\n",
4876747b715Smrg                    ptr->is_tablet.val ? "yes" : "no");
4881b5d61b8Smrg        if (ptr->is_tablet_pad.set)
4891b5d61b8Smrg            fprintf(cf, "\tIsTabletPad     \"%s\"\n",
4901b5d61b8Smrg                    ptr->is_tablet_pad.val ? "yes" : "no");
4916747b715Smrg        if (ptr->is_touchpad.set)
4926747b715Smrg            fprintf(cf, "\tIsTouchpad      \"%s\"\n",
4936747b715Smrg                    ptr->is_touchpad.val ? "yes" : "no");
4946747b715Smrg        if (ptr->is_touchscreen.set)
4956747b715Smrg            fprintf(cf, "\tIsTouchscreen   \"%s\"\n",
4966747b715Smrg                    ptr->is_touchscreen.val ? "yes" : "no");
4976747b715Smrg        xf86printOptionList(cf, ptr->option_lst, 1);
4986747b715Smrg        fprintf(cf, "EndSection\n\n");
4996747b715Smrg        ptr = ptr->list.next;
5006747b715Smrg    }
5016747b715Smrg}
502