Mercurial > freewnn
comparison Xwnmo/xwnmo/do_xjpdrct.c @ 0:bbc77ca4def5
initial import
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Thu, 13 Dec 2007 04:30:14 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bbc77ca4def5 |
---|---|
1 /* | |
2 * $Id: do_xjpdrct.c,v 1.2 2001/06/14 18:16:15 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 | |
38 #if defined(XJPLIB) && defined(XJPLIB_DIRECT) | |
39 | |
40 #include <stdio.h> | |
41 #include <X11/Xlib.h> | |
42 #ifdef X11R4 | |
43 #define NEED_EVENTS 1 | |
44 #include <X11/Xlibos.h> | |
45 #else /* X11R4 */ | |
46 #include "Xlibnet.h" | |
47 | |
48 #ifndef X11R5 | |
49 /* followings were included in Xlibnet.h, but none in X11R6 */ | |
50 #include <netinet/in.h> | |
51 #include <sys/ioctl.h> | |
52 #include <netdb.h> | |
53 /* end */ | |
54 #endif /* !X11R5 */ | |
55 | |
56 #endif /* X11R4 */ | |
57 #include <X11/Xos.h> | |
58 #if defined(TCPCONN) || defined(UNIXCONN) | |
59 #include <sys/socket.h> | |
60 #endif /* defined(TCPCONN) || defined(UNIXCONN) */ | |
61 #ifdef TCPCONN | |
62 #define XJP_PORT_IN 0x9494 | |
63 #endif /* TCPCONN */ | |
64 | |
65 #ifdef UNIXCONN | |
66 #include <sys/un.h> | |
67 #ifndef XJP_UNIX_PATH | |
68 #define XJP_UNIX_PATH "/tmp/xwnmo.V2" | |
69 #endif /* XJP_UNIX_PATH */ | |
70 #endif /* UNIXCONN */ | |
71 | |
72 #include "do_xjplib.h" | |
73 | |
74 #define XJP_UNIX_ACPT 3 | |
75 #define XJP_INET_ACPT 4 | |
76 | |
77 extern XIMCmblk accept_blk[]; | |
78 extern XIMCmblk *cblk; | |
79 extern XIMCmblk *cur_cblk; | |
80 | |
81 extern int *all_socks; | |
82 extern int *ready_socks; | |
83 | |
84 extern int max_client; | |
85 extern int cur_sock; | |
86 | |
87 #define BINTSIZE (sizeof(int)*8) | |
88 #define sock_set(array,pos) (array[pos/BINTSIZE] |= (1<<(pos%BINTSIZE))) | |
89 #define sock_clr(array,pos) (array[pos/BINTSIZE] &= ~(1<<(pos%BINTSIZE))) | |
90 #define sock_tst(array,pos) (array[pos/BINTSIZE] & (1<<(pos%BINTSIZE))) | |
91 | |
92 extern int read (), write (); | |
93 | |
94 extern XJpClientRec *xjp_clients; | |
95 extern XJpClientRec *xjp_cur_client; | |
96 extern XJpInputRec *xjp_inputs; | |
97 extern XJpInputRec *xjp_cur_input; | |
98 | |
99 static int need_write = 0; | |
100 | |
101 static int real_port = 0; | |
102 | |
103 int | |
104 XJp_get_xjp_port () | |
105 { | |
106 return (real_port); | |
107 } | |
108 | |
109 static void | |
110 xjp_init_net_area () | |
111 { | |
112 #ifdef UNIXCONN | |
113 accept_blk[XJP_UNIX_ACPT].sd = -1; | |
114 #endif /* UNIXCONN */ | |
115 #ifdef TCPCONN | |
116 accept_blk[XJP_INET_ACPT].sd = -1; | |
117 #endif /* TCPCONN */ | |
118 } | |
119 | |
120 #ifdef UNIXCONN | |
121 static int | |
122 xjp_init_net_un () | |
123 { | |
124 int so; | |
125 struct sockaddr_un saddr_un; | |
126 extern int unlink (), socket (), bind (), shutdown (), listen (); | |
127 | |
128 unlink (XJP_UNIX_PATH); | |
129 saddr_un.sun_family = AF_UNIX; | |
130 strcpy (saddr_un.sun_path, XJP_UNIX_PATH); | |
131 | |
132 if ((so = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | |
133 { | |
134 return (-1); | |
135 } | |
136 if (bind (so, (struct sockaddr *) &saddr_un, strlen (saddr_un.sun_path) + 2) < 0) | |
137 { | |
138 shutdown (so, 2); | |
139 return (-1); | |
140 } | |
141 if (listen (so, 5) < 0) | |
142 { | |
143 shutdown (so, 2); | |
144 return (-1); | |
145 } | |
146 accept_blk[XJP_UNIX_ACPT].sd = so; | |
147 sock_set (all_socks, so); | |
148 return (0); | |
149 } | |
150 #endif /* UNIXCONN */ | |
151 | |
152 #ifdef TCPCONN | |
153 static int | |
154 xjp_init_net_in () | |
155 { | |
156 int so; | |
157 struct servent *sp; | |
158 struct sockaddr_in saddr_in; | |
159 unsigned short port; | |
160 #ifndef SOLARIS | |
161 int on = 1; | |
162 #else /* SOLARIS */ | |
163 int on = 0; | |
164 #endif /* SOLARIS */ | |
165 int i, ok = 0; | |
166 extern int setsockopt (); | |
167 | |
168 if ((sp = getservbyname ("xwnmo", "tcp")) == NULL) | |
169 { | |
170 real_port = port = XJP_PORT_IN; | |
171 } | |
172 else | |
173 { | |
174 real_port = port = ntohs (sp->s_port); | |
175 } | |
176 saddr_in.sin_family = AF_INET; | |
177 saddr_in.sin_port = htons (port); | |
178 saddr_in.sin_addr.s_addr = htonl (INADDR_ANY); | |
179 | |
180 for (i = 0; i < MAX_PORT_NUMBER; i++) | |
181 { | |
182 if ((so = socket (AF_INET, SOCK_STREAM, 0)) < 0) | |
183 { | |
184 return (-1); | |
185 } | |
186 setsockopt (so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (int)); | |
187 if (bind (so, (struct sockaddr *) &saddr_in, sizeof (struct sockaddr_in)) == 0) | |
188 { | |
189 ok = 1; | |
190 break; | |
191 } | |
192 shutdown (so, 2); | |
193 if (port == real_port) | |
194 port += 0x10; | |
195 else | |
196 port += 1; | |
197 saddr_in.sin_port = htons (port); | |
198 } | |
199 if (ok == 0) | |
200 { | |
201 return (-1); | |
202 } | |
203 real_port = port; | |
204 if (listen (so, 5) < 0) | |
205 { | |
206 shutdown (so, 2); | |
207 return (-1); | |
208 } | |
209 accept_blk[XJP_INET_ACPT].sd = so; | |
210 sock_set (all_socks, so); | |
211 return (0); | |
212 } | |
213 #endif /* TCPCONN */ | |
214 | |
215 void | |
216 XJp_init_net () | |
217 { | |
218 xjp_init_net_area (); | |
219 #ifdef UNIXCONN | |
220 if (xjp_init_net_un () < 0) | |
221 { | |
222 print_out ("Could not open UNIX domain socket for XJp protocol."); | |
223 } | |
224 #endif /* UNIXCONN */ | |
225 #ifdef TCPCONN | |
226 if (xjp_init_net_in () < 0) | |
227 { | |
228 print_out ("Could not open INET domain socket for XJp protocol."); | |
229 } | |
230 #endif /* TCPCONN */ | |
231 } | |
232 | |
233 void | |
234 XJp_close_net () | |
235 { | |
236 int trueFlag = 1; | |
237 #ifdef UNIXCONN | |
238 struct sockaddr_un addr_un; | |
239 #endif /* UNIXCONN */ | |
240 #ifdef TCPCONN | |
241 struct sockaddr_in addr_in; | |
242 #endif /* TCPCONN */ | |
243 #if defined(UNIXCONN) || defined(TCPCONN) | |
244 int addrlen; | |
245 extern int accept (), close (); | |
246 #endif | |
247 | |
248 #ifdef UNIXCONN | |
249 if (accept_blk[XJP_UNIX_ACPT].sd != -1) | |
250 { | |
251 #ifndef SOLARIS | |
252 #if defined(FIONBIO) | |
253 ioctl (accept_blk[XJP_UNIX_ACPT].sd, FIONBIO, &trueFlag); | |
254 #endif | |
255 #else /* !SOLARIS */ | |
256 fcntl (accept_blk[XJP_UNIX_ACPT].sd, F_SETFL, F_UNLCK); | |
257 #endif /* !SOLARIS */ | |
258 for (;;) | |
259 { | |
260 addrlen = sizeof (addr_un); | |
261 if (accept (accept_blk[XJP_UNIX_ACPT].sd, (struct sockaddr *) &addr_un, &addrlen) < 0) | |
262 break; | |
263 } | |
264 shutdown (accept_blk[XJP_UNIX_ACPT].sd, 2); | |
265 close (accept_blk[XJP_UNIX_ACPT].sd); | |
266 } | |
267 #endif /* UNIXCONN */ | |
268 | |
269 #ifdef TCPCONN | |
270 if (accept_blk[XJP_INET_ACPT].sd != -1) | |
271 { | |
272 #ifndef SOLARIS | |
273 #if defined(FIONBIO) | |
274 ioctl (accept_blk[XJP_INET_ACPT].sd, FIONBIO, &trueFlag); | |
275 #endif | |
276 #else /* !SOLARIS */ | |
277 fcntl (accept_blk[XJP_INET_ACPT].sd, F_SETFL, F_UNLCK); | |
278 #endif /* !SOLARIS */ | |
279 for (;;) | |
280 { | |
281 addrlen = sizeof (addr_in); | |
282 if (accept (accept_blk[XJP_INET_ACPT].sd, (struct sockaddr *) &addr_in, &addrlen) < 0) | |
283 break; | |
284 } | |
285 shutdown (accept_blk[XJP_INET_ACPT].sd, 2); | |
286 close (accept_blk[XJP_INET_ACPT].sd); | |
287 } | |
288 #endif /* TCPCONN */ | |
289 } | |
290 | |
291 int | |
292 XJp_return_sock (state, detail, open, keysym, string) | |
293 short state, detail; | |
294 int open; | |
295 KeySym keysym; | |
296 char *string; | |
297 { | |
298 unsigned short tmp_short; | |
299 unsigned long tmp_long; | |
300 | |
301 tmp_short = (unsigned short) htons (state); | |
302 if (_WriteToClient (&tmp_short, sizeof (short)) == -1) | |
303 return (-1); | |
304 tmp_short = (unsigned short) htons (detail); | |
305 if (_WriteToClient (&tmp_short, sizeof (short)) == -1) | |
306 return (-1); | |
307 | |
308 if (open == 0 && state == (short) 0) | |
309 { | |
310 tmp_long = (unsigned long) htonl (keysym); | |
311 if (_WriteToClient (&tmp_long, sizeof (KeySym)) == -1) | |
312 return (-1); | |
313 if (detail > (short) 0) | |
314 { | |
315 if (_WriteToClient (string, (int) detail) == -1) | |
316 return (-1); | |
317 } | |
318 need_write = 0; | |
319 } | |
320 if (_Send_Flush () == -1) | |
321 return (-1); | |
322 return (0); | |
323 } | |
324 | |
325 static int | |
326 xjp_new_cl_sock (fd) | |
327 int fd; | |
328 { | |
329 register XJpClientRec *xjp; | |
330 register XIMClientRec *xc; | |
331 short detail; | |
332 char buf[32]; | |
333 ximICValuesReq ic_req; | |
334 ximICAttributesReq pre_req, st_req; | |
335 XCharStruct cs; | |
336 | |
337 if ((_ReadFromClient (buf, 2) == -1) || (_ReadFromClient (buf, (int) buf[1]) == -1)) | |
338 { | |
339 return (-1); | |
340 } | |
341 if ((xjp = (XJpClientRec *) Malloc (sizeof (XJpClientRec))) == NULL) | |
342 { | |
343 XJp_return_sock ((short) -1, (short) 7, 1, (KeySym) 0, NULL); | |
344 return (-1); | |
345 } | |
346 xjp->dispmode = XJP_ROOT; | |
347 xjp->w = 0; | |
348 XJp_xjp_to_xim (xjp, &ic_req, &pre_req, &st_req, &cs); | |
349 if ((xc = create_client (&ic_req, &pre_req, &st_req, NULL, NULL, 0, 0, NULL, NULL, NULL, &detail)) == NULL) | |
350 { | |
351 Free ((char *) xjp); | |
352 XJp_return_sock ((short) -1, (short) 7, 1, (KeySym) 0, NULL); | |
353 return (-1); | |
354 } | |
355 if (XJp_return_sock ((short) 0, (short) 0, 1, (KeySym) 0, NULL) < 0) | |
356 { | |
357 Free ((char *) xjp); | |
358 return (-1); | |
359 } | |
360 xc->xjp = 1; | |
361 xjp->xim_client = xc; | |
362 xjp->direct_fd = fd; | |
363 xjp->next = xjp_clients; | |
364 xjp->ref_count = 0; | |
365 xjp_clients = xjp; | |
366 return (0); | |
367 } | |
368 | |
369 static int | |
370 xjp_new_client_acpt (fd) | |
371 int fd; | |
372 { | |
373 #ifdef UNIXCONN | |
374 struct sockaddr_un addr_un; | |
375 #endif /* UNIXCONN */ | |
376 #ifdef TCPCONN | |
377 struct sockaddr_in addr_in; | |
378 #endif /* TCPCONN */ | |
379 #if defined(UNIXCONN) || defined(TCPCONN) | |
380 register int i; | |
381 int addrlen; | |
382 #endif | |
383 | |
384 #ifdef UNIXCONN | |
385 if (accept_blk[XJP_UNIX_ACPT].sd != -1) | |
386 { | |
387 if (fd == accept_blk[XJP_UNIX_ACPT].sd) | |
388 { | |
389 for (i = 0; i < max_client; i++) | |
390 { | |
391 if (cblk[i].use == 0) | |
392 { | |
393 addrlen = sizeof (addr_un); | |
394 if ((cblk[i].sd = accept (fd, (struct sockaddr *) &addr_un, &addrlen)) < 0) | |
395 { | |
396 return (-1); | |
397 } | |
398 cur_cblk = &cblk[i]; | |
399 cur_cblk->use = 1; | |
400 cur_cblk->xjp = 1; | |
401 cur_cblk->byteOrder = False; | |
402 cur_sock = cur_cblk->sd; | |
403 if (xjp_new_cl_sock (cur_sock) == 0) | |
404 { | |
405 sock_set (all_socks, cur_sock); | |
406 } | |
407 return (0); | |
408 } | |
409 } | |
410 } | |
411 } | |
412 #endif /* UNIXCONN */ | |
413 #ifdef TCPCONN | |
414 if (fd == accept_blk[XJP_INET_ACPT].sd) | |
415 { | |
416 for (i = 0; i < max_client; i++) | |
417 { | |
418 if (cblk[i].use == 0) | |
419 { | |
420 addrlen = sizeof (addr_in); | |
421 if ((cblk[i].sd = accept (fd, (struct sockaddr *) &addr_in, &addrlen)) < 0) | |
422 { | |
423 return (-1); | |
424 } | |
425 cur_cblk = &cblk[i]; | |
426 cur_cblk->use = 1; | |
427 cur_cblk->xjp = 1; | |
428 cur_cblk->byteOrder = False; | |
429 cur_sock = cur_cblk->sd; | |
430 if (xjp_new_cl_sock (cur_sock) == 0) | |
431 { | |
432 sock_set (all_socks, cur_sock); | |
433 } | |
434 break; | |
435 } | |
436 } | |
437 } | |
438 #endif /* TCPCONN */ | |
439 return (0); | |
440 } | |
441 | |
442 int | |
443 XJp_wait_for_socket () | |
444 { | |
445 #ifdef UNIXCONN | |
446 if (accept_blk[XJP_UNIX_ACPT].sd != -1) | |
447 { | |
448 if (sock_tst (ready_socks, accept_blk[XJP_UNIX_ACPT].sd)) | |
449 { | |
450 sock_clr (ready_socks, accept_blk[XJP_UNIX_ACPT].sd); | |
451 cur_cblk = NULL; | |
452 cur_sock = -1; | |
453 xjp_new_client_acpt (accept_blk[XJP_UNIX_ACPT].sd); | |
454 return (XJP_DIRECT_TYPE); | |
455 } | |
456 } | |
457 #endif /* UNIXCONN */ | |
458 #ifdef TCPCONN | |
459 if (accept_blk[XJP_INET_ACPT].sd != -1) | |
460 { | |
461 if (sock_tst (ready_socks, accept_blk[XJP_INET_ACPT].sd)) | |
462 { | |
463 sock_clr (ready_socks, accept_blk[XJP_INET_ACPT].sd); | |
464 cur_cblk = NULL; | |
465 cur_sock = -1; | |
466 xjp_new_client_acpt (accept_blk[XJP_INET_ACPT].sd); | |
467 return (XJP_DIRECT_TYPE); | |
468 } | |
469 } | |
470 #endif /* TCPCONN */ | |
471 return (0); | |
472 } | |
473 | |
474 void | |
475 XJp_destroy_for_sock (fd) | |
476 int fd; | |
477 { | |
478 XJpClientRec *p, **prev_p; | |
479 XJpInputRec *i, **prev_i; | |
480 | |
481 for (prev_p = &xjp_clients; p = *prev_p; prev_p = &p->next) | |
482 { | |
483 if (p->direct_fd != -1 && p->direct_fd == fd) | |
484 { | |
485 if (p == xjp_cur_client) | |
486 { | |
487 xjp_cur_client = NULL; | |
488 xjp_cur_input = NULL; | |
489 } | |
490 destroy_client (p->xim_client); | |
491 for (prev_i = &xjp_inputs; i = *prev_i;) | |
492 { | |
493 if (i->pclient == p) | |
494 { | |
495 *prev_i = i->next; | |
496 Free ((char *) i); | |
497 } | |
498 else | |
499 { | |
500 prev_i = &i->next; | |
501 } | |
502 } | |
503 *prev_p = p->next; | |
504 Free ((char *) p); | |
505 return; | |
506 } | |
507 } | |
508 } | |
509 | |
510 static void | |
511 xjp_buffer_to_xevent (buf, ev) | |
512 char *buf; | |
513 XEvent *ev; | |
514 { | |
515 ev->xkey.display = dpy; | |
516 ev->xkey.type = (int) buf[0]; | |
517 ev->xkey.state = (unsigned int) buf[1]; | |
518 ev->xkey.serial = (unsigned long) ntohs (*(short *) (buf + 2)); | |
519 ev->xkey.time = (Time) ntohl (*(Time *) (buf + 4)); | |
520 ev->xkey.root = (Window) ntohl (*(Window *) (buf + 8)); | |
521 ev->xkey.window = (Window) ntohl (*(Window *) (buf + 12)); | |
522 ev->xkey.subwindow = (Window) ntohl (*(Window *) (buf + 16)); | |
523 ev->xkey.x_root = (int) ntohs (*(short *) (buf + 20)); | |
524 ev->xkey.y_root = (int) ntohs (*(short *) (buf + 22)); | |
525 ev->xkey.x = (int) ntohs (*(short *) (buf + 24)); | |
526 ev->xkey.y = (int) ntohs (*(short *) (buf + 26)); | |
527 ev->xkey.keycode = (unsigned int) ntohs (*(short *) (buf + 28)); | |
528 ev->xkey.same_screen = (Bool) buf[30]; | |
529 } | |
530 | |
531 static int | |
532 xjp_get_event (ev) | |
533 XEvent *ev; | |
534 { | |
535 char readbuf[64]; | |
536 register XJpClientRec *p; | |
537 register XJpInputRec *i; | |
538 | |
539 if (_ReadFromClient (readbuf, 32) == -1) | |
540 { | |
541 return (-1); | |
542 } | |
543 xjp_buffer_to_xevent (readbuf, ev); | |
544 for (p = xjp_clients; p; p = p->next) | |
545 { | |
546 if (p->direct_fd != -1 && p->direct_fd == cur_sock) | |
547 { | |
548 if (p->w == (Window) 0) | |
549 { | |
550 p->w = ev->xkey.window; | |
551 } | |
552 for (i = xjp_inputs; i; i = i->next) | |
553 { | |
554 if (i->pclient == p && i->w == ev->xkey.window) | |
555 return (0); | |
556 } | |
557 if ((i = (XJpInputRec *) Malloc (sizeof (XJpInputRec))) == NULL) | |
558 { | |
559 malloc_error ("allocation of Focus data struct(XJp)"); | |
560 return (-1); | |
561 } | |
562 i->w = ev->xkey.window; | |
563 i->pclient = p; | |
564 i->save_event = 0; | |
565 i->next = xjp_inputs; | |
566 xjp_inputs = i; | |
567 return (0); | |
568 } | |
569 } | |
570 return (-1); | |
571 } | |
572 | |
573 void | |
574 XJp_Direct_Dispatch () | |
575 { | |
576 XEvent ev; | |
577 int buff[32], in; | |
578 int ret, i, n_bytes; | |
579 | |
580 if (xjp_get_event (&ev) == -1) | |
581 return; | |
582 ret = key_input (buff, &ev); | |
583 for (i = 0; i < ret;) | |
584 { | |
585 n_bytes = get_cswidth_by_char (in = buff[i++]); | |
586 for (; n_bytes > 1 && i < ret; n_bytes--, i++) | |
587 { | |
588 in = (in << 8) + buff[i]; | |
589 } | |
590 in_put (in); | |
591 } | |
592 if (need_write) | |
593 { | |
594 XJp_return_sock ((short) 0, (short) 0, 0, (KeySym) 0, NULL); | |
595 } | |
596 return; | |
597 } | |
598 | |
599 static KeySym save_sock_keysym = (KeySym) 0; | |
600 static unsigned char save_sock_str[32]; | |
601 static unsigned int save_sock_str_len = 0; | |
602 | |
603 void | |
604 XJp_save_sockbuf (len, str, keysym) | |
605 int len; | |
606 unsigned char *str; | |
607 KeySym keysym; | |
608 { | |
609 if (xjp_cur_client && xjp_cur_client->direct_fd != -1) | |
610 { | |
611 need_write = 1; | |
612 save_sock_keysym = keysym; | |
613 save_sock_str_len = len; | |
614 if (len > 0) | |
615 { | |
616 bcopy (str, save_sock_str, len); | |
617 } | |
618 } | |
619 } | |
620 | |
621 void | |
622 XJp_direct_send_cl_key () | |
623 { | |
624 XJp_return_sock ((short) 0, (short) save_sock_str_len, 0, save_sock_keysym, save_sock_str); | |
625 } | |
626 | |
627 #endif /* defined(XJPLIB) && defined(XJPLIB_DIRECT) */ |