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) */