Mercurial > freewnn
diff Xwnmo/xwnmo/do_xjplib.c @ 0:bbc77ca4def5
initial import
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Thu, 13 Dec 2007 04:30:14 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Xwnmo/xwnmo/do_xjplib.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,1169 @@ +/* + * $Id: do_xjplib.c,v 1.2 2001/06/14 18:16:15 ura Exp $ + */ + +/* + * FreeWnn is a network-extensible Kana-to-Kanji conversion system. + * This file is part of FreeWnn. + * + * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999 + * Copyright 1991, 1992 by Massachusetts Institute of Technology + * + * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Emacs; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Commentary: + * + * Change log: + * + * Last modified date: 8,Feb.1999 + * + * Code: + * + */ + +#ifdef XJPLIB + +#include "do_xjplib.h" + +#define XJPLIB_PORT_IN (0x9494) +#define UNIX_PATH "/tmp/xwnmo.V2" +#define UNIX_ACPT 0 +#define INET_ACPT 1 + +#define XIMCLIENT (xim->root_pointer[xim->default_screen]->ximclient) + +static Atom xjp_select_id = (Atom) 0; + +XJpClientRec *xjp_clients = NULL; +XJpClientRec *xjp_cur_client = NULL; +XJpInputRec *xjp_inputs = NULL; +XJpInputRec *xjp_cur_input = NULL; + +char *def_escape[4] = { + "(J", + "$B", + "(I", + "$0" +}; + +#define vname_size 128 +#define hname_size 128 +#define XWNMO_XJP_NAME "xwnmo.V2" +void +XJp_init () +{ + char name[hname_size]; + unsigned char buffer[hname_size * 2 + 10]; + register unsigned char *p; + long pnumber = 0L; + extern int gethostname (); + + if (!(xjp_select_id = XInternAtom (dpy, "XJPFRONTEND", True))) + { + xjp_select_id = XInternAtom (dpy, "XJPFRONTEND", False); + } +#ifdef XJPLIB_DIRECT + pnumber = (long) XJp_get_xjp_port (); +#endif /* XJPLIB_DIRECT */ + gethostname (name, hname_size); + p = buffer; + strcpy (p, XWNMO_XJP_NAME); + p += vname_size; + strcpy (p, name); + bcopy (&pnumber, (p += hname_size), sizeof (long)); + *(p += sizeof (long)) = '\0'; + XChangeProperty (dpy, xim->root_pointer[xim->default_screen]->root_window, xjp_select_id, XA_STRING, 8, PropModeReplace, buffer, p - buffer); + XSetSelectionOwner (dpy, xjp_select_id, XIMCLIENT->w, 0L); +} + +static void +xjp_send_open (xjp, w) + XJpClientRec *xjp; + Window w; +{ + XEvent event; + + event.type = ClientMessage; + event.xclient.format = 32; + event.xclient.window = w; + event.xclient.data.l[0] = XJP_OPEN; + event.xclient.data.l[1] = w; + if (xjp->dispmode == XJP_ROOT) + { + event.xclient.data.l[2] = FontWidth (XIMCLIENT->xl[0]); + event.xclient.data.l[3] = FontHeight (XIMCLIENT->xl[0]); + } + else + { + event.xclient.data.l[2] = FontWidth (xjp->xim_client->xl[0]); + event.xclient.data.l[3] = FontHeight (xjp->xim_client->xl[0]); + } + XSendEvent (dpy, xjp->w, False, NoEventMask, &event); + XFlush (dpy); +} + +static void +xjp_send_err (w, err) + Window w; + int err; +{ + XEvent event; + + event.type = ClientMessage; + event.xclient.format = 32; + event.xclient.window = XIMCLIENT->w; + event.xclient.data.l[0] = XJP_ERROR; + event.xclient.data.l[1] = err; + XSendEvent (dpy, w, False, NoEventMask, &event); + XFlush (dpy); +} + +void +XJp_end () +{ + XEvent event; + XJpClientRec *p; + + if (dpy) + { + event.type = ClientMessage; + event.xclient.format = 32; + event.xclient.message_type = xjp_select_id; + event.xclient.data.l[0] = XJP_ERROR; + event.xclient.data.l[1] = 0; + for (p = xjp_clients; p; p = p->next) + { +#ifdef XJPLIB_DIRECT + if (p->direct_fd == -1) + { +#endif /* XJPLIB_DIRECT */ + XSendEvent (dpy, p->w, False, NoEventMask, &event); + XFlush (dpy); +#ifdef XJPLIB_DIRECT + } +#endif /* XJPLIB_DIRECT */ + } + } + XDeleteProperty (dpy, XIMCLIENT->w, xjp_select_id); +} + +static char * +xjp_get_xim_fontname (xjp, p, cs) + XJpClientRec *xjp; + register char *p; + XCharStruct *cs; +{ + register char *s, *ss, *xim_font; + char save_escape[10]; + int char_set; + register int i; + int get_height = 0; + XFontStruct *font; + + if ((xim_font = Malloc (strlen (p))) == NULL) + { + malloc_error ("allocation of work area"); + return (NULL); + } + + s = xim_font; + for (; *p; s++) + { + for (i = 0; *p && *p != 0x09; i++, p++) + save_escape[i] = *p; + save_escape[i] = '\0'; + p++; + ss = s; + for (; *p && *p != 0x0a; s++, p++) + { + *s = *p; + } + p++; + if (!get_height) + { + *s = '\0'; + if (font = XLoadQueryFont (dpy, ss)) + { + cs->ascent = font->ascent; + cs->descent = font->descent; + cs->width = font->max_bounds.width; + get_height = 1; + XFreeFont (dpy, font); + } + } + *s = ','; + if (save_escape[0] == '(') + { + if (save_escape[1] == 'I') + { + char_set = 2; + } + else + { + char_set = 0; + } + } + else if (save_escape[0] == '$') + { + if (save_escape[1] == 'B') + { + char_set = 1; + } + else + { + char_set = 3; + } + } + else + { + char_set = 0; + } + strcpy (xjp->escape[char_set], save_escape); + } + *s = '\0'; + return (xim_font); +} + +void +XJp_xjp_to_xim (xjp, ic_req, pre_req, st_req, cs) + XJpClientRec *xjp; + ximICValuesReq *ic_req; + ximICAttributesReq *pre_req, *st_req; + XCharStruct *cs; +{ + XWindowAttributes attr; + int height = cs->ascent + cs->descent; + int min_keycode, max_keycode; + + XDisplayKeycodes (dpy, &min_keycode, &max_keycode); + ic_req->c_window = ic_req->focus_window = xjp->w; + ic_req->max_keycode = max_keycode; + ic_req->mask = (1 << ICClientWindow); + ic_req->mask |= (1 << ICFocusWindow); + + switch (xjp->dispmode) + { + case XJP_UNDER: + ic_req->input_style = (XIMPreeditArea | XIMStatusArea); + ic_req->mask |= (1 << (ICInputStyle)); + ic_req->mask |= (1 << (ICArea)); + ic_req->mask |= (1 << (ICForeground)); + ic_req->mask |= (1 << (ICBackground)); + ic_req->mask |= (1 << (ICFontSet)); + ic_req->mask |= (1 << (ICArea + StatusOffset)); + ic_req->mask |= (1 << (ICForeground + StatusOffset)); + ic_req->mask |= (1 << (ICBackground + StatusOffset)); + ic_req->mask |= (1 << (ICFontSet + StatusOffset)); + pre_req->area_x = xjp->x + cs->width * MHL0; + pre_req->area_y = xjp->y + (xjp->height - height) / 2; + pre_req->area_width = xjp->width - cs->width * MHL0; + pre_req->area_height = xjp->height; + pre_req->foreground = xjp->fg; + pre_req->background = xjp->bg; + st_req->area_x = xjp->x; + st_req->area_y = xjp->y + (xjp->height - height) / 2; + st_req->area_width = cs->width * MHL0; + st_req->area_height = xjp->height; + st_req->foreground = xjp->fg; + st_req->background = xjp->bg; + break; + case XJP_XY: + ic_req->input_style = (XIMPreeditPosition | XIMStatusArea); + ic_req->mask |= (1 << (ICInputStyle)); + ic_req->mask |= (1 << (ICArea)); + ic_req->mask |= (1 << (ICForeground)); + ic_req->mask |= (1 << (ICBackground)); + ic_req->mask |= (1 << (ICSpotLocation)); + ic_req->mask |= (1 << (ICFontSet)); + ic_req->mask |= (1 << (ICArea + StatusOffset)); + ic_req->mask |= (1 << (ICForeground + StatusOffset)); + ic_req->mask |= (1 << (ICBackground + StatusOffset)); + ic_req->mask |= (1 << (ICFontSet + StatusOffset)); + XGetWindowAttributes (dpy, xjp->w, &attr); + pre_req->area_x = attr.x; + pre_req->area_y = attr.y; + pre_req->area_width = attr.width; + pre_req->area_height = attr.height; + pre_req->spot_x = xjp->x; + pre_req->spot_y = xjp->y + cs->ascent; + pre_req->foreground = xjp->fg; + pre_req->background = xjp->bg; + st_req->area_x = xjp->status_x; + st_req->area_y = xjp->status_y; + st_req->area_width = cs->width * MHL0; + st_req->area_height = xjp->height; + st_req->foreground = xjp->fg; + st_req->background = xjp->bg; + break; + case XJP_ROOT: + ic_req->input_style = (XIMPreeditNothing | XIMStatusNothing); + ic_req->mask |= (1 << (ICInputStyle)); + break; + } +} + +static void +xjp_open (ev) + XClientMessageEvent *ev; +{ + XJpClientRec *xjp, *p; + XIMClientRec *xc = NULL; + Atom client_atom = (Atom) ev->data.l[2]; + Window client_window = (Window) ev->data.l[1]; + Atom actual_type; + int actual_format; + unsigned long nitems, leftover; + unsigned char *data; + ximICValuesReq ic_req; + ximICAttributesReq pre_req, st_req; + XIMNestLangList lc_list = NULL; + char *font = NULL; + XCharStruct cs; + short detail; + int err_code = 0, i; + + if ((xjp = (XJpClientRec *) Malloc (sizeof (XJpClientRec))) == NULL) + { + malloc_error ("allocation of client data(XJp)"); + return; + } + XGetWindowProperty (dpy, client_window, client_atom, 0L, 1000000L, False, XA_STRING, &actual_type, &actual_format, &nitems, &leftover, &data); + if (nitems < 184) + { + print_out ("XJp_open data was bad format."); + return; + } + bcopy ((char *) data, (char *) xjp, 184); + data += 184; + for (p = xjp_clients; p; p = p->next) + { + if (p->w == xjp->w) + { + p->ref_count++; + if (xjp->dispmode == XJP_ROOT) + { + xjp_send_open (xjp, XIMCLIENT->xl[0]->wp[0]); + } + else + { + xjp_send_open (xjp, p->xim_client->xl[0]->wp[0]); + } + Free ((char *) xjp); + return; + } + } + for (i = 0; i < 4; i++) + { + xjp->escape[i][0] = '\0'; + } + if (xjp->dispmode != XJP_ROOT) + { + font = xjp_get_xim_fontname (xjp, data, &cs); + if ((xjp->mask & XJP_FG) == 0) + xjp->fg = XIMCLIENT->pe.fg; + if ((xjp->mask & XJP_BG) == 0) + xjp->bg = XIMCLIENT->pe.bg; + if (xjp->dispmode == XJP_UNDER) + { + if ((xjp->mask & XJP_BP) == 0) + xjp->bp = 1; + if ((xjp->mask & XJP_WIDTH) == 0) + xjp->width = xjp->p_width; + if ((xjp->mask & XJP_HEIGHT) == 0) + xjp->height = cs.ascent + cs.descent; + if ((xjp->mask & XJP_X) == 0) + xjp->x = 0; + if ((xjp->mask & XJP_Y) == 0) + xjp->y = xjp->p_height - (xjp->height + xjp->bp); + } + else if (xjp->dispmode == XJP_XY) + { + if ((xjp->mask & XJP_BP) == 0) + xjp->bp = 1; + if ((xjp->mask & XJP_HEIGHT) == 0) + xjp->height = cs.ascent + cs.descent; + } + } + for (i = 0; i < 4; i++) + { + if (xjp->escape[i][0] == '\0') + strcpy (xjp->escape[i], def_escape[i]); + } + XJp_xjp_to_xim (xjp, &ic_req, &pre_req, &st_req, &cs); + if (get_langlist (def_locale, &lc_list) >= 0 && lc_list) + { + xc = create_client (&ic_req, &pre_req, &st_req, lc_list, lc_list, 0, 0, font, font, xjp->c_data, &detail); + } + if (font) + Free (font); + if (lc_list) + free_langlist (lc_list); + if (xc == NULL) + { + switch (detail) + { + case BadStyle: + err_code = XJP_F_OPEN_NOT_SUPPORT; + break; + case BadFontSet: + err_code = XJP_F_OPEN_BAD_FN; + break; + case BadClientWindow: + case BadFocusWindow: + err_code = XJP_F_OPEN_BAD_WID; + break; + case BadSpotLocation: + err_code = XJP_F_OPEN_BAD_SZ; + break; + case BadSomething: + default: + err_code = XJP_F_OPEN_NOT_WIN; + break; + } + xjp_send_err (xjp->w, err_code); + Free ((char *) xjp); + return; + } + else + { + xc->xjp = 1; + xjp->xim_client = xc; +#ifdef XJPLIB_DIRECT + xjp->direct_fd = -1; +#endif /* XJPLIB_DIRECT */ + xjp->next = xjp_clients; + xjp->ref_count = 0; + xjp_clients = xjp; + XSelectInput (dpy, xjp->w, StructureNotifyMask); + if (xjp->dispmode == XJP_ROOT) + { + xjp_send_open (xjp, XIMCLIENT->xl[0]->wp[0]); + } + else + { + xjp_send_open (xjp, xc->xl[0]->wp[0]); + } + } +} + +static void +xjp_close (ev) + XClientMessageEvent *ev; +{ + Window client_window = ev->window; + XJpClientRec *p, **prev_p; + XJpInputRec *i, **prev_i; + + for (prev_p = &xjp_clients; p = *prev_p; prev_p = &p->next) + { + if (client_window == p->w) + { + if (p->ref_count) + { + p->ref_count--; + return; + } + if (p == xjp_cur_client) + { + xjp_cur_client = NULL; + xjp_cur_input = NULL; + } + destroy_client (p->xim_client); + for (prev_i = &xjp_inputs; i = *prev_i;) + { + if (i->pclient == p) + { + XSelectInput (dpy, i->w, NoEventMask); + *prev_i = i->next; + Free ((char *) i); + } + else + { + prev_i = &i->next; + } + } + XSelectInput (dpy, p->w, NoEventMask); + *prev_p = p->next; + Free ((char *) p); + return; + } + } +} + +static void +xjp_begin (ev) + XClientMessageEvent *ev; +{ + register XJpClientRec *xjp = NULL, *p; + register XJpInputRec *i; + Window grab_window = ev->data.l[2]; + Window client_window = ev->window; + + for (p = xjp_clients; p; p = p->next) + { + if (p->w == client_window) + { + xjp = p; + break; + } + } + if (p == NULL) + return; + + for (p = xjp_clients; p; p = p->next) + { + if (p->w == grab_window) + { + XSelectInput (dpy, grab_window, (KeyPressMask | StructureNotifyMask)); + break; + } + } + if (p == NULL) + { + XSelectInput (dpy, grab_window, KeyPressMask); + } + XFlush (dpy); + for (i = xjp_inputs; i; i = i->next) + { + if (i->w == grab_window) + { + if (i->pclient != xjp) + { + i->pclient = xjp; + cur_input = NULL; + } + return; + } + } + if ((i = (XJpInputRec *) Malloc (sizeof (XJpInputRec))) == NULL) + { + if (p) + { + XSelectInput (dpy, grab_window, StructureNotifyMask); + } + else + { + XSelectInput (dpy, grab_window, NoEventMask); + } + return; + } + i->w = grab_window; + i->pclient = xjp; + i->save_event = 0; + i->next = xjp_inputs; + xjp_inputs = i; +} + +static void +xjp_end (ev) + XClientMessageEvent *ev; +{ + register XJpClientRec *p; + Window grab_window = ev->data.l[2]; + + for (p = xjp_clients; p; p = p->next) + { + if (p->w == grab_window) + { + XSelectInput (dpy, grab_window, StructureNotifyMask); + break; + } + } + if (p == NULL) + XSelectInput (dpy, grab_window, NoEventMask); + cur_input = NULL; + XFlush (dpy); +} + +static void +xjp_change (ev) + XClientMessageEvent *ev; +{ + register XJpClientRec *xjp = NULL, *p; + register XIMClientRec *xc = NULL; + Window pre_window = (Window) ev->data.l[1]; + XJpClientRec savexjp; + Atom client_atom; + Atom actual_type; + int actual_format; + unsigned long nitems, leftover; + unsigned char *data; + ximICValuesReq ic_req; + ximICAttributesReq pre_req, st_req; + short detail; + unsigned long mask, xim_mask = 0; + + for (p = xjp_clients; p; p = p->next) + { + if (IsPreeditNothing (p->xim_client)) + continue; + if (p->xim_client->xl[0]->wp[0] == pre_window) + { + xjp = p; + xc = p->xim_client; + break; + } + } + if (xjp == NULL) + return; + if (!(client_atom = XInternAtom (dpy, "XJPCLIENT", True))) + return; + XGetWindowProperty (dpy, p->w, client_atom, 0L, 1000000L, False, XA_STRING, &actual_type, &actual_format, &nitems, &leftover, &data); + if (nitems < 184) + return; + + bcopy ((char *) data, (char *) &savexjp, 184); + mask = savexjp.mask; + + if (mask & XJP_FG) + { + if (xjp->fg != savexjp.fg) + { + xjp->fg = savexjp.fg; + xim_mask |= ((1 << ICForeground) | (1 << (ICForeground + StatusOffset))); + } + xjp->mask |= XJP_FG; + } + if (mask & XJP_BG) + { + if (xjp->bg != savexjp.bg) + { + xjp->bg = savexjp.bg; + xim_mask |= ((1 << ICBackground) | (1 << (ICBackground + StatusOffset))); + } + xjp->mask |= XJP_BG; + } + if ((mask & XJP_WIDTH) /* && xjp->dispmode == XJP_XY */ ) + { + if (xjp->width != savexjp.width) + { + xjp->width = savexjp.width; + xim_mask |= (1 << ICArea); + } + xjp->mask |= XJP_WIDTH; + } + if (mask & XJP_HEIGHT) + { + if (xjp->height != savexjp.height) + { + xjp->height = savexjp.height; + xim_mask |= (1 << ICArea); + } + xjp->mask |= XJP_HEIGHT; + } + if ((mask & XJP_X) && xjp->dispmode == XJP_XY) + { + if (xjp->x != savexjp.x) + { + xjp->x = savexjp.x; + xim_mask |= (1 << ICSpotLocation); + } + xjp->mask |= XJP_X; + } + if ((mask & XJP_Y) && xjp->dispmode == XJP_XY) + { + if (xjp->y != savexjp.y) + { + xjp->y = savexjp.y; + xim_mask |= (1 << ICSpotLocation); + } + xjp->mask |= XJP_Y; + } + if (mask & XJP_PWIDTH) + { + if (xjp->p_width != savexjp.p_width) + { + xjp->p_width = savexjp.p_width; + if (xjp->dispmode == XJP_UNDER && !(xjp->mask & XJP_WIDTH)) + { + xjp->width = xjp->p_width; + xim_mask |= (1 << ICArea); + } + } + xjp->mask |= XJP_PWIDTH; + } + if (mask & XJP_PHEIGHT) + { + if (xjp->p_height != savexjp.p_height) + { + xjp->p_height = savexjp.p_height; + if (xjp->dispmode == XJP_UNDER /* && !(xjp->mask & XJP_HEIGHT) */ ) + { + xjp->y = xjp->p_height - xjp->height; + xim_mask |= ((1 << ICArea) | (1 << (ICArea + StatusOffset))); + } + } + xjp->mask |= XJP_HEIGHT; + } + if (mask & XJP_STATUS) + { + if (xjp->dispmode == XJP_XY) + { + xjp->status_x = savexjp.status_x; + xjp->status_y = savexjp.status_y; + xim_mask |= (1 << (ICArea + StatusOffset)); + } + xjp->mask |= XJP_STATUS; + } + + XJp_xjp_to_xim (xjp, &ic_req, &pre_req, &st_req, xc->xl[0]->pe_b_char); + ic_req.mask = xim_mask; + change_client (xc, &ic_req, &pre_req, &st_req, NULL, NULL, NULL, &detail); +} + +static void +xjp_move (ev) + XClientMessageEvent *ev; +{ + register XJpClientRec *p; + Window pre_window = (Window) ev->data.l[1]; + int x = (int) ev->data.l[2]; + int y = (int) ev->data.l[3]; + + for (p = xjp_clients; p; p = p->next) + { + if (IsPreeditNothing (p->xim_client)) + continue; + if (p->xim_client->xl[0]->wp[0] == pre_window) + { + p->x = x; + p->y = y + FontAscent (p->xim_client->cur_xl); + change_spotlocation (p->xim_client, p->x, p->y); + return; + } + } +} + +static void +xjp_visible (ev, visible) + XClientMessageEvent *ev; + int visible; +{ + Window visible_window = ev->window; + register XJpClientRec *p; + register XIMClientRec *xc; + XIMClientRec *save_cur_p, *save_cur_x; + WnnClientRec *save_c_c; + + for (p = xjp_clients; p; p = p->next) + { + if (p->w == visible_window) + { + break; + } + } + if (p == NULL) + return; + xc = p->xim_client; + save_cur_p = cur_p; + save_cur_x = cur_x; + save_c_c = c_c; + cur_x = xc; + if (IsPreeditNothing (xc)) + { + cur_p = XIMCLIENT; + } + else + { + cur_p = cur_x; + } + c_c = cur_p->cur_xl->w_c; + cur_rk = c_c->rk; + cur_rk_table = cur_rk->rk_table; + if (IsPreeditPosition (xc) || IsPreeditArea (xc)) + { + if (visible) + { + reset_preedit (xc); + } + else + { + invisual_window (); + } + } + if (IsStatusArea (xc)) + { + if (visible) + { + visual_status (); + } + else + { + invisual_status (); + } + } + cur_p = save_cur_p; + cur_x = save_cur_x; + c_c = save_c_c; + if (c_c) + { + cur_rk = c_c->rk; + cur_rk_table = cur_rk->rk_table; + } +} + +static void +xjp_indicator (ev) + XClientMessageEvent *ev; +{ + register XJpClientRec *p; + Window pre_window = (Window) ev->data.l[1]; + Window window = (Window) ev->data.l[2]; + int x = (int) ev->data.l[3]; + int y = (int) ev->data.l[4]; + + for (p = xjp_clients; p; p = p->next) + { + if (p->dispmode == XJP_ROOT) + continue; + if (p->xim_client->xl[0]->wp[0] == pre_window) + { + p->x = x; + p->y = y; + XReparentWindow (dpy, p->xim_client->xl[0]->ws, window, x, y); + return; + } + } +} + +void +XJp_event_dispatch (ev) + XClientMessageEvent *ev; +{ + switch (ev->data.l[0]) + { + case XJP_OPEN: + xjp_open (ev); + break; + case XJP_CLOSE: + xjp_close (ev); + break; + case XJP_BEGIN: + xjp_begin (ev); + break; + case XJP_END: + xjp_end (ev); + break; + case XJP_CHANGE: + xjp_change (ev); + break; + case XJP_MOVE: + xjp_move (ev); + break; + case XJP_VISIBLE: + xjp_visible (ev, 1); + break; + case XJP_INVISIBLE: + xjp_visible (ev, 0); + break; + case XJP_INDICATOR: + xjp_indicator (ev); + break; + } + +} + +XIMClientRec * +XJp_cur_cl_set (set_window) + Window set_window; +{ + register XJpInputRec *i; + + if (set_window == (Window) 0) + { + xjp_cur_input = NULL; + xjp_cur_client = NULL; + return (NULL); + } + for (i = xjp_inputs; i; i = i->next) + { + if (i->w == set_window) + { + xjp_cur_input = i; + xjp_cur_client = i->pclient; + cur_input = NULL; + return (i->pclient->xim_client); + } + } + return (NULL); +} + +int +XJp_check_cur_input (w) + Window w; +{ + if (xjp_cur_input && w == xjp_cur_input->w) + return (0); + return (1); +} + +static void +xjp_send_cl_key (ev) + XKeyEvent *ev; +{ +#ifdef XJPLIB_DIRECT + if (xjp_cur_client && xjp_cur_client->direct_fd != -1) + { + XJp_direct_send_cl_key (); + return; + } +#endif /* XJPLIB_DIRECT */ + if (!xjp_cur_input) + return; + ev->window = xjp_cur_input->w; + XSendEvent (dpy, xjp_cur_input->w, False, NoEventMask, (XEvent *) ev); + XFlush (dpy); +} + +void +XJp_check_send_cl_key (ev) + XKeyEvent *ev; +{ + if (xjp_cur_input == NULL || xjp_cur_client == NULL) + return; + if (ifempty () || henkan_off_flag) + xjp_send_cl_key (ev); +} + +static void +xjp_save_event (ev) + XKeyEvent *ev; +{ + if (!xjp_cur_input) + return; + ev->window = xjp_cur_input->w; + bcopy ((char *) ev, (char *) &(xjp_cur_input->ev), sizeof (XKeyEvent)); + xjp_cur_input->save_event = 1; +} + +void +XJp_check_save_event (ev, must) + XKeyEvent *ev; + int must; +{ + if (xjp_cur_input == NULL || xjp_cur_client == NULL) + return; + if (must || ifempty () || henkan_off_flag) + xjp_save_event (ev); +} + +void +XJp_return_cl_it () +{ +#ifdef XJPLIB_DIRECT + if (xjp_cur_client && xjp_cur_client->direct_fd != -1) + { + XJp_direct_send_cl_key (); + return; + } +#endif /* XJPLIB_DIRECT */ + if (!xjp_cur_input || !xjp_cur_input->save_event) + return; + xjp_send_cl_key (&(xjp_cur_input->ev)); + xjp_cur_input->save_event = 0; +} + +static void +xjp_send_buf (ptr, len, cs) + register unsigned char *ptr; + int len; + int cs; +{ + XEvent ev; + register int i; + + ev.type = ClientMessage; + ev.xclient.format = 8; + ev.xclient.message_type = xjp_select_id; + ev.xclient.window = xjp_cur_input->w; + bcopy (xjp_cur_client->escape[cs], ev.xclient.data.b, 2); + while (len > 0) + { + for (i = 4; i < 4 + len && i < 20; i++, ptr++) + { + ev.xclient.data.b[i] = *ptr; + } + ev.xclient.data.b[3] = (char) (i - 4); + XSendEvent (dpy, xjp_cur_input->w, False, NoEventMask, &ev); + len -= 16; + } +} + +void +XJp_xw_write (w_buf, size) + register w_char *w_buf; + register int size; +{ + unsigned char *ptr, *send_ptr, *save_ptr, buf[512], send_buf[512]; + int len, send_len = 0; + int cs = 0; + + if (henkan_off_flag) + { + XJp_return_cl_it (); + return; + } + + if ((len = w_char_to_char (w_buf, buf, size)) <= 0) + return; + buf[len] = '\0'; + +#ifdef XJPLIB_DIRECT + if (xjp_cur_client->direct_fd != -1) + { + XJp_return_sock ((short) 0, (short) len, 0, (KeySym) 0, buf); + return; + } +#endif /* XJPLIB_DIRECT */ + + for (ptr = buf, send_ptr = save_ptr = send_buf; *ptr;) + { + if (*ptr >= 0xa1 && *ptr <= 0xfe) + { + if (cs != 1 && send_len > 0) + { + xjp_send_buf (save_ptr, send_len, cs); + save_ptr = send_ptr; + send_len = 0; + } + *send_ptr++ = *ptr++ & 0x7f; + *send_ptr++ = *ptr++ & 0x7f; + cs = 1; + send_len += 2; + } + else if (*ptr == SS2) + { + if (cs != 2 && send_len > 0) + { + xjp_send_buf (save_ptr, send_len, cs); + save_ptr = send_ptr; + send_len = 0; + } + ptr++; + *send_ptr++ = *ptr++ &= 0x7f; + cs = 2; + send_len += 1; + } + else if (*ptr == SS3) + { + if (cs != 3 && send_len > 0) + { + xjp_send_buf (save_ptr, send_len, cs); + save_ptr = send_ptr; + send_len = 0; + } + ptr++; + *send_ptr++ = *ptr++ &= 0x7f; + *send_ptr++ = *ptr++ &= 0x7f; + cs = 2; + send_len += 2; + } + else + { + if (*ptr == 0xd || *ptr == 0xa) + { + if (send_len > 0) + { + xjp_send_buf (save_ptr, send_len, cs); + save_ptr = send_ptr; + send_len = 0; + } + XJp_return_cl_it (); + ptr++; + } + else + { + if (cs != 0 && send_len > 0) + { + xjp_send_buf (save_ptr, send_len, cs); + save_ptr = send_ptr; + send_len = 0; + } + *send_ptr++ = *ptr++; + cs = 0; + send_len += 1; + } + } + } + xjp_send_buf (save_ptr, send_len, cs); +} + +int +XJp_xw_destroy (ev) + register XDestroyWindowEvent *ev; +{ + Window client_window = ev->window; + XJpClientRec *p, **prev_p; + XJpInputRec *i, **prev_i; + + for (prev_p = &xjp_clients; p = *prev_p; prev_p = &p->next) + { + if (client_window == p->w) + { + if (p == xjp_cur_client) + { + xjp_cur_client = NULL; + xjp_cur_input = NULL; + } + destroy_client (p->xim_client); + for (prev_i = &xjp_inputs; i = *prev_i;) + { + if (i->pclient == p) + { + XSelectInput (dpy, i->w, NoEventMask); + *prev_i = i->next; + Free ((char *) i); + } + else + { + prev_i = &i->next; + } + } + XSelectInput (dpy, p->w, NoEventMask); + *prev_p = p->next; + Free ((char *) p); + return (1); + } + } + return (0); +} + +int +XJp_check_map (xc) + register XIMClientRec *xc; +{ + register XJpInputRec *i; + + for (i = xjp_inputs; i != NULL; i = i->next) + { + if (i->pclient && i->pclient->xim_client == xc) + return (1); + } + return (0); +} + +int +XJp_get_client_cnt () +{ + register XJpClientRec *p; + register int i; + + for (i = 0, p = xjp_clients; p; p = p->next) + i++; + return (i); +} +#endif