Mercurial > freewnn
diff Xwnmo/xwnmo/evdispatch.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/evdispatch.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,705 @@ +/* + * $Id: evdispatch.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: + * '99/04/19 TAOKA Satoshi - 田岡 智志<taoka@infonets.hiroshima-u.ac.jp> + * kill()、getpid() の宣言をコメントアウト。 + * + * Last modified date: 19,Apr.1999 + * + * Code: + * + */ +/* Version 4.0 + */ +#include <stdio.h> +#include "commonhd.h" +#include "sdefine.h" +#include "xim.h" +#include "sheader.h" +#include "ext.h" + +#ifdef BC_X11R5 +#define IS_NOT_FROM_XIMR5(ev) ((ev).xselectionrequest.selection == server_id) + +int ximr5_client = 1; /* True when XIM R5 client comes */ +extern Atom server_id; /* IM server of X11R6 */ +#endif /* BC_X11R5 */ + +static void +keyboard_mapping (ev) + XMappingEvent *ev; +{ + XRefreshKeyboardMapping (ev); +} + +static int +motif_event (ev) + XClientMessageEvent *ev; +{ + /* extern int kill(), getpid(); */ + + if (ev->window == xim->root_pointer[xim->default_screen]->ximclient->w) + { + do_end (); + } + else if (xim->j_c && (ev->window == xim->cur_j_c_root->ichi->w || ev->window == xim->cur_j_c_root->inspect->w)) + { + xim->sel_ret = -2; + cur_cl_change3 (xim->j_c); + return (0); + } + return (1); +} + + +static char *syuuryou_title = "X INPUT MANAGER"; +static char *syuuryou_syuuryou = " EXIT "; +static void +syuuryou_menu (in) + int in; +{ + static char *buf[1]; + int c; + + cur_x = xim->root_pointer[xim->default_screen]->ximclient; + cur_p = cur_x; + cur_lang = cur_p->cur_xl->lang_db; + c_c = cur_p->cur_xl->w_c; + cur_rk = c_c->rk; + cur_rk_table = cur_rk->rk_table; + cur_input = 0; + xim->exit_menu_flg = (char) 1; + buf[0] = syuuryou_syuuryou; + c = xw_select_one_element (buf, 1, -1, syuuryou_title, SENTAKU, main_table[4], in); + if (c == 0) + { + do_end (); + } + else if (c == BUFFER_IN_CONT) + { + return; + } + xim->exit_menu_flg = (char) 0; + return; +} + + +static void +search_expose (event) + register XExposeEvent *event; +{ + register XIMClientRec *xc; + register XIMLangRec *xl; + register BoxRec *p; + register Window window = event->window; + + for (xc = ximclient_list; xc != NULL; xc = xc->next) + { + if (IsPreeditArea (xc) || IsPreeditPosition (xc)) + { + cur_p = cur_x = xc; + xl = cur_p->cur_xl; + cur_lang = xl->lang_db; + if (window == xl->w[0]) + { + if (IsPreeditArea (cur_x)) + { + redraw_window3 (event->x, event->width); + return; + } + else if (IsPreeditPosition (cur_x)) + { + redraw_lines (event->x, event->width, 1); + return; + } + } + else if (window == xl->w[1]) + { + redraw_lines (event->x, event->width, 2); + return; + } + else if (window == xl->w[2]) + { + redraw_lines (event->x, event->width, 3); + return; + } + else if (window == xl->wn[0]) + { + redraw_note (0); + return; + } + else if (window == xl->wn[1]) + { + redraw_note (1); + return; + } + } + + if (IsStatusArea (xc)) + { + if (window == cur_p->cur_xl->ws) + { + redraw_window0 (); + return; + } + } + } + for (p = box_list; p != NULL; p = p->next) + { + if (window == p->window) + { + if (p->redraw_cb) + (p->redraw_cb) (p->redraw_cb_data); + redraw_box (p); + return; + } + } + if (xim->j_c) + { + cur_cl_change3 (xim->j_c); + if (window == xim->cur_j_c_root->ichi->w1) + { + redraw_ichi_w (); + return; + } + else if (window == xim->cur_j_c_root->ichi->nyuu_w) + { + JW3Mputc (xim->cur_j_c_root->ichi->nyuu, xim->cur_j_c_root->ichi->nyuu_w, 0, 1, 0); + return; + } + if (window == xim->cur_j_c_root->inspect->w1) + { + JW3Mputc (xim->cur_j_c_root->inspect->msg, xim->cur_j_c_root->inspect->w1, 0, 0, IN_BORDER); + return; + } + } + return; +} + +static void +xw_expose (event) + register XExposeEvent *event; +{ + register XIMClientRec *cur_x_sv, *cur_p_sv; + register XIMLangDataBase *cur_lang_sv; + + cur_x_sv = cur_x; + cur_p_sv = cur_p; + cur_lang_sv = cur_lang; + search_expose (event); + cur_p = cur_p_sv; + cur_x = cur_x_sv; + cur_lang = cur_lang_sv; +} + +static Status +xw_buttonpress (event) + XButtonEvent *event; +{ + register XIMClientRec *xc; + register BoxRec *p; + register Window window = event->window; + + xim->sel_ret = -1; + for (xc = ximclient_list; xc != NULL; xc = xc->next) + { + if (IsPreeditNothing (xc)) + continue; + if (window == xc->cur_xl->ws) + { + if (xim->j_c == NULL) + { + xim->sel_button = 1; + cur_cl_change3 (xc); + if (event->button == Button1) + { + jutil_c (); + } + else + { + lang_c (); + } + } + return (False); + } + } + + for (p = box_list; p != NULL; p = p->next) + { + if (window == p->window) + { + if (p->freeze) + return (False); + xim->sel_ret = p->sel_ret; + if (p->cb) + (*p->cb) (p->cb_data); + return (p->do_ret); + } + } + if (xim->j_c) + { + if (window == xim->cur_j_c_root->ichi->w1) + { + xim->sel_button = 1; + if (xim->cur_j_c_root->ichi->mode == SENTAKU) + { + xw_select_button (event); + } + else + { + xw_select_jikouho_button (event); + } + cur_cl_change3 (xim->j_c); + return (True); + } + } + return (False); +} + +static void +xw_destroy (event) + register XDestroyWindowEvent *event; +{ + register XIMClientRec *xc; + register int i; + +#ifdef XJPLIB + if (XJp_xw_destroy (event)) + return; +#endif /* XJPLIB */ +#ifdef USING_XJUTIL + if (xjutil_destroy (event)) + return; +#endif /* USING_XJUTIL */ + for (xc = ximclient_list; xc != NULL; xc = xc->next) + { + if (event->window == xc->w) + { + for (i = 0; i < xim->screen_count; i++) + { + if (xc == xim->root_pointer[i]->ximclient) + { + create_xim_window (xim->root_pointer[i], xc); + create_preedit (xc, xc->cur_xl, 1); + create_status (xc, xc->cur_xl, 1); + XMapWindow (dpy, xc->cur_xl->ws); + return; + } + } + destroy_client (xc); + return; + } + } +} + +static void +xw_mousemove (event) + XMotionEvent *event; +{ + if (xim->j_c) + { + if (xim->cur_j_c_root->ichi->mode == SENTAKU) + { + xw_move_hilite (event->y); + } + else + { + xw_jikouho_move_hilite (event->x, event->y); + } + } +} + +static void +xw_enterleave (event, el) + XCrossingEvent *event; + char el; +{ + register BoxRec *p; + register Window window = event->window; + + for (p = box_list; p != NULL; p = p->next) + { + if (window == p->window) + { + if (!p->freeze && p->reverse && el != p->in) + { + reverse_box (p, p->invertgc); + p->in = el; + } + return; + } + } + if (xim->j_c) + { + if (window == xim->cur_j_c_root->ichi->w1) + { + if (el) + { + xw_mousemove (event); + } + else + { + if (xim->cur_j_c_root->ichi->mode == SENTAKU) + xw_mouseleave (); + } + return; + } + } + return; +} + +static void +xw_reparent (event) + XReparentEvent *event; +{ +/* + register XIMClientRec *xc; + + for (xc = ximclient_list; xc != NULL; xc = xc->next) { + if (xc->xl[0] && (xc->lang_num > 1)) { + if (event->window == xc->xl[0]->wp[0]) { + reparent_preedit(xc, event->parent); + return; + } + if (event->window == xc->xl[0]->ws) { + reparent_status(xc, event->parent); + return; + } + } + } +*/ + read_wm_id (); +} + +static void +xw_configure (ev) + XConfigureEvent *ev; +{ + register XIMClientRec *xc; + + for (xc = ximclient_list; xc != NULL; xc = xc->next) + { + if (xc->w == ev->window) + { + change_client_area (xc, ev->x, ev->y, ev->width, ev->height); + return; + } + else if (xc->focus_window == ev->window) + { + change_focus_area (xc, ev->x, ev->y, ev->width, ev->height); + return; + } + } +} + +void +X_flush () +{ + if (cur_x && cur_p && IsPreeditPosition (cur_x) && cur_p->cur_xl->del_x >= cur_p->cur_xl->max_pos) + { + JWMline_clear1 (); + } + XFlush (dpy); +} + +static void +kill_xim (window, prop_id, force) + Window window; + Atom prop_id; + int force; +{ + XEvent event; + register int i, ok = 0; + register XIMClientRec *xc; + unsigned char *data; + Atom actual_type; + int actual_format; + unsigned long nitems, leftover; + + for (i = 0, xc = ximclient_list; xc; xc = xc->next) + i++; +#ifdef XJPLIB + i += XJp_get_client_cnt (); +#endif /* XJPLIB */ + event.type = ClientMessage; + event.xclient.format = 32; + event.xclient.window = xim->root_pointer[xim->default_screen]->ximclient->w; + event.xclient.data.l[0] = XWNMO_KILL; + if (prop_id) + { + XGetWindowProperty (dpy, xim->root_pointer[xim->default_screen]->root_window, prop_id, 0L, 1000000L, False, XA_STRING, &actual_type, &actual_format, &nitems, &leftover, &data); + if (nitems > 0 && data && *data && !strncmp (root_username, (char *) data, nitems)) + { + if (force || i == 1) + { + ok = 1; + event.xclient.data.l[2] = 0; + } + else + { + event.xclient.data.l[2] = i - 1; + } + } + else + { + event.xclient.data.l[2] = -1; + } + XFree (data); + } + else + { + event.xclient.data.l[2] = -1; + } + if (ok) + { + event.xclient.data.l[1] = XWNMO_KILL_OK; + } + else + { + event.xclient.data.l[1] = XWNMO_KILL_NG; + } + XSendEvent (dpy, window, False, NoEventMask, &event); + XFlush (dpy); + if (ok) + { + do_end (); + } +} + +static Bool +dummy_proc (display, ev, arg) + Display *display; + XEvent *ev; + char *arg; +{ + return (True); +} + +void +XEventDispatch () +{ + int buff[32], in; + XEvent event; + int ret = 0, n_bytes; + register int i; + extern Atom wm_id; + extern Atom wm_id1; + +/* + while (XPending(dpy) > 0) { +*/ + do + { +/* + XNextEvent(dpy, &event); + if (XCheckMaskEvent(dpy, ~NoEventMask, &event) == False) return; +*/ + if (XCheckIfEvent (dpy, &event, dummy_proc, 0) == False) + return; + ret = 0; + switch (event.type) + { + case KeyPress: + xim->sel_button = (char) 0; + ret = key_input (buff, &event); + break; + case Expose: + xw_expose (&event); + break; + case ButtonRelease: + button.x = event.xbutton.x_root; + button.y = event.xbutton.y_root; + if (event.xbutton.window == xim->root_pointer[xim->default_screen]->ximclient->w) + { + if (xim->exit_menu) + { + xim->sel_button = 1; + syuuryou_menu (); + } + } + else + { + if (xw_buttonpress (&event) == True) + { + if (xim->exit_menu_flg && xim->j_c && ((event.xbutton.window == xim->cur_j_c_root->ichi->button[CANCEL_W]->window) || (event.xbutton.window == xim->cur_j_c_root->ichi->w1))) + { + syuuryou_menu (); + } + else + { + buff[0] = 0xd; + ret = 1; + } + } + } + break; + case DestroyNotify: + xw_destroy (&event); + break; + case MotionNotify: + xw_mousemove (&event); + break; + case EnterNotify: + xw_enterleave (&event, 1); + break; + case LeaveNotify: + xw_enterleave (&event, 0); + break; + case ReparentNotify: + xw_reparent (&event); + break; + case MapNotify: + check_map (event.xmap.window); + break; + case MappingNotify: + keyboard_mapping (&event); + break; + case ConfigureNotify: + xw_configure (&event); + break; + case ClientMessage: + if (wm_id && (event.xclient.message_type == wm_id) && (event.xclient.data.l[0] == wm_id1)) + { + motif_event (&event); + break; + } +#ifdef USING_XJUTIL + if (event.xclient.data.l[0] == DIC_START) + { + set_xjutil_id (event.xclient.data.l[1], event.xclient.data.l[2], 0); + } + else if (event.xclient.data.l[0] == DIC_START_ER) + { + set_xjutil_id (event.xclient.data.l[1], event.xclient.data.l[2], 1); + } + else if (event.xclient.data.l[0] == DIC_FONTSET_ER) + { + reset_xjutil_fs_id (event.xclient.data.l[1], event.xclient.data.l[2]); + } + else if (event.xclient.data.l[0] == DIC_END) + { + end_xjutil_work (event.xclient.data.l[1]); + } +#endif /* USING_XJUTIL */ + if (event.xclient.data.l[0] == XWNMO_KILL) + { + kill_xim (event.xclient.data.l[1], event.xclient.data.l[2], event.xclient.data.l[3]); + } +#ifdef XJPLIB + else + { + XJp_event_dispatch (&event); + } +#endif + break; +#ifndef X11R5 + case SelectionRequest: +#ifdef BC_X11R5 + if (IS_NOT_FROM_XIMR5 (event)) + ximr5_client = 0; +#endif /* BC_X11R5 */ + XimConvertTarget (dpy, (XSelectionRequestEvent *) & event); + break; +#endif /* !X11R5 */ + default: + break; + } + for (i = 0; i < ret;) + { + n_bytes = get_cswidth_by_char (in = buff[i++]); + for (; n_bytes > 1 && i < ret; n_bytes--, i++) + { + in = (in << 8) + buff[i]; + } + in_put (in); + } +/* + } +*/ + } + while (XPending (dpy) > 0); +} + +static Bool +yes_no_proc (display, ev, arg) + Display *display; + XEvent *ev; + char *arg; +{ + register Window w = ev->xany.window; + + if (w == cur_p->yes_no->w || w == cur_p->yes_no->title->window || w == cur_p->yes_no->button[0]->window || w == cur_p->yes_no->button[1]->window) + { + return (True); + } + return (False); +} + +int +get_yes_no_event () +{ + int buff[16]; + XEvent event; + + while (1) + { + XFlush (dpy); + XIfEvent (dpy, &event, yes_no_proc, 0); + switch (event.type) + { + case KeyPress: + if (key_input (buff, &event) > 0) + return (buff[0]); + break; + case Expose: + xw_expose (&event); + return (0); + case ButtonRelease: + button.x = event.xbutton.x_root; + button.y = event.xbutton.y_root; + if (xw_buttonpress (&event) == True) + { + return (0xd); + } + break; + case EnterNotify: + xw_enterleave (&event, 1); + break; + case LeaveNotify: + xw_enterleave (&event, 0); + break; + case MapNotify: + check_map (event.xmap.window); + return (0); + default: + break; + } + } +}