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