1 /******************************************************************
2
3 Copyright 1992, 1993, 1994 by FUJITSU LIMITED
4
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and
8 that both that copyright notice and this permission notice appear
9 in supporting documentation, and that the name of FUJITSU LIMITED
10 not be used in advertising or publicity pertaining to distribution
11 of the software without specific, written prior permission.
12 FUJITSU LIMITED makes no representations about the suitability of
13 this software for any purpose.
14 It is provided "as is" without express or implied warranty.
15
16 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 PERFORMANCE 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
40 static Xim *_XimCurrentIMlist = (Xim *)NULL;
41 static int _XimCurrentIMcount = 0;
42
43 static Bool
_XimSetIMStructureList(Xim im)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
75 void
_XimDestroyIMStructureList(Xim im)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
89 void
_XimServerDestroy(Xim im_2_destroy)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
123 void
_XimServerReconectableDestroy(void)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
150 static const char *
_XimStrstr(register const char * src,register const char * dest)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
166 static char *
_XimMakeImName(XLCd lcd)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
196 XIM
_XimOpenIM(XLCd lcd,Display * dpy,XrmDatabase rdb,char * res_name,char * res_class)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
237 Error4 :
238 _XimImSportRec[i].im_free(im);
239 Xfree(im);
240 return NULL;
241 Error3 :
242 Xfree(im->core.im_name);
243 Error2:
244 Xfree(im->core.res_class);
245 Error1:
246 Xfree(im->core.res_name);
247 Xfree(im);
248 return NULL;
249 }
250
251 Bool
_XInitIM(XLCd lcd)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