/*  $Header: /cvsroot/easymotif/EasyMotif/EasyMotif/lib/addmotif.c,v 5.5 2010/05/23 11:29:50 keidel Exp $ */
/*
 * $Log: addmotif.c,v $
 * Revision 5.5  2010/05/23 11:29:50  keidel
 * cleaned prototyping
 * removed UIL-code and files from source and Imakefile.
 * Prototype correction in Combibox.c
 * adding note in README to indicate how to change the PDF-reader
 * correcting prototypes in lib/PD/ListTree.c
 * correcting ANSI define in Xmind.h
 *
 * Revision 5.4  2007/02/11 10:21:25  keidel
 * more replaces of long int by int
 * Global project is now G_EASYMOTIF.PRJ, as it would conflict with
 *    CYGWIN (running under windows -- caseinsensitive filenames)
 * change getdelim to getdelim_h  in printhighlight.c (conflict with lib at CYGWIN)
 * correct Imake handling for CYGWIN
 * correct easymotid-Imakefile + Demo/Imakefile for CYGWIN
 * removed of globalproject
 *
 * Revision 5.3  2006/07/11 15:17:39  keidel
 * List_select callback segfaulted in clipboard at second selection (deselect)
 * Use menubar for cascaded Option-button (optional)
 * Create cascaded menus for option menu if cascade is selected
 * using menubar with one entry.
 * Modifiied the mask for Cascade button.
 *
 * Revision 5.1  2005/04/30 08:39:05  keidel
 * extern defined callbacks must able to change the name
 * xman cannot do -helpfile - (cannot pipe xman from man,
 * build compund comman in three steps and use own system function
 * to background the command.
 * psplot adapted to g++  error messages
 * Callback editor+Texteditor protected against misuse by user
 * make fileselector modal (CreatefilteredFBox)
 *
 * Revision 5.0  2004/12/11 11:42:18  keidel
 * *** empty log message ***
 *
 * Revision 4.2  2004/12/11 10:27:10  keidel
 * insensitivity via resources results in widget not editable, take out from RED
 * deleting function from workbench, ask for confirmation
 * indicating actual Projectfile and readonly in main title,
 * make save buttons insensitive if readonly
 * close ED if same function as called from CE
 * cannot change callbackname direct from CE, need to enter editor
 * Error Message, if function text is deleted, no save
 * WED/CE correction for open callbacks out of workbench
 * Make compiler happy
 *
 * Revision 4.1  2004/03/21 07:38:24  keidel
 * *** empty log message ***
 *
 * Revision 4.0  2004/02/28 09:53:00  keidel
 * Major Version
 *
 * Revision 3.2  2002/11/22 16:40:49  keidel
 * changes:
 * there are some templates with casesensitivity, change the name and correct the refs
 * final changes for uil creation
 * Cygwin support (compiling is OK - at aborts (as nedit))
 *
 * Revision 3.1  2002/09/27 16:53:51  keidel
 * SGI makefiles corrected
 * resourcename in question dialog changed (duplicated resource)
 * corrected recursion in WED, (editing cascades from option button run into infinite)
 * changes for sun4/Solaris8
 * added WRotLabel Widget (rotable label widget  >PD< )
 *
 * Revision 3.0  2002/08/01 07:59:39  keidel
 * stable version now, start all with 3.0
 *
 * Revision 2.1  2001/11/01 09:31:56  keidel
 * set revision 2  as beta version
 *
 * Revision 1.3  2001/10/30 17:03:23  keidel
 * added help using browser via resource-file and environment EasyMotif
 * extended Clipboard to save/restore  from file
 * no help on filebox if using libeasmofif.a
 * Makefile for SGI
 *
 * Revision 1.2  2001/09/01 07:14:08  keidel
 * added scaler (slider)-widget
 * added conditionals     use  -DLINUX   or -DSGI in Makefile
 *
 * Revision 1.7  2000/09/05 08:41:55  keidel
 * create filtere fbox   dont return if plaoin directory
 *
 * Revision 1.6  2000/04/05 04:54:59  keidel
 * .linux adaptions
 *
 * Revision 1.5  1998/02/06 06:35:13  keidel
 * adaptions to option -fullwarn IRIX 6.4
 *
 * Revision 1.3  1997/09/03  12:04:40  keidel
 * changed display of hex-numbers from %x  to %X 
 *
 * Revision 1.2  1996/12/04  12:32:40  keidel
 * corrected null char string check in gethex
 *
 * Revision 1.1  1996/10/08  11:50:33  keidel
 * Initial revision
 *
 */
/* INCLUDES */
#include <Xm/XmAll.h>
#include <Xm/AtomMgr.h>
#ifndef NOEASY
#include "../include/XMind.h"
#include "../include/Image.h"
#else
#include "../include/XMind.h"
#endif
#include <Xm/FileSB.h>

#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>

/* Declare a real callback to destroy the FileBox from, C.S. 18 October 2021 */
void destroyCB(Widget, XtPointer, XtPointer);

static  void  ActionCallback(Widget parent, void (*function)(char *), XmFileSelectionBoxCallbackStruct *cbs);
static void Highlight_on_cursor ( Widget w , void *data , XEvent *event,  Boolean *cont);

void GrabDelete(Widget dialog , XtCallbackProc call ) 
{
   Atom WM_DELETE_WINDOW;

	XtVaSetValues(dialog , XmNdeleteResponse,XmDO_NOTHING , NULL);
	WM_DELETE_WINDOW = XmInternAtom(XtDisplay(dialog)
		, "WM_DELETE_WINDOW" , False);
	XmAddWMProtocolCallback(dialog,WM_DELETE_WINDOW , call
		, (XtPointer)dialog);

}


/***************************************************************************
 ***************************************************************************
 *
 *  Functionname:	CreatefilteredFileBox
 *  
 *  Input:		Widget parent, char *path, 
 *                      (XtCallbackProc)ActionCallback , char * selected
 *
 *  Return:		Widget FileBox
 *
 *  Documentation:	Creates a FileSelectionDialog and adds two callbacks.
 *			the user callback "ActionCallback" with data char *
 *			it should retrieve the selected item. It is linked to
 *			the OK button	
 *

 *
 *  History:		22.1.95
 *  changed 	Wed Oct 25 08:27:36 MDT 1995
 *
 *
 ***************************************************************************
 ***************************************************************************/

static  void  ActionCallback(Widget parent, void (*function)(char *), XmFileSelectionBoxCallbackStruct *cbs)
{
  String fileString;

  
  
/*  XmStringGetLtoR(cbs->dir, XmSTRING_DEFAULT_CHARSET, &dirString); */
  XmStringGetLtoR(cbs->value, XmSTRING_DEFAULT_CHARSET, &fileString);
  if(fileString[strlen(fileString)-1] == '/')
      return;
  XtDestroyWidget(parent);
  function (fileString);
}

Widget CreatefilteredFBox (Widget parent, char *path ,void (*function)(char *)
		, char *title)
  {
  Widget FileBox;
  Arg args[40];
  Cardinal n;
  XmString tmpLabelString = NULL;

	n=0;
	XtSetArg(args[n],XmNdialogStyle,XmDIALOG_PRIMARY_APPLICATION_MODAL);
    n++;
 	FileBox = XmCreateFileSelectionDialog(XtParent(parent), title,args,n);

	n=0;
/*	set the search path */

  	tmpLabelString = XmStringCreate(path, XmSTRING_DEFAULT_CHARSET);  
 	XtSetArg(args[n], XmNdirMask, tmpLabelString); n++ ;  /* thats OK */

 	XtSetValues(FileBox,args,n) ; 


  	XtManageChild(FileBox);
	XtUnmanageChild(XtNameToWidget(FileBox,"Help"));
  /* It's tricky: XtDestroyWidget is a Motif function. In this case, 
     XtDestroyWidget destroys the FileBox-Widget, that's what we want.   
     ^^^^^^^^^^^^^^^ This is the wrong thing to do here, need to create 
     a real callback and call XtDestroyWidget from there, C.S. 18 October 2021 */
  /* XtAddCallback(FileBox, XmNcancelCallback, (XtCallbackProc) XtDestroyWidget, NULL); */
  destroyCB(FileBox, NULL, NULL);

  /* Double-click or activate 'OK'-Button: Jump to ActionCallback,     */
  /* User defined               */

  /* DEBUG: I'm not sure what he's trying to do here but the compiler hates it:
     XtAddCallback(FileBox, XmNokCallback,(XtCallbackProc) ActionCallback, (XtPointer) function); */
     XtAddCallback(FileBox, XmNokCallback,(XtCallbackProc) ActionCallback, NULL);
  XmStringFree(tmpLabelString);
  return FileBox;
}  
  

/***************************************************************************
 ***************************************************************************
 *
 *  Functionname:	GetColorbyName
 *  
 *  Input:		Widget w , char *colorstr
 *
 *  Return:		unsigned int 
 *
 *  Documentation:	gets the pixel value for the given colout name
 *			"colorstr"   may be used to set background
 *
 *
 *  History:		29.10.94
 *
 *
 ***************************************************************************
 ***************************************************************************/
unsigned int GetColorbyName(Widget w , char *colorstr) 
{
  int screen , stat;
  Display *dis;
  XColor hardware , RGB;

	dis = XtDisplay(w);
	screen = DefaultScreen(dis);
	stat = XLookupColor(dis , DefaultColormap(dis,screen),
		colorstr, &RGB,&hardware);
	if(stat) XAllocColor(dis,DefaultColormap(dis,screen),&hardware);
	return (hardware.pixel);


}

/***************************************************************************
 *
 *  Funktionsname:	MTxtGetHex
 *  
 *  Input:		Widget parent (Widget class XmText)
 *
 *  Return:		Integer value, zero when failed.
 *
 *  Documentation:	MTextGetInt is a function to access the contents
 *			of text-widgets. MTextGetInt converts the string     
 *			into an integer.
 *
 *
 *
 *  History:		27.12.94	generated by WizAnt  J.keidel
 *
 *
 ***************************************************************************/
 

int MTxtGetHex(Widget parent)
{
  char *contents;			/* Text-widget contentes	*/
  unsigned int value;

  if((contents = XmTextGetString(parent))) { 
    if (contents[0] == 0) 		/* Invalid String ?		*/
      value = 0;
    else
      sscanf(contents,"%x",&value);
  } else {
      value = 0;
  }

  XtFree(contents);			/* Free string			*/
  return value;				/* Return integer value		*/
} 


/***************************************************************************
 *
 *  Funktionsname:	MTxtSetHex
 *  
 *  Input:		Widget parent, int value
 *
 *  Return:		Bool
 *
 *  Documentation:	Sets an integer value into text-widgets as hex number. 
 *			Returns	TRUE when success, otherwise FALSE.
 *
 *  History:		27.12.94	created by WizAnt  J.keidel
 *
 *
 ***************************************************************************/
 
Bool MTxtSetHex(Widget parent, int value)
{

  char str[50];

  sprintf(str,"%8.8X",value);


  if (str[0]) {
    XmTextSetString(parent, str);
  }
  return (str!=NULL);
}
	

/***************************************************************************
 *
 *  Funktionsname:	MTextGetHexlong
 *  
 *  Input:		Widget parent (Widget class XmText)
 *
 *  Return:		long long Integer value, zero when failed.
 *
 *  Documentation:	MTextGetInt is a function to access the contents
 *			of text-widgets. MTextGetInt converts the string     
 *			into an integer.
 *
 *
 *
 *  History:		21.6.95	generated by WizAnt  J.keidel
 *
 *
 ***************************************************************************/
 

long long  MTextGetHexlong(Widget parent)
{
  char *contents;			/* Text-widget contentes	*/
  long long value;

  if((contents = XmTextGetString(parent))) { 
    if (contents[0] == 0) 		/* Invalid String ?		*/
      value = 0;
    else
      sscanf(contents,"%lli", &value);
  } else {
      value = 0;
  }

  XtFree(contents);			/* Free string			*/
  return value;				/* Return integer value		*/
} 


