Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Other / WindowSystemMotif.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: WindowSystemMotif.C /main/35 1998/04/20 12:54:36 mgreess $ */
24 /*
25  * (c) Copyright 1996 Digital Equipment Corporation.
26  * (c) Copyright 1996 Hewlett-Packard Company.
27  * (c) Copyright 1996 International Business Machines Corp.
28  * (c) Copyright 1996 Sun Microsystems, Inc.
29  * (c) Copyright 1996 Novell, Inc. 
30  * (c) Copyright 1994, 1995, 1996 FUJITSU LIMITED.
31  * (c) Copyright 1996 Hitachi.
32  */
33 /*
34  * Copyright (c) 1991 HaL Computer Systems, Inc.  All rights reserved.
35  * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
36  * States.  Use of a copyright notice is precautionary only and does not
37  * imply publication or disclosure.
38  * 
39  * This software contains confidential information and trade secrets of HaL
40  * Computer Systems, Inc.  Use, disclosure, or reproduction is prohibited
41  * without the prior express written permission of HaL Computer Systems, Inc.
42  * 
43  *                         RESTRICTED RIGHTS LEGEND
44  * Use, duplication, or disclosure by the Government is subject to
45  * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
46  * Technical Data and Computer Software clause at DFARS 252.227-7013.
47  *                        HaL Computer Systems, Inc.
48  *                  1315 Dell Avenue, Campbell, CA  95008
49  * 
50  */
51
52 #include <X11/Xmu/Editres.h>
53 #include <Xm/Xm.h>
54 #include <Xm/XmP.h>
55 #include <Xm/Protocols.h>
56 #include <Xm/Scale.h>
57
58 #include <Xm/XpmP.h>
59
60 #include <Dt/Dt.h>
61 #include <Dt/EnvControlP.h>
62
63 typedef enum {
64     DtIgnore,
65     DtInformation,
66     DtWarning,
67     DtError,
68     DtFatalError,
69     DtInternalError
70 } DtSeverity;
71
72 extern "C" void _DtSimpleError( 
73     char *progName,
74     DtSeverity severity,
75     char *help,
76     char *format,
77     ...) ;
78
79
80 extern "C" int _DtPrintDefaultErrorSafe(
81     Display *dpy,
82     XErrorEvent *event,
83     char *msg,
84     int bytes);
85
86
87 #if XmVersion < 1002
88 #include <X11/IntrinsicP.h>
89 #include <X11/CoreP.h>
90 #include <X11/StringDefs.h>
91 #endif /* XmVersion < 1002 */
92
93 #include <X11/Xmu/Converters.h>
94
95 #if XmVersion >= 1002
96 #include <Xm/RepType.h>
97 #include <Xm/AtomMgr.h>
98 #endif /* XmVersion >= 1002 */
99
100 #define C_TOC_Element
101 #define L_Basic
102
103 #define C_WindowGeometryPref
104 #define L_Preferences
105
106 #ifdef UseDlOpen
107 #   define C_XpmLib
108 #endif
109
110 #define C_WindowSystem
111 #define L_Other
112
113 #define C_ServiceMgr
114 #define C_MessageMgr
115 #define C_EnvMgr
116 #define L_Managers
117
118
119
120 #define USES_OLIAS_FONT
121
122 #include "Prelude.h"
123
124 #include "Other/XmStringLocalized.hh"
125 #include "Managers/CatMgr.hh"
126
127 #include "Registration.hh"
128
129 #include <WWL/WApplicationShell.h>
130 #include <WWL/WXmMessageBox.h>
131 #include <WWL/WXmPushButton.h>
132
133 // These guys are backups for when there is not enough
134 // colors to display the standard ones
135 #ifdef UseDlOpen
136 #include "graphic_unavailable.xbm"
137 #include "detached_bw.xbm"
138 #else
139 #include "graphic_unavailable.xpm"
140 #include "detached_bw.xpm"
141 #endif
142
143 // four bitmap images for user marks
144
145 #define mark_single_width 13
146 #define mark_single_height 13
147 static unsigned char mark_single_bits[] = {
148    0x00, 0x00, 0xfe, 0x01, 0x82, 0x02, 0x82, 0x04, 0x82, 0x08, 0x82, 0x0f,
149    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0xfe, 0x0f,
150    0x00, 0x00};
151
152 #define mark_double_width 15
153 #define mark_double_height 15
154 static unsigned char mark_double_bits[] = {
155    0x00, 0x00, 0xf8, 0x07, 0x08, 0x0a, 0x0e, 0x12, 0x0a, 0x22, 0x0a, 0x3e,
156    0x0a, 0x20, 0x0a, 0x20, 0x0a, 0x20, 0x0a, 0x20, 0x0a, 0x20, 0xfa, 0x3f,
157    0x02, 0x08, 0xfe, 0x0f, 0x00, 0x00};
158
159 #define anno_single_width 13
160 #define anno_single_height 13
161 static unsigned char anno_single_bits[] = {
162    0x00, 0x00, 0xfe, 0x01, 0x82, 0x02, 0xba, 0x04, 0x82, 0x08, 0xba, 0x0f,
163    0x02, 0x08, 0xfa, 0x0b, 0x02, 0x08, 0xfa, 0x0b, 0x02, 0x08, 0xfe, 0x0f,
164    0x00, 0x00};
165
166 #define anno_double_width 15
167 #define anno_double_height 15
168 static unsigned char anno_double_bits[] = {
169    0x00, 0x00, 0xf8, 0x07, 0x08, 0x0a, 0xee, 0x12, 0x0a, 0x22, 0xea, 0x3e,
170    0x0a, 0x20, 0xea, 0x2f, 0x0a, 0x20, 0xea, 0x2f, 0x0a, 0x20, 0xfa, 0x3f,
171    0x02, 0x08, 0xfe, 0x0f, 0x00, 0x00};
172
173 #ifdef SVR4
174 #include <signal.h>
175 #else
176 #include <sys/signal.h>
177 #endif
178
179 #ifdef hpux
180 typedef void (*SIG_PF)();
181 #endif
182
183 #include <unistd.h>
184 #include <stdio.h>
185
186 #include <DtI/ActionsI.h>
187
188 // virtual root finder
189 extern "C" {
190 #include "vroot.h"
191 }
192
193 extern Boolean print_server_error;
194
195 static String fallbacks[] = {
196 "Dtinfo.Print*background:white",
197 "Dtinfo.Print*renderTable:-dt-application-bold-r-normal-serif-0-0-0-0-p-0-iso8859-1",
198 "Dtinfo.Print*shadowThickness:0",
199 "Dtinfo.Print*highlightThickness:0",
200 "Dtinfo.Print*pform.marginHeight: 1in",
201 "Dtinfo.Print*pform.marginWidth: 1in",
202 "Dtinfo.Print*ptext.Attachment:attach_form",
203 NULL
204 };
205
206
207 static XtActionsRec DrawnBActions[] =
208     {
209         {"DeSelectAll"    , _DtHelpDeSelectAll    },
210         {"SelectAll"      , _DtHelpSelectAll      },
211         {"ActivateLink"   , _DtHelpActivateLink   },
212         {"CopyToClipboard", _DtHelpCopyAction     },
213         {"PageUpOrDown"   , _DtHelpPageUpOrDown   },
214         {"PageLeftOrRight", _DtHelpPageLeftOrRight},
215         {"NextLink"       , _DtHelpNextLink       }
216     };
217
218
219
220 WindowSystem *WindowSystem::f_window_system;
221 static Atom XA_WM_STATE;
222
223 class Shell_Info {
224 public:
225   Shell_Info (Widget w)
226     : f_shell (w),
227       f_restore (False),
228       f_size_hints (NULL)
229     { }
230
231 public:
232   Widget f_shell;
233   XSizeHints *f_size_hints;
234   bool f_has_size_hints : 1;
235   bool f_restore : 1;
236   bool f_iconic : 1;
237   bool f_has_wm_state : 1;
238 };
239
240
241 // /////////////////////////////////////////////////////////////////
242 // class constructor
243 // /////////////////////////////////////////////////////////////////
244
245 WindowSystem::WindowSystem (int &argc, char *argv[])
246 : f_shell_list (20),
247   f_default_pixmap (NULL),
248   f_defpix_width (0),
249   f_defpix_height (0),
250   f_printing(False),
251   f_detached_pixmap(NULL),
252   f_cursor_stack_pos(-1),
253   f_dtinfo_font(NULL),
254   f_dtinfo_space_font(NULL)
255 {
256   f_argc = &argc;
257   f_argv = argv;
258   f_window_system = this;
259   init();
260
261   f_modal_cursor = create_cursor ("xm_noenter16");
262   f_wait_cursor = create_cursor ("xm_hour16");
263   f_bomb_cursor = create_cursor ("bomb");
264
265   /* -------- Debugging setup.  Should be a function. -------- */
266
267   bool debugging = get_boolean_app_resource("debug");
268   if (!debugging)
269     {
270       signal (SIGABRT, /*DWC IBM (SIG_PF)*/ core_dump_handler);
271       signal (SIGBUS, /*(SIG_PF)*/ core_dump_handler);
272       signal (SIGSEGV, /*(SIG_PF)*/ core_dump_handler);
273       signal (SIGINT, interrupt_handler);
274     }
275
276   /* Reference the scale widget so Veritas Replay Xt lib can link. */
277   WidgetClass xxx = xmScaleWidgetClass;
278
279   int count;
280   char **names = XListFonts(window_system().display(),
281                             "-dt-dtinfo-*-14-*-dtinfo-?", 1, &count);
282
283   if (count && names)
284   {
285     f_dtinfo_font = XmFontListEntryLoad(f_display, *names,
286                                         XmFONT_IS_FONT, "olias");
287     f_dtinfo_space_font = XmFontListEntryLoad(f_display, *names,
288                                               XmFONT_IS_FONT, "ospace");
289     XFreeFontNames(names);
290   }
291 }
292
293 // /////////////////////////////////////////////////////////////////////////
294 // Destructor
295 // /////////////////////////////////////////////////////////////////////////
296
297 WindowSystem::~WindowSystem()
298 {
299   signal (SIGABRT, SIG_DFL);
300   signal (SIGBUS, SIG_DFL);
301   signal (SIGSEGV, SIG_DFL);
302 }
303
304 XmFontListEntry
305 WindowSystem::dtinfo_font() 
306 {
307     return f_dtinfo_font; 
308 }
309
310 XmFontListEntry 
311 WindowSystem::dtinfo_space_font() 
312 {
313     return f_dtinfo_space_font; 
314 }
315
316 WApplicationShell &
317 WindowSystem::toplevel()
318 {
319     if (f_printing) {
320         return (f_print_toplevel);
321     }
322     else {
323         return (f_toplevel);
324     }
325 }
326
327 WApplicationShell &
328 WindowSystem::printToplevel()
329 {
330     return (f_print_toplevel);
331 }
332
333 WApplicationShell &
334 WindowSystem::onlineToplevel()
335 {
336     return (f_toplevel);
337 }
338
339 Display *
340 WindowSystem::display()
341 {
342     if (f_printing) {
343         return (f_print_display);
344     }
345     else {
346         return (f_display);
347     }
348 }
349
350 Screen *
351 WindowSystem::screen()
352 {
353     if (f_printing) {
354         return (f_print_screen);
355     }
356     else {
357         return (f_screen);
358     }
359 }
360
361 Display *
362 WindowSystem::onlineDisplay()
363 {
364     return (f_display);
365 }
366
367 Display *
368 WindowSystem::printDisplay()
369 {
370     return (f_print_display);
371 }
372
373 Boolean
374 WindowSystem::printing()
375 {
376     return (f_printing);
377 }
378
379 void
380 WindowSystem::setPrintDisplay(Widget widget) 
381 {
382     f_print_toplevel = widget;
383     f_print_display = XtDisplay(widget);
384     f_print_screen = XtScreen(widget);
385 }
386
387 void
388 WindowSystem::setPrinting(Boolean state)
389 {
390     f_printing = state;
391 }
392
393 void
394 WindowSystem::update_display()
395 {
396   XmUpdateDisplay (f_toplevel);
397 }
398
399
400 // /////////////////////////////////////////////////////////////////
401 // init - initialize
402 // /////////////////////////////////////////////////////////////////
403
404 #ifdef JBM
405 extern "C" { void tml_dp_set_font_display(Display *); }
406 #endif
407
408 // command line options
409
410 // include "dbg" so we can use the startup script -debug flag independently 
411 XrmOptionDescRec options[] = {
412   {"-debug",            "*debug",         XrmoptionNoArg,  "True"},
413   {"-dbg",              "*debug",         XrmoptionNoArg,  "True"},
414   {"-author",           "*author",        XrmoptionNoArg,  "True"},
415   {"-readonly",         "*readonly",      XrmoptionNoArg,  "True"},
416   {"-ro",               "*readonly",      XrmoptionNoArg,  "True"},
417   {"-autohelp",         "*AutomaticHelp", XrmoptionNoArg,  "On"},
418   {"-nofonts",          "*NoFonts",       XrmoptionNoArg,  "True"},
419   {"-print",            "printOnly",      XrmoptionNoArg,  "True"},
420   {"-hierarchy",        "hierarchy",      XrmoptionNoArg,  "True"},
421   {"-printer",          "printer",        XrmoptionSepArg, NULL},
422   {"-copies",           "copies",         XrmoptionSepArg, NULL},
423   {"-paperSize",        "paperSize",      XrmoptionSepArg, NULL},
424   {"-silent",           "silent",         XrmoptionNoArg,  "True"},
425   {"-outputFile",       "outputFile",     XrmoptionSepArg, NULL}
426 };
427
428 static XtResource VideoResources[] =
429 {
430   {"printOnly", "PrintOnly", XmRBoolean, sizeof (Boolean),
431         XtOffsetOf (VideoShell, print_only), XmRImmediate, (XtPointer)False,
432   },
433   {"outputFile", "OutputFile", XmRString, sizeof (char *),
434         XtOffsetOf (VideoShell, file_name), XmRImmediate, (XtPointer)NULL,
435   },
436   {"hierarchy", "Hierarchy", XmRBoolean, sizeof (Boolean),
437         XtOffsetOf (VideoShell, hierarchy), XmRImmediate, (XtPointer)False,
438   },
439   {"printer", "Printer", XmRString, sizeof (char *),
440         XtOffsetOf (VideoShell, printer), XmRImmediate, (XtPointer)NULL,
441   },
442   {"copies", "Copies", XmRInt, sizeof (int),
443         XtOffsetOf (VideoShell, copies), XmRImmediate, (XtPointer)1,
444   },
445   {"paperSize", "PaperSize", XmRString, sizeof (char *),
446         XtOffsetOf (VideoShell, paper_size), XmRImmediate, (XtPointer)NULL,
447   },
448   {"silent", "Silent", XmRBoolean, sizeof (Boolean),
449         XtOffsetOf (VideoShell, silent), XmRImmediate, (XtPointer)False,
450   },
451 };
452
453 /*
454  * static function declarations
455  */
456 VideoShell* VideoShell_new(Display* display);
457
458
459 /*
460  * ------------------------------------------------------------------------
461  * Name: videoShell
462  *
463  * Description:
464  *
465  *     Access function for f_video_shell containing application resources
466  *     and command line options.
467  *
468  * Return value:
469  *
470  *     A pointer to the VideoShell structure.
471  */
472 VideoShell *
473 WindowSystem::videoShell()
474 {
475   return (f_video_shell);
476 }
477
478 /*
479  * ------------------------------------------------------------------------
480  * Name: VideoShell_new
481  *
482  * Description:
483  *
484  *     Allocates a new VideoShell data structure.
485  *
486  *     This function creates a top level application shell on the passed
487  *     video display.
488  *
489  * Return value:
490  *
491  *     A pointer to the new VideoShell structure.
492  */
493 VideoShell*
494 VideoShell_new(Display*, Widget app_shell)
495 {
496     VideoShell* me = (VideoShell*)XtCalloc(1, sizeof(VideoShell));
497
498     me->widget = app_shell;
499
500     XtGetApplicationResources(me->widget, me,
501                               VideoResources, XtNumber(VideoResources),
502                               NULL, 0);
503
504     // Modify the videoShell data based on environment variable settings
505   
506     // if DTPRINTSILENT is set then turn silent printing on
507
508     if (getenv("DTPRINTSILENT") != NULL) {
509         me->silent = True;
510     }
511
512     return me;
513 }
514
515 static int
516 xevent_error_aborter(Display *display, XErrorEvent* error_event)
517 {
518     #define _DTINFO_BUFSIZE 1024
519     char error_msg[_DTINFO_BUFSIZE];
520
521     // log error
522
523     _DtPrintDefaultErrorSafe(display, error_event, error_msg, _DTINFO_BUFSIZE);
524     _DtSimpleError("dtinfo", DtWarning, NULL, error_msg, NULL);
525     
526     // if the error occured on the print display we're going to set 
527     // a variable so that and when the job is done, right before calling
528     // XpEndJob, we call XpCancelJob, and notify the user.
529
530     if ( (display == window_system().printDisplay()) &&
531          (error_event->error_code == BadAlloc) ) {      
532         print_server_error = True;
533     }
534
535     return 0;
536
537 }
538
539 void
540 WindowSystem::init()
541 {
542   Arg    args[8];
543   int    i = 0;
544
545   XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL);
546
547   _DtEnvControl(DT_ENV_SET);
548
549   Widget app_shell = XtAppInitialize(&f_application_context, CLASS_NAME,
550                                         options, XtNumber(options),
551                                         f_argc, f_argv, fallbacks, NULL, 0);
552   f_display = XtDisplay(app_shell);
553
554 #ifdef XEV_DEBUG
555   XSynchronize(f_display, True);
556 #endif
557   XSync(f_display, False);
558   XSetErrorHandler(xevent_error_aborter);
559
560 #if 0
561   XtAppSetFallbackResources(f_application_context, fallbacks);
562 #endif
563
564   //  exit if display cannot be opened.  this code will need to be revised
565   //  if we ever want to handle gui-less printing
566
567   if (f_display == (Display*)NULL)
568   {
569       fprintf(stderr, CATGETS(Set_WindowSystem, 3, "Unable to open display.\n"));
570       exit(1);
571   }
572     
573   //  Create the top level video shell
574
575   f_video_shell = VideoShell_new(f_display, app_shell);
576
577   //  Create a new AppPrintData object here and initialize it since 
578   //  the $%^& doesn't seem to get called.
579
580   f_AppPrintData = new AppPrintData;
581   f_AppPrintData->f_print_data = (DtPrintSetupData*)XtCalloc(1, sizeof(DtPrintSetupData));
582   f_AppPrintData->f_pform = NULL ;
583   f_AppPrintData->f_print_dialog = NULL;
584   f_AppPrintData->f_print_shell = NULL;
585   f_AppPrintData->f_print_only = f_video_shell->print_only;
586   f_toplevel = f_video_shell->widget;
587
588   if (DtAppInitialize( f_application_context,
589                f_display, f_toplevel, f_argv[0], CLASS_NAME) == False)
590   {
591      /* DtAppInitialize() has already logged an appropriate error msg */
592      exit(-1);
593   }
594
595   // Make sure this shell never appears. 
596   XtSetMappedWhenManaged (f_toplevel, False);
597
598   XtAppAddActions (f_application_context, DrawnBActions, XtNumber (DrawnBActions));
599
600   //  register_shell (f_toplevel) 
601
602   f_display = XtDisplay(f_toplevel);
603   // NOTE: Check for failure DJB
604 #ifdef JBM
605   tml_dp_set_font_display(f_display);
606 #endif
607
608   // Create atom used elsewhere by agents
609   f_wm_delete_window = XmInternAtom (f_display, "WM_DELETE_WINDOW", False);
610   XA_WM_STATE = XmInternAtom (f_display, "WM_STATE", False);
611
612   // -------- Add some converters -------- //
613
614 #if XmVersion < 1002
615   // This converter let's us specify form connections in resources
616   static XtConvertArgRec parentCvtArg[] = {
617     { XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.parent),
618       sizeof(Widget)}
619   };
620   XtSetTypeConverter (XtRString, XtRWindow, XmuNewCvtStringToWidget,
621               parentCvtArg, XtNumber (parentCvtArg), XtCacheNone, NULL);
622 #endif /* XmVersion < 1002 */
623
624   XtAddConverter (XtRString, XtRGravity, XmuCvtStringToGravity, NULL, 0);
625
626 #if XmVersion >= 1002
627   XmRepTypeInstallTearOffModelConverter();
628 #endif /* XmVersion >= 1002 */
629
630   // NOTE: Really need to install a string to pixmap converter!
631   /* -------- Get some pixmaps. -------- */
632
633   f_screen = XtScreen(f_toplevel);
634   f_nofonts = get_boolean_default ("NoFonts");
635
636   f_locked_pixmap = NULL;
637   f_semilocked_pixmap  = NULL;
638   f_unlocked_pixmap = NULL; 
639
640   XImage *mark_single =
641         XCreateImage(f_display, DefaultVisualOfScreen(f_screen),
642         1, XYBitmap, 0, (char*)mark_single_bits,
643         mark_single_width, mark_single_height, 8, 0);
644   mark_single->byte_order = LSBFirst;
645   mark_single->bitmap_bit_order = LSBFirst;
646   mark_single->bitmap_unit = 8;
647
648   XImage *mark_double =
649         XCreateImage(f_display, DefaultVisualOfScreen(f_screen),
650         1, XYBitmap, 0, (char*)mark_double_bits,
651         mark_double_width, mark_double_height, 8, 0);
652   mark_double->byte_order = LSBFirst;
653   mark_double->bitmap_bit_order = LSBFirst;
654   mark_double->bitmap_unit = 8;
655
656   XImage *anno_single =
657         XCreateImage(f_display, DefaultVisualOfScreen(f_screen),
658         1, XYBitmap, 0, (char*)anno_single_bits,
659         anno_single_width, anno_single_height, 8, 0);
660   anno_single->byte_order = LSBFirst;
661   anno_single->bitmap_bit_order = LSBFirst;
662   anno_single->bitmap_unit = 8;
663                 
664   XImage *anno_double =
665         XCreateImage(f_display, DefaultVisualOfScreen(f_screen),
666         1, XYBitmap, 0, (char*)anno_double_bits,
667         anno_double_width, anno_double_height, 8, 0);
668   anno_double->byte_order = LSBFirst;
669   anno_double->bitmap_bit_order = LSBFirst;
670   anno_double->bitmap_unit = 8;
671
672   XmInstallImage(mark_single, "mark_single");
673   XmInstallImage(mark_double, "mark_double");
674   XmInstallImage(anno_single, "anno_single");
675   XmInstallImage(anno_double, "anno_double");
676 }
677
678 Pixmap 
679 WindowSystem::locked_pixmap(Widget w)
680
681     Pixel  fg, bg;
682
683     if (!f_locked_pixmap) {
684         XtVaGetValues(w,
685                       XmNforeground, &fg,
686                       XmNbackground, &bg,
687                       NULL);
688         
689         f_locked_pixmap = XmGetPixmap (f_screen, "locked.xbm", fg, bg);
690         if (f_locked_pixmap == XmUNSPECIFIED_PIXMAP) {
691             fprintf(stderr, "Couldn't load locked.xbm.\n");
692         }
693     }
694     
695     return (f_locked_pixmap); 
696 }
697
698 Pixmap 
699 WindowSystem::unlocked_pixmap(Widget w)
700
701     Pixel  fg, bg;
702
703     
704     if (!f_unlocked_pixmap) {
705         XtVaGetValues(w,
706                       XmNforeground, &fg,
707                       XmNbackground, &bg,
708                       NULL);
709         
710         f_unlocked_pixmap = XmGetPixmap (f_screen, "unlocked.xbm", fg, bg);
711         if (f_unlocked_pixmap == XmUNSPECIFIED_PIXMAP) {
712             fprintf(stderr, "Couldn't load locked.xbm.\n");
713         }
714     }
715
716     return (f_unlocked_pixmap); 
717 }
718
719 Pixmap 
720 WindowSystem::semilocked_pixmap(Widget w)
721
722     Pixel  fg, bg;
723
724     if (!f_semilocked_pixmap) {
725         XtVaGetValues(w,
726                       XmNforeground, &fg,
727                       XmNbackground, &bg,
728                       NULL);
729         
730         f_semilocked_pixmap = XmGetPixmap (f_screen, "semilocked.xbm", fg, bg);
731         if (f_semilocked_pixmap == XmUNSPECIFIED_PIXMAP) {
732             fprintf(stderr, "Couldn't load locked.xbm.\n");
733         }
734     }
735
736     return (f_semilocked_pixmap); 
737 }
738
739 // /////////////////////////////////////////////////////////////////
740 // run - main event handling loop
741 // /////////////////////////////////////////////////////////////////
742
743 void
744 WindowSystem::run()
745 {
746     // don't realize the toplevel shell if we are doing print only
747
748     toplevel().Realize();
749
750     service_manager().establish_server();
751
752     XtAppMainLoop (app_context());
753 }
754
755
756 // return value is success/failure value 
757 unsigned long
758 WindowSystem::get_color( const char * colorval, unsigned long &pixel) const
759 {
760     // NOTE: do we have to free these colors on exit ??? 
761
762
763     pixel = 0 ;                 // a reasonable value on failures ! 
764
765     XColor xcolor ;
766     Status status ;
767     Colormap colormap = DefaultColormap(f_display,DefaultScreen(f_display));
768
769     status = XParseColor( f_display,
770                           colormap,
771                           colorval,
772                           &xcolor);
773     
774     //  return now if call failed
775     if (!status)
776       return status ;
777
778     // now see if we can get the requested color
779     status = XAllocColor( f_display,
780                           colormap,
781                           &xcolor );
782
783     if (status)
784       pixel = xcolor.pixel ;
785
786     return status ;
787
788 }
789
790
791 // /////////////////////////////////////////////////////////////////
792 // register_shell - register a toplevel shell for cursor stuff
793 // /////////////////////////////////////////////////////////////////
794
795 // TMP hack for bogus HGL help lib
796 extern "C" { void olias_register_shell (Widget); }
797 void olias_register_shell (Widget shell)
798 {
799   window_system().register_shell ((WShell *) shell);
800 }
801
802 void
803 WindowSystem::register_shell (WShell *shell)
804 {
805   Shell_Info *si = new Shell_Info (*shell);
806   f_shell_list.append ((FolioObject *) si);
807
808   shell->SetDestroyCallback (this, (WWL_FUN)&WindowSystem::unregister_shell,
809                              (void *) si);
810
811   XtAddEventHandler (*shell, (EventMask) 0, TRUE,
812                      (XtEventHandler) _XEditResCheckMessages, NULL);
813 }
814
815 void
816 WindowSystem::register_full_modal_shell (WShell *shell)
817 {
818   Shell_Info *si = new Shell_Info (*shell);
819   f_shell_list.append ((FolioObject *) si);
820
821   shell->SetPopupCallback (this, (WWL_FUN) &WindowSystem::full_modal_cursor);
822   shell->SetPopdownCallback (this,(WWL_FUN) &WindowSystem::reset_cursor);
823   shell->SetDestroyCallback (this, (WWL_FUN) &WindowSystem::unregister_shell,
824                              (void *) si);
825
826   XtAddEventHandler (*shell, (EventMask) 0, TRUE,
827                      (XtEventHandler) _XEditResCheckMessages, NULL);
828 }
829
830 void
831 WindowSystem::register_primary_modal_shell (WShell *shell)
832 {
833   Shell_Info *si = new Shell_Info (*shell);
834   shell->SetPopupCallback (this, (WWL_FUN)&WindowSystem::primary_modal_cursor);
835   shell->SetPopdownCallback (this,(WWL_FUN) &WindowSystem::reset_cursor);
836   shell->SetDestroyCallback (this, (WWL_FUN) &WindowSystem::unregister_shell,
837                              (void *) si);
838
839   XtAddEventHandler (*shell, (EventMask) 0, TRUE,
840                      (XtEventHandler) _XEditResCheckMessages, NULL);
841 }
842
843
844 // /////////////////////////////////////////////////////////////////
845 // unregister_shell
846 // /////////////////////////////////////////////////////////////////
847
848 void
849 WindowSystem::unregister_shell (WCallback *wcb)
850 {
851   // Reset the cursor if it is currently set because of this shell. 
852   if (f_cursor_stack_pos >= 0 &&
853       f_cursor_stack[f_cursor_stack_pos].exception == wcb->GetWidget())
854     reset_cursor (wcb);
855
856   Shell_Info *si = (Shell_Info *) wcb->ClientData();
857   f_shell_list.remove ((FolioObject *) si);
858   if (si->f_size_hints != NULL)
859     XFree ((char *) si->f_size_hints);
860   delete si;
861 }
862
863
864 // /////////////////////////////////////////////////////////////////
865 // set_cursor - turn a cursor on
866 // /////////////////////////////////////////////////////////////////
867
868 void
869 WindowSystem::set_cursor (Cursor cursor, Widget exception)
870 {
871   Widget shell;
872   //  ON_DEBUG (printf ("Cursor change <%d>\n", f_cursor_stack_pos));
873   for (int i = 0; i < f_shell_list.length(); i++)
874     {
875       shell = ((Shell_Info *) f_shell_list[i])->f_shell;
876       if (shell != exception && XtWindow (shell) != 0)
877         {
878           //  ON_DEBUG (printf("  Setting cursor on %s\n", XtName(shell)));
879           XDefineCursor (f_display, XtWindow (shell), cursor);
880         }
881     }
882   XFlush (f_display);
883   // Save the cursor setting on the cursor stack.
884   ON_DEBUG (printf ("Setting cursor #%d\n", f_cursor_stack_pos + 1));
885   assert (f_cursor_stack_pos <
886           (int)(sizeof(f_cursor_stack) / sizeof(f_cursor_stack[0])));
887   f_cursor_stack_pos++;
888   f_cursor_stack[f_cursor_stack_pos].cursor = cursor;
889   f_cursor_stack[f_cursor_stack_pos].exception = exception;
890 }
891
892
893 // /////////////////////////////////////////////////////////////////
894 // reset_cursor - reset the cursor to the previous
895 // /////////////////////////////////////////////////////////////////
896
897 void
898 WindowSystem::reset_cursor (WCallback *wcb)
899 {
900   // Make sure a cursor has been set first. 
901   assert (f_cursor_stack_pos >= 0);
902   Widget shell;
903   Widget exception = wcb ? wcb->GetWidget() : NULL;
904   f_cursor_stack_pos--;
905   Cursor cursor;
906   if (f_cursor_stack_pos >= 0)
907     cursor = f_cursor_stack[f_cursor_stack_pos].cursor;
908
909   for (int i = 0; i < f_shell_list.length(); i++)
910     {
911       shell = ((Shell_Info *) f_shell_list[i])->f_shell;
912       if (shell != exception && XtWindow (shell) != 0)
913         // Reset the previous cursor if there's one on the stack, revert
914         // to default cursor if the stack is empty. 
915         //  printf ("Resetting cursor on %s\n", XtName(shell));
916         if (f_cursor_stack_pos >= 0 &&
917             shell != f_cursor_stack[f_cursor_stack_pos].exception)
918           XDefineCursor (f_display, XtWindow (shell), cursor);
919         else
920           XUndefineCursor (f_display, XtWindow (shell));
921     }
922   XFlush (f_display);
923 }
924
925
926 // /////////////////////////////////////////////////////////////////
927 // modal_cursor - turn on the modal cursor
928 // /////////////////////////////////////////////////////////////////
929
930 void
931 WindowSystem::full_modal_cursor (WCallback *wcb)
932 {
933   set_cursor (f_modal_cursor, wcb ? wcb->GetWidget() : (Widget) NULL);
934   // Make sure the cursor of a freshly popped up dialog is the default. 
935   if (wcb && wcb->GetWidget())
936     XUndefineCursor (f_display, XtWindow (wcb->GetWidget()));
937 }
938
939 void
940 WindowSystem::primary_modal_cursor (WCallback *wcb)
941 {
942   // NOTE: really needs to traverse up hierarchy setting cursor on shell
943   // parents! 
944   set_cursor (f_modal_cursor, wcb ? wcb->GetWidget() : (Widget) NULL);
945 }
946
947
948 // /////////////////////////////////////////////////////////////////
949 // create_cursor
950 // /////////////////////////////////////////////////////////////////
951
952 Cursor
953 WindowSystem::create_cursor (const char *filename)
954 {
955   Cursor cursor;
956   Pixmap cursor_bits, cursor_mask;
957   Screen *screen = DefaultScreenOfDisplay (f_display);
958   static XColor white = { 0, ~0, ~0, ~0, DoRed | DoGreen | DoBlue };
959   static XColor black = { 0,  0,  0,  0, DoRed | DoGreen | DoBlue };
960   int  hot_x, hot_y;
961   int depth;
962   Boolean success;
963
964   // Get the cursor pixmap. 
965   cursor_bits = XmGetPixmapByDepth (screen, (char *) filename, 1, 0, 1);
966   if (cursor_bits == XmUNSPECIFIED_PIXMAP)
967     {
968       fprintf (stderr, "Unable to load bitmap %s\n", filename);
969       abort();
970     }
971
972   success = XmeGetPixmapData (screen, cursor_bits, //
973                               0,                   // image_name
974                               &depth,              // depth
975                               0, 0,                // foreground, background
976                               &hot_x, &hot_y,      // 
977                               0, 0);               // width, height
978
979   assert (success);
980
981   // Get the cursor mask pixmap. 
982   char *mask_filename = new char [strlen(filename) + 2];
983   strcpy (mask_filename, filename);
984   strcat (mask_filename, "m");
985   cursor_mask = XmGetPixmapByDepth (screen, mask_filename, 1, 0, 1);
986   if (cursor_mask == XmUNSPECIFIED_PIXMAP)
987     {
988       fprintf (stderr, "Unable to load bitmap %s\n", mask_filename);
989       abort();
990     }
991
992   delete [] mask_filename;
993
994   cursor = XCreatePixmapCursor (f_display, cursor_bits, cursor_mask,
995                                 &black, &white, hot_x, hot_y);
996
997   XmDestroyPixmap (screen, cursor_bits);
998   XmDestroyPixmap (screen, cursor_mask);
999
1000   return (cursor);
1001 }
1002
1003
1004 // /////////////////////////////////////////////////////////////////
1005 // core_dump_handler
1006 // /////////////////////////////////////////////////////////////////
1007
1008 void
1009 WindowSystem::core_dump_handler (int signal_number)
1010 {
1011   if ((XtWindow ((Widget)window_system().toplevel())) != 0)
1012     {
1013       WXmMessageDialog byebye (window_system().toplevel(), "core_dump");
1014       XtVaSetValues((Widget)byebye, XmNmessageString,
1015         (XmString)XmStringLocalized(CATGETS(Set_WindowSystem, 2,
1016                                             "Bombing...")), NULL);
1017
1018       WShell shell (XtParent ((Widget) byebye));
1019       window_system().register_shell (&shell);
1020       window_system().set_cursor (window_system().f_bomb_cursor);
1021       XtVaSetValues((Widget)shell, XmNtitle, 
1022         CATGETS(Set_WindowSystem, 1, "Dtinfo: Fatal Error"), NULL);
1023
1024       byebye.OkPB().Unmanage();
1025       byebye.CancelPB().Unmanage();
1026       byebye.HelpPB().Unmanage();
1027       byebye.Separator().Unmanage();
1028
1029       byebye.Manage();
1030       // Wait for window manager then process events.
1031       // The best solution would be to wait for the dialog to be mapped,
1032       // but this generally works. 
1033       XSync (window_system().f_display, False);
1034       XmUpdateDisplay (byebye);
1035       sleep (1);
1036       XmUpdateDisplay (byebye);
1037     }
1038   else
1039     {
1040       fputs ("Fatal error: core dumping...\n", stderr);
1041     }
1042
1043   signal (signal_number, SIG_DFL);
1044   kill (getpid(), signal_number);
1045 }
1046
1047 // /////////////////////////////////////////////////////////////////
1048 // Get default pixmap
1049 // /////////////////////////////////////////////////////////////////
1050
1051 Pixmap
1052 WindowSystem::default_pixmap (Dimension *width, Dimension *height)
1053 {
1054     Pixmap temp_pixmap;
1055     Dimension temp_width, temp_height;
1056
1057     // if printing return default print pixmap info
1058
1059     if (f_printing) {
1060         if (f_default_print_pixmap) {       
1061             *width = f_print_defpix_width;
1062             *height = f_print_defpix_height;
1063             return f_default_print_pixmap;          
1064         }
1065     }
1066
1067
1068     // if not printing return default print pixmap info
1069
1070     else {
1071         if (f_default_pixmap) {     
1072             *width = f_defpix_width;
1073             *height = f_defpix_height;
1074             return f_default_pixmap;        
1075         }
1076     }    
1077
1078     // NOTE: name should be a resource 
1079     temp_pixmap = read_pixmap("default.xpm", width, height);
1080     temp_width = *width ;
1081     temp_height = *height ;
1082     
1083     if (temp_pixmap == 0){
1084
1085 #ifdef UseDlOpen
1086         Screen* screen = XtScreen((Widget)toplevel());
1087         temp_pixmap =
1088             XCreatePixmapFromBitmapData(f_display, XtWindow((Widget)toplevel()),
1089                                         default_bits, default_width, default_height,
1090                                         screen->black_pixel, screen->white_pixel,
1091                                         DefaultDepthOfScreen(screen));
1092         
1093         if (! temp_pixmap)
1094             throw(CASTEXCEPT Exception());
1095         
1096         temp_width = default_width;
1097         temp_height = default_height;
1098 #else
1099         int status ;
1100         XpmAttributes xpm_attr ;
1101         xpm_attr.valuemask = 0 ;
1102         
1103         status = XmeXpmCreatePixmapFromData(f_display,
1104                                             XtWindow((Widget)toplevel()),
1105                                             graphic_unavailable_data,
1106                                             &temp_pixmap,
1107                                             NULL, &xpm_attr);
1108         temp_width = xpm_attr.width;
1109         temp_height = xpm_attr.height ;
1110 #endif
1111         
1112         *width = temp_width ;
1113         *height = temp_height ;
1114     }
1115
1116     // if printing, store values in print variables
1117
1118     if (f_printing) {
1119         f_default_print_pixmap = temp_pixmap;
1120         f_print_defpix_width = temp_width;
1121         f_print_defpix_height = temp_height;    
1122     }
1123
1124     // if not printing store values in display variables
1125
1126     else {
1127         f_default_pixmap = temp_pixmap;
1128         f_defpix_width = temp_width;
1129         f_defpix_height = temp_height;
1130     }
1131
1132     return temp_pixmap;
1133 }
1134
1135 Pixmap
1136 WindowSystem::detached_pixmap(Dimension *width, Dimension *height)
1137 {
1138   if (f_detached_pixmap){
1139     *width = f_detached_width ;
1140     *height = f_detached_height ;
1141   } else { 
1142     // NOTE: name should be a resource 
1143     f_detached_pixmap = read_pixmap("detached.xpm", width, height);
1144     f_detached_width = *width ;
1145     f_detached_height = *height ;
1146     if (f_detached_pixmap == 0) {
1147 #ifdef UseDlOpen
1148       Screen* screen = XtScreen((Widget)toplevel());
1149       f_detached_pixmap =
1150         XCreatePixmapFromBitmapData(f_display, XtWindow((Widget)toplevel()),
1151                 detached_bits, detached_width, detached_height,
1152                 screen->black_pixel, screen->white_pixel,
1153                 DefaultDepthOfScreen(screen));
1154
1155       int status = f_detached_pixmap ? 0 : 1;
1156
1157       f_detached_width  = detached_width;
1158       f_detached_height = detached_height;
1159 #else
1160       XpmAttributes xpm_attr;
1161       xpm_attr.valuemask = 0 ;
1162
1163       int status = XmeXpmCreatePixmapFromData(f_display,
1164                                            XtWindow((Widget)toplevel()),
1165                                            detached_pixmap_data,
1166                                            &f_detached_pixmap,
1167                                            NULL, &xpm_attr);
1168       f_detached_width = xpm_attr.width ;
1169       f_detached_height = xpm_attr.height ;
1170 #endif
1171       
1172       if (status != XpmSuccess){
1173         fprintf(stderr, "missing pixmap \"detached.xpm\"\n");
1174         throw(CASTEXCEPT Exception());
1175       }else{
1176         *width = f_detached_width ;
1177         *height = f_detached_height ;
1178       }
1179     }
1180   }
1181   return f_detached_pixmap ;
1182 }
1183
1184
1185 Pixmap 
1186 WindowSystem::read_pixmap(const char *pname,
1187                           Dimension *width, Dimension *height)
1188
1189 {
1190   XpmAttributes  xpm_attributes;
1191   int            status;
1192   char           fname[255];
1193
1194   Pixmap        pixmap ;
1195
1196   xpm_attributes.valuemask = 0;
1197
1198   strcpy(fname, pname);
1199
1200 #ifdef UseDlOpen
1201   status = xpm_lib().ReadFileToPixmap (f_display, XtWindow ((Widget)toplevel()),
1202                                 fname, &pixmap, NULL, &xpm_attributes);
1203 #else
1204   status = XmeXpmReadFileToPixmap (f_display, XtWindow ((Widget)toplevel()),
1205                                 fname, &pixmap, NULL, &xpm_attributes);
1206 #endif
1207
1208   if (status != XpmSuccess) {
1209     pixmap = NULL;
1210     *width = 0;
1211     *height = 0;
1212
1213     // NOTE: exception to throw here! 
1214
1215   }
1216   else {
1217     *width = xpm_attributes.width;
1218     *height = xpm_attributes.height;
1219   }
1220
1221   return pixmap ;
1222 }
1223
1224
1225 bool
1226 WindowSystem::get_boolean_default (const char *name)
1227 {
1228   Boolean value;
1229
1230   XtResource resource [1];
1231   
1232   resource[0].resource_name = (char *) name;
1233   resource[0].resource_class = (char *) name;
1234   resource[0].resource_type = XtRBoolean;
1235   resource[0].resource_size = sizeof(Boolean);
1236   resource[0].resource_offset = NULL;
1237   resource[0].default_type = XtRImmediate;
1238   resource[0].default_addr = False;
1239
1240   XtGetApplicationResources(toplevel(), &value, resource, 1, NULL, 0);
1241
1242   return ((bool) value);
1243 }
1244
1245 int
1246 WindowSystem::get_int_default (const char *name)
1247 {
1248   int value;
1249
1250   XtResource resource [1];
1251   
1252   resource[0].resource_name = (char *) name;
1253   resource[0].resource_class = (char *) name;
1254   resource[0].resource_type = XtRInt;
1255   resource[0].resource_size = sizeof(int);
1256   resource[0].resource_offset = NULL;
1257   resource[0].default_type = XtRImmediate ;
1258   resource[0].default_addr = 0;
1259
1260   XtGetApplicationResources(toplevel(), &value, resource, 1, NULL, 0);
1261
1262   return (value);
1263 }
1264
1265 const char *
1266 WindowSystem::get_string_default (const char *name)
1267 {
1268   XtResource resource [1];
1269   String string;
1270   
1271   resource[0].resource_name = (char *) name;
1272   resource[0].resource_class = (char *) name;
1273   resource[0].resource_type = XtRString;
1274   resource[0].resource_size = sizeof(String);
1275   resource[0].resource_offset = NULL;
1276   resource[0].default_type = XtRString;
1277   resource[0].default_addr = "";
1278
1279   XtGetApplicationResources(toplevel(), &string, resource, 1, NULL, 0);
1280
1281   return (string);
1282 }
1283
1284 const WindowGeometry &
1285 WindowSystem::get_geometry_default (const char *name)
1286 {
1287   XtResource resource [1];
1288   String string;
1289   static WindowGeometry wg;
1290   
1291   resource[0].resource_name = (char *) name;
1292   resource[0].resource_class = (char *) name;
1293   resource[0].resource_type = XtRString;
1294   resource[0].resource_size = sizeof(String);
1295   resource[0].resource_offset = NULL;
1296   resource[0].default_type = XtRString;
1297   resource[0].default_addr = "0x0";
1298
1299   XtGetApplicationResources(toplevel(), &string, resource, 1, NULL, 0);
1300
1301   // -1 is sentinel value for now.
1302   wg.ulx = wg.uly = -1;
1303   wg.width = wg.height = 0;
1304   XParseGeometry (string, &wg.ulx, &wg.uly, &wg.width, &wg.height);
1305
1306   return (wg);
1307 }
1308
1309
1310 Pixel
1311 WindowSystem::get_color_default(const char *name)
1312 {
1313   Pixel value ;
1314
1315   XtResource resource [1];
1316   
1317   resource[0].resource_name = (char *) name;
1318   resource[0].resource_class = (char *) name;
1319   resource[0].resource_type = XtRPixel;
1320   resource[0].resource_size = sizeof(Pixel);
1321   resource[0].resource_offset = NULL;
1322   resource[0].default_type = XtRImmediate ;
1323   resource[0].default_addr = (XtPointer)
1324     WhitePixelOfScreen(DefaultScreenOfDisplay(f_display));
1325
1326   XtGetApplicationResources(toplevel(), &value, resource, 1, NULL, 0);
1327
1328   return value ;
1329 }
1330
1331
1332 char *
1333 WindowSystem::get_message (const char *message_name)
1334 {
1335   XtResource resource[1];
1336   String     string;
1337   static char default_message[256];
1338
1339   resource[0].resource_name = (char *) message_name;
1340   resource[0].resource_class = "Message";
1341   resource[0].resource_type = XtRString;
1342   resource[0].resource_size = sizeof(String);
1343   resource[0].resource_offset = NULL;
1344   resource[0].default_type = XtRString;
1345   resource[0].default_addr = default_message;
1346
1347   XtGetApplicationResources (toplevel(), &string, resource, 1, NULL, 0);
1348
1349   if (string == default_message)
1350     sprintf (string, "%s (Message description not found)", message_name);
1351
1352   return (string);
1353 }
1354
1355 XmString
1356 WindowSystem::make_space (int space_to_fill, Widget w)
1357 {
1358   // make sure we can deal with bad args, as space is usually a calculated
1359   // value 
1360   if (space_to_fill <= 0)
1361     return WXmString("").disown();
1362
1363   char space_array[256];
1364   int i;
1365
1366   // Check for missing fonts case
1367   if (f_nofonts)
1368     {
1369       // get the font that the widget is using
1370       XmFontList fontlist;
1371       XtVaGetValues (w, XmNfontList, &fontlist, NULL);
1372
1373       // Get width of space character in the font
1374       WXmString sp(" ");
1375       Dimension width = XmStringWidth (fontlist, sp);
1376
1377       // compute closest number of spaces
1378       int nspaces = space_to_fill / width + 1;
1379
1380       // generate space string
1381       for (i = 0; i < nspaces && i < 255; i++)
1382         space_array[i] = ' ';
1383       space_array[i] = '\0';
1384
1385       return WXmString (space_array).disown();
1386     }
1387
1388   int thirty_two, sixteen, eight, four, two, one ;
1389
1390   thirty_two = space_to_fill / 32 ;
1391   space_to_fill -= 32 * thirty_two ;
1392
1393   sixteen = space_to_fill / 16 ;
1394   space_to_fill -= 16 * sixteen ;
1395
1396   eight = space_to_fill / 8 ;
1397   space_to_fill -= 8 * eight ;
1398
1399   four = space_to_fill / 4 ;
1400   space_to_fill -= 4 * four ;
1401
1402   two = space_to_fill / 2 ;
1403   space_to_fill -= 2 * two ;
1404
1405   one = space_to_fill ;
1406
1407   space_array[0] = 0 ;
1408
1409   if (thirty_two != 0){
1410     for (i = 0 ; i < thirty_two ; i++)
1411       space_array[i] = OLIAS_SPACE32 ;
1412     space_array[i] = 0 ;
1413   } 
1414   WXmString string_32(space_array, OLIAS_SPACE_FONT) ;
1415
1416   
1417   space_array[0] = 0 ;
1418   if (sixteen != 0){
1419     for (i = 0 ; i < sixteen ; i++)
1420       space_array[i] = OLIAS_SPACE16 ;
1421     space_array[i] = 0 ;
1422   } 
1423   WXmString string_16(space_array, OLIAS_SPACE_FONT) ;
1424
1425   space_array[0] = 0 ;
1426   if (eight != 0){
1427     for (i = 0 ; i < eight ; i++)
1428       space_array[i] = OLIAS_SPACE08 ;
1429     space_array[i] = 0 ;
1430   }
1431   WXmString string_8(space_array, OLIAS_SPACE_FONT) ;
1432
1433   space_array[0] = 0 ;
1434   if (four != 0){
1435     for (i = 0 ; i < four; i++)
1436       space_array[i] = OLIAS_SPACE04 ;
1437     space_array[i] = 0 ;
1438   }
1439   WXmString string_4(space_array, OLIAS_SPACE_FONT) ;
1440
1441   space_array[0] = 0 ;
1442   if (two != 0){
1443     for (i = 0 ; i < two ; i++)
1444       space_array[i] = OLIAS_SPACE02 ;
1445     space_array[i] = 0 ;
1446   }
1447   WXmString string_2(space_array, OLIAS_SPACE_FONT) ;
1448
1449   space_array[0] = 0 ;
1450   if (one != 0){
1451     for (i = 0 ; i < one ; i++)
1452       space_array[i] = OLIAS_SPACE01 ;
1453     space_array[i] = 0 ;
1454   }
1455   WXmString string_1(space_array, OLIAS_SPACE_FONT) ;
1456
1457   WXmString space = string_32 + string_16 + string_8 + string_4 + string_2 + string_1 ;
1458
1459   return space.disown();
1460 }
1461
1462
1463 // /////////////////////////////////////////////////////////////////
1464 // wait_for_wm
1465 // /////////////////////////////////////////////////////////////////
1466
1467 static void
1468 wait_for_wm (Widget, XtPointer client_data, XEvent *event, Boolean *)
1469 {
1470   // See if the property we're waiting for has changed.
1471   if (event->type == PropertyNotify &&
1472       event->xproperty.atom == XA_WM_STATE)
1473     {
1474       // Got our event.  waiting_for_wm = False. 
1475       *((bool *) client_data) = False;
1476     }
1477 }
1478
1479 // /////////////////////////////////////////////////////////////////
1480 // show_all_windows
1481 // /////////////////////////////////////////////////////////////////
1482
1483
1484 /*  Here's how this routine works:
1485
1486     For each shell window
1487       if the window needs to be restored
1488          map the window
1489          restore the initial state to normal if it was iconic
1490          restore the size hints if there were any
1491
1492 */
1493
1494 void
1495 WindowSystem::show_all_windows()
1496 {
1497   Shell_Info *si;
1498   Boolean waiting_for_wm;
1499
1500   for (int i = 0; i < f_shell_list.length(); i++)
1501     {
1502       si = (Shell_Info *) f_shell_list[i];
1503       if (si->f_restore)
1504         {
1505           // Set up an event handler so we can tell when the window
1506           // manager has finished dealing with our map request.
1507           if (si->f_has_wm_state)
1508             {
1509               waiting_for_wm = True;
1510               XtAddEventHandler (si->f_shell, PropertyChangeMask, False,
1511                                  (XtEventHandler) wait_for_wm,
1512                                  &waiting_for_wm);
1513             }
1514             
1515           // Get the window back on the screen. 
1516           XMapWindow (f_display, XtWindow (si->f_shell));
1517
1518           // Wait for wm if one is running. 
1519           if (si->f_has_wm_state)
1520             {
1521               XEvent event;
1522               ON_DEBUG (printf ("Wait for wm to handle 0x%p", si->f_shell));
1523               while (waiting_for_wm)
1524                 {
1525                   XtAppNextEvent (f_application_context, &event);
1526                   XtDispatchEvent (&event);
1527                 }
1528               // Get rid of event handler now. 
1529               XtRemoveEventHandler (si->f_shell, PropertyChangeMask, False,
1530                                     (XtEventHandler) wait_for_wm,
1531                                     &waiting_for_wm);
1532             }
1533
1534           ON_DEBUG (printf (" - done\n"));
1535           // Now that the wm is finished (if there is one), we can reset
1536           // the various state variables. 
1537           if (si->f_iconic)
1538             {
1539               // If it was iconic, reset the initial state.
1540               WWMShell (si->f_shell).InitialState (NormalState);
1541             }
1542           else
1543             {
1544               // Restore the the size hints, because we set USPosition
1545               // and USSize to prevent interactive placement.
1546               if (si->f_has_size_hints)
1547                 XSetWMNormalHints (f_display, XtWindow (si->f_shell),
1548                                    si->f_size_hints);
1549             }
1550
1551           // Reset the restore flag.
1552           si->f_restore = FALSE;
1553         }
1554     }
1555 }
1556
1557 // /////////////////////////////////////////////////////////////////
1558 // generally necessary after a fork to avoid weird conditions
1559 // /////////////////////////////////////////////////////////////////
1560
1561 void
1562 WindowSystem::close_display_connection()
1563 {
1564   close (ConnectionNumber(display()));
1565 }
1566
1567
1568 // /////////////////////////////////////////////////////////////////
1569 // interrupt_handler - deal with user interrupt (usually ^C)
1570 // /////////////////////////////////////////////////////////////////
1571
1572 void
1573 WindowSystem::interrupt_handler (int /* signal_number */)
1574 {
1575   // I'm probably forgetting why it's bad to call the message_mgr
1576   // from within the WindowSystem object.  We'll find out why
1577   // eventually, I'm sure.  20:56 04-May-94 DJB 
1578
1579   Wait_Cursor bob;
1580
1581   if (!(window_system().videoShell()->silent)) {
1582       message_mgr().quit_dialog (
1583           (char*)UAS_String(CATGETS(Set_Messages, 6, "Quit Dtinfo?")));
1584   }
1585   else {
1586       exit(1);
1587   }
1588
1589 #if defined(SVR4) || defined(hpux) || defined(_IBMR2)
1590   signal (SIGINT, interrupt_handler);
1591 #endif
1592 }