⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oxim_module.c#1.45

📁 linux 下的 oxim 输入法,简单易用.
💻 45
📖 第 1 页 / 共 2 页
字号:
/*    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 + -