Mercurial > kinput2.yaz
comparison cmd/kinput2.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children | 115737ec0041 598fcbe482b5 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 /* | |
2 * kinput2 | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (C) 1991 by Software Research Associates, Inc. | |
7 * | |
8 * Permission to use, copy, modify, and distribute this software and its | |
9 * documentation for any purpose and without fee is hereby granted, provided | |
10 * that the above copyright notice appear in all copies and that both that | |
11 * copyright notice and this permission notice appear in supporting | |
12 * documentation, and that the name of Software Research Associates not be | |
13 * used in advertising or publicity pertaining to distribution of the | |
14 * software without specific, written prior permission. Software Research | |
15 * Associates makes no representations about the suitability of this software | |
16 * for any purpose. It is provided "as is" without express or implied | |
17 * warranty. | |
18 * | |
19 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
20 * ishisone@sra.co.jp | |
21 */ | |
22 | |
23 #ifndef lint | |
24 static char *rcsid = "$Id: kinput2.c,v 1.46 2002/01/06 15:13:38 ishisone Exp $"; | |
25 #endif | |
26 | |
27 #include <stdio.h> | |
28 #include <signal.h> | |
29 #include <X11/Intrinsic.h> | |
30 #include <X11/StringDefs.h> | |
31 #include <X11/Shell.h> | |
32 #include "patchlevel.h" | |
33 #include "AsyncErr.h" | |
34 #include "MyDispatch.h" | |
35 #include "IOECall.h" | |
36 #include "ConvMgr.h" | |
37 #include "KIProto.h" | |
38 #include "XimpProto.h" | |
39 #include "IMProto.h" | |
40 | |
41 #if !defined(USE_WNN) && !defined(USE_CANNA) && !defined(USE_SJ3) && !defined(USE_ATOK) | |
42 #define USE_WNN /* default */ | |
43 #endif | |
44 | |
45 #ifdef USE_WNN | |
46 #include "CcWnn.h" | |
47 #include "WcharDisp.h" | |
48 #endif | |
49 #ifdef USE_CANNA | |
50 #include "Canna.h" | |
51 #include "WcharDisp.h" | |
52 #endif | |
53 #ifdef USE_SJ3 | |
54 #include "Sj3.h" | |
55 #include "WcharDisp.h" | |
56 #endif | |
57 #ifdef USE_ATOK | |
58 #include "Atok.h" | |
59 #include "WcharDisp.h" | |
60 #endif | |
61 | |
62 #include "DebugPrint.h" | |
63 | |
64 int debug_all; | |
65 | |
66 /* application resource */ | |
67 typedef struct { | |
68 char *conversionEngine; | |
69 int debugLevel; | |
70 Boolean useKinputProtocol; | |
71 Boolean useXimpProtocol; | |
72 Boolean useXIMProtocol; | |
73 Boolean appdefs_loaded; | |
74 } AppResRec, *AppResP; | |
75 | |
76 static AppResRec appres; | |
77 | |
78 static XtResource app_resources[] = { | |
79 { "conversionEngine", "ConversionEngine", XtRString, sizeof(String), | |
80 XtOffset(AppResP, conversionEngine), XtRString, (XtPointer)"" }, | |
81 { "debugLevel", "DebugLevel", XtRInt, sizeof(int), | |
82 XtOffset(AppResP, debugLevel), XtRImmediate, (XtPointer)0 }, | |
83 { "useKinputProtocol", "UseKinputProtocol", XtRBoolean, sizeof(Boolean), | |
84 XtOffset(AppResP, useKinputProtocol), XtRImmediate, (XtPointer)True }, | |
85 { "useXimpProtocol", "UseXimpProtocol", XtRBoolean, sizeof(Boolean), | |
86 XtOffset(AppResP, useXimpProtocol), XtRImmediate, (XtPointer)True }, | |
87 { "useXIMProtocol", "UseXIMProtocol", XtRBoolean, sizeof(Boolean), | |
88 XtOffset(AppResP, useXIMProtocol), XtRImmediate, (XtPointer)True }, | |
89 { "ki2AppDefsLoaded", "Ki2AppDefsLoaded", XtRBoolean, sizeof(Boolean), | |
90 XtOffset(AppResP, appdefs_loaded), XtRImmediate, (XtPointer)True }, | |
91 }; | |
92 | |
93 static String fallback_resources[] = { | |
94 "*ki2AppDefsLoaded: false", | |
95 "Kinput2.mappedWhenManaged: false", | |
96 "Kinput2.width: 1", | |
97 "Kinput2.height: 1", | |
98 NULL, | |
99 }; | |
100 | |
101 static XrmOptionDescRec options[] = { | |
102 {"-bc", "*KinputProtocol.backwardCompatible", XrmoptionNoArg, "True"}, | |
103 {"-font", "*JpWcharDisplay.font", XrmoptionSepArg, NULL}, | |
104 {"-kanjifont", "*JpWcharDisplay.kanjiFont", XrmoptionSepArg, NULL}, | |
105 {"-kanafont", "*JpWcharDisplay.kanaFont", XrmoptionSepArg, NULL}, | |
106 {"-kinput", ".useKinputProtocol", XrmoptionNoArg, "on"}, | |
107 {"+kinput", ".useKinputProtocol", XrmoptionNoArg, "off"}, | |
108 {"-ximp", ".useXimpProtocol", XrmoptionNoArg, "on"}, | |
109 {"+ximp", ".useXimpProtocol", XrmoptionNoArg, "off"}, | |
110 {"-xim", ".useXIMProtocol", XrmoptionNoArg, "on"}, | |
111 {"+xim", ".useXIMProtocol", XrmoptionNoArg, "off"}, | |
112 {"-tbheight", "*ConversionControl.titlebarHeight", | |
113 XrmoptionSepArg, NULL}, | |
114 #ifdef DEBUG | |
115 {"-debug", ".debugLevel", XrmoptionNoArg, "1"}, | |
116 {"-trace", ".debugLevel", XrmoptionNoArg, "10"}, | |
117 {"-debuglevel", ".debugLevel", XrmoptionSepArg, NULL}, | |
118 #endif | |
119 #ifdef USE_WNN | |
120 {"-wnn", ".conversionEngine", XrmoptionNoArg, "wnn"}, | |
121 {"-jserver", "*CcWnn.jserver", XrmoptionSepArg, NULL}, | |
122 {"-ccdef", "*CcWnn.ccdef", XrmoptionSepArg, NULL}, | |
123 {"-wnnenvname", "*CcWnn.wnnEnvname", XrmoptionSepArg, NULL}, | |
124 {"-wnnenvrc4", "*CcWnn.wnnEnvrc4", XrmoptionSepArg, NULL}, | |
125 {"-wnnenvrc6", "*CcWnn.wnnEnvrc6", XrmoptionSepArg, NULL}, | |
126 {"-wnnenvrc", "*CcWnn.wnnEnvrc", XrmoptionSepArg, NULL}, | |
127 #endif | |
128 #ifdef USE_CANNA | |
129 {"-canna", ".conversionEngine", XrmoptionNoArg, "canna"}, | |
130 {"-cannaserver", "*Canna.cannahost", XrmoptionSepArg, NULL}, | |
131 {"-cs", "*Canna.cannahost", XrmoptionSepArg, NULL}, | |
132 {"-cannafile", "*Canna.cannafile", XrmoptionSepArg, NULL}, | |
133 #endif | |
134 #ifdef USE_SJ3 | |
135 {"-sj3", ".conversionEngine", XrmoptionNoArg, "sj3"}, | |
136 {"-sj3serv", "*Sj3.sj3serv", XrmoptionSepArg, NULL}, | |
137 {"-sj3serv2", "*Sj3.sj3serv2", XrmoptionSepArg, NULL}, | |
138 {"-sj3user", "*Sj3.sj3user", XrmoptionSepArg, NULL}, | |
139 {"-rcfile", "*Sj3.rcfile", XrmoptionSepArg, NULL}, | |
140 {"-sbfile", "*Sj3.sbfile", XrmoptionSepArg, NULL}, | |
141 {"-rkfile", "*Sj3.rkfile", XrmoptionSepArg, NULL}, | |
142 {"-hkfile", "*Sj3.hkfile", XrmoptionSepArg, NULL}, | |
143 {"-zhfile", "*Sj3.zhfile", XrmoptionSepArg, NULL}, | |
144 {"-sjrc", "*Sj3.rcfile", XrmoptionSepArg, NULL}, | |
145 {"-sjsb", "*Sj3.sbfile", XrmoptionSepArg, NULL}, | |
146 {"-sjrk", "*Sj3.rkfile", XrmoptionSepArg, NULL}, | |
147 {"-sjhk", "*Sj3.hkfile", XrmoptionSepArg, NULL}, | |
148 {"-sjzh", "*Sj3.zhfile", XrmoptionSepArg, NULL}, | |
149 #endif | |
150 #ifdef USE_ATOK | |
151 {"-atok", ".conversionEngine", XrmoptionNoArg, "atok"}, | |
152 {"-atokserver", "*Atok.server", XrmoptionSepArg, NULL}, | |
153 {"-as", "*Atok.server", XrmoptionSepArg, NULL}, | |
154 {"-atokport", "*Atok.port", XrmoptionSepArg, NULL}, | |
155 {"-atokconf", "*Atok.conf", XrmoptionSepArg, NULL}, | |
156 {"-atokstyle", "*Atok.style", XrmoptionSepArg, NULL}, | |
157 #endif | |
158 }; | |
159 | |
160 XtAppContext apc; | |
161 Widget toplevel; | |
162 | |
163 static int numProtocols; | |
164 static int (*DefaultErrorHandler)(); | |
165 | |
166 #if XtSpecificationRelease > 5 | |
167 static XtSignalId interrupt; | |
168 static void interruptCallback(); | |
169 #else | |
170 static void exitTimer(); | |
171 #endif | |
172 | |
173 static WidgetClass getInputObjClass(); | |
174 static int IgnoreBadWindow(); | |
175 #ifdef SIGNALRETURNSINT | |
176 static int scheduleExit(); | |
177 #else | |
178 static void scheduleExit(); | |
179 #endif | |
180 static void Destroyed(); | |
181 static void Exit(); | |
182 static void realExit(); | |
183 static void usage(); | |
184 static void print_version(); | |
185 | |
186 int | |
187 main(ac, av) | |
188 int ac; | |
189 char **av; | |
190 { | |
191 Widget manager, protocol; | |
192 int i; | |
193 WidgetClass inputobjclass, displayobjclass; | |
194 Widget inputobj; | |
195 | |
196 toplevel = XtAppInitialize(&apc, "Kinput2", | |
197 options, XtNumber(options), | |
198 &ac, av, | |
199 fallback_resources, (ArgList)NULL, 0); | |
200 | |
201 /* check invalid argument */ | |
202 if (ac > 1) { | |
203 int do_usage = 0; | |
204 for (i = 1; i < ac; i++) { | |
205 if (!strcmp(av[i], "-version")) { | |
206 print_version(); | |
207 } else { | |
208 fprintf(stderr, "unknown argument: %s\n", av[i]); | |
209 do_usage = 1; | |
210 } | |
211 } | |
212 if (do_usage) usage(); | |
213 } | |
214 | |
215 /* initialize asynchronous error handler */ | |
216 XAEInit(); | |
217 | |
218 /* initialize I/O error callback handler */ | |
219 XIOEInit(); | |
220 | |
221 XtGetApplicationResources(toplevel, &appres, | |
222 app_resources, XtNumber(app_resources), | |
223 NULL, 0); | |
224 | |
225 /* | |
226 * If the application-specific class resource file | |
227 * (the "app-defaults" file) is not found, | |
228 * print a warning message. | |
229 */ | |
230 if (!appres.appdefs_loaded) { | |
231 fprintf(stderr, "Warning: Cannot load app-defaults file.\n"); | |
232 fprintf(stderr, " Kinput2 may not work properly without it.\n"); | |
233 fprintf(stderr, " Maybe kinput2 is not installed correctly,\n"); | |
234 fprintf(stderr, " or your file search path (specified by\n"); | |
235 fprintf(stderr, " environment variable 'XFILESEARCHPATH')\n"); | |
236 fprintf(stderr, " is wrong.\n"); | |
237 } | |
238 | |
239 /* set debug level */ | |
240 debug_all = appres.debugLevel; | |
241 | |
242 #ifdef RANDOM_ID | |
243 /* | |
244 * one nasty hack here: | |
245 * | |
246 * kinput clients often use server's window ID for the only key | |
247 * value to identify their conversion server (kinput), and they | |
248 * think it is dead and take appropriate action (eg connecting to | |
249 * the new server) when they notice the ID has changed. | |
250 * | |
251 * but it is likely that another kinput has the same resource ID | |
252 * base (because X servers always choose the smallest unused ID | |
253 * base for new clients). and if it is the same, so is the owner | |
254 * window ID, and the clients don't notice the change. | |
255 * | |
256 * to get rid of the problem, we add some small random offset to | |
257 * the resource ID so that every time we get different owner ID | |
258 * even if the resource ID base is the same. | |
259 * | |
260 * of course it heavily depends on the current implementaion of | |
261 * the resource ID allocation in Xlib, so I call it 'nasty'. | |
262 */ | |
263 XtDisplay(toplevel)->resource_id += getpid() % 1024; | |
264 #endif | |
265 | |
266 inputobjclass = getInputObjClass(); | |
267 | |
268 inputobj = XtCreateWidget("inputObj", inputobjclass, | |
269 toplevel, 0, 0); | |
270 XtRealizeWidget(inputobj); | |
271 ICRegisterTriggerKeys(inputobj); | |
272 /* | |
273 Destroying the `inputobj' is postponed until all the widgets | |
274 are realized in order to prevent duplicate initialization of | |
275 input object, that is, to prevent making connection twice to | |
276 input conversion server. | |
277 */ | |
278 | |
279 displayobjclass = jpWcharDisplayObjectClass; | |
280 | |
281 manager = XtVaCreateManagedWidget("convmanager", | |
282 conversionManagerWidgetClass, | |
283 toplevel, | |
284 XtNwidth, 1, | |
285 XtNheight, 1, | |
286 NULL); | |
287 | |
288 numProtocols = 0; | |
289 | |
290 if (appres.useKinputProtocol) { | |
291 protocol = XtVaCreateWidget("kinputprotocol", | |
292 kinputProtocolWidgetClass, | |
293 manager, | |
294 XtNlanguage, "JAPANESE", | |
295 XtNinputObjectClass, inputobjclass, | |
296 XtNdisplayObjectClass, displayobjclass, | |
297 XtNwidth, 1, | |
298 XtNheight, 1, | |
299 NULL); | |
300 XtAddCallback(protocol, XtNdestroyCallback, | |
301 Destroyed, (XtPointer)NULL); | |
302 numProtocols++; | |
303 } | |
304 | |
305 if (appres.useXimpProtocol) { | |
306 protocol = XtVaCreateWidget("ximpprotocol", | |
307 ximpProtocolWidgetClass, | |
308 manager, | |
309 XtNlocaleName, "ja_JP", | |
310 XtNinputObjectClass, inputobjclass, | |
311 XtNdisplayObjectClass, displayobjclass, | |
312 XtNwidth, 1, | |
313 XtNheight, 1, | |
314 NULL); | |
315 XtAddCallback(protocol, XtNdestroyCallback, | |
316 Destroyed, (XtPointer)NULL); | |
317 numProtocols++; | |
318 } | |
319 | |
320 if (appres.useXIMProtocol) { | |
321 protocol = XtVaCreateWidget("improtocol", | |
322 imProtocolWidgetClass, | |
323 manager, | |
324 XtNlanguage, "ja_JP", | |
325 XtNinputObjectClass, inputobjclass, | |
326 XtNdisplayObjectClass, displayobjclass, | |
327 XtNwidth, 1, | |
328 XtNheight, 1, | |
329 NULL); | |
330 XtAddCallback(protocol, XtNdestroyCallback, | |
331 Destroyed, (XtPointer)NULL); | |
332 numProtocols++; | |
333 } | |
334 | |
335 if (numProtocols == 0) { | |
336 fprintf(stderr, "no protocols activated\n"); | |
337 exit(1); | |
338 } | |
339 | |
340 /* set signal handler */ | |
341 if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, scheduleExit); | |
342 #if XtSpecificationRelease > 5 | |
343 interrupt = XtAppAddSignal(apc, interruptCallback, (XtPointer)NULL); | |
344 #endif | |
345 signal(SIGTERM, scheduleExit); | |
346 #ifdef USE_WNN | |
347 signal(SIGPIPE, SIG_IGN); | |
348 #endif | |
349 | |
350 /* set my error handler */ | |
351 DefaultErrorHandler = XAESetErrorHandler(IgnoreBadWindow); | |
352 | |
353 XtRealizeWidget(toplevel); | |
354 | |
355 XtDestroyWidget(inputobj); /* Don't move this before XtRealizeWidget() */ | |
356 | |
357 for (;;) { | |
358 XEvent event; | |
359 | |
360 XtAppNextEvent(apc, &event); | |
361 XtDispatchEvent(&event); | |
362 MyDispatchEvent(&event); /* additional dispatcher */ | |
363 } | |
364 /* NOTREACHED */ | |
365 | |
366 return 0; /* for lint */ | |
367 } | |
368 | |
369 static WidgetClass | |
370 getInputObjClass() | |
371 { | |
372 WidgetClass class; | |
373 | |
374 #ifdef USE_WNN | |
375 if (!strcmp(appres.conversionEngine, "wnn")) { | |
376 return ccWnnObjectClass; | |
377 } | |
378 #endif | |
379 #ifdef USE_CANNA | |
380 if (!strcmp(appres.conversionEngine, "canna") || | |
381 !strcmp(appres.conversionEngine, "iroha")) { | |
382 return cannaObjectClass; | |
383 } | |
384 #endif | |
385 #ifdef USE_SJ3 | |
386 if (!strcmp(appres.conversionEngine, "sj3")) { | |
387 return sj3ObjectClass; | |
388 } | |
389 #endif | |
390 #ifdef USE_ATOK | |
391 if (!strcmp(appres.conversionEngine, "atok")) { | |
392 return atokObjectClass; | |
393 } | |
394 #endif | |
395 | |
396 /* set default input object */ | |
397 #ifdef USE_ATOK | |
398 class = atokObjectClass; | |
399 #endif | |
400 #ifdef USE_SJ3 | |
401 class = sj3ObjectClass; | |
402 #endif | |
403 #ifdef USE_CANNA | |
404 class = cannaObjectClass; | |
405 #endif | |
406 #ifdef USE_WNN | |
407 class = ccWnnObjectClass; | |
408 #endif | |
409 | |
410 return class; | |
411 } | |
412 | |
413 static int | |
414 IgnoreBadWindow(dpy, error) | |
415 Display *dpy; | |
416 XErrorEvent *error; | |
417 { | |
418 /* | |
419 * BadWindow events will be sent if any of the active clients die | |
420 * during conversion. Although I select DestroyNotify event on the | |
421 * client windows to detect their destruction and take appropriate | |
422 * actions, and I'm careful when doing critical operations, but still | |
423 * there is a chance of getting unexpecting BadWindow error caused by | |
424 * client death. | |
425 * There are also chances of getting BadDrawable as well. | |
426 * So I set the error handler to ignore BadWindow/BadDrawable errors. | |
427 * Of course I'd better check if the resourceid field of the error | |
428 * event is the window ID of a client, but I'm too lazy to do that... | |
429 * P.S. We should ignore BadColor also.. | |
430 */ | |
431 if (error->error_code != BadWindow && | |
432 error->error_code != BadDrawable && | |
433 error->error_code != BadColor) { | |
434 /* invoke default error handler */ | |
435 (*DefaultErrorHandler)(dpy, error); | |
436 } | |
437 return 0; | |
438 } | |
439 | |
440 #ifdef SIGNALRETURNSINT | |
441 static int | |
442 #else | |
443 static void | |
444 #endif | |
445 scheduleExit() | |
446 { | |
447 #if XtSpecificationRelease > 5 | |
448 XtNoticeSignal(interrupt); | |
449 #else | |
450 /* | |
451 * It is unwise to do complex operation (in this case, | |
452 * XtDestroyWidget) in a signal handler. | |
453 * So postpone the real work... | |
454 */ | |
455 XtAppAddTimeOut(apc, 1L, exitTimer, (XtPointer)NULL); | |
456 #endif | |
457 } | |
458 | |
459 #if XtSpecificationRelease > 5 | |
460 /* ARGSUSED */ | |
461 static void | |
462 interruptCallback(cldata, sigid) | |
463 XtPointer cldata; | |
464 XtSignalId *sigid; | |
465 { | |
466 Exit(); | |
467 } | |
468 #else | |
469 /* ARGSUSED */ | |
470 static void | |
471 exitTimer(cldata, timerp) | |
472 XtPointer cldata; | |
473 XtIntervalId *timerp; | |
474 { | |
475 Exit(); | |
476 } | |
477 #endif | |
478 | |
479 /* ARGSUSED */ | |
480 static void | |
481 Destroyed(w, client_data, call_data) | |
482 Widget w; | |
483 XtPointer client_data; | |
484 XtPointer call_data; | |
485 { | |
486 static int cnt = 0; | |
487 | |
488 /* | |
489 * if all the protocol widgets are dead, kill myself. | |
490 */ | |
491 if (++cnt >= numProtocols) Exit(); | |
492 } | |
493 | |
494 static void | |
495 Exit() | |
496 { | |
497 static int exiting = 0; | |
498 | |
499 TRACE(("Exit()\n")); | |
500 | |
501 if (exiting) return; | |
502 exiting = 1; | |
503 | |
504 /* | |
505 * Destroy all widgets. | |
506 */ | |
507 XtDestroyWidget(toplevel); | |
508 | |
509 /* | |
510 * Postpone calling exit() until next XtNextEvent(), | |
511 * in order to give each widget time to execute their | |
512 * destroy procedure. | |
513 */ | |
514 XtAppAddTimeOut(apc, 1L, realExit, (XtPointer)NULL); | |
515 } | |
516 | |
517 /* ARGSUSED */ | |
518 static void | |
519 realExit(cldata, timerp) | |
520 XtPointer cldata; | |
521 XtIntervalId *timerp; | |
522 { | |
523 exit(0); | |
524 } | |
525 | |
526 static void | |
527 usage() | |
528 { | |
529 char **p; | |
530 static char *syntaxtable[] = { | |
531 #ifdef USE_WNN | |
532 "-wnn", "use Wnn as the conversion engine", | |
533 "-jserver <hostname>", "specify jserver host", | |
534 "-ccdef <ccdeffile>", "specify character conversion def. file", | |
535 "-wnnenvname <name>", "specify Wnn environment name", | |
536 "-wnnenvrc4 <wnnenvrcfile>", "specify Wnn environment file for Wnn4", | |
537 "-wnnenvrc6 <wnnenvrcfile>", "specify Wnn environment file for Wnn6", | |
538 "-wnnenvrc <wnnenvrcfile>", "specify Wnn environment file", | |
539 #endif | |
540 #ifdef USE_CANNA | |
541 "-canna", "use Canna (Iroha) as the conversion engine", | |
542 "{-cannaserver|-cs} <hostname>[:n]", "specify cannaserver host", | |
543 "-cannafile <cannafile>", "specify canna customize file", | |
544 #endif | |
545 #ifdef USE_SJ3 | |
546 "-sj3", "use SJ3 as the conversion engine", | |
547 "-sj3serv <hostname>", "specify first sj3serv host", | |
548 "-sj3serv2 <hostname>", "specify second sj3serv host", | |
549 "-sj3user <user>", "specify user name connect to sj3serv", | |
550 "{-rcfile|-sjrc} <file>", "specify resource definition file", | |
551 "{-sbfile|-sjsb} <file>", "specify symbol table file", | |
552 "{-rkfile|-sjrk} <file>", "specify roma-kana coversion definition file", | |
553 "{-hkfile|-sjhk} <file>", "specify hira-kata coversion definition file", | |
554 "{-zhfile|-sjzh} <file>", "specify zen/han coversion definition file", | |
555 #endif | |
556 #ifdef USE_ATOK | |
557 "-atok", "use ATOK as the conversion engine", | |
558 "{-atokserver|-as} <hostname>", "specify atok server host", | |
559 "-atokport <port#>", "specify atok service port", | |
560 "-atokconf <file>", "specify atok customize file", | |
561 "-atokstyle <file>", "specify atok style file", | |
562 #endif | |
563 "-bc", "backward compatible mode", | |
564 "-font <font>", "ASCII font to be used", | |
565 "-kanjifont <font>", "KANJI font to be used", | |
566 "-kanafont <font>", "KANA font to be used", | |
567 "-/+kinput", "activate/deactivate kinput protocol family", | |
568 "-/+ximp", "activate/deactivate Ximp protocol", | |
569 "-/+xim", "activate/deactivate X Input Method protocol", | |
570 "-tbheight <number>", "specify pop-up shell's titlebar height", | |
571 "-background <color>", "background color", | |
572 "-foreground <color>", "foreground color", | |
573 "-rv", "reverse video mode", | |
574 "-display <display>", "specify display", | |
575 "-version", "print version information and exit", | |
576 #ifdef DEBUG | |
577 "-debug", "print debug messages (debug level 1)", | |
578 "-trace", "print trace messages (debug level 10)", | |
579 "-debuglevel <level>", "set debug level", | |
580 #endif | |
581 NULL, NULL, | |
582 }; | |
583 | |
584 fprintf(stderr, "options are:\n"); | |
585 for (p = syntaxtable; *p != NULL; p += 2) { | |
586 fprintf(stderr, " %-30s %s\n", *p, *(p + 1)); | |
587 } | |
588 exit(1); | |
589 } | |
590 | |
591 static void | |
592 print_version() | |
593 { | |
594 char *p; | |
595 | |
596 printf("kinput2 %s ", KINPUT2_VERSION); | |
597 if (PATCHLEVEL > 0) printf("fix %d ", PATCHLEVEL); | |
598 #ifdef STATUS | |
599 printf("-%s- ", STATUS); | |
600 #endif | |
601 printf(" ("); | |
602 p = DATE + 7; /* skip '$Date: ' */ | |
603 while (*p != '\0' && *p != ' ') { | |
604 putchar(*p); /* print date */ | |
605 p++; | |
606 } | |
607 printf(")\n"); | |
608 | |
609 printf("\toptions: "); | |
610 #ifdef USE_WNN | |
611 #ifdef USE_WNN6 | |
612 printf("[Wnn6] "); | |
613 #else | |
614 printf("[Wnn] "); | |
615 #endif | |
616 #endif | |
617 #ifdef USE_CANNA | |
618 printf("[Canna2] "); | |
619 #endif | |
620 #ifdef USE_SJ3 | |
621 printf("[Sj3] "); | |
622 #endif | |
623 #ifdef USE_ATOK | |
624 printf("[Atok] "); | |
625 #endif | |
626 #ifdef DEBUG | |
627 printf("[DEBUG] "); | |
628 #endif | |
629 printf("\n"); | |
630 exit(0); | |
631 } | |
632 | |
633 #if defined(USE_WNN) && defined(NEED_Strlen) | |
634 /* | |
635 * Wnn/jlib/js.c should have this function... | |
636 */ | |
637 int | |
638 Strlen(s) | |
639 unsigned short *s; | |
640 { | |
641 int n = 0; | |
642 | |
643 while (*s++) n++; | |
644 return n; | |
645 } | |
646 #endif |