# HG changeset patch # User pfalcon@localhost # Date 1181567228 0 # Node ID 869314ae90f46a8c2d34080005d4079cb0d0fcf4 # Parent 38c3459f2e1a1c8dc7aacb486f201bdda638c7f2 Add support for loading multiple independent layouts. All layouts found in ~/.matchbox/keyboard.d/ are loaded, realistically these will be symlinks to system-wide store. This directory has the highest priority of all other layout selection mechanism (except for $MB_KBD_CONFIG). diff -r 38c3459f2e1a -r 869314ae90f4 src/config-parser.c --- a/src/config-parser.c Mon Apr 09 00:08:07 2007 +0000 +++ b/src/config-parser.c Mon Jun 11 13:07:08 2007 +0000 @@ -17,6 +17,7 @@ * */ +#include #include "matchbox-keyboard.h" /* @@ -57,6 +58,9 @@ */ + +int mb_kbd_config_parse_file(MBKeyboard *kbd, char *path); +static int mb_kbd_config_parse_data(MBKeyboard *kbd, char *data); struct _keysymlookup { @@ -170,12 +174,9 @@ config_str_to_modtype(const char* str) } -static char* -config_load_file(MBKeyboard *kbd, char *variant_in) -{ - struct stat stat_info; - FILE* fp; - char *result; +int +mb_kbd_config_load(MBKeyboard *kbd, char *variant_in) +{ char *country = NULL; char *variant = NULL; char *lang = NULL; @@ -195,7 +196,44 @@ config_load_file(MBKeyboard *kbd, char * if (util_file_readable(path)) goto load; - return NULL; + return 0; + } + + if (getenv("HOME")) + { + snprintf(path, 1024, "%s/.matchbox/keyboard.d", getenv("HOME")); + + DBG("checking %s\n", path); + + if (util_file_readable(path)) + { + DIR *dir = opendir(path); + struct dirent *dirent; + if (!dir) + { + perror("matchbox-keyboard"); + util_fatal_error("Cannot read keyboard.d.\n"); + } + errno = 0; + while ((dirent = readdir(dir))) + { + if (dirent->d_name[0] == '.') + continue; + snprintf(path, 1024, "%s/.matchbox/keyboard.d/%s", getenv("HOME"), dirent->d_name); + if (!mb_kbd_config_parse_file(kbd, path)) + { + util_fatal_error("Cannot read file in keyboard.d.\n"); + } + + } + if (errno) + { + perror("matchbox-keyboard"); + util_fatal_error("Error reading keyboard.d.\n"); + } + closedir(dir); + return 1; + } } lang = getenv("MB_KBD_LANG"); @@ -268,29 +306,11 @@ config_load_file(MBKeyboard *kbd, char * DBG("checking %s\n", path); if (!util_file_readable(path)) - return NULL; + return 0; load: - if (stat(path, &stat_info)) - return NULL; - - if ((fp = fopen(path, "rb")) == NULL) - return NULL; - - DBG("loading %s\n", path); - - kbd->config_file = strdup(path); - - result = malloc(stat_info.st_size + 1); - - n = fread(result, 1, stat_info.st_size, fp); - - if (n >= 0) result[n] = '\0'; - - fclose(fp); - - return result; + return mb_kbd_config_parse_file(kbd, path); } static const char * @@ -567,25 +587,48 @@ config_xml_start_cb(void *data, const ch int -mb_kbd_config_load(MBKeyboard *kbd, char *variant) -{ - char *data; +mb_kbd_config_parse_file(MBKeyboard *kbd, char *path) +{ + char *buffer; + struct stat stat_info; + FILE* fp; + int n; + + if (stat(path, &stat_info)) + return 0; + + if ((fp = fopen(path, "rb")) == NULL) + return 0; + + DBG("loading %s\n", path); + + kbd->config_file = strdup(path); + + buffer = malloc(stat_info.st_size + 1); + + n = fread(buffer, 1, stat_info.st_size, fp); + + if (n >= 0) buffer[n] = '\0'; + + fclose(fp); + + mb_kbd_config_parse_data(kbd, buffer); + + free(buffer); + + return 1; +} + +static int +mb_kbd_config_parse_data(MBKeyboard *kbd, char *data) +{ XML_Parser p; MBKeyboardConfigState *state; - if ((data = config_load_file(kbd, variant)) == NULL) - util_fatal_error("Couldn't find a keyboard config file\n"); - p = XML_ParserCreate(NULL); if (!p) util_fatal_error("Couldn't allocate memory for XML parser\n"); - - if (variant && !strstr(kbd->config_file, variant)) - fprintf(stderr, - "matchbox-keyboard: *Warning* Unable to locate variant: %s\n" - " falling back to %s\n", - variant, kbd->config_file); state = util_malloc0(sizeof(MBKeyboardConfigState)); @@ -607,6 +650,9 @@ mb_kbd_config_load(MBKeyboard *kbd, char util_fatal_error("XML Parse failed.\n"); } + free(state); + XML_ParserFree(p); + return 1; }