1/****************************************************************** 2 3 Copyright 1992, 1993, 1994 by FUJITSU LIMITED 4 5Permission to use, copy, modify, distribute, and sell this software 6and its documentation for any purpose is hereby granted without fee, 7provided that the above copyright notice appear in all copies and 8that both that copyright notice and this permission notice appear 9in supporting documentation, and that the name of FUJITSU LIMITED 10not be used in advertising or publicity pertaining to distribution 11of the software without specific, written prior permission. 12FUJITSU LIMITED makes no representations about the suitability of 13this software for any purpose. 14It is provided "as is" without express or implied warranty. 15 16FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 20USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22PERFORMANCE OF THIS SOFTWARE. 23 24 Author: Takashi Fujiwara FUJITSU LIMITED 25 fujiwara@a80.tech.yk.fujitsu.co.jp 26 27******************************************************************/ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <X11/Xatom.h> 33#include <X11/Xlib.h> 34#include <X11/Xmd.h> 35#include "Xlibint.h" 36#include "Xlcint.h" 37#include "Ximint.h" 38#include "XimImSw.h" 39 40static Xim *_XimCurrentIMlist = (Xim *)NULL; 41static int _XimCurrentIMcount = 0; 42 43static Bool 44_XimSetIMStructureList( 45 Xim im) 46{ 47 register int i; 48 Xim *xim; 49 50 if(!(_XimCurrentIMlist)) { 51 if(!(_XimCurrentIMlist = Xmalloc(sizeof(Xim)))) 52 return False; 53 _XimCurrentIMlist[0] = im; 54 _XimCurrentIMcount = 1; 55 } 56 else { 57 for(i = 0; i < _XimCurrentIMcount; i++) { 58 if(!( _XimCurrentIMlist[i])) { 59 _XimCurrentIMlist[i] = im; 60 break; 61 } 62 } 63 if(i >= _XimCurrentIMcount) { 64 if(!(xim = Xrealloc(_XimCurrentIMlist, 65 ((i + 1) * sizeof(Xim))))) 66 return False; 67 _XimCurrentIMlist = xim; 68 _XimCurrentIMlist[_XimCurrentIMcount] = im; 69 _XimCurrentIMcount++; 70 } 71 } 72 return True; 73} 74 75void 76_XimDestroyIMStructureList(Xim im) 77{ 78 register int i; 79 80 for(i = 0; i < _XimCurrentIMcount; i++) { 81 if(_XimCurrentIMlist[i] == im) { 82 _XimCurrentIMlist[i] = NULL; 83 break; 84 } 85 } 86 return; 87} 88 89void 90_XimServerDestroy(Xim im_2_destroy) 91{ 92 register int i; 93 Xim im; 94 XIC ic; 95 96 for(i = 0; i < _XimCurrentIMcount; i++) { 97 if(!(im = _XimCurrentIMlist[i])) 98 continue; 99 /* 100 * Only continue if this im is the one to be destroyed. 101 */ 102 if (im != im_2_destroy) 103 continue; 104 105 if (im->core.destroy_callback.callback) 106 (*im->core.destroy_callback.callback)((XIM)im, 107 im->core.destroy_callback.client_data, NULL); 108 for (ic = im->core.ic_chain; ic; ic = ic->core.next) { 109 if (ic->core.destroy_callback.callback) { 110 (*ic->core.destroy_callback.callback)(ic, 111 ic->core.destroy_callback.client_data, NULL); 112 } 113 } 114 _XimResetIMInstantiateCallback( im ); 115 (void)im->methods->close((XIM)im); 116 Xfree(im); 117 _XimCurrentIMlist[i] = NULL; 118 return; 119 } 120} 121 122#ifdef XIM_CONNECTABLE 123void 124_XimServerReconectableDestroy(void) 125{ 126 register int i; 127 Xim im; 128 XIC ic; 129 130 for(i = 0; i < _XimCurrentIMcount; i++) { 131 if(!(im = _XimCurrentIMlist[i])) 132 continue; 133 134 if (im->core.destroy_callback.callback) 135 (*im->core.destroy_callback.callback)(im, 136 im->core.destroy_callback.client_data, NULL); 137 for (ic = im->core.ic_chain; ic; ic = ic->core.next) { 138 if (ic->core.destroy_callback.callback) { 139 (*ic->core.destroy_callback.callback)(ic, 140 ic->core.destroy_callback.client_data, NULL); 141 } 142 } 143 _XimResetIMInstantiateCallback( im ); 144 (void)im->methods->close((XIM)im); 145 } 146 return; 147} 148#endif /* XIM_CONNECTABLE */ 149 150static const char * 151_XimStrstr( 152 register const char *src, 153 register const char *dest) 154{ 155 int len; 156 157 len = strlen(dest); 158 while((src = strchr(src, *dest))) { 159 if(!strncmp(src, dest, len)) 160 return src; 161 src++; 162 } 163 return NULL; 164} 165 166static char * 167_XimMakeImName( 168 XLCd lcd) 169{ 170 const char* begin = NULL; 171 const char* end = NULL; 172 char* ret = NULL; 173 const char* ximmodifier = XIMMODIFIER; 174 175 if(lcd->core->modifiers != NULL && *lcd->core->modifiers != '\0') { 176 begin = _XimStrstr(lcd->core->modifiers, ximmodifier); 177 if (begin != NULL) { 178 end = begin += strlen(ximmodifier); 179 while (*end && *end != '@') 180 end++; 181 } 182 } 183 ret = Xmalloc(end - begin + 1); 184 if (ret != NULL) { 185 if (begin != NULL && end != NULL) { 186 (void)strncpy(ret, begin, end - begin); 187 ret[end - begin] = '\0'; 188 } else { 189 ret[0] = '\0'; 190 } 191 } 192 193 return ret; 194} 195 196XIM 197_XimOpenIM( 198 XLCd lcd, 199 Display *dpy, 200 XrmDatabase rdb, 201 char *res_name, 202 char *res_class) 203{ 204 Xim im; 205 register int i; 206 207 if (!(im = Xcalloc(1, sizeof(XimRec)))) 208 return (XIM)NULL; 209 210 im->core.lcd = lcd; 211 im->core.ic_chain = (XIC)NULL; 212 im->core.display = dpy; 213 im->core.rdb = rdb; 214 im->core.res_name = NULL; 215 im->core.res_class = NULL; 216 if((res_name != NULL) && (*res_name != '\0')){ 217 if(!(im->core.res_name = strdup(res_name))) 218 goto Error1; 219 } 220 if((res_class != NULL) && (*res_class != '\0')){ 221 if(!(im->core.res_class = strdup(res_class))) 222 goto Error2; 223 } 224 if(!(im->core.im_name = _XimMakeImName(lcd))) 225 goto Error3; 226 227 for(i= 0; ; i++) { 228 if(_XimImSportRec[i].checkprocessing(im)) { 229 if(!(_XimImSportRec[i].im_open(im))) 230 goto Error4; 231 if(!_XimSetIMStructureList(im)) 232 goto Error4; 233 return (XIM)im; 234 } 235 } 236 237Error4 : 238 _XimImSportRec[i].im_free(im); 239 Xfree(im); 240 return NULL; 241Error3 : 242 Xfree(im->core.im_name); 243Error2: 244 Xfree(im->core.res_class); 245Error1: 246 Xfree(im->core.res_name); 247 Xfree(im); 248 return NULL; 249} 250 251Bool 252_XInitIM(XLCd lcd) 253{ 254 if(lcd == (XLCd)NULL) 255 return False; 256 lcd->methods->open_im = _XimOpenIM; 257 lcd->methods->register_callback = _XimRegisterIMInstantiateCallback; 258 lcd->methods->unregister_callback = _XimUnRegisterIMInstantiateCallback; 259 return True; 260} 261