1 /*
2 * $Id: keyin.c,v 1.2 2001/06/14 18:16:16 ura Exp $
3 */
4
5 /*
6 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7 * This file is part of FreeWnn.
8 *
9 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10 * Copyright 1991, 1992 by Massachusetts Institute of Technology
11 *
12 * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with GNU Emacs; see the file COPYING. If not, write to the
26 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Commentary:
29 *
30 * Change log:
31 *
32 * Last modified date: 8,Feb.1999
33 *
34 * Code:
35 *
36 */
37 /* Version 4.0
38 */
39 #include <stdio.h>
40 #include "sdefine.h"
41 #include "xim.h"
42 #include "sheader.h"
43 #include "proto.h"
44 #include "ext.h"
45
46 static int
read_xevent(ev)47 read_xevent (ev)
48 XEvent *ev;
49 {
50 ximEventReq req;
51
52 if (EACH_REQUEST (&req, sz_ximEventReq) == -1)
53 return (-1);
54 if (_ReadFromClient (ev, sizeof (XEvent)) == -1)
55 return (-1);
56 if (need_byteswap () == True)
57 {
58 byteswap_xevent (ev);
59 }
60 xim->sel_button = '\0';
61 return (0);
62 }
63
64 static int
check_cur_input(w)65 check_cur_input (w)
66 Window w;
67 {
68 if (cur_input == NULL)
69 {
70 #ifdef XJPLIB
71 if (XJp_check_cur_input (w) == 0)
72 return (0);
73 #endif /* XJPLIB */
74 }
75 else
76 {
77 if (w == cur_input->w)
78 return (0);
79 }
80 if (cur_p && w == cur_p->yes_no->w)
81 return (0);
82 return (1);
83 }
84
85 static int
cur_cl_set(set_window)86 cur_cl_set (set_window)
87 Window set_window;
88 {
89 register XIMClientRec *xc = NULL;
90 register XIMInputRec *xi;
91
92 for (xi = input_list; xi != NULL; xi = xi->next)
93 {
94 if (xi->w == set_window)
95 {
96 xc = xi->pclient;
97 break;
98 }
99 }
100 #ifdef XJPLIB
101 if (xc)
102 {
103 XJp_cur_cl_set (0);
104 }
105 else
106 {
107 xc = XJp_cur_cl_set (set_window);
108 }
109 #endif /* XJPLIB */
110 if (xc)
111 {
112 cur_x = xc;
113 if (IsPreeditNothing (cur_x))
114 {
115 cur_p = cur_x->root_pointer->ximclient;
116 cur_lang = cur_p->cur_xl->lang_db;
117 c_c = cur_p->cur_xl->w_c;
118 }
119 else
120 {
121 cur_p = cur_x;
122 cur_lang = cur_p->cur_xl->lang_db;
123 c_c = cur_x->cur_xl->w_c;
124 }
125 cur_rk = c_c->rk;
126 cur_rk_table = cur_rk->rk_table;
127 cur_input = xi;
128 set_cswidth (cur_lang->cswidth_id);
129 return (0);
130 }
131 for (xc = ximclient_list; xc; xc = xc->next)
132 {
133 if (!IsPreeditNothing (xc) && set_window == xc->yes_no->w)
134 {
135 cur_p = xc;
136 cur_lang = cur_p->cur_xl->lang_db;
137 c_c = cur_p->cur_xl->w_c;
138 cur_rk = c_c->rk;
139 cur_rk_table = cur_rk->rk_table;
140 set_cswidth (cur_lang->cswidth_id);
141 return (0);
142 }
143 }
144 if (xim->j_c && (set_window == xim->cur_j_c_root->ichi->w || set_window == xim->cur_j_c_root->inspect->w))
145 {
146 cur_p = xim->j_c;
147 cur_lang = cur_p->cur_xl->lang_db;
148 c_c = cur_p->cur_xl->w_c;
149 cur_rk = c_c->rk;
150 cur_rk_table = cur_rk->rk_table;
151 set_cswidth (cur_lang->cswidth_id);
152 return (0);
153 }
154 return (-1);
155 }
156
157 static XComposeStatus compose_status = { NULL, 0 };
158
159 int
key_input(buff,ev)160 key_input (buff, ev)
161 register int *buff;
162 register XEvent *ev;
163 {
164 unsigned char strbuf[512];
165 KeySym keysym;
166 int nbytes;
167 int ck;
168 register int i;
169
170 if (check_cur_input (ev->xkey.window))
171 {
172 if (cur_cl_set (ev->xkey.window) != 0)
173 {
174 return (-1);
175 }
176 }
177 if (dpy != ev->xkey.display)
178 ev->xkey.display = dpy;
179 #ifdef CALLBACKS
180 if (IsPreeditCallbacks (cur_x) && cur_x->cb_redraw_needed)
181 {
182 *buff++ = 0;
183 return (1);
184 }
185 #endif /* CALLBACKS */
186 #ifdef USING_XJUTIL
187 if (cur_p->cur_xl->working_xjutil)
188 {
189 xjutil_send_key_event (ev);
190 return (-1);
191 }
192 #endif /* USING_XJUTIL */
193 nbytes = XLookupString ((XKeyEvent *) ev, strbuf, 512, &keysym, &compose_status);
194 #if defined(XJPLIB) && defined(XJPLIB_DIRECT)
195 XJp_save_sockbuf (nbytes, strbuf, keysym);
196 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */
197 if ((ck = cvt_key_fun (keysym, ev->xkey.state)) >= 0)
198 {
199 #ifdef XJPLIB
200 XJp_check_save_event (ev, 0);
201 #endif /* XJPLIB */
202 *buff++ = ck;
203 return (1);
204 }
205 if ((keysym & 0xff00) == 0xff00)
206 { /* Function Key */
207 if (nbytes > 0)
208 {
209 #ifdef XJPLIB
210 XJp_check_save_event (ev, 1);
211 #endif /* XJPLIB */
212 for (i = 0; i < nbytes; i++)
213 {
214 *buff++ = (int) strbuf[i];
215 }
216 return (nbytes);
217 }
218 else
219 {
220 #ifdef XJPLIB
221 XJp_check_send_cl_key (ev);
222 #endif /* XJPLIB */
223 return (0);
224 }
225 }
226 if (ev->xkey.state & ControlMask)
227 { /* Control Key */
228 if (*strbuf >= 0x20)
229 {
230 #ifdef XJPLIB
231 XJp_check_send_cl_key (ev);
232 #endif /* XJPLIB */
233 return (-1);
234 }
235 else if (*strbuf == 0x0)
236 {
237 #ifdef XJPLIB
238 XJp_check_save_event (ev, 0);
239 #endif /* XJPLIB */
240 *buff++ = (int) *strbuf;
241 return (1);
242 }
243 else if (*strbuf <= 0x1f)
244 {
245 #ifdef XJPLIB
246 XJp_check_save_event (ev, 0);
247 #endif /* XJPLIB */
248 *buff++ = (int) *strbuf;
249 return (1);
250 }
251 }
252 if ((keysym >= 0x4a0) && (keysym <= 0x4df))
253 { /* Kana Key */
254 #ifdef XJPLIB
255 XJp_check_save_event (ev, 0);
256 #endif /* XJPLIB */
257 *buff++ = (int) ((SS2 << 8) | (keysym & 0xff));
258 return (1);
259 }
260 else if ((keysym < 0x100) && (keysym > 0))
261 {
262 #ifdef XJPLIB
263 XJp_check_save_event (ev, 1);
264 #endif /* XJPLIB */
265 if (nbytes <= 0)
266 {
267 nbytes = -1;
268 }
269 for (i = 0; i < nbytes; i++)
270 {
271 *buff++ = (int) strbuf[i];
272 }
273 return (nbytes);
274 }
275 return (-1);
276 }
277
278 int
ifempty()279 ifempty ()
280 {
281 if (cur_p->cur_xl->max_pos == 0)
282 {
283 return (1);
284 }
285 else
286 {
287 return (0);
288 }
289 }
290
291 int
RequestDispatch()292 RequestDispatch ()
293 {
294 int buff[32], in;
295 XEvent event;
296 int ret = 0;
297 register int i, n_bytes;
298
299 switch (read_requestheader ())
300 {
301 case XIM_Event:
302 if (read_xevent (&event) == -1)
303 {
304 break;
305 }
306 ret = key_input (buff, &event);
307 if (ret == 0)
308 {
309 send_nofilter ();
310 }
311 else if (ret > 0)
312 {
313 for (i = 0; i < ret;)
314 {
315 n_bytes = get_cswidth_by_char (in = buff[i++]);
316 for (; n_bytes > 1 && i < ret; n_bytes--, i++)
317 {
318 in = (in << 8) + buff[i];
319 }
320 in_put (in);
321 }
322 }
323 send_end ();
324 break;
325 case XIM_GetIM:
326 GetIM ();
327 break;
328 case XIM_CreateIC:
329 CreateIC ();
330 break;
331 case XIM_ChangeIC:
332 ChangeIC ();
333 break;
334 case XIM_GetIC:
335 GetIC ();
336 break;
337 case XIM_DestroyIC:
338 DestroyIC ();
339 break;
340 case XIM_SetICFocus:
341 SetICFocus ();
342 break;
343 case XIM_UnsetICFocus:
344 UnsetICFocus ();
345 break;
346 case XIM_ResetIC:
347 ResetIC ();
348 break;
349 #ifdef SPOT
350 case XIM_ChangeSpot:
351 ChangeSpot ();
352 break;
353 #endif /* SPOT */
354 }
355 return (0);
356 }
357