1 /* Copyright 1992 NEC Corporation, Tokyo, Japan.
2  *
3  * Permission to use, copy, modify, distribute and sell this software
4  * and its documentation for any purpose is hereby granted without
5  * fee, provided that the above copyright notice appear in all copies
6  * and that both that copyright notice and this permission notice
7  * appear in supporting documentation, and that the name of NEC
8  * Corporation not be used in advertising or publicity pertaining to
9  * distribution of the software without specific, written prior
10  * permission.  NEC Corporation makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
16  * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #if !defined(lint) && !defined(__CODECENTER__)
24 static char rcsid[] = "$Id: ebind.c,v 1.6 2003/09/17 08:50:53 aida_s Exp $";
25 #endif
26 
27 #include "canna.h"
28 
29 #define MAX_BYTE_PER_CHAR 4
30 
31 /*********************************************************************
32  *                      wchar_t replace begin                        *
33  *********************************************************************/
34 #ifdef wchar_t
35 # error "wchar_t is already defined"
36 #endif
37 #define wchar_t cannawc
38 
39 extern int howToReturnModeInfo;
40 
41 static wchar_t *inbuf = 0;
42 static int inbufsize = 0;
43 
44 static
StoreWCtoEUC(wbuf,wbuflen,wks,ebuf,maxebuf,ks,ch,nbytes)45 StoreWCtoEUC(wbuf, wbuflen, wks, ebuf, maxebuf, ks, ch, nbytes)
46 wchar_t *wbuf;
47 int wbuflen;
48 wcKanjiStatus *wks;
49 char *ebuf;
50 int maxebuf;
51 jrKanjiStatus *ks;
52 int ch;
53 int nbytes;
54 {
55   int ret, rest, totallen = 0, len;
56   char *p;
57 
58   /* info */
59 
60   ks->info = wks->info;
61 
62   /* ��� */
63 
64   if (ks->info & KanjiThroughInfo) {
65     if (nbytes) {
66       ebuf[0] = ch;
67     }
68     ret = nbytes;
69   }
70   else {
71     ret = (wbuflen > 0) ? WCstombs(ebuf, wbuf, maxebuf) : 0;
72     if (ks->info & KanjiYomiInfo) {
73       wchar_t *ep;
74       len = WCstombs(ebuf + ret + 1, wbuf + wbuflen + 1,
75 		     maxebuf - ret - 1);
76       ep = wbuf + wbuflen + 1;
77       while (*ep) ep++;
78       WCstombs(ebuf + ret + 1 + len + 1, ep + 1,
79 	       maxebuf - ret - 1 - len - 1);
80     }
81   }
82 
83   if (wks->length > 0) {
84     totallen = wks->length;
85   }
86   if (wks->info & KanjiModeInfo) {
87     totallen += WStrlen(wks->mode);
88   }
89   if (wks->info & KanjiGLineInfo) {
90     totallen += wks->gline.length;
91   }
92 
93   if (inbufsize < totallen) {
94     inbufsize = totallen; /* inbufsize will be greater than 0 */
95     if (inbuf) free(inbuf);
96     inbuf = (wchar_t *)malloc(inbufsize * sizeof(wchar_t));
97     if (!inbuf) {
98       inbufsize = 0;
99       jrKanjiError = "\245\341\245\342\245\352\244\254\302\255\244\352\244\336\244\273\244\363";
100                      /* ���꤬­��ޤ��� */
101       return -1;
102     }
103   }
104 
105   rest = inbufsize * sizeof(wchar_t);
106   p = (char *)inbuf;
107 
108   if (wks->length < 0) {
109     ks->length = -1;
110   }
111   else {
112     /* ������ʸ�� */
113 
114     ks->length = ks->revLen = ks->revPos = 0;
115 
116     if (wks->length > 0) {
117       ks->echoStr = (unsigned char *)p;
118       if (wks->revPos > 0) {
119 	len = ks->revPos = CNvW2E(wks->echoStr, wks->revPos, p, rest);
120 	p += len;
121 	rest -= len;
122       }
123       if (wks->revLen > 0) {
124 	len = ks->revLen
125 	  = CNvW2E(wks->echoStr + wks->revPos, wks->revLen, p, rest);
126 	p += len;
127 	rest -= len;
128       }
129       len = 0;
130       if (wks->length - wks->revPos - wks->revLen > 0) {
131 	len = CNvW2E(wks->echoStr + wks->revPos + wks->revLen,
132 		     wks->length - wks->revPos - wks->revLen, p, rest);
133 	p += len;
134 	rest -= len;
135       }
136       ks->length = ks->revLen + ks->revPos + len;
137       *p++ = '\0';
138       rest--;
139     }
140   }
141 
142   /* �⡼��ɽ�� */
143 
144   if (wks->info & KanjiModeInfo) {
145     len = WCstombs(p, wks->mode, rest);
146     ks->mode = (unsigned char *)p;
147     p[len] = '\0';
148     p += len + 1;
149     rest -= len + 1;
150   }
151 
152   /* ������ɽ�� */
153 
154   if (wks->info & KanjiGLineInfo) {
155     ks->gline.length = ks->gline.revLen = ks->gline.revPos = 0;
156 
157     if (wks->gline.length > 0) {
158       ks->gline.line = (unsigned char *)p;
159       if (wks->gline.revPos > 0) {
160 	len = ks->gline.revPos
161 	  = CNvW2E(wks->gline.line, wks->gline.revPos, p, rest);
162 	p += len;
163 	rest -= len;
164       }
165       if (wks->gline.revLen > 0) {
166 	len = ks->gline.revLen
167 	  = CNvW2E(wks->gline.line + wks->gline.revPos, wks->gline.revLen,
168 		   p, rest);
169 	p += len;
170 	rest -= len;
171       }
172       len = 0;
173       if (wks->gline.length - wks->gline.revPos - wks->gline.revLen > 0) {
174 	len = CNvW2E(wks->gline.line + wks->gline.revPos +
175 		     wks->gline.revLen,
176 		     wks->gline.length -
177 		     wks->gline.revPos - wks->gline.revLen,
178 		     p, rest);
179 	p += len;
180 	rest -= len;
181       }
182       ks->gline.length = ks->gline.revLen + ks->gline.revPos + len;
183       *p++ = '\0';
184       rest--;
185     }
186   }
187   return ret;
188 }
189 
XLookupKanji2(dpy,win,buffer_return,bytes_buffer,nbytes,functionalChar,kanji_status_return)190 XLookupKanji2(dpy, win, buffer_return, bytes_buffer, nbytes, functionalChar,
191 	      kanji_status_return)
192 unsigned int dpy, win;
193 int functionalChar, nbytes;
194 char *buffer_return;
195 int bytes_buffer;
196 jrKanjiStatus *kanji_status_return;
197 {
198   int ret;
199   wcKanjiStatus wks;
200   int ch;
201   int i;
202 
203   /* �����Хåե��������Ȥ��� */
204   if (inbufsize < bytes_buffer) {
205     inbufsize = bytes_buffer; /* inbufsize will be greater than 0 */
206     if (inbuf) free(inbuf);
207     inbuf = (wchar_t *)malloc(inbufsize * sizeof(wchar_t));
208     if (!inbuf) {
209       inbufsize = 0;
210       jrKanjiError = "\245\341\245\342\245\352\244\254\302\255\244\352\244\336\244\273\244\363";
211                      /* ���꤬­��ޤ��� */
212       return -1;
213     }
214   }
215 
216   inbuf[0] = (wchar_t)(unsigned char)buffer_return[0];
217   for (i = 1 ; i < nbytes ; i++) {
218     inbuf[i] = (wchar_t)(unsigned char)buffer_return[i];
219   }
220   ch = buffer_return[0] & 0xff;
221   ret = XwcLookupKanji2(dpy, win, inbuf, inbufsize, nbytes, functionalChar,
222 			&wks);
223   if (ret >= inbufsize)
224     ret = inbufsize - 1;
225   inbuf[ret] = (wchar_t)0;
226 
227   return StoreWCtoEUC(inbuf, ret, &wks,
228 		      (char *)buffer_return, bytes_buffer, kanji_status_return,
229 		      ch, nbytes);
230 }
231 
232 int
EUCListCallback(client_data,func,items,nitems,cur_item)233 EUCListCallback(client_data, func, items, nitems, cur_item)
234 char *client_data;
235 int func;
236 wchar_t **items;
237 int nitems, *cur_item;
238 {
239   const jrEUCListCallbackStruct *elistcb;
240   int r = -1;
241   char **eitems = NULL;
242   char *ebuf = NULL;
243   char *ep;
244   size_t buflen = 0;
245   int i;
246 
247   elistcb = (const jrEUCListCallbackStruct *)client_data;
248   if (!items) /* CANNA_LIST_Insert sets 'nitems' to the pressed key (!=0) */
249     return elistcb->callback_func(elistcb->client_data,
250 	func, NULL, nitems, cur_item);
251   for (i = 0; i < nitems; i++) {
252     /* EUC(����3�Х���) + ��ü�̥� */
253     buflen += WStrlen(items[i]) * 3 + 1;
254   }
255   ebuf = (char *)malloc(buflen);
256   eitems = (char **)malloc((nitems + 1) * sizeof(char **));
257   if (!ebuf || !eitems)
258     goto last;	/* XXX: ñ��-1���֤��Ƥ����Τ��� */
259   ep = ebuf;
260   for (i = 0; i < nitems; i++) {
261     size_t len = WCstombs(ep, items[i], ebuf + buflen - ep);
262     eitems[i] = ep;
263     ep += len + 1;  /* �Хåե��Ͼ��­��Ƥ��ƥ̥뽪ü������ */
264   }
265   eitems[nitems] = NULL;
266   r = elistcb->callback_func(elistcb->client_data,
267       func, eitems, nitems, cur_item);
268 last:
269   free(ebuf);
270   free(eitems);
271   return r;
272 }
273 
274 int
XKanjiControl2(display,window,request,arg)275 XKanjiControl2(display, window, request, arg)
276 unsigned int display, window, request;
277 BYTE *arg;
278 {
279   int ret = -1, len1, len2;
280   wcKanjiStatusWithValue wksv;
281   wcKanjiStatus wks;
282   jrListCallbackStruct list_cb;
283   int ch;
284 #ifndef USE_MALLOC_FOR_BIG_ARRAY
285   wchar_t arg2[256];
286   wchar_t wbuf[320], wbuf1[320], wbuf2[320];
287 #else
288   wchar_t *arg2, *wbuf, *wbuf1, *wbuf2;
289   arg2 = (wchar_t *)malloc(sizeof(wchar_t) * 256);
290   wbuf = (wchar_t *)malloc(sizeof(wchar_t) * 320);
291   wbuf1 = (wchar_t *)malloc(sizeof(wchar_t) * 320);
292   wbuf2 = (wchar_t *)malloc(sizeof(wchar_t) * 320);
293   if (!arg2 || !wbuf || !wbuf1 || !wbuf2) {
294     if (arg2) {
295       (void)free((char *)arg2);
296     }
297     if (wbuf) {
298       (void)free((char *)wbuf);
299     }
300     if (wbuf1) {
301       (void)free((char *)wbuf1);
302     }
303     if (wbuf2) {
304       (void)free((char *)wbuf2);
305     }
306     return ret;
307   }
308 #endif
309 
310   wksv.buffer = wbuf;
311   wksv.n_buffer = 320;
312   wksv.ks = &wks;
313 
314   switch (request) {
315   case KC_DO: /* val �� buffer_return ������륿���� */
316     wbuf[0] = ((jrKanjiStatusWithValue *)arg)->buffer[0];
317     /* ����³�� */
318   case KC_CHANGEMODE: /* val ��Ϳ���륿���� */
319     wksv.val = ((jrKanjiStatusWithValue *)arg)->val;
320     goto withksv;
321   case KC_STOREYOMI: /* echoStr �� length �� mode ��Ϳ���륿���� */
322     /* �ޤ� mode ��磻�ɤˤ��Ƥߤ褦 */
323     if (((jrKanjiStatusWithValue *)arg)->ks->mode) {
324       len2 = MBstowcs(wbuf2, (char *)((jrKanjiStatusWithValue *)arg)->ks->mode,
325 		      320);
326       wbuf2[len2] = (wchar_t)0;
327       wks.mode = wbuf2;
328     }
329     else {
330       wks.mode = (wchar_t *)0;
331     }
332     /* ����³�� */
333   case KC_DEFINEKANJI: /* echoStr �� length ��Ϳ���륿���� */
334     /* echoStr ��磻�ɤˤ���Ϳ���Ƥߤ褦 */
335     len1 = MBstowcs(wbuf1,
336 		    (char *)((jrKanjiStatusWithValue *)arg)->ks->echoStr, 320);
337     wbuf1[len1] = (wchar_t)0;
338     wks.echoStr = wbuf1;
339     wks.length = len1;
340     /* ����³�� */
341   case KC_KAKUTEI: /* ����ñ��Ϳ�����֤ä���륿���� */
342   case KC_KILL:
343     goto withksv;
344   case KC_CLOSEUICONTEXT:
345     goto closecont;
346   case KC_QUERYMODE: /* querymode */
347     ret = XwcKanjiControl2(display, window, request, (BYTE *)arg2);
348     if (!ret) {
349       switch (howToReturnModeInfo) {
350       case ModeInfoStyleIsString:
351 	WCstombs((char *)arg, arg2, 256);
352 	break;
353       case ModeInfoStyleIsBaseNumeric:
354         arg[2] = (unsigned char)arg2[2];
355       case ModeInfoStyleIsExtendedNumeric:
356 	arg[1] = (unsigned char)arg2[1];
357       case ModeInfoStyleIsNumeric:
358 	arg[0] = (unsigned char)arg2[0];
359 	break;
360       }
361     }
362     goto return_ret;
363   case KC_SETLISTCALLBACK: /* dirty, dirty hack */
364     /* list_cb��KC_setListCallback��d->elistcb�˰��ñۤ� */
365     list_cb.client_data = (char *)arg;
366     list_cb.callback_func = &EUCListCallback;
367     ret = XwcKanjiControl2(display, window, request, (char *)&list_cb);
368     goto return_ret;
369     /* FALLTHROUGH */
370   default: /* �磻�ɤǤ�EUC�Ǥ��Ѥ��ʤ���� */
371     ret = XwcKanjiControl2(display, window, request, arg);
372     goto return_ret;
373   }
374  withksv:
375   ch = ((jrKanjiStatusWithValue *)arg)->buffer[0];
376   ret = XwcKanjiControl2(display, window, request, (BYTE *)&wksv);
377   if (ret < 0) {
378     goto return_ret;
379   }
380   else {
381     wksv.buffer[ret] = (wchar_t)0;
382     ((jrKanjiStatusWithValue *)arg)->val =
383       StoreWCtoEUC(wksv.buffer, wksv.val, wksv.ks,
384 		   (char *)((jrKanjiStatusWithValue *)arg)->buffer,
385 		   ((jrKanjiStatusWithValue *)arg)->bytes_buffer,
386 		   ((jrKanjiStatusWithValue *)arg)->ks,
387 		   ch, ((jrKanjiStatusWithValue *)arg)->val);
388     ret = ((jrKanjiStatusWithValue *)arg)->val;
389     goto return_ret;
390   }
391  closecont:
392   ch = ((jrKanjiStatusWithValue *)arg)->buffer[0];
393   ret = XwcKanjiControl2(display, window, request, (BYTE *)&wksv);
394   if (ret < 0) {
395     goto return_ret;
396   }
397   else {
398     wksv.val = 0;
399     ((jrKanjiStatusWithValue *)arg)->val =
400       StoreWCtoEUC(wksv.buffer, wksv.val, wksv.ks,
401 		   (char *)((jrKanjiStatusWithValue *)arg)->buffer,
402 		   ((jrKanjiStatusWithValue *)arg)->bytes_buffer,
403 		   ((jrKanjiStatusWithValue *)arg)->ks,
404 		   ch, ((jrKanjiStatusWithValue *)arg)->val);
405     goto return_ret;
406   }
407  return_ret:
408 #ifdef USE_MALLOC_FOR_BIG_ARRAY
409   (void)free((char *)wbuf2);
410   (void)free((char *)wbuf1);
411   (void)free((char *)wbuf);
412   (void)free((char *)arg2);
413 #endif
414   return ret;
415 }
416 
417 exp(int)
418 jrKanjiString(context_id, ch, buffer_return, nbuffer, kanji_status_return)
419 const int context_id, ch, nbuffer;
420 char  *buffer_return;
421 jrKanjiStatus  *kanji_status_return;
422 {
423   *buffer_return = ch;
424 
425   return XLookupKanji2((unsigned int)0, (unsigned int)context_id,
426 		       buffer_return, nbuffer,
427 		       1/* byte */, 1/* functional char*/,
428 		       kanji_status_return);
429 }
430 
431 /* jrKanjiControl -- ���ʴ����Ѵ��������Ԥ� */
432 
433 exp(int)
434 jrKanjiControl(context, request, arg)
435      const int context;
436      const int request;
437      char *arg;
438 {
439   return XKanjiControl2((unsigned int)0, (unsigned int)context,
440 			request, (BYTE *)arg);
441 }
442 
443 #ifndef wchar_t
444 # error "wchar_t is already undefined"
445 #endif
446 #undef wchar_t
447 /*********************************************************************
448  *                       wchar_t replace end                         *
449  *********************************************************************/
450