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