/* * 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; }