1 /* # skkinput (Simple Kana-Kanji Input)
2  * main.c
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 <setjmp.h>
24 #include <signal.h>
25 #include <locale.h>
26 #include <sys/types.h>
27 #include <X11/Xlib.h>
28 #include <X11/Xatom.h>
29 #include <X11/Intrinsic.h>
30 #include <X11/StringDefs.h>
31 #include <X11/Shell.h>
32 #include <sys/socket.h>
33 
34 #define main_c
35 #include "commondef.h"
36 #include "buffers.h"
37 #if defined(SUPPORT_KINPUT)
38 #include "Kinput.h"
39 #endif
40 #if defined(SUPPORT_XIMP)
41 #include "Ximp.h"
42 #endif
43 #if defined(SUPPORT_XIM)
44 #include "XIMServer.h"
45 #endif
46 #include "SeparateWin.h"
47 #include "OverWin.h"
48 #include "skkkey.h"
49 #include "config.h"
50 #include "version.h"
51 #include "MyError.h"
52 #include "HistMgr.h"
53 #include "FontMgr.h"
54 
55 /*
56  * main �������Ѥ����ѿ��η������
57  */
58 struct skkinputOptionDef {
59   char *chara ;
60   int  function_no ;
61   int  need_argument ;
62 } ;
63 
64 /*
65  * �ᥤ��������Ѥ�����������
66  */
67 enum {
68   OPTION_HOST = 0, OPTION_PORT, OPTION_USERDIC, OPTION_BAKDIC,
69   OPTION_SKKDIC, OPTION_SKKREC, OPTION_HELP, OPTION_VERSION,
70   OPTION_CONFIG, OPTION_XIM_OFF, OPTION_XIM_ON, OPTION_XIMP_OFF,
71   OPTION_XIMP_ON,OPTION_AUTOSAVE, OPTION_KINPUT_ON, OPTION_KINPUT_OFF,
72   OPTION_IPv4, OPTION_IPv6,
73 } ;
74 
75 
76 /*
77  * �ץ�ȥ����������
78  */
79 static int skkinput_checkOptions( int *argc, char *argv[], int flag ) ;
80 static int skkinput_usage( void ) ;
81 static void skkinput_Quit( void ) ;
82 static void skkinput_redraw_allskkinputs( void ) ;
83 static void skkinput_CheckEvent( Display *display, XEvent *xevent ) ;
84 static int skkinputIOErrorHandler( Display *display ) ;
85 
86 /*
87  * �Ҷ����������åȤ���ƤФ�륳����Хå��ؿ��Υץ�ȥ����������
88  */
89 static void setupInputWindow
90 ( Widget gw, caddr_t client, caddr_t caller ) ;
91 static void closeProtocolServer
92 ( Widget gw, caddr_t client, caddr_t caller ) ;
93 static void destroy_protocolServers( void ) ;
94 
95 /*
96  * ������֤ηв���˸ƤӽФ���뼭��Υ����֤�Ԥ��٤����ɤ�����Ƚ�ꤹ��ؿ���
97  */
98 static void skkinput_CheckAutoSaveJisyo( XtPointer closure, XtIntervalId *id ) ;
99 static Boolean skkinput_AutoSaveJisyo( XtPointer closure ) ;
100 
101 /*
102  * ¾���ͤΥ������ˤ���ؿ��ǡ�main.c ���黲�Ȥ���Ƥ����ΤΥץ�ȥ�
103  * ���������
104  */
105 /* skkconfig.c */
106 extern void initSkkinputDousaketteiVariables( void ) ;
107 extern int  skkinput_readConfigFile( char *config_file ) ;
108 extern int  skkinput_setSkkInputValues( Widget gw ) ;
109 /* skksvect.c */
110 extern void initVectorHashTable( void ) ;
111 /* skkldrec.c */
112 extern void initHenkanKakuteiHashTable( void ) ;
113 extern void clearHenkanKakuteiHash( void ) ;
114 /* skksoc.c */
115 extern int  skkinput_StartCommunication( char *server_name, char *service_name, int pf ) ;
116 extern int  skkinput_CloseCommunication( void ) ;
117 /* skkldic.c */
118 extern int  set_localjisyo
119 ( unsigned char *jisyo_path,  unsigned char *jisyobak_path,
120   unsigned char *record_path, unsigned char *master_localjisyo ) ;
121 extern int  close_localjisyo( void ) ;
122 extern void skkinput_updateLocalJisyo( void ) ;
123 extern void skkinput_autosaveLocalJisyo( void ) ;
124 extern void skkinput_readAutoSavedLocalJisyo( void ) ;
125 /* mydispatch.c */
126 extern int mydispatch_event( Display *disp, XEvent *xevent ) ;
127 
128 extern void initialize_myerrorhandler( void ) ;
129 extern int remove_allmyeventhandler( Display *disp, Window src_win ) ;
130 
131 /*
132  * ���Υ��������Ǥ������Ѥ���ʤ������Х��ѿ��������
133  */
134 /* X Tool Kit ������ ���ץꥱ���������ƥ����ȡ�*/
135 static XtAppContext app_context ;
136 
137 static Widget toplevel ;
138 #if defined(SUPPORT_KINPUT)
139 static Widget kinput_protocol ;
140 static Boolean support_kinput_protocol = True ;
141 #endif
142 #if defined(SUPPORT_XIM)
143 static Widget xim_protocol ;
144 static Boolean support_xim_protocol = True ;
145 #endif
146 #if defined(SUPPORT_XIMP)
147 static Widget ximp_protocol ;
148 static Boolean support_ximp_protocol = True ;
149 #endif
150 static jmp_buf noprotocol_env ;
151 
152 /* X Tool Kit �������ɬ�פȤ��Ƥ���� Option �����ꡣ*/
153 static XrmOptionDescRec options[] = {
154   { "-fontset",	"*fontSet",		XrmoptionSepArg,	NULL },
155   { "-mfontset","*minibufferFontSet",	XrmoptionSepArg,	NULL },
156   { "-rv",	"*reverseVideo",	XrmoptionNoArg,		"TRUE" },
157   { "+rv",	"*reverseVideo",	XrmoptionNoArg,		"FALSE" },
158   { "-fg",	"*foreground",		XrmoptionSepArg,	NULL },
159   { "-bg",	"*background",		XrmoptionSepArg,	NULL },
160   { "-bd",	"*borderColor",		XrmoptionSepArg,	NULL },
161   { "-width",	"*separate.width", 	XrmoptionSepArg,	NULL },
162   { "-height",	"*separate.height",	XrmoptionSepArg,	NULL },
163   { "-mwidth",	"*minibuffer_width", 	XrmoptionSepArg,	NULL },
164   { "-mfc",	"*changeMinibufferFont", XrmoptionNoArg,	"TRUE" },
165   { "+mfc",	"*changeMinibufferFont", XrmoptionNoArg,	"FALSE" },
166   { "-nc",      "*controlHaTugiDeYukou", XrmoptionNoArg,	"TRUE" },
167   { "+nc",      "*controlHaTugiDeYukou", XrmoptionNoArg,	"FALSE" },
168   { "-ns",      "*shiftHaTugiDeYukou",	XrmoptionNoArg,		"TRUE" },
169   { "+ns",      "*shiftHaTugiDeYukou",	XrmoptionNoArg,		"FALSE" },
170   { "-sc",	"*southCursor",		XrmoptionNoArg,		"TRUE" },
171   { "+sc",	"*southCursor",		XrmoptionNoArg,		"FALSE" },
172 } ;
173 
174 typedef struct {
175   String fontSet ;
176   String mfontSet ;
177 } toplevelResourceRec, *toplevelResourcePtr ;
178 
179 static XtResource toplevel_resources[] = {
180   { XtNfontset, XtCFontset, XtRString, sizeof( String ),
181     XtOffset( toplevelResourcePtr, fontSet ), XtRImmediate,
182     DEFAULT_FONTSET },
183   { XtNmfontset, XtCFontset, XtRString, sizeof( String ),
184     XtOffset( toplevelResourcePtr, mfontSet ), XtRImmediate,
185     DEFAULT_FONTSET },
186 } ;
187 
188 static toplevelResourceRec toplevel_value ;
189 
190 /* �Ѵ������Ф����äƤ���ץ�ȥ���ο���*/
191 static int number_of_protocols ;
192 
193 /* "~/.skkinput" ���ǥե���ȤǤ�������ե����롣*/
194 static char *skkinput_config_name ;
195 
196 /*
197  * skkinput �Τۤ���������Ѥ����褦�ʥ����Х��ѿ��������
198  */
199 /* ����¾��skkinput ��ɬ�פȤ����skkInputWidget ��ˤ�ɬ�פȤ��ʤ�����*/
200 char *skkserv_host ;
201 char *skkserv_service ;
202 int skkserv_pf = PF_UNSPEC ;
203 char *skkinput_local_jisyo_name ;
204 char *skkinput_backup_jisyo_name ;
205 char *skk_local_jisyo_name ;
206 char *skkinput_record_name ;
207 int  skk_egg_like_newline ;
208 int  skkinput_chatadaptermode ;
209 int  skkinput_search_skk_jisyo ;
210 int  skkinput_keep_record ;
211 int  skkinput_date_ad ;
212 int  skkinput_number_style ;
213 int  skkinput_delete_implies_kakutei ;
214 int  skkinput_use_numeric_conversion ;
215 int  skkinput_dabbrev_like_completion ;
216 int  skkinput_tab_width ;
217 int  skkinput_rjj_like_input ;
218 
219 Boolean  skkinput_jisyo_dirty ;
220 Boolean  skkinput_prev_jisyo_dirty ;
221 
222 unsigned long skkinput_j_count_kakutei ;
223 unsigned long skkinput_j_count_touroku ;
224 
225 /* ���޻���̾�Ѵ��ε�§��*/
226 struct skk_rom_kana_rule *skkinput_rom_kana_rule_list ;
227 
228 /*
229  * �����Х��ѿ� --- �����ȥ����֤����ꡣ
230  */
231 /* ��ư�����֤��뤫�ݤ���Ƚ�ꡣ*/
232 Boolean			skkinput_autosave_jisyo_dirty ;
233 Boolean			skkinput_autosave_key_dirty ;
234 /* ��ư�����֥����å��δ��֡�ñ�̤ϥߥ��á�*/
235 unsigned long		skkinput_autosave_interval ;
236 /* ��ư��������Ǥ��뤫�ݤ���*/
237 static Boolean		skkinput_now_autosaving ;
238 static XtWorkProcId	skkinput_autosave_work_id ;
239 
240 /*
241  * �ᥤ��ؿ���
242  *-------
243  * �����Υ����å����Ǥ⤦�����ˤ��䤫�ˤʤ�Ĥ�ꡣ
244  */
main(int argc,char * argv[])245 int main( int argc, char *argv[] )
246 {
247   Display *display ;
248   /* XtTranslations trans ; */
249   Arg arg[ 20 ] ;
250   Cardinal i ;
251   XEvent xevent ;
252   volatile XtIntervalId checkautosave_id = 0;
253   int (*defaultIOErrorHandler)( Display *disp ) ;
254 
255 #if defined(DEBUG)
256   setbuffer( stdout, NULL, 0 ) ;
257 #endif
258   setlocale( LC_ALL, "C" ) ;
259   /* skkinput ��ư����ѿ����������Ƥ�����*/
260   initSkkinputDousaketteiVariables() ;
261   /* ����Ϥޤä���Ǥ��롣*/
262   skkinput_jisyo_dirty = skkinput_prev_jisyo_dirty = False ;
263   /* �Ѵ��κݤ��Ѥ���ϥå���ơ��֥���������Ƥ�����*/
264   initVectorHashTable() ;
265   /* ����κݤ��Ѥ���ϥå���ơ��֥���������Ƥ�����*/
266   initHenkanKakuteiHashTable() ;
267 
268   /* �ץ�ȥ�����б����륦�������åȤ�ؤ��ѿ����������Ƥ�����*/
269 #if defined(SUPPORT_KINPUT)
270   kinput_protocol = NULL ;
271 #endif
272 #if defined(SUPPORT_XIMP)
273   ximp_protocol = NULL ;
274 #endif
275 #if defined(SUPPORT_XIM)
276   xim_protocol = NULL ;
277 #endif
278 
279   /* Toolkit ����˥��ץ��������å�������ȥ��ץ�������Ƭ���פ�
280    * ����Ʊ�����ץ������Ȥ��פ����ޤ�Ƥ��ޤ��������Ǥ��Ƥ���Τǡ�
281    * ��˼����Υ��ץ��������å����롣*/
282   skkinput_config_name = DEFAULT_CONFIGFILE ;
283   if( argc > 1 ){
284     if( !skkinput_checkOptions( &argc, argv, False ) ){
285       return 1 ;
286     }
287   }
288   /* config file ���ɤ�Ǥ�餦��*/
289   skkinput_readConfigFile( skkinput_config_name ) ;
290 
291   /* ���ץ��������꤬��ͥ��ˤʤ�褦�ˡ������������ֺǸ���ɤࡣ*/
292   /* ��� prescan �ˤ�äơ������Ǥΰ��������å��ǥ��顼���֤뤳�� *
293    * �Ϥʤ���*/
294   skkinput_checkOptions( &argc, argv, True ) ;
295 
296   /* �ޤ���Tool Kit �ν�������롣*/
297   toplevel = XtAppInitialize
298     ( &app_context, "Skkinput", options, XtNumber( options ), &argc, argv,
299       NULL, NULL, ( Cardinal ) 0);
300   if( argc > 1 ){
301     skkinput_usage() ;
302     XtDestroyApplicationContext
303       ( XtWidgetToApplicationContext( toplevel ) ) ;
304     return 1 ;
305   }
306   initialize_myerrorhandler() ;
307 
308   /* application resource �����Ƥ�����*/
309   XtGetApplicationResources
310     ( toplevel, &toplevel_value,
311       toplevel_resources, XtNumber( toplevel_resources ),
312       NULL, 0 ) ;
313 
314   /* �������Ϥ��Ȥ��褦�ˤ��롣*/
315   i = 0 ;
316   XtSetArg( arg[ i ], XtNinput,  True ) ;
317   i ++ ;
318   XtSetArg( arg[ i ], XtNwidth,  10 ) ;
319   i ++ ;
320   XtSetArg( arg[ i ], XtNheight, 10 ) ;
321   i ++ ;
322   XtSetArg( arg[ i ], XtNmappedWhenManaged, False ) ;
323   i ++ ;
324   XtSetValues( toplevel, arg, i ) ;
325 
326   number_of_protocols = 0 ;
327 
328 #if defined(SUPPORT_KINPUT)
329   if( support_kinput_protocol ){
330     /* Kinput Protocol ���Ѥ��뤿��ν������Ԥ���*/
331     kinput_protocol = XtVaCreateManagedWidget
332       ( "kinput2", kinputWidgetClass, toplevel, NULL ) ;
333     /* ɬ�פʥ�����Хå���ä��롣*/
334     XtAddCallback
335       ( kinput_protocol, XtNsetupInputWindowNotify,
336 	( XtCallbackProc )setupInputWindow, ( XtPointer )NULL ) ;
337     XtAddCallback
338       ( kinput_protocol, XtNserverCloseNotify,
339 	( XtCallbackProc )closeProtocolServer,
340 	( XtPointer )( &kinput_protocol ) ) ;
341     number_of_protocols ++ ;
342   }
343 #endif
344 
345 #if defined(SUPPORT_XIMP)
346   if( support_ximp_protocol ){
347     /* Ximp Protocol ���Ѥ��뤿��ν������Ԥ���*/
348     ximp_protocol = XtVaCreateManagedWidget
349       ( "ximp", ximpWidgetClass, toplevel, XtNwidth, 1, XtNheight, 1, NULL ) ;
350     /* ɬ�פʥ�����Хå���ä��롣*/
351     XtAddCallback
352       ( ximp_protocol, XtNsetupInputWindowNotify,
353 	( XtCallbackProc )setupInputWindow, ( XtPointer )NULL ) ;
354     XtAddCallback
355       ( ximp_protocol, XtNserverCloseNotify,
356 	( XtCallbackProc )closeProtocolServer,
357 	( XtPointer )( &ximp_protocol ) ) ;
358     number_of_protocols ++ ;
359   }
360 #endif
361 
362 #if defined(SUPPORT_XIM)
363   /* Xim Protocol ���Ѥ��뤿��ν������Ԥ���*/
364   if( support_xim_protocol ){
365 	  xim_protocol = XtVaCreateManagedWidget
366 		  ( "xim", ximServerWidgetClass, toplevel, XtNwidth, 1, XtNheight, 1, NULL ) ;
367 	  /* ɬ�פʥ�����Хå���ä��롣*/
368 	  XtAddCallback
369 		  ( xim_protocol, XtNsetupInputWindowNotify,
370 			( XtCallbackProc )setupInputWindow, ( XtPointer )NULL ) ;
371 	  XtAddCallback
372 		  ( xim_protocol, XtNserverCloseNotify,
373 			( XtCallbackProc )closeProtocolServer,
374 			( XtPointer )( &xim_protocol ) ) ;
375 	  number_of_protocols ++ ;
376   }
377 #endif
378   if( number_of_protocols > 0 ){
379 #ifndef MAIKAI_SKKSERV_TO_CONNECT_SURU
380     /* socket ��������Ƥ�����*/
381     skkinput_StartCommunication( skkserv_host, skkserv_service, skkserv_pf ) ;
382 #endif
383     /* �ɽ꼭��ξ��������Ƥ�����*/
384     set_localjisyo
385       ( skkinput_local_jisyo_name, skkinput_backup_jisyo_name,
386 	skkinput_record_name, skk_local_jisyo_name ) ;
387     /* �����Υ����ȥ����֥ե����뤬¸�ߤ������ˤ�����ɤ�ľ����*/
388     skkinput_readAutoSavedLocalJisyo() ;
389 
390     /* Widget ����ޤ���������������Ǥϼ��ΤϤʤ��Τǡ������Ǽ��Τ�
391      * ���ΤǤ���*/
392     XtRealizeWidget( toplevel ) ;
393 
394     display = XtDisplay( toplevel ) ;
395     defaultIOErrorHandler = XSetIOErrorHandler( skkinputIOErrorHandler ) ;
396     /* �꥽�����ǡ����١����ˤ���ե���ȥ��åȤ���ݤ��롣Separate ��
397      * ��OverTheSpot �Ȥ���ľ�˻ؤ���Ƥ��ޤ��ȤȤƤ�ޤȤ��ư���
398      * ���ˤʤ����ɤ͡��ޤ��������������Ȥ����顢����Ϥ���Ȥ�����
399      * �Ȥǡ�*/
400     fontMgr_initDefaultFontSet
401       ( display, toplevel_value.fontSet, toplevel_value.mfontSet ) ;
402     /* �����ȥ����֤��٤���Ƚ�ꤹ��ؿ�����Ͽ���롣*/
403     skkinput_autosave_key_dirty = False ;
404     skkinput_now_autosaving     = False ;
405     /* �����ȥ����֤Υ������Х뤬���ʤ�Х����ȥ����֤�¹Ԥ��롣*/
406     if( skkinput_autosave_interval != 0 ){
407       checkautosave_id = XtAppAddTimeOut
408 	( app_context, skkinput_autosave_interval,
409 	  skkinput_CheckAutoSaveJisyo, NULL ) ;
410     }
411     /* �ᥤ��롼�ס�*/
412     if( !setjmp( noprotocol_env ) ){
413       signal( SIGINT,  ( void (*)() )skkinput_Quit ) ;
414       signal( SIGQUIT, ( void (*)() )skkinput_Quit ) ;
415       signal( SIGTERM, ( void (*)() )skkinput_Quit ) ;
416       signal( SIGPIPE, ( void (*)() )skkinput_Quit ) ;
417       for( ; ; ){
418 	XtSafeAppNextEvent( app_context, &xevent ) ;
419 	skkinput_CheckEvent( display, &xevent ) ;
420 	/*XSafeFlush( display ) ;*/
421       }
422     }
423     /* �⤷�����ȥ����֤Υ����å�����Ͽ����Ƥ�������ä��롣*/
424     if( skkinput_autosave_interval > 0 )
425       XtRemoveTimeOut( checkautosave_id ) ;
426     /* �⤷ autosave ����Ͽ����Ƥ�������ä��롣*/
427     if( skkinput_now_autosaving )
428       XtRemoveWorkProc( skkinput_autosave_work_id ) ;
429 
430     ( void )XSetIOErrorHandler( defaultIOErrorHandler ) ;
431 
432     /* �����ʥ�ν�����ǥե���Ȥ��᤹��*/
433     signal( SIGINT,  SIG_DFL ) ;
434     signal( SIGQUIT, SIG_DFL ) ;
435     signal( SIGTERM, SIG_DFL ) ;
436     signal( SIGPIPE, SIG_DFL ) ;
437 
438 #ifndef MAIKAI_SKKSERV_TO_CONNECT_SURU
439     /* SKKSERV �ȤΥ��ͥ��������ڤ�ޤ���*/
440     skkinput_CloseCommunication() ;
441 #endif
442     destroy_protocolServers() ;
443     fontMgr_closeDefaultFontSet( display ) ;
444   } else {
445     fprintf( stderr, "(skkinput) No protocol is supported.\n" ) ;
446   }
447   /* ���Ѥ��Ƥ����������Ʋ������롣*/
448   XtSafeDestroyApplicationContext
449     ( XtWidgetToApplicationContext( toplevel ) ) ;
450   /* �������ʤ��ä���� */
451   if( skkinput_jisyo_dirty ){
452     fprintf( stderr, "(skkinput) Saving Jisyo..." ) ;
453     /* ���ߤޤǤ˳����Ѵ����Ƥ�����������֤��롣*/
454     skkinput_updateLocalJisyo() ;
455     fprintf( stderr, "done\n" ) ;
456   }
457   /* malloc ���Ƥ�������β�����*/
458   close_localjisyo() ;
459   /* �ϥå�����ꥢ���롣*/
460   clearHenkanKakuteiHash() ;
461   return 0 ;
462 }
463 
464 /*
465  * ����ξ��֤��Ѳ������Ƥ����ܸ���������Ф��ƥ֥��ɥ��㥹�Ȥ����
466  * ����
467  *------
468  * main -> widget �ؤ��̿��ˤϡ�XtSetValues ��Ȥ��Τ��������Ȼפ�����
469  * ��ϡ�
470  */
skkinput_redraw_allskkinputs(void)471 static void skkinput_redraw_allskkinputs( void )
472 {
473   /* ������Ѳ��������롣*/
474 #if defined(SUPPORT_KINPUT)
475   if( kinput_protocol != NULL ){
476     XtVaSetValues
477       ( kinput_protocol, XtNjisyoDirty, skkinput_jisyo_dirty, NULL ) ;
478   }
479 #endif
480 #if defined(SUPPORT_XIM)
481   if( xim_protocol != NULL ){
482     XtVaSetValues
483       ( xim_protocol, XtNjisyoDirty, skkinput_jisyo_dirty, NULL ) ;
484   }
485 #endif
486 #if defined(SUPPORT_XIMP)
487   if( ximp_protocol != NULL ){
488     XtVaSetValues
489       ( ximp_protocol, XtNjisyoDirty, skkinput_jisyo_dirty, NULL ) ;
490   }
491 #endif
492   return ;
493 }
494 
495 /*
496  * ���ä��褿���٥�Ȥ�����å�����ؿ���
497  */
skkinput_CheckEvent(Display * disp,XEvent * xevent)498 static void skkinput_CheckEvent( Display *disp, XEvent *xevent )
499 {
500 #ifdef DEBUG
501   fprintf( stderr, "[XEvent] Type(%d), Serial(%ld), Window(%ld)\n",
502 	   xevent->type, xevent->xany.serial, xevent->xany.window ) ;
503 #endif
504 
505   /* ������֤ޤ����ļ�ʬ�Τ�����äƤ��륦����ɥ��Τɤ줫���˴����� *
506    *         �褦�Ȥ��Ƥ��롩����                                     *
507    * �̱�  �֤��Τ褦�Ǥ��͡ġ���                                     *
508    * �ե��꡼�֤��Τ褦�Ǥ��ͤäƤ͡� �������Ȥ��ʤ�ʤ��Ρ���      */
509   if( xevent->type == DestroyNotify ){
510     Window dwin = xevent->xany.window ;
511 
512     /* �Ƽ�ץ�ȥ���Υ����Ф˲��餫�Υ�����ɥ����˴����줿�Ȥ�����
513      * �Ȥ���ã���롣*/
514 #if defined(SUPPORT_KINPUT)
515     if( kinput_protocol != NULL ){
516       XtVaSetValues
517 	( kinput_protocol, XtNdestroyWindowEvent, xevent, NULL ) ;
518     }
519 #endif
520 #if defined(SUPPORT_XIMP)
521     if( ximp_protocol != NULL ){
522       XtVaSetValues
523 	( ximp_protocol, XtNdestroyWindowEvent, xevent, NULL ) ;
524     }
525 #endif
526 #if defined(SUPPORT_XIM)
527     if( xim_protocol != NULL ){
528       XtVaSetValues
529 	( xim_protocol, XtNdestroyWindowEvent, xevent, NULL ) ;
530     }
531 #endif
532     /* �ҥ��ȥ���˴���*/
533     history_destroy( dwin ) ;
534     /*
535      * �˴����줿����Ф�³���ƥ�����ɥ��δƻ��Ԥ����Ȥ�̵��̣��
536      */
537     remove_allmyeventhandler( disp, dwin ) ;
538     XSafeSelectInput( disp, dwin, NoEventMask ) ;
539     return ;
540   }
541   mydispatch_event( disp, xevent ) ;
542 
543   /* ������ѹ������ä����ˤ����Ƥ�����Ф��ƽ�ľ���׵᤬ɬ *
544    * �פǤ��롣���줬�¹ԤǤ���Τϡ������ᥤ�������*/
545   if( skkinput_jisyo_dirty != skkinput_prev_jisyo_dirty ){
546     skkinput_redraw_allskkinputs() ;
547     skkinput_prev_jisyo_dirty = skkinput_jisyo_dirty ;
548   }
549   return ;
550 }
551 
destroy_protocolServers(void)552 static void destroy_protocolServers( void )
553 {
554   /* �⤷�ޤ����Τ����ä����˴����롣*/
555 #if defined(SUPPORT_KINPUT)
556   if( kinput_protocol != NULL )
557     XtDestroyWidget( kinput_protocol ) ;
558   kinput_protocol = NULL;
559 #endif
560 #if defined(SUPPORT_XIMP)
561   if( ximp_protocol != NULL )
562     XtDestroyWidget( ximp_protocol ) ;
563   ximp_protocol = NULL;
564 #endif
565 #if defined(SUPPORT_XIM)
566   if( xim_protocol != NULL )
567     XtDestroyWidget( xim_protocol ) ;
568   xim_protocol = NULL;
569 #endif
570   return ;
571 }
572 
573 /*
574  * skkinput ��λ���ν�����Ԥ��ؿ���
575  *-----
576  * �Ȥ��äƤ⡢main �ؿ��ν�λ������ʬ������Ǥ�������Ǥ����ɡ�
577  * ��λ������ˤ� application context ��������ʤ������ܤʤΤǡ���ä�
578  * �ؿ��Ǥ�������� Selection Owner ������Ǥ��ޤ��Τǡ����Τ��Ҥä���
579  * �뤳�ȤϾ��ʤ��Ȼפ��ΤǤ����ɡ�
580  */
skkinput_Quit(void)581 static void skkinput_Quit( void )
582 {
583   /* signal ��������롣*/
584   signal( SIGINT,  SIG_DFL ) ;
585   signal( SIGQUIT, SIG_DFL ) ;
586   signal( SIGTERM, SIG_DFL ) ;
587   signal( SIGPIPE, SIG_DFL ) ;
588 
589   destroy_protocolServers() ;
590   return ;
591 }
592 
593 /*
594  * ������ˡ�����ؿ���
595  */
skkinput_usage(void)596 static int skkinput_usage( void )
597 {
598   char **ptr ;
599   char *syntaxtable[] = {
600     "-\\?           or -help",		  "shows this help",
601     "-v            or -version",	  "shows version",
602     "-h <hostname> or -host <hostname>",  "specifies skkserv host",
603     "-p <port_num> or -port <port_num>",  "specifies port number",
604     "-4",				  "specifies to use IPv4",
605     "-6",				  "specifies to use IPv6",
606     "-uj <jisyo>   or -userjisyo <jisyo>","specifies skkinput-local-jisyo",
607     "-bj <jisyo>   or -backjisyo <jisyo>","specifies skkinput-local-jisyo\'s backup",
608     "-sj <jisyo>   or -skkjisyo <jisyo>", "specifies skk-local-jisyo",
609     "-rc <jisyo>   or -record <record>",  "specifies skkinput-record",
610     "-fontset <fontset>",		  "specifies fontset",
611     "-mfontset <fontset>",		  "specifies fontset of minibuffer window",
612     "-fg <color>",			  "specifies foreground color",
613     "-bg <color>",			  "specifies background color",
614     "-bd <color>",			  "specifies border color",
615     "-/+rv",				  "reverse video mode on/off",
616     "-width",				  "specifies width of separate window",
617     "-height",				  "specifies height of separate window",
618     "-mwidth",				  "specifies width of minibuffer window",
619     "-/+mfc",				  "changing minibuffer font on/off",
620     "-/+nc",				  "next control on/off",
621     "-/+ns",				  "next shift on/off",
622 #if defined(SUPPORT_KINPUT)
623     "-/+kinput",			  "kinput protocol support on/off",
624 #endif
625 #if defined(SUPPORT_XIM)
626     "-/+xim",				  "xim protocol support on/off",
627 #endif
628 #if defined(SUPPORT_XIMP)
629     "-/+ximp",				  "ximp protocol support on/off",
630 #endif
631     "-autosave",			  "specifies interval(msec) of auto-save",
632     NULL, NULL,
633   } ;
634   ptr = syntaxtable ;
635   while( *ptr != NULL ){
636     fprintf( stderr, "%-35s ", *ptr ++ ) ;
637     fprintf( stderr, "%s\n", *ptr ++ ) ;
638   }
639   return 0 ;
640 }
641 
642 /*
643  * ���ץ����Υ����å�����ؿ���
644  */
skkinput_checkOptions(int * argc,char * argv[],int flag)645 static int skkinput_checkOptions( int *argc, char *argv[], int flag )
646 {
647   int i, j ;
648   struct skkinputOptionDef local_options[] = {
649     { "-h",		OPTION_HOST,		True },
650     { "-host",		OPTION_HOST,		True },
651     { "-p",		OPTION_PORT,		True },
652     { "-port",		OPTION_PORT,		True },
653     { "-4",		OPTION_IPv4,		False },
654     { "-6",		OPTION_IPv6,		False },
655     { "-uj",		OPTION_USERDIC,		True },
656     { "-userjisyo",	OPTION_USERDIC,		True },
657     { "-bj",		OPTION_BAKDIC,		True },
658     { "-backjisyo",	OPTION_BAKDIC,		True },
659     { "-sj",		OPTION_SKKDIC,		True },
660     { "-skkjisyo",	OPTION_SKKDIC,		True },
661     { "-rc",		OPTION_SKKREC,		True },
662     { "-record",	OPTION_SKKREC,		True },
663     { "-config",	OPTION_CONFIG,		True },
664     { "-cnf",		OPTION_CONFIG,		True },
665     { "-?",		OPTION_HELP,		False },
666     { "-help",		OPTION_HELP,		False },
667     { "-v",		OPTION_VERSION,		False },
668     { "-version",	OPTION_VERSION,		False },
669 #if defined(SUPPORT_KINPUT)
670     { "-kinput",	OPTION_KINPUT_ON,	False },
671     { "+kinput",	OPTION_KINPUT_OFF, 	False },
672 #endif
673 #if defined(SUPPORT_XIM)
674     { "-xim",		OPTION_XIM_ON,		False },
675     { "+xim",		OPTION_XIM_OFF, 	False },
676 #endif
677 #if defined(SUPPORT_XIMP)
678     { "-ximp",		OPTION_XIMP_ON,		False },
679     { "+ximp",		OPTION_XIMP_OFF,	False },
680 #endif
681     { "-autosave",	OPTION_AUTOSAVE,	True  },
682     { NULL,             0,              	False },
683   } ;
684 
685   for( i = 1 ; i < *argc ; i ++ ){
686     /* �ɤ�˰��פ��뤫�������롣*/
687     for( j = 0 ; local_options[ j ].chara != NULL ; j ++ ){
688       if( !strcmp( argv[ i ], local_options[ j ].chara ) )
689 	break ;
690     }
691     if( local_options[ j ].chara == NULL )
692       continue ;
693     /* ���˰�����ɬ�פȤ��Ƥ���Τ��� */
694     if( local_options[ j ].need_argument ){
695       if( flag )
696 	argv[ i ] = NULL ;
697       i ++ ;
698       if( i >= ( *argc ) ){
699 	fprintf( stderr, "Lack of argument: \"%s\".\n", argv[ i - 1 ] ) ;
700 	goto checkoption_errorreturn ;
701       }
702     }
703     /* ���ץ������ν�����*/
704     switch( local_options[ j ].function_no ){
705       /* skkserv �ε����Ƥ���ۥ���̾�����ꤹ�롣*/
706     case OPTION_HOST :
707       skkserv_host = argv[ i ] ;
708       break ;
709       /* skkserv ���̿���������Ѥ��륵���ӥ�̾/�ݡ����ֹ�����ꤹ�롣*/
710     case OPTION_PORT :
711       if (skkserv_service) free(skkserv_service) ;
712       skkserv_service = strdup(argv[i]);
713       break ;
714     case OPTION_IPv4:
715       skkserv_pf = PF_INET;
716       break;
717     case OPTION_IPv6:
718 #if defined(USE_INET6)
719       skkserv_pf = PF_INET6;
720       break;
721 #else
722       fprintf( stderr, "IPv6 not supported.\n" ) ;
723       goto checkoption_errorreturn ;
724 #endif
725 
726       /* �ɽ꼭���̾�������ꤹ�롣*/
727     case OPTION_USERDIC :
728       skkinput_local_jisyo_name = argv[ i ] ;
729       break ;
730     case OPTION_BAKDIC :
731       skkinput_backup_jisyo_name = argv[ i ] ;
732       break ;
733       /* �إ�פ�ɽ�����롣*/
734     case OPTION_SKKREC :
735       skkinput_record_name = argv[ i ] ;
736       break ;
737       /* ����ե�����ν�ߤ���ꤹ�롣*/
738     case OPTION_CONFIG :
739       skkinput_config_name = argv[ i ] ;
740       break ;
741     case OPTION_HELP :
742       goto checkoption_errorreturn ;
743       /* �С�������ɽ�����롣*/
744     case OPTION_VERSION :
745       fprintf( stderr, "skkinput version %s\n\n", skkinput_version ) ;
746       fprintf( stderr, "This is free software. Skkinput can be copied only under the terms of\nthe GNU General Public license. There is NO warranty; not even for \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" ) ;
747       return False ;
748 #if defined(SUPPORT_KINPUT)
749     case OPTION_KINPUT_ON :
750       support_kinput_protocol = True ;
751       break ;
752     case OPTION_KINPUT_OFF :
753       support_kinput_protocol = False ;
754       break ;
755 #endif
756 #if defined(SUPPORT_XIMP)
757     case OPTION_XIMP_ON :
758       support_ximp_protocol = True ;
759       break ;
760     case OPTION_XIMP_OFF :
761       support_ximp_protocol = False ;
762       break ;
763 #endif
764 #if defined(SUPPORT_XIM)
765     case OPTION_XIM_ON :
766       support_xim_protocol = True ;
767       break ;
768     case OPTION_XIM_OFF :
769       support_xim_protocol = False ;
770       break ;
771 #endif
772     case OPTION_AUTOSAVE :
773       /* ����ι��������å�������֤����ꤹ�롣*/
774       skkinput_autosave_interval = atol( argv[ i ] ) ;
775       break ;
776     default :
777       goto checkoption_errorreturn ;
778     }
779     if( flag )
780       argv[ i ] = NULL ;
781   }
782   if( flag ){
783     for( j = 0, i = 0 ; i < *argc ; i ++ ){
784       if( argv[ i ] != NULL ){
785 	argv[ j ++ ] = argv[ i ] ;
786       }
787     }
788     *argc = j ;
789   }
790   return True ;
791 
792 checkoption_errorreturn:
793   skkinput_usage() ;
794   return False ;
795 }
796 
797 /*
798  * �ƤǤ���ᥤ�����Τ�ʤ������ Skkinput Widget ���Ф��ƹԤ��ؿ���
799  *------
800  * �֤���㥰���Х��ѿ�������̵�뤷�ƥ����������������ɡġ�
801  * �֤����ޤ�����
802  * �֤��� ����աġ�
803  * �֡Ĥ���ϡ�����ʤ��ȤǤ��äȤ��������ꤷ�ޤ�����
804  * �֤���ĤǤ�Ĥ������ġ�
805  */
setupInputWindow(Widget gw,caddr_t client,caddr_t caller)806 static void setupInputWindow
807 ( Widget gw, caddr_t client, caddr_t caller )
808 {
809   skkinput_setSkkInputValues( ( Widget )caller ) ;
810   return ;
811 }
812 
813 /*
814  * Kinput Procotol Server �Ȥ��Ƥε�ǽ����ߤ�����ؿ���
815  *----------------
816  * ���δؿ��ϥ�����Хå��Ȥ��Ʋ��̤Υ��������å�(�ĤޤꡢkinputWidget)
817  * ����ƤӽФ���뤳�Ȥˤʤ롣
818  */
closeProtocolServer(Widget gw,caddr_t client,caddr_t caller)819 static void closeProtocolServer
820 ( Widget gw, caddr_t client, caddr_t caller )
821 {
822   Widget *protocol_widget = ( Widget * )client ;
823   /*
824    * �Ƽ� Protocol �Τ�����Ѱդ��Ƥ���������Хå��������˴����Ƥ�����
825    */
826   XtRemoveAllCallbacks( gw, XtNsetupInputWindowNotify ) ;
827   XtRemoveAllCallbacks( gw, XtNserverCloseNotify ) ;
828   /*
829    * ���ݡ��Ȥ��Ƥ���ץ�ȥ���ο����餹������̵���ʤä��顢��Ϥ�
830    * �Ѵ������ФȤ��Ƥε�ǽ�ϲ̤����ʤ��ΤǶ�����λ���롣
831    */
832   number_of_protocols -- ;
833   *protocol_widget = NULL ;
834   if( number_of_protocols <= 0 )
835     longjmp( noprotocol_env, 1 ) ;
836   return ;
837 }
838 
839 /*
840  * ������ַв���˼���Υ����֤�Ԥ��٤����ɤ�����Ƚ�ꤹ��ؿ���
841  */
skkinput_CheckAutoSaveJisyo(XtPointer closure,XtIntervalId * id)842 static void skkinput_CheckAutoSaveJisyo
843 ( XtPointer closure, XtIntervalId *id )
844 {
845   /* ���ߥ����ȥ����֤μ¹��椸��ʤ������������ˤϥ����������줺�ˡ�
846    * �������������ȥ����֤���Ƥ��鼭���ѹ�����Ƥ����顢�����ȥ���
847    * �֤�¹Ԥ��롣*/
848   if( !skkinput_autosave_key_dirty && !skkinput_now_autosaving &&
849       skkinput_autosave_jisyo_dirty ){
850     skkinput_now_autosaving = True ;
851     /* �����Ǽ������֤�Ԥ��ؿ�����Ͽ���롣*/
852     skkinput_autosave_work_id = XtAppAddWorkProc
853       ( app_context, skkinput_AutoSaveJisyo, NULL ) ;
854   } else {
855     skkinput_autosave_key_dirty = False ;
856   }
857   *id = XtAppAddTimeOut
858     ( app_context, 1000 * 15, skkinput_CheckAutoSaveJisyo, NULL ) ;
859   return ;
860 }
861 
862 /*
863  * �����ȥ����֤�¹Ԥ���ؿ���
864  */
skkinput_AutoSaveJisyo(XtPointer closure)865 static Boolean skkinput_AutoSaveJisyo( XtPointer closure )
866 {
867   /* ���ơ��ɤ���äƥ����֤��褦���ʡ� ����äƾ�꤯�Ԥ��Τ��ʡ� */
868   skkinput_autosaveLocalJisyo() ;
869   /* �����֤���λ�����Τǡ���å�������*/
870   skkinput_now_autosaving       = False ;
871   /* �����ȥ����֤��줿�Τǡ�����ι����������ޤǺ��٤Υ����ȥ�����
872    * �ϹԤ��ʤ��褦�ˤ��롣*/
873   skkinput_autosave_jisyo_dirty = False ;
874   /* ���γ���ߤϼ�ưŪ�˾õ���٤��Ǥ��롣*/
875   return True ;
876 }
877 
878 /*
879  * X connection to %s is broken �λ��ν�����Ԥ��ؿ���
880  */
skkinputIOErrorHandler(Display * display)881 static int skkinputIOErrorHandler( Display *display )
882 {
883 #ifndef MAIKAI_SKKSERV_TO_CONNECT_SURU
884   /* SKKSERV �ȤΥ��ͥ��������ڤ�ޤ���*/
885   skkinput_CloseCommunication() ;
886 #endif
887   /* ���Ѥ��Ƥ����������Ʋ������롣*/
888   XCloseDisplay( display ) ;
889   /* �������ʤ��ä���� */
890   if( skkinput_jisyo_dirty ){
891     fprintf( stderr, "(skkinput) Saving Jisyo..." ) ;
892     /* ���ߤޤǤ˳����Ѵ����Ƥ�����������֤��롣*/
893     skkinput_updateLocalJisyo() ;
894     fprintf( stderr, "done\n" ) ;
895   }
896   /* malloc ���Ƥ�������β�����*/
897   close_localjisyo() ;
898   /* �ϥå�����ꥢ���롣*/
899   clearHenkanKakuteiHash() ;
900   exit( 1 ) ;
901 }
902