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/************************************************************************/
24/* THIS SOURCE CODE IS MODIFIED FOR TKO BY T.MURAI 1997
25/************************************************************************/
26
27
28#if !defined(lint) && !defined(__CODECENTER__)
29static char rcs_id[] = "@(#) 102.1 $Id: jrbind.c 14875 2005-11-12 21:25:31Z bonefish $";
30#endif /* lint */
31
32#include "canna.h"
33#include <canna/mfdef.h>
34#include <sys/types.h>
35
36#define ACTHASHTABLESIZE 64
37#define KEYHASHTABLESIZE 16
38
39typedef int (*keycallback)(unsigned, unsigned char *, int,
40			   unsigned char *, int, char *);
41
42static uiContext newUiContext(unsigned int dpy, unsigned int win);
43static void GetCannaKeyOnAMode(unsigned modeid, unsigned char *mode, keycallback keyfn, char *con);
44static void GetCannaKeyfunc(keycallback keyfn, char *con);
45
46/*
47
48  jrKanjiString ¤Ï TTY ¤Î¥­¡¼ÆþÎϤò¼õ¤±¼è¤ê¡¢¤½¤Î¥­¡¼¤Ë¤·¤¿¤¬¤Ã¤ÆɬÍ×
49  ¤Ê¤é¥«¥Ê´Á»úÊÑ´¹¤ò¹Ô¤¤¡¢¤½¤Î¥­¡¼ÆþÎϤηë²Ì¤È¤·¤ÆÆÀ¤é¤ì¤ëʸ»úÎó¤ò
50  buffer_return ¤ÇÊÖ¤¹¡£buffer_return ¤Ï¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¦¤ËÍÑ°Õ¤¹¤ë¥Ð¥Ã
51  ¥Õ¥¡¤Ç¤¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¤½¤Î¥Ð¥Ã¥Õ¥¡¤ÎŤµ¤ò bytes_buffer ¤ÇÅÏ
52  ¤¹¡£
53
54  kanji_status_return ¤Ï³ÎÄꤷ¤Æ¤¤¤Ê¤¤ÆþÎÏʸ»úÎó¤òɽ¼¨¤¹¤ë¤¿¤á¤Î¥Ç¡¼¥¿
55  ¤Ç¤¢¤ê¡¢Ì¤³ÎÄê¤ÎÆɤߤä¸õÊä´Á»ú¤Ê¤É¤¬ÊÖ¤µ¤ì¤ë¡£kanji_status_return¤Î
56  ¥á¥ó¥Ð¤Ë¤Ï¡¢ echoStr, length, revPos, revLen ¤¬¤¢¤ê¤½¤ì¤¾¤ì¡¢Ì¤³ÎÄê
57  ʸ»úÎó¤Ø¤Î¥Ý¥¤¥ó¥¿¡¢¤½¤ÎŤµ¡¢Ì¤³ÎÄêʸ»úÎó¤Î¤¦¤Á¡¢¶¯Ä´¤¹¤ëÉôʬ¤Ø¤Î¥ª
58  ¥Õ¥»¥Ã¥È¡¢¶¯Ä´¤¹¤ëÉôʬ¤ÎŤµ¤òÊÖ¤¹¡£Ì¤³ÎÄêʸ»úÎó¤ò³ÊǼ¤¹¤ëÎΰè¤Ï
59  jrKanjiString ¤Ç¼«Æ°Åª¤ËÍÑ°Õ¤µ¤ì¤ë¡£
60
61 */
62
63extern int FirstTime;
64
65extern BYTE *actFromHash();
66
67int
68wcKanjiString (
69	int context_id,
70	int ch,
71	WCHAR_T *buffer_return,
72	const int nbuffer,
73	wcKanjiStatus *kanji_status_return)
74{
75  int res;
76
77  *buffer_return = (WCHAR_T)ch;
78
79  res = XwcLookupKanji2((unsigned int)0, (unsigned int)context_id,
80			buffer_return, nbuffer,
81			1/* byte */, 1/* functional char*/,
82			kanji_status_return);
83  return res;
84}
85
86/* jrKanjiControl -- ¥«¥Ê´Á»úÊÑ´¹¤ÎÀ©¸æ¤ò¹Ô¤¦ */
87
88int
89wcKanjiControl (
90const int context,
91const int request,
92char *arg)
93{
94  return XwcKanjiControl2((unsigned int)0, (unsigned int)context,
95			  (unsigned int)request, (BYTE *)arg);
96}
97
98inline
99uiContext
100newUiContext(unsigned int dpy, unsigned int win)
101{
102  extern struct CannaConfig cannaconf;
103  uiContext d;
104
105  if ((d = (uiContext)malloc(sizeof(uiContextRec))) != (uiContext)0) {
106    if (initRomeStruct(d, cannaconf.chikuji) == 0) {
107      if (internContext(dpy, win, d)) {
108	return d;
109      }
110      freeRomeStruct(d);
111    }
112    free(d);
113  }
114  return (uiContext)0;
115}
116
117extern int kanjiControl (int, uiContext, caddr_t);
118
119int XwcLookupKanji2(unsigned int dpy, unsigned int win, WCHAR_T *buffer_return, int nbuffer, int nbytes, int functionalChar, wcKanjiStatus *kanji_status_return)
120{
121  uiContext d;
122  int retval;
123  extern int locale_insufficient;
124
125  /* locale ¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬ÉÔ½½Ê¬¤Ç WCHAR_T ¤È¤ÎÊÑ´¹½èÍý¤¬¤Ç¤­¤Ê¤¤¾ì¹ç¤Ï
126     ¡Ø¤«¤ó¤Ê¡Ù¤Ë¤È¤Ã¤ÆÂçÂÇ·â¡£¤â¤¦ÊÑ´¹¤Ï¤Ç¤­¤Ê¤¤¡ª */
127  if (locale_insufficient) {
128    kanji_status_return->info = KanjiEmptyInfo | KanjiThroughInfo;
129    if (nbytes) { /* ¥­¥ã¥é¥¯¥¿¥³¡¼¥É¤¬¤È¤ì¤¿¾ì¹ç */
130      kanji_status_return->length =
131	kanji_status_return->revPos =
132	  kanji_status_return->revLen = 0;
133      return nbytes;
134    }
135    else { /* ¥­¥ã¥é¥¯¥¿¥³¡¼¥É¤¬¤È¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡Ê¥·¥Õ¥È¥­¡¼¤Ê¤É¡Ë... */
136      kanji_status_return->length = -1;
137      return 0;
138    }
139  }
140
141  /* ½é¤á¤Æ XLookupKanjiString ¤¬¸Æ¤Ð¤ì¤¿»þ¤Ï¼­½ñ¤Î½é´ü²½¤Ê¤É¤Î½èÍý¤¬
142     ¹Ô¤ï¤ì¤ë¡£ */
143
144  if (FirstTime) {
145    if (kanjiControl(KC_INITIALIZE, (uiContext)NULL, (char *)NULL) == -1) {
146      return -1;
147    }
148    FirstTime = 0;
149  }
150
151  d = keyToContext(dpy, win);
152
153  if (d == (uiContext)NULL) {
154    /* ¤³¤Î¥¦¥£¥ó¥É¥¦¤«¤é¥¤¥Ù¥ó¥È¤¬Í褿¤Î¤¬»Ï¤á¤Æ¤À¤Ã¤¿¤ê¤¹¤ë¤ï¤±¤è */
155    d = newUiContext(dpy, win);
156    if (d == (uiContext)NULL) {
157      return NoMoreMemory();
158    }
159  }
160
161
162  bzero(kanji_status_return, sizeof(wcKanjiStatus));
163
164  d->ch = (unsigned)*buffer_return;
165  d->buffer_return = buffer_return;
166  d->n_buffer = nbuffer;
167  d->kanji_status_return = kanji_status_return;
168
169  debug_message("current_mode(0x%x)\n", d->current_mode,0,0);
170
171  if ( nbytes || functionalChar ) { /* ¥­¥ã¥é¥¯¥¿¥³¡¼¥É¤¬¤È¤ì¤¿¾ì¹ç */
172    int check;
173
174    *buffer_return = key2wchar(d->ch, &check);
175    if (!check) {
176      return NothingChangedWithBeep(d);
177    }
178
179    d->nbytes = nbytes;
180
181    retval = doFunc(d, 0);
182#ifdef DEBUG
183    checkModec(d);
184#endif /* DEBUG */
185    return(retval);
186  }
187  else { /* ¥­¥ã¥é¥¯¥¿¥³¡¼¥É¤¬¤È¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡Ê¥·¥Õ¥È¥­¡¼¤Ê¤É¡Ë... */
188    d->kanji_status_return->length = -1;
189    return 0;
190  }
191}
192
193int
194XwcKanjiControl2(unsigned int display, unsigned int window, unsigned int request, BYTE *arg)
195{
196  if (request == KC_INITIALIZE || request == KC_FINALIZE ||
197      request == KC_SETSERVERNAME || request == KC_SETINITFILENAME ||
198      request == KC_SETVERBOSE || request == KC_KEYCONVCALLBACK ||
199      request == KC_QUERYCONNECTION || request == KC_SETUSERINFO ||
200      request == KC_QUERYCUSTOM) {
201    return kanjiControl(request, (uiContext)NULL, (char *)arg);
202  }
203  else if (/* 0 <= request && (ɬ¤º¿¿) */ request < MAX_KC_REQUEST) {
204    uiContext d;
205
206    /* ½é¤á¤Æ wcKanjiString ¤¬¸Æ¤Ð¤ì¤¿»þ¤Ï¼­½ñ¤Î½é´ü²½¤Ê¤É¤Î½èÍý¤¬
207       ¹Ô¤ï¤ì¤ë¡£ */
208
209    if (FirstTime) {
210      if (kanjiControl(KC_INITIALIZE, (uiContext)NULL, (char *)NULL) == -1) {
211	return -1;
212      }
213      FirstTime = 0;
214    }
215
216    d = keyToContext((unsigned int)display, (unsigned int)window);
217
218    if (d == (uiContext)NULL) {
219      d = newUiContext(display, window);
220      if (d == (uiContext)NULL) {
221	return NoMoreMemory();
222      }
223    }
224
225    if (request == KC_CLOSEUICONTEXT) {
226      rmContext(display, window);
227    }
228    return kanjiControl(request, d, (char *)arg);
229  }
230  else {
231    return -1;
232  }
233}
234
235struct map {
236  KanjiMode tbl;
237  BYTE key;
238  KanjiMode mode;
239  struct map *next;
240};
241
242struct map *mapFromHash();
243
244/* cfuncdef
245
246  pushCallback -- ¥³¡¼¥ë¥Ð¥Ã¥¯¤Î½¸¹ç¤ò¥×¥Ã¥·¥å¤¹¤ë¡£
247
248  ¥³¡¼¥ë¥Ð¥Ã¥¯¤Î½¸¹ç¤ò³ÊǼ¤¹¤ëÇÛÎó¤¬ malloc ¤µ¤ì¤Æ¡¢¤½¤ì¤¬ uiContext ¤Ë
249  ¥×¥Ã¥·¥å¤µ¤ì¤ë¡£
250
251  malloc ¤µ¤ì¤¿ÇÛÎó¤¬Ìá¤êÃͤȤ·¤ÆÊ֤롣
252
253 */
254
255struct callback *
256pushCallback(uiContext d, mode_context env, canna_callback_t ev, canna_callback_t ex, canna_callback_t qu, canna_callback_t au)
257{
258  struct callback *newCB;
259
260  newCB = (struct callback *)malloc(sizeof(struct callback));
261  if (newCB) {
262    newCB->func[0] = ev;
263    newCB->func[1] = ex;
264    newCB->func[2] = qu;
265    newCB->func[3] = au;
266    newCB->env = env;
267    newCB->next = d->cb;
268    d->cb = newCB;
269  }
270  return newCB;
271}
272
273void
274popCallback(uiContext d)
275{
276  struct callback *oldCB;
277
278  oldCB = d->cb;
279  d->cb = oldCB->next;
280  free(oldCB);
281}
282
283#if defined(WIN) && defined(_RK_h)
284
285extern RkwGetProtocolVersion (int *, int *);
286extern char *RkwGetServerName (void);
287
288struct cannafn{
289  {
290    RkwGetProtocolVersion,
291    RkwGetServerName,
292    RkwGetServerVersion,
293    RkwInitialize,
294    RkwFinalize,
295    RkwCreateContext,
296    RkwDuplicateContext,
297    RkwCloseContext,
298    RkwSetDicPath,
299    RkwCreateDic,
300    RkwSync,
301    RkwGetDicList,
302    RkwGetMountList,
303    RkwMountDic,
304    RkwRemountDic,
305    RkwUnmountDic,
306    RkwDefineDic,
307    RkwDeleteDic,
308    RkwGetHinshi,
309    RkwGetKanji,
310    RkwGetYomi,
311    RkwGetLex,
312    RkwGetStat,
313    RkwGetKanjiList,
314    RkwFlushYomi,
315    RkwGetLastYomi,
316    RkwRemoveBun,
317    RkwSubstYomi,
318    RkwBgnBun,
319    RkwEndBun,
320    RkwGoTo,
321    RkwLeft,
322    RkwRight,
323    RkwNext,
324    RkwPrev,
325    RkwNfer,
326    RkwXfer,
327    RkwResize,
328    RkwEnlarge,
329    RkwShorten,
330    RkwStoreYomi,
331    RkwSetAppName,
332    RkwSetUserInfo,
333    RkwQueryDic,
334    RkwCopyDic,
335    RkwListDic,
336    RkwRemoveDic,
337    RkwRenameDic,
338    RkwChmodDic,
339    RkwGetWordTextDic,
340    RkwGetSimpleKanji,
341  },
342  wcKanjiControl,
343  wcKanjiString,
344};
345#endif
346
347#ifdef WIN
348#include "cannacnf.h"
349
350/* Interfaces for CannaGetConfigure/CannaSetConfigure */
351
352#define CANNA_MODE_AllModes 255
353#define MAX_KEYS_IN_A_MODE 256
354
355
356inline void
357GetCannaKeyOnAMode(unsigned modeid, unsigned char *mode,
358		   keycallback keyfn, char *con)
359{
360  unsigned char key;
361  int i;
362
363  for (i = 0 ; i < MAX_KEYS_IN_A_MODE ; i++) {
364    if (mode[i] != CANNA_FN_Undefined) { /* is this required? */
365      key = i;
366      (*keyfn)(modeid, &key, 1, mode + i, 1, con);
367    }
368  }
369}
370
371inline void
372GetCannaKeyfunc(keycallback keyfn, char *con)
373{
374  extern unsigned char default_kmap[], alpha_kmap[], empty_kmap[];
375
376  GetCannaKeyOnAMode(CANNA_MODE_AllModes, default_kmap, keyfn, con);
377  GetCannaKeyOnAMode(CANNA_MODE_AlphaMode, alpha_kmap, keyfn, con);
378  GetCannaKeyOnAMode(CANNA_MODE_EmptyMode, empty_kmap, keyfn, con);
379}
380
381#endif
382