Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtprintinfo / libUI / MotifUI / Application.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: Application.C /main/9 1998/07/24 16:14:41 mgreess $ */
24 /*                                                                      *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                *
29  */
30
31 #include "Application.h"
32 #include <sys/stat.h>
33 #include <Xm/Protocols.h>
34
35 #ifndef NO_CDE
36 extern "C" {
37 #include <Dt/Dt.h>
38 #include <Dt/EnvControlP.h>
39 #include <Dt/DbUtil.h>
40 #include <Dt/Action.h>
41 #include <Dt/Session.h>
42 }
43 #endif
44
45 #include <stdlib.h>  // for putenv function
46
47 const char *SESSION_FLAG = "-session";
48 const char *SESSION_NAME = "session";
49 const char *SESSION_CLASSNAME = "Session";
50 const char *DEFAULT_FONT = "fixed";
51
52 typedef struct
53 {
54    XmFontList user_font;
55    XmFontList system_font;
56    char *session_file;
57    Dimension shadow_thickness;
58 } ApplicationArgs, *ApplicationArgsPtr;
59     
60 static XtResource resources[] =
61 {
62    {"userFont", "XmCFontList", XmRFontList, sizeof(XmFontList), 
63     XtOffsetOf (ApplicationArgs, user_font), XmRString,
64 #ifdef aix
65     (XtPointer) DEFAULT_FONT
66 #else
67     (XtPointer) "fixed"
68 #endif
69    },
70    {"systemFont", "XmCFontList", XmRFontList, sizeof(XmFontList), 
71     XtOffsetOf (ApplicationArgs, system_font), XmRString,
72 #ifdef aix
73     (XtPointer) DEFAULT_FONT
74    },
75    {(char *)SESSION_NAME, (char *)SESSION_CLASSNAME, XtRString, sizeof(char *), 
76 #else
77     (XtPointer) "fixed"
78    },
79    {"session", "Session", XtRString, sizeof(char *), 
80 #endif
81     XtOffsetOf (ApplicationArgs, session_file), XmRString, (XtPointer) NULL,
82    },
83    {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
84     sizeof (Dimension), XtOffsetOf (ApplicationArgs, shadow_thickness),
85     XmRImmediate, (XtPointer) 1
86    } 
87 };
88
89 static XrmOptionDescRec options[] =
90 {
91 #ifdef aix
92    {(char *)SESSION_FLAG, (char *)SESSION_NAME, XrmoptionSepArg, NULL}
93 #else
94    {"-session", "session", XrmoptionSepArg, NULL}
95 #endif
96 };
97
98 extern "C" {
99    extern void XmeRenderTableGetDefaultFont(XmFontList, XFontStruct **);
100
101
102 Application::Application(char *name,
103                          char *appClassName,
104                          int *_argc,
105                          char **_argv)
106         : MotifUI(NULL, name, appClassName, appClassName)
107 {
108 #ifndef NO_CDE
109    _DtEnvControl(DT_ENV_SET);
110 #endif
111
112    XtSetLanguageProc(NULL, NULL, NULL);
113    _w = XtVaAppInitialize(&appContext, appClassName, options, XtNumber(options),
114                           _argc, _argv, NULL, XmNallowShellResize, true,
115                           XmNtitle, name, XmNiconName, name, NULL);
116
117    topLevel = _w;
118    display = XtDisplay(_w);
119    root = RootWindowOfScreen(XtScreen(_w));
120    white = WhitePixelOfScreen(XtScreen(_w));
121    black = BlackPixelOfScreen(XtScreen(_w));
122    depth = DefaultDepthOfScreen(XtScreen(_w));
123    int numMouseButtons = XGetPointerMapping(display, (unsigned char *)NULL, 0);
124    bMenuButton = (numMouseButtons < 3) ? Button2 : Button3;
125    ApplicationArgs application_args;
126    XtGetApplicationResources(_w, &application_args, resources,
127                              XtNumber(resources), NULL, 0);
128    userFont = application_args.user_font;
129    userFont = application_args.system_font;
130    session_info = NULL;
131    attributes = NULL;
132    values = NULL;
133    n_attrs = 0;
134    session_path = NULL;
135    fp = NULL;
136    if (session_file = application_args.session_file)
137     {
138       if (*session_file == '/')
139          session_path = strdup(session_file);
140       else
141          DtSessionRestorePath(topLevel, &session_path, session_file);
142     }
143       
144    shadowThickness = application_args.shadow_thickness;
145    {
146      XmFontContext context;
147      if (XmFontListInitFontContext(&context, userFont))
148        {
149          XmFontListEntry entry = XmFontListNextEntry(context);
150          if (entry)
151            {
152              XmFontType _type_return;
153              fs = (XFontStruct *)XmFontListEntryGetFont(entry, &_type_return);
154              if (_type_return != XmFONT_IS_FONT)
155                XmeRenderTableGetDefaultFont(userFont, &fs);
156              font = fs->fid;
157            }
158          XmFontListFreeFontContext(context);
159        }
160    }
161
162    argc = *_argc;
163    argv = _argv;
164
165    InstallDestroyCB();
166
167    // If the user specified -display on the command line, we need 
168    // to set the environment variable DISPLAY to this value so that
169    // any aixterms or X applications launched from this program
170    // go to the same display
171    new_display = new char [strlen("DISPLAY=") +
172                            strlen(DisplayString(display)) + 1];
173    sprintf(new_display, "DISPLAY=%s", DisplayString(display));
174    putenv(new_display);
175
176    // Make the environment variable ENV set to nothing.  This is so that
177    // we don't run the user's ENV every time we open a child process.
178    putenv("ENV=");
179
180 #ifndef NO_CDE
181    if (!DtAppInitialize(appContext, display, topLevel, argv[0], appClassName))
182      {
183       // Fatal Error: could not connect to the messaging system.
184       // DtAppInitialize() has already logged an appropriate error msg
185       exit(-1);
186     }
187    // Load the filetype/action dbs; DtInvokeAction() requires this 
188    DtDbLoad();
189 #endif
190
191    Atom xa_WM_SAVE_YOURSELF = XInternAtom(display, "WM_SAVE_YOURSELF", False);
192    XmAddWMProtocols(topLevel, &xa_WM_SAVE_YOURSELF, 1);
193    XmAddWMProtocolCallback(topLevel, xa_WM_SAVE_YOURSELF, SaveSessionCB,
194                            (XtPointer)this);
195    XmAddWMProtocolCallback(topLevel,
196                            XmInternAtom(display, "WM_DELETE_WINDOW", False),
197                            CloseCB, (XtPointer)this);
198 }
199
200 Application::~Application()
201 {
202    if (userFont)
203       XmFontListFree(userFont);
204    delete session_info;
205    delete attributes;
206    delete values;
207    delete new_display;
208 }
209
210 boolean Application::SetName(char *name)
211 {       
212    if (!_w)
213       return false;
214
215    XtVaSetValues(_w, XmNtitle, name, XmNiconName, name, NULL);
216
217    return true;
218 }
219
220 boolean Application::SetVisiblity(boolean flag)
221 {       
222    if (!_w)
223       return false;
224    
225    if (flag)
226     {
227       XtRealizeWidget(_w);
228       XtVaSetValues(_w, XmNallowShellResize, False, NULL);
229     }
230
231    return true;
232 }
233
234 void Application::Run()
235 {       
236    XtAppMainLoop(appContext);
237 }
238
239 void Application::SaveSessionCB(Widget, XtPointer client_data, XtPointer)
240 {
241    Application *obj = (Application *)client_data;
242    obj->SaveMe(true);
243 }
244
245 void Application::CloseCB(Widget, XtPointer client_data, XtPointer)
246 {
247    Application *obj = (Application *)client_data;
248    obj->SaveMe();
249 }
250
251 void Application::SaveMe(boolean save_as_session)
252 {
253    char *path = NULL, *name = NULL;
254
255    if (save_as_session)
256       DtSessionSavePath(topLevel, &path, &name);
257    else
258     {
259       name = SessionFile();
260       char *path1 = SessionPath();
261       path = new char[strlen(path1) + strlen(name) + 2];
262       sprintf(path, "%s/%s", path1, name);
263       name = NULL;
264     }
265    if (path && (fp = fopen(path, "w")))
266     {
267       SaveYourSelf();
268       fflush(fp);
269       fclose(fp);
270       fp = NULL;
271     }
272
273
274    if (save_as_session)
275     {
276       char **new_argv = NULL;
277       char **_argv;
278       int _argc;
279
280       XtVaGetValues(topLevel, XmNargc, &_argc, XmNargv, &_argv, NULL);
281
282       int i;
283       if (path && name)
284        {
285          if (_argc > 2 && !STRCMP(SESSION_FLAG, _argv[1]))
286           {
287             new_argv = new char *[_argc + 1];
288             for (i = 0; i < _argc; i++)
289                new_argv[i] = _argv[i];
290             new_argv[2] = name;
291             new_argv[i] = NULL;
292           }
293          else
294           {
295             int j;
296
297             new_argv = new char *[_argc + 3];
298             new_argv[0] = _argv[0];
299             new_argv[1] = (char *)SESSION_FLAG;
300             new_argv[2] = name;
301             for (i = 1, j = 3; i < _argc; i++, j++)
302                new_argv[j] = _argv[i];
303             new_argv[j] = NULL;
304             _argc += 2;
305           }
306        }
307       else
308        {
309          new_argv = new char *[_argc + 1];
310          for (i = 0; i < _argc; i++)
311             new_argv[i] = _argv[i];
312          new_argv[i] = NULL;
313        }
314       XSetCommand(display, XtWindow(topLevel), new_argv, _argc);
315       delete [] new_argv;
316     }
317    if (path)
318       XtFree(path);
319    if (name)
320       XtFree(name);
321 }
322
323 void Application::Save(char *attribute, char *value)
324 {
325    if (fp)
326       fprintf(fp, "%s\n%s\n", attribute, value);
327 }
328
329 char *Application::Restore(char *attribute)
330 {
331    char *value = NULL;
332    if (!session_info)
333     {
334       if (!session_path)
335        {
336          char *name = SessionFile();
337          char *path = SessionPath();
338          session_path = new char[strlen(path) + strlen(name) + 2];
339          sprintf(session_path, "%s/%s", path, name);
340          session_file = strdup(session_path);
341        }
342       struct stat statbuff;
343       if (stat(session_path, &statbuff) != -1)
344        {
345          FILE *fp1;
346          if (fp1 = fopen(session_path, "r"))
347           {
348             session_info = new char[statbuff.st_size + 1];
349             fread(session_info, (unsigned int)statbuff.st_size, 1, fp1);
350             fclose(fp1);
351             session_info[statbuff.st_size] = '\0';
352             char *s, *s1 = session_info;
353             s = s1;
354             while (s && (s = strchr(s1, '\n')))
355              {
356                n_attrs++;
357                s1 = s + 1;
358              }
359
360             n_attrs /= 2;
361             attributes = new char*[n_attrs];
362             values = new char*[n_attrs];
363             s = strtok(session_info, "\n");
364             int i = 0;
365             while (s && *s)
366              {
367                attributes[i] = s;
368                values[i] = strtok(NULL, "\n");
369                s = strtok(NULL, "\n");
370                i++;
371              }
372           }
373        }
374       if (!session_info)
375          session_info = strdup("");
376     }
377    int i;
378    for (i = 0; i < n_attrs; i++)
379       if (!STRCMP(attributes[i], attribute))
380        {
381          value = values[i];
382          break;
383        }
384    return value;
385 }