
/* asutil.c  -  some Motif utilities used in the asedit program
		(C) A. Stochniol, 1991
		Last revision 14.10.1992

*/


#ifdef AMIGA
#include "amiga.h"
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <X11/Intrinsic.h>

#include <Xm/Xm.h>
#include <Xm/MessageB.h>
#include <Xm/SelectioB.h>
#include <Xm/Label.h>
#include <Xm/RowColumn.h>

#include "asedit_icon"

extern XmStringCharSet charset;
extern char   *PROGRAM_NAME;


/*
**	create_4buttons_dialog
**		create special 4 buttons  dialog box out of a
**		selection box and supports graphical pixmap.
**		The message contains of the pixmap and string
**		If you do not want use any pixmap
**		specify None  pixmap like this:  None
*/
#ifdef _NO_PROTO
Widget create_4buttons_dialog (parent, name, pixmap, message, arglist, argcount)
	Widget parent;
	String name;
	Pixmap pixmap;
	String message;
	Arg arglist[];
	int argcount;
#else  /* _NO_PROTO */
Widget create_4buttons_dialog (Widget parent, String name, Pixmap pixmap,
	String message, Arg arglist[], int argcount)
#endif
{
	Widget 		message_dialog;	/*  special message selection box */
	Widget		apply_button;	/*  4th button which should be managed */
	Widget          kid[5];         /*  children		          */
	Arg             al[10];         /*  arg list		          */
	register int    ac;             /*  arg count		          */
	XmString  	label_string;   /*  work string */
	Widget 		work_area;	/*  rowcolumn for pixmap and text */
	Widget 		pixmap_label;	/*  pixmap label 		  */
	Widget 		text_label;	/*  text label 			  */


	message_dialog = XmCreatePromptDialog(parent, name, arglist, argcount);


	ac = 0;
	XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
	work_area = XmCreateRowColumn(message_dialog, "workarea", al, ac);
	XtManageChild(work_area);

	if(pixmap != None)
	{
		ac = 0;
		XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
		XtSetArg(al[ac], XmNlabelPixmap, pixmap); ac++;
		pixmap_label = XmCreateLabel(work_area, "pixmap_label", al, ac);
		XtManageChild(pixmap_label);
	}

	ac = 0;
	label_string = XmStringCreateLtoR(message, charset);
	XtSetArg(al[ac], XmNlabelString, label_string ); ac++;
	text_label = XmCreateLabel(work_area, "text_label", al, ac);
	XtManageChild(text_label);
	XmStringFree(label_string);

	/* manage the apply button */
	apply_button = XmSelectionBoxGetChild (message_dialog,
						 XmDIALOG_APPLY_BUTTON);
	XtManageChild(apply_button);

	/*      Unmanage unneeded children.    */
	ac = 0;
	kid[ac++] = XmSelectionBoxGetChild (message_dialog, XmDIALOG_TEXT);
	kid[ac++] = XmSelectionBoxGetChild (message_dialog,
						     XmDIALOG_SELECTION_LABEL);
	XtUnmanageChildren (kid, ac);

	return(message_dialog);

}	/* create_4buttons_dialog */



/*-------------------------------------------------------------
**	create_4buttons_image_dialog
**		Create special 4 button message box out of a
**	Selection box.
*/
#ifdef _NO_PROTO
Widget create_4buttons_image_dialog (parent, name,
	image_string, message, arglist, argcount)
	Widget parent;
	String name;
	String image_string;
	String message;
	Arg arglist[];
	int argcount;
#else  /* _NO_PROTO */
Widget create_4buttons_image_dialog (Widget parent, String name,
	String image_string, String message, Arg arglist[], int argcount)
#endif
{
	Widget 		warning_dialog;	/*  special warning selection box */
	Widget 		work_area;	/*  rowcolumn for pixmap and text */
	Widget 		pixmap_label;	/*  pixmap label 		  */
	Widget 		text_label;	/*  text label 			  */
	Widget 		apply_button;	/*  apply button		  */
	Widget          kid[5];         /*  buttons		          */
	Pixel		foreground;	/*  dialog foreground		  */
	Pixel		background;	/*  dialog background		  */
	Pixmap		pixmap;		/*  dialog pixmap		  */
	register int    i;              /*  kid index			  */
	Arg             al[10];         /*  arg list		          */
	register int    ac;             /*  arg count		          */
	XmString  	label_string;   /*  work string */


	warning_dialog = XmCreatePromptDialog(parent, name, arglist, argcount);

	ac = 0;
	XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
	work_area = XmCreateRowColumn(warning_dialog, "workarea", al, ac);
	XtManageChild(work_area);

	ac = 0;
	XtSetArg(al[ac], XmNforeground, &foreground); ac++;
	XtSetArg(al[ac], XmNbackground, &background); ac++;
	XtGetValues(warning_dialog, al, ac);

	ac = 0;
	XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
	pixmap = XmGetPixmap(XtScreen(warning_dialog), image_string,
			     foreground, background);
	XtSetArg(al[ac], XmNlabelPixmap, pixmap); ac++;
	pixmap_label = XmCreateLabel(work_area, "pixmap_label", al, ac);
	XtManageChild(pixmap_label);

	ac = 0;
	label_string = XmStringCreateLtoR(message, charset);
	XtSetArg(al[ac], XmNlabelString, label_string ); ac++;
	text_label = XmCreateLabel(work_area, "text_label", al, ac);
	XtManageChild(text_label);
	/* because XmString is copied into an internal area by the label widget
	   we can free the storage associated with the string by calling XmStringFree
	   (after XtCreateManagedWidget or XtSetValues (etc.) are finished) */
	XmStringFree(label_string);

	apply_button = XmSelectionBoxGetChild (warning_dialog,
						 XmDIALOG_APPLY_BUTTON);
	XtManageChild(apply_button);



	/*      Unmanage unneeded children.    */
	i = 0;
	kid[i++] = XmSelectionBoxGetChild (warning_dialog, XmDIALOG_TEXT);
	kid[i++] = XmSelectionBoxGetChild (warning_dialog,
						     XmDIALOG_SELECTION_LABEL);
	XtUnmanageChildren (kid, i);

	return(warning_dialog);

}	/* create_4buttons_image_dialog */


/* bits for exclamation point in dialog */
char warningBits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00,
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00,
   0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00,
   0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};


/************************************************************************
 *
 *  CreateDefaultImage - create a default images for warning symbol.
 *
 **********************************<->***********************************/
#ifdef _NO_PROTO
XImage * CreateDefaultImage (bits, width, height)
    char *bits;
    int width;
    int height;
#else  /* _NO_PROTO */
XImage * CreateDefaultImage (char *bits, int width, int height)
#endif
{
    XImage *image;

    image = (XImage *) XtMalloc (sizeof (XImage));
    image->width = width;
    image->height = height;
    image->data = bits;
    image->depth = 1;
    image->xoffset = 0;
    image->format = XYBitmap;
    image->byte_order = LSBFirst;
    image->bitmap_unit = 8;
    image->bitmap_bit_order = LSBFirst;
    image->bitmap_pad = 8;
    image->bytes_per_line = (width+7)/8;
    return (image);
}   /* CreateDefaultImage */

extern Widget error_message;

#ifdef _NO_PROTO
void show_error_message(message)
	char *message;
#else  /* _NO_PROTO */
void show_error_message(char *message)
#endif
{
	/* procedure is used to show the error message widget with the current
	   message using the preset character set "charset" */
	Arg al[3];
	int ac=0;
	XmString  message_string =XmStringCreateLtoR(message, charset);

	XtSetArg(al[ac], XmNmessageString, message_string);  ac++;
	XtSetValues(error_message, al, ac);

	XmStringFree(message_string);	/* free memory allocated for XmString */

	XtManageChild (error_message);

}	/* show_error_message */


/*
**	CreateSorryHelp		- create simple help window
*/
#ifdef _NO_PROTO
Widget CreateSorryHelp (parent)
	Widget parent;
