📄 config-parser.c.svn-base
字号:
/* * Matchbox Keyboard - A lightweight software keyboard. * * Authored By Matthew Allum <mallum@o-hand.com> * * Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */#include "matchbox-keyboard.h"/* <keyboard> <options> <font prefered-size=''> <size fixed='100x100'> <padding> </options> <layout id="name"> <row> <key id="optional-id" obey-caps='true|false' width="1000" // 1/1000's of a unit key size fill="true" // Set width to available space > <default display="a" display="image:" action="utf8char" // optional, action defaults to this action="string" // from lookup below action="modifier:Shift|Alt|ctrl|mod1|mod2|mod3|caps" action="xkeysym:XK_BLAH" <shifted ...... > <mod1 ...... > /> <key ... /> <key ... /> <space width="1000" </row> </layout> </keyboard>*/struct _keysymlookup{ KeySym keysym; char *name; } MBKeyboardKeysymLookup[] ={ { XK_BackSpace, "backspace" }, { XK_Tab, "tab" }, { XK_Linefeed, "linefeed" }, { XK_Clear, "clear" }, { XK_Return, "return" }, { XK_Pause, "pause" }, { XK_Scroll_Lock, "scrolllock" }, { XK_Sys_Req, "sysreq" }, { XK_Escape, "escape" }, { XK_Delete, "delete" }, { XK_Home, "home" }, { XK_Left, "left" }, { XK_Up, "up" }, { XK_Right, "right" }, { XK_Down, "down" }, { XK_Prior, "prior" }, { XK_Page_Up, "pageup" }, { XK_Next, "next" }, { XK_Page_Down, "pagedown" }, { XK_End, "end" }, { XK_Begin, "begin" }, { XK_space, "space" }, { XK_F1, "f1" }, { XK_F2, "f2" }, { XK_F3, "f3" }, { XK_F4, "f4" }, { XK_F5, "f5" }, { XK_F6, "f6" }, { XK_F7, "f7" }, { XK_F8, "f8" }, { XK_F9, "f9" }, { XK_F10, "f10" }, { XK_F11, "f11" }, { XK_F12, "f12" }};struct _modlookup{ char *name; MBKeyboardKeyModType type;}ModLookup[] ={ { "shift", MBKeyboardKeyModShift }, { "alt", MBKeyboardKeyModAlt }, { "ctrl", MBKeyboardKeyModControl }, { "control", MBKeyboardKeyModControl }, { "mod1", MBKeyboardKeyModMod1 }, { "mod2", MBKeyboardKeyModMod2 }, { "mod3", MBKeyboardKeyModMod3 }, { "caps", MBKeyboardKeyModCaps }};struct _layoutlookup{ MBKeyboardLayoutType type; char *name;}LayoutLookup[] ={ {MBKeyboardLows, "lows" }, {MBKeyboardCaps, "caps" }, {MBKeyboardNumbers, "numbers" }, {MBKeyboardSymbols, "symbols" }, {MBKeyboardChinese, "Chinese" }};typedef struct MBKeyboardConfigState{ MBKeyboard *keyboard; MBKeyboardLayout *current_layout; MBKeyboardRow *current_row; MBKeyboardKey *current_key; Bool error; char *error_msg; int error_lineno; XML_Parser parser;}MBKeyboardConfigState;void set_error(MBKeyboardConfigState *state, char *msg){ state->error = True; state->error_lineno = XML_GetCurrentLineNumber(state->parser); state->error_msg = msg;}KeySymconfig_str_to_keysym(const char* str){ int i; DBG("checking %s", str); for (i=0; i<sizeof(MBKeyboardKeysymLookup)/sizeof(struct _keysymlookup); i++) if (streq(str, MBKeyboardKeysymLookup[i].name)) return MBKeyboardKeysymLookup[i].keysym; DBG("didnt find it %s", str); return 0;}MBKeyboardKeyModTypeconfig_str_to_modtype(const char* str){ int i; for (i=0; i<sizeof(ModLookup)/sizeof(struct _modlookup); i++) { DBG("checking '%s' vs '%s'", str, ModLookup[i].name); if (streq(str, ModLookup[i].name)) return ModLookup[i].type; } return 0;}MBKeyboardLayoutTypeconfig_str_to_layouttype(const char* str){ int i; for (i=0; i<sizeof(LayoutLookup)/sizeof(struct _modlookup); i++) { DBG("checking '%s' vs '%s'", str, LayoutLookup[i].name); if (streq(str, LayoutLookup[i].name)) return LayoutLookup[i].type; } return 0;}static char* config_load_file(MBKeyboard *kbd, char *variant_in){ struct stat stat_info; FILE* fp; char *result; char *country = NULL; char *variant = NULL; char *lang = NULL; int n = 0, i = 0; char path[1024]; /* XXX MAXPATHLEN */ /* keyboard[-country][-variant].xml */ /* This is an overide mainly for people developing keyboard layouts */ if (getenv("MB_KBD_CONFIG")) { snprintf(path, 1024, "%s", getenv("MB_KBD_CONFIG")); DBG("checking %s\n", path); if (util_file_readable(path)) goto load; return NULL; } lang = getenv("MB_KBD_LANG"); if (lang == NULL) lang = getenv("LANG"); if (lang) { n = strlen(lang) + 2; country = alloca(n); snprintf(country, n, "-%s", lang); /* strip anything after first '.' */ while(country[i] != '\0') if (country[i] == '.') country[i] = '\0'; else i++; } if (variant_in) { n = strlen(variant_in) + 2; variant = alloca(n); snprintf(variant, n, "-%s", variant_in); } if (getenv("HOME")) { snprintf(path, 1024, "%s/.matchbox/keyboard.xml", getenv("HOME")); DBG("checking %s\n", path); if (util_file_readable(path)) goto load; } /* Hmmm :/ */ snprintf(path, 1024, PKGDATADIR "/keyboard%s%s.xml", country == NULL ? "" : country, variant == NULL ? "" : variant); DBG("checking %s\n", path); if (util_file_readable(path)) goto load; snprintf(path, 1024, PKGDATADIR "/keyboard%s.xml", variant == NULL ? "" : variant); DBG("checking %s\n", path); if (util_file_readable(path)) goto load; snprintf(path, 1024, PKGDATADIR "/keyboard%s.xml", country == NULL ? "" : country); DBG("checking %s\n", path); if (util_file_readable(path)) goto load; snprintf(path, 1024, PKGDATADIR "/keyboard.xml"); DBG("checking %s\n", path); if (!util_file_readable(path)) return NULL; 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;}static const char *attr_get_val (char *key, const char **attr){ int i = 0; while (attr[i] != NULL) { if (!strcmp(attr[i], key)) return attr[i+1]; i += 2; } return NULL;}static voidconfig_handle_key_background_tag(MBKeyboardConfigState *state, const char *tag, const char **attr){ const char *val; char buf[512]; Bool pushimage; if (streq(tag, "normalimage")) { pushimage = False; } else if (streq(tag, "pushimage")) { pushimage = True; } else { set_error(state, "Unknown background image"); return; } if ((val = attr_get_val("image", attr)) == NULL) { set_error(state, "Attribute 'image' is required"); return; } if (val[0] != '/') { snprintf(buf, 512, "%s/%s", PKGDATADIR, val); if (!util_file_readable(buf)) snprintf(buf, 512, "%s/.matchbox/%s", getenv("HOME"), val); } else { snprintf(buf, 512, "%s", val); } if (pushimage) mb_kbd_key_set_normal_image(state->current_key, buf); else mb_kbd_key_set_push_image(state->current_key, buf);}static voidconfig_handle_key_subtag(MBKeyboardConfigState *state, const char *tag, const char **attr){ MBKeyboardKeyStateType keystate; const char *val; KeySym found_keysym; /* TODO: Fix below with a lookup table */ if (streq(tag, "normal") || streq(tag, "default")) { keystate = MBKeyboardKeyStateNormal; } else if (streq(tag, "shifted")) { keystate = MBKeyboardKeyStateShifted; } else if (streq(tag, "mod1")) { keystate = MBKeyboardKeyStateMod1; } else if (streq(tag, "mod2")) { keystate = MBKeyboardKeyStateMod2; } else if (streq(tag, "mod3")) { keystate = MBKeyboardKeyStateMod3; } else { set_error(state, "Unknown key subtag"); return; } if ((val = attr_get_val("display", attr)) == NULL) { set_error(state, "Attribute 'display' is required"); return; } if (!strncmp(val, "image:", 6)) { MBKeyboardImage *img; if (val[6] != '/') { /* Relative, rather than absolute path, try pkddatadir and home */ char buf[512]; snprintf(buf, 512, "%s/%s", PKGDATADIR, &val[6]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -