15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 1999 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 30f14f4646Smrg/* $XdotOrg: xc/programs/xedit/ispell.c,v 1.6 2004/12/04 00:43:13 kuhn Exp $ */ 315dfecf96Smrg/* $XFree86: xc/programs/xedit/ispell.c,v 1.19 2002/10/19 20:04:20 herrb Exp $ */ 325dfecf96Smrg 335dfecf96Smrg#include "xedit.h" 34f14f4646Smrg#include "util.h" 355dfecf96Smrg#include <stdlib.h> 365dfecf96Smrg#include <unistd.h> 375dfecf96Smrg#include <fcntl.h> 385dfecf96Smrg#include <signal.h> 395dfecf96Smrg#include <ctype.h> 40f14f4646Smrg#include <locale.h> 415dfecf96Smrg#include <errno.h> 425dfecf96Smrg#include <sys/types.h> 435dfecf96Smrg#include <sys/wait.h> 445dfecf96Smrg#include <X11/Xaw/Toggle.h> 455dfecf96Smrg#include <X11/Xaw/MenuButton.h> 465dfecf96Smrg#include <X11/Xaw/SmeBSB.h> 475dfecf96Smrg#include <X11/Xaw/SimpleMenu.h> 485dfecf96Smrg#include <X11/Xos.h> 495dfecf96Smrg 505dfecf96Smrg#define RECEIVE 1 515dfecf96Smrg#define SEND 2 525dfecf96Smrg 535dfecf96Smrg#define CHECK 0 545dfecf96Smrg#define ADD 1 555dfecf96Smrg#define REMOVE 2 565dfecf96Smrg 575dfecf96Smrg#define ASIS 1 585dfecf96Smrg#define UNCAP 2 595dfecf96Smrg 605dfecf96Smrg/* 615dfecf96Smrg * Types 625dfecf96Smrg */ 635dfecf96Smrg#define UNDO_DEPTH 16 645dfecf96Smrgtypedef struct _ispell_undo { 655dfecf96Smrg char *undo_str; 665dfecf96Smrg int undo_count; 675dfecf96Smrg XawTextPosition undo_pos; 685dfecf96Smrg Boolean repeat; /* two (misspelled?) words together */ 695dfecf96Smrg Boolean terse; 705dfecf96Smrg int format; /* remember text formatting style */ 715dfecf96Smrg struct _ispell_undo *next, *prev; 725dfecf96Smrg} ispell_undo; 735dfecf96Smrg 745dfecf96Smrgtypedef struct _ispell_dict { 755dfecf96Smrg Widget sme; 765dfecf96Smrg char *wchars; 775dfecf96Smrg struct _ispell_dict *next; 785dfecf96Smrg} ispell_dict; 795dfecf96Smrg 805dfecf96Smrg#define TEXT 0 815dfecf96Smrg#define HTML 1 825dfecf96Smrgstruct _ispell_format { 835dfecf96Smrg char *name; 845dfecf96Smrg int value; 855dfecf96Smrg Widget sme; 865dfecf96Smrg}; 875dfecf96Smrg 885dfecf96Smrgstatic struct _ispell_format ispell_format[] = { 895dfecf96Smrg {"text", TEXT}, 905dfecf96Smrg {"html", HTML}, 915dfecf96Smrg}; 925dfecf96Smrg 935dfecf96Smrgstruct _ispell { 945dfecf96Smrg Widget shell, form, mispelled, repeated, word, replacement, text, 955dfecf96Smrg suggestions, viewport, list, commands, replace, status, 965dfecf96Smrg replaceAll, undo, ignore, ignoreAll, add, addUncap, suspend, 975dfecf96Smrg cancel, check, look, terse, options, dict, dictMenu, 985dfecf96Smrg format, formatMenu; 995dfecf96Smrg 1005dfecf96Smrg Widget ascii, source; 1015dfecf96Smrg XtInputId id; 1025dfecf96Smrg int pid, ifd[2], ofd[2]; 1035dfecf96Smrg XawTextPosition left, right; 1045dfecf96Smrg char *item; 1055dfecf96Smrg Bool lock; 1065dfecf96Smrg Bool repeat; 1075dfecf96Smrg Bool checkit; 1085dfecf96Smrg int stat; 1095dfecf96Smrg char *buf; 1105dfecf96Smrg int bufsiz; 1115dfecf96Smrg int buflen; 1125dfecf96Smrg char sendbuf[1024]; 1135dfecf96Smrg char sentbuf[1024]; 1145dfecf96Smrg 1155dfecf96Smrg int undo_depth; 1165dfecf96Smrg ispell_undo *undo_head, *undo_base; 1175dfecf96Smrg char *undo_for; 1185dfecf96Smrg 1195dfecf96Smrg char *wchars; 1205dfecf96Smrg char *cmd; 1215dfecf96Smrg char *skip; 1225dfecf96Smrg char *command; 1235dfecf96Smrg Boolean terse_mode, undo_terse_mode; 1245dfecf96Smrg char *guess_label, *miss_label, *root_label, *none_label, *eof_label, 1255dfecf96Smrg *compound_label, *ok_label, *repeat_label, *working_label, *look_label; 1265dfecf96Smrg char *look_cmd; 1275dfecf96Smrg char *words_file; 1285dfecf96Smrg 1295dfecf96Smrg char *dictionary; 1305dfecf96Smrg char *dict_list; 1315dfecf96Smrg ispell_dict *dict_info; 1325dfecf96Smrg 1335dfecf96Smrg int format_mode; /* to undo correctly */ 1345dfecf96Smrg char *formatting; 1355dfecf96Smrg struct _ispell_format *format_info; 1365dfecf96Smrg}; 1375dfecf96Smrg 138f14f4646Smrgtypedef struct _ReplaceEntry ReplaceEntry; 139f14f4646Smrgstruct _ReplaceEntry { 140f14f4646Smrg hash_key *word; 141f14f4646Smrg ReplaceEntry*next; 142f14f4646Smrg char *replace; 143f14f4646Smrg}; 1445dfecf96Smrg 145f14f4646Smrgtypedef struct _IgnoreEntry IgnoreEntry; 146f14f4646Smrgstruct _IgnoreEntry { 147f14f4646Smrg hash_key *word; 148f14f4646Smrg IgnoreEntry *next; 149f14f4646Smrg int add; 150f14f4646Smrg}; 1515dfecf96Smrg 1525dfecf96Smrg/* 1535dfecf96Smrg * Prototypes 1545dfecf96Smrg */ 1555dfecf96Smrgstatic void AddIspell(Widget, XtPointer, XtPointer); 1565dfecf96Smrgstatic void ChangeDictionaryIspell(Widget, XtPointer, XtPointer); 1575dfecf96Smrgstatic void ChangeFormatIspell(Widget, XtPointer, XtPointer); 1585dfecf96Smrgstatic void CheckIspell(Widget, XtPointer, XtPointer); 1595dfecf96Smrgstatic void IgnoreIspell(Widget, XtPointer, XtPointer); 1605dfecf96Smrgstatic Bool InitIspell(void); 1615dfecf96Smrgstatic void IspellCheckUndo(void); 1625dfecf96Smrgstatic int IspellConvertHtmlAmp(char*); 1635dfecf96Smrgstatic Bool IspellDoIgnoredWord(char*, int, int); 1645dfecf96Smrgstatic Bool IspellIgnoredWord(char*, int, int); 1655dfecf96Smrgstatic void IspellInputCallback(XtPointer, int*, XtInputId*); 1665dfecf96Smrgstatic void IspellKillUndoBuffer(void); 1675dfecf96Smrgstatic Bool IspellReceive(void); 1685dfecf96Smrgstatic char *IspellReplacedWord(char*, char*); 1695dfecf96Smrgstatic int IspellSend(void); 1705dfecf96Smrgstatic void IspellSetSelection(XawTextPosition, XawTextPosition); 1715dfecf96Smrgstatic void IspellSetRepeated(Bool); 1725dfecf96Smrgstatic void IspellSetSensitive(Bool); 1735dfecf96Smrgstatic void IspellSetStatus(char*); 1745dfecf96Smrgstatic void IspellSetTerseMode(Bool); 1755dfecf96Smrgstatic Bool IspellStartProcess(void); 176f14f4646Smrgstatic Bool IspellCheckProcess(void); 1775dfecf96Smrgstatic Bool IspellEndProcess(Bool, Bool); 1785dfecf96Smrgstatic void LookIspell(Widget, XtPointer, XtPointer); 1795dfecf96Smrgstatic void PopdownIspell(Widget, XtPointer, XtPointer); 1805dfecf96Smrgstatic void ReplaceIspell(Widget, XtPointer, XtPointer); 1815dfecf96Smrgstatic void RevertIspell(Widget, XtPointer, XtPointer); 1825dfecf96Smrgstatic void SelectIspell(Widget, XtPointer, XtPointer); 1835dfecf96Smrgstatic void ToggleTerseIspell(Widget, XtPointer, XtPointer); 1845dfecf96Smrgstatic void timeout_signal(int); 1855dfecf96Smrgstatic void (*old_timeout)(int); 1865dfecf96Smrgstatic void UndoIspell(Widget, XtPointer, XtPointer); 1875dfecf96Smrg 1885dfecf96SmrgBool _XawTextSrcUndo(TextSrcObject, XawTextPosition*); 1895dfecf96Smrg 1905dfecf96Smrg/* 1915dfecf96Smrg * Initialization 1925dfecf96Smrg */ 1935dfecf96Smrgstatic struct _ispell ispell; 1945dfecf96Smrg 1955dfecf96Smrg#define RSTRTBLSZ 23 1965dfecf96Smrg#define ISTRTBLSZ 71 197f14f4646Smrgstatic hash_table *replace_hash; 198f14f4646Smrgstatic hash_table *ignore_hash; 1995dfecf96Smrg 2005dfecf96Smrg#ifndef XtCStatus 2015dfecf96Smrg#define XtCStatus "Status" 2025dfecf96Smrg#endif 2035dfecf96Smrg 2045dfecf96Smrg#define Offset(field) XtOffsetOf(struct _ispell, field) 2055dfecf96Smrgstatic XtResource resources[] = { 2065dfecf96Smrg {"wordChars", "Chars", XtRString, sizeof(char*), 2075dfecf96Smrg Offset(wchars), XtRString, ""}, 2085dfecf96Smrg {"ispellCommand", "CommandLine", XtRString, sizeof(char*), 2095dfecf96Smrg Offset(cmd), XtRString, "/usr/local/bin/ispell"}, 2105dfecf96Smrg {"terseMode", "Terse", XtRBoolean, sizeof(Boolean), 2115dfecf96Smrg Offset(terse_mode), XtRImmediate, (XtPointer)False}, 2125dfecf96Smrg {"guessLabel", XtCStatus, XtRString, sizeof(String), 2135dfecf96Smrg Offset(guess_label), XtRString, "Guess"}, 2145dfecf96Smrg {"missLabel", XtCStatus, XtRString, sizeof(String), 2155dfecf96Smrg Offset(miss_label), XtRString, "Miss"}, 2165dfecf96Smrg {"rootLabel", XtCStatus, XtRString, sizeof(String), 2175dfecf96Smrg Offset(root_label), XtRString, "Root:"}, 2185dfecf96Smrg {"noneLabel", XtCStatus, XtRString, sizeof(String), 2195dfecf96Smrg Offset(none_label), XtRString, "None"}, 2205dfecf96Smrg {"compoundLabel", XtCStatus, XtRString, sizeof(String), 2215dfecf96Smrg Offset(compound_label), XtRString, "Compound"}, 2225dfecf96Smrg {"okLabel", XtCStatus, XtRString, sizeof(String), 2235dfecf96Smrg Offset(ok_label), XtRString, "Ok"}, 2245dfecf96Smrg {"eofLabel", XtCStatus, XtRString, sizeof(String), 2255dfecf96Smrg Offset(eof_label), XtRString, "End Of File"}, 2265dfecf96Smrg {"repeatLabel", XtCStatus, XtRString, sizeof(String), 2275dfecf96Smrg Offset(repeat_label), XtRString, "Repeat"}, 2285dfecf96Smrg {"workingLabel", XtCStatus, XtRString, sizeof(String), 2295dfecf96Smrg Offset(working_label), XtRString, "..."}, 2305dfecf96Smrg {"lookLabel", XtCStatus, XtRString, sizeof(String), 2315dfecf96Smrg Offset(look_label), XtRString, "Look"}, 2325dfecf96Smrg {"lookCommand", "CommandLine", XtRString, sizeof(char*), 2335dfecf96Smrg Offset(look_cmd), XtRString, "/usr/bin/egrep -i"}, 2345dfecf96Smrg {"wordsFile", "Words", XtRString, sizeof(char*), 2355dfecf96Smrg Offset(words_file), XtRString, "/usr/share/dict/words"}, 2365dfecf96Smrg {"dictionary", "Dictionary", XtRString, sizeof(char*), 2375dfecf96Smrg Offset(dictionary), XtRString, "american"}, 2385dfecf96Smrg {"dictionaries", "Dictionary", XtRString, sizeof(char*), 2395dfecf96Smrg Offset(dict_list), XtRString, "american americanmed+ english"}, 2405dfecf96Smrg {"formatting", "TextFormat", XtRString, sizeof(char*), 2415dfecf96Smrg Offset(formatting), XtRString, "text"}, 2425dfecf96Smrg}; 2435dfecf96Smrg#undef Offset 2445dfecf96Smrg 2455dfecf96Smrg#ifdef NO_LIBC_I18N 2465dfecf96Smrgstatic int 2475dfecf96SmrgToLower(int ch) 2485dfecf96Smrg{ 2495dfecf96Smrg char buf[2]; 2505dfecf96Smrg 2515dfecf96Smrg *buf = ch; 2525dfecf96Smrg XmuNCopyISOLatin1Lowered(buf, buf, sizeof(buf)); 2535dfecf96Smrg 2545dfecf96Smrg return (*buf); 2555dfecf96Smrg} 2565dfecf96Smrg 2575dfecf96Smrgstatic int 2585dfecf96SmrgToUpper(int ch) 2595dfecf96Smrg{ 2605dfecf96Smrg char buf[2]; 2615dfecf96Smrg 2625dfecf96Smrg *buf = ch; 2635dfecf96Smrg XmuNCopyISOLatin1Uppered(buf, buf, sizeof(buf)); 2645dfecf96Smrg 2655dfecf96Smrg return (*buf); 2665dfecf96Smrg} 2675dfecf96Smrg 2685dfecf96Smrgstatic int 2695dfecf96SmrgIsLower(int ch) 2705dfecf96Smrg{ 2715dfecf96Smrg char upbuf[2]; 2725dfecf96Smrg char lobuf[2]; 2735dfecf96Smrg 2745dfecf96Smrg *upbuf = *lobuf = ch; 2755dfecf96Smrg XmuNCopyISOLatin1Lowered(lobuf, lobuf, sizeof(lobuf)); 2765dfecf96Smrg XmuNCopyISOLatin1Uppered(upbuf, upbuf, sizeof(upbuf)); 2775dfecf96Smrg 2785dfecf96Smrg return (*lobuf != *upbuf && ch == *lobuf); 2795dfecf96Smrg} 2805dfecf96Smrg 2815dfecf96Smrgstatic int 2825dfecf96SmrgIsUpper(int ch) 2835dfecf96Smrg{ 2845dfecf96Smrg char upbuf[2]; 2855dfecf96Smrg char lobuf[2]; 2865dfecf96Smrg 2875dfecf96Smrg *upbuf = *lobuf = ch; 2885dfecf96Smrg XmuNCopyISOLatin1Lowered(lobuf, lobuf, sizeof(lobuf)); 2895dfecf96Smrg XmuNCopyISOLatin1Uppered(upbuf, upbuf, sizeof(upbuf)); 2905dfecf96Smrg 2915dfecf96Smrg return (*lobuf != *upbuf && ch == *upbuf); 2925dfecf96Smrg} 2935dfecf96Smrg#else 2945dfecf96Smrg#define ToLower tolower 2955dfecf96Smrg#define ToUpper toupper 2965dfecf96Smrg#define IsLower islower 2975dfecf96Smrg#define IsUpper isupper 2985dfecf96Smrg#endif 2995dfecf96Smrg 3005dfecf96Smrg/* 3015dfecf96Smrg * Implementation 3025dfecf96Smrg */ 3035dfecf96Smrg#ifdef STDERR_FILENO 3045dfecf96Smrg# define WRITES(s) write(STDERR_FILENO, s, strlen(s)) 3055dfecf96Smrg#else 3065dfecf96Smrg# define WRITES(s) write(fileno(stderr), s, strlen(s)) 3075dfecf96Smrg#endif 3085dfecf96Smrg 3095dfecf96Smrg/*ARGSUSED*/ 3105dfecf96Smrgstatic void 3115dfecf96Smrgtimeout_signal(int unused) 3125dfecf96Smrg{ 3135dfecf96Smrg int olderrno = errno; 3145dfecf96Smrg 3155dfecf96Smrg WRITES("Warning: Timeout waiting ispell process to die.\n"); 3165dfecf96Smrg kill(ispell.pid, SIGTERM); 3175dfecf96Smrg errno = olderrno; 3185dfecf96Smrg} 3195dfecf96Smrg 3205dfecf96Smrgstatic void 3215dfecf96SmrgIspellSetSelection(XawTextPosition left, XawTextPosition right) 3225dfecf96Smrg{ 3235dfecf96Smrg /* Try to make sure the selected word is completely visible */ 3245dfecf96Smrg XawTextSetInsertionPoint(ispell.ascii, right); 3255dfecf96Smrg XawTextSetInsertionPoint(ispell.ascii, left); 3265dfecf96Smrg XawTextSetSelection(ispell.ascii, left, right); 3275dfecf96Smrg} 3285dfecf96Smrg 3295dfecf96Smrgstatic void 3305dfecf96SmrgIspellSetStatus(char *label) 3315dfecf96Smrg{ 3325dfecf96Smrg Arg args[1]; 3335dfecf96Smrg 3345dfecf96Smrg XtSetArg(args[0], XtNlabel, label); 3355dfecf96Smrg XtSetValues(ispell.status, args, 1); 3365dfecf96Smrg} 3375dfecf96Smrg 3385dfecf96Smrgstatic void 3395dfecf96SmrgIspellSetRepeated(Bool state) 3405dfecf96Smrg{ 3415dfecf96Smrg static char *mispelled, *repeated; 3425dfecf96Smrg Arg args[1]; 3435dfecf96Smrg 3445dfecf96Smrg if (mispelled == NULL) { 3455dfecf96Smrg XtSetArg(args[0], XtNlabel, &mispelled); 3465dfecf96Smrg XtGetValues(ispell.mispelled, args, 1); 3475dfecf96Smrg mispelled = XtNewString(mispelled); 3485dfecf96Smrg } 3495dfecf96Smrg if (repeated == NULL) { 3505dfecf96Smrg XtSetArg(args[0], XtNlabel, &repeated); 3515dfecf96Smrg XtGetValues(ispell.repeated, args, 1); 3525dfecf96Smrg repeated = XtNewString(repeated); 3535dfecf96Smrg } 3545dfecf96Smrg XtSetSensitive(ispell.replaceAll, !state); 3555dfecf96Smrg XtSetSensitive(ispell.ignoreAll, !state); 3565dfecf96Smrg XtSetSensitive(ispell.add, !state); 3575dfecf96Smrg XtSetSensitive(ispell.addUncap, !state); 3585dfecf96Smrg if (!state) { 3595dfecf96Smrg XtSetArg(args[0], XtNlabel, mispelled); 3605dfecf96Smrg XtSetValues(ispell.mispelled, args, 1); 3615dfecf96Smrg } 3625dfecf96Smrg else { 3635dfecf96Smrg XtSetArg(args[0], XtNlabel, repeated); 3645dfecf96Smrg XtSetValues(ispell.mispelled, args, 1); 3655dfecf96Smrg } 3665dfecf96Smrg} 3675dfecf96Smrg 3685dfecf96Smrgstatic void 3695dfecf96SmrgIspellSetSensitive(Bool state) 3705dfecf96Smrg{ 3715dfecf96Smrg XtSetSensitive(ispell.replace, state); 3725dfecf96Smrg XtSetSensitive(ispell.replaceAll, state); 3735dfecf96Smrg XtSetSensitive(ispell.ignore, state); 3745dfecf96Smrg XtSetSensitive(ispell.ignoreAll, state); 3755dfecf96Smrg XtSetSensitive(ispell.add, state); 3765dfecf96Smrg XtSetSensitive(ispell.addUncap, state); 3775dfecf96Smrg} 3785dfecf96Smrg 3795dfecf96Smrgstatic void 3805dfecf96SmrgIspellSetTerseMode(Bool mode) 3815dfecf96Smrg{ 3825dfecf96Smrg Arg args[1]; 3835dfecf96Smrg 3845dfecf96Smrg XtSetArg(args[0], XtNstate, ispell.terse_mode = mode); 3855dfecf96Smrg XtSetValues(ispell.terse, args, 1); 3865dfecf96Smrg write(ispell.ofd[1], mode ? "!\n" : "%\n", 2); 3875dfecf96Smrg} 3885dfecf96Smrg 3895dfecf96Smrgstatic void 3905dfecf96SmrgIspellCheckUndo(void) 3915dfecf96Smrg{ 3925dfecf96Smrg ispell_undo *undo = XtNew(ispell_undo); 3935dfecf96Smrg 3945dfecf96Smrg if (ispell.undo_for && strcmp(ispell.undo_for, ispell.dictionary)) { 3955dfecf96Smrg XeditPrintf("Undo: Dictionary changed. Previous undo information lost.\n"); 3965dfecf96Smrg IspellKillUndoBuffer(); 3975dfecf96Smrg Feep(); 3985dfecf96Smrg } 3995dfecf96Smrg 4005dfecf96Smrg undo->next = NULL; 4015dfecf96Smrg undo->repeat = False; 4025dfecf96Smrg undo->terse = ispell.undo_terse_mode; 4035dfecf96Smrg undo->format = ispell.format_mode; 4045dfecf96Smrg if ((undo->prev = ispell.undo_head) != NULL) 4055dfecf96Smrg undo->prev->next = undo; 4065dfecf96Smrg else 4075dfecf96Smrg undo->prev = NULL; 4085dfecf96Smrg ++ispell.undo_depth; 4095dfecf96Smrg if (!ispell.undo_base) { 4105dfecf96Smrg ispell.undo_base = undo; 4115dfecf96Smrg XtSetSensitive(ispell.undo, True); 4125dfecf96Smrg } 4135dfecf96Smrg else if (ispell.undo_depth > UNDO_DEPTH) { 4145dfecf96Smrg ispell_undo *tmp; 4155dfecf96Smrg 4165dfecf96Smrg if (ispell.undo_base->undo_str) 4175dfecf96Smrg XtFree(ispell.undo_base->undo_str); 4185dfecf96Smrg tmp = ispell.undo_base->next; 4195dfecf96Smrg XtFree((char*)ispell.undo_base); 4205dfecf96Smrg tmp->prev = NULL; 4215dfecf96Smrg ispell.undo_base = tmp; 4225dfecf96Smrg ispell.undo_depth = UNDO_DEPTH; 4235dfecf96Smrg } 4245dfecf96Smrg ispell.undo_head = undo; 4255dfecf96Smrg} 4265dfecf96Smrg 4275dfecf96Smrgstatic char * 4285dfecf96SmrgIspellReplacedWord(char *word, char *replace) 4295dfecf96Smrg{ 430f14f4646Smrg int word_len; 431f14f4646Smrg hash_key *word_key; 432f14f4646Smrg ReplaceEntry *entry; 433f14f4646Smrg 434f14f4646Smrg word_len = strlen(word); 435f14f4646Smrg entry = (ReplaceEntry *)hash_check(replace_hash, word, word_len); 436f14f4646Smrg if (entry == NULL) { 437f14f4646Smrg word_key = XtNew(hash_key); 438f14f4646Smrg word_key->value = XtNewString(word); 439f14f4646Smrg word_key->length = word_len; 440f14f4646Smrg entry = XtNew(ReplaceEntry); 441f14f4646Smrg entry->word = word_key; 442f14f4646Smrg entry->replace = NULL; 443f14f4646Smrg entry->next = NULL; 444f14f4646Smrg hash_put(replace_hash, (hash_entry *)entry); 445f14f4646Smrg } 4465dfecf96Smrg 447f14f4646Smrg if (replace) { 448f14f4646Smrg XtFree(entry->replace); 449f14f4646Smrg entry->replace = XtNewString(replace); 450f14f4646Smrg } 4515dfecf96Smrg 452f14f4646Smrg return (entry->replace); 4535dfecf96Smrg} 4545dfecf96Smrg 4555dfecf96Smrgstatic Bool 4565dfecf96SmrgIspellDoIgnoredWord(char *word, int cmd, int add) 4575dfecf96Smrg{ 458f14f4646Smrg int word_len; 459f14f4646Smrg hash_key *word_key; 460f14f4646Smrg IgnoreEntry *entry; 461f14f4646Smrg 462f14f4646Smrg word_len = strlen(word); 463f14f4646Smrg entry = (IgnoreEntry *)hash_check(ignore_hash, word, word_len); 464f14f4646Smrg if (entry == NULL) { 465f14f4646Smrg if (cmd != ADD) 466f14f4646Smrg return (False); 4675dfecf96Smrg 468f14f4646Smrg word_key = XtNew(hash_key); 469f14f4646Smrg word_key->value = XtNewString(word); 470f14f4646Smrg word_key->length = word_len; 471f14f4646Smrg entry = XtNew(IgnoreEntry); 472f14f4646Smrg entry->word = word_key; 473f14f4646Smrg entry->add = add; 474f14f4646Smrg entry->next = NULL; 475f14f4646Smrg hash_put(ignore_hash, (hash_entry *)entry); 4765dfecf96Smrg 477f14f4646Smrg return (True); 478f14f4646Smrg } 479f14f4646Smrg else if (cmd == REMOVE) 480f14f4646Smrg hash_rem(ignore_hash, (hash_entry *)entry); 4815dfecf96Smrg 482f14f4646Smrg return (cmd == CHECK); 4835dfecf96Smrg} 4845dfecf96Smrg 4855dfecf96Smrgstatic Bool 4865dfecf96SmrgIspellIgnoredWord(char *word, int cmd, int add) 4875dfecf96Smrg{ 4885dfecf96Smrg if (add != UNCAP && IspellDoIgnoredWord(word, cmd, add)) 4895dfecf96Smrg return (True); 4905dfecf96Smrg 4915dfecf96Smrg /* add/remove uncapped word to/of list, 4925dfecf96Smrg * or cheks for correct capitalization */ 4935dfecf96Smrg if (add == UNCAP || cmd == CHECK) { 4945dfecf96Smrg unsigned char *str = (unsigned char*)word; 4955dfecf96Smrg unsigned char string[1024]; 4965dfecf96Smrg Bool upper, status; 4975dfecf96Smrg int i; 4985dfecf96Smrg 4995dfecf96Smrg status = True; 5005dfecf96Smrg upper = IsUpper(*str); 5015dfecf96Smrg *string = upper ? ToLower(*str) : *str; 5025dfecf96Smrg if (*str) 5035dfecf96Smrg str++; 5045dfecf96Smrg if (IsLower(*str)) 5055dfecf96Smrg upper = False; 5065dfecf96Smrg for (i = 1; *str && i < sizeof(string) - 1; i++, str++) { 5075dfecf96Smrg if (upper && IsLower(*str)) 5085dfecf96Smrg status = False; 5095dfecf96Smrg else if (!upper && IsUpper(*str)) 5105dfecf96Smrg status = False; 5115dfecf96Smrg string[i] = ToLower(*str); 5125dfecf96Smrg } 5135dfecf96Smrg string[i] = '\0'; 5145dfecf96Smrg 5155dfecf96Smrg if ((cmd != CHECK || status) && 5165dfecf96Smrg IspellDoIgnoredWord((char*)string, cmd, add)) 5175dfecf96Smrg return (True); 5185dfecf96Smrg } 5195dfecf96Smrg 5205dfecf96Smrg return (False); 5215dfecf96Smrg} 5225dfecf96Smrg 5235dfecf96Smrg/*ARGSUSED*/ 5245dfecf96Smrgstatic Bool 5255dfecf96SmrgIspellReceive(void) 5265dfecf96Smrg{ 5275dfecf96Smrg int i, len, old_len; 5285dfecf96Smrg Arg args[2]; 5295dfecf96Smrg char *str, *end, **list, **old_list; 5305dfecf96Smrg char *tmp, word[1024]; 5315dfecf96Smrg int j; 5325dfecf96Smrg 5335dfecf96Smrg if (ispell.lock || ispell.stat != RECEIVE) 5345dfecf96Smrg return (False); 5355dfecf96Smrg 5365dfecf96Smrg while (1) { /* read the entire line */ 5375dfecf96Smrg if (ispell.buflen >= ispell.bufsiz - 1) 5385dfecf96Smrg ispell.buf = XtRealloc(ispell.buf, ispell.bufsiz += BUFSIZ); 5395dfecf96Smrg if ((len = read(ispell.ifd[0], &ispell.buf[ispell.buflen], 5405dfecf96Smrg ispell.bufsiz - ispell.buflen - 1)) <= 0) 5415dfecf96Smrg break; 5425dfecf96Smrg ispell.buflen += len; 5435dfecf96Smrg } 5445dfecf96Smrg if (ispell.buflen <= 0) 5455dfecf96Smrg return (False); 5465dfecf96Smrg len = 0; 5475dfecf96Smrg i = ispell.buflen - 1; 5485dfecf96Smrg while (i >= 0 && ispell.buf[i] == '\n') { 5495dfecf96Smrg ++len; 5505dfecf96Smrg --i; 5515dfecf96Smrg } 5525dfecf96Smrg if (len < 2 - ((ispell.terse_mode && i == -1) || ispell.buf[0] == '@')) 5535dfecf96Smrg return (False); 5545dfecf96Smrg ispell.buf[ispell.buflen - len] = '\0'; 5555dfecf96Smrg ispell.buflen = 0; 5565dfecf96Smrg 5575dfecf96Smrg if ((tmp = strchr(ispell.sendbuf, '\n')) != NULL) 5585dfecf96Smrg *tmp = '\0'; 5595dfecf96Smrg 5605dfecf96Smrg switch (ispell.buf[0]) { 5615dfecf96Smrg case '&': /* MISS */ 5625dfecf96Smrg case '?': /* GUESS */ 5635dfecf96Smrg str = strchr(&ispell.buf[2], ' '); 5645dfecf96Smrg if (!ispell.checkit) { 5655dfecf96Smrg *str = '\0'; 5665dfecf96Smrg XtSetArg(args[0], XtNlabel, &ispell.buf[2]); 5675dfecf96Smrg XtSetValues(ispell.word, args, 1); 5685dfecf96Smrg } 5695dfecf96Smrg ++str; 5705dfecf96Smrg list = NULL; 5715dfecf96Smrg str = strchr(str, ':') + 1; 5725dfecf96Smrg for (i = 0; ; i++) { 5735dfecf96Smrg end = strchr(str, ','); 5745dfecf96Smrg if (end) *end = '\0'; 5755dfecf96Smrg if ((i % 16) == 0) 5765dfecf96Smrg list = (char**)XtRealloc((char*)list, (i + 16) * sizeof(char*)); 5775dfecf96Smrg tmp = word; 5785dfecf96Smrg for (j = 1; j < sizeof(word) && str[j]; j++) { 5795dfecf96Smrg if (str[j] == '+') 5805dfecf96Smrg continue; 5815dfecf96Smrg else if (str[j] == '-' && str[j+1] != '-' && str[j-1] != '-') { 5825dfecf96Smrg char *p, string[256]; 5835dfecf96Smrg int k, l; 5845dfecf96Smrg 5855dfecf96Smrg for (l = 0, k = j + 1; str[k] != '+' && str[k] != '-' 5865dfecf96Smrg && str[k] && l < sizeof(string) - 1; k++, l++) 5875dfecf96Smrg string[l] = str[k]; 5885dfecf96Smrg string[l] = '\0'; 5895dfecf96Smrg *tmp = '\0'; 5905dfecf96Smrg if (l && (p = strstr(word, string)) != NULL) { 5915dfecf96Smrg char *sav = p; 5925dfecf96Smrg 5935dfecf96Smrg while ((p = strstr(p + l, string)) != NULL) 5945dfecf96Smrg sav = p; 5955dfecf96Smrg p = sav; 5965dfecf96Smrg if (strcmp(p, string) == 0) { 5975dfecf96Smrg tmp = p; 5985dfecf96Smrg j = k - 1; 5995dfecf96Smrg } 6005dfecf96Smrg else 6015dfecf96Smrg *tmp++ = '-'; 6025dfecf96Smrg } 6035dfecf96Smrg else 6045dfecf96Smrg *tmp++ = '-'; 6055dfecf96Smrg } 6065dfecf96Smrg else 6075dfecf96Smrg *tmp++ = str[j]; 6085dfecf96Smrg } 6095dfecf96Smrg *tmp = '\0'; 6105dfecf96Smrg list[i] = XtNewString(word); 6115dfecf96Smrg 6125dfecf96Smrg if (end) str = end + 1; 6135dfecf96Smrg else break; 6145dfecf96Smrg } 6155dfecf96Smrg len = i + 1; 6165dfecf96Smrg 6175dfecf96Smrg XtSetArg(args[0], XtNlist, &old_list); 6185dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, &old_len); 6195dfecf96Smrg XtGetValues(ispell.list, args, 2); 6205dfecf96Smrg 6215dfecf96Smrg ispell.item = NULL; 6225dfecf96Smrg if ((str = IspellReplacedWord(&ispell.buf[2], NULL)) != NULL) 6235dfecf96Smrg for (i = 0; i < len; i++) { 6245dfecf96Smrg if (strcmp(list[i], str) == 0) { 6255dfecf96Smrg ispell.item = list[i]; 6265dfecf96Smrg break; 6275dfecf96Smrg } 6285dfecf96Smrg } 6295dfecf96Smrg else 6305dfecf96Smrg ispell.item = list[i = 0]; 6315dfecf96Smrg if (!ispell.item) { 6325dfecf96Smrg list = (char**)XtRealloc((char*)list, (len + 1) * sizeof(char*)); 6335dfecf96Smrg ispell.item = list[i] = XtNewString(str); 6345dfecf96Smrg ++len; 6355dfecf96Smrg } 6365dfecf96Smrg 6375dfecf96Smrg XtSetArg(args[0], XtNlist, list); 6385dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, len); 6395dfecf96Smrg XtSetValues(ispell.list, args, 2); 6405dfecf96Smrg 6415dfecf96Smrg XtSetSensitive(ispell.list, True); 6425dfecf96Smrg if (!ispell.checkit) 6435dfecf96Smrg XawListHighlight(ispell.list, i); 6445dfecf96Smrg 6455dfecf96Smrg if (old_len > 1 || (XtName(ispell.list) != old_list[0])) { 6465dfecf96Smrg while (--old_len > -1) 6475dfecf96Smrg XtFree(old_list[old_len]); 6485dfecf96Smrg XtFree((char*)old_list); 6495dfecf96Smrg } 6505dfecf96Smrg 6515dfecf96Smrg if (!ispell.checkit) { 6525dfecf96Smrg XtSetArg(args[0], XtNstring, ispell.item); 6535dfecf96Smrg XtSetValues(ispell.text, args, 1); 6545dfecf96Smrg IspellSetSelection(ispell.left, ispell.right); 6555dfecf96Smrg if (ispell.repeat) 6565dfecf96Smrg IspellSetRepeated(ispell.repeat = False); 6575dfecf96Smrg } 6585dfecf96Smrg 6595dfecf96Smrg IspellSetStatus(ispell.buf[0] == '?' ? 6605dfecf96Smrg ispell.guess_label : ispell.miss_label); 6615dfecf96Smrg ispell.undo_terse_mode = ispell.terse_mode; 6625dfecf96Smrg ispell.format_mode = ispell.format_info->value; 6635dfecf96Smrg ispell.lock = True; 6645dfecf96Smrg break; 6655dfecf96Smrg case '#': /* NONE */ 6665dfecf96Smrg case '-': /* COMPOUND */ 6675dfecf96Smrg case '+': /* ROOT */ 6685dfecf96Smrg check_label: 6695dfecf96Smrg str = &ispell.sendbuf[1]; 6705dfecf96Smrg if (!ispell.checkit) { 6715dfecf96Smrg XtSetArg(args[0], XtNlabel, str); 6725dfecf96Smrg XtSetValues(ispell.word, args, 1); 6735dfecf96Smrg } 6745dfecf96Smrg 6755dfecf96Smrg XtSetArg(args[0], XtNlist, &old_list); 6765dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, &old_len); 6775dfecf96Smrg XtGetValues(ispell.list, args, 2); 6785dfecf96Smrg ispell.item = NULL; 6795dfecf96Smrg 6805dfecf96Smrg list = (char**)XtMalloc(sizeof(char**)); 6815dfecf96Smrg if ((tmp = IspellReplacedWord(str, NULL)) != NULL) 6825dfecf96Smrg str = tmp; 6835dfecf96Smrg if (tmp == NULL && ispell.buf[0] == '#') 6845dfecf96Smrg list[0] = XtNewString(""); 6855dfecf96Smrg else 6865dfecf96Smrg list[0] = XtNewString(str); 6875dfecf96Smrg 6885dfecf96Smrg XtSetArg(args[0], XtNlist, list); 6895dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, 1); 6905dfecf96Smrg XtSetValues(ispell.list, args, 2); 6915dfecf96Smrg 6925dfecf96Smrg if (tmp == NULL && ispell.buf[0] == '#') { 6935dfecf96Smrg XawListUnhighlight(ispell.list); 6945dfecf96Smrg XtSetSensitive(ispell.list, False); 6955dfecf96Smrg } 6965dfecf96Smrg else { 6975dfecf96Smrg XtSetSensitive(ispell.list, True); 6985dfecf96Smrg if (!ispell.checkit) 6995dfecf96Smrg XawListHighlight(ispell.list, 0); 7005dfecf96Smrg } 7015dfecf96Smrg if (old_len > 1 || (XtName(ispell.list) != old_list[0])) { 7025dfecf96Smrg while (--old_len > -1) 7035dfecf96Smrg XtFree(old_list[old_len]); 7045dfecf96Smrg XtFree((char*)old_list); 7055dfecf96Smrg } 7065dfecf96Smrg 7075dfecf96Smrg if (!ispell.checkit) { 7085dfecf96Smrg XtSetArg(args[0], XtNstring, str); 7095dfecf96Smrg XtSetValues(ispell.text, args, 1); 7105dfecf96Smrg IspellSetSelection(ispell.left, ispell.right); 7115dfecf96Smrg if (ispell.repeat) 7125dfecf96Smrg IspellSetRepeated(ispell.repeat = False); 7135dfecf96Smrg } 7145dfecf96Smrg 7155dfecf96Smrg ispell.undo_terse_mode = ispell.terse_mode; 7165dfecf96Smrg ispell.format_mode = ispell.format_info->value; 7175dfecf96Smrg ispell.lock = True; 7185dfecf96Smrg if (ispell.buf[0] == '+') { 7195dfecf96Smrg if ((tmp = strchr(&ispell.buf[2], '\n')) != NULL) 7205dfecf96Smrg *tmp = '\0'; 7215dfecf96Smrg XmuSnprintf(word, sizeof(word), "%s %s", 7225dfecf96Smrg ispell.root_label, &ispell.buf[2]); 7235dfecf96Smrg IspellSetStatus(word); 7245dfecf96Smrg } 7255dfecf96Smrg else 7265dfecf96Smrg IspellSetStatus(ispell.buf[0] == '#' ? ispell.none_label : 7275dfecf96Smrg ispell.buf[0] == '-' ? ispell.compound_label : 7285dfecf96Smrg ispell.ok_label); 7295dfecf96Smrg break; 7305dfecf96Smrg case '*': /* OK */ 7315dfecf96Smrg case '\0': /* when running in terse mode */ 7325dfecf96Smrg if (!ispell.checkit) 7335dfecf96Smrg (void)IspellIgnoredWord(&ispell.sendbuf[1], ADD, 0); 7345dfecf96Smrg else 7355dfecf96Smrg goto check_label; 7365dfecf96Smrg ispell.lock = False; 7375dfecf96Smrg break; 7385dfecf96Smrg case '@': /* Ispell banner */ 7395dfecf96Smrg /* it only happens when the dictionary is changed */ 7405dfecf96Smrg if (!ispell.repeat) { 7415dfecf96Smrg XawTextPosition left, right; 7425dfecf96Smrg 7435dfecf96Smrg ispell.stat = SEND; 7445dfecf96Smrg while (IspellSend() == 0) 7455dfecf96Smrg ; 7465dfecf96Smrg /* word chars may have changed */ 7475dfecf96Smrg XawTextGetSelectionPos(ispell.ascii, &left, &right); 7485dfecf96Smrg if (left != ispell.left || right != ispell.right) { 7495dfecf96Smrg XtSetArg(args[0], XtNstring, &ispell.sendbuf[1]); 7505dfecf96Smrg XtSetValues(ispell.text, args, 1); 7515dfecf96Smrg IspellSetSelection(ispell.left, ispell.right); 7525dfecf96Smrg } 7535dfecf96Smrg ispell.checkit = True; 7545dfecf96Smrg } 7555dfecf96Smrg else { 7565dfecf96Smrg IspellSetStatus(ispell.repeat_label); 7575dfecf96Smrg ispell.undo_terse_mode = ispell.terse_mode; 7585dfecf96Smrg ispell.format_mode = ispell.format_info->value; 7595dfecf96Smrg ispell.lock = True; 7605dfecf96Smrg return (True); 7615dfecf96Smrg } 7625dfecf96Smrg break; 7635dfecf96Smrg default: 7645dfecf96Smrg fprintf(stderr, "Unknown ispell command '%c'\n", ispell.buf[0]); 7655dfecf96Smrg return (False); 7665dfecf96Smrg } 7675dfecf96Smrg 7685dfecf96Smrg if (!ispell.lock && !ispell.checkit) { 7695dfecf96Smrg ispell.stat = SEND; 7705dfecf96Smrg while (IspellSend() == 0) 7715dfecf96Smrg ; 7725dfecf96Smrg } 7735dfecf96Smrg 7745dfecf96Smrg return (True); 7755dfecf96Smrg} 7765dfecf96Smrg 7775dfecf96Smrgstatic int 7785dfecf96SmrgIspellConvertHtmlAmp(char *buf) 7795dfecf96Smrg{ 7805dfecf96Smrg int len, ch = '?'; 7815dfecf96Smrg 7825dfecf96Smrg /* this function is static, so I can do it */ 7835dfecf96Smrg *strchr(++buf, ';') = '\0'; 7845dfecf96Smrg 7855dfecf96Smrg len = strlen(buf); 7865dfecf96Smrg if (len == 0) 7875dfecf96Smrg return ('&'); 7885dfecf96Smrg if (len > 1) { 7895dfecf96Smrg if (strcasecmp(&buf[1], "lt") == 0) 7905dfecf96Smrg ch = '<'; 7915dfecf96Smrg else if (strcasecmp(&buf[1], "gt") == 0) 7925dfecf96Smrg ch = '>'; 7935dfecf96Smrg else if (strcasecmp(&buf[1], "nbsp") == 0) 7945dfecf96Smrg ch = ' '; 7955dfecf96Smrg else if (strcasecmp(&buf[1], "amp") == 0) 7965dfecf96Smrg ch = '&'; 7975dfecf96Smrg else if (strcasecmp(&buf[1], "quot") == 0) 7985dfecf96Smrg ch = '"'; 7995dfecf96Smrg else if (*buf == '#') { 8005dfecf96Smrg char *tmp; 8015dfecf96Smrg 8025dfecf96Smrg if (len == 1) 8035dfecf96Smrg return ('?'); 8045dfecf96Smrg ch = strtol(&buf[1], &tmp, 10); 8055dfecf96Smrg if (*tmp) 8065dfecf96Smrg fprintf(stderr, "Warning: bad html interpreting '&#' mark.\n"); 8075dfecf96Smrg } 8085dfecf96Smrg else if (strcmp(&buf[1], "acute") == 0) { 8095dfecf96Smrg switch (*buf) { 8105dfecf96Smrg case 'a': ch = 0xe1; break; 8115dfecf96Smrg case 'e': ch = 0xe9; break; 8125dfecf96Smrg case 'i': ch = 0xed; break; 8135dfecf96Smrg case 'o': ch = 0xf3; break; 8145dfecf96Smrg case 'u': ch = 0xfa; break; 8155dfecf96Smrg case 'A': ch = 0xc1; break; 8165dfecf96Smrg case 'E': ch = 0xc9; break; 8175dfecf96Smrg case 'I': ch = 0xcd; break; 8185dfecf96Smrg case 'O': ch = 0xd3; break; 8195dfecf96Smrg case 'U': ch = 0xda; break; 8205dfecf96Smrg } 8215dfecf96Smrg } 8225dfecf96Smrg else if (strcmp(&buf[1], "grave") == 0) { 8235dfecf96Smrg switch (*buf) { 8245dfecf96Smrg case 'a': ch = 0xe0; break; 8255dfecf96Smrg case 'e': ch = 0xe8; break; 8265dfecf96Smrg case 'i': ch = 0xec; break; 8275dfecf96Smrg case 'o': ch = 0xf2; break; 8285dfecf96Smrg case 'u': ch = 0xf9; break; 8295dfecf96Smrg case 'A': ch = 0xc0; break; 8305dfecf96Smrg case 'E': ch = 0xc8; break; 8315dfecf96Smrg case 'I': ch = 0xcc; break; 8325dfecf96Smrg case 'O': ch = 0xd2; break; 8335dfecf96Smrg case 'U': ch = 0xd9; break; 8345dfecf96Smrg } 8355dfecf96Smrg } 8365dfecf96Smrg else if (strcmp(&buf[1], "tilde") == 0) { 8375dfecf96Smrg switch (*buf) { 8385dfecf96Smrg case 'a': ch = 0xe3; break; 8395dfecf96Smrg case 'o': ch = 0xf5; break; 8405dfecf96Smrg case 'n': ch = 0xf1; break; 8415dfecf96Smrg case 'A': ch = 0xe3; break; 8425dfecf96Smrg case 'O': ch = 0xd5; break; 8435dfecf96Smrg case 'N': ch = 0xd1; break; 8445dfecf96Smrg } 8455dfecf96Smrg } 8465dfecf96Smrg else if (strcmp(&buf[1], "circ") == 0) { 8475dfecf96Smrg switch (*buf) { 8485dfecf96Smrg case 'a': ch = 0xe2; break; 8495dfecf96Smrg case 'e': ch = 0xea; break; 8505dfecf96Smrg case 'i': ch = 0xee; break; 8515dfecf96Smrg case 'o': ch = 0xf4; break; 8525dfecf96Smrg case 'u': ch = 0xfb; break; 8535dfecf96Smrg case 'A': ch = 0xc2; break; 8545dfecf96Smrg case 'E': ch = 0xca; break; 8555dfecf96Smrg case 'I': ch = 0xce; break; 8565dfecf96Smrg case 'O': ch = 0xd4; break; 8575dfecf96Smrg case 'U': ch = 0xdb; break; 8585dfecf96Smrg } 8595dfecf96Smrg } 8605dfecf96Smrg else if (strcmp(&buf[1], "cedil") == 0) { 8615dfecf96Smrg switch (*buf) { 8625dfecf96Smrg case 'c': ch = 0xe7; break; 8635dfecf96Smrg case 'C': ch = 0xc7; break; 8645dfecf96Smrg } 8655dfecf96Smrg } 8665dfecf96Smrg /* add more cases here */ 8675dfecf96Smrg } 8685dfecf96Smrg 8695dfecf96Smrg return (ch); 8705dfecf96Smrg} 8715dfecf96Smrg 8725dfecf96Smrg/*ARGSUSED*/ 8735dfecf96Smrgstatic int 8745dfecf96SmrgIspellSend(void) 8755dfecf96Smrg{ 8765dfecf96Smrg XawTextPosition position, old_left, pos; 8775dfecf96Smrg XawTextBlock block; 8785dfecf96Smrg int i, len, spaces, nls; 8795dfecf96Smrg Bool nl, html, inside_html; 8805dfecf96Smrg char ampbuf[32]; 8815dfecf96Smrg int amplen; 8825dfecf96Smrg 8835dfecf96Smrg if (ispell.lock || ispell.stat != SEND) 8845dfecf96Smrg return (-1); 8855dfecf96Smrg 8865dfecf96Smrg len = 1; 8875dfecf96Smrg ispell.sendbuf[0] = '^'; /* don't evaluate following characters as commands */ 8885dfecf96Smrg 8895dfecf96Smrg spaces = nls = 0; 8905dfecf96Smrg 8915dfecf96Smrg html = ispell.format_info->value == HTML; 8925dfecf96Smrg inside_html = False; 8935dfecf96Smrg amplen = 0; 8945dfecf96Smrg 8955dfecf96Smrg /* skip non word characters */ 8965dfecf96Smrg pos = position = ispell.right; 8975dfecf96Smrg nl = False; 8985dfecf96Smrg while (1) { 8995dfecf96Smrg Bool done = False; 9005dfecf96Smrg char mb[sizeof(wchar_t)]; 9015dfecf96Smrg 9025dfecf96Smrg retry_html_space: 9035dfecf96Smrg position = XawTextSourceRead(ispell.source, position, 9045dfecf96Smrg &block, BUFSIZ); 9055dfecf96Smrg if (block.length == 0) { /* end of file */ 9065dfecf96Smrg ispell.stat = 0; 9075dfecf96Smrg ispell.lock = True; 9085dfecf96Smrg XawTextSetInsertionPoint(ispell.ascii, ispell.right); 9095dfecf96Smrg XawTextUnsetSelection(ispell.ascii); 9105dfecf96Smrg IspellSetSensitive(False); 9115dfecf96Smrg IspellSetStatus(ispell.eof_label); 9125dfecf96Smrg return (-1); 9135dfecf96Smrg } 9145dfecf96Smrg for (i = 0; i < block.length; i++) { 915f14f4646Smrg if (international) 916f14f4646Smrg wctomb(mb, ((wchar_t*)block.ptr)[i]); 917f14f4646Smrg else 918f14f4646Smrg mb[0] = block.ptr[i]; 9195dfecf96Smrg if (amplen) { 9205dfecf96Smrg if (amplen + 2 >= sizeof(ampbuf)) { 9215dfecf96Smrg if (!ispell.terse_mode) 9225dfecf96Smrg fprintf(stderr, "Warning: error interpreting '&' mark.\n"); 9235dfecf96Smrg amplen = 0; 9245dfecf96Smrg position = pos + 1; 9255dfecf96Smrg goto retry_html_space; 9265dfecf96Smrg } 9275dfecf96Smrg else if ((ampbuf[amplen++] = *mb) == ';') { 9285dfecf96Smrg int ch; 9295dfecf96Smrg 9305dfecf96Smrg ampbuf[amplen] = '\0'; 9315dfecf96Smrg ch = IspellConvertHtmlAmp(ampbuf); 9325dfecf96Smrg amplen = 0; 9335dfecf96Smrg if (isalpha(ch) || 9345dfecf96Smrg (ch && strchr(ispell.wchars, ch))) { 9355dfecf96Smrg /* interpret it again */ 9365dfecf96Smrg ispell.right = pos; 9375dfecf96Smrg i = 0; 9385dfecf96Smrg done = True; 9395dfecf96Smrg break; 9405dfecf96Smrg } 9415dfecf96Smrg else if ((ch == '\n' || isspace(ch)) && spaces >= 0) 9425dfecf96Smrg ++spaces; 9435dfecf96Smrg else 9445dfecf96Smrg spaces = -1; 9455dfecf96Smrg } 9465dfecf96Smrg } 9475dfecf96Smrg else if (html && *mb == '&') { 9485dfecf96Smrg ampbuf[amplen++] = *mb; 9495dfecf96Smrg pos = block.firstPos + i; 9505dfecf96Smrg continue; 9515dfecf96Smrg } 9525dfecf96Smrg else if ((!html || !inside_html) && (isalpha(*mb) || 9535dfecf96Smrg (*mb && strchr(ispell.wchars, *mb)))) { 9545dfecf96Smrg done = True; 9555dfecf96Smrg break; 9565dfecf96Smrg } 9575dfecf96Smrg else if (!html && *mb == '\n') { 9585dfecf96Smrg nl = True; 9595dfecf96Smrg if (++nls > 1 && (!html || !inside_html)) 9605dfecf96Smrg spaces = -1; 9615dfecf96Smrg else if (spaces >= 0) 9625dfecf96Smrg ++spaces; 9635dfecf96Smrg } 9645dfecf96Smrg else if (nl) { 9655dfecf96Smrg nl = False; 9665dfecf96Smrg if (*mb && strchr(ispell.skip, *mb)) { 9675dfecf96Smrg position = ispell.right = 9685dfecf96Smrg XawTextSourceScan(ispell.source, ispell.right + i, 9695dfecf96Smrg XawstEOL, XawsdRight, 1, False); 9705dfecf96Smrg i = 0; 9715dfecf96Smrg break; 9725dfecf96Smrg } 9735dfecf96Smrg else if (spaces >= 0 && isspace(*mb)) 9745dfecf96Smrg ++spaces; 9755dfecf96Smrg else 9765dfecf96Smrg spaces = -1; 9775dfecf96Smrg } 9785dfecf96Smrg else if (html && inside_html) { 9795dfecf96Smrg if (*mb == '>') 9805dfecf96Smrg inside_html = False; 9815dfecf96Smrg } 9825dfecf96Smrg else if (html && *mb == '<') 9835dfecf96Smrg inside_html = True; 9845dfecf96Smrg else if (spaces >= 0 && (isspace(*mb) || (html && *mb == '\n'))) 9855dfecf96Smrg ++spaces; 9865dfecf96Smrg else 9875dfecf96Smrg spaces = -1; 9885dfecf96Smrg } 9895dfecf96Smrg 9905dfecf96Smrg ispell.right += i; 9915dfecf96Smrg if (done) 9925dfecf96Smrg break; 9935dfecf96Smrg } 9945dfecf96Smrg 9955dfecf96Smrg old_left = ispell.left; 9965dfecf96Smrg 9975dfecf96Smrg /* read a word */ 9985dfecf96Smrg position = ispell.left = ispell.right; 9995dfecf96Smrg while (1) { 10005dfecf96Smrg Bool done = False; 10015dfecf96Smrg char mb[sizeof(wchar_t)]; 10025dfecf96Smrg 10035dfecf96Smrg retry_html_word: 10045dfecf96Smrg position = XawTextSourceRead(ispell.source, position, 10055dfecf96Smrg &block, BUFSIZ); 10065dfecf96Smrg if (block.length == 0 && len == 1) { /* end of file */ 10075dfecf96Smrg ispell.stat = 0; 10085dfecf96Smrg ispell.lock = True; 10095dfecf96Smrg XawTextSetInsertionPoint(ispell.ascii, ispell.right); 10105dfecf96Smrg XawTextUnsetSelection(ispell.ascii); 10115dfecf96Smrg IspellSetSensitive(False); 10125dfecf96Smrg IspellSetStatus(ispell.eof_label); 10135dfecf96Smrg return (-1); 10145dfecf96Smrg } 10155dfecf96Smrg for (i = 0; i < block.length; i++) { 1016f14f4646Smrg if (international) 1017f14f4646Smrg wctomb(mb, ((wchar_t*)block.ptr)[i]); 1018f14f4646Smrg else 1019f14f4646Smrg mb[0] = block.ptr[i]; 10205dfecf96Smrg if (amplen) { 10215dfecf96Smrg if (amplen + 2 >= sizeof(ampbuf)) { 10225dfecf96Smrg if (!ispell.terse_mode) 10235dfecf96Smrg fprintf(stderr, "Warning: error interpreting '&' mark.\n"); 10245dfecf96Smrg amplen = 0; 10255dfecf96Smrg position = pos + 1; 10265dfecf96Smrg if (strchr(ispell.wchars, '&')) { 10275dfecf96Smrg if (len + 1 >= sizeof(ispell.sendbuf) - 1) { 10285dfecf96Smrg done = True; 10295dfecf96Smrg fprintf(stderr, "Warning: word is too large!\n"); 10305dfecf96Smrg break; 10315dfecf96Smrg } 10325dfecf96Smrg ispell.sendbuf[len++] = '&'; 10335dfecf96Smrg goto retry_html_word; 10345dfecf96Smrg } 10355dfecf96Smrg else { 10365dfecf96Smrg ispell.right = position; 10375dfecf96Smrg i = 0; 10385dfecf96Smrg done = True; 10395dfecf96Smrg break; 10405dfecf96Smrg } 10415dfecf96Smrg } 10425dfecf96Smrg else if ((ampbuf[amplen++] = *mb) == ';') { 10435dfecf96Smrg int ch; 10445dfecf96Smrg 10455dfecf96Smrg ampbuf[amplen] = '\0'; 10465dfecf96Smrg ch = IspellConvertHtmlAmp(ampbuf); 10475dfecf96Smrg amplen = 0; 10485dfecf96Smrg if (!isalpha(ch) && 10495dfecf96Smrg (!ch || !strchr(ispell.wchars, ch))) { 10505dfecf96Smrg ispell.right = pos; 10515dfecf96Smrg i = 0; 10525dfecf96Smrg done = True; 10535dfecf96Smrg break; 10545dfecf96Smrg } 10555dfecf96Smrg *mb = ch; 10565dfecf96Smrg } 10575dfecf96Smrg else 10585dfecf96Smrg continue; 10595dfecf96Smrg } 10605dfecf96Smrg else if (html && *mb == '&') { 10615dfecf96Smrg ampbuf[amplen++] = *mb; 10625dfecf96Smrg pos = block.firstPos + i; 10635dfecf96Smrg continue; 10645dfecf96Smrg } 10655dfecf96Smrg else if (!isalpha(*mb) && (!*mb || !strchr(ispell.wchars, *mb))) { 10665dfecf96Smrg done = True; 10675dfecf96Smrg break; 10685dfecf96Smrg } 10695dfecf96Smrg ispell.sendbuf[len] = *mb; 10705dfecf96Smrg if (++len >= sizeof(ispell.sendbuf) - 1) { 10715dfecf96Smrg done = True; 10725dfecf96Smrg fprintf(stderr, "Warning: word is too large!\n"); 10735dfecf96Smrg break; 10745dfecf96Smrg } 10755dfecf96Smrg } 10765dfecf96Smrg ispell.right += i; 10775dfecf96Smrg if (done || block.length == 0) 10785dfecf96Smrg break; 10795dfecf96Smrg } 10805dfecf96Smrg 10815dfecf96Smrg ispell.sendbuf[len] = '\0'; 10825dfecf96Smrg 10835dfecf96Smrg if (spaces > 0 && spaces <= 32 && strcmp(ispell.sendbuf, ispell.sentbuf) == 0) { 10845dfecf96Smrg Arg args[2]; 10855dfecf96Smrg int old_len; 10865dfecf96Smrg char **list, **old_list; 10875dfecf96Smrg char label[sizeof(ispell.sendbuf) + sizeof(ispell.sentbuf) + 32]; 10885dfecf96Smrg 10895dfecf96Smrg strcpy(label, &ispell.sendbuf[1]); 10905dfecf96Smrg for (i = 0; i < spaces; i++) 10915dfecf96Smrg label[len + i - 1] = ' '; 10925dfecf96Smrg strcpy(&label[len + i - 1], &ispell.sendbuf[1]); 10935dfecf96Smrg XtSetArg(args[0], XtNlabel, label); 10945dfecf96Smrg XtSetValues(ispell.word, args, 1); 10955dfecf96Smrg 10965dfecf96Smrg XtSetArg(args[0], XtNstring, &ispell.sendbuf[1]); 10975dfecf96Smrg XtSetValues(ispell.text, args, 1); 10985dfecf96Smrg 10995dfecf96Smrg XtSetArg(args[0], XtNlist, &old_list); 11005dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, &old_len); 11015dfecf96Smrg XtGetValues(ispell.list, args, 2); 11025dfecf96Smrg list = (char**)XtMalloc(sizeof(char**)); 11035dfecf96Smrg list[0] = XtNewString(&ispell.sendbuf[1]); 11045dfecf96Smrg XtSetArg(args[0], XtNlist, list); 11055dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, 1); 11065dfecf96Smrg XtSetValues(ispell.list, args, 2); 11075dfecf96Smrg XtSetSensitive(ispell.list, True); 11085dfecf96Smrg XawListHighlight(ispell.list, 0); 11095dfecf96Smrg if (old_len > 1 || (XtName(ispell.list) != old_list[0])) { 11105dfecf96Smrg while (--old_len > -1) 11115dfecf96Smrg XtFree(old_list[old_len]); 11125dfecf96Smrg XtFree((char*)old_list); 11135dfecf96Smrg } 11145dfecf96Smrg 11155dfecf96Smrg IspellSetRepeated(True); 11165dfecf96Smrg IspellSetSelection(old_left, ispell.right); 11175dfecf96Smrg IspellSetStatus(ispell.repeat_label); 11185dfecf96Smrg ispell.repeat = ispell.lock = True; 11195dfecf96Smrg 11205dfecf96Smrg return (1); 11215dfecf96Smrg } 11225dfecf96Smrg strcpy(ispell.sentbuf, ispell.sendbuf); 11235dfecf96Smrg 11245dfecf96Smrg if (len <= 2 || IspellIgnoredWord(&ispell.sendbuf[1], CHECK, 0)) 11255dfecf96Smrg return (0); 11265dfecf96Smrg 11275dfecf96Smrg ispell.sendbuf[len++] = '\n'; 11285dfecf96Smrg 11295dfecf96Smrg write(ispell.ofd[1], ispell.sendbuf, len); 11305dfecf96Smrg 11315dfecf96Smrg ispell.stat = RECEIVE; 11325dfecf96Smrg 11335dfecf96Smrg return (1); 11345dfecf96Smrg} 11355dfecf96Smrg 11365dfecf96Smrg/*ARGSUSED*/ 11375dfecf96Smrgstatic void 11385dfecf96SmrgIspellInputCallback(XtPointer closure, int *source, XtInputId *id) 11395dfecf96Smrg{ 11405dfecf96Smrg if (ispell.right < 0) { 11415dfecf96Smrg int len; 11425dfecf96Smrg char buf[1024]; 11435dfecf96Smrg 11445dfecf96Smrg ispell.right = XawTextGetInsertionPoint(ispell.ascii); 11455dfecf96Smrg ispell.right = XawTextSourceScan(ispell.source, ispell.right, 11465dfecf96Smrg XawstEOL, XawsdLeft, 1, True); 11475dfecf96Smrg len = read(ispell.ifd[0], buf, sizeof(buf)); 11485dfecf96Smrg if (strncmp(buf, "@(#)", 4) == 0) { 11495dfecf96Smrg Arg args[1]; 11505dfecf96Smrg 11515dfecf96Smrg buf[len - 1] = '\0'; 11525dfecf96Smrg XtSetArg(args[0], XtNtitle, &buf[5]); 11535dfecf96Smrg XtSetValues(ispell.shell, args, 1); 11545dfecf96Smrg } 11555dfecf96Smrg else 11565dfecf96Smrg fprintf(stderr, "Error: is ispell talking with me?\n"); 11575dfecf96Smrg IspellSetTerseMode(ispell.terse_mode); 11585dfecf96Smrg while (IspellSend() == 0) 11595dfecf96Smrg ; 11605dfecf96Smrg } 11615dfecf96Smrg else if (ispell.source) 11625dfecf96Smrg IspellReceive(); 11635dfecf96Smrg} 11645dfecf96Smrg 11655dfecf96Smrg/*ARGSUSED*/ 11665dfecf96Smrgvoid 11675dfecf96SmrgIspellCallback(Widget w, XtPointer client_data, XtPointer call_data) 11685dfecf96Smrg{ 11695dfecf96Smrg Cardinal zero = 0; 11705dfecf96Smrg 11715dfecf96Smrg IspellAction(textwindow, NULL, NULL, &zero); 11725dfecf96Smrg} 11735dfecf96Smrg 11745dfecf96Smrg/*ARGSUSED*/ 11755dfecf96Smrgvoid 11765dfecf96SmrgIspellAction(Widget w, XEvent *event, String *params, Cardinal *num_params) 11775dfecf96Smrg{ 11785dfecf96Smrg Arg args[3]; 11795dfecf96Smrg Cardinal num_args; 11805dfecf96Smrg char **strs, **list; 11815dfecf96Smrg int n_strs; 11825dfecf96Smrg Bool first_time = InitIspell(); 11835dfecf96Smrg 11845dfecf96Smrg if (*num_params == 1 && (params[0][0] == 'e' || params[0][0] == 'E')) { 11855dfecf96Smrg PopdownIspell(w, (XtPointer)True, NULL); 11865dfecf96Smrg return; 11875dfecf96Smrg } 11885dfecf96Smrg 11895dfecf96Smrg if (!XtIsSubclass(w, textWidgetClass) || ispell.source) { 11905dfecf96Smrg Feep(); 11915dfecf96Smrg return; 11925dfecf96Smrg } 11935dfecf96Smrg 11945dfecf96Smrg ispell.source = XawTextGetSource(ispell.ascii = w); 11955dfecf96Smrg 11965dfecf96Smrg if (first_time) { 11975dfecf96Smrg /* let the user choose the better position for the ispell window */ 11985dfecf96Smrg Dimension width, height, b_width; 11995dfecf96Smrg Position x, y, max_x, max_y; 12005dfecf96Smrg 12015dfecf96Smrg x = y = -1; 12025dfecf96Smrg if (event) { 12035dfecf96Smrg switch (event->type) { 12045dfecf96Smrg case ButtonPress: 12055dfecf96Smrg case ButtonRelease: 12065dfecf96Smrg x = event->xbutton.x_root; 12075dfecf96Smrg y = event->xbutton.y_root; 12085dfecf96Smrg break; 12095dfecf96Smrg case KeyPress: 12105dfecf96Smrg case KeyRelease: 12115dfecf96Smrg x = event->xkey.x_root; 12125dfecf96Smrg y = event->xkey.y_root; 12135dfecf96Smrg break; 12145dfecf96Smrg } 12155dfecf96Smrg } 12165dfecf96Smrg if (x < 0 || y < 0) { 12175dfecf96Smrg Window r, c; 12185dfecf96Smrg int rx, ry, wx, wy; 12195dfecf96Smrg unsigned mask; 12205dfecf96Smrg 12215dfecf96Smrg XQueryPointer(XtDisplay(ispell.shell), XtWindow(ispell.shell), 12225dfecf96Smrg &r, &c, &rx, &ry, &wx, &wy, &mask); 12235dfecf96Smrg x = rx; 12245dfecf96Smrg y = ry; 12255dfecf96Smrg } 12265dfecf96Smrg 12275dfecf96Smrg num_args = 0; 12285dfecf96Smrg XtSetArg(args[num_args], XtNwidth, &width); num_args++; 12295dfecf96Smrg XtSetArg(args[num_args], XtNheight, &height); num_args++; 12305dfecf96Smrg XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++; 12315dfecf96Smrg XtGetValues(ispell.shell, args, num_args); 12325dfecf96Smrg 12335dfecf96Smrg width += b_width << 1; 12345dfecf96Smrg height += b_width << 1; 12355dfecf96Smrg 12365dfecf96Smrg x -= (Position)(width >> 1); 12375dfecf96Smrg if (x < 0) 12385dfecf96Smrg x = 0; 12395dfecf96Smrg if (x > (max_x = (Position)(XtScreen(w)->width - width))) 12405dfecf96Smrg x = max_x; 12415dfecf96Smrg 12425dfecf96Smrg y -= (Position)(height >> 1); 12435dfecf96Smrg if (y < 0) 12445dfecf96Smrg y = 0; 12455dfecf96Smrg if (y > (max_y = (Position)(XtScreen(w)->height - height))) 12465dfecf96Smrg y = max_y; 12475dfecf96Smrg 12485dfecf96Smrg num_args = 0; 12495dfecf96Smrg XtSetArg(args[num_args], XtNx, x); num_args++; 12505dfecf96Smrg XtSetArg(args[num_args], XtNy, y); num_args++; 12515dfecf96Smrg XtSetValues(ispell.shell, args, num_args); 12525dfecf96Smrg } 12535dfecf96Smrg 12545dfecf96Smrg if (ispell.repeat) 12555dfecf96Smrg IspellSetRepeated(False); 12565dfecf96Smrg ispell.lock = ispell.repeat = ispell.checkit = False; 12575dfecf96Smrg ispell.stat = SEND; 12585dfecf96Smrg 12595dfecf96Smrg IspellSetSensitive(True); 12605dfecf96Smrg XtSetSensitive(ispell.undo, False); 12615dfecf96Smrg 12625dfecf96Smrg XtSetArg(args[0], XtNlabel, ""); 12635dfecf96Smrg XtSetValues(ispell.word, args, 1); 12645dfecf96Smrg 12655dfecf96Smrg XtSetArg(args[0], XtNstring, ""); 12665dfecf96Smrg XtSetValues(ispell.text, args, 1); 12675dfecf96Smrg 12685dfecf96Smrg XtSetArg(args[0], XtNlist, &strs); 12695dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, &n_strs); 12705dfecf96Smrg XtGetValues(ispell.list, args, 2); 12715dfecf96Smrg 12725dfecf96Smrg list = (char**)XtMalloc(sizeof(char**)); 12735dfecf96Smrg list[0] = XtNewString(""); 12745dfecf96Smrg XtSetArg(args[0], XtNlist, list); 12755dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, 1); 12765dfecf96Smrg XtSetValues(ispell.list, args, 2); 12775dfecf96Smrg 12785dfecf96Smrg if (n_strs > 1 || (XtName(ispell.list) != strs[0])) { 12795dfecf96Smrg while (--n_strs > -1) 12805dfecf96Smrg XtFree(strs[n_strs]); 12815dfecf96Smrg XtFree((char*)strs); 12825dfecf96Smrg } 12835dfecf96Smrg 12845dfecf96Smrg IspellSetStatus(ispell.working_label); 12855dfecf96Smrg 12865dfecf96Smrg if (!ispell.pid) 12875dfecf96Smrg (void)IspellStartProcess(); 12885dfecf96Smrg else { 12895dfecf96Smrg ispell.right = XawTextGetInsertionPoint(ispell.ascii); 12905dfecf96Smrg ispell.right = XawTextSourceScan(ispell.source, ispell.right, 12915dfecf96Smrg XawstEOL, XawsdLeft, 1, True); 12925dfecf96Smrg while (IspellSend() == 0) 12935dfecf96Smrg ; 12945dfecf96Smrg } 12955dfecf96Smrg 12965dfecf96Smrg XtPopup(ispell.shell, XtGrabExclusive); 12975dfecf96Smrg XtSetKeyboardFocus(ispell.shell, ispell.text); 12985dfecf96Smrg} 12995dfecf96Smrg 13005dfecf96Smrgstatic Bool 13015dfecf96SmrgIspellStartProcess(void) 13025dfecf96Smrg{ 13035dfecf96Smrg if (!ispell.pid) { 13045dfecf96Smrg int len; 1305f14f4646Smrg char format[32]; 1306f14f4646Smrg static char *command; 13075dfecf96Smrg 13085dfecf96Smrg ispell.source = XawTextGetSource(ispell.ascii); 13095dfecf96Smrg 1310f14f4646Smrg if (command) 1311f14f4646Smrg XtFree(command); 1312f14f4646Smrg 1313f14f4646Smrg strcpy(format, "%s -a"); 1314f14f4646Smrg len = strlen(ispell.cmd) + 4; 1315f14f4646Smrg if (ispell.dictionary && *ispell.dictionary) { 1316f14f4646Smrg len += strlen(ispell.dictionary) + 6; 1317f14f4646Smrg strcat(format, " -d '%s'"); 1318f14f4646Smrg if (ispell.wchars && *ispell.wchars) { 1319f14f4646Smrg len += strlen(ispell.wchars + 6); 1320f14f4646Smrg strcat(format, " -w '%s'"); 1321f14f4646Smrg } 1322f14f4646Smrg } 13235dfecf96Smrg command = XtMalloc(len); 1324f14f4646Smrg XmuSnprintf(command, len, format, 13255dfecf96Smrg ispell.cmd, ispell.dictionary, ispell.wchars); 13265dfecf96Smrg 13275dfecf96Smrg pipe(ispell.ifd); 13285dfecf96Smrg pipe(ispell.ofd); 13295dfecf96Smrg if ((ispell.pid = fork()) == 0) { 13305dfecf96Smrg close(0); 13315dfecf96Smrg close(1); 13325dfecf96Smrg dup2(ispell.ofd[0], 0); 13335dfecf96Smrg dup2(ispell.ifd[1], 1); 13345dfecf96Smrg close(ispell.ofd[0]); 13355dfecf96Smrg close(ispell.ofd[1]); 13365dfecf96Smrg close(ispell.ifd[0]); 13375dfecf96Smrg close(ispell.ifd[1]); 1338f14f4646Smrg if (!international) 1339f14f4646Smrg setlocale(LC_ALL, "ISO-8859-1"); 1340f14f4646Smrg execl("/bin/sh", "sh", "-c", command, NULL); 13415dfecf96Smrg exit(-127); 13425dfecf96Smrg } 13435dfecf96Smrg else if (ispell.pid < 0) { 13445dfecf96Smrg fprintf(stderr, "Cannot fork\n"); 13455dfecf96Smrg exit(1); 13465dfecf96Smrg } 13475dfecf96Smrg ispell.buf = XtMalloc(ispell.bufsiz = BUFSIZ); 13485dfecf96Smrg ispell.right = -1; 13495dfecf96Smrg ispell.id = XtAppAddInput(XtWidgetToApplicationContext(ispell.shell), 13505dfecf96Smrg ispell.ifd[0], (XtPointer)XtInputReadMask, 13515dfecf96Smrg IspellInputCallback, NULL); 13525dfecf96Smrg fcntl(ispell.ifd[0], F_SETFL, O_NONBLOCK); 13535dfecf96Smrg } 13545dfecf96Smrg else 13555dfecf96Smrg return (False); 13565dfecf96Smrg 13575dfecf96Smrg return (True); 13585dfecf96Smrg} 13595dfecf96Smrg 13605dfecf96Smrg/*ARGSUSED*/ 13615dfecf96Smrgstatic void 13625dfecf96SmrgPopdownIspell(Widget w, XtPointer client_data, XtPointer call_data) 13635dfecf96Smrg{ 13645dfecf96Smrg (void)IspellEndProcess((Bool)(long)client_data, True); 13655dfecf96Smrg XtPopdown(ispell.shell); 13665dfecf96Smrg *ispell.sentbuf = '\0'; 13675dfecf96Smrg} 13685dfecf96Smrg 1369f14f4646Smrgstatic Bool 1370f14f4646SmrgIspellCheckProcess(void) 1371f14f4646Smrg{ 1372f14f4646Smrg int status; 1373f14f4646Smrg 1374f14f4646Smrg if (ispell.pid) { 1375f14f4646Smrg waitpid(ispell.pid, &status, WNOHANG); 1376f14f4646Smrg if (WIFEXITED(status)) { 1377f14f4646Smrg ispell.pid = 0; 1378f14f4646Smrg } 1379f14f4646Smrg else 1380f14f4646Smrg return (True); 1381f14f4646Smrg } 1382f14f4646Smrg 1383f14f4646Smrg return (False); 1384f14f4646Smrg} 1385f14f4646Smrg 13865dfecf96Smrgstatic Bool 13875dfecf96SmrgIspellEndProcess(Bool killit, Bool killundo) 13885dfecf96Smrg{ 13895dfecf96Smrg ispell.source = NULL; 13905dfecf96Smrg 13915dfecf96Smrg if (ispell.pid) { 1392f14f4646Smrg IgnoreEntry *ientry; 1393f14f4646Smrg ReplaceEntry *rentry; 13945dfecf96Smrg 13955dfecf96Smrg /* insert added words in private dictionary */ 1396f14f4646Smrg for (ientry = (IgnoreEntry *)hash_iter_first(ignore_hash); 1397f14f4646Smrg ientry; 1398f14f4646Smrg ientry = (IgnoreEntry *)hash_iter_next(ignore_hash)) { 1399f14f4646Smrg if (ientry->add) { 1400f14f4646Smrg if (ientry->add == UNCAP) 1401f14f4646Smrg write(ispell.ofd[1], "&", 1); 14025dfecf96Smrg else 1403f14f4646Smrg write(ispell.ofd[1], "*", 1); 1404f14f4646Smrg write(ispell.ofd[1], ientry->word->value, ientry->word->length); 1405f14f4646Smrg write(ispell.ofd[1], "\n", 1); 14065dfecf96Smrg } 14075dfecf96Smrg } 14085dfecf96Smrg write(ispell.ofd[1], "#\n", 2); /* save dictionary */ 1409f14f4646Smrg hash_clr(ignore_hash); 14105dfecf96Smrg 14115dfecf96Smrg if (killit) { 14125dfecf96Smrg XtRemoveInput(ispell.id); 14135dfecf96Smrg 14145dfecf96Smrg close(ispell.ofd[0]); 14155dfecf96Smrg close(ispell.ofd[1]); 14165dfecf96Smrg close(ispell.ifd[0]); 14175dfecf96Smrg close(ispell.ifd[1]); 14185dfecf96Smrg 14195dfecf96Smrg /* if something goes wrong, we don't want to block here forever */ 14205dfecf96Smrg old_timeout = signal(SIGALRM, timeout_signal); 14215dfecf96Smrg alarm(10); 14225dfecf96Smrg waitpid(ispell.pid, NULL, 0); 14235dfecf96Smrg alarm(0); 14245dfecf96Smrg signal(SIGALRM, old_timeout); 14255dfecf96Smrg 14265dfecf96Smrg ispell.pid = 0; 14275dfecf96Smrg if (ispell.buf) 14285dfecf96Smrg XtFree(ispell.buf); 14295dfecf96Smrg ispell.buf = NULL; 14305dfecf96Smrg 1431f14f4646Smrg /* forget about replace matches */ 1432f14f4646Smrg for (rentry = (ReplaceEntry *)hash_iter_first(replace_hash); 1433f14f4646Smrg rentry; 1434f14f4646Smrg rentry = (ReplaceEntry *)hash_iter_next(replace_hash)) { 1435f14f4646Smrg XtFree(rentry->replace); 14365dfecf96Smrg } 1437f14f4646Smrg hash_clr(replace_hash); 14385dfecf96Smrg } 14395dfecf96Smrg 14405dfecf96Smrg if (killundo) 14415dfecf96Smrg IspellKillUndoBuffer(); 14425dfecf96Smrg } 14435dfecf96Smrg else 14445dfecf96Smrg return (False); 14455dfecf96Smrg 14465dfecf96Smrg return (True); 14475dfecf96Smrg} 14485dfecf96Smrg 14495dfecf96Smrgstatic void 14505dfecf96SmrgIspellKillUndoBuffer(void) 14515dfecf96Smrg{ 14525dfecf96Smrg ispell_undo *undo, *pundo; 14535dfecf96Smrg 14545dfecf96Smrg undo = pundo = ispell.undo_base; 14555dfecf96Smrg while (undo) { 14565dfecf96Smrg undo = undo->next; 14575dfecf96Smrg if (pundo->undo_str) 14585dfecf96Smrg XtFree(pundo->undo_str); 14595dfecf96Smrg XtFree((char*)pundo); 14605dfecf96Smrg pundo = undo; 14615dfecf96Smrg } 14625dfecf96Smrg ispell.undo_base = ispell.undo_head = NULL; 14635dfecf96Smrg ispell.undo_for = NULL; 14645dfecf96Smrg ispell.undo_depth = 0; 14655dfecf96Smrg XtSetSensitive(ispell.undo, False); 14665dfecf96Smrg} 14675dfecf96Smrg 14685dfecf96Smrg/*ARGSUSED*/ 14695dfecf96Smrgstatic void 14705dfecf96SmrgRevertIspell(Widget w, XtPointer client_data, XtPointer call_data) 14715dfecf96Smrg{ 14725dfecf96Smrg Arg args[1]; 14735dfecf96Smrg char *string, *repstr = NULL; 14745dfecf96Smrg 14755dfecf96Smrg XtSetArg(args[0], XtNlabel, &string); 14765dfecf96Smrg XtGetValues(ispell.word, args, 1); 14775dfecf96Smrg if ((repstr = strchr(string, ' ')) != NULL) { 14785dfecf96Smrg string = repstr = XtNewString(string); 14795dfecf96Smrg *strchr(repstr, ' ') = '\0'; 14805dfecf96Smrg } 14815dfecf96Smrg XtSetArg(args[0], XtNstring, string); 14825dfecf96Smrg XtSetValues(ispell.text, args, 1); 14835dfecf96Smrg if (repstr) 14845dfecf96Smrg XtFree(repstr); 14855dfecf96Smrg} 14865dfecf96Smrg 14875dfecf96Smrg/*ARGSUSED*/ 14885dfecf96Smrgstatic void 14895dfecf96SmrgSelectIspell(Widget w, XtPointer client_data, XtPointer call_data) 14905dfecf96Smrg{ 14915dfecf96Smrg XawListReturnStruct *info = (XawListReturnStruct *)call_data; 14925dfecf96Smrg Arg args[1]; 14935dfecf96Smrg 14945dfecf96Smrg XtSetArg(args[0], XtNstring, ispell.item = info->string); 14955dfecf96Smrg XtSetValues(ispell.text, args, 1); 14965dfecf96Smrg} 14975dfecf96Smrg 14985dfecf96Smrg/*ARGSUSED*/ 14995dfecf96Smrgvoid 15005dfecf96SmrgReplaceIspell(Widget w, XtPointer client_data, XtPointer call_data) 15015dfecf96Smrg{ 15025dfecf96Smrg XawTextPosition pos = XawTextGetInsertionPoint(ispell.ascii); 15035dfecf96Smrg XawTextBlock check, search, replace; 15045dfecf96Smrg Arg args[1]; 15055dfecf96Smrg char *text; 15065dfecf96Smrg 15075dfecf96Smrg if (!ispell.lock) 15085dfecf96Smrg return; 15095dfecf96Smrg 15105dfecf96Smrg XtSetArg(args[0], XtNlabel, &text); 15115dfecf96Smrg XtGetValues(ispell.word, args, 1); 15125dfecf96Smrg search.ptr = text; 15135dfecf96Smrg search.format = XawFmt8Bit; 15145dfecf96Smrg search.firstPos = 0; 15155dfecf96Smrg search.length = ispell.right - pos; 15165dfecf96Smrg 15175dfecf96Smrg XtSetArg(args[0], XtNstring, &text); 15185dfecf96Smrg XtGetValues(ispell.text, args, 1); 15195dfecf96Smrg replace.ptr = text; 15205dfecf96Smrg replace.format = XawFmt8Bit; 15215dfecf96Smrg replace.firstPos = 0; 15225dfecf96Smrg replace.length = strlen(text); 15235dfecf96Smrg 15245dfecf96Smrg if (strcmp(search.ptr, replace.ptr) != 0 && 15255dfecf96Smrg XawTextReplace(ispell.ascii, pos, pos + search.length, 15265dfecf96Smrg &replace) == XawEditDone) { 15275dfecf96Smrg ispell.right += replace.length - search.length; 15285dfecf96Smrg IspellCheckUndo(); 15295dfecf96Smrg ispell.undo_head->undo_str = NULL; 15305dfecf96Smrg ispell.undo_head->undo_pos = pos; 15315dfecf96Smrg ispell.undo_head->undo_count = 1; 15325dfecf96Smrg 15335dfecf96Smrg if (ispell.repeat) { 15345dfecf96Smrg ispell.undo_head->repeat = 2; /* To recognize later it was replaced */ 15355dfecf96Smrg ispell.undo_head->undo_count = ispell.right; 15365dfecf96Smrg ispell.undo_head->undo_str = XtNewString(search.ptr); 15375dfecf96Smrg } 15385dfecf96Smrg if (client_data && !ispell.repeat) { 15395dfecf96Smrg XawTextDisableRedisplay(ispell.ascii); 15405dfecf96Smrg pos = ispell.right; 15415dfecf96Smrg while ((pos = XawTextSourceSearch(ispell.source, pos, XawsdRight, &search)) 15425dfecf96Smrg != XawTextSearchError) { 15435dfecf96Smrg Bool do_replace = True; 15445dfecf96Smrg char mb[sizeof(wchar_t)]; 15455dfecf96Smrg 15465dfecf96Smrg if (XawTextSourceRead(ispell.source, pos - 1, &check, 1) > 0) { 1547f14f4646Smrg if (international) 1548f14f4646Smrg wctomb(mb, *(wchar_t*)check.ptr); 1549f14f4646Smrg else 1550f14f4646Smrg mb[0] = check.ptr[0]; 15515dfecf96Smrg do_replace = !isalpha(*mb) && *mb && !strchr(ispell.wchars, *mb); 15525dfecf96Smrg } 15535dfecf96Smrg if (do_replace && 15545dfecf96Smrg XawTextSourceRead(ispell.source, pos + search.length, &check, 1) > 0) { 1555f14f4646Smrg if (international) 1556f14f4646Smrg wctomb(mb, *(wchar_t*)check.ptr); 1557f14f4646Smrg else 1558f14f4646Smrg mb[0] = check.ptr[0]; 15595dfecf96Smrg do_replace = !isalpha(*mb) && *mb && !strchr(ispell.wchars, *mb); 15605dfecf96Smrg } 15615dfecf96Smrg if (do_replace) { 15625dfecf96Smrg XawTextReplace(ispell.ascii, pos, pos + search.length, &replace); 15635dfecf96Smrg ++ispell.undo_head->undo_count; 15645dfecf96Smrg } 15655dfecf96Smrg pos += search.length; 15665dfecf96Smrg } 15675dfecf96Smrg XawTextEnableRedisplay(ispell.ascii); 15685dfecf96Smrg } 15695dfecf96Smrg (void)IspellReplacedWord(search.ptr, replace.ptr); 15705dfecf96Smrg 15715dfecf96Smrg strncpy(&ispell.sentbuf[1], replace.ptr, sizeof(ispell.sentbuf) - 2); 15725dfecf96Smrg ispell.sentbuf[sizeof(ispell.sentbuf) - 1] = '\0'; 15735dfecf96Smrg } 15745dfecf96Smrg else 15755dfecf96Smrg Feep(); 15765dfecf96Smrg 15775dfecf96Smrg if (ispell.repeat) 15785dfecf96Smrg ispell.right = ispell.left = XawTextGetInsertionPoint(ispell.ascii); 15795dfecf96Smrg else if (!ispell.terse_mode || !ispell.item || 15805dfecf96Smrg strcmp(ispell.item, replace.ptr)) 15815dfecf96Smrg ispell.right = ispell.left; /* check it again! */ 15825dfecf96Smrg 15835dfecf96Smrg ispell.lock = ispell.checkit = False; 15845dfecf96Smrg 15855dfecf96Smrg ispell.stat = SEND; 15865dfecf96Smrg IspellSetStatus(ispell.working_label); 15875dfecf96Smrg while (IspellSend() == 0) 15885dfecf96Smrg ; 15895dfecf96Smrg} 15905dfecf96Smrg 15915dfecf96Smrg/*ARGSUSED*/ 15925dfecf96Smrgvoid 15935dfecf96SmrgIgnoreIspell(Widget w, XtPointer client_data, XtPointer call_data) 15945dfecf96Smrg{ 15955dfecf96Smrg Arg args[1]; 15965dfecf96Smrg char *text; 15975dfecf96Smrg 15985dfecf96Smrg if (!ispell.lock) 15995dfecf96Smrg return; 16005dfecf96Smrg 16015dfecf96Smrg XtSetArg(args[0], XtNlabel, &text); 16025dfecf96Smrg XtGetValues(ispell.word, args, 1); 16035dfecf96Smrg 16045dfecf96Smrg IspellCheckUndo(); 16055dfecf96Smrg 16065dfecf96Smrg if ((ispell.undo_head->repeat = ispell.repeat) != False) { 16075dfecf96Smrg ispell.undo_head->undo_count = ispell.right; 16085dfecf96Smrg ispell.undo_head->undo_str = XtNewString(text); 16095dfecf96Smrg } 16105dfecf96Smrg else 16115dfecf96Smrg ispell.undo_head->undo_count = 0; 16125dfecf96Smrg 16135dfecf96Smrg ispell.undo_head->undo_pos = XawTextGetInsertionPoint(ispell.ascii); 16145dfecf96Smrg 16155dfecf96Smrg if (!ispell.repeat) { 16165dfecf96Smrg if (client_data) { 16175dfecf96Smrg IspellIgnoredWord(text, ADD, 0); 16185dfecf96Smrg ispell.undo_head->undo_str = XtNewString(text); 16195dfecf96Smrg } 16205dfecf96Smrg else 16215dfecf96Smrg ispell.undo_head->undo_str = NULL; 16225dfecf96Smrg } 16235dfecf96Smrg 16245dfecf96Smrg ispell.lock = ispell.checkit = False; 16255dfecf96Smrg 16265dfecf96Smrg ispell.stat = SEND; 16275dfecf96Smrg IspellSetStatus(ispell.working_label); 16285dfecf96Smrg while (IspellSend() == 0) 16295dfecf96Smrg ; 16305dfecf96Smrg} 16315dfecf96Smrg 16325dfecf96Smrg/*ARGSUSED*/ 16335dfecf96Smrgvoid 16345dfecf96SmrgAddIspell(Widget w, XtPointer client_data, XtPointer call_data) 16355dfecf96Smrg{ 16365dfecf96Smrg Arg args[1]; 16375dfecf96Smrg char *text; 16385dfecf96Smrg int cmd = (long)client_data; 16395dfecf96Smrg 16405dfecf96Smrg if (!ispell.lock || ispell.repeat) 16415dfecf96Smrg return; 16425dfecf96Smrg 16435dfecf96Smrg XtSetArg(args[0], XtNlabel, &text); 16445dfecf96Smrg XtGetValues(ispell.word, args, 1); 16455dfecf96Smrg 16465dfecf96Smrg IspellCheckUndo(); 16475dfecf96Smrg ispell.undo_head->undo_str = XtNewString(text); 16485dfecf96Smrg ispell.undo_head->undo_pos = XawTextGetInsertionPoint(ispell.ascii); 16495dfecf96Smrg ispell.undo_head->undo_count = -cmd; 16505dfecf96Smrg 16515dfecf96Smrg (void)IspellIgnoredWord(text, ADD, cmd); 16525dfecf96Smrg 16535dfecf96Smrg ispell.lock = ispell.checkit = False; 16545dfecf96Smrg ispell.stat = SEND; 16555dfecf96Smrg IspellSetStatus(ispell.working_label); 16565dfecf96Smrg while (IspellSend() == 0) 16575dfecf96Smrg ; 16585dfecf96Smrg} 16595dfecf96Smrg 16605dfecf96Smrg/*ARGSUSED*/ 16615dfecf96Smrgstatic void 16625dfecf96SmrgUndoIspell(Widget w, XtPointer client_data, XtPointer call_data) 16635dfecf96Smrg{ 16645dfecf96Smrg Bool enable_redisplay = False; 16655dfecf96Smrg ispell_undo *undo = ispell.undo_head; 16665dfecf96Smrg 16675dfecf96Smrg if ((!ispell.lock && ispell.stat) || !undo) 16685dfecf96Smrg return; 16695dfecf96Smrg 16705dfecf96Smrg if (ispell.undo_for && strcmp(ispell.undo_for, ispell.dictionary)) { 16715dfecf96Smrg XeditPrintf("Undo: Dictionary changed. Undo information was lost.\n"); 16725dfecf96Smrg IspellKillUndoBuffer(); 16735dfecf96Smrg Feep(); 16745dfecf96Smrg return; 16755dfecf96Smrg } 16765dfecf96Smrg 16775dfecf96Smrg if (undo->terse != ispell.terse_mode) 16785dfecf96Smrg IspellSetTerseMode(undo->terse); 16795dfecf96Smrg 16805dfecf96Smrg if (undo->format != ispell.format_info->value) { 16815dfecf96Smrg struct _ispell_format *fmt = &ispell_format[undo->format]; 16825dfecf96Smrg ChangeFormatIspell(fmt->sme, (XtPointer)fmt, NULL); 16835dfecf96Smrg } 16845dfecf96Smrg 16855dfecf96Smrg if (undo->undo_count > 0 && !undo->repeat) { 16865dfecf96Smrg XawTextPosition tmp; 16875dfecf96Smrg 16885dfecf96Smrg enable_redisplay = undo->undo_count > 1; 16895dfecf96Smrg if (enable_redisplay) 16905dfecf96Smrg XawTextDisableRedisplay(ispell.ascii); 16915dfecf96Smrg while (undo->undo_count--) 16925dfecf96Smrg if (!_XawTextSrcUndo((TextSrcObject)ispell.source, &tmp)) { 16935dfecf96Smrg Feep(); 16945dfecf96Smrg break; 16955dfecf96Smrg } 16965dfecf96Smrg } 16975dfecf96Smrg else if (undo->undo_count < 0) { 16985dfecf96Smrg if (undo->undo_str) 16995dfecf96Smrg (void)IspellIgnoredWord(undo->undo_str, REMOVE, -undo->undo_count); 17005dfecf96Smrg } 17015dfecf96Smrg else if (undo->undo_str) { 17025dfecf96Smrg if (!undo->repeat) 17035dfecf96Smrg IspellIgnoredWord(undo->undo_str, REMOVE, 0); 17045dfecf96Smrg } 17055dfecf96Smrg 17065dfecf96Smrg XawTextSetInsertionPoint(ispell.ascii, 17075dfecf96Smrg ispell.right = ispell.left = undo->undo_pos); 17085dfecf96Smrg if (enable_redisplay) 17095dfecf96Smrg XawTextEnableRedisplay(ispell.ascii); 17105dfecf96Smrg 17115dfecf96Smrg /* need to do it because may be two misspelled words together */ 17125dfecf96Smrg if (undo->repeat) { 17135dfecf96Smrg char **list, **old_list; 17145dfecf96Smrg int old_len; 17155dfecf96Smrg Arg args[2]; 17165dfecf96Smrg 17175dfecf96Smrg if (undo->repeat > 1) { 17185dfecf96Smrg XawTextDisableRedisplay(ispell.ascii); 17195dfecf96Smrg if (!_XawTextSrcUndo((TextSrcObject)ispell.source, &ispell.right)) 17205dfecf96Smrg Feep(); 17215dfecf96Smrg XawTextEnableRedisplay(ispell.ascii); 17225dfecf96Smrg } 17235dfecf96Smrg else 17245dfecf96Smrg ispell.right = (XawTextPosition)undo->undo_count; 17255dfecf96Smrg IspellSetRepeated(ispell.repeat = True); 17265dfecf96Smrg XtSetArg(args[0], XtNlabel, undo->undo_str); 17275dfecf96Smrg XtSetValues(ispell.word, args, 1); 17285dfecf96Smrg XmuSnprintf(ispell.sentbuf, sizeof(ispell.sentbuf), "^%s", 17295dfecf96Smrg strrchr(undo->undo_str, ' ') + 1); 17305dfecf96Smrg strcpy(ispell.sendbuf, ispell.sentbuf); 17315dfecf96Smrg XtSetArg(args[0], XtNstring, &ispell.sentbuf[1]); 17325dfecf96Smrg XtSetValues(ispell.text, args, 1); 17335dfecf96Smrg 17345dfecf96Smrg XtSetArg(args[0], XtNlist, &old_list); 17355dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, &old_len); 17365dfecf96Smrg XtGetValues(ispell.list, args, 2); 17375dfecf96Smrg 17385dfecf96Smrg list = (char **)XtMalloc(sizeof(char*)); 17395dfecf96Smrg list[0] = XtNewString(&ispell.sentbuf[1]); 17405dfecf96Smrg XtSetArg(args[0], XtNlist, list); 17415dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, 1); 17425dfecf96Smrg XtSetValues(ispell.list, args, 2); 17435dfecf96Smrg XtSetSensitive(ispell.list, True); 17445dfecf96Smrg XawListHighlight(ispell.list, 0); 17455dfecf96Smrg 17465dfecf96Smrg if (old_len > 1 || (XtName(ispell.list) != old_list[0])) { 17475dfecf96Smrg while (--old_len > -1) 17485dfecf96Smrg XtFree(old_list[old_len]); 17495dfecf96Smrg XtFree((char*)old_list); 17505dfecf96Smrg } 17515dfecf96Smrg 17525dfecf96Smrg IspellSetSelection(ispell.left, ispell.right); 17535dfecf96Smrg IspellSetStatus(ispell.repeat_label); 17545dfecf96Smrg ispell.lock = True; 17555dfecf96Smrg ispell.checkit = False; 17565dfecf96Smrg } 17575dfecf96Smrg else if (ispell.repeat) { 17585dfecf96Smrg *ispell.sentbuf = '\0'; 17595dfecf96Smrg IspellSetRepeated(ispell.repeat = False); 17605dfecf96Smrg } 17615dfecf96Smrg 17625dfecf96Smrg if (undo->prev) 17635dfecf96Smrg undo->prev->next = NULL; 17645dfecf96Smrg ispell.undo_head = undo->prev; 17655dfecf96Smrg if (undo == ispell.undo_base) { 17665dfecf96Smrg ispell.undo_base = NULL; 17675dfecf96Smrg ispell.undo_for = NULL; 17685dfecf96Smrg XtSetSensitive(ispell.undo, False); 17695dfecf96Smrg } 17705dfecf96Smrg if (undo->undo_str) 17715dfecf96Smrg XtFree(undo->undo_str); 17725dfecf96Smrg XtFree((char*)undo); 17735dfecf96Smrg --ispell.undo_depth; 17745dfecf96Smrg 17755dfecf96Smrg if (!ispell.stat || ispell.checkit) 17765dfecf96Smrg IspellSetSensitive(True); 17775dfecf96Smrg 17785dfecf96Smrg if (!ispell.repeat) { 17795dfecf96Smrg ispell.lock = ispell.checkit = False; 17805dfecf96Smrg ispell.stat = SEND; 17815dfecf96Smrg IspellSetStatus(ispell.working_label); 17825dfecf96Smrg while (IspellSend() == 0) 17835dfecf96Smrg ; 17845dfecf96Smrg } 17855dfecf96Smrg} 17865dfecf96Smrg 17875dfecf96Smrg/*ARGSUSED*/ 17885dfecf96Smrgstatic void 17895dfecf96SmrgCheckIspell(Widget w, XtPointer client_data, XtPointer call_data) 17905dfecf96Smrg{ 17915dfecf96Smrg Arg args[1]; 17925dfecf96Smrg char *text, *str, string[1024]; 17935dfecf96Smrg int i, len; 17945dfecf96Smrg 17955dfecf96Smrg if (!ispell.lock) 17965dfecf96Smrg return; 17975dfecf96Smrg 17985dfecf96Smrg XtSetArg(args[0], XtNstring, &text); 17995dfecf96Smrg XtGetValues(ispell.text, args, 1); 18005dfecf96Smrg 18015dfecf96Smrg /* Check only a word at a time */ 18025dfecf96Smrg len = 0; 18035dfecf96Smrg str = text; 18045dfecf96Smrg while (*str) { 18055dfecf96Smrg if (isalpha(*str) || strchr(ispell.wchars, *str)) 18065dfecf96Smrg break; 18075dfecf96Smrg ++str; 18085dfecf96Smrg ++len; 18095dfecf96Smrg } 18105dfecf96Smrg i = 0; 18115dfecf96Smrg while (*str) { 18125dfecf96Smrg if (isalpha(*str) || strchr(ispell.wchars, *str)) 18135dfecf96Smrg string[i++] = *str++; 18145dfecf96Smrg else 18155dfecf96Smrg break; 18165dfecf96Smrg } 18175dfecf96Smrg string[i] = '\0'; 18185dfecf96Smrg 18195dfecf96Smrg if (strcmp(text, string)) { 18205dfecf96Smrg XawTextPosition pos = XawTextGetInsertionPoint(ispell.text) - len; 18215dfecf96Smrg 18225dfecf96Smrg XtSetArg(args[0], XtNstring, string); 18235dfecf96Smrg XtSetValues(ispell.text, args, 1); 18245dfecf96Smrg XawTextSetInsertionPoint(ispell.text, pos); 18255dfecf96Smrg Feep(); 18265dfecf96Smrg } 18275dfecf96Smrg 18285dfecf96Smrg if (i == 0) { 18295dfecf96Smrg Feep(); 18305dfecf96Smrg return; 18315dfecf96Smrg } 18325dfecf96Smrg 18335dfecf96Smrg len = XmuSnprintf(ispell.sendbuf, sizeof(ispell.sendbuf), "^%s\n", string); 18345dfecf96Smrg 18355dfecf96Smrg ispell.sendbuf[sizeof(ispell.sendbuf) - 1] = '\n'; 18365dfecf96Smrg 18375dfecf96Smrg write(ispell.ofd[1], ispell.sendbuf, len); 18385dfecf96Smrg 18395dfecf96Smrg ispell.lock = False; 18405dfecf96Smrg ispell.checkit = True; 18415dfecf96Smrg ispell.stat = RECEIVE; 18425dfecf96Smrg} 18435dfecf96Smrg 18445dfecf96Smrg/*ARGSUSED*/ 18455dfecf96Smrgstatic void 18465dfecf96SmrgLookIspell(Widget w, XtPointer client_data, XtPointer call_data) 18475dfecf96Smrg{ 18485dfecf96Smrg int len, old_len; 18495dfecf96Smrg FILE *fd; 18505dfecf96Smrg Arg args[2]; 18515dfecf96Smrg char *text, *str, **list, **old_list, command[1024], buffer[1024]; 18525dfecf96Smrg Bool sensitive = True; 18535dfecf96Smrg 18545dfecf96Smrg if (!ispell.lock) 18555dfecf96Smrg return; 18565dfecf96Smrg 18575dfecf96Smrg XtSetArg(args[0], XtNstring, &text); 18585dfecf96Smrg XtGetValues(ispell.text, args, 1); 18595dfecf96Smrg 18605dfecf96Smrg if (!*text) { 18615dfecf96Smrg Feep(); 18625dfecf96Smrg return; 18635dfecf96Smrg } 18645dfecf96Smrg 18655dfecf96Smrg if (strlen(ispell.look_cmd) + strlen(text) + strlen(ispell.words_file) + 8 18665dfecf96Smrg > sizeof(command) - 1) { 18675dfecf96Smrg fprintf(stderr, "Command line too large\n"); 18685dfecf96Smrg return; 18695dfecf96Smrg } 18705dfecf96Smrg 18715dfecf96Smrg XmuSnprintf(command, sizeof(command), "%s '^%s.*$' %s", 18725dfecf96Smrg ispell.look_cmd, text, ispell.words_file); 18735dfecf96Smrg 18745dfecf96Smrg if ((fd = popen(command, "r")) == NULL) { 18755dfecf96Smrg fprintf(stderr, "Cannot popen '%s'\n", ispell.look_cmd); 18765dfecf96Smrg return; 18775dfecf96Smrg } 18785dfecf96Smrg 18795dfecf96Smrg list = NULL; 18805dfecf96Smrg len = 0; 18815dfecf96Smrg 18825dfecf96Smrg#define MAX_LOOK_RESULTS 256 18835dfecf96Smrg while (fgets(buffer, sizeof(buffer), fd) != NULL) { 18845dfecf96Smrg if ((str = strchr(buffer, '\n')) == NULL) { 18855dfecf96Smrg fprintf(stderr, "String is too large\n"); 18865dfecf96Smrg break; 18875dfecf96Smrg } 18885dfecf96Smrg *str = '\0'; 18895dfecf96Smrg if ((len % 16) == 0) 18905dfecf96Smrg list = (char**)XtRealloc((char*)list, sizeof(char*) * (len + 16)); 18915dfecf96Smrg list[len] = XtNewString(buffer); 18925dfecf96Smrg if (++len >= MAX_LOOK_RESULTS) { 18935dfecf96Smrg Feep(); 18945dfecf96Smrg break; 18955dfecf96Smrg } 18965dfecf96Smrg } 18975dfecf96Smrg#undef MAX_LOOK_RESULTS 18985dfecf96Smrg 18995dfecf96Smrg XtSetArg(args[0], XtNlist, &old_list); 19005dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, &old_len); 19015dfecf96Smrg XtGetValues(ispell.list, args, 2); 19025dfecf96Smrg 19035dfecf96Smrg if (len == 0) { 19045dfecf96Smrg list = (char**)XtMalloc(sizeof(char*)); 19055dfecf96Smrg list[0] = XtNewString(""); 19065dfecf96Smrg len = 1; 19075dfecf96Smrg sensitive = False; 19085dfecf96Smrg } 19095dfecf96Smrg 19105dfecf96Smrg XtSetArg(args[0], XtNlist, list); 19115dfecf96Smrg XtSetArg(args[1], XtNnumberStrings, len); 19125dfecf96Smrg XtSetValues(ispell.list, args, 2); 19135dfecf96Smrg 19145dfecf96Smrg XtSetSensitive(ispell.list, sensitive); 19155dfecf96Smrg IspellSetStatus(sensitive ? ispell.look_label : ispell.none_label); 19165dfecf96Smrg 19175dfecf96Smrg if (old_len > 1 || (XtName(ispell.list) != old_list[0])) { 19185dfecf96Smrg while (--old_len > -1) 19195dfecf96Smrg XtFree(old_list[old_len]); 19205dfecf96Smrg XtFree((char*)old_list); 19215dfecf96Smrg } 19225dfecf96Smrg 19235dfecf96Smrg pclose(fd); 19245dfecf96Smrg} 19255dfecf96Smrg 19265dfecf96Smrg/*ARGSUSED*/ 19275dfecf96Smrgstatic void 19285dfecf96SmrgToggleTerseIspell(Widget w, XtPointer client_data, XtPointer call_data) 19295dfecf96Smrg{ 19305dfecf96Smrg if (!ispell.lock) 19315dfecf96Smrg return; 19325dfecf96Smrg 19335dfecf96Smrg ispell.terse_mode = !ispell.terse_mode; 19345dfecf96Smrg write(ispell.ofd[1], ispell.terse_mode ? "!\n" : "%\n", 2); 19355dfecf96Smrg} 19365dfecf96Smrg 19375dfecf96Smrg/*ARGSUSED*/ 19385dfecf96Smrgstatic void 19395dfecf96SmrgChangeDictionaryIspell(Widget w, XtPointer client_data, XtPointer call_data) 19405dfecf96Smrg{ 19415dfecf96Smrg ispell_dict *tmp, *dic = (ispell_dict*)client_data; 19425dfecf96Smrg XawTextPosition pos = XawTextGetInsertionPoint(ispell.ascii); 19435dfecf96Smrg XawTextPosition right = ispell.right; 19445dfecf96Smrg Arg args[1]; 19455dfecf96Smrg 19465dfecf96Smrg if (strcmp(XtName(dic->sme), ispell.dictionary) == 0) 19475dfecf96Smrg return; 19485dfecf96Smrg 19495dfecf96Smrg if (!ispell.lock) { 1950f14f4646Smrg if (IspellCheckProcess()) { 1951f14f4646Smrg Feep(); 1952f14f4646Smrg return; 1953f14f4646Smrg } 19545dfecf96Smrg } 19555dfecf96Smrg 19565dfecf96Smrg for (tmp = ispell.dict_info; tmp; tmp = tmp->next) 19575dfecf96Smrg if (strcmp(XtName(tmp->sme), ispell.dictionary) == 0) { 19585dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, None); 19595dfecf96Smrg XtSetValues(tmp->sme, args, 1); 19605dfecf96Smrg } 19615dfecf96Smrg 19625dfecf96Smrg if (ispell.undo_base && !ispell.undo_for) 19635dfecf96Smrg ispell.undo_for = ispell.dictionary; 19645dfecf96Smrg 19655dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, flist.pixmap); 19665dfecf96Smrg XtSetValues(dic->sme, args, 1); 19675dfecf96Smrg ispell.dictionary = XtName(dic->sme); 19685dfecf96Smrg ispell.wchars = dic->wchars; 19695dfecf96Smrg XtSetArg(args[0], XtNlabel, XtName(dic->sme)); 19705dfecf96Smrg XtSetValues(ispell.dict, args, 1); 19715dfecf96Smrg 19725dfecf96Smrg IspellSetStatus(ispell.working_label); 19735dfecf96Smrg 19745dfecf96Smrg (void)IspellEndProcess(True, False); 19755dfecf96Smrg ispell.lock = ispell.checkit = False; 19765dfecf96Smrg (void)IspellStartProcess(); 19775dfecf96Smrg 19785dfecf96Smrg ispell.stat = RECEIVE; 19795dfecf96Smrg 19805dfecf96Smrg /* restart at the same selected word */ 19815dfecf96Smrg if (ispell.repeat == False) 19825dfecf96Smrg ispell.left = ispell.right = pos; 19835dfecf96Smrg else 19845dfecf96Smrg ispell.right = right; 19855dfecf96Smrg} 19865dfecf96Smrg 19875dfecf96Smrg/*ARGSUSED*/ 19885dfecf96Smrgstatic void 19895dfecf96SmrgChangeFormatIspell(Widget w, XtPointer client_data, XtPointer call_data) 19905dfecf96Smrg{ 19915dfecf96Smrg struct _ispell_format *fmt = (struct _ispell_format*)client_data; 19925dfecf96Smrg Arg args[1]; 19935dfecf96Smrg 19945dfecf96Smrg if (strcmp(fmt->name, ispell.formatting) == 0) 19955dfecf96Smrg return; 19965dfecf96Smrg 19975dfecf96Smrg if (!ispell.lock) { 19985dfecf96Smrg Feep(); 19995dfecf96Smrg return; 20005dfecf96Smrg } 20015dfecf96Smrg 20025dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, None); 20035dfecf96Smrg XtSetValues(ispell.format_info->sme, args, 1); 20045dfecf96Smrg 20055dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, flist.pixmap); 20065dfecf96Smrg XtSetValues(fmt->sme, args, 1); 20075dfecf96Smrg ispell.formatting = fmt->name; 20085dfecf96Smrg ispell.format_info = fmt; 20095dfecf96Smrg XtSetArg(args[0], XtNlabel, fmt->name); 20105dfecf96Smrg XtSetValues(ispell.format, args, 1); 20115dfecf96Smrg} 20125dfecf96Smrg 20135dfecf96Smrgstatic Bool 20145dfecf96SmrgInitIspell(void) 20155dfecf96Smrg{ 20165dfecf96Smrg Atom delete_window; 20175dfecf96Smrg char *str, *list; 20185dfecf96Smrg XtResource dict_res; 2019f14f4646Smrg ispell_dict *dict, *prev_dict; 20205dfecf96Smrg int i; 20215dfecf96Smrg static XtResource text_res[] = { 20225dfecf96Smrg {"skipLines", "Skip", XtRString, sizeof(char*), 20235dfecf96Smrg XtOffsetOf(struct _ispell, skip), XtRString, "#"}, 20245dfecf96Smrg }; 20255dfecf96Smrg 20265dfecf96Smrg if (ispell.shell) 20275dfecf96Smrg return (False); 20285dfecf96Smrg 2029f14f4646Smrg replace_hash = hash_new(RSTRTBLSZ, NULL); 2030f14f4646Smrg ignore_hash = hash_new(ISTRTBLSZ, NULL); 2031f14f4646Smrg 20325dfecf96Smrg ispell.shell = XtCreatePopupShell("ispell", transientShellWidgetClass, 20335dfecf96Smrg topwindow, NULL, 0); 20345dfecf96Smrg 20355dfecf96Smrg XtGetApplicationResources(ispell.shell, (XtPointer)&ispell, resources, 20365dfecf96Smrg XtNumber(resources), NULL, 0); 20375dfecf96Smrg 20385dfecf96Smrg ispell.form = XtCreateManagedWidget("form", formWidgetClass, 20395dfecf96Smrg ispell.shell, NULL, 0); 20405dfecf96Smrg ispell.mispelled = XtCreateManagedWidget("mispelled", labelWidgetClass, 20415dfecf96Smrg ispell.form, NULL, 0); 20425dfecf96Smrg ispell.repeated = XtCreateWidget("repeated", labelWidgetClass, 20435dfecf96Smrg ispell.form, NULL, 0); 20445dfecf96Smrg ispell.word = XtCreateManagedWidget("word", commandWidgetClass, 20455dfecf96Smrg ispell.form, NULL, 0); 20465dfecf96Smrg XtAddCallback(ispell.word, XtNcallback, RevertIspell, NULL); 20475dfecf96Smrg ispell.replacement = XtCreateManagedWidget("replacement", labelWidgetClass, 20485dfecf96Smrg ispell.form, NULL, 0); 20495dfecf96Smrg ispell.text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, 20505dfecf96Smrg ispell.form, 20515dfecf96Smrg XtNeditType, XawtextEdit, 20525dfecf96Smrg NULL); 20535dfecf96Smrg ispell.suggestions = XtCreateManagedWidget("suggestions", labelWidgetClass, 20545dfecf96Smrg ispell.form, NULL, 0); 20555dfecf96Smrg ispell.viewport = XtCreateManagedWidget("viewport", viewportWidgetClass, 20565dfecf96Smrg ispell.form, NULL, 0); 20575dfecf96Smrg ispell.list = XtCreateManagedWidget("list", listWidgetClass, 20585dfecf96Smrg ispell.viewport, NULL, 0); 20595dfecf96Smrg XtAddCallback(ispell.list, XtNcallback, SelectIspell, NULL); 20605dfecf96Smrg ispell.commands = XtCreateManagedWidget("commands", formWidgetClass, 20615dfecf96Smrg ispell.form, NULL, 0); 20625dfecf96Smrg ispell.check = XtCreateManagedWidget("check", commandWidgetClass, 20635dfecf96Smrg ispell.commands, NULL, 0); 20645dfecf96Smrg XtAddCallback(ispell.check, XtNcallback, CheckIspell, NULL); 20655dfecf96Smrg ispell.look = XtCreateManagedWidget("look", commandWidgetClass, 20665dfecf96Smrg ispell.commands, NULL, 0); 20675dfecf96Smrg XtAddCallback(ispell.look, XtNcallback, LookIspell, NULL); 20685dfecf96Smrg ispell.undo = XtCreateManagedWidget("undo", commandWidgetClass, 20695dfecf96Smrg ispell.commands, NULL, 0); 20705dfecf96Smrg XtAddCallback(ispell.undo, XtNcallback, UndoIspell, NULL); 20715dfecf96Smrg ispell.replace = XtCreateManagedWidget("replace", commandWidgetClass, 20725dfecf96Smrg ispell.commands, NULL, 0); 20735dfecf96Smrg XtAddCallback(ispell.replace, XtNcallback, ReplaceIspell, (XtPointer)False); 20745dfecf96Smrg ispell.replaceAll = XtCreateManagedWidget("replaceAll", commandWidgetClass, 20755dfecf96Smrg ispell.commands, NULL, 0); 20765dfecf96Smrg XtAddCallback(ispell.replaceAll, XtNcallback, ReplaceIspell, (XtPointer)True); 20775dfecf96Smrg ispell.ignore = XtCreateManagedWidget("ignore", commandWidgetClass, 20785dfecf96Smrg ispell.commands, NULL, 0); 20795dfecf96Smrg XtAddCallback(ispell.ignore, XtNcallback, IgnoreIspell, (XtPointer)False); 20805dfecf96Smrg ispell.ignoreAll = XtCreateManagedWidget("ignoreAll", commandWidgetClass, 20815dfecf96Smrg ispell.commands, NULL, 0); 20825dfecf96Smrg XtAddCallback(ispell.ignoreAll, XtNcallback, IgnoreIspell, (XtPointer)True); 20835dfecf96Smrg ispell.add = XtCreateManagedWidget("add", commandWidgetClass, 20845dfecf96Smrg ispell.commands, NULL, 0); 20855dfecf96Smrg XtAddCallback(ispell.add, XtNcallback, AddIspell, (XtPointer)ASIS); 20865dfecf96Smrg ispell.addUncap = XtCreateManagedWidget("addUncap", commandWidgetClass, 20875dfecf96Smrg ispell.commands, NULL, 0); 20885dfecf96Smrg XtAddCallback(ispell.addUncap, XtNcallback, AddIspell, (XtPointer)UNCAP); 20895dfecf96Smrg ispell.suspend = XtCreateManagedWidget("suspend", commandWidgetClass, 20905dfecf96Smrg ispell.commands, NULL, 0); 20915dfecf96Smrg XtAddCallback(ispell.suspend, XtNcallback, PopdownIspell, (XtPointer)False); 20925dfecf96Smrg ispell.cancel = XtCreateManagedWidget("cancel", commandWidgetClass, 20935dfecf96Smrg ispell.commands, NULL, 0); 20945dfecf96Smrg XtAddCallback(ispell.cancel, XtNcallback, PopdownIspell, (XtPointer)True); 20955dfecf96Smrg ispell.terse = XtVaCreateManagedWidget("terse", toggleWidgetClass, 20965dfecf96Smrg ispell.commands, 20975dfecf96Smrg XtNstate, ispell.terse_mode, 20985dfecf96Smrg NULL); 20995dfecf96Smrg XtAddCallback(ispell.terse, XtNcallback, ToggleTerseIspell, NULL); 21005dfecf96Smrg ispell.status = XtCreateManagedWidget("status", labelWidgetClass, 21015dfecf96Smrg ispell.form, NULL, 0); 21025dfecf96Smrg ispell.options = XtCreateManagedWidget("options", formWidgetClass, 21035dfecf96Smrg ispell.form, NULL, 0); 21045dfecf96Smrg ispell.dict = XtVaCreateManagedWidget("dict", menuButtonWidgetClass, 21055dfecf96Smrg ispell.options, 21065dfecf96Smrg XtNmenuName, "dictionaries", 21075dfecf96Smrg NULL); 21085dfecf96Smrg ispell.dictMenu = XtCreatePopupShell("dictionaries", simpleMenuWidgetClass, 21095dfecf96Smrg ispell.options, NULL, 0); 21105dfecf96Smrg XtRealizeWidget(ispell.dictMenu); 21115dfecf96Smrg 21125dfecf96Smrg ispell.format = XtVaCreateManagedWidget("format", menuButtonWidgetClass, 21135dfecf96Smrg ispell.options, 21145dfecf96Smrg XtNmenuName, "formats", 21155dfecf96Smrg NULL); 21165dfecf96Smrg ispell.formatMenu = XtCreatePopupShell("formats", simpleMenuWidgetClass, 21175dfecf96Smrg ispell.options, NULL, 0); 21185dfecf96Smrg XtRealizeWidget(ispell.formatMenu); 21195dfecf96Smrg 21205dfecf96Smrg XtRealizeWidget(ispell.shell); 21215dfecf96Smrg 21225dfecf96Smrg for (i = 0; i < sizeof(ispell_format) / sizeof(ispell_format[0]); i++) { 21235dfecf96Smrg struct _ispell_format *fmt = &ispell_format[i]; 21245dfecf96Smrg 21255dfecf96Smrg fmt->sme = XtCreateManagedWidget(fmt->name, smeBSBObjectClass, 21265dfecf96Smrg ispell.formatMenu, NULL, 0); 21275dfecf96Smrg XtAddCallback(fmt->sme, XtNcallback, ChangeFormatIspell, (XtPointer)fmt); 21285dfecf96Smrg 21295dfecf96Smrg if (strcmp(fmt->name, ispell.formatting) == 0) { 21305dfecf96Smrg Arg args[1]; 21315dfecf96Smrg 21325dfecf96Smrg XtSetArg(args[0], XtNlabel, ispell.formatting); 21335dfecf96Smrg XtSetValues(ispell.format, args, 1); 21345dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, flist.pixmap); 21355dfecf96Smrg XtSetValues(fmt->sme, args, 1); 21365dfecf96Smrg ispell.format_info = fmt; 21375dfecf96Smrg } 21385dfecf96Smrg } 21395dfecf96Smrg if (ispell.format_info == NULL) { 21405dfecf96Smrg Arg args[1]; 21415dfecf96Smrg char msg[256]; 21425dfecf96Smrg 21435dfecf96Smrg ispell.format_info = &ispell_format[TEXT]; 21445dfecf96Smrg 21455dfecf96Smrg XmuSnprintf(msg, sizeof(msg), 21465dfecf96Smrg "Unrecognized formatting type \"%s\", will use \"%s\"", 21475dfecf96Smrg ispell.formatting, ispell.format_info->name); 21485dfecf96Smrg XtAppWarning(XtWidgetToApplicationContext(ispell.shell), msg); 21495dfecf96Smrg ispell.formatting = ispell.format_info->name; 21505dfecf96Smrg 21515dfecf96Smrg XtSetArg(args[0], XtNlabel, ispell.format_info->name); 21525dfecf96Smrg XtSetValues(ispell.format, args, 1); 21535dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, flist.pixmap); 21545dfecf96Smrg XtSetValues(ispell.format_info->sme, args, 1); 21555dfecf96Smrg } 21565dfecf96Smrg XtGetApplicationResources(ispell_format[TEXT].sme, (XtPointer)&ispell, 21575dfecf96Smrg text_res, XtNumber(text_res), NULL, 0); 21585dfecf96Smrg 21595dfecf96Smrg dict_res.resource_name = "wordChars"; 21605dfecf96Smrg dict_res.resource_class = "Chars"; 21615dfecf96Smrg dict_res.resource_type = XtRString; 21625dfecf96Smrg dict_res.resource_size = sizeof(char*); 21635dfecf96Smrg dict_res.resource_offset = XtOffsetOf(ispell_dict, wchars); 21645dfecf96Smrg dict_res.default_type = XtRString; 21655dfecf96Smrg dict_res.default_addr = ""; 21665dfecf96Smrg 21675dfecf96Smrg list = XtNewString(ispell.dict_list); 21685dfecf96Smrg 2169f14f4646Smrg /* Create first empty entry */ 2170f14f4646Smrg dict = XtNew(ispell_dict); 2171f14f4646Smrg dict->sme = XtCreateManagedWidget("", smeBSBObjectClass, 2172f14f4646Smrg ispell.dictMenu, NULL, 0); 2173f14f4646Smrg dict->wchars = ""; 2174f14f4646Smrg XtAddCallback(dict->sme, XtNcallback, ChangeDictionaryIspell, 2175f14f4646Smrg (XtPointer)dict); 2176f14f4646Smrg ispell.dict_info = prev_dict = dict; 2177f14f4646Smrg 2178f14f4646Smrg for (str = strtok(list, " \t,"); str; str = strtok(NULL, " \t,")) { 2179f14f4646Smrg dict = XtNew(ispell_dict); 2180f14f4646Smrg dict->sme = XtCreateManagedWidget(str, smeBSBObjectClass, 2181f14f4646Smrg ispell.dictMenu, NULL, 0); 2182f14f4646Smrg XtGetApplicationResources(dict->sme, (XtPointer)dict, &dict_res, 21835dfecf96Smrg 1, NULL, 0); 2184f14f4646Smrg XtAddCallback(dict->sme, XtNcallback, ChangeDictionaryIspell, 2185f14f4646Smrg (XtPointer)dict); 2186f14f4646Smrg prev_dict->next = dict; 2187f14f4646Smrg prev_dict = dict; 2188f14f4646Smrg dict->next = NULL; 2189f14f4646Smrg } 2190f14f4646Smrg XtFree(list); 2191f14f4646Smrg 2192f14f4646Smrg for (dict = ispell.dict_info; dict; dict = dict->next) { 2193f14f4646Smrg if (strcmp(XtName(dict->sme), ispell.dictionary) == 0) { 21945dfecf96Smrg Arg args[1]; 21955dfecf96Smrg 21965dfecf96Smrg XtSetArg(args[0], XtNleftBitmap, flist.pixmap); 2197f14f4646Smrg XtSetValues(dict->sme, args, 1); 2198f14f4646Smrg XtSetArg(args[0], XtNlabel, XtName(dict->sme)); 21995dfecf96Smrg XtSetValues(ispell.dict, args, 1); 2200f14f4646Smrg ispell.wchars = dict->wchars; 2201f14f4646Smrg break; 22025dfecf96Smrg } 22035dfecf96Smrg } 2204f14f4646Smrg 22055dfecf96Smrg 22065dfecf96Smrg delete_window = XInternAtom(XtDisplay(ispell.shell), "WM_DELETE_WINDOW", False); 22075dfecf96Smrg XSetWMProtocols(XtDisplay(ispell.shell), XtWindow(ispell.shell), &delete_window, 1); 22085dfecf96Smrg 22095dfecf96Smrg return (True); 22105dfecf96Smrg} 2211