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