/*
        mindlib/wid_funcs.c

        Copyright (C) 1994-97 flux GbR (flux@berlin.snafu.de)

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2, or (at your option)
        any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/***************************************************************************
 ***************************************************************************
 *
 *  Filename:		wid_funcs.c
 *  
 *  Description:	Some 'easy-to-use' functions to access the 
 *			contents of widgets or to manipulate them.
 *
 *
 ***************************************************************************
 *
 *  Function Export:
 *
 *  TEXT FUNCTIONS :	int 	MTextGetInt(Widget parent);
 *  			double 	MTextGetFloat(Widget parent);
 *			Bool 	MTextSetInt(Widget parent, int value);
 *			Bool 	MTextSetFloat(Widget parent, double value);
 *
 *  SCALE FUNCTIONS:	double	MScaleGetFloat(Widget parent); 
 *			Bool 	MScaleSetFloat(Widget parent, double float);
 *
 *  LIST FUNCTIONS:	char   *MListGetString(Widget parent);
 *                 	char  **MListGetStrings(Widget parent);
 *
 *                 	Bool    MListSetString(Widget parent, char *item);
 *
 *			Bool    MListAddString(Widget parent, char *item);
 *			Bool    MListAddStrings(Widget parent, char **items,
 *                                              int number);
 *
 *			int 	MListGetPosition(Widget parent);
 *			int    *MListGetPositions(Widget parent);
 *			int     MListGetSelectedCount(Widget parent);
 *
 *			void 	MListDeleteAllItems(Widget parent);
 *			void 	MListSelectAllItems(Widget parent);
 *			
 * RADIO FUNCTIONS	char   *MRadioGetSelectedItem(Widget parent);
 *                      Widget  MRadioGetWidget(Widget parent, int pos);
 *			Bool    MRadioSetPosition(Widget parent, int);
 *
 * STRING FUNCTIONS	char   *MGetString(XmString xstr);
 *                      XmString MStringCreate(char *str);
 *
 * OPTIONMENU FUNCTIONS int     MOptionGetPosition(Widget parent);
 *			int     MOptionSetPosition(Widget parent, int);
 *
 * DIALOG FUNCTIONS	void 	MCloseDialog(Widget wid);
 *
 ***************************************************************************
 ***************************************************************************/
/*
    Modified MListSort due to the fact, that under IRIX the redisplay after sorting
    	      within the strintable of list-widget doesn't work. Duplicate the string table
	      do the sort within the duplicated, delete all in widget and add  the sorted table in again.
	      J.Keidel  (wizAnt Software   Email  wizant.keidel@freenet.de )Wed Nov  7 16:57:39 CET 2001

*/
	 
/* DEFINES */

#define XPM_YES
/* #define XPM_NO */

 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <Xm/XmAll.h>
#include <Xm/Protocols.h>
#include <Xm/SelectioB.h>
#include <Xm/AtomMgr.h>
#if NOEASY != 1 
#include "../include/XMind.h"
#include "../include/Image.h"
#else
#include "../include/XMind.h"
#include "../include/Image.h"
#endif

#ifdef XPM_YES
#include <X11/xpm.h>
#endif

/* STATIC FUNCTIONS */

static int GetExp(int value);
#ifndef DEC
#ifndef strdup
char *strdup(const char *s); 
#endif
#endif

/***   TEXT WIDGETS FUNCTIONS ***/

/***************************************************************************
 *
 *  Funktionsname:	MTextGetInt
 *  
 *  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:		09.02.93	Created by flux
 *          		30.07.97	Check for TextField
 *
 *
 ***************************************************************************/
 
