/*
 * CDE - Common Desktop Environment
 *
 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
 *
 * These libraries and programs are free software; you can
 * redistribute them and/or modify them under the terms of the GNU
 * Lesser General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * These libraries and programs are distributed in the hope that
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with these libraries and programs; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301 USA
 */
/*                                                                      *
 * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
 * (c) Copyright 1993, 1994 International Business Machines Corp.       *
 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
 * (c) Copyright 1993, 1994 Novell, Inc.                                *
 */

#ifdef sun
#include <dlfcn.h>
#endif /* sun */
#include "TermHeader.h"
#include "TermPrim.h"
#include "TermPrimDebug.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h> 
#include <string.h>
#include <locale.h>
#include <ctype.h>
#include <signal.h>
#include <Xm/Form.h>
#include <Xm/TextF.h>
#include <Xm/PushBG.h>
#include <Xm/LabelG.h>
#include <Xm/Protocols.h>
#include <Xm/Display.h>
/*
 * This for the sleazy hack to get the window manager frame width/height
 */
#include <Xm/VendorSEP.h>
#define	DEBUG_INCLUDES	/*DKS*/
#ifdef	DEBUG_INCLUDES
#include "TermPrimBufferP.h"
#include "TermPrimParserP.h"
#include "TermPrimPendingTextP.h"
#include "TermPrimSelectP.h"
#include "TermPrimP.h"
#include "TermPrimRenderP.h"
#include "TermPrimLineDrawP.h"
#include "TermPrimLineFontP.h"
#include "TermPrimSetUtmp.h"
#include "TermBufferP.h"
#include "TermP.h"
#include "TermParseTableP.h"
#include "TermFunction.h"
/* #include "TermFunctionKeyP.h" */
#include "TermViewP.h"
#endif	/* DEBUG_INCLUDES */
#include "TermPrim.h"
#include "TermView.h"
#include "TermViewMenu.h"
#include "DtTermMain.h"
#include "DtTermSyntax.h"
#ifdef	TERMINAL_SERVER
#include "DtTermServer.h"
#endif	/* TERMINAL_SERVER */
#include "TermPrimWMProtocols.h"
#include "TermPrimMessageCatI.h"
#ifdef	LOG_USAGE
#include "DtTermLogit.h"
#endif	/* LOG_USAGE */
#ifdef  HPVUE
#include <Xv/Session.h>
#include <Xv/EnvControl.h>
#define DtSessionSavePath 	XvSessionSavePath 
#define DtSessionRestorePath 	XvSessionRestorePath 
#define DtWsmGetWorkspacesOccupied XvGetWorkspacePresence
#define DtWsmSetWorkspacesOccupied XvSetWorkspaceHints
#else   /*  HPVUE */
#include <Dt/Dt.h>
#include <Dt/Wsm.h>
#include <Dt/EnvControlP.h>
#include <Dt/Session.h>
#endif  /* HPVUE */ 

/* From Xm/BaseClassI.h */
extern XmWidgetExtData _XmGetWidgetExtData( 
                        Widget widget,
#if NeedWidePrototypes
                        unsigned int extType) ;
#else
                        unsigned char extType) ;
#endif /* NeedWidePrototypes */

/* extern forward declarations */
void _DtTermViewMenuToggleMenuBar(Widget w);
void _DtTermPrimPtyCleanup(void);
void _DtTermPrimLogFileCleanup(void);
void _XmVirtKeysInitialize(Widget widget);
int FinishToolTalkInit(Widget topLevel);
#if defined(SUN_TERMINAL_SERVER)
Boolean ServerStartSession(Widget topLevel, int argc, char **argv,
                           Boolean loginShell, char **commandToExec);
#endif

#ifdef SUN_TERMINAL_SERVER
Boolean
#else
static void
#endif /* SUN_TERMINAL_SERVER */
CreateInstance(Widget topLevelWidget, char *name, Arg *arglist,
               int argcnt, Boolean enableCloneCallback);


/* forward declarations... */
static void activateCallback(
    Widget		  w,
    XtPointer		  client_data,
    XtPointer		  call_data
);

static void ToggleMenuBar(
    Widget		  w,
    XtPointer		  client_data,
    XtPointer		  call_data
);

static void SaveSessionCB(
	Widget w,			
	caddr_t client_data,	
	caddr_t call_data );
static Boolean RestoreSession(
	Widget topDog,
	Arg *arglist,
	int i);
static void SaveTerm(
        DtTermViewWidget dtvw,
        int cloneNum,
        int fd);
static void RestoreTerm(
	Widget shellWidget,
        DtTermViewWidget dtvw,
	int termNum,
        XrmDatabase db);
static void SetWorkSpaceHints(
        Widget shell,
        char *workspaces );

static void TestProbeHandler(
 	Widget	w,
	XtPointer	client_data,
	XEvent		*event,
	Boolean		*ctd);
static void RegisterTestProbe(
    Widget                topLevel,
    DtTermViewWidget      tw);

static char defaultIgnoredKeysyms[] = "\
<Key>F1\n\
<Key>F2\n\
<Key>F3\n\
<Key>F4\n\
<Key>F5\n\
<Key>F6\n\
<Key>F7\n\
<Key>F8\n\
<Key>F9\n\
<Key>F10\n\
<Key>F11\n\
<Key>F12\
";

typedef struct _termattrs {
        char    *debugString;
        char    *ignoredKeysyms;
        char    *session;
        Boolean  loginShell;
#ifdef TERMINAL_SERVER
        Boolean  block;
        Boolean  exitOnLastClose;
        Boolean  server;
        char    *serverId;
        Boolean  standAlone;
        int      PingInterval;
#endif
#ifdef SUN_TERMINAL_SERVER
       Boolean server;
#endif   
        char *title;
        char *icon_name;
        char *dtterm_name;
} TERMATTRS;

#ifdef TERMINAL_SERVER
static TERMATTRS attrs = { NULL, defaultIgnoredKeysyms, NULL, False,
                           TRUE, False, False, NULL, False, 5, NULL, NULL, NULL};
#elif SUN_TERMINAL_SERVER
static TERMATTRS attrs = { NULL, defaultIgnoredKeysyms, NULL, False, False, NULL, NULL, NULL};
#else
static TERMATTRS attrs = { NULL, defaultIgnoredKeysyms, NULL, False, NULL, NULL, NULL };
#endif

static Atom xa_MOTIF_WM_MESSAGES = None;
static Atom xa_DTTERM_TOGGLE_MENUBAR = None;
static Atom xa_DTTERM_TEST_PROBE_IDS = None;
static Atom xa_DTTERM_REMOTE_PROBE_REQUEST = None;
static Atom xa_WM_SAVE_YOURSELF;
static XtAppContext appContext;
static Widget topLevel;
static Widget topShell;
static char *title = NULL;
static DtTermViewWidget *instance_list = NULL;
static Boolean RestoringTerms = False;
static int  savedArgc = 0;
static char	**savedArgv = NULL;

#ifdef SUN_TERMINAL_SERVER
int InstanceCount = 0;
#else
#ifndef TERMINAL_SERVER
static int InstanceCount = 0;
#endif  /* TERMINAL_SERVER */
#endif /* SUN_TERMINAL_SERVER */

static const char _true[] = "true";
static const char _false[] = "false";

/* command line options...
 */
static XrmOptionDescRec optionDescList[] = {
/* special (not end user) options...
 */
{"-~",             "*debugLevel",       XrmoptionSepArg, (XtPointer) NULL},
{"-debugLevel",    "*debugLevel",       XrmoptionSepArg, (XtPointer) NULL},
{"-session",       "*session",		XrmoptionSepArg, (XtPointer) NULL},

#ifdef	TERMINAL_SERVER
/* server options...
 */
{"-noBlocking",    "*blocking",		XrmoptionNoArg,  (XtPointer) _false},
{"-server",        "*server",		XrmoptionNoArg,  (XtPointer) _true},
{"-serverId",      "*serverId",		XrmoptionSepArg, (XtPointer) NULL},
#endif	/* TERMINAL_SERVER */
#ifdef	SUN_TERMINAL_SERVER
{"-dtserver",      "*server",		XrmoptionNoArg,  (XtPointer) _true},
{"-sdtserver",     "*server",	        XrmoptionNoArg,  (XtPointer) _true},
#endif	/* SUN_TERMINAL_SERVER */

/* terminal emulation options...
 */
{"-132",           "*c132",		XrmoptionNoArg,  (XtPointer) _true},
{"+132",           "*c132",		XrmoptionNoArg,  (XtPointer) _false},
{"-aw",            "*autoWrap",		XrmoptionNoArg,  (XtPointer) _true},
{"+aw",            "*autoWrap",		XrmoptionNoArg,  (XtPointer) _false},
{"-bs",            "*backgroundIsSelect",
					XrmoptionNoArg,  (XtPointer) _true},
{"+bs",            "*backgroundIsSelect",
					XrmoptionNoArg,  (XtPointer) _false},
{"-C",             "*consoleMode",	XrmoptionNoArg,  (XtPointer) _true},
{"-cc",            "*charClass",	XrmoptionSepArg, (XtPointer) NULL},
{"-cu",            "*curses",           XrmoptionNoArg,  (XtPointer) _true},
{"+cu",            "*curses",           XrmoptionNoArg,  (XtPointer) _false},
{"-e",             NULL,		XrmoptionSkipLine,
							 (XtPointer) NULL},
{"-fb",            "*userBoldFont",	XrmoptionSepArg, (XtPointer) NULL},
{"-fn",            "*userFont",		XrmoptionSepArg, (XtPointer) NULL},
{"+iconic",        ".iconic",           XrmoptionNoArg,  (XtPointer) _false},
{"-j",             "*jumpScroll",	XrmoptionNoArg,  (XtPointer) _true},
{"+j",             "*jumpScroll",       XrmoptionNoArg,  (XtPointer) _false},
{"-kshMode",       "*kshMode",		XrmoptionNoArg,  (XtPointer) _true},
{"+kshMode",       "*kshMode",		XrmoptionNoArg,  (XtPointer) _false},
{"-l",             "*logging",		XrmoptionNoArg,  (XtPointer) _true},
{"+l",             "*logging",		XrmoptionNoArg,  (XtPointer) _false},
{"-lf",            "*logFile",		XrmoptionSepArg, (XtPointer) NULL},
{"-ls",            "*loginShell",	XrmoptionNoArg,  (XtPointer) _true},
{"+ls",            "*loginShell",	XrmoptionNoArg,  (XtPointer) _false},
{"-map",           "*mapOnOutput",	XrmoptionNoArg,  (XtPointer) _true},
{"+map",           "*mapOnOutput",	XrmoptionNoArg,  (XtPointer) _false},
{"-mb",            "*marginBell",	XrmoptionNoArg,  (XtPointer) _true},
{"+mb",            "*marginBell",	XrmoptionNoArg,  (XtPointer) _false},
{"-ms",            "*pointerColor",	XrmoptionSepArg, (XtPointer) NULL},
{"-n",  	   "*iconName",		XrmoptionSepArg, (XtPointer) NULL},
{"-nb",            "*nMarginBell",	XrmoptionSepArg, (XtPointer) NULL},
{"-rw",            "*reverseWrap",	XrmoptionNoArg,  (XtPointer) _true},
{"+rw",            "*reverseWrap",	XrmoptionNoArg,  (XtPointer) _false},
{"-sb",            "*scrollBar",        XrmoptionNoArg,  (XtPointer) _true},
{"+sb",            "*scrollBar",        XrmoptionNoArg,  (XtPointer) _false},
{"-sf",            "*sunFunctionKeys",  XrmoptionNoArg,  (XtPointer) _true},
{"+sf",            "*sunFunctionKeys",  XrmoptionNoArg,  (XtPointer) _false},
{"-si",            "*scrollTtyOutput",  XrmoptionNoArg,  (XtPointer) _true},
{"+si",            "*scrollTtyOutput",  XrmoptionNoArg,  (XtPointer) _false},
{"-sk",            "*scrollKey",        XrmoptionNoArg,  (XtPointer) _true},
{"+sk",            "*scrollKey",        XrmoptionNoArg,  (XtPointer) _false},
{"-sl",            "*saveLines",	XrmoptionSepArg, (XtPointer) NULL},
{"-ti",            "*termId",		XrmoptionSepArg, (XtPointer) NULL},
{"-tm",            "*ttyModes",		XrmoptionSepArg, (XtPointer) NULL},
{"-tn",            "*termName",		XrmoptionSepArg, (XtPointer) NULL},
{"-standAlone",    "*standAlone",	XrmoptionNoArg,	 (XtPointer) _true},
{"-vb",            "*visualBell",	XrmoptionNoArg,  (XtPointer) _true},
{"+vb",            "*visualBell",	XrmoptionNoArg,  (XtPointer) _false},
/* legacy options that are ignored...
 */
{"-ah",            NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+ah",            NULL,		XrmoptionNoArg,  (XtPointer) _false},
{"-b",             NULL,		XrmoptionSepArg, (XtPointer) NULL},
{"-cb",            NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+cb",            NULL,		XrmoptionNoArg,  (XtPointer) _false},
{"-cn",            NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+cn",            NULL,		XrmoptionNoArg,  (XtPointer) _false},
{"-cr",            NULL,		XrmoptionSepArg, (XtPointer) NULL},
{"-s",             NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+s",             NULL,		XrmoptionNoArg,  (XtPointer) _false},
{"-t",             NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+t",             NULL,		XrmoptionNoArg,  (XtPointer) _false},
{"-ut",            NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+ut",            NULL,		XrmoptionNoArg,  (XtPointer) _false},
{"-wf",            NULL,		XrmoptionNoArg,  (XtPointer) _true},
{"+wf",            NULL,		XrmoptionNoArg,  (XtPointer) _false},
};

/* application specific resources...
 */
static XtResource applicationResources[] = {
    {"debugLevel", "DebugLevel", XtRString, sizeof(char *),
	    XtOffsetOf(TERMATTRS, debugString), XtRImmediate, NULL},
    {"ignoredKeysyms", "IgnoredKeysyms", XtRString, sizeof(char *),
	    XtOffsetOf(TERMATTRS, ignoredKeysyms), XtRImmediate, NULL},
    {"loginShell", "LoginShell", XtRBoolean, sizeof(Boolean),
	    XtOffsetOf(TERMATTRS, loginShell), XtRString, "false"},
    {"session", "Session", XtRString, sizeof(char *),
	    XtOffsetOf(TERMATTRS, session), XtRString, NULL},
#ifdef	TERMINAL_SERVER
    {"blocking", "Blocking", XtRBoolean, sizeof(Boolean),
	    XtOffsetOf(TERMATTRS, block), XtRString, "true"},
    {"exitOnLastClose", "ExitOnLastClose", XtRBoolean, sizeof(Boolean),
	    XtOffsetOf(TERMATTRS, exitOnLastClose), XtRString, "false"},
    {"server", "Server", XtRBoolean, sizeof(Boolean),
	    XtOffsetOf(TERMATTRS, server), XtRString, "false"},
    {"serverId", "ServerId", XtRString, sizeof(char *),
	    XtOffsetOf(TERMATTRS, serverId), XtRImmediate, NULL},
    {"standAlone", "StandAlone", XtRBoolean, sizeof(Boolean),
	    XtOffsetOf(TERMATTRS, standAlone), XtRString, "false"},
    {"pingInterval", "PingInterval", XtRInt, sizeof(int),
	    XtOffsetOf(TERMATTRS, PingInterval), XtRString, "5"},
#endif	/* TERMINAL_SERVER */
#ifdef	SUN_TERMINAL_SERVER
    {"server", "Server", XtRBoolean, sizeof(Boolean),
	    XtOffsetOf(TERMATTRS, server), XtRString, "false"},
#endif	/* SUN_TERMINAL_SERVER */
    {XtNtitle, XtCTitle, XtRString, sizeof(char *),
	XtOffsetOf(TERMATTRS, title), XtRString, (caddr_t) NULL},
    {XtNiconName, XtCIconName, XtRString, sizeof(char *),
	XtOffsetOf(TERMATTRS, icon_name), XtRString, (caddr_t) NULL},
    {"name", "Name", XtRString, sizeof(char *),
	XtOffsetOf(TERMATTRS, dtterm_name), XtRString, (caddr_t) NULL},
};

extern String fallbackResources[];

#ifdef sun
void
sunSetupIA(Widget w)
{
    int	i, major_op, first_event, first_err;
    int	*pids;
    void 	(*IAptr)()=(void (*)())NULL;
    DtTermPrimitiveWidget tw;

    if ((IAptr = (void (*)())dlsym(RTLD_NEXT, "XSolarisIASetProcessInfo"))!=NULL) {
        pids = (int *)malloc(sizeof(int) * (InstanceCount + 1));
        pids[0] = getpid();
        for (i = 0; i < InstanceCount; i++) {
	    tw = (DtTermPrimitiveWidget)instance_list[i]->termview.term;
            pids[i + 1] = tw->term.subprocessPid;
        }
        if (XQueryExtension(XtDisplay(w), "SolarisIA",
		        &major_op, &first_event, &first_err))
            (*IAptr)(XtDisplay(w),pids,
	         0x1,InstanceCount + 1);
        free(pids);
    }
}
#endif /* sun */

#ifdef	DELAY_DESTROY
static void
DestroyTree(XtPointer client_data, XtIntervalId *id)
{
    (void) XtDestroyWidget((Widget) client_data);
}
#endif	/* DELAY_DESTROY */

/*ARGSUSED*/
static void
DestroyDtTerm(Widget w, XtPointer client_data, XtPointer call_data)
{
    /* destroy the whole interface... */
    (void) XtDestroyWidget((Widget) client_data);
}

/*ARGSUSED*/
static void
ExitTimeout(XtPointer client_data, XtIntervalId *id)
{
    if (title) {
      XtFree(title);
    }
    (void) exit(0);
}

/*ARGSUSED*/
static void
DecrementInstanceCountAndExit(Widget w, XtPointer client_data,
	XtPointer call_data)
{
    DtTermViewWidget *new_instance_list;
    int i,j;
    
/****************
 *
 * First, update the instance list cache by "deleting" the current instance
 *
 ****************/
    InstanceCount--;
    if (InstanceCount > 0)
    {
        new_instance_list = (DtTermViewWidget *)XtMalloc(sizeof(DtTermViewWidget) * InstanceCount);
	for (j = 0,i = 0; i < (InstanceCount+1); i++)
	    if (instance_list[i] != (DtTermViewWidget )w)
	    {
		new_instance_list[j] = instance_list[i];
		j++;
	    }
        XtFree((char *)instance_list);
	instance_list = new_instance_list;
    }
    else 
        XtFree((char *)instance_list);
		
    /* check off this instance... */
#ifdef	TERMINAL_SERVER
    if (attrs.standAlone || !attrs.serverId) {
#endif	/* TERMINAL_SERVER */
	if (InstanceCount <= 0) {
	    /* use a timeout so that the toolkit can finish killing off
	     * this widget...
	     */
	    (void) XtAppAddTimeOut(XtWidgetToApplicationContext(w), 0,
		    ExitTimeout, (XtPointer) 0);
	}
#ifdef	TERMINAL_SERVER
    } else {
	ServerInstanceTerminated((Widget) client_data);
    }
#endif	/* TERMINAL_SERVER */
}

/***************************************************************************
 *									   *
 * RegisterTestProbe - shoves a property on the root window that says	   *
 * we're ready to be tested, and sets up the event handler for the client  *
 * messages.								   *
 *									   *
 ***************************************************************************/
static void RegisterTestProbe(
    Widget		  topLevel,
    DtTermViewWidget	  tw
)
{
    Window win = XtWindow(topLevel);

    if (xa_DTTERM_TEST_PROBE_IDS == None) 
    {
	xa_DTTERM_TEST_PROBE_IDS = XInternAtom(XtDisplay(topLevel),
		"_DTTERM_TEST_PROBE_IDS", False);
    }
    if (xa_DTTERM_REMOTE_PROBE_REQUEST == None) 
    {
	xa_DTTERM_REMOTE_PROBE_REQUEST = XInternAtom(XtDisplay(topLevel),
		"_DTTERM_REMOTE_PROBE_REQUEST", False);
    }
    
    XChangeProperty(XtDisplay(topLevel), RootWindowOfScreen(XtScreen(topLevel)),
                    xa_DTTERM_TEST_PROBE_IDS, xa_DTTERM_TEST_PROBE_IDS,
		    32, PropModeReplace, (unsigned char *)&win, 1);
    XtAddEventHandler(topLevel, NoEventMask , True, (XtEventHandler )TestProbeHandler, 
                      (XtPointer )tw);
}

#define ONE_BYTE 0
#define TWO_BYTE 1
#define FOUR_BYTE 2
#define FOUR_BYTE_PTR 3
#define GET_USER_KEY_LOCK 4
#define GET_AUTO_LINE_FEED 5
#define GET_CURSOR_VISIBLE 6
#define	GET_SCROLLBAR_WINDOW 7
/***************************************************************************
 *									   *
 * TestProbeHandler - handle the client message for test probes		   *
 *									   *
 ***************************************************************************/
static void TestProbeHandler(
 	Widget	w,
	XtPointer	client_data,
	XEvent		*event,
	Boolean		*ctd)
{
    XClientMessageEvent *cm = (XClientMessageEvent *)event;
    DtTermViewWidget tw = (DtTermViewWidget )client_data;
    Window win;
    Atom   prop_name, actual_type;
    int	   prop_type;		/* THIS WILL BREAK ON A 16-BIT INT SYSTEM */
    int    actual_format;
    long   offset, length;
    unsigned long nitems, bytes_left;
    unsigned char *data;
    typedef union {
	char c;
	unsigned char uc;
	int i;
	short s;
	char *cp;
    } alltype;

    alltype fourbyte;
    alltype twobyte;
    alltype onebyte;
    unsigned char  *reply;
    Arg   al[5];
    
    *ctd = True;
    if (cm->send_event == False) return;
    if (cm->message_type != xa_DTTERM_REMOTE_PROBE_REQUEST) return;
    
    reply = (unsigned char*) malloc(sizeof(unsigned char) * 1024);

/****************
 *
 * If it's a xa_DTTERM_REMOTE_PROBE_REQUEST, then the data is three 32-bit
 * quantities: 0 is the window ID, 1 is the property atom to get off the
 * window, and 2 is the number of bytes required to getvalues the requested 
 *  data.
 *
 ****************/

    *ctd = False;
    win = cm->data.l[0];
    prop_name = cm->data.l[1];	
    prop_type = cm->data.l[2];
    offset = 0;
    length = 1000L;
   	
    if (XGetWindowProperty(XtDisplay(w), win, prop_name, offset, length,
    			   False, AnyPropertyType, &actual_type,&actual_format,
			   &nitems, &bytes_left, &data) == Success)
    {
        switch(prop_type) 
	{
            case GET_CURSOR_VISIBLE:
		sprintf((char *)reply,"%d", (int )_DtTermPrimGetCursorVisible(tw->termview.term));
		break;
    
            case GET_USER_KEY_LOCK:
		sprintf((char *)reply,"%d", (int )_DtTermGetUserKeyLock(tw->termview.term));
		break;

            case GET_AUTO_LINE_FEED:
		sprintf((char *)reply,"%d", (int )_DtTermGetAutoLineFeed(tw->termview.term));
		break;

	    case GET_SCROLLBAR_WINDOW:
		sprintf((char *)reply, "0x%lx", tw->termview.scrollBar.widget ?
			XtWindow(tw->termview.scrollBar.widget) : 0);
		break;

	    case ONE_BYTE:
		XtSetArg(al[0], (XtPointer ) data,&onebyte);
	        if (!strcmp((char *)data, XmNmenuBar) ||
		    !strcmp((char *)data, DtNscrollBar))
		    XtGetValues((Widget)tw, al, 1);
		else
		    XtGetValues(tw->termview.term, al, 1);
		sprintf((char *)reply,"%d", onebyte.uc);
		break;

	    case TWO_BYTE:
		XtSetArg(al[0], (XtPointer ) data,&twobyte);
		XtGetValues(tw->termview.term, al, 1);
		sprintf((char *)reply,"%d", twobyte.s);
		break;
		
	    case FOUR_BYTE:
	    case FOUR_BYTE_PTR:
		XtSetArg(al[0], (XtPointer ) data,&fourbyte);
		XtGetValues(tw->termview.term, al, 1);
		if (prop_type == FOUR_BYTE_PTR)
		    if (fourbyte.cp) {
			sprintf((char *)reply,"%s", fourbyte.cp);
		    } else {
			sprintf((char *)reply,"%s", "<NULL>");
		    }
		else 
		    sprintf((char *)reply,"%d", fourbyte.i);
		break;
	     default:
	     	sprintf((char *)reply,"%s","ERROR");
	}
	     
	XChangeProperty(XtDisplay(w), win, prop_name, prop_name, 8,
	                PropModeReplace, reply, strlen((char *)reply));
	XSync(XtDisplay(w),False);
    }
    free(reply);
}

	
static void
AddMenubarToggle
(
    Widget		  topLevel,
    Widget		  termViewWidget
)
{
    Arg al[20];
    int ac;
    char *menu;
    char buffer[BUFSIZ];

    /* intern the necessary atoms... */
    if (xa_MOTIF_WM_MESSAGES == None) {
	/* get the atom value... */
	xa_MOTIF_WM_MESSAGES = XInternAtom(XtDisplay(topLevel),
		"_MOTIF_WM_MESSAGES", False);
    }
    if (xa_DTTERM_TOGGLE_MENUBAR == None) {
	/* get the atom value... */
	xa_DTTERM_TOGGLE_MENUBAR = XInternAtom(XtDisplay(topLevel),
		"_DTTERM_TOGGLE_MENUBAR", False);
    }

    /* add a menubar toggle to the mwm pulldown... */
    ac = 0;
    menu = GETMESSAGE(NL_SETN_Main,1,"\
	Sep             f.separator\n\
	Toggle\\ Menu\\ Bar  f.send_msg %d\
	");
    (void) sprintf(buffer, menu, xa_DTTERM_TOGGLE_MENUBAR);
    (void) XtSetArg(al[ac], XmNmwmMenu, buffer); ac++;
    (void) XtSetValues(topLevel, al, ac);

    /* add a protocoll handler for MOTIF_WM_MESSAGES... */
    if (xa_MOTIF_WM_MESSAGES != None) {
	(void) XmAddProtocols(topLevel, xa_MOTIF_WM_MESSAGES,
		&xa_DTTERM_TOGGLE_MENUBAR, 1);
	(void) XmAddProtocolCallback(topLevel, xa_MOTIF_WM_MESSAGES,
		xa_DTTERM_TOGGLE_MENUBAR,
		ToggleMenuBar, (XtPointer) termViewWidget);
    }
}

static void
CloneCallback(Widget wid, XtPointer client_data, XtPointer call_data)
{
    DtTermViewWidget w = (DtTermViewWidget) wid;
    DtTermViewCallbackStruct *termCB = (DtTermViewCallbackStruct *) call_data;

    Widget parent = XtParent((Widget) w);
    Widget shellWidget;
    Widget termWidget;
    Arg arglist[10];
    int i;
    /* duplicate the dtterm widget's parent widget...
     */
    if (XtIsShell(parent)) {
	int argc;
	String *argv;
	Boolean allowShellResize;
#ifdef	COPY_WHEN_CLONING
	String geometry;
	Dimension width;
	Dimension height;
#endif	/* COPY_WHEN_CLONING */
	char *topShellIconName;

	i = 0;
	if (XtIsApplicationShell(parent)) {
	    (void) XtSetArg(arglist[i], XmNargc, &argc); i++;
	    (void) XtSetArg(arglist[i], XmNargv, &argv); i++;
	}
#ifdef	COPY_WHEN_CLONING
	(void) XtSetArg(arglist[i], XmNgeometry, &geometry); i++;
	(void) XtSetArg(arglist[i], XmNwidth, &width); i++;
	(void) XtSetArg(arglist[i], XmNheight, &height); i++;
#endif	/* COPY_WHEN_CLONING */
	(void) XtSetArg(arglist[i], XmNallowShellResize, &allowShellResize);
		i++;
	(void) XtGetValues(parent, arglist, i);

	i = 0;
	if (XtIsApplicationShell(parent)) {
	    (void) XtSetArg(arglist[i], XmNargc, argc); i++;
	    (void) XtSetArg(arglist[i], XmNargv, argv); i++;
	}
#ifdef	COPY_WHEN_CLONING
	(void) XtSetArg(arglist[i], XmNgeometry, geometry); i++;
	(void) XtSetArg(arglist[i], XmNwidth, width); i++;
	(void) XtSetArg(arglist[i], XmNheight, height); i++;
#endif	/* COPY_WHEN_CLONING */
	(void) XtSetArg(arglist[i], XmNallowShellResize, allowShellResize); i++;
	/* Set the title (and icon name) for the clone (new) dtterm window 
	   the same as the initial title (and icon name) of the top level 
	   shell dtterm window 
	 */
	(void) XtSetArg(arglist[i], XmNtitle, attrs.title); i++;
	if (attrs.icon_name)
	    topShellIconName = attrs.icon_name;
	else if (attrs.dtterm_name)
	    topShellIconName = attrs.dtterm_name;
	else topShellIconName = attrs.title;
	(void) XtSetArg(arglist[i], XmNiconName, topShellIconName); i++;

	shellWidget = XtAppCreateShell((char *) 0, "Dtterm",
		XtClass(parent), XtDisplay((Widget) w), arglist, i);
    } else {
	i = 0;
	(void) XtSetArg(arglist[i], XmNallowShellResize, True); i++;
	shellWidget = XtAppCreateShell((char *) 0, "Dtterm",
		applicationShellWidgetClass, XtDisplay((Widget) w), arglist, i);
    }

#ifdef	COPY_WHEN_CLONING
    termWidget = DtCreateTermView(shellWidget, "dtTermView", termCB->arglist,
	    termCB->argcount);
#else	/* COPY_WHEN_CLONING */
    termWidget = DtCreateTermView(shellWidget, "dtTermView", termCB->arglist,
	    0);
#endif	/* COPY_WHEN_CLONING */

    /* add a menubar toggle to the mwm pulldown... */
    (void) AddMenubarToggle(shellWidget, termWidget);

    (void) InstanceCount++;
    (void) XtManageChild(termWidget);

    /* destroy the widget on child termination... */
    (void) XtAddCallback(termWidget, DtNsubprocessTerminationCallback,
	    DestroyDtTerm, (XtPointer) shellWidget);
    (void) XtAddCallback(termWidget, XmNdestroyCallback,
	    DecrementInstanceCountAndExit, (XtPointer) topLevel);
    (void) _DtTermPrimAddDeleteWindowCallback(shellWidget, DestroyDtTerm,
	    (XtPointer) shellWidget);
    (void) XtAddCallback(termWidget, DtNnewCallback,
	    CloneCallback, (XtPointer) 0);
    instance_list = (DtTermViewWidget *)XtRealloc((char *)instance_list,
         					(sizeof(DtTermViewWidget) * InstanceCount));
    instance_list[InstanceCount - 1] = (DtTermViewWidget )termWidget;

    (void) XtRealizeWidget(shellWidget);
    return;
}

static void
ToggleMenuBar
(
    Widget		  w,
    XtPointer		  client_data,
    XtPointer		  call_data
)
{
    XmAnyCallbackStruct	 *cb = (XmAnyCallbackStruct *) call_data;

    if (cb->event->xclient.message_type == xa_MOTIF_WM_MESSAGES) {
	/* can't use case here, since we are not switching on a pre-defined
	 * value...
	 */
	if (cb->event->xclient.data.l[0] == xa_DTTERM_TOGGLE_MENUBAR) {
	    (void) _DtTermViewMenuToggleMenuBar((Widget) client_data);
	}
    }
}
#ifdef SUN_TERMINAL_SERVER
Boolean
#else
static void
#endif /* SUN_TERMINAL_SERVER */
CreateInstance
(
    Widget		  topLevelWidget,
    char		 *name,
    Arg			 *arglist,
    int			  argcnt,
    Boolean		  enableCloneCallback
)
{
    Widget termViewWidget;

    /* bump our session count... */
#ifdef	LOG_USAGE
    (void) LogBumpSessionCount(1);
#endif	/* LOG_USAGE */

    termViewWidget = DtCreateTermView(topLevelWidget, name, arglist, argcnt);

    /* add a menubar toggle to the mwm pulldown... */
    (void) AddMenubarToggle(topLevelWidget, termViewWidget);

#ifdef	TERMINAL_SERVER
    if (attrs.standAlone || !attrs.serverId) {
#endif	/* TERMINAL_SERVER */
	(void) InstanceCount++;
#ifdef	TERMINAL_SERVER
    }
#endif	/* TERMINAL_SERVER */
    (void) XtManageChild(termViewWidget);
    /* destroy the widget on termination... */
    (void) XtAddCallback(termViewWidget, DtNsubprocessTerminationCallback,
	    DestroyDtTerm, (XtPointer) topLevelWidget);
    (void) XtAddCallback(termViewWidget, XmNdestroyCallback,
	    DecrementInstanceCountAndExit, (XtPointer) topLevelWidget);
    (void) _DtTermPrimAddDeleteWindowCallback(topLevelWidget, DestroyDtTerm,
	    (XtPointer) topLevelWidget);
    instance_list = (DtTermViewWidget * ) XtRealloc((char *)instance_list, (sizeof(DtTermViewWidget) * InstanceCount));
    instance_list[InstanceCount - 1] = (DtTermViewWidget )termViewWidget;
    if (enableCloneCallback)
	(void) XtAddCallback(termViewWidget, DtNnewCallback,
		CloneCallback, (XtPointer) 0);

#ifdef SUN_TERMINAL_SERVER
    return(True);
#endif
}

void
AtExitProc(void)
{
    static int i = 0;

    i++;
#ifdef	BBA
    _bA_dump();
#endif	/* BBA */
}

void
SignalHandler
(
    int			  sig
)
{
    DebugF('s', 10, fprintf(stderr, ">>SignalHandler() starting\n"));
    _DtTermPrimPtyCleanup();
#ifndef HAS_UTEMPTER_LIBRARY
    _DtTermPrimUtmpCleanup();
#endif
    _DtTermPrimLogFileCleanup();
    DebugF('s', 10, fprintf(stderr, ">>SignalHandler() finished\n"));
    (void) exit(0);
}

static int signalList[] = {
    SIGHUP,
    SIGINT,
    SIGQUIT,
    /* SIGILL, */
    /* SIGTRAP, */
    /* SIGABRT, */
    /* SIGIOT, */
    /* SIGEMT, */
    /* SIGFPE, */
    SIGKILL,
    /* SIGBUS, */
    /* SIGSEGV, */
    /* SIGSYS, */
    SIGPIPE,
    SIGALRM,
    SIGTERM,
    SIGUSR1,
    SIGUSR2,
    /* SIGVTALRM, */
    /* SIGPROF, */
    /* SIGLOST, */
};

static Boolean
GetBindingsProperty
(
    Display		 *display,
    String		  property,
    String		 *binding
)
{
    char		 *prop = (char *) 0;
    Atom		  actualType;
    int			  actualFormat;
    unsigned long	  numItems;
    unsigned long	  bytesAfter;

    (void) XGetWindowProperty(display,
	    RootWindow(display, 0),
	    XmInternAtom(display, property, FALSE),
	    0,
	    (long) 1000000,
	    FALSE,
	    XA_STRING,
	    &actualType,
	    &actualFormat,
	    &numItems,
	    &bytesAfter,
	    (unsigned char **) &prop);

    if ((actualType != XA_STRING) ||
	    (actualFormat != 8) ||
	    (numItems == 0)) {
	if (prop) {
	    XFree(prop);
	}
	return(False);
    } else {
	*binding = prop;
	return(True);
    }
}

#ifndef	XmNdefaultVirtualBindings
#define	XmNdefaultVirtualBindings	"defaultVirtualBindings"
#endif	/* XmNdefaultVirtualBindings */
static void
FixOSFBindings
(
    Display		 *display
)
{
    Widget		  w;
    Arg			  al[10];
    int			  ac;
    char		 *origDisplayBindings,*freeOrigBindings=NULL;
    char		 *newDisplayBindings;
    char		 *c1;
    char		 *c2;
    char		 *cHold;
    int			  i1;
    char		**ignoredKeysymList;
    int			  numIgnoredKeysyms;
    
    /* malloc a copy of the ignoredKeysym string... */
    if (attrs.ignoredKeysyms && *attrs.ignoredKeysyms) {
	c1 = XtMalloc(strlen(attrs.ignoredKeysyms) + 1);
	(void) strcpy(c1, attrs.ignoredKeysyms);
	attrs.ignoredKeysyms = c1;
    }

    /* count the number of keysyms in the list... */
    for (c1 = attrs.ignoredKeysyms, numIgnoredKeysyms = 0; c1 && *c1; ) {
	numIgnoredKeysyms++;
	c1 = strchr(c1, '\n');
	if (c1) {
	    (void) c1++;
	}
    }

    /* malloc space for the array... */
    ignoredKeysymList = (char **) XtMalloc((numIgnoredKeysyms + 1) *
	    sizeof(char *));

    /* build the list... */
    for (c1 = attrs.ignoredKeysyms, i1 = 0; i1 < numIgnoredKeysyms; i1++) {
	ignoredKeysymList[i1] = c1;
	c1 = strchr(c1, '\n');
	if (c1 && *c1) {
	    *c1++ = '\0';
	}
    }

    /* null terminate the list... */
    ignoredKeysymList[i1] = (char *) 0;


    w = XmGetXmDisplay(display);

    ac = 0;
    (void) XtSetArg(al[ac], XmNdefaultVirtualBindings, &origDisplayBindings);
	    ac++;
    (void) XtGetValues(w, al, ac);

    if (!origDisplayBindings) {
	GetBindingsProperty(display, "_MOTIF_BINDINGS", &origDisplayBindings);
        freeOrigBindings = origDisplayBindings ;
    }

    if (!origDisplayBindings) {
	GetBindingsProperty(display, "_MOTIF_DEFAULT_BINDINGS",
		&origDisplayBindings);
        freeOrigBindings = origDisplayBindings ;
    }

    if (!origDisplayBindings) {
        XtFree((char *)ignoredKeysymList);
	return;
    }

    DebugF('b', 10, fprintf(stderr,
	    "FixOSFBindings(): bindings: %s\n", origDisplayBindings));
    newDisplayBindings = XtMalloc(strlen(origDisplayBindings) + 1);
    c1 = origDisplayBindings;
    c2 = newDisplayBindings;
    while (*c1) {
	/* remember the current position in the new string... */
	cHold = c2;

	/* copy over everything up to the '\n' or null... */
	while (*c1 && (*c1 != '\n')) {
	    *c2++ = *c1++;
	}

	/* null terminate the string... */
	*c2 = '\0';

	/* run through the exclusion list and look for a match... */
	for (i1 = 0; i1 < numIgnoredKeysyms; i1++) {
	    DebugF('b', 10, fprintf(stderr, "!strcmp(\"%s\", \"%s\") = %d\n",
		    c2 - strlen(ignoredKeysymList[i1]),
		    ignoredKeysymList[i1],
		    !strcmp(c2 - strlen(ignoredKeysymList[i1]),
		    ignoredKeysymList[i1])));
	    if ((strlen(ignoredKeysymList[i1]) <= (size_t)(c2 - cHold)) &&
		    !strcmp(c2 - strlen(ignoredKeysymList[i1]),
		    ignoredKeysymList[i1])) {
		/* we hit a match... */
		DebugF('b', 10, fprintf(stderr, "match!\n"));
		break;
	    }
	}

	/* if we hit a match, back up the string... */
	if (i1 < numIgnoredKeysyms) {
	    DebugF('b', 10, fprintf(stderr, "dropping %s\n", cHold));
	    c2 = cHold;
	    /* skip over whitespace in the source... */
	    while (isspace(*c1)) {
		c1++;
	    }
	} else {
	    /* copy over whitespace in the source... */
	    DebugF('b', 10, fprintf(stderr, "keeping %s\n", cHold));
	    while (isspace(*c1)) {
		*c2++ = *c1++;
	    }
	    cHold = c2;
	}
    }

    /* null terminate the string... */
    *c2 = '\0';

    /* and set this new bindings string... */
    ac = 0;
    (void) XtSetArg(al[ac], XmNdefaultVirtualBindings, newDisplayBindings);
	    ac++;
    (void) XtSetValues(w, al, ac);

  /* changed from XtFree to free as it was allocated with malloc to avoid FMM */
    if (freeOrigBindings) free(origDisplayBindings);

    XtFree((char *)ignoredKeysymList);

    /* and finally, reparse the string... */
    _XmVirtKeysInitialize(w);
}

static void
removeWmCommandCallback
(
    Widget		  w,
    XtPointer		  clientData,
    XEvent		 *event,
    Boolean		 *cont
)
{
    static Atom		  xa_WM_STATE = None;
    Boolean		  firstTime = True;

    if (firstTime) {
	xa_WM_STATE = XInternAtom(XtDisplay(w), "WM_STATE", True);
	firstTime = False;
    }

    if (((XPropertyEvent *) event)->atom == xa_WM_STATE) {
	/* blow away the atom... */
	(void) XDeleteProperty(XtDisplay(w), XtWindow(w),
		XA_WM_COMMAND);

	/* we have done our job and don't need to be called again... */
	(void) XtRemoveEventHandler(w, (EventMask) XtAllEvents,
		True, removeWmCommandCallback, clientData);
    }
}

static char *
base_name(
     char *name
)
{
	char *cp;

	cp = strrchr(name, '/');
	return(cp ? cp + 1 : name);
}

int
main(int argc, char **argv)
{
    Arg			  arglist[20];
    int			  i;
    char		 *c;
    char		 *c2;
    char		 *saved_arg0;
    char		**commandToExecute = (char **) 0;
    int			  ptyMasterFd = -1;
    struct sigaction	  sa;
#ifdef SUN_TERMINAL_SERVER
    Boolean 		  iAmTheServer = False;
#endif /* SUN_TERMINAL_SERVER */
    
    (void) atexit(AtExitProc);

    if (c = getenv("dttermDebugFlags")) {
	(void) setDebugFlags(c);
    }
    if (isDebugSet('T')) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
	(void) timeStamp("starting");
    }

    if (c = getenv("dttermDelayFlags"))
    {
	if (NULL != c)
	{
	    int delay = atoi(c);
	    pid_t pid = getpid();
	    printf("dtterm (%d) sleeping for %d seconds\n", pid, delay);
	    sleep(delay);
	}
    }

    /* before we do anything, let's set up signal handlers to clean up
     * after ourself...
     */
    (void) sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    sa.sa_handler = SignalHandler;
    /* trap all signals that we want to clean up after... */
    for (i = 0; i < (sizeof(signalList) / sizeof(signalList[0])); i++) {
	(void) sigaction(signalList[i], &sa, (struct sigaction *) 0);
    }

    /* ignore SIGHUP... */
    sa.sa_handler = SIG_IGN;
    (void) sigaction(SIGHUP, &sa, (struct sigaction *) 0);

    /*
    ** set up the environment variables for this client...
    */
#if defined(HPVUE)
#if       (OSMINORVERSION > 01)
    VuEnvControl(VUE_ENV_SET);
#endif /* (OSMINORVERSION > 01) */
#else
    _DtEnvControl(DT_ENV_SET);
#endif   /* HPVUE */

    /* set up the I18N world... */
    (void) XtSetLanguageProc(NULL, NULL, NULL);

    if (isDebugSet('T')) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
	(void) timeStamp("XtSetLangProc() finished");
    }

    /* before we initialize Xt, let's save argv and argc... */
    savedArgc = argc;
    savedArgv = (char **) XtMalloc((argc + 1) * sizeof(char *));
    for (i = 0; i < argc; i++) {
	savedArgv[i] = XtMalloc(strlen(argv[i]) + 1);
	(void) strcpy(savedArgv[i], argv[i]);
#ifdef SUN_TERMINAL_SERVER
	if ((!strcmp(argv[i], "-sdtserver")) || (!strcmp(argv[i], "-dtserver")))
	    iAmTheServer = TRUE;
#endif /* SUN_TERMINAL_SERVER */
    }
    savedArgv[i] = (char *) 0;

#ifdef sun
    (void) setsid();
#endif /* sun */


    /* before we do anything with the toolkit, let's usurp the constraint
     * initialize proc for the XmManager widget class.  This will allow us
     * to prevent it from performing that awful
     * DoMagicBBCompatibilityStuff() on us that steals (among other things)
     * our return key.  Note that currently, this is all that the
     * XmManager widget does for widgets, but if it did more than we
     * would loose out on that.
     */
    /* initialize Xt and the X world... */
    (void) DtTermInitialize();

    i = 0;
    (void) XtSetArg(arglist[i], XmNallowShellResize, True); i++;

    topLevel = XtAppInitialize(&appContext,
	    "Dtterm",
	    optionDescList,
	    XtNumber(optionDescList),
	    &argc,
	    argv,
	    fallbackResources,
	    arglist,
	    i);

#ifdef SUN_TERMINAL_SERVER
    if (iAmTheServer) {
       (void) ServerStartSession(topLevel, savedArgc, savedArgv,
                attrs.loginShell,
                commandToExecute);
    } 
#endif /* SUN_TERMINAL_SERVER */

    /* get application specific resources... */
    i = 0;
    /* Need to specify base address of the resources. In our case, attrs */
    (void) XtGetApplicationResources(topLevel, (XtPointer)&attrs, 
				     applicationResources,
				     XtNumber(applicationResources), 
				     arglist, i);    

    /* set all the debug flags... */
    (void) setDebugFlags(attrs.debugString);
    
    (void) FixOSFBindings(XtDisplay(topLevel));

    /* Add the Save_yourself callback... */
    xa_WM_SAVE_YOURSELF = XInternAtom(XtDisplay(topLevel),
                                      "WM_SAVE_YOURSELF", False);
    XmAddWMProtocolCallback(topLevel, xa_WM_SAVE_YOURSELF,
                           (XtCallbackProc)SaveSessionCB, (XtPointer)NULL);
    
    i = 0;
    (void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
    (void) XtSetArg(arglist[i], XmNallowShellResize, True); i++;
    topShell = XtAppCreateShell((char *) 0, "Dtterm",
		applicationShellWidgetClass, XtDisplay(topLevel), arglist, i);

    if (attrs.session != NULL)
       RestoringTerms = TRUE;

    if (isDebugSet('T')) {
#ifdef	BBA
#pragma BBA_IGNORE
#endif	/*BBA*/
	(void) timeStamp("XtAppInitialize() finished");
    }

    for (i = 1; i < argc; i++) {
	if (argv[i][0] != '-') {
	    (void) Syntax(argv[0], argv[i]);
	    exit(1);
	}

	switch(argv[i][1]) {
	case 'S' :
	    /* slave mode...
	     */
	    /* skip past the '-S'... */
	    c = argv[i] + 2;
	    if (c2 = strchr(c, '.')) {
		/* skip past the '.'... */
		(void) c2++;
	    } else {
		/* skip past the first 2 characters since they are the
		 * name of the pty...
		 */
		c2 = c + 2;
	    }
	    /* use scanf instead of atoi since it won't change the value
	     * of ptyMasterFd if the string does not contain a valid
	     * number...
	     */
	    (void) sscanf(c2, "%d", &ptyMasterFd);
	    break;

	case 'e' :
	    /* command to exec...
	     */
	    (void) i++;
	    if (i < argc) {
		commandToExecute = &argv[i];
		i = argc;
	    }
	    break;
	case 'h' :
	case 'u' :
	    /* help/usage...
	     */
	    (void) Help(argv[0]);
	    exit(0);
	    break;

	default :
	    (void) Syntax(argv[0], argv[i]);
	    (void) exit(1);
	    break;
	}
    }

#ifdef	TERMINAL_SERVER
    if (attrs.standAlone || !attrs.serverId) {
#endif	/* TERMINAL_SERVER */
	/* log our startup... */
#ifdef	LOG_USAGE
	(void) LogStart(0, argc, argv);
#endif	/* LOG_USAGE */

	i = 0;
	if (commandToExecute) {	    
	    (void) XtSetArg(arglist[i], DtNsubprocessArgv, commandToExecute);
		    i++;
	}
        
        if (!RestoringTerms || !RestoreSession(topShell, arglist, i)) {

	    RestoringTerms = False;

	    if (ptyMasterFd >= 0) {
		/* set the workspace for the initial dtterm instance... */
		(void) XtSetArg(arglist[i], DtNtermDevice, ptyMasterFd); i++;
		(void) XtSetArg(arglist[i], DtNtermDeviceAllocate, False); i++;
		(void) XtSetArg(arglist[i], DtNsubprocessExec, False); i++;
		(void) CreateInstance(topShell, "dtTermView", arglist, i, False);
	    } 
	    else {
		(void) CreateInstance(topShell, "dtTermView", arglist, i, True);
	    }
	}

	/* realize the interface... */
	i = 0;
	(void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
	(void) XtSetValues(topLevel, arglist, i);
	(void) XtRealizeWidget(topLevel);

#ifdef SUN_TERMINAL_SERVER
	if (iAmTheServer)
	    FinishToolTalkInit(topLevel);
#endif /* SUN_TERMINAL_SERVER */

	/* Set title to the command to execute (if any) 
	 */
	if (commandToExecute && !attrs.title) {
	   attrs.title = base_name (commandToExecute[0]);
	}

	/* Else set title to default ("Terminal")
	 */
	if (!attrs.title) {	    
	    title = XtMalloc(strlen(GETMESSAGE(NL_SETN_Main, 3, "Terminal")) + 1);
	    (void) strcpy(title, GETMESSAGE(NL_SETN_Main, 3, "Terminal"));
	    attrs.title = title;
	}

	/* realize the interface... */
	i = 0;
    (void) XtSetArg(arglist[i], XmNtitle, attrs.title); i++;
	if ((!attrs.icon_name) && (!attrs.dtterm_name)) {
	  (void) XtSetArg(arglist[i], XmNiconName, attrs.title); i++;
	}
	(void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
	(void) XtSetArg(arglist[i], XmNgeometry, NULL); i++;
	(void) XtSetValues(topShell, arglist, i);
	(void) XtRealizeWidget(topShell);

        if (RestoringTerms != True) {
	    /* use the wm command to pass the -xrm resource to the wm... */
	    (void) XSetCommand(XtDisplay(topShell), XtWindow(topShell),
		    savedArgv, savedArgc);
	    /* add a callback to remove it after it has been seen... */
	    (void) XtAddEventHandler(topShell, (EventMask) PropertyChangeMask,
		    False, removeWmCommandCallback, (XtPointer) 0);
	}

        (void) XtSetArg(arglist[0], XmNmappedWhenManaged, True); 
        (void) XtSetValues(topShell, arglist, 1);
	XtMapWidget(topShell);
        RegisterTestProbe(topShell,instance_list[0]);
	
	if (ptyMasterFd >= 0) {
	    /* write out the window id... */
	    char buffer[BUFSIZ];

	    (void) sprintf(buffer, "%lx\n", XtWindow(topLevel));
	    (void) write(ptyMasterFd, buffer, strlen(buffer));
	}
#ifdef sun
	sunSetupIA(topLevel);
#endif /* sun */

#ifdef	TERMINAL_SERVER
    } else {
	if (ptyMasterFd >= 0) {
	    (void) fprintf(stderr,
		    GETMESSAGE(NL_SETN_Main,2, "%s: the -S option cannot be used with the -server or -serverid options\n"),
		    argv[0]);
	    (void) exit(1);
	}

	i = 0;
	(void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
	(void) XtSetValues(topLevel, arglist, i);
	(void) XtRealizeWidget(topLevel);

	(void) ServerStartSession(topLevel, savedArgc, savedArgv,
		attrs.server, attrs.serverId, attrs.exitOnLastClose, 
		attrs.block, attrs.loginShell,
		commandToExecute);
    }
#endif	/* TERMINAL_SERVER */

    /* and hand off to Xt... */
    (void) XtAppMainLoop(appContext);
}

/************************************************************************
 *
 *  SaveSessionCB 
 *
 ************************************************************************/

/* ARGSUSED */
static void 
SaveSessionCB(
        Widget w,			/* widget id */
        caddr_t client_data,		/* data from application  */
        caddr_t call_data )		/* data from widget class */
{
    char *longpath, *fileName;
    char bufr[1024];
    int fd;
    char *xa_CommandStr[1024];
    int i,j;
    
     if(!XtIsShell(w))
	w = XtParent(w);

    DtSessionSavePath(w, &longpath, &fileName);

    /*  Create the session file  */
    if ((fd = creat (longpath, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
    {
        return;
    }

    sprintf(bufr, "*dtterm.numClonedTerms: %d\n", InstanceCount);
    write (fd, bufr, strlen(bufr));

    for(i = 0; i < InstanceCount; i++)
        SaveTerm(instance_list[i], i, fd);

    sprintf(bufr,
          "*dtterm.sessionFileVersionId: dttermSessionFileVersion.1.0.0\n");
    write (fd, bufr, strlen(bufr));

    close(fd);

    i = 0;
    xa_CommandStr[i] = savedArgv[0]; i++;
    xa_CommandStr[i] =  "-session"; i++;
    xa_CommandStr[i] =  fileName; i++;
/****************
 *
 * Now restore the command line minus the old session parameter 
 *
 ****************/
    for (j = 1; j < savedArgc; j++)
    {
        if (strcmp(savedArgv[j], "-session") == 0)
	{
	    j++;
	    continue;
	}
        else
	{
	    xa_CommandStr[i] =  savedArgv[j];
	    i++;
	}
    }

    XSetCommand(XtDisplay(topLevel), 
		XtWindow(topLevel), xa_CommandStr, i);


    XtFree ((char *)fileName);
}

static void 
SaveTerm(
        DtTermViewWidget dtvw,
        int cloneNum,
        int fd)
{
    char *bufr = malloc(1024);
    Position x,y;
    Dimension width, height;
    Atom *pWsPresence;
    unsigned long numInfo;
    unsigned char	  charCursorStyle;
    int			  blinkRate;
    Boolean		  jumpScroll;
    Boolean		  marginBell;
    int			  nMarginBell;
    Boolean		  visualBell;
    Boolean		  reverseVideo;
    Boolean		  cursorMode;
    Boolean		  keypadMode;
    Boolean		  autoWrap;
    Boolean		  reverseWrap;
    Boolean		  c132;
    Boolean		  lockState;
    Boolean		  autoLineFeed;
    Boolean		  menuBar;
    Boolean		  scrollBar;
    short		  rows;
    short		  columns;
    char		 *cwd;
    static char		 *defaultCwd = (char *) 0;
    Arg			  al[30];
    int			  ac;
    char		  buffer[BUFSIZ];
    DtTermWidget dtw = (DtTermWidget )dtvw->termview.term;
    static Boolean	  firstTime = True;
    static Atom		  xa_WM_STATE = None;
    struct _wmStateStruct {
	CARD32		  state;
	Window		  icon;
    }			 *prop;
    Atom		  actualType;
    int			  actualFormat;
    unsigned long	  nItems;
    unsigned long	  bytesAfter;

    XmVendorShellExtObject vendorExt;
    XmWidgetExtData        extData;

    x = XtX(XtParent(dtvw));
    y = XtY(XtParent(dtvw));

    /*
     * Modify x & y to take into account window mgr frames
     * This is pretty bogus, but I don't know a better way to do it.
     */
    extData = _XmGetWidgetExtData(XtParent(dtvw), XmSHELL_EXTENSION);
    vendorExt = (XmVendorShellExtObject)extData->widget;
    x -= vendorExt->vendor.xOffset;
    y -= vendorExt->vendor.yOffset;
    width = XtWidth(XtParent(dtvw));
    height = XtHeight(XtParent(dtvw));

    sprintf(bufr, "*dtterm_%d.x: %d\n", cloneNum, x);
    write (fd, bufr, strlen(bufr));
    sprintf(bufr, "*dtterm_%d.y: %d\n", cloneNum, y);
    write (fd, bufr, strlen(bufr));
    sprintf(bufr, "*dtterm_%d.width: %d\n", cloneNum, width);
    write (fd, bufr, strlen(bufr));
    sprintf(bufr, "*dtterm_%d.height: %d\n", cloneNum, height);
    write (fd, bufr, strlen(bufr));

    /* Write out iconic state...
     */
    if (firstTime) {
	xa_WM_STATE = XInternAtom(XtDisplay(dtvw), "WM_STATE", True);
	firstTime = False;
    }
    if (xa_WM_STATE && (Success == XGetWindowProperty(
	    XtDisplay(dtvw),
	    XtWindow(XtParent(dtvw)),
	    xa_WM_STATE,
	    0L,
	    (sizeof(struct _wmStateStruct) + 3) / 4,
	    False,
	    AnyPropertyType,
	    &actualType,
	    &actualFormat,
	    &nItems,
	    &bytesAfter,
	    (unsigned char **) &prop))) {
	if (prop->state == IconicState) {
	    sprintf(bufr, "*dtterm_%d.iconify: %s\n", cloneNum, "True");
	} else {
	    sprintf(bufr, "*dtterm_%d.iconify: %s\n", cloneNum, "False");
	}
	write (fd, bufr, strlen(bufr));
    }
	
    if(DtWsmGetWorkspacesOccupied(XtDisplay(dtvw), 
				  XtWindow(XtParent(dtvw)), &pWsPresence,
				  &numInfo) == Success)
    {
	int i;
	sprintf(bufr, "*dtterm_%d.workspaceList: ", cloneNum);
	write (fd, bufr, strlen(bufr));
	for(i = 0; i < numInfo; i++)
	{
	    char *name =  XGetAtomName(XtDisplay(dtvw),
				       pWsPresence[i]);
	    sprintf(bufr, " %s", name);
	    write (fd, bufr, strlen(bufr));
	    XtFree(name);
	}
	sprintf(bufr, "\n");
	write (fd, bufr, strlen(bufr));
	XtFree((char *)pWsPresence);
    }

    sprintf(bufr, "*dtterm_%d.userFontListIndex: %d\n", cloneNum,
	    _DtTermViewGetUserFontListIndex((Widget )dtvw));
    write (fd, bufr, strlen(bufr));

    /* get the current widget values... */
    ac = 0;
    (void) XtSetArg(al[ac], DtNmenuBar, &menuBar);			ac++;
    (void) XtSetArg(al[ac], DtNscrollBar, &scrollBar);			ac++;
    (void) XtGetValues((Widget)dtvw, al, ac);
    ac = 0;
    (void) XtSetArg(al[ac], DtNrows, &rows);				ac++;
    (void) XtSetArg(al[ac], DtNcolumns, &columns);			ac++;
    (void) XtSetArg(al[ac], DtNblinkRate, &blinkRate);			ac++;
    (void) XtSetArg(al[ac], DtNcharCursorStyle, &charCursorStyle);	ac++;
    (void) XtSetArg(al[ac], DtNblinkRate, &blinkRate);			ac++;
    (void) XtSetArg(al[ac], DtNjumpScroll, &jumpScroll);		ac++;
    (void) XtSetArg(al[ac], DtNmarginBell, &marginBell);		ac++;
    (void) XtSetArg(al[ac], DtNnMarginBell, &nMarginBell);		ac++;
    (void) XtSetArg(al[ac], DtNvisualBell, &visualBell);		ac++;
    (void) XtSetArg(al[ac], DtNreverseVideo, &reverseVideo);		ac++;
    (void) XtSetArg(al[ac], DtNappCursorDefault, &cursorMode);		ac++;
    (void) XtSetArg(al[ac], DtNappKeypadDefault, &keypadMode);		ac++;
    (void) XtSetArg(al[ac], DtNautoWrap, &autoWrap);			ac++;
    (void) XtSetArg(al[ac], DtNreverseWrap, &reverseWrap);		ac++;
    (void) XtSetArg(al[ac], DtNc132, &c132);				ac++;
    (void) XtGetValues((Widget)dtw, al, ac);
    lockState = _DtTermGetUserKeyLock((Widget) dtw);
    autoLineFeed = _DtTermGetAutoLineFeed((Widget) dtw);

    /* get the current working directory if it was saved... */
    cwd = _DtTermGetCurrentWorkingDirectory((Widget) dtw);
    if (!cwd || !*cwd) {
	/* no saved cwd, use the one we were started from... */
	if (!defaultCwd) {
	    /* first time through, use getcwd() to get it... */
	    if (getcwd(buffer, sizeof(buffer))) {
		defaultCwd = XtMalloc(strlen(buffer) + 1);
		(void) strcpy(defaultCwd, buffer);
	    }
	}
	cwd = defaultCwd;
    }

    (void) sprintf(bufr, "*dtterm_%d*rows: %d\n", cloneNum, rows);
    (void) write(fd, bufr, strlen(bufr));
    (void) sprintf(bufr, "*dtterm_%d*columns: %d\n", cloneNum, columns);
    (void) write(fd, bufr, strlen(bufr));

    if(menuBar == False)
    {
	sprintf(bufr, "*dtterm_%d*menuBar: False\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(scrollBar == False)
    {
	sprintf(bufr, "*dtterm_%d*scrollBar: False\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if (_DtTermPrimGetCursorVisible((Widget )dtw))
    {
	if (charCursorStyle == DtTERM_CHAR_CURSOR_BAR)
   	    sprintf(bufr, "*dtterm_%d*charCursorStyle: CHARCURSOR_BAR\n", cloneNum);
	else
	    sprintf(bufr, "*dtterm_%d*charCursorStyle: CHARCURSOR_BOX\n", cloneNum);
    }
    else 
        sprintf(bufr, "*dtterm_%d*charCursorStyle: CHARCURSOR_INVISIBLE\n", cloneNum);
    write (fd, bufr, strlen(bufr));
    

    sprintf(bufr, "*dtterm_%d*blinkRate: %d\n", cloneNum,blinkRate);
    write (fd, bufr, strlen(bufr));

    if(jumpScroll == False)
    {
	sprintf(bufr, "*dtterm_%d*jumpScroll: False\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(marginBell == True)
    {
	sprintf(bufr, "*dtterm_%d*marginBell: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
	sprintf(bufr, "*dtterm_%d*nMarginBell: %d\n", cloneNum,nMarginBell);
        write (fd, bufr, strlen(bufr));
    }
    if(visualBell == True)
    {
	sprintf(bufr, "*dtterm_%d*visualBell: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(reverseVideo == True)
    {
	sprintf(bufr, "*dtterm_%d*reverseVideo: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(cursorMode == True)
    {
	sprintf(bufr, "*dtterm_%d*appCursorDefault: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(keypadMode == True)
    {
	sprintf(bufr, "*dtterm_%d*appKeypadDefault: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(autoWrap == False)
    {
	sprintf(bufr, "*dtterm_%d*autoWrap: False\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(reverseWrap == True)
    {
	sprintf(bufr, "*dtterm_%d*reverseWrap: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(c132 == True)
    {
	sprintf(bufr, "*dtterm_%d*c132: True\n", cloneNum);
        write (fd, bufr, strlen(bufr));
    }
    if(lockState == False)
	sprintf(bufr, "*dtterm_%d*userKeyLock: False\n", cloneNum);
    else
    	sprintf(bufr, "*dtterm_%d*userKeyLock: True\n", cloneNum);
    write (fd, bufr, strlen(bufr));
    if(autoLineFeed == False)
	sprintf(bufr, "*dtterm_%d*autoLineFeed: False\n", cloneNum);
    else
    	sprintf(bufr, "*dtterm_%d*autoLineFeed: True\n", cloneNum);
    write (fd, bufr, strlen(bufr));

    if (cwd && *cwd) {
	(void) sprintf(bufr, "*dtterm_%d*currentWorkingDirectory: %s\n",
		cloneNum, cwd);
	(void) write(fd, bufr, strlen(bufr));
    }
    free(bufr);
}

/***********************************************************************
 *
 * RestoreSession - returns True for success, False for failure...
 *
 ***********************************************************************/
static Boolean
RestoreSession(
            Widget topDog,
	    Arg *passedAl,
	    int passedAc)
{
    char *fileName = attrs.session;
    char *path;
    XrmDatabase db;
    char *tmpStr;
    XrmName xrm_name[5];
    XrmRepresentation rep_type;
    XrmValue value;
    Widget ShellWidget;
    int numToRestore, i, j;
    Arg			  al[30];
    int			  ac;
    
    if(DtSessionRestorePath(topLevel, &path, fileName) == False)
	path = fileName;

    /*  Open the file as a resource database */
    if ((db = XrmGetFileDatabase (path)) == NULL) 
    {
      /* if we got a bogus filename, bail out... */
      return(False);
    }

    xrm_name[0] = XrmStringToQuark ("dtterm");
    xrm_name[1] = XrmStringToQuark ("numClonedTerms");
    xrm_name[2] = 0;
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);

    /* if we got nothing back, bail out... */
    if (!value.addr || !*((char *) value.addr)) {
	return(False);
    }

    numToRestore = atoi((char *)value.addr);
    /* if we don't have at least one to restore, bail out... */
    if (numToRestore < 1) {
	return(False);
    }

    ShellWidget = topDog;
        
    for (j = 0; j < numToRestore; j++)
    {
	/* use the passed arglist as a starting point... */
	for (ac = 0; ac < passedAc; ac++) {
	    al[ac].value = passedAl[ac].value;
	    al[ac].name = passedAl[ac].name;
	}

	(void) CreateInstance(ShellWidget, "dtTermView", al, ac, True);
        RestoreTerm(ShellWidget, instance_list[j], j, db);
        (void) XtSetArg(al[0], XmNmappedWhenManaged, True); 
        (void) XtSetValues(ShellWidget, al, 1);
	/* mapping the shell widget here is redundant, and it turns out
	 * was responsible for CMVC7216: broken restoring of
	 * iconified instances in multiple workspaces...
	 */

        ac = 0;
	(void) XtSetArg(al[ac], XmNallowShellResize, True); ac++;
        (void) XtSetArg(al[ac], XmNmappedWhenManaged, True); ac++;
	ShellWidget = XtAppCreateShell((char *) 0, "Dtterm",
		    applicationShellWidgetClass, XtDisplay(topDog), al, ac);
    }
    /* success, return True... */
    return(True);
}

static void
RestoreTerm(
	Widget shellWidget,
        DtTermViewWidget dtvw,
	int termNum,
        XrmDatabase db)
{
    char buf[1024];
    XrmName xrm_name[5];
    XrmRepresentation rep_type;
    XrmValue value;
    DtTermWidget dtw = (DtTermWidget )dtvw->termview.term;
    Position x,y;
    Dimension width, height;
    char                  *ws_list;
    unsigned char	  charCursorStyle;
    int			  blinkRate;
    Boolean		  jumpScroll;
    Boolean		  marginBell;
    int			  nMarginBell;
    Boolean		  visualBell;
    Boolean		  reverseVideo;
    Boolean		  cursorMode;
    Boolean		  keypadMode;
    Boolean		  autoWrap;
    Boolean		  reverseWrap;
    Boolean		  c132;
    Boolean		  lockState;
    Boolean		  autoLineFeed;
    Boolean		  menuBar;
    Boolean		  scrollBar;
    char		 *cwd;
    Arg			  al[30];
    int			  ac;
    int			  rows = 0;
    int			  columns = 0;

    sprintf(buf, "dtterm_%d", termNum);
    xrm_name[0] = XrmStringToQuark(buf);
    xrm_name[2] = 0;

/* Pass 1, before widget realization...
 */

    /* get x position */
    xrm_name[1] = XrmStringToQuark ("x");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    x = atoi((char *)value.addr);

    /* get y position */
    xrm_name [1] = XrmStringToQuark ("y");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    y = atoi((char *)value.addr);

    /* get width */
    xrm_name [1] = XrmStringToQuark ("width");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    width = atoi((char *)value.addr);

    /* get height */
    xrm_name [1] = XrmStringToQuark ("height");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    height = atoi((char *)value.addr);

/****************
 *
 * First the shell resources...
 *
 ****************/
    ac = 0;
    (void) XtSetArg(al[ac], XmNx, x);			ac++;
    (void) XtSetArg(al[ac], XmNy, y);			ac++;
    (void) XtSetArg(al[ac], XmNwidth, width);			ac++;
    (void) XtSetArg(al[ac], XmNheight, height);			ac++;

    /* get iconify... */
    xrm_name[1] = XrmStringToQuark("iconify");
    if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) {
	if (!strcmp((char *)value.addr, "True")) {
	    (void) XtSetArg(al[ac], XmNinitialState, IconicState); ac++;
	} else {
	    (void) XtSetArg(al[ac], XmNinitialState, NormalState); ac++;
	}
    } else {
	(void) XtSetArg(al[ac], XmNinitialState, NormalState);
    }

    (void) XtSetValues(XtParent((Widget)dtvw), al, ac);

/****************
 *
 * Now the TermView resources...
 *
 ****************/
    ac = 0;
    xrm_name[1] = XrmStringToQuark ("rows");
    if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) {
	rows = atoi((char *)value.addr);
	(void) XtSetArg(al[ac], DtNrows, rows); ac++;
    }

    xrm_name[1] = XrmStringToQuark ("columns");
    if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) {
	columns = atoi((char *)value.addr);
	(void) XtSetArg(al[ac], DtNcolumns, columns); ac++;
    }

    xrm_name[1] = XrmStringToQuark ("menuBar");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], XmNmenuBar, False);	ac++;}
    xrm_name[1] = XrmStringToQuark ("scrollBar");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNscrollBar, False);	ac++;}

    xrm_name[1] = XrmStringToQuark ("userFontListIndex");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True) {
	_DtTermViewSetUserFontListIndex((Widget )dtvw, atol(value.addr));
    }

    (void) XtSetValues((Widget)dtvw, al, ac);

/****************
 *
 * And finally the termprim stuff...
 *
 ****************/
    ac = 0;
    if(rows > 0) {
	(void) XtSetArg(al[ac], DtNrows, rows); ac++;
    }

    if(columns > 0) {
	(void) XtSetArg(al[ac], DtNcolumns, columns); ac++;
    }

    xrm_name[1] = XrmStringToQuark ("charCursorStyle");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    if (!strcmp(value.addr, "CHARCURSOR_INVISIBLE"))
        _DtTermPrimSetCursorVisible((Widget )dtw, False);
    else  
    {
    	if (!strcmp(value.addr, "CHARCURSOR_BAR"))
              (void) XtSetArg(al[ac], DtNcharCursorStyle, DtTERM_CHAR_CURSOR_BAR);
        else 
              (void) XtSetArg(al[ac], DtNcharCursorStyle, DtTERM_CHAR_CURSOR_BOX);
        ac++;
    }
    
    xrm_name [1] = XrmStringToQuark ("blinkRate");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    blinkRate = atoi((char *)value.addr);
    (void) XtSetArg(al[ac], DtNblinkRate, blinkRate);			ac++;

    xrm_name[1] = XrmStringToQuark ("jumpScroll");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNjumpScroll, False);	ac++;}

    xrm_name[1] = XrmStringToQuark ("marginBell");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
    {
    	(void) XtSetArg(al[ac], DtNmarginBell, True);	ac++;
         xrm_name [1] = XrmStringToQuark ("nMarginBell");
         XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
         nMarginBell = atoi((char *)value.addr);
         (void) XtSetArg(al[ac], DtNnMarginBell, nMarginBell);ac++;
    }

    xrm_name[1] = XrmStringToQuark ("visualBell");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNvisualBell, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("reverseVideo");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNreverseVideo, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("appCursorDefault");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNappCursorDefault, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("appKeypadDefault");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNappKeypadDefault, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("autoWrap");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNautoWrap, False);	ac++;}

    xrm_name[1] = XrmStringToQuark ("reverseWrap");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNreverseWrap, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("c132");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNc132, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("reverseVideo");
    if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
        {(void) XtSetArg(al[ac], DtNreverseVideo, True);	ac++;}

    xrm_name[1] = XrmStringToQuark ("userKeyLock");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    if (!strcmp(value.addr, "True"))
         _DtTermSetUserKeyLock((Widget) dtw, True);
    else 
         _DtTermSetUserKeyLock((Widget) dtw, False);

    xrm_name[1] = XrmStringToQuark ("autoLineFeed");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    if (!strcmp(value.addr, "True"))
         _DtTermSetAutoLineFeed((Widget) dtw, True);
    else 
         _DtTermSetAutoLineFeed((Widget) dtw, False);

    (void) XtSetValues((Widget)dtw, al, ac);

    xrm_name[1] = XrmStringToQuark ("currentWorkingDirectory");
    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
    if (value.addr && *value.addr) {
	_DtTermSetCurrentWorkingDirectory((Widget) dtw, value.addr);
    }

    /* realize the interface...
     */
    (void) XtRealizeWidget(shellWidget);



/* Pass 2, after widget realization...
 */

    /* get workspace list */
    xrm_name[1] = XrmStringToQuark("workspaceList");
    XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value);
    SetWorkSpaceHints( XtParent((Widget)dtvw),(char *) value.addr);
}

static void
SetWorkSpaceHints
(
    Widget shell,
    char *workspaces
)
{
    char * ptr;
    Atom * workspace_atoms = NULL;
    int num_workspaces=0;
    Atom thisWsAtom;

    if (workspaces) {
	do {
	    ptr = strchr (workspaces, ' ');
	    if (ptr != NULL)
		*ptr = 0;
	    thisWsAtom = None;

	    /* if we haven't hit a match, try interning the atom... */
	    if (thisWsAtom == None) {
		thisWsAtom = XmInternAtom (XtDisplay(shell), workspaces, True);
	    }

	    if (thisWsAtom != None) {
		workspace_atoms = (Atom *) XtRealloc ((char *)workspace_atoms,
			sizeof (Atom) * (num_workspaces + 1));
		workspace_atoms[num_workspaces] = thisWsAtom;
		num_workspaces++;
	    }

	    if (ptr != NULL) {
		*ptr = ' ';
		workspaces = ptr + 1;
	    }
	} while (ptr != NULL);

	if (num_workspaces > 0) {
	    DtWsmSetWorkspacesOccupied(XtDisplay(shell), XtWindow (shell),
		    workspace_atoms, num_workspaces);
	}

	XtFree ((char *) workspace_atoms);
	workspace_atoms = NULL;
    }
}
