home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
-
- /* This distribution of JWP makes use of the Kana-to-Kanji conversion */
- /* dictionary of the Kyoto University "Wnn" project. The original wnn */
- /* copyright follows... */
-
- /*
- * Copyright Kyoto University Research Institute for Mathematical Sciences
- * 1987, 1988, 1989, 1990, 1991
- * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991
- * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that all of the following conditions are satisfied:
- *
- * 1) The above copyright notices appear in all copies
- * 2) Both those copyright notices and this permission notice appear
- * in supporting documentation
- * 3) The name of "Wnn" isn't changed unless substantial modifications
- * are made, or
- * 3') Following words followed by the above copyright notices appear
- * in all supporting documentation of software based on "Wnn":
- *
- * "This software is based on the original version of Wnn developed by
- * Kyoto University Research Institute for Mathematical Sciences (KURIMS),
- * OMRON Corporation and ASTEC Inc."
- *
- * 4) The names KURIMS, OMRON and ASTEC not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission
- *
- * KURIMS, OMRON and ASTEC make no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * Wnn consortium is one of distributors of the official Wnn source code
- * release. Wnn consortium also makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * KURIMS, OMRON, ASTEC AND WNN CONSORTIUM DISCLAIM ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KURIMS, OMRON, ASTEC OR
- * WNN CONSORTIUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
- #include "jwp.h"
-
-
- #define INDEXLEVEL 3
- #define SEPARATION (SYSFONT->width / 2)
- #define CACHESIZE (5L * 1024L)
-
- typedef struct {
- BYTE key[INDEXLEVEL+1];
- LONG int offset;
- } INDEX;
-
- typedef struct {
- BYTE keylen;
- BYTE choicelen;
- union {
- BYTE string[4];
- BYTE far *ptr;
- } key;
- union {
- KANJI string[2];
- KANJI far *ptr;
- } choice;
- } CHOICE;
-
-
-
- static OFSTRUCT dctof;
-
- static BYTE far *index = NULL;
- static LONG int far *offset = NULL;
- static int nr_index = 0;
- static int words[BUFSIZE];
-
- static CHOICE far *ConvCache = NULL;
- static int ConvCacheSize = 0;
- static long int ConvRequests = 0L, ConvHits = 0L, ConvUsage = 0L, ConvChoiceChanges = 0L;
-
- static BOOL sizing = FALSE;
-
- KANJI kanji_list[MAXLINELEN];
-
- typedef struct KanjiListStruct {
- KANJI far *kanji;
- struct KanjiListStruct far *prev, far *next;
- } KANJILIST;
-
- typedef struct UserConvListStruct {
- BYTE far *kana;
- KANJILIST far *list;
- struct UserConvListStruct far *prev, far *next;
- } USERCONV;
-
- static USERCONV far *UserConversions = NULL;
- static USERCONV far *CurrentConv = NULL;
- static KANJILIST far *CurrentKanji = NULL;
- static BOOL UserConvChanged = FALSE;
- static BOOL AfterHitTest = FALSE;
-
-
-
- int bytelen (BYTE far *p)
- {
- int i;
-
- for (i = 0; *p; i++, p++);
-
- return (i);
- }
-
-
-
- int bytecmp (BYTE far *p1, BYTE far *p2)
- {
- for (; *p1 == *p2; p1++, p2++) {
- if (*p1 == 0) return (0);
- }
-
- return (*p1 - *p2);
- }
-
-
- int bytencmp (BYTE far *p1, BYTE far *p2, int n)
- {
- int i;
-
- for (i = 0; i < n; i++) {
- if (p1[i] != p2[i]) return (p1[i] - p2[i]);
- if (p1[i] == 0) return (0);
- }
-
- return (0);
- }
-
-
- KANJI far *kanjicpy (KANJI far *p1, KANJI far *p2)
- {
- while (*p1++ = *p2++);
-
- return (p1);
- }
-
-
-
- int kanjicmp (KANJI far *p1, KANJI far *p2)
- {
- for (; *p1 == *p2; p1++, p2++) {
- if (*p1 == 0) return (0);
- }
-
- return (*p1 - *p2);
- }
-
-
- int kanjincmp (KANJI far *p1, KANJI far *p2, int n)
- {
- int i;
-
- for (i = 0; i < n; i++) {
- if (p1[i] != p2[i]) return (p1[i] - p2[i]);
- if (p1[i] == 0) return (0);
- }
-
- return (0);
- }
-
-
- int kanjilen (KANJI far *s)
- {
- int i;
-
- for (i = 0; *s; s++, i++);
- return (i);
- }
-
-
- int unitlen (UNIT far *s)
- {
- int i;
-
- for (i = 0; s->kanji; s++, i++);
- return (i);
- }
-
-
- KANJI far *kanjicat (KANJI far *d, KANJI far *s)
- {
- kanjicpy(d + kanjilen(d), s);
- return (d);
- }
-
-
- static int ConvHash (BYTE far *key)
- {
- int i;
- long int sum;
-
- for (i = 0, sum = 0L; key[i]; i++) sum += key[i];
-
- return (sum % ConvCacheSize);
- }
-
-
-
- static int indexcmp (BYTE far *p1, BYTE far *p2)
- {
- int i;
-
- for (i = 0; i < INDEXLEVEL; i++) {
- if (p1[i] != p2[i]) return (p1[i] - p2[i]);
- if (p1[i] == '\0') return (0);
- }
-
- return (0);
- }
-
-
-
- static void ReadUserConversions (char *fname)
- {
- int fd;
- int i, j, nr_conv, nr_list, n;
- OFSTRUCT of;
- USERCONV far *up;
- KANJILIST far *kp;
-
- fd = OpenFile(fname, &of, OF_READ);
- if (fd < 0) return;
-
- lseek(fd, 0L, 0);
-
- read(fd, &nr_conv, sizeof(int));
-
- for (i = 0; i < nr_conv; i++) {
- if (UserConversions == NULL) {
- UserConversions = up = StructAlloc(USERCONV);
- up->prev = up->next = NULL;
- } else {
- up->next = StructAlloc(USERCONV);
- up->next->prev = up;
- up = up->next;
- up->next = NULL;
- }
- up->list = NULL;
-
- read (fd, &n, sizeof(int));
- up->kana = BlockAlloc(n);
- _lread(fd, up->kana, n);
-
- read (fd, &nr_list, sizeof(int));
-
- for (j = 0; j < nr_list; j++) {
- if (up->list == NULL) {
- up->list = kp = StructAlloc(KANJILIST);
- kp->prev = kp->next = NULL;
- } else {
- kp->next = StructAlloc(KANJILIST);
- kp->next->prev = kp;
- kp = kp->next;
- kp->next = NULL;
- }
-
- read (fd, &n, sizeof(int));
- kp->kanji = BlockAlloc(n * sizeof(KANJI));
- _lread(fd, kp->kanji, n * sizeof(KANJI));
- }
- }
-
- close(fd);
- }
-
-
-
- void WriteUserConversions (char *fname)
- {
- int fd, n;
- OFSTRUCT of;
- USERCONV far *up;
- KANJILIST far *kp;
-
- if (!UserConvChanged) return;
-
- fd = OpenFile(fname, &of, OF_CREATE | OF_WRITE);
- if (fd < 0) {
- ErrorMessage(global.hwnd, "WARNING: Cannot write User Conversion Dictionary '%s'!", fname);
- return;
- }
-
- lseek(fd, 0L, 0);
-
- /* How many conversions? */
-
- for (up = UserConversions, n = 0; up != NULL; up = up->next, n++);
- write(fd, &n, sizeof(int));
-
- for (up = UserConversions; up != NULL; up = up->next) {
- n = bytelen(up->kana) + 1;
- write(fd, &n, sizeof(int));
- _lwrite(fd, up->kana, n);
-
- /* How many kanji's? */
-
- for (kp = up->list, n = 0; kp != NULL; kp = kp->next, n++);
- write(fd, &n, sizeof(int));
-
- for (kp = up->list; kp != NULL; kp = kp->next) {
- n = kanjilen(kp->kanji) + 1;
- write(fd, &n, sizeof(int));
- _lwrite(fd, kp->kanji, n * sizeof(KANJI));
- }
- }
-
- close(fd);
- }
-
-
-
- int InitConversion (void)
- {
- int fd;
- int bytes, n, blocks;
- unsigned int i, j;
- BYTE far *cp;
- INDEX far *ip;
- OFSTRUCT idxof;
-
-
- kanji_list[0] = 0;
-
- fd = OpenFile (global.userdict, &idxof, OF_READ);
- if (fd >= 0) {
- close(fd);
- ReadUserConversions(global.userdict);
- }
-
- for (;;) {
- fd = OpenFile (global.convdict, &dctof, OF_READ);
- if (fd >= 0) break;
- if (!RetryMessage ("Cannot open dictionary '%s'!", global.convdict)) {
- ErrorMessage(global.hwnd, PROGNAME " cannot continue.");
- exit (-1);
- }
- }
- close(fd);
-
- for (;;) {
- fd = OpenFile (global.convidx, &idxof, OF_READ);
- if (fd >= 0) break;
- if (!RetryMessage ("Cannt open index file '%s'!", global.convidx)) {
- ErrorMessage(global.hwnd, PROGNAME " cannot continue.");
- exit (-1);
- }
- }
-
- lseek(fd, 0L, 0);
-
- cp = index = (BYTE far *) BlockAlloc(C64K);
- offset = (LONG int far *) BlockAlloc(C64K);
-
- nr_index = 0;
-
- /* Read the file in blocks of 32K */
-
- blocks = 32760 / sizeof(INDEX); /* A little less than 32K */
- bytes = blocks * sizeof(INDEX);
- ip = (INDEX far *) BlockAlloc(bytes);
-
- for (;;) {
- n = _lread(fd, (char far *) ip, bytes);
- n /= sizeof(INDEX);
- for (i = 0; i < n; i++) {
- for (j = 0; j < INDEXLEVEL; j++) *cp++ = ip[i].key[j];
- offset[nr_index++] = ip[i].offset;
- }
- if (n < blocks) break;
- }
-
- FreeBlock(ip);
-
- close(fd);
-
- return (TRUE);
- }
-
-
-
- BOOL MergeKanjiLists (KANJI *d, KANJI *s)
- {
- int i, j, k, len;
- BOOL diff;
-
- if (!d[0]) {
- if (!s[0]) return (FALSE);
-
- kanjicpy(d, s);
- return (TRUE);
- }
-
- if (!s[0]) return (TRUE);
-
- len = kanjilen(s);
- s[len++] = '/';
- s[len] = 0;
-
- len = kanjilen(d);
- d[len++] = '/';
- d[len] = 0;
-
- for (i = 0; s[i]; i++) {
- j = 0;
-
- for (; d[j]; j++) {
- diff = TRUE;
- for (k = 0; d[j+k] != '/' && d[j+k] == s[i+k]; k++);
-
- if (d[j+k] == s[i+k]) {
- diff = FALSE;
- break;
- }
- for (; d[j] != '/'; j++);
- }
-
- if (diff) {
- for (k = 0; s[i+k] && s[i+k] != '/'; k++) d[len++] = s[i+k];
- d[len++] = '/';
- d[len] = 0;
- }
-
- for (; s[i] && s[i] != '/'; i++);
-
- if (!s[i]) break;
- }
-
- len = kanjilen(d);
- if (d[len-1] == '/') d[len-1] = 0;
-
- return (TRUE);
- }
-
-
-
- static int BinarySearch (BYTE *key)
- {
- unsigned int top, bottom, middle;
- int diff;
-
- top = 0;
- bottom = nr_index - 1;
-
- for (;;) {
- middle = (top + bottom) / 2;
-
- diff = indexcmp(key, &(index[middle * (unsigned int) INDEXLEVEL]));
-
- if (diff == 0) return (middle);
-
- if (top >= bottom - 1) {
- diff = indexcmp(key, &(index[bottom * (unsigned int) INDEXLEVEL]));
- if (diff == 0) return (bottom);
- break;
- }
-
- if (diff > 0) top = middle;
- else bottom = middle;
- }
-
- return (top);
-
- }
-
-
- static int SearchUserDictionary (USERCONV far *UserConv, BYTE *target, KANJI endkana, KANJI *out)
- {
- int i, tlen, klen, olen;
- char *cp, ending = '*', kending;
- USERCONV far *up;
- KANJILIST far *kp;
- BOOL exact = FALSE, hope = FALSE;
-
- if (endkana != 0) {
- cp = ReverseKana(endkana);
- if (*cp == '-') cp++;
- ending = *cp;
- }
-
- tlen = bytelen(target);
- olen = kanjilen(out);
-
- for (up = UserConv; up != NULL; up = up->next) {
- klen = bytelen(up->kana);
- if (!(up->kana[klen - 1] & 0x80)) {
- kending = up->kana[klen - 1];
- klen--;
- } else {
- kending = '*';
- }
-
- if (klen == tlen) {
- if (!bytencmp(up->kana, target, tlen) && ending == kending) {
- exact = TRUE;
- /* Put in the kanji strings */
- for (kp = up->list; kp != NULL; kp = kp->next) {
- if (olen > 0) out[olen++] = '/';
- for (i = 0; kp->kanji[i]; i++) out[olen++] = kp->kanji[i];
- if (endkana != 0) out[olen++] = endkana;
- }
- out[olen] = 0;
- }
- } else if (tlen < klen && ending == '*') {
- if (!bytencmp(up->kana, target, tlen)) hope = TRUE;
- }
-
- if (exact && hope) break;
- }
-
- if (!exact) return (hope ? 1 : 0);
- else return (hope ? 3 : 2);
- }
-
-
-
- static int SearchStandardDictionary (FILE *fp, BYTE *target, KANJI endkana, KANJI *out)
- {
- int i, j, diff;
- int ReturnVal;
- char ending = '*';
- char *cp;
- BOOL exact = FALSE;
- BOOL hope = FALSE;
-
- BYTE kana[MAXLINELEN];
- char dct_ending[2];
- BYTE conv[MAXLINELEN];
- BYTE buffer[MAXLINELEN];
-
- out[0] = 0;
-
- if (endkana != 0) {
- cp = ReverseKana(endkana);
- if (*cp == '-') cp++;
- ending = *cp;
- }
-
- for (;;) {
- if (fgets(buffer, MAXLINELEN, fp) == NULL) break;
-
- kana[0] = dct_ending[0] = conv[0] = '\0';
-
- sscanf(buffer, "%s %s %s", kana, dct_ending, conv);
-
- diff = bytecmp (kana, target);
-
- if (diff > 0 && ending == '*') {
- if (bytencmp (kana, target, bytelen(target)) == 0) hope = TRUE;
- }
-
- if (diff > 0) break;
-
- if (ending != dct_ending[0]) continue;
-
- if (diff == 0) {
- exact = TRUE;
- for (i = j = 0; conv[j]; i++, j++) {
- if (conv[j] & 0x0080) {
- out[i] = (conv[j] << 8) | conv[j+1];
- j++;
- } else {
- if (endkana != 0 && conv[j] == '/') out[i++] = endkana;
- out[i] = conv[j];
- }
- }
-
- if (endkana != 0) out[i++] = endkana;
- out[i] = 0;
-
- if (ending != '*') break;
- }
- }
-
- for (i = 0; out[i]; i++) out[i] &= 0x7f7f;
-
- if (!exact) ReturnVal = (hope ? 1 : 0);
- else ReturnVal = (hope ? 3 : 2);
-
-
- /* Anything in the user dictionary? */
-
- i = SearchUserDictionary (UserConversions, target, endkana, out);
-
- return (i | ReturnVal);
- }
-
-
-
- int FindConversion (KANJI *line, KANJI *match)
- {
- int i, r, len;
- int fd;
- FILE *fp;
- BYTE key[MAXLINELEN];
- KANJI conv[MAXLINELEN];
- KANJI ending;
-
-
- match[0] = conv[0] = 0;
-
-
- for (i = 0; line[i] != 0; i++) {
- if (ISKANJI(line[i])) {
- key[i] = LOBYTE(line[i]) | 0x0080;
- } else {
- key[i] = LOBYTE(line[i]) & 0x007f;
- }
- }
- key[i] = '\0';
-
-
- /* Find the conversion without ending */
-
- i = BinarySearch(key);
- if (i < 0) return (0);
-
- fd = OpenFile(NULL, &(dctof), OF_READ | OF_REOPEN);
-
- fp = fdopen(fd, "r");
- if (fp == NULL) return (0);
-
- fseek(fp, offset[i], 0);
-
- kanji_list[0] = 0;
-
- r = SearchStandardDictionary(fp, key, 0, match);
-
- len = kanjilen(line);
-
- if (len <= 1) {
- fclose(fp);
- return (r);
- }
-
-
- /* Find the conversion with ending */
-
- ending = line[len-1];
-
- key[len-1] = '\0';
-
- i = BinarySearch(key);
- if (i < 0) {
- fclose(fp);
- return (r);
- }
-
- fseek(fp, offset[i], 0);
-
- if (SearchStandardDictionary(fp, key, ending, conv)) {
- MergeKanjiLists(match, conv);
- r |= 0x02;
- }
-
- fclose(fp);
-
- return (r);
- }
-
-
-
- void PutIntoConvCache (BYTE far *key, KANJI far *choice)
- {
- long int i, j, k, n;
- BYTE far *bp;
- KANJI far *kp;
-
-
- /* Cache there? */
-
- if (ConvCache == NULL) {
- ConvCache = (CHOICE far *) BlockAlloc(CACHESIZE);
- ConvCacheSize = CACHESIZE / sizeof(CHOICE);
- ConvRequests = ConvHits = ConvUsage = 0L;
- for (i = 0; i < ConvCacheSize; i++)
- ConvCache[i].keylen = ConvCache[i].choicelen = 0;
- }
-
- n = ConvHash(key);
-
- ConvChoiceChanges++;
-
- /* In the cache already? */
-
- for (i = n; ;) {
- j = ConvCache[i].keylen;
- k = ConvCache[i].choicelen;
-
- if (j <= 0 || k <= 0) break;
-
- if (j > 4) bp = ConvCache[i].key.ptr; else bp = ConvCache[i].key.string;
- //if (ConvHash(bp) != n) break;
-
- if (!bytencmp(bp, key, j)) { /* Found it! */
- if (k > 2) FreeBlock(ConvCache[i].choice.ptr);
- k = kanjilen(choice);
-
- if (k > 2) kp = ConvCache[i].choice.ptr = (KANJI far *) BlockAlloc(k * sizeof(KANJI));
- else kp = ConvCache[i].choice.string;
-
- _fmemcpy(kp, choice, k * sizeof(KANJI));
- ConvCache[i].choicelen = k;
- return;
- }
- if (++i >= ConvCacheSize) i = 0; /* Wrap around */
- if (i == n) break; /* Complete cycle */
- }
-
- /* Is the cache too full? */
-
- if (ConvUsage > (ConvCacheSize * 2 / 3)) {
- /* Bump off something by random */
- i = n;
- }
-
- /* Put it in the cache */
-
- if (j > 4) FreeBlock(ConvCache[i].key.ptr);
- j = bytelen(key);
-
- if (j > 4) bp = ConvCache[i].key.ptr = (BYTE far *) BlockAlloc(j);
- else bp = ConvCache[i].key.string;
-
- _fmemcpy(bp, key, j);
- ConvCache[i].keylen = j;
-
- if (k > 2) FreeBlock(ConvCache[i].choice.ptr);
- k = kanjilen(choice);
-
- if (k > 2) kp = ConvCache[i].choice.ptr = (KANJI far *) BlockAlloc(k * sizeof(KANJI));
- else kp = ConvCache[i].choice.string;
-
- _fmemcpy(kp, choice, k * sizeof(KANJI));
- ConvCache[i].choicelen = k; //((k > 2) ? -1 : k);
-
- ConvUsage++;
- }
-
-
- int ConvCacheLookup (BYTE far *key, KANJI far *list)
- {
- long int i, j, k, n;
- BYTE far *bp;
- KANJI far *kp;
-
-
- if (ConvCache == NULL) return (-1);
-
- ConvRequests++;
-
- n = ConvHash(key);
-
- for (i = n; ;) {
- j = ConvCache[i].keylen;
- k = ConvCache[i].choicelen;
-
- if (j <= 0 || k <= 0) break;
-
- /* Found it! */
- if (j > 4) bp = ConvCache[i].key.ptr; else bp = ConvCache[i].key.string;
-
- if (!bytencmp(bp, key, j)) { /* Found it! */
- ConvHits++;
-
- /* Look it up in the list */
-
- if (k > 2) kp = ConvCache[i].choice.ptr; else kp = ConvCache[i].choice.string;
-
- for (i = j = 0; ; ) {
- if (!kanjincmp(kp, list + j, k) && (list[j + k] == '/' || list[j + k] == 0))
- return (i);
-
- /* Skip to the next word */
-
- for (; list[j] && list[j] != '/'; j++);
- if (!list[j]) return (-1);
-
- i++; j++;
- }
- }
- if (++i >= ConvCacheSize) i = 0; /* Wrap around */
- if (i == n) break; /* Complete cycle */
- }
-
- return (-1);
- }
-
-
-
- void WriteConversionCache (char *fname)
- {
- int i, j, k;
- int fd;
- OFSTRUCT of;
- KANJI far *kp;
- BYTE far *bp;
-
- if (ConvChoiceChanges <= 0L) return;
-
- fd = OpenFile(fname, &of, OF_CREATE | OF_WRITE);
- if (fd < 0) {
- ErrorMessage(global.hwnd, "WARNING: Cannot write conversion cache '%s'!", fname);
- return;
- }
-
- lseek(fd, 0L, 0);
-
- for (i = 0; i < ConvCacheSize; i++) {
- j = ConvCache[i].keylen;
- k = ConvCache[i].choicelen;
-
- if (j <= 0 || k <= 0) continue;
-
- write(fd, &j, sizeof(int));
- if (j > 4) bp = ConvCache[i].key.ptr; else bp = ConvCache[i].key.string;
- _lwrite(fd, bp, j);
-
- write(fd, &k, sizeof(int));
- if (k > 2) kp = ConvCache[i].choice.ptr; else kp = ConvCache[i].choice.string;
- _lwrite(fd, kp, k * sizeof(KANJI));
- }
-
- close(fd);
- }
-
-
-
- void ReadConversionCache (char *fname)
- {
- int i, fd;
- OFSTRUCT of;
- BYTE keybuf[BUFSIZE];
- KANJI choicebuf[BUFSIZE];
-
- fd = OpenFile(fname, &of, OF_READ);
- if (fd < 0) return;
-
- lseek(fd, 0L, 0);
-
- for (;;) {
- if (read(fd, &i, sizeof(int)) != sizeof(int)) break;
- if (read(fd, keybuf, i) != i) break;
- keybuf[i] = 0;
-
- if (read(fd, &i, sizeof(int)) != sizeof(int)) break;
- if (read(fd, choicebuf, i * sizeof(KANJI)) != i * sizeof(KANJI)) break;
- choicebuf[i] = 0;
-
- PutIntoConvCache(keybuf, choicebuf);
- }
-
- close(fd);
- }
-
-
-
- static void MoveChoice (HWND hwnd, int oldpos, int oldlen, int newpos, int length, int gap)
- {
- HDC hdc;
- RECT rect;
- HRGN hrgn;
-
- hdc = GetDC(hwnd);
-
- GetClientRect(hwnd, &rect);
- hrgn = CreateRectRgn (BORDERSPACE - gap, BORDERSPACE - gap,
- rect.right - BORDERSPACE + gap + 1,
- rect.bottom - BORDERSPACE + gap + 1);
- SelectClipRgn(hdc, hrgn);
- DeleteObject(hrgn);
-
- if (oldpos >= 0) {
- PatBlt(hdc, oldpos- gap, BORDERSPACE - gap, oldlen - SYSFONT->leading + 2 * gap,
- SYSFONT->height + 2 * gap, DSTINVERT);
- }
-
- if (newpos >= 0 && length > 0) {
- PatBlt(hdc, newpos - gap, BORDERSPACE - gap, length - SYSFONT->leading + 2*gap,
- SYSFONT->height + 2*gap, DSTINVERT);
- }
-
- ReleaseDC(hwnd, hdc);
- }
-
-
-
- static void ChangeChoice(FILEOPTIONS *f, int wordchoice)
- {
- int j, k, convlen;
- int options = OP_REFORMAT | OP_UPDATE | OP_CHOOSEKANJI;
- POSITION p;
- ONELINE far *lp;
- KANJI buffer[BUFSIZE];
-
- if (SELPARA1(f) == NULL || SELTYPE(f) != SEL_CONVERSION) return;
-
- for (k = 0, j = words[wordchoice]; j < words[wordchoice+1] - 1; j++, k++)
- buffer[k] = kanji_list[j];
- buffer[k] = 0;
-
- p = SEL1(f);
-
- convlen = SELPOS2(f) - SELPOS1(f) + 1,
- SELPOS2(f) = SELPOS1(f) + kanjilen(buffer) - 1;
- SELNOW(f) = FALSE;
-
- if (k == convlen) options |= OP_SAMELEN;
-
- /* Find the line */
-
- for (lp = PARAOF(p)->lines; lp != NULL; lp = lp->next)
- if (lp->position > SELPOS1(f)) break;
-
- if (lp != NULL) lp = lp->prev;
- else lp = PARAOF(p)->lastline;
-
- LINEOF(p) = lp;
- POSOF(p) = SELPOS1(f) - LINEOF(p)->position;
-
- EnableFontCache(FALSE);
- UndoFixConvert(f, p, convlen, kanjilen(buffer));
- ReplaceString(f, p, convlen, buffer, options);
- EnableFontCache(TRUE);
- }
-
-
- /* LB_RESETCONTENT = Initialize (lParam = FILEOPTIONS *) */
- /* LB_SETHORIZONTALEXTENT = Move selection to the middle */
-
- LONG FAR PASCAL ConvProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- int i, j, k, r;
- int leftgap, rightgap, gap;
- HDC hdc;
- HRGN hrgn;
- PAINTSTRUCT ps;
- RECT rect;
- BYTE far *cbufp;
- static FILEOPTIONS *selfile;
- static int scrollrange;
- static int scrollpos;
- static int choicepos;
-
-
- switch (message) {
-
- case WM_CREATE:
- sizing = FALSE;
- global.convsel = -1;
- scrollpos = 0;
- scrollrange = choicepos = -1;
- SetScrollRange(hwnd, SB_HORZ, 0, 100, TRUE);
- SetScrollPos(hwnd, SB_HORZ, 0, TRUE);
- kanji_list[0] = 0;
-
- if (global.listposition == 0) {
- GetWindowRect(global.hwnd, &rect);
-
- i = /*GetSystemMetrics(SM_CYCAPTION) + */ SYSFONT->height +
- 2 * BORDERSPACE + GetSystemMetrics(SM_CYHSCROLL) +
- 2 * GetSystemMetrics(SM_CYBORDER);
-
- if (global.convbar.right < 0) global.convbar.right = rect.right;
- global.convbar.bottom = i;
-
- MoveWindow(hwnd, rect.left + global.convbar.left, rect.top + global.convbar.top,
- global.convbar.right, global.convbar.bottom, TRUE);
- SetActiveWindow(global.hwnd);
- }
-
- return (0);
-
- case WM_GETMINMAXINFO: {
- POINT far *lp;
-
- lp = (POINT far *) lParam;
-
- lp[3].y = lp[4].y = global.convbar.bottom;
- if (lp[3].x < global.convbar.right) {
- lp[3].x = 2 * SYSFONT->width + 2 * BORDERSPACE;
- }
-
- return (0);
- }
-
- case WM_SIZE:
- if (global.listposition != 0 || global.convhwnd == NULL) break;
-
- GetWindowRect(hwnd, &rect);
- global.convbar.right = rect.right - rect.left;
- return (0);
-
- case WM_MOVE: {
- int x, y1, y2;
- RECT rect1, rect2;
-
- if (global.hwnd == NULL || global.clienthwnd == NULL) return (0);
- if (IsIconic(hwnd) || IsIconic(global.hwnd)) return (0);
-
- GetWindowRect(global.clienthwnd, &rect1);
- GetWindowRect(hwnd, &rect2);
-
- if (!AfterHitTest) {
- if (global.listposition == 0) {
- GetWindowRect(global.hwnd, &rect1);
-
- global.convbar.left = rect2.left - rect1.left;
- global.convbar.top = rect2.top - rect1.top;
- }
-
- return (0);
- }
-
- AfterHitTest = FALSE;
-
- if (global.listposition != 0) {
- if (rect2.top < rect1.top) {
- global.listposition = 1;
- } else if (rect2.bottom > rect1.bottom) {
- global.listposition = 2;
- } else {
- GetWindowRect(global.hwnd, &rect1);
- global.convbar.left = rect2.left - rect1.left;
- global.convbar.top = rect2.top - rect1.top;
- global.listposition = 0;
- }
- } else {
- if (rect2.top < rect1.top) {
- global.listposition = 1;
- } else if (rect2.bottom > rect1.bottom) {
- global.listposition = 2;
- } else {
- GetWindowRect(global.hwnd, &rect1);
-
- global.convbar.left = rect2.left - rect1.left;
- global.convbar.top = rect2.top - rect1.top;
-
- return (0);
- }
- }
-
- GetClientRect(global.hwnd, &rect1);
- i = rect1.bottom - rect1.top;
- PostMessage(global.hwnd, WM_SIZE, 0, MAKELONG(rect1.right - rect1.left, i));
- OptionsChanged = TRUE;
- return (0);
- }
-
- case LB_RESETCONTENT:
- choicepos = scrollrange = -1;
- selfile = (FILEOPTIONS *) lParam;
-
- k = 0;
- words[k++] = 0;
- scrollrange = 0;
-
- for (i = 0; kanji_list[i] != 0; i++) {
- if ((kanji_list[i] & 0x7fff) == '/') {
- words[k++] = i + 1;
- scrollrange++;
- }
- }
- words[k++] = i + 1;
-
- SendMessage(hwnd, LB_SETHORIZONTALEXTENT, 0, 0L); /* Move to middle */
-
- SetScrollRange(hwnd, SB_HORZ, 0, (scrollrange <= 0) ? 1 : scrollrange, FALSE);
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
-
- InvalidateRect(hwnd, NULL, FALSE);
- UpdateWindow(hwnd);
- SetActiveWindow(global.hwnd);
- return (0);
-
- case LB_SETHORIZONTALEXTENT:
- if (global.convsel < 0) {
- scrollpos = 0;
- } else {
- /* Put it into the middle */
-
- scrollpos = global.convsel;
- if (scrollpos > scrollrange) scrollpos = scrollrange;
-
- GetClientRect(hwnd, &rect);
- j = (rect.right - 2 * BORDERSPACE) / 2;
-
- for (; scrollpos > 0; scrollpos--) {
- j -= (words[scrollpos] - words[scrollpos-1] - 1) * (SYSFONT->width + SYSFONT->leading) + SEPARATION;
- if (j < 0) break;
- }
- if (scrollpos < 0) scrollpos = 0;
- }
- SetActiveWindow(global.hwnd);
- return (0);
-
- case WM_HSCROLL:
- SetActiveWindow(global.hwnd);
-
- gap = SYSFONT->leading;
-
- switch (wParam) {
-
- case SB_LINEUP:
- if (scrollpos <= 0) return (0);
-
- GetClientRect(hwnd, &rect);
- rect.top = rect.left = BORDERSPACE - gap;
- rect.bottom -= (BORDERSPACE - gap - 1);
- rect.right -= (BORDERSPACE - gap - 1);
-
- k = (words[scrollpos] - words[scrollpos-1] - 1) * (SYSFONT->width + SYSFONT->leading) + SEPARATION;
-
- ScrollWindow(hwnd, k, 0, NULL, &rect);
-
- if (choicepos >= 0) choicepos += k;
- if (choicepos >= (rect.right - BORDERSPACE) || choicepos < BORDERSPACE)
- choicepos = -1;
-
- scrollpos--;
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
- break;
-
- case SB_LINEDOWN:
- if (scrollpos >= scrollrange) return (0);
-
- GetClientRect(hwnd, &rect);
- rect.top = rect.left = BORDERSPACE - gap;
- rect.bottom -= (BORDERSPACE - gap - 1);
- rect.right -= (BORDERSPACE - gap - 1);
-
- k = (words[scrollpos+1] - words[scrollpos] - 1) * (SYSFONT->width + SYSFONT->leading) + SEPARATION;
-
- ScrollWindow(hwnd, -k, 0, NULL, &rect);
-
- if (choicepos >= 0) choicepos -= k;
- if (choicepos >= (rect.right - BORDERSPACE) || choicepos < BORDERSPACE)
- choicepos = -1;
-
- scrollpos++;
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
- break;
-
- case SB_PAGEUP:
- if (scrollpos <= 0) return (0);
-
- GetClientRect(hwnd, &rect);
-
- j = 0;
- for (i = scrollpos; i >= 0; i--) {
- k = (words[i] - words[i-1] - 1) * (SYSFONT->width + SYSFONT->leading);
- if (j + k + SEPARATION > rect.right - BORDERSPACE) break;
- j += k + SEPARATION;
- }
- if (i + 1 != scrollpos) i++;
- scrollpos = i;
- choicepos = -1;
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
- InvalidateRect(hwnd, NULL, FALSE);
- break;
-
- case SB_PAGEDOWN:
- if (scrollpos >= scrollrange) return (0);
-
- GetClientRect(hwnd, &rect);
-
- j = 0;
- for (i = scrollpos; i <= scrollrange; i++) {
- k = (words[i+1] - words[i] - 1) * (SYSFONT->width + SYSFONT->leading);
- if (j + k + SEPARATION > rect.right - BORDERSPACE) break;
- j += k + SEPARATION;
- }
- if (i - 1 != scrollpos) i--;
- scrollpos = i;
- choicepos = -1;
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
- InvalidateRect(hwnd, NULL, FALSE);
- break;
-
- case SB_THUMBPOSITION:
- scrollpos = LOWORD(lParam);
- choicepos = -1;
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
- InvalidateRect(hwnd, NULL, FALSE);
- break;
-
- default:
- return (0);
- }
-
- UpdateWindow(hwnd);
- return (0);
-
- case WM_KEYDOWN:
- SetActiveWindow(global.hwnd);
-
- if (global.convsel < 0) return (0);
-
- gap = SYSFONT->leading;
-
- switch (wParam) {
-
- case VK_HOME:
- scrollpos = 0;
- global.convsel = 0;
- choicepos = -1;
- SetScrollPos(hwnd, SB_HORZ, 0, TRUE);
- InvalidateRect(hwnd, NULL, FALSE);
- break;
-
- case VK_END:
- global.convsel = scrollrange;
- choicepos = -1;
-
- SendMessage(hwnd, LB_SETHORIZONTALEXTENT, 0, 0L); /* Move to middle */
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
-
- InvalidateRect(hwnd, NULL, FALSE);
- return (0);
-
- case VK_LEFT:
- if (global.convsel <= 0) {
- global.convsel = scrollrange;
- scrollpos = scrollrange;
- SendMessage(hwnd, LB_SETHORIZONTALEXTENT, 0, 0L); /* Move to middle */
- InvalidateRect(hwnd, NULL, FALSE);
- UpdateWindow(hwnd);
- SetScrollPos(hwnd, SB_HORZ, scrollpos, TRUE);
- return (0);
- }
-
- i = (words[global.convsel+1] - words[global.convsel] - 1) * (SYSFONT->width + SYSFONT->leading);
- global.convsel--;
- j = (words[global.convsel+1] - words[global.convsel] - 1) * (SYSFONT->width + SYSFONT->leading);
-
- if (choicepos < 0) {
- scrollpos = global.convsel;
- InvalidateRect(hwnd, NULL, FALSE);
- UpdateWindow(hwnd);
- } else {
- MoveChoice(hwnd, choicepos, i, choicepos - j - SEPARATION, j, gap);
- choicepos -= j + SEPARATION;
- if (scrollpos == global.convsel + 1)
- SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, 0L);
- }
- return (0);
-
- case VK_RIGHT:
- if (global.convsel >= scrollrange) {
- global.convsel = 0;
- scrollpos = 0;
- InvalidateRect(hwnd, NULL, FALSE);
- UpdateWindow(hwnd);
- SetScrollPos(hwnd, SB_HORZ, 0, TRUE);
- return (0);
- }
-
- GetClientRect(hwnd, &rect);
-
- i = (words[global.convsel+1] - words[global.convsel] - 1) * (SYSFONT->width + SYSFONT->leading);
- global.convsel++;
- j = (words[global.convsel+1] - words[global.convsel] - 1) * (SYSFONT->width + SYSFONT->leading);
-
- if (choicepos < 0) {
- scrollpos = global.convsel;
- InvalidateRect(hwnd, NULL, FALSE);
- UpdateWindow(hwnd);
- } else {
- MoveChoice(hwnd, choicepos, i, choicepos + i + SEPARATION, j, gap);
- choicepos += i + SEPARATION;
- while (choicepos + j >= (rect.right - BORDERSPACE) && scrollpos < scrollrange)
- SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, 0L);
- }
- return (0);
-
- case VK_RETURN: {
- KANJI buffer[BUFSIZE];
-
- if (selfile == NULL) return (0);
-
- ChangeChoice(selfile, global.convsel);
-
- for (k = 0, j = words[global.convsel]; j < words[global.convsel + 1] - 1; j++, k++)
- buffer[k] = kanji_list[j];
- buffer[k] = 0;
-
- PutIntoConvCache(LastConvKey, buffer);
- return (0);
- }
-
- default: return (0);
- }
- UpdateWindow(hwnd);
- return (0);
-
- case WM_NCHITTEST:
- case WM_LBUTTONDOWN: {
- int x, y, i;
- int oldlen;
-
- SetActiveWindow(global.hwnd);
-
- if (message == WM_NCHITTEST) {
- i = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
-
- if (i != HTCLIENT) return (i);
-
- GetWindowRect(hwnd, &rect);
-
- x = LOWORD(lParam) - rect.left;
- y = HIWORD(lParam) - rect.top;
-
- if (global.listposition == 0) {
- x -= GetSystemMetrics(SM_CXFRAME);
- y -= GetSystemMetrics(SM_CYFRAME);
- }
-
- if (x < BORDERSPACE || y < BORDERSPACE) {
- AfterHitTest = TRUE;
- return (HTCAPTION);
- }
- if (y >= BORDERSPACE + SYSFONT->height) {
- AfterHitTest = TRUE;
- return (HTCAPTION);
- }
- } else {
- x = LOWORD(lParam);
- y = HIWORD(lParam);
-
- if (x < BORDERSPACE || y < BORDERSPACE) return (0);
- if (y >= BORDERSPACE + SYSFONT->height) return (0);
- }
-
- gap = SYSFONT->leading;
- GetClientRect(hwnd, &rect);
-
- /* Find the old selected position */
-
- oldlen = (words[global.convsel+1] - words[global.convsel] - 1) * (SYSFONT->width + SYSFONT->leading);
-
- j = BORDERSPACE;
-
- for (i = scrollpos; i <= scrollrange; i++) {
- k = (words[i+1] - words[i] - 1) * (SYSFONT->width + SYSFONT->leading);
- if (j + k > x) break;
- if (message == WM_NCHITTEST && j + k + SEPARATION > x) {
- AfterHitTest = TRUE;
- return (HTCAPTION);
- }
- j += k + SEPARATION;
- }
-
- if (message == WM_NCHITTEST) {
- if (i > scrollrange) {
- AfterHitTest = TRUE;
- return (HTCAPTION);
- } else {
- AfterHitTest = FALSE;
- return (HTCLIENT);
- }
- } else {
- if (i > scrollrange) return (0);
- }
-
- if (i == global.convsel) return (0);
-
- MoveChoice(hwnd, choicepos, oldlen, j, k, gap);
- choicepos = j;
-
- global.convsel = i;
-
- /* Replace the kanji */
-
- SendMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0L);
-
- return (0);
- }
-
- case WM_PAINT:
- if (global.convsel < 0) choicepos = -1;
-
- gap = SYSFONT->leading;
-
- hdc = BeginPaint(hwnd, &ps);
-
- SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
- SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
-
- GetClientRect(hwnd, &rect);
- rect.top = rect.left = -1;
- rect.bottom++; rect.right++;
- Create3DEffect(hdc, &rect, 1, 0);
-
- if (scrollrange < 0) {
- EndPaint(hwnd, &ps);
- return (0);
- }
-
- hrgn = CreateRectRgn (BORDERSPACE - gap, BORDERSPACE - gap,
- rect.right - BORDERSPACE + gap,
- rect.bottom - BORDERSPACE + gap);
- SelectClipRgn(hdc, hrgn);
- DeleteObject(hrgn);
-
- j = BORDERSPACE;
-
- EnableFontCache(FALSE);
-
- for (i = words[scrollpos]; kanji_list[i]; i++) {
- if (j + SYSFONT->width + gap < ps.rcPaint.left) {
- j += ((kanji_list[i] & 0x7fff) == '/') ?
- SEPARATION : SYSFONT->width + SYSFONT->leading;
- continue;
- }
- if (j > ps.rcPaint.right) break;
-
- if ((kanji_list[i] & 0x7fff) == '/') {
- j += SEPARATION;
- continue;
- }
- if (ISASCII(kanji_list[i])) continue;
-
- r = Jis2Index(kanji_list[i], SYSFONT->holes);
- if (r < 0) r = Jis2Index(BADKANJI, SYSFONT->holes);
- r = GetKanjiBitmap(SYSFONT, r, &cbufp);
-
- DisplayKanjiBitmap(hdc, j, BORDERSPACE + SYSFONT->height,
- SYSFONT->width, SYSFONT->height,
- r, SRCCOPY, cbufp);
-
- if (global.convsel >= 0 &&
- words[global.convsel] <= i && i < words[global.convsel+1]) {
-
- if (i > words[global.convsel]) {
- PatBlt(hdc, j - SYSFONT->leading, BORDERSPACE - gap,
- SYSFONT->leading, SYSFONT->height + 2*gap, DSTINVERT);
- } else {
- choicepos = j;
- }
-
- leftgap = rightgap = 0;
-
- if (i <= words[global.convsel]) {
- leftgap = gap;
- }
- if (i >= words[global.convsel+1] - 2) {
- rightgap = gap;
- }
-
- PatBlt(hdc, j - leftgap, BORDERSPACE - gap,
- SYSFONT->width + leftgap + rightgap, SYSFONT->height + 2*gap,
- DSTINVERT);
- }
-
- j += SYSFONT->width + SYSFONT->leading;
- }
-
- EnableFontCache(TRUE);
-
- EndPaint(hwnd, &ps);
-
- return (0);
- }
-
- return (DefWindowProc(hwnd, message, wParam, lParam));
- }
-
-
-
- void ConvCacheStatistics (long int *usage, long int *requests, long int *hits)
- {
- *requests = ConvRequests;
- *hits = ConvHits;
- *usage = ConvUsage;
- }
-
-
-
- static BOOL IsValidReading (UNIT far *s)
- {
- int i;
- KANJI ch;
-
- if (!s[0].kanji) return (FALSE);
-
- for (i = 0; s[i].kanji; i++) {
- ch = s[i].kanji;
- if (!ISKANJI(ch)) {
- if ('A' <= ch && ch <= 'Z') ch += 32;
- if (i <= 0) return (FALSE);
- if (strchr("ukgsztdnmhbpr", LOBYTE(ch)) == NULL) return (FALSE);
- return (!s[i+1].kanji);
- } else if (HIBYTE(ch) != 0x24) return (FALSE);
- }
-
- return (TRUE);
- }
-
-
-
- static KANJI far *ConvertUser (int id, LONG lParam, KANJI *buf)
- {
- int i;
- USERCONV far *up;
- KANJILIST far *kp;
-
- if (lParam == NULL) {
- buf[0] = 0;
- return (buf);
- }
-
- if (id == 4201) {
- up = (USERCONV far *) lParam;
- for (i = 0; up->kana[i]; i++) {
- if (up->kana[i] & 0x80) buf[i] = 0x2400 | (up->kana[i] & 0x007f);
- else buf[i] = up->kana[i];
- }
- buf[i] = 0;
- return (buf);
- } else if (id == 4202) {
- kp = (KANJILIST far *) lParam;
- return (kp->kanji);
- } else {
- ErrorMessage(global.hwnd, "Bad id to ConvertUser! (%d)", id);
- return (buf);
- }
- }
-
-
-
- BOOL FAR PASCAL EditUserConversionProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- switch (message) {
- case WM_INITDIALOG: {
- int i;
- FILEOPTIONS *f;
- KANJI buf[BUFSIZE];
-
- /* Set the type and mode-change icon */
- SendDlgItemMessage(hwnd, 4201, EM_SETMODIFY, FN_CONTROL | FN_NOKANJI, 0L);
- SendDlgItemMessage(hwnd, 4201, EM_SETRECT, GetDlgItem(hwnd, 4211), 0L);
-
- SendDlgItemMessage(hwnd, 4202, EM_SETMODIFY, FN_CONTROL, 0L);
- SendDlgItemMessage(hwnd, 4202, EM_SETRECT, GetDlgItem(hwnd, 4211), 0L);
-
- f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
- SendDlgItemMessage(hwnd, 4211, EM_SETHANDLE, f->hwnd, 0L); /* mode-change icon */
-
- if (CurrentConv != NULL) {
- for (i = 0; CurrentConv->kana[i]; i++) {
- if (CurrentConv->kana[i] & 0x80) buf[i] = 0x2400 | (CurrentConv->kana[i] & 0x007f);
- else buf[i] = CurrentConv->kana[i];
- }
- buf[i] = 0;
- SendDlgItemMessage(hwnd, 4201, EM_REPLACESEL, 0, (LONG) buf);
- SetFocus(GetDlgItem(hwnd, 4202));
- }
-
- if (CurrentKanji != NULL) {
- /* Edit */
- SendDlgItemMessage(hwnd, 4202, EM_REPLACESEL, 0, (LONG) CurrentKanji->kanji);
- i = kanjilen(CurrentKanji->kanji);
- SendDlgItemMessage(hwnd, 4202, EM_SETSEL, i, MAKELONG(0, i-1));
- SetWindowText(GetDlgItem(hwnd, 1), "&Done!");
- SetWindowText(hwnd, "Edit an Existing User Conversion");
- } else {
- /* Add */
- SetWindowText(GetDlgItem(hwnd, 1), "&Add!");
- SetWindowText(hwnd, "Add a New User Conversion");
- }
-
- CenterDialogBox(hwnd);
- return (TRUE);
- }
-
- case WM_COMMAND:
- switch (wParam) {
- case IDCANCEL:
- CurrentConv = NULL;
- CurrentKanji = NULL;
- EndDialog(hwnd, FALSE);
- return (TRUE);
-
- case IDOK: {
- int i;
- UNIT far *up, far *up1;
- KANJI ch;
-
- up1 = (UNIT far *) SendDlgItemMessage(hwnd, 4202, EM_GETLINE, 0, 0L);
- if (unitlen(up1) <= 0) {
- ErrorMessage(hwnd, "Sorry, you must enter a KANJI for the conversion");
- SetFocus(GetDlgItem(hwnd, 4202));
- return (TRUE);
- }
-
- if (CurrentKanji == NULL) {
- /* An Add */
- up = (UNIT far *) SendDlgItemMessage(hwnd, 4201, EM_GETLINE, 0, 0L);
- if (!IsValidReading(up)) {
- ErrorMessage(hwnd, "Sorry, what you have entered is not "
- "a proper kana reading. A proper kana "
- "reading is a string of hiragana, with "
- "no spaces and other symbols. It may "
- "or may not be followed by ONE (and only "
- "one) of the following letters:\n"
- "\n"
- " u, k, g, s, z, t, d, n, m, h, b, p, r\n"
- "\n"
- "Consult the documentation for details.");
- SetFocus(GetDlgItem(hwnd, 4201));
- return (TRUE);
- }
-
- CurrentConv = StructAlloc(USERCONV);
- CurrentKanji = StructAlloc(KANJILIST);
-
- CurrentConv->list = CurrentKanji;
- CurrentConv->next = CurrentConv->prev = NULL;
- CurrentKanji->next = CurrentKanji->prev = NULL;
-
- CurrentConv->kana = BlockAlloc(unitlen(up) + 5);
-
- for (i = 0; ; i++) {
- ch = up[i].kanji;
- if (ch == 0) {
- CurrentConv->kana[i] = 0;
- break;
- }
- if (ISKANJI(ch)) CurrentConv->kana[i] = LOBYTE(ch) | 0x0080;
- else {
- ch = LOBYTE(ch) & 0x7f;
- if ('A' <= ch && ch <= 'Z') ch += 32;
- CurrentConv->kana[i] = ch;
- }
- }
- } else {
- /* An Edit */
- FreeBlock(CurrentKanji->kanji);
- }
-
- CurrentKanji->kanji = BlockAlloc((unitlen(up1) + 5) * sizeof(KANJI));
- for (i = 0; ; i++) {
- if (!(CurrentKanji->kanji[i] = up1[i].kanji)) break;
- }
- UserConvChanged = TRUE;
- EndDialog(hwnd, FALSE);
- return (TRUE);
- }
- }
- return (TRUE);
-
- case WM_PAINT: {
- HDC hdc;
- PAINTSTRUCT ps;
-
- hdc = BeginPaint(hwnd, &ps);
-
- DrawBoundingBox(hwnd, hdc, 4201);
- DrawBoundingBox(hwnd, hdc, 4202);
-
- EndPaint(hwnd, &ps);
- return (TRUE);
- }
- }
- return (FALSE);
- }
-
-
-
- BOOL FAR PASCAL UserConversionProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- int i, j;
- USERCONV far *up;
- KANJILIST far *kp;
- INPUTMODE oldmode;
-
- switch (message) {
- case WM_INITDIALOG:
- EnableWindow(GetDlgItem(hwnd, 4212), FALSE); /* Edit */
- EnableWindow(GetDlgItem(hwnd, 4213), FALSE); /* Delete */
-
- for (up = UserConversions; up != NULL; up = up->next) {
- SendDlgItemMessage(hwnd, 4201, LB_ADDSTRING, 0, (LONG) up);
- }
- CenterDialogBox(hwnd);
- return (TRUE);
-
- case WM_KEYDOWN:
- switch (wParam) {
- case VK_ESCAPE: SendMessage(hwnd, WM_COMMAND, IDCANCEL, 0L);
- return (TRUE);
- }
- break;
-
- case WM_COMMAND:
- switch (wParam) {
- case 4201: /* Kana list */
- switch (HIWORD(lParam)) {
- case LBN_SELCHANGE: {
- i = SendDlgItemMessage(hwnd, 4201, LB_GETCURSEL, 0, 0L);
- if (i == LB_ERR) {
- MessageBeep(0);
- return (TRUE);
- }
-
- SendDlgItemMessage(hwnd, 4202, LB_RESETCONTENT, 0, 0L);
- SendDlgItemMessage(hwnd, 4202, WM_SETREDRAW, FALSE, 0L);
-
- up = (USERCONV far *) SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, i, 0L);
- for (kp = up->list; kp != NULL; kp = kp->next) {
- SendDlgItemMessage(hwnd, 4202, LB_ADDSTRING, 0, (LONG) kp);
- }
-
- SendDlgItemMessage(hwnd, 4202, WM_SETREDRAW, TRUE, 0L);
- InvalidateRect(GetDlgItem(hwnd, 4202), NULL, TRUE);
-
- EnableWindow(GetDlgItem(hwnd, 4212), FALSE); /* Edit */
- EnableWindow(GetDlgItem(hwnd, 4213), FALSE); /* Delete */
- return (0);
- }
- }
- return (TRUE);
-
- case 4202: /* Kanji list */
- switch (HIWORD(lParam)) {
- case LBN_SELCHANGE: {
- i = SendDlgItemMessage(hwnd, 4202, LB_GETCURSEL, 0, 0L);
- if (i == LB_ERR) {
- MessageBeep(0);
- return (TRUE);
- }
-
- EnableWindow(GetDlgItem(hwnd, 4212), TRUE); /* Edit */
- EnableWindow(GetDlgItem(hwnd, 4213), TRUE); /* Delete */
-
- return (0);
- }
-
- case LBN_DBLCLK:
- SendMessage(hwnd, WM_COMMAND, 4212, 0L); /* Edit */
- return (TRUE);
- }
- return (TRUE);
-
- case 4211: /* Add button */
- i = SendDlgItemMessage(hwnd, 4201, LB_GETCURSEL, 0, 0L);
- if (i == LB_ERR) {
- CurrentConv = NULL;
- } else {
- CurrentConv = (USERCONV far *) SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, i, 0L);
- }
- CurrentKanji = NULL;
-
- oldmode = global.mode;
- DialogBox (hInstance, "EditUserDict", hwnd, EditUserConversionProc);
- if (oldmode != global.mode) ToggleInputMode();
-
- if (CurrentConv == NULL && CurrentKanji == NULL) return (TRUE);
-
- /* Kana already in the list? */
-
- j = SendDlgItemMessage(hwnd, 4201, LB_GETCOUNT, 0, 0L);
- for (i = 0; i < j; i++) {
- up = (USERCONV far *) SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, i, 0L);
- if (!bytecmp(up->kana, CurrentConv->kana)) break;
- }
-
- if (i >= j) { /* Add to the list */
- CurrentConv->next = UserConversions;
- CurrentConv->prev = NULL;
- if (UserConversions != NULL) UserConversions->prev = CurrentConv;
- UserConversions = CurrentConv;
- SendDlgItemMessage(hwnd, 4201, LB_ADDSTRING, 0, (LONG) CurrentConv);
-
- /* Now determine which string is the one we added */
- j = SendDlgItemMessage(hwnd, 4201, LB_GETCOUNT, 0, 0L);
- for (i = 0; i < j; i++) {
- up = (USERCONV far *) SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, i, 0L);
- if (!bytecmp(up->kana, CurrentConv->kana)) break;
- }
-
- if (i < j) {
- SendDlgItemMessage(hwnd, 4201, LB_SETCURSEL, i, 0L);
- SendMessage(hwnd, WM_COMMAND, 4201, MAKELONG(0, LBN_SELCHANGE));
- } else {
- SendDlgItemMessage(hwnd, 4202, LB_RESETCONTENT, 0, 0L);
- }
-
- EnableWindow(GetDlgItem(hwnd, 4212), TRUE); /* Edit */
- EnableWindow(GetDlgItem(hwnd, 4213), TRUE); /* Delete */
- } else { /* Add to the kanji list */
- CurrentKanji->next = up->list;
- CurrentKanji->prev = NULL;
- if (up->list != NULL) up->list->prev = CurrentKanji;
- up->list = CurrentKanji;
- FreeBlock(CurrentConv);
-
- SendDlgItemMessage(hwnd, 4201, LB_SETCURSEL, i, 0L);
- SendMessage(hwnd, WM_COMMAND, 4201, MAKELONG(0, LBN_SELCHANGE));
- EnableWindow(GetDlgItem(hwnd, 4212), TRUE); /* Edit */
- EnableWindow(GetDlgItem(hwnd, 4213), FALSE); /* Delete */
- }
- return (TRUE);
-
- case 4212: /* Edit button */
- i = SendDlgItemMessage(hwnd, 4201, LB_GETCURSEL, 0, 0L);
- j = SendDlgItemMessage(hwnd, 4202, LB_GETCURSEL, 0, 0L);
- if (i == LB_ERR || j == LB_ERR) {
- MessageBeep(0);
- return (TRUE);
- }
- CurrentConv = (USERCONV far *) SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, i, 0L);
- CurrentKanji = (KANJILIST far *) SendDlgItemMessage(hwnd, 4202, LB_GETITEMDATA, j, 0L);
-
- oldmode = global.mode;
- DialogBox (hInstance, "EditUserDict", hwnd, EditUserConversionProc);
- if (oldmode != global.mode) ToggleInputMode();
-
- if (CurrentConv == NULL && CurrentKanji == NULL) return (TRUE);
-
- FreeBlock(CurrentConv->kana);
- FreeStruct(CurrentConv);
-
- InvalidateRect(GetDlgItem(hwnd, 4202), NULL, TRUE);
- return (TRUE);
-
- case 4213: /* Delete button */
- i = SendDlgItemMessage(hwnd, 4201, LB_GETCURSEL, 0, 0L);
- j = SendDlgItemMessage(hwnd, 4202, LB_GETCURSEL, 0, 0L);
- if (i == LB_ERR || j == LB_ERR) {
- MessageBeep(0);
- return (TRUE);
- }
-
- if (YesNo(hwnd, "Do you REALLY want to delete this conversion?") != IDYES)
- return (TRUE);
-
- up = (USERCONV far *) SendDlgItemMessage(hwnd, 4201, LB_GETITEMDATA, i, 0L);
- kp = (KANJILIST far *) SendDlgItemMessage(hwnd, 4202, LB_GETITEMDATA, j, 0L);
-
- UserConvChanged = TRUE;
- EnableWindow(GetDlgItem(hwnd, 4212), FALSE); /* Edit */
- EnableWindow(GetDlgItem(hwnd, 4213), FALSE); /* Delete */
-
- /* First delete the kanji */
- if (kp->prev != NULL) kp->prev->next = kp->next;
- if (kp->next != NULL) kp->next->prev = kp->prev;
- if (up->list == kp) up->list = kp->next;
- FreeBlock(kp->kanji);
- FreeStruct(kp);
-
- if (up->list != NULL) {
- SendDlgItemMessage(hwnd, 4202, LB_DELETESTRING, j, 0L);
- return (TRUE);
- }
-
- /* Delete the kana also */
-
- if (up->prev != NULL) up->prev->next = up->next;
- if (up->next != NULL) up->next->prev = up->prev;
- if (UserConversions == up) UserConversions = up->next;
- SendDlgItemMessage(hwnd, 4201, LB_DELETESTRING, i, 0L);
- SendDlgItemMessage(hwnd, 4202, LB_RESETCONTENT, 0, 0L);
- return (TRUE);
-
- case IDOK:
- case IDCANCEL:
- EndDialog(hwnd, FALSE);
- return (TRUE);
- }
-
- case WM_COMPAREITEM:
- case WM_DELETEITEM:
- case WM_DRAWITEM:
- case WM_MEASUREITEM:
- return (JlistProc(hwnd, message, wParam, lParam, TRUE, ConvertUser));
- }
- return (FALSE);
- }
-