📄 oxim_module.c#1.45
字号:
/* Copyright (C) 2006 by OXIM TEAM 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 of the License, 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ #include "oximint.h"#include "gencin.h"/*---------------------------------------------------------------------------- Dynamic module loading: For ELF systems (Solaris, GNU/Linux, FreeBSD, HP-UX.11) For HP-UX PA32, PA64 systems.----------------------------------------------------------------------------*/#ifdef HAVE_DLOPEN /* ELF */#include <dlfcn.h>#else#ifdef HAVE_SHL_LOAD /* HP-UX */#include <dl.h>#endif#endif#include <locale.h>struct _mod_stack_s { void *ld; mod_header_t *modp; int ref; struct _mod_stack_s *next;};struct _mod_stack_s *mod_stack = NULL;char *realCname(char *s, char *e);/*---------------------------------------------------------------------------- Load and Unload modules.----------------------------------------------------------------------------*/static intfind_module(char *path, int path_size, char *sub_path){ char fn[BUFFER_LEN]; if (oxim_check_datafile(path, sub_path, fn, BUFFER_LEN) == False) return False; strcpy(path, fn); return oxim_check_file_exist(path, FTYPE_FILE);}mod_header_t *load_module(char *modname, enum mtype mod_type, char *version, char *sub_path){ struct _mod_stack_s *ms=mod_stack; char ldfn[BUFFER_LEN]; mod_header_t *module; void *ld=NULL; int err=1; while (ms != NULL) { if (strcmp(modname, ms->modp->name) == 0) { ms->ref ++; return ms->modp; } ms = ms->next; } sprintf(ldfn, "%s.so", modname); if (find_module(ldfn, BUFFER_LEN, sub_path) == True &&#ifdef HAVE_DLOPEN (ld = dlopen(ldfn, RTLD_LAZY)) != NULL)#else#ifdef HAVE_SHL_LOAD (ld = (void *)shl_load(ldfn, BIND_DEFERRED, 0L)) != NULL)#endif#endif err = 0; if (err) {#ifdef HAVE_DLOPEN char *errstr = dlerror(); oxim_perr(OXIMMSG_IWARNING, N_("dlerror: %s\n"), errstr);#endif ld = NULL; }#ifdef HAVE_DLOPEN if (!err && !(module = (mod_header_t *)dlsym(ld, "module_ptr")))#else#ifdef HAVE_SHL_LOAD if (!err && shl_findsym((shl_t *)&ld, "module_ptr", TYPE_DATA, &module)!=0)#endif#endif { oxim_perr(OXIMMSG_IWARNING, N_("module symbol \"module_ptr\" not found.\n")); err = 1; } if (!err && module->module_type != mod_type) { oxim_perr(OXIMMSG_IWARNING, N_("invalid module type, type %d required.\n"), mod_type); err = 1; } if (!err && strcmp(module->version, version) != 0) { oxim_perr(OXIMMSG_IWARNING, N_("invalid module version: %s, version %s required.\n"), module->version, version); } if (err) { oxim_perr(OXIMMSG_WARNING, N_("cannot load module \"%s\", ignore.\n"), modname); if (ld)#ifdef HAVE_DLOPEN dlclose(ld);#else#ifdef HAVE_SHL_OPEN shl_unload((shl_t)ld);#endif#endif return NULL; } else { ms = oxim_malloc(sizeof(struct _mod_stack_s), 0); ms->ld = ld; ms->modp = module; ms->ref = 1; ms->next = mod_stack; mod_stack = ms; return module; }}voidunload_module(mod_header_t *modp){ struct _mod_stack_s *ms = mod_stack; while (ms != NULL) { if (modp == ms->modp) { ms->ref --; break; } ms = ms->next; } if (ms && ms->ref <= 0) {#ifdef HAVE_DLOPEN dlclose(ms->ld);#else#ifdef HAVE_SHL_LOAD shl_unload((shl_t)(ms->ld));#endif#endif mod_stack = ms->next; free(ms); }}/*---------------------------------------------------------------------------- Print the module comment.----------------------------------------------------------------------------*/voidmodule_comment(mod_header_t *modp, char *mod_name){ if (modp) { oxim_perr(OXIMMSG_NORMAL, N_("module \"%s\":"), mod_name); if (modp->comments) oxim_perr(OXIMMSG_EMPTY, "\n\n%s\n", N_(modp->comments)); else oxim_perr(OXIMMSG_EMPTY, N_("no comments available.\n")); }}/*--------------------------------------------------------------------------- Load Module & Module Init.---------------------------------------------------------------------------*/static intcheck_module(module_t *modp, char *objname){ char *str = NULL, **objn; int check_ok=0; if (modp == NULL) return False;/* * Check for necessary symbols. */ if (! modp->conf_size) str = "conf_size"; else if (! modp->init) str = "init"; else if (! modp->xim_init) str = "xim_init"; else if (! modp->xim_end) str = "xim_end"; else if (! modp->keystroke) str = "keystroke"; else if (! modp->show_keystroke) str = "show_keystroke"; if (str) { oxim_perr(OXIMMSG_IWARNING, N_("undefined symbol \"%s\" in module \"%s\", ignore.\n"), str, modp->module_header.name); return False; }/* * Check for the valid objname. */ objn = modp->valid_objname; if (!objn) { if (strcmp_wild(modp->module_header.name, objname) == 0) check_ok = 1; } else { while (*objn) { if(strcmp_wild(*objn, objname) == 0) { check_ok = 1; break; } objn ++; } } if (check_ok == 0) { oxim_perr(OXIMMSG_WARNING, N_("invalid objname \"%s\" for module \"%s\", ignore.\n"), objname, modp->module_header.name); return False; } return True;}static imodule_t *creat_module(module_t *templet, char *objname){ imodule_t *imodp; imodp = oxim_malloc(sizeof(imodule_t), 1); imodp->modp = (void *)templet; imodp->name = templet->module_header.name; imodp->version = templet->module_header.version; imodp->comments = templet->module_header.comments; imodp->module_type = templet->module_header.module_type; imodp->conf = oxim_malloc(templet->conf_size, 1); imodp->init = templet->init; imodp->xim_init = templet->xim_init; imodp->xim_end = templet->xim_end; imodp->keystroke = templet->keystroke; imodp->show_keystroke = templet->show_keystroke; imodp->terminate = templet->terminate; imodp->objname = (objname) ? (char *)strdup(objname) : imodp->name; return imodp;}static imodule_t *IM_load(char *modname, char *objname){ module_t *modp; imodule_t *imodp; int load_ok=1; modp = (module_t *)load_module(modname, MTYPE_IM,MODULE_VERSION, "modules"); if (check_module(modp, objname) == False) load_ok = 0; else { imodp = creat_module(modp, objname); if (imodp->init(imodp->conf, objname) != True) { free(imodp->conf); free(imodp); load_ok = 0; } } if (load_ok == 0) { oxim_perr(OXIMMSG_WARNING, N_("cannot load IM: %s, ignore.\n"), objname); unload_module((mod_header_t *)modp); return NULL; } return imodp;}/*---------------------------------------------------------------------------- Cinput structer manager.----------------------------------------------------------------------------*/static void OXIM_IMFree(int idx){ im_rc *imlist = &(_Config->sys_imlist); if (idx < 0 || idx >= imlist->NumberOfIM) return; im_t *imp = imlist->IMList[idx]; if (imp->inpname) { free(imp->inpname); imp->inpname = NULL; } if (imp->aliasname) { free(imp->aliasname); imp->aliasname = NULL; } if (imp->modname) { free(imp->modname); imp->modname = NULL; } if (imp->objname) { free(imp->objname); imp->objname = NULL; } if (imp->settings) { oxim_settings_destroy(imp->settings); imp->settings = NULL; } if (imp->imodp) { if (imp->imodp->terminate) imp->imodp->terminate(imp->imodp->conf); if (imp->imodp->modp) unload_module((mod_header_t *)imp->imodp->modp); if (imp->imodp->conf) free(imp->imodp->conf); free(imp->imodp); imp->imodp = NULL; } imp->key = -1;}imodule_t *OXIM_IMGet(int idx){ im_rc imlist = _Config->sys_imlist; if (idx < 0 || idx >= imlist.NumberOfIM) return NULL; im_t *imp = imlist.IMList[idx]; if (imp->modname && imp->objname && imp->imodp == NULL) imp->imodp = IM_load(imp->modname, imp->objname); if (imp->imodp == NULL) OXIM_IMFree(idx); return imp->imodp;}imodule_t *OXIM_IMGetNext(int idx, int *idx_ret){ im_rc imlist = _Config->sys_imlist; if (idx < 0 || idx >= imlist.NumberOfIM) return NULL; int i, j; im_t *imp; *idx_ret = -1; for (j = 0, i = idx ; j < imlist.NumberOfIM ; j++, i++) { if (i >= imlist.NumberOfIM) { i = 0; } imp = imlist.IMList[i]; if (imp->modname && imp->objname) { if (imp->imodp == NULL) { imp->imodp = IM_load(imp->modname, imp->objname); if (imp->imodp != NULL ) { *idx_ret = i; break; } } } } if (imp->imodp == NULL) OXIM_IMFree(*idx_ret); return imp->imodp;}imodule_t *OXIM_IMGetPrev(int idx, int *idx_ret){ im_rc imlist = _Config->sys_imlist; if (idx < 0 || idx >= imlist.NumberOfIM) return NULL; int i, j; im_t *imp; *idx_ret = -1; for (j = 0, i = idx ; j < imlist.NumberOfIM ; j++, i--) { if (i < 0) { i = imlist.NumberOfIM - 1; } imp = imlist.IMList[i]; if (imp->modname && imp->objname) { *idx_ret = i; break; } } if (*idx_ret != -1 && imp->modname && imp->objname && imp->imodp == NULL) imp->imodp = IM_load(imp->modname, imp->objname); if (imp->imodp == NULL) OXIM_IMFree(*idx_ret); return imp->imodp;}imodule_t *OXIM_IMSearch(char *objname, int *idx_ret){ int i; im_rc imlist = _Config->sys_imlist; im_t *imp; *idx_ret = -1; for (i = 0 ; i < imlist.NumberOfIM; i++) { imp = imlist.IMList[i]; if (imp->objname && strcmp(imp->objname, objname) == 0) { *idx_ret = i; break; } } if (*idx_ret != -1 && imp->modname && imp->objname && imp->imodp == NULL) imp->imodp = IM_load(imp->modname, imp->objname); if (imp->imodp == NULL) OXIM_IMFree(*idx_ret); return imp->imodp;}voidOXIM_IMFreeAll(void){ im_rc *imlist = &(_Config->sys_imlist); if (!imlist->IMList) return; int i; for (i = 0; i < imlist->NumberOfIM ; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -