 /*
  * Khoros: $Id: view.c,v 1.3 1992/03/20 22:50:07 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: view.c,v 1.3 1992/03/20 22:50:07 dkhoros Exp $";
#endif

 /*
  * $Log: view.c,v $
 * Revision 1.3  1992/03/20  22:50:07  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xvutils.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    	    file name: view.c                         <<<<
   >>>>                                                       <<<<
   >>>>         Creates a View Widget			      <<<<
   >>>>                                                       <<<<
   >>>>                xvf_view_wait()			      <<<<              
   >>>>                xvf_create_view()		      <<<<              
   >>>>                xvf_quit_view()			      <<<<              
   >>>>                xvf_unglyph_view()		      <<<<              
   >>>>                xvf_glyph_view()		  	      <<<<   
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/************************************************************
*
*  Routine Name:  xvf_view_wait(filename,label,glyph_label)
*
*      Purpose:   creates a warning form which has two
*                 choises (Yes is 1, NO puts 0 in WARN_SIG).
*                 NOTE: this routine will grab all events 
*                 while running.  You may wish to use
*		  xvf_create_view().
*
*        Input:   filename  - character string containing the name
*                            (and path) of the ascii file to be displayed
*                            in help widget.  The filename may be specified
*                            using a '~' since the ~ will be expanded
*                            for the current machine.
*
*                 label    - short label for top of viewer.
*			     NULL gives default of "VIEW".
*
*		  glyph_label - label to be used if view widget is glyphed
*
*       Output:   a form with the desired ascii  file displayed in it will
*		  appear until "quit" is chosen.
*
*    Called By:   the application program
*
*   Written By:   Stephanie Hallett
*
*
*************************************************************/

int xvf_view_wait(filename,label,glyph_label)
char *filename;
char *label;
char *glyph_label;
{
   int status;

   VIEW_DONE = false;

   if (xvf_display == NULL)
   {
	fprintf(stderr, "see file '%s'\n", filename);
	return(true);
   }
   status = xvf_create_view(filename,label,glyph_label);

   if (status == false)
      return(false);

   while(!VIEW_DONE)
   {
      xvf_process_event();      /* this does XtNextEvent/DispatchEvent*/
   }
   return(true);
}


/************************************************************
*
*  Routine Name:  xvf_create_view(filename,view_label,glyph_label)
*
*      Purpose:   Does the  actual creation of a viewwer widget. 
*		  The viewwer widget consists of a form widget with a label
*		  text widget for displaying the file, a glyph button,
*		  and a quit button.
*
*        Input:   filename      - name and full path of file to be displayed
*                 view_label    - short label for top of widget
*                                 NULL will cause default of "ERROR"
*		  glyph_label   - label for acknowledgement button
*                                 NULL will cause default of "OK"
*
*       Output:   wait to user to acknowledge message.
*
*    Called By:   xvf_view_wait() or the application program
*
*   Written By:   Danielle Argiro Stephanie Hallett
*
*************************************************************/
typedef struct {
	Widget toplevel;
        Widget glyph;
	char   *tempfile;
	}  View_Data;
#define VIEWWER_WIDTH  60
#define VIEWWER_HEIGHT 40

