summaryrefslogtreecommitdiff
path: root/xc/lib/xkbfile/maprules.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/xkbfile/maprules.c')
-rw-r--r--xc/lib/xkbfile/maprules.c160
1 files changed, 143 insertions, 17 deletions
diff --git a/xc/lib/xkbfile/maprules.c b/xc/lib/xkbfile/maprules.c
index 68e1ecfbd..8c5ce1a42 100644
--- a/xc/lib/xkbfile/maprules.c
+++ b/xc/lib/xkbfile/maprules.c
@@ -24,7 +24,7 @@
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
-/* $XFree86: xc/lib/xkbfile/maprules.c,v 3.16 2002/06/05 00:00:33 dawes Exp $ */
+/* $XFree86: xc/lib/xkbfile/maprules.c,v 3.17 2002/11/26 01:43:25 dawes Exp $ */
#include <stdio.h>
#include <ctype.h>
@@ -459,12 +459,14 @@ static Bool
#if NeedFunctionPrototypes
CheckLine( InputLine * line,
RemapSpec * remap,
- XkbRF_RulePtr rule)
+ XkbRF_RulePtr rule,
+ XkbRF_GroupPtr group)
#else
-CheckLine(line,remap,rule)
+CheckLine(line,remap,rule,group)
InputLine * line;
RemapSpec * remap;
XkbRF_RulePtr rule;
+ XkbRF_GroupsPtr group;
#endif
{
char * str,*tok;
@@ -474,9 +476,35 @@ _Xstrtokparams strtok_buf;
Bool append = False;
if (line->line[0]=='!') {
- SetUpRemap(line,remap);
- return False;
+ if (line->line[1] == '$' ||
+ (line->line[1] == ' ' && line->line[2] == '$')) {
+ char *gname = strchr(line->line, '$');
+ char *words = strchr(gname, ' ');
+ if(!words)
+ return False;
+ *words++ = '\0';
+ for (; *words; words++) {
+ if (*words != '=' && *words != ' ')
+ break;
+ }
+ if (*words == '\0')
+ return False;
+ group->name = _XkbDupString(gname);
+ group->words = _XkbDupString(words);
+ for (i = 1, words = group->words; *words; words++) {
+ if ( *words == ' ') {
+ *words++ = '\0';
+ i++;
+ }
+ }
+ group->number = i;
+ return True;
+ } else {
+ SetUpRemap(line,remap);
+ return False;
+ }
}
+
if (remap->num_remap==0) {
PR_DEBUG("Must have a mapping before first line of data\n");
PR_DEBUG("Illegal line of data ignored\n");
@@ -690,16 +718,49 @@ XkbRF_ApplyRule(rule,names)
Apply(rule->keymap, &names->keymap);
}
+static Bool
+#if NeedFunctionPrototypes
+CheckGroup( XkbRF_RulesPtr rules,
+ char * group_name,
+ char * name)
+#else
+XkbRF_CheckApplyRule(rules,group,name)
+ XkbRF_RulesPtr rules;
+ char * group_name;
+ char * name;
+#endif
+{
+ int i;
+ char *p;
+ XkbRF_GroupPtr group;
+
+ for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
+ if (! strcmp(group->name, group_name)) {
+ break;
+ }
+ }
+ if (i == rules->num_groups)
+ return False;
+ for (i = 0, p = group->words; i < group->number; i++, p += strlen(p)+1) {
+ if (! strcmp(p, name)) {
+ return True;
+ }
+ }
+ return False;
+}
+
static int
#if NeedFunctionPrototypes
XkbRF_CheckApplyRule( XkbRF_RulePtr rule,
XkbRF_MultiDefsPtr mdefs,
- XkbComponentNamesPtr names)
+ XkbComponentNamesPtr names,
+ XkbRF_RulesPtr rules)
#else
XkbRF_CheckApplyRule(rule,mdefs,names)
XkbRF_RulePtr rule;
XkbRF_MultiDefsPtr mdefs;
XkbComponentNamesPtr names;
+ XkbRF_RulesPtr rules;
#endif
{
Bool pending = False;
@@ -710,8 +771,13 @@ XkbRF_CheckApplyRule(rule,mdefs,names)
if (strcmp(rule->model, "*") == 0) {
pending = True;
} else {
- if (strcmp(rule->model, mdefs->model) != 0)
- return 0;
+ if (rule->model[0] == '$') {
+ if (!CheckGroup(rules, rule->model, mdefs->model))
+ return 0;
+ } else {
+ if (strcmp(rule->model, mdefs->model) != 0)
+ return 0;
+ }
}
}
if (rule->option != NULL) {
@@ -728,8 +794,14 @@ XkbRF_CheckApplyRule(rule,mdefs,names)
if (strcmp(rule->layout, "*") == 0) {
pending = True;
} else {
- if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
- return 0;
+ if (rule->layout[0] == '$') {
+ if (!CheckGroup(rules, rule->layout,
+ mdefs->layout[rule->layout_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
+ return 0;
+ }
}
}
if (rule->variant != NULL) {
@@ -739,8 +811,15 @@ XkbRF_CheckApplyRule(rule,mdefs,names)
if (strcmp(rule->variant, "*") == 0) {
pending = True;
} else {
- if (strcmp(rule->variant, mdefs->variant[rule->variant_num]) != 0)
- return 0;
+ if (rule->variant[0] == '$') {
+ if (!CheckGroup(rules, rule->variant,
+ mdefs->variant[rule->variant_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->variant,
+ mdefs->variant[rule->variant_num]) != 0)
+ return 0;
+ }
}
}
if (pending) {
@@ -808,7 +887,7 @@ int skip;
for (rule = rules->rules, i=0; i < rules->num_rules; rule++, i++) {
if ((rule->flags & flags) != flags)
continue;
- skip = XkbRF_CheckApplyRule(rule, mdefs, names);
+ skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules);
if (skip && !(flags & XkbRF_Option)) {
for ( ;(i < rules->num_rules) && (rule->number == skip);
rule++, i++);
@@ -991,6 +1070,33 @@ XkbRF_AddRule(rules)
return &rules->rules[rules->num_rules++];
}
+XkbRF_GroupPtr
+#if NeedFunctionPrototypes
+XkbRF_AddGroup(XkbRF_RulesPtr rules)
+#else
+XkbRF_AddGroup(rules)
+ XkbRF_RulesPtr rules;
+#endif
+{
+ if (rules->sz_groups<1) {
+ rules->sz_groups= 16;
+ rules->num_groups= 0;
+ rules->groups= _XkbTypedCalloc(rules->sz_groups,XkbRF_GroupRec);
+ }
+ else if (rules->num_groups >= rules->sz_groups) {
+ rules->sz_groups *= 2;
+ rules->groups= _XkbTypedRealloc(rules->groups,rules->sz_groups,
+ XkbRF_GroupRec);
+ }
+ if (!rules->groups) {
+ rules->sz_groups= rules->num_groups= 0;
+ return NULL;
+ }
+
+ bzero((char *)&rules->groups[rules->num_groups],sizeof(XkbRF_GroupRec));
+ return &rules->groups[rules->num_groups++];
+}
+
Bool
#if NeedFunctionPrototypes
XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules)
@@ -1003,16 +1109,25 @@ XkbRF_LoadRules(file,rules)
InputLine line;
RemapSpec remap;
XkbRF_RuleRec trule,*rule;
+XkbRF_GroupRec tgroup,*group;
if (!(rules && file))
return False;
bzero((char *)&remap,sizeof(RemapSpec));
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
InitInputLine(&line);
while (GetInputLine(file,&line,True)) {
- if (CheckLine(&line,&remap,&trule)) {
- if ((rule= XkbRF_AddRule(rules))!=NULL) {
- *rule= trule;
- bzero((char *)&trule,sizeof(XkbRF_RuleRec));
+ if (CheckLine(&line,&remap,&trule,&tgroup)) {
+ if (tgroup.number) {
+ if ((group= XkbRF_AddGroup(rules))!=NULL) {
+ *group= tgroup;
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
+ }
+ } else {
+ if ((rule= XkbRF_AddRule(rules))!=NULL) {
+ *rule= trule;
+ bzero((char *)&trule,sizeof(XkbRF_RuleRec));
+ }
}
}
line.num_line= 0;
@@ -1384,6 +1499,7 @@ XkbRF_Free(rules,freeRules)
{
int i;
XkbRF_RulePtr rule;
+XkbRF_GroupPtr group;
if (!rules)
return;
@@ -1417,6 +1533,16 @@ XkbRF_RulePtr rule;
rules->num_rules= rules->sz_rules= 0;
rules->rules= NULL;
}
+
+ if (rules->groups) {
+ for (i=0, group=rules->groups;i<rules->num_groups;i++,group++) {
+ if (group->name) _XkbFree(group->name);
+ if (group->words) _XkbFree(group->words);
+ }
+ _XkbFree(rules->groups);
+ rules->num_groups= 0;
+ rules->groups= NULL;
+ }
if (freeRules)
_XkbFree(rules);
return;