Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtpad / session.c
1 /* $XConsortium: session.c /main/3 1995/11/01 10:39:26 rswiston $ */
2 /**********************************<+>*************************************
3 ***************************************************************************
4 **
5 **  File:        session.c
6 **
7 **  Project:     DT dtpad, a memo maker type editor based on the motif
8 **               text widget.
9 **
10 **  Description:  Provides the functionality for saving and restoring the
11 **                user's session.
12 **                      
13 **
14 *******************************************************************
15 **  (c) Copyright Hewlett-Packard Company, 1990, 1991, 1992, 1993.
16 **  All rights are
17 **  reserved.  Copying or other reproduction of this program
18 **  except for archival purposes is prohibited without prior
19 **  written consent of Hewlett-Packard Company.
20 ********************************************************************
21 **
22 ********************************************************************
23 **  (c) Copyright 1993, 1994 Hewlett-Packard Company
24 **  (c) Copyright 1993, 1994 International Business Machines Corp.
25 **  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 **  (c) Copyright 1993, 1994 Novell, Inc.
27 ********************************************************************
28 **
29 **
30 **************************************************************************
31 **********************************<+>*************************************/
32 #include "dtpad.h"
33 #include <Dt/Wsm.h> 
34 /*
35  * This for the sleazy hack to get the window manager frame width/height
36  */
37 #include <Xm/VendorSEP.h>
38
39 /* Copied from BaseClassI.h */
40 extern XmWidgetExtData _XmGetWidgetExtData( 
41                         Widget widget,
42 #if NeedWidePrototypes
43                         unsigned int extType) ;
44 #else
45                         unsigned char extType) ;
46 #endif /* NeedWidePrototypes */
47
48 #define MSG1  ((char *)GETMESSAGE(10, 1, "Check the file permissions."))
49 #define MSG2  ((char *)GETMESSAGE(10, 2, "%s is the file that would have been used to save your session."))
50
51 extern Widget topLevelWithWmCommand;    /* declared in main.c */
52 extern Editor *pPadList;
53 extern int numActivePads;
54
55 /*  Structure used on a save session to see if a dt is iconic  */
56
57 static Atom wm_state_atom;
58 typedef struct
59 {
60    int state;
61    Window icon;
62 } WM_STATE;
63
64
65 /************************************************************************
66  *
67  * SaveMain - saves the parameters associated with a Pad's mainWindow
68  *      (called from SaveSessionCB() below).
69  *
70  ***********************************************************************/
71 void 
72 SaveMain(
73         Editor *pPad,
74         int padNum,
75         int fd)
76 {
77     char bufr[1024];
78     Position x,y;
79     Dimension width, height;
80     Atom *pWsPresence;
81     unsigned long numInfo;
82     Atom actual_type;
83     int  actual_format;
84     unsigned long nitems;
85     unsigned long leftover;
86     WM_STATE * wm_state;
87
88     if(pPad->mainWindow != (Widget)NULL) 
89     {
90         XmVendorShellExtObject vendorExt;
91         XmWidgetExtData        extData;
92
93         if(XtIsRealized(pPad->mainWindow))
94             sprintf(bufr,"*mainWindow%d.ismapped: True\n", padNum);
95
96         /* Get and write out the geometry info for our Window */
97         x = XtX(XtParent(pPad->mainWindow));
98         y = XtY(XtParent(pPad->mainWindow));
99
100         /*
101          * Modify x & y to take into account window mgr frames
102          * This is pretty bogus, but I don't know a better way to do it.
103          */
104         extData = _XmGetWidgetExtData(pPad->app_shell, XmSHELL_EXTENSION);
105         vendorExt = (XmVendorShellExtObject)extData->widget;
106         x -= vendorExt->vendor.xOffset;
107         y -= vendorExt->vendor.yOffset;
108
109         width = XtWidth(XtParent(pPad->mainWindow));
110         height = XtHeight(XtParent(pPad->mainWindow));
111
112         sprintf(bufr, "%s*mainWindow%d.x: %d\n", bufr, padNum, x);
113         sprintf(bufr, "%s*mainWindow%d.y: %d\n", bufr, padNum, y);
114         sprintf(bufr, "%s*mainWindow%d.width: %d\n", bufr, padNum, width);
115         sprintf(bufr, "%s*mainWindow%d.height: %d\n", bufr, padNum, height);
116
117         wm_state_atom = XmInternAtom (XtDisplay(pPad->app_shell), "WM_STATE", 
118                                       False);
119         /*  Getting the WM_STATE property to see if iconified or not */
120         XGetWindowProperty (XtDisplay(pPad->app_shell), 
121                             XtWindow (pPad->app_shell),
122                             wm_state_atom, 0L, (long) BUFSIZ, False,
123                             wm_state_atom, &actual_type, &actual_format,
124                             &nitems, &leftover, (unsigned char **) &wm_state);
125
126         /* Write out if iconified our not */
127         sprintf(bufr, "%s*mainWindow%d.iconify: ", bufr, padNum);
128
129         if (wm_state->state == IconicState)
130           sprintf (bufr, "%sTrue\n", bufr);
131         else
132           sprintf (bufr, "%sFalse\n", bufr);
133
134         if(DtWsmGetWorkspacesOccupied(XtDisplay(pPad->app_shell), 
135                                   XtWindow(pPad->app_shell), &pWsPresence,
136                                   &numInfo) == Success)
137         {
138             int i;
139             sprintf(bufr, "%s*mainWindow%d.workspaceList: ", bufr, padNum);
140             for(i = 0; i < numInfo; i++)
141             {
142                 char *name =  XGetAtomName(XtDisplay(pPad->app_shell),
143                                            pWsPresence[i]);
144                 sprintf(bufr, "%s %s", bufr, name);
145                 XtFree(name);
146             }
147             sprintf(bufr, "%s\n", bufr);
148             XtFree((char *)pWsPresence);
149         }
150
151         write (fd, bufr, strlen(bufr));
152     }
153     if(pPad->fileStuff.fileName != (char *)NULL)
154     {
155         sprintf(bufr, "*mainWindow%d.fileName: %s\n", padNum, 
156                 pPad->fileStuff.fileName);
157         write (fd, bufr, strlen(bufr));
158     }
159 }
160
161
162 /************************************************************************
163  *
164  *  SaveSessionCB - saves the editor state (just filename) - does not save
165  *      the file at this time.
166  *
167  *      This routines is setup as the "WM_SAVE_YOURSELF" WMProtocolCallback
168  *      on the top level widget (created via XtInitialize).
169  *
170  ************************************************************************/
171 /* ARGSUSED */
172 void 
173 SaveSessionCB(
174         Widget w,                       /* widget id */
175         caddr_t client_data,            /* data from application  */
176         caddr_t call_data )             /* data from widget class */
177 {
178     char *longpath, *fileName;
179     int fd, numPadsToSave;
180     char *xa_CommandStr[10];
181     char *tmpStr, bufr[1024];
182     Editor *pPad;
183     int i;
184
185     /* Xt may not pass a widget as advertised (??? is this needed? - hp) */
186     if(!XtIsShell(w))
187         w = XtParent(w);
188
189     for(pPad = pPadList, numPadsToSave = 0; pPad != (Editor *)NULL; 
190         pPad = pPad->pNextPad)
191     {
192         if(pPad->inUse == True)
193             numPadsToSave++;
194     }
195     if(numPadsToSave < 1)
196     {
197         xa_CommandStr[0] = (char *)NULL;
198         XSetCommand(XtDisplay(w), XtWindow(w), xa_CommandStr, 1);
199         return;
200     }
201
202     DtSessionSavePath(w, &longpath, &fileName);
203
204     /*  Create the session file  */
205     if ((fd = creat (longpath, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
206     {
207         tmpStr = (char *)malloc(strlen(MSG2) + strlen(longpath)+ 1);
208         sprintf(tmpStr, MSG2, longpath);
209         _DtSimpleErrnoError(pPad->progname, DtError, MSG1, tmpStr, NULL);
210         free(tmpStr);
211         XtFree ((char *)longpath);
212         return;
213     }
214
215     sprintf(bufr, "*pads.numActivePads: %d\n", numPadsToSave);
216     write (fd, bufr, strlen(bufr));
217
218     for(pPad = pPadList, i = 0; pPad != (Editor *)NULL; 
219         pPad = pPad->pNextPad, i++)
220     {
221         if(pPad->inUse == True)
222             SaveMain(pPad, i, fd);
223     }
224
225     close(fd);
226
227     i = 0;
228     xa_CommandStr[i] = pPadList->progname; i++;
229     xa_CommandStr[i] =  "-session"; i++;
230     xa_CommandStr[i] =  fileName; i++;
231
232     XSetCommand(XtDisplay(topLevelWithWmCommand), 
233                 XtWindow(topLevelWithWmCommand), xa_CommandStr, i);
234
235     XtFree ((char *)fileName);
236 }
237
238
239 /***********************************************************************
240  *
241  * closeCB - set up as the "WM_DELETE_WINDOW" WMProtocolCallback on the
242  *      application shell for each Editor instance - and called when
243  *      a delete window command is received from the Window Manager.
244  *      Waits for CloseWindow to become false before it continues.
245  *
246  ***********************************************************************/
247  
248 /* ARGSUSED */
249 void
250 closeCB(
251         Widget w,
252         caddr_t client_data,
253         caddr_t call_data )
254 {
255     Editor *pPad = (Editor *)client_data;
256
257     /* call the callback for Exit within the File Menu pulldown */
258     XtCallCallbacks(pPad->ExitWid, XmNactivateCallback, (XtPointer)pPad);
259 }
260
261
262 /***********************************************************************
263  *
264  * restoreSession - gets the valid x and y location of where to put the
265  *      Text Edit on the root window.  Sets the global varible
266  *      dtpad.saveRestore to True so the rest of the program knows that
267  *      a session is being restored.
268  *
269  ***********************************************************************/
270 void
271 restoreSession(
272         Editor *pPad)
273 {
274     XrmDatabase db;
275     char *tmpStr;
276     XrmName xrm_name[5];
277     XrmRepresentation rep_type;
278     XrmValue value;
279     char *fileName = pPad->xrdb.session;
280     char *path;
281     int numPadsToRestore, i;
282     Boolean foundPad;
283
284     if(DtSessionRestorePath(topLevelWithWmCommand, &path, fileName) == False)
285         path = fileName;
286
287     /*  Open the file as a resource database */
288     if ((db = XrmGetFileDatabase (path)) == NULL) 
289     {
290       tmpStr = (char *)XtMalloc(strlen(MSG2) + strlen(path)+ 1);
291       sprintf(tmpStr, MSG2, path);
292       _DtSimpleErrnoError(pPad->progname, DtError, MSG1, tmpStr, NULL);
293       XtFree(tmpStr);
294       return;
295     }
296
297     xrm_name[0] = XrmStringToQuark ("pads");
298     xrm_name[1] = XrmStringToQuark ("numActivePads");
299     xrm_name[2] = NULL;
300     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
301     numPadsToRestore = atoi((char *)value.addr);
302
303     if(numPadsToRestore == 0)
304     {
305         /*
306          * Either it's an old (i.e. 2.01) session file,
307          * or it's bogus.  Either way, we'll create one
308          * window, taking whatever mainWindow: resources
309          * we can find.
310          */
311         xrm_name[0] = XrmStringToQuark ("mainWindow");
312         xrm_name[2] = NULL;
313
314         /* get x position */
315         xrm_name[1] = XrmStringToQuark ("x");
316         XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
317         pPad->x = atoi((char *)value.addr);
318
319         /* get y position */
320         xrm_name[1] = XrmStringToQuark ("y");
321         XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
322         pPad->y = atoi((char *)value.addr);
323  
324         pPad->saveRestore = True;
325
326         return;
327     }      
328
329     RestorePad(pPad, 0, db);
330
331     for(i = 1; i < numPadsToRestore; i++)
332     {
333         foundPad = FindOrCreatePad(&pPad);
334         RestorePad(pPad, i, db);
335
336         if(foundPad == False)
337             RealizeNewPad(pPad);
338         else
339             ManageOldPad(pPad, False);
340     }
341 }
342
343
344 /************************************************************************
345  *
346  * RestoreMain - 
347  *
348  ***********************************************************************/
349 static void
350 RestoreMain(
351         Editor *pPad,
352         int padNum,
353         XrmDatabase db)
354 {
355     char * iconify = NULL;
356     char buf[1024];
357     XrmName xrm_name[5];
358     XrmRepresentation rep_type;
359     XrmValue value;
360
361     sprintf(buf, "mainWindow%d", padNum);
362     xrm_name[0] = XrmStringToQuark(buf);
363     xrm_name[2] = NULL;
364
365     /* get x position */
366     xrm_name[1] = XrmStringToQuark ("x");
367     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
368     pPad->x = atoi((char *)value.addr);
369
370     /* get y position */
371     xrm_name [1] = XrmStringToQuark ("y");
372     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
373     pPad->y = atoi((char *)value.addr);
374
375     /* get width */
376     xrm_name [1] = XrmStringToQuark ("width");
377     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
378     pPad->width = atoi((char *)value.addr);
379
380     /* get height */
381     xrm_name [1] = XrmStringToQuark ("height");
382     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
383     pPad->height = atoi((char *)value.addr);
384  
385    /*  Get and set whether the view is iconic  */
386    xrm_name [1] = XrmStringToQuark ("iconify");
387    XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
388    /*  If there is an iconify resource and its value is True,  */
389    /*  then mark the window as iconified.                      */
390    if ((iconify = (char *) value.addr) != NULL &&
391                                     strcmp (iconify, "True") == 0)
392       pPad->iconic = True;
393    else
394       pPad->iconic = False;
395
396     /* get the file name */
397     xrm_name [1] = XrmStringToQuark ("fileName");
398     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
399     pPad->fileStuff.fileName = strdup((char *) value.addr);
400
401     /* get workspace list */
402     xrm_name[1] = XrmStringToQuark("workspaceList");
403     XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value);
404     pPad->xrdb.workspaceList = strdup((char *) value.addr);
405
406 }
407
408
409 /************************************************************************
410  *
411  * RestorePad - 
412  *
413  ***********************************************************************/
414 void
415 RestorePad(
416         Editor *pPad,
417         int padNum,
418         XrmDatabase db)
419 {
420     RestoreMain(pPad, padNum, db);
421     pPad->saveRestore = True;
422 }