1 /* # skkinput (Simple Kana-Kanji Input)
2 *
3 * This file is part of skkinput.
4 * Copyright (C) 2002
5 * Takashi SAKAMOTO (PXG01715@nifty.ne.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 "AfxWin.h"
22 #include <stdio.h>
23 #include <locale.h>
24 #include <signal.h>
25 #include "skkinput.h"
26 #include "dispatch.h"
27 #if defined (SUPPORT_KINPUT)
28 #include "KinputServer.h"
29 #endif
30 #if defined (SUPPORT_XIM)
31 #include "XIMServer.h"
32 #endif
33 #include "kanji.h"
34
35 /*========================================================================*
36 * �ץ�ȥ����������
37 *========================================================================*/
38 static Boolean skkinputApp_initApplication (int*, char*[]) ;
39 static Boolean skkinputApp_exitApplication (void) ;
40 static Boolean skkinputApp_initInstance (void) ;
41 static Boolean skkinputApp_exitInstance (void) ;
42 static Boolean skkinputApp_mainLoop (void) ;
43 static Boolean skkinputApp_initLispMgr (void) ;
44 static int skkinputApp_getExitFlag (void) ;
45 static void skkinputApp_onProtocolDestroy (Widget, XtPointer, XtPointer) ;
46 static int skkinputApp_onXIoError (Display*) ;
47 static void skkinputApp_onSignal (int) ;
48 static void skkinputApp_showUsage (int*, char*[]) ;
49 #if defined (DEBUG_CONSOLE)
50 static void skkinputApp_testModeMainLoop (void) ;
51 #endif
52
53 /*========================================================================*
54 * �����Х��ѿ���
55 *========================================================================*/
56 static SkkinputApp theApp ;
57
58 #if !defined (XtNlispMachine)
59 #define XtNlispMachine "lispMachine"
60 #endif
61
62 typedef struct {
63 #if defined (SUPPORT_KINPUT)
64 Boolean m_fUseKinputProtocol ;
65 #endif
66 #if defined (SUPPORT_XIM)
67 Boolean m_fUseXIMProtocol ;
68 #endif
69 String m_strServerHost ;
70 int m_nPortNum ;
71 String m_strConfigPath ;
72 #if defined (DEBUG_CONSOLE)
73 Boolean m_fTestMode ;
74 #endif
75 } SkkinputAppResRec ;
76
77 static SkkinputAppResRec theAppRes ;
78
79 #define offset(field) XtOffsetOf(SkkinputAppResRec,field)
80
81 static XtResource rresSkkinputApp [] = {
82 #if defined (SUPPORT_KINPUT)
83 { "useKinputProtocol", "UseKinputProtocol", XtRBoolean,
84 sizeof (Boolean), offset (m_fUseKinputProtocol),
85 XtRImmediate, (XtPointer) True, },
86 #endif
87 #if defined (SUPPORT_XIM)
88 { "useXIMProtocol", "UseXIMProtocol", XtRBoolean,
89 sizeof (Boolean), offset (m_fUseXIMProtocol),
90 XtRImmediate, (XtPointer) True, },
91 #endif
92 { "serverHost", "SkkserverHost", XtRString,
93 sizeof (String), offset (m_strServerHost),
94 XtRImmediate, (XtPointer)"", },
95 { "portnum", "Portnum", XtRInt,
96 sizeof (int), offset (m_nPortNum),
97 XtRImmediate, (XtPointer)-1, },
98 { "configPath", "ConfigPath", XtRString,
99 sizeof (String), offset (m_strConfigPath),
100 XtRImmediate, (XtPointer) ELISP_DIR, },
101 #if defined (DEBUG_CONSOLE)
102 { "testMode", "TestMode", XtRBoolean,
103 sizeof (Boolean), offset (m_fTestMode),
104 XtRImmediate, (XtPointer) False, },
105 #endif
106 } ;
107
108 #undef offset
109
110 static XrmOptionDescRec roptDescSkkinputApp [] = {
111 #if defined (SUPPORT_KINPUT)
112 { "-kinput", ".useKinputProtocol", XrmoptionNoArg, "True", },
113 { "+kinput", ".useKinputProtocol", XrmoptionNoArg, "False", },
114 #endif
115 #if defined (SUPPORT_XIM)
116 { "-xim", ".useXIMProtocol", XrmoptionNoArg, "True", },
117 { "+xim", ".useXIMProtocol", XrmoptionNoArg, "False", },
118 #endif
119 { "-server", ".serverHost", XrmoptionSepArg, NULL, },
120 { "-portnum", ".portnum", XrmoptionSepArg, NULL, },
121 { "-config", ".configPath", XrmoptionSepArg, NULL, },
122 { "-fontset", "*fontSet", XrmoptionSepArg, NULL, },
123 { "-rv", "*reverseVideo", XrmoptionNoArg, "True", },
124 { "+rv", "*reverseVideo", XrmoptionNoArg, "False", },
125 { "-fg", "*foreground", XrmoptionSepArg, NULL, },
126 { "-bg", "*background", XrmoptionSepArg, NULL, },
127 { "-bd", "*borderColor", XrmoptionSepArg, NULL, },
128 #if defined (DEBUG_CONSOLE)
129 { "-test", ".testMode", XrmoptionNoArg, "True", },
130 { "+test", ".testMode", XrmoptionNoArg, "False", },
131 #endif
132 } ;
133
134 int
main(int iArgc,char * rpArgv[])135 main (int iArgc, char* rpArgv [])
136 {
137 register void (*pOrgSigHandler)(int) ;
138
139 setlocale (LC_ALL, "japanese") ;
140
141 if (! skkinputApp_initApplication (&iArgc, rpArgv))
142 return EXIT_FAILURE ;
143
144 #if defined (DEBUG_CONSOLE)
145 if (theAppRes.m_fTestMode) {
146 skkinputApp_testModeMainLoop () ;
147 } else {
148 #endif
149 pOrgSigHandler = signal (SIGHUP, SIG_IGN) ;
150 theApp.m_pLispMgr = NULL ;
151 do {
152 theApp.m_fContinue = False ;
153 theApp.m_fExitFlag = False ;
154
155 if (! skkinputApp_initInstance ())
156 return EXIT_FAILURE ;
157
158 (void) signal (SIGHUP, skkinputApp_onSignal) ;
159 (void) signal (SIGINT, skkinputApp_onSignal) ;
160 (void) signal (SIGQUIT, skkinputApp_onSignal) ;
161 if (theApp.m_nProtocol > 0)
162 skkinputApp_mainLoop () ;
163 (void) signal (SIGHUP, SIG_IGN) ;
164 (void) signal (SIGINT, SIG_IGN) ;
165 (void) signal (SIGQUIT, SIG_IGN) ;
166 skkinputApp_exitInstance () ;
167 } while (theApp.m_fContinue) ;
168
169 (void) signal (SIGHUP, pOrgSigHandler) ;
170 #if defined (DEBUG_CONSOLE)
171 }
172 #endif
173 skkinputApp_exitApplication () ;
174
175 return EXIT_SUCCESS ; ;
176 }
177
178 #if defined (DEBUG)
179 TLispManager*
skkinputApp_GetLispMgr(void)180 skkinputApp_GetLispMgr (void)
181 {
182 return theApp.m_pLispMgr ;
183 }
184 #endif
185
186 /*========================================================================*
187 * ������ؿ���
188 *========================================================================*/
189 Boolean
skkinputApp_initApplication(register int * pnArgc,register char * pArgv[])190 skkinputApp_initApplication (
191 register int* pnArgc,
192 register char* pArgv [])
193 {
194 /*register TEditorClient* pClient ;*/
195 register Widget wgToplevel ;
196 Arg rArg [8] ;
197 register int nArg, nArgc ;
198
199 wgToplevel = XtAppInitialize (&theApp.m_appContext, "Skkinput", roptDescSkkinputApp, XtNumber (roptDescSkkinputApp), pnArgc, pArgv, NULL, NULL, (Cardinal) 0) ;
200 nArgc = *pnArgc ;
201 if (nArgc > 1) {
202 skkinputApp_showUsage (pnArgc, pArgv) ;
203 return False ;
204 }
205 if (wgToplevel == NULL)
206 return False ;
207
208 nArg = 0 ;
209 XtSetArg (rArg [nArg], XtNmappedWhenManaged, False) ; nArg ++ ;
210 XtSetArg (rArg [nArg], XtNwidth, 1) ; nArg ++ ;
211 XtSetArg (rArg [nArg], XtNheight, 1) ; nArg ++ ;
212 XtSetValues (wgToplevel, rArg, nArg) ;
213
214 XtGetApplicationResources (wgToplevel, &theAppRes, rresSkkinputApp, XtNumber (rresSkkinputApp), NULL, 0) ;
215 AfxWinInitialize (wgToplevel) ;
216 XtRealizeWidget (wgToplevel) ;
217 theApp.m_wgToplevel = wgToplevel ;
218 return True ;
219 }
220
221 Boolean
skkinputApp_initInstance(void)222 skkinputApp_initInstance (void)
223 {
224 /*register TEditorClient* pClient ;*/
225 register Widget wgToplevel ;
226 #if defined (SUPPORT_KINPUT)
227 register Widget wgKinputProtocol ;
228 #endif
229 #if defined (SUPPORT_XIM)
230 register Widget wgXIMProtocol ;
231 #endif
232 Arg rArg [8] ;
233 register int nArg ;
234
235 theApp.m_nProtocol = 0 ;
236 wgToplevel = theApp.m_wgToplevel ;
237
238 /* lisp manager ������*/
239 if (TFAILED (skkinputApp_initLispMgr ()))
240 return False ;
241
242 nArg = 0 ;
243 XtSetArg (rArg [nArg], XtNlispMachine, theApp.m_pLM) ; nArg ++ ;
244
245 #if defined (SUPPORT_KINPUT)
246 /* Kinput Protocol ���Ѥ��뤿��ν������Ԥ���*/
247 if (theAppRes.m_fUseKinputProtocol) {
248 wgKinputProtocol = XtCreateManagedWidget ("kinput2", kinputServerWidgetClass, wgToplevel, rArg, nArg) ;
249 if (wgKinputProtocol != NULL) {
250 XtAddCallback (wgKinputProtocol, XtNdestroyCallback, skkinputApp_onProtocolDestroy, 0) ;
251 XtRealizeWidget (wgKinputProtocol) ;
252 theApp.m_nProtocol ++ ;
253 }
254 } else {
255 wgKinputProtocol = NULL ;
256 }
257 theApp.m_wgKinputProtocol = wgKinputProtocol ;
258 #endif
259 #if defined (SUPPORT_XIM)
260 /* XIMProtocol ¦�ν�����*/
261 if (theAppRes.m_fUseXIMProtocol) {
262 wgXIMProtocol = XtCreateManagedWidget ("xim", ximServerWidgetClass, wgToplevel, rArg, nArg) ;
263 if (wgXIMProtocol != NULL) {
264 XtAddCallback (wgXIMProtocol, XtNdestroyCallback, skkinputApp_onProtocolDestroy, 0) ;
265 XtRealizeWidget (wgXIMProtocol) ;
266 theApp.m_nProtocol ++ ;
267 }
268 } else {
269 wgXIMProtocol = NULL ;
270 }
271 theApp.m_wgXIMProtocol = wgXIMProtocol ;
272 #endif
273 if (theApp.m_nProtocol <= 0) {
274 fprintf (stderr, "No protocol server is available.\n") ;
275 return False ;
276 }
277 return True ;
278 }
279
280 Boolean
skkinputApp_exitInstance(void)281 skkinputApp_exitInstance (void)
282 {
283 #if defined (SUPPORT_KINPUT)
284 if (theApp.m_wgKinputProtocol != NULL) {
285 XtDestroyWidget (theApp.m_wgKinputProtocol) ;
286 theApp.m_wgKinputProtocol = NULL ;
287 }
288 #endif
289 #if defined (SUPPORT_XIM)
290 if (theApp.m_wgXIMProtocol != NULL) {
291 XtDestroyWidget (theApp.m_wgXIMProtocol) ;
292 theApp.m_wgXIMProtocol = NULL ;
293 }
294 #endif
295 theApp.m_nProtocol = 0 ;
296 TLispClient_ClassFinalize (theApp.m_pLM) ;
297 theApp.m_pLM = NULL ;
298 return True ;
299 }
300
301 Boolean
skkinputApp_exitApplication(void)302 skkinputApp_exitApplication (void)
303 {
304 register Display* pDisplay ;
305
306 pDisplay = XtDisplay (theApp.m_wgToplevel) ;
307 XtDestroyWidget (theApp.m_wgToplevel) ;
308 XtDestroyApplicationContext (theApp.m_appContext) ;
309 return True ;
310 }
311
312 Boolean
skkinputApp_mainLoop(void)313 skkinputApp_mainLoop (void)
314 {
315 register int (*pOrgHandler)(Display*, XErrorEvent*) ;
316 register int (*pOrgIOHandler)(Display*) ;
317
318 #if defined (DEBUG)
319 fprintf (stderr, "skkinputApp_mainLoop(): enter\n") ;
320 #endif
321 pOrgHandler = XSetErrorHandler (AfxHandleXError) ;
322 pOrgIOHandler = XSetIOErrorHandler (skkinputApp_onXIoError) ;
323 TLispClient_MainLoop (theApp.m_appContext, theApp.m_pLM, &skkinputApp_getExitFlag) ;
324 (void) XSetIOErrorHandler (pOrgIOHandler) ;
325 (void) XSetErrorHandler (pOrgHandler) ;
326 #if defined (DEBUG)
327 fprintf (stderr, "skkinputApp_mainLoop(): leave\n") ;
328 #endif
329 return True ;
330 }
331
332 Boolean
skkinputApp_initLispMgr(void)333 skkinputApp_initLispMgr (void)
334 {
335 register Boolean fCreate ;
336 register const char* strConfigPath ;
337 register const char* strServerHost ;
338 register int nPortNum ;
339
340 fCreate = (theApp.m_pLispMgr == NULL) ;
341 strConfigPath = theAppRes.m_strConfigPath ;
342 strServerHost = theAppRes.m_strServerHost ;
343 nPortNum = theAppRes.m_nPortNum ;
344 if (TFAILED (TLispClient_ClassInitialize (&theApp.m_pLispMgr, &theApp.m_pLM, strConfigPath, strServerHost, nPortNum, fCreate))) {
345 fprintf (stderr, "skkinput: failed: initialize lisp manager.\n") ;
346 return False ;
347 }
348 return True ;
349 }
350
351 int
skkinputApp_getExitFlag(void)352 skkinputApp_getExitFlag (void)
353 {
354 return theApp.m_fExitFlag ;
355 }
356
357 void
skkinputApp_onSignal(register int nSignal)358 skkinputApp_onSignal (
359 register int nSignal)
360 {
361 register Display* pDisplay ;
362 XEvent xev ;
363
364 #if defined (DEBUG)
365 fprintf (stderr, "Catch SIGHUP (%d)\n", nSignal) ;
366 #endif
367 theApp.m_fContinue = (nSignal == SIGHUP)? True : False ;
368 theApp.m_fExitFlag = True ;
369
370 pDisplay = XtDisplay (theApp.m_wgToplevel) ;
371 memset (&xev, 0, sizeof (xev)) ;
372 xev.xclient.type = ClientMessage ;
373 xev.xclient.serial = 0UL ;
374 xev.xclient.window = XtWindow (theApp.m_wgToplevel) ;
375 xev.xclient.display = pDisplay ;
376 xev.xclient.message_type = None ;
377 xev.xclient.format = 8 ;
378 XSendEvent (pDisplay, XtWindow (theApp.m_wgToplevel), True, NoEventMask, &xev) ;
379 XFlush (pDisplay) ;
380 return ;
381 }
382
383 void
skkinputApp_onProtocolDestroy(register Widget gw,register XtPointer closure,register XtPointer call_data)384 skkinputApp_onProtocolDestroy (
385 register Widget gw,
386 register XtPointer closure,
387 register XtPointer call_data)
388 {
389 #if defined (SUPPORT_KINPUT)
390 if (gw == theApp.m_wgKinputProtocol) {
391 theApp.m_nProtocol -- ;
392 theApp.m_wgKinputProtocol = NULL ;
393 }
394 #endif
395 #if defined (SUPPORT_XIM)
396 if (gw == theApp.m_wgXIMProtocol) {
397 theApp.m_nProtocol -- ;
398 theApp.m_wgXIMProtocol = NULL ;
399 }
400 #endif
401 #if defined (DEBUG)
402 fprintf (stderr, "theApp.m_nProtocol = %d\n", theApp.m_nProtocol) ;
403 #endif
404 if (theApp.m_nProtocol <= 0)
405 theApp.m_fExitFlag = True ;
406 return ;
407 }
408
409 /* X IO Error �Υϥ�ɥ顣
410 */
411 int
skkinputApp_onXIoError(register Display * pDisplay)412 skkinputApp_onXIoError (
413 register Display* pDisplay)
414 {
415 #if defined (DEBUG)
416 fprintf (stderr, "skkinputApp_onXIoError (%p)\n", pDisplay) ;
417 #endif
418 if (theApp.m_pLispMgr != NULL &&
419 theApp.m_pLM != NULL) {
420 TLispClient_ClassFinalize (theApp.m_pLM) ;
421 }
422 exit (0) ;
423 }
424
425 void
skkinputApp_showUsage(register int * pnArgc,register char * pArgv[])426 skkinputApp_showUsage (
427 register int* pnArgc,
428 register char* pArgv [])
429 {
430 register int i, nArgc ;
431
432 nArgc = *pnArgc ;
433 for (i = 1 ; i < nArgc ; i ++) {
434 if (strcmp (pArgv [i], "-v") && strcmp (pArgv [i], "-version"))
435 fprintf (stderr, "Unknown option: %s\n", pArgv [i]) ;
436 }
437 fprintf (stderr, "skkinput version 3.0.6\n") ;
438 fprintf (stderr, "[usage]\n") ;
439 fprintf (stderr, " -v, -version: show version\n") ;
440 #if defined (SUPPORT_KINPUT)
441 fprintf (stderr, " -/+kinput: enable/disable kinput protocol server\n") ;
442 #endif
443 #if defined (SUPPORT_XIM)
444 fprintf (stderr, " -/+xim: enable/disable XIM protocol server\n") ;
445 #endif
446 fprintf (stderr, " -server: specify skk-server-host\n") ;
447 fprintf (stderr, " -portnum: specify skk-portnum\n") ;
448 fprintf (stderr, " -config: specify load-path (default:%s)\n", ELISP_DIR) ;
449 fprintf (stderr, " -fontset: specify default fontset\n") ;
450 fprintf (stderr, " -fg: specify default foreground pixel\n") ;
451 fprintf (stderr, " -bg: specify default background pixel\n") ;
452 fprintf (stderr, " -bd: specify default border pixel\n") ;
453 fprintf (stderr, " -/+rv: enable/disable reverse video\n") ;
454 return ;
455 }
456
457 #if defined (DEBUG_CONSOLE)
458 void
skkinputApp_testModeMainLoop(void)459 skkinputApp_testModeMainLoop (void)
460 {
461 register TLispManager* pLispMgr ;
462 register TLispMachine* pLM ;
463 TLispEntity* pEntBuffer ;
464 register TLispEntity* pEntity ;
465 char rbuf [256] ;
466 register int nLength ;
467
468 /* lisp manager ������*/
469 if (TFAILED (TLispMgr_Create (&theApp.m_pLispMgr)))
470 return ;
471 pLispMgr = theApp.m_pLispMgr ;
472 if (TFAILED (TLispMachine_Create (pLispMgr, NULL, &theApp.m_pLM)))
473 return ;
474 pLM = theApp.m_pLM ;
475 lispMgr_CreateBuffer (pLispMgr, &pEntBuffer) ;
476 lispMachine_InsertBuffer (pLM, pEntBuffer) ;
477 lispMachineCode_SetCurrentBuffer (pLM, pEntBuffer) ;
478
479 while (! feof (stdin)) {
480 printf ("> ") ;
481 fflush (stdout) ;
482 if (fgets (rbuf, NELEMENTS (rbuf), stdin) == NULL)
483 break ;
484 nLength = strlen (rbuf) ;
485 if (nLength > 0) {
486 while (nLength > 0 && (rbuf [nLength - 1] == '\n' || rbuf [nLength - 1] == '\r'))
487 nLength -- ;
488 rbuf [nLength] = '\0' ;
489 }
490 if (nLength <= 0)
491 continue ;
492
493 pEntity = lispMgr_ParseStringA (pLispMgr, rbuf, nLength, NULL) ;
494 if (pEntity != NULL)
495 TLispMachine_Test (pLM, pEntity) ;
496 fflush (stderr) ;
497 lispMgr_CollectGarbage (pLispMgr) ;
498 lispMgr_CollectGarbage (pLispMgr) ;
499 lispMgr_CollectGarbage (pLispMgr) ;
500 lispMgr_CollectGarbage (pLispMgr) ;
501 }
502 return ;
503 }
504 #endif
505
506