X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Fxkbcomp.c;h=68e180f779132659d050b273d472788c3a5de394;hb=db3e8f2c0842aeaf1d00177c248ff908073fe73a;hp=4adb4bed86bc3faec39476af6c809364556bb7c3;hpb=99d2f4a5eb858d3d906f3de1f78f1118e148e8d7;p=profile%2Fivi%2Flibxkbcommon.git diff --git a/src/xkbcomp/xkbcomp.c b/src/xkbcomp/xkbcomp.c index 4adb4be..68e180f 100644 --- a/src/xkbcomp/xkbcomp.c +++ b/src/xkbcomp/xkbcomp.c @@ -24,171 +24,303 @@ sale, use or other dealings in this Software without prior written authorization from the authors. */ -#include -#include "X11/extensions/XKBcommon.h" -#include -#include "XKBcommonint.h" -#include "xkbcomp.h" +#include "xkbcomp-priv.h" +#include "rules.h" #include "parseutils.h" -#include "utils.h" +#include "path.h" -#ifndef DFLT_XKB_CONFIG_ROOT -#define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb" -#endif - -/* Global debugging flags */ -unsigned int debugFlags = 0; +/* Global warning level */ unsigned int warningLevel = 0; #define ISEMPTY(str) (!(str) || (strlen(str) == 0)) static XkbFile * -XkbKeymapFileFromComponents(const XkbComponentNamesPtr ktcsg) +XkbKeymapFileFromComponents(struct xkb_context *ctx, + const struct xkb_component_names *ktcsg) { - XkbFile *keycodes, *types, *compat, *symbols, *geometry; + XkbFile *keycodes, *types, *compat, *symbols; IncludeStmt *inc; - if (!ktcsg) { - ERROR("no components to generate keymap file from\n"); - return NULL; - } - inc = IncludeCreate(ktcsg->keycodes, MergeDefault); - keycodes = CreateXKBFile(XkmKeyNamesIndex, NULL, (ParseCommon *)inc, 0); + keycodes = CreateXKBFile(ctx, XkmKeyNamesIndex, NULL, + (ParseCommon *)inc, 0); inc = IncludeCreate(ktcsg->types, MergeDefault); - types = CreateXKBFile(XkmTypesIndex, NULL, (ParseCommon *)inc, 0); + types = CreateXKBFile(ctx, XkmTypesIndex, NULL, + (ParseCommon *)inc, 0); AppendStmt(&keycodes->common, &types->common); inc = IncludeCreate(ktcsg->compat, MergeDefault); - compat = CreateXKBFile(XkmCompatMapIndex, NULL, (ParseCommon *)inc, 0); + compat = CreateXKBFile(ctx, XkmCompatMapIndex, NULL, + (ParseCommon *)inc, 0); AppendStmt(&keycodes->common, &compat->common); inc = IncludeCreate(ktcsg->symbols, MergeDefault); - symbols = CreateXKBFile(XkmSymbolsIndex, NULL, (ParseCommon *)inc, 0); + symbols = CreateXKBFile(ctx, XkmSymbolsIndex, NULL, + (ParseCommon *)inc, 0); AppendStmt(&keycodes->common, &symbols->common); - inc = IncludeCreate(ktcsg->geometry, MergeDefault); - geometry = CreateXKBFile(XkmGeometryIndex, NULL, (ParseCommon *)inc, 0); - AppendStmt(&keycodes->common, &geometry->common); - - return CreateXKBFile(XkmKeymapFile, ktcsg->keymap, &keycodes->common, 0); + return CreateXKBFile(ctx, XkmKeymapFile, + ktcsg->keymap ? ktcsg->keymap : strdup(""), + &keycodes->common, 0); } -static XkbComponentNamesPtr -XkbComponentsFromRules(const char *rulesPath, const XkbRF_VarDefsPtr defs) +static struct xkb_component_names * +XkbComponentsFromRules(struct xkb_context *ctx, + const char *rules, + const XkbRF_VarDefsPtr defs) { - XkbRF_RulesPtr rules; - XkbComponentNamesPtr names = NULL; + FILE *rulesFile = NULL; + char *rulesPath = NULL; + XkbRF_RulesPtr loaded = NULL; + struct xkb_component_names * names = NULL; + int i; + + rulesFile = XkbFindFileInPath(ctx, rules, XkmRulesFile, &rulesPath); + if (!rulesFile) { + ERROR("could not find \"%s\" rules in XKB path\n", rules); + ERROR("%d include paths searched:\n", + xkb_context_num_include_paths(ctx)); + for (i = 0; i < xkb_context_num_include_paths(ctx); i++) + ERROR("\t%s\n", xkb_context_include_path_get(ctx, i)); + return NULL; + } - if (!(rules = XkbcRF_Load((char *)rulesPath, NULL, False, True))) { + if (!(loaded = uTypedCalloc(1, XkbRF_RulesRec))) { + ERROR("failed to allocate XKB rules\n"); + goto unwind_file; + } + + if (!XkbcRF_LoadRules(rulesFile, loaded)) { ERROR("failed to load XKB rules \"%s\"\n", rulesPath); - goto fail; + goto unwind_file; } - if (!(names = _XkbTypedCalloc(1, XkbComponentNamesRec))) { + if (!(names = uTypedCalloc(1, struct xkb_component_names))) { ERROR("failed to allocate XKB components\n"); - goto unwind_rules; + goto unwind_file; } - if (!XkbcRF_GetComponents(rules, defs, names)) { - _XkbFree(names->keymap); - _XkbFree(names->keycodes); - _XkbFree(names->types); - _XkbFree(names->compat); - _XkbFree(names->symbols); - _XkbFree(names->geometry); - _XkbFree(names); + if (!XkbcRF_GetComponents(loaded, defs, names)) { + free(names->keymap); + free(names->keycodes); + free(names->types); + free(names->compat); + free(names->symbols); + free(names); names = NULL; ERROR("no components returned from XKB rules \"%s\"\n", rulesPath); } -unwind_rules: - XkbcRF_Free(rules, True); -fail: +unwind_file: + XkbcRF_Free(loaded); + if (rulesFile) + fclose(rulesFile); + free(rulesPath); return names; } -XkbcDescPtr -XkbcCompileKeymapFromRules(const char *rules, XkbRF_VarDefsPtr defs) +_X_EXPORT struct xkb_keymap * +xkb_map_new_from_names(struct xkb_context *ctx, + const struct xkb_rule_names *rmlvo, + enum xkb_map_compile_flags flags) { - char rulesPath[PATH_MAX]; - int pathlen; - XkbComponentNamesPtr names; - XkbcDescPtr xkb; + XkbRF_VarDefsRec defs; + struct xkb_component_names *names; + struct xkb_keymap *keymap; - if (ISEMPTY(rules) || ISEMPTY(defs->layout)) { + if (!rmlvo || ISEMPTY(rmlvo->rules) || ISEMPTY(rmlvo->layout)) { ERROR("rules and layout required to generate XKB keymap\n"); return NULL; } - pathlen = snprintf(rulesPath, sizeof(rulesPath), - DFLT_XKB_CONFIG_ROOT "/rules/%s", rules); - if (pathlen >= sizeof(rulesPath)) { - ERROR("XKB rules path truncated\n"); - return NULL; - } + defs.model = rmlvo->model; + defs.layout = rmlvo->layout; + defs.variant = rmlvo->variant; + defs.options = rmlvo->options; - names = XkbComponentsFromRules(rulesPath, defs); + names = XkbComponentsFromRules(ctx, rmlvo->rules, &defs); if (!names) { ERROR("failed to generate XKB components from rules \"%s\"\n", - rules); + rmlvo->rules); return NULL; } - xkb = XkbcCompileKeymapFromComponents(names); + keymap = xkb_map_new_from_kccgst(ctx, names, 0); - _XkbFree(names->keymap); - _XkbFree(names->keycodes); - _XkbFree(names->types); - _XkbFree(names->compat); - _XkbFree(names->symbols); - _XkbFree(names->geometry); - _XkbFree(names); + free(names->keymap); + free(names->keycodes); + free(names->types); + free(names->compat); + free(names->symbols); + free(names); - return xkb; + return keymap; } -XkbcDescPtr -XkbcCompileKeymapFromComponents(XkbComponentNamesPtr ktcsg) +static XkbFile * +XkbChooseMap(XkbFile *file, const char *name) { - XkbFile *file, *mapToUse; - XkbcDescPtr xkb; + XkbFile *map = file; - if (!(file = XkbKeymapFileFromComponents(ktcsg))) { - ERROR("failed to generate parsed XKB file from components\n"); - goto fail; - } + /* map specified? */ + if (name) { + while (map) { + if (map->name && strcmp(map->name, name) == 0) + break; + map = (XkbFile *) map->common.next; + } - /* Find map to use */ - mapToUse = file; - if (file->common.next) { - for (; mapToUse; mapToUse = (XkbFile *)mapToUse->common.next) { - if (mapToUse->flags & XkbLC_Default) + if (!map) + ERROR("no map named \"%s\" in input file\n", name); + } + else if (file->common.next) { + /* look for map with XkbLC_Default flag. */ + for (; map; map = (XkbFile *) map->common.next) { + if (map->flags & XkbLC_Default) break; } - if (!mapToUse) { - mapToUse = file; + + if (!map) { + map = file; WARN("no map specified, but components have several\n"); + WARN("using the first defined map, \"%s\"\n", + map->name ? map->name : ""); } } - /* Compile the keyboard */ - if (!(xkb = XkbcAllocKeyboard())) { - ERROR("could not allocate keyboard description\n"); - goto unwind_file; + return map; +} + +static struct xkb_keymap * +compile_keymap(struct xkb_context *ctx, XkbFile *file) +{ + XkbFile *mapToUse; + struct xkb_keymap *keymap = NULL; + + /* Find map to use */ + mapToUse = XkbChooseMap(file, NULL); + if (!mapToUse) + goto err; + + if (mapToUse->type != XkmKeymapFile) { + ERROR("file type %d not handled\n", mapToUse->type); + goto err; } - if (!CompileKeymap(mapToUse, xkb, MergeReplace)) { - ERROR("failed to compile keymap\n"); - goto unwind_xkb; + keymap = CompileKeymap(ctx, mapToUse); + if (!keymap) + goto err; + +err: + FreeXKBFile(file); + return keymap; +} + +_X_EXPORT struct xkb_keymap * +xkb_map_new_from_kccgst(struct xkb_context *ctx, + const struct xkb_component_names *kccgst, + enum xkb_map_compile_flags flags) +{ + XkbFile *file; + + if (!kccgst) { + ERROR("no components specified\n"); + return NULL; } - return xkb; -unwind_xkb: - XkbcFreeKeyboard(xkb, XkbAllComponentsMask, True); -unwind_file: - /* XXX: here's where we would free the XkbFile */ -fail: - return NULL; + if (ISEMPTY(kccgst->keycodes)) { + ERROR("keycodes required to generate XKB keymap\n"); + return NULL; + } + + if (ISEMPTY(kccgst->compat)) { + ERROR("compat map required to generate XKB keymap\n"); + return NULL; + } + + if (ISEMPTY(kccgst->types)) { + ERROR("types required to generate XKB keymap\n"); + return NULL; + } + + if (ISEMPTY(kccgst->symbols)) { + ERROR("symbols required to generate XKB keymap\n"); + return NULL; + } + + if (!(file = XkbKeymapFileFromComponents(ctx, kccgst))) { + ERROR("failed to generate parsed XKB file from components\n"); + return NULL; + } + + return compile_keymap(ctx, file); +} + +_X_EXPORT struct xkb_keymap * +xkb_map_new_from_string(struct xkb_context *ctx, + const char *string, + enum xkb_keymap_format format, + enum xkb_map_compile_flags flags) +{ + XkbFile *file; + + if (format != XKB_KEYMAP_FORMAT_TEXT_V1) { + ERROR("unsupported keymap format %d\n", format); + return NULL; + } + + if (!string) { + ERROR("no string specified to generate XKB keymap\n"); + return NULL; + } + + if (!XKBParseString(ctx, string, "input", &file)) { + ERROR("failed to parse input xkb file\n"); + return NULL; + } + + return compile_keymap(ctx, file); +} + +_X_EXPORT struct xkb_keymap * +xkb_map_new_from_file(struct xkb_context *ctx, + FILE *file, + enum xkb_keymap_format format, + enum xkb_map_compile_flags flags) +{ + XkbFile *xkb_file; + + if (format != XKB_KEYMAP_FORMAT_TEXT_V1) { + ERROR("unsupported keymap format %d\n", format); + return NULL; + } + + if (!file) { + ERROR("no file specified to generate XKB keymap\n"); + return NULL; + } + + if (!XKBParseFile(ctx, file, "(unknown file)", &xkb_file)) { + ERROR("failed to parse input xkb file\n"); + return NULL; + } + + return compile_keymap(ctx, xkb_file); +} + +_X_EXPORT struct xkb_keymap * +xkb_map_ref(struct xkb_keymap *keymap) +{ + keymap->refcnt++; + return keymap; +} + +_X_EXPORT void +xkb_map_unref(struct xkb_keymap *keymap) +{ + if (--keymap->refcnt > 0) + return; + + XkbcFreeKeyboard(keymap); }