/*
* 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
*/
/* $XConsortium: session.c /main/3 1995/11/01 10:39:26 rswiston $ */
/**********************************<+>*************************************
***************************************************************************
**
** File: session.c
**
** Project: DT dtpad, a memo maker type editor based on the motif
** text widget.
**
** Description: Provides the functionality for saving and restoring the
** user's session.
**
**
*******************************************************************
** (c) Copyright Hewlett-Packard Company, 1990, 1991, 1992, 1993.
** 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 Hewlett-Packard Company
** (c) Copyright 1993, 1994 International Business Machines Corp.
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
** (c) Copyright 1993, 1994 Novell, Inc.
********************************************************************
**
**
**************************************************************************
**********************************<+>*************************************/
#include "dtpad.h"
#include
/*
* This for the sleazy hack to get the window manager frame width/height
*/
#include
/* Copied from BaseClassI.h */
extern XmWidgetExtData _XmGetWidgetExtData(
Widget widget,
#if NeedWidePrototypes
unsigned int extType) ;
#else
unsigned char extType) ;
#endif /* NeedWidePrototypes */
#define MSG1 ((char *)GETMESSAGE(10, 1, "Check the file permissions."))
#define MSG2 ((char *)GETMESSAGE(10, 2, "%s is the file that would have been used to save your session."))
extern Widget topLevelWithWmCommand; /* declared in main.c */
extern Editor *pPadList;
extern int numActivePads;
/* Structure used on a save session to see if a dt is iconic */
static Atom wm_state_atom;
typedef struct
{
int state;
Window icon;
} WM_STATE;
/************************************************************************
*
* SaveMain - saves the parameters associated with a Pad's mainWindow
* (called from SaveSessionCB() below).
*
***********************************************************************/
void
SaveMain(
Editor *pPad,
int padNum,
int fd)
{
char bufr[1024];
Position x,y;
Dimension width, height;
Atom *pWsPresence;
unsigned long numInfo;
Atom actual_type;
int actual_format;
unsigned long nitems;
unsigned long leftover;
WM_STATE * wm_state;
if(pPad->mainWindow != (Widget)NULL)
{
XmVendorShellExtObject vendorExt;
XmWidgetExtData extData;
if(XtIsRealized(pPad->mainWindow))
{
sprintf(bufr,"*mainWindow%d.ismapped: True\n", padNum);
write (fd, bufr, strlen(bufr));
}
/* Get and write out the geometry info for our Window */
x = XtX(XtParent(pPad->mainWindow));
y = XtY(XtParent(pPad->mainWindow));
/*
* Modify x & y to take into account window mgr frames
* This is pretty bogus, but I don't know a better way to do it.
*/
extData = _XmGetWidgetExtData(pPad->app_shell, XmSHELL_EXTENSION);
vendorExt = (XmVendorShellExtObject)extData->widget;
x -= vendorExt->vendor.xOffset;
y -= vendorExt->vendor.yOffset;
width = XtWidth(XtParent(pPad->mainWindow));
height = XtHeight(XtParent(pPad->mainWindow));
snprintf(bufr, sizeof(bufr), "*mainWindow%d.x: %d\n", padNum, x);
write (fd, bufr, strlen(bufr));
snprintf(bufr, sizeof(bufr), "*mainWindow%d.y: %d\n", padNum, y);
write (fd, bufr, strlen(bufr));
snprintf(bufr, sizeof(bufr), "*mainWindow%d.width: %d\n", padNum, width);
write (fd, bufr, strlen(bufr));
snprintf(bufr, sizeof(bufr), "*mainWindow%d.height: %d\n", padNum, height);
write (fd, bufr, strlen(bufr));
wm_state_atom = XmInternAtom (XtDisplay(pPad->app_shell), "WM_STATE",
False);
/* Getting the WM_STATE property to see if iconified or not */
XGetWindowProperty (XtDisplay(pPad->app_shell),
XtWindow (pPad->app_shell),
wm_state_atom, 0L, (long) BUFSIZ, False,
wm_state_atom, &actual_type, &actual_format,
&nitems, &leftover, (unsigned char **) &wm_state);
/* Write out if iconified our not */
snprintf(bufr, sizeof(bufr), "*mainWindow%d.iconify: ", padNum);
write (fd, bufr, strlen(bufr));
if (wm_state->state == IconicState)
snprintf(bufr, sizeof(bufr), "True\n");
else
snprintf(bufr, sizeof(bufr), "False\n");
write (fd, bufr, strlen(bufr));
if(DtWsmGetWorkspacesOccupied(XtDisplay(pPad->app_shell),
XtWindow(pPad->app_shell), &pWsPresence,
&numInfo) == Success)
{
int i;
snprintf(bufr, sizeof(bufr), "*mainWindow%d.workspaceList: ", padNum);
write (fd, bufr, strlen(bufr));
for(i = 0; i < numInfo; i++)
{
char *name = XGetAtomName(XtDisplay(pPad->app_shell),
pWsPresence[i]);
snprintf(bufr, sizeof(bufr), " %s", name);
write (fd, bufr, strlen(bufr));
XtFree(name);
}
snprintf(bufr, sizeof(bufr), "\n");
write (fd, bufr, strlen(bufr));
XtFree((char *)pWsPresence);
}
write (fd, bufr, strlen(bufr));
}
if(pPad->fileStuff.fileName != (char *)NULL)
{
sprintf(bufr, "*mainWindow%d.fileName: %s\n", padNum,
pPad->fileStuff.fileName);
write (fd, bufr, strlen(bufr));
}
}
/************************************************************************
*
* SaveSessionCB - saves the editor state (just filename) - does not save
* the file at this time.
*
* This routines is setup as the "WM_SAVE_YOURSELF" WMProtocolCallback
* on the top level widget (created via XtInitialize).
*
************************************************************************/
/* ARGSUSED */
void
SaveSessionCB(
Widget w, /* widget id */
caddr_t client_data, /* data from application */
caddr_t call_data ) /* data from widget class */
{
char *longpath, *fileName;
int fd, numPadsToSave;
char *xa_CommandStr[10];
char *tmpStr, bufr[1024];
Editor *pPad;
int i;
/* Xt may not pass a widget as advertised (??? is this needed? - hp) */
if(!XtIsShell(w))
w = XtParent(w);
for(pPad = pPadList, numPadsToSave = 0; pPad != (Editor *)NULL;
pPad = pPad->pNextPad)
{
if(pPad->inUse == True)
numPadsToSave++;
}
if(numPadsToSave < 1)
{
xa_CommandStr[0] = (char *)NULL;
XSetCommand(XtDisplay(w), XtWindow(w), xa_CommandStr, 1);
return;
}
DtSessionSavePath(w, &longpath, &fileName);
/* Create the session file */
if ((fd = creat (longpath, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
{
tmpStr = (char *)malloc(strlen(MSG2) + strlen(longpath)+ 1);
sprintf(tmpStr, MSG2, longpath);
_DtSimpleErrnoError(pPad->progname, DtError, MSG1, tmpStr, NULL);
free(tmpStr);
XtFree ((char *)longpath);
return;
}
sprintf(bufr, "*pads.numActivePads: %d\n", numPadsToSave);
write (fd, bufr, strlen(bufr));
for(pPad = pPadList, i = 0; pPad != (Editor *)NULL;
pPad = pPad->pNextPad, i++)
{
if(pPad->inUse == True)
SaveMain(pPad, i, fd);
}
close(fd);
i = 0;
xa_CommandStr[i] = pPadList->progname; i++;
xa_CommandStr[i] = "-session"; i++;
xa_CommandStr[i] = fileName; i++;
XSetCommand(XtDisplay(topLevelWithWmCommand),
XtWindow(topLevelWithWmCommand), xa_CommandStr, i);
XtFree ((char *)fileName);
}
/***********************************************************************
*
* closeCB - set up as the "WM_DELETE_WINDOW" WMProtocolCallback on the
* application shell for each Editor instance - and called when
* a delete window command is received from the Window Manager.
* Waits for CloseWindow to become false before it continues.
*
***********************************************************************/
/* ARGSUSED */
void
closeCB(
Widget w,
caddr_t client_data,
caddr_t call_data )
{
Editor *pPad = (Editor *)client_data;
/* call the callback for Exit within the File Menu pulldown */
XtCallCallbacks(pPad->ExitWid, XmNactivateCallback, (XtPointer)pPad);
}
/***********************************************************************
*
* restoreSession - gets the valid x and y location of where to put the
* Text Edit on the root window. Sets the global varible
* dtpad.saveRestore to True so the rest of the program knows that
* a session is being restored.
*
***********************************************************************/
void
restoreSession(
Editor *pPad)
{
XrmDatabase db;
char *tmpStr;
XrmName xrm_name[5];
XrmRepresentation rep_type;
XrmValue value;
char *fileName = pPad->xrdb.session;
char *path;
int numPadsToRestore, i;
Boolean foundPad;
if(DtSessionRestorePath(topLevelWithWmCommand, &path, fileName) == False)
path = fileName;
/* Open the file as a resource database */
if ((db = XrmGetFileDatabase (path)) == NULL)
{
tmpStr = (char *)XtMalloc(strlen(MSG2) + strlen(path)+ 1);
sprintf(tmpStr, MSG2, path);
_DtSimpleErrnoError(pPad->progname, DtError, MSG1, tmpStr, NULL);
XtFree(tmpStr);
return;
}
xrm_name[0] = XrmStringToQuark ("pads");
xrm_name[1] = XrmStringToQuark ("numActivePads");
xrm_name[2] = 0;
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
numPadsToRestore = atoi((char *)value.addr);
if(numPadsToRestore == 0)
{
/*
* Either it's an old (i.e. 2.01) session file,
* or it's bogus. Either way, we'll create one
* window, taking whatever mainWindow: resources
* we can find.
*/
xrm_name[0] = XrmStringToQuark ("mainWindow");
xrm_name[2] = 0;
/* get x position */
xrm_name[1] = XrmStringToQuark ("x");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->x = atoi((char *)value.addr);
/* get y position */
xrm_name[1] = XrmStringToQuark ("y");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->y = atoi((char *)value.addr);
pPad->saveRestore = True;
return;
}
RestorePad(pPad, 0, db);
for(i = 1; i < numPadsToRestore; i++)
{
foundPad = FindOrCreatePad(&pPad);
RestorePad(pPad, i, db);
if(foundPad == False)
RealizeNewPad(pPad);
else
ManageOldPad(pPad, False);
}
}
/************************************************************************
*
* RestoreMain -
*
***********************************************************************/
static void
RestoreMain(
Editor *pPad,
int padNum,
XrmDatabase db)
{
char * iconify = NULL;
char buf[1024];
XrmName xrm_name[5];
XrmRepresentation rep_type;
XrmValue value;
sprintf(buf, "mainWindow%d", padNum);
xrm_name[0] = XrmStringToQuark(buf);
xrm_name[2] = 0;
/* get x position */
xrm_name[1] = XrmStringToQuark ("x");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->x = atoi((char *)value.addr);
/* get y position */
xrm_name [1] = XrmStringToQuark ("y");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->y = atoi((char *)value.addr);
/* get width */
xrm_name [1] = XrmStringToQuark ("width");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->width = atoi((char *)value.addr);
/* get height */
xrm_name [1] = XrmStringToQuark ("height");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->height = atoi((char *)value.addr);
/* Get and set whether the view is iconic */
xrm_name [1] = XrmStringToQuark ("iconify");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
/* If there is an iconify resource and its value is True, */
/* then mark the window as iconified. */
if ((iconify = (char *) value.addr) != NULL &&
strcmp (iconify, "True") == 0)
pPad->iconic = True;
else
pPad->iconic = False;
/* get the file name */
xrm_name [1] = XrmStringToQuark ("fileName");
XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
pPad->fileStuff.fileName = strdup((char *) value.addr);
/* get workspace list */
xrm_name[1] = XrmStringToQuark("workspaceList");
XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value);
pPad->xrdb.workspaceList = strdup((char *) value.addr);
}
/************************************************************************
*
* RestorePad -
*
***********************************************************************/
void
RestorePad(
Editor *pPad,
int padNum,
XrmDatabase db)
{
RestoreMain(pPad, padNum, db);
pPad->saveRestore = True;
}