[comp.sources.x] v12i001: xrolo -- an XView rolodex, Patch 4 and, Patch5, Part01/01

luis@rice.edu (Luis Soltero) (03/02/91)

Submitted-by: luis@rice.edu (Luis Soltero)
Posting-number: Volume 12, Issue 1
Archive-name: xrolo/patch5
Patch-To: xrolo: Volume 9, Issue 84-86
Patch-To: xrolo: Volume 10, Issue 71
Patch-To: xrolo: Volume 11, Issue 1-2

This file contains patches to xrolo version 2.0 patchlevel 5.  To
apply the patch unshar this file and the apply xrolo.patch4 using
Larry Walls patch program.
	 cd XROLO_SRC ; patch < xrolo.patch4; xmkmf; make

Sources to xrolo and previous patches to xrolo can be obtained from
the comp.sources.x archive volume9 and volume10.  patch2 and 3 have
been submitted but have not yet been placed in the archive.

A set of patched sources can be obtained from expo.lcs.mit.edu look in
contrib/xrolo.v2p5.tar.Z

Patch 5:
    Added ability to use regex match when creating lists of cards.
    This functionality has also been added to the print function. All
    three types of regex matching (Soundex, Case Insensitive and Egrep)
    are supported.

    Added dialing support for SparcStations.  Xrolo now knows how to
    use the internal speaker in SS to dial touch tones.  3 new
    resources have been added. xrolo.DefaultVolume, xrolo.DialPrefix
    and xrolo.UseDialPrefix.

    Added OL ifdef to panel.c.  when OL is defined at compile time
    xrolo used OL type buttons instead of PANEL_IMAGE buttons.

    Faster list_button function.

	Replaced load/save from/to file menu items in the file menu w/
    item called "File IO" which creates a panel w/ file name, load, save,
    and cancel widgets.  This panel stays sticks around until the user
    selects the cancel button.  This feature allows users to switch
    between rolo databases quickly.  I would have used a FRAME_CMD to
    implement this functionality but I couldnt get FRAME_CMD to work
    correctly for me.  In the future a pin will be provided to the user so
    that he may control the File IO panel directly.


#! /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 shell archive."
# Contents:  TODO phone.c phone.icon xrolo.patch4
# Wrapped by luis@oort on Fri Feb 15 14:44:46 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'TODO' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'TODO'\"
else
echo shar: Extracting \"'TODO'\" \(232 characters\)
sed "s/^X//" >'TODO' <<'END_OF_FILE'
Xa) Includes in xrolo database.
Xc) record locking and multiple xrolo communication using rpc.
Xe) print formating of cards.  reduce x num cards / page.  landscape mode.
Xh) check -Ww option. why does it not work?
Xi) make buttons wrap.
END_OF_FILE
if test 232 -ne `wc -c <'TODO'`; then
    echo shar: \"'TODO'\" unpacked with wrong size!
fi
# end of 'TODO'
fi
if test -f 'phone.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phone.c'\"
else
echo shar: Extracting \"'phone.c'\" \(10124 characters\)
sed "s/^X//" >'phone.c' <<'END_OF_FILE'
X/*
X * derived from the sun microsystems play.c demo.  Please send bugs,
X * fixes or comments to me directly.
X * 
X * Luis Soltero (luis@rice.edu)
X */
X
X#include <xview/xview.h>
X#include <xview/panel.h>
X#include <sys/dir.h>
X#include "defs.h"
X
Xstatic Frame volume_frame;
Xstatic Panel volume_panel;
Xextern Frame frame;
Xstatic Menu_item volume_prefix_item, volume_item,
X  volume_use_prefix_item;
X
Xstatic void do_create_phone_attribute_panel();
X
Xstatic in_phone_button=0;
Xvoid set_phone_attributes(item, event)
XPanel_item item;
XEvent *event;
X{
X	if ( in_phone_button ) {
X		in_phone_button = 0;
X		return;
X	}
X#ifdef SOUNDS
X	do_create_phone_attribute_panel(item, event);
X	xv_set(volume_frame, XV_SHOW, TRUE, NULL);
X#else
X	msg("Using the system speaker to dial only works on SparcStations");
X#endif
X}
X
Xextern Menu_item regex_item;
X
Xvoid dial_a_number(item, event)
XPanel_item item;
XEvent *event;
X{
X	char *get_selection();
X	char *cp;
X	char buff[100];
X	if ( in_phone_button ) {
X		in_phone_button = 0;
X		return;
X	}
X#ifdef SOUNDS
X	/* make sure the attribute panel and all default attributes are */
X	/* initialized */
X	do_create_phone_attribute_panel();
X	cp = get_selection();
X	if ( cp == NULL )
X	  cp = (char *)xv_get(regex_item, PANEL_VALUE);
X	if ( cp == NULL || *cp == '\0' ) {
X		msg("No number to dial");
X		return;
X	}
X	buff[0] = '\0';
X	if ( xv_get(volume_use_prefix_item, PANEL_VALUE) ) {
X		strcpy(buff, xv_get(volume_prefix_item, PANEL_VALUE));
X	}
X	strcat(buff, cp);
X	if ( !confirm("Dial %s", buff) )
X	  return;
X	for( cp = buff; *cp != '\0'; cp++ ) {
X		dial(*cp);
X	}
X#else
X	msg("Using the system speaker to dial only works on SparcStations");
X#endif
X}
X
Xvoid phone_button(item, event)
XPanel_item item;
XEvent *event;
X{
X	if ( event_action(event) == ACTION_MENU )
X	  return;
X
X	switch (value_from_mask (event)) {
X	  case PLAIN_CLICK:			/* Plain save */
X		dial_a_number(item, event);
X		break;
X
X	  case SHIFT_CLICK:			/* reload, no save first */
X		set_phone_attributes(item, event);
X		break;
X	}
X	in_phone_button = 1;
X}
X
X#ifdef SOUNDS
X
X#include <stdio.h>
X#include <errno.h>
X#include <ctype.h>
X#include <stdlib.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/stat.h>
X#include <sys/param.h>
X#include <sys/signal.h>
X
X#include <stropts.h>
X#include <sys/ioctl.h>
X
X#include <multimedia/libaudio.h>
X#include <multimedia/audio_device.h>
X
X
X#define	MAX_GAIN		(100)		/* maximum gain */
X
Xchar tones[20][MAXNAMLEN];
X
X#define TONE(x)    tones[x]
X#define POUND 10
X#define STAR  11
X#define GONG  12
X
X#define DEFAULT_VOLUME 50
X
X
Xstatic void init_tones()
X{
X	int i;
X	for ( i = 0; i < 10; i++ )
X	  sprintf(tones[i],"%s/touchtone.%1d.au", SOUNDS, i);
X	sprintf(tones[i++], "%s/touchtone.pound.au", SOUNDS);
X	sprintf(tones[i++], "%s/touchtone.star.au", SOUNDS);
X	sprintf(tones[i++], "%s/drip.au", SOUNDS);
X}
X
Xstatic void slider_volume_proc(item, value, event)
XPanel_item item;
Xint value;
XEvent *event;
X{
X	volume(value);
X	play(TONE(GONG));
X}
X
Xstatic void volume_done_proc(item, event)
XPanel_item item;
XEvent *event;
X{
X	xv_set(volume_frame, XV_SHOW, FALSE, NULL);
X}
X
Xstatic void do_create_phone_attribute_panel()
X{
X	static int inited = 0;
X	Menu_item prefix_item;
X	if ( inited )
X	  return;
X	inited++;
X		
X	volume_frame = xv_create(frame, FRAME,
X							 FRAME_LABEL, "Phone Attributes",
X							 FRAME_SHOW_LABEL, TRUE,
X							 NULL);
X	volume_panel = xv_create(volume_frame, PANEL, NULL);
X	volume_use_prefix_item = xv_create(volume_panel, PANEL_CHECK_BOX,
X							PANEL_CHOOSE_ONE, FALSE,
X							PANEL_CHOICE_STRINGS, "Use Dial Prefix:", NULL,
X							PANEL_VALUE, defaults_get_integer("xrolo.usedialprefix", 
X															  "xrolo.UseDialPrefix", 1), 
X							NULL);
X	volume_prefix_item = xv_create(volume_panel, PANEL_TEXT, 
X								   PANEL_BLINK_CARET, TRUE,
X								   PANEL_VALUE_DISPLAY_LENGTH, 24,
X								   PANEL_VALUE_STORED_LENGTH, 80,
X								   PANEL_VALUE, defaults_get_string("xrolo.dialprefix",
X																	"xrolo.DialPrefix", ""),
X								   NULL);
X
X	volume_item = xv_create(volume_panel, PANEL_SLIDER,
X			  XV_X, xv_col(volume_panel, 0),
X			  XV_Y, xv_row(volume_panel, 1),
X			  PANEL_LABEL_STRING, "Volume:",
X			  PANEL_VALUE, defaults_get_integer("xrolo.defaultvolume",
X							   "xrolo.DefaultVolume", DEFAULT_VOLUME),
X			  PANEL_MIN_VALUE, 0,
X			  PANEL_MAX_VALUE, MAX_GAIN,
X			  PANEL_SLIDER_WIDTH, 100,
X			  PANEL_SHOW_RANGE, TRUE,
X			  PANEL_SHOW_VALUE, TRUE,
X			  PANEL_NOTIFY_LEVEL, PANEL_DONE,
X			  PANEL_NOTIFY_PROC, slider_volume_proc,
X			  NULL);
X	xv_create(volume_panel, PANEL_BUTTON,
X			  PANEL_LABEL_STRING, "Done",
X			  PANEL_NOTIFY_PROC, volume_done_proc,
X			  NULL);
X	window_fit(volume_panel);
X	window_fit(volume_frame);
X}
X
Xdial(c)
Xchar c;
X{
X	int tone;
X	if ( isdigit(c) ) {
X		play_wait(TONE(c - '0'));
X		return;
X	}
X	if ( c == '*'  ) {
X		play_wait(TONE(STAR));
X		return;
X	}
X	if ( c == '#' ) {
X		play_wait(TONE(POUND));
X		return;
X	}
X	if ( c == ',' ) {
X		sleep(2);
X		return;
X	}
X	tone = islower(c) ? toupper(c) : c;
X	if ( tone >= 'A' && tone < 'Z') {
X		if ( tone >= 'Q' )
X		  tone--;
X		tone -= 'A';
X		tone = (tone / 3) ;
X		tone += 2;
X		play_wait(TONE(tone));
X	}
X}
X
Xplay_wait(cp)
Xchar *cp;
X{
X	play(cp);
X	usleep(50000);
X}
X
X/*
X * This defines the tolerable sample rate error as a ratio between the
X * sample rates of the audio data and the audio device.
X */
X#define	SAMPLE_RATE_THRESHOLD	(.01)
X
Xdouble		Savevol;		/* saved volume level */
Xchar		*Audio_dev = "/dev/audio";
X
Xint		Audio_fd = -1;		/* file descriptor for audio device */
XAudio_hdr	Dev_hdr;		/* audio header for device */
XAudio_hdr	File_hdr;		/* audio header for file */
X
X
Xinit_audio()
X{
X	int err;
X	struct stat	st;
X	static inited = 0;
X
X	if ( inited )
X	  return(1);
X
X	/* make sure that the volume panel + defaults have been intialized */
X	do_create_phone_attribute_panel();
X	init_tones();
X
X	/* Validate and open the audio device */
X	err = stat(Audio_dev, &st);
X	if (err < 0) {
X		msg("Play: No audio device");
X		return(0);
X	}
X	if (!S_ISCHR(st.st_mode)) {
X		msg("Play: %s is not an audio device", Audio_dev);
X		return(0);
X	}
X
X	/* Try it quickly, first */
X	Audio_fd = open(Audio_dev, O_WRONLY | O_NDELAY);
X	if ((Audio_fd < 0) && (errno == EBUSY)) {
X		msg("Play: Audio device in use");
X		return(0);
X	}
X	if (Audio_fd < 0) {
X		msg("Play: Error opening audio device");
X		return(0);
X	}
X
X	/* Get the device output encoding configuration */
X	if (audio_get_play_config(Audio_fd, &Dev_hdr) != AUDIO_SUCCESS) {
X		msg("Play: %s is not an audio device", Audio_dev);
X		return(0);
X	}
X	inited++;
X	/* set default volume level */
X	volume(xv_get(volume_item, PANEL_VALUE));
X	return(1);
X}
X
Xclose_audio()
X{
X	/*
X	 * Though drain is implicit on close(), it's performed here
X	 * for the sake of completeness, and to ensure that the volume
X	 * is reset after all output is complete.
X	 */
X	(void) audio_drain(Audio_fd, FALSE);
X	(void) audio_set_play_gain(Audio_fd, &Savevol);
X	(void) close(Audio_fd);			/* close output */
X}
X
Xvolume(Volume)
Xunsigned Volume;
X{
X	double		vol;
X	int         err;
X
X	if ( !init_audio() )
X	  return;
X
X	if ( Volume > MAX_GAIN ) {
X		msg("Volume: Volume must be in the range 0 to %d",
X				MAX_GAIN);
X		return;
X	}
X	vol = (double) Volume / (double) MAX_GAIN;
X	(void) audio_get_play_gain(Audio_fd, &Savevol);
X	err = audio_set_play_gain(Audio_fd, &vol);
X	if (err != AUDIO_SUCCESS) {
X		msg("Volume: Could not set volume for %s", Audio_dev);
X		return;
X	}
X}
X
X/*
X * Play a list of audio files.
X */
Xplay(Ifile)
Xchar *Ifile;
X{
X	int		cnt;
X	int		ifd;
X	int     err;
X	static unsigned char buf[1024 * 64];		/* size should depend on sample_rate */
X
X	if ( !init_audio() )
X	  return;
X
X/*
Xfprintf(stderr,"file = %s\n", Ifile);
X*/
X	if ((ifd = open(Ifile, O_RDONLY, 0)) < 0) {
X		msg("Play: Could not open audio file %s", Ifile);
X		return;
X	}
X
X	/* Check to make sure this is an audio file */
X	err = audio_read_filehdr(ifd, &File_hdr, (char *)NULL, 0);
X
X	if (err != AUDIO_SUCCESS) {
X		msg("Play: %s is not a valid audio file", Ifile);
X		goto closeinput;
X	}
X
X	/* Check the device configuration */
X	if (audio_cmp_hdr(&Dev_hdr, &File_hdr) != 0) {
X		/*
X		 * The device does not match the input file.
X		 * Wait for any old output to drain, then attempt
X		 * to reconfigure the audio device to match the
X		 * input data.
X		 */
X		if (audio_drain(Audio_fd, FALSE) != AUDIO_SUCCESS) {
X			msg("Play: AUDIO_DRAIN error");
X			goto closeinput;
X		}
X		if (!reconfig(Ifile))
X		  goto closeinput;
X	}
X
X	/*
X	 * At this point, we're all ready to copy the data.
X	 */
X	while ((cnt = read(ifd, (char *)buf, sizeof (buf))) >= 0) {
X		/* If input EOF, write an eof marker */
X		err = write(Audio_fd, (char *)buf, cnt);
X		if (err != cnt) {
X			msg("Play: output error");
X			break;
X		}
X		if (cnt == 0)
X		  break;
X	}
X	if (cnt < 0) {
X		msg("Play: error reading file %s", Ifile);
X	}
X
Xcloseinput:
X	(void) close(ifd);		/* close input file */
X	audio_drain(Audio_fd, FALSE);
X}
X
X
X/*
X * Try to reconfigure the audio device to match the file encoding.
X * If this fails, we should attempt to make the input data match the
X * device encoding.  For now, we give up on this file.
X *
X * Returns TRUE if successful.  Returns FALSE if not.
X */
Xreconfig(Ifile)
Xchar *Ifile;
X{
X	int	err;
X	char	mesg[AUDIO_MAX_ENCODE_INFO];
X
X	Dev_hdr = File_hdr;
X	err = audio_set_play_config(Audio_fd, &Dev_hdr);
X
X	switch (err) {
X	  case AUDIO_SUCCESS:
X		return (TRUE);
X
X	  case AUDIO_ERR_NOEFFECT:
X		/*
X		 * Couldn't change the device.
X		 * Check to see if we're nearly compatible.
X		 * audio_cmp_hdr() returns >0 if only sample rate difference.
X		 */
X		if (audio_cmp_hdr(&Dev_hdr, &File_hdr) > 0) {
X			double	ratio;
X			
X			ratio = (double) abs((int)
X								 (Dev_hdr.sample_rate - File_hdr.sample_rate)) /
X								   (double) File_hdr.sample_rate;
X			if (ratio <= SAMPLE_RATE_THRESHOLD) {
X				msg("Play: WARNING: %s sampled at %d, playing at %d",
X					    Ifile, File_hdr.sample_rate,
X					    Dev_hdr.sample_rate);
X				return(TRUE);
X			}
X			msg("Play: %s sample rate %d not available",
X					Ifile, File_hdr.sample_rate);
X			return (FALSE);
X		}
X		(void) audio_enc_to_str(&File_hdr, mesg);
X		msg("Play: %s encoding not available: %s",Ifile,mesg);
X		return (FALSE);
X
X	  default:
X		msg("Play: i/o error (set config)");
X		abort();
X	}
X}
X
X
X#endif
END_OF_FILE
if test 10124 -ne `wc -c <'phone.c'`; then
    echo shar: \"'phone.c'\" unpacked with wrong size!
fi
# end of 'phone.c'
fi
if test -f 'phone.icon' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phone.icon'\"
else
echo shar: Extracting \"'phone.icon'\" \(589 characters\)
sed "s/^X//" >'phone.icon' <<'END_OF_FILE'
X/* Format_version=1, Width=32, Height=32, Depth=1, Valid_bits_per_item=16
X */
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0FFF,0xFFF0,
X	0x3000,0x000C,
X	0x4000,0x0002,
X	0x4030,0x0C02,
X	0x807F,0xFE01,
X	0x80B0,0x0D01,
X	0x83FF,0xFFC1,
X	0x8400,0x0021,
X	0x7C0D,0xB03E,
X	0x040D,0xB020,
X	0x0400,0x0020,
X	0x040D,0xB020,
X	0x040D,0xB020,
X	0x0400,0x0020,
X	0x040D,0xB020,
X	0x040D,0xB020,
X	0x0400,0x0020,
X	0x0400,0x0020,
X	0x05FF,0xFFA0,
X	0x0400,0x0020,
X	0x0400,0x0020,
X	0x07FF,0xFFE0,
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0000,0x0000,
X	0x0000,0x0000
END_OF_FILE
if test 589 -ne `wc -c <'phone.icon'`; then
    echo shar: \"'phone.icon'\" unpacked with wrong size!
