123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050 |
- /************************************************************
- Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ********************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #define X_INCLUDE_STRING_H
- #define XOS_USE_NO_LOCKING
- #include <X11/Xos_r.h>
- #include <X11/Xproto.h>
- #include <X11/X.h>
- #include <X11/Xos.h>
- #include <X11/Xfuncs.h>
- #include <X11/Xatom.h>
- #include <X11/keysym.h>
- #include "misc.h"
- #include "inputstr.h"
- #include "dix.h"
- #include "os.h"
- #include "xkbstr.h"
- #define XKBSRV_NEED_FILE_FUNCS
- #include <xkbsrv.h>
- /***====================================================================***/
- #define DFLT_LINE_SIZE 128
- typedef struct {
- int line_num;
- int sz_line;
- int num_line;
- char buf[DFLT_LINE_SIZE];
- char *line;
- } InputLine;
- static void
- InitInputLine(InputLine * line)
- {
- line->line_num = 1;
- line->num_line = 0;
- line->sz_line = DFLT_LINE_SIZE;
- line->line = line->buf;
- return;
- }
- static void
- FreeInputLine(InputLine * line)
- {
- if (line->line != line->buf)
- free(line->line);
- line->line_num = 1;
- line->num_line = 0;
- line->sz_line = DFLT_LINE_SIZE;
- line->line = line->buf;
- return;
- }
- static int
- InputLineAddChar(InputLine * line, int ch)
- {
- if (line->num_line >= line->sz_line) {
- if (line->line == line->buf) {
- line->line = malloc(line->sz_line * 2);
- memcpy(line->line, line->buf, line->sz_line);
- }
- else {
- line->line = realloc((char *) line->line, line->sz_line * 2);
- }
- line->sz_line *= 2;
- }
- line->line[line->num_line++] = ch;
- return ch;
- }
- #define ADD_CHAR(l,c) ((l)->num_line<(l)->sz_line?\
- (int)((l)->line[(l)->num_line++]= (c)):\
- InputLineAddChar(l,c))
- static Bool
- GetInputLine(FILE * file, InputLine * line, Bool checkbang)
- {
- int ch;
- Bool endOfFile, spacePending, slashPending, inComment;
- endOfFile = FALSE;
- while ((!endOfFile) && (line->num_line == 0)) {
- spacePending = slashPending = inComment = FALSE;
- while (((ch = getc(file)) != '\n') && (ch != EOF)) {
- if (ch == '\\') {
- if ((ch = getc(file)) == EOF)
- break;
- if (ch == '\n') {
- inComment = FALSE;
- ch = ' ';
- line->line_num++;
- }
- }
- if (inComment)
- continue;
- if (ch == '/') {
- if (slashPending) {
- inComment = TRUE;
- slashPending = FALSE;
- }
- else {
- slashPending = TRUE;
- }
- continue;
- }
- else if (slashPending) {
- if (spacePending) {
- ADD_CHAR(line, ' ');
- spacePending = FALSE;
- }
- ADD_CHAR(line, '/');
- slashPending = FALSE;
- }
- if (isspace(ch)) {
- while (isspace(ch) && (ch != '\n') && (ch != EOF)) {
- ch = getc(file);
- }
- if (ch == EOF)
- break;
- if ((ch != '\n') && (line->num_line > 0))
- spacePending = TRUE;
- ungetc(ch, file);
- }
- else {
- if (spacePending) {
- ADD_CHAR(line, ' ');
- spacePending = FALSE;
- }
- if (checkbang && ch == '!') {
- if (line->num_line != 0) {
- DebugF("The '!' legal only at start of line\n");
- DebugF("Line containing '!' ignored\n");
- line->num_line = 0;
- inComment = 0;
- break;
- }
- }
- ADD_CHAR(line, ch);
- }
- }
- if (ch == EOF)
- endOfFile = TRUE;
- /* else line->num_line++;*/
- }
- if ((line->num_line == 0) && (endOfFile))
- return FALSE;
- ADD_CHAR(line, '\0');
- return TRUE;
- }
- /***====================================================================***/
- #define MODEL 0
- #define LAYOUT 1
- #define VARIANT 2
- #define OPTION 3
- #define KEYCODES 4
- #define SYMBOLS 5
- #define TYPES 6
- #define COMPAT 7
- #define GEOMETRY 8
- #define MAX_WORDS 9
- #define PART_MASK 0x000F
- #define COMPONENT_MASK 0x03F0
- static const char *cname[MAX_WORDS] = {
- "model", "layout", "variant", "option",
- "keycodes", "symbols", "types", "compat", "geometry"
- };
- typedef struct _RemapSpec {
- int number;
- int num_remap;
- struct {
- int word;
- int index;
- } remap[MAX_WORDS];
- } RemapSpec;
- typedef struct _FileSpec {
- char *name[MAX_WORDS];
- struct _FileSpec *pending;
- } FileSpec;
- typedef struct {
- const char *model;
- const char *layout[XkbNumKbdGroups + 1];
- const char *variant[XkbNumKbdGroups + 1];
- const char *options;
- } XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
- #define NDX_BUFF_SIZE 4
- /***====================================================================***/
- static char *
- get_index(char *str, int *ndx)
- {
- char ndx_buf[NDX_BUFF_SIZE];
- char *end;
- if (*str != '[') {
- *ndx = 0;
- return str;
- }
- str++;
- end = strchr(str, ']');
- if (end == NULL) {
- *ndx = -1;
- return str - 1;
- }
- if ((end - str) >= NDX_BUFF_SIZE) {
- *ndx = -1;
- return end + 1;
- }
- strlcpy(ndx_buf, str, 1 + end - str);
- *ndx = atoi(ndx_buf);
- return end + 1;
- }
- static void
- SetUpRemap(InputLine * line, RemapSpec * remap)
- {
- char *tok, *str;
- unsigned present, l_ndx_present, v_ndx_present;
- register int i;
- int len, ndx;
- _Xstrtokparams strtok_buf;
- Bool found;
- l_ndx_present = v_ndx_present = present = 0;
- str = &line->line[1];
- len = remap->number;
- memset((char *) remap, 0, sizeof(RemapSpec));
- remap->number = len;
- while ((tok = _XStrtok(str, " ", strtok_buf)) != NULL) {
- found = FALSE;
- str = NULL;
- if (strcmp(tok, "=") == 0)
- continue;
- for (i = 0; i < MAX_WORDS; i++) {
- len = strlen(cname[i]);
- if (strncmp(cname[i], tok, len) == 0) {
- if (strlen(tok) > len) {
- char *end = get_index(tok + len, &ndx);
- if ((i != LAYOUT && i != VARIANT) ||
- *end != '\0' || ndx == -1)
- break;
- if (ndx < 1 || ndx > XkbNumKbdGroups) {
- DebugF("Illegal %s index: %d\n", cname[i], ndx);
- DebugF("Index must be in range 1..%d\n",
- XkbNumKbdGroups);
- break;
- }
- }
- else {
- ndx = 0;
- }
- found = TRUE;
- if (present & (1 << i)) {
- if ((i == LAYOUT && l_ndx_present & (1 << ndx)) ||
- (i == VARIANT && v_ndx_present & (1 << ndx))) {
- DebugF("Component \"%s\" listed twice\n", tok);
- DebugF("Second definition ignored\n");
- break;
- }
- }
- present |= (1 << i);
- if (i == LAYOUT)
- l_ndx_present |= 1 << ndx;
- if (i == VARIANT)
- v_ndx_present |= 1 << ndx;
- remap->remap[remap->num_remap].word = i;
- remap->remap[remap->num_remap++].index = ndx;
- break;
- }
- }
- if (!found) {
- fprintf(stderr, "Unknown component \"%s\" ignored\n", tok);
- }
- }
- if ((present & PART_MASK) == 0) {
- unsigned mask = PART_MASK;
- ErrorF("Mapping needs at least one of ");
- for (i = 0; (i < MAX_WORDS); i++) {
- if ((1L << i) & mask) {
- mask &= ~(1L << i);
- if (mask)
- DebugF("\"%s,\" ", cname[i]);
- else
- DebugF("or \"%s\"\n", cname[i]);
- }
- }
- DebugF("Illegal mapping ignored\n");
- remap->num_remap = 0;
- return;
- }
- if ((present & COMPONENT_MASK) == 0) {
- DebugF("Mapping needs at least one component\n");
- DebugF("Illegal mapping ignored\n");
- remap->num_remap = 0;
- return;
- }
- remap->number++;
- return;
- }
- static Bool
- MatchOneOf(const char *wanted, const char *vals_defined)
- {
- const char *str, *next;
- int want_len = strlen(wanted);
- for (str = vals_defined, next = NULL; str != NULL; str = next) {
- int len;
- next = strchr(str, ',');
- if (next) {
- len = next - str;
- next++;
- }
- else {
- len = strlen(str);
- }
- if ((len == want_len) && (strncmp(wanted, str, len) == 0))
- return TRUE;
- }
- return FALSE;
- }
- /***====================================================================***/
- static Bool
- CheckLine(InputLine * line,
- RemapSpec * remap, XkbRF_RulePtr rule, XkbRF_GroupPtr group)
- {
- char *str, *tok;
- register int nread, i;
- FileSpec tmp;
- _Xstrtokparams strtok_buf;
- Bool append = FALSE;
- if (line->line[0] == '!') {
- 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 = Xstrdup(gname);
- group->words = Xstrdup(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) {
- DebugF("Must have a mapping before first line of data\n");
- DebugF("Illegal line of data ignored\n");
- return FALSE;
- }
- memset((char *) &tmp, 0, sizeof(FileSpec));
- str = line->line;
- for (nread = 0; (tok = _XStrtok(str, " ", strtok_buf)) != NULL; nread++) {
- str = NULL;
- if (strcmp(tok, "=") == 0) {
- nread--;
- continue;
- }
- if (nread > remap->num_remap) {
- DebugF("Too many words on a line\n");
- DebugF("Extra word \"%s\" ignored\n", tok);
- continue;
- }
- tmp.name[remap->remap[nread].word] = tok;
- if (*tok == '+' || *tok == '|')
- append = TRUE;
- }
- if (nread < remap->num_remap) {
- DebugF("Too few words on a line: %s\n", line->line);
- DebugF("line ignored\n");
- return FALSE;
- }
- rule->flags = 0;
- rule->number = remap->number;
- if (tmp.name[OPTION])
- rule->flags |= XkbRF_Option;
- else if (append)
- rule->flags |= XkbRF_Append;
- else
- rule->flags |= XkbRF_Normal;
- rule->model = Xstrdup(tmp.name[MODEL]);
- rule->layout = Xstrdup(tmp.name[LAYOUT]);
- rule->variant = Xstrdup(tmp.name[VARIANT]);
- rule->option = Xstrdup(tmp.name[OPTION]);
- rule->keycodes = Xstrdup(tmp.name[KEYCODES]);
- rule->symbols = Xstrdup(tmp.name[SYMBOLS]);
- rule->types = Xstrdup(tmp.name[TYPES]);
- rule->compat = Xstrdup(tmp.name[COMPAT]);
- rule->geometry = Xstrdup(tmp.name[GEOMETRY]);
- rule->layout_num = rule->variant_num = 0;
- for (i = 0; i < nread; i++) {
- if (remap->remap[i].index) {
- if (remap->remap[i].word == LAYOUT)
- rule->layout_num = remap->remap[i].index;
- if (remap->remap[i].word == VARIANT)
- rule->variant_num = remap->remap[i].index;
- }
- }
- return TRUE;
- }
- static char *
- _Concat(char *str1, const char *str2)
- {
- int len;
- if ((!str1) || (!str2))
- return str1;
- len = strlen(str1) + strlen(str2) + 1;
- str1 = realloc(str1, len * sizeof(char));
- if (str1)
- strcat(str1, str2);
- return str1;
- }
- static void
- squeeze_spaces(char *p1)
- {
- char *p2;
- for (p2 = p1; *p2; p2++) {
- *p1 = *p2;
- if (*p1 != ' ')
- p1++;
- }
- *p1 = '\0';
- }
- static Bool
- MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
- {
- char *options;
- memset((char *) mdefs, 0, sizeof(XkbRF_MultiDefsRec));
- mdefs->model = defs->model;
- options = Xstrdup(defs->options);
- if (options)
- squeeze_spaces(options);
- mdefs->options = options;
- if (defs->layout) {
- if (!strchr(defs->layout, ',')) {
- mdefs->layout[0] = defs->layout;
- }
- else {
- char *p;
- char *layout;
- int i;
- layout = Xstrdup(defs->layout);
- if (layout == NULL)
- return FALSE;
- squeeze_spaces(layout);
- mdefs->layout[1] = layout;
- p = layout;
- for (i = 2; i <= XkbNumKbdGroups; i++) {
- if ((p = strchr(p, ','))) {
- *p++ = '\0';
- mdefs->layout[i] = p;
- }
- else {
- break;
- }
- }
- if (p && (p = strchr(p, ',')))
- *p = '\0';
- }
- }
- if (defs->variant) {
- if (!strchr(defs->variant, ',')) {
- mdefs->variant[0] = defs->variant;
- }
- else {
- char *p;
- char *variant;
- int i;
- variant = Xstrdup(defs->variant);
- if (variant == NULL)
- return FALSE;
- squeeze_spaces(variant);
- mdefs->variant[1] = variant;
- p = variant;
- for (i = 2; i <= XkbNumKbdGroups; i++) {
- if ((p = strchr(p, ','))) {
- *p++ = '\0';
- mdefs->variant[i] = p;
- }
- else {
- break;
- }
- }
- if (p && (p = strchr(p, ',')))
- *p = '\0';
- }
- }
- return TRUE;
- }
- static void
- FreeMultiDefs(XkbRF_MultiDefsPtr defs)
- {
- free((void *) defs->options);
- free((void *) defs->layout[1]);
- free((void *) defs->variant[1]);
- }
- static void
- Apply(const char *src, char **dst)
- {
- if (src) {
- if (*src == '+' || *src == '!') {
- *dst = _Concat(*dst, src);
- }
- else {
- if (*dst == NULL)
- *dst = Xstrdup(src);
- }
- }
- }
- static void
- XkbRF_ApplyRule(XkbRF_RulePtr rule, XkbComponentNamesPtr names)
- {
- rule->flags &= ~XkbRF_PendingMatch; /* clear the flag because it's applied */
- Apply(rule->keycodes, &names->keycodes);
- Apply(rule->symbols, &names->symbols);
- Apply(rule->types, &names->types);
- Apply(rule->compat, &names->compat);
- Apply(rule->geometry, &names->geometry);
- }
- static Bool
- CheckGroup(XkbRF_RulesPtr rules, const char *group_name, const char *name)
- {
- 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
- XkbRF_CheckApplyRule(XkbRF_RulePtr rule,
- XkbRF_MultiDefsPtr mdefs,
- XkbComponentNamesPtr names, XkbRF_RulesPtr rules)
- {
- Bool pending = FALSE;
- if (rule->model != NULL) {
- if (mdefs->model == NULL)
- return 0;
- if (strcmp(rule->model, "*") == 0) {
- pending = TRUE;
- }
- else {
- 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) {
- if (mdefs->options == NULL)
- return 0;
- if ((!MatchOneOf(rule->option, mdefs->options)))
- return 0;
- }
- if (rule->layout != NULL) {
- if (mdefs->layout[rule->layout_num] == NULL ||
- *mdefs->layout[rule->layout_num] == '\0')
- return 0;
- if (strcmp(rule->layout, "*") == 0) {
- pending = TRUE;
- }
- else {
- 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) {
- if (mdefs->variant[rule->variant_num] == NULL ||
- *mdefs->variant[rule->variant_num] == '\0')
- return 0;
- if (strcmp(rule->variant, "*") == 0) {
- pending = TRUE;
- }
- else {
- 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) {
- rule->flags |= XkbRF_PendingMatch;
- return rule->number;
- }
- /* exact match, apply it now */
- XkbRF_ApplyRule(rule, names);
- return rule->number;
- }
- static void
- XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules)
- {
- register int i;
- XkbRF_RulePtr rule;
- for (i = 0, rule = rules->rules; i < rules->num_rules; i++, rule++) {
- rule->flags &= ~XkbRF_PendingMatch;
- }
- }
- static void
- XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules, XkbComponentNamesPtr names)
- {
- int i;
- XkbRF_RulePtr rule;
- for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) {
- if ((rule->flags & XkbRF_PendingMatch) == 0)
- continue;
- XkbRF_ApplyRule(rule, names);
- }
- }
- static void
- XkbRF_CheckApplyRules(XkbRF_RulesPtr rules,
- XkbRF_MultiDefsPtr mdefs,
- XkbComponentNamesPtr names, int flags)
- {
- int i;
- XkbRF_RulePtr rule;
- 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, rules);
- if (skip && !(flags & XkbRF_Option)) {
- for (; (i < rules->num_rules) && (rule->number == skip);
- rule++, i++);
- rule--;
- i--;
- }
- }
- }
- /***====================================================================***/
- static char *
- XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs)
- {
- char *str, *outstr, *orig, *var;
- int len, ndx;
- orig = name;
- str = index(name, '%');
- if (str == NULL)
- return name;
- len = strlen(name);
- while (str != NULL) {
- char pfx = str[1];
- int extra_len = 0;
- if ((pfx == '+') || (pfx == '|') || (pfx == '_') || (pfx == '-')) {
- extra_len = 1;
- str++;
- }
- else if (pfx == '(') {
- extra_len = 2;
- str++;
- }
- var = str + 1;
- str = get_index(var + 1, &ndx);
- if (ndx == -1) {
- str = index(str, '%');
- continue;
- }
- if ((*var == 'l') && mdefs->layout[ndx] && *mdefs->layout[ndx])
- len += strlen(mdefs->layout[ndx]) + extra_len;
- else if ((*var == 'm') && mdefs->model)
- len += strlen(mdefs->model) + extra_len;
- else if ((*var == 'v') && mdefs->variant[ndx] && *mdefs->variant[ndx])
- len += strlen(mdefs->variant[ndx]) + extra_len;
- if ((pfx == '(') && (*str == ')')) {
- str++;
- }
- str = index(&str[0], '%');
- }
- name = malloc(len + 1);
- str = orig;
- outstr = name;
- while (*str != '\0') {
- if (str[0] == '%') {
- char pfx, sfx;
- str++;
- pfx = str[0];
- sfx = '\0';
- if ((pfx == '+') || (pfx == '|') || (pfx == '_') || (pfx == '-')) {
- str++;
- }
- else if (pfx == '(') {
- sfx = ')';
- str++;
- }
- else
- pfx = '\0';
- var = str;
- str = get_index(var + 1, &ndx);
- if (ndx == -1) {
- continue;
- }
- if ((*var == 'l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) {
- if (pfx)
- *outstr++ = pfx;
- strcpy(outstr, mdefs->layout[ndx]);
- outstr += strlen(mdefs->layout[ndx]);
- if (sfx)
- *outstr++ = sfx;
- }
- else if ((*var == 'm') && (mdefs->model)) {
- if (pfx)
- *outstr++ = pfx;
- strcpy(outstr, mdefs->model);
- outstr += strlen(mdefs->model);
- if (sfx)
- *outstr++ = sfx;
- }
- else if ((*var == 'v') && mdefs->variant[ndx] &&
- *mdefs->variant[ndx]) {
- if (pfx)
- *outstr++ = pfx;
- strcpy(outstr, mdefs->variant[ndx]);
- outstr += strlen(mdefs->variant[ndx]);
- if (sfx)
- *outstr++ = sfx;
- }
- if ((pfx == '(') && (*str == ')'))
- str++;
- }
- else {
- *outstr++ = *str++;
- }
- }
- *outstr++ = '\0';
- if (orig != name)
- free(orig);
- return name;
- }
- /***====================================================================***/
- Bool
- XkbRF_GetComponents(XkbRF_RulesPtr rules,
- XkbRF_VarDefsPtr defs, XkbComponentNamesPtr names)
- {
- XkbRF_MultiDefsRec mdefs;
- MakeMultiDefs(&mdefs, defs);
- memset((char *) names, 0, sizeof(XkbComponentNamesRec));
- XkbRF_ClearPartialMatches(rules);
- XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal);
- XkbRF_ApplyPartialMatches(rules, names);
- XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
- XkbRF_ApplyPartialMatches(rules, names);
- XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
- XkbRF_ApplyPartialMatches(rules, names);
- if (names->keycodes)
- names->keycodes = XkbRF_SubstituteVars(names->keycodes, &mdefs);
- if (names->symbols)
- names->symbols = XkbRF_SubstituteVars(names->symbols, &mdefs);
- if (names->types)
- names->types = XkbRF_SubstituteVars(names->types, &mdefs);
- if (names->compat)
- names->compat = XkbRF_SubstituteVars(names->compat, &mdefs);
- if (names->geometry)
- names->geometry = XkbRF_SubstituteVars(names->geometry, &mdefs);
- FreeMultiDefs(&mdefs);
- return (names->keycodes && names->symbols && names->types &&
- names->compat && names->geometry);
- }
- static XkbRF_RulePtr
- XkbRF_AddRule(XkbRF_RulesPtr rules)
- {
- if (rules->sz_rules < 1) {
- rules->sz_rules = 16;
- rules->num_rules = 0;
- rules->rules = calloc(rules->sz_rules, sizeof(XkbRF_RuleRec));
- }
- else if (rules->num_rules >= rules->sz_rules) {
- rules->sz_rules *= 2;
- rules->rules = realloc(rules->rules,
- rules->sz_rules * sizeof(XkbRF_RuleRec));
- }
- if (!rules->rules) {
- rules->sz_rules = rules->num_rules = 0;
- DebugF("Allocation failure in XkbRF_AddRule\n");
- return NULL;
- }
- memset((char *) &rules->rules[rules->num_rules], 0, sizeof(XkbRF_RuleRec));
- return &rules->rules[rules->num_rules++];
- }
- static XkbRF_GroupPtr
- XkbRF_AddGroup(XkbRF_RulesPtr rules)
- {
- if (rules->sz_groups < 1) {
- rules->sz_groups = 16;
- rules->num_groups = 0;
- rules->groups = calloc(rules->sz_groups, sizeof(XkbRF_GroupRec));
- }
- else if (rules->num_groups >= rules->sz_groups) {
- rules->sz_groups *= 2;
- rules->groups = realloc(rules->groups,
- rules->sz_groups * sizeof(XkbRF_GroupRec));
- }
- if (!rules->groups) {
- rules->sz_groups = rules->num_groups = 0;
- return NULL;
- }
- memset((char *) &rules->groups[rules->num_groups], 0,
- sizeof(XkbRF_GroupRec));
- return &rules->groups[rules->num_groups++];
- }
- Bool
- XkbRF_LoadRules(FILE * file, XkbRF_RulesPtr rules)
- {
- InputLine line;
- RemapSpec remap;
- XkbRF_RuleRec trule, *rule;
- XkbRF_GroupRec tgroup, *group;
- if (!(rules && file))
- return FALSE;
- memset((char *) &remap, 0, sizeof(RemapSpec));
- memset((char *) &tgroup, 0, sizeof(XkbRF_GroupRec));
- InitInputLine(&line);
- while (GetInputLine(file, &line, TRUE)) {
- if (CheckLine(&line, &remap, &trule, &tgroup)) {
- if (tgroup.number) {
- if ((group = XkbRF_AddGroup(rules)) != NULL) {
- *group = tgroup;
- memset((char *) &tgroup, 0, sizeof(XkbRF_GroupRec));
- }
- }
- else {
- if ((rule = XkbRF_AddRule(rules)) != NULL) {
- *rule = trule;
- memset((char *) &trule, 0, sizeof(XkbRF_RuleRec));
- }
- }
- }
- line.num_line = 0;
- }
- FreeInputLine(&line);
- return TRUE;
- }
- Bool
- XkbRF_LoadRulesByName(char *base, char *locale, XkbRF_RulesPtr rules)
- {
- FILE *file;
- char buf[PATH_MAX];
- Bool ok;
- if ((!base) || (!rules))
- return FALSE;
- if (locale) {
- if (snprintf(buf, PATH_MAX, "%s-%s", base, locale) >= PATH_MAX)
- return FALSE;
- }
- else {
- if (strlen(base) + 1 > PATH_MAX)
- return FALSE;
- strcpy(buf, base);
- }
- file = fopen(buf, "r");
- if ((!file) && (locale)) { /* fallback if locale was specified */
- strcpy(buf, base);
- file = fopen(buf, "r");
- }
- if (!file)
- return FALSE;
- ok = XkbRF_LoadRules(file, rules);
- fclose(file);
- return ok;
- }
- /***====================================================================***/
- XkbRF_RulesPtr
- XkbRF_Create(void)
- {
- return calloc(1, sizeof(XkbRF_RulesRec));
- }
- /***====================================================================***/
- void
- XkbRF_Free(XkbRF_RulesPtr rules, Bool freeRules)
- {
- int i;
- XkbRF_RulePtr rule;
- XkbRF_GroupPtr group;
- if (!rules)
- return;
- if (rules->rules) {
- for (i = 0, rule = rules->rules; i < rules->num_rules; i++, rule++) {
- free((void *) rule->model);
- free((void *) rule->layout);
- free((void *) rule->variant);
- free((void *) rule->option);
- free((void *) rule->keycodes);
- free((void *) rule->symbols);
- free((void *) rule->types);
- free((void *) rule->compat);
- free((void *) rule->geometry);
- memset((char *) rule, 0, sizeof(XkbRF_RuleRec));
- }
- free(rules->rules);
- 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++) {
- free((void *) group->name);
- free(group->words);
- }
- free(rules->groups);
- rules->num_groups = 0;
- rules->groups = NULL;
- }
- if (freeRules)
- free(rules);
- return;
- }
|