v03i044: Webster client, Part01/02

Mike Wexler mikew at wyse.wyse.com
Sat Mar 11 05:09:39 AEST 1989


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

[This is the official version of xweb.  Please replace the last one
posted with this one.  I have set the archive name to be the same
as the last posting so that this will replace the existing entry
in archives. -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 AUTHOR Xwebster.ad user_prefs.h xwebster.c
#   xwebster.h
# Wrapped by mikew at wyse on Fri Mar 10 11:06:42 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'\" \(5959 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		Human-Computer Interaction Department.
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 expects to use the X11r3 HP Xwidgets library, libXw.a, and the
XX11R3 Xt intrinsics, libXt.a (with the latest patches, particularly
Xfixes/fix8). The HP widgets are on the X11R3 tape (under
Xcontrib/widgets/Xhp/Xw/), and require a set of fixes by Martin Friedmann
X<martin at citi.umich.edu> in order to work under R3. These will probably be
Xavailable from the usual archive sites, and in particular, from
Xexpo.lcs.mit.edu:contrib/Xhp.patch.works.tar.Z.
X
XXwebster has been tested under HPUX 6.2 and SunOS3.5. I've avoided any
Xparticularly hairy SYSVisms, so you sholdn't have any trouble getting it to
Xrun on your machine. You'll need the strtok() call - if your system doesn't
Xhave it (HPUX, System V, SunOS have it), get Henry Spencer's public domain
Xstrings(3) library from some comp.sources.unix archive site.
X
X				----------
X
XCUSTOMIZING:
X
XAll the resources for xwebster are specified in the application default
Xfile Xwebster.ad, which MUST be installed in APPDEFAULTSDIR/Xwebster.  Fully
Xqualified resource names are used in this app-defaults file so as to
Xdocument the widget hierarchy in the application. Documentation on
Xcustomizing xwebster also appears in this defaults file.  (APPDEFAULTSDIR
Xis set in the imake defaults, it is usually /usr/lib/X11/app-defaults/)
X
XParameters for connecting to a webster server are contained in the
Xresources "hostAddrList", "hostPort", and "hostServiceName". See the
XXwebster.ad 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
XI personally use the following set of .Xdefaults for xwebster, in addition
Xto the defaults provided by APPDEFAULTSDIR/Xwebster:
X
X#
X# Global Defaults.
X#
X*foreground:			White
X*background:			DarkSlateGray
X*font:				6x13
X*Sash*background:		wheat
X*Sash*foreground:		black
X*topShadowColor:		light blue
X*topShadowTile:			foreground
X*bottomShadowColor:		black
X*bottomShadowTile:		foreground
X*TextEdit*background:		IndianRed
X*TextEdit*foreground:		Green
X*TextEdit*highlightThickness:	1
X*TextEdit*font:			fixed
X*StaticText*background:         DarkSlateGray
X*StaticText*foreground:         White
X*StaticText.BorderWidth:	1
X*StaticText.ShadowOn:		yes
X*StaticText*font:		variable
X*PushButton*background: 	Blue
X*PushButton*foreground:		White
X*PushButton*font:		variable
X
X#
X# Xwebster
X#
Xxwebster*hostAddrList: 26.0.0.73 10.0.0.51
Xxwebster*hostPort: 103
Xxwebster*useEditorAsDisplay: TRUE
Xxwebster*highlightColor: white
Xxwebster*highlightTile: foreground
Xxwebster*display.foreground: White
Xxwebster*display.background: IndianRed
Xxwebster*word_input*foreground: Green
Xxwebster*word_input*background: IndianRed
X
X				----------
X
XHISTORY/THANKS/AUTHORS:
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
XXwebster was originally written and released by Niels Mayer
X<mayer at hplabs.hp.com> on the X11r3 contrib tape. Mark Moraes
X<moraes at csri.toronto.edu> took that version, updated it to work with the r3
XHP Xwidgets and r3 Toolkit Intrinsics, and fixed a bunch of stupid bugs
Xthat were making xwebster dump core an a SUN. He also made xwebster
Xdisconnect gracefully after the webster dictionary server times out.
XFinally, he wrote up a manual page and put together an Imake file. Thanks
XMark! 
X
XIf you have contributions to make to xwebster, please send them to me via
Xemail.
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 5959 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'AUTHOR' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AUTHOR'\"
else
echo shar: Extracting \"'AUTHOR'\" \(352 characters\)
sed "s/^X//" >'AUTHOR' <<'END_OF_FILE'
XMailing Address:
X	Hewlett Packard
X	Niels Mayer 3U/18		
X	P.O. Box 10490
X	Palo Alto, CA  94303-0969
X
XStreet Address:
X	Niels Mayer
X	Hewlett-Packard Laboratories
X	Software Technology Lab
X	Human-Computer Interaction Department
X	Building 3U
X	1501 Page Mill Rd.
X	Palo Alto CA. 94304-1126
X
XEmail Address:
X	internet: mayer at hplabs.hp.com
X	uucp:     hplabs!mayer
END_OF_FILE
if test 352 -ne `wc -c <'AUTHOR'`; then
    echo shar: \"'AUTHOR'\" unpacked with wrong size!
fi
# end of 'AUTHOR'
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'\" \(19325 characters\)
sed "s/^X//" >'Xwebster.ad' <<'END_OF_FILE'
X################################################################################
X#
X# File:         Xwebster
X# RCS:          $Header: Xwebster.ad,v 1.8 89/03/06 01:38:49 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 Mar  6 01:10:41 1989 (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, 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*panel.sashIndent: -20
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 == *panel.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 19325 -ne `wc -c <'Xwebster.ad'`; then
    echo shar: \"'Xwebster.ad'\" unpacked with wrong size!
fi
# end of 'Xwebster.ad'
fi
if test -f 'user_prefs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'user_prefs.h'\"
else
echo shar: Extracting \"'user_prefs.h'\" \(1892 characters\)
sed "s/^X//" >'user_prefs.h' <<'END_OF_FILE'
X/* -*-C-*-
X********************************************************************************
X*
X* File:         user_prefs.h
X* RCS:          $Header: user_prefs.h,v 1.5 89/03/06 01:42:00 mayer Exp $
X* Description:  type definition and global datastructure for user preferences
X* Author:       Niels Mayer, HPLabs
X* Created:      Thu Aug 11 00:06:04 1988
X* Modified:     Tue Sep 13 15:34:34 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_user_prefs[] = "@(#)$Header: user_prefs.h,v 1.5 89/03/06 01:42:00 mayer Exp $";
X
Xtypedef struct {
X  String help_text;
X  String host_addr_list;	/* a list of whitespace separated host addrs */
X  int    host_port;
X  String host_service_name;
X  int    word_input_Wgt_width;
X  int    use_editor_as_display;	/* if TRUE use TextEdit, else StaticText */
X  int    display_width;
X  int    display_height;
X  int    num_words_before_refresh;
X} USER_PREFS_DATA, *USER_PREFS_DATA_PTR;
X
Xextern USER_PREFS_DATA user_prefs;
END_OF_FILE
if test 1892 -ne `wc -c <'user_prefs.h'`; then
    echo shar: \"'user_prefs.h'\" unpacked with wrong size!