int MTextGetInt(Widget parent)
{
  char *contents;			/* Text-widget contentes	*/
  int value;

  /* Check Widget */
  if (!parent) return 0;
  if (!(XtIsObject(parent))) return 0;

  if (XmIsTextField(parent)){
    contents = XmTextFieldGetString(parent);
  } else { 
    if (XmIsText(parent)){
        contents = XmTextGetString(parent);
    } else{
      return 0;
    }
  }

  if(contents) { 
    if (contents == (char *) "") 		/* Invalid String ?		*/
      value = 0;
    else
      value = atoi(contents);
  } else {
      value = 0;
  }

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


/***************************************************************************
 *
 *  Funktionsname:	MTextGetFloat
 *  
 *  Input:		Widget parent (Widget class XmText)
 *
 *  Return:		double, zero when failed.
 *
 *  Documentation:	MTextGetFlaot is a function to access the contents
 *			of text-widgets. MTextGetFlaot converts the string     
 *			into a double-precision floating-point number.
 *			Its not possible to return a double-precision value,
 *			some machines would cause error.
 *
 *
 *
 *  History:		09.02.93	Created by flux
 *			04.18.95	Motif type converter added
 *			07.09.95        Motif type converter deleted by daniel
 *			30.07.97	Check for Widget and Textfield added
 *
 *
 ***************************************************************************/
 
double MTextGetFloat(Widget parent)
{
  char *contents;			
  double value=0.0;
  
  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;

  if (XmIsTextField(parent)){
    contents = XmTextFieldGetString(parent);
  } else { 
    if (XmIsText(parent)){
        contents = XmTextGetString(parent);
    } else{
      return FALSE;
    }
  }
  if(contents) {
    if (!(contents))	value = 0.0;
    else 		value = atof(contents);
  } else value = 0.0;

  if (contents) XtFree(contents);	
  return value;		
} 


/***************************************************************************
 *
 *  Funktionsname:	MTextSetString
 *  
 *  Input:		Widget parent, char * value
 *
 *  Return:		Bool
 *
 *  Documentation:	Sets a string into text-widgets. 
 *			Returns	TRUE when success, otherwise FALSE.
 *			MTextSetString tests for valid widgets and if the
 *			destination widget is a XmTextField or XmText-Widget.
 *
 *
 *  History:		01-22-99 	Created by flux.
 *
 *
 ***************************************************************************/
 
Bool MTextSetString(Widget parent, char *str)
{
  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;

  if (str) {
    if (XmIsTextField(parent)){
        XmTextFieldSetString(parent, str);
    } else { 
      if (XmIsText(parent)){
        XmTextSetString(parent, str);
      } else{
        return FALSE;
      }
    }
  }
  return False;
}

/***************************************************************************
 *
 *  Funktionsname:	MTextGetString
 *  
 *  Input:		Widget parent (Widget class XmText or XmTextField)
 *
 *  Return:		char * or NULL
 *
 *  Documentation:	MTextGetString is a wrapper for XmTextGetString and
 *			XmTextFieldGetString. The parents widget class is
 *			checked and the proper function is called (returns NULL
 *			when parent is no text or no textfield).
 *
 *
 *  History:		22.01.99	Created by flux
 *
 *
 ***************************************************************************/
 
char * MTextGetString(Widget parent)
{
  if (XmIsTextField(parent)){
    return (XmTextFieldGetString(parent));
  }
  if (XmIsText(parent)){
    return (XmTextGetString(parent));
  }
  return NULL;
} 


/***************************************************************************
 *
 *  Funktionsname:	MTextSetInt
 *  
 *  Input:		Widget parent, int value
 *
 *  Return:		Bool
 *
 *  Documentation:	Sets an integer value into text-widgets. 
 *			Returns	TRUE when success, otherwise FALSE.
 *
 *
 *  History:		09-07-93 	Created by flux.
 *			30.07.97	Check for textfield added
 *
 *
 ***************************************************************************/
 
Bool MTextSetInt(Widget parent, int value)
{
    char str[50];

    sprintf(str, "%d", value);

    /* Check Widget */
    if (!parent) return FALSE;
    if (!(XtIsObject(parent))) return FALSE;

    if(str != NULL) {
        if (XmIsTextField(parent)){
            XmTextFieldSetString(parent, str);
        } else { 
            if (XmIsText(parent)){
                XmTextSetString(parent, str);
            } else {
                return FALSE;
            }
        }
    }
    return (str != NULL);
}
	
/***************************************************************************
 *
 *  Funktionsname:	MTextSetFloat
 *  
 *  Input:		Widget parent, double value
 *
 *  Return:		Bool
 *
 *  Documentation:	Sets an float value into text-widgets. 
 *			Returns	TRUE when success, otherwise FALSE.
 *
 *
 *  History:		09-07-93 	Created by flux.
 *			30.07.97	Check for textfield added
 *
 *
 ***************************************************************************/
 
Bool MTextSetFloat(Widget parent, double value)
{
  char str[1000];

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;

  sprintf(str, "%f", value);

  if (XmIsTextField(parent)){
        XmTextFieldSetString(parent, str);
  } else { 
      if (XmIsText(parent)){
        XmTextSetString(parent, str);
      } else{
        return FALSE;
      }
  }
  return TRUE;
}


/***************************************************************************
 *
 *  Funktionsname:	MTextGetHex
 *  
 *  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
 *			11.11.97	Test for XmTextField (flux GbR)
 *			11.11.97	Changed "long int value" to
 *					"unsigned int value" (flux GbR)
 *
 *
 ***************************************************************************/
 

unsigned int MTextGetHex(Widget parent)
{
  char *contents;			/* Text-widget contentes	*/
  unsigned int value;
  
  if (XmIsTextField(parent)){
    contents = XmTextFieldGetString(parent);
  } else {
    contents = XmTextGetString(parent);
  }
  if(contents) { 
    if (contents[0] == 0) 		/* Invalid String ?		*/
      value = 0;
    else
      sscanf(contents,"%x",&value);
  } else {
      value = 0;
  }

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


/***************************************************************************
 *
 *  Funktionsname:	MTextSetHex
 *  
 *  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
 *			11.11.97	Test for XmTextField (flux GbR)
 *
 *
 ***************************************************************************/
Bool MTextSetHex(Widget parent, int value)
{
    char str[50];

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


    if (str != NULL) {
        if (XmIsTextField(parent))
            XmTextFieldSetString(parent, str);
        else
            XmTextSetString(parent, str);
    }
    return (str != NULL);
}
	
/*** MESSAGEBOX WIDGET FUNCTIONS ***/


/***************************************************************************
 *
 *  Funktionsname:	MMessageBoxSetText
 *  
 *  Input:		Widget parent, char *text
 *
 *  Return:		Bool
 *
 *  Documentation:	This function sets the string 'text' as the 
 *			XmNmessageString into a MessageBox.
 *
 *
 *  History:		11-11-97	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MMessageBoxSetText(Widget parent, char *text)
{
  if (!(XmIsMessageBox(parent))) return FALSE;
  if (!text) return FALSE;

  XtVaSetValues(parent,
	XmNmessageString, XmStringCreateLtoR(text, XmFONTLIST_DEFAULT_TAG),
        NULL);
  return TRUE;
}

/*** SCALE WIDGET FUNCTIONS ***/


/***************************************************************************
 *
 *  Funktionsname:	MScaleSetFloat
 *  
 *  Input:		Widget parent, double value
 *
 *  Return:		Bool
 *
 *  Documentation:	This function sets float-values to a scale-widget.
 *			Theres one problem: Scales have only integer values.
 *			The point is the XmNdecimalPoint Ressource. If this
 *			has a value of 2, all values will be shifted (two
 *			positions).
 *
 *
 *  History:		09-07-93	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MScaleSetFloat(Widget parent, double value)
{
  int ScaleValue;
  short DecimalPoints;

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsScale(parent))) return FALSE;

  XtVaGetValues(parent, XmNdecimalPoints, &DecimalPoints, NULL);

  if (!DecimalPoints){
    ScaleValue = (int) value;
    XtVaSetValues(parent, XmNvalue, ScaleValue, NULL);
    return TRUE;
  }

  if (DecimalPoints >= 0 && DecimalPoints <= 10){
	  ScaleValue = (int) (value * GetExp(DecimalPoints));
	  XtVaSetValues(parent, XmNvalue, ScaleValue, NULL);
	  return TRUE;
  } else {
	  return FALSE;
  }
}


/***************************************************************************
 *
 *  Funktionsname:	MScaleGetFloat
 *  
 *  Input:		Widget parent
 *
 *  Return:		double
 *
 *  Documentation:	The 'XmNdecimalPoints'-Ressource is used to shift
 *			an integer-value (the only possible scale-value).
 *			If 'XmNdecimalPoints' > 0 , then MScaleGetFloat can
 *			be used to access the double precision value easy. 
 *
 *
 *  History:		09-07-93	Created by flux.
 *
 *
 ***************************************************************************/
 
double MScaleGetFloat(Widget parent) 
{
  int ScaleValue;
  short DecimalPoints;
  int exp;
  double value=0.0;
  
  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsScale(parent))) return FALSE;

  XtVaGetValues(parent, 
		XmNvalue, &ScaleValue,
		XmNdecimalPoints, &DecimalPoints, 
		NULL);
  if (!DecimalPoints){
	  value = (double)ScaleValue;
  } else {
  	exp = GetExp(DecimalPoints);
  	if(exp) value = ((double)ScaleValue / (double)exp);
  }
  return value;
} 


/*** LIST WIDGET FUNCTIONS ***/

/***************************************************************************
 *
 *  Funktionsname:	MListReplaceItem
 *  
 *  Input:		Widget parent, XmString item, XmString newItem
 *
 *  Return:		Bool, TRUE on succes
 *
 *  Documentation:	MListReplaceItem replace item with newItem. If item
 *			is NULL, the first selected position will be replaced
 *			with newItem
 *
 *
 *  History:		04-20-95	Created by flux.
 *
 *
 ***************************************************************************/
Bool MListReplaceItem(Widget parent, XmString item, XmString newItem) {

  XmString New[1];

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsList(parent))) return FALSE;

  if (item){
    XmString Old[1];
    Old[0] = XmStringCopy(item);
    New[0] = XmStringCopy(newItem);

    XmListReplaceItems(parent, Old, 1, New);
    XmStringFree(New[0]);
    XmStringFree(Old[0]);
  } else {
    int pos;

    if (!(pos = MListGetPosition(parent))) return FALSE;

    New[0] = XmStringCopy(newItem);
    if(!New[0]) return FALSE;
    XmListReplaceItemsPos(parent, New, 1, pos);
    XmListSelectPos(parent,pos,FALSE);
    XmStringFree(New[0]);
  }
  return TRUE;
}

/***************************************************************************
 *
 *  Funktionsname:	MListSetString
 *  
 *  Input:		Widget parent, char *item
 *
 *  Return:		Bool, TRUE on succes
 *
 *  Documentation:	MListSetString changes the string of the first
 *                      selected item of the ListWidget, if one.
 *
 *
 *  History:		09-07-93	Created by flux.
 *
 *
 ***************************************************************************/
 
Bool MListSetString(Widget parent, char *item) {

  int pos;
  XmString New[1];

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsList(parent))) return FALSE;

  pos = MListGetPosition(parent);
  if(!pos) return TRUE;

  New[0] = MStringCreate(item);
  if(!New[0]) return FALSE;
  XmListReplaceItemsPos(parent, New, 1, pos);
  XmListSelectPos(parent,pos,FALSE);
  XmStringFree(New[0]);
  return TRUE;
}

/***************************************************************************
 *
 *  Funktionsname:	MListGetStrings
 *  
 *  Input:		Widget parent
 *
 *  Return:		char **
 *
 *  Documentation:	MListGetString returns all selected items in
 *			a specified list widget as array of 'char *'. 
 *			When there is no selected item, MListGetString
 *			returns 'NULL'.
 *
 *
 *  History:		09-07-93	Created by flux.
 *
 *
 ***************************************************************************/
 
char **MListGetStrings(Widget parent)
{
  int *pos_list, pos_count = 0;
  XmStringTable sel;
  char **sel_string;
  int i;

  /* Check Widget */
  if (!parent) return NULL;
  if (!(XtIsObject(parent))) return NULL;
  if (!(XmIsList(parent))) return NULL;

  if (!(XmListGetSelectedPos(parent, &pos_list, &pos_count))) return NULL;
  if (!pos_count) return NULL;       /* No item selected 	*/
			
  sel_string = (char **) malloc(sizeof(char *) * (pos_count+1));
  if(!sel_string) return NULL;
  XtVaGetValues(parent, XmNselectedItems, &sel, NULL);
  for(i=0;i<pos_count;i++) {
    sel_string[i] = MGetString(sel[i]);
  }
  sel_string[pos_count] = NULL;

  return sel_string;
}


/***************************************************************************
 *
 *  Funktionsname:	MListGetString
 *  
 *  Input:		Widget parent
 *
 *  Return:		char *
 *
 *  Documentation:	MListGetString returns the first selected item in
 *			a specified list widget as 'char *'. 
 *			When there is no selected item, MListGetString will
 *			return 'NULL'.
 *
 *
 *  History:		09-07-93	Created by flux.
 *
 *
 ***************************************************************************/
 
char *MListGetString(Widget parent)
{
  int *pos_list, pos_count = 0;
  XmString *sel;
  char *sel_string = NULL;

  /* Check Widget */
  if (!parent) return NULL;
  if (!(XtIsObject(parent))) return NULL;
  if (!(XmIsList(parent)) )return NULL;

  if (!(XmListGetSelectedPos(parent, &pos_list, &pos_count))) return NULL;
  if (!pos_count) return NULL;       /* No item selected 	*/
  XtVaGetValues(parent, XmNselectedItems, &sel, NULL);  /* Get first selected   */
  if(sel) XmStringGetLtoR(sel[0], XmSTRING_DEFAULT_CHARSET, &sel_string);

  return sel_string;
}

/***************************************************************************
 *
 *  Funktionsname:	MListAddStrings
 *  
 *  Input:		Widget parent, char **item, int number
 *
 *                      parent : ListWidget.
 *                      **items: Array of strings, must be null-terminated,
 *                               if number is set to -1.
 *                      number : Number of arrayelements or -1.
 *
 *  Return:		Bool
 *
 *  Documentation:	MListAddStrings is a simple function to add a set
 *			of items at the end of a given list widget. Returns
 *			FALSE when failed.
 *
 *
 *  History:		09-07-93	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MListAddStrings(Widget parent, char **item, int number)
{
  XmString *tmp;
  int i;

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsList(parent))) return FALSE;

  if(!item) return FALSE;
  if(!number) return TRUE;    /* Nothing to do */
  if(number == -1) {          /* array ist null-terminated */
    number = 0;
    while(item[number]) number++;
    if(!number) return TRUE;    /* Nothing to do */
  }
  tmp = (XmString *) malloc(sizeof(XmString) * number);
  if(!tmp) return FALSE;
  for(i=0;i<number;i++) {
    tmp[i] = XmStringCreateSimple(item[i]);
  }
  XmListAddItems(parent, tmp, number, 0);
  for(i=0;i<number;i++) {
    XmStringFree(tmp[i]);
  }
  free(tmp);
  return TRUE;
}


/***************************************************************************
 *
 *  Funktionsname:	MListAddString
 *  
 *  Input:		Widget parent, char *item
 *
 *  Return:		Bool
 *
 *  Documentation:	MListAddString is a simple function to add an item
 *			(char *) at the end of a given list widget. Returns
 *			FALSE when failed.
 *
 *
 *  History:		09-07-93	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MListAddString(Widget parent, char *item)
{
  XmString tmp;

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsList(parent))) return FALSE;

  if(!item) return FALSE;
  if((tmp = XmStringCreateSimple(item))) {
    XmListAddItem(parent, tmp, 0);
    XmStringFree(tmp);
    return TRUE;
  } else {
    return FALSE;
  }
}

/***************************************************************************
 *
 *  Funktionsname:	MListGetPositions
 *  
 *  Input:		Widget parent
 *
 *  Return:		int *
 *
 *  Documentation:	MListGetPosition returns the positions of the first
 *			selected items in a listbox.
 *
 *
 *  History:		09-08-93	Created by flux
 *
 *
 ***************************************************************************/
 
int MListGetSelectedCount(Widget parent)
{
  int *pos_list, pos_count = 0;

  /* Check Widget */
  if (!parent) return 0;
  if (!(XtIsObject(parent))) return 0;
  if (!(XmIsList(parent))) return 0;

  if (!(XmListGetSelectedPos(parent, &pos_list, &pos_count))) return 0;
  return pos_count;
}



/***************************************************************************
 *
 *  Funktionsname:	MListGetPositions
 *  
 *  Input:		Widget parent
 *
 *  Return:		int *
 *
 *  Documentation:	MListGetPosition returns the positions of the first
 *			selected items in a listbox.
 *
 *
 *  History:		09-08-93	Created by flux
 *
 *
 ***************************************************************************/
 
int *MListGetPositions(Widget parent)
{
  int *pos_list, pos_count = 0;

  /* Check Widget */
  if (!parent) return 0;
  if (!(XtIsObject(parent))) return 0;
  if (!(XmIsList(parent))) return 0;

  if (!(XmListGetSelectedPos(parent, &pos_list, &pos_count))) return NULL;
  if (!pos_count)				/* No item selected 	*/
	return NULL;
  else
	return pos_list;
}

/***************************************************************************
 *
 *  Funktionsname:	MOptionGetItem
 *  
 *  Input:		Widget parent
 *
 *  Return:		char * item
 *
 *  Documentation:	MOptionGetPosition returns the label of the
 *			selected item in an optionmenu.
 *
 *
 *  History:		12-06-93	Created by flux
 *
 *
 ***************************************************************************/
 
char * MOptionGetItem(Widget parent)
{
  Widget Actual = 0;
  WidgetList Children;
  int i = 0;

  /* Check Widget */
  if (!parent) return NULL;
  if (!(XtIsObject(parent))) return NULL;
  if (!(XmIsRowColumn(parent))) return NULL;

  XtVaGetValues(parent,XmNmenuHistory, &Actual, NULL);
  XtVaGetValues(XtParent(Actual),XmNchildren, &Children, NULL);
  do {
    if(Children[i] == Actual){
	XmString OptionLabel;
	
	XtVaGetValues(Children[i], XmNlabelString, &OptionLabel, NULL);
	return MGetString(OptionLabel);
    }
  } while(Children[i++]);
  return NULL;
}

/***************************************************************************
 *
 *  Funktionsname:	MOptionGetPosition
 *  
 *  Input:		Widget parent
 *
 *  Return:		int position
 *
 *  Documentation:	MOptionGetPosition returns the position of the first
 *			selected item in a optionmenu.
 *
 *
 *  History:		09-08-93	Created by flux
 *
 *
 ***************************************************************************/
 
int MOptionGetPosition(Widget parent)
{
  Widget Actual = 0;
  WidgetList Children;
  int i = 0;

  /* Check Widget */
  if (!parent) return 0;
  if (!(XtIsObject(parent))) return 0;
  if (!(XmIsRowColumn(parent))) return 0;

  XtVaGetValues(parent,XmNmenuHistory, &Actual, NULL);
  XtVaGetValues(XtParent(Actual),XmNchildren, &Children, NULL);
  do {
    if(Children[i] == Actual) return i+1;
  } while(Children[i++]);
  return 0;
}

/***************************************************************************
 *
 *  Funktionsname:	MOptionSetPosition
 *  
 *  Input:		Widget parent, int pos
 *
 *  Return:		int stat
 *
 *  Documentation:	MOptionSetPosition sets the position
 *			in an optionmenu.
 *
 *
 *  History:		03-02-95	Created by flux
 *
 *
 ***************************************************************************/
 
Widget MOptionGetWidget(Widget parent, int pos) 
{
  Widget *WidList, OptionMenu;
  Cardinal numChild;

  XtVaGetValues(parent, XmNsubMenuId, &OptionMenu, NULL);
  XtVaGetValues(OptionMenu, XmNchildren, &WidList, XmNnumChildren, &numChild, NULL);

  if ((int)numChild < pos) 	return NULL;
  else			return (WidList[pos-1]);
}

Boolean MOptionSetPosition(Widget parent, int pos) {

  Widget posWid = MOptionGetWidget(parent, pos);

  if (posWid){
        XtVaSetValues(parent, XmNmenuHistory, posWid, NULL);
        return TRUE;
  }else return FALSE;
}

Widget MOptionAddItem(Widget OptionMenu, char *item)
{
  Widget PulldownMenu, NewEntry;
  XmString tmpLabelString;
  Cardinal n=0;
  Arg args[10];

  XtVaGetValues(OptionMenu, XmNsubMenuId, &PulldownMenu, NULL);

  if (!(PulldownMenu)) return NULL;
  if (!(item)) return NULL;
  tmpLabelString = XmStringCreate(item, XmFONTLIST_DEFAULT_TAG);
  XtSetArg(args[n], XmNlabelString, tmpLabelString); n++;
  NewEntry = (Widget)XmCreatePushButton(PulldownMenu, "cascadeButton", args, n);
  XtManageChild(NewEntry);
  return NewEntry;
}

/***************************************************************************
 *
 *  Funktionsname:	MListGetPosition
 *  
 *  Input:		Widget parent
 *
 *  Return:		int position
 *
 *  Documentation:	MListGetPosition returns the position of the first
 *			selected item in a listbox.
 *
 *
 *  History:		09-08-93	Created by flux
 *
 *
 ***************************************************************************/
 
int MListGetPosition(Widget parent)
{
  int *pos_list, pos_count = 0;

  /* Check Widget */
  if (!parent) return 0;
  if (!(XtIsObject(parent))) return 0;
  if (!(XmIsList(parent))) return 0;

  if (!(XmListGetSelectedPos(parent, &pos_list, &pos_count))) return 0;
  if (!pos_count)				/* No item selected 	*/
	return 0;
  else
	return pos_list[0];
}

/***************************************************************************
 *
 *  Funktionsname:	MListPositionVisible
 *  
 *  Input:		Widget parent
 *                      int Position
 *
 *  Return:		void
 *
 *  Documentation:	Makes the given position visible, if possible.
 *
 *
 *  History:		09-07-93	Created by flux
 *
 *
 ***************************************************************************/

void MListPositionVisible(Widget parent, int ThePosition) {

  int VisCnt;
  int Cnt;

  /* Check Widget */
  if (!parent) return ;
  if (!(XtIsObject(parent))) return ;
  if (!(XmIsList(parent))) return ;

  XtVaGetValues(parent,XmNitemCount, &Cnt, XmNvisibleItemCount, &VisCnt, NULL);
  if(Cnt <= VisCnt) return; /* All items ARE visible */
  if(ThePosition > Cnt-(VisCnt/2)) ThePosition = Cnt;
  else ThePosition += VisCnt/2;
  XmListSetBottomPos(parent,ThePosition);
}


/***************************************************************************
 *
 *  Funktionsname:	MListSelectAllItems
 *  
 *  Input:		Widget parent
 *
 *  Return:		void
 *
 *  Documentation:	                                                   
 *			                                 
 *
 *
 *  History:		16-11-94	Created by flux
 *
 *
 ***************************************************************************/

void MListSelectAllItems(Widget parent)
{

  int anz,i;

  /* Check Widget */
  if (!parent) return ;
  if (!(XtIsObject(parent))) return ;
  if (!(XmIsList(parent))) return ;

  XtVaGetValues(parent,XmNitemCount, &anz, NULL);
  for(i=0;i<anz;i++) {
    if(!XmListPosSelected(parent, i)) XmListSelectPos(parent,i,FALSE);
  }
}


/***************************************************************************
 *
 *  Funktionsname:	MListDeleteAllItems
 *  
 *  Input:		Widget parent
 *
 *  Return:		void
 *
 *  Documentation:	If 'XmListDeleteAllItems' failed (often happened
 *			in Motif 1.1), try this function.
 *
 *
 *  History:		09-07-93	Created by flux
 *
 *
 ***************************************************************************/

void MListDeleteAllItems(Widget parent)
{
  /* Check Widget */
  if (!parent) return;
  if (!(XtIsObject(parent))) return;
  if (!(XmIsList(parent))) return;

  XmListSetPos(parent, 1);
  XmListDeleteAllItems(parent);
}


/***************************************************************************
 *
 *  Funktionsname:	MRadioGetSelectedItem
 *  
 *  Input:		Widget parent
 *
 *  Return:		char *selectedItem
 *
 *  Documentation:	MRadioGetSelectedItem returns the label (as char *)
 *			of the selected ToggleButton in radio-boxes.
 *
 *
 *  History:		09-08-93	Created by flux
 *
 *
 ***************************************************************************/
 
char *MRadioGetSelectedItem(Widget parent)
{
  Widget *WidList;
  Cardinal numChild, i;

  /* Check Widget */
  if (!parent) return NULL;
  if (!(XtIsObject(parent))) return NULL;
  if (!(XmIsRowColumn(parent))) return NULL;

  XtVaGetValues(parent, 
	XmNchildren, &WidList,
	XmNnumChildren, &numChild, NULL);

  for(i=0; i<numChild; i++){ 
	if (XmToggleButtonGetState(WidList[i])){
		XmString Label;

		XtVaGetValues(WidList[i], XmNlabelString, &Label, NULL);
		return MGetString(Label);
	}
  }
  return "";
}

/***************************************************************************
 *
 *  Funktionsname:	MRadioGetSelectedPos
 *  
 *  Input:		Widget parent
 *
 *  Return:		int selectedPos
 *
 *  Documentation:	MRadioGetSelectedPos returns the position
 *			of the selected ToggleButton in radio-boxes. Returns
 *			0 when failed.
 *
 *
 *  History:		09-14-93	Created by flux
 *
 *
 ***************************************************************************/
 
int MRadioGetSelectedPos(Widget parent)
{
  Widget *WidList;
  Cardinal numChild, i;

  /* Check Widget */
  if (!parent) return 0;
  if (!(XtIsObject(parent))) return 0;
  if (!(XmIsRowColumn(parent))) return 0;

  XtVaGetValues(parent, 
	XmNchildren, &WidList,
	XmNnumChildren, &numChild, NULL);

  for(i=0; i<numChild; i++){ 
	if (XmToggleButtonGetState(WidList[i])){
		return i+1;
	}
  }
  return 0;
}


/***************************************************************************
 *
 *  Funktionsname:	MRadioSetPosition
 *  
 *  Input:		Widget parent  -> a radio container
 *			int position   -> Widget position (first item = 1)
 *
 *  Return:		Bool status
 *
 *  Documentation:	MRadioSetPosition sets the state of the XmToggleButton 
 *			at the position 'pos' to TRUE.
 *
 *
 *  History:		09-29-97	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MRadioSetPosition(Widget parent, int pos) 
{  
  Widget posWid = MRadioGetWidget(parent, pos);

  if (posWid){
	XmToggleButtonSetState(posWid, TRUE, FALSE);
        return TRUE;
  }else return FALSE;
}


/***************************************************************************
 *
 *  Funktionsname:	MRadioGetWidget
 *  
 *  Input:		Widget parent  -> a radio container
 *			int position   -> Widget position (first item = 1)
 *
 *  Return:		Widget         -> Widget-ID
 *
 *
 *  Documentation:	Returns the widget id of the ToggleButton at the
 *			position 'pos' (first = 1). Returns NULL by error.
 *
 *
 *  History:		09-29-97	Created by flux
 *
 *
 ***************************************************************************/
 
Widget MRadioGetWidget(Widget parent, int pos) 
{
  Widget *WidList;
  Cardinal numChild;

  XtVaGetValues(parent, XmNchildren, &WidList, XmNnumChildren, &numChild, NULL);

  if ((int)numChild < pos)  return NULL;
  else                      return (WidList[pos-1]); 
}


/* SMALL USEFUL FUNCTIONS */

/***************************************************************************
 *
 *  Funktionsname:	MStringCreate(XmString xstr)
 *  
 *  Input:		char *str
 *
 *  Return:		XmString
 *
 *  Documentation:	Converts a char * into a XmString.
 *
 *
 *  History:		09-08-93	Created by flux
 *
 *
 ***************************************************************************/
 
XmString MStringCreate(char *str) 
{
  if(!str) return NULL;
  return XmStringCreate(str,XmSTRING_DEFAULT_CHARSET);
}


/***************************************************************************
 *
 *  Funktionsname:	MGetString(XmString xstr)
 *  
 *  Input:		XmString xstr
 *
 *  Return:		char *
 *
 *  Documentation:	Converts a XmString into a char *.
 *
 *
 *  History:		09-08-93	Created by flux
 *			04-18-95	MGetString can convert XmStrings
 *					with different TAGS
 *					Some code parts are from the Motif
 *					Programming Manual (VI), S.698
 *
 *
 ***************************************************************************/
 
char *MGetString(XmString str) 
{

  XmStringContext	context;
  char 			*text, *buf, *tag, *p;
  XmStringDirection	direction;
  Boolean		separator;

  if (!XmStringInitContext(&context, str)){
	XtWarning ("Can't convert compound string");
	return NULL;
  }
  buf = (char *) malloc(sizeof(char *) * (XmStringLength(str)+1));
  p = buf;
  while (XmStringGetNextSegment(context, &text, &tag, &direction, &separator)){
	p += (strlen (strcpy (p, text)));
	if(separator == True){
		*p++ = '\n';
		*p = 0;
	}
	XtFree(text);
  }
  XmStringFreeContext(context);
  return buf;

/**** THE OLD VERSION ********
  char *str;

  XmStringGetLtoR(xstr, XmFONTLIST_DEFAULT_TAG, &str);
  return str;
******************************/
}


/* DIALOG AND APPLICATION FUNCTIONS */


/***************************************************************************
 *
 *  Funktionsname:	MCloseDialog
 *  
 *  Input:		Widget wid
 *
 *  Return:		void
 *
 *  Documentation:	This function is useful to close a DialogShell 
 *			Window. The input widget can be any widget, that
 *			is child or subchild of DialogShell. 
 *			DialogShells are windows that are NOT the first
 *			window in your application.
 *
 *
 *  History:		09-13-93	Created by flux
 *
 *
 ***************************************************************************/
/***************************************************************************
 *
 *  Funktionsname:	MCloseDialog
 *                      Mterminate_thread( XtAppContext *app)
 *  
 *  Input:		Widget wid
 *                      XtAppContext *app
 *  Return:		void
 *
 *  Documentation:	This function is useful to close a DialogShell 
 *			Window. The input widget can be any widget, that
 *			is child or subchild of DialogShell. 
 *			DialogShells are windows that are NOT the first
 *			window in your application.
 *
 *                      Mterminate_thread is used to clear down remaining
 *                      from application loop befor returning from thread
 *
 *  History:		09-13-93	Created by flux
 *
 *
 ***************************************************************************/
void Mterminate_thread( XtAppContext *app){
    while(XtAppPending(*app))
        XtAppProcessEvent(*app,XtIMAll);
    XtDestroyApplicationContext(*app);
}
 
void MCloseDialog(Widget wid)
{
  Widget parent = wid;

  while(TRUE){
	if (XmIsDialogShell(parent)){
		XtDestroyWidget(parent);
 		return;
	}
	if (XtIsApplicationShell(parent)){
		XtDestroyWidget(parent);
		XtDestroyApplicationContext(XtWidgetToApplicationContext(parent));
		exit(0);
	}
	if(XtIsTopLevelShell(parent)){
		XtDestroyWidget(parent);
		return;
	}
	parent = XtParent(parent);
  }
}


/* SMALL STATIC FUNCTIONS */

/***************************************************************************
 *
 *  Funktionsname:	GetExp
 *  
 *  Input:		int value
 *
 *  Return:		int exponent
 *
 *  Documentation:	This is exactly the 'exp'-function, but you don't
 *			have to link the libm-Library. Thats all.
 *
 *
 *  History:		09-02-93	Created by flux
 *
 *
 ***************************************************************************/
 
static int GetExp(int value)
{
   if(value <=0) return 0;
   if (value == 1) return 10;
   else return (10 * GetExp(value - 1));
}

/***************************************************************************
 *
 *  Funktionsname:	MTextRead
 *  
 *  Input:		Widget parent
 *			char *filename
 *
 *  Return:		Bool
 *
 *  Documentation:	MTextRead read the contents of a file and put it
 *                      in an entryfield. Returns FALSE when the file 
 *                      wasn't found.
 *
 *
 *  History:		02-01-94	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MTextRead(Widget parent, char *filename)
{
 struct stat buf;
 long buf_length=0;
 FILE *fp;
 char *ptr;
 
 if(stat(filename,&buf)) return FALSE;
    
 buf_length = buf.st_size;
 ptr = (char *)malloc(buf_length+1);
 
 fp = fopen(filename,"r");
 if(fp) {
   fread(ptr,buf_length,1,fp);
   ptr[buf_length] = 0;
   fclose(fp);
   XmTextSetString(parent,ptr);
 } else {
   free(ptr);
   return FALSE;
 }
 free(ptr);
 return TRUE;
}

/***************************************************************************
 *
 *  Funktionsname:	MTextInsert
 *  
 *  Input:		Widget parent
 *			char *filename
 *
 *  Return:		Bool
 *
 *  Documentation:	MTextRead read the contents of a file and put it
 *                      in an entryfield. Returns FALSE when the file 
 *                      wasn't found.
 *
 *
 *  History:		02-01-94	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MTextInsert(Widget parent, char *filename)
{
 struct stat buf;
 long buf_length=0;
 FILE *fp;
 char *ptr;
 
 if(stat(filename,&buf)) return FALSE;
    
 buf_length = buf.st_size;
 ptr = (char *)malloc(buf_length+1);
 
 fp = fopen(filename,"r");
 if(fp) {
   fread(ptr,buf_length,1,fp);
   ptr[buf_length] = 0;
   fclose(fp);
   XmTextInsert(parent, XmTextGetInsertionPosition(parent), ptr);
 } else {
   free(ptr);
   return FALSE;
 }
 free(ptr);
 return TRUE;
   
}


/***************************************************************************
 *
 *  Funktionsname:	MTextWrite
 *  
 *  Input:		Widget parent
 *			char *filename
 *
 *  Return:		Bool
 *
 *  Documentation:	MTextWrite write the contents of an entryfield
 *                      in a file. Returns FALSE when the file couldn't
 *                      open.
 *
 *
 *  History:		02-01-94	Created by flux
 *
 *
 ***************************************************************************/
 
