/*
 * * Generated by X-Designer
 */
/*
 * *LIBS: -lXm -lXt -lX11
 */

#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>

#include <Xm/Xm.h>
#include <Xm/DialogS.h>
#include <Xm/Form.h>
#include <Xm/List.h>
#include <Xm/ScrollBar.h>
#include <Xm/AtomMgr.h>
#include <Xm/XmP.h>
#include <X11/Xmu/StdSel.h>
#include <X11/Xfuncs.h>
#include <stdio.h>

extern void     select_callback();
Widget          appshell = (Widget) NULL;

Boolean         convert_proc();
void            lose_proc();

void 
select_callback(w, client_data, cd)
	Widget          w;
	XtPointer       client_data;
	XtPointer       cd;
{
	XmListCallbackStruct *call_data = (XmListCallbackStruct *) cd;
	if (call_data->selected_item_count)
		XtOwnSelection(w, XA_PRIMARY, call_data->event->xbutton.time,
			       convert_proc, lose_proc, NULL);
	else
		XtDisownSelection(w, XA_PRIMARY,
				  call_data->event->xbutton.time);
}

Boolean
convert_proc(w, selection, target, type_return, value, length, format)
	Widget          w;
	Atom           *selection, *target, *type_return;
	XtPointer      *value;
	unsigned long  *length;
	int            *format;
{
	Atom            COMPOUND_TEXT = XmInternAtom(XtDisplay(w),
						     "COMPOUND_TEXT", False);
	Atom            TARGETS = XmInternAtom(XtDisplay(w), "TARGETS", False);
	XSelectionRequestEvent *request = XtGetSelectionRequest(w,
					    *selection, (XtRequestId) NULL);
	if (*target == TARGETS) {
		Atom           *targets;
		Atom           *std_targets;
		unsigned long   std_length;
		/* Get standard list of targets */
		XmuConvertStandardSelection(w, request->time, selection, target,
			type_return, (caddr_t *) & std_targets, &std_length,
					    format);
		/*
		 * Allocate extra storage for our extra targets and build a
		 * list. We return the list via the value parameter
		 */
		*length = std_length + 4;
		*value = (XtPointer) XtMalloc(sizeof(Atom) * (*length));
		targets = *(Atom **) value;
		*targets++ = TARGETS;
		*targets++ = XmInternAtom(XtDisplay(w), "MULTIPLE", False);
		*targets++ = XA_STRING;
		*targets++ = COMPOUND_TEXT;
		/* Append standard list to ours, and free the standard one */
		bcopy((char *) std_targets, (char *) targets, sizeof(Atom) * std_length);
		XtFree((char *) std_targets);
		*type_return = XA_ATOM;
		*format = 32;
		return True;
	} else if (*target == XA_STRING) {
		char          **tmp_value;
		XTextProperty   tmp_prop;
		int             status = 0;
		XmString       *selected_items;
		int             selected_count;
		int             i;

		XtVaGetValues(w, XmNselectedItems, &selected_items,
			      XmNselectedItemCount, &selected_count, 0);
		if (selected_count == 0)
			return False;

		tmp_value = (char **) XtMalloc(selected_count * sizeof(char *));
		for (i = 0; i < selected_count; i++)
			if (!XmStringGetLtoR(selected_items[i],
				     XmFONTLIST_DEFAULT_TAG, &tmp_value[i]))
				tmp_value[i] = NULL;
		status = XmbTextListToTextProperty(XtDisplay(w), tmp_value,
			   selected_count, (XICCEncodingStyle) XStringStyle,
						   &tmp_prop);
		for (i = 0; i < selected_count; i++)
			XtFree((char *)tmp_value[i]);
		XtFree((char *)tmp_value);
		if (status == Success || status > 0) {
			*type_return = XA_STRING;
			*format = 8;
			*value = (XtPointer) XtMalloc((unsigned) tmp_prop.nitems);
			memcpy((void *) *value,
			(void *) tmp_prop.value, (unsigned) tmp_prop.nitems);
			XFree((char *) tmp_prop.value);
			*length = tmp_prop.nitems;
			return True;
		}
	} else if (*target == COMPOUND_TEXT) {
		XmString       *selected_items, s1, s2, sep;
		int             selected_count;
		int             i;
		XrmValue        from_val, to_val;

		XtVaGetValues(w, XmNselectedItems, &selected_items,
			      XmNselectedItemCount, &selected_count, 0);
		if (selected_count == 0)
			return False;

		s1 = XmStringCopy(selected_items[0]);
		sep = XmStringSeparatorCreate();
		for (i = 1; i < selected_count; i++) {
			s2 = XmStringConcat(s1, sep);
			XmStringFree(s1);
			s1 = XmStringConcat(s2, selected_items[i]);
			XmStringFree(s2);
		}
		from_val.addr = (char *) s1;
		if (_XmCvtXmStringToCT(&from_val, &to_val)) {
			*type_return = COMPOUND_TEXT;
			*format = 8;
			*value = to_val.addr;
			*length = to_val.size + 1;
			XmStringFree(s1);
			XmStringFree(sep);
			return True;
		}
		XmStringFree(s1);
		XmStringFree(sep);
	} else if (XmuConvertStandardSelection(w, request->time, selection, target,
			    type_return, (caddr_t *) value, length, format))
		return True;
	*value = NULL;
	*length = 0;
	return False;
}

void
lose_proc(w, selection)
	Widget          w;
	Atom           *selection;
{
	XmListDeselectAllItems(w);
}
void 
create_appshell(display, app_name, app_argc, app_argv)
	Display        *display;
	char           *app_name;
	int             app_argc;
	char          **app_argv;
{
	Arg             al[64];	/* Arg List */
	register int    ac = 0;	/* Arg Count */
	XmString       *list_items;	/* For list items */
	int             list_item;	/* Index for list_items */
	Widget          form = (Widget) NULL;
	Widget          list_sw = (Widget) NULL;
	Widget          list = (Widget) NULL;

	XtSetArg(al[ac], XmNallowShellResize, TRUE); ac++;
	XtSetArg(al[ac], XmNtitle, "Primary Selection"); ac++;
	XtSetArg(al[ac], XmNargc, app_argc); ac++;
	XtSetArg(al[ac], XmNargv, app_argv); ac++;
	appshell = XtAppCreateShell(app_name, "XApplication", applicationShellWidgetClass, display, al, ac);
	ac = 0;
	XtSetArg(al[ac], XmNautoUnmanage, FALSE); ac++;
	form = XmCreateForm(appshell, "form", al, ac);
	ac = 0;
	XtSetArg(al[ac], XmNvisibleItemCount, 11); ac++;
	XtSetArg(al[ac], XmNselectionPolicy, XmMULTIPLE_SELECT); ac++;
	XtSetArg(al[ac], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE); ac++;
	XtSetArg(al[ac], XmNitemCount, 4); ac++;
	list_items = (XmString *) XtMalloc(sizeof(XmString) * 4);
	list_items[0] = XmStringCreateLtoR("Item1", (XmStringCharSet) XmFONTLIST_DEFAULT_TAG);
	list_items[1] = XmStringCreateLtoR("Item2", (XmStringCharSet) XmFONTLIST_DEFAULT_TAG);
	list_items[2] = XmStringCreateLtoR("Item3", (XmStringCharSet) XmFONTLIST_DEFAULT_TAG);
	list_items[3] = XmStringCreateLtoR("Item4", (XmStringCharSet) XmFONTLIST_DEFAULT_TAG);
	XtSetArg(al[ac], XmNitems, list_items); ac++;
	list = XmCreateScrolledList(form, "list", al, ac);
	XtAddCallback(list, XmNmultipleSelectionCallback, select_callback, NULL);

	ac = 0;
	list_sw = XtParent(list);

	for (list_item = 0; list_item < 4; list_item++)
		XmStringFree(list_items[list_item]);
	XtFree((char *) list_items);

	XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
	XtSetValues(list_sw, al, ac);
	ac = 0;
	XtManageChild(list);
	XtManageChild(form);
}



XtAppContext    app_context;
Display        *display;	/* Display             */

int 
main(argc, argv)
	int             argc;
	char          **argv;
{
	XtSetLanguageProc((XtAppContext) NULL, (XtLanguageProc) NULL, (XtPointer) NULL);
	XtToolkitInitialize();
	app_context = XtCreateApplicationContext();
	display = XtOpenDisplay(app_context, NULL, argv[0], "XApplication",
				NULL, 0, &argc, argv);
	if (!display) {
		printf("%s: can't open display, exiting...\n", argv[0]);
		exit(-1);
	}
	create_appshell(display, argv[0], argc, argv);
	XtRealizeWidget(appshell);
	
{
    static XtWidgetGeometry Expected[] = {
   CWWidth | CWHeight            ,   56,   72,   40,  183, 0,0,0, /* form */
   CWWidth | CWHeight | CWX | CWY,    0,    0,   40,  183, 0,0,0, /* listSW */
   CWWidth | CWHeight | CWX | CWY,    0,    0,   40,  183, 0,0,0, /* list */ 
    };
    PrintDetails(appshell,Expected);
};
	LessTifTestMainLoop(appshell);
	exit(0);
}
