/* write_lw - printf function like to write into a label widget or gadget;
	      procedure accepts variable number of arguments;
	      A widget into which something will be written must belongs
	      to a label widget class or to a label gadget class.
	      The output will be written using appropriate character set.
	      (C) A. Stochniol 1992 - 1993
	      Last revision: 15.01.1993
	      (version for ANSI and non-ANSI compilers)
 */


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

#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>



/* Definitions of functions that accept a variable number of arguments.
   There are separate definitions for macros compatible with UNIX System V
   (<varargs.h>) and for ANSI C (<stdarg.h>). Because of that to be on the
   safe side I wrote two versions of write_lw that stick exactly to the
   rules in both cases.
   Use STDARG.H for ANSI C compatibility (whenever possible).
   NOTE: You can't include both STDARG.H and VARARGS.H
   A symbol _NO_STDARG is defined by me in the Imakefile !!!
*/

#ifndef _NO_STDARG
#include <stdarg.h>

#ifdef _NO_PROTO
void write_lw(Widget label, XmStringCharSet charset, va_list arg_list, ...)
/*** to be honest you SHOULD (must ?) use prototypes
	for ANSI style functions with variable number of arguments,
	otherwise passing of parameters might be wrong; so
	if you change above declaration watch out if the label
	widgets show what you intended to show !!! */
#else  /* _NO_PROTO */
void write_lw(Widget label, XmStringCharSet charset, va_list arg_list, ...)
#endif
{
 va_list arg_ptr;
 char *format;
 char output[512];	/* watch out not to use longer output !!!! */
 Arg       al[1];
 XmString  xmstr;

 /* a following bug has been reported by marmor@bimacs.cs.biu.ac.il (Eli Marmor) :
        write_lw() is called sometimes (in the initialization, in some
        platforms like SunOS 4.1.x with X11R4 and Motif 1.1) with NULL as its
        1st parameter (which should be a widget). When write_lw() checks the
        type of this NULL-widget, by the following command
                if(!XmIsLabel(label) && !XmIsLabelGadget(label))
        it fails, and core is dumped. I don't know why it is called with NULL
        widget, but I added a test for its value in the beginning of the
        function.
    So to be on the safe side we do the following test for a NULL widget ...
 */
 if(!label) return;             /* safety test .... */

 /* init the variable length argument list */
 va_start(arg_ptr, arg_list);
 format = arg_list;
 /* use vsprintf to format the string to be displayed in the widget */
 vsprintf(output, format, arg_ptr);
 va_end(arg_ptr);		/* ends variable argument access */

 /* Make sure that the destination widget is a subclass of XmLabel. */
  if(!XmIsLabel(label) && !XmIsLabelGadget(label))
  {
	fprintf(stderr, "Error: write_lw requires a Label Widget or Gadget. The following output not written:\n %s \n",
		output);
	return;
  }

  /* convert the string to an appropriate compound string and set it */
  xmstr =  XmStringLtoRCreate(output, charset);
  XtSetArg(al[0], XmNlabelString, xmstr);
  XtSetValues(label, al, 1);
  /* 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 are finished) */
  XmStringFree(xmstr);

} /* write_lw */

#else	/*  ( _NO_STDARG) now version for non-ANSI C (UNIX system V varargs)  */

#include <varargs.h>

#ifdef _NO_PROTO
void write_lw(va_alist)
va_dcl
#else  /* _NO_PROTO */
void write_lw(va_list va_alist)
#endif
{
 va_list arg_ptr;
 char *format;
 char output[512];	/* watch out not to use longer output !!!! */
 Arg       al[1];
 XmString  xmstr;

 Widget label;
 XmStringCharSet charset;


 /* init the variable length argument list */
 va_start(arg_ptr);
 label  = va_arg(arg_ptr, Widget);	/* 1-st argument -> Widget  */

 /* a following bug has been reported by marmor@bimacs.cs.biu.ac.il (Eli Marmor) : 
        write_lw() is called sometimes (in the initialization, in some
        platforms like SunOS 4.1.x with X11R4 and Motif 1.1) with NULL as its
        1st parameter (which should be a widget). When write_lw() checks the
        type of this NULL-widget, by the following command
                if(!XmIsLabel(label) && !XmIsLabelGadget(label))
        it fails, and core is dumped. I don't know why it is called with NULL
        widget, but I added a test for its value in the beginning of the
        function.
    So to be on the safe side we do the following test for a NULL widget ...
 */
 if(!label) return;		/* safety test .... */

 charset= va_arg(arg_ptr, XmStringCharSet);	/* 2-nd argument -> charset */
 format = va_arg(arg_ptr, char *);	/* 3-rd argument -> format  */
 /* use vsprintf to format the string to be displayed in the widget */
 vsprintf(output, format, arg_ptr);
 va_end(arg_ptr);		/* ends variable argument access */

 /* Make sure that the destination widget is a subclass of XmLabel. */
  if(!XmIsLabel(label) && !XmIsLabelGadget(label))
  {
	fprintf(stderr, "Error: write_lw requires a Label Widget or Gadget. The following output not written:\n %s \n",
		output);
	return;
  }

  /* convert the string to an appropriate compound string and set it */
  xmstr =  XmStringLtoRCreate(output, charset);
  XtSetArg(al[0], XmNlabelString, xmstr);
  XtSetValues(label, al, 1);
  /* 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 are finished) */
  XmStringFree(xmstr);

} /* write_lw */

#endif	/* _NO_STDARG  */

