Enlightenment CVS committal Author : sndev Project : e_modules Module : language
Dir : e_modules/language/src/module Modified Files: Makefile.am e_mod_lang.c Log Message: So, finally, the module is able to switch between selected languages. I hope it will work for everybody, since some paths to X files are hard coded and they can not to exist in different versions of Xorg. Moreover, the current implementation is connected to my Xorg7.0. Basically, I cannot predict the behavior of the module on older Xorg versions. Please Just try the module, and report any problems/bugs to me. =================================================================== RCS file: /cvs/e/e_modules/language/src/module/Makefile.am,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- Makefile.am 15 May 2006 19:32:10 -0000 1.1 +++ Makefile.am 17 May 2006 22:26:00 -0000 1.2 @@ -13,7 +13,7 @@ e_mod_keybindings.h \ e_mod_lang.c \ e_mod_lang.h -module_la_LIBADD = @e_libs@ -lexml +module_la_LIBADD = @e_libs@ -lexml -lxkbfile -lX11 module_la_LDFLAGS = -module -avoid-version module_la_DEPENDENCIES = $(top_builddir)/config.h =================================================================== RCS file: /cvs/e/e_modules/language/src/module/e_mod_lang.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- e_mod_lang.c 15 May 2006 19:32:10 -0000 1.1 +++ e_mod_lang.c 17 May 2006 22:26:00 -0000 1.2 @@ -3,6 +3,12 @@ #include "e_mod_main.h" #include <EXML.h> +#include <X11/Xlib.h> +//#include <X11/Xos.h> +#include <X11/XKBlib.h> +//#include <X11/extensions/XKBfile.h> +//#include <X11/extensions/XKBconfig.h> +#include <X11/extensions/XKBrules.h> #define EXML_RETURN_ON_ERROR(xml) \ { \ @@ -10,6 +16,75 @@ return; \ } +/******************************************************/ + +#define DFLT_XKB_RULES_FILE "/usr/share/X11/xkb/rules/xorg" +#define DFLT_XKB_LAYOUT "us" +#define DFLT_XKB_MODEL "pc101" + +#define RULES_INDX 0 +#define CONFIG_INDX 1 +#define DISPLAY_INDX 2 +#define LOCALE_INDX 3 +#define MODEL_INDX 4 +#define LAYOUT_INDX 5 +#define VARIANT_INDX 6 +#define KEYCODES_INDX 7 +#define TYPES_INDX 8 +#define COMPAT_INDX 9 +#define SYMBOLS_INDX 10 +#define GEOMETRY_INDX 11 +#define KEYMAP_INDX 12 +#define NUM_OF_INDX 13 + +#define LXC_FREE(p) \ + { \ + int i; \ + for (i = 0; i < NUM_OF_INDX; i++) \ + if (p->sv[i]) evas_stringshare_del(p->sv[i]); \ + if (p->dpy) XCloseDisplay(p->dpy); \ + E_FREE(p); \ + } + +#define LANG_SETTING_SET_RETURN_ON_ERROR(p) \ + { \ + LXC_FREE(p); \ + e_module_dialog_show("Error", "Error : If You get this error dialog please<br>" \ + "let the author([EMAIL PROTECTED]) to know about it.<br>" \ + "Moreover, please let him know about your version of Xorg." \ + "<br>Please be patient. We are working on fixing all the" \ + "problems"); \ + return; \ + } + +#define LXC_SET_STRING(l, c, s) \ + { \ + if (!(l->sv[c])) \ + l->sv[c] = (!s ? NULL : (char *)evas_stringshare_add(s)); \ + } + +typedef struct _Language_Xkb_Config Language_Xkb_Config; + +struct _Language_Xkb_Config +{ + Display *dpy; + XkbRF_VarDefsRec rdefs; + char *sv[NUM_OF_INDX]; +}; + +#if 0 +static int _lang_check_name(char *name, char* string); +#endif + +static int _lang_apply_components_names(Language_Xkb_Config *lxc); +static int _lang_apply_rules(Language_Xkb_Config *lxc); +static int _lang_server_values_get(Language_Xkb_Config *lxc); +static Display * _lang_server_display_get(); +static void _lang_apply_language_settings(const char *model, const char *layout, + const char *variant); + +/******************************************************/ + /************** private ******************/ static void _lang_load_xfree_language_kbd_layouts_load_configItem(EXML *xml, Language_Predef *lp); @@ -32,6 +107,16 @@ /* here goes the actuall work that calls X to switch the kbd layout, etc. */ + { + Language *l; + + l = evas_list_nth(cfg->languages, cfg->language_selector); + if (l) + { + _lang_apply_language_settings(l->kbd_model, l->kbd_layout, l->kbd_variant); + } + } + /* debug */ #if 0 { @@ -535,3 +620,226 @@ return strcmp((const char *)lp1->lang_name, (const char *)lp2->lang_name); } /****************************************/ + +static void +_lang_apply_language_settings(const char *model, const char *layout, + const char *variant) +{ + Language_Xkb_Config *lxc; + + if (!layout) return; + + lxc = E_NEW(Language_Xkb_Config, 1); + if (!lxc) return; + + LXC_SET_STRING(lxc, MODEL_INDX, model); + LXC_SET_STRING(lxc, LAYOUT_INDX, layout); + LXC_SET_STRING(lxc, VARIANT_INDX, variant); + + if (!(lxc->dpy = _lang_server_display_get())) + LANG_SETTING_SET_RETURN_ON_ERROR(lxc); + + // this is a hack of locale. + lxc->sv[LOCALE_INDX] = (char *)evas_stringshare_add("C"); + + if (!_lang_server_values_get(lxc)) + LANG_SETTING_SET_RETURN_ON_ERROR(lxc); + + if (!_lang_apply_rules(lxc)) + LANG_SETTING_SET_RETURN_ON_ERROR(lxc); + + if (!_lang_apply_components_names(lxc)) + LANG_SETTING_SET_RETURN_ON_ERROR(lxc); + + LXC_FREE(lxc); +} +static Display * +_lang_server_display_get() +{ + int major, minor, why; + char *display; + + major = XkbMajorVersion; + minor = XkbMinorVersion; + + display = getenv("DISPLAY"); + + return XkbOpenDisplay(display, NULL, NULL, &major, &minor, &why); +} + +static int +_lang_server_values_get(Language_Xkb_Config *lxc) +{ + XkbRF_VarDefsRec vd; + char *tmp = NULL; + + if (!lxc) return 0; + + if (!XkbRF_GetNamesProp(lxc->dpy, &tmp, &vd) || !tmp) + { + tmp = DFLT_XKB_RULES_FILE; + vd.model = DFLT_XKB_MODEL; + vd.layout = DFLT_XKB_LAYOUT; + vd.variant = NULL; + vd.options = NULL; + } + + if (tmp) LXC_SET_STRING(lxc, RULES_INDX, tmp); + if (vd.model) LXC_SET_STRING(lxc, MODEL_INDX, vd.model); + if (vd.layout) LXC_SET_STRING(lxc, LAYOUT_INDX, vd.layout); + if (vd.variant) LXC_SET_STRING(lxc, VARIANT_INDX, vd.variant); + + if (vd.options) XFree(vd.options); + + return 1; +} + +static int +_lang_apply_rules(Language_Xkb_Config *lxc) +{ + //FIXME: rfName is a hack it points to /usr/share/X11/xkb/rules/xorg + //I'm not sure that this file exist in all the versions of X + //Mostprobably this path should be /usr/X11R6/lib/X11/xkb/rules/xfree86 + char *rfName = DFLT_XKB_RULES_FILE; + XkbComponentNamesRec rnames; + XkbRF_RulesPtr rules = NULL; + + if (!lxc) return 0; + + lxc->rdefs.model = lxc->sv[MODEL_INDX]; + lxc->rdefs.layout = lxc->sv[LAYOUT_INDX]; + lxc->rdefs.variant = lxc->sv[VARIANT_INDX]; + + rules = XkbRF_Load(rfName, lxc->sv[LOCALE_INDX], True, True); + + if (!rules) + return 0; + + XkbRF_GetComponents(rules, &(lxc->rdefs), &rnames); + + if (rnames.keycodes) + { + LXC_SET_STRING(lxc, KEYCODES_INDX, rnames.keycodes); + rnames.keycodes = NULL; + //E_FREE(rnames.keycodes); + } + if (rnames.symbols) + { + LXC_SET_STRING(lxc, SYMBOLS_INDX, rnames.symbols); + rnames.symbols = NULL; + //E_FREE(rnames.symbols); + } + if(rnames.types) + { + LXC_SET_STRING(lxc, TYPES_INDX, rnames.types); + rnames.types = NULL; + //E_FREE(rnames.types); + } + if (rnames.compat) + { + LXC_SET_STRING(lxc, COMPAT_INDX, rnames.compat); + rnames.compat = NULL; + //E_FREE(rnames.compat); + } + if (rnames.geometry) + { + LXC_SET_STRING(lxc, GEOMETRY_INDX, rnames.geometry); + rnames.geometry = NULL; + //E_FREE(rnames.geometry); + } + if (rnames.keymap) + { + LXC_SET_STRING(lxc, KEYMAP_INDX, rnames.keymap); + rnames.keymap = NULL; + //E_FREE(rnames.keymap); + } + return 1; +} +static int +_lang_apply_components_names(Language_Xkb_Config *lxc) +{ + XkbDescPtr xkb = NULL; + XkbComponentNamesRec cmdNames; + + if (!lxc) return 0; + +#if 0 + if (!_lang_check_name(lxc->sv[TYPES_INDX], "types")) { printf("\n[1]\n");return 0;} + if (!_lang_check_name(lxc->sv[COMPAT_INDX], "compat")) { printf("\n[2]\n");return 0;} + if (!_lang_check_name(lxc->sv[SYMBOLS_INDX], "symbols")) { printf("\n[3]\n");return 0;} + if (!_lang_check_name(lxc->sv[KEYCODES_INDX], "keycodes")) { printf("\n[4]\n");return 0;} + if (!_lang_check_name(lxc->sv[GEOMETRY_INDX], "geometry")) { printf("\n[5]\n");return 0;} + if (!_lang_check_name(lxc->sv[KEYMAP_INDX], "keymap")) { printf("\n[6]\n");return 0;} +#endif + + memset(&cmdNames, 0, sizeof(XkbComponentNamesRec)); + + cmdNames.types = lxc->sv[TYPES_INDX]; + cmdNames.compat = lxc->sv[COMPAT_INDX]; + cmdNames.symbols = lxc->sv[SYMBOLS_INDX]; + cmdNames.keycodes = lxc->sv[KEYCODES_INDX]; + cmdNames.geometry = lxc->sv[GEOMETRY_INDX]; + cmdNames.keymap = lxc->sv[KEYMAP_INDX]; + + xkb = XkbGetKeyboardByName(lxc->dpy, XkbUseCoreKbd, &cmdNames, + XkbGBN_AllComponentsMask, + XkbGBN_AllComponentsMask & (~XkbGBN_GeometryMask), 1); + + if (!xkb) + { + return 0; + } + + if (lxc->rdefs.model || lxc->rdefs.layout) + { + if (!XkbRF_SetNamesProp(lxc->dpy, DFLT_XKB_RULES_FILE, &(lxc->rdefs))) + { + return 0; + } + } + return 1; +} + +#if 0 +static int +_lang_check_name(char *name, char* string) +{ + char *i = name, *opar = NULL; + int ret = 1; + + if(!name) + return 1; + + while (*i){ + if (opar == NULL) { + if (*i == '(') + opar = i; + } else { + if ((*i == '(') || (*i == '|') || (*i == '+')) { + ret = 0; + break; + } + if (*i == ')') + opar = NULL; + } + i++; + } + if (opar) + ret = 0; + if (!ret) { + char c; + int n = 1; + for(i = opar+1; *i && n; i++) { + if (*i == '(') n++; + if (*i == ')') n--; + } + if (*i) i++; + c = *i; + *i = '\0'; + printf("Illegal map name '%s' ", opar); + *i = c; + printf("in %s name '%s'\n", string, name); + } + return ret; +} +#endif ------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs