1 /* # skkinput (Simple Kana-Kanji Input)
2  * MyDispatch.c --- Dispatch X Event
3  * This file is part of skkinput.
4  * Copyright (C) 1997
5  * Takashi SAKAMOTO (sakamoto@yajima.kuis.kyoto-u.ac.jp)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with skkinput; see the file COPYING.  If not, write to
19  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/types.h>
24 #include <X11/Xlib.h>
25 #include <X11/IntrinsicP.h>
26 #include <X11/StringDefs.h>
27 
28 #include "MyDispatch.h"
29 #include "MyError.h"
30 
31 #define MAX_EVENTTYPES		(10)
32 
33 struct my_eventtable {
34   Window dest_window ;
35   Window src_window ;
36   long event_mask ;
37   int number_of_eventtypes ;
38   int event_type[ MAX_EVENTTYPES ] ;
39   struct my_eventtable *next ;
40 } ;
41 
42 static struct my_eventtable *my_eventtable_listtop = NULL ;
43 
44 /*
45  *
46  */
find_whether_myeventhandler_exists(Window win)47 static struct my_eventtable *find_whether_myeventhandler_exists
48 ( Window win )
49 {
50   struct my_eventtable *node ;
51 
52   /* ���ꤵ�줿������ɥ����Ф��ơ����˥��٥�ȥϥ�ɥ��¸�ߤ���Τ��� */
53   for( node = my_eventtable_listtop ; node != NULL ; node = node->next ){
54     if( node->src_window == win ){
55       return node ;
56     }
57   }
58   /* ���⸫�դ���ʤ��ä���硣*/
59   return NULL ;
60 }
61 
alloc_myeventhandler(void)62 static struct my_eventtable *alloc_myeventhandler( void )
63 {
64   struct my_eventtable *node ;
65 
66   /* �������ݤ���ġ�*/
67   if( ( node = malloc( sizeof( struct my_eventtable ) ) ) == NULL ){
68     /* ��������Ƥ��ޤä��顢�⤦�ɤ����褦��ʤ����齪λ���롣*/
69     fprintf( stderr, "Memory fault.\n" ) ;
70     exit( 1 ) ;
71   }
72   node->src_window = node->dest_window = None ;
73   node->event_mask = NoEventMask ;
74 
75   node->number_of_eventtypes = 0 ;
76 
77   node->next            = my_eventtable_listtop ;
78   my_eventtable_listtop = node ;
79   return node ;
80 }
81 
82 /*
83  * �����Υ��٥�Ƚ�����ɬ�פˤʤä����˸ƤФ��ؿ���
84  *------
85  * �оݤȤʤ륦����ɥ���å���٤����٥�Ȥμ��ࡢ���λ��Υޥ�����
86  */
add_myeventhandler(Display * disp,Window src_win,Window dest_win,int event_type,long event_mask)87 int add_myeventhandler
88 ( Display *disp, Window src_win, Window dest_win,
89   int event_type, long event_mask )
90 {
91 	struct my_eventtable *node ;
92 	int i ;
93 
94 	if( ( node = find_whether_myeventhandler_exists( src_win ) ) != NULL ){
95 		/* ���ˤ��Υ��٥�Ȥ�å���褦�˻ؼ�����Ƥ��뤫�⤷��ʤ����顢*
96 		 * �����å�����  */
97 		for( i = 0 ; i < node->number_of_eventtypes ; i ++ ){
98 			/* ������Ͽ�ѤߤǤ��礦���� */
99 			if( node->event_type[ i ] == event_type )
100 				return True ;
101 		}
102 		/* ���٥�Ȥ���Ͽ���ơ����Υ��٥�Ȥ�������褦�ؼ����롣*/
103 		node->event_type[ node->number_of_eventtypes ++ ] = event_type ;
104 		node->event_mask |= event_mask ;
105 		XSelectInput( disp, src_win, node->event_mask ) ;
106 		return True ;
107 	}
108 	node = alloc_myeventhandler() ;
109 	node->src_window           = src_win ;
110 	node->dest_window          = dest_win ;
111 	node->event_mask           = event_mask ;
112 	node->event_type[ 0 ]      = event_type ;
113 	node->number_of_eventtypes = 1 ;
114 	XSelectInput( disp, src_win, event_mask ) ;
115 	return True ;
116 }
117 
118 /*
119  * �����Υ��٥�Ƚ�������ߤ�����˸ƤӽФ��ؿ���
120  */
remove_allmyeventhandler(Display * disp,Window src_win)121 int remove_allmyeventhandler
122 ( Display *disp, Window src_win )
123 {
124 	struct my_eventtable *node, *pNode ;
125 	/* ���⤽����Ȥ�̵���Τ���ʤ����ȵ��äƤߤ롣*/
126 	if( ( node = my_eventtable_listtop ) == NULL )
127 		return False ;
128 
129 	pNode = NULL ;
130 	while( node != NULL ){
131 		/* �õ�٤� event �����դ��ä����ġ�*/
132 		if( node->src_window == src_win ){
133 			if( pNode == NULL ){
134 				/* �õ�٤���Τ��ꥹ�Ȥ���Ƭ���ä���硣*/
135 				my_eventtable_listtop = node->next ;
136 				/* ��Ϥ䥤�٥�Ȥ�������ʤ��褦�ˤ��롣*/
137 				XSafeSelectInput( disp, src_win, NoEventMask ) ;
138 				/* ����β�����*/
139 				free( node ) ;
140 				return True ;
141 			} else {
142 				/* �ꥹ�Ȥ�������ä���硣*/
143 				pNode->next = node->next ;
144 				/* ��Ϥ䥤�٥�Ȥ�������ʤ��褦�ˤ��롣*/
145 				XSafeSelectInput( disp, src_win, NoEventMask ) ;
146 				/* ����β�����*/
147 				free( node ) ;
148 				return True ;
149 			}
150 		}
151 		pNode = node ;
152 		node  = node->next ;
153 	}
154 	/* ����ʥ�����ɥ����Τ�ޤ���*/
155 	return False ;
156 }
157 
158 
159 /*
160  * �����Υ��٥�Ƚ�������ߤ�����˸ƤӽФ��ؿ���
161  */
remove_myeventhandler(Display * disp,Window src_win,int event_type,unsigned long event_mask)162 int remove_myeventhandler
163 ( Display *disp, Window src_win, int event_type,
164   unsigned long event_mask )
165 {
166 	struct my_eventtable *node, *pNode ;
167 	int i ;
168 
169 	/* ���⤽����Ȥ�̵���Τ���ʤ����ȵ��äƤߤ롣*/
170 	if( ( node = my_eventtable_listtop ) == NULL )
171 		return False ;
172 
173 	pNode = NULL ;
174 	while( node != NULL ){
175 		/* �õ�٤� event �����դ��ä����ġ�*/
176 		if( node->src_window == src_win ){
177 			node->event_mask &= ~event_mask ;
178 			for( i = 0 ; i < MAX_EVENTTYPES ; i ++ ){
179 				if( node->event_type[ i ] == event_type )
180 					node->event_type[ i ] = NO_EVENT_HANDLE ;
181 			}
182 			XSafeSelectInput( disp, src_win, node->event_mask ) ;
183 			if( node->event_mask == NoEventMask ){
184 				if( pNode == NULL ){
185 					/* �õ�٤���Τ��ꥹ�Ȥ���Ƭ���ä���硣*/
186 					my_eventtable_listtop = node->next ;
187 				} else {
188 					/* �ꥹ�Ȥ�������ä���硣*/
189 					pNode->next = node->next ;
190 				}
191 			}
192 			return True ;
193 		}
194 		pNode = node ;
195 		node  = node->next ;
196 	}
197 	/* ����ʥ�����ɥ����Τ�ޤ���*/
198 	return False ;
199 }
200 
201 /*
202  * ���٥�Ȥ�Ŭ�ڤʥ��������åȤؤ������Ϥ���ؿ���
203  */
mydispatch_event(Display * disp,XEvent * xevent)204 int mydispatch_event( Display *disp, XEvent *xevent )
205 {
206 	struct my_eventtable *node ;
207 	int i ;
208 
209 	/* �ޤ��ܤ��Ƥߤ롣*/
210 	node = find_whether_myeventhandler_exists( xevent->xany.window ) ;
211 	/* ���դ��ä����ˤϡġ�*/
212 	if( node != NULL ){
213 		/* ���Υ�����ɥ����Ф��ơ��ɤΥ��٥�Ȥ��뤫�λ��꤬����Ȧ�� *
214 		 * �Τǡ����������å����롣*/
215 		for( i = 0 ; i < node->number_of_eventtypes ; i ++ ){
216 			/* ���դ���ޤ������� */
217 			if( node->event_type[ i ] == xevent->type ){
218 				if( xevent->type == KeyPress || xevent->type == KeyRelease ){
219 					xevent->xkey.window    = node->dest_window ;
220 					xevent->xkey.subwindow = None ;
221 				} else {
222 					xevent->xany.window = node->dest_window ;
223 				}
224 				XSafeSendEvent
225 					( disp, xevent->xany.window, False, NoEventMask, xevent ) ;
226 				break ;
227 			}
228 		}
229 	} else {
230 		/* ���٥�Ȥ�ȯ�Ԥ��롣*/
231 		XtSafeDispatchEvent( xevent ) ;
232 	}
233 	return True ;
234 }
235 
236