/***************************************************************************
 *
 *  Funktionsname:	MTextSetHexlong
 *  
 *  Input:		Widget parent, int value
 *
 *  Return:		Bool
 *
 *  Documentation:	Sets an integer value into text-widgets as hex number. 
 *			Returns	TRUE when success, otherwise FALSE.
 *
 *  History:		21.6.95	created by WizAnt  J.keidel
 *
 *
 ***************************************************************************/
 
Bool MTextSetHexlong(Widget parent, long long value)
{

  char str[50];

  sprintf(str,"%16.16llX",value);


  if (str[0]) {
    XmTextSetString(parent, str);
  }
  return (str!=NULL);
}
	

/***************************************************************************
 ***************************************************************************
 *
 *  Functionname:	SetColorbyName
 *  
 *  Input:		Widget target , String XmNforeground , char * colorname
 *
 *  Return:		
 *
 *  Documentation:	changes the color of target widget either foregound
 *			or background
 *
 *
 *  History:		Started 31.10.94
 *
 *
 ***************************************************************************
 ***************************************************************************/
void SetColorbyName(Widget target,String ground ,char *color) 
{
  int Narg;
  Arg	args[5];

	Narg=0;
	XtSetArg(args[Narg],ground,GetColorbyName(target,color));
	Narg++;
	XtSetValues(target,args,Narg);


}

/***************************************************************************
 ***************************************************************************
 *
 *  Functionname:	get16hex
 *  
 *  Input:		char *string , 
 *
 *  Return:		 unsigned int *value
 *
 *  Documentation:	void function get16flz gets a long hexadecimal value
 *		     (64 bit) from string
 *
 *
 *  History:		28.12.94
 *
 *
 ***************************************************************************
 ***************************************************************************/
void get16hex(char *string , unsigned int *value) 
{
   register char term='\0';

   register int i = 0;
   *value = *(value+1) = 0;        /* preclear */

   while ((term = *string++) != '\0' &&
           term != ' ')              
  {
     term=tolower(term);          /*  convert to lower case it's easier */
     if(isdigit(term) && !i)      /* convert numeric digit  */
     {
        *value = (*(value+1) >> 28) | *value <<4 ;
        *(value+1) = (*(value+1) << 4 ) | (int)(term-'0');
     }
     else if (term >='a' && term <='f' && !i)
     {
/*
       convert alpha digit  "a to f "
*/
        *value = (*(value+1) >> 28) | *value <<4 ;
        *(value+1) = (*(value+1) << 4 ) | (int)(term-'W');
     }
     else if( *(value+1) != 0)
        i++;
/*
   terminate conversion at non hex
*/
 }
 if (term == '\n' || term == '!') term = '\0';


}
  

void nav_highlight(Widget w){

	XtAddEventHandler(w , EnterWindowMask | LeaveWindowMask
	    ,FALSE,(XtEventHandler) Highlight_on_cursor, NULL);
}


static void Highlight_on_cursor ( Widget w , void *data , XEvent *event,  Boolean *cont){
  static Pixel bg,high = -1;
  XtResource request;
  
  	if((signed int)high == -1){
  		request.resource_name = "highlight";
  		request.resource_class= "Highlight";
  		request.resource_type = XtRPixel;
  		request.resource_size = sizeof(Pixel);
  		request.resource_offset = 0;
  		request.default_addr  = (XtPointer)NULL;
		request.default_type	=XmRImmediate;
  		XtGetSubresources(w, (XtPointer)&high,"highlight"
  		   , "Highlight", &request,1,NULL,0);
  	}
  	if(event->type == EnterNotify){
  			/* get original values for save */
  		XtVaGetValues(w , XmNbackground , &bg,NULL);
  		if(bg == high)
  			XtVaGetValues(XtParent(w), XmNbackground , &bg,NULL);
  		XtVaSetValues(w , XmNbackground , high,NULL);  
	}
	else if(event->type == LeaveNotify)
		XtVaSetValues(w , XmNbackground , bg,NULL);
}		 

void destroyCB(Widget w, XtPointer a, XtPointer b)
{
    XtDestroyWidget(w);
}
