1 /* # skkinput (Simple Kana-Kanji Input)
2  * skkkip.h --- Kinput Protocol
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/Xatom.h>
26 #include <X11/IntrinsicP.h>
27 #include <X11/StringDefs.h>
28 #include <X11/Shell.h>
29 
30 #include "skkmain.h"
31 #include "skkproto.h"
32 #include "SkkInput.h"
33 
34 /*
35  * �ץ�ȥ����������
36  */
37 static void KIP_SendEndOfConversion( SKKInputRootNode *rNode ) ;
38 static int KIP_RemoveSkkInputCallback( SKKInputRootNode *rNode ) ;
39 static SKKInputRootNode *KIP_GetPopup
40 ( Widget parent, Window request_window ) ;
41 static void KIP_messageConversionRequest_Handler
42 ( Widget w, XEvent *xevent, String *params, Cardinal *num_params ) ;
43 static void KIP_messageConversionEndRequest_Handler
44 ( Widget w, XEvent *xevent, String *params, Cardinal *num_params ) ;
45 
46 static SKKInputRootNode *KIP_FindFreeNode( Window req_window ) ;
47 static SKKInputRootNode *KIP_FindSkkInputNode( Window req_window ) ;
48 
49 extern int convJWStoCT( char *str, unsigned char *xstr, int jisroman ) ;
50 extern int setSkkInputConversionCallback( SKKInputRootNode *rNode ) ;
51 extern int removeSkkInputConversionCallback( SKKInputRootNode *rNode ) ;
52 extern int skkinput_setSkkInputValues
53 ( Widget gw, int flag, int cmode, int eggnl ) ;
54 
55 /*
56  * �����Х��ѿ���
57  */
58 static Atom KIP_convAtom ;	/* ���ܸ����Ϥ��Ѥ��롣*/
59 static Atom KIP_propAtom ;
60 static Atom KIP_ctextAtom ;
61 static Atom KIP_reqAtom ;
62 static Atom KIP_notifyAtom ;
63 static Atom KIP_endAtom ;
64 static Atom KIP_endReqAtom ;
65 
66 extern Atom wm_delete_window ;
67 
68 /* Kinput Protocol �Τ���� Actoin Table */
69 static XtActionsRec KIP_Actions[] = {
70   { "beginConversion",	KIP_messageConversionRequest_Handler },
71   { "endConversion",	KIP_messageConversionEndRequest_Handler },
72 } ;
73 
74 /* Kinput Protocol �Τ���� Translation Table */
75 static char KIP_Translations[] =
76 "<Message>CONVERSION_REQUEST:     beginConversion()\n\
77  <Message>CONVERSION_END_REQUEST: endConversion()\n" ;
78 
79 /*
80  * Kinput Protocol �� Message �������Ѥ���� Atom ���������ؿ���
81  */
KIP_GetAtoms(Widget gw)82 static void KIP_GetAtoms( Widget gw )
83 {
84   Display *display = XtDisplay( gw ) ;
85 
86 #define MakeAtom(s)	XInternAtom(display,s,False)
87 
88   /* Kinput Protocol ��ɬ�פȤ���� Atom ��������롣*/
89   KIP_convAtom   = MakeAtom( "JAPANESE_CONVERSION" ) ;
90   KIP_propAtom   = MakeAtom( "CONVERSION_STRING" ) ;
91   KIP_ctextAtom  = MakeAtom( "COMPOUND_TEXT" ) ;
92   KIP_reqAtom    = MakeAtom( "CONVERSION_REQUEST" ) ;
93   KIP_notifyAtom = MakeAtom( "CONVERSION_NOTIFY" ) ;
94   KIP_endAtom    = MakeAtom( "CONVERSION_END" ) ;
95   KIP_endReqAtom = MakeAtom( "CONVERSIOIN_END_REQUEST" ) ;
96 
97 #undef MakeAtom
98   return ;
99 }
100 
101 /*
102  * Kinput Protocol �����Ѳ�ǽ�ˤ��뤿��ν�����ؿ���
103  */
KIP_initialize(XtAppContext app_context,Widget gw)104 int KIP_initialize( XtAppContext app_context, Widget gw )
105 {
106   /* �ޤ��Ѵ��Τ���� atom ���äơġ�*/
107   KIP_GetAtoms( gw ) ;
108   /* ���� CONVERSION_REQUEST �� OWNER �ˤʤ롣*/
109   XSetSelectionOwner( XtDisplay( gw ), KIP_convAtom, XtWindow( gw ),
110 		      CurrentTime ) ;
111   /* ̵���� Owner �ˤʤ줿���ɤ�����Ƚ�ꤹ�롣*/
112   if( XGetSelectionOwner
113       ( XtDisplay( gw ), KIP_convAtom ) != XtWindow( gw ) ){
114     /* Owner �ˤʤ�ʤ��ä����ˤϡ��Ѵ��׵������Ȥ뤳�ȤϤ��ä� *
115      * �Ǥ��ʤ��Τǡ����褦�ʤ餹�롩 */
116     fprintf( stderr, "Can't own selection.\n" ) ;
117     return False ;
118   }
119   /* �������륤�٥�ȤȤ��ν����ؿ����롣*/
120   XtAppAddActions( app_context, KIP_Actions, XtNumber( KIP_Actions ) ) ;
121   XtOverrideTranslations
122     ( gw,  XtParseTranslationTable( KIP_Translations ) ) ;
123   return True ;
124 }
125 
126 /*
127  * Kinput Protocol ����Ѵ��׵�Ԥؤ�ʸ����������Ԥ�����δؿ���
128  *-----
129  * ʸ���������� SkkInputWidget ����ƽФ���뤿�ᡢcallback�η��ˤʤ�
130  * �Ƥ��롣
131  */
KIP_SendMessageToRequestorCallback(Widget w,caddr_t client,caddr_t caller)132 static int KIP_SendMessageToRequestorCallback
133 ( Widget w, caddr_t client, caddr_t caller )
134 {
135   SKKInputRootNode *rNode = ( SKKInputRootNode * )client ;
136   char *text = ( char * )caller ;
137 
138   Atom	proptype ;
139   int	propsize ;
140   int	propformat ;
141   caddr_t propvalue ;
142   XClientMessageEvent	*ev = &( ( rNode->xevent ).xclient ) ;
143 
144   char *p ;
145 
146   /*
147    * �ǡ������饤����Ȥ��ꥯ�����Ȥ��������Ѵ�����
148    */
149   /*if (ev->data.l[2] == ctextAtom){ */
150   /* compound text ���Ѵ����� */
151   /* ������ comound text �Ǥ� \r ������ʤ��Τ� ����� \n ��
152    * �Ѵ����Ƥ���
153    */
154   for( p = text ; *p != '\0' ; p ++ )
155     if( *p == '\r' )
156       *p = '\n';
157   proptype = KIP_ctextAtom ;
158   propformat = 8 ;
159   propsize = convJWStoCT( text, NULL, 0 ) ;
160   if ( propsize <= 0 ){
161 #ifdef DEBUG_LV1
162     fprintf( stderr, "Propsize <= 0 then return.\n" ) ;
163 #endif
164     return 1 ;
165   }
166   propvalue = ( caddr_t )malloc( propsize * sizeof( unsigned char ) * 4 ) ;
167   (void)convJWStoCT( text, (unsigned char *)propvalue, 0 ) ;
168 #ifdef DEBUG
169   fprintf( stderr, "XChangeProperty : \"%s\" ... %d\n", propvalue, propsize ) ;
170 #endif
171 
172   /* Property �˷�̤��åȤ��� */
173   XChangeProperty( XtDisplay( rNode->skkinp ), ( Window )ev->data.l[1],
174 		   ( Atom )ev->data.l[3], proptype, propformat,
175 		   PropModeAppend, propvalue, propsize ) ;
176   free( propvalue ) ;
177   return 0 ;
178 }
179 
180 /*
181  * Kinput Protocol ��Ǥ��Ѵ��׵�Ԥؤ��Ѵ���λ����ã����ؿ���
182  *-----
183  * ����� SkkInputWidget ���Ѵ��׵�Ԥ��Τ뤳�Ȥ��Ǥ��ʤ�����Ǥ��롣
184  * XSetArg ���Ϥ��Ƥ������Ȥ��Ǥ�����ɤ��Τ����ġ���������ȡ�Resource ��
185  * ����Ǥ���Ȥ�����̵�����ڤ������ȤˤʤäƤ��ޤäơ�(;_;)
186  * ���줫�顢�ᥤ��¦�Ǥⲿ��ȤĤʤ��äƤ���Τ����ΤäƤ��ʤ���̵���¤�
187  * SkkInputWidget ���äƤ��ޤ����Ȥˤʤ롣�����顢main �� widget ��ξ��
188  * ���ΤäƤ��ʤ���Фʤ�ʤ� req_window �� main �˴���������callback ��
189  * �������� main �����Τ��뤳�ȤˤʤäƤ���ΤǤ��롣
190  */
KIP_EndMessageToRequestorCallback(Widget gw,caddr_t client,caddr_t caller)191 static int KIP_EndMessageToRequestorCallback
192 ( Widget gw, caddr_t client, caddr_t caller )
193 {
194   SKKInputRootNode *rNode = ( SKKInputRootNode * )client ;
195   Arg arg[ 3 ] ;
196   Cardinal i ;
197 
198   /* ���Ѥ���ʤ��ʤä����Ȥ��Τ餻�롣*/
199   rNode->probe        = False ;
200   rNode->reserve      = False ;
201 
202   i = 0 ;
203   XtSetArg( arg[ i ], XtNchatAdapter,    &rNode->chat_adapter ) ;
204   i ++ ;
205   XtSetArg( arg[ i ], XtNeggLikeNewline, &rNode->eggnl ) ;
206   i ++ ;
207   XtGetValues( rNode->skkinp, arg, i ) ;
208 
209   /* callback ���˴����롣*/
210   KIP_RemoveSkkInputCallback( rNode ) ;
211   removeSkkInputConversionCallback( rNode ) ;
212   XFlush( XtDisplay( rNode->popup ) ) ;
213   /* Pop Down ���롣*/
214   XtPopdown( rNode->popup ) ;
215 
216   /* ��λ���Τ����롣���������Ƥ� DestroyNotify �ˤ�ä��˲�����Ƥ� *
217    * ����ˤ����ƤϤ��θ¤�ǤϤʤ������ξ��ˤ� req_window ==    *
218    * None �ȤʤäƤ��롣*/
219   if( rNode->req_window != None ){
220     KIP_SendEndOfConversion( rNode ) ;
221 #if 0
222     /* �Ѵ����饤����Ȥ��鲿������Ƥ�̵�뤹�롣*/
223     XSelectInput
224       ( XtDisplay( rNode->popup ), rNode->req_window, NoEventMask ) ;
225     /* �ݥ�����������᤹��*/
226     XSetInputFocus
227       ( XtDisplay( rNode->popup ), rNode->req_window,
228 	RevertToParent, CurrentTime ) ;
229 #endif
230   }
231   return 0 ;
232 }
233 
234 /*
235  * �����������Ȥ������٥�Ȥ��̤���ؤ�ž������Τ����Ѥ����ؿ���
236  */
KIP_KeyEventToRequestorCallback(Widget gw,caddr_t client,caddr_t caller)237 static void KIP_KeyEventToRequestorCallback
238 ( Widget gw, caddr_t client, caddr_t caller )
239 {
240   SKKInputRootNode *rNode = ( SKKInputRootNode *)client ;
241   XEvent *xevent = ( XEvent *)caller ;
242 
243   /* �ե�����������Ƥ�����ؤȥ�å����������롣*/
244   xevent->xkey.window    = rNode->focus_window ;
245   xevent->xkey.subwindow = None ;
246 
247   XSendEvent
248     ( XtDisplay( gw ), xevent->xkey.window, False, NoEventMask, xevent ) ;
249   return ;
250 }
251 
252 /*
253  * Kinput Protocol ��Ǥ��Ѵ���Ȥ�Ԥ��Ȥ������Ȥ� Widget ���Τ餻��
254  * ����� Callback �� Kinput Protocol �����ꤹ��ؿ���
255  *------
256  * �Τ餻��Ȥ������İ�äƤ�����ʬ��¿ʬ callback �����ʤΤ������顢
257  * �����������������סġ� ��������C-h �����줿���Ȥ������ȡ�¾�ˤ�
258  * �פ�Ȼפ���
259  */
KIP_SetSkkInputCallback(SKKInputRootNode * rNode)260 static int KIP_SetSkkInputCallback( SKKInputRootNode *rNode )
261 {
262   /* ʸ������Ѵ��׵�Ԥ�����Ĥ������callback����Ͽ��*/
263   XtAddCallback( rNode->skkinp, XtNfixNotify,
264 		 (XtCallbackProc)KIP_SendMessageToRequestorCallback,
265 		 (XtPointer)rNode) ;
266   /* �Ѵ��׵�Ԥ��Ѵ��ν�λ�����Τ������callback����Ͽ��*/
267   XtAddCallback( rNode->skkinp, XtNendNotify,
268 		 (XtCallbackProc)KIP_EndMessageToRequestorCallback,
269 		 (XtPointer)rNode) ;
270   /* �Ѵ��׵�Ԥإ��������᤹�����callback����Ͽ��*/
271   XtAddCallback( rNode->skkinp, XtNkeybackNotify,
272 		 (XtCallbackProc)KIP_KeyEventToRequestorCallback,
273 		 (XtPointer)rNode) ;
274   return 0 ;
275 }
276 
KIP_RemoveSkkInputCallback(SKKInputRootNode * rNode)277 static int KIP_RemoveSkkInputCallback( SKKInputRootNode *rNode )
278 {
279   /* ʸ������Ѵ��׵�Ԥ�����Ĥ������callback����Ͽ��*/
280   XtRemoveAllCallbacks( rNode->skkinp, XtNfixNotify ) ;
281   /* �Ѵ��׵�Ԥ��Ѵ��ν�λ�����Τ������callback����Ͽ��*/
282   XtRemoveAllCallbacks( rNode->skkinp, XtNendNotify ) ;
283   /* �Ѵ��׵�Ԥإ��������᤹�����callback����Ͽ��*/
284   XtRemoveAllCallbacks( rNode->skkinp, XtNkeybackNotify ) ;
285   return 0 ;
286 }
287 
288 /*
289  * Kinput Protocl ����Ѵ��׵��Ф������饤����Ȥ��Ѵ��׵�μ�������
290  * �Τ���ؿ���
291  */
KIP_SendConvNotify(XEvent * xevent,Atom property,Window skkinputwin)292 static void KIP_SendConvNotify
293 ( XEvent *xevent, Atom property, Window skkinputwin )
294 {
295   XClientMessageEvent *ev = &( xevent->xclient ) ;
296   XEvent event ;
297 
298   event.xclient.type         = ClientMessage ;
299   event.xclient.window       = ev->data.l[ 1 ] ;
300   event.xclient.message_type = KIP_notifyAtom ;
301   event.xclient.format       = 32 ;
302   event.xclient.data.l[0]    = KIP_convAtom ;
303   event.xclient.data.l[1]    = ev->data.l[ 2 ] ;
304   event.xclient.data.l[2]    = property ;
305   event.xclient.data.l[3]    = skkinputwin ;
306 
307   XSendEvent( ev->display, ev->data.l[ 1 ], False, NoEventMask, &event ) ;
308   return ;
309 }
310 
311 /*
312  * Kinput Protocol ���Ѵ���λ�׵�˽��äƥ��饤����ȤȤ���³��λ��
313  * ��ؿ���
314  */
KIP_SendEndOfConversion(SKKInputRootNode * rNode)315 static void KIP_SendEndOfConversion( SKKInputRootNode *rNode )
316 {
317   XEvent event ;
318 
319   event.xclient.type         = ClientMessage ;
320   event.xclient.window       = rNode->req_window ;
321   event.xclient.message_type = KIP_endAtom ;
322   event.xclient.format       = 32 ;
323   event.xclient.data.l[0]    = KIP_convAtom ;
324   event.xclient.data.l[1]    = XtWindow( rNode->skkinp ) ;
325 
326   XSendEvent( XtDisplay( rNode->skkinp ), rNode->req_window,
327 	      False, NoEventMask, &event ) ;
328   return ;
329 }
330 
331 /*
332  * Kinput Protocol �Ȥ�����������å��������������褿�Τ��ɤ�����Ƚ
333  * �ꤹ��ؿ���
334  */
KIP_CorrectClientMessageP(Widget w,XEvent * xevent)335 static int KIP_CorrectClientMessageP( Widget w, XEvent *xevent )
336 {
337   XClientMessageEvent *ev = &xevent->xclient ;
338 
339 #ifdef DEBUG
340   fprintf( stderr, "Get Client Message. I check whether it is correct.\n" ) ;
341   fflush( stderr ) ;
342 #endif
343 
344   /* ��������å������������Ƥ����Τ��ɤ�����Ƚ�ꤹ�롣*/
345   if( ev->window != XtWindow( w ) ||
346       ev->format != 32 ||
347       ev->data.l[ 0 ] != KIP_convAtom ){
348     /* �����ʥ�å������������Ƥ����ߤ����ʤΤǡ�̵�뤷�ޤ�����*/
349     return  False ;
350   }
351   return True ;
352 }
353 
354 /*
355  * Kinput Protocol �ˤ���Ѵ��׵����������ν����ؿ���
356  *-----
357  * SkkInputWidget ���������Conversion Methode �� Kinput Protocol ����
358  * ��롣
359  */
KIP_messageConversionRequest_Handler(Widget w,XEvent * xevent,String * params,Cardinal * num_params)360 static void KIP_messageConversionRequest_Handler
361 ( Widget w, XEvent *xevent, String *params, Cardinal *num_params )
362 {
363   SKKInputRootNode *rNode ;
364   XClientMessageEvent *ev = &( xevent->xclient ) ;
365 
366 #ifdef DEBUG
367   fprintf( stderr, "KIP:begin-conversion.\n" ) ;
368   fflush( stderr ) ;
369 #endif
370 
371   /* �����ʥ�å����������Ť�̵�뤷�ƺ����夲�롣*/
372   if( !KIP_CorrectClientMessageP( w, xevent ) )
373     return ;
374 
375   /* �����Ƥ��� Window ��̵���ä��齪λ��������������ˤ��롣*/
376   if( ( rNode = KIP_GetPopup( w, ev->data.l[ 1 ] ) ) == NULL ){
377     /* ������ϵ����Ƥ����硢�⤷���Ϥ���ʾ�����������Ȥ����� *
378      * �ʤ������������롣*/
379     return ;
380   }
381   /* ���λ����׵��Ĥ��Ƥ����Ĥ���ɬ�����Ϻ����ʬ����ʤ����ɡ�*/
382   rNode->xevent = *xevent ;
383   rNode->xevent.xclient.data.l[ 2 ] = KIP_ctextAtom ;
384 
385   if( ev->data.l[3] == None )
386     rNode->xevent.xclient.data.l[ 3 ] = KIP_propAtom ;
387 
388   /* ̵�����׵᤬�̤ä����Ȥ� client �����Τ��롣*/
389   KIP_SendConvNotify
390     ( &( rNode->xevent ), rNode->xevent.xclient.data.l[3],
391       XtWindow( rNode->skkinp ) ) ;
392   return ;
393 }
394 
395 /*
396  * �Ѵ���λ��å���������������ν�����Ԥ��ؿ���
397  */
KIP_messageConversionEndRequest_Handler(Widget w,XEvent * xevent,String * params,Cardinal * num_params)398 static void KIP_messageConversionEndRequest_Handler
399 ( Widget w, XEvent *xevent, String *params, Cardinal *num_params )
400 {
401   XClientMessageEvent *cev = &( xevent->xclient ) ;
402   SKKInputRootNode *rNode ;
403 
404 #ifdef DEBUG
405   fprintf( stderr, "KIP : end-conversion.\n" ) ;
406   fflush( stderr ) ;
407 #endif
408 
409   /* �����ʥ�å����������Ť�̵�뤷�ƺ����夲�롣*/
410   if( !KIP_CorrectClientMessageP( w, xevent ) )
411     return ;
412 
413   if( ( rNode = KIP_FindSkkInputNode( cev->data.l[ 1 ] ) ) == NULL ){
414     /* �Τ�ʤ��ͤ����Τ���ä��㤤���ʤ��Τǡ����Ť�̵�뤷�ƺ��� *
415      * �夲�ޤ�����*/
416     return ;
417   }
418   /* Widget ���˴����롣*/
419   XtDestroyWidget( rNode->skkinp ) ;
420   return ;
421 }
422 
423 /*
424  * client ������׵�˽��äơ��Ѵ��Ѥ� Window �������ؿ���
425  */
KIP_GetPopup(Widget parent,Window request_window)426 static SKKInputRootNode *KIP_GetPopup
427 ( Widget parent, Window request_window )
428 {
429   SKKInputRootNode *rNode ;
430   Arg arg[ 10 ] ;
431   int i, is_popup_before ;
432 
433   /* ���������ݤǤ���Τ��� �ޤ��ϡ����ˤ����׵����­����Ƥ���� *
434    * ����Ĵ�٤롣*/
435   if( ( rNode = KIP_FindFreeNode( request_window ) ) == NULL ){
436     return NULL ;
437   }
438   /* �����˰��ٵ����������ȤΤ�����ʤΡ� */
439   is_popup_before =
440     ( rNode->req_window == request_window )? True : False ;
441   /* �ɤ��뤫���׵᤬��Ƥ����Τ��������Ƥ�����*/
442   rNode->req_window   = request_window ;
443   /* �ɤ���ʬ����ʤ����ɡ�requestor ��Ʊ���ˤ��Ƥ�����*/
444   rNode->focus_window = request_window ;
445 
446   rNode->probe        = True ;
447   rNode->reserve      = True ;
448 
449   /* �Ѵ� Widget ��������롣*/
450   i = 0;
451   XtSetArg( arg[ i ], XtNinput, True ) ;
452   i ++ ;
453   XtSetArg( arg[ i ], XtNmappedWhenManaged, True ) ;
454   i ++ ;
455   XtSetArg( arg[ i ], XtNinitPosition,  ( is_popup_before )? False : True ) ;
456   i ++ ;
457   rNode->skkinp = XtCreateManagedWidget
458     ( "Skkinput-client", skkinputWidgetClass, rNode->popup, arg, i ) ;
459   /* values ������ġ�*/
460   skkinput_setSkkInputValues
461     ( rNode->skkinp, is_popup_before, rNode->chat_adapter, rNode->eggnl ) ;
462 
463   /* SkkInputWidget �Υ�����Хå������ꤹ�롣*/
464   KIP_SetSkkInputCallback( rNode ) ;
465   setSkkInputConversionCallback( rNode ) ;
466 
467   XFlush( XtDisplay( rNode->popup ) ) ;
468   /* Window �� Pop Up ���롣Exclusive �ˤ���ȡ�¾�� Popup ��������  *
469    * ������˥������٥�Ȥ��Ȥ�ʤ��ʤäƤ��ޤ��Τǡ�Nonexclusive �� *
470    * ���뤳�ȡ�*/
471   XtPopup( rNode->popup, XtGrabNone ) ;
472   XSelectInput
473     ( XtDisplay( rNode->popup ), rNode->req_window, StructureNotifyMask ) ;
474 
475   /* Window Manager ����Υ�å�����������Ȥ�褦�����ꤹ�롣       *
476    * ���� XSetWMProtocols �����ꤹ��ˤϡ�Popup �θ�Ǥʤ�������ܤ� *
477    * ���롣����� PopUp ���¹Ԥ����ޤǡ��ºݤ� Window ��¸�ߤ��ʤ� *
478    * ��Ǥ��롣*/
479   (void) XSetWMProtocols( XtDisplay( rNode->popup ),
480 			  XtWindow( rNode->popup ), &wm_delete_window, 1 ) ;
481   XtOverrideTranslations
482     ( rNode->popup, XtParseTranslationTable( "<Message>WM_PROTOCOLS: \
483 stopConversion()\n" ) ) ;
484 
485   XtSetKeyboardFocus( rNode->popup, rNode->skkinp ) ;
486   /* XtRealizeWidget( rNode->toplevel ) ; */
487   return rNode ;
488 }
489 
490 /*
491  * �����Ƥ��� skkinput ���դ������Ƥ����ˡ��Ѵ��׵������ƤƤ��ޤ��ؿ���
492  */
KIP_FindFreeNode(Window req_window)493 static SKKInputRootNode *KIP_FindFreeNode( Window req_window )
494 {
495   int i ;
496   SKKInputRootNode *rNode = NULL ;
497 
498   /* �롼�׳��ϡ�*/
499   for( i = 0 ; i < MAX_SKKINPUTS ; i ++ ){
500     /* �ޤ�������Τ�Τ�̵����Ĵ�٤롣*/
501     if( skkinputs[ i ].req_window == req_window &&
502 	skkinputs[ i ].probe == True ){
503       return NULL ;
504     }
505     /* �����Ƥ���Ρ��ɤǡ������ƤӽФ��줿��Τ�����Ф����餬ͥ�衣*/
506     if( skkinputs[ i ].req_window == req_window &&
507 	skkinputs[ i ].probe == False &&
508 	skkinputs[ i ].reserve == False ){
509       rNode = &( skkinputs[ i ] ) ;
510       break ;
511     }
512     /* �����Ƥ���Ρ��ɤ⸫�դ��Ƥ���������������˶����Ƥ����ۡ�*/
513     if(	skkinputs[ i ].req_window == None &&
514 	skkinputs[ i ].probe == False &&
515 	skkinputs[ i ].reserve == False ){
516       rNode = &( skkinputs[ i ] ) ;
517       continue ;
518     }
519     /* ��������ʤ��ơİ��դ���������ʤ��äƤΤϡ� */
520     if( rNode == NULL &&
521 	skkinputs[ i ].probe == False &&
522 	skkinputs[ i ].reserve == False ){
523       rNode = &( skkinputs[ i ] ) ;
524       continue ;
525     }
526   }
527   return rNode ;
528 }
529 
530 /*
531  * �׵ᤵ�줿 Window ���Ѵ����饤����ȤǤ����뤬¸�ߤ��뤫�ɤ���Ĵ�٤�ؿ���
532  */
KIP_FindSkkInputNode(Window req_window)533 static SKKInputRootNode *KIP_FindSkkInputNode( Window req_window )
534 {
535   int i ;
536   for( i = 0 ; i < MAX_SKKINPUTS ; i ++ ){
537     /* �����뤬�����Ƥ��ʤ���С�̵�뤹�뤷���ʤ���*/
538     if( !skkinputs[ i ].probe )
539       continue ;
540     /* �����Ƥ����顢ï���׵�˽��äƤ���Τ���Ĵ�٤롣*/
541     if( skkinputs[ i ].req_window == req_window )
542       return &( skkinputs[ i ] ) ;
543   }
544   /* ���ꤵ�줿����׵�˽��äƤ���ԤϤ��ʤ��ä���硣*/
545   return NULL ;
546 }
547 
548