fi
# end of 'user_prefs.h'
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'\" \(21440 characters\)
sed "s/^X//" >'xwebster.c' <<'END_OF_FILE'
X/* -*-C-*-
X********************************************************************************
X*
X* File:         xwebster.c
X* RCS:          $Header: xwebster.c,v 1.12 89/03/06 03:43:31 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:     Mon Mar  6 03:43:14 1989 (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.12 89/03/06 03:43:31 mayer Exp $";
Xchar xwebster_version[] = "Xwebster, version 1.10";
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
Xstatic XtInputCallbackProc Webster_Get_Server_Output();
Xstatic void Process_Webster_Line();
Xstatic int Webster_Connect_To_Server();
Xstatic void Webster_Reconnect();
Xstatic XtInputCallbackProc Webster_Handle_Server_Exception();
Xstatic void Webster_Disconnect();
X
Xint              webster_Socket = NULL;
Xstatic XtInputId webster_xinput;
Xstatic XtInputId webster_xexcept;
Xstatic Widget    toplevel_Wgt = NULL;
XDisplay*         display;
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    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  display = XtDisplay(toplevel_Wgt);
X  XDefineCursor(display, XtWindow(toplevel_Wgt), 
X		XCreateFontCursor(display, XC_plus));
X  XtMainLoop();
X}
X
X/******************************************************************************
X * This procedure is called indirectly, via XtAddInput() callback from 
X * XtMainLoop() whenever new input appears on webster_Socket. This callback
X * is setup in procedure Webster_Reconnect().
X * This 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 ******************************************************************************/
Xstatic XtInputCallbackProc 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  
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 * 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/*-----------------------------------------------------------------------------*/
Xstatic void Process_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    } 
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(display, 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(display, 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(display, 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(display, 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(display, 100); XBell(display, 100);
X      Wordlist_Reset();
X      Controlpanel_Reactivate();
X      /* webster_state = WEBSTER_READY; */
X    }
X    else if (strncmp(line, "ERROR FATAL", 11) == 0) {
X      XBell(display, 100); XBell(display, 100);
X      XBell(display, 100); XBell(display, 100);
X      Display_Def_Text_Reset();
X      Display_Def_Text_Append(line);
X      Display_Def_Refresh();
X      Webster_Disconnect();
X      Controlpanel_Reactivate();
X    }
X    else {
X      sprintf(temptext, "unknown server message: %s", line);
X      Controlpanel_Titlebar_Set_Label(temptext); 
X      XBell(display, 100); XBell(display, 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(display, 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 * returns 0 if it couldn't send, else 1.
X ******************************************************************************/
Xint Webster_Send(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(0);
X  if (send(webster_Socket, buf, strlen(buf), 0) < 0) {
X    Display_Def_Text_Reset();
X    if (errno < sys_nerr)
X      (void) sprintf(temptext, "Error sending to webster server: %s\n", sys_errlist[errno]);
X    else
X      (void) strcpy(temptext, "Error sending to webster server: unknown error\n");
X    Display_Def_Text_Append(temptext);
X    Display_Def_Refresh();
X    return(0);
X  }
X  return(1);
X}
X
X/******************************************************************************
X * originally from webster.c, but by now, highly modified.
X ******************************************************************************/
Xstatic int 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    return(-1);
X  }
X
X  /* Try to connect. */
X  if (connect(s, &sin, sizeof(struct sockaddr_in)) < 0) {
X    return(-1);
X  }
X  return(s);
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 ******************************************************************************/
Xstatic void Webster_Reconnect()
X{
X  extern int   sys_nerr;
X  extern char* sys_errlist[];
X  extern int   errno;
X  extern char* strtok();	/* if you don't have this, get the source from 
X				   Henry Spencer's public domain strings package */
X
X  char* host_addr = strtok(user_prefs.host_addr_list, " \t");
X  Display_Def_Text_Reset();
X  do {
X    sprintf(temptext, "Trying webster server at address %s ...\n", host_addr);
X    Display_Def_Text_Append(temptext);
X    Display_Def_Refresh();
X    XSync(display, FALSE);
X    while (XtPending()) {	/* since we can't get back to XtMainLoop yet-*/
X      XEvent event;		/*-we process the events here... (yech) */
X      XtNextEvent(&event);
X      XtDispatchEvent(&event);
X    }
X    webster_Socket = Webster_Connect_To_Server(host_addr, user_prefs.host_port, 
X					       user_prefs.host_service_name);
X    if (webster_Socket < 0) {
X      Display_Def_Text_Reset();
X      (void) sprintf(temptext, "Problem with server host %s\n", host_addr);
X      Display_Def_Text_Append(temptext);
X      if (errno < sys_nerr)
X	(void) sprintf(temptext, "webster server error: %s\n", sys_errlist[errno]);
X      else
X	(void) strcpy(temptext, "webster server error: unknown error\n");
X      Display_Def_Text_Append(temptext);
X    }
X  } while ((webster_Socket < 0) && ((host_addr = strtok(NULL, " \t")) != NULL));
X	
X  if (webster_Socket < 0) {
X    Controlpanel_Titlebar_Set_Label("Error:");
X    Display_Def_Text_Reset();
X    Display_Def_Text_Append("Couldn't access a webster host. Be sure that the following Xdefaults\n");
X    Display_Def_Text_Append("have been set correctly for accessing your Webster server:\n");
X    Display_Def_Text_Append("*hostAddrList *hostPort *hostServiceName\n");
X    sprintf(temptext, "See %s/Xwebster for details.\n", APPDEFAULTSDIR);
X    Display_Def_Text_Append(temptext);
X    Display_Def_Refresh();
X    webster_Socket = NULL;  /* indicates we still don't have server connection */
X  } 
X  else {
X    Controlpanel_Titlebar_Set_Label(xwebster_version);
X    Display_Def_Text_Reset();
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/******************************************************************************
X * This procedure is called indirectly, via XtAddInput() callback from 
X * XtMainLoop() whenever an exception occurs on webster_Socket. This callback
X * is setup in procedure Webster_Reconnect().
X ******************************************************************************/
Xstatic XtInputCallbackProc Webster_Handle_Server_Exception(client_data, source_fildes, id)
X     caddr_t   client_data;
X     int       source_fildes;
X     XtInputId id;
X{
X  Webster_Disconnect();
X}
X
X/******************************************************************************
X *
X ******************************************************************************/
Xstatic void Webster_Disconnect()
X{
X  extern int   sys_nerr;
X  extern char* sys_errlist[];
X  extern int   errno;
X
X  Controlpanel_Titlebar_Set_Label("Webster Server Error:");
X  Display_Def_Text_Reset();
X  if (errno < sys_nerr)
X    (void) sprintf(temptext, "Webster server error: %s\n", sys_errlist[errno]);
X  else
X    (void) strcpy(temptext, "Webster server error: unknown error\n");
X  Display_Def_Text_Append(temptext);
X  Display_Def_Text_Append("Webster server connection closed.\n");
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}
END_OF_FILE
if test 21440 -ne `wc -c <'xwebster.c'`; then
    echo shar: \"'xwebster.c'\" unpacked with wrong size!
fi
# end of 'xwebster.c'
fi
if test -f 'xwebster.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xwebster.h'\"
else
echo shar: Extracting \"'xwebster.h'\" \(2358 characters\)
sed "s/^X//" >'xwebster.h' <<'END_OF_FILE'
X/* -*-C-*-
X********************************************************************************
X*
X* File:         xwebster.h
X* RCS:          $Header: xwebster.h,v 1.5 89/03/06 01:42:04 mayer Exp $
X* Description:  Miscellaneous macros
X* Author:       Niels Mayer, HPLabs
X* Created:      Wed Aug 31 14:09:08 1988
X* Modified:     Tue Sep 13 15:33:32 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_xwebster[] = "@(#)$Header: xwebster.h,v 1.5 89/03/06 01:42:04 mayer Exp $";
X
X#include <X11/Xos.h>
X#include <X11/StringDefs.h>
X#include <X11/Intrinsic.h>
X#include <Xw/Xw.h>
X
X
X/*----------------------------------------------------------------------------
X * Kludges to sweeten Xt's ugly argument processing for widget creation.
X *---------------------------------------------------------------------------*/
Xstatic Arg _args[100];
Xstatic int _num_args;
X
X#define ARGLIST_RESET() \
X  _num_args = 0
X
X#define ARGLIST_ADD(name, value) \
X  XtSetArg(_args[_num_args], (name), (value)); _num_args++
X
X#define ARGLIST_SET_LAST_ELT(name, value) \
X  XtSetArg(_args[(_num_args - 1)], (name), (value))
X
X#define ARGLIST() \
X  _args, _num_args
X
Xstatic char temptext[1024]; /* local text storage, mostly used for sprintf */
X
X#define FONTHEIGHT(f) ((f)->max_bounds.ascent + (f)->max_bounds.descent)
X#define FONTWIDTH(f)  (f)->max_bounds.width
X
X#define COPY_STRING(str) \
X  (char *) strcpy(XtMalloc((strlen(str)+1) * sizeof(char)), (str))
END_OF_FILE
if test 2358 -ne `wc -c <'xwebster.h'`; then
    echo shar: \"'xwebster.h'\" unpacked with wrong size!
fi
# end of 'xwebster.h'
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