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