#else  /* _NO_PROTO */
Widget CreateSorryHelp (Widget parent)
#endif
{
	Widget		button;
	Widget		message_box;	/*  Message Dialog 	*/
	Arg		al[10];		/*  arg list		*/
	register int	n;		/*  arg count		*/

	static char	message[1000];	/*  help text	*/
	XmString	title_string = NULL;
	XmString	message_string = NULL;
	XmString	button_string = NULL;
	char 		work[128];



	/*	Generate message to display.
	*/
	sprintf (message, "\
The appropriate help system has not been yet implemented. \n\
\n\
I am very sorry about that.  A.S.\n\
Press the 'close' button to close this help window.  \n");

	message_string = XmStringCreateLtoR (message, charset);
	button_string = XmStringCreateLtoR (" Close ", charset);
	sprintf(work,"%s - %s", PROGRAM_NAME, "Help");
	title_string = XmStringCreateLtoR(work, charset);

	/*	Create MessageBox dialog.	*/
	n = 0;
	XtSetArg (al[n], XmNdialogTitle, title_string);  n++;

	/* let's unmanage OK and Help button so the
	   original cancel button will be positioned in the centre of the widget
	   i.e. in the visually recommended position ... */
	XtSetArg (al[n], XmNcancelLabelString, button_string);  n++;
	/* The default button needs to be set now to the Cancel button. Otherwise
	   when we press Enter the button won't change the colour to the select
	   colour etc. (the standard defaults to OK button) */
	XtSetArg(al[n], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON); n++;

	XtSetArg (al[n], XmNmessageString, message_string);  n++;
	message_box = XmCreateMessageDialog (parent, "helpbox", al, n);

	/* unmanage OK and Help buttons */
	button = XmMessageBoxGetChild (message_box, XmDIALOG_OK_BUTTON);
	XtUnmanageChild (button);
	button = XmMessageBoxGetChild (message_box, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild (button);


	/*	Free strings and return MessageBox.	*/

	XmStringFree(  title_string);
	XmStringFree(message_string);
	XmStringFree( button_string);

	return (message_box);

}	/* CreateSorryHelp */

static Pixmap icon_pixmap = NULL;	/* globally accessible for about program message */


/*
**	CreateAboutProgramMessage	- create simple message widget
*/
#ifdef _NO_PROTO
Widget CreateAboutProgramMessage (parent)
	Widget parent;
#else  /* _NO_PROTO */
Widget CreateAboutProgramMessage (Widget parent)
#endif
{
	Widget		button;
	Widget		message_box;	/*  Message Dialog 	*/
	Arg		al[10];		/*  arg list		*/
	register int	n;		/*  arg count		*/

	static char	message[1000];	/*  help text	*/
	XmString	title_string = NULL;
	XmString	message_string = NULL;
	XmString	button_string = NULL;
	char 		work[128];



	/*	Generate message to display.
	*/
	sprintf (message, "\
ASEDIT editor\n\
Version 1.1\n\
Copyright (C) A. Stochniol, 1992.\n\
(A.Stochniol@ic.ac.uk)");

	message_string = XmStringCreateLtoR (message, charset);
	button_string = XmStringCreateLtoR (" Close ", charset);

	sprintf(work, "%s - %s", PROGRAM_NAME, "About");
	title_string = XmStringCreateLtoR(work, charset);

	/*	Create MessageBox dialog.	*/
	n = 0;
	XtSetArg (al[n], XmNdialogTitle, title_string);  n++;
	/* specify the icon_pixmap as the symbol pixmap */
	if(icon_pixmap != NULL)
	{
	    XtSetArg(al[n], XmNsymbolPixmap, icon_pixmap);  n++;
	}

	/* let's unmanage OK and Help button so the
	   original cancel button will be positioned in the centre of the widget
	   i.e. in the visually recommended position ... */
	XtSetArg (al[n], XmNcancelLabelString, button_string);  n++;
	/* The default button needs to be set now to the Cancel button. Otherwise
	   when we press Enter the button won't change the colour to the select
	   colour etc. (the standard defaults to OK button) */
	XtSetArg(al[n], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON); n++;

	XtSetArg (al[n], XmNmessageString, message_string);  n++;
	XtSetArg (al[n], XmNmessageAlignment, XmALIGNMENT_CENTER); n++;
	message_box = XmCreateMessageDialog (parent, "about", al, n);

	/* unmanage OK and Help buttons */
	button = XmMessageBoxGetChild (message_box, XmDIALOG_OK_BUTTON);
	XtUnmanageChild (button);
	button = XmMessageBoxGetChild (message_box, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild (button);


	/*	Free strings and return MessageBox.	*/

	XmStringFree(  title_string);
	XmStringFree(message_string);
	XmStringFree( button_string);

	return (message_box);

}	/* CreateAboutProgramMessage */


/****************************  set_appl_icon_pixmap  ***********************
 *
 * Set the icon for the application shell widget (top level) to the icon_pixmap.
 * For the best results in portability into environments where the user may
 * not be running the most up-to-date window manager (that supports setting
 * iconPixmap directly) the icon window is created directly. Additionally, once
 * done we can paint whatever image we like in that window ! So, the function
 * may also be called repeatedly to dynamically update shell's icon window.
 *
*/

#ifdef _NO_PROTO
void set_appl_icon_pixmap (shell, icon_pixmap)
    Widget shell;
    Pixmap icon_pixmap;
#else  /* _NO_PROTO */
void set_appl_icon_pixmap (Widget shell, Pixmap icon_pixmap)
#endif
{
    Window icon_window, root_window;
    int x, y;
    unsigned int width, height, border_width, depth;
    Status status;
    Arg al[4];
    register int ac;
    Display *display = XtDisplay(shell);

    /* get the current icon window associated with the shell */
    ac = 0;
    XtSetArg(al[ac], XmNiconWindow, &icon_window );  ac++;
    XtGetValues(shell, al, ac);

    /* if there is no window associated with the shell create one.
       (first call - shell has not yet had its icon window set).
    */
    if(!icon_window)
    {
	/* get the size of the icon_pixmap, then create an InputOutput window */
	status = XGetGeometry(display, icon_pixmap, &root_window, &x, &y,
			&width, &height, &border_width, &depth);
	if(!status || !(icon_window = XCreateSimpleWindow (display, root_window,
				0, 0, width, height, border_width,
				CopyFromParent, CopyFromParent)))
	{
	    /* in the unlikely event that XGetGeometry or XCreateSimpleWindow
	       fails, we fall back on a modern method using XmNiconPixmap and
	       hope that the window managers understand it */
	    ac = 0;
	    XtSetArg(al[ac], XmNiconPixmap, icon_pixmap);  ac++;
	    XtSetValues(shell, al, ac);
	    return;
	}
	/* set the window created as the icon window */
	ac = 0;
	XtSetArg(al[ac], XmNiconWindow, icon_window);  ac++;
	XtSetValues(shell, al, ac);
    }
    /* set the current icon_pixmap as the window's background pixmap */
    XSetWindowBackgroundPixmap(display, icon_window, icon_pixmap);
    XClearWindow(display, icon_window);		/* to redisplay this window */

}   /* set_appl_icon_pixmap */

/****************************  set_asedit_icon  *****************************
    procedure first creates a pixmap from bitmap then calls procedure to create
    an icon for the application
*/
#ifdef _NO_PROTO
void set_asedit_icon(shell, colours_source, icon_name)
    Widget shell;
    Widget colours_source;
    char *icon_name;
#else  /* _NO_PROTO */
void set_asedit_icon(Widget shell, Widget colours_source, char *icon_name)
#endif
{
    /**Pixmap icon_pixmap; ** making it globally accessible for CreateAboutProgram .. */
    Pixel background, foreground;
    Arg al[4];
    register int ac;

    /* get the foreground and background colours from colours_source widget;
       from a shell widget only background can be obtained (foreground is not
       defined); for asedit the most appropriate colours are those from the
       edit_text window (set that widget on a call for this procedure) */

    ac = 0;
    XtSetArg(al[ac], XmNforeground, &foreground );  ac++;
    XtSetArg(al[ac], XmNbackground, &background);   ac++;
    XtGetValues(colours_source, al, ac);

    /* create a pixmap from a bitmap using colours just obtained */
    icon_pixmap = XCreatePixmapFromBitmapData (XtDisplay(shell),
	    RootWindowOfScreen(XtScreen(shell)),
	    asedit_icon_bits, asedit_icon_width, asedit_icon_height,
	    foreground, background,
	    DefaultDepthOfScreen(XtScreen(shell)));
    /*test*** fprintf(stderr, "\n foreground, background = %lu  %lu", foreground, background ); *****/

    set_appl_icon_pixmap (shell, icon_pixmap);

    /* finally set the icon name */
    ac = 0;
    XtSetArg (al[ac], XmNiconName, icon_name);     ac++;
    XtSetValues (shell, al, ac);

}   /* set_asedit_icon */


#ifdef _NO_PROTO
void set_dialog_title(w, title)
    Widget w;
    char *title;
#else  /* _NO_PROTO */
void set_dialog_title(Widget w, char *title)
#endif
{	/* sets the dialogTitle of the widget w using character set 'charset'
	   and adding in front of the 'title' string PROGRAM_NAME and a dash */

    register int  ac;		/* arg count		    */
    Arg 	  al[3];	/* arg list		    */
    XmString  	  xmstr;	/* work XmString */
    char	  work[256];

    ac = 0;
    sprintf(work, "%s - %s", PROGRAM_NAME, title);
    xmstr =XmStringCreateLtoR(work, charset);
    XtSetArg (al[ac], XmNdialogTitle, xmstr);   ac++;
    XtSetValues(w, al, ac);
    XmStringFree(xmstr);	/* free memory allocated for XmString */

}   /* set_dialog_title */
