/*@ cc -g -c @I @F @L -o @R.o
*/

/*
** Variously:
**
** LIBS: -lXm -lXt -lX11 -lXp -lXext -lSM -lICE
*/

/*
** This file is provided as is, and may be used and
** distributed freely without liability.
*/

/*
** A.J.Fountain,
** Imperial Software Technology (IST),
** Berkshire House,
** 252 Kings Road,
** Reading, 
** Berkshire,
** United Kingdom RG1 4HP.
**
** Telephone: +44 1189 587055
** Fax:       +44 1189 589005
** Email:     support@ist.co.uk
*/

#ifndef   lint
static char *sccsid[] = {"%Z%%Q%%M%	%I%"} ; /* %E% */
#endif /* lint */

/* colored_list.c: illustrates the basic features of
** render tables and renditions by creating a 
** multi-font, multi-color List widget.
*/

#include <Xm/Xm.h>
#include <Xm/List.h>
#include <Xm/RowColumn.h>

/* ConvertStringToPixel()
** A utility function to convert a color name to a Pixel 
*/
Pixel ConvertStringToPixel (Widget widget, char *name)
{
	XrmValue from_value, to_value; /* For resource conversion */

	from_value.addr = name; 
	from_value.size = strlen(name) + 1;
	to_value.addr = NULL;
	XtConvertAndStore (widget, XmRString, &from_value, XmRPixel, &to_value);
	
	if (to_value.addr) {
		return (*((Pixel*) to_value.addr));
	}
	
	return XmUNSPECIFIED_PIXEL;
}

/*
** A convenient structure to hold the data
** for creating various renditions
*/
typedef struct RenditionData_s
{
	char *color;
	char *font;
} RenditionData_t;

#define   MAX_LINES   4

RenditionData_t rendition_data[MAX_LINES] =
{
	{ "red",    "fixed"                                                      },
	{ "green",  "-adobe-helvetica-bold-r-normal--10-100-75-75-*-*-iso8859-1" },
	{ "blue",   "bembo-bold"                                                 },
	{ "orange", "-adobe-*-medium-i-normal--24-240-75-75-*-*-iso8859-1"       }
};

/*
** Arbitrary data to display in the List.
** Each line will appear in a different font/color.
*/
static char *poem[] =
{
	"Mary had a little lamb",
	"Its fleece was white as snow",
	"And everywhere that Mary went",
	"The lamb was sure to follow",
	(char *) 0
};

/*
** CreateListData(): routine to convert the
** poem into an array of compound strings
*/
XmStringTable CreateListData (int *count)
{
	XmStringTable table = (XmStringTable) 0;
	int           line = 0;

	table = (XmStringTable) XtMalloc ((unsigned) MAX_LINES * sizeof (XmString)) ;

	while (poem[line] != (char *) 0) {
		/* create a compound string, using the rendition tag */
		table[line] = XmStringGenerate ((XtPointer) poem[line], 
					        NULL,
						XmCHARSET_TEXT, 
						rendition_data[line].color);

		line++;
	}

	*count = line;

	return table;
}

main (int argc, char *argv[])
{
	Widget        toplevel, rowcol, list;
	XtAppContext  app;
	Arg           args[10];
	XmRendition   renditions[MAX_LINES];
	XmRenderTable rendertable;
	XmStringTable xmstring_table;
	int           xmstring_count;
	Pixel         pixels[MAX_LINES];
	int           n, i;
	
	XtSetLanguageProc (NULL, NULL, NULL);
	toplevel = XtVaOpenApplication (&app, "ColoredList", NULL, 0, &argc, argv, NULL, 
					sessionShellWidgetClass, NULL);

	rowcol = XmCreateRowColumn (toplevel, "rowcol", NULL, 0);

	/* Create some colors */
	for (i = 0; i < MAX_LINES; i++) {
		pixels[i] = ConvertStringToPixel (toplevel, rendition_data[i].color);
	}

	/* Create some Renditions: one per line */
	for (i = 0 ; i < MAX_LINES ; i++) {
		n = 0;
		XtSetArg (args[n], XmNrenditionForeground, pixels[i]); n++;
		XtSetArg (args[n], XmNfontName, rendition_data[i].font); n++;
		XtSetArg (args[n], XmNfontType, XmFONT_IS_FONT); n++;
		renditions[i] = XmRenditionCreate (toplevel, rendition_data[i].color, args, n);
	}

	/* Create the Render Table */
	rendertable = XmRenderTableAddRenditions (NULL, renditions, XtNumber (renditions), XmMERGE_NEW);
	
	/* Create the data for the list */
	xmstring_table = CreateListData (&xmstring_count);
	
	/* Create the List, using the render table */
	n = 0;
	XtSetArg (args[n], XmNrenderTable, rendertable); n++;
	XtSetArg (args[n], XmNitems, xmstring_table); n++;
	XtSetArg (args[n], XmNitemCount, xmstring_count); n++;
	XtSetArg (args[n], XmNwidth, 400); n++;
	XtSetArg (args[n], XmNvisibleItemCount, xmstring_count + 1); n++;
	list = XmCreateScrolledList (rowcol, "list", args, n);
	XtManageChild (list);
	
	/* Free the memory now the widget has copied the data */
	/* First, the compound strings */
	for (i = 0; i < xmstring_count; i++)
		XmStringFree (xmstring_table[i]);
	XtFree ((char *) xmstring_table);
#if 0	
	/* Secondly, the XmRendition objects */
	for (i = 0; i < XtNumber (renditions); i++)
		XmRenditionFree (renditions[i]);
		
	/* Lastly, the XmRenderTable object */
	XmRenderTableFree (rendertable);
#endif
	XtManageChild (rowcol);
	XtRealizeWidget (toplevel);
	XtAppMainLoop (app);
}
