ftp.nice.ch/pub/next/database/plz/xplz.3.4.s.tar.gz#/xplz-3.4/gui.c

This is gui.c in view mode; [Download] [Up]

/* $Id: gui.c,v 2.8 1993/06/28 09:31:07 klute Exp klute $ */

/* 
 * Copyright 1993 Rainer Klute <klute@irb.informatik.uni-dortmund.de>
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation. The author makes no representations about the suitability
 * of this software for any purpose. It is provided "as is" without express
 * or implied warranty.
 *
 */

#include <malloc.h>
#include <string.h>

#include <Xm/Xm.h>
#include <Xm/Text.h>

#include "gui.h"
#include "ui.h"

#include "gui_batch.h"
#include "gui_build.h"
#include "gui_utils.h"
#include "convert.h"
#include "message.h"
#include "parse.h"
#include "strada.h"
#include "utils.h"


#if defined (HANDLE_BROKEN_DATAFILES)
#define IbmToIso IbmAndBrokenToIso
#endif




static char *messageBuffer = (char *) 0;




XtCallbackProc StrassenverzeichnisCallback
(Widget widget, XtPointer clientData, XtPointer callData)
{
    ConversionData *cd = (ConversionData *) clientData;
    PlzConversion *pc = cd->pc;
    GuiComponents *gc = cd->gc;

    SetBusyCursor (gc->plz_neu);
    LabelSetString (gc->plz_neu, "");
    if (pc->orte->entries > 0)
	pc->strassen = Strassenverzeichnis (pc->orte->list[0].alort);
    else if (pc->archivOrte->entries > 0)
	pc->strassen = Strassenverzeichnis (pc->archivOrte->list[0].alort);
    StradaSetToList (gc->list, pc->strassen, pc->ort);
    XtAddCallback (gc->list, XmNsingleSelectionCallback,
		   (XtCallbackProc) ListStreetSelected, cd);
    UnsetBusyCursor (gc->plz_neu);
}




static void GuiMsgFlush (UiComponents *uc)
{
    GuiComponents *gc = (GuiComponents *) uc;
    InformationDialog (TopLevelShell (gc->messages), "Hinweis:", messageBuffer);
    free (messageBuffer);
    messageBuffer = (char *) 0;
}




static void GuiMsgWrite (UiComponents *uc, char *msg)
{
    char *help;

    if (messageBuffer == (char *) 0)
    {
	messageBuffer = (char *) malloc (1);
	*messageBuffer = '\0';
    }
    help = messageBuffer;
    messageBuffer = (char *) malloc (strlen (messageBuffer) + strlen (msg) + 1);
    strcpy (messageBuffer, help);
    strcat (messageBuffer, msg);
    free (help);
}




static void GuiNoteWrite (UiComponents *uc, char *msg)
{
    GuiComponents *gc = (GuiComponents *) uc;

    XmTextInsert (gc->messages, XmTextGetLastPosition (gc->messages), msg);
    XmTextSetInsertionPosition (gc->messages,
				XmTextGetLastPosition (gc->messages));
    XmUpdateDisplay (gc->messages);
}




static void GuiNoteClear (UiComponents *uc)
{
    GuiComponents *gc = (GuiComponents *) uc;

    XtVaSetValues (gc->messages, XmNvalue, "", NULL);
}




void InitDisplay (ConversionData *cd, char **strasse, char **hausnummer, char**postfach, char **plz_alt, char **ort, char **postanstalt, char **ortsteil)
{
    GuiComponents *gc = cd->gc;

    LabelSetString (gc->plz_neu, "");
    XtVaSetValues (gc->list,
		   XmNitems, (XmString *) 0,
		   XmNitemCount, 0L,
		   NULL);

}




XtCallbackProc ConvertCallback (Widget widget, XtPointer clientData,
				XtPointer callData)
{
    char string[300];
    char *help;
    ConversionData *conversionData = (ConversionData *) clientData;
    PlzConversion *pc = conversionData->pc;
    char *strasse, *hausnummer, *postfach, *plz_alt, *ort, *postanstalt,
	 *ortsteil;
    static XtCallbackRec emptyCallbackList[] = 
	{{(XtCallbackProc) 0, (XtPointer) 0}};

    SetBusyCursor (widget);
    LabelSetString (conversionData->gc->plz_neu, "");
    XtVaSetValues (conversionData->gc->list,
		   XmNitems, (XmString *) 0,
		   XmNitemCount, 0L,
		   NULL);

    help = XmTextGetString (conversionData->gc->strasse);
    ParseStrasse (help, &strasse, &hausnummer, &postfach);
    XtFree (help);
    help = XmTextGetString (conversionData->gc->ort);
    ParseOrt (help, &plz_alt, &ort, &postanstalt, &ortsteil);
    XtFree (help);

    ConvertPlz (pc, strasse, hausnummer, postfach, plz_alt, ort, postanstalt, 
		ortsteil);
    free (strasse);
    free (hausnummer);
    free (postfach);
    free (plz_alt);
    free (ort);
    free (postanstalt);
    free (ortsteil);

    Message (ConversionStatusString (pc->status));
    MessageFlush ();
    XtVaSetValues (conversionData->gc->list,
		   XmNitems, (XmString *) 0, 
		   XmNitemCount, 0L,
		   XmNsingleSelectionCallback, emptyCallbackList,
		   NULL);
    XtVaSetValues (conversionData->gc->menuStrassenverzeichnis, 
		   XmNsensitive, False, NULL);

    if (IsOrtGefunden (pc))
    {
	if (IsOrtEindeutig (pc))
	{
	    if ((pc->orte->entries > 0 && pc->orte->list[0].nplzo_z[0] == '2')
	    || (pc->archivOrte && pc->archivOrte->entries == 1
	    && pc->archivOrte->list[0].nplz_z[0] == '2'))
		XtVaSetValues (conversionData->gc->menuStrassenverzeichnis,
			       XmNsensitive, True, NULL);
	    XmProcessTraversal (conversionData->gc->strasse,
				XmTRAVERSE_CURRENT);
	}
	else
	{
	    /* Mehrere PLZ, möglicherweise auch mehrere Orte */
	    OrteToList (conversionData->gc->list, pc->orte, pc->archivOrte);
	    XtAddCallback (conversionData->gc->list,
			   XmNsingleSelectionCallback,
			   (XtCallbackProc) ListPlaceSelected, conversionData);
	    XmProcessTraversal (conversionData->gc->list, XmTRAVERSE_CURRENT);
	}

	if (pc->status == PlzPlzNeuGefunden)
	    LabelSetString (conversionData->gc->plz_neu, pc->plz_neu);

	strcpy (string, OrtString (pc->plz_alt, pc->ort, pc->postanstalt,
		pc->ortsteil));
	XmTextSetString (conversionData->gc->ort, string);
    }
    else
	XmProcessTraversal (conversionData->gc->ort, XmTRAVERSE_CURRENT);



    if (IsStrasseGefunden (pc))
    {
	strcpy (string, StrasseString (pc->strasse, pc->hausnummer,
		pc->postfach));
	XmTextSetString (conversionData->gc->strasse, string);
	if (!IsStrasseEindeutig (pc))
        {
	    StradaSetToList (conversionData->gc->list, pc->strassen, pc->ort);
	    XtAddCallback (conversionData->gc->list,
			   XmNsingleSelectionCallback, 
		           (XtCallbackProc) ListStreetSelected, 
			    conversionData);
	}
    }


    if (IsPostfachGefunden (pc))
    {
	if (IsPostfachEindeutig (pc))
	{
	    strcpy (string, "Postfach ");
	    strcat (string, pc->postfach);
	    XmTextSetString (conversionData->gc->strasse, string);
	}
	else
        {
	    PofadaSetToList (conversionData->gc->list, pc->postfaecher, 
                             pc->orte->list->ortname_a);
	    XtAddCallback (conversionData->gc->list,
			   XmNsingleSelectionCallback, 
		           (XtCallbackProc) ListPoboxSelected, conversionData);
        }
    }

    UnsetBusyCursor (widget);
}




XtCallbackProc ListActivated (Widget widget, XtPointer clientData,
			      XtPointer callData)
{
    XtCallCallbacks (widget, XmNsingleSelectionCallback, callData);
    ConvertCallback (widget, clientData, callData);
}




/*
 * "ListPlaceSelected" holt den Orts-String aus dem ersten Segment des
 * CompountString und überträgt ihn in das Ortseingabefeld. Falls das zweite
 * Segment als erste Zeichen " -> " enthält, ist dies der aktuelle Ortsname,
 * und der Inhalt des ersten Segments historisch. Er wird als Ortsteil
 * eingesetzt.
 */

XtCallbackProc ListPlaceSelected (Widget widget, XtPointer clientData,
				  XtPointer callData)
{
    XmListCallbackStruct *cd = (XmListCallbackStruct *) callData;
    ConversionData *conversionData = (ConversionData *) clientData;
    XmStringContext context;
    Boolean success;
    XmStringCharSet tag;
    XmStringDirection direction;
    Boolean separator;
    char *item;
    char *plz, *ort, *zustellamt, *ortsteil;

    if (cd->reason != XmCR_SINGLE_SELECT && cd->reason != XmCR_DEFAULT_ACTION)
	return;
    success = XmStringInitContext (&context, cd->item);
    success = XmStringGetNextSegment (context, &item, &tag, &direction,
	      &separator);
    ParseOrt (item, &plz, &ort, &zustellamt, &ortsteil);
    success = XmStringGetNextSegment (context, &item, &tag, &direction,
	      &separator);
    if (success && strncmp (item, " -> ", 4) == 0)
    {
	free (ortsteil);
	ortsteil = ort;
	ort = (char *) malloc (strlen (item + 4) + 1);
	strcpy (ort, item + 4);
    }
    item = OrtString (plz, ort, zustellamt, ortsteil);
    free (plz);
    free (ort);
    free (zustellamt);
    free (ortsteil);
    XmTextSetString (conversionData->gc->ort, item);
    conversionData->pc->status = PlzOrtEindeutig;
}




XtCallbackProc ListPoboxSelected (Widget widget, XtPointer clientData,
				  XtPointer callData)
{
    XmListCallbackStruct *cd = (XmListCallbackStruct *) callData;
    ConversionData *conversionData = (ConversionData *) clientData;
    char *item;
    XmStringContext context;
    XmStringCharSet tag;
    XmStringDirection direction;
    Boolean separator;
    char *plz;
    char *ort;
    char *zustellamt;
    char *ortsteil;

    if (cd->reason != XmCR_SINGLE_SELECT && cd->reason != XmCR_DEFAULT_ACTION)
	return;
    XmStringInitContext (&context, cd->item);
    XmStringGetNextSegment (context, &item, &tag, &direction, &separator);
    ParseOrt (item, &plz, &ort, &zustellamt, &ortsteil);
    item = OrtString (plz, ort, zustellamt, ortsteil);
    XmTextSetString (conversionData->gc->ort, item);
    conversionData->pc->status = PlzSuchePostfach;
}




/*
 * "ListStreetSelected" holt den Straßennamen und gegebenenfalls den
 * Orts-String aus dem CompoundString. Dieser ist wie folgt aufgebaut:
 *     <PLZ>< ><Straßenname>[<, ><Hausnummernbereich>][<SEP><Orts-String>]
 */

XtCallbackProc ListStreetSelected (Widget widget, XtPointer clientData,
				  XtPointer callData)
{
    XmListCallbackStruct *cbs = (XmListCallbackStruct *) callData;
    ConversionData *cd = (ConversionData *) clientData;
    char *item;
    XmStringContext context;
    Boolean success;
    XmStringCharSet tag;
    XmStringDirection direction;
    Boolean separator;
    XmStringComponentType unknown_tag;
    unsigned short unknown_length;
    unsigned char *unknown_value;
    char *postfach;
    char *plz;
    char *ort;
    char *zustellamt;
    char *ortsteil;

    if (cbs->reason != XmCR_SINGLE_SELECT && cbs->reason != XmCR_DEFAULT_ACTION)
	return;
    success = XmStringInitContext (&context, cbs->item);

    /* Postleitzahl: */
    success = XmStringGetNextSegment (context, &item, &tag, &direction,
	      &separator);
    UpdateString (&cd->pc->plz_neu, item);
    LabelSetString (cd->gc->plz_neu, item);
    cd->pc->status = PlzPlzNeuGefunden;
    success = XmStringGetNextSegment (context, &item, &tag, &direction,
	      &separator);

    /* Straßenname: */
    success = XmStringGetNextSegment (context, &item, &tag, &direction,
	      &separator);
    UpdateString (&cd->pc->strasse, item);
    item = StrasseString (item, cd->pc->hausnummer, postfach);
    XmTextSetString (cd->gc->strasse, item);

    /* Hausnummernbereich: */
    if (!separator)
    {
	success = XmStringGetNextSegment (context, &item, &tag, &direction,
					  &separator);
	success = XmStringGetNextSegment (context, &item, &tag, &direction,
					  &separator);
    }

    /* Orts-String: */
    if (separator)
    {
	XmStringGetNextComponent (context, &item, &tag, &direction,
				  &unknown_tag, &unknown_length,
				  &unknown_value);
	success = XmStringGetNextSegment (context, &item, &tag, &direction,
					  &separator);
	ParseOrt (item, &plz, &ort, &zustellamt, &ortsteil);
	item = OrtString (plz, ort, zustellamt, ortsteil);
	UpdateString (&cd->pc->plz_alt, plz);
	UpdateString (&cd->pc->ort, ort);
	UpdateString (&cd->pc->postanstalt, zustellamt);
	UpdateString (&cd->pc->ortsteil, ortsteil);
	free (plz);
	free (ort);
	free (zustellamt);
	free (ortsteil);
	XmTextSetString (cd->gc->ort, item);
    }
    else
    {
	UpdateString (&cd->pc->postanstalt, "");
	UpdateString (&cd->pc->ortsteil, "");
	item = OrtString (cd->pc->plz_alt, cd->pc->ort, "", "");
	XmTextSetString (cd->gc->ort, item);
    }
    XmStringFreeContext (context);
}




void PofadaSetToList (Widget list, PofadaSet *pofadaSet, char *ortsname)
{
    Pofada *l;
    Pofada *newPobox;
    int i, j;
    XmString *stringList = (XmString *) calloc ((int) pofadaSet->entries, 
						sizeof (XmString *));
    char msg[300];
    char *isoMsg;
    int entriesLeft = pofadaSet->entries;
    char postanstalt[5];

    newPobox = pofadaSet->list;
    postanstalt[0] = '\0';
    for (l = pofadaSet->list, i = j = 0; i < pofadaSet->entries; i++, l++)
    {
	msg[0] = '\0';
	if (strncmp (l->npanst, postanstalt, sizeof (l->npanst)) != 0)
	{
	    strncpy (postanstalt, l->npanst, sizeof (l->npanst));
	    strncat (msg, l->plz_w_o, sizeof (l->plz_w_o));
	    strncat (msg, l->plzalt, sizeof (l->plzalt));
    	    strcat  (msg, " ");
    	    strncat (msg, ortsname, sizeof (((Umsda *) 0)->ortname_a));
    	    StripBlanks (msg);
    	    strcat  (msg, " ");
    	    strncat (msg, l->npanst, sizeof (l->npanst));
	}
	else
	{
	    entriesLeft--;
	    continue;
	}

#if defined (HANDLE_BROKEN_DATAFILES)
	isoMsg = IbmAndBrokenToIso (msg);
#else
	isoMsg = IbmToIso (msg);
#endif
	stringList[j++] = XmStringCreateLtoR (isoMsg, XmFONTLIST_DEFAULT_TAG);
	free (isoMsg);
    }

    XtVaSetValues (list, XmNitems, stringList, XmNitemCount, 
		   (long) entriesLeft, NULL);
    for (i = 0; i < entriesLeft; i++)
	XmStringFree (stringList[i]);
    free (stringList);
}




static void AppendHn (char *s, char *tag, int length)
{
    char *c = tag;

    while (*c == ' ' && c - tag < length)
	c++;
    if (c - tag < length)
    {
	strncat (s, c, length - (c - tag));
	StripBlanks (s);
    }
}




void StradaSetToList (Widget list, StradaSet *stradaSet, char *ortsname)
{
    Strada *l;
    Strada *newStreet;
    int i, j;
    XmString s1;
    XmString *stringList = (XmString *) calloc ((int) stradaSet->entries, 
						sizeof (XmString *));
    char msg[300];
    char *isoMsg;
    char ortsteil[sizeof (((Strada *) 0)->ortsteil)];
    char sname[sizeof (((Strada *) 0)->sname)];
    char strlfdnr[sizeof (((Strada *) 0)->strlfdnr)];
    int entriesLeft = stradaSet->entries;

    newStreet = stradaSet->list;
    ortsteil[0] = sname[0] = strlfdnr[0] = '\0';
    for (l = stradaSet->list, i = j = 0; i < stradaSet->entries; i++, l++)
    {
	/* neue Postleitzahl: */
	msg[0] = '\0';
	strncat (msg, l->plz_z, sizeof (l->plz_z));
	s1 = XmStringCreate (msg, XmFONTLIST_DEFAULT_TAG);
	s1 = StringCat (s1, XmStringCreate (" ", XmFONTLIST_DEFAULT_TAG));

	/* Straßenname: */
	msg[0] = '\0';
	strncat (msg, l->sname, sizeof (l->sname));
	StripBlanks (msg);
	isoMsg = IbmToIso (msg);
	s1 = StringCat (s1, XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG));
	free (isoMsg);

	/* Hausnummernbereich (falls vorhanden): */
	if (strntoi (l->nplz_z, sizeof (l->nplz_z)) > 1)
	{
	    s1 = StringCat (s1, XmStringCreate (", ", XmFONTLIST_DEFAULT_TAG));
	    msg[0] = '\0';
	    AppendHn (msg, l->hnr1von, sizeof (l->hnr1von));
	    AppendHn (msg, l->hnr2von, sizeof (l->hnr2von));
	    strcat (msg, "-");
	    AppendHn (msg, l->hnr1bis, sizeof (l->hnr1bis));
	    AppendHn (msg, l->hnr2bis, sizeof (l->hnr2bis));
	    isoMsg = IbmToIso (msg);
	    s1 = StringCat (s1, XmStringCreate (isoMsg,
						XmFONTLIST_DEFAULT_TAG));
	    free (isoMsg);
	}
	else
	{
	    if (strncmp (l->sname, sname, sizeof (l->sname)) != 0
	    || strncmp (l->strlfdnr, strlfdnr, sizeof (l->strlfdnr)) != 0)
	    {
		strncpy (sname, l->sname, sizeof (l->sname));
		strncpy (strlfdnr, l->strlfdnr, sizeof (l->strlfdnr));
	    }
	    else
	    {
		entriesLeft--;
		XmStringFree (s1);
		continue;
	    }
	}

	/* Orts-String (bei mehreren gleichnamigen Straßen): */
	if (strntoi (l->anzgleist, sizeof (l->anzgleist)) > 1)
	{
	    if (strncmp (l->ortsteil, ortsteil, sizeof (l->ortsteil)) != 0)
	    {
		s1 = StringCat (s1, XmStringSeparatorCreate ());
		strncpy (ortsteil, l->ortsteil, sizeof (l->ortsteil));
		strcpy (msg, "          ");
		strncat (msg, l->plz_w_o, sizeof (l->plz_w_o));
	    	StripBlanks (msg);
		strncat (msg, l->plzalt, sizeof (l->plzalt));
	    	strcat  (msg, " ");
	    	strncat (msg, ortsname, sizeof (((Umsda *) 0)->ortname_a));
	    	StripBlanks (msg);
	    	strcat  (msg, " ");
	    	strncat (msg, l->npanst, sizeof (l->npanst));
	    	StripBlanks (msg);
	    	strcat  (msg, " (");
		strncat (msg, l->ortsteil, sizeof (l->ortsteil));
	    	StripBlanks (msg);
            	strcat  (msg, ")");
	    	StripBlanks (msg);
		isoMsg = IbmToIso (msg);
		s1 = StringCat (s1, XmStringCreate (isoMsg,
						    XmFONTLIST_DEFAULT_TAG));
		free (isoMsg);
	    }
	    else
	    {
		entriesLeft--;
		XmStringFree (s1);
		continue;
	    }
	}

	stringList[j++] = s1;
    }

    XtVaSetValues (list, XmNitems, stringList, XmNitemCount, 
		   (long) entriesLeft, NULL);
    for (i = 0; i < entriesLeft; i++)
	XmStringFree (stringList[i]);
    free (stringList);
}




void OrteToList (Widget list, UmsdaSet *orte, OrtardaSet *archivOrte)
{
    Umsda *lu;
    Ortarda *lo;
    int i;
    XmString *stringList = (XmString *) calloc ((int) orte->entries
			   + (int) archivOrte->entries, sizeof (XmString *));
    XmString s1;
    char msg[300];
    char *isoMsg;
    char *c;

    for (lu = orte->list, i = 0; i < orte->entries; i++)
    {
	/* PLZ alt, Ortsname, Postanstalt: */
	msg[0] = '\0';
	strncat (msg, lu->plz_w_o, sizeof (lu->plz_w_o));
	strncat (msg, lu->plzalt, sizeof (lu->plzalt));
        strcat  (msg, " ");
        strncat (msg, lu->ortname_a, sizeof (lu->ortname_a));
	StripBlanks (msg);
        strcat  (msg, " ");
        strncat (msg, lu->npanst_a, sizeof (lu->npanst_a));
	StripBlanks (msg);
	isoMsg = IbmToIso (msg);
	s1 = XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG);
	free (isoMsg);

	/* Ortszusatz: */
	*msg = '\0';
	c = lu->ortzusa;
	if (*c != ',' && *c != '-')
	    strcat (msg, " ");
	while (*c == ' ' && c - lu->ortzusa < sizeof (lu->ortzusa))
	    c++;
	if (c - lu->ortzusa < sizeof (lu->ortzusa))
	    strncat (msg, c, sizeof (lu->ortzusa) - (c - lu->ortzusa));
	StripBlanks (msg);

	isoMsg = IbmToIso (msg);
	stringList[i] = StringCat (s1, XmStringCreate (isoMsg, "italic"));
	free (isoMsg);
	lu++;
    }

    for (lo = archivOrte->list; i < orte->entries + archivOrte->entries; i++)
    {
	/* PLZ alt, Ortsname, Postanstalt: */
	msg[0] = '\0';
	strncat (msg, lo->plz_w_o, sizeof (lo->plz_w_o));
	strncat (msg, lo->plzalt, sizeof (lo->plzalt));
        strcat  (msg, " ");
        strncat (msg, lo->ortname_a, sizeof (lo->ortname_a));
	StripBlanks (msg);
        strcat  (msg, " ");
        strncat (msg, lo->npanst_a, sizeof (lo->npanst_a));
	StripBlanks (msg);
	isoMsg = IbmToIso (msg);
	s1 = XmStringCreate (isoMsg, XmFONTLIST_DEFAULT_TAG);
	free (isoMsg);

	/* aktueller Ortsname: */
	strcpy (msg, " -> ");
	strncat (msg, lo->ortname_n, sizeof (lo->ortname_n));
	StripBlanks (msg);

	isoMsg = IbmToIso (msg);
	stringList[i] = StringCat (s1, XmStringCreate (isoMsg, "italic"));
	free (isoMsg);
	lo++;
    }

    XtVaSetValues (list, XmNitems, stringList, XmNitemCount,
		   (long) (orte->entries + archivOrte->entries), NULL);
    for (i = 0; i < orte->entries + archivOrte->entries; i++)
	XmStringFree (stringList[i]);
    free (stringList);
}




XtCallbackProc QuitCallback (Widget widget, XtPointer clientData,
			     XtPointer callData)
{
    XtDestroyApplicationContext (XtWidgetToApplicationContext (widget));
    exit (0);
}




static Boolean RecordRead (char *record)
{
    Note (".");
    return True;
}

static Boolean PofadaRecordRead (char *record)
{
    return RecordRead (record);
}

static Boolean StradaRecordRead (char *record)
{
    return RecordRead (record);
}

static Boolean UmsdaRecordRead (char *record)
{
    return RecordRead (record);
}

static Boolean OrtardaRecordRead (char *record)
{
    return RecordRead (record);
}




void MotifInterface (Display *display)
{
    static ConversionData cd;
    static PlzConversion pc;
    static GuiComponents gc;
    Widget applicationShell;

    cd.pc = &pc;
    cd.gc = &gc;
    cd.batch = (Batch *) 0;
    gc.strasse = gc.ort = gc.plz_neu = (Widget) 0;
    cd.pc->plz_alt = (char *) 0;
    cd.pc->ort = (char *) 0;
    cd.pc->postanstalt = (char *) 0;
    cd.pc->ortsteil = (char *) 0;
    cd.pc->strasse = (char *) 0;
    cd.pc->hausnummer = (char *) 0;
    cd.pc->postfach = (char *) 0;
    cd.pc->plz_neu = (char *) 0;
    cd.pc->verkehrsgebiet = 'W';
    cd.pc->orte = (UmsdaSet *) 0;
    cd.pc->strassen = (StradaSet *) 0;
    cd.pc->postfaecher = (PofadaSet *) 0;

    /* kleiner Hack für Motif 1.2.1: */

    XDeleteProperty (display, 
		     RootWindowOfScreen (DefaultScreenOfDisplay (display)),
		     XInternAtom (display, "_MOTIF_DRAG_WINDOW", False));
    applicationShell = CreateMainWindow (display, &cd);

    userInterfaceMethods.uiComponents = (UiComponents *) &gc;
    userInterfaceMethods.NoteClear = GuiNoteClear;
    userInterfaceMethods.NoteWrite = GuiNoteWrite;
    userInterfaceMethods.MsgWrite = GuiMsgWrite;
    userInterfaceMethods.MsgFlush = GuiMsgFlush;
    userInterfaceMethods.PofadaRecordRead = PofadaRecordRead;
    userInterfaceMethods.StradaRecordRead = StradaRecordRead;
    userInterfaceMethods.UmsdaRecordRead = UmsdaRecordRead;
    userInterfaceMethods.OrtardaRecordRead = OrtardaRecordRead;

    XmProcessTraversal (cd.gc->ort, XmTRAVERSE_CURRENT);
    XtAppMainLoop (XtWidgetToApplicationContext (applicationShell));
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.