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