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