fi
# end of 'phone.icon'
fi
if test -f 'xrolo.patch4' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xrolo.patch4'\"
else
echo shar: Extracting \"'xrolo.patch4'\" \(55035 characters\)
sed "s/^X//" >'xrolo.patch4' <<'END_OF_FILE'
X*** Imakefile	Fri Feb 15 14:34:46 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/Imakefile	Fri Feb 15 14:23:56 1991
X***************
X*** 5,22 ****
X  #
X  
X  #
X- # linking against openlook libraries on suns after patching ol_button.c. 
X- # see README for details.
X- LOCAL_LIBRARIES = -L$$OPENWINHOME/lib -lxview -Bstatic -lolgx -Bdynamic
X- 
X- #
X  # linking against XView libraries compiled from mit distribution after 
X  # patching ol_button.c. see README for details.
X! # LOCAL_LIBRARIES = -lxview -lolgx
X  
X! 		CDEBUGFLAGS = -O
X!            SRCS = main.c panel.c cards.c popup.c send_mail.c soundex.c
X!            OBJS = main.o panel.o cards.o popup.o send_mail.o soundex.o
X         INCLUDES = -I$$OPENWINHOME/include
X  #
X  # User setable defines
X--- 5,17 ----
X  #
X  
X  #
X  # linking against XView libraries compiled from mit distribution after 
X  # patching ol_button.c. see README for details.
X! # LOCAL_LIBRARIES = -lxview -lolgx 
X  
X!     CDEBUGFLAGS = -O
X!            SRCS = main.c panel.c cards.c popup.c send_mail.c soundex.c phone.c
X!            OBJS = main.o panel.o cards.o popup.o send_mail.o soundex.o phone.o
X         INCLUDES = -I$$OPENWINHOME/include
X  #
X  # User setable defines
X***************
X*** 23,33 ****
X  # 
X  #	MAILER = Mailer to use when send mail to author menu entry is selected.
X  #   VERSION = Xrolo version number
X! #   NEED_STRSTR = Include only if your system does not have a strstr(3C).
X  
X  	MAILER  = /bin/mail
X  	VERSION = 2.0
X!     DEFINES = -DSTANDALONE -DMAILER=\"$(MAILER)\" -DVERSION=\"$(VERSION)\"
X  
X  AllTarget(xrolo)
X  NormalProgramTarget(xrolo,$(OBJS),$(DEPLIBS), $(LOCAL_LIBRARIES), $(XLIB))
X--- 18,43 ----
X  # 
X  #	MAILER = Mailer to use when send mail to author menu entry is selected.
X  #   VERSION = Xrolo version number
X! #   OL = OpenLook menu buttons.
X! #   STANDALONE = Xrolo will be run as a stand alone application.
X! #   SOUNDS directory containing touch tone sound files. comment out the -DSOUNDS
X! #       in DEFINES if your system is not a sparcstation w/ installed 
X! #       sound libraries.  
X  
X  	MAILER  = /bin/mail
X  	VERSION = 2.0
X!     SOUNDS  =  /usr/local/lib/sounds  # or /usr/demo/SOUNDS/sounds
X!     DEFINES = -DSTANDALONE -DMAILER=\"$(MAILER)\" -DVERSION=\"$(VERSION)\" \
X!               -DSOUNDS=\"$(SOUNDS)\" # -DOL
X! 
X! #
X! # comment this out if you do not have SOUNDS defined above
X! AUDIOLIB = -laudio  -lm
X! 
X! #
X! # linking against openlook libraries on suns after patching ol_button.c. 
X! # see README for details.
X! LOCAL_LIBRARIES = -L$$OPENWINHOME/lib -lxview -Bstatic -lolgx -Bdynamic $(AUDIOLIB)
X  
X  AllTarget(xrolo)
X  NormalProgramTarget(xrolo,$(OBJS),$(DEPLIBS), $(LOCAL_LIBRARIES), $(XLIB))
X*** Makefile	Fri Feb 15 14:32:28 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/Makefile	Fri Feb 15 14:24:07 1991
X***************
X*** 7,13 ****
X  #
X  
X  ###########################################################################
X! # Makefile generated from "Imake.tmpl" and </tmp/IIf.a13794>
X  # $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
X  #
X  # Platform-specific parameters may be set in the appropriate .cf
X--- 7,13 ----
X  #
X  
X  ###########################################################################
X! # Makefile generated from "Imake.tmpl" and </tmp/IIf.a22611>
X  # $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
X  #
X  # Platform-specific parameters may be set in the appropriate .cf
X***************
X*** 236,254 ****
X  #
X  
X  #
X- # linking against openlook libraries on suns after patching ol_button.c.
X- # see README for details.
X- LOCAL_LIBRARIES = -L$$OPENWINHOME/lib -lxview -Bstatic -lolgx -Bdynamic
X- 
X- #
X  # linking against XView libraries compiled from mit distribution after
X  # patching ol_button.c. see README for details.
X  # LOCAL_LIBRARIES = -lxview -lolgx
X  
X!            SRCS = main.c panel.c cards.c popup.c
X!            OBJS = main.o panel.o cards.o popup.o
X         INCLUDES = -I$$OPENWINHOME/include
X!         DEFINES = -DSTANDALONE
X  
X  all:: xrolo
X  
X--- 236,274 ----
X  #
X  
X  #
X  # linking against XView libraries compiled from mit distribution after
X  # patching ol_button.c. see README for details.
X  # LOCAL_LIBRARIES = -lxview -lolgx
X  
X!     CDEBUGFLAGS = -O
X!            SRCS = main.c panel.c cards.c popup.c send_mail.c soundex.c phone.c
X!            OBJS = main.o panel.o cards.o popup.o send_mail.o soundex.o phone.o
X         INCLUDES = -I$$OPENWINHOME/include
X! #
X! # User setable defines
X! #
X! #	MAILER = Mailer to use when send mail to author menu entry is selected.
X! #   VERSION = Xrolo version number
X! #   OL = OpenLook menu buttons.
X! #   STANDALONE = Xrolo will be run as a stand alone application.
X! #   SOUNDS directory containing touch tone sound files. comment out the -DSOUNDS
X! #       in DEFINES if your system is not a sparcstation w/ installed
X! #       sound libraries.
X! 
X! 	MAILER  = /bin/mail
X! 	VERSION = 2.0
X!     SOUNDS  =  /usr/local/lib/sounds  # or /usr/demo/SOUNDS/sounds
X!     DEFINES = -DSTANDALONE -DMAILER=\"$(MAILER)\" -DVERSION=\"$(VERSION)\" \
X!               -DSOUNDS=\"$(SOUNDS)\" # -DOL
X! 
X! #
X! # comment this out if you do not have SOUNDS defined above
X! AUDIOLIB = -laudio  -lm
X! 
X! #
X! # linking against openlook libraries on suns after patching ol_button.c.
X! # see README for details.
X! LOCAL_LIBRARIES = -L$$OPENWINHOME/lib -lxview -Bstatic -lolgx -Bdynamic $(AUDIOLIB)
X  
X  all:: xrolo
X  
X*** Patchlevel	Fri Feb 15 14:34:47 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/Patchlevel	Fri Feb 15 14:23:49 1991
X***************
X*** 1,4 ****
X! Rolo, release 2.0, patch level 4
X  
X  Patch 4:
X      Replaced list_button procedure with one that is much faster and 
X--- 1,29 ----
X! Rolo, release 2.0, patch level 5
X! 
X! Patch 5:
X!     Added ability to use regex match when creating lists of cards.
X!     This functionality has also been added to the print function. All
X!     three types of regex matching (Soundex, Case Insensitive and Egrep)
X!     are supported.
X! 
X!     Added dialing support for SparcStations.  Xrolo now knows how to
X!     use the internal speaker in SS to dial touch tones.  3 new
X!     resources have been added. xrolo.DefaultVolume, xrolo.DialPrefix
X!     and xrolo.UseDialPrefix.
X! 
X!     Added OL ifdef to panel.c.  when OL is defined at compile time
X!     xrolo used OL type buttons instead of PANEL_IMAGE buttons.
X! 
X!     Faster list_button function.
X! 
X! 	Replaced load/save from/to file menu items in the file menu w/
X!     item called "File IO" which creates a panel w/ file name, load, save,
X!     and cancel widgets.  This panel stays sticks around until the user
X!     selects the cancel button.  This feature allows users to switch
X!     between rolo databases quickly.  I would have used a FRAME_CMD to
X!     implement this functionality but I couldnt get FRAME_CMD to work
X!     correctly for me.  In the future a pin will be provided to the user so
X!     that he may control the File IO panel directly.
X  
X  Patch 4:
X      Replaced list_button procedure with one that is much faster and 
X*** help.h	Fri Feb 15 14:34:47 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/help.h	Fri Feb 15 14:23:52 1991
X***************
X*** 96,101 ****
X--- 96,106 ----
X  desired entry followed by a <SHIFT>-click \n\
X  on the list button (or use the list button \n\
X  menu) to bring up the selected card.\n\
X+ The \"List Cards Matching Regex\" menu\n\
X+ entry produces an index list of cards\n\
X+ matching the regular expression in the\n\
X+ Expression text panel using the selected\n\
X+ match type.\n\
X  \n\
X  FILE BUTTON\n\
X     This button loads and saves your rolodex\n\
X***************
X*** 113,126 ****
X  menu or by setting the \n\
X         \"xrolo.CaseInsensitiveSort\"\n\
X  resource to 0 or 1. Xrolo implements a very \n\
X! rudimentary field sort. each line in the card\n\
X  is considered to be a field. Pointing and\n\
X  clicking on a selected field before invoking \n\
X  the sort will cause xrolo to sort the cards\n\
X! by the selected field. The last two items on\n\
X  the menu, which can only be selected from\n\
X  the menu, will load from or save to a named\n\
X! file.  You must select a string in some\n\
X  window to provide the file name, similar\n\
X  to the way the TextEdit tool\n\
X  works.  The path you give must be relative to\n\
X--- 118,131 ----
X  menu or by setting the \n\
X         \"xrolo.CaseInsensitiveSort\"\n\
X  resource to 0 or 1. Xrolo implements a very \n\
X! rudimentary field sort. Each line in the card\n\
X  is considered to be a field. Pointing and\n\
X  clicking on a selected field before invoking \n\
X  the sort will cause xrolo to sort the cards\n\
X! by the selected field. The last item on\n\
X  the menu, which can only be selected from\n\
X  the menu, will load from or save to a named\n\
X! file.  You can select a string in some\n\
X  window to provide the file name, similar\n\
X  to the way the TextEdit tool\n\
X  works.  The path you give must be relative to\n\
X***************
X*** 133,140 ****
X  existing files, etc.\n\
X  \n\
X  HELP BUTTON\n\
X!    Displays the information you're reading now.\n\
X  \n\
X  FINISHED BUTTON\n\
X     This button is used when you are finished\n\
X  using Rolo.  A normal click saves any changes\n\
X--- 138,171 ----
X  existing files, etc.\n\
X  \n\
X  HELP BUTTON\n\
X!    Displays the information you're reading now\n\
X! and allows you to send mail to me.\n\
X  \n\
X+ PHONE BUTTON\n\
X+    On SparcStations this button can be used to\n\
X+ dial a number entered in the expression field\n\
X+ or highlighted with the mouse.  When selected\n\
X+ the \"Set Phone Attributes\" menu item creates\n\
X+ a panel that allows speaker volume adjustment,\n\
X+ the entering of a dial prefix and the enabling\n\
X+ or disabling of the dial prefix.  Phone\n\
X+ numbers and dial prefixes may consist of any\n\
X+ alpha numeric character, *, # and \",\". \n\
X+ A comma in the dial string causes the dial\n\
X+ routine to pause for 2 seconds before\n\
X+ dialing the next character in the sequence.\n\
X+ Xrolo supports several X resources used to\n\
X+ to control default phone attributes.\n\
X+ \"xrolo.DefaultVolume\" sets the default\n\
X+ speaker volume. The volume must be entered\n\
X+ as an integer value ranging in value from\n\
X+ 0 to 100 where 100 is the maximum gain.\n\
X+ \"xrolo.UseDialPrefix\" accepts a boolean value\n\
X+ which enables or disables the use of the dial\n\
X+ prefix while dialing.\n\
X+ \"xrolo.DialPrefix\" sets the default dial prefix\n\
X+ string.\n\
X+ \n\
X  FINISHED BUTTON\n\
X     This button is used when you are finished\n\
X  using Rolo.  A normal click saves any changes\n\
X***************
X*** 157,162 ****
X--- 188,198 ----
X  the default printer command by creating an\n\
X  X resource entry called\n\
X       \"xrolo.PrintCommand\".\n\
X+ The \"Print Records Matching Regex\" menu\n\
X+ entry spools to the print command all cards\n\
X+ matching the regular expression in the\n\
X+ Expression text panel using the selected\n\
X+ match type.\n\
X  \n\
X  FIND BUTTON\n\
X     This button searches for a regular expression\n\
X***************
X*** 208,214 ****
X     Xrolo supports a number of resources which\n\
X  include:\n\
X      xrolo.TextWidth - set width of text window\n\
X!                       in pixels.\n\
X      xrolo.CaseInsensitive - 1 causes xrolo to\n\
X           ignore case when sorting. 0 turns on\n\
X           case sensitive sorts.\n\
X--- 244,250 ----
X     Xrolo supports a number of resources which\n\
X  include:\n\
X      xrolo.TextWidth - set width of text window\n\
X!           in pixels.\n\
X      xrolo.CaseInsensitive - 1 causes xrolo to\n\
X           ignore case when sorting. 0 turns on\n\
X           case sensitive sorts.\n\
X***************
X*** 217,222 ****
X--- 253,266 ----
X      xrolo.SearchType - default search mode for\n\
X           find. 0, 1 or 2 for EGREP, SLOPPY or\n\
X           SOUNDEX search modes respectively.\n\
X+     xrolo.UseDialPrefix - 1 causes xrolo to\n\
X+          use the dial prefix when dialing.\n\
X+     xrolo.DefaultVolume - volume gain for\n\
X+         SS1 internal speaker.  The gain must\n\
X+         be entered as an integer value between\n\
X+         0 and 100 where 100 is the maximum gain.\n\
X+     xrolo.DialPrefix - text string used to set\n\
X+         the default dial prefix.\n\
X  \n",
X  
X  "\
X***************
X*** 223,228 ****
X--- 267,275 ----
X  AUTHOR\n\
X     Ron Hitchens\n\
X      ronbo@vixen.uucp, hitchens@cs.utexas.edu\n\
X+    And\n\
X+    Luis Soltero\n\
X+     luis@rice.edu\n\
X  \n\
X     March  1987, version 1.0\n\
X     August 1988, version 2.0\n\
X*** panel.c	Fri Feb 15 14:34:49 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/panel.c	Fri Feb 15 14:23:54 1991
X***************
X*** 91,103 ****
X  
X  /* ------------------------------ Locals ----------------------------------- */
X  
X! static Panel_item	regex_item, slider_item;
X  
X  static int		panel_height, panel_width;
X  
X! static int		mask_from_menu_value (), value_from_mask (),
X  			filename_ok ();
X  
X  static void		next_button (), next_button_next(),  next_button_S_next(),
X    prev_button (), prev_button_prev(), prev_button_S_prev(),
X    new_button (), new_card_after(), new_card_before(),
X--- 91,105 ----
X  
X  /* ------------------------------ Locals ----------------------------------- */
X  
X! Panel_item	regex_item, slider_item;
X  
X  static int		panel_height, panel_width;
X  
X! static int		mask_from_menu_value (), 
X  			filename_ok ();
X  
X+ int value_from_mask ();
X+ 
X  static void		next_button (), next_button_next(),  next_button_S_next(),
X    prev_button (), prev_button_prev(), prev_button_S_prev(),
X    new_button (), new_card_after(), new_card_before(),
X***************
X*** 104,111 ****
X    delete_button (), delete_button_delete(), delete_button_undelete(),
X    delete_button_undelete_before(), 
X    file_button (), file_button_save(), file_button_reload(), file_button_sort(),
X!   file_button_sort_backwards(), file_button_load(),
X!   file_button_save_to_file(), turn_on_case_insensitive_sort(),
X    turn_off_case_insensitive_sort(), 
X  
X    done_button (), done_n_save(), done_n_save_exit(), done_n_exit(),
X--- 106,113 ----
X    delete_button (), delete_button_delete(), delete_button_undelete(),
X    delete_button_undelete_before(), 
X    file_button (), file_button_save(), file_button_reload(), file_button_sort(),
X!   file_button_sort_backwards(), file_button_io(),
X!   turn_on_case_insensitive_sort(),
X    turn_off_case_insensitive_sort(), 
X  
X    done_button (), done_n_save(), done_n_save_exit(), done_n_exit(),
X***************
X*** 112,134 ****
X    find_button (), find_button_forward(), find_button_reverse(),
X    turn_on_sloppy(), turn_on_egrep(), turn_on_soundex(),
X  
X!   print_button(), print_entry(), print_all(), set_print_command(),
X  
X!   list_button_main(), list_goto_button(), list_button (),
X    help_button(), popup_send_mail(),
X  
X    slider_proc (), button_event(), goto_card (),
X    no_comprendo ();
X  
X! static Menu_item list_menu, find_menu, file_menu;
X! static char		*get_selection ();
X  
X  
X  /* prev new next delete */
X  static u_short		buttons1_image [] = {
X  #include "buttons1.icon"
X  };
X  
X  static u_short printer_image[] = {
X  #include "print.icon"   
X  };
X--- 114,143 ----
X    find_button (), find_button_forward(), find_button_reverse(),
X    turn_on_sloppy(), turn_on_egrep(), turn_on_soundex(),
X  
X!   print_button(), print_entry(), print_all(), set_print_command(), print_regex(),
X  
X!   list_button_main(), list_goto_button(), list_button (), list_button_match(),
X    help_button(), popup_send_mail(),
X  
X    slider_proc (), button_event(), goto_card (),
X+ 
X    no_comprendo ();
X  
X! extern void dial_a_number(), set_phone_attributes(), phone_button();
X  
X+ static Menu_item list_menu, find_menu, file_menu, regex_menu, print_menu;
X+ char		*get_selection ();
X  
X+ 
X  /* prev new next delete */
X  static u_short		buttons1_image [] = {
X  #include "buttons1.icon"
X  };
X  
X+ static u_short phone_image[] = {
X+ #include "phone.icon"
X+ };
X+ 
X  static u_short printer_image[] = {
X  #include "print.icon"   
X  };
X***************
X*** 188,196 ****
X  	frame = _frame;
X  	panel = xv_create (frame, PANEL,
X  					   PANEL_LAYOUT, PANEL_HORIZONTAL,
X  					   WIN_COLUMN_GAP, 15,
X  					   WIN_ROW_GAP, 25,
X! 		0);
X  
X  	/* 1st row */
X  	/* next prev new delete list file help done */
X--- 197,207 ----
X  	frame = _frame;
X  	panel = xv_create (frame, PANEL,
X  					   PANEL_LAYOUT, PANEL_HORIZONTAL,
X+ #ifndef OL
X  					   WIN_COLUMN_GAP, 15,
X  					   WIN_ROW_GAP, 25,
X! #endif
X! 		NULL);
X  
X  	/* 1st row */
X  	/* next prev new delete list file help done */
X***************
X*** 200,222 ****
X  						   NULL, NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 		PANEL_LABEL_IMAGE,	pr_region(buttons1_image, 64, 0, 32, 32, 32),
X! 		PANEL_ITEM_MENU,	tmpmenu,
X! 		PANEL_NOTIFY_PROC,	next_button, 
X! 		XV_X, xv_col(panel, 0),
X!         XV_Y, xv_row(panel, 0),
X! 		0);
X  
X  	tmpmenu = menu_create (
X  						   MENU_ACTION_ITEM,"    Previous Card", prev_button_prev,
X  						   MENU_ACTION_ITEM, "(S) First Card   ", prev_button_S_prev,
X  						   NULL, NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 		PANEL_LABEL_IMAGE,	pr_region(buttons1_image, 64, 0, 0, 32, 32),
X! 		PANEL_ITEM_MENU,	tmpmenu,
X! 		PANEL_NOTIFY_PROC,	prev_button,
X!         XV_Y, xv_row(panel, 0),
X! 		0);
X  
X  	tmpmenu = menu_create (
X  						   MENU_ACTION_ITEM, "    New Card After this One ", new_card_after,
X--- 211,242 ----
X  						   NULL, NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,	pr_region(buttons1_image, 64,0,32,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "Next",
X! #endif
X  
X+ 					  PANEL_ITEM_MENU,	tmpmenu,
X+ 					  PANEL_NOTIFY_PROC,	next_button, 
X+ 					  XV_X, xv_col(panel, 0),
X+ 					  XV_Y, xv_row(panel, 0),
X+ 					  NULL);
X+ 
X  	tmpmenu = menu_create (
X  						   MENU_ACTION_ITEM,"    Previous Card", prev_button_prev,
X  						   MENU_ACTION_ITEM, "(S) First Card   ", prev_button_S_prev,
X  						   NULL, NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,	pr_region(buttons1_image, 64,0,0,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "Prev",
X! #endif
X! 					  PANEL_ITEM_MENU,	tmpmenu,
X! 					  PANEL_NOTIFY_PROC,	prev_button,
X! 					  XV_Y, xv_row(panel, 0),
X! 					  0);
X  
X  	tmpmenu = menu_create (
X  						   MENU_ACTION_ITEM, "    New Card After this One ", new_card_after,
X***************
X*** 223,234 ****
X  						   MENU_ACTION_ITEM, "(S) New Card Before this One", new_card_before,
X  						   NULL, NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X- 		PANEL_LABEL_IMAGE,	pr_region (buttons1_image, 64, 32, 0, 32, 32),
X- 		PANEL_ITEM_MENU,	tmpmenu,
X- 		PANEL_NOTIFY_PROC,	new_button,
X-         XV_Y, xv_row(panel, 0),
X- 		0);
X  
X  	tmpmenu =  xv_create (NULL, MENU,
X  				MENU_NOTIFY_PROC, delete_button_delete,
X  				MENU_ITEM,
X--- 243,260 ----
X  						   MENU_ACTION_ITEM, "(S) New Card Before this One", new_card_before,
X  						   NULL, NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X  
X+ #ifndef OL
X+ 					  PANEL_LABEL_IMAGE,	pr_region (buttons1_image, 64,32,0,32,32),
X+ #else
X+ 					  PANEL_LABEL_STRING,  "New",
X+ #endif
X+ 
X+ 					  PANEL_ITEM_MENU,	tmpmenu,
X+ 					  PANEL_NOTIFY_PROC,	new_button,
X+ 					  XV_Y, xv_row(panel, 0),
X+ 					  0);
X+ 
X  	tmpmenu =  xv_create (NULL, MENU,
X  				MENU_NOTIFY_PROC, delete_button_delete,
X  				MENU_ITEM,
X***************
X*** 256,283 ****
X  			   NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 		PANEL_LABEL_IMAGE,	pr_region (buttons1_image, 64, 32, 32, 32, 32),
X! 		PANEL_ITEM_MENU, tmpmenu,
X! 		PANEL_NOTIFY_PROC,	delete_button,
X!         XV_Y, xv_row(panel, 0),
X! 		0);
X  
X  	list_menu = menu_create (
X! 						   MENU_ACTION_ITEM, "Show Index List of Cards",  list_button,
X  							
X! 							MENU_ITEM,
X! 							MENU_STRING, "(S) Go to Selected Entry",
X! 							MENU_NOTIFY_PROC, list_goto_button,
X! 							MENU_INACTIVE, TRUE,
X! 							NULL,
X  
X! 						   NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 		PANEL_LABEL_IMAGE,	pr_region(buttons2_image, 64, 32, 32, 32, 32),
X! 		PANEL_ITEM_MENU,	list_menu,
X! 		PANEL_NOTIFY_PROC, list_button_main,
X!         XV_Y, xv_row(panel, 0),
X! 		0);
X  
X  #define CASE_INSENSITIVE_SORT_STR "Case Insensitive Sort"
X  #define CASE_SORT_STR             "Case Sensitive Sort"
X--- 282,360 ----
X  			   NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,	pr_region (buttons1_image,64,32,32,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "Del",
X! #endif
X  
X+ 					  PANEL_ITEM_MENU, tmpmenu,
X+ 					  PANEL_NOTIFY_PROC,	delete_button,
X+ 					  XV_Y, xv_row(panel, 0),
X+ 					  0);
X+ 
X+ #define SLOPPY_EXPR_STR	  "Sloppy Regex Match"
X+ #define EGREP_EXPR_STR	  "Egrep(1) Regex Match"
X+ #define SOUNDEX_EXPR_STR  "Soundex Match"
X+ #define EGREP   0
X+ #define SLOPPY  1
X+ #define SOUNDEX 2
X+ 
X+ 	regex_menu = menu_create(
X+ 						  MENU_ITEM,
X+ 						  MENU_STRING,
X+ 						  SLOPPY_EXPR_STR,
X+ 						  MENU_NOTIFY_PROC,
X+ 						  turn_on_sloppy,
X+ 						  NULL,
X+ 						  
X+ 						  MENU_ITEM,
X+ 						  MENU_STRING,
X+ 						  EGREP_EXPR_STR,
X+ 						  MENU_NOTIFY_PROC,
X+ 						  turn_on_egrep,
X+ 						  NULL,
X+ 
X+ 						  MENU_ITEM,
X+ 						  MENU_STRING,
X+ 						  SOUNDEX_EXPR_STR,
X+ 						  MENU_NOTIFY_PROC,
X+ 						  turn_on_soundex,
X+ 						  NULL,
X+ 
X+ 						  NULL);
X+ 
X  	list_menu = menu_create (
X! 							 MENU_ACTION_ITEM, "Show Index List of Cards",  list_button,
X  							
X! 							 MENU_ITEM,
X! 							 MENU_STRING, "(S) Go to Selected Entry",
X! 							 MENU_NOTIFY_PROC, list_goto_button,
X! 							 MENU_INACTIVE, TRUE,
X! 							 NULL,
X! 							
X! 							 MENU_ACTION_ITEM, "(C) List of Cards Matching Regex",
X! 							 list_button_match,
X  
X! 							 MENU_ITEM,
X! 							 MENU_STRING,
X! 							 defaults_set_search_type_str(),
X! 							 MENU_PULLRIGHT, regex_menu,
X! 							 MENU_CLIENT_DATA, -1,
X! 							 NULL,
X! 
X! 							 NULL);
X! 
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,pr_region(buttons2_image,64,32,32,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "List",
X! #endif
X! 					  PANEL_ITEM_MENU,	list_menu,
X! 					  PANEL_NOTIFY_PROC, list_button_main,
X! 					  XV_Y, xv_row(panel, 0),
X! 					  NULL);
X  
X  #define CASE_INSENSITIVE_SORT_STR "Case Insensitive Sort"
X  #define CASE_SORT_STR             "Case Sensitive Sort"
X***************
X*** 333,348 ****
X  							 NULL,
X  						   
X  							 MENU_ACTION_ITEM,
X! 							 "      Load From Named File",
X! 							 file_button_load,
X  
X- 							 MENU_ACTION_ITEM,
X- 							 "      Save To Named File  ",
X- 							 file_button_save_to_file,
X  							 NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 					  PANEL_LABEL_IMAGE,	pr_region(buttons2_image, 64, 0, 0, 32, 32),
X  					  PANEL_NOTIFY_PROC,	file_button,
X  					  PANEL_ITEM_MENU, file_menu,
X  					  XV_X, xv_col(panel, 0),
X--- 410,426 ----
X  							 NULL,
X  						   
X  							 MENU_ACTION_ITEM,
X! 							 "(C+M) File I/O",
X! 							 file_button_io,
X  
X  							 NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,pr_region(buttons2_image,64,0,0,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "File",
X! #endif
X  					  PANEL_NOTIFY_PROC,	file_button,
X  					  PANEL_ITEM_MENU, file_menu,
X  					  XV_X, xv_col(panel, 0),
X***************
X*** 357,445 ****
X  						   NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 		PANEL_LABEL_IMAGE,	pr_region(buttons2_image, 64, 32, 0, 32, 32),
X! 		PANEL_ITEM_MENU,	tmpmenu,
X!         XV_Y, xv_row(panel, 1),
X! 		0);
X! 
X! #define SLOPPY_EXPR_STR	  "Sloppy Regex Match"
X! #define EGREP_EXPR_STR	  "Egrep(1) Regex Match"
X! #define SOUNDEX_EXPR_STR  "Soundex"
X! #define EGREP   0
X! #define SLOPPY  1
X! #define SOUNDEX 2
X! 
X! 	tmpmenu = menu_create(
X! 						  MENU_ITEM,
X! 						  MENU_STRING,
X! 						  SLOPPY_EXPR_STR,
X! 						  MENU_NOTIFY_PROC,
X! 						  turn_on_sloppy,
X! 						  NULL,
X! 						  
X! 						  MENU_ITEM,
X! 						  MENU_STRING,
X! 						  EGREP_EXPR_STR,
X! 						  MENU_NOTIFY_PROC,
X! 						  turn_on_egrep,
X! 						  NULL,
X! 
X! 						  MENU_ITEM,
X! 						  MENU_STRING,
X! 						  SOUNDEX_EXPR_STR,
X! 						  MENU_NOTIFY_PROC,
X! 						  turn_on_soundex,
X! 						  NULL,
X! 
X! 						  NULL);
X! 
X! 	find_menu = menu_create (
X! 							 MENU_ACTION_ITEM,
X! 							 "    Find Regular Expression, Forward",
X! 							 find_button_forward,
X  						   
X! 							 MENU_ACTION_ITEM,
X! 							 "(S) Find Regular Expression, Reverse", 
X! 							 find_button_reverse, 
X! 
X! 							 MENU_CLIENT_DATA, 
X! 							 defaults_set_search_type(), 
X! 							 
X! 							 MENU_ITEM,
X! 							 MENU_STRING, 
X! 							 defaults_set_search_type_str(),
X! 							 MENU_CLIENT_DATA, -1,
X! 							 MENU_PULLRIGHT, tmpmenu,
X! 							 NULL,
X  						   
X  						   NULL);
X- 
X  	(void) xv_create (panel, PANEL_BUTTON,
X  					  PANEL_LABEL_IMAGE, xv_create(NULL, SERVER_IMAGE,
X! 												   XV_WIDTH, 32,
X! 												   XV_HEIGHT, 32,
X! 												   SERVER_IMAGE_BITS,
X! 												   find_image,
X! 												   NULL),
X! 					  PANEL_ITEM_MENU,	find_menu, 
X! 					  PANEL_NOTIFY_PROC,	find_button,
X  					  NULL);
X  
X- 	tmpmenu = menu_create(
X- 						  MENU_ACTION_ITEM, 
X- 						  "Print Entry",
X- 						  print_entry,
X  
X! 						  MENU_ACTION_ITEM, 
X! 						  "Print All",
X! 						  print_all,
X  
X! 						  MENU_ACTION_ITEM,
X! 						  "Set Print Command",
X! 						  set_print_command,
X! 						  NULL);
X  
X  	(void) xv_create(panel, PANEL_BUTTON,
X  					 PANEL_LABEL_IMAGE, xv_create(NULL, SERVER_IMAGE,
X  												  XV_WIDTH, 32,
X  												  XV_HEIGHT, 32,
X--- 435,502 ----
X  						   NULL);
X  
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,pr_region(buttons2_image,64,32,0,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "Help",
X! #endif
X! 					  PANEL_ITEM_MENU,	tmpmenu,
X! 					  XV_Y, xv_row(panel, 1),
X! 					  0);
X! 	
X! 	tmpmenu = menu_create (
X! 						   MENU_ACTION_ITEM, 
X! 						   "    Dial Number", 
X! 						   dial_a_number,
X  						   
X! 						   MENU_ACTION_ITEM,
X! 						   "(S) Set Phone Attributes",
X! 						   set_phone_attributes,
X  						   
X  						   NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X+ #ifndef OL
X  					  PANEL_LABEL_IMAGE, xv_create(NULL, SERVER_IMAGE,
X! 												  XV_WIDTH, 32,
X! 												  XV_HEIGHT, 32,
X! 												  SERVER_IMAGE_BITS,
X! 												  phone_image,
X! 												  NULL),
X! #else
X! 					  PANEL_LABEL_STRING, "Tel",
X! #endif
X! 					  PANEL_NOTIFY_PROC,	phone_button,
X! 					  PANEL_ITEM_MENU,	tmpmenu,
X  					  NULL);
X  
X  
X! 	print_menu = menu_create(
X! 							 MENU_ACTION_ITEM, 
X! 							 "Print Entry",
X! 							 print_entry,
X! 							 
X! 							 MENU_ACTION_ITEM, 
X! 							 "(S) Print All",
X! 							 print_all,
X  
X! 							 MENU_ACTION_ITEM,
X! 							 "(C) Print Records Matching Regex",
X! 							 print_regex,
X  
X+ 							 MENU_ITEM,
X+ 							 MENU_STRING,
X+ 							 defaults_set_search_type_str(),
X+ 							 MENU_PULLRIGHT, regex_menu,
X+ 							 MENU_CLIENT_DATA, -1,
X+ 							 NULL,
X+ 							 
X+ 							 MENU_ACTION_ITEM,
X+ 							 "(C+S) Set Print Command",
X+ 							 set_print_command,
X+ 							 NULL);
X+ 
X  	(void) xv_create(panel, PANEL_BUTTON,
X+ #ifndef OL
X  					 PANEL_LABEL_IMAGE, xv_create(NULL, SERVER_IMAGE,
X  												  XV_WIDTH, 32,
X  												  XV_HEIGHT, 32,
X***************
X*** 446,455 ****
X  												  SERVER_IMAGE_BITS,
X  												  printer_image,
X  												  NULL),
X  					 PANEL_NOTIFY_PROC, print_button,
X! 					 PANEL_ITEM_MENU, tmpmenu,
X  					 XV_Y, xv_row(panel, 1),
X- 
X  					 NULL);
X  
X  	tmpmenu = menu_create (
X--- 503,514 ----
X  												  SERVER_IMAGE_BITS,
X  												  printer_image,
X  												  NULL),
X+ #else
X+ 					 PANEL_LABEL_STRING, "Print",
X+ #endif
X  					 PANEL_NOTIFY_PROC, print_button,
X! 					 PANEL_ITEM_MENU, print_menu,
X  					 XV_Y, xv_row(panel, 1),
X  					 NULL);
X  
X  	tmpmenu = menu_create (
X***************
X*** 466,477 ****
X  						   done_n_exit,
X  						   NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X! 		PANEL_LABEL_IMAGE,	pr_region(buttons2_image, 64, 0, 32, 32, 32),
X! 		PANEL_NOTIFY_PROC,	done_button,
X! 		PANEL_ITEM_MENU,	tmpmenu,
X!         XV_Y, xv_row(panel, 1),
X! 		0);
X  
X  	/*
X  	 * Tighten up the window around the buttons in the first row, this
X  	 * will be the width of the panel window, so we save that size for
X--- 525,579 ----
X  						   done_n_exit,
X  						   NULL);
X  	(void) xv_create (panel, PANEL_BUTTON,
X! #ifndef OL
X! 					  PANEL_LABEL_IMAGE,pr_region(buttons2_image,64,0,32,32,32),
X! #else
X! 					  PANEL_LABEL_STRING, "Fini",
X! #endif
X! 					  PANEL_NOTIFY_PROC,	done_button,
X! 					  PANEL_ITEM_MENU,	tmpmenu,
X! 					  XV_Y, xv_row(panel, 1),
X! 					  NULL);
X  
X+ 
X+ 	find_menu = menu_create (
X+ 							 MENU_ACTION_ITEM,
X+ 							 "    Find Regular Expression, Forward",
X+ 							 find_button_forward,
X+ 						   
X+ 							 MENU_ACTION_ITEM,
X+ 							 "(S) Find Regular Expression, Reverse", 
X+ 							 find_button_reverse, 
X+ 
X+ 							 MENU_CLIENT_DATA, 
X+ 							 defaults_set_search_type(), 
X+ 							 
X+ 							 MENU_ITEM,
X+ 							 MENU_STRING, 
X+ 							 defaults_set_search_type_str(),
X+ 							 MENU_CLIENT_DATA, -1,
X+ 							 MENU_PULLRIGHT, regex_menu,
X+ 							 NULL,
X+ 						   
X+ 						   NULL);
X+ 
X+ 	(void) xv_create (panel, PANEL_BUTTON,
X+ #ifdef  NEVER
X+ 					  PANEL_LABEL_IMAGE, xv_create(NULL, SERVER_IMAGE,
X+ 												   XV_WIDTH, 32,
X+ 												   XV_HEIGHT, 32,
X+ 												   SERVER_IMAGE_BITS,
X+ 												   find_image,
X+ 												   NULL),
X+ #else
X+ 					  PANEL_LABEL_STRING, "Find",
X+ #endif
X+ 					  PANEL_ITEM_MENU,	find_menu, 
X+ 					  PANEL_NOTIFY_PROC,	find_button,
X+ 					  XV_Y, xv_row(panel, 2),
X+ 					  XV_X, xv_col(panel, 0),
X+ 					  NULL);
X+ 
X  	/*
X  	 * Tighten up the window around the buttons in the first row, this
X  	 * will be the width of the panel window, so we save that size for
X***************
X*** 481,509 ****
X  	window_fit_width (panel); 
X  	panel_width = (int) xv_get (panel, XV_WIDTH);
X  	panel_columns = (int) xv_get (panel, WIN_COLUMNS);
X- 
X- 	/*
X- 	 * Begin second row, set the inter-item gap so the Find button and
X- 	 * the text item following it are placed nicely.
X- 	 */
X- 	xv_set (panel, PANEL_ITEM_X_GAP, 8, 0);
X- 
X  	regex_item = xv_create (panel, PANEL_TEXT,
X  							PANEL_BLINK_CARET,		TRUE,
X! 							PANEL_LABEL_STRING,		"Find Expression:",
X! 							PANEL_VALUE_DISPLAY_LENGTH,	panel_width - 344,
X! 							XV_X, xv_col(panel, 0),
X  							XV_Y, xv_row(panel, 2),
X  							PANEL_VALUE_STORED_LENGTH,	80,
X  							PANEL_NOTIFY_PROC,	find_button,
X  							0);
X  
X- 	/*
X- 	 * Begin the third row, squeeze the inter-item gap back down so that
X- 	 * the slider value is displayed close to the slider bar.
X- 	 */
X- 	xv_set (panel, PANEL_ITEM_X_GAP, 4, 0);
X  
X  	tmpmenu = menu_create (
X  				MENU_ITEM,
X  					MENU_STRING,	"Pick a card, any card",
X--- 583,599 ----
X  	window_fit_width (panel); 
X  	panel_width = (int) xv_get (panel, XV_WIDTH);
X  	panel_columns = (int) xv_get (panel, WIN_COLUMNS);
X  	regex_item = xv_create (panel, PANEL_TEXT,
X  							PANEL_BLINK_CARET,		TRUE,
X! 							PANEL_LABEL_STRING,		"Expression:",
X! 							PANEL_VALUE_DISPLAY_LENGTH,	panel_width - 349,
X  							XV_Y, xv_row(panel, 2),
X  							PANEL_VALUE_STORED_LENGTH,	80,
X  							PANEL_NOTIFY_PROC,	find_button,
X  							0);
X  
X  
X+ 
X  	tmpmenu = menu_create (
X  				MENU_ITEM,
X  					MENU_STRING,	"Pick a card, any card",
X***************
X*** 926,942 ****
X  static Frame file_frame;
X  static Panel file_panel;
X  static Panel_item file_item;
X! static char FileName[256];
X! static int FileLoad;
X! static void file_ok_proc()
X  {
X! 	strcpy(FileName, xv_get(file_item, PANEL_VALUE));
X! 	xv_set(file_frame, WIN_SHOW, FALSE, NULL);
X! 	FileLoad ? do_read_rolo(FileName) : do_write_rolo(FileName);
X  }
X  static void file_cancel_proc()
X  {
X! 	xv_set(file_frame, WIN_SHOW, FALSE, NULL);
X  }
X  
X  static void do_create_file_frame(item, event)
X--- 1016,1034 ----
X  static Frame file_frame;
X  static Panel file_panel;
X  static Panel_item file_item;
X! static void load_from_file_proc()
X  {
X! 	do_read_rolo(xv_get(file_item, PANEL_VALUE));
X  }
X+ 
X+ static void save_to_file_proc()
X+ {
X+ 	do_write_rolo(xv_get(file_item, PANEL_VALUE));
X+ }
X+ 
X  static void file_cancel_proc()
X  {
X! 	xv_set(file_frame, XV_SHOW, FALSE, NULL);
X  }
X  
X  static void do_create_file_frame(item, event)
X***************
X*** 944,969 ****
X  Event      *event;
X  {
X  	file_frame = xv_create(frame, FRAME,
X! 							XV_LABEL, "Set File Name",
X! 							FRAME_SHOW_LABEL, TRUE,
X! 							NULL);
X  	file_panel = xv_create(file_frame, PANEL, NULL);
X  	file_item = xv_create(file_panel, PANEL_TEXT,
X  							 XV_X, 4,
X! 							 XV_Y, 4,
X  							 PANEL_LABEL_STRING, "File Name:", 
X  							 PANEL_VALUE_STORED_LENGTH, 256,
X! 							 PANEL_VALUE_DISPLAY_LENGTH, 40,
X  							 NULL);
X  	xv_create(file_panel, PANEL_BUTTON,
X! 			  PANEL_LABEL_STRING, "   OK   ",
X! 			  XV_X, 450,
X! 			  XV_Y, 4,
X! 			  PANEL_NOTIFY_PROC, file_ok_proc,
X  			  NULL);
X  	xv_create(file_panel, PANEL_BUTTON,
X  			  PANEL_LABEL_STRING, "Cancel",
X! 			  XV_X, 450,
X  			  XV_Y, 35,
X  			  PANEL_NOTIFY_PROC, file_cancel_proc,
X  			  NULL);
X--- 1036,1072 ----
X  Event      *event;
X  {
X  	file_frame = xv_create(frame, FRAME,
X! 						   FRAME_LABEL, "File IO",
X! 						   FRAME_SHOW_LABEL, TRUE,
X! 						   NULL);
X! /*
X! 	file_panel = xv_get(file_frame, FRAME_CMD_PANEL);
X! */
X  	file_panel = xv_create(file_frame, PANEL, NULL);
X+ 
X  	file_item = xv_create(file_panel, PANEL_TEXT,
X  							 XV_X, 4,
X! 							 XV_Y, 6,
X  							 PANEL_LABEL_STRING, "File Name:", 
X  							 PANEL_VALUE_STORED_LENGTH, 256,
X! 							 PANEL_VALUE_DISPLAY_LENGTH, 30,
X  							 NULL);
X+ 
X  	xv_create(file_panel, PANEL_BUTTON,
X! 			  PANEL_LABEL_STRING, "Load From File",
X! 			  XV_X, 4,
X! 			  XV_Y, 35,
X! 			  PANEL_NOTIFY_PROC, load_from_file_proc,
X  			  NULL);
X  	xv_create(file_panel, PANEL_BUTTON,
X+ 			  PANEL_LABEL_STRING, "Save To File",
X+ 			  XV_X, 120,
X+ 			  XV_Y, 35,
X+ 			  PANEL_NOTIFY_PROC, save_to_file_proc,
X+ 			  NULL);
X+ 	xv_create(file_panel, PANEL_BUTTON,
X  			  PANEL_LABEL_STRING, "Cancel",
X! 			  XV_X, 220,
X  			  XV_Y, 35,
X  			  PANEL_NOTIFY_PROC, file_cancel_proc,
X  			  NULL);
X***************
X*** 971,1011 ****
X  	window_fit(file_frame);
X  }
X  
X! static void get_file_name(fileload)
X! int fileload;
X  {
X  	static int firsttime = 1;
X  	if (firsttime) {
X  		do_create_file_frame();
X  		firsttime = 0;
X  	}
X! 	FileLoad = fileload;
X! 	xv_set(file_frame, WIN_SHOW, TRUE, NULL);
X  }
X  
X! static void file_button_load (item, event)
X  Panel_item	item;
X  Event		*event;
X  {
X- 	char *filename;
X  	if ( in_file_button ) {
X  		in_file_button = 0;
X  		return;
X  	}
X  	save_card (current);
X! 	filename = get_selection ();
X! 	if ( filename == NULL ) {
X! 		get_file_name(1);
X! 		return;
X! 	} else if ( !confirm("Load from file %s?", filename) ) {
X! 		return;
X! 	}
X! 	
X! 	if (filename == NULL || filename[0] == '\0' ) {
X! 		msg ("No active selection, need a filename to load from");
X! 		return;
X! 	}
X! 	do_read_rolo(filename);
X  }
X  
X  do_read_rolo(filename)
X--- 1074,1103 ----
X  	window_fit(file_frame);
X  }
X  
X! static void do_file_io_panel()
X  {
X  	static int firsttime = 1;
X+ 	char *cp = get_selection();
X  	if (firsttime) {
X  		do_create_file_frame();
X  		firsttime = 0;
X  	}
X! 	if ( cp != NULL ) {
X! 		xv_set(file_item, PANEL_VALUE, cp);
X! 	}
X! 	xv_set(file_frame, XV_SHOW, TRUE, NULL);
X  }
X  
X! static void file_button_io (item, event)
X  Panel_item	item;
X  Event		*event;
X  {
X  	if ( in_file_button ) {
X  		in_file_button = 0;
X  		return;
X  	}
X  	save_card (current);
X! 	do_file_io_panel();
X  }
X  
X  do_read_rolo(filename)
X***************
X*** 1028,1058 ****
X  	}
X  	write_rolo (filename);
X  }
X- static void file_button_save_to_file (item, event)
X- Panel_item	item;
X- Event		*event;
X- {
X- 	char *filename;
X- 	if ( in_file_button ) {
X- 		in_file_button = 0;
X- 		return;
X- 	}
X- 	save_card (current);
X- 	filename = get_selection ();
X- 	if (filename == NULL ) {
X- 		get_file_name(0);
X- 		return;
X- 	} else if ( !confirm("Save to file %s?", filename) ) {
X- 		return;
X- 	}
X- 	if (filename == NULL || filename[0] == '\0' ) {
X- 		msg ("No active selection, need a filename to save to");
X- 		return;
X- 	}
X- 	do_write_rolo(filename);
X- }
X- 
X- /*ARGSUSED*/
X  static void file_button (item, event)
X  Panel_item	item;
X  Event		*event;
X--- 1120,1125 ----
X***************
X*** 1067,1093 ****
X  		file_button_save(item, event);
X  		break;
X  
X! 	case SHIFT_CLICK:			/* reload, no save first */
X  		file_button_reload(item, event);
X  		break;
X  
X! 	case CTRL_CLICK:			/* sort ascending */
X  		file_button_sort(item, event);
X  		break;
X  
X! 	case CTRL_SHIFT_CLICK:			/* sort descending */
X  		file_button_sort_backwards(item, event);
X  		break;
X  
X! 	case META_CLICK:			/* load named file */
X! 		file_button_load(item, event);
X  		break;
X  
X! 	case META_SHIFT_CLICK:			/* store to named file */
X! 		file_button_save_to_file(item, event);
X! 		break;
X! 
X! 	default:				/* say what? */
X  		no_comprendo (event, "file_button");
X  		return;
X  	}
X--- 1134,1156 ----
X  		file_button_save(item, event);
X  		break;
X  
X! 	  case SHIFT_CLICK:			/* reload, no save first */
X  		file_button_reload(item, event);
X  		break;
X  
X! 	  case CTRL_CLICK:			/* sort ascending */
X  		file_button_sort(item, event);
X  		break;
X  
X! 	  case CTRL_SHIFT_CLICK:			/* sort descending */
X  		file_button_sort_backwards(item, event);
X  		break;
X  
X! 	  case META_CTRL_CLICK:			/* load named file */
X! 		file_button_io(item, event);
X  		break;
X  
X! 	  default:				/* say what? */
X  		no_comprendo (event, "file_button");
X  		return;
X  	}
X***************
X*** 1207,1212 ****
X--- 1270,1276 ----
X   */
X  static char Print_Command[256] = "lpr";
X  static int First_Print_Call = 1;
X+ static int in_print_button = 0;
X  
X  get_print_resource()
X  {
X***************
X*** 1221,1226 ****
X--- 1285,1315 ----
X  Panel_item item;
X  Event      *event;
X  {
X+ 	if ( event_action(event) == ACTION_MENU )
X+ 	  return;
X+ 
X+ 	switch (value_from_mask (event)) {
X+ 	  case PLAIN_CLICK:			/* Plain save */
X+ 		print_entry(item, event);
X+ 		break;
X+ 
X+ 	  case SHIFT_CLICK:			/* reload, no save first */
X+ 		print_all(item, event);
X+ 		break;
X+ 
X+ 	  case CTRL_CLICK:			/* sort ascending */
X+ 		print_regex(item, event);
X+ 		break;
X+ 
X+ 	  case CTRL_SHIFT_CLICK:			/* sort descending */
X+ 		set_print_command(item, event);
X+ 		break;
X+ 
X+ 	  default:				/* say what? */
X+ 		no_comprendo (event, "file_button");
X+ 		return;
X+ 	}
X+ 	in_print_button = 1;
X  }
X  
X  static void print_entry(item, event)
X***************
X*** 1227,1252 ****
X  Panel_item item;
X  Event      *event;
X  {
X! 	FILE *fp = popen(Print_Command, "w");
X  	if (First_Print_Call)
X  	  get_print_resource();
X  	save_card(current);
X  	fprintf(fp, "%s\n", current->c_text);
X  	pclose(fp);
X  }
X  
X  static void print_all(item, event)
X  Panel_item item;
X  Event      *event;
X  {
X  	struct card *p;
X! 	int i;
X! 	FILE *fp = popen(Print_Command, "w");
X  	if (First_Print_Call)
X  	  get_print_resource();
X  	save_card(current);
X! 	for (p = first, i =0; p != NULL_CARD; i++, p=p->c_next)
X! 	  fprintf(fp, "Record # %d \n%s\n\n", i, p->c_text);
X  	pclose(fp);
X  }
X  
X--- 1316,1387 ----
X  Panel_item item;
X  Event      *event;
X  {
X! 	FILE *fp;
X! 	if ( in_print_button ) {
X! 		in_print_button = 0;
X! 		return;
X! 	}
X  	if (First_Print_Call)
X  	  get_print_resource();
X+ 	fp = popen(Print_Command, "w");
X+ 	if ( fp == NULL ) {
X+ 		confirm("Could not execute print command %s", Print_Command);
X+ 		return;
X+ 	}
X  	save_card(current);
X  	fprintf(fp, "%s\n", current->c_text);
X  	pclose(fp);
X  }
X  
X+ static void print_regex(item, event)
X+ Panel_item item;
X+ Event      *event;
X+ {
X+ 	struct card *p;
X+ 	int search_type = xv_get(find_menu, MENU_CLIENT_DATA);
X+ 	char *match();
X+ 	FILE *fp;
X+ 	if ( in_print_button ) {
X+ 		in_print_button = 0;
X+ 		return;
X+ 	}
X+ 	if ( !init_find_button(search_type) )
X+ 	  return;
X+ 	if (First_Print_Call)
X+ 	  get_print_resource();
X+ 	fp = popen(Print_Command, "w");
X+ 	if ( fp == NULL ) {
X+ 		confirm("Could not execute print command %s", Print_Command);
X+ 		return;
X+ 	}
X+ 	save_card(current);
X+ 	for (p = first; p != NULL_CARD; p=p->c_next) {
X+ 		if ( match(p->c_text, search_type) )
X+ 		  fprintf(fp, "Record # %d \n%s\n\n", p->c_num, p->c_text);
X+ 	}
X+ 	pclose(fp);
X+ }
X+ 
X  static void print_all(item, event)
X  Panel_item item;
X  Event      *event;
X  {
X  	struct card *p;
X! 	FILE *fp;
X! 	if ( in_print_button ) {
X! 		in_print_button = 0;
X! 		return;
X! 	}
X  	if (First_Print_Call)
X  	  get_print_resource();
X+ 	fp = popen(Print_Command, "w");
X+ 	if ( fp == NULL ) {
X+ 		confirm("Could not execute print command %s", Print_Command);
X+ 		return;
X+ 	}
X  	save_card(current);
X! 	for (p = first; p != NULL_CARD; p=p->c_next)
X! 	  fprintf(fp, "Record # %d \n%s\n\n", p->c_num, p->c_text);
X  	pclose(fp);
X  }
X  
X***************
X*** 1270,1275 ****
X--- 1405,1414 ----
X  Event      *event;
X  {
X  	static int firsttime = 1;
X+ 	if ( in_print_button ) {
X+ 		in_print_button = 0;
X+ 		return;
X+ 	}
X  	if ( firsttime ) {
X  		firsttime = 0;
X  		if (First_Print_Call)
X***************
X*** 1506,1517 ****
X  {
X  	Menu_item find_item = xv_find(find_menu, MENUITEM, 
X  								  MENU_CLIENT_DATA, -1, NULL);
X! 	if ( find_item == NULL ) {
X! 		confirm("turn_on_sloppy: Bad news!");
X  		return;
X  	}
X  	xv_set(find_item, MENU_STRING, SLOPPY_EXPR_STR, NULL);
X  	xv_set(find_menu, MENU_CLIENT_DATA, SLOPPY);
X  }
X  
X  static void turn_on_egrep(item, event)
X--- 1645,1664 ----
X  {
X  	Menu_item find_item = xv_find(find_menu, MENUITEM, 
X  								  MENU_CLIENT_DATA, -1, NULL);
X! 	Menu_item list_item = xv_find(list_menu, MENUITEM,
X! 								  MENU_CLIENT_DATA, -1, NULL);
X! 	Menu_item print_item = xv_find(print_menu, MENUITEM,
X! 								  MENU_CLIENT_DATA, -1, NULL);
X! 
X! 	if ( find_item == NULL || list_item == NULL ) {
X! 		confirm("turn_on_sloppy: Bad news! xrolo internal error");
X  		return;
X  	}
X  	xv_set(find_item, MENU_STRING, SLOPPY_EXPR_STR, NULL);
X+ 	xv_set(list_item, MENU_STRING, SLOPPY_EXPR_STR, NULL);
X+ 	xv_set(print_item, MENU_STRING, SLOPPY_EXPR_STR, NULL);
X  	xv_set(find_menu, MENU_CLIENT_DATA, SLOPPY);
X+ 
X  }
X  
X  static void turn_on_egrep(item, event)
X***************
X*** 1520,1530 ****
X  {
X  	Menu_item find_item = xv_find(find_menu, MENUITEM, 
X  								  MENU_CLIENT_DATA, -1, NULL);
X! 	if ( find_item == NULL ) {
X! 		confirm("turn_on_egrep: Bad news!");
X  		return;
X  	}
X  	xv_set(find_item, MENU_STRING, EGREP_EXPR_STR, NULL);
X  	xv_set(find_menu, MENU_CLIENT_DATA, EGREP);
X  }
X  
X--- 1667,1683 ----
X  {
X  	Menu_item find_item = xv_find(find_menu, MENUITEM, 
X  								  MENU_CLIENT_DATA, -1, NULL);
X! 	Menu_item list_item = xv_find(list_menu, MENUITEM, 
X! 								  MENU_CLIENT_DATA, -1, NULL);
X! 	Menu_item print_item = xv_find(print_menu, MENUITEM, 
X! 								  MENU_CLIENT_DATA, -1, NULL);
X! 	if ( find_item == NULL || list_item == NULL) {
X! 		confirm("turn_on_egrep: Bad news! xrolo internal error");
X  		return;
X  	}
X  	xv_set(find_item, MENU_STRING, EGREP_EXPR_STR, NULL);
X+ 	xv_set(list_item, MENU_STRING, EGREP_EXPR_STR, NULL);
X+ 	xv_set(print_item, MENU_STRING, EGREP_EXPR_STR, NULL);
X  	xv_set(find_menu, MENU_CLIENT_DATA, EGREP);
X  }
X  
X***************
X*** 1534,1544 ****
X  {
X  	Menu_item find_item = xv_find(find_menu, MENUITEM, 
X  								  MENU_CLIENT_DATA, -1, NULL);
X! 	if ( find_item == NULL ) {
X! 		confirm("turn_on_soundex: Bad news!");
X  		return;
X  	}
X  	xv_set(find_item, MENU_STRING, SOUNDEX_EXPR_STR, NULL);
X  	xv_set(find_menu, MENU_CLIENT_DATA, SOUNDEX);
X  }
X  
X--- 1687,1703 ----
X  {
X  	Menu_item find_item = xv_find(find_menu, MENUITEM, 
X  								  MENU_CLIENT_DATA, -1, NULL);
X! 	Menu_item list_item = xv_find(list_menu, MENUITEM, 
X! 								  MENU_CLIENT_DATA, -1, NULL);
X! 	Menu_item print_item = xv_find(print_menu, MENUITEM, 
X! 								  MENU_CLIENT_DATA, -1, NULL);
X! 	if ( find_item == NULL || list_item == NULL ) {
X! 		confirm("turn_on_soundex: Bad news! xrolo internal error");
X  		return;
X  	}
X  	xv_set(find_item, MENU_STRING, SOUNDEX_EXPR_STR, NULL);
X+ 	xv_set(list_item, MENU_STRING, SOUNDEX_EXPR_STR, NULL);
X+ 	xv_set(print_item, MENU_STRING, SOUNDEX_EXPR_STR, NULL);
X  	xv_set(find_menu, MENU_CLIENT_DATA, SOUNDEX);
X  }
X  
X***************
X*** 1559,1571 ****
X  	if (event_action(event) == ACTION_MENU )
X  	  return;
X  
X! 	if (value_from_mask (event) == SHIFT_CLICK ) {
X  		if (xv_get(list_item, MENU_INACTIVE) == FALSE) {
X  			list_goto_button(item, event);
X- 			in_list_button = 1;
X- 			return;
X  		}
X  	}
X  }
X  
X  char *catbuf(buf, str)
X--- 1718,1737 ----
X  	if (event_action(event) == ACTION_MENU )
X  	  return;
X  
X! 	switch (value_from_mask (event) ) {
X! 	  case SHIFT_CLICK: 
X  		if (xv_get(list_item, MENU_INACTIVE) == FALSE) {
X  			list_goto_button(item, event);
X  		}
X+ 		break;
X+ 	  case CTRL_CLICK:
X+ 		list_button_match(item,event);
X+ 		break;
X+ 	  default:
X+ 		list_button(item, event);
X+ 		break;
X  	}
X+ 	in_list_button = 1;
X  }
X  
X  char *catbuf(buf, str)
X***************
X*** 1582,1591 ****
X  	return(buf);
X  }
X  
X  /*ARGSUSED*/
X! static void list_button (item, event)
X  	Panel_item	item;
X  	Event		*event;
X  {
X  	struct card 	*p;
X  	void notify_proc();
X--- 1748,1782 ----
X  	return(buf);
X  }
X  
X+ static void list_button_egrep();
X+ 
X+ static void list_button(item, event)
X+ 	Panel_item	item;
X+ 	Event		*event;
X+ {
X+ 	char *cp=re_comp("..");
X+ 	if ( cp ) {
X+ 		fprintf(stderr,cp);
X+ 		abort();
X+ 	}
X+ 	list_button_egrep(item, event, EGREP);
X+ }
X+ 
X+ static void list_button_match(item, event)
X+ 	Panel_item	item;
X+ 	Event		*event;
X+ {
X+ 	int search_type = xv_get(find_menu, MENU_CLIENT_DATA);
X+ 	if ( !init_find_button(search_type) )
X+ 	  return;
X+ 	list_button_egrep(item, event, search_type);
X+ }
X+ 
X  /*ARGSUSED*/
X! static void list_button_egrep (item, event, search_type)
X  	Panel_item	item;
X  	Event		*event;
X+     int         search_type;
X  {
X  	struct card 	*p;
X  	void notify_proc();
X***************
X*** 1593,1598 ****
X--- 1784,1790 ----
X  
X  #ifndef DONT_USE_MALLOC_LIST
X  	char *index_buf = NULL;
X+ 	char *index_current;
X  	int len;
X  #endif
X  
X***************
X*** 1612,1633 ****
X  	textsw_reset (rolocard, 0, 0);		/* clear the text window */
X  
X  #ifndef DONT_USE_MALLOC_LIST
X  	for (p = first; p != NULL_CARD; p = p->c_next) {
X  		char	*nl;
X  		char	line_buf [MAX_INDEX_LINE + 2];
X  
X! 		(void) sprintf (line_buf, "%d: ", p->c_num);	/* prepend # */
X! 		(void) strncat (line_buf, first_char (p->c_text),
X! 			MAX_INDEX_LINE);
X! 		line_buf [MAX_INDEX_LINE] = 0;	/* make sure it's terminated */
X  
X! 		(void) strcat (line_buf, "\n");	/* make sure of newline */
X! 		nl = index (line_buf, '\n');
X! 		*++nl = '\0';			/* chop at first line break */
X! 		index_buf = catbuf (index_buf, line_buf);
X  	}
X  
X- 	len = strlen (index_buf);
X  	window_set (rolocard, TEXTSW_MEMORY_MAXIMUM, len + 20000, 0);
X  
X  	(void) textsw_insert (rolocard, index_buf, len);
X--- 1804,1853 ----
X  	textsw_reset (rolocard, 0, 0);		/* clear the text window */
X  
X  #ifndef DONT_USE_MALLOC_LIST
X+ 
X+ 	/*  first calculate length of string to insert, then actually */
X+ 	/*  malloc the string and put the text into it.  even though this */
X+ 	/*  means two list traversals, for really large lists it will */
X+ 	/*  probably save a lot of time.  */
X+ 
X+ 	len = 0;
X  	for (p = first; p != NULL_CARD; p = p->c_next) {
X  		char	*nl;
X  		char	line_buf [MAX_INDEX_LINE + 2];
X  
X! 		if ( match(p->c_text, search_type) ) {
X! 			(void) sprintf (line_buf, "%d: ", p->c_num);	/* prepend # */
X! 			(void) strncat (line_buf, first_char (p->c_text),
X! 							MAX_INDEX_LINE);
X! 			line_buf [MAX_INDEX_LINE] = 0;	/* make sure it's terminated */
X! 			
X! 			(void) strcat (line_buf, "\n");	/* make sure of newline */
X! 			nl = index (line_buf, '\n');
X! 			*++nl = '\0';			/* chop at first line break */
X! 			len += strlen (line_buf);
X! 		}
X! 	}
X! 	index_buf = malloc (len);
X  
X! 	index_current = index_buf;	/* strcat slower than strcpy */
X! 	for (p = first; p != NULL_CARD; p = p->c_next) {
X! 		char	*nl;
X! 		char	line_buf [MAX_INDEX_LINE + 2];
X! 
X! 		if ( match(p->c_text, search_type) ) {
X! 			(void) sprintf (line_buf, "%d: ", p->c_num);	/* prepend # */
X! 			(void) strncat (line_buf, first_char (p->c_text),
X! 							MAX_INDEX_LINE);
X! 			line_buf [MAX_INDEX_LINE] = 0;	/* make sure it's terminated */
X! 
X! 			(void) strcat (line_buf, "\n");	/* make sure of newline */
X! 			nl = index (line_buf, '\n');
X! 			*++nl = '\0';			/* chop after first line break */
X! 			strcpy (index_current, line_buf);
X! 			index_current = index (index_current, '\n') + 1;
X! 		}
X  	}
X  
X  	window_set (rolocard, TEXTSW_MEMORY_MAXIMUM, len + 20000, 0);
X  
X  	(void) textsw_insert (rolocard, index_buf, len);
X***************
X*** 1637,1653 ****
X  		char	*nl;
X  		char	line_buf [MAX_INDEX_LINE + 2];
X  
X! 		(void) sprintf (line_buf, "%d: ", p->c_num);/* prepend number */
X! 		textsw_insert (rolocard, line_buf, strlen (line_buf));
X  
X! 		(void) strncpy (line_buf, first_char (p->c_text),
X! 			MAX_INDEX_LINE);
X! 		line_buf [MAX_INDEX_LINE] = 0;	/* make sure it's terminated */
X! 
X! 		(void) strcat (line_buf, "\n");	/* make sure of newline */
X! 		nl = index (line_buf, '\n');
X! 		*++nl = '\0';			/* chop at first line break */
X! 		textsw_insert (rolocard, line_buf, strlen (line_buf));
X  	}
X  #endif
X  
X--- 1857,1875 ----
X  		char	*nl;
X  		char	line_buf [MAX_INDEX_LINE + 2];
X  
X! 		if ( match(p->c_text, search_type) ) {
X! 			(void) sprintf (line_buf, "%d: ", p->c_num);/* prepend number */
X! 			textsw_insert (rolocard, line_buf, strlen (line_buf));
X  
X! 			(void) strncpy (line_buf, first_char (p->c_text),
X! 							MAX_INDEX_LINE);
X! 			line_buf [MAX_INDEX_LINE] = 0;	/* make sure it's terminated */
X! 			
X! 			(void) strcat (line_buf, "\n");	/* make sure of newline */
X! 			nl = index (line_buf, '\n');
X! 			*++nl = '\0';			/* chop at first line break */
X! 			textsw_insert (rolocard, line_buf, strlen (line_buf));
X! 		}
X  	}
X  #endif
X  
X***************
X*** 2008,2014 ****
X   *	current primary selection to get.
X   */
X  
X! static char *
X  get_selection()
X  {
X  	static Seln_holder	holder;
X--- 2230,2236 ----
X   *	current primary selection to get.
X   */
X  
X! char *
X  get_selection()
X  {
X  	static Seln_holder	holder;
X***************
X*** 2050,2056 ****
X   *	the value initially passed into mask_from_menu_value().
X   */
X  
X- static
X  int
X  value_from_mask (event)
X  	Event	*event;
X--- 2272,2277 ----
X*** patchlevel.h	Fri Feb 15 14:34:49 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/patchlevel.h	Fri Feb 15 14:23:59 1991
X***************
X*** 1 ****
X! #define PATCHLEVEL 4
X--- 1 ----
X! #define PATCHLEVEL 5
X*** xrolo.man	Fri Feb 15 14:34:50 1991
X--- /lutetia/luis/src/xrolo/xrolo.v2.5/xrolo.man	Fri Feb 15 14:23:48 1991
X***************
X*** 100,105 ****
X--- 100,110 ----
X  desired entry followed by a <SHIFT>-click
X  on the list button (or use the list button 
X  menu) to bring up the selected card.
X+ The "List Cards Matching Regex" menu
X+ entry produces an index list of cards
X+ matching the regular expression in the
X+ Expression text panel using the selected
X+ match type.
X  .TP
X  FILE BUTTON
X  This button loads and saves your rolodex
X***************
X*** 116,128 ****
X  by selecting the case [In]Sensitive pullright
X  menu or by setting the "xrolo.CaseInsensitiveSort"
X  resource to 0 or 1. Xrolo implements a very 
X! rudimentary field sort. each line in the card
X!  is considered to be a field. Pointing and
X  clicking on a selected field before invoking
X  the sort will cause xrolo to sort the cards
X! by the selected field. The last two items on the menu, which
X  can only be selected from the menu, will load
X! from or save to a named file.  You must select
X  a string in some window to provide the file
X  name, similar to the way the
X  .I TextEdit
X--- 121,133 ----
X  by selecting the case [In]Sensitive pullright
X  menu or by setting the "xrolo.CaseInsensitiveSort"
X  resource to 0 or 1. Xrolo implements a very 
X! rudimentary field sort. Each line in the card
X! is considered to be a field. Pointing and
X  clicking on a selected field before invoking
X  the sort will cause xrolo to sort the cards
X! by the selected field. The last item on the menu, which
X  can only be selected from the menu, will load
X! from or save to a named file.  You can select
X  a string in some window to provide the file
X  name, similar to the way the
X  .I TextEdit
X***************
X*** 141,148 ****
X  existing files, etc.
X  .TP
X  HELP BUTTON
X! Displays the information you're reading now.
X  .TP
X  FINISHED BUTTON
X     This button is used when you are finished
X  using
X--- 146,179 ----
X  existing files, etc.
X  .TP
X  HELP BUTTON
X! Displays the information you're reading now
X! and allows you to send mail to me.
X  .TP
X+ PHONE BUTTON
X+ On SparcStations this button can be used to
X+ dial a number entered in the expression field
X+ or highlighted with the mouse.  When selected
X+ the "Set Phone Attributes\" menu item creates
X+ a panel that allows speaker volume adjustment,
X+ the entering of a dial prefix and the enabling
X+ or disabling of the dial prefix.  Phone
X+ numbers and dial prefixes may consist of any
X+ alpha numeric character, *, # and \",\". 
X+ A comma in the dial string causes the dial
X+ routine to pause for 2 seconds before
X+ dialing the next character in the sequence.
X+ Xrolo supports several X resources used to
X+ to control default phone attributes.
X+ "xrolo.DefaultVolume" sets the default
X+ speaker volume. The volume must be entered
X+ as an integer value ranging in value from
X+ 0 to 100 where 100 is the maximum gain.
X+ "xrolo.UseDialPrefix" accepts a boolean value
X+ which enables or disables the use of the dial
X+ prefix while dialing.
X+ "xrolo.DialPrefix" set the default dial prefix
X+ string.
X+ .TP
X  FINISHED BUTTON
X     This button is used when you are finished
X  using
X***************
X*** 172,177 ****
X--- 203,213 ----
X  command is "lpr".  A user can customize
X  the default printer command by creating an
X  X resource entry called "xrolo.PrintCommand".
X+ The "Print Records Matching Regex" menu
X+ entry spools to the print command all cards
X+ matching the regular expression in the
X+ Expression text panel using the selected
X+ match type.
X  .TP
X  FIND BUTTON
X  This button searches for a regular expression
X***************
X*** 228,233 ****
X--- 264,276 ----
X  
X  xrolo.SearchType - default search mode for find. 0, 1 or 2 for EGREP,
X  SLOPPY or SOUNDEX search modes respectively.
X+ 
X+ xrolo.UseDialPrefix - 1 causes xrolo to use the dial prefix when dialing.
X+ 
X+ xrolo.DefaultVolume - volume gain for SS1 internal speaker.  The gain must
X+ be entered as an integer value between 0 and 100 where 100 is the maximum gain.
X+ 
X+ xrolo.DialPrefix - text string used to set the default dial prefix.
X  .SH FILES
X  .TP
X  $HOME/.rolo
X***************
X*** 241,247 ****
X  .I Rolo
X  changes to your home directory when it begins.
X  .SH AUTHOR
X! Ron Hitchens   (ronbo@vixen.uucp, hitchens@cs.utexas.edu)
X  .br
X     Version 1.0, March  1987
X     Version 2.0, August 1988
X--- 284,293 ----
X  .I Rolo
X  changes to your home directory when it begins.
X  .SH AUTHOR
X!  Ron Hitchens   (ronbo@vixen.uucp, hitchens@cs.utexas.edu)
X!    And
X!  Luis Soltero (luis@rice.edu)
X! 
X  .br
X     Version 1.0, March  1987
X     Version 2.0, August 1988
END_OF_FILE
if test 55035 -ne `wc -c <'xrolo.patch4'`; then
    echo shar: \"'xrolo.patch4'\" unpacked with wrong size!
fi
# end of 'xrolo.patch4'
fi
echo shar: End of shell archive.
exit 0