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