int xvf_create_view(filename,view_label,glyph_label)
char *filename;
char *view_label;
char *glyph_label;
{
   Widget toplevel;	/* toplevel widget for view */
   Widget back;		/* backplane for view */
   Widget label;	/* label describing type of view */
   Widget quit;		/* quit button to get rid of view */
   Widget glyph_button; /* glyph widget on view pane */
   Widget glyph;	/* glyph widget to glyph view */
   Widget glyph_to_form; /* command wid of glyph */
   Arg    arg[25];
   char   *fullpath;
   void   xvf_quit_view();
   int    i, stat, label_width;
   char   name[MaxLength], glyph_name[MaxLength], command[MaxLength];
   char   *top_name, *cap_top_name, *transport_identifier(), *tempfile;
   void   xvf_unglyph_view(), xvf_glyph_view();
   View_Data *viewdata;

   if (filename == NULL)
   {
      fprintf(stderr,"xvf_view: needs the filename of the man page\n");
      return(false);
   }
   viewdata = (View_Data *)calloc(1, sizeof(View_Data));

   /*
    *  Create a temporary file in which we will copy the data over.
    */
   if (transport_identifier(filename, command) != NULL)
   { 
      if (tempfile = vtempnam("xview.tmp"))
      {
	 (void) sprintf(command, "kcp -i %s -o %s", filename, tempfile);
         if (ksystem(command) != 0)
	 {
	    (void) sprintf(command, "Sorry, unable to retrieve the file '%s' \
from the appropriate transport.  The xvviewer must copy the file into a \
temporary file in which to view the file data, but the kcp failed.", filename);
	    xvf_error_wait(command, "HELP ERROR","OK");
	    return(false);
	 }
      }
      else
      {
	 (void) sprintf(command, "Sorry, unable to create a temporary file '%s'\
 from the appropriate transport.  The xvviewer must copy the file into a \
temporary file in which to view the file data, but the kcp failed.", filename);
	 xvf_error_wait(command, "HELP ERROR","OK");
	 return(false);
      }
      filename = tempfile;
      viewdata->tempfile = tempfile;
   }

   fullpath = vfullpath(filename, NULL, NULL);
   stat = open(fullpath,O_RDONLY,0664);
   if (stat <= 0)
   {  /* file not there, or cannot be opened */
      xvf_error_wait("Sorry, unable to find appropriate file",
	  "HELP ERROR","OK");
      return(false);
   }
   (void) close(stat);


   /*
    * create identifying widget name
    */
   sprintf(name,"%d_view",View_cnt);
   sprintf(glyph_name,"%d_view_glyph",View_cnt);
   View_cnt++;
   top_name = xvf_strcpy(glyph_name);
   cap_top_name = xvf_cap_first_letter(top_name);

   /* 
    * create the view box's glyph and add it to the list of 
    * toplevels that is used with journal playback. 
    */
   i = 0;
   XtSetArg(arg[i], XtNscreen, xvf_screen); 		i++;
   XtSetArg(arg[i], XtNargc, xvf_ac); 	         	i++;
   XtSetArg(arg[i], XtNargv, xvf_av);	          	i++;
   XtSetArg(arg[i], XtNwinGravity, StaticGravity);	i++; 
   XtSetArg(arg[i], XtNmappedWhenManaged, False);       i++;
   glyph = XtAppCreateShell(top_name, cap_top_name,
			applicationShellWidgetClass, xvf_display, arg, i);
   viewdata->glyph = glyph;
   xvf_add_toplevel(viewdata->glyph);

   i = 0;
   XtSetArg(arg[i],XtNheight, (Dimension) 2*F_H);		i++;
   if (glyph_label == NULL)
      XtSetArg(arg[i],XtNlabel, xvf_strcpy("view file"));
   else
      XtSetArg(arg[i],XtNlabel, xvf_strcpy(glyph_label));	i++;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);          	i++;
   glyph_to_form = XtCreateManagedWidget("glyph_to_form",
	commandWidgetClass,glyph,arg,i);
   XtAddCallback(glyph_to_form,XtNcallback,xvf_unglyph_view,viewdata);
   top_name = xvf_strcpy(name);
   cap_top_name = xvf_cap_first_letter(top_name);

   /* 
    * create the view box's toplevel widget and add it to the list of 
    * toplevels that is used with journal playback. 
    */
   i = 0;
   XtSetArg(arg[i], XtNscreen, xvf_screen); 		i++;
   XtSetArg(arg[i], XtNargc, xvf_ac); 	         	i++;
   XtSetArg(arg[i], XtNargv, xvf_av);	          	i++;
   XtSetArg(arg[i], XtNwinGravity, StaticGravity);	i++; 
   toplevel = XtAppCreateShell(top_name, cap_top_name,
 			applicationShellWidgetClass, xvf_display, arg, i);
   viewdata->toplevel = toplevel;
   xvf_add_toplevel(viewdata->toplevel);

   /* 
    * create the backplane widget 
    */
   i = 0;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);      		i++;    
   XtSetArg(arg[i],XtNborderWidth,1);				i++;
   XtSetArg(arg[i],XtNdefaultDistance,4);			i++;
   back = XtCreateManagedWidget("form_back",
		formWidgetClass, toplevel,arg,i);

   /* 
    * create the glyph_button widget 
    */
   i = 0;
   XtSetArg(arg[i],XtNlabel,xvf_strcpy("glyph"));		i++;
   XtSetArg(arg[i],XtNwidth,(Dimension) 6*xvf_font_width);	i++;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);			i++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[i],XtNfont,xvf_font);                      i++;
   }
   glyph_button = XtCreateManagedWidget("glyph",
      	commandWidgetClass,back,arg,i);
   XtAddCallback(glyph_button,XtNcallback,xvf_glyph_view,viewdata);

   /* 
    * create label widget 
    */
   i = 0;
   label_width = VIEWWER_WIDTH*xvf_font_width - 12*xvf_font_width;
   if(view_label != NULL)
      XtSetArg(arg[i],XtNlabel,xvf_strcpy(view_label));
   else
      XtSetArg(arg[i],XtNlabel,xvf_strcpy("VIEWER"));		i++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[i],XtNfont,xvf_font);                      i++;
   }
   XtSetArg(arg[i],XtNwidth,(Dimension) label_width);		i++;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);			i++;
   XtSetArg(arg[i],XtNfromHoriz,glyph_button);			i++;
   XtSetArg(arg[i],XtNborderWidth,0);				i++;
   label = XtCreateManagedWidget("view_wid",
      	labelWidgetClass,back,arg,i);

   /* 
    * create text widget 
    */
   i = 0;
   XtSetArg(arg[i],XtNeditType,XawtextRead);			i++;
   XtSetArg(arg[i],XtNtype,XawAsciiFile);			i++;
   XtSetArg(arg[i],XtNstring,fullpath);				i++;
   XtSetArg(arg[i],XtNwidth ,(Dimension) 
		(VIEWWER_WIDTH*xvf_font_width));		i++;
   XtSetArg(arg[i],XtNheight,(Dimension) 
		(VIEWWER_HEIGHT*xvf_font_height));		i++;
   XtSetArg(arg[i],XtNscrollVertical,  XawtextScrollWhenNeeded);i++;
   XtSetArg(arg[i],XtNwrap,    XawtextWrapWord);        	i++;
   XtSetArg(arg[i],XtNinsertPosition,0);			i++;
   XtSetArg(arg[i],XtNfromVert,glyph_button);			i++;
   XtSetArg(arg[i],XtNleftMargin,LEFT_MARGIN);			i++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[i],XtNfont,xvf_font);                      i++;
   }
   (void) XtCreateManagedWidget("text", asciiTextWidgetClass, back, arg, i);

   /* 
    * create quit button 
    */
   i = 0;
   XtSetArg(arg[i],XtNfromVert,NULL);				i++;
   XtSetArg(arg[i],XtNfromHoriz,label);				i++;
   XtSetArg(arg[i],XtNlabel,"QUIT");				i++;
   XtSetArg(arg[i],XtNwidth,(Dimension) 5*xvf_font_width);	i++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[i],XtNfont,xvf_font);                      i++;
   }
   quit = XtCreateManagedWidget("quit_wid",
	commandWidgetClass,back,arg,i);
   XtAddCallback(quit,XtNcallback,xvf_quit_view,viewdata);

   XtRealizeWidget(toplevel);
   XtRealizeWidget(glyph);

   xvf_add_protocol_handler(viewdata->toplevel, "WM_DELETE_WINDOW", 
			    xvf_quit_view, viewdata);
   XFlush(XtDisplay(toplevel));
   return(true);
}


/* callback used to exit viewer */

void xvf_quit_view(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   View_Data *viewdata;

   viewdata = (View_Data *) clientData;

   /*
    * delete the view box's toplevel & glyph from the list 
    * used by journal playback before destroying them
    */
   xvf_remove_protocol_handler(viewdata->toplevel, "WM_DELETE_WINDOW", 
			       xvf_quit_view, viewdata);
   xvf_delete_toplevel(viewdata->toplevel);
   xvf_delete_toplevel(viewdata->glyph);
   XtUnmapWidget(viewdata->toplevel);
   XtDestroyWidget(viewdata->toplevel);
   XtUnmapWidget(viewdata->glyph);
   XtDestroyWidget(viewdata->glyph);
   if (viewdata->tempfile != NULL)
   {
      unlink(viewdata->tempfile);
      free(viewdata->tempfile);
   }
   free(viewdata);

   VIEW_DONE = true;
}


void xvf_unglyph_view(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   View_Data *viewdata;

   viewdata = (View_Data *) clientData;

   XtUnmapWidget(viewdata->glyph);
   XtMapWidget(viewdata->toplevel);
   XSync(xvf_display,0);
}


void xvf_glyph_view(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   View_Data *viewdata;

   viewdata = (View_Data *) clientData;

   XtUnmapWidget(viewdata->toplevel);
   XtMapWidget(viewdata->glyph);
   XSync(xvf_display,0);
}
