2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 #ifdef VERBOSE_REV_INFO
25 static char rcs_id[] = "$TOG: DtTermMain.c /main/19 1999/09/17 13:26:34 mgreess $";
26 #endif /* VERBOSE_REV_INFO */
30 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
31 * (c) Copyright 1993, 1994 International Business Machines Corp. *
32 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
33 * (c) Copyright 1993, 1994 Novell, Inc. *
39 #include "TermHeader.h"
40 #include "TermPrimDebug.h"
42 #include <sys/types.h>
50 #include <Xm/PushBG.h>
51 #include <Xm/LabelG.h>
52 #include <Xm/Protocols.h>
53 #include <Xm/Display.h>
55 * This for the sleazy hack to get the window manager frame width/height
57 #include <Xm/VendorSEP.h>
58 #define DEBUG_INCLUDES /*DKS*/
60 #include "TermPrimBufferP.h"
61 #include "TermPrimParserP.h"
62 #include "TermPrimPendingTextP.h"
63 #include "TermPrimSelectP.h"
64 #include "TermPrimP.h"
65 #include "TermPrimRenderP.h"
66 #include "TermPrimLineDrawP.h"
67 #include "TermPrimLineFontP.h"
68 #include "TermBufferP.h"
70 #include "TermParseTableP.h"
71 #include "TermFunction.h"
72 /* #include "TermFunctionKeyP.h" */
73 #include "TermViewP.h"
74 #endif /* DEBUG_INCLUDES */
77 #include "TermViewMenu.h"
78 #include "DtTermMain.h"
79 #include "DtTermSyntax.h"
80 #ifdef TERMINAL_SERVER
81 #include "DtTermServer.h"
82 #endif /* TERMINAL_SERVER */
83 #include "TermPrimWMProtocols.h"
84 #include "TermPrimMessageCatI.h"
86 #include "DtTermLogit.h"
87 #endif /* LOG_USAGE */
89 #include <Xv/Session.h>
90 #include <Xv/EnvControl.h>
91 #define DtSessionSavePath XvSessionSavePath
92 #define DtSessionRestorePath XvSessionRestorePath
93 #define DtWsmGetWorkspacesOccupied XvGetWorkspacePresence
94 #define DtWsmSetWorkspacesOccupied XvSetWorkspaceHints
98 #include <Dt/EnvControlP.h>
101 /* From Xm/BaseClassI.h */
102 extern XmWidgetExtData _XmGetWidgetExtData(
104 #if NeedWidePrototypes
105 unsigned int extType) ;
107 unsigned char extType) ;
108 #endif /* NeedWidePrototypes */
110 /* forward declarations... */
111 static void activateCallback(
113 XtPointer client_data,
117 static void ToggleMenuBar(
119 XtPointer client_data,
123 static void SaveSessionCB(
127 static Boolean RestoreSession(
131 static void SaveTerm(
132 DtTermViewWidget dtvw,
135 static void RestoreTerm(
137 DtTermViewWidget dtvw,
140 static void SetWorkSpaceHints(
144 static XtEventHandler TestProbeHandler(
146 XtPointer client_data,
149 static void RegisterTestProbe(
151 DtTermViewWidget tw);
153 static char defaultIgnoredKeysyms[] = "\
168 typedef struct _termattrs {
170 char *ignoredKeysyms;
173 #ifdef TERMINAL_SERVER
175 Boolean exitOnLastClose;
181 #ifdef SUN_TERMINAL_SERVER
189 #ifdef TERMINAL_SERVER
190 static TERMATTRS attrs = { NULL, defaultIgnoredKeysyms, NULL, False,
191 TRUE, False, False, NULL, False, 5, NULL, NULL, NULL};
192 #elif SUN_TERMINAL_SERVER
193 static TERMATTRS attrs = { NULL, defaultIgnoredKeysyms, NULL, False, False, NULL, NULL, NULL};
195 static TERMATTRS attrs = { NULL, defaultIgnoredKeysyms, NULL, False, NULL, NULL, NULL };
198 static Atom xa_MOTIF_WM_MESSAGES = None;
199 static Atom xa_DTTERM_TOGGLE_MENUBAR = None;
200 static Atom xa_DTTERM_TEST_PROBE_IDS = None;
201 static Atom xa_DTTERM_REMOTE_PROBE_REQUEST = None;
202 static Atom xa_WM_SAVE_YOURSELF;
203 static XtAppContext appContext;
204 static Widget topLevel;
205 static Widget topShell;
206 static char *title = NULL;
207 static DtTermViewWidget *instance_list = NULL;
208 static Boolean RestoringTerms = False;
209 static int savedArgc = 0;
210 static char **savedArgv = NULL;
212 #ifdef SUN_TERMINAL_SERVER
213 int InstanceCount = 0;
215 #ifndef TERMINAL_SERVER
216 static int InstanceCount = 0;
217 #endif /* TERMINAL_SERVER */
218 #endif /* SUN_TERMINAL_SERVER */
220 static const char _true[] = "true";
221 static const char _false[] = "false";
223 /* command line options...
225 static XrmOptionDescRec optionDescList[] = {
226 /* special (not end user) options...
228 {"-~", "*debugLevel", XrmoptionSepArg, (XtPointer) NULL},
229 {"-debugLevel", "*debugLevel", XrmoptionSepArg, (XtPointer) NULL},
230 {"-session", "*session", XrmoptionSepArg, (XtPointer) NULL},
232 #ifdef TERMINAL_SERVER
235 {"-noBlocking", "*blocking", XrmoptionNoArg, (XtPointer) _false},
236 {"-server", "*server", XrmoptionNoArg, (XtPointer) _true},
237 {"-serverId", "*serverId", XrmoptionSepArg, (XtPointer) NULL},
238 #endif /* TERMINAL_SERVER */
239 #ifdef SUN_TERMINAL_SERVER
240 {"-dtserver", "*server", XrmoptionNoArg, (XtPointer) _true},
241 {"-sdtserver", "*server", XrmoptionNoArg, (XtPointer) _true},
242 #endif /* SUN_TERMINAL_SERVER */
244 /* terminal emulation options...
246 {"-132", "*c132", XrmoptionNoArg, (XtPointer) _true},
247 {"+132", "*c132", XrmoptionNoArg, (XtPointer) _false},
248 {"-aw", "*autoWrap", XrmoptionNoArg, (XtPointer) _true},
249 {"+aw", "*autoWrap", XrmoptionNoArg, (XtPointer) _false},
250 {"-bs", "*backgroundIsSelect",
251 XrmoptionNoArg, (XtPointer) _true},
252 {"+bs", "*backgroundIsSelect",
253 XrmoptionNoArg, (XtPointer) _false},
254 {"-C", "*consoleMode", XrmoptionNoArg, (XtPointer) _true},
255 {"-cc", "*charClass", XrmoptionSepArg, (XtPointer) NULL},
256 {"-cu", "*curses", XrmoptionNoArg, (XtPointer) _true},
257 {"+cu", "*curses", XrmoptionNoArg, (XtPointer) _false},
258 {"-e", NULL, XrmoptionSkipLine,
260 {"-fb", "*userBoldFont", XrmoptionSepArg, (XtPointer) NULL},
261 {"-fn", "*userFont", XrmoptionSepArg, (XtPointer) NULL},
262 {"+iconic", ".iconic", XrmoptionNoArg, (XtPointer) _false},
263 {"-j", "*jumpScroll", XrmoptionNoArg, (XtPointer) _true},
264 {"+j", "*jumpScroll", XrmoptionNoArg, (XtPointer) _false},
265 {"-kshMode", "*kshMode", XrmoptionNoArg, (XtPointer) _true},
266 {"+kshMode", "*kshMode", XrmoptionNoArg, (XtPointer) _false},
267 {"-l", "*logging", XrmoptionNoArg, (XtPointer) _true},
268 {"+l", "*logging", XrmoptionNoArg, (XtPointer) _false},
269 {"-lf", "*logFile", XrmoptionSepArg, (XtPointer) NULL},
270 {"-ls", "*loginShell", XrmoptionNoArg, (XtPointer) _true},
271 {"+ls", "*loginShell", XrmoptionNoArg, (XtPointer) _false},
272 {"-map", "*mapOnOutput", XrmoptionNoArg, (XtPointer) _true},
273 {"+map", "*mapOnOutput", XrmoptionNoArg, (XtPointer) _false},
274 {"-mb", "*marginBell", XrmoptionNoArg, (XtPointer) _true},
275 {"+mb", "*marginBell", XrmoptionNoArg, (XtPointer) _false},
276 {"-ms", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
277 {"-n", "*iconName", XrmoptionSepArg, (XtPointer) NULL},
278 {"-nb", "*nMarginBell", XrmoptionSepArg, (XtPointer) NULL},
279 {"-rw", "*reverseWrap", XrmoptionNoArg, (XtPointer) _true},
280 {"+rw", "*reverseWrap", XrmoptionNoArg, (XtPointer) _false},
281 {"-sb", "*scrollBar", XrmoptionNoArg, (XtPointer) _true},
282 {"+sb", "*scrollBar", XrmoptionNoArg, (XtPointer) _false},
283 {"-sf", "*sunFunctionKeys", XrmoptionNoArg, (XtPointer) _true},
284 {"+sf", "*sunFunctionKeys", XrmoptionNoArg, (XtPointer) _false},
285 {"-si", "*scrollTtyOutput", XrmoptionNoArg, (XtPointer) _true},
286 {"+si", "*scrollTtyOutput", XrmoptionNoArg, (XtPointer) _false},
287 {"-sk", "*scrollKey", XrmoptionNoArg, (XtPointer) _true},
288 {"+sk", "*scrollKey", XrmoptionNoArg, (XtPointer) _false},
289 {"-sl", "*saveLines", XrmoptionSepArg, (XtPointer) NULL},
290 {"-ti", "*termId", XrmoptionSepArg, (XtPointer) NULL},
291 {"-tm", "*ttyModes", XrmoptionSepArg, (XtPointer) NULL},
292 {"-tn", "*termName", XrmoptionSepArg, (XtPointer) NULL},
293 {"-standAlone", "*standAlone", XrmoptionNoArg, (XtPointer) _true},
294 {"-vb", "*visualBell", XrmoptionNoArg, (XtPointer) _true},
295 {"+vb", "*visualBell", XrmoptionNoArg, (XtPointer) _false},
296 /* legacy options that are ignored...
298 {"-ah", NULL, XrmoptionNoArg, (XtPointer) _true},
299 {"+ah", NULL, XrmoptionNoArg, (XtPointer) _false},
300 {"-b", NULL, XrmoptionSepArg, (XtPointer) NULL},
301 {"-cb", NULL, XrmoptionNoArg, (XtPointer) _true},
302 {"+cb", NULL, XrmoptionNoArg, (XtPointer) _false},
303 {"-cn", NULL, XrmoptionNoArg, (XtPointer) _true},
304 {"+cn", NULL, XrmoptionNoArg, (XtPointer) _false},
305 {"-cr", NULL, XrmoptionSepArg, (XtPointer) NULL},
306 {"-s", NULL, XrmoptionNoArg, (XtPointer) _true},
307 {"+s", NULL, XrmoptionNoArg, (XtPointer) _false},
308 {"-t", NULL, XrmoptionNoArg, (XtPointer) _true},
309 {"+t", NULL, XrmoptionNoArg, (XtPointer) _false},
310 {"-ut", NULL, XrmoptionNoArg, (XtPointer) _true},
311 {"+ut", NULL, XrmoptionNoArg, (XtPointer) _false},
312 {"-wf", NULL, XrmoptionNoArg, (XtPointer) _true},
313 {"+wf", NULL, XrmoptionNoArg, (XtPointer) _false},
316 /* application specific resources...
318 static XtResource applicationResources[] = {
319 {"debugLevel", "DebugLevel", XtRString, sizeof(char *),
320 XtOffsetOf(TERMATTRS, debugString), XtRImmediate, NULL},
321 {"ignoredKeysyms", "IgnoredKeysyms", XtRString, sizeof(char *),
322 XtOffsetOf(TERMATTRS, ignoredKeysyms), XtRImmediate, NULL},
323 {"loginShell", "LoginShell", XtRBoolean, sizeof(Boolean),
324 XtOffsetOf(TERMATTRS, loginShell), XtRString, "false"},
325 {"session", "Session", XtRString, sizeof(char *),
326 XtOffsetOf(TERMATTRS, session), XtRString, NULL},
327 #ifdef TERMINAL_SERVER
328 {"blocking", "Blocking", XtRBoolean, sizeof(Boolean),
329 XtOffsetOf(TERMATTRS, block), XtRString, "true"},
330 {"exitOnLastClose", "ExitOnLastClose", XtRBoolean, sizeof(Boolean),
331 XtOffsetOf(TERMATTRS, exitOnLastClose), XtRString, "false"},
332 {"server", "Server", XtRBoolean, sizeof(Boolean),
333 XtOffsetOf(TERMATTRS, server), XtRString, "false"},
334 {"serverId", "ServerId", XtRString, sizeof(char *),
335 XtOffsetOf(TERMATTRS, serverId), XtRImmediate, NULL},
336 {"standAlone", "StandAlone", XtRBoolean, sizeof(Boolean),
337 XtOffsetOf(TERMATTRS, standAlone), XtRString, "false"},
338 {"pingInterval", "PingInterval", XtRInt, sizeof(int),
339 XtOffsetOf(TERMATTRS, PingInterval), XtRString, "5"},
340 #endif /* TERMINAL_SERVER */
341 #ifdef SUN_TERMINAL_SERVER
342 {"server", "Server", XtRBoolean, sizeof(Boolean),
343 XtOffsetOf(TERMATTRS, server), XtRString, "false"},
344 #endif /* SUN_TERMINAL_SERVER */
345 {XtNtitle, XtCTitle, XtRString, sizeof(char *),
346 XtOffsetOf(TERMATTRS, title), XtRString, (caddr_t) NULL},
347 {XtNiconName, XtCIconName, XtRString, sizeof(char *),
348 XtOffsetOf(TERMATTRS, icon_name), XtRString, (caddr_t) NULL},
349 {"name", "Name", XtRString, sizeof(char *),
350 XtOffsetOf(TERMATTRS, dtterm_name), XtRString, (caddr_t) NULL},
353 extern String fallbackResources[];
359 int i, major_op, first_event, first_err;
361 void (*IAptr)()=(void (*)())NULL;
362 DtTermPrimitiveWidget tw;
364 if ((IAptr = (void (*)())dlsym(RTLD_NEXT, "XSolarisIASetProcessInfo"))!=NULL) {
365 pids = (int *)malloc(sizeof(int) * (InstanceCount + 1));
367 for (i = 0; i < InstanceCount; i++) {
368 tw = (DtTermPrimitiveWidget)instance_list[i]->termview.term;
369 pids[i + 1] = tw->term.subprocessPid;
371 if (XQueryExtension(XtDisplay(w), "SolarisIA",
372 &major_op, &first_event, &first_err))
373 (*IAptr)(XtDisplay(w),pids,
374 0x1,InstanceCount + 1);
382 DestroyTree(XtPointer client_data, XtIntervalId *id)
384 (void) XtDestroyWidget((Widget) client_data);
386 #endif /* DELAY_DESTROY */
390 DestroyDtTerm(Widget w, XtPointer client_data, XtPointer call_data)
392 /* destroy the whole interface... */
393 (void) XtDestroyWidget((Widget) client_data);
398 ExitTimeout(XtPointer client_data, XtIntervalId *id)
408 DecrementInstanceCountAndExit(Widget w, XtPointer client_data,
411 DtTermViewWidget *new_instance_list;
416 * First, update the instance list cache by "deleting" the current instance
420 if (InstanceCount > 0)
422 new_instance_list = (DtTermViewWidget *)XtMalloc(sizeof(DtTermViewWidget *)*InstanceCount);
423 for (j = 0,i = 0; i < (InstanceCount+1); i++)
424 if (instance_list[i] != (DtTermViewWidget )w)
426 new_instance_list[j] = instance_list[i];
429 XtFree((char *)instance_list);
430 instance_list = new_instance_list;
433 XtFree((char *)instance_list);
435 /* check off this instance... */
436 #ifdef TERMINAL_SERVER
437 if (attrs.standAlone || !attrs.serverId) {
438 #endif /* TERMINAL_SERVER */
442 if (InstanceCount <= 0) {
443 /* use a timeout so that the toolkit can finish killing off
446 (void) XtAppAddTimeOut(XtWidgetToApplicationContext(w), 0,
447 ExitTimeout, (XtPointer) 0);
449 #ifdef TERMINAL_SERVER
451 ServerInstanceTerminated((Widget) client_data);
453 #endif /* TERMINAL_SERVER */
456 /* Here is where one would add the call into sunDtTermServer.c
457 * implement a "lurking" dtterm server. */
462 /***************************************************************************
464 * RegisterTestProbe - shoves a property on the root window that says *
465 * we're ready to be tested, and sets up the event handler for the client *
468 ***************************************************************************/
469 static void RegisterTestProbe(
474 Window win = XtWindow(topLevel);
476 if (xa_DTTERM_TEST_PROBE_IDS == None)
478 xa_DTTERM_TEST_PROBE_IDS = XInternAtom(XtDisplay(topLevel),
479 "_DTTERM_TEST_PROBE_IDS", False);
481 if (xa_DTTERM_REMOTE_PROBE_REQUEST == None)
483 xa_DTTERM_REMOTE_PROBE_REQUEST = XInternAtom(XtDisplay(topLevel),
484 "_DTTERM_REMOTE_PROBE_REQUEST", False);
487 XChangeProperty(XtDisplay(topLevel), RootWindowOfScreen(XtScreen(topLevel)),
488 xa_DTTERM_TEST_PROBE_IDS, xa_DTTERM_TEST_PROBE_IDS,
489 32, PropModeReplace, (unsigned char *)&win, 1);
490 XtAddEventHandler(topLevel, NoEventMask , True, (XtEventHandler )TestProbeHandler,
497 #define FOUR_BYTE_PTR 3
498 #define GET_USER_KEY_LOCK 4
499 #define GET_AUTO_LINE_FEED 5
500 #define GET_CURSOR_VISIBLE 6
501 #define GET_SCROLLBAR_WINDOW 7
502 /***************************************************************************
504 * TestProbeHandler - handle the client message for test probes *
506 ***************************************************************************/
507 static XtEventHandler TestProbeHandler(
509 XtPointer client_data,
513 XClientMessageEvent *cm = (XClientMessageEvent *)event;
514 DtTermViewWidget tw = (DtTermViewWidget )client_data;
516 Atom prop_name, actual_type;
517 int prop_type; /* THIS WILL BREAK ON A 16-BIT INT SYSTEM */
520 unsigned long nitems, bytes_left;
533 unsigned char *reply;
537 if (cm->send_event == False) return;
538 if (cm->message_type != xa_DTTERM_REMOTE_PROBE_REQUEST) return;
540 reply = (unsigned char*) malloc(sizeof(unsigned char) * 1024);
544 * If it's a xa_DTTERM_REMOTE_PROBE_REQUEST, then the data is three 32-bit
545 * quantities: 0 is the window ID, 1 is the property atom to get off the
546 * window, and 2 is the number of bytes required to getvalues the requested
553 prop_name = cm->data.l[1];
554 prop_type = cm->data.l[2];
558 if (XGetWindowProperty(XtDisplay(w), win, prop_name, offset, length,
559 False, AnyPropertyType, &actual_type,&actual_format,
560 &nitems, &bytes_left, &data) == Success)
564 case GET_CURSOR_VISIBLE:
565 sprintf((char *)reply,"%d", (int )_DtTermPrimGetCursorVisible(tw->termview.term));
568 case GET_USER_KEY_LOCK:
569 sprintf((char *)reply,"%d", (int )_DtTermGetUserKeyLock(tw->termview.term));
572 case GET_AUTO_LINE_FEED:
573 sprintf((char *)reply,"%d", (int )_DtTermGetAutoLineFeed(tw->termview.term));
576 case GET_SCROLLBAR_WINDOW:
577 sprintf((char *)reply, "0x%lx", tw->termview.scrollBar.widget ?
578 XtWindow(tw->termview.scrollBar.widget) : 0);
582 XtSetArg(al[0], (XtPointer ) data,&onebyte);
583 if (!strcmp((char *)data, XmNmenuBar) ||
584 !strcmp((char *)data, DtNscrollBar))
585 XtGetValues((Widget)tw, al, 1);
587 XtGetValues(tw->termview.term, al, 1);
588 sprintf((char *)reply,"%d", onebyte.uc);
592 XtSetArg(al[0], (XtPointer ) data,&twobyte);
593 XtGetValues(tw->termview.term, al, 1);
594 sprintf((char *)reply,"%d", twobyte.s);
599 XtSetArg(al[0], (XtPointer ) data,&fourbyte);
600 XtGetValues(tw->termview.term, al, 1);
601 if (prop_type == FOUR_BYTE_PTR)
603 sprintf((char *)reply,"%s", fourbyte.cp);
605 sprintf((char *)reply,"%s", "<NULL>");
608 sprintf((char *)reply,"%d", fourbyte.i);
611 sprintf((char *)reply,"%s","ERROR");
614 XChangeProperty(XtDisplay(w), win, prop_name, prop_name, 8,
615 PropModeReplace, reply, strlen((char *)reply));
616 XSync(XtDisplay(w),False);
626 Widget termViewWidget
634 /* intern the necessary atoms... */
635 if (xa_MOTIF_WM_MESSAGES == None) {
636 /* get the atom value... */
637 xa_MOTIF_WM_MESSAGES = XInternAtom(XtDisplay(topLevel),
638 "_MOTIF_WM_MESSAGES", False);
640 if (xa_DTTERM_TOGGLE_MENUBAR == None) {
641 /* get the atom value... */
642 xa_DTTERM_TOGGLE_MENUBAR = XInternAtom(XtDisplay(topLevel),
643 "_DTTERM_TOGGLE_MENUBAR", False);
646 /* add a menubar toggle to the mwm pulldown... */
648 menu = GETMESSAGE(NL_SETN_Main,1,"\
650 Toggle\\ Menu\\ Bar f.send_msg %d\
652 (void) sprintf(buffer, menu, xa_DTTERM_TOGGLE_MENUBAR);
653 (void) XtSetArg(al[ac], XmNmwmMenu, buffer); ac++;
654 (void) XtSetValues(topLevel, al, ac);
656 /* add a protocoll handler for MOTIF_WM_MESSAGES... */
657 if (xa_MOTIF_WM_MESSAGES != None) {
658 (void) XmAddProtocols(topLevel, xa_MOTIF_WM_MESSAGES,
659 &xa_DTTERM_TOGGLE_MENUBAR, 1);
660 (void) XmAddProtocolCallback(topLevel, xa_MOTIF_WM_MESSAGES,
661 xa_DTTERM_TOGGLE_MENUBAR,
662 ToggleMenuBar, (XtPointer) termViewWidget);
667 CloneCallback(Widget wid, XtPointer client_data, XtPointer call_data)
669 register DtTermViewWidget w = (DtTermViewWidget) wid;
670 DtTermViewCallbackStruct *termCB = (DtTermViewCallbackStruct *) call_data;
672 Widget parent = XtParent((Widget) w);
677 /* duplicate the dtterm widget's parent widget...
679 if (XtIsShell(parent)) {
682 Boolean allowShellResize;
683 #ifdef COPY_WHEN_CLONING
687 #endif /* COPY_WHEN_CLONING */
688 char *topShellIconName;
691 if (XtIsApplicationShell(parent)) {
692 (void) XtSetArg(arglist[i], XmNargc, &argc); i++;
693 (void) XtSetArg(arglist[i], XmNargv, &argv); i++;
695 #ifdef COPY_WHEN_CLONING
696 (void) XtSetArg(arglist[i], XmNgeometry, &geometry); i++;
697 (void) XtSetArg(arglist[i], XmNwidth, &width); i++;
698 (void) XtSetArg(arglist[i], XmNheight, &height); i++;
699 #endif /* COPY_WHEN_CLONING */
700 (void) XtSetArg(arglist[i], XmNallowShellResize, &allowShellResize);
702 (void) XtGetValues(parent, arglist, i);
705 if (XtIsApplicationShell(parent)) {
706 (void) XtSetArg(arglist[i], XmNargc, argc); i++;
707 (void) XtSetArg(arglist[i], XmNargv, argv); i++;
709 #ifdef COPY_WHEN_CLONING
710 (void) XtSetArg(arglist[i], XmNgeometry, geometry); i++;
711 (void) XtSetArg(arglist[i], XmNwidth, width); i++;
712 (void) XtSetArg(arglist[i], XmNheight, height); i++;
713 #endif /* COPY_WHEN_CLONING */
714 (void) XtSetArg(arglist[i], XmNallowShellResize, allowShellResize); i++;
715 /* Set the title (and icon name) for the clone (new) dtterm window
716 the same as the initial title (and icon name) of the top level
719 (void) XtSetArg(arglist[i], XmNtitle, attrs.title); i++;
721 topShellIconName = attrs.icon_name;
722 else if (attrs.dtterm_name)
723 topShellIconName = attrs.dtterm_name;
724 else topShellIconName = attrs.title;
725 (void) XtSetArg(arglist[i], XmNiconName, topShellIconName); i++;
727 shellWidget = XtAppCreateShell((char *) 0, "Dtterm",
728 XtClass(parent), XtDisplay((Widget) w), arglist, i);
731 (void) XtSetArg(arglist[i], XmNallowShellResize, True); i++;
732 shellWidget = XtAppCreateShell((char *) 0, "Dtterm",
733 applicationShellWidgetClass, XtDisplay((Widget) w), arglist, i);
736 #ifdef COPY_WHEN_CLONING
737 termWidget = DtCreateTermView(shellWidget, "dtTermView", termCB->arglist,
739 #else /* COPY_WHEN_CLONING */
740 termWidget = DtCreateTermView(shellWidget, "dtTermView", termCB->arglist,
742 #endif /* COPY_WHEN_CLONING */
744 /* add a menubar toggle to the mwm pulldown... */
745 (void) AddMenubarToggle(shellWidget, termWidget);
747 (void) InstanceCount++;
748 (void) XtManageChild(termWidget);
750 /* destroy the widget on child termination... */
751 (void) XtAddCallback(termWidget, DtNsubprocessTerminationCallback,
752 DestroyDtTerm, (XtPointer) shellWidget);
753 (void) XtAddCallback(termWidget, XmNdestroyCallback,
754 DecrementInstanceCountAndExit, (XtPointer) topLevel);
755 (void) _DtTermPrimAddDeleteWindowCallback(shellWidget, DestroyDtTerm,
756 (XtPointer) shellWidget);
757 (void) XtAddCallback(termWidget, DtNnewCallback,
758 CloneCallback, (XtPointer) 0);
759 instance_list = (DtTermViewWidget *)XtRealloc((char *)instance_list,
760 (sizeof(DtTermViewWidget *)*InstanceCount));
761 instance_list[InstanceCount - 1] = (DtTermViewWidget )termWidget;
763 (void) XtRealizeWidget(shellWidget);
771 XtPointer client_data,
775 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data;
777 if (cb->event->xclient.message_type == xa_MOTIF_WM_MESSAGES) {
778 /* can't use case here, since we are not switching on a pre-defined
781 if (cb->event->xclient.data.l[0] == xa_DTTERM_TOGGLE_MENUBAR) {
782 (void) _DtTermViewMenuToggleMenuBar((Widget) client_data);
786 #ifdef SUN_TERMINAL_SERVER
790 #endif /* SUN_TERMINAL_SERVER */
793 Widget topLevelWidget,
797 Boolean enableCloneCallback
800 Widget termViewWidget;
802 /* bump our session count... */
804 (void) LogBumpSessionCount(1);
805 #endif /* LOG_USAGE */
807 termViewWidget = DtCreateTermView(topLevelWidget, name, arglist, argcnt);
809 /* add a menubar toggle to the mwm pulldown... */
810 (void) AddMenubarToggle(topLevelWidget, termViewWidget);
812 #ifdef TERMINAL_SERVER
813 if (attrs.standAlone || !attrs.serverId) {
814 #endif /* TERMINAL_SERVER */
815 (void) InstanceCount++;
816 #ifdef TERMINAL_SERVER
818 #endif /* TERMINAL_SERVER */
819 (void) XtManageChild(termViewWidget);
820 /* destroy the widget on termination... */
821 (void) XtAddCallback(termViewWidget, DtNsubprocessTerminationCallback,
822 DestroyDtTerm, (XtPointer) topLevelWidget);
823 (void) XtAddCallback(termViewWidget, XmNdestroyCallback,
824 DecrementInstanceCountAndExit, (XtPointer) topLevelWidget);
825 (void) _DtTermPrimAddDeleteWindowCallback(topLevelWidget, DestroyDtTerm,
826 (XtPointer) topLevelWidget);
827 instance_list = (DtTermViewWidget * )XtRealloc((char *)instance_list,(sizeof(DtTermViewWidget *)*InstanceCount));
828 instance_list[InstanceCount - 1] = (DtTermViewWidget )termViewWidget;
829 if (enableCloneCallback)
830 (void) XtAddCallback(termViewWidget, DtNnewCallback,
831 CloneCallback, (XtPointer) 0);
851 DebugF('s', 10, fprintf(stderr, ">>SignalHandler() starting\n"));
852 _DtTermPrimPtyCleanup();
853 _DtTermPrimUtmpCleanup();
854 _DtTermPrimLogFileCleanup();
855 DebugF('s', 10, fprintf(stderr, ">>SignalHandler() finished\n"));
859 static int signalList[] = {
891 char *prop = (char *) 0;
894 unsigned long numItems;
895 unsigned long bytesAfter;
897 (void) XGetWindowProperty(display,
898 RootWindow(display, 0),
899 XmInternAtom(display, property, FALSE),
908 (unsigned char **) &prop);
910 if ((actualType != XA_STRING) ||
911 (actualFormat != 8) ||
923 #ifndef XmNdefaultVirtualBindings
924 #define XmNdefaultVirtualBindings "defaultVirtualBindings"
925 #endif /* XmNdefaultVirtualBindings */
935 char *origDisplayBindings,*freeOrigBindings=NULL;
936 char *newDisplayBindings;
941 char **ignoredKeysymList;
942 int numIgnoredKeysyms;
944 /* malloc a copy of the ignoredKeysym string... */
945 if (attrs.ignoredKeysyms && *attrs.ignoredKeysyms) {
946 c1 = XtMalloc(strlen(attrs.ignoredKeysyms) + 1);
947 (void) strcpy(c1, attrs.ignoredKeysyms);
948 attrs.ignoredKeysyms = c1;
951 /* count the number of keysyms in the list... */
952 for (c1 = attrs.ignoredKeysyms, numIgnoredKeysyms = 0; c1 && *c1; ) {
954 c1 = strchr(c1, '\n');
960 /* malloc space for the array... */
961 ignoredKeysymList = (char **) XtMalloc((numIgnoredKeysyms + 1) *
964 /* build the list... */
965 for (c1 = attrs.ignoredKeysyms, i1 = 0; i1 < numIgnoredKeysyms; i1++) {
966 ignoredKeysymList[i1] = c1;
967 c1 = strchr(c1, '\n');
973 /* null terminate the list... */
974 ignoredKeysymList[i1] = (char *) 0;
977 w = XmGetXmDisplay(display);
980 (void) XtSetArg(al[ac], XmNdefaultVirtualBindings, &origDisplayBindings);
982 (void) XtGetValues(w, al, ac);
984 if (!origDisplayBindings) {
985 GetBindingsProperty(display, "_MOTIF_BINDINGS", &origDisplayBindings);
986 freeOrigBindings = origDisplayBindings ;
989 if (!origDisplayBindings) {
990 GetBindingsProperty(display, "_MOTIF_DEFAULT_BINDINGS",
991 &origDisplayBindings);
992 freeOrigBindings = origDisplayBindings ;
995 if (!origDisplayBindings) {
996 if (ignoredKeysymList) XtFree((char *)ignoredKeysymList);
1000 DebugF('b', 10, fprintf(stderr,
1001 "FixOSFBindings(): bindings: %s\n", origDisplayBindings));
1002 newDisplayBindings = XtMalloc(strlen(origDisplayBindings) + 1);
1003 c1 = origDisplayBindings;
1004 c2 = newDisplayBindings;
1006 /* remember the current position in the new string... */
1009 /* copy over everything up to the '\n' or null... */
1010 while (*c1 && (*c1 != '\n')) {
1014 /* null terminate the string... */
1017 /* run through the exclusion list and look for a match... */
1018 for (i1 = 0; i1 < numIgnoredKeysyms; i1++) {
1019 DebugF('b', 10, fprintf(stderr, "!strcmp(\"%s\", \"%s\") = %d\n",
1020 c2 - strlen(ignoredKeysymList[i1]),
1021 ignoredKeysymList[i1],
1022 !strcmp(c2 - strlen(ignoredKeysymList[i1]),
1023 ignoredKeysymList[i1])));
1024 if ((strlen(ignoredKeysymList[i1]) <= (size_t)(c2 - cHold)) &&
1025 !strcmp(c2 - strlen(ignoredKeysymList[i1]),
1026 ignoredKeysymList[i1])) {
1027 /* we hit a match... */
1028 DebugF('b', 10, fprintf(stderr, "match!\n"));
1033 /* if we hit a match, back up the string... */
1034 if (i1 < numIgnoredKeysyms) {
1035 DebugF('b', 10, fprintf(stderr, "dropping %s\n", cHold));
1037 /* skip over whitespace in the source... */
1038 while (isspace(*c1)) {
1042 /* copy over whitespace in the source... */
1043 DebugF('b', 10, fprintf(stderr, "keeping %s\n", cHold));
1044 while (isspace(*c1)) {
1051 /* null terminate the string... */
1054 /* and set this new bindings string... */
1056 (void) XtSetArg(al[ac], XmNdefaultVirtualBindings, newDisplayBindings);
1058 (void) XtSetValues(w, al, ac);
1060 /* changed from XtFree to free as it was allocated with malloc to avoid FMM */
1061 if (freeOrigBindings) free(origDisplayBindings);
1063 if (ignoredKeysymList) XtFree((char *)ignoredKeysymList);
1065 /* and finally, reparse the string... */
1066 _XmVirtKeysInitialize(w);
1070 removeWmCommandCallback
1073 XtPointer clientData,
1078 static Atom xa_WM_STATE = None;
1079 Boolean firstTime = True;
1082 xa_WM_STATE = XInternAtom(XtDisplay(w), "WM_STATE", True);
1086 if (((XPropertyEvent *) event)->atom == xa_WM_STATE) {
1087 /* blow away the atom... */
1088 (void) XDeleteProperty(XtDisplay(w), XtWindow(w),
1091 /* we have done our job and don't need to be called again... */
1092 (void) XtRemoveEventHandler(w, (EventMask) XtAllEvents,
1093 True, removeWmCommandCallback, clientData);
1104 cp = strrchr(name, '/');
1105 return(cp ? cp + 1 : name);
1109 main(int argc, char **argv)
1116 char **commandToExecute = (char **) 0;
1117 int ptyMasterFd = -1;
1118 struct sigaction sa;
1119 #ifdef SUN_TERMINAL_SERVER
1120 Boolean iAmTheServer = False;
1121 #endif /* SUN_TERMINAL_SERVER */
1123 (void) atexit(AtExitProc);
1125 if (c = getenv("dttermDebugFlags")) {
1126 (void) setDebugFlags(c);
1128 if (isDebugSet('T')) {
1132 (void) timeStamp("starting");
1135 if (c = getenv("dttermDelayFlags"))
1139 int delay = atoi(c);
1140 pid_t pid = getpid();
1141 printf("dtterm (%d) sleeping for %d seconds\n", pid, delay);
1146 /* before we do anything, let's set up signal handlers to clean up
1149 (void) sigemptyset(&sa.sa_mask);
1152 sa.sa_handler = SignalHandler;
1153 /* trap all signals that we want to clean up after... */
1154 for (i = 0; i < (sizeof(signalList) / sizeof(signalList[0])); i++) {
1155 (void) sigaction(signalList[i], &sa, (struct sigaction *) 0);
1158 /* ignore SIGHUP... */
1159 sa.sa_handler = SIG_IGN;
1160 (void) sigaction(SIGHUP, &sa, (struct sigaction *) 0);
1163 ** set up the environment variables for this client...
1166 #if (OSMINORVERSION > 01)
1167 VuEnvControl(VUE_ENV_SET);
1168 #endif /* (OSMINORVERSION > 01) */
1170 _DtEnvControl(DT_ENV_SET);
1173 /* set up the I18N world... */
1174 (void) XtSetLanguageProc(NULL, NULL, NULL);
1176 if (isDebugSet('T')) {
1180 (void) timeStamp("XtSetLangProc() finished");
1183 /* before we initialize Xt, let's save argv and argc... */
1185 savedArgv = (char **) XtMalloc((argc + 1) * sizeof(char *));
1186 for (i = 0; i < argc; i++) {
1187 savedArgv[i] = XtMalloc(strlen(argv[i]) + 1);
1188 (void) strcpy(savedArgv[i], argv[i]);
1189 #ifdef SUN_TERMINAL_SERVER
1190 if ((!strcmp(argv[i], "-sdtserver")) || (!strcmp(argv[i], "-dtserver")))
1191 iAmTheServer = TRUE;
1192 #endif /* SUN_TERMINAL_SERVER */
1194 savedArgv[i] = (char *) 0;
1201 /* before we do anything with the toolkit, let's usurp the constraint
1202 * initialize proc for the XmManager widget class. This will allow us
1203 * to prevent it from performing that awful
1204 * DoMagicBBCompatibilityStuff() on us that steals (among other things)
1205 * our return key. Note that currently, this is all that the
1206 * XmManager widget does for widgets, but if it did more than we
1207 * would loose out on that.
1209 /* initialize Xt and the X world... */
1210 (void) DtTermInitialize();
1213 (void) XtSetArg(arglist[i], XmNallowShellResize, True); i++;
1215 topLevel = XtAppInitialize(&appContext,
1218 XtNumber(optionDescList),
1225 #ifdef SUN_TERMINAL_SERVER
1227 (void) ServerStartSession(topLevel, savedArgc, savedArgv,
1231 #endif /* SUN_TERMINAL_SERVER */
1233 /* get application specific resources... */
1235 /* Need to specify base address of the resources. In our case, attrs */
1236 (void) XtGetApplicationResources(topLevel, (XtPointer)&attrs,
1237 applicationResources,
1238 XtNumber(applicationResources),
1241 /* set all the debug flags... */
1242 (void) setDebugFlags(attrs.debugString);
1244 (void) FixOSFBindings(XtDisplay(topLevel));
1246 /* Add the Save_yourself callback... */
1247 xa_WM_SAVE_YOURSELF = XInternAtom(XtDisplay(topLevel),
1248 "WM_SAVE_YOURSELF", False);
1249 XmAddWMProtocolCallback(topLevel, xa_WM_SAVE_YOURSELF,
1250 (XtCallbackProc)SaveSessionCB, (XtPointer)NULL);
1253 (void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
1254 (void) XtSetArg(arglist[i], XmNallowShellResize, True); i++;
1255 topShell = XtAppCreateShell((char *) 0, "Dtterm",
1256 applicationShellWidgetClass, XtDisplay(topLevel), arglist, i);
1258 if (attrs.session != NULL)
1259 RestoringTerms = TRUE;
1261 if (isDebugSet('T')) {
1265 (void) timeStamp("XtAppInitialize() finished");
1268 for (i = 1; i < argc; i++) {
1269 if (argv[i][0] != '-') {
1270 (void) Syntax(argv[0], argv[i]);
1274 switch(argv[i][1]) {
1278 /* skip past the '-S'... */
1280 if (c2 = strchr(c, '.')) {
1281 /* skip past the '.'... */
1284 /* skip past the first 2 characters since they are the
1285 * name of the pty...
1289 /* use scanf instead of atoi since it won't change the value
1290 * of ptyMasterFd if the string does not contain a valid
1293 (void) sscanf(c2, "%d", &ptyMasterFd);
1297 /* command to exec...
1301 commandToExecute = &argv[i];
1309 (void) Help(argv[0]);
1314 (void) Syntax(argv[0], argv[i]);
1320 #ifdef TERMINAL_SERVER
1321 if (attrs.standAlone || !attrs.serverId) {
1322 #endif /* TERMINAL_SERVER */
1323 /* log our startup... */
1325 (void) LogStart(0, argc, argv);
1326 #endif /* LOG_USAGE */
1329 if (commandToExecute) {
1330 (void) XtSetArg(arglist[i], DtNsubprocessArgv, commandToExecute);
1334 if (!RestoringTerms || !RestoreSession(topShell, arglist, i)) {
1336 RestoringTerms = False;
1338 if (ptyMasterFd >= 0) {
1339 /* set the workspace for the initial dtterm instance... */
1340 (void) XtSetArg(arglist[i], DtNtermDevice, ptyMasterFd); i++;
1341 (void) XtSetArg(arglist[i], DtNtermDeviceAllocate, False); i++;
1342 (void) XtSetArg(arglist[i], DtNsubprocessExec, False); i++;
1343 (void) CreateInstance(topShell, "dtTermView", arglist, i, False);
1346 (void) CreateInstance(topShell, "dtTermView", arglist, i, True);
1350 /* realize the interface... */
1352 (void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
1353 (void) XtSetValues(topLevel, arglist, i);
1354 (void) XtRealizeWidget(topLevel);
1356 #ifdef SUN_TERMINAL_SERVER
1358 FinishToolTalkInit(topLevel);
1359 #endif /* SUN_TERMINAL_SERVER */
1361 /* Set title to the command to execute (if any)
1363 if (commandToExecute && !attrs.title) {
1364 attrs.title = base_name (commandToExecute[0]);
1367 /* Else set title to default ("Terminal")
1370 title = XtMalloc(strlen(GETMESSAGE(NL_SETN_Main, 3, "Terminal")) + 1);
1371 (void) strcpy(title, GETMESSAGE(NL_SETN_Main, 3, "Terminal"));
1372 attrs.title = title;
1375 /* realize the interface... */
1377 (void) XtSetArg(arglist[i], XmNtitle, attrs.title); i++;
1378 if ((!attrs.icon_name) && (!attrs.dtterm_name))
1379 (void) XtSetArg(arglist[i], XmNiconName, attrs.title); i++;
1380 (void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
1381 (void) XtSetArg(arglist[i], XmNgeometry, NULL); i++;
1382 (void) XtSetValues(topShell, arglist, i);
1383 (void) XtRealizeWidget(topShell);
1385 if (RestoringTerms != True) {
1386 /* use the wm command to pass the -xrm resource to the wm... */
1387 (void) XSetCommand(XtDisplay(topShell), XtWindow(topShell),
1388 savedArgv, savedArgc);
1389 /* add a callback to remove it after it has been seen... */
1390 (void) XtAddEventHandler(topShell, (EventMask) PropertyChangeMask,
1391 False, removeWmCommandCallback, (XtPointer) 0);
1394 (void) XtSetArg(arglist[0], XmNmappedWhenManaged, True);
1395 (void) XtSetValues(topShell, arglist, 1);
1396 XtMapWidget(topShell);
1397 RegisterTestProbe(topShell,instance_list[0]);
1399 if (ptyMasterFd >= 0) {
1400 /* write out the window id... */
1401 char buffer[BUFSIZ];
1403 (void) sprintf(buffer, "%lx\n", XtWindow(topLevel));
1404 (void) write(ptyMasterFd, buffer, strlen(buffer));
1407 sunSetupIA(topLevel);
1410 #ifdef TERMINAL_SERVER
1412 if (ptyMasterFd >= 0) {
1413 (void) fprintf(stderr,
1414 GETMESSAGE(NL_SETN_Main,2, "%s: the -S option cannot be used with the -server or -serverid options\n"),
1420 (void) XtSetArg(arglist[i], XmNmappedWhenManaged, False); i++;
1421 (void) XtSetValues(topLevel, arglist, i);
1422 (void) XtRealizeWidget(topLevel);
1424 (void) ServerStartSession(topLevel, savedArgc, savedArgv,
1425 attrs.server, attrs.serverId, attrs.exitOnLastClose,
1426 attrs.block, attrs.loginShell,
1429 #endif /* TERMINAL_SERVER */
1431 /* and hand off to Xt... */
1432 (void) XtAppMainLoop(appContext);
1435 /************************************************************************
1439 ************************************************************************/
1444 Widget w, /* widget id */
1445 caddr_t client_data, /* data from application */
1446 caddr_t call_data ) /* data from widget class */
1448 char *longpath, *fileName;
1451 char *xa_CommandStr[1024];
1457 DtSessionSavePath(w, &longpath, &fileName);
1459 /* Create the session file */
1460 if ((fd = creat (longpath, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
1465 sprintf(bufr, "*dtterm.numClonedTerms: %d\n", InstanceCount);
1466 write (fd, bufr, strlen(bufr));
1468 for(i = 0; i < InstanceCount; i++)
1469 SaveTerm(instance_list[i], i, fd);
1472 "*dtterm.sessionFileVersionId: dttermSessionFileVersion.1.0.0\n");
1473 write (fd, bufr, strlen(bufr));
1478 xa_CommandStr[i] = savedArgv[0]; i++;
1479 xa_CommandStr[i] = "-session"; i++;
1480 xa_CommandStr[i] = fileName; i++;
1483 * Now restore the command line minus the old session parameter
1486 for (j = 1; j < savedArgc; j++)
1488 if (strcmp(savedArgv[j], "-session") == 0)
1495 xa_CommandStr[i] = savedArgv[j];
1500 XSetCommand(XtDisplay(topLevel),
1501 XtWindow(topLevel), xa_CommandStr, i);
1504 XtFree ((char *)fileName);
1509 DtTermViewWidget dtvw,
1513 char *bufr = malloc(1024);
1515 Dimension width, height;
1517 unsigned long numInfo;
1518 unsigned char charCursorStyle;
1524 Boolean reverseVideo;
1528 Boolean reverseWrap;
1531 Boolean autoLineFeed;
1537 static char *defaultCwd = (char *) 0;
1540 char buffer[BUFSIZ];
1541 DtTermWidget dtw = (DtTermWidget )dtvw->termview.term;
1542 static Boolean firstTime = True;
1543 static Atom xa_WM_STATE = None;
1544 struct _wmStateStruct {
1550 unsigned long nItems;
1551 unsigned long bytesAfter;
1553 XmVendorShellExtObject vendorExt;
1554 XmWidgetExtData extData;
1556 x = XtX(XtParent(dtvw));
1557 y = XtY(XtParent(dtvw));
1560 * Modify x & y to take into account window mgr frames
1561 * This is pretty bogus, but I don't know a better way to do it.
1563 extData = _XmGetWidgetExtData(XtParent(dtvw), XmSHELL_EXTENSION);
1564 vendorExt = (XmVendorShellExtObject)extData->widget;
1565 x -= vendorExt->vendor.xOffset;
1566 y -= vendorExt->vendor.yOffset;
1567 width = XtWidth(XtParent(dtvw));
1568 height = XtHeight(XtParent(dtvw));
1570 sprintf(bufr, "*dtterm_%d.x: %d\n", cloneNum, x);
1571 sprintf(bufr, "%s*dtterm_%d.y: %d\n", bufr, cloneNum, y);
1572 sprintf(bufr, "%s*dtterm_%d.width: %d\n", bufr, cloneNum, width);
1573 sprintf(bufr, "%s*dtterm_%d.height: %d\n", bufr, cloneNum, height);
1575 /* Write out iconic state...
1578 xa_WM_STATE = XInternAtom(XtDisplay(dtvw), "WM_STATE", True);
1581 if (xa_WM_STATE && (Success == XGetWindowProperty(
1583 XtWindow(XtParent(dtvw)),
1586 (sizeof(struct _wmStateStruct) + 3) / 4,
1593 (unsigned char **) &prop))) {
1594 if (prop->state == IconicState) {
1595 sprintf(bufr, "%s*dtterm_%d.iconify: %s\n", bufr, cloneNum,
1598 sprintf(bufr, "%s*dtterm_%d.iconify: %s\n", bufr, cloneNum,
1603 if(DtWsmGetWorkspacesOccupied(XtDisplay(dtvw),
1604 XtWindow(XtParent(dtvw)), &pWsPresence,
1605 &numInfo) == Success)
1608 sprintf(bufr, "%s*dtterm_%d.workspaceList: ", bufr, cloneNum);
1609 for(i = 0; i < numInfo; i++)
1611 char *name = XGetAtomName(XtDisplay(dtvw),
1613 sprintf(bufr, "%s %s", bufr, name);
1616 sprintf(bufr, "%s\n", bufr);
1617 XtFree((char *)pWsPresence);
1620 write (fd, bufr, strlen(bufr));
1622 sprintf(bufr, "*dtterm_%d.userFontListIndex: %d\n", cloneNum,
1623 _DtTermViewGetUserFontListIndex((Widget )dtvw));
1624 write (fd, bufr, strlen(bufr));
1626 /* get the current widget values... */
1628 (void) XtSetArg(al[ac], DtNmenuBar, &menuBar); ac++;
1629 (void) XtSetArg(al[ac], DtNscrollBar, &scrollBar); ac++;
1630 (void) XtGetValues((Widget)dtvw, al, ac);
1632 (void) XtSetArg(al[ac], DtNrows, &rows); ac++;
1633 (void) XtSetArg(al[ac], DtNcolumns, &columns); ac++;
1634 (void) XtSetArg(al[ac], DtNblinkRate, &blinkRate); ac++;
1635 (void) XtSetArg(al[ac], DtNcharCursorStyle, &charCursorStyle); ac++;
1636 (void) XtSetArg(al[ac], DtNblinkRate, &blinkRate); ac++;
1637 (void) XtSetArg(al[ac], DtNjumpScroll, &jumpScroll); ac++;
1638 (void) XtSetArg(al[ac], DtNmarginBell, &marginBell); ac++;
1639 (void) XtSetArg(al[ac], DtNnMarginBell, &nMarginBell); ac++;
1640 (void) XtSetArg(al[ac], DtNvisualBell, &visualBell); ac++;
1641 (void) XtSetArg(al[ac], DtNreverseVideo, &reverseVideo); ac++;
1642 (void) XtSetArg(al[ac], DtNappCursorDefault, &cursorMode); ac++;
1643 (void) XtSetArg(al[ac], DtNappKeypadDefault, &keypadMode); ac++;
1644 (void) XtSetArg(al[ac], DtNautoWrap, &autoWrap); ac++;
1645 (void) XtSetArg(al[ac], DtNreverseWrap, &reverseWrap); ac++;
1646 (void) XtSetArg(al[ac], DtNc132, &c132); ac++;
1647 (void) XtGetValues((Widget)dtw, al, ac);
1648 lockState = _DtTermGetUserKeyLock((Widget) dtw);
1649 autoLineFeed = _DtTermGetAutoLineFeed((Widget) dtw);
1651 /* get the current working directory if it was saved... */
1652 cwd = _DtTermGetCurrentWorkingDirectory((Widget) dtw);
1653 if (!cwd || !*cwd) {
1654 /* no saved cwd, use the one we were started from... */
1656 /* first time through, use getcwd() to get it... */
1657 if (getcwd(buffer, sizeof(buffer))) {
1658 defaultCwd = XtMalloc(strlen(buffer) + 1);
1659 (void) strcpy(defaultCwd, buffer);
1665 (void) sprintf(bufr, "*dtterm_%d*rows: %d\n", cloneNum, rows);
1666 (void) write(fd, bufr, strlen(bufr));
1667 (void) sprintf(bufr, "*dtterm_%d*columns: %d\n", cloneNum, columns);
1668 (void) write(fd, bufr, strlen(bufr));
1670 if(menuBar == False)
1672 sprintf(bufr, "*dtterm_%d*menuBar: False\n", cloneNum);
1673 write (fd, bufr, strlen(bufr));
1675 if(scrollBar == False)
1677 sprintf(bufr, "*dtterm_%d*scrollBar: False\n", cloneNum);
1678 write (fd, bufr, strlen(bufr));
1680 if (_DtTermPrimGetCursorVisible((Widget )dtw))
1682 if (charCursorStyle == DtTERM_CHAR_CURSOR_BAR)
1683 sprintf(bufr, "*dtterm_%d*charCursorStyle: CHARCURSOR_BAR\n", cloneNum);
1685 sprintf(bufr, "*dtterm_%d*charCursorStyle: CHARCURSOR_BOX\n", cloneNum);
1688 sprintf(bufr, "*dtterm_%d*charCursorStyle: CHARCURSOR_INVISIBLE\n", cloneNum);
1689 write (fd, bufr, strlen(bufr));
1692 sprintf(bufr, "*dtterm_%d*blinkRate: %d\n", cloneNum,blinkRate);
1693 write (fd, bufr, strlen(bufr));
1695 if(jumpScroll == False)
1697 sprintf(bufr, "*dtterm_%d*jumpScroll: False\n", cloneNum);
1698 write (fd, bufr, strlen(bufr));
1700 if(marginBell == True)
1702 sprintf(bufr, "*dtterm_%d*marginBell: True\n", cloneNum);
1703 write (fd, bufr, strlen(bufr));
1704 sprintf(bufr, "*dtterm_%d*nMarginBell: %d\n", cloneNum,nMarginBell);
1705 write (fd, bufr, strlen(bufr));
1707 if(visualBell == True)
1709 sprintf(bufr, "*dtterm_%d*visualBell: True\n", cloneNum);
1710 write (fd, bufr, strlen(bufr));
1712 if(reverseVideo == True)
1714 sprintf(bufr, "*dtterm_%d*reverseVideo: True\n", cloneNum);
1715 write (fd, bufr, strlen(bufr));
1717 if(cursorMode == True)
1719 sprintf(bufr, "*dtterm_%d*appCursorDefault: True\n", cloneNum);
1720 write (fd, bufr, strlen(bufr));
1722 if(keypadMode == True)
1724 sprintf(bufr, "*dtterm_%d*appKeypadDefault: True\n", cloneNum);
1725 write (fd, bufr, strlen(bufr));
1727 if(autoWrap == False)
1729 sprintf(bufr, "*dtterm_%d*autoWrap: False\n", cloneNum);
1730 write (fd, bufr, strlen(bufr));
1732 if(reverseWrap == True)
1734 sprintf(bufr, "*dtterm_%d*reverseWrap: True\n", cloneNum);
1735 write (fd, bufr, strlen(bufr));
1739 sprintf(bufr, "*dtterm_%d*c132: True\n", cloneNum);
1740 write (fd, bufr, strlen(bufr));
1742 if(lockState == False)
1743 sprintf(bufr, "*dtterm_%d*userKeyLock: False\n", cloneNum);
1745 sprintf(bufr, "*dtterm_%d*userKeyLock: True\n", cloneNum);
1746 write (fd, bufr, strlen(bufr));
1747 if(autoLineFeed == False)
1748 sprintf(bufr, "*dtterm_%d*autoLineFeed: False\n", cloneNum);
1750 sprintf(bufr, "*dtterm_%d*autoLineFeed: True\n", cloneNum);
1751 write (fd, bufr, strlen(bufr));
1754 (void) sprintf(bufr, "*dtterm_%d*currentWorkingDirectory: %s\n",
1756 (void) write(fd, bufr, strlen(bufr));
1761 /***********************************************************************
1763 * RestoreSession - returns True for success, False for failure...
1765 ***********************************************************************/
1772 char *fileName = attrs.session;
1776 XrmName xrm_name[5];
1777 XrmRepresentation rep_type;
1780 int numToRestore, i, j;
1784 if(DtSessionRestorePath(topLevel, &path, fileName) == False)
1787 /* Open the file as a resource database */
1788 if ((db = XrmGetFileDatabase (path)) == NULL)
1790 /* if we got a bogus filename, bail out... */
1794 xrm_name[0] = XrmStringToQuark ("dtterm");
1795 xrm_name[1] = XrmStringToQuark ("numClonedTerms");
1797 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1799 /* if we got nothing back, bail out... */
1800 if (!value.addr || !*((char *) value.addr)) {
1804 numToRestore = atoi((char *)value.addr);
1805 /* if we don't have at least one to restore, bail out... */
1806 if (numToRestore < 1) {
1810 ShellWidget = topDog;
1812 for (j = 0; j < numToRestore; j++)
1814 /* use the passed arglist as a starting point... */
1815 for (ac = 0; ac < passedAc; ac++) {
1816 al[ac].value = passedAl[ac].value;
1817 al[ac].name = passedAl[ac].name;
1820 (void) CreateInstance(ShellWidget, "dtTermView", al, ac, True);
1821 RestoreTerm(ShellWidget, instance_list[j], j, db);
1822 (void) XtSetArg(al[0], XmNmappedWhenManaged, True);
1823 (void) XtSetValues(ShellWidget, al, 1);
1824 /* mapping the shell widget here is redundant, and it turns out
1825 * was responsible for CMVC7216: broken restoring of
1826 * iconified instances in multiple workspaces...
1830 (void) XtSetArg(al[ac], XmNallowShellResize, True); ac++;
1831 (void) XtSetArg(al[ac], XmNmappedWhenManaged, True); ac++;
1832 ShellWidget = XtAppCreateShell((char *) 0, "Dtterm",
1833 applicationShellWidgetClass, XtDisplay(topDog), al, ac);
1835 /* success, return True... */
1842 DtTermViewWidget dtvw,
1847 XrmName xrm_name[5];
1848 XrmRepresentation rep_type;
1850 DtTermWidget dtw = (DtTermWidget )dtvw->termview.term;
1852 Dimension width, height;
1854 unsigned char charCursorStyle;
1860 Boolean reverseVideo;
1864 Boolean reverseWrap;
1867 Boolean autoLineFeed;
1876 sprintf(buf, "dtterm_%d", termNum);
1877 xrm_name[0] = XrmStringToQuark(buf);
1880 /* Pass 1, before widget realization...
1883 /* get x position */
1884 xrm_name[1] = XrmStringToQuark ("x");
1885 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1886 x = atoi((char *)value.addr);
1888 /* get y position */
1889 xrm_name [1] = XrmStringToQuark ("y");
1890 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1891 y = atoi((char *)value.addr);
1894 xrm_name [1] = XrmStringToQuark ("width");
1895 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1896 width = atoi((char *)value.addr);
1899 xrm_name [1] = XrmStringToQuark ("height");
1900 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1901 height = atoi((char *)value.addr);
1905 * First the shell resources...
1909 (void) XtSetArg(al[ac], XmNx, x); ac++;
1910 (void) XtSetArg(al[ac], XmNy, y); ac++;
1911 (void) XtSetArg(al[ac], XmNwidth, width); ac++;
1912 (void) XtSetArg(al[ac], XmNheight, height); ac++;
1914 /* get iconify... */
1915 xrm_name[1] = XrmStringToQuark("iconify");
1916 if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) {
1917 if (!strcmp((char *)value.addr, "True")) {
1918 (void) XtSetArg(al[ac], XmNinitialState, IconicState); ac++;
1920 (void) XtSetArg(al[ac], XmNinitialState, NormalState); ac++;
1923 (void) XtSetArg(al[ac], XmNinitialState, NormalState);
1926 (void) XtSetValues(XtParent((Widget)dtvw), al, ac);
1930 * Now the TermView resources...
1934 xrm_name[1] = XrmStringToQuark ("rows");
1935 if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) {
1936 rows = atoi((char *)value.addr);
1937 (void) XtSetArg(al[ac], DtNrows, rows); ac++;
1940 xrm_name[1] = XrmStringToQuark ("columns");
1941 if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) {
1942 columns = atoi((char *)value.addr);
1943 (void) XtSetArg(al[ac], DtNcolumns, columns); ac++;
1946 xrm_name[1] = XrmStringToQuark ("menuBar");
1947 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
1948 {(void) XtSetArg(al[ac], XmNmenuBar, False); ac++;}
1949 xrm_name[1] = XrmStringToQuark ("scrollBar");
1950 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
1951 {(void) XtSetArg(al[ac], DtNscrollBar, False); ac++;}
1953 xrm_name[1] = XrmStringToQuark ("userFontListIndex");
1954 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True) {
1955 _DtTermViewSetUserFontListIndex((Widget )dtvw, atol(value.addr));
1958 (void) XtSetValues((Widget)dtvw, al, ac);
1962 * And finally the termprim stuff...
1967 (void) XtSetArg(al[ac], DtNrows, rows); ac++;
1971 (void) XtSetArg(al[ac], DtNcolumns, columns); ac++;
1974 xrm_name[1] = XrmStringToQuark ("charCursorStyle");
1975 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1976 if (!strcmp(value.addr, "CHARCURSOR_INVISIBLE"))
1977 _DtTermPrimSetCursorVisible((Widget )dtw, False);
1980 if (!strcmp(value.addr, "CHARCURSOR_BAR"))
1981 (void) XtSetArg(al[ac], DtNcharCursorStyle, DtTERM_CHAR_CURSOR_BAR);
1983 (void) XtSetArg(al[ac], DtNcharCursorStyle, DtTERM_CHAR_CURSOR_BOX);
1987 xrm_name [1] = XrmStringToQuark ("blinkRate");
1988 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
1989 blinkRate = atoi((char *)value.addr);
1990 (void) XtSetArg(al[ac], DtNblinkRate, blinkRate); ac++;
1992 xrm_name[1] = XrmStringToQuark ("jumpScroll");
1993 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
1994 {(void) XtSetArg(al[ac], DtNjumpScroll, False); ac++;}
1996 xrm_name[1] = XrmStringToQuark ("marginBell");
1997 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
1999 (void) XtSetArg(al[ac], DtNmarginBell, True); ac++;
2000 xrm_name [1] = XrmStringToQuark ("nMarginBell");
2001 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
2002 nMarginBell = atoi((char *)value.addr);
2003 (void) XtSetArg(al[ac], DtNnMarginBell, nMarginBell);ac++;
2006 xrm_name[1] = XrmStringToQuark ("visualBell");
2007 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2008 {(void) XtSetArg(al[ac], DtNvisualBell, True); ac++;}
2010 xrm_name[1] = XrmStringToQuark ("reverseVideo");
2011 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2012 {(void) XtSetArg(al[ac], DtNreverseVideo, True); ac++;}
2014 xrm_name[1] = XrmStringToQuark ("appCursorDefault");
2015 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2016 {(void) XtSetArg(al[ac], DtNappCursorDefault, True); ac++;}
2018 xrm_name[1] = XrmStringToQuark ("appKeypadDefault");
2019 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2020 {(void) XtSetArg(al[ac], DtNappKeypadDefault, True); ac++;}
2022 xrm_name[1] = XrmStringToQuark ("autoWrap");
2023 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2024 {(void) XtSetArg(al[ac], DtNautoWrap, False); ac++;}
2026 xrm_name[1] = XrmStringToQuark ("reverseWrap");
2027 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2028 {(void) XtSetArg(al[ac], DtNreverseWrap, True); ac++;}
2030 xrm_name[1] = XrmStringToQuark ("c132");
2031 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2032 {(void) XtSetArg(al[ac], DtNc132, True); ac++;}
2034 xrm_name[1] = XrmStringToQuark ("reverseVideo");
2035 if(XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value) == True)
2036 {(void) XtSetArg(al[ac], DtNreverseVideo, True); ac++;}
2038 xrm_name[1] = XrmStringToQuark ("userKeyLock");
2039 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
2040 if (!strcmp(value.addr, "True"))
2041 _DtTermSetUserKeyLock((Widget) dtw, True);
2043 _DtTermSetUserKeyLock((Widget) dtw, False);
2045 xrm_name[1] = XrmStringToQuark ("autoLineFeed");
2046 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
2047 if (!strcmp(value.addr, "True"))
2048 _DtTermSetAutoLineFeed((Widget) dtw, True);
2050 _DtTermSetAutoLineFeed((Widget) dtw, False);
2052 (void) XtSetValues((Widget)dtw, al, ac);
2054 xrm_name[1] = XrmStringToQuark ("currentWorkingDirectory");
2055 XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
2056 if (value.addr && *value.addr) {
2057 _DtTermSetCurrentWorkingDirectory((Widget) dtw, value.addr);
2060 /* realize the interface...
2062 (void) XtRealizeWidget(shellWidget);
2066 /* Pass 2, after widget realization...
2069 /* get workspace list */
2070 xrm_name[1] = XrmStringToQuark("workspaceList");
2071 XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value);
2072 SetWorkSpaceHints( XtParent((Widget)dtvw),(char *) value.addr);
2083 Atom * workspace_atoms = NULL;
2084 int num_workspaces=0;
2089 ptr = strchr (workspaces, ' ');
2094 /* if we haven't hit a match, try interning the atom... */
2095 if (thisWsAtom == None) {
2096 thisWsAtom = XmInternAtom (XtDisplay(shell), workspaces, True);
2099 if (thisWsAtom != None) {
2100 workspace_atoms = (Atom *) XtRealloc ((char *)workspace_atoms,
2101 sizeof (Atom) * (num_workspaces + 1));
2102 workspace_atoms[num_workspaces] = thisWsAtom;
2108 workspaces = ptr + 1;
2110 } while (ptr != NULL);
2112 if (num_workspaces > 0) {
2113 DtWsmSetWorkspacesOccupied(XtDisplay(shell), XtWindow (shell),
2114 workspace_atoms, num_workspaces);
2117 XtFree ((char *) workspace_atoms);
2118 workspace_atoms = NULL;