1 /******************************************************************
2
3 Copyright (C) 1994-1995 Sun Microsystems, Inc.
4 Copyright (C) 1993-1994 Hewlett-Packard Company
5 Copyright (C) 2014 Peng Huang <shawn.p.huang@gmail.com>
6 Copyright (C) 2014 Red Hat, Inc.
7
8 Permission to use, copy, modify, distribute, and sell this software
9 and its documentation for any purpose is hereby granted without fee,
10 provided that the above copyright notice appear in all copies and
11 that both that copyright notice and this permission notice appear
12 in supporting documentation, and that the name of Sun Microsystems, Inc.
13 and Hewlett-Packard not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior permission.
15 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
16 the suitability of this software for any purpose. It is provided "as is"
17 without express or implied warranty.
18
19 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
20 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
23 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
24 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
25 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
26 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27
28 Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
29
30 This version tidied and debugged by Steve Underwood May 1999
31
32 ******************************************************************/
33
34 #include <X11/Xlib.h>
35 #include "IMdkit.h"
36 #include "Xi18n.h"
37 #include "FrameMgr.h"
38 #include "XimFunc.h"
39
40 Xi18nClient *_Xi18nFindClient (Xi18n, CARD16);
41 void _Xi18nInitOffsetCache (Xi18nOffsetCache *);
42
43 int
_Xi18nNeedSwap(Xi18n i18n_core,CARD16 connect_id)44 _Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id)
45 {
46 CARD8 im_byteOrder = i18n_core->address.im_byteOrder;
47 Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id);
48
49 return (client->byte_order != im_byteOrder);
50 }
51
_Xi18nNewClient(Xi18n i18n_core)52 Xi18nClient *_Xi18nNewClient(Xi18n i18n_core)
53 {
54 static CARD16 connect_id = 0;
55 int new_connect_id;
56 Xi18nClient *client;
57
58 if (i18n_core->address.free_clients)
59 {
60 client = i18n_core->address.free_clients;
61 i18n_core->address.free_clients = client->next;
62 new_connect_id = client->connect_id;
63 }
64 else
65 {
66 client = (Xi18nClient *) malloc (sizeof (Xi18nClient));
67 new_connect_id = ++connect_id;
68 }
69 /*endif*/
70 memset (client, 0, sizeof (Xi18nClient));
71 client->connect_id = new_connect_id;
72 client->pending = (XIMPending *) NULL;
73 client->sync = False;
74 client->byte_order = '?'; /* initial value */
75 memset (&client->pending, 0, sizeof (XIMPending *));
76 _Xi18nInitOffsetCache (&client->offset_cache);
77 client->next = i18n_core->address.clients;
78 i18n_core->address.clients = client;
79
80 return (Xi18nClient *) client;
81 }
82
_Xi18nFindClient(Xi18n i18n_core,CARD16 connect_id)83 Xi18nClient *_Xi18nFindClient (Xi18n i18n_core, CARD16 connect_id)
84 {
85 Xi18nClient *client = i18n_core->address.clients;
86
87 while (client)
88 {
89 if (client->connect_id == connect_id)
90 return client;
91 /*endif*/
92 client = client->next;
93 }
94 /*endwhile*/
95 return NULL;
96 }
97
_Xi18nDeleteClient(Xi18n i18n_core,CARD16 connect_id)98 void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id)
99 {
100 Xi18nClient *target = _Xi18nFindClient (i18n_core, connect_id);
101 Xi18nClient *ccp;
102 Xi18nClient *ccp0;
103
104 for (ccp = i18n_core->address.clients, ccp0 = NULL;
105 ccp != NULL;
106 ccp0 = ccp, ccp = ccp->next)
107 {
108 if (ccp == target)
109 {
110 if (ccp0 == NULL)
111 i18n_core->address.clients = ccp->next;
112 else
113 ccp0->next = ccp->next;
114 /*endif*/
115 /* put it back to free list */
116 target->next = i18n_core->address.free_clients;
117 i18n_core->address.free_clients = target;
118 return;
119 }
120 /*endif*/
121 }
122 /*endfor*/
123 }
124
_Xi18nSendMessage(XIMS ims,CARD16 connect_id,CARD8 major_opcode,CARD8 minor_opcode,unsigned char * data,long length)125 void _Xi18nSendMessage (XIMS ims,
126 CARD16 connect_id,
127 CARD8 major_opcode,
128 CARD8 minor_opcode,
129 unsigned char *data,
130 long length)
131 {
132 Xi18n i18n_core = ims->protocol;
133 FrameMgr fm;
134 extern XimFrameRec packet_header_fr[];
135 unsigned char *reply_hdr = NULL;
136 int header_size;
137 unsigned char *reply = NULL;
138 unsigned char *replyp;
139 int reply_length;
140 long p_len = length/4;
141
142 fm = FrameMgrInit (packet_header_fr,
143 NULL,
144 _Xi18nNeedSwap (i18n_core, connect_id));
145
146 header_size = FrameMgrGetTotalSize (fm);
147 reply_hdr = (unsigned char *) malloc (header_size);
148 if (reply_hdr == NULL)
149 {
150 _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
151 FrameMgrFree (fm);
152 return;
153 }
154 /*endif*/
155 FrameMgrSetBuffer (fm, reply_hdr);
156
157 /* put data */
158 FrameMgrPutToken (fm, major_opcode);
159 FrameMgrPutToken (fm, minor_opcode);
160 FrameMgrPutToken (fm, p_len);
161
162 reply_length = header_size + length;
163 reply = (unsigned char *) malloc (reply_length);
164 replyp = reply;
165 memmove (reply, reply_hdr, header_size);
166 replyp += header_size;
167 if (length > 0 && data != NULL)
168 memmove (replyp, data, length);
169
170 i18n_core->methods.send (ims, connect_id, reply, reply_length);
171
172 XFree (reply);
173 XFree (reply_hdr);
174 FrameMgrFree (fm);
175 }
176
_Xi18nSendTriggerKey(XIMS ims,CARD16 connect_id)177 void _Xi18nSendTriggerKey (XIMS ims, CARD16 connect_id)
178 {
179 Xi18n i18n_core = ims->protocol;
180 FrameMgr fm;
181 extern XimFrameRec register_triggerkeys_fr[];
182 XIMTriggerKey *on_keys = i18n_core->address.on_keys.keylist;
183 XIMTriggerKey *off_keys = i18n_core->address.off_keys.keylist;
184 int on_key_num = i18n_core->address.on_keys.count_keys;
185 int off_key_num = i18n_core->address.off_keys.count_keys;
186 unsigned char *reply = NULL;
187 register int i, total_size;
188 CARD16 im_id;
189
190 if (on_key_num == 0 && off_key_num == 0)
191 return;
192 /*endif*/
193
194 fm = FrameMgrInit (register_triggerkeys_fr,
195 NULL,
196 _Xi18nNeedSwap (i18n_core, connect_id));
197
198 /* set iteration count for on-keys list */
199 FrameMgrSetIterCount (fm, on_key_num);
200 /* set iteration count for off-keys list */
201 FrameMgrSetIterCount (fm, off_key_num);
202
203 /* get total_size */
204 total_size = FrameMgrGetTotalSize (fm);
205
206 reply = (unsigned char *) malloc (total_size);
207 if (!reply) {
208 FrameMgrFree (fm);
209 return;
210 }
211 /*endif*/
212 memset (reply, 0, total_size);
213 FrameMgrSetBuffer (fm, reply);
214
215 /* Right now XIM_OPEN_REPLY hasn't been sent to this new client, so
216 the input-method-id is still invalid, and should be set to zero...
217 Reter to $(XC)/lib/X11/imDefLkup.c:_XimRegisterTriggerKeysCallback
218 */
219 im_id = 0;
220 FrameMgrPutToken (fm, im_id); /* input-method-id */
221 for (i = 0; i < on_key_num; i++)
222 {
223 FrameMgrPutToken (fm, on_keys[i].keysym);
224 FrameMgrPutToken (fm, on_keys[i].modifier);
225 FrameMgrPutToken (fm, on_keys[i].modifier_mask);
226 }
227 /*endfor*/
228 for (i = 0; i < off_key_num; i++)
229 {
230 FrameMgrPutToken (fm, off_keys[i].keysym);
231 FrameMgrPutToken (fm, off_keys[i].modifier);
232 FrameMgrPutToken (fm, off_keys[i].modifier_mask);
233 }
234 /*endfor*/
235 _Xi18nSendMessage (ims,
236 connect_id,
237 XIM_REGISTER_TRIGGERKEYS,
238 0,
239 reply,
240 total_size);
241 FrameMgrFree (fm);
242 XFree(reply);
243 }
244
_Xi18nSetEventMask(XIMS ims,CARD16 connect_id,CARD16 im_id,CARD16 ic_id,CARD32 forward_mask,CARD32 sync_mask)245 void _Xi18nSetEventMask (XIMS ims,
246 CARD16 connect_id,
247 CARD16 im_id,
248 CARD16 ic_id,
249 CARD32 forward_mask,
250 CARD32 sync_mask)
251 {
252 Xi18n i18n_core = ims->protocol;
253 FrameMgr fm;
254 extern XimFrameRec set_event_mask_fr[];
255 unsigned char *reply = NULL;
256 register int total_size;
257
258 fm = FrameMgrInit (set_event_mask_fr,
259 NULL,
260 _Xi18nNeedSwap (i18n_core, connect_id));
261
262 total_size = FrameMgrGetTotalSize (fm);
263 reply = (unsigned char *) malloc (total_size);
264 if (!reply) {
265 FrameMgrFree (fm);
266 return;
267 }
268 /*endif*/
269 memset (reply, 0, total_size);
270 FrameMgrSetBuffer (fm, reply);
271
272 FrameMgrPutToken (fm, im_id); /* input-method-id */
273 FrameMgrPutToken (fm, ic_id); /* input-context-id */
274 FrameMgrPutToken (fm, forward_mask);
275 FrameMgrPutToken (fm, sync_mask);
276
277 _Xi18nSendMessage (ims,
278 connect_id,
279 XIM_SET_EVENT_MASK,
280 0,
281 reply,
282 total_size);
283
284 FrameMgrFree (fm);
285 XFree(reply);
286 }
287