Mercurial > kinput2.yaz
comparison lib/Sj3.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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: Sj3.c,v 2.10 1999/05/25 08:13:05 ishisone Exp $"; | |
3 #endif | |
4 /* | |
5 * Copyright (c) 1990 Software Research Associates, Inc. | |
6 * | |
7 * Permission to use, copy, modify, and distribute this software and its | |
8 * documentation for any purpose and without fee is hereby granted, provided | |
9 * that the above copyright notice appear in all copies and that both that | |
10 * copyright notice and this permission notice appear in supporting | |
11 * documentation, and that the name of Software Research Associates not be | |
12 * used in advertising or publicity pertaining to distribution of the | |
13 * software without specific, written prior permission. Software Research | |
14 * Associates makes no representations about the suitability of this software | |
15 * for any purpose. It is provided "as is" without express or implied | |
16 * warranty. | |
17 * | |
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
19 */ | |
20 /* | |
21 * Copyright 1991 Sony Corporation | |
22 * | |
23 * Permission to use, copy, modify, distribute, and sell this software and its | |
24 * documentation for any purpose is hereby granted without fee, provided that | |
25 * the above copyright notice appear in all copies and that both that | |
26 * copyright notice and this permission notice appear in supporting | |
27 * documentation, and that the name of Sony not be used in advertising or | |
28 * publicity pertaining to distribution of the software without specific, | |
29 * written prior permission. Sony makes no representations about the | |
30 * suitability of this software for any purpose. It is provided "as is" | |
31 * without express or implied warranty. | |
32 * | |
33 * SONY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL | |
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SONY | |
35 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
36 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
37 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
38 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
39 */ | |
40 /* | |
41 * Author: Naoshi Suzuki, SONY Corporation. (nao@sm.sony.co.jp) | |
42 */ | |
43 | |
44 #include <X11/IntrinsicP.h> | |
45 #include <X11/StringDefs.h> | |
46 #if XtSpecificationRelease > 4 | |
47 #include <X11/Xfuncs.h> | |
48 #endif | |
49 #include <X11/Xmu/Atoms.h> | |
50 #include <X11/Xutil.h> | |
51 #include <X11/keysym.h> | |
52 #ifdef X_LOCALE | |
53 #include <X11/Xlocale.h> | |
54 #else /* X_LOCALE */ | |
55 #include <locale.h> | |
56 #endif /* X_LOCALE */ | |
57 #include <pwd.h> | |
58 #include "Sj3P.h" | |
59 | |
60 static XtResource resources[] = { | |
61 #define offset(field) XtOffset(Sj3Object, sj3.field) | |
62 { XtNsj3serv, XtCSj3serv, XtRString, sizeof(String), | |
63 offset(sj3serv), XtRString, NULL }, | |
64 { XtNsj3serv2, XtCSj3serv2, XtRString, sizeof(String), | |
65 offset(sj3serv2), XtRString, NULL }, | |
66 { XtNsj3user, XtCSj3user, XtRString, sizeof(String), | |
67 offset(sj3user), XtRString, NULL }, | |
68 { XtNrcfile, XtCRcfile, XtRString, sizeof(String), | |
69 offset(rcfile), XtRString, NULL }, | |
70 { XtNsbfile, XtCSbfile, XtRString, sizeof(String), | |
71 offset(sbfile), XtRString, NULL }, | |
72 { XtNrkfile, XtCRkfile, XtRString, sizeof(String), | |
73 offset(rkfile), XtRString, NULL }, | |
74 { XtNhkfile, XtCHkfile, XtRString, sizeof(String), | |
75 offset(hkfile), XtRString, NULL }, | |
76 { XtNzhfile, XtCZhfile, XtRString, sizeof(String), | |
77 offset(zhfile), XtRString, NULL }, | |
78 #undef offset | |
79 }; | |
80 | |
81 static void ClassInitialize(); | |
82 static void Initialize(), Destroy(); | |
83 static Boolean SetValues(); | |
84 static int InputEvent(); | |
85 static ICString *GetMode(); | |
86 static int CursorPos(); | |
87 static int NumSegments(); | |
88 static ICString *GetSegment(); | |
89 static int CompareSegment(); | |
90 static ICString *GetItemList(); | |
91 static int SelectItem(); | |
92 static int ConvertedString(); | |
93 static int ClearConversion(); | |
94 static ICString *GetAuxSegments(); | |
95 static int PreeditString(); | |
96 static int StatusString(); | |
97 | |
98 Sj3ClassRec sj3ClassRec = { | |
99 { /* object fields */ | |
100 /* superclass */ (WidgetClass) &inputConvClassRec, | |
101 /* class_name */ "Sj3", | |
102 /* widget_size */ sizeof(Sj3Rec), | |
103 /* class_initialize */ ClassInitialize, | |
104 /* class_part_initialize */ NULL, | |
105 /* class_inited */ FALSE, | |
106 /* initialize */ Initialize, | |
107 /* initialize_hook */ NULL, | |
108 /* obj1 */ NULL, | |
109 /* obj2 */ NULL, | |
110 /* obj3 */ 0, | |
111 /* resources */ resources, | |
112 /* num_resources */ XtNumber(resources), | |
113 /* xrm_class */ NULLQUARK, | |
114 /* obj4 */ FALSE, | |
115 /* obj5 */ FALSE, | |
116 /* obj6 */ FALSE, | |
117 /* obj7 */ FALSE, | |
118 /* destroy */ Destroy, | |
119 /* obj8 */ NULL, | |
120 /* obj9 */ NULL, | |
121 /* set_values */ SetValues, | |
122 /* set_values_hook */ NULL, | |
123 /* obj10 */ NULL, | |
124 /* get_values_hook */ NULL, | |
125 /* obj11 */ NULL, | |
126 /* version */ XtVersion, | |
127 /* callback_private */ NULL, | |
128 /* obj12 */ NULL, | |
129 /* obj13 */ NULL, | |
130 /* obj14 */ NULL, | |
131 /* extension */ NULL | |
132 }, | |
133 { /* inputConv fields */ | |
134 /* InputEvent */ InputEvent, | |
135 /* GetMode */ GetMode, | |
136 /* CursorPos */ CursorPos, | |
137 /* NumSegments */ NumSegments, | |
138 /* GetSegment */ GetSegment, | |
139 /* CompareSegment */ CompareSegment, | |
140 /* GetItemList */ GetItemList, | |
141 /* SelectItem */ SelectItem, | |
142 /* GetConvertedString */ ConvertedString, | |
143 /* ClearConversion */ ClearConversion, | |
144 /* GetAuxSegments */ GetAuxSegments, | |
145 /* SupportMultipleObjects */ True, | |
146 /* GetTriggerKeys */ XtInheritGetTriggerKeys, | |
147 /* num_trigger_keys */ 0, | |
148 /* trigger_keys */ NULL, | |
149 /* GetPreeditString */ PreeditString, | |
150 /* GetStatusString */ StatusString, | |
151 /* NoMoreObjects */ False, | |
152 }, | |
153 { /* sj3 fields */ | |
154 /* foo */ (int)NULL, | |
155 } | |
156 }; | |
157 | |
158 WidgetClass sj3ObjectClass = (WidgetClass)&sj3ClassRec; | |
159 | |
160 static void startCandidate(); | |
161 static void startSymbol(); | |
162 static void startHinsi(); | |
163 static void moveSelection(); | |
164 static int endSelection(); | |
165 static int insertSelection(); | |
166 static void hinsiInit(); | |
167 static void symbolInit(); | |
168 static void allocCandlist(); | |
169 static void startRegistration(); | |
170 static void changeRegistration(); | |
171 static void endRegistration(); | |
172 static void setLocale(); | |
173 static void setUser(); | |
174 | |
175 static void addObject(); | |
176 static void deleteObject(); | |
177 static void bell(); | |
178 | |
179 static ICString *SymbolList = NULL; | |
180 static int NumSymbol; | |
181 static ICString *HinsiList = NULL; | |
182 static int NumHinsi; | |
183 | |
184 static int clcount = 0; | |
185 | |
186 static int usr_code; | |
187 static char home[256]; | |
188 static char uname[32]; | |
189 | |
190 /* | |
191 * ClassInitialize() | |
192 * Initialize common resource. | |
193 */ | |
194 static void | |
195 ClassInitialize() | |
196 { | |
197 setLocale(); | |
198 setUser(); | |
199 | |
200 Xsj3cSetInLang(usr_code); | |
201 Xsj3cSetOutLang(JP_EUC); | |
202 } | |
203 | |
204 /* | |
205 * setLocale() | |
206 * Set locale and decide file code for all set-up files. | |
207 */ | |
208 static void | |
209 setLocale() | |
210 { | |
211 char *loc; | |
212 | |
213 #ifdef X_LOCALE | |
214 if (loc = _Xsetlocale (LC_CTYPE, "")) { | |
215 #else /* X_LOCALE */ | |
216 if (loc = setlocale (LC_CTYPE, "")) { | |
217 #endif /* X_LOCALE */ | |
218 if (!strcmp(loc, "ja_JP.SJIS")||!strcmp(loc, "ja_JP.mscode")) | |
219 usr_code = JP_SJIS; | |
220 else if (!strcmp(loc, "ja_JP.jis7")) | |
221 usr_code = JP_JIS7; | |
222 else if (!strcmp(loc, "ja_JP.jis8")) | |
223 usr_code = JP_JIS8; | |
224 else | |
225 usr_code = JP_EUC; | |
226 } else | |
227 usr_code = JP_EUC; | |
228 #ifdef FORCE_SJIS | |
229 usr_code = JP_SJIS; | |
230 #endif | |
231 #ifdef FORCE_JIS8 | |
232 usr_code = JP_JIS8; | |
233 #endif | |
234 #ifdef FORCE_JIS7 | |
235 usr_code = JP_JIS7; | |
236 #endif | |
237 } | |
238 | |
239 /* | |
240 * setUser() | |
241 * Set user name and home directory. | |
242 */ | |
243 static void | |
244 setUser() | |
245 { | |
246 extern char *getenv(), *getlogin(); | |
247 char *login; | |
248 struct passwd *pwd, *getpwnam(), *getpwuid(); | |
249 | |
250 | |
251 if (login = getlogin()) | |
252 strcpy(uname, login); | |
253 setpwent(); | |
254 if (!uname || *uname == '\0') { | |
255 if (pwd = getpwuid(getuid())) { | |
256 strcpy(uname, pwd->pw_name); | |
257 } | |
258 } else { | |
259 pwd = getpwnam(uname); | |
260 } | |
261 if (pwd) | |
262 strcpy(home, pwd->pw_dir); | |
263 else | |
264 strcpy(home, getenv("HOME")); | |
265 endpwent(); | |
266 } | |
267 | |
268 /* | |
269 * InputEvent() | |
270 * KeyPress event dispatch routine | |
271 */ | |
272 static int | |
273 InputEvent(w, ev) | |
274 Widget w; | |
275 XEvent *ev; | |
276 { | |
277 Sj3Object obj = (Sj3Object)w; | |
278 Xsj3cBuf buf = obj->sj3.sj3buf; | |
279 int ret = 0, len, nbytes; | |
280 unsigned char *pre; | |
281 unsigned long modmask; | |
282 KeySym ks; | |
283 register Xsj3cEvent value, select, dict; | |
284 | |
285 /* KeyPress$B0J30$O<N$F$k(B */ | |
286 if (ev->type != KeyPress) | |
287 return ret; | |
288 | |
289 pre = Xsj3cGetPreeditArea(buf, &len); | |
290 | |
291 /* $B%$%Y%s%H$rJ8;zNs5Z$S(B KeySym $B$KJQ49$9$k(B */ | |
292 nbytes = XmuLookupKana((XKeyPressedEvent *)ev, (char *)pre, len, &ks, NULL); | |
293 modmask = ev->xkey.state & 0xff; | |
294 | |
295 value = Xsj3cKeyConv(buf, nbytes, modmask, ks); | |
296 | |
297 if (select = (value & KEY_SELECT)) { | |
298 switch (select) { | |
299 case KEY_CAND_START: | |
300 startCandidate(obj); | |
301 break; | |
302 case KEY_SYMBOL_START: | |
303 startSymbol(obj); | |
304 break; | |
305 case KEY_HINSI_START: | |
306 startHinsi(obj); | |
307 break; | |
308 case KEY_SELECT_RIGHT: | |
309 moveSelection(obj, ICMoveRight); | |
310 break; | |
311 case KEY_SELECT_LEFT: | |
312 moveSelection(obj, ICMoveLeft); | |
313 break; | |
314 case KEY_SELECT_UP: | |
315 moveSelection(obj, ICMoveUp); | |
316 break; | |
317 case KEY_SELECT_DOWN: | |
318 moveSelection(obj, ICMoveDown); | |
319 break; | |
320 case KEY_SELECT_FIRST: | |
321 moveSelection(obj, ICMoveFirst); | |
322 break; | |
323 case KEY_SELECT_LAST: | |
324 moveSelection(obj, ICMoveLast); | |
325 break; | |
326 case KEY_SELECT_NEXTP: | |
327 moveSelection(obj, ICMoveNextPage); | |
328 break; | |
329 case KEY_SELECT_PREVP: | |
330 moveSelection(obj, ICMovePrevPage); | |
331 break; | |
332 case KEY_SELECT_RIGHTMOST: | |
333 moveSelection(obj, ICMoveRightMost); | |
334 break; | |
335 case KEY_SELECT_LEFTMOST: | |
336 moveSelection(obj, ICMoveLeftMost); | |
337 break; | |
338 case KEY_SELECT_END: | |
339 endSelection(obj, False); | |
340 break; | |
341 case KEY_SELECT_ABORT: | |
342 endSelection(obj, True); | |
343 break; | |
344 default: | |
345 break; | |
346 } | |
347 } | |
348 if (dict = (value & KEY_DICT)) { | |
349 switch (dict) { | |
350 case KEY_DICT_START: | |
351 startRegistration(obj); | |
352 break; | |
353 case KEY_DICT_CHANGE: | |
354 changeRegistration(obj); | |
355 break; | |
356 case KEY_DICT_REGISTER: | |
357 Xsj3cDictRegister(buf); | |
358 changeRegistration(obj); | |
359 break; | |
360 case KEY_DICT_CLEAR: | |
361 Xsj3cDictClear(buf); | |
362 changeRegistration(obj); | |
363 break; | |
364 case KEY_DICT_END: | |
365 endRegistration(obj); | |
366 break; | |
367 default: | |
368 break; | |
369 } | |
370 } | |
371 if (value & KEY_CONTROL || value == KEY_NULL) | |
372 ret = 1; | |
373 if (value & KEY_CHANGE){ | |
374 if (value & KEY_MODE_CHANGE) { | |
375 /* Change display mode string */ | |
376 XtCallCallbackList(w, obj->inputConv.modechangecallback, | |
377 (XtPointer)NULL); | |
378 } | |
379 if (value & KEY_TEXT_FIXED) { | |
380 /* Fix converting strings */ | |
381 XtCallCallbackList(w, obj->inputConv.fixcallback, | |
382 (XtPointer)NULL); | |
383 Xsj3cFixBuffer(buf); | |
384 } else if (value & KEY_TEXT_FLUSH) { | |
385 /* Fix & Input strings at same time */ | |
386 XtCallCallbackList(w, obj->inputConv.fixcallback, | |
387 (XtPointer)NULL); | |
388 Xsj3cFlushBuffer(buf); | |
389 } | |
390 if (value & KEY_TEXT_CHANGE) { | |
391 /* Change converting strings */ | |
392 XtCallCallbackList(w, obj->inputConv.textchangecallback, | |
393 (XtPointer)NULL); | |
394 } | |
395 if (value & KEY_HENKAN_END) { | |
396 /* End conversion */ | |
397 XtCallCallbackList((Widget)obj, obj->inputConv.endcallback, | |
398 (XtPointer)NULL); | |
399 Xsj3cClearBuffer(buf); | |
400 } | |
401 } | |
402 if (value & KEY_BELL){ | |
403 bell(obj); | |
404 return ret; | |
405 } else if (value & KEY_RECONNECT) { | |
406 Xsj3cConnect(buf, obj->sj3.sj3serv, | |
407 obj->sj3.sj3serv2, obj->sj3.sj3user); | |
408 Xsj3cClearBuffer(buf); | |
409 return ret; | |
410 } | |
411 return ret; | |
412 } | |
413 | |
414 static ICString * | |
415 GetMode(w) | |
416 Widget w; | |
417 { | |
418 Sj3Object obj = (Sj3Object)w; | |
419 Xsj3cBuf buf = obj->sj3.sj3buf; | |
420 int len; | |
421 static ICString icstr; | |
422 | |
423 icstr.data = (char *)Xsj3cGetModeStr(buf, &len); | |
424 icstr.nchars = len; | |
425 icstr.nbytes = icstr.nchars * sizeof(wchar); | |
426 icstr.attr = ICAttrNormalString; | |
427 return &icstr; | |
428 } | |
429 | |
430 static int | |
431 CursorPos(w, nsegp, ncharp) | |
432 Widget w; | |
433 Cardinal *nsegp; | |
434 Cardinal *ncharp; | |
435 { | |
436 Sj3Object obj = (Sj3Object)w; | |
437 Xsj3cBuf buf = obj->sj3.sj3buf; | |
438 | |
439 return(Xsj3cGetPosition(buf, nsegp, ncharp)); | |
440 } | |
441 | |
442 static int | |
443 NumSegments(w) | |
444 Widget w; | |
445 { | |
446 Sj3Object obj = (Sj3Object)w; | |
447 Xsj3cBuf buf = obj->sj3.sj3buf; | |
448 | |
449 return (Xsj3cGetSegNum(buf)); | |
450 } | |
451 | |
452 static ICString * | |
453 GetSegment(w, n) | |
454 Widget w; | |
455 Cardinal n; | |
456 { | |
457 Sj3Object obj = (Sj3Object)w; | |
458 Xsj3cBuf buf = obj->sj3.sj3buf; | |
459 static ICString seg; | |
460 int len, attr; | |
461 | |
462 seg.data = (char *)Xsj3cGetSeg(buf, n, &len, &attr); | |
463 seg.nchars = len; | |
464 seg.nbytes = seg.nchars * sizeof(wchar); | |
465 switch (attr) { | |
466 case SEG_REVERSED: | |
467 seg.attr = ICAttrConverted|ICAttrCurrentSegment; | |
468 break; | |
469 case SEG_UNDER_LINE: | |
470 seg.attr = ICAttrNotConverted; | |
471 break; | |
472 case SEG_NORMAL: | |
473 seg.attr = ICAttrConverted; | |
474 break; | |
475 default: | |
476 seg.attr = ICAttrConverted; | |
477 break; | |
478 } | |
479 | |
480 return &seg; | |
481 } | |
482 | |
483 /* ARGSUSED */ | |
484 static int | |
485 CompareSegment(w, seg1, seg2, n) | |
486 Widget w; | |
487 ICString *seg1; | |
488 ICString *seg2; | |
489 Cardinal *n; | |
490 { | |
491 register unsigned char *p, *q; | |
492 register int len, nsame = 0; | |
493 int result = ICSame; | |
494 | |
495 if (seg1->attr != seg2->attr) | |
496 result |= ICAttrChanged; | |
497 | |
498 len = seg1->nbytes > seg2->nbytes ? seg2->nbytes : seg1->nbytes; | |
499 p = (unsigned char *)seg1->data; | |
500 q = (unsigned char *)seg2->data; | |
501 while (nsame < len && *p++ == *q++) nsame++; | |
502 | |
503 if (nsame != len || len != seg1->nbytes | |
504 || len != seg2->nbytes || seg1->data != seg2->data) | |
505 result |= ICStringChanged; | |
506 | |
507 if (n) | |
508 *n = nsame / sizeof(wchar); | |
509 | |
510 return result; | |
511 | |
512 } | |
513 | |
514 static ICString * | |
515 GetItemList(w, n) | |
516 Widget w; | |
517 Cardinal *n; | |
518 { | |
519 Sj3Object obj = (Sj3Object)w; | |
520 | |
521 switch (obj->sj3.state) { | |
522 case candidate_state: | |
523 *n = obj->sj3.numcand; | |
524 return obj->sj3.candlist; | |
525 case symbol_state: | |
526 *n = NumSymbol; | |
527 return obj->sj3.symbollist; | |
528 case hinsi_state: | |
529 *n = NumHinsi; | |
530 return obj->sj3.hinsilist; | |
531 default: | |
532 *n = 0; | |
533 return NULL; /* no item available */ | |
534 } | |
535 /* NOTREACHED */ | |
536 | |
537 } | |
538 | |
539 static int | |
540 SelectItem(w, n) | |
541 Widget w; | |
542 int n; | |
543 { | |
544 Sj3Object obj = (Sj3Object)w; | |
545 Xsj3cBuf buf = obj->sj3.sj3buf; | |
546 int ret = 0, changed = False, flush = False; | |
547 | |
548 if (obj->sj3.state == normal_state ) | |
549 return -1; | |
550 else if (n >= 0) | |
551 ret = insertSelection(obj, n, &changed, &flush); | |
552 | |
553 switch (obj->sj3.state) { | |
554 case candidate_state: | |
555 Xsj3cEndCandidate(buf, changed); | |
556 break; | |
557 case symbol_state: | |
558 Xsj3cEndSymbol(buf); | |
559 break; | |
560 case hinsi_state: | |
561 Xsj3cEndHinsi(buf); | |
562 break; | |
563 default: | |
564 XtAppWarning(XtWidgetToApplicationContext((Widget)obj), | |
565 "sj3 Object: Unknown ConvMode state"); | |
566 break; | |
567 } | |
568 obj->sj3.state = normal_state; | |
569 | |
570 if (changed) { | |
571 if (flush) { | |
572 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback, | |
573 (XtPointer)NULL); | |
574 Xsj3cFlushBuffer(buf); | |
575 } | |
576 XtCallCallbackList((Widget)obj, | |
577 obj->inputConv.textchangecallback, | |
578 (XtPointer)NULL); | |
579 } | |
580 | |
581 return ret; | |
582 | |
583 } | |
584 | |
585 static int | |
586 ConvertedString(w, encoding, format, length, string) | |
587 Widget w; | |
588 Atom *encoding; | |
589 int *format; | |
590 int *length; | |
591 XtPointer *string; | |
592 { | |
593 Sj3Object obj = (Sj3Object)w; | |
594 Xsj3cBuf buf = obj->sj3.sj3buf; | |
595 wchar *wbuf, *wp; | |
596 wchar *data; | |
597 int len, wlen; | |
598 extern int convJWStoCT(); | |
599 | |
600 wlen = Xsj3cGetConvertedLength(buf); | |
601 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); | |
602 | |
603 if ((Xsj3cGetConvertedStr(buf, wbuf)) == NULL) { | |
604 XtAppWarning(XtWidgetToApplicationContext(w), | |
605 "sj3 Object: Could not get converted string"); | |
606 return -1; | |
607 } | |
608 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject((Widget)obj)); | |
609 *format = 8; | |
610 | |
611 for (wp = wbuf; *wp != 0; wp++) { | |
612 if (*wp == '\r') *wp = '\n'; | |
613 } | |
614 | |
615 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); | |
616 *string = XtMalloc(len + 1); | |
617 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); | |
618 | |
619 XtFree((char *)wbuf); | |
620 | |
621 return 0; | |
622 } | |
623 | |
624 static int | |
625 ClearConversion(w) | |
626 Widget w; | |
627 { | |
628 Sj3Object obj = (Sj3Object)w; | |
629 Xsj3cBuf buf = obj->sj3.sj3buf; | |
630 | |
631 Xsj3cClearBuffer(buf); | |
632 XtCallCallbackList(w, obj->inputConv.textchangecallback, (XtPointer)NULL); | |
633 return 0; | |
634 } | |
635 | |
636 static ICString * | |
637 GetAuxSegments(w, n, ns, nc) | |
638 Widget w; | |
639 Cardinal *n, *ns, *nc; | |
640 { | |
641 Sj3Object obj = (Sj3Object)w; | |
642 Xsj3cBuf buf = obj->sj3.sj3buf; | |
643 register int i; | |
644 register Xsj3cDictMsg p; | |
645 register ICString *seg; | |
646 static ICString *ics; | |
647 | |
648 *n = Xsj3cGetDictMsgNum(buf); | |
649 if (!ics) { | |
650 ics = (ICString *)XtCalloc(*n, sizeof(ICString)); | |
651 } else { | |
652 ics = (ICString *)XtRealloc((char *)ics, *n * sizeof(ICString)); | |
653 } | |
654 bzero(ics, *n * sizeof(ICString)); | |
655 for (i = 0, seg = ics, p = Xsj3cGetDictMsgs(buf); | |
656 i < *n; i++, seg++) { | |
657 seg->data = (char *)p[i].data; | |
658 seg->nchars = p[i].len; | |
659 seg->nbytes = seg->nchars * sizeof(wchar); | |
660 switch (p[i].attr) { | |
661 case SEG_REVERSED: | |
662 seg->attr = ICAttrConverted|ICAttrCurrentSegment; | |
663 break; | |
664 case SEG_UNDER_LINE: | |
665 seg->attr = ICAttrNotConverted; | |
666 break; | |
667 case SEG_NORMAL: | |
668 seg->attr = ICAttrConverted; | |
669 break; | |
670 default: | |
671 seg->attr = ICAttrNotConverted; | |
672 break; | |
673 } | |
674 } | |
675 *ns = *n - 1; | |
676 *nc = 0; | |
677 | |
678 return ics; | |
679 } | |
680 | |
681 /* ARGSUSED */ | |
682 static int | |
683 PreeditString(w, segn, offset, encoding, format, length, string) | |
684 Widget w; | |
685 int segn; | |
686 int offset; | |
687 Atom *encoding; | |
688 int *format; | |
689 int *length; | |
690 XtPointer *string; | |
691 { | |
692 Sj3Object obj = (Sj3Object)w; | |
693 Xsj3cBuf buf = obj->sj3.sj3buf; | |
694 int segnum = Xsj3cGetSegNum(buf); | |
695 int seglen, junk; | |
696 wchar *segdata; | |
697 Boolean deleted; | |
698 int i; | |
699 wchar *wbuf, *wp; | |
700 int len, wlen; | |
701 extern int convJWStoCT(); | |
702 | |
703 if (segn < segnum) { | |
704 segdata = Xsj3cGetSeg(buf, segn, &seglen, &junk); | |
705 if (offset >= seglen) { | |
706 /* $B%;%0%a%s%H$N:G8e(B */ | |
707 ++segn; | |
708 offset = 0; | |
709 } | |
710 } | |
711 if (segn >= segnum) { | |
712 deleted = True; | |
713 } | |
714 else { | |
715 segdata = Xsj3cGetSeg(buf, segn, &seglen, &junk); | |
716 deleted = (offset >= seglen); | |
717 } | |
718 if (deleted) { | |
719 /* $B:o=|$5$l$?(B */ | |
720 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); | |
721 *format = 8; | |
722 *length = 0; | |
723 *string = (XtPointer)XtMalloc(1); | |
724 return 0; | |
725 } | |
726 | |
727 wlen = 0; | |
728 for (i = segn; i < segnum; i++) { | |
729 segdata = Xsj3cGetSeg(buf, i, &seglen, &junk); | |
730 wlen += seglen; | |
731 } | |
732 wlen -= offset; | |
733 | |
734 wp = wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); | |
735 segdata = Xsj3cGetSeg(buf, segn, &seglen, &junk); | |
736 len = seglen - offset; | |
737 (void)bcopy((char *)(segdata + offset), (char *)wp, sizeof(wchar) * len); | |
738 wp += len; | |
739 for (i = segn + 1; i < segnum; i++) { | |
740 segdata = Xsj3cGetSeg(buf, i, &seglen, &junk); | |
741 (void)bcopy((char *)segdata, (char *)wp, sizeof(wchar) * seglen); | |
742 wp += seglen; | |
743 } | |
744 wbuf[wlen] = 0; | |
745 | |
746 /* | |
747 * Sj3 $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B | |
748 * COMPOUND_TEXT $B$KJQ49$9$k(B | |
749 */ | |
750 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); | |
751 *format = 8; | |
752 | |
753 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ | |
754 for (wp = wbuf; *wp != 0; wp++) { | |
755 if (*wp == '\r') *wp = '\n'; | |
756 } | |
757 | |
758 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); | |
759 *string = (XtPointer)XtMalloc(len + 1); | |
760 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); | |
761 | |
762 /* wbuf $B$r(B free $B$7$F$*$/(B */ | |
763 XtFree((char *)wbuf); | |
764 | |
765 return 0; | |
766 } | |
767 | |
768 /* ARGSUSED */ | |
769 static int | |
770 StatusString(w, encoding, format, length, string, nchars) | |
771 Widget w; | |
772 Atom *encoding; | |
773 int *format; | |
774 int *length; | |
775 XtPointer *string; | |
776 int *nchars; | |
777 { | |
778 ICString *seg; | |
779 wchar *wbuf, *wp; | |
780 int len, wlen; | |
781 extern int convJWStoCT(); | |
782 | |
783 seg = GetMode(w); | |
784 if (seg == NULL) { | |
785 *length = *nchars = 0; | |
786 return -1; | |
787 } | |
788 | |
789 wlen = seg->nchars; | |
790 if (wlen <= 0) { | |
791 *length = *nchars = 0; | |
792 return -1; | |
793 } | |
794 | |
795 /* | |
796 * data $B$KF~$C$F$$$kJQ49%F%-%9%H$O(B null $B%?!<%_%M!<%H$5$l$F$$$J$$$+$b(B | |
797 * $B$7$l$J$$$N$G!"$^$:%3%T!<$7$F(B null $B%?!<%_%M!<%H$9$k(B | |
798 */ | |
799 wbuf = (wchar *)XtMalloc((wlen + 1) * sizeof(wchar)); | |
800 (void)bcopy(seg->data, (char *)wbuf, sizeof(wchar) * wlen); | |
801 wbuf[wlen] = 0; | |
802 | |
803 /* | |
804 * Sj3 $B%*%V%8%'%/%H$O(B COMPOUND_TEXT $B%(%s%3!<%G%#%s%0$7$+%5%]!<%H$7$J$$(B | |
805 * COMPOUND_TEXT $B$KJQ49$9$k(B | |
806 */ | |
807 *encoding = XA_COMPOUND_TEXT(XtDisplayOfObject(w)); | |
808 *format = 8; | |
809 | |
810 /* COMPOUND_TEXT $B$O(B \r $B$,Aw$l$J$$$N$G(B \n $B$KJQ49$7$F$*$/(B */ | |
811 for (wp = wbuf; *wp != 0; wp++) { | |
812 if (*wp == '\r') *wp = '\n'; | |
813 } | |
814 | |
815 *length = len = convJWStoCT(wbuf, (unsigned char *)NULL, 0); | |
816 *string = XtMalloc(len + 1); | |
817 (void)convJWStoCT(wbuf, (unsigned char *)*string, 0); | |
818 *nchars = seg->nchars; | |
819 | |
820 /* wbuf $B$r(B free $B$7$F$*$/(B */ | |
821 XtFree((char *)wbuf); | |
822 | |
823 return 0; | |
824 } | |
825 | |
826 /* ARGSUSED */ | |
827 static void | |
828 Initialize(req, new, args, num_args) | |
829 Widget req; | |
830 Widget new; | |
831 ArgList args; | |
832 Cardinal *num_args; | |
833 { | |
834 Sj3Object obj = (Sj3Object)new; | |
835 Xsj3cBuf buf = NULL; | |
836 int min_keycode, max_keycode, keysyms_per_keycode; | |
837 register int i, j, k; | |
838 unsigned long kanamod = 0; | |
839 KeySym *keymap; | |
840 XModifierKeymap *modmap; | |
841 | |
842 obj->sj3.symbollist = SymbolList; | |
843 obj->sj3.hinsilist = HinsiList; | |
844 obj->sj3.candlist = NULL; | |
845 obj->sj3.numcand = 0; | |
846 obj->sj3.curcand = 0; | |
847 obj->sj3.cursymbol = 0; | |
848 obj->sj3.curhinsi = 0; | |
849 obj->sj3.candlistsize = 0; | |
850 obj->sj3.state = normal_state; | |
851 obj->sj3.selectionending = False; | |
852 | |
853 if (!obj->sj3.sj3user || *obj->sj3.sj3user == '\0') | |
854 obj->sj3.sj3user = uname; | |
855 | |
856 if (!clcount++) { | |
857 /* Get kana lock modmask */ | |
858 XDisplayKeycodes (XtDisplayOfObject((Widget)obj), | |
859 &min_keycode, &max_keycode); | |
860 keymap = XGetKeyboardMapping (XtDisplayOfObject((Widget)obj), | |
861 min_keycode, (max_keycode - min_keycode + 1), | |
862 &keysyms_per_keycode); | |
863 XFree(keymap); | |
864 | |
865 if (keysyms_per_keycode == 4) { | |
866 modmap = XGetModifierMapping(XtDisplayOfObject((Widget)obj)); | |
867 k = 0; | |
868 for (i = 0; i < 8; i++) { | |
869 for (j = 0; j < modmap->max_keypermod; j++) { | |
870 if (XK_Mode_switch == | |
871 XKeycodeToKeysym(XtDisplayOfObject((Widget)obj), | |
872 modmap->modifiermap[k], 0)) { | |
873 kanamod |= 1 << i; | |
874 } | |
875 k++; | |
876 } | |
877 } | |
878 XFreeModifiermap(modmap); | |
879 } | |
880 | |
881 /* Set kana lock modmask */ | |
882 Xsj3cSetKanaMod(kanamod); | |
883 | |
884 } | |
885 | |
886 /* Making buffer for Xsj3clib */ | |
887 buf = obj->sj3.sj3buf = Xsj3cCreateBuffer(); | |
888 if (!buf) { | |
889 XtAppError(XtWidgetToApplicationContext(new), | |
890 "sj3 Object: Failed to allocate buffers"); | |
891 } | |
892 | |
893 /* Read user resource customize file and set flags */ | |
894 (void)Xsj3cRCInit(buf, obj->sj3.rcfile, home); | |
895 | |
896 /* Convertion table initialization */ | |
897 Xsj3cInitializeTables(buf, home, obj->sj3.rkfile, obj->sj3.hkfile, | |
898 obj->sj3.zhfile, obj->sj3.sbfile); | |
899 | |
900 /* Connect to Kana-kanji conversion server */ | |
901 if ((Xsj3cOpen(buf, obj->sj3.sj3serv, | |
902 obj->sj3.sj3user, False, False)) != CONNECT_OK) { | |
903 XtAppWarning(XtWidgetToApplicationContext(new), | |
904 "sj3 Object: Failed to connect first server, then try to second server"); | |
905 if ((Xsj3cOpen(buf, obj->sj3.sj3serv2, | |
906 obj->sj3.sj3user, False, True)) != CONNECT_OK) { | |
907 XtAppError(XtWidgetToApplicationContext(new), | |
908 "sj3 Object: Failed to connect to second server"); | |
909 } | |
910 }; | |
911 | |
912 addObject(obj); | |
913 } | |
914 | |
915 static void | |
916 Destroy(w) | |
917 Widget w; | |
918 { | |
919 Sj3Object obj = (Sj3Object)w; | |
920 Xsj3cBuf buf = obj->sj3.sj3buf; | |
921 | |
922 Xsj3cClose(buf, False); | |
923 Xsj3cFreeBuffer(buf); | |
924 deleteObject(obj); | |
925 } | |
926 | |
927 static void | |
928 symbolInit(obj) | |
929 Sj3Object obj; | |
930 { | |
931 Xsj3cBuf buf = obj->sj3.sj3buf; | |
932 register ICString *strp; | |
933 register int i; | |
934 register Xsj3cSymbol p; | |
935 | |
936 for (i = 0, strp = SymbolList, p = Xsj3cGetSymbols(buf); | |
937 i < NumSymbol; i++, strp++) { | |
938 strp->data = (char *)p[i].data; | |
939 strp->nchars = p[i].len; | |
940 strp->nbytes = strp->nchars * sizeof(wchar); | |
941 strp->attr = ICAttrNormalString; | |
942 } | |
943 } | |
944 | |
945 static void | |
946 startSymbol(obj) | |
947 Sj3Object obj; | |
948 { | |
949 Xsj3cBuf buf = obj->sj3.sj3buf; | |
950 ICSelectionControlArg arg; | |
951 | |
952 /* Symbol list initialization */ | |
953 if (!SymbolList) { | |
954 NumSymbol = Xsj3cGetSymbolNum(buf, &obj->sj3.cursymbol); | |
955 SymbolList = (ICString *)XtMalloc(NumSymbol * sizeof(ICString)); | |
956 symbolInit(obj); | |
957 obj->sj3.symbollist = SymbolList; | |
958 } else if (!obj->sj3.symbollist) { | |
959 obj->sj3.symbollist = SymbolList; | |
960 } | |
961 | |
962 obj->sj3.state = symbol_state; | |
963 | |
964 arg.command = ICSelectionStart; | |
965 arg.u.selection_kind = ICSelectionCandidates; | |
966 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
967 (XtPointer)&arg); | |
968 | |
969 /* set current item */ | |
970 arg.command = ICSelectionSet; | |
971 arg.u.current_item = obj->sj3.cursymbol; | |
972 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
973 (XtPointer)&arg); | |
974 } | |
975 | |
976 static void | |
977 startCandidate(obj) | |
978 Sj3Object obj; | |
979 { | |
980 Xsj3cBuf buf = obj->sj3.sj3buf; | |
981 ICSelectionControlArg arg; | |
982 register ICString *strp; | |
983 register int i; | |
984 int ncand, curcand; | |
985 register Xsj3cCand p; | |
986 | |
987 if ((ncand = Xsj3cGetCandidateNum(buf, &curcand)) <= 0) { | |
988 bell(obj); | |
989 return; | |
990 } | |
991 obj->sj3.curcand = curcand; | |
992 obj->sj3.numcand = ncand; | |
993 | |
994 allocCandlist(obj, obj->sj3.numcand); | |
995 | |
996 for (i = 0, strp = obj->sj3.candlist, p = Xsj3cGetCandidates(buf); | |
997 i < obj->sj3.numcand; i++, strp++) { | |
998 strp->data = (char *)p[i].data; | |
999 strp->nchars = p[i].len; | |
1000 strp->nbytes = strp->nchars * sizeof(wchar); | |
1001 strp->attr = ICAttrNormalString; | |
1002 } | |
1003 | |
1004 obj->sj3.state = candidate_state; | |
1005 | |
1006 arg.command = ICSelectionStart; | |
1007 arg.u.selection_kind = ICSelectionCandidates; | |
1008 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1009 (XtPointer)&arg); | |
1010 | |
1011 /* set current candidate */ | |
1012 arg.command = ICSelectionSet; | |
1013 arg.u.current_item = curcand; | |
1014 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1015 (XtPointer)&arg); | |
1016 } | |
1017 | |
1018 static void | |
1019 hinsiInit(obj) | |
1020 Sj3Object obj; | |
1021 { | |
1022 Xsj3cBuf buf = obj->sj3.sj3buf; | |
1023 register ICString *strp; | |
1024 register int i; | |
1025 register Xsj3cHinsi p; | |
1026 | |
1027 for (i = 0, strp = HinsiList, p = Xsj3cGetHinsis(buf); | |
1028 i < NumHinsi; i++, strp++) { | |
1029 strp->data = (char *)p[i].data; | |
1030 strp->nchars = p[i].len; | |
1031 strp->nbytes = strp->nchars * sizeof(wchar); | |
1032 strp->attr = ICAttrNormalString; | |
1033 } | |
1034 } | |
1035 | |
1036 static void | |
1037 startHinsi(obj) | |
1038 Sj3Object obj; | |
1039 { | |
1040 Xsj3cBuf buf = obj->sj3.sj3buf; | |
1041 ICSelectionControlArg arg; | |
1042 | |
1043 /* Hinsi list initialization */ | |
1044 if (!HinsiList) { | |
1045 NumHinsi = Xsj3cGetHinsiNum(buf, &obj->sj3.curhinsi); | |
1046 HinsiList = (ICString *)XtMalloc(NumHinsi * sizeof(ICString)); | |
1047 hinsiInit(obj); | |
1048 obj->sj3.hinsilist = HinsiList; | |
1049 } else if (!obj->sj3.hinsilist) { | |
1050 obj->sj3.hinsilist = HinsiList; | |
1051 } | |
1052 | |
1053 obj->sj3.state = hinsi_state; | |
1054 | |
1055 arg.command = ICSelectionStart; | |
1056 arg.u.selection_kind = ICSelectionCandidates; | |
1057 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1058 (XtPointer)&arg); | |
1059 | |
1060 /* set current item */ | |
1061 arg.command = ICSelectionSet; | |
1062 arg.u.current_item = obj->sj3.curhinsi; | |
1063 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1064 (XtPointer)&arg); | |
1065 } | |
1066 | |
1067 static void | |
1068 moveSelection(obj, dir) | |
1069 Sj3Object obj; | |
1070 int dir; | |
1071 { | |
1072 ICSelectionControlArg arg; | |
1073 | |
1074 if (obj->sj3.state == normal_state) return; | |
1075 arg.command = ICSelectionMove; | |
1076 arg.u.dir = dir; | |
1077 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1078 (XtPointer)&arg); | |
1079 } | |
1080 | |
1081 static int | |
1082 endSelection(obj, abort) | |
1083 Sj3Object obj; | |
1084 int abort; | |
1085 { | |
1086 ICSelectionControlArg arg; | |
1087 int selected; | |
1088 int ret = 0, changed = False, flush = False; | |
1089 Xsj3cBuf buf = obj->sj3.sj3buf; | |
1090 | |
1091 if (obj->sj3.selectionending) | |
1092 return 0; | |
1093 | |
1094 if (obj->sj3.state == normal_state) | |
1095 return -1; | |
1096 | |
1097 arg.command = ICSelectionEnd; | |
1098 arg.u.current_item = -1; | |
1099 XtCallCallbackList((Widget)obj, obj->inputConv.selectioncallback, | |
1100 (XtPointer)&arg); | |
1101 | |
1102 if (!abort && (selected = arg.u.current_item) >= 0) { | |
1103 ret = insertSelection(obj, selected, &changed, &flush); | |
1104 } | |
1105 | |
1106 switch (obj->sj3.state) { | |
1107 case candidate_state: | |
1108 Xsj3cEndCandidate(buf, changed); | |
1109 break; | |
1110 case symbol_state: | |
1111 Xsj3cEndSymbol(buf); | |
1112 break; | |
1113 case hinsi_state: | |
1114 Xsj3cEndHinsi(buf); | |
1115 break; | |
1116 default: | |
1117 XtAppWarning(XtWidgetToApplicationContext((Widget)obj), | |
1118 "sj3 Object: Unknow ConvMode state"); | |
1119 break; | |
1120 } | |
1121 obj->sj3.state = normal_state; | |
1122 | |
1123 if (changed) { | |
1124 if (flush) { | |
1125 XtCallCallbackList((Widget)obj, obj->inputConv.fixcallback, | |
1126 (XtPointer)NULL); | |
1127 Xsj3cFlushBuffer(buf); | |
1128 } | |
1129 XtCallCallbackList((Widget)obj, | |
1130 obj->inputConv.textchangecallback, | |
1131 (XtPointer)NULL); | |
1132 } | |
1133 | |
1134 return ret; | |
1135 } | |
1136 | |
1137 /* ARGSUSED */ | |
1138 static Boolean | |
1139 SetValues(cur, req, wid, args, num_args) | |
1140 Widget cur; | |
1141 Widget req; | |
1142 Widget wid; | |
1143 ArgList args; | |
1144 Cardinal *num_args; | |
1145 { | |
1146 return False; | |
1147 } | |
1148 | |
1149 static int | |
1150 insertSelection(obj, selected, changed, flush) | |
1151 Sj3Object obj; | |
1152 int selected; | |
1153 int *changed; | |
1154 int *flush; | |
1155 { | |
1156 Xsj3cBuf buf = obj->sj3.sj3buf; | |
1157 int ret = 0; | |
1158 | |
1159 obj->sj3.selectionending = True; | |
1160 switch (obj->sj3.state) { | |
1161 case candidate_state: | |
1162 obj->sj3.curcand = selected; | |
1163 ret = Xsj3cSetCandidate(buf, selected, changed, flush); | |
1164 break; | |
1165 case symbol_state: | |
1166 obj->sj3.cursymbol = selected; | |
1167 ret = Xsj3cSetSymbol(buf, selected, changed, flush); | |
1168 break; | |
1169 case hinsi_state: | |
1170 obj->sj3.curhinsi = selected; | |
1171 ret = Xsj3cSetHinsi(buf, selected, changed, flush); | |
1172 break; | |
1173 } | |
1174 obj->sj3.selectionending = False; | |
1175 | |
1176 return ret; | |
1177 } | |
1178 | |
1179 static void | |
1180 allocCandlist(obj, n) | |
1181 Sj3Object obj; | |
1182 int n; | |
1183 { | |
1184 ICString *p; | |
1185 | |
1186 if (n <= obj->sj3.candlistsize) | |
1187 return; | |
1188 | |
1189 if (obj->sj3.candlistsize == 0) { | |
1190 p = (ICString *)XtMalloc(n * sizeof(ICString)); | |
1191 } else { | |
1192 p = (ICString *)XtRealloc((char *)obj->sj3.candlist, | |
1193 n * sizeof(ICString)); | |
1194 } | |
1195 | |
1196 obj->sj3.candlist = p; | |
1197 obj->sj3.candlistsize = n; | |
1198 } | |
1199 | |
1200 static void | |
1201 startRegistration(obj) | |
1202 Sj3Object obj; | |
1203 { | |
1204 ICAuxControlArg arg; | |
1205 | |
1206 arg.command = ICAuxStart; | |
1207 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, | |
1208 (XtPointer)&arg); | |
1209 } | |
1210 | |
1211 static void | |
1212 changeRegistration(obj) | |
1213 Sj3Object obj; | |
1214 { | |
1215 ICAuxControlArg arg; | |
1216 | |
1217 arg.command = ICAuxChange; | |
1218 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, | |
1219 (XtPointer)&arg); | |
1220 } | |
1221 | |
1222 static void | |
1223 endRegistration(obj) | |
1224 Sj3Object obj; | |
1225 { | |
1226 Xsj3cBuf buf = obj->sj3.sj3buf; | |
1227 ICAuxControlArg arg; | |
1228 | |
1229 arg.command = ICAuxEnd; | |
1230 XtCallCallbackList((Widget)obj, obj->inputConv.auxcallback, | |
1231 (XtPointer)&arg); | |
1232 Xsj3cEndDict(buf); | |
1233 } | |
1234 | |
1235 /* | |
1236 * keeping list of objects | |
1237 */ | |
1238 typedef struct _oblist_ { | |
1239 Sj3Object obj; | |
1240 struct _oblist_ *next; | |
1241 } ObjRec; | |
1242 | |
1243 static ObjRec *ObjList = NULL; | |
1244 | |
1245 static void | |
1246 addObject(obj) | |
1247 Sj3Object obj; | |
1248 { | |
1249 ObjRec *objp = XtNew(ObjRec); | |
1250 | |
1251 objp->obj = obj; | |
1252 objp->next = ObjList; | |
1253 ObjList = objp; | |
1254 } | |
1255 | |
1256 static void | |
1257 deleteObject(obj) | |
1258 Sj3Object obj; | |
1259 { | |
1260 ObjRec *objp, *objp0; | |
1261 | |
1262 for (objp0 = NULL, objp = ObjList; | |
1263 objp != NULL; | |
1264 objp0 = objp, objp = objp->next) { | |
1265 if (objp->obj == obj) { | |
1266 if (objp0 == NULL) { | |
1267 ObjList = objp->next; | |
1268 } else { | |
1269 objp0->next = objp->next; | |
1270 } | |
1271 XtFree((char *)objp); | |
1272 return; | |
1273 } | |
1274 } | |
1275 } | |
1276 | |
1277 static void | |
1278 bell(obj) | |
1279 Sj3Object obj; | |
1280 { | |
1281 XBell(XtDisplayOfObject((Widget)obj), 0); | |
1282 } |