v03i034: Webster client, Part01/02

Mike Wexler mikew at wyse.wyse.com
Wed Mar 8 04:06:59 AEST 1989


Submitted-by: mayer at hplabs.hp.com (Niels P. Mayer)
Posting-number: Volume 3, Issue 34
Archive-name: xweb/part01

[I couldn't test this as I don't have the R3 version of the HP
widgets running. -mcw]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  README Imakefile Xwebster.ad display_def.c xwebster.c
# Wrapped by mikew at wyse on Tue Mar  7 10:03:59 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(4534 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X	Xwebster, A Dictionary Browser
X		Niels P. Mayer
X		Hewlett-Packard Laboratories
X		Software Technology Lab.
X------------------------------------------------------------------------------
X
XXwebster is used to look up words in the online copy of Webster's 7th
Xdictionary, stored at SRI-NIC  and also available on machines located at
XBoston U., Indiana U, Purdue U., MIT, Stanford, etc. In order to run xwebster
Xyou must have access to a webster server. In order to make xwebster run faster
Xand more reliably (the "arpanet" can be flaky), you may want to ask your 
Xsystem administrators whether there is a webster server running locally.
XChances are, if people at your site are using the tty-based webster(1) 
Xinterface, there is probably a webster server "nearby".
X
XUsing xwebster is simple -- words are typed into a TextEdit widget in
Xxwebster, and then one of three actions can be taken:
X
X	1) mousing [Define] (or hitting <ret>) after typing in a
X	word will attempt to show you a complete dictionary entry for the
X	word including definitions,  pronunciation, and derivation. If the word
X	is misspelled, then a browser of similar words will be presented. If
X	the word contains wildcard characters (%=any char; *=any char seq),
X	then a browser of all matching words will be presented.
X	
X	2) mousing [Complete] (or hitting <esc>) after a partial word has
X	been typed will attempt to complete what you have typed so far.  If 
X	what you have typed is a unique abbreviation for a word, the word is 
X	completed. Otherwise xwebster will beep and indicate the ambiguity of 
X	the partial word.
X
X	3) mousing [Endings] (or hitting <?>) after a partial word has been
X	entered will display a browser of all the words matching the partial
X	word.
X
XAnytime there are words in the word browser panel, clicking on a word will
Xcause its definition to be dispayed. 
X
X				----------
XCOMPILING:
X
XXwebster uses the HP Xwidgets library and the X11R3 Xt intrinsics:  The HP
Xwidgets are on the X11R3 tape, and require a set of fixes by martin
XFriedmann <martin at citi.umich.edu> in order to work under R3. These are
Xavailable from the usual archive sites.
X
XI've only tested xwebster on my own machine, a HP9000s350 running HPUX 6.21,
XHP's X11R2 product server and libraries, and color displays. HPUX is SYSV
Xcompliant with various BSD + HP extensions -- I only used a few SYSVisms, so
Xyou should be able to get xwebster running on your unix too.  The HP
XXwidgets and Xwebster make no assumptions about color hardware, so it should
Xwork just as well under black and white displays.  The version of the
XXwidgets I used in designing xwebster are the HP 3-D widgets whereas the HP
Xwidgets on the R3 tape have been castrated into 2-D pending resolution of
Xsome patenting issues.  Xwebster looks ok with the 2-D widgets. Xwebster has
Xalso been tested on Suns running R3 under SunOS3.5.
X
XYou need the strtok() call - if your system doesn't have it (System V, Suns
Xhave it), get Henry Spencer's public domain strings(3) library from some
Xcomp.sources.unix archive site.
X
X				----------
X
XCUSTOMIZING:
X
XAll the resources for xwebster are specified in the application default
Xfile Xwebster, which MUST be installed in APPDEFAULTSDIR/Xwebster.
XFully qualified resource names are used in this app-defaults file so
Xas to document the widget hierarchy in the application. Documentation
Xon customizing xwebster also appears in this defaults file.
X(APPDEFAULTSDIR is set in the imake defaults)
X
XParameters for connecting to a webster server are contained in the
Xresources "hostAddrList", "hostPort", and "hostServiceName". See the
XXwebster file for details and documentation.
X
XXwebster allows dictionary definitions to be viewed in either a scrolled
XStaticText widget (for those who like scrollbars), or in a TextEdit widget
X(for those who like Emacs, and need better control of cut/paste
Xoperations). The resource that controls this is "useEditorAsDisplay"
X
X				----------
X
XHISTORY:
X
XThis program was inspired by the webster(1) tty-based client to a webster
Xserver written by Dave Curry <davy at riacs.edu>, although most of the code
Xwas written from scratch because I didn't find the webster(1) source code
Xuntil after the application was prototyped. The original webster
Xclient/server was written in MIDAS and ran under Tops-20, it was probably
Xdone by someone at SRI-NIC.
X
X-------------------------------------------------------------------------------
X	    Niels Mayer -- hplabs!mayer -- mayer at hplabs.hp.com
X		       Hewlett-Packard Laboratories
X			      Palo Alto, CA.
X				   *
END_OF_FILE
if test 4534 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(682 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X#XWSRC         = $(CONTRIBSRC)/widgets/Xhp
X#INCLUDES      = -I$(XWSRC) -I$(TOP)
X# Define FAST_SERVER if you have an X server that is fast enough to make
X# sensitizing and desensitizing buttons non-painful. On Suns with the
X# MIT sample server, it is VERY painful.
XDEFINES       = -DAPPDEFAULTSDIR=\"$(XAPPLOADDIR)\" # -DFAST_SERVER 
XCDEBUGFLAGS   = -g -O # +Nd4000 +Ns4000
XHDRS	      = user_prefs.h \
X		xwebster.h
XLOCAL_LIBRARIES = $(XWLIB) \
X		$(XTOOLLIB) \
X		$(XLIB)
XOBJS	      = controlpanel.o \
X		display_def.o \
X		wordlist.o \
X		xwebster.o
XSRCS	      = controlpanel.c \
X		display_def.c \
X		wordlist.c \
X		xwebster.c
X
XComplexProgramTarget(xwebster)
XInstallAppDefaults(Xwebster)
END_OF_FILE
if test 682 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Xwebster.ad' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Xwebster.ad'\"
else
echo shar: Extracting \"'Xwebster.ad'\" \(19306 characters\)
sed "s/^X//" >'Xwebster.ad' <<'END_OF_FILE'
X################################################################################
X#
X# File:         Xwebster
X# RCS:          $Header: Xwebster,v 1.7 88/09/19 18:19:19 mayer Exp $
X# Description:  Application Default: put in /usr/lib/X11/app-defaults/Xwebster
X# Author:       Niels Mayer, HPLabs
X# Created:      Thu Sep  1 01:14:17 1988
X# Modified:     Mon Sep 19 14:12:04 1988 (Niels Mayer) mayer at hplnpm
X# Language:     N/A
X# Package:      N/A
X# Status:       G-Job
X#
X# xwebster - dictionary browser
X#
X# Copyright 1988 Hewlett-Packard Company
X#
X# Permission to use, copy, modify, and distribute this software and its
X# documentation for any purpose and without fee is hereby granted, provided
X# that the above copyright notice appear in all copies and that both that
X# copyright notice and this permission notice appear in supporting
X# documentation, and that the name of HP not be used in advertising or
X# publicity pertaining to distribution of the software without specific,
X# written prior permission.  HP makes no representations about the
X# suitability of this software for any purpose.  It is provided "as is"
X# without express or implied warranty.
X#
X# Please send any improvements, bug fixes, useful modifications, and comments
X# to mayer at hplabs.hp.com.
X################################################################################
X
X##
X## this is the help display that comes up initially when you run Xwebster.
X##
X*helpText: WELCOME TO XWEBSTER, hacked by Niels Mayer (mayer at hplabs.hp.com)\n\n\
X    Webster's 7th Collegiate Dictionary, Copyright (C) 1963 by Merriam-Webster,\n\
X    Inc.  No part of this information may be copied or reprinted without the\n\
X    express written consent of the publisher.\n\n\
XThis program connects to a Webster dictionary server to get definitions of\n\
Xwords.  Words are entered in the TextEdit Widget in the center panel of\n\
Xthis program.  You may then type <ret> or mouse [Define] to get the\n\
Xdefinition of the word. If the word has any cross-references, they will be\n\
Xpresented in the word browser panel in xwebster. If the word is\n\
X"slightly misspelled", then a list of words is presented in the word browser\n\
Xpanel, one of which might be the word that you had intended.\n\n\
XTyping '?' or mousing [Endings] following part of a word will cause\n\
Xxwebster to list all words beginning with the partial word in the word\n\
Xbrowser panel. The program will beep and give an error message if nothing\n\
Xmatches.\n\n\
XTyping <esc> or mousing [Complete] causes the program to attempt to\n\
Xcomplete the word.  If the word can be completed, the new word is placed in\n\
Xthe TextEdit widget; otherwise, the program beeps and displays a message\n\
Xindicating that the word is ambiguous.\n\n\
XIn all the above cases, the wildcard characters '%' and '*' may be used to\n\
Xspecify partial words. The '%' character matches exactly one character,\n\
Xwhile the '*' matches zero or more characters.  If wildcards are used, the\n\
Xprogram will return either "No match" or a browser of matching words.\n
X
X##
X## The following are parameters for accessing the webster server. Note that
X## hostAddrList is a list of internet adresses that are tried in succession
X## incase there's problems connecting to a server. In the following example, 
X## we try the two different SRI-NIC server addresses for a total of 10 times
X## before giving up. Or replace these with your own webster server's parameters
X##
X## (Webster servers are available at ???.bu.edu, ???.indiana.edu, ???.mit.edu,
X## ??.purdue.edu, and others. If you have the webster(1) tty interface to 
X## webster, then run strings on it to find out which server host it uses 
X## (or look at the source  code). Webster servers tend to be located on port 
X## 103 or 2627.)
X##
X*hostAddrList: 26.0.0.73 10.0.0.51 26.0.0.73 10.0.0.51 26.0.0.73 10.0.0.51 26.0.0.73 10.0.0.51 26.0.0.73 10.0.0.51
X*hostPort: 103
X*hostServiceName: webster
X
X##
X## This is the width of the wordinput widget. I figure that most words are
X## less than 30 characters long.
X##
X*wordInputWidgetWidth: 30
X
X##
X## if useEditorAsDisplay is true, then a TextEdit widget is used to display,
X## definitions.
X## if useEditorAsDisplay is false, then a statictext widget within a
X## scrolled window is used to display definitions.
X##
X## Advantages for "*useEditorAsDisplay: FALSE" are:
X## 	1) obvious to use -- move around the definition with the scrollbar.
X## Disadvantages are:
X## 	1) Can only cut entire text of definition via left-mouse selection,
X##	   cannot cut an individual region of text, such as a single word.
X##      2) Scrolling refreshes in an ugly fashion.
X##
X## Advantages for "*useEditorAsDisplay: TRUE" are:
X## 	1) can cut individual regions from the definition text.
X## Disadvantages are:
X## 	1) "beginners" may not know that "emacs" commands allow moving around
X##         the definition. The TexEdit widget doesn't have a scrollbar, so it's
X##         not visually obvious that part of the definition may be off-screen.
X##
X*useEditorAsDisplay: FALSE
X
X##
X## The following control the size of the pane that display's word definitions.
X## The webster server formats it's output for 80-column wide displays, and 
X## therefore, *displayWidth should be at least this wide. Due to weirdness
X## of this implementation and the Xwidgets, "85" width allows for a scrollbar
X## to fit in the display pane without covering up 80-column wide text.
X##
X*displayWidth: 85
X*displayHeight: 10
X
X##
X## When a long list of words is being sent by the server (eg, list endings of
X## all words beginning with "a"), the wordlist display is updated every 
X## "numWordsBeforeRefresh" words. If the server is very slow (or the network is 
X## slow), it is useful to see its progress, so as to show that xwebster hasn't 
X## hung. On the other hand, if the server is very fast, then the wordlist display
X## will update too much. So Adjust this value upwards if you don't care to see 
X## the words in the wordlist arrive from the server incementally or if you want
X## to reduce the amount of display updating.
X## 
X*numWordsBeforeRefresh: 10
X
X###############################################################################
X# *panel -- XwvPanedWidgetClass.
X#
X
X###############################################################################
X##
X## *panel.display_scroller and *panel.display_scroller.display below only
X## count if "*useEditorAsDisplay" resource is false. In that case, the 
X## widget displaying the definition is made up from a statictext widget within
X## a scrollbar.
X##
X# *panel.display_scroller -- XwswindowWidgetClass
X#
X## preset: *panel.display_scroller.width = displayWidth*fontwidth where by default
X## *displayWidth: 85
X#
X## preset: *panel.display_scroller.height = displayHeight*fonthheight where by default
X## *displayHeight: 10
X#
X## Constraint resources added by VerticallyPanedWidget (XwvPanedWidgetClass):
X# *panel.display_scroller.min: 1
X# *panel.display_scroller.max: 10000
X# *panel.display_scroller.allowResize: FALSE
X# *panel.display_scroller.skipAdjust: FALSE
X
X#
X# *panel.display_scroller.display -- XwstaticTextWidgetClass
X#
X*panel.display_scroller.display.borderWidth: 0
X*panel.display_scroller.display.shadowOn: no
X*panel.display_scroller.display.alignment: Left
X*panel.display_scroller.display.gravity: CenterGravity
X*panel.display_scroller.display.wrap: FALSE
X*panel.display_scroller.display.strip: FALSE
X# it would be very silly to use proportional fonts here, since the webster
X# server formats the text output for fixed width fonts.
X*display_scroller.display.font: 6x13
X
X###############################################################################
X##
X## *panel.display below only counts if "*useEditorAsDisplay" resource is true.
X## In that case, the widget displaying the definition is made up from a 
X## TextEdit widget.
X##
X# *panel.display -- XwtexteditWidgetClass
X#
X## preset: *display.width = displayWidth*fontwidth where by default
X## *displayWidth: 85
X#
X## preset: *display.height = displayHeight*fonthheight where by default
X## *displayHeight: 10
X#
X## Constraint resources added by VerticallyPanedWidget (XwvPanedWidgetClass):
X# *panel.display.min: 1
X# *panel.display.max: 10000
X# *panel.display.allowResize: FALSE
X# *panel.display.skipAdjust: FALSE
X
X*panel.display.wrap: wrapoff
X## it would be very silly to use proportional fonts here, since the webster
X## server formats the text output for fixed width fonts.
X*panel.display.font: 6x13
X## this is the default TextEdit txlation table with all bindings that alter 
X## the editor's text removed. In addition, backspace and space move to 
X## previous and next pages, respectively. 
X*panel.display.translations: \
X     <Key>BackSpace:		previous-page() \n\
X     Ctrl<Key>H:		previous-page() \n\
X     <Key>\\ :		        next-page() \n\
X     Ctrl<Key>F:		forward-character() \n\
X     Ctrl<Key>Right:		traverse-right() \n\
X     <Key>Right:		forward-character() \n\
X     Ctrl<Key>B:		backward-character() \n\
X     Ctrl<Key>Left:		traverse-left() \n\
X     <Key>Left: 		backward-character() \n\
X     Meta<Key>F:		forward-word() \n\
X     Meta<Key>B:		backward-word() \n\
X     Meta<Key>]:		forward-paragraph() \n\
X     Ctrl<Key>[:		backward-paragraph() \n\
X     Ctrl<Key>A:		beginning-of-line() \n\
X     Ctrl<Key>E:		end-of-line() \n\
X     Ctrl<Key>N:		next-line() \n\
X     Ctrl<Key>Down:		traverse-down() \n\
X     <Key>Down: 		next-line() \n\
X     Ctrl<Key>P:		previous-line() \n\
X     Ctrl<Key>Up:           	traverse-up() \n\
X     <Key>Up:  	 	 	previous-line() \n\
X     Ctrl<Key>V:		next-page() \n\
X     Ctrl<Key>Next:		traverse-next() \n\
X     <Key>Next:			next-page() \n\
X     Meta<Key>V:		previous-page() \n\
X     Ctrl<Key>Prior:		traverse-prev() \n\
X     <Key>Prior:		previous-page() \n\
X     Meta<Key>\\<:		beginning-of-file() \n\
X     Meta<Key>\\>:		end-of-file() \n\
X     Ctrl<Key>Home:		traverse-home() \n\
X     Shift<Key>Home:		end-of-file() \n\
X     <Key>Home:			beginning-of-file() \n\
X     Ctrl<Key>Z:		scroll-one-line-up() \n\
X     Meta<Key>Z:		scroll-one-line-down() \n\
X     Ctrl<Key>L:		redraw-display() \n\
X     <FocusIn>:			focus-in() \n\
X     <FocusOut>:		focus-out() \n\
X     <Btn1Down>:		select-start() \n\
X     Button1<PtrMoved>:		extend-adjust() \n\
X     <Btn1Up>:			extend-end() \n\
X     <Btn3Down>:		extend-start() \n\
X     Button3<PtrMoved>:		extend-adjust() \n\
X     <Btn3Up>:			extend-end() \n\
X     <Key>Execute:		execute() \n\
X     <EnterWindow>:		enter() \n\
X     <LeaveWindow>:		leave()
X
X###############################################################################
X# *panel.titlebar -- XwtitlebarWidgetClass
X#
X## preset: *panel.titlebar.titleForeground == *panel.titlebar.foreground
X## preset: *panel.titlebar.titleBackground == *panel.titlebar.background
X
X## Constraint resources added by VerticallyPanedWidget (XwvPanedWidgetClass):
X## preset: *panel.titlebar.min == *panel.titlebar.height
X## preset: *panel.titlebar.max == *panel.titlebar.height
X# *panel.titlebar.allowResize: FALSE
X# *panel.titlebar.skipAdjust: FALSE
X
X*panel.titlebar.titlePrecedence: 0
X*panel.titlebar.titleRegion: Center
X
X#
X# *panel.titlebar.StaticText -- the label text on the titlebar panel
X#
X*panel.titlebar.StaticText.gravity: CenterGravity
X*panel.titlebar.StaticText.borderWith: 0
X*panel.titlebar.StaticText.shadowOn: no
X*panel.titlebar.alignment: Left
X*panel.titlebar.wrap: FALSE
X*panel.titlebar.font: variable
X
X#
X# *panel.titlebar.PushButton -- XwpushButtonWidgetClass
X#
X*panel.titlebar.PushButton.traversalType: highlight_enter
X*panel.titlebar.PushButton.highlightThickness: 1
X## color display users might want to uncomment the following line and set
X## .highlightTile to foreground as well. 
X# *panel.titlebar.PushButton.highlightColor: white
X*panel.titlebar.PushButton.highlightTile: 50_foreground
X*panel.titlebar.PushButton.font: variable
X
X*panel.titlebar.quit_button.label: Quit
X*panel.titlebar.quit_button.region: Left
X# *panel.titlebar.quit_button.lPadding: 2
X# *panel.titlebar.quit_button.rPadding: 2
X# *panel.titlebar.quit_button.precedence: 1
X
X*panel.titlebar.help_button.label: Help
X*panel.titlebar.help_button.region: Right
X# *panel.titlebar.help_button.lPadding: 2
X# *panel.titlebar.help_button.rPadding: 2
X# *panel.titlebar.help_button.precedence: 1
X
X###############################################################################
X# *panel.wordlist_scroller -- XwswindowWidgetClass
X#
X*panel.wordlist_scroller.height: 100
X
X## Constraint resources added by VerticallyPanedWidget (XwvPanedWidgetClass):
X# *panel.wordlist_scroller.min: 1
X# *panel.wordlist_scroller.max: 10000
X# *panel.wordlist_scroller.allowResize: FALSE
X# *panel.wordlist_scroller.skipAdjust: FALSE
X
X#
X# *panel.wordlist_scroller.wordlist -- XwrowColWidgetClass
X#
X*panel.wordlist_scroller.wordlist.hSpace: 2
X*panel.wordlist_scroller.wordlist.vSpace: 2
X*panel.wordlist_scroller.wordlist.layoutType: requested_columns
X*panel.wordlist_scroller.wordlist.columns: 4
X*panel.wordlist_scroller.wordlist.forceSize: TRUE
X*panel.wordlist_scroller.wordlist.singleRow: FALSE
X*panel.wordlist_scroller.wordlist.mode: n_of_many
X*panel.wordlist_scroller.wordlist.borderWidth: 0
X
X#
X# *panel.wordlist_scroller.wordlist.word -- XwpushButtonWidgetClass
X# ??? for some reason, I must spec this as *panel.wordlist_scroller*wordlist...
X# ??? rather than panel.wordlist_scroller.wordlist... even though
X# ??? wordlist_scroller is the parent of wordlist -- an Xtk bug, perhaps?
X*panel.wordlist_scroller*wordlist.word.font: 6x13
X*panel.wordlist_scroller*wordlist.word.traversalType: highlight_enter
X*panel.wordlist_scroller*wordlist.word.highlightThickness: 1
X## color display users might want to uncomment the following line and set
X## .highlightTile to foreground as well. 
X# *panel.wordlist_scroller*wordlist.word.highlightColor: white
X*panel.wordlist_scroller*wordlist.word.highlightTile: 50_foreground
X
X###############################################################################
X# *panel.control_panel -- XwtitlebarWidgetClass
X
X## Constraint resources added by VerticallyPanedWidget (XwvPanedWidgetClass):
X## preset: *panel.control_panel.min == *panel.control_panel.height
X## preset: *panel.control_panel.max == *paenl.control_panel.height
X# *panel.control_panel.allowResize: FALSE
X# *panel.control_panel.skipAdjust: FALSE
X
X#
X# *panel.control_panel.PushButton -- XwpushButtonWidgetClass
X#
X*panel.control_panel.PushButton.traversalType: highlight_enter
X*panel.control_panel.PushButton.highlightThickness: 1
X## color display users might want to uncomment the following line and set
X## .highlightTile to foreground as well. 
X# *panel.control_panel.PushButton.highlightColor: white
X*panel.control_panel.PushButton.highlightTile: 50_foreground
X*panel.control_panel.PushButton.font: variable
X
X*panel.control_panel.define_button.label: Define <ret>
X*panel.control_panel.define_button.region: Center
X*panel.control_panel.define_button.precedence: 0
X# *panel.control_panel.define_button.lPadding: 2
X# *panel.control_panel.define_button.rPadding: 2
X
X*panel.control_panel.complete_button.label: Complete <esc>
X*panel.control_panel.complete_button.region: Center
X*panel.control_panel.complete_button.precedence: 1
X# *panel.control_panel.complete_button.lPadding: 2
X# *panel.control_panel.complete_button.rPadding: 2
X
X*panel.control_panel.endings_button.label: Endings <?>
X*panel.control_panel.endings_button.region: Center
X*panel.control_panel.endings_button.precedence: 1
X# *panel.control_panel.endings_button.lPadding: 2
X# *panel.control_panel.endings_button.rPadding: 2
X
X#
X# *panel.control_panel.word_input -- XwtexteditWidgetClass
X#
X## preset: *word_input.height = 1*fontheight, 
X## preset: *word_input.width = wordInputWidgetWidth*fontheight where by default
X## *wordInputWidgetWidth: 30
X#
X*panel.control_panel.word_input.traversalType: highlight_enter
X*panel.control_panel.word_input.highlightThickness: 1
X## color display users might want to uncomment the following line and set
X## .highlightTile to foreground as well. 
X# *panel.control_panel.word_input.highlightColor: white
X*panel.control_panel.word_input.highlightTile: 50_foreground
X*panel.control_panel.word_input.font: 6x13
X
X*panel.control_panel.word_input.region: Center
X*panel.control_panel.word_input.precedence: 0
X# *panel.control_panel.word_input.lPadding: 2
X# *panel.control_panel.word_input.rPadding: 2
X*panel.control_panel.word_input.shadowOn: FALSE
X
X## TextEdit's default translation table that has been munged so that
X## (1) ?, <esc> and <return> call endings, complete, and define.
X## (2) since the word_input widget is only for a single line of text, all
X## keystrokes from the default TextEdit table that deal with multiline text
X## have been rebound to webster-no-op(), a function that just beeps.
X*panel.control_panel.word_input.translations: \
X     <Key>Return:		webster-define-word() \n\
X     <Key>Escape:		webster-complete-word() \n\
X     <Key>?:			webster-list-endings() \n\
X     Shift<Key>/:		webster-list-endings() \n\
X     Ctrl<Key>M:		webster-no-op() \n\
X     Meta<Key>]:		webster-no-op() \n\
X     Ctrl<Key>[:		webster-no-op() \n\
X     Ctrl<Key>N:		webster-no-op() \n\
X     Ctrl<Key>P:		webster-no-op() \n\
X     Ctrl<Key>V:		webster-no-op() \n\
X     Meta<Key>V:		webster-no-op() \n\
X     Ctrl<Key>Z:		webster-no-op() \n\
X     Meta<Key>Z:		webster-no-op() \n\
X     Ctrl<Key>J:		webster-no-op() \n\
X     Ctrl<Key>O:		webster-no-op() \n\
X     Ctrl<Key>F:		forward-character() \n\
X     Ctrl<Key>Right:		traverse-right() \n\
X     <Key>Right:		forward-character() \n\
X     Ctrl<Key>B:		backward-character() \n\
X     Ctrl<Key>Left:		traverse-left() \n\
X     <Key>Left: 		backward-character() \n\
X     Meta<Key>F:		forward-word() \n\
X     Meta<Key>B:		backward-word() \n\
X     Ctrl<Key>A:		beginning-of-line() \n\
X     Ctrl<Key>E:		end-of-line() \n\
X     Ctrl<Key>Down:		traverse-down() \n\
X     <Key>Down:			webster-no-op() \n\
X     Ctrl<Key>Up:           	traverse-up() \n\
X     <Key>Up:			webster-no-op() \n\
X     Ctrl<Key>Next:		traverse-next() \n\
X     Ctrl<Key>Prior:		traverse-prev() \n\
X     <Key>Prior:		webster-no-op() \n\
X     Meta<Key>\\<:		beginning-of-file() \n\
X     Meta<Key>\\>:		end-of-file() \n\
X     Ctrl<Key>Home:		traverse-home() \n\
X     Shift<Key>Home:		end-of-file() \n\
X     <Key>Home:			beginning-of-file() \n\
X     Shift Meta<Key>D:		kill-word() \n\
X     Ctrl<Key>D:		delete-next-character() \n\
X     <Key>Delete:		delete-previous-character() \n\
X     <Key>BackSpace:		delete-previous-character() \n\
X     Ctrl<Key>H:		delete-previous-character() \n\
X     Meta<Key>D:		delete-next-word() \n\
X     Meta<Key>H:		delete-previous-word() \n\
X     Shift Meta<Key>H:		backward-kill-word() \n\
X     Ctrl<Key>W:		kill-selection() \n\
X     Ctrl<Key>K:		kill-to-end-of-line() \n\
X     Meta<Key>K:		kill-to-end-of-paragraph() \n\
X     Ctrl<Key>Y:		unkill() \n\
X     Meta<Key>Y:		stuff() \n\
X     Ctrl<Key>L:		redraw-display() \n\
X     <FocusIn>:			focus-in() \n\
X     <FocusOut>:		focus-out() \n\
X     <Btn1Down>:		select-start() \n\
X     Button1<PtrMoved>:		extend-adjust() \n\
X     <Btn1Up>:			extend-end() \n\
X     <Btn2Down>:		stuff() \n\
X     <Btn3Down>:		extend-start() \n\
X     Button3<PtrMoved>:		extend-adjust() \n\
X     <Btn3Up>:			extend-end() \n\
X     <Key>Execute:		execute() \n\
X     <Key>:			insert-char() \n\
X     Shift<Key>:		insert-char() \n\
X     <EnterWindow>:		enter() \n\
X     <LeaveWindow>:		leave()
END_OF_FILE
if test 19306 -ne `wc -c <'Xwebster.ad'`; then
    echo shar: \"'Xwebster.ad'\" unpacked with wrong size!
fi
# end of 'Xwebster.ad'
fi
if test -f 'display_def.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'display_def.c'\"
else
echo shar: Extracting \"'display_def.c'\" \(6985 characters\)
sed "s/^X//" >'display_def.c' <<'END_OF_FILE'
X/* -*-C-*-
X********************************************************************************
X*
X* File:         display_def.c
X* RCS:          $Header: display_def.,v 1.7 88/09/13 17:19:54 mayer Exp $
X* Description:  Module for clearing, appending to and displaying a definition.
X* Author:       Niels Mayer, HPLabs
X* Created:      Wed Aug 31 19:17:42 1988
X* Modified:     Tue Sep 13 15:42:15 1988 (Niels Mayer) mayer at hplnpm
X* Language:     C
X* Package:      N/A
X* Status:       G-Job
X*
X* xwebster - dictionary browser
X*
X* Copyright 1988 Hewlett-Packard Company
X*
X* Permission to use, copy, modify, and distribute this software and its
X* documentation for any purpose and without fee is hereby granted, provided
X* that the above copyright notice appear in all copies and that both that
X* copyright notice and this permission notice appear in supporting
X* documentation, and that the name of HP not be used in advertising or
X* publicity pertaining to distribution of the software without specific,
X* written prior permission.  HP makes no representations about the
X* suitability of this software for any purpose.  It is provided "as is"
X* without express or implied warranty.
X*
X* Please send any improvements, bug fixes, useful modifications, and comments
X* to mayer at hplabs.hp.com.
X********************************************************************************
X*/
Xstatic char rcs_identity[] = "@(#)$Header: display_def.,v 1.7 88/09/13 17:19:54 mayer Exp $";
X
X#include "xwebster.h"
X#include "user_prefs.h"
X#include <Xw/SText.h>
X#include <Xw/SWindow.h>
X#include <Xw/TextEdit.h>
X
Xstatic Widget display_Wgt = NULL;
Xstatic char   text[20000]; /* hopefully no def will be longer than this! */
Xstatic int    end_idx = 0;
X
X
X/******************************************************************************
X * KLUDGE_O_RAMA: on select, invert the text in the StaticText widget to show 
X * that something's being done and store the definition in the cut buffer.
X ******************************************************************************/
Xstatic XtCallbackProc Display_Select_Callback(widget, client_data, call_data)
X     Widget widget;
X     caddr_t client_data;
X     caddr_t call_data;
X{
X  Pixel foreground;
X  Pixel background;
X  char* displ_text;
X
X  ARGLIST_RESET();
X  ARGLIST_ADD(XtNforeground, &foreground);
X  ARGLIST_ADD(XtNbackground, &background);
X  XtGetValues(widget, ARGLIST());
X  ARGLIST_RESET();
X  ARGLIST_ADD(XtNforeground, background);
X  ARGLIST_ADD(XtNbackground, foreground);
X  XtSetValues(widget, ARGLIST());
X  
X  ARGLIST_RESET();
X  ARGLIST_ADD(XtNstring, &displ_text);
X  XtGetValues(display_Wgt, ARGLIST());
X  XStoreBuffer(XtDisplay(widget), displ_text, strlen(displ_text), 0);
X}
X
X
X/******************************************************************************
X * KLUDGE_O_RAMA: on release, uninvert the text in the StaticText widget.
X ******************************************************************************/
Xstatic XtCallbackProc Display_Release_Callback(widget, client_data, call_data)
X     Widget widget;
X     caddr_t client_data;
X     caddr_t call_data;
X{
X  Pixel foreground;
X  Pixel background;
X
X  /* 
X   * Uninvert the display that was inverted in Display_Select_Callback
X   */
X  ARGLIST_RESET();
X  ARGLIST_ADD(XtNforeground, &foreground);
X  ARGLIST_ADD(XtNbackground, &background);
X  XtGetValues(widget, ARGLIST());
X  ARGLIST_RESET();
X  ARGLIST_ADD(XtNforeground, background);
X  ARGLIST_ADD(XtNbackground, foreground);
X  XtSetValues(widget, ARGLIST());
X}
X
X
X/******************************************************************************
X *
X ******************************************************************************/
XDisplay_Def_Init(w)
X     Widget w;
X{
X  XFontStruct *font;
X
X  if (user_prefs.use_editor_as_display) {
X    /* 
X     * Create a TextEdit widget to use for the display.
X     */
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNstring, user_prefs.help_text);
X    display_Wgt = XtCreateManagedWidget("display", XwtexteditWidgetClass, 
X					w, ARGLIST());
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNfont, &font);
X    XtGetValues(display_Wgt, ARGLIST());
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNheight, (Dimension) (user_prefs.display_height
X     *FONTHEIGHT(font) + 6));
X    ARGLIST_ADD(XtNwidth,  (Dimension) (user_prefs.display_width
X     *FONTWIDTH(font)));
X    XtSetValues(display_Wgt, ARGLIST());
X  }
X  else {
X    /*
X     * Create a statictextwidget within a scrolled window as the display.
X     */
X    Widget display_scroller_Wgt = XtCreateManagedWidget("display_scroller", 
X							XwswindowWidgetClass, w, 
X							NULL, 0);
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNstring, user_prefs.help_text);
X    display_Wgt = XtCreateManagedWidget("display", 
X					XwstatictextWidgetClass, 
X					display_scroller_Wgt, ARGLIST());
X    XtAddCallback(display_Wgt, XtNselect, Display_Select_Callback, NULL);
X    XtAddCallback(display_Wgt, XtNrelease, Display_Release_Callback, NULL);
X
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNfont, &font);
X    XtGetValues(display_Wgt, ARGLIST());
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNheight, (Dimension) (user_prefs.display_height
X     *FONTHEIGHT(font) + 6));
X    ARGLIST_ADD(XtNwidth,  (Dimension) (user_prefs.display_width
X     *FONTWIDTH(font)));
X    XtSetValues(display_scroller_Wgt, ARGLIST());
X  }
X}
X
X
X/******************************************************************************
X *
X ******************************************************************************/
XDisplay_Def_Text_Reset()
X{
X  if (user_prefs.use_editor_as_display) {
X    XwTextClearBuffer(display_Wgt);
X  }
X  else {
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNstring, "");
X    XtSetValues(display_Wgt, ARGLIST());
X    end_idx = 0;
X  }
X}
X
X
X/******************************************************************************
X *
X ******************************************************************************/
XDisplay_Def_Text_Append(intext)
X     char* intext;
X{
X  if (user_prefs.use_editor_as_display) {
X    XwTextInsert(display_Wgt, intext);
X  }
X  else {
X    int intext_length = strlen(intext);
X    strncpy(&text[end_idx], intext, intext_length);
X    end_idx += intext_length;
X  }
X}
X
X
X/******************************************************************************
X *
X ******************************************************************************/
XDisplay_Def_Refresh()
X{
X  if (user_prefs.use_editor_as_display) {
X    /*
X     * When done writing definition to display_Wgt, move cursor back to home.
X     */
X    XwTextSetInsertPos(display_Wgt, 0);	
X  }
X  else {
X    /*
X     * When done writing def to the buffer, display the text.
X     */
X    text[end_idx] = '\000';
X    ARGLIST_RESET();
X    ARGLIST_ADD(XtNstring, text);
X    XtSetValues(display_Wgt, ARGLIST());
X  }
X}
X
X
X/******************************************************************************
X *
X ******************************************************************************/
XDisplay_Def_Show_Help()
X{
X  ARGLIST_RESET();
X  ARGLIST_ADD(XtNstring, user_prefs.help_text);
X  XtSetValues(display_Wgt, ARGLIST());
X}
END_OF_FILE
if test 6985 -ne `wc -c <'display_def.c'`; then
    echo shar: \"'display_def.c'\" unpacked with wrong size!
fi
# end of 'display_def.c'
fi
if test -f 'xwebster.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xwebster.c'\"
else
echo shar: Extracting \"'xwebster.c'\" \(19753 characters\)
sed "s/^X//" >'xwebster.c' <<'END_OF_FILE'
X/* -*-C-*-
X********************************************************************************
X*
X* File:         xwebster.c
X* RCS:          $Header: xwebster.c,v 1.10 88/09/13 17:20:01 mayer Exp $
X* Description:  X11 + HP-Xwidgets interface to a webster dictionary server
X* Author:       Niels Mayer, HPLabs
X* Created:      Wed Aug 31 14:09:08 1988
X* Modified:     Tue Sep 13 15:38:42 1988 (Niels Mayer) mayer at hplnpm
X* Language:     C
X* Package:      N/A
X* Status:       G-Job
X*
X* xwebster - dictionary browser
X*
X* Copyright 1988 Hewlett-Packard Company
X*
X* Permission to use, copy, modify, and distribute this software and its
X* documentation for any purpose and without fee is hereby granted, provided
X* that the above copyright notice appear in all copies and that both that
X* copyright notice and this permission notice appear in supporting
X* documentation, and that the name of HP not be used in advertising or
X* publicity pertaining to distribution of the software without specific,
X* written prior permission.  HP makes no representations about the
X* suitability of this software for any purpose.  It is provided "as is"
X* without express or implied warranty.
X*
X* Please send any improvements, bug fixes, useful modifications, and comments
X* to mayer at hplabs.hp.com.
X********************************************************************************
X*/
Xstatic char rcs_identity[] = "@(#)$Header: xwebster.c,v 1.10 88/09/13 17:20:01 mayer Exp $";
Xchar xwebster_version[] = "Xwebster, version 1.01";
X
X/* 
X * Some aspects of this program were inspired by the first
X * C-language translation of the webster client program, webster.c, done by:
X *                   "David A. Curry
X *                    Purdue University
X *                    Engineering Computer Network
X *                    April, 1986"
X * The only copyright notice appearing in the webster.c source is:
X *   "Webster's 7th Collegiate Dictionary, Copyright (C) 1963 by Merriam-Webster,
X *    Inc.  No part of this information may be copied or reprinted without the
X *    express written consent of the publisher."
X */
X
X#include "xwebster.h"
X#include "user_prefs.h"
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <netdb.h>
X#include <memory.h>
X#include <Xw/VPW.h>
X#include <X11/cursorfont.h>
X#include <X11/Xos.h>
X
Xint Webster_Connect_To_Server();
XXtInputCallbackProc Webster_Get_Server_Output();
XXtInputCallbackProc Webster_Handle_Server_Exception();
X
X
Xint webster_Socket = NULL;
Xstatic XtInputId webster_xinput;
Xstatic XtInputId webster_xexcept;
Xstatic Widget toplevel_Wgt = NULL;
XUSER_PREFS_DATA user_prefs; /* extern declared in user_prefs.h, really here */
X
X/* 
X * Data on how user-customization resources are interpreted:
X * this must be kept up to date with data structure USER_PREFS_DATA_PTR 
X * in user_prefs.h
X *
X * My philosophy is to place all my intended defaults in 
X * APPDEFAULTSDIR/Xwebster, so that the program doesn't have to
X * be recompiled just to change a simple default. Thus I don't always have
X * the best defaults in this structure.
X */
Xstatic XtResource resources[] = {
X  {"helpText", "HelpText",
X     XtRString, sizeof(String),
X     XtOffset(USER_PREFS_DATA_PTR, help_text),
X     XtRString, "Warning -- Someone forgot to install APPDEFAULTSDIR/Xwebster"},
X  {"hostAddrList", "HostAddrList",
X     XtRString, sizeof(String),
X     XtOffset(USER_PREFS_DATA_PTR, host_addr_list),
X     XtRString, "10.0.0.51 26.0.0.73"},
X  {"hostPort", "HostPort",
X     XtRInt, sizeof(int),
X     XtOffset(USER_PREFS_DATA_PTR, host_port),
X     XtRString, "103"},
X  {"hostServiceName", "HostServiceName",
X     XtRString, sizeof(String),
X     XtOffset(USER_PREFS_DATA_PTR, host_service_name),
X     XtRString, "webster"},
X  {"wordInputWidgetWidth", "WordInputWidgetWidth",
X     XtRInt, sizeof(int),
X     XtOffset(USER_PREFS_DATA_PTR, word_input_Wgt_width),
X     XtRString, "30"},
X  {"useEditorAsDisplay", "UseEditorAsDisplay", 
X     XtRBoolean, sizeof(Boolean),
X     XtOffset(USER_PREFS_DATA_PTR, use_editor_as_display),
X     XtRString, "FALSE"},  
X  {"displayWidth", "DisplayWidth",
X     XtRInt, sizeof(int),
X     XtOffset(USER_PREFS_DATA_PTR, display_width),
X     XtRString, "85"},
X  {"displayHeight", "DisplayHeight",
X     XtRInt, sizeof(int),
X     XtOffset(USER_PREFS_DATA_PTR, display_height),
X     XtRString, "10"},
X  {"numWordsBeforeRefresh", "NumWordsBeforeRefresh",
X     XtRInt, sizeof(int),
X     XtOffset(USER_PREFS_DATA_PTR, num_words_before_refresh),
X     XtRString, "20"}
X};
X
X
X/******************************************************************************
X *
X ******************************************************************************/
Xmain(argc, argv)
X     int             argc;
X     char          **argv;
X{
X  /* 
X   * Initialize the toolkit, place xwebster-defined resources in user_prefs.
X   */
X  toplevel_Wgt = XtInitialize(argv[0], "Xwebster", NULL, 0, &argc, argv);
X  XwRegisterConverters();	/* Xw WORKAROUND-KLUDGE -- needed for XtRTileType converter, which should be registered but isn't */
X  XtGetApplicationResources(toplevel_Wgt, &user_prefs, 
X			    resources, XtNumber(resources), NULL, 0);
X  
X  {
X    Widget panel_Wgt = XtCreateManagedWidget("panel", XwvPanedWidgetClass, 
X					     toplevel_Wgt, NULL, 0);
X    Controlpanel_Titlebar_Init(panel_Wgt);
X    Wordlist_Init(panel_Wgt);
X    Controlpanel_Init(panel_Wgt);
X    Display_Def_Init(panel_Wgt);
X  }
X  XtRealizeWidget(toplevel_Wgt);
X  XDefineCursor(XtDisplay(toplevel_Wgt), XtWindow(toplevel_Wgt), 
X		XCreateFontCursor(XtDisplay(toplevel_Wgt), XC_plus));
X  XtMainLoop();
X}
X
X
X/******************************************************************************
X * originally from webster.c, but by now, highly modified.
X ******************************************************************************/
Xint Webster_Connect_To_Server(host_addr, host_port, host_service_name)
X  char* host_addr;
X  int host_port;
X  char* host_service_name;
X{
X  struct sockaddr_in sin;
X  register int s;
X  register struct servent *sp;
X
X  /* Look up the host in the host file. */
X  memset( (char*) &sin, '\000', sizeof(struct sockaddr_in));
X  sin.sin_family = AF_INET;
X  sin.sin_addr.s_addr = inet_addr(host_addr);
X  if (sin.sin_addr.s_addr == -1) {
X    fprintf(stderr, "xwebster: %s: unknown host.\n", host_addr);
X    return(-1);
X  }
X
X  if ((sp = getservbyname(host_service_name, "tcp")) == NULL)
X    sin.sin_port = htons(host_port);
X  else
X    sin.sin_port = sp->s_port;
X
X  /* Get a TCP socket. */
X  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
X    perror("xwebster: socket");
X    return(-1);
X  }
X
X  /* Try to connect. */
X  if (connect(s, &sin, sizeof(struct sockaddr_in)) < 0) {
X    perror("xwebster: connect");
X    return(-1);
X  }
X  return(s);
X}
X
XXtInputCallbackProc
XWebster_Handle_Server_Exception(client_data, source_fildes, id)
X     caddr_t   client_data;
X     int       source_fildes;
X     XtInputId id;
X{
X  extern void Webster_Disconnect();
X  
X  Webster_Disconnect();
X}
X
X/******************************************************************************
X * This procedure is called (indirectly, via XtAddInput() callback) from 
X * XtMainLoop() in main() whenever new input appears on webster_Socket. This 
X * procedure will read all the data from webster_Socket, and then call 
X * Process_Webster_Line() for each line of input received. If an incomplete 
X * line of text is received, then this procedure will buffer that line until
X * the next time it gets called from the callback.
X ******************************************************************************/
XXtInputCallbackProc Webster_Get_Server_Output(client_data, source_fildes, id)
X     caddr_t   client_data;
X     int       source_fildes;
X     XtInputId id;
X{
X  unsigned nbytes;
X  char readbuf[BUFSIZ];
X  static char buf[2*BUFSIZ]; /* overkill -- buf shouldn't get longer than BUFSIZ+
X				the size of any remaining line (max 80). */
X  static char linebuf[BUFSIZ];
X  static int buf_end_idx = 0;	/* init value only on first call */
X  int prev_buf_end_idx;
X  int prev_buf_idx;
X  register int buf_idx;
X  register int linebuf_idx;
X  extern void Webster_Disconnect();
X  
X  if (webster_Socket == NULL)
X  	Webster_Reconnect();
X  if (webster_Socket == NULL)
X    return;
X  if ((nbytes = read(webster_Socket, readbuf, BUFSIZ)) <= 0) {
X    Webster_Disconnect();
X    return;
X  }
X  memcpy(&(buf[buf_end_idx]), readbuf, nbytes);	/* append new input to buf */
X  buf_end_idx += nbytes;
X  buf[buf_end_idx] = '\000';	/* NULL marks end of buf */
X  prev_buf_end_idx = buf_end_idx;
X
X  buf_idx = 0; 
X  while (1) {			/* process lines till none left: exits w/ break*/
X    linebuf_idx = 0;
X    prev_buf_idx = buf_idx;
X    /** try to copy a line of characters to linebuf, quitting on EOF or \000 **/
X    while (((buf[buf_idx] & 0177) != '\n')
X	   && (buf[buf_idx] != '\000')
X	   && (buf[buf_idx] != '\200'))	/* webster server's <EOF> char */
X      linebuf[linebuf_idx++] = buf[buf_idx++] & 0177;
X
X    if ((buf[buf_idx] & 0177) == '\n') { /* copy to linebuf stopped at LF */
X      linebuf[linebuf_idx-1] = '\n'; /* overwrite CR with LF */
X      linebuf[linebuf_idx] = '\000'; /* NULL terminate linebuf */
X      Process_Webster_Line(linebuf); /* process a line of input */
X      buf_idx++;		/* skip over \n in buf */
X      buf_end_idx -= linebuf_idx + 1; /* shorten by len(linebuf)+len(\n) */
X    }
X    else if (buf[buf_idx] == '\200') { /* copy to linebuf stopped at EOF */
X      Process_Webster_Line(NULL); /* signal special case of EOF */
X      buf_idx++;		/* skip over \200 in buf */
X      buf_end_idx -= linebuf_idx + 1; /* shorten by len(linebuf)+len(\200) */
X    }
X    else {			/* copy to linebuf stopped at \000 (end of buf) */
X      /** IF characters were transferred from buf to linebuf... **/
X      if (prev_buf_end_idx != buf_end_idx)
X	/** ...THEN shiftLeft characters that weren't transferred. **/
X	memccpy(&(buf[0]), &(buf[prev_buf_idx]), '\000', 2*BUFSIZ); 
X      break;			/*@@@---EXIT THE WHILE LOOP---@@@*/
X      /* Buf_end_idx is now really end of buf: on the next call to this proc,
X	 new input will append after remaining unprocessed input in buf.*/
X    }
X  }
X}
X
X
X/******************************************************************************
X * This is a "state machine" procedure that is called for every line of text
X * received from the webster server. The state of the webster program is
X * contained in the static variable webster_state which lets this procedure
X * handle the current line of text in a way that depends on what the previous
X * line of text was. For more info on the webster protocol that is embodied in
X * this procedure, do "/usr/bin/telnet 10.0.0.51 103" and then type "HELP<cr>".
X ******************************************************************************/
X#define WEBSTER_READY 0
X#define GET_WORDLIST 1
X#define GET_XREFS 2
X#define GET_DEFINITION 3
X/*------------------------------------------------------------------------------*/
XProcess_Webster_Line(line)
X     char* line;
X{
X  static int num_xrefs;
X  static int webster_state = WEBSTER_READY;
X  static int current_wordlist_is_xrefs = FALSE;
X
X  switch(webster_state) {
X  case WEBSTER_READY:
X    if (line == NULL) {
X      Wordlist_Reset();
X      Controlpanel_Reactivate(); /* ready for user input */
X    } else if (strncmp(line, "AMBIGUOUS ", 10) == 0) {	/* returned by COMPLETE */
X      int num_ambiguities = 0;
X      sscanf(line, "AMBIGUOUS %d\n", &num_ambiguities);
X      sprintf(temptext, "Ambiguous! Matches %d other words.", num_ambiguities);
X      Controlpanel_Titlebar_Set_Label(temptext);
X      XBell(XtDisplay(toplevel_Wgt), 100);
X      Wordlist_Reset();
X      Controlpanel_Reactivate(); /* ready for user input */
X      /* webster_state = WEBSTER_READY; */
X    }
X    else if (strncmp(line, "COMPLETION ", 11) == 0) { /* returned by COMPLETE */
X      sscanf(line, "COMPLETION %s\n", temptext);
X      Controlpanel_Set_Input_Word(temptext);
X      Controlpanel_Titlebar_Set_Label("\000");
X      Wordlist_Reset();
X      Controlpanel_Reactivate(); /* ready for user input */
X      /* webster_state = WEBSTER_READY; */
X    }
X    else if (strncmp(line, "MATCHS 0\n", 9) == 0) { /* returned by ENDINGS */
X      XBell(XtDisplay(toplevel_Wgt), 100);
X      Controlpanel_Titlebar_Set_Label("No matching words!");
X      Wordlist_Reset();
X      Controlpanel_Reactivate(); /* ready for user input */
X      /* webster_state = WEBSTER_READY; */
X    }      
X    else if (strncmp(line, "MATCHS\n", 7) == 0) { /* returned by ENDINGS */
X      Controlpanel_Titlebar_Set_Label("Choose a word:");
X      Wordlist_Reset();
X      webster_state = GET_WORDLIST; current_wordlist_is_xrefs = FALSE;
X    }
X    else if (strncmp(line, "SPELLING 0\n", 11) == 0) { /* returned by DEFINE and SPELL */
X      Controlpanel_Titlebar_Set_Label("No such word!");
X      XBell(XtDisplay(toplevel_Wgt), 100);
X      Wordlist_Reset();
X      Controlpanel_Reactivate(); /* ready for user input */
X      /* webster_state = WEBSTER_READY; */
X    }
X    else if (strncmp(line, "SPELLING\n", 9) == 0) { /* returned by DEFINE */
X      Controlpanel_Titlebar_Set_Label("Word not in dictionary. Do you mean:");
X      Wordlist_Reset();
X      webster_state = GET_WORDLIST; current_wordlist_is_xrefs = FALSE;
X    }
X    else if (strncmp(line, "WILD 0\n", 7) == 0) { /* returned by DEFINE */
X      Controlpanel_Titlebar_Set_Label("No Match!");
X      XBell(XtDisplay(toplevel_Wgt), 100);
X      Wordlist_Reset();
X      Controlpanel_Reactivate();
X      /* webster_state = WEBSTER_READY; */
X    } 
X    else if (strncmp(line, "WILD\n", 5) == 0) {	/* returned by DEFINE */
X      Controlpanel_Titlebar_Set_Label("Choose a word:");
X      Wordlist_Reset();
X      webster_state = GET_WORDLIST; current_wordlist_is_xrefs = FALSE;
X    }      
X    else if (strncmp(line, "DEFINITION ", 11) == 0) { /* returned by DEFINE */
X      sscanf(line, "DEFINITION %d\n", &num_xrefs);
X      if (num_xrefs == 0) {
X	/** don't clear the wordlist if last define req came from the wordlist **/
X	if (Controlpanel_Cur_Word_Is_From_TextEdit()) {
X	  Wordlist_Reset();
X	  Controlpanel_Titlebar_Set_Label("\000");
X	}
X	webster_state = GET_DEFINITION;
X      }
X      else {
X	/** don't clear old xrefs if new set of xrefs gend from a word in old xrefs **/
X	if (Controlpanel_Cur_Word_Is_From_TextEdit() || !current_wordlist_is_xrefs)
X	  Wordlist_Reset();
X	Controlpanel_Titlebar_Set_Label("Cross References:");
X	webster_state = GET_XREFS; current_wordlist_is_xrefs = TRUE;
X      }
X    }
X    else if (strncmp(line, "ERROR RECOVERABLE", 17) == 0) {
X      Controlpanel_Titlebar_Set_Label("Error:");
X      Display_Def_Text_Reset();
X      Display_Def_Text_Append(line);
X      Display_Def_Refresh();
X      XBell(XtDisplay(toplevel_Wgt), 100); XBell(XtDisplay(toplevel_Wgt), 100);
X      Wordlist_Reset();
X      Controlpanel_Reactivate();
X      /* webster_state = WEBSTER_READY; */
X    }
X    else if (strncmp(line, "ERROR FATAL", 11) == 0) {
X      XBell(XtDisplay(toplevel_Wgt), 100); XBell(XtDisplay(toplevel_Wgt), 100);
X      XBell(XtDisplay(toplevel_Wgt), 100); XBell(XtDisplay(toplevel_Wgt), 100);
X      Controlpanel_Titlebar_Set_Label("Error:");
X      Display_Def_Text_Reset();
X      Display_Def_Text_Append(line);
X      Display_Def_Refresh();
X      XtRemoveInput(webster_xinput);
X      XtRemoveInput(webster_xexcept);
X      close(webster_Socket);
X      webster_Socket = NULL;
X      Controlpanel_Reactivate();
X    }
X    else {
X      sprintf(temptext, "unknown server message: %s", line);
X      Controlpanel_Titlebar_Set_Label(temptext); 
X      XBell(XtDisplay(toplevel_Wgt), 100); XBell(XtDisplay(toplevel_Wgt), 100);
X      Wordlist_Reset();
X      Controlpanel_Reactivate();
X      /* webster_state = WEBSTER_READY; */
X    }
X    break;
X  case GET_WORDLIST:		/* get words, one per line, till EOF reached */
X    if (line == NULL) {		/* EOF reached */
X      Wordlist_Show();
X      Controlpanel_Reactivate(); /* ready for user input */
X      webster_state = WEBSTER_READY;
X    }
X    else {
X      sscanf(line, "%*d %[^\n]", temptext);
X      Wordlist_Add(temptext);
X      /* webster_state = GET_WORDLIST; */
X    }
X    break;
X  case GET_XREFS:
X    if (line == NULL) {
X      Display_Def_Refresh();	/* show the definition */
X      Controlpanel_Reactivate();
X      webster_state = WEBSTER_READY;
X      break;
X    }
X    sscanf(line, "%*d %[^\n]", temptext);
X    Wordlist_Add(temptext);
X    num_xrefs--;
X    if (num_xrefs == 0) {
X      Wordlist_Show();
X      webster_state = GET_DEFINITION;
X    }
X    /* else
X       webster_state = GET_XREFS; */
X    break;
X  case GET_DEFINITION:
X    if (line == NULL) {		/* EOF reached */
X      Controlpanel_Set_Input_Word(NULL);
X      Display_Def_Refresh();	/* show the definition */
X      Controlpanel_Reactivate(); /* ready for user input */
X      webster_state = WEBSTER_READY;
X    }
X    else {
X      Display_Def_Text_Append(line);
X      /* webster_state = GET_DEFINITION; */
X    }
X    break;
X  default:
X    XBell(XtDisplay(toplevel_Wgt), 100);
X    Controlpanel_Titlebar_Set_Label("error -- xwebster programmer goofed");
X    Controlpanel_Reactivate();
X    webster_state = WEBSTER_READY;
X    break;
X  }
X}
X
X
X/*
X * Try to connect up to a webster server. Xwebster will try each host address
X * in the Xdefault hostAddrList successively until it connects succesfully
X * or until it runs out of hosts to try to connect.
X */
XWebster_Reconnect()
X{
X	/* 
X	 *  If you don't have strtok(), get one; For example, from Henry
X	 *  Spencer's public domain strings package. Or in the worst
X	 *  case, write one. It's useful.
X	 */
X	extern char *strtok();
X	char* host_addr = strtok(user_prefs.host_addr_list, " \t");
X	char buf[128];
X
X	Display_Def_Text_Reset();
X	do {
X		webster_Socket = Webster_Connect_To_Server(host_addr,
X		 user_prefs.host_port, user_prefs.host_service_name);
X		if (webster_Socket < 0) {
X			Controlpanel_Titlebar_Set_Label("Error:");
X			(void) sprintf(buf, "Problem with server host %s\n",
X			 host_addr);
X			Display_Def_Text_Append(buf);
X			Display_Def_Refresh();
X		}
X	} while ((webster_Socket < 0)
X		&& ((host_addr = strtok(NULL, " \t")) != NULL));
X	
X	if (webster_Socket < 0) {
X		Display_Def_Text_Reset();
X		Display_Def_Text_Append(
X"Couldn't access a webster host. Be sure that the following Xdefaults\n");
X		Display_Def_Text_Append(
X"have been set correctly for accessing your Webster server:\n");
X		Display_Def_Text_Append(
X"*hostAddrList *hostPort *hostServiceName\n");
X		Display_Def_Text_Append(sprintf(buf, 
X"See %s/Xwebster for details.\n", APPDEFAULTSDIR));
X		Display_Def_Refresh();
X		return;
X	} else {
X		webster_xinput = XtAddInput(webster_Socket, XtInputReadMask,
X		 Webster_Get_Server_Output, NULL);
X		webster_xexcept = XtAddInput(webster_Socket, XtInputExceptMask,
X		 Webster_Handle_Server_Exception, NULL);
X	}
X	
X}
X
Xvoid
XWebster_Disconnect()
X{
X  char errbuf[128];
X  extern int sys_nerr;
X  extern char *sys_errlist[];
X  extern int errno;
X
X  Display_Def_Text_Reset();
X  if (errno < sys_nerr) {
X    (void) sprintf(errbuf, "webster server error:", sys_errlist[errno]);
X  } else {
X    (void) strcpy(errbuf, "webster server error: unknown error");
X  }
X  Display_Def_Text_Append(errbuf);
X  Display_Def_Refresh();
X  XtRemoveInput(webster_xinput);
X  XtRemoveInput(webster_xexcept);
X  close(webster_Socket);
X  webster_Socket = NULL;
X  /* No point reconnecting - we'll wait till we try to do something. */
X}
X
X
XWebsterSend(buf)
Xchar *buf;
X{
X  extern int sys_nerr;
X  extern char *sys_errlist[];
X  extern int errno;
X
X  if (webster_Socket == NULL)
X  	Webster_Reconnect();
X  if (webster_Socket == NULL)
X	return;
X  if (send(webster_Socket, buf, strlen(buf), 0) < 0) {
X    char errbuf[128];
X    if (errno < sys_nerr) {
X      Display_Def_Text_Reset();
X      (void) sprintf(errbuf, "send error:", sys_errlist[errno]);
X      Display_Def_Text_Append(errbuf);
X      Display_Def_Refresh();
X    }
X  }
X}
X
END_OF_FILE
if test 19753 -ne `wc -c <'xwebster.c'`; then
    echo shar: \"'xwebster.c'\" unpacked with wrong size!
fi
# end of 'xwebster.c'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x



More information about the Comp.sources.x mailing list