1882 lines
67 KiB
C
1882 lines
67 KiB
C
/*
|
|
* 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
|
|
*/
|
|
/* $TOG: main.c /main/27 1999/09/15 15:16:51 mgreess $ */
|
|
/**********************************<+>*************************************
|
|
***************************************************************************
|
|
**
|
|
** File: main.c
|
|
**
|
|
** Project: DT dtpad, a memo maker type editor based on the Dt Editor
|
|
** widget.
|
|
**
|
|
** Description:
|
|
** -----------
|
|
**
|
|
** Dtpad is basically a wrapper around the DT Editor widget providing:
|
|
**
|
|
** o a menu interface to Editor widget features
|
|
** o client/server architecture (via the DtSvc library)
|
|
** o session save/restore
|
|
** o wm_delete protocol and "panic save" signal handling
|
|
** o ToolTalk support of media exchange and desktop message sets
|
|
** o printing
|
|
**
|
|
** This file contains the routines that control the client/server architecture
|
|
** of dtpad and creation of the top level widgets.
|
|
**
|
|
** See the comments preceding main() for a description of the client/server
|
|
** architecture of dtpad as well as an overview of the routine hierarchy of
|
|
** dtpad. The widget hierarchy of dtpad goes something like this:
|
|
**
|
|
** Creating Routine Creating Function Widget
|
|
** ---------------------- ---------------------- -----------------------
|
|
** (1) CreateFirstPad: XtInitialize() topLevelWithWmCommand
|
|
** (2) CreateFirstPad: XtAppCreateShell() pPad->app_shell
|
|
** (3) RealizeNewPad: XmCreateMainWindow() pPad->mainWindow
|
|
** CreateMenuBar: XmCreateMenuBar() pPad->menu_bar
|
|
** CreateFileMenu: XmCreatePulldownMenu() (file_pane)
|
|
** CreateEditMenu: XmCreatePulldownMenu() (edit_pane)
|
|
** CreateFormatMenu: XmCreatePulldownMenu() (format_pane)
|
|
** CreateOptionsMenu:XmCreatePulldownMenu() (options_pane)
|
|
** CreateHelpMenu: XmCreatePulldownMenu() (help_pane)
|
|
** CreateEditorWidget: DtCreateEditor() pPad->editor
|
|
** #ifdef POPUP
|
|
** CreatePopupMenu: XmCreatePopupMenu() pPad->popup
|
|
** #endif
|
|
**
|
|
** (1) The topLevelWithWmCommand is only created once whereas the others
|
|
** are created and realized whenever a Editor window is opened.
|
|
** The display is opened once but stored in the pPad Editor struct
|
|
** associated with each opened edit window.
|
|
** (2) The pPad->app_shell is created initially (in CreateFirstPad) and
|
|
** (in dtpad.c:FindOrCreatePad) whenever the server receives a message
|
|
** (via messageCB.c:OpenNewPadCB) to start another edit session.
|
|
** (3) The pPad->mainWindow as well as the pPad->menu_bar and pPad->editor
|
|
** are only created via RealizeNewPad. RealizeNewPad is called
|
|
** whenever an app_shell is created and also when a session is restored.
|
|
**
|
|
*******************************************************************
|
|
** (c) Copyright Hewlett-Packard Company, 1990 - 1995. All rights are
|
|
** reserved. Copying or other reproduction of this program
|
|
** except for archival purposes is prohibited without prior
|
|
** written consent of Hewlett-Packard Company.
|
|
********************************************************************
|
|
**
|
|
********************************************************************
|
|
** (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
|
|
** (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
|
|
** (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
|
|
** (c) Copyright 1993, 1994, 1995 Novell, Inc.
|
|
********************************************************************
|
|
**
|
|
**
|
|
**************************************************************************
|
|
**********************************<+>*************************************/
|
|
#include "dtpad.h"
|
|
#include "stdlib.h"
|
|
#include "messageParam.h"
|
|
#include "signal.h"
|
|
#include <locale.h>
|
|
#include <sys/wait.h>
|
|
#include <Xm/MwmUtil.h>
|
|
#include <Dt/EnvControlP.h>
|
|
#include <Dt/Lock.h>
|
|
#include <Dt/Action.h>
|
|
#include <Dt/DtpadM.h>
|
|
#include <Dt/MsgCatP.h>
|
|
#include "X11/Xutil.h"
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/ShellP.h>
|
|
|
|
#ifdef HAVE_EDITRES
|
|
#include <X11/Xmu/Editres.h>
|
|
#endif
|
|
|
|
#ifndef NO_MESSAGE_CATALOG
|
|
# define TRUE 1
|
|
# define FALSE 0
|
|
# include <Dt/MsgCatP.h>
|
|
# if !defined(NL_CAT_LOCALE)
|
|
# define NL_CAT_LOCALE 0
|
|
# endif
|
|
static const char catalogName[] = "dtpad";
|
|
# define _DTPAD_CAT_NAME catalogName
|
|
#endif
|
|
|
|
void SetWorkSpaceHints(Widget shell, char *workspaces);
|
|
|
|
|
|
|
|
/************************************************************************
|
|
* Global Definitions
|
|
************************************************************************/
|
|
|
|
Atom xa_WM_DELETE_WINDOW;
|
|
|
|
/* bits for exclamation point in dialog */
|
|
unsigned char warningBits[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00,
|
|
0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00,
|
|
0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00,
|
|
0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static XtResource resources[] = {
|
|
{"statusLine", "StatusLine", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,statusLine), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"wrapToFit", "WrapToFit", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,wordWrap), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"overstrike", "Overstrike", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,overstrike), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"saveOnClose", "SaveOnClose", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,saveOnClose), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"missingFileWarning", "MissingFileWarning", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,missingFileWarning), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"readOnlyWarning", "ReadOnlyWarning", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,readOnlyWarning), XmRImmediate, (XtPointer)True,
|
|
},
|
|
{"nameChange", "NameChange", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,nameChange), XmRImmediate, (XtPointer)True,
|
|
},
|
|
{"viewOnly", "ViewOnly", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,viewOnly), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"workspaceList", "WorkspaceList", XmRString, sizeof(char *),
|
|
XtOffset(ApplicationDataPtr,workspaceList), XmRImmediate,(XtPointer)NULL,
|
|
},
|
|
{"session", "Session", XmRString, sizeof(char *),
|
|
XtOffset(ApplicationDataPtr,session), XmRImmediate, (XtPointer)NULL,
|
|
},
|
|
|
|
{"standAlone", "StandAlone", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,standAlone), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"blocking", "Blocking", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,blocking), XmRImmediate, (XtPointer)True,
|
|
},
|
|
{"server", "Server", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,server), XmRImmediate, (XtPointer)False,
|
|
},
|
|
{"exitOnLastClose", "ExitOnLastClose", XmRBoolean, sizeof(Boolean),
|
|
XtOffset(ApplicationDataPtr,exitOnLastClose), XmRImmediate, (XtPointer)False,
|
|
},
|
|
};
|
|
|
|
static XrmOptionDescRec option_list[] =
|
|
{
|
|
{"-statusLine", "statusLine", XrmoptionNoArg,(caddr_t)"TRUE"},
|
|
{"-wrapToFit", "wrapToFit", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-overstrike", "overstrike", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-saveOnClose", "saveOnClose", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-missingFileWarning", "missingFileWarning", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-noReadOnlyWarning", "readOnlyWarning", XrmoptionNoArg, (caddr_t)"FALSE"},
|
|
{"-noNameChange", "nameChange", XrmoptionNoArg, (caddr_t)"FALSE"},
|
|
{"-viewOnly", "viewOnly", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-workspaceList", "workspaceList", XrmoptionSepArg, (caddr_t)NULL},
|
|
{"-session", "session", XrmoptionSepArg, (caddr_t)NULL},
|
|
|
|
{"-standAlone", "standAlone", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-noBlocking", "blocking", XrmoptionNoArg, (caddr_t)"FALSE"},
|
|
{"-server", "server", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
{"-exitOnLastClose", "exitOnLastClose", XrmoptionNoArg, (caddr_t)"TRUE"},
|
|
};
|
|
|
|
static String fallbacks[] =
|
|
{
|
|
"Dtpad.Print.width:8.5in",
|
|
"Dtpad.Print.height:11.0in",
|
|
"Dtpad.Print*renderTable:-adobe-courier-medium-r-normal--0-140-0-0-m-0-iso8859-1",
|
|
"Dtpad.Print*shadowThickness:0",
|
|
NULL
|
|
};
|
|
|
|
ApplicationData initialServerResources;
|
|
char *initialServerGeometry;
|
|
Editor *pPadList = (Editor *)NULL;
|
|
int numActivePads = 0;
|
|
Widget topLevelWithWmCommand;
|
|
Boolean ActionDBInitialized = False;
|
|
int waitCB = 1;
|
|
char *value = NULL;
|
|
|
|
char **pArgv = NULL;
|
|
int pArgc = 0;
|
|
|
|
|
|
/************************************************************************
|
|
* Forward Declarations
|
|
************************************************************************/
|
|
|
|
static Editor *CreateFirstPad(
|
|
int *pArgc,
|
|
char **argv);
|
|
static void SendMessageToServer(
|
|
Editor *pPad,
|
|
int argc,
|
|
char **argv);
|
|
static void InitEditSessionAndFirstPad(
|
|
Editor *pPad,
|
|
int argc,
|
|
char **argv);
|
|
static void SetStateFromResources(
|
|
Editor *pPad);
|
|
static Tt_callback_action HostCB(
|
|
Tt_message m,
|
|
Tt_pattern p);
|
|
static void Usage(
|
|
char **argv );
|
|
static int dtpadXErrorHandler(
|
|
Display *display,
|
|
XErrorEvent *xerr);
|
|
static int dtpadXIOErrorHandler(
|
|
Display *display);
|
|
|
|
|
|
|
|
/************************************************************************
|
|
* main - controls the high level client/server processing of dtpad based
|
|
* on the three modes of operation:
|
|
*
|
|
* 1) requestor mode - send message to dtpad server to do actual
|
|
* editing
|
|
* 2) server mode - do editing for one or more dtpad requestors
|
|
* (via multiple edit windows)
|
|
* 3) standAlone mode - do all editing alone (via a single
|
|
* edit window)
|
|
*
|
|
************************************************************************/
|
|
int
|
|
main(
|
|
int argc,
|
|
char **argv )
|
|
{
|
|
Editor *pPad;
|
|
|
|
char *sessId, *tmpStr;
|
|
Tt_pattern requests2Handle;
|
|
Tt_message msg;
|
|
Tt_status status = TT_OK;
|
|
int ttFd; /* ToolTalk file descriptor */
|
|
|
|
/* Set up the environment to allow relocation of the various bitmaps
|
|
* and message catalogs. */
|
|
(void)_DtEnvControl(DT_ENV_SET);
|
|
|
|
(void) XtSetLanguageProc((XtAppContext)NULL, (XtLanguageProc)NULL,
|
|
(XtPointer)NULL);
|
|
|
|
pArgc = argc;
|
|
pArgv = argv;
|
|
pPad = CreateFirstPad(&argc, argv);
|
|
XtAppSetFallbackResources(pPad->app_context, fallbacks);
|
|
|
|
if (DtInitialize(pPad->display, topLevelWithWmCommand, pPad->progname,
|
|
DTPAD_TOOL_CLASS) != True ) {
|
|
XtError((char *) GETMESSAGE(7, 4,
|
|
"Unable to initialize Desktop services ... exiting Text Editor."));
|
|
}
|
|
|
|
/* -----> Resolve conficts between -standAlone, -session and -server */
|
|
if (pPad->xrdb.standAlone) { /* standAlone takes precedence */
|
|
pPad->xrdb.session = (char *) NULL;
|
|
pPad->xrdb.server = False;
|
|
} else if (pPad->xrdb.session) { /* session is 2nd in precedence */
|
|
pPad->xrdb.server = False;
|
|
pPad->xrdb.blocking = False;
|
|
}
|
|
|
|
if (pPad->xrdb.standAlone) {
|
|
|
|
/*--------------------------------------------------------
|
|
* StandAlone Mode
|
|
*
|
|
* Initialize self as an editing session.
|
|
*
|
|
*-------------------------------------------------------*/
|
|
InitEditSessionAndFirstPad(pPad, argc, argv);
|
|
|
|
} else if (pPad->xrdb.server) {
|
|
/*--------------------------------------------------------
|
|
* Server Mode
|
|
*
|
|
* Indicate the types of messages interested in and
|
|
* callbacks to process each message type, then
|
|
* initialize self as an editing session.
|
|
*
|
|
*-------------------------------------------------------*/
|
|
/* Exit if there's another dtpad server servicing the display */
|
|
if (_DtGetLock(pPad->display, DTPAD_CLASS_NAME) == 0) {
|
|
FileWidgets *pFileWidgets = &pPad->fileStuff.fileWidgets;
|
|
Boolean validTT= True;
|
|
Boolean notDone= True;
|
|
|
|
/* we want to get the hostname of where the server is running.
|
|
* To do that, we need to open a ToolTalk connection, the use
|
|
* the Desktop request "Get_Sysinfo" to get the host name.
|
|
*/
|
|
while(validTT && notDone)
|
|
{
|
|
/* go open a simple ToolTalk connection */
|
|
status = TTdesktopOpen( &ttFd, pPad, False );
|
|
if (TT_OK != status) {
|
|
TTwarning( pPad, status,
|
|
GETMESSAGE(7, 11, "Exiting text editor ...") );
|
|
exit(status);
|
|
}
|
|
|
|
/* Create the message */
|
|
msg = tttk_message_create(
|
|
0, /* no inherited context */
|
|
TT_REQUEST, /* class */
|
|
TT_SESSION, /* scope */
|
|
0, /* TT_PROCEDURE addr */
|
|
"Get_Sysinfo", /* op */
|
|
(Tt_message_callback) HostCB); /* msg callback */
|
|
status = tt_ptr_error(msg);
|
|
if(status != TT_OK) {
|
|
validTT= False;
|
|
break;
|
|
}
|
|
|
|
/* set the ptype to DTPAD */
|
|
status = tt_message_handler_ptype_set(msg, "DTPAD");
|
|
if(status != TT_OK) {
|
|
validTT= False;
|
|
break;
|
|
}
|
|
|
|
/* the first two variable returned by Get_Sysinfo is all we need
|
|
* to get the hostname. hostname is the 2nd variable. Let's
|
|
* register that we want them
|
|
*/
|
|
status = tt_message_arg_add(msg, TT_OUT, "string", 0);
|
|
if(status != TT_OK) {
|
|
validTT= False;
|
|
break;
|
|
}
|
|
status = tt_message_arg_add(msg, TT_OUT, "string", 0);
|
|
if(status != TT_OK) {
|
|
validTT= False;
|
|
break;
|
|
}
|
|
|
|
/* Finally, Let's send the Message ... */
|
|
status = tt_message_send(msg);
|
|
if(status != TT_OK) {
|
|
validTT= False;
|
|
break;
|
|
}
|
|
|
|
/* block for 10 seconds or until the HostCB is called */
|
|
tttk_block_while(pPad->app_context, &waitCB, 10000);
|
|
notDone = False;
|
|
}
|
|
|
|
/* If we sent a valid ToolTalk message and the Callback set value
|
|
* to something other then NULL, lets use it to print out the
|
|
* message.
|
|
*/
|
|
if(validTT && value != NULL) {
|
|
tmpStr = (char *)XtMalloc(strlen(GETMESSAGE(7, 7, "ERROR: A dtpad server on %s\nis already serving this display.")) + strlen(value) + 10);
|
|
|
|
sprintf(tmpStr, GETMESSAGE(7, 7, "ERROR: A dtpad server on %s\nis already serving this display."), value);
|
|
Warning(pPad, tmpStr, XmDIALOG_ERROR);
|
|
}
|
|
else
|
|
/* ToolTalk connection/message was bogus or unable to get
|
|
* hostname in Callback.
|
|
*/
|
|
Warning(pPad, GETMESSAGE(7, 8, "ERROR: A dtpad server is already\nserving this display."), XmDIALOG_ERROR);
|
|
|
|
XtAddCallback (pFileWidgets->gen_warning, XmNokCallback,
|
|
exitCB, (XtPointer) pPad);
|
|
XFlush(pPad->display);
|
|
XSync(pPad->display, False);
|
|
}
|
|
|
|
InitEditSessionAndFirstPad(pPad, argc, argv);
|
|
|
|
/* -----> Initialize TT connection & process start message */
|
|
status = TTstartDesktopMediaExchange(topLevelWithWmCommand, pPad);
|
|
if (TT_OK == status)
|
|
tttk_Xt_input_handler(0, 0, 0);
|
|
else {
|
|
TTwarning( pPad, status,
|
|
GETMESSAGE(7, 11, "Exiting text editor ...") );
|
|
exit(status);
|
|
}
|
|
|
|
} else {
|
|
|
|
/*--------------------------------------------------------
|
|
* Requestor Mode
|
|
*
|
|
* Just tell server to do actual editing and wait
|
|
* for DTPAD_DONE msg from server to exit (or exit
|
|
* immediately if -noBlocking).
|
|
*
|
|
*-------------------------------------------------------*/
|
|
|
|
/* Send message to dtpad server to either open-and-edit a
|
|
* file or to restart a session. Also set up callbacks to
|
|
* handle success, failure and done-editing notification.
|
|
*/
|
|
SendMessageToServer(pPad, argc, argv);
|
|
}
|
|
|
|
XtAppMainLoop(pPad->app_context);
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* CreateFirstPad - Performs initialization common to all modes of
|
|
* operation (i.e. to requestor mode, server mode and standAlone
|
|
* mode).
|
|
*
|
|
* This routine initializes the primary sturcture used by dtpad, pPadList
|
|
* which is a list of Editor structs (pPad) with one entry per edit request.
|
|
*
|
|
* Specifically, this routine:
|
|
*
|
|
* 1) creates the first entry in pPadList and returns a pointer to it
|
|
* 2) initializes Xt and the display, and creates the top level widget
|
|
* 3) adds the "save yourself" protocol to the top level widget
|
|
* 4) creates the applic shell widget and applic context
|
|
* 5) loads the application resources to the initial pPad and sets some
|
|
* initial editing process values
|
|
*
|
|
* Creation of subsequent entries in the pPadList (1) and creation of
|
|
* corresponding applic shells and contexts (4) are also done by the server
|
|
* (via TTmedia_ptype_declareCB) for each new edit request that it receives.
|
|
* This means that there is one top level widget and display connection
|
|
* per process and one applic shell widget and applic context PER EDIT
|
|
* REQUEST (i.e. per entry in pPadList).
|
|
*
|
|
* Note that CreateFirstPad is run in all modes the first time the requestor
|
|
* or server starts up and that resource are only loaded via this routine.
|
|
* This means that resources are obtained (via XtGetApplicationResources)
|
|
* on both the requestor and the server and saved in the initial pPad Editor
|
|
* on the requestor or server. This also means that for requestor dtpads, a
|
|
* pPad struct is created on both the requestor and the server (the server
|
|
* pPad may be the initial struct created by CreateFirstPad or it may be a
|
|
* subsequent pPad created by TTmedia_ptype_declareCB but with the initial
|
|
* server resource values). For requestor mode, the dtpad pPad resources are
|
|
* shipped to the server (in the TTDT_EDIT request) where they override
|
|
* resources in the corresponding pPad struct on the server.
|
|
*
|
|
* XXX - Some of the stuff in this routine probably does not need to be
|
|
* done in all modes of operation - primarily in requestor mode.
|
|
* Note that resources need to be loaded in all modes.
|
|
*
|
|
* [SuG 5/12/95] Modified for fishy argument checking.
|
|
************************************************************************/
|
|
static Editor *
|
|
CreateFirstPad(
|
|
int *pArgc,
|
|
char **argv)
|
|
{
|
|
int argc_l;
|
|
char **argv_l, **c_argv_l;
|
|
Editor *pPad;
|
|
Arg al[10];
|
|
int ac;
|
|
Widget foo;
|
|
int i;
|
|
/* Added for the argument fix*/
|
|
char* inS;
|
|
int in;
|
|
Atom xa_WM_SAVE_YOURSELF;
|
|
extern char *optarg;
|
|
extern int optind, opterr, optind;
|
|
char c;
|
|
|
|
/* Create the 1st Editor entry in list of Editor instances.
|
|
* This is also done in FindOrCreatePad() for each Editor pad instance */
|
|
CreatePad(&pPad);
|
|
|
|
if (pPad->progname=MbStrrchr(argv[0], '/'))
|
|
pPad->progname++;
|
|
else
|
|
pPad->progname = argv[0];
|
|
|
|
/* Initialize the toolkit, open the display and create top level widget */
|
|
topLevelWithWmCommand = XtInitialize(argv[0], DTPAD_CLASS_NAME,
|
|
option_list, XtNumber(option_list),
|
|
(int *) pArgc, argv);
|
|
|
|
#if 0
|
|
/*
|
|
* At this point Xt has stripped for us all valid arguments.
|
|
* If number of arguments is <= 2, first one is program name and second
|
|
* one will be file name always (we don't care if it has a '-').
|
|
*/
|
|
if (*pArgc > 2) {
|
|
/*
|
|
* Now we check for illegal arguments, note argv[0] is
|
|
* progname, so we skip that, argv[last] should be file name
|
|
* so we check for '-' character in (i = 1 to i = (n-1)) to
|
|
* catch inbetween invalids.
|
|
* Any extras with '-' as first characters are treated as
|
|
* illegal options and ones without it as superfluous
|
|
* arguments.
|
|
*/
|
|
for (i = 1; i < ((*pArgc) - 1); i++)
|
|
{
|
|
inS = MbStrchri(argv[i], '-', &in);
|
|
if (inS != NULL) {
|
|
if (in == 0)
|
|
{
|
|
printf(GETMESSAGE(2, 2,"dtpad: illegal option: %s"),
|
|
argv[i]);
|
|
printf("\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
else {
|
|
printf(GETMESSAGE(2, 3, "dtpad: extra argument: %s"),
|
|
argv[i]);
|
|
printf("\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
ac = 0;
|
|
XtSetArg(al[ac], XmNgeometry, &pPad->geometry); ac++;
|
|
XtGetValues(topLevelWithWmCommand, al, ac);
|
|
|
|
/* Realize the top level widget */
|
|
XtSetMappedWhenManaged(topLevelWithWmCommand, False);
|
|
XtRealizeWidget(topLevelWithWmCommand);
|
|
|
|
/* Determine the display connection */
|
|
if (!(pPad->display = XtDisplay(topLevelWithWmCommand))) {
|
|
XtError((char *) GETMESSAGE(7, 5,
|
|
"Can not open display ... exiting Text Editor."));
|
|
}
|
|
|
|
/* TTT - ToolTalk Debug
|
|
* XSynchronize(pPad->display, True);
|
|
*/
|
|
|
|
/* Add the Save-Yourself protocol to the top level widget.
|
|
* Application shell widgets (one per Editor request) don't need it,
|
|
* since they don't have a WM_COMMAND property on them. */
|
|
xa_WM_SAVE_YOURSELF = XInternAtom(pPad->display,
|
|
"WM_SAVE_YOURSELF", False);
|
|
XmAddWMProtocolCallback(topLevelWithWmCommand, xa_WM_SAVE_YOURSELF,
|
|
(XtCallbackProc)SaveSessionCB, (XtPointer)pPadList);
|
|
|
|
|
|
/* Create the application shell widget and obtain the application context.
|
|
* This is also done in FindOrCreatePad() for each Editor pad instance */
|
|
ac = 0;
|
|
XtSetArg(al[ac], XmNargv, &argv_l); ac++;
|
|
XtSetArg(al[ac], XmNargc, &argc_l); ac++;
|
|
XtGetValues(topLevelWithWmCommand, al, ac);
|
|
|
|
c_argv_l = (char **) XtMalloc(argc_l * sizeof(char*));
|
|
for (i=0; i<argc_l; i++)
|
|
c_argv_l[i] = strdup(argv_l[i]);
|
|
|
|
ac = 0;
|
|
XtSetArg(al[ac], XmNargv, argv_l); ac++;
|
|
XtSetArg(al[ac], XmNargc, argc_l); ac++;
|
|
pPad->app_shell = XtAppCreateShell(pPad->progname, DTPAD_CLASS_NAME,
|
|
applicationShellWidgetClass,
|
|
pPad->display, al, ac);
|
|
pPad->app_context = XtWidgetToApplicationContext(pPad->app_shell);
|
|
|
|
/* Get the application resources */
|
|
XtGetApplicationResources(pPad->app_shell, &pPad->xrdb, resources,
|
|
XtNumber(resources), NULL, 0);
|
|
if (pPad->xrdb.server) {
|
|
initialServerResources = pPad->xrdb;
|
|
initialServerResources.server = False; /* so window will be mapped */
|
|
initialServerGeometry = pPad->geometry;
|
|
if(pPad->xrdb.workspaceList)
|
|
pPad->xrdb.workspaceList = strdup(pPad->xrdb.workspaceList);
|
|
if(pPad->xrdb.session)
|
|
pPad->xrdb.session = strdup(pPad->xrdb.session);
|
|
pPad->geometry = strdup(pPad->geometry);
|
|
}
|
|
|
|
/* Set some initial Editor instance values */
|
|
if (pPad->xrdb.server == False) {
|
|
pPad->inUse = True;
|
|
}
|
|
|
|
return pPad;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* CreatePad - creates a new entry in the pPadList of Editor structs.
|
|
* Both the top of the list (the global, pPadList) and the current
|
|
* entry (whose address is passed as a parameter) are updated to
|
|
* point to the newly created entry.
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
void
|
|
CreatePad(
|
|
Editor **ppPad)
|
|
{
|
|
Editor *pPad;
|
|
|
|
pPad = *ppPad = (Editor *) XtCalloc(1, sizeof(Editor));
|
|
pPad->pPrevPad = (Editor *)NULL;
|
|
|
|
if (pPadList == (Editor *)NULL) {
|
|
pPadList = pPad;
|
|
pPad->pNextPad = (Editor *)NULL;
|
|
} else {
|
|
Editor *pTemp = pPadList;
|
|
pPadList = pPad;
|
|
pPad->pNextPad = pTemp;
|
|
pTemp->pPrevPad = pPad;
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* SetupLoadArgs - pack requestor options into the Edit request
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
void
|
|
SetupLoadArgs(Tt_message m, Editor *pPad)
|
|
{
|
|
ApplicationDataPtr pArgs = &pPad->xrdb;
|
|
|
|
/* -----> Ignore all other resources if restoring a session.
|
|
* XXX - Currently, an Edit request is not used to restore a session.
|
|
* Instead a "private" ToolTalk request, DtPadSession_Run is
|
|
* used (which is sent in SendMessageToServer() and handled in
|
|
* HandleTtRequest() - the handler is setup in main()) */
|
|
if (pPad->xrdb.session != (char *)NULL) {
|
|
tt_message_context_set(m, "SESSION", pArgs->session);
|
|
return;
|
|
}
|
|
|
|
/* -----> The following is the only resource passed to the text editor
|
|
* server which is not a text editor specific resource.
|
|
* It is always passed. */
|
|
if (pPad->geometry != (char *)NULL) {
|
|
tt_message_context_set(m, "GEOMETRY", pPad->geometry);
|
|
}
|
|
|
|
/* -----> Basic options */
|
|
tt_message_context_set(m, "STATUSLINE", pArgs->statusLine ? "t" : "f");
|
|
tt_message_context_set(m, "WINDOWWORDWRAP", pArgs->wordWrap ? "t" : "f");
|
|
tt_message_context_set(m, "OVERSTRIKE", pArgs->overstrike ? "t" : "f");
|
|
tt_message_context_set(m, "SAVEONCLOSE", pArgs->saveOnClose ? "t" : "f");
|
|
tt_message_context_set(m, "MISSINGFILEWARNING", pArgs->missingFileWarning ? "t" : "f");
|
|
tt_message_context_set(m, "NOREADONLYWARNING",
|
|
pArgs->readOnlyWarning ? "t" : "f");
|
|
tt_message_context_set(m, "NONAMECHANGE",
|
|
pArgs->nameChange ? "t" : "f");
|
|
tt_message_context_set(m, "VIEWONLY", pArgs->viewOnly ? "t" : "f");
|
|
tt_message_context_set(m, "WORKSPACELIST", pArgs->workspaceList);
|
|
|
|
/* -----> client/server control options */
|
|
if (pArgs->blocking == True) {
|
|
char *buf = (char *)XtMalloc(32);
|
|
sprintf(buf, "%ld", (long)getpid());
|
|
tt_message_context_set(m, "BLOCKING", buf);
|
|
pPad->blockChannel = buf;
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* pLoadMsgCB - requestor side ttmedia_load() callback setup in
|
|
* SendMessageToServer() to handle Replies from the dtpad server.
|
|
*
|
|
* Replies are sent by the server via the following functions:
|
|
*
|
|
* ttMediaLoadReply (in TTmediaReply). TTmediaReply is executed when:
|
|
*
|
|
* 1) an Edit or Display request is being processed and either the
|
|
* edit window is closed or a new file is selected by the user
|
|
* 2) an Instantiate request is being processed and the edit window
|
|
* is closed
|
|
* 3) a Quit request is handled which matches the Edit request
|
|
*
|
|
* tttk_message_fail. tttk_message_fail is normally called whenever
|
|
*
|
|
* 1) the edit/display/instantiate request can't be handled
|
|
* 2) a buffer is being edited and the user closed the window
|
|
* (XXX - actually, this should only be done if a buffer
|
|
* is being edited and there are unsaved changes
|
|
* - otherwise ttMediaLoadReply should be used)
|
|
* 3) a Quit request is handled for the window and there are
|
|
* unsaved changed
|
|
*
|
|
************************************************************************/
|
|
Tt_message
|
|
pLoadMsgCB(Tt_message msg,
|
|
void *clientData,
|
|
Tttk_op op,
|
|
unsigned char *contents,
|
|
int len,
|
|
char *file)
|
|
{
|
|
Tt_state state = tt_message_state(msg);
|
|
StartupStruct *pStruct = (StartupStruct *)tt_message_user(msg, 0);
|
|
|
|
if (state == TT_HANDLED) {
|
|
tttk_message_destroy(msg);
|
|
exit(0);
|
|
} else if (state == TT_FAILED) {
|
|
pStruct->pPad->inUse = True;
|
|
pStruct->pPad->xrdb.server = False;
|
|
pStruct->pPad->xrdb.standAlone = True;
|
|
InitEditSessionAndFirstPad(pStruct->pPad, pStruct->argc, pStruct->argv);
|
|
return 0;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* pStatusCB - requestor side ttdt_subcontract_manage() callback setup in
|
|
* SendMessageToServer() to handle Status messages from the dtpad
|
|
* server.
|
|
*
|
|
* The server sends a Status message via ttdt_message_accept() when
|
|
* it determines that it can actually handle the EDIT request.
|
|
*
|
|
************************************************************************/
|
|
Tt_message
|
|
pStatusCB(Tt_message msg,
|
|
void *clientdata,
|
|
Tt_message contract)
|
|
{
|
|
if (clientdata) {
|
|
/* This is the blocking case, just return 0 (we'll exit in
|
|
* pLoadMsgCB when we get a Reply from the dtpad server when it's
|
|
* done handling the request).*/
|
|
return 0;
|
|
} else {
|
|
/* This is the non-blocking case, exit if this is a Status notice */
|
|
if (tttk_string_op(tt_message_op(msg)) == TTDT_STATUS) {
|
|
exit(0);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SendMessageToServer - requestor mode routine to setup callbacks and send
|
|
* a message to the dtpad "server" to do one of the following:
|
|
*
|
|
* case 1) restore dtpad session & exit dtpad requestor immediately
|
|
* case 2) edit a file & exit dtpad requestor immediately
|
|
* case 3) edit a file & and wait till editing is done before exiting
|
|
* requestor dtpad
|
|
*
|
|
************************************************************************/
|
|
static void
|
|
SendMessageToServer(
|
|
Editor *pPad,
|
|
int argc,
|
|
char **argv)
|
|
{
|
|
StartupStruct *pStruct = (StartupStruct *)XtMalloc(sizeof(StartupStruct));
|
|
char *fileName, *pArgs;
|
|
Tt_message msg;
|
|
Tt_status status;
|
|
Tttk_op op;
|
|
|
|
if (pPad->xrdb.session != (char *)NULL) {
|
|
fileName = pPad->xrdb.session;
|
|
} else if (argc > 1) {
|
|
fileName = argv[argc - 1];
|
|
} else {
|
|
fileName = "*";
|
|
}
|
|
|
|
/* -----> Obtain the netfile name of the file to be edited. If the
|
|
* directory can't be accessed via the requestor's host, don't
|
|
* use the server since we can't pass it a netfile name and we
|
|
* can't assume the filename is appropriate on the server's host.
|
|
*/
|
|
pPad->fileStuff.netfile = tt_file_netfile(fileName);
|
|
status = tt_ptr_error(pPad->fileStuff.netfile);
|
|
if (status != TT_OK) {
|
|
tt_free(pPad->fileStuff.netfile);
|
|
pPad->fileStuff.netfile = (char *) NULL;
|
|
pPad->xrdb.standAlone = True;
|
|
InitEditSessionAndFirstPad(pPad, argc, argv); /* start standAlone */
|
|
TTwarning( pPad, status,
|
|
GETMESSAGE(7, 12, "Running in standalone mode ...") );
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Keep from saving our session if we've sent a message to the server.
|
|
* We'll restore this to true iff the server sends a failure notification.
|
|
*/
|
|
pPad->inUse = False;
|
|
|
|
pStruct->pPad = pPad;
|
|
pStruct->argc = argc;
|
|
pStruct->argv = argv;
|
|
|
|
#ifdef HAVE_EDITRES
|
|
XtAddEventHandler(topLevelWithWmCommand, 0, True,
|
|
(XtEventHandler) _XEditResCheckMessages,
|
|
(XtPointer) NULL);
|
|
#endif
|
|
|
|
status = TTstartDesktopMediaExchange(topLevelWithWmCommand, pPad);
|
|
if (TT_OK != status) {
|
|
tt_free(pPad->fileStuff.netfile);
|
|
pPad->fileStuff.netfile = (char *) NULL;
|
|
pPad->xrdb.standAlone = True;
|
|
InitEditSessionAndFirstPad(pPad, argc, argv);
|
|
TTwarning( pPad, status,
|
|
GETMESSAGE(7, 12, "Running in standalone mode ...") );
|
|
return;
|
|
}
|
|
|
|
/*--------------------------------------------------------
|
|
* case 2 (noBlocking) - exit if the request is successfully
|
|
* handled by the dtpad server.
|
|
* case 3 (Blocking) - do nothing if the request is successfully
|
|
* handled, then wait for a Reply from the dtpad
|
|
* server to exit.
|
|
*
|
|
* Build and send either a TTME_EDIT request if a file is specified
|
|
* or TTME_INSTANTIATE if no file is specified. These requests
|
|
* are handled via TTmedia_ptype_declareCB() on the dtpad server.
|
|
*
|
|
* 1. If server can not handle the request, it will fail the request
|
|
* immediately. pLoadMsgCB will receive the reply message and
|
|
* start a standAlone dtpad.
|
|
* 2. If server can handle the request, it will send a Status notice.
|
|
* pStatusCB will receive the notice and either exit (noBlocking)
|
|
* or do nothing (Blocking). The server will then reply to a
|
|
* TTME_EDIT request when editing for the specified file/buffer
|
|
* is done (the edit window may still remain open though) and
|
|
* to a TTME_INSTANTIATE request when the edit window is closed.
|
|
*-------------------------------------------------------*/
|
|
|
|
if (strcmp(fileName, "*") == 0) {
|
|
op = TTME_INSTANTIATE;
|
|
} else {
|
|
op = TTME_EDIT;
|
|
}
|
|
|
|
msg = ttmedia_load(0,
|
|
pLoadMsgCB,
|
|
NULL,
|
|
op,
|
|
"C_STRING",
|
|
NULL,
|
|
0,
|
|
fileName,
|
|
NULL,
|
|
0);
|
|
|
|
status = tt_ptr_error(msg);
|
|
if (tt_is_err(status))
|
|
{
|
|
/* Error message */
|
|
return;
|
|
}
|
|
|
|
ttdt_subcontract_manage(msg,
|
|
pStatusCB,
|
|
NULL,
|
|
(void *) ((XtArgVal) pPad->xrdb.blocking));/* client data */
|
|
|
|
/* Add pArgs to msg using tt_message_context_set */
|
|
SetupLoadArgs(msg, pPad);
|
|
tt_message_user_set(msg, 0, pStruct);
|
|
tt_message_send(msg);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* InitEditSessionAndFirstPad - performs initialization related to
|
|
* starting the edit session and then calls the routine that creates
|
|
* the first pPad Editor.
|
|
*
|
|
* (was InitGlobalAndFirstPad)
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
static void
|
|
InitEditSessionAndFirstPad(
|
|
Editor *pPad,
|
|
int argc,
|
|
char **argv)
|
|
{
|
|
char *pTmp = (char *)NULL;
|
|
|
|
CreateDefaultImage ((char *) warningBits, 32, 32, "warn_image");
|
|
|
|
xa_WM_DELETE_WINDOW = XInternAtom(pPad->display,
|
|
"WM_DELETE_WINDOW", False);
|
|
|
|
/* get the users group and user id for file type checking */
|
|
pPad->group_id = getgid();
|
|
pPad->user_id = getuid();
|
|
|
|
/* Set up file name */
|
|
if (pPad->saveRestore == True && argv[3] != NULL) {
|
|
pTmp = argv[3];
|
|
} else if (argc > 1) {
|
|
pTmp = argv[argc - 1];
|
|
}
|
|
|
|
if (pTmp != (char *)NULL) {
|
|
pPad->fileStuff.fileName = (char *) XtMalloc(strlen(pTmp) + 1);
|
|
strcpy(pPad->fileStuff.fileName, pTmp);
|
|
} else {
|
|
pPad->fileStuff.fileName = (char *)NULL;
|
|
}
|
|
pPad->fileStuff.lastIncludeName = (char *)NULL;
|
|
RealizeNewPad(pPad); /* display first pPad Editor window */
|
|
|
|
setPanicConditions(); /* Set up emergency calls to PanicSave */
|
|
|
|
/*
|
|
* Set up a handler for SIGCLD so that the command invoker library
|
|
* doesn't leave zombies.
|
|
*/
|
|
{
|
|
struct sigaction act;
|
|
sigfillset(&act.sa_mask);
|
|
act.sa_flags = 0;
|
|
act.sa_handler = SigcldHndlr;
|
|
sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* RealizeNewPad - creates the GUI components of a pPad Editor, sets
|
|
* pPad resources, maps the window and loads the file to be edited.
|
|
*
|
|
* NOTE: This routine in normally called only when a new edit window is to
|
|
* be displayed. However, it is also called when the server is first
|
|
* started (when no edit requests have been received). In this
|
|
* situation, the window is not mapped and the file is not loaded.
|
|
* These actions are done when the dummy pPad is "reused" when the
|
|
* actual edit request is received from the requestor dtpad.
|
|
*
|
|
************************************************************************/
|
|
void
|
|
RealizeNewPad(
|
|
Editor *pPad)
|
|
{
|
|
Arg al[5]; /* arg list */
|
|
int ac; /* arg count */
|
|
|
|
/* Create the title */
|
|
pPad->dialogTitle = DialogTitle(pPad);
|
|
|
|
/* Set some applic shell resources */
|
|
ac = 0;
|
|
XtSetArg(al[ac], XmNuseAsyncGeometry, True); ac++;
|
|
XtSetArg(al[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
|
|
XtSetArg(al[ac], XmNgeometry, NULL); ac++;
|
|
XtSetValues(pPad->app_shell, al, ac);
|
|
|
|
if (pPad->xrdb.session != NULL) {
|
|
restoreSession(pPad);
|
|
}
|
|
pPad->nodo = False;
|
|
|
|
/* Create Main Window */
|
|
pPad->mainWindow = XmCreateMainWindow (pPad->app_shell, "main", al, 0);
|
|
XtManageChild (pPad->mainWindow);
|
|
|
|
/* Create MenuBar in Main Window */
|
|
CreateMenuBar(pPad);
|
|
XtManageChild (pPad->menu_bar);
|
|
|
|
/* Create the DT Editor Widget in the Main Window. */
|
|
CreateEditorWidget (pPad);
|
|
XtManageChild (pPad->editor);
|
|
|
|
#ifdef POPUP
|
|
/* Create the popup for the editor */
|
|
CreatePopupMenu (pPad);
|
|
#endif
|
|
|
|
/* Associate menu bar and editor widgets created above with menu bar and
|
|
* work area of the main window (the main window command line area and
|
|
* the horizontal/vertical scroll bars are not used) */
|
|
XmMainWindowSetAreas(pPad->mainWindow, pPad->menu_bar,
|
|
(Widget) NULL, (Widget) NULL, (Widget) NULL,
|
|
pPad->editor);
|
|
|
|
/* Realize toplevel widgets. */
|
|
XtSetMappedWhenManaged(pPad->app_shell, False);
|
|
XtRealizeWidget (pPad->app_shell);
|
|
|
|
/* Set the window title */
|
|
ChangeMainWindowTitle(pPad);
|
|
|
|
XSync(pPad->display, 0);
|
|
|
|
/* setup where a close by the window manager will be handled */
|
|
XmAddWMProtocolCallback(pPad->app_shell, xa_WM_DELETE_WINDOW,
|
|
(XtCallbackProc) closeCB, (XtPointer)pPad);
|
|
|
|
/* reset the "save with newLines" flag */
|
|
pPad->fileStuff.saveWithNewlines = True;
|
|
|
|
/* set app shell geometry (pixels), resize hints, position & size hints */
|
|
SetWindowSize(pPad);
|
|
|
|
/* set the state of the pPad based on its resources */
|
|
SetStateFromResources(pPad);
|
|
|
|
/* set File menu SaveAs label/mnemonic based on xrdb.nameChange */
|
|
SetSaveAsLabelAndDialog(pPad);
|
|
|
|
ChangeMainWindowTitle(pPad);
|
|
|
|
/* If we're the server initially starting up, this is a "dummy" edit
|
|
* request and we really don't want to map anything to the display yet
|
|
* (this will be done when the actual edit request comes in and this
|
|
* dummy pPad is reused and mapped). */
|
|
if (pPad->xrdb.server == False) {
|
|
XtSetMappedWhenManaged(pPad->app_shell, True);
|
|
XtPopup(pPad->app_shell, XtGrabNone);
|
|
XtMapWidget(pPad->app_shell);
|
|
numActivePads++;
|
|
}
|
|
|
|
/* load the file (if there's actually a file name specified) */
|
|
LoadFile(pPad, NULL);
|
|
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* ManageOldPad - opens a new file in an exiting Editor pad "window".
|
|
*
|
|
* Existing windows have their widget structure already created but
|
|
* may or may not be managed/visible. The existing window could be
|
|
* any of the following:
|
|
*
|
|
* o the initial "dummy" window created when the server was started
|
|
* up (this window is not managed until the actual edit message
|
|
* from the requestor is received)
|
|
* o a window which has been closed previously
|
|
* o a window that is currently managed/visible and is to be reused
|
|
* (and is identified by the window id resource)
|
|
************************************************************************/
|
|
void
|
|
ManageOldPad(
|
|
Editor *pPad,
|
|
Boolean isCurrentlyVisible)
|
|
{
|
|
|
|
if(pPad->xrdb.session != NULL)
|
|
restoreSession(pPad);
|
|
|
|
/*.. create the title */
|
|
ChangeMainWindowTitle(pPad);
|
|
SetStateFromResources(pPad); /* set the pPad state based on resources */
|
|
pPad->nodo = False;
|
|
|
|
/* set File menu SaveAs label/mnemonic based on xrdb.nameChange */
|
|
SetSaveAsLabelAndDialog(pPad);
|
|
|
|
/* set app shell geometry (pixels), resize hints, position & size hints */
|
|
SetWindowSize(pPad);
|
|
|
|
ChangeMainWindowTitle(pPad);
|
|
|
|
/* If the window is iconified and autoRaise is disabled, then
|
|
* we don't what to deiconify the window.
|
|
*/
|
|
if (!isCurrentlyVisible) {
|
|
XtSetMappedWhenManaged(pPad->app_shell, True);
|
|
XtPopup(pPad->app_shell, XtGrabNone);
|
|
XtMapWidget(pPad->app_shell);
|
|
}
|
|
|
|
LoadFile(pPad, NULL);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* StartDbUpdate -
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
void
|
|
StartDbUpdate(
|
|
XtPointer clientData)
|
|
{
|
|
|
|
/* Read in the new databases */
|
|
DtDbLoad();
|
|
ActionDBInitialized = True;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* exitCB -
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
void
|
|
exitCB(Widget w, XtPointer callData, XtPointer clientData)
|
|
{
|
|
exit((XtArgVal) clientData);
|
|
}
|
|
|
|
/************************************************************************
|
|
* setPanicConditions -
|
|
************************************************************************/
|
|
void
|
|
setPanicConditions(void)
|
|
{
|
|
struct sigaction act;
|
|
|
|
sigfillset(&act.sa_mask);
|
|
/*
|
|
signal(SIGHUP, (void (*)(int))PanicSave);
|
|
signal(SIGINT, (void (*)(int))PanicSave);
|
|
signal(SIGQUIT, (void (*)(int))PanicSave);
|
|
signal(SIGILL, (void (*)(int))PanicSave);
|
|
signal(SIGABRT, (void (*)(int))PanicSave);
|
|
signal(SIGIOT, (void (*)(int))PanicSave);
|
|
signal(SIGEMT, (void (*)(int))PanicSave);
|
|
signal(SIGFPE, (void (*)(int))PanicSave);
|
|
signal(SIGBUS, (void (*)(int))PanicSave);
|
|
signal(SIGSEGV, (void (*)(int))PanicSave);
|
|
signal(SIGSYS, (void (*)(int))PanicSave);
|
|
signal(SIGPIPE, (void (*)(int))PanicSave);
|
|
signal(SIGTERM, (void (*)(int))PanicSave);
|
|
*/
|
|
sigfillset(&act.sa_mask);
|
|
act.sa_flags = 0;
|
|
act.sa_handler = (void (*)(int))PanicSave;
|
|
sigaction(SIGHUP, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGINT, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGQUIT, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGILL, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGABRT, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGIOT, &act, (struct sigaction *)NULL);
|
|
#ifdef SIGEMT
|
|
sigaction(SIGEMT, &act, (struct sigaction *)NULL);
|
|
#endif
|
|
sigaction(SIGFPE, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGBUS, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGSEGV, &act, (struct sigaction *)NULL);
|
|
#ifdef SIGSYS
|
|
sigaction(SIGSYS, &act, (struct sigaction *)NULL);
|
|
#endif
|
|
sigaction(SIGPIPE, &act, (struct sigaction *)NULL);
|
|
sigaction(SIGTERM, &act, (struct sigaction *)NULL);
|
|
|
|
/* TTT - comment out for debugging TookTalk code */
|
|
#if 0
|
|
XSetErrorHandler((int (*)()) PanicSave);
|
|
XSetIOErrorHandler((int (*)())PanicSave);
|
|
#endif
|
|
XSetErrorHandler(dtpadXErrorHandler);
|
|
XSetIOErrorHandler(dtpadXIOErrorHandler);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* GetAdjustedResizeHints - returns the size hints for the pPad Dt Editor
|
|
* widget with its min_height incremented by the height of dtpad's
|
|
* menu bar.
|
|
************************************************************************/
|
|
static void
|
|
GetAdjustedResizeHints(
|
|
Editor *pPad,
|
|
XSizeHints *pHints)
|
|
{
|
|
Arg al[2]; /* arg list */
|
|
int ac; /* arg count */
|
|
Dimension MBheight;
|
|
|
|
/* get Dt Editor widget size hints */
|
|
DtEditorGetSizeHints(pPad->editor, pHints);
|
|
|
|
/* get the menu bar height */
|
|
XtSetArg(al[0], XmNheight, &MBheight);
|
|
XtGetValues(pPad->menu_bar, al, 1);
|
|
|
|
/* adjust the editor widget min height by menu bar height */
|
|
pHints->min_height += MBheight;
|
|
pHints->base_height += MBheight;
|
|
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SetAppShellResizeHints - sets the app_shell's normal resize hints
|
|
* (resize increment, minimum window size, etc.) based on the resize
|
|
* hints returned from the Dt Editor widget but with the dtpad menu
|
|
* bar height added to the min_height.
|
|
************************************************************************/
|
|
void
|
|
SetAppShellResizeHints(
|
|
Editor *pPad)
|
|
{
|
|
XSizeHints size_hints;
|
|
long supplied_return;
|
|
|
|
/* make sure stuff not set by GetAdjustedResizeHints is not lost */
|
|
XGetWMSizeHints(pPad->display, XtWindow(pPad->app_shell), &size_hints,
|
|
&supplied_return, XA_WM_NORMAL_HINTS);
|
|
|
|
GetAdjustedResizeHints(pPad, &size_hints); /* consider the menu bar */
|
|
|
|
XSetWMSizeHints(pPad->display, XtWindow(pPad->app_shell), &size_hints,
|
|
XA_WM_NORMAL_HINTS);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SetPadGeometry - sets the pad's width, height and x & y IN PIXELS
|
|
* based on the pad's geometry string. Returns a flag
|
|
* indicating which geometry components were specified.
|
|
************************************************************************/
|
|
static int
|
|
SetPadGeometry(
|
|
Editor *pPad)
|
|
{
|
|
int geometryBits;
|
|
int geometryX;
|
|
int geometryY;
|
|
unsigned int geometryWidth;
|
|
unsigned int geometryHeight;
|
|
XSizeHints size_hints;
|
|
|
|
|
|
/* -----> convert geometry string to integers */
|
|
geometryBits = XParseGeometry(pPad->geometry, /* geometry string */
|
|
&geometryX, /* x position return*/
|
|
&geometryY, /* y position return*/
|
|
&geometryWidth, /* width return */
|
|
&geometryHeight); /* height return */
|
|
|
|
if (!(geometryBits & WidthValue))
|
|
geometryWidth = DEFAULT_COLS;
|
|
if (!(geometryBits & HeightValue))
|
|
geometryHeight = DEFAULT_ROWS;
|
|
|
|
/* -----> Get width/height increments and minimum sizes in pixels
|
|
* and then compute window width/height in pixels.
|
|
* The min_width & min_height size hints include a character. */
|
|
GetAdjustedResizeHints(pPad, &size_hints); /* consider the menu bar */
|
|
geometryWidth = geometryWidth * size_hints.width_inc +
|
|
size_hints.min_width - size_hints.width_inc;
|
|
geometryHeight = geometryHeight * size_hints.height_inc +
|
|
size_hints.min_height - size_hints.height_inc;
|
|
|
|
/* -----> allow for negative X and Y values */
|
|
if (geometryBits & XValue) {
|
|
if (geometryBits & XNegative) {
|
|
geometryX += DisplayWidth(pPad->display,
|
|
DefaultScreen(pPad->display)) -
|
|
geometryWidth -
|
|
2 * pPad->app_shell->core.border_width;
|
|
}
|
|
} else {
|
|
geometryX = 0;
|
|
}
|
|
if (geometryBits & YValue) {
|
|
if (geometryBits & YNegative) {
|
|
geometryY += DisplayHeight(pPad->display,
|
|
DefaultScreen(pPad->display)) -
|
|
geometryHeight -
|
|
2 * pPad->app_shell->core.border_width;
|
|
}
|
|
} else {
|
|
geometryY = 0;
|
|
}
|
|
|
|
/* -----> set pad's pixel geometry */
|
|
pPad->width = geometryWidth;
|
|
pPad->height = geometryHeight;
|
|
pPad->x = geometryX;
|
|
pPad->y = geometryY;
|
|
|
|
return geometryBits;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SetWindowSize - sets the following for the pad's application shell:
|
|
*
|
|
* 1) geometry (in pixels) - after converting the geometry string
|
|
* to pixel values and storing in the pad struct
|
|
* 2) resize hints (PMinSize, PResizeInc and PBaseSize)
|
|
* 3) position and size hints (PPosition and PSize)
|
|
*
|
|
************************************************************************/
|
|
void
|
|
SetWindowSize(
|
|
Editor *pPad)
|
|
{
|
|
Arg al[10]; /* arg list */
|
|
int ac; /* arg count */
|
|
XSizeHints size_hints;
|
|
XWMHints *wmhints;
|
|
long supplied_return;
|
|
int geometryBits = 0;
|
|
XWindowChanges changesStruct;
|
|
WMShellWidget wm;
|
|
|
|
/* -----> set pad's app_shell geometry (in pixels) */
|
|
ac = 0;
|
|
if (pPad->saveRestore == True) {
|
|
/* if we're restoring a session, the geometry is already in
|
|
* pixel values so set the app_shell geometry directly */
|
|
wm = (WMShellWidget)(pPad->app_shell);
|
|
wm->wm.size_hints.flags |= USSize|USPosition;
|
|
wm->wm.size_hints.flags |= PMinSize|PResizeInc|PBaseSize;
|
|
XtSetArg (al[ac], XmNx, pPad->x); ac++;
|
|
XtSetArg (al[ac], XmNy, pPad->y); ac++;
|
|
XtSetArg (al[ac], XmNwidth, pPad->width); ac++;
|
|
XtSetArg (al[ac], XmNheight, pPad->height); ac++;
|
|
XtSetValues(pPad->app_shell, al, ac);
|
|
} else {
|
|
/* parse the pPad->geometry STRING into
|
|
* pPad->geometry[Width|Height|X|Y] PIXELS values and
|
|
* return flags indicating which geometry parts were specified */
|
|
geometryBits = SetPadGeometry(pPad); /* parse geometry str to pixels */
|
|
wm = (WMShellWidget)(pPad->app_shell);
|
|
|
|
/* set only the geometry parts that were specified */
|
|
if (geometryBits & XValue) {
|
|
wm->wm.size_hints.flags |= USPosition;
|
|
XtSetArg (al[ac], XmNx, pPad->x); ac++;
|
|
}
|
|
if (geometryBits & YValue) {
|
|
wm->wm.size_hints.flags |= USPosition;
|
|
XtSetArg (al[ac], XmNy, pPad->y); ac++;
|
|
}
|
|
if (geometryBits & WidthValue) {
|
|
wm->wm.size_hints.flags |= USSize;
|
|
XtSetArg (al[ac], XmNwidth, pPad->width); ac++;
|
|
}
|
|
if (geometryBits & HeightValue) {
|
|
wm->wm.size_hints.flags |= USSize;
|
|
XtSetArg (al[ac], XmNheight, pPad->height); ac++;
|
|
}
|
|
if (ac > 0) {
|
|
XtSetValues(pPad->app_shell, al, ac);
|
|
}
|
|
}
|
|
|
|
/* -----> set app_shell resize hints based on resize hints returned
|
|
* from the Dt Editor widget (PMinSize, PResizeInc and PBaseSize)
|
|
* and adjusted by the dtpad menu bar */
|
|
SetAppShellResizeHints(pPad);
|
|
|
|
|
|
/* -----> set app_shell position and size hints
|
|
* (and whether user specified (US) or program specified (P) */
|
|
XGetWMSizeHints(pPad->display, XtWindow(pPad->app_shell), &size_hints,
|
|
&supplied_return, XA_WM_NORMAL_HINTS);
|
|
wm->wm.size_hints.flags |= PMinSize|PResizeInc|PBaseSize;/* set previously*/
|
|
if (pPad->saveRestore == True) {
|
|
wm->wm.size_hints.x = pPad->x;
|
|
wm->wm.size_hints.y = pPad->y;
|
|
wm->wm.size_hints.width = pPad->width;
|
|
wm->wm.size_hints.height = pPad->height;
|
|
wm->wm.size_hints.min_width = size_hints.min_width;
|
|
wm->wm.size_hints.min_height = size_hints.min_height;
|
|
wm->wm.size_hints.width_inc = size_hints.width_inc;
|
|
wm->wm.size_hints.height_inc = size_hints.height_inc;
|
|
wm->wm.base_width = size_hints.base_width;
|
|
wm->wm.base_height = size_hints.base_height;
|
|
wm->wm.size_hints.flags |= USSize|USPosition;
|
|
} else {
|
|
if (geometryBits & XValue && geometryBits & YValue) {
|
|
wm->wm.size_hints.x = pPad->x;
|
|
wm->wm.size_hints.y = pPad->y;
|
|
wm->wm.size_hints.flags |= USPosition;
|
|
} else {
|
|
wm->wm.size_hints.flags |= PPosition;
|
|
}
|
|
if (geometryBits & WidthValue && geometryBits & HeightValue) {
|
|
wm->wm.size_hints.width = pPad->width;
|
|
wm->wm.size_hints.height = pPad->height;
|
|
wm->wm.size_hints.min_width = size_hints.min_width;
|
|
wm->wm.size_hints.min_height = size_hints.min_height;
|
|
wm->wm.size_hints.width_inc = size_hints.width_inc;
|
|
wm->wm.size_hints.height_inc = size_hints.height_inc;
|
|
wm->wm.base_width = size_hints.base_width;
|
|
wm->wm.base_height = size_hints.base_height;
|
|
wm->wm.size_hints.flags |= USSize;
|
|
} else {
|
|
wm->wm.size_hints.flags |= PSize;
|
|
}
|
|
}
|
|
|
|
/* Remove the iconify hint from the current shell */
|
|
wmhints = XGetWMHints(XtDisplay(pPad->app_shell),
|
|
XtWindow(pPad->app_shell));
|
|
wmhints->flags |= IconWindowHint;
|
|
if (pPad->iconic)
|
|
wmhints->initial_state = IconicState;
|
|
else
|
|
wmhints->initial_state = NormalState;
|
|
XSetWMHints(XtDisplay(pPad->app_shell),
|
|
XtWindow(pPad->app_shell), wmhints);
|
|
|
|
changesStruct.x = pPad->x;
|
|
changesStruct.y = pPad->y;
|
|
changesStruct.width = pPad->width;
|
|
changesStruct.height = pPad->height;
|
|
XConfigureWindow(pPad->display, XtWindow(pPad->app_shell),
|
|
CWWidth | CWHeight, &changesStruct);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SetInitialMenuSensitivity - sets the initial sensitivity of various menu
|
|
items primarily based on whether or not we're in viewOnly mode.
|
|
************************************************************************/
|
|
static void
|
|
SetInitialMenuSensitivity(
|
|
Editor *pPad)
|
|
{
|
|
Boolean editable = ! pPad->xrdb.viewOnly;
|
|
|
|
/* -----> set sensitivity of File menu items */
|
|
XtSetSensitive(pPad->fileStuff.fileWidgets.newBtn, editable);
|
|
/****Begin Change - SuG 5/5/95 */
|
|
XtSetSensitive(pPad->fileStuff.fileWidgets.openBtn, editable);
|
|
XtSetSensitive(pPad->fileStuff.fileWidgets.includeBtn, editable);
|
|
XtSetSensitive(pPad->fileStuff.fileWidgets.saveBtn, editable);
|
|
|
|
/* -----> set sensitivity of Edit menu items
|
|
* Edit Menu items that deal with the current selection (Cut, Copy,
|
|
* Clear and Delete) are made sensitive/insensitive via the DtEditor
|
|
* widget's DtNtextSelectCallback and DtNtextDeselectCallback.
|
|
* Currently nothing is being done with Paste based on text
|
|
* selected/deselected outside the edit window.
|
|
* findChangeBtn is left sensitive since the DtEditor widget will
|
|
* enable/disable changes in the Find/Change dialog based on the
|
|
* DtNeditable resource. */
|
|
XtSetSensitive(pPad->editStuff.widgets.undoBtn, editable);
|
|
XtSetSensitive(pPad->editStuff.widgets.pasteBtn, editable);
|
|
if (pPad->editStuff.widgets.checkSpellingBtn != (Widget) NULL) {
|
|
XtSetSensitive(pPad->editStuff.widgets.checkSpellingBtn, editable);
|
|
}
|
|
SetSelectionMenuItems(pPad, False); /* set Cut, Copy, Clear & Delete */
|
|
|
|
/* -----> set sensitivity of Format menu */
|
|
XtSetSensitive(pPad->formatStuff.widgets.formatBtn, editable);
|
|
|
|
/* -----> set sensitivity of Options menu items */
|
|
XtSetSensitive(pPad->optionsStuff.widgets.overstrikeBtn, editable);
|
|
XtSetSensitive(pPad->optionsStuff.widgets.wordWrapBtn, editable);
|
|
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SetStateFromResources - set pPad's state (e.g. GUI components) based on
|
|
* current pPad->xrdb resource values. The resources are initially
|
|
* obtained from either:
|
|
*
|
|
* 1) the dtpad requestor's resource data base and command line
|
|
* options - if running in standAlone mode or in server mode and
|
|
* handling an Edit request containing resource context fields
|
|
* 2) the server's data base - if running in server mode and
|
|
* handling an Edit request without resource context fields
|
|
*
|
|
************************************************************************/
|
|
static void
|
|
SetStateFromResources(
|
|
Editor *pPad)
|
|
{
|
|
Arg al[1]; /* arg list */
|
|
OptionsMenuWidgets *pWidg = &pPad->optionsStuff.widgets;
|
|
|
|
SetWorkSpaceHints(pPad->app_shell, pPad->xrdb.workspaceList);
|
|
/* Create the title */
|
|
pPad->dialogTitle = DialogTitle(pPad);
|
|
|
|
/* -----> Set the overstrike, wordWrap and statusLine for the Editor
|
|
* widget and corresponding Options menu toggle buttons.
|
|
* This is done in one place - in the valueChanged callback for
|
|
* each option - which is called only if parameter 3 is True AND
|
|
* the state being set is different than what it currently is.
|
|
* The first XmToggleButtonSetState (with parm 3 = False) ensures
|
|
* that the state is opposite of what we want it to be so that
|
|
* when we set it, the valueChanged callback will be called. */
|
|
|
|
if (pPad->xrdb.overstrike == XmToggleButtonGetState(pWidg->overstrikeBtn))
|
|
XmToggleButtonSetState(pWidg->overstrikeBtn,
|
|
!pPad->xrdb.overstrike, False);
|
|
XmToggleButtonSetState(pWidg->overstrikeBtn,
|
|
pPad->xrdb.overstrike, True);
|
|
|
|
if (pPad->xrdb.wordWrap == XmToggleButtonGetState(pWidg->wordWrapBtn))
|
|
XmToggleButtonSetState(pWidg->wordWrapBtn,
|
|
!pPad->xrdb.wordWrap, False);
|
|
XmToggleButtonSetState(pWidg->wordWrapBtn,
|
|
pPad->xrdb.wordWrap, True);
|
|
|
|
if (pPad->xrdb.statusLine == XmToggleButtonGetState(pWidg->statusLineBtn))
|
|
XmToggleButtonSetState(pWidg->statusLineBtn,
|
|
!pPad->xrdb.statusLine, False);
|
|
XmToggleButtonSetState(pWidg->statusLineBtn,
|
|
pPad->xrdb.statusLine, True);
|
|
|
|
/* -----> Set whether text can be edited */
|
|
XtSetArg(al[0], DtNeditable, !pPad->xrdb.viewOnly);
|
|
XtSetValues(pPad->editor, al, 1);
|
|
SetInitialMenuSensitivity(pPad);
|
|
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* SigcldHndlr -
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
void SigcldHndlr (int dummy)
|
|
{
|
|
int status, w;
|
|
struct sigaction act;
|
|
sigfillset(&act.sa_mask);
|
|
act.sa_flags = 0;
|
|
act.sa_handler = SigcldHndlr;
|
|
|
|
w = wait (&status);
|
|
|
|
/*
|
|
* Is this really necessary?
|
|
*/
|
|
sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* UnmanageAllDialogs - unmanages all the dialogs which may be managed
|
|
* when a pad gets closed or withdrawn.
|
|
************************************************************************/
|
|
void
|
|
UnmanageAllDialogs(
|
|
Editor *pPad)
|
|
{
|
|
HelpStruct *pHelp;
|
|
/*
|
|
* Unmanage all Modal dialogs that might possibly be up.
|
|
*/
|
|
if (pPad->fileStuff.fileWidgets.saveAs.alrdy_exist != (Widget)NULL &&
|
|
pPad->fileStuff.fileWidgets.saveAs.alrdy_exist->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pPad->fileStuff.fileWidgets.saveAs.alrdy_exist);
|
|
}
|
|
|
|
if (pPad->fileStuff.fileWidgets.select.save_warning != (Widget)NULL &&
|
|
pPad->fileStuff.fileWidgets.select.save_warning->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pPad->fileStuff.fileWidgets.select.save_warning);
|
|
}
|
|
|
|
if (pPad->fileStuff.fileWidgets.gen_warning != (Widget)NULL &&
|
|
pPad->fileStuff.fileWidgets.gen_warning->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pPad->fileStuff.fileWidgets.gen_warning);
|
|
}
|
|
|
|
/*
|
|
* Unmanage File menu dialogs that might be posted.
|
|
* The Edit and Format menu dialogs are managed by the DtEditor widget.
|
|
* XXX - unmanage print dialog too.
|
|
*/
|
|
if (pPad->fileStuff.fileWidgets.select.file_dialog != (Widget)NULL &&
|
|
pPad->fileStuff.fileWidgets.select.file_dialog->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pPad->fileStuff.fileWidgets.select.file_dialog);
|
|
}
|
|
|
|
if (pPad->fileStuff.fileWidgets.saveAs.saveAs_form != (Widget)NULL &&
|
|
pPad->fileStuff.fileWidgets.saveAs.saveAs_form->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pPad->fileStuff.fileWidgets.saveAs.saveAs_form);
|
|
}
|
|
|
|
/*
|
|
* Unmanage help if it's up.
|
|
*/
|
|
if (pPad->MainHelp != (Widget)NULL && pPad->MainHelp->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pPad->MainHelp);
|
|
}
|
|
for (pHelp = pPad->pHelpCache; pHelp != (HelpStruct *)NULL;
|
|
pHelp = pHelp->pNext)
|
|
{
|
|
if (pHelp->dialog != (Widget)NULL &&
|
|
pHelp->dialog->core.managed == True)
|
|
{
|
|
XtUnmanageChild(pHelp->dialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* RestoreInitialServerResources -
|
|
************************************************************************/
|
|
void
|
|
RestoreInitialServerResources(
|
|
Editor *pPad)
|
|
{
|
|
/* -----> free resource strings */
|
|
if (pPad->xrdb.workspaceList != (char *)NULL)
|
|
XtFree(pPad->xrdb.workspaceList);
|
|
if (pPad->xrdb.session != (char *)NULL)
|
|
XtFree(pPad->xrdb.session);
|
|
if (pPad->geometry != (char *)NULL)
|
|
XtFree(pPad->geometry );
|
|
|
|
pPad->xrdb = initialServerResources;
|
|
|
|
/* -----> duplicate resource strings */
|
|
if (initialServerResources.workspaceList != (char *)NULL)
|
|
pPad->xrdb.workspaceList = strdup(initialServerResources.workspaceList);
|
|
if (initialServerResources.session != (char *)NULL)
|
|
pPad->xrdb.session = strdup(initialServerResources.session);
|
|
if (initialServerGeometry != (char *)NULL)
|
|
pPad->geometry = strdup(initialServerGeometry);
|
|
|
|
}
|
|
|
|
|
|
#ifndef NO_MESSAGE_CATALOG
|
|
/*****************************************************************************
|
|
* _DtpadGetMessage - obtains a localized message from dtpad's message catalog
|
|
*
|
|
* Parameters:
|
|
*
|
|
* int set - The message catalog set number.
|
|
* int number - The message number.
|
|
* char *string - The default message if the message is not
|
|
* retrieved from a message catalog.
|
|
*
|
|
* Returns: the message string for set 'set' and number 'number'.
|
|
*
|
|
*****************************************************************************/
|
|
char *
|
|
_DtpadGetMessage(
|
|
int set,
|
|
int number,
|
|
const char *string)
|
|
{
|
|
static int first = 1;
|
|
static nl_catd nlmsg_fd = (nl_catd) -1;
|
|
|
|
if ( first ) {
|
|
first = 0;
|
|
nlmsg_fd = CATOPEN(_DTPAD_CAT_NAME, NL_CAT_LOCALE);
|
|
|
|
if (nlmsg_fd == (nl_catd) -1)
|
|
perror("catopen");
|
|
}
|
|
return CATGETS(nlmsg_fd, set, number, string);
|
|
}
|
|
|
|
#endif /* NO_MESSAGE_CATALOG */
|
|
|
|
/************************************************************************
|
|
* HostCB - message callback for (op) Get_SysInfo message
|
|
************************************************************************/
|
|
/* ARGSUSED */
|
|
static
|
|
Tt_callback_action
|
|
HostCB(Tt_message m, Tt_pattern p)
|
|
{
|
|
Tt_state state = tt_message_state(m);
|
|
|
|
if (state == TT_HANDLED) {
|
|
value = tt_message_arg_val(m, 1);
|
|
waitCB = 0;
|
|
return TT_CALLBACK_PROCESSED;
|
|
}
|
|
return TT_CALLBACK_CONTINUE;
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* Usage
|
|
* When incorrect parameters have been specified on the command
|
|
* line, print out a set of messages detailing the correct use
|
|
* and exit.
|
|
*
|
|
************************************************************************/
|
|
|
|
static void
|
|
Usage(
|
|
char **argv )
|
|
{
|
|
char * template;
|
|
char * message_string1 = "'%s' is a bad option.\nUsage: %s...\n"
|
|
" -saveOnClose\n\t"
|
|
"Dtpad automatically and silently saves the current text when there\n\t"
|
|
"are unsaved changes and the Text Editor is closed.\n\n"
|
|
" -missingFileWarning\n\t"
|
|
"Posts a warning dialog whenever a file name is specified and\n\t"
|
|
"the file dones not exist or cannot be accessed.\n\n"
|
|
" -noReadOnlyWarning\n\t"
|
|
"Disables the warning dialog posted whenever a file is\n\t"
|
|
"specified for which the user does not have write permission.\n\n"
|
|
" -noNameChange\n\t"
|
|
"Indicates that the default file name associated with the\n\t"
|
|
"current text is not to change when the text is saved under a\n\t"
|
|
"name different than what it was read in under.\n\n"
|
|
" -viewOnly\n\t"
|
|
"Disallows editing of text in the edit window, essentially\n\t"
|
|
"turning the Text Editor into a Text Viewer.\n\n"
|
|
" -statusLine\n\t"
|
|
"Displays a status line at the bottom of the edit window. The\n\t"
|
|
"status line shows the line number of the line where the text\n\t"
|
|
"cursor is currently positioned.\n\n"
|
|
" -wrapToFit\n\t"
|
|
"Initially turns on wrap-to-fit mode.\n\n"
|
|
" -workspaceList WorkspaceList\n\t"
|
|
"Displays the edit window for the current invocation of the\n\t"
|
|
"Text Editor in the specified workspace or workspaces.\n\n"
|
|
" -session SessionFile\n";
|
|
|
|
char * message_string2 = "\tRestores the Text Editor to all text editing windows and\n\t"
|
|
"settings that were in effect at a previous CDE shutdown. All\n\t"
|
|
"other command-line options are ignored when this option is\n\t"
|
|
"specified.\n\n"
|
|
" -standAlone\n\t"
|
|
"Forces the current invocation of the Text Editor to do its\n\t"
|
|
"own text processing in its own window, independent of the\n\t"
|
|
"Text Editor server.\n\n"
|
|
" -noBlocking\n\t"
|
|
"Terminates the Text Editor requestor process as soon as the\n\t"
|
|
"Text Editor server determines that it can handle the\n\t"
|
|
"requestor's edit request.\n\n"
|
|
" -server\n\t"
|
|
"Forces a Text Editor server to be started up (if one is not\n\t"
|
|
"already running) to process all subsequent edit requests for\n\t"
|
|
"the display.\n\n"
|
|
" -exitOnLastClose\n\t"
|
|
"Specifies that the Text Editor server process is to terminate\n\t"
|
|
"when the last edit window for the display is closed. It\n\t"
|
|
"should only be used with the -server option since it only\n\t"
|
|
"applies to the server process.\n\n"
|
|
"See the dtpad man page for more details on any of these options.\n\n";
|
|
|
|
|
|
template = (GETMESSAGE(7,9, message_string1));
|
|
|
|
fprintf (stderr, template, argv[1], argv[0]);
|
|
|
|
template = (GETMESSAGE(7,10, message_string2));
|
|
|
|
fprintf (stderr, "%s", template);
|
|
|
|
exit (0);
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* dtpadXErrorHandler
|
|
*
|
|
************************************************************************/
|
|
|
|
static int
|
|
dtpadXErrorHandler(
|
|
Display *display,
|
|
XErrorEvent *xerr)
|
|
{
|
|
#define _DTPAD_BUFSIZE 1024
|
|
static char msg[_DTPAD_BUFSIZE];
|
|
|
|
/* log error */
|
|
_DtPrintDefaultErrorSafe(display, xerr, msg, _DTPAD_BUFSIZE);
|
|
_DtSimpleError("dtpad", DtWarning, NULL, msg, NULL);
|
|
|
|
/*
|
|
* if the error occurred on the print display we're going to set
|
|
* a variable so that and when the job is done, right before calling
|
|
* XpEndJob, we call XpCancelJob, and notify the user.
|
|
*/
|
|
|
|
if (PrintJobIsActivePrintDisplay(display) && xerr->error_code == BadAlloc)
|
|
{
|
|
PrintJobSetErrorPrintDisplay(display);
|
|
return 1;
|
|
}
|
|
|
|
XGetErrorText(display, xerr->error_code, msg, 1024);
|
|
fprintf(stderr, "Error Code %s\n", msg);
|
|
PanicSave();
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* dtpadXIOErrorHandler
|
|
*
|
|
************************************************************************/
|
|
|
|
static int
|
|
dtpadXIOErrorHandler(
|
|
Display *display)
|
|
{
|
|
static char msg[1024];
|
|
|
|
fprintf(stderr, "X IO Error");
|
|
PanicSave();
|
|
|
|
/* Man page for XSetIOErrorhandler says this is a fatal error and
|
|
* should not return */
|
|
exit(EXIT_FAILURE);
|
|
}
|