Bool MTextWrite(Widget parent, char *filename)
{
 FILE *fp;
 char *ptr;
 
 ptr = XmTextGetString(parent);
 
 if((fp = fopen(filename,"w")) == NULL)
    return FALSE;
 
 if(ptr) fwrite(ptr,sizeof(char),strlen(ptr),fp);
 fclose(fp);

 return TRUE;
}

/***************************************************************************
 *
 *  Funktionsname:	DialogGrabDelete
 *  
 *  Input:		Widget wid, XtCallbackProc call, XtPointer closure
 *
 *  Return:		Bool
 *
 *  Documentation:	DialogGrabDelete permits the double-click on the
 *			upper-left window to close a dialog. Instead of
 *			the destroy-function the function "call" is called.
 *			Widget can be any widget in the dialog or the
 *			dialog shell.
 *			Call is an existing funcion, i.e. a callback.
 *			closure is the same as client_data in calbacks.
 *			If something goes wrong, return is FALSE, otherwise
 *			DialogGrabDelete returns TRUE.
 *
 *
 *  History:		15.11.1995 Created by flux
 *
 *
 ***************************************************************************/
 
Bool MGrabDelete(Widget wid, XtCallbackProc call, XtPointer closure)
{
   Atom WM_DELETE_WINDOW;
   Widget parent = wid;

   /* Check Widget */
   if (!parent) return FALSE;
   if (!(XtIsObject(parent))) return FALSE;

   /* Find the dialog-shell */

   while(TRUE){
     if ( (XmIsDialogShell(parent)) || (XtIsApplicationShell(parent)) || (XtIsTopLevelShell(parent))) break;
     else parent = XtParent(parent);
   }

   /* Do NOT destroy the dialog */

   XtVaSetValues(parent, XmNdeleteResponse, XmDO_NOTHING, NULL);

   WM_DELETE_WINDOW = XmInternAtom(XtDisplay(wid), "WM_DELETE_WINDOW", False);

   /* Call the function "call" instead */
   XmAddWMProtocolCallback(parent, WM_DELETE_WINDOW, call, closure);

   return TRUE;
}


/***************************************************************************
 *
 *  Funktionsname:	MListSort
 *  
 *  Input:		Widget parent
 *
 *  Return:		Bool, always TRUE
 *
 *  Documentation:	MListSort sort the items of a List.
 *
 *
 *  History:		02-01-94	Created by flux
 *              17-04-96  Updated by Daniel
 *
 ***************************************************************************/

Bool MListSort(Widget parent)
{
 XmStringTable org ;
#ifdef SGI
 XmStringTable org2;
#else
 XmString Xtmp;
#endif
 char **arr;
 char *tmp;
 int count;
 int i,j,changed,len;

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
  if (!(XmIsList(parent))) return FALSE;

 XtVaGetValues(parent,XmNitemCount,&count,XmNitems,&org,NULL);
 XmListDeselectAllItems(parent);

 if(count<2) return TRUE;

 arr = (char **) malloc(sizeof(char *) * count);
#ifdef SGI
 org2 = (XmStringTable)malloc(sizeof(XmString )* count);
 for(i=0;i<count;i++) {
 	org2[i] = XmStringCopy(org[i]);
    arr[i] = MGetString(org2[i]);
    len = strlen(arr[i]);
    for(j=0;j<len;j++) arr[i][j] = toupper(arr[i][j]);
 }
 changed = TRUE;
 for(i=0;(i<count) && changed;i++) {
   changed = FALSE;
   for(j=0;j<count-i-1;j++) {
     if(strcmp(arr[j],arr[j+1]) > 0) {
       changed = TRUE;

       tmp = arr[j];
       arr[j] = arr[j+1];
       arr[j+1] = tmp;

       Xtmp = org2[j];
       org2[j] = org2[j+1];
       org2[j+1] = Xtmp;
     }
   }
 }
 /* Initiate an Redraw */
  XmListSetPos(parent, 1);
  XmListDeleteAllItems(parent);
  for(i=0;i<count ;i++)
 	XmListAddItem(parent, org2[i], 0);

 for(i=0;i<count;i++){
   XmStringFree(org2[i]);
  free(arr[i]);
 }
 free(arr);
 free(org2);
#else
 for(i=0;i<count;i++) {
    arr[i] = MGetString(org[i]);
    len = strlen(arr[i]);
    for(j=0;j<len;j++) arr[i][j] = toupper(arr[i][j]);
 }
 changed = TRUE;
 for(i=0;(i<count) && changed;i++) {
   changed = FALSE;
   for(j=0;j<count-i-1;j++) {
     if(strcmp(arr[j],arr[j+1]) > 0) {
       changed = TRUE;

       tmp = arr[j];
       arr[j] = arr[j+1];
       arr[j+1] = tmp;

       Xtmp = org[j];
       org[j] = org[j+1];
       org[j+1] = Xtmp;
     }
   }
 }
 Xtmp = XmStringCopy(org[0]);
 XmListDeletePos(parent, 1);
 XmListAddItem(parent, Xtmp, 1);
 XmStringFree(Xtmp);

 for(i=0;i<count;i++) free(arr[i]);
 free(arr);
#endif 
 return TRUE;
}

/***************************************************************************
 *
 *  Funktionsname:	MMakePixmapName
 *  
 *  Input:		char *filename
 *
 *  Return:		char *pixname;
 *
 *  Documentation:	To include pixmaps and bitmaps we need to extract the 
 *			real name:
 *			
 *			/usr/include/xpm/test.xpm -> test
 *
 *                     
 *  History:		04-10-95	Created by flux
 *
 *
 ***************************************************************************/
 
char *MMakePixmapName(char *fn)
{
  char *erg, *tmp, *step;

  if(!fn) return NULL;
  if(!*fn) return NULL;

  tmp = strdup(fn);
  step = tmp + strlen(fn) -1;
  while(step > tmp && *step != '/') {
    if(*step == '.') *step = 0;
    step--;
  }
  if(*step == '/') step++;
  erg = strdup(step);
  free(tmp);
  return erg;
}


/***************************************************************************
 *
 *  Funktionsname:	MMakeFilename
 *  
 *  Input:		char *filename, char *directorypath
 *
 *  Return:		Bool
 *
 *  Documentation:	In FileSelectionDialogs its possible, that Motif
 *			returns the filename WITH the directorypath. To 
 *			get only the filename, use MMakeFilename.
 *
 *                     
 *  History:		02-02-94	Created by flux
 *
 *
 ***************************************************************************/
 
char *MMakeFilename(char *Fn, char *Path)
{
  char *erg;

  if(!Fn || !Path) return NULL;

  if(strstr(Fn,Path)) { /* Fn includes Path */
    erg = strdup(Fn);

  } else {
    erg = (char *) malloc(sizeof(char) * (strlen(Fn) + strlen(Path) + 1));
    sprintf(erg,"%s%s",Path,Fn);
  }
  return erg;
}

/***************************************************************************
 *
 *  Funktionsname:	MLoadGraphic
 *  
 *  Input:		Widget parent, char *filename, int *format
 *
 *  Return:		Pixmap (NULL when failed)
 *
 *  Documentation:	MLoadGraphic reads XBM- or XPM-format pixmaps
 *
 *			MLoadGraphic tries to read the pixmap in the format
 *			given in the 'format' flag. If format is 0, 
 *			MLoadGraphic read XBM at first.           
 *
 *			NOTICE: If the filename contains an extension such as
 *			.xpm, in order to get a valid C variable name, the
 *			dot character is replaced by an underscore (_) when
 *			reading the file.
 *
 *                     
 *  History:		04-10-95	Created by flux
 *
 *
 ***************************************************************************/
#ifdef XPM_YES
Pixmap MLoadGraphic(Widget parent, char *filename, int *format)
{
    Pixmap pixmap;

    /* Check Widget */
    if (!parent) {
        return (Pixmap)NULL;
    }
    if (!(XtIsObject(parent))) {
        return (Pixmap)NULL;
    }

    /* Check filename */
    if (!filename) {
        return (Pixmap)NULL;
    }

    switch (*format)
    {
        case XPM:
            /* XPM, the X Pixmap-Format */
            if ( !(pixmap = MLoadXPM(parent, filename))) {
                if ( !(pixmap = MLoadXBM(parent, filename))) 
                    *format = XPM;
		} else { 
                    *format = XBM;
            }

            return pixmap;
            break;
	case XBM:
	default:
	    /* XBM, the default X Bitmap-Format */
            if ( !(pixmap = MLoadXPM(parent, filename))) {
                if ( !(pixmap = MLoadXBM(parent, filename))) 
                    *format = XPM;
		} else {
                    *format = XBM;
                }

                return pixmap;
         break;
    }
}
#endif 

Pixmap MLoadGraphics(Widget parent, char *filename, int format)
{
  int stat = format;

  return MLoadGraphic(parent, filename, &stat);

}


Pixmap MLoadXBM(Widget parent, char *filename)
{
  Pixel fg, bg;
  Pixmap pixmap;

  XtVaGetValues(parent, XmNforeground, &fg, XmNbackground, &bg, NULL);
  pixmap = XmGetPixmap (XtScreen(parent), filename, fg, bg);

  if (pixmap == XmUNSPECIFIED_PIXMAP) return (Pixmap) NULL;
  else return pixmap;
}


/***************************************************************************
 *
 *  Funktionsname:	MLoadXPM
 *  
 *  Input:		Widget parent, char *filename
 *
 *  Return:		Pixmap
 *
 *  Documentation:	MLoadXPM reads an XPM-format pixmap
 *
 *			NOTICE: If the filename contains an extension such as
 *			.xpm, in order to get a valid C variable name, the
 *			dot character is replaced by an underscore (_) when
 *			reading the file.
 *
 *                     
 *  History:		02-13-95	Created by flux
 *
 *
 ***************************************************************************/

#ifdef XPM_YES
Pixmap MLoadXPM(Widget parent, char *filename)
{
 Pixmap pixmap;
 int stat;
 
  /* Check Widget */
  if (!parent) return (Pixmap)NULL;
  if (!(XtIsObject(parent))) return (Pixmap)NULL;
 
  stat = XpmReadFileToPixmap(XtDisplay(parent), RootWindowOfScreen(XtScreen(parent)), filename, &pixmap, NULL, NULL);

  if (MCheckXpmStatus(stat)) return pixmap;
  else{
	return (Pixmap) NULL;
  }
}
#endif

/***************************************************************************
 *
 *  Funktionsname:	MReadXPM
 *  
 *  Input:		Widget parent, char *filename
 *
 *  Return:		Pixmap
 *
 *  Documentation:	MReadPixmap reads a XWD-format pixmap
 *                      and set the pixmap in a Drawingarea.
 *
 *			NOTICE: If the filename contains an extension such as
 *			.xpm, in order to get a valid C variable name, the
 *			dot character is replaced by an underscore (_) when
 *			reading the file.
 *
 *                     
 *  History:		02-13-95	Created by flux
 *
 *
 ***************************************************************************/

#ifdef XPM_YES
Pixmap MReadXPM(Widget parent, char *filename)
{
 Pixmap pixmap;
 Dimension width, height;
 GC gc;

 /* Create GC */
 gc = XCreateGC(XtDisplay(parent),RootWindowOfScreen(XtScreen(parent)),(unsigned long)0,0);

 /* Read XPM file */
 if((pixmap = (Pixmap)MLoadXPM(parent, filename))) {
 	XtVaGetValues(parent,XmNwidth,&width,XmNheight,&height,NULL);
 	XCopyArea(XtDisplay(parent),pixmap,XtWindow(parent),gc,0,0,width,height,0,0);

 	return pixmap;
 }else  return (Pixmap) NULL;
 
}
#endif

/***************************************************************************
 *
 *  Funktionsname:	MWriteXPM
 *  
 *  Input:		Widget parent, char *filename,
 *			Pixmap pix
 *
 *  Return:		Bool
 *
 *  Documentation:	Saves the given pixmap to the file filename in
 *			xpm-format. 
 *
 *			NOTICE: If the filename contains an extension such as
 *			.xpm, in order to get a valid C variable name, the
 *			dot character is replaced by an underscore (_) when
 *			writing the file.
 *
 *                     
 *  History:		02-13-95	Created by flux
 *
 *
 ***************************************************************************/

#ifdef XPM_YES
Bool MWriteXPM(Widget parent, char *filename, Pixmap pix)
{
  int stat;

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;

  stat = XpmWriteFileFromPixmap(XtDisplay(parent), filename, pix, 0, NULL);

  if (MCheckXpmStatus(stat)) {
    return TRUE;
  } else {
/* wer die naechste Zeile verfasst hat, der kann sich bei Daniel zum koepfen melden !
    sprintf("[MWriteXPM] File: %s\n",filename);
*/
    return FALSE;
  }
}
#endif

/***************************************************************************
 *
 *  Funktionsname:	MLoadPixmap
 *  
 *  Input:		Widget parent, char *filename
 *
 *  Return:		Pixmap
 *
 *  Documentation:	MLoadPixmap reads an image (XWD-format) and convert
 *                      it to a pixmap .
 *
 *                     
 *  History:		03-30-94	Created by flux
 *
 *
 ***************************************************************************/

Pixmap MLoadPixmap(Widget parent, char *filename)
{
 Pixmap pixmap;
 XImage *image;
 GC gc = XCreateGC(XtDisplay(parent), RootWindowOfScreen(XtScreen(parent)),(unsigned long)0,0);
 
  /* Check Widget */
  if (!parent) return (Pixmap)NULL;
  if (!(XtIsObject(parent))) return (Pixmap)NULL;
 
 if(!(image = ReadXWD(filename, parent))) return (Pixmap) NULL;
 pixmap = XCreatePixmap(XtDisplay(parent),XtWindow(parent), image->width, image->height, DefaultDepthOfScreen(XtScreen(parent)));
 if (pixmap){
   XPutImage(XtDisplay(parent), pixmap, gc, image, 0,0,0,0, image->width, image->height); 
 }
    
 return pixmap;
}

/***************************************************************************
 *
 *  Funktionsname:	MReadPixmap
 *  
 *  Input:		Widget parent, char *filename
 *
 *  Return:		Pixmap
 *
 *  Documentation:	MReadPixmap reads an image (XWD-format) and convert
 *                      it to a pixmap and put it in a Drawingarea.
 *
 *                     
 *  History:		02-02-94	Created by flux
 *
 *
 ***************************************************************************/

Pixmap MReadPixmap(Widget parent, char *filename)
{
 Pixmap pixmap;
 XImage *image;
 GC gc;
 Dimension width, height;
 
  /* Check Widget */
  if (!parent) return (Pixmap) NULL;
  if (!(XtIsObject(parent))) return (Pixmap) NULL;
 
 /* Create GC */
 gc = XCreateGC(XtDisplay(parent),RootWindowOfScreen(XtScreen(parent)),(unsigned long)0,0);

 /* Read XWD-File, convert XImage to Pixmap */
 if(!(image = ReadXWD(filename, parent))) return (Pixmap) NULL;
 pixmap = XCreatePixmap(XtDisplay(parent),XtWindow(parent), image->width, image->height, DefaultDepthOfScreen(XtScreen(parent)));
 if (pixmap){
   XPutImage(XtDisplay(parent), pixmap, gc, image, 0,0,0,0, image->width, image->height);
 }
    

 XtVaGetValues(parent,XmNwidth,&width,XmNheight,&height,NULL);

 XCopyArea(XtDisplay(parent),pixmap,XtWindow(parent),gc,0,0,width,height,0,0);
 
 return pixmap;
}

/***************************************************************************
 *
 *  Funktionsname:	MWritePixmap
 *  
 *  Input:		Widget parent, char *filename,
 *			Pixmap pix
 *
 *  Return:		Bool
 *
 *  Documentation:	
 *
 *                     
 *  History:		02-02-94	Created by flux
 *
 *
 ***************************************************************************/

Bool MWritePixmap(Widget parent, char *filename, Pixmap pix)
{
 Image *image;
 Colormap cmap;
 
  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
 
 cmap = DefaultColormapOfScreen(XtScreen(parent));

 image = PixmapToImage(parent,pix,cmap);

 if(!WriteXWD(filename,image))
    return FALSE;
    
 return TRUE;
}

/***************************************************************************
 *
 *  Funktionsname:	MWriteArea
 *  
 *  Input:		Widget parent, char *filename,
 *
 *  Return:		Bool
 *
 *  Documentation:	
 *
 *                     
 *  History:		02-02-94	Created by flux
 *
 *
 ***************************************************************************/

Bool MWriteArea(Widget parent, char *filename)
{
 Pixmap pix;
 Dimension width, height;
 GC gc = XCreateGC(XtDisplay(parent),
                   RootWindowOfScreen(XtScreen(parent)),(unsigned long)0,0);

  /* Check Widget */
  if (!parent) return FALSE;
  if (!(XtIsObject(parent))) return FALSE;
 
 XtVaGetValues(parent,XmNwidth,&width,XmNheight,&height,NULL);
 pix = XCreatePixmap(XtDisplay(parent),XtWindow(parent),width,height,
                     DefaultDepthOfScreen(XtScreen(parent)));
 XCopyArea(XtDisplay(parent),XtWindow(parent),pix,gc,0,0,width,height,0,0);

 if(!MWritePixmap(parent,filename,pix))
    return FALSE;
    
 return TRUE;
}
/***************************************************************************
 *
 *  Funktionsname:	EAddQuickHelp
 *  
 *  Input:		Widget help , Widget helpme , char *text
 *
 *  Return:		void
 *
 *  Documentation:	Functions to add a  quickhelp
 *
 *
 *  History:		Mon Jul 22 13:35:37 CEST 2002
 *
 *
 ***************************************************************************/
void EAddQuickHelp (Widget help , Widget helpme , char *text){ 


  USER_DATA *data;
  
	data = (USER_DATA *) malloc(sizeof(USER_DATA));
	data->Qhelp_name = strdup(text);
	data->Qhelp_widget = help;
	XtAddEventHandler(helpme, EnterWindowMask, FALSE, (XtEventHandler) MSetQuickhelp, (XtPointer)data);
	XtAddCallback(helpme, XmNdestroyCallback, (XtCallbackProc) MDestroyQuickhelp, (XtPointer)data);
        XtAddEventHandler(helpme, LeaveWindowMask, FALSE, (XtEventHandler) MResetQuickhelp, (XtPointer)data);
}

/***************************************************************************
 *
 *  Funktionsname:	MSetQuickhelp, MDestroyQuickhelp 
 *  
 *  Input:		Widget parent, USER_DATA *data, ... 
 *
 *  Return:		void
 *
 *  Documentation:	Functions to set or destroy quickhelps
 *
 *
 *  History:		03-30-94
 *
 *
 ***************************************************************************/
void MResetQuickhelp(Widget parent, USER_DATA *data, XEvent *event,  Boolean *cont)
{
  /* Check Widget */
  if (!parent) return;
  if (!(XtIsObject(parent))) return;
        XmTextSetString(data->Qhelp_widget, "");
}
 
void MSetQuickhelp(Widget parent, USER_DATA *data, XEvent *event,  Boolean *cont)
{
  /* Check Widget */
  if (!parent) return;
  if (!(XtIsObject(parent))) return;
        XmTextSetString(data->Qhelp_widget, data->Qhelp_name);
}

void MDestroyQuickhelp(Widget parent, USER_DATA *data, XmAnyCallbackStruct *cbs)
{
  if (data){
    if (data->Qhelp_name) free(data->Qhelp_name);
    free(data);
  }
}

void MSetFocus(Widget destination)
{
  if (!destination) return;
  if (!(XtIsObject(destination))) return;

  XmProcessTraversal(destination, XmTRAVERSE_CURRENT);
} 


/***************************************************************************
 *
 *  Funktionsname:	GRAFISCHE FUNKTIONEN
 *  
 *  Documentation:	Einige hilfreiche Funktionen fuer Grafiken, Pixel
 *			und die XPM-Lib.
 *
 *
 *  History:		2.3.95		Create
 *
 *
 ***************************************************************************/
 
Pixel MGetPixelByName(char *str)
{
#ifndef WIN_NT
#if XmVersion < 2000
  Display *dpy = (Display *)_XmGetDefaultDisplay();
  int scr      = DefaultScreen(dpy);
  Colormap cmap= DefaultColormap(dpy, scr);
  XColor color, ignore;

  if (XAllocNamedColor(dpy, cmap, str, &color, &ignore))
        return (color.pixel);
  else
        return (BlackPixel(dpy, scr));
#else
  return 0;
#endif
#else
  return 0;
#endif
}

Pixel MGetPixel(char *str, Widget wid)
{
  Display *dpy = XtDisplay(wid);
  int scr      = DefaultScreen(dpy);
  Colormap cmap= DefaultColormap(dpy, scr);
  XColor color, ignore;

  if (XAllocNamedColor(dpy, cmap, str, &color, &ignore))
        return (color.pixel);
  else
        return (BlackPixel(dpy, scr));
}

#ifdef XPM_YES
Bool MCheckXpmStatus(int stat)
{
  switch (stat){
	case XpmSuccess:
		return TRUE;	
		break;
	case XpmOpenFailed:
		return FALSE;
		break;
	case XpmNoMemory:
		return FALSE;
		break;
	case XpmFileInvalid:
		return FALSE;
		break;
	case XpmColorFailed:
		return FALSE;
		break;
	case XpmColorError:
		return FALSE;
		break;
        default:
		XtWarning("Unknown XPM error-message");
                return FALSE;
  }
}
#endif
