home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
-
-
- #include "jwp.h"
-
- #include "idm.h"
-
-
- #define DICTINDENT 5
- #define NRCACHE 20
-
- typedef struct {
- long int offset;
- KANJI far *string;
- } DICTCACHE;
-
-
- static BOOL DictOK = FALSE;
- static OFSTRUCT dictof, idxof;
- static DICTCACHE cache[NRCACHE];
-
-
-
-
- static KANJI far *ConvertOffset (int id, LONG lParam, KANJI *buf)
- {
- FILE *fp;
- int fd, i, j, ch;
- long int offset;
- int length;
-
- length = (lParam >> 24) & 0x00ff;
- offset = lParam & 0x00ffffff;
-
- /* In the cache? */
-
- for (i = 0; i < NRCACHE; i++) {
- if (cache[i].string == NULL) continue;
- if (cache[i].offset == offset) break;
- }
-
- if (i < NRCACHE) return (cache[i].string);
-
-
- /* Not in the cache */
-
- buf[0] = 0;
-
- fd = OpenFile(NULL, &dictof, OF_READ | OF_REOPEN);
-
- fp = fdopen(fd, "rb");
- if (fp == NULL) {
- close(fd);
- return ((KANJI far *) buf);
- }
-
- fseek(fp, offset, 0);
-
- for (i = j = 0; j < length; i++) {
- ch = getc(fp);
- j++;
-
- if (ch & 0x80) {
- ch &= 0x007f;
- buf[i] = (ch << 8) | (getc(fp) & 0x007f);
- j++;
- } else if (ch == '/') {
- buf[i++] = ',';
- buf[i] = ' ';
- } else {
- buf[i] = ch;
- }
- }
-
- buf[i] = 0;
- fclose(fp);
-
- if (i <= 0) {
- return ((KANJI far *) buf);
- } else if (!ISKANJI(buf[0])) {
- for (; i >= 0; i--) buf[i+DICTINDENT] = buf[i];
- for (i = 0; i < DICTINDENT; i++) buf[i] = ' ';
- } else {
- for (i = 0; buf[i] != 0; i++) {
- if (buf[i] == '[') buf[i] = 0x215a;
- else if (buf[i] == ']') buf[i] = 0x215b;
- else if (buf[i] == ' ') buf[i] = 0x2121;
- }
- }
-
-
- /* Put in the cache */
-
- for (i = 0; i < NRCACHE && cache[i].string != NULL; i++);
- if (i >= NRCACHE) {
- long int diff, maxdiff;
-
- for (i = maxdiff = 0, j = -1; i < NRCACHE; i++) {
- diff = cache[i].offset - offset;
- if (diff < 0) diff = -diff;
- if (diff > maxdiff) {
- j = i;
- maxdiff = diff;
- }
- }
- if (j < 0) j = rand() % NRCACHE;
- i = j;
- }
-
- if (cache[i].string != NULL) FreeBlock(cache[i].string);
- cache[i].string = (KANJI far *) BlockAlloc((kanjilen(buf) + 5) * sizeof(KANJI));
- cache[i].offset = offset;
- kanjicpy(cache[i].string, buf);
-
- return ((KANJI far *) buf);
- }
-
-
-
- static BOOL CheckDictionary (void)
- {
- int fd;
- long int indexsize;
- long int dictsize;
-
-
- if (DictOK) return (TRUE);
-
- for (;;) {
- fd = OpenFile(global.jdict, &dictof, OF_READ);
- if (fd >= 0) break;
- if (!RetryMessage ("Cannot open dictionary '%s'!", global.jdict))
- return (FALSE);
- }
- lseek(fd, 0L, 2);
- dictsize = tell(fd);
- close(fd);
-
- for (;;) {
- fd = OpenFile(global.jdictidx, &idxof, OF_READ);
- if (fd >= 0) break;
- if (!RetryMessage ("Cannot open dictionary index '%s'!", global.jdictidx))
- return (FALSE);
- }
-
- lseek(fd, 0L, 0);
- read(fd, &indexsize, sizeof(long int));
- close(fd);
-
- if (indexsize != dictsize + 15) {
- ErrorMessage(global.hwnd, "This index file does not belong to this dictionary!");
- return (FALSE);
- }
-
- DictOK = TRUE;
-
- return (TRUE);
- }
-
-
-
- static int DictComp (BYTE *p1, BYTE *p2, int n)
- {
- int i;
- BYTE c1, c2;
- BOOL f1 = FALSE, f2 = FALSE;
-
- for (i = 0; ; i++, p1++, p2++) {
- if (n > 0 && i >= n) return (0);
-
- c1 = *p1;
- c2 = *p2;
-
- if ('A' <= c1 && c1 <= 'Z') c1 += 32;
- if ('A' <= c2 && c2 <= 'Z') c2 += 32;
-
- if (c1 & 0x80) {
- f1 = !f1;
- if (f1 && c1 == 0xa5) c1 = 0xa4; /* Katakana? */
- } else {
- f1 = FALSE;
- }
- if (c2 & 0x80) {
- f2 = !f2;
- if (f2 && c2 == 0xa5) c2 = 0xa4; /* Katakana? */
- } else {
- f2 = FALSE;
- }
-
- if (c1 != c2) return (c1 - c2);
- if (c1 == 0) return (0);
- }
-
- return (c1 - c2);
- }
-
-
-
- static int SearchDictionary (HWND DlgHwnd, HWND KeyHwnd, HWND ListHwnd)
- {
- int i, j, k, last, len;
- int fd, nr_matches;
- BOOL PassedKanji, Duplicate;
- FILE *fp;
- long int nr_index;
- long int top, bottom, middle;
- long int offset, cut, temp;
- int diff, length;
- MSG msg;
- BYTE key[MAXLINELEN], target[MAXLINELEN];
- KANJI ch;
- UNIT far *up;
- RECT rect;
-
-
- /* Deletes everything from the list box */
- if (SendMessage(ListHwnd, LB_GETCOUNT, 0, 0L) > 0)
- SendMessage(ListHwnd, LB_RESETCONTENT, 0, 0L);
-
- while (PeekMessage(&msg, DlgHwnd, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
-
- /* Opens the dictionary and index files */
-
- fd = OpenFile(NULL, &dictof, OF_READ | OF_REOPEN);
- if (fd < 0) return (0);
-
- fp = fdopen(fd, "rb");
- if (fp == NULL) {
- close(fd);
- return (0);
- }
-
- fd = OpenFile(NULL, &idxof, OF_READ | OF_REOPEN);
- if (fd < 0) {
- fclose(fp);
- return (0);
- }
-
- lseek(fd, 0L, 2); /* Move to EOF */
-
- nr_index = (tell(fd) / sizeof(long int)) - 1;
- nr_matches = 0;
-
-
- /* Create the key string */
-
- up = (UNIT far *) SendMessage(KeyHwnd, EM_GETLINE, 0, 0L);
-
- for (i = j = 0; ; j++) {
- ch = up[j].kanji;
- if (ch == 0) break;
-
- if (ISKANJI(ch)) {
- key[i++] = HIBYTE(ch) | 0x0080;
- key[i++] = LOBYTE(ch) | 0x0080;
- } else {
- key[i++] = ch;
- }
- }
-
- key[i] = '\0';
- length = i;
-
-
-
- /* Binary Search */
-
- top = 0;
- bottom = nr_index - 1;
-
- for (;;) {
- middle = (top + bottom) / 2;
-
- /* Get the offset */
-
- lseek(fd, (middle + 1) * sizeof(long int), 0);
- read(fd, &offset, sizeof(long int));
-
-
- /* Get the target string */
-
- fseek(fp, offset - 1, 0);
- fgets(target, MAXLINELEN, fp);
-
- diff = DictComp(key, target, -1);
-
- if (diff == 0) {
- cut = middle;
- break;
- }
-
- if (top >= bottom - 1) {
- cut = bottom;
- break;
- }
-
- if (diff > 0) top = middle;
- else bottom = middle;
- }
-
- SendMessage(ListHwnd, WM_SETREDRAW, FALSE, 0L);
- GetClientRect(ListHwnd, &rect);
- rect.right -= 2 * GetSystemMetrics(SM_CXVSCROLL);
-
-
- for (;; cut++) {
- /* Now, did the user abort? */
-
- if (PeekMessage(&msg, DlgHwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) {
- if (msg.message == WM_CHAR && msg.wParam == '\x1b') {
- if (YesNo(DlgHwnd, "Dictionary search interrupted!\n\nContinue?") != IDYES) break;
- } else {
- TranslateMessage(&msg);
- }
- //DispatchMessage(&msg);
- }
-
- lseek(fd, (cut + 1) * sizeof(long int), 0);
- read(fd, &offset, sizeof(long int));
-
- /* Get the text string */
-
- offset--;
- fseek(fp, offset, 0);
- fgets(target, MAXLINELEN, fp);
-
-
- /* Still matches? */
-
- if (DictComp(key, target, length)) break;
- nr_matches++;
-
- if (nr_matches > 0) {
- char tempbuf[50];
-
- sprintf(tempbuf, "%d match%s", nr_matches, (nr_matches > 1) ? "es" : "");
- SetDlgItemText(GetParent(KeyHwnd), 4202, tempbuf);
- }
-
-
- /* OK, now backseek to the beginning of the line, shall we? */
-
- fseek(fp, offset, 0);
-
- for (;;) {
- if (offset < MAXLINELEN) {
- fseek(fp, 0L, 0);
- j = offset;
- offset = 0L;
- } else {
- fseek(fp, -MAXLINELEN, 1); /* Get the previous block */
- j = MAXLINELEN;
- offset -= MAXLINELEN;
- }
- fread(target, sizeof(BYTE), MAXLINELEN, fp);
-
- for(i = j - 1; i >= 0; i--) {
- if (target[i] == '\n' || target[i] == '\r') break;
- }
-
- if (i > 0) {
- i++;
- offset += i;
- break;
- }
-
- if (offset <= 0L) break;
- }
-
-
- fseek(fp, offset, 0);
- fgets(target, MAXLINELEN, fp);
-
- for (i = strlen(target) - 1; i >= 0; i--) {
- if (target[i] != '\n' && target[i] != '\r' && target[i] != '/') break;
- }
- target[i+1] = '\0';
-
-
- /* Is it in the dictionary already? */
-
- Duplicate = FALSE;
- len = SendMessage(ListHwnd, LB_GETCOUNT, 0, 0L);
-
- for (i = 0; i < len; i++) {
- temp = (long int) SendMessage(ListHwnd, LB_GETITEMDATA, i, 0L);
- temp &= 0x00ffffff;
- if (offset == temp) {
- Duplicate = TRUE;
- break;
- }
- }
-
- if (Duplicate) continue;
-
-
- /* Now break it down into individual lines */
-
- last = -1;
- PassedKanji = FALSE;
-
-
- for (i = j = k = 0; ; i++) {
- if (FALSE) {
- if (!target[i]) break;
-
- if (target[i] == '/') {
- SendMessage(ListHwnd, LB_ADDSTRING, 0,
- (offset & 0x00ffffff) | (((LONG) j) << 24));
- offset += (j + 1);
- j = 0;
- } else {
- j++;
- }
- } else {
- if (target[i] <= ' ' || target[i] == '/') last = j;
-
- if (target[i]) {
- if (target[i] == '/') {
- if (!PassedKanji) {
- SendMessage(ListHwnd, LB_ADDSTRING, 0,
- (offset & 0x00ffffff) | (((LONG) j) << 24));
- offset += (j + 1);
- j = 0;
- k = DICTINDENT * FontCharWidth(' ', 0); /* System font */
- PassedKanji = TRUE;
- continue;
- }
- k += FontCharWidth(',', 0); /* System font */
- k += FontCharWidth(' ', 0); /* System font */
- } else {
- k += FontCharWidth(target[i], 0); /* System font */
- }
- }
-
- if (!target[i]) {
- SendMessage(ListHwnd, LB_ADDSTRING, 0,
- (offset & 0x00ffffff) | (((LONG) j) << 24));
- break;
- } else if (PassedKanji && k >= rect.right) {
- SendMessage(ListHwnd, LB_ADDSTRING, 0,
- (offset & 0x00ffffff) | (((LONG) last + 1) << 24));
-
- offset += (last + 1);
- i -= (j - last);
- j = 0;
- k = DICTINDENT * FontCharWidth(' ', 0); /* System font */
- } else {
- j++;
- }
- }
- }
- }
-
- SendMessage(ListHwnd, WM_SETREDRAW, TRUE, 0L);
- InvalidateRect(ListHwnd, NULL, TRUE);
-
- fclose(fp);
- close(fd);
- return (nr_matches);
- }
-
-
-
- LONG FAR PASCAL InputModeIconProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- HDC hdc, hdcmem;
- HBITMAP hbitmap;
- PAINTSTRUCT ps;
- HWND hwnd1;
-
- switch (message) {
- case EM_SETHANDLE:
- SetWindowWord(hwnd, 0, wParam);
- return (0);
-
- case WM_LBUTTONDOWN: {
- FILEOPTIONS *f;
-
- hwnd1 = (HWND) GetWindowWord(hwnd, 0);
- f = (FILEOPTIONS *) SendMessage(hwnd1, EM_GETHANDLE, 0, 0L);
- if (f->type & FN_EITHER) SendMessage(hwnd1, EM_REPLACESEL, 0, (LONG) NULL);
- SendMessage(hwnd1, WM_COMMAND, IDM_TOGGLEMODE, 0L);
- InvalidateRect(hwnd, NULL, FALSE);
- return (0);
- }
-
- case WM_PAINT:
- SetWindowPos(hwnd, NULL, 0, 0, 24, 24, SWP_NOMOVE | SWP_NOZORDER);
-
- /* Put in the bitmap */
- hdc = BeginPaint(hwnd, &ps);
- hdcmem = CreateCompatibleDC(hdc);
-
- switch (global.mode) {
- case M_ASCII: hbitmap = LoadBitmap(hInstance, "ASCIIBmp"); break;
-
- default:
- case M_KANA: hbitmap = LoadBitmap(hInstance, "KanaBmp"); break;
- }
-
- SelectObject(hdcmem, hbitmap);
- BitBlt(hdc, 0, 0, 24, 24, hdcmem, 0, 0, SRCCOPY);
- DeleteDC(hdcmem);
- DeleteObject(hbitmap);
- EndPaint(hwnd, &ps);
- return (0);
- }
-
- return (DefWindowProc(hwnd, message, wParam, lParam));
- }
-
-
-
- BOOL FAR PASCAL DictionaryProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
- {
- switch (message) {
-
- case WM_INITDIALOG: {
- int i, len;
- BOOL IsKanji1, IsKanji2;
- KANJI buf[MAXLINELEN];
- FILEOPTIONS *f, *f1;
-
- if (!CheckDictionary()) {
- EndDialog(hwnd, FALSE);
- return (TRUE);
- }
-
- /* Set the type and mode-change icon of the Jedit control */
- SendDlgItemMessage(hwnd, 4201, EM_SETMODIFY, FN_CONTROL | FN_EITHER, 0L);
- SendDlgItemMessage(hwnd, 4201, EM_SETRECT, GetDlgItem(hwnd, 4231), 0L);
-
- f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
-
- SendDlgItemMessage(hwnd, 4231, EM_SETHANDLE, f->hwnd, 0L); /* icon-change */
-
- if (global.active != NULL) f1 = global.active;
-
- if (global.active == NULL || SELPARA1(f1) == NULL) {
- if (global.mode != M_ASCII) ToggleInputMode();
- } else {
- /* Copy the selected text */
-
- if (SELPARA1(f1) != SELPARA2(f1)) {
- len = unitlen(SELPARA1(f1)->text) - SELPOS1(f1);
- } else {
- len = SELPOS2(f1) - SELPOS1(f1) + 1;
- }
-
- IsKanji1 = ISKANJI(SELPARA1(f1)->text[SELPOS1(f1)].kanji);
-
- for (i = 0; i < len; i++) {
- buf[i] = SELPARA1(f1)->text[SELPOS1(f1)+i].kanji;
- IsKanji2 = ISKANJI(buf[i]);
- if (IsKanji1 && !IsKanji2) break;
- if (!IsKanji1 && IsKanji2) break;
- }
- buf[i] = 0;
-
- SendDlgItemMessage(hwnd, 4201, EM_REPLACESEL, 0, (LONG) buf);
-
- if (len > 0) {
- SendDlgItemMessage(hwnd, 4201, EM_SETSEL, len, MAKELONG(0, len - 1));
- }
- }
-
- EnableWindow(GetDlgItem(hwnd, 4212), FALSE);
- EnableWindow(GetDlgItem(hwnd, 4211), (f->nr_bytes > 0));
-
- for (i = 0; i < NRCACHE; i++) cache[i].string = NULL;
-
- SetFocus(GetDlgItem(hwnd, 4201));
-
- CenterDialogBox(hwnd);
-
- return (TRUE);
- }
-
- case WM_PAINT: {
- HDC hdc;
- PAINTSTRUCT ps;
-
- hdc = BeginPaint(hwnd, &ps);
-
- DrawBoundingBox(hwnd, hdc, 4201);
-
- EndPaint(hwnd, &ps);
- return (TRUE);
- }
-
- case WM_COMMAND: {
- int i, n;
- UNIT far *up;
- HCURSOR hCursor;
- HWND ChildHwnd;
-
-
- switch (wParam) {
- case 4201: /* Japanese Edit Control */
- if (HIWORD(lParam) == EN_CHANGE) {
- if (SendMessage(LOWORD(lParam), EM_LINELENGTH, 0, 0L) > 0) {
- EnableWindow(GetDlgItem(hwnd, 4211), TRUE);
- } else {
- EnableWindow(GetDlgItem(hwnd, 4211), FALSE);
- }
- }
- return (TRUE);
-
- case 4211: /* Search Button */
- case IDOK:
- up = (UNIT far *) SendDlgItemMessage(hwnd, 4201, EM_GETLINE, 0, 0L);
- i = unitlen(up);
-
- if (!ISKANJI(up[0].kanji) && i <= 2) {
- /* Cannot search for less than 3 letters */
- MessageBeep(0);
- } else if (ISKANJI(up[0].kanji) && i <= 1 &&
- (HIBYTE(up[0].kanji) == 0x24 || HIBYTE(up[0].kanji) == 0x25)) {
-
- /* Cannot search for less than 2 kana */
- MessageBeep(0);
- } else if (i > 0) {
- hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
- EnableWindow(GetDlgItem(hwnd, 4212), FALSE);
-
- SetDlgItemText(hwnd, 4202, "");
- n = SearchDictionary(hwnd, GetDlgItem(hwnd, 4201), GetDlgItem(hwnd, 4221));
- if (n <= 0) {
- MessageBeep(0);
- SetDlgItemText(hwnd, 4202, "No matches");
- } else {
- SetFocus(GetDlgItem(hwnd, 4221));
- }
-
- ShowCursor(FALSE);
- SetCursor(hCursor);
- } else {
- MessageBeep(0);
- }
- return (TRUE);
-
- case 4212: { /* Insert Button */
- KANJI buf[MAXLINELEN], far *kp;
- LONG offset;
- FILEOPTIONS *f;
-
- ChildHwnd = GetDlgItem(hwnd, 4221);
-
- if (HIWORD(lParam) == BN_CLICKED && global.active != NULL) {
- n = SendMessage(ChildHwnd, LB_GETCURSEL, 0, 0L);
- if (n == LB_ERR) {
- EnableWindow(LOWORD(lParam), FALSE);
- return (TRUE);
- }
-
- f = global.active;
- offset = SendMessage(ChildHwnd, LB_GETITEMDATA, n, 0L);
- kp = ConvertOffset(0, offset, buf);
-
- /* Trim surrounding spaces */
- for (i = kanjilen(kp); i > 0; i--) {
- if (ISKANJI(kp[i])) {
- if (kp[i] > 0x2121) break;
- } else {
- if (kp[i] > ' ') break;
- }
- }
-
- kp[i+1] = 0;
-
- for (i = 0; kp[i]; i++) {
- if (ISKANJI(kp[i])) {
- if (kp[i] > 0x2121) break;
- } else {
- if (kp[i] > ' ') break;
- }
- }
-
- if (kp[i] > 0) {
- TurnOffSelection(f);
- UndoAddTyping(f, f->current, kanjilen(kp + i), FALSE);
- InsertString(f, f->current, kp + i,
- OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND);
- } else {
- MessageBeep(0);
- return (TRUE);
- }
- }
-
- for (i = 0; i < NRCACHE; i++) {
- if (cache[i].string != NULL) FreeBlock(cache[i].string);
- cache[i].string = NULL;
- }
-
- EndDialog(hwnd, TRUE);
- return (TRUE);
- }
-
- case 4221: /* Japanese List Box */
- ChildHwnd = GetDlgItem(hwnd, 4212);
-
- if (HIWORD(lParam) == LBN_SELCHANGE || HIWORD(lParam) == LBN_DBLCLK) {
- n = SendMessage(LOWORD(lParam), LB_GETCURSEL, 0, 0L);
- if (n == LB_ERR) {
- EnableWindow(ChildHwnd, FALSE);
- return (TRUE);
- }
-
- if (global.active != NULL) EnableWindow(ChildHwnd, TRUE);
- if (HIWORD(lParam) == LBN_DBLCLK) {
- /* Flash button */
- SendMessage(ChildHwnd, BM_SETSTATE, 1, 0L);
- SendMessage(ChildHwnd, BM_SETSTATE, 0, 0L);
- SendMessage(hwnd, WM_COMMAND, 4212, MAKELONG(ChildHwnd, BN_CLICKED));
- }
- }
- return (TRUE);
-
- case IDCANCEL: /* Done Button */
- for (i = 0; i < NRCACHE; i++) {
- if (cache[i].string != NULL) FreeBlock(cache[i].string);
- cache[i].string = NULL;
- }
- EndDialog(hwnd, FALSE);
- return (TRUE);
-
- default:
- break;
- }
- break;
- }
-
- case WM_COMPAREITEM:
- case WM_DELETEITEM:
- case WM_DRAWITEM:
- case WM_MEASUREITEM:
- return (JlistProc(hwnd, message, wParam, lParam, TRUE, ConvertOffset));
- }
-
- return (FALSE);
- }
-