1 /*
2  * $Id: keyin.c,v 1.2 2001/06/14 18:16:13 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 Kyoto University Research Institute for Mathematical Sciences
10  *                 1987, 1988, 1989, 1990, 1991, 1992
11  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
12  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
13  * Copyright 1991, 1992 by Massachusetts Institute of Technology
14  *
15  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2, or (at your option)
20  * any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with GNU Emacs; see the file COPYING.  If not, write to the
29  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30  *
31  * Commentary:
32  *
33  * Change log:
34  *
35  * Last modified date: 8,Feb.1999
36  *
37  * Code:
38  *
39  */
40 /*      Version 4.0
41  */
42 #include <stdio.h>
43 #include "commonhd.h"
44 #include "sdefine.h"
45 #include "xjutil.h"
46 #include "sxheader.h"
47 #include "config.h"
48 #include "xext.h"
49 
50 static XGCValues xgcv;
51 XPoint button;
52 Atom actual_type;
53 int actual_format;
54 unsigned long nitems;
55 unsigned long leftover;
56 
57 extern Atom wm_id;
58 extern Atom wm_id1;
59 
60 extern char xjutil_env_name[];
61 
62 static void
change_fore()63 change_fore ()
64 {
65   xgcv.foreground = cur_root->fg;
66   XChangeGC (dpy, cur_root->gc, GCForeground, &xgcv);
67   xgcv.background = cur_root->fg;
68   XChangeGC (dpy, cur_root->reversegc, GCBackground, &xgcv);
69   xgcv.foreground = cur_root->fg;
70   xgcv.plane_mask = XOR (cur_root->fg, cur_root->bg);
71   XChangeGC (dpy, cur_root->invertgc, (GCForeground | GCPlaneMask), &xgcv);
72 }
73 
74 static void
change_back()75 change_back ()
76 {
77   xgcv.background = cur_root->bg;
78   XChangeGC (dpy, cur_root->gc, GCBackground, &xgcv);
79   xgcv.foreground = cur_root->bg;
80   XChangeGC (dpy, cur_root->reversegc, GCForeground, &xgcv);
81   xgcv.background = cur_root->bg;
82   xgcv.plane_mask = XOR (cur_root->fg, cur_root->bg);
83   XChangeGC (dpy, cur_root->invertgc, (GCBackground | GCPlaneMask), &xgcv);
84 }
85 
86 static int
set_xjutil_bun(xjutil_env,p)87 set_xjutil_bun (xjutil_env, p)
88      Xjutil_envRec *xjutil_env;
89      register char *p;
90 {
91   XFontSet fs;
92   XjutilFSRec *fsl;
93   int i;
94   WnnEnv *we;
95 #ifdef X11R5
96   XLocale xlc;
97 #else
98   XLCd xlc;
99 #endif /* X11R5 */
100   extern XjutilFSRec *add_fontset_list (), *get_fontset_list ();
101   extern XFontSet create_font_set ();
102 
103   if (!cur_root || cur_root->screen != xjutil_env->screen)
104     {
105       for (i = 0; i < xjutil->screen_count; i++)
106         {
107           if (xjutil->root_pointer[i]->screen == xjutil_env->screen)
108             {
109               cur_root = xjutil->root_pointer[i];
110               break;
111             }
112         }
113     }
114   if (!cur_root)
115     return (-1);
116   if (strcmp (xjutil->lc_name, xjutil_env->lc_name))
117     {
118       xjutil->lc_name = alloc_and_copy (xjutil_env->lc_name);
119       xjutil->cswidth_id = xjutil_env->cswidth_id;
120       setlocale (LC_ALL, xjutil->lc_name);
121 #ifdef X11R5
122       Free ((char *) xjutil->xlc);
123       xlc = _XFallBackConvert ();
124       xjutil->xlc = _XlcDupLocale (xlc);
125 #else
126       xlc = _XlcCurrentLC ();
127       xjutil->xlc = xlc;
128 #endif /* X11R5 */
129       set_cswidth (xjutil->cswidth_id);
130     }
131   if ((fsl = get_fontset_list (xjutil_env->fs_id)) == NULL)
132     {
133       if ((xjutil_env->fn_len <= 0) || (p == NULL) || (*p == '\0'))
134         {
135           print_out ("XCreateFontSet failed");
136           return (-1);
137         }
138       if ((fs = create_font_set (p)) == NULL)
139         {
140           return (-1);
141         }
142       cur_fs = add_fontset_list (fs, xjutil_env->fs_id);
143     }
144   else
145     {
146       cur_fs = fsl;
147     }
148   if (cur_root->fg != xjutil_env->fore_ground)
149     {
150       cur_root->fg = xjutil_env->fore_ground;
151       change_fore ();
152     }
153   if (cur_root->bg != xjutil_env->back_ground)
154     {
155       cur_root->bg = xjutil_env->back_ground;
156       change_back ();
157     }
158   for (i = 0, we = normal_env; we; i++, we = we->next)
159     {
160       if (we->env == NULL)
161         continue;
162       we->env->env_id = xjutil_env->env_id[i];
163       if (xjutil_env->env_id[i] == xjutil_env->cur_env_id)
164         cur_normal_env = we;
165     }
166   for (i = 0, we = reverse_env; we; i++, we = we->next)
167     {
168       if (we->env == NULL)
169         continue;
170       we->env->env_id = xjutil_env->env_reverse_id[i];
171       if (xjutil_env->env_id[i] == xjutil_env->cur_env_id)
172         cur_reverse_env = we;
173     }
174   env_is_reverse = xjutil_env->env_is_reverse;
175   return (0);
176 }
177 
178 int
get_env()179 get_env ()
180 {
181   Atom atom_env;
182   unsigned char *data;
183   Xjutil_envRec xjutil_env;
184 
185   if ((atom_env = XInternAtom (dpy, xjutil_env_name, True)) == (Atom) NULL)
186     {
187       return (-1);
188     }
189   XGetWindowProperty (dpy, xjutil->root_pointer[xjutil->default_screen]->root_window, atom_env, 0L, 1000000L, False, XA_STRING, &actual_type, &actual_format, &nitems, &leftover, &data);
190   bcopy (data, &xjutil_env, sizeof (Xjutil_envRec));
191   if (set_xjutil_bun (&xjutil_env, (data + sizeof (Xjutil_envRec))) == -1)
192     {
193       XFree ((char *) data);
194       return (-1);
195     }
196   XFree ((char *) data);
197   return (0);
198 }
199 
200 int
get_touroku_data(buffer)201 get_touroku_data (buffer)
202      w_char *buffer;
203 {
204   Atom atom_env;
205   unsigned char *data, *data_sv;
206   int ret;
207   Xjutil_envRec xjutil_env;
208 
209   if ((atom_env = XInternAtom (dpy, xjutil_env_name, True)) == (Atom) NULL)
210     {
211       return (-1);
212     }
213   XGetWindowProperty (dpy, xjutil->root_pointer[xjutil->default_screen]->root_window, atom_env, 0L, 1000000L, False, XA_STRING, &actual_type, &actual_format, &nitems, &leftover, &data);
214   data_sv = data;
215   bcopy (data, &xjutil_env, sizeof (Xjutil_envRec));
216   if (set_xjutil_bun (&xjutil_env, (data += sizeof (Xjutil_envRec))) == -1)
217     {
218       XFree (data_sv);
219       return (-1);
220     }
221   data += xjutil_env.fn_len;
222   bcopy (data, &ret, sizeof (int));
223   data += sizeof (int);
224   bcopy (data, buffer, (nitems - (data - data_sv)));
225   buffer[(nitems - (data - data_sv)) / 2] = 0;
226   XFree (data_sv);
227   return (ret);
228 }
229 
230 static void
keyboard_mapping(ev)231 keyboard_mapping (ev)
232      XMappingEvent *ev;
233 {
234   XRefreshKeyboardMapping (ev);
235 }
236 
237 static int
wm_event(ev)238 wm_event (ev)
239      XClientMessageEvent *ev;
240 {
241   if (ev->window == cur_root->ichi->w || ev->window == cur_root->jutil->w)
242     {
243       xjutil->sel_ret = -2;
244       return (0);
245     }
246   return (1);
247 }
248 
249 static void
check_map(w)250 check_map (w)
251      Window w;
252 {
253   if (w == cur_root->ichi->w)
254     {
255       cur_root->ichi->map = 1;
256       return;
257     }
258   else if (w == cur_root->ichi->keytable->w)
259     {
260       cur_root->ichi->keytable->map = 1;
261       return;
262     }
263   else if (w == cur_root->yes_no->w)
264     {
265       cur_root->yes_no->map = 1;
266       return;
267     }
268   return;
269 }
270 
271 static XComposeStatus compose_status = { NULL, 0 };
272 static int work = 0;
273 
274 int
xw_read(buff)275 xw_read (buff)
276      register int *buff;
277 {
278   XEvent event;
279   unsigned char strbuf[32];
280   KeySym keycode;
281   int nbytes;
282   int ck;
283   int i;
284 
285   for (;;)
286     {
287       XNextEvent (dpy, &event);
288       if (event.type != ClientMessage && !cur_root)
289         continue;
290       switch (event.type)
291         {
292         case KeyPress:
293           xjutil->sel_button = 0;
294           nbytes = XLookupString ((XKeyEvent *) & event, strbuf, 32, &keycode, &compose_status);
295           if ((ck = cvt_key_fun (keycode, event.xkey.state)) >= 0)
296             {
297               *buff++ = ck;
298               return (1);
299             }
300           if ((keycode & 0xff00) == 0xff00)
301             {                   /* �ե���������� */
302               if (nbytes > 0)
303                 {
304                   for (i = 0; i < nbytes; i++)
305                     {
306                       *buff++ = (int) strbuf[i];
307                     }
308                   return (nbytes);
309                 }
310               else
311                 {
312                   break;
313                 }
314             }
315           if (event.xkey.state & ControlMask)
316             {                   /* ����ȥ��륭�� */
317               if (*strbuf >= 0x20)
318                 {
319                   break;
320                 }
321               else if (*strbuf == 0x0)
322                 {
323                   *buff++ = (int) *strbuf;
324                   return (1);
325                 }
326               else if (*strbuf <= 0x1f)
327                 {
328                   *buff++ = (int) *strbuf;
329                   return (1);
330                 }
331             }
332           if ((keycode >= 0x4a0) && (keycode <= 0x4df))
333             {                   /* ��̾���� */
334               *buff++ = (int) ((SS2 << 8) | (keycode & 0xff));
335               return (1);
336             }
337           else if ((keycode < 0x100) && (keycode > 0))
338             {
339               for (i = 0; i < nbytes; i++)
340                 {
341                   *buff++ = (int) strbuf[i];
342                 }
343               return (nbytes);
344             }
345           break;
346 
347         case ClientMessage:     /* ���ܸ�ġ��륭�åȤ�����׵� */
348 /* MOTIF */
349           if (wm_id && event.xclient.message_type == wm_id && event.xclient.data.l[0] == wm_id1)
350             {
351               if (wm_event (&event) == 0)
352                 {
353                   *buff = (int) 0xd;
354                   return (1);
355                 }
356               break;
357             }
358 /* MOTIF */
359           if (event.xclient.data.l[0] == DIC_KILL)
360             terminate_handler ();
361           if (work)
362             break;
363           xjutil->sel_button = 0;
364           switch (event.xclient.data.l[0])
365             {
366             case DIC_ADD:
367               work = 1;
368               jishoadd ();
369               send_end_work ();
370               work = 0;
371               break;
372             case DIC_KENSAKU:
373               work = 1;
374               kensaku ();
375               send_end_work ();
376               work = 0;
377               break;
378             case DIC_ICHIRAN:
379               work = 1;
380               select_one_dict9 ();
381               send_end_work ();
382               work = 0;
383               break;
384             case DIC_PARAM:
385               work = 1;
386               paramchg ();
387               send_end_work ();
388               work = 0;
389               break;
390             case DIC_INFO:
391               work = 1;
392               dicinfoout ();
393               send_end_work ();
394               work = 0;
395               break;
396             case DIC_FZK:
397               work = 1;
398               fuzoku_set ();
399               send_end_work ();
400               work = 0;
401               break;
402             case DIC_TOUROKU:
403               work = 1;
404               touroku ();
405               send_end_work ();
406               work = 0;
407               break;
408             default:
409               break;
410             }
411 
412         case Expose:
413           xw_expose (&event);
414           return (-1);
415           break;
416         case ButtonRelease:
417           button.x = event.xbutton.x_root;
418           button.y = event.xbutton.y_root;
419           xjutil->sel_button = 1;
420           if (xw_buttonpress (&event) == True)
421             {
422               *buff = (int) 0xd;
423               return (1);
424             }
425           break;
426         case DestroyNotify:
427           terminate_handler ();
428           break;
429         case MotionNotify:
430           xw_mousemove (&event);
431           break;
432         case EnterNotify:
433           xw_enterleave (&event, (char) 1);
434           break;
435         case LeaveNotify:
436           xw_enterleave (&event, (char) 0);
437           break;
438         case ReparentNotify:
439           read_wm_id ();
440           break;
441         case MapNotify:
442           check_map (event.xmap.window);
443           break;
444         case MappingNotify:
445           keyboard_mapping (&event);
446           break;
447         default:
448           break;
449 
450         }
451     }
452 }
453