1 /*
2 **
3 ** main.c
4 **
5 ** Copyright (C) 1995, 1996, 1997 Johannes Plass
6 ** Copyright (C) 2004 Jose E. Marchesi
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 3 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with GNU gv; see the file COPYING.  If not, write to
20 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA 02111-1307, USA.
22 **
23 ** Author:   Johannes Plass (plass@thep.physik.uni-mainz.de)
24 **           Department of Physics
25 **           Johannes Gutenberg-University
26 **           Mainz, Germany
27 **
28 **           Jose E. Marchesi (jemarch@gnu.org)
29 **           GNU Project
30 **
31 */
32 #include "ac_config.h"
33 
34 #define _GV_MAIN_C_
35 
36 /*
37 #define MESSAGES
38 */
39 #include "message.h"
40 
41 #include "config.h"
42 
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include <math.h>
47 #include <getopt.h>
48 
49 #include <inttypes.h>
50 
51 #include "paths.h"
52 #include INC_X11(Intrinsic.h)
53 #include INC_X11(cursorfont.h)
54 #include INC_X11(StringDefs.h)
55 #include INC_X11(Shell.h)
56 #include INC_X11(Xatom.h)
57 #include INC_XAW(Cardinals.h)
58 #include INC_XAW(SimpleMenu.h)
59 #include INC_XAW(SmeBSB.h)
60 #include INC_XAW(SmeLine.h)
61 #include INC_XAW(Label.h)
62 #include INC_XAW(Scrollbar.h)
63 #include INC_XAW(XawInit.h)
64 #include INC_XMU(Editres.h)
65 #ifdef HAVE_LIBXINERAMA
66    #include INC_EXT(Xinerama.h)
67 #endif
68 #include "Aaa.h"
69 #include "Button.h"
70 #include "Clip.h"
71 #include "FileSel.h"
72 #include "Frame.h"
73 #include "Ghostview.h"
74 #include "MButton.h"
75 #include "Vlist.h"
76 
77 #include <string.h>
78 #include <sys/stat.h>
79 #include <unistd.h>
80 
81 #include "types.h"
82 #include "actions.h"
83 #include "callbacks.h"
84 #include "confirm.h"
85 #include "dialog.h"
86 #include "error.h"
87 #include "file.h"
88 #include "gv_message.h"
89 #include "note.h"
90 #include "info.h"
91 #include "magmenu.h"
92 #include "main_resources.h"
93 #include "main_globals.h"
94 #include "media.h"
95 #include "misc.h"
96 #include "miscmenu.h"
97 #include "options.h"
98 #include "options_gs.h"
99 #include "options_gv.h"
100 #include "options_setup.h"
101 #include "popup.h"
102 #include "process.h"
103 #include "ps.h"
104 #include "resource.h"
105 #include "doc_misc.h"
106 #include "version.h"
107 #include "scale.h"
108 
109 #if defined(USE_SIGNAL_HANDLER) && (XtSpecificationRelease < 6)
110 #   undef USE_SIGNAL_HANDLER
111 #endif
112 #ifdef USE_SIGNAL_HANDLER
113 #   include "gv_signal.h"
114 #endif /* USE_SIGNAL_HANDLER */
115 
116 #define BITSOF(name) name ## _bits
117 #define WIDTHOF(name) name ## _width
118 #define HEIGHTOF(name) name ## _height
119 #define BITMAP_ARGS(name)\
120            (const char*)BITSOF(name), WIDTHOF(name), HEIGHTOF(name)
121 
122 #include FALLBACK_ICON_PIXMAP
123 #include FALLBACK_SELECTED_BITMAP
124 #include FALLBACK_DOCUMENT_BITMAP
125 #include FALLBACK_MARK_ODD_BITMAP
126 #include FALLBACK_MARK_EVEN_BITMAP
127 #include FALLBACK_MARK_CURRENT_BITMAP
128 #include FALLBACK_MARK_UNMARK_BITMAP
129 #include FALLBACK_MARK_EMPTY_BITMAP
130 
131 
132 /*********************************************************
133    GNU command line options
134 **********************************************************/
135 
136 enum
137   {
138     CENTER_ARG,
139     NOCENTER_ARG,
140     SCALE_ARG,
141     MAGSTEP_ARG,
142     SCALEBASE_ARG,
143     RESIZE_ARG,
144     NORESIZE_ARG,
145     SWAP_ARG,
146     NOSWAP_ARG,
147     DSC_ARG,
148     NODSC_ARG,
149     EOF_ARG,
150     NOEOF_ARG,
151     WATCH_ARG,
152     NOWATCH_ARG,
153     AD_ARG,
154     STYLE_ARG,
155     ARGUMENTS_ARG,
156     ANTIALIAS_ARG,
157     NOANTIALIAS_ARG,
158     SAFER_ARG,
159     NOSAFER_ARG,
160     SAFEDIR_ARG,
161     NOSAFEDIR_ARG,
162     PIXMAP_ARG,
163     NOPIXMAP_ARG,
164     COLOR_ARG,
165     GRAYSCALE_ARG,
166     HELP_ARG,
167     QUIET_ARG,
168     INFOSILENT_ARG,
169     INFOERRORS_ARG,
170     INFOALL_ARG,
171     DEBUG_ARG,
172     FULLSCREEN_ARG,
173     PRESENTATION_ARG,
174     MONOCHROME_ARG,
175     NOQUIET_ARG,
176     MEDIA_ARG,
177     ORIENTATION_ARG,
178     PAGE_ARG,
179     PASSWORD_ARG,
180     SPARTAN_ARG,
181     WIDGETLESS_ARG,
182     USAGE_ARG,
183     VERSION_ARG
184   };
185 
186 static struct option const GNU_longOptions[] =
187   {
188     {"grayscale", no_argument, NULL, GRAYSCALE_ARG},
189     {"center", no_argument, NULL, CENTER_ARG},
190     {"nocenter", no_argument, NULL, NOCENTER_ARG},
191     {"scale", required_argument, NULL, SCALE_ARG},
192     {"magstep", required_argument, NULL, MAGSTEP_ARG},
193     {"scalebase", required_argument, NULL, SCALEBASE_ARG},
194     {"resize", no_argument, NULL, RESIZE_ARG},
195     {"noresize", no_argument, NULL, NORESIZE_ARG},
196     {"swap", no_argument, NULL, SWAP_ARG},
197     {"noswap", no_argument, NULL, NOSWAP_ARG},
198     {"dsc", no_argument, NULL, DSC_ARG},
199     {"nodsc", no_argument, NULL, NODSC_ARG},
200     {"eof", no_argument, NULL, EOF_ARG},
201     {"noeof", no_argument, NULL, NOEOF_ARG},
202     {"watch", no_argument, NULL, WATCH_ARG},
203     {"nowatch", no_argument, NULL, NOWATCH_ARG},
204     {"ad", required_argument, NULL, AD_ARG},
205     {"style", required_argument, NULL, STYLE_ARG},
206     {"arguments", required_argument, NULL, ARGUMENTS_ARG},
207     {"antialias", no_argument, NULL, ANTIALIAS_ARG},
208     {"noantialias", no_argument, NULL, NOANTIALIAS_ARG},
209     {"safer", no_argument, NULL, SAFER_ARG},
210     {"nosafer", no_argument, NULL, NOSAFER_ARG},
211     {"safedir", no_argument, NULL, SAFEDIR_ARG},
212     {"nosafedir", no_argument, NULL, NOSAFEDIR_ARG},
213     {"pixmap", no_argument, NULL, PIXMAP_ARG},
214     {"nopixmap", no_argument, NULL, NOPIXMAP_ARG},
215     {"color", no_argument, NULL, COLOR_ARG},
216     {"help", no_argument, NULL, HELP_ARG},
217     {"quiet", no_argument, NULL, QUIET_ARG},
218     {"infoSilent", no_argument, NULL, INFOSILENT_ARG},
219     {"infoErrors", no_argument, NULL, INFOERRORS_ARG},
220     {"infoAll", no_argument, NULL, INFOALL_ARG},
221     {"debug", no_argument, NULL, DEBUG_ARG},
222     {"fullscreen", no_argument, NULL, FULLSCREEN_ARG},
223     {"presentation", no_argument, NULL, PRESENTATION_ARG},
224     {"monochrome", no_argument, NULL, MONOCHROME_ARG},
225     {"noquiet", no_argument, NULL, NOQUIET_ARG},
226     {"media", required_argument, NULL, MEDIA_ARG},
227     {"orientation", required_argument, NULL, ORIENTATION_ARG},
228     {"page", required_argument, NULL, PAGE_ARG},
229     {"password", required_argument, NULL, PASSWORD_ARG},
230     {"usage", no_argument, NULL, USAGE_ARG},
231     {"spartan", no_argument, NULL, SPARTAN_ARG},
232     {"widgetless", no_argument, NULL, WIDGETLESS_ARG},
233     {"version", no_argument, NULL, VERSION_ARG},
234     {NULL, 0, NULL, 0}
235   };
236 
237 typedef struct menu_entry {
238   Widget		*widgetP;
239   String		name;
240   XtCallbackProc	callback;
241   XtPointer		client_data;
242 } MenuEntry;
243 
244 static XtActionsRec actions[] = {
245  { "GV_Antialias"	, action_antialias		},
246  { "GV_CheckFile"	, action_checkFile		},
247  { "GV_ConfigureNotify"	, action_shellConfigureNotify	},
248  { "GV_DeleteWindow"	, action_deleteWindow		},
249  { "GV_DismissPopup"	, action_dismissPopup		},
250  { "GV_EraseLocator"	, action_eraseLocator		},
251  { "GV_HandleDSC"	, action_handleDSC		},
252  { "GV_MagMenu"         , magmenu_a_magMenu           	},
253  { "GV_MenuPopdown"     , action_menuPopdown           	},
254  { "GV_MiscMenu"        , miscmenu_a_miscMenu          	},
255  { "GV_MovePage"	, action_movePage		},
256  { "GV_Open"		, action_open			},
257  { "GV_OtherPage"	, action_otherPage		},
258  { "GV_Page"		, action_page			},
259  { "GV_Panner"		, action_panner			},
260  { "GV_Print"		, action_print			},
261  { "GV_PrintPos"	, action_print_pos		},
262  { "GV_Quit"		, action_quit			},
263  { "GV_Reopen"		, action_reopen			},
264  { "GV_SavePos"		, action_savepos		},
265  { "GV_Presentation"	, action_presentation		},
266  { "GV_Resizing"	, action_autoResize		},
267  { "GV_Save"		, action_save			},
268  { "GV_SetScale"	, action_setScale		},
269  { "GV_SetOrientation"	, action_setOrientation		},
270  { "GV_SetPageMark"	, action_setPageMark		},
271  { "GV_SetPageMedia"	, action_setPagemedia		},
272  { "GV_Toc"		, action_toc			},
273  { "GV_TogDialPrefBut"	, action_preferDialogPopupButton },
274  { "GV_TogConfPrefBut"	, action_preferConfirmPopupButton },
275  { "GV_WatchFile"	, action_watchFile },
276 };
277 
278 /*--------------------------------------------------------------
279    dummyCvtStringToPixmap
280    Dummy String to Pixmap converter. Used to suppress warnings
281    about missing String to Pixmap converter.
282    Background: on Motif displays 'xrdb -q' shows resource
283    entries "*topShadowPixmap: unspecified_pixmap" and
284    "*bottomShadowPixmap: unspecified_pixmap". Since the ThreeD
285    widget of Xaw3d also uses these resources without
286    installing a converter we get tons of warnings. ###jp###
287 --------------------------------------------------------------*/
288 
289 static Boolean
dummyCvtStringToPixmap(Display * dpy _GL_UNUSED,XrmValue * args _GL_UNUSED,Cardinal * num_args _GL_UNUSED,XrmValue * fromVal _GL_UNUSED,XrmValue * toVal _GL_UNUSED,XtPointer * converter_data _GL_UNUSED)290 dummyCvtStringToPixmap(Display *dpy _GL_UNUSED, XrmValue *args _GL_UNUSED, Cardinal *num_args _GL_UNUSED, XrmValue *fromVal _GL_UNUSED, XrmValue *toVal _GL_UNUSED, XtPointer *converter_data _GL_UNUSED)
291 {
292    BEGINMESSAGE(dummyCvtStringToPixmap)
293 #  ifdef MESSAGES
294    {
295       char *name = (char*) fromVal->addr;
296       INFSMESSAGE(will not convert,name)
297    }
298 #  endif
299    ENDMESSAGE(dummyCvtStringToPixmap)
300    return(False);
301 }
302 
303 /*### Procedure and Macro Declarations ###########################################*/
304 
305 static void  main_createMenu(MenuEntry*,Widget*,Cardinal*);
306 void main_setGhostscriptResources(XrmDatabase);
307 void main_setInternResource(XrmDatabase,String*,char*);
308 void main_setResolutions(int);
309 void main_createScaleMenu(void);
310 
311 #ifdef max
312 #   undef max
313 #endif
314 #define max(a,b) ((a)>(b)?(a):(b))
315 #ifdef min
316 #   undef min
317 #endif
318 #define min(a,b) ((a)<(b)?(a):(b))
319 
320 /*#################################################################################
321    Main
322 #################################################################################*/
323 
main(int argc,char * argv[])324 int main(int argc, char *argv[])
325 {
326   MAINBEGINMESSAGE(main)
327   gv_safe_gs_workdir = GV_LIBDIR "/safe-gs-workdir";
328   gv_safe_gs_tempdir = 0;
329 
330   {
331     Arg          args[20];
332     Cardinal     n;
333     int          number;
334     Widget       cont_child[50];
335     Cardinal     cont_child_num=0;
336     Dimension    maximum_width,maximum_height;
337     unsigned int gwidth=0,gheight=0;
338     int          dim_forced;
339     int          c;
340 
341 /*###  initializing global variables ####################################*/
342 
343     INFMESSAGE(initializing global variables)
344     gv_bin = argv[0];
345     gv_scroll_mode = SCROLL_MODE_NONE;
346     gv_class = GV_CLASS;
347     gv_pending_page_request=NO_CURRENT_PAGE;
348     gv_gs_arguments  = NULL;
349     gv_psfile        = NULL;
350     gv_filename      = NULL;
351     gv_filename_unc  = NULL;
352     gv_filename_dsc  = NULL;
353     gv_filename_old  = NULL;
354     gv_filename_raw  = NULL;
355     toc_text         = NULL;
356     infopopup        = NULL;
357     confirmpopup     = NULL;
358     dialogpopup      = NULL;
359     notepopup        = NULL;
360     versionpopup     = NULL;
361     FileSel_popup    = NULL;
362     pagemediaEntry   = NULL;
363     gv_print_kills_file = 0;
364     gv_infoSkipErrors = 0;
365 
366     antialias_p = 0;
367     noantialias_p = 0;
368     safer_p = 0;
369     nosafer_p = 0;
370     safedir_p = 0;
371     nosafedir_p = 0;
372     pixmap_p = 0;
373     nopixmap_p = 0;
374     color_p = 0;
375     grayscale_p = 0;
376     quiet_p = 0;
377     infoverbose_p = -1;
378     monochrome_p = 0;
379     noquiet_p = 0;
380     media_p = 0;
381     orientation_p = 0;
382     page_p = 0;
383     spartan_p = 0;
384     widgetless_p = 0;
385     center_p = 0;
386     nocenter_p = 0;
387     scale_p = 0;
388     magstep_p = 0;
389     scalebase_p = 0;
390     resize_p = 0;
391     noresize_p = 0;
392     swap_p = 0;
393     noswap_p = 0;
394     dsc_p = 0;
395     nodsc_p = 0;
396     eof_p = 0;
397     noeof_p = 0;
398     watch_p = 0;
399     nowatch_p = 0;
400     ad_p = 0;
401     style_p = 0;
402     arguments_p = 0;
403     fullscreen_p = 0;
404     ascale_p = 1.0;
405 
406 
407     /*###  initializing toolkit and the application context ########*/
408 
409     /*
410       Make sure that LC_NUMERIC is POSIX.
411       LC_NUMERIC must not use locales like de_DE.UTF-8 or de_DE@euro where
412       the decimal separator is ',' or gv will fail with the
413       message "**** Unable to open the initial device, quitting."
414     */
415 
416     if (getenv("LC_ALL")) {
417 	    char *locale;
418 	    locale = getenv("LC_ALL");
419             gnu_gv_unsetenv("LC_ALL");
420 	    gnu_gv_setenv("LC_CTYPE", locale, 1);
421 	    gnu_gv_setenv("LC_NUMERIC", locale, 1);
422 	    gnu_gv_setenv("LC_TIME", locale, 1);
423 	    gnu_gv_setenv("LC_COLLATE", locale, 1);
424 	    gnu_gv_setenv("LC_MONETARY", locale, 1);
425 	    gnu_gv_setenv("LC_MESSAGES", locale, 1);
426 	    gnu_gv_setenv("LC_PAPER", locale, 1);
427 	    gnu_gv_setenv("LC_NAME", locale, 1);
428 	    gnu_gv_setenv("LC_ADDRESS", locale, 1);
429 	    gnu_gv_setenv("LC_TELEPHONE", locale, 1);
430 	    gnu_gv_setenv("LC_MEASUREMENT", locale, 1);
431 	    gnu_gv_setenv("LC_IDENTIFICATION", locale, 1);
432     }
433     gnu_gv_setenv("LC_NUMERIC", "POSIX", 1);
434     XtSetLanguageProc(NULL, NULL, NULL);
435 
436     INFMESSAGE(initializing toolkit and the application context)
437     XtToolkitInitialize();
438     app_con = XtCreateApplicationContext();
439     XtAppAddActions(app_con, actions, XtNumber(actions));
440 
441 /*### opening display #######################################################*/
442 
443    INFMESSAGE(opening display)
444    {
445      /*
446        The following doesn't work for XFILESEARCHPATH since stupid
447        XtResolvePathname, when passed a NULL path, checks XFILESEARCHPATH
448        only on the first call. (jp)
449      */
450      const char *xufsp="XUSERFILESEARCHPATH";
451      char *xuf;
452      xuf = getenv(xufsp); if (xuf) xuf = XtNewString(xuf);
453      gnu_gv_setenv(xufsp,"___",1);
454      gv_display = XtOpenDisplay(app_con,NULL,NULL,gv_class,NULL,0,&argc,argv);
455 
456      if (xuf) { gnu_gv_setenv(xufsp,xuf,1); XtFree(xuf); } else gnu_gv_unsetenv(xufsp);
457      if (gv_display)
458         XtGetApplicationNameAndClass(gv_display,&gv_name,&gv_class);
459      SMESSAGE(gv_name) SMESSAGE(gv_class)
460    }
461 
462    /*### Manage GNU command line arguments ########################*/
463    while ((c = getopt_long_only (argc, argv, "vhu", GNU_longOptions, NULL))
464 	  != -1)
465      {
466 
467        switch (c)
468 	 {
469 	 case CENTER_ARG:
470 	   center_p = 1;
471 	   break;
472 	 case NOCENTER_ARG:
473 	   nocenter_p = 1;
474 	   break;
475 	 case SCALE_ARG:
476 	   if (strstr(optarg, "."))
477 	   {
478 	      scale_p = 1;
479 	      scale_value = "-1002";
480 	      sscanf(optarg, "%f", &ascale_p);
481 	   }
482 	   else
483 	   {
484 	      scale_p = 1;
485 	      scale_value = optarg;
486 	   }
487 	   break;
488 	 case MAGSTEP_ARG:
489 	   magstep_p = 1;
490 	   magstep_value = optarg;
491 	   break;
492 	 case SCALEBASE_ARG:
493 	   scalebase_p = 1;
494 	   scalebase_value = optarg;
495 	   break;
496 	 case RESIZE_ARG:
497 	   resize_p = 1;
498 	   break;
499 	 case NORESIZE_ARG:
500 	   noresize_p = 1;
501 	   break;
502 	 case FULLSCREEN_ARG:
503 	   fullscreen_p = 1;
504 	   break;
505 	 case PRESENTATION_ARG:
506 	   fullscreen_p = 1;
507 	   noresize_p = 1;
508 	   widgetless_p = 1;
509 	   scale_p = 1;
510 	   scale_value = "-1000";
511 	   break;
512 	 case SWAP_ARG:
513 	   swap_p = 1;
514 	   break;
515 	 case NOSWAP_ARG:
516 	   noswap_p = 1;
517 	   break;
518 	 case DSC_ARG:
519 	   dsc_p = 1;
520 	   break;
521 	 case NODSC_ARG:
522 	   nodsc_p = 1;
523 	   break;
524 	 case EOF_ARG:
525 	   eof_p = 1;
526 	   break;
527 	 case NOEOF_ARG:
528 	   noeof_p = 1;
529 	   break;
530 	 case WATCH_ARG:
531 	   watch_p = 1;
532 	   break;
533 	 case NOWATCH_ARG:
534 	   nowatch_p = 1;
535 	   break;
536 	 case AD_ARG:
537 	   ad_p = 1;
538 	   ad_value = optarg;
539 	   break;
540 	 case STYLE_ARG:
541 	   style_p = 1;
542 	   style_value = optarg;
543 	   break;
544 	 case ARGUMENTS_ARG:
545 	   arguments_p = 1;
546 	   arguments_value = optarg;
547 	   break;
548 	 case PIXMAP_ARG:
549 	   pixmap_p = 1;
550 	   break;
551 	 case NOPIXMAP_ARG:
552 	   nopixmap_p = 1;
553 	   break;
554 	 case SAFER_ARG:
555 	   safer_p = 1;
556 	   break;
557 	 case NOSAFER_ARG:
558 	   nosafer_p = 1;
559 	   break;
560 	 case SAFEDIR_ARG:
561 	   safedir_p = 1;
562 	   break;
563 	 case NOSAFEDIR_ARG:
564 	   nosafedir_p = 1;
565 	   break;
566 	 case ANTIALIAS_ARG:
567 	   antialias_p = 1;
568 	   break;
569 	 case NOANTIALIAS_ARG:
570 	   noantialias_p = 1;
571 	   break;
572 	 case COLOR_ARG:
573 	   color_p = 1;
574 	   break;
575 	 case GRAYSCALE_ARG:
576 	   grayscale_p = 1;
577 	   break;
578 	 case HELP_ARG:
579 	   /* Show some help and return */
580 	   fprintf(stdout,"%s\n", message_usage);
581 	   exit(0);
582 	 case QUIET_ARG:
583 	   quiet_p = 1;
584 	   break;
585 	 case INFOSILENT_ARG:
586 	   infoverbose_p = 0;
587 	   break;
588 	 case INFOERRORS_ARG:
589 	   infoverbose_p = 1;
590 	   break;
591 	 case INFOALL_ARG:
592 	   infoverbose_p = 2;
593 	   break;
594 	 case DEBUG_ARG:
595 	   debug_p = 1;
596 	   break;
597 	 case MONOCHROME_ARG:
598 	   monochrome_p = 1;
599 	   break;
600 	 case NOQUIET_ARG:
601 	   noquiet_p = 1;
602 	   break;
603 	 case MEDIA_ARG:
604 	   {
605 	     media_p = 1;
606 	     media_value = optarg;
607 	     break;
608 	   }
609 
610 	 case ORIENTATION_ARG:
611 	   {
612 	     orientation_p = 1;
613 	     orientation_value = optarg;
614 	     break;
615 	   }
616 
617 	 case PAGE_ARG:
618 	   {
619 	     page_p = 1;
620 	     page_value = optarg;
621 	     break;
622 	   }
623 
624 	 case USAGE_ARG:
625 	   /* Show usage */
626 	   fprintf(stdout,"%s\n", message_usage);
627 	   exit(0);
628 
629 	 case PASSWORD_ARG:
630 	   gv_pdf_password = XtNewString(optarg);
631 	   break;
632 
633 	 case SPARTAN_ARG:
634 	   spartan_p = 1;
635 	   break;
636 
637 	 case WIDGETLESS_ARG:
638 	   widgetless_p = 1;
639 	   break;
640 
641 	 case VERSION_ARG:
642 	   /* Show the program version */
643 	   fprintf(stdout,"%s\n", versionIdentification[0]);
644 	   exit(0);
645 
646 
647 	 default:
648 	   /* Error, usage and exit */
649 	   fprintf(stdout, "%s\n", message_usage);
650 	   exit(1);
651 	   break;
652 	 }
653      }
654 
655      if (!gv_display) {
656        fprintf(stderr, "%s: Unable to open the display.\n", GV_APPLICATION_NAME);
657        exit(EXIT_STATUS_ERROR);
658      }
659 
660    /*### getting resources ############################################*/
661    gv_database = resource_buildDatabase (gv_display,
662                                          gv_class,
663                                          gv_name,
664                                          &argc,argv);
665 
666 /*### initializing widget set and creating application shell #########################*/
667 
668     INFMESSAGE(initializing widget set)
669     XawInitializeWidgetSet();
670     XtAppSetTypeConverter(app_con,XtRString,XtRPixmap,dummyCvtStringToPixmap,NULL,0,XtCacheNone,NULL);
671     old_Xerror = XSetErrorHandler(catch_Xerror);
672     wm_delete_window = XInternAtom(gv_display, "WM_DELETE_WINDOW", False);
673     dim_forced=resource_checkGeometryResource(&gv_database,gv_class,gv_name);
674 
675     INFMESSAGE(creating the application shell)
676 							     n=0;
677       XtSetArg(args[n], XtNallowShellResize, (dim_forced?False:True));n++;
678       XtSetArg(args[n], XtNtitle,versionIdentification[0]);  n++;
679     toplevel = XtAppCreateShell(NULL,gv_class,applicationShellWidgetClass,gv_display,args,n);
680 
681     /* support for Editres ###jp### 06/18/95 */
682     XtAddEventHandler(toplevel, (EventMask) 0, TRUE,_XEditResCheckMessages, (XtPointer)NULL);
683 
684 /*### getting application resources ####################################*/
685 
686     INFMESSAGE(retrieving and analyzing application resources)
687     XtGetApplicationResources(toplevel,(XtPointer) &app_res,resources,XtNumber(resources),NULL,ZERO);
688     if (!resource_checkResources(gv_name,app_res.version,versionCompatibility)) {
689       XtDestroyApplicationContext(app_con);
690       exit(EXIT_STATUS_ERROR);
691     }
692 
693 /*### initialization of global variables based on resource ##################*/
694      if (access(gv_safe_gs_workdir, R_OK | X_OK))
695      {
696         char buffer[512];
697 	strcpy(buffer, app_res.scratch_dir);
698 	strcat(buffer,"gv-safe-workdir-XXXXXX");
699 	file_translateTildeInPath(buffer, sizeof(buffer));
700         gv_safe_gs_workdir = strdup(mkdtemp(buffer));
701 	gv_safe_gs_tempdir = 1;
702 
703 	if (!gv_safe_gs_workdir)
704 	{
705 	   perror("Cannot create safe workdir");
706 	   exit(1);
707 	}
708      }
709 
710 
711     main_setGhostscriptResources(gv_database);
712     main_setInternResource(gv_database,&gv_print_command,"printCommand");
713 
714     {
715        char* tmp_savepos_filename;
716        main_setInternResource(gv_database,&tmp_savepos_filename,"saveposFilename");
717        strcpy(gv_savepos_filename, tmp_savepos_filename);
718        file_translateTildeInPath(gv_savepos_filename, sizeof(gv_savepos_filename));
719     }
720 
721     main_setInternResource(gv_database,&gv_uncompress_command,"uncompressCommand");
722 
723     gv_user_defaults_file = resource_userDefaultsFile();
724     gv_screen = XtScreen(toplevel);
725     gv_scanstyle = 0;
726     gv_scanstyle |= (app_res.ignore_eof ? SCANSTYLE_IGNORE_EOF : 0);
727     gv_scanstyle |= (app_res.respect_dsc ? 0 : SCANSTYLE_IGNORE_DSC);
728 
729     if (dim_forced) app_res.auto_resize=False;
730 
731     app_res.minimum_width  = app_res.minimum_width  < 300 ? 300 : app_res.minimum_width;
732     app_res.minimum_height = app_res.minimum_height < 300 ? 300 : app_res.minimum_height;
733 
734     gv_medias_res = resource_getResource(gv_database,gv_class,gv_name,"medias","Medias");
735     gv_medias_res = XtNewString(gv_medias_res);
736     gv_medias = media_parseMedias(gv_medias_res);
737     gv_num_std_pagemedia = media_numMedias(gv_medias);
738 
739     gv_magmenu_entries_res = resource_getResource(gv_database,gv_class,gv_name,"magMenu","MagMenu");
740     gv_magmenu_entries_res = XtNewString(gv_magmenu_entries_res);
741     gv_magmenu_entries = magmenu_parseMagMenuEntries(gv_magmenu_entries_res);
742 
743     gv_miscmenu_entries_res = resource_getResource(gv_database,gv_class,gv_name,"miscMenuEntries","MiscMenuEntries");
744     gv_miscmenu_entries_res = XtNewString(gv_miscmenu_entries_res);
745     gv_miscmenu_entries = miscmenu_parseMiscMenuEntries(gv_miscmenu_entries_res);
746 
747     gv_scales_res = resource_getResource(gv_database,gv_class,gv_name,"scales","Scales");
748     gv_scales_res = XtNewString(gv_scales_res);
749     gv_scales = scale_parseScales(gv_scales_res);
750     gv_scale_current = gv_scale_base_current = -1;
751 
752     gv_ascale = 1.0;
753 
754     if (app_res.scale == -1000)
755     {
756        int j;
757        gv_scale = scale_checkScaleNum(gv_scales,0|SCALE_REL) & SCALE_VAL;
758        for (j=0; gv_scales[j]; j++)
759           if (!gv_scales[j]->scale)
760 	  {
761 	     gv_scale = j;
762 	     break;
763           }
764     }
765     else if (app_res.scale == -1001)
766     {
767        int j;
768 
769        gv_scale = scale_checkScaleNum(gv_scales,0|SCALE_REL) & SCALE_VAL;
770 
771        for (j=0; gv_scales[j]; j++)
772           if (fabs(gv_scales[j]->scale+1) <= 0.001)
773 	  {
774 	     gv_scale = j;
775 	     break;
776           }
777        gv_ascale = sqrt(ascale_p);
778     }
779     else if (app_res.scale == -1002)
780     {
781        int j;
782 
783        gv_scale = scale_checkScaleNum(gv_scales,0|SCALE_REL) & SCALE_VAL;
784 
785        for (j=0; gv_scales[j]; j++)
786           if (fabs(gv_scales[j]->scale+2) <= 0.001)
787 	  {
788 	     gv_scale = j;
789 	     break;
790           }
791        gv_ascale = sqrt(ascale_p);
792     }
793     else if (app_res.scale == -1003)
794     {
795        int j;
796 
797        gv_scale = scale_checkScaleNum(gv_scales,0|SCALE_REL) & SCALE_VAL;
798 
799        for (j=0; gv_scales[j]; j++)
800           if (fabs(gv_scales[j]->scale+3) <= 0.001)
801 	  {
802 	     gv_scale = j;
803 	     break;
804           }
805        gv_ascale = sqrt(ascale_p);
806     }
807     else
808     {
809        if (app_res.scale < 0) app_res.scale = (-app_res.scale)|SCALE_MIN;
810        app_res.scale &= (SCALE_VAL|SCALE_MIN);
811        gv_scale = scale_checkScaleNum(gv_scales,app_res.scale|SCALE_REL);
812        if (gv_scale < 0) gv_scale = scale_checkScaleNum(gv_scales,0|SCALE_REL);
813        gv_scale &= SCALE_VAL;
814     }
815     if (app_res.scale_base<1) app_res.scale_base = 1;
816     app_res.scale_base &= SCALE_VAL;
817     gv_scale_base = scale_checkScaleNum(gv_scales,(app_res.scale_base-1)|SCALE_BAS);
818     if (gv_scale_base < 0) gv_scale_base = 0;
819     gv_scale_base &= SCALE_VAL;
820 
821     if      (app_res.confirm_quit < 0) app_res.confirm_quit = 0;
822     else if (app_res.confirm_quit > 2) app_res.confirm_quit = 2;
823 
824     if (app_res.watch_file_frequency < 500) app_res.watch_file_frequency = 500;
825 
826     main_setResolutions(1);
827     default_xdpi = gv_real_xdpi;
828     default_ydpi = gv_real_ydpi;
829 
830 /*### creating bitmaps #####################################################*/
831 
832     INFMESSAGE(setting the icon)
833     {
834        Pixmap icon_pixmap;
835        XtSetArg(args[0], XtNiconPixmap, &icon_pixmap);
836        XtGetValues(toplevel, args, 1);
837        if (icon_pixmap == None) {
838           icon_pixmap =
839           XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
840                                 BITMAP_ARGS(FALLBACK_ICON_NAME));
841           XtSetArg(args[0], XtNiconPixmap, icon_pixmap);
842           XtSetValues(toplevel, args, 1);
843        }
844     }
845        if (app_res.mark_odd_bitmap == None)
846            app_res.mark_odd_bitmap =
847               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
848                                   BITMAP_ARGS(FALLBACK_MARK_ODD_NAME));
849        if (app_res.mark_even_bitmap == None)
850            app_res.mark_even_bitmap =
851               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
852                                   BITMAP_ARGS(FALLBACK_MARK_EVEN_NAME));
853        if (app_res.mark_current_bitmap == None)
854            app_res.mark_current_bitmap =
855               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
856                                   BITMAP_ARGS(FALLBACK_MARK_CURRENT_NAME));
857        if (app_res.mark_unmark_bitmap == None)
858            app_res.mark_unmark_bitmap =
859               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
860                                   BITMAP_ARGS(FALLBACK_MARK_UNMARK_NAME));
861        if (app_res.mark_empty_bitmap == None)
862            app_res.mark_empty_bitmap =
863               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
864                                   BITMAP_ARGS(FALLBACK_MARK_EMPTY_NAME));
865        if (app_res.selected_bitmap == None)
866            app_res.selected_bitmap =
867               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
868                                   BITMAP_ARGS(FALLBACK_SELECTED_NAME));
869        if (app_res.document_bitmap == None)
870            app_res.document_bitmap =
871               XCreateBitmapFromData(gv_display, RootWindowOfScreen(gv_screen),
872                                   BITMAP_ARGS(FALLBACK_DOCUMENT_NAME));
873 
874 /*### Parsing maximum width, maximum height resources, creating control ####################*/
875 
876     {
877        char *pos;
878        int width,height;
879        char* max_size_screen = "screen";
880 
881        INFMESSAGE(parsing maximum size resources)
882 
883        pos= strstr(app_res.maximum_width,max_size_screen);
884        if (pos) { width=WidthOfScreen(gv_screen)+atoi(pos+strlen(max_size_screen)); }
885        else     { width=atoi(app_res.maximum_width); }
886        maximum_width = (width > 0 ? (Dimension) width : 0);
887        maximum_width = max(maximum_width,(Dimension)app_res.minimum_width);
888        if (maximum_width<(Dimension)gwidth) maximum_width=(Dimension)gwidth;
889        pos= strstr(app_res.maximum_height,max_size_screen);
890        if (pos) { height=HeightOfScreen(gv_screen)+atoi(pos+strlen(max_size_screen)); }
891        else     { height=atoi(app_res.maximum_height); }
892        maximum_height = (height > 0 ? (Dimension) height : 0);
893        maximum_height = max(maximum_height,(Dimension)app_res.minimum_height);
894        if (maximum_height<(Dimension)gheight) maximum_height=(Dimension)gheight;
895        IIMESSAGE(maximum_width,maximum_height)
896 
897        INFMESSAGE(creating control)
898                                				n=0;
899        if (gwidth) {
900           app_res.auto_resize=False;
901           XtSetArg(args[n], XtNresizeWidth, False);	n++;
902           XtSetArg(args[n], XtNwidth, (Dimension)gwidth);n++;
903           INFIMESSAGE(forcing width for control:,gwidth)
904        } else {
905           XtSetArg(args[n], XtNresizeWidth, True);	n++;
906        }
907        if (gheight) {
908           app_res.auto_resize=False;
909           XtSetArg(args[n], XtNresizeHeight, False);	n++;
910           XtSetArg(args[n], XtNheight, (Dimension)gheight);n++;
911           INFIMESSAGE(forcing height for control:,gheight)
912        } else {
913           XtSetArg(args[n], XtNresizeHeight, True);	n++;
914        }
915        XtSetArg(args[n], XtNmaximumWidth, maximum_width); n++;
916        XtSetArg(args[n], XtNmaximumHeight,maximum_height);n++;
917        XtSetArg(args[n], XtNminimumWidth, (Dimension)app_res.minimum_width); n++;
918        XtSetArg(args[n], XtNminimumHeight,(Dimension)app_res.minimum_height);n++;
919        main_control = XtCreateWidget("control",aaaWidgetClass,toplevel,args,n);
920     }
921 
922 /*### Creating the Menus ###############################################################*/
923 
924     INFMESSAGE(menus)
925 
926    {
927      MenuEntry m[] = {
928        { &fileButton,       "fileButton", NULL , NULL},
929        { &fileMenu,         "menu", NULL ,NULL},
930        { &openEntry,        "open", cb_openFile, NULL},
931        { &reopenEntry,      "reopen", cb_reopen, NULL},
932        { &saveposEntry,     "savepos", cb_savepos, NULL},
933        { &updateEntry,      "update", cb_checkFile, (XtPointer)CHECK_FILE_VERSION },
934        { NULL,              "line", NULL, NULL },
935        { &printAllEntry,    "printAllPages", cb_print, (XtPointer)PAGE_MODE_ALL},
936        { &printMarkedEntry, "printMarkedPages",cb_print , (XtPointer)(PAGE_MODE_MARKED|PAGE_MODE_CURRENT)},
937        { &saveAllEntry,     "saveAllPages", cb_save, (XtPointer)PAGE_MODE_ALL},
938        { &saveMarkedEntry,  "saveMarkedPages",cb_save , (XtPointer)(PAGE_MODE_MARKED|PAGE_MODE_CURRENT)},
939        { NULL,              "line", NULL, NULL },
940        { &copyrightEntry,   "copyright", cb_popupVersionPopup, NULL},
941        { NULL,              "line", NULL, NULL },
942        { &quitEntry,        "quit", cb_quitGhostview, NULL},
943        { NULL, NULL, NULL, NULL },
944      };
945      main_createMenu(m,cont_child,&cont_child_num);
946    }
947 
948    {
949      MenuEntry m[] = {
950        { &stateButton,     "stateButton",NULL ,NULL},
951        { &stateMenu,       "menu", NULL, NULL},
952        { &stopEntry,       "stop", cb_stopInterpreter, NULL},
953        { &dscEntry,        "dsc", cb_handleDSC, (XtPointer)1},
954        { &eofEntry,        "eof", cb_handleEOF, (XtPointer)1},
955        { &antialiasEntry,  "antialias", cb_antialias, (XtPointer)1},
956        { &watchFileEntry,  "watchFile", cb_watchFile, (XtPointer)1},
957        { &sizeEntry,       "size", cb_autoResize, (XtPointer)1},
958        { NULL,             "line", NULL, NULL },
959        { &optiongvEntry,   "optionsgv", NULL, NULL},
960        { &optiongsEntry,   "optionsgs", NULL, NULL},
961        { &optionfsEntry,   "optionsfs", NULL, NULL},
962        { &optionsetupEntry,"optionssetup", NULL, NULL},
963        { NULL,             "line", NULL, NULL },
964        { &presentationEntry,     "presentation", cb_presentation, NULL},
965        { NULL, NULL, NULL, NULL },
966      };
967      main_createMenu(m,cont_child,&cont_child_num);
968      XtAddCallback(optionfsEntry, XtNcallback,options_cb_popup,(XtPointer)gv_options_fs);
969      XtAddCallback(optiongvEntry, XtNcallback,options_cb_popup,(XtPointer)gv_options_gv);
970      XtAddCallback(optiongsEntry, XtNcallback,options_cb_popup,(XtPointer)gv_options_gs);
971      XtAddCallback(optionsetupEntry, XtNcallback,options_cb_popup,(XtPointer)gv_options_setup);
972      cb_handleDSC(dscEntry,NULL,NULL);
973      cb_handleEOF(eofEntry,NULL,NULL);
974      cb_antialias(dscEntry,NULL,NULL);
975    }
976 
977    {
978      MenuEntry m[] = {
979        { &pageButton,     "pageButton", NULL, NULL},
980        { &pageMenu,       "menu", NULL, NULL},
981        { &nextEntry,      "next", cb_page, "+1"},
982        { &redisplayEntry, "redisplay", cb_redisplay, NULL},
983        { &prevEntry,      "prev", cb_page, "-1"},
984        { NULL,            "line", NULL, NULL },
985        { &centerEntry,    "center", cb_positionPage, (XtPointer)1},
986        { NULL,            "line", NULL, NULL },
987        { &currentEntry,   "current" , cb_setPageMark, (XtPointer)(SPM_CURRENT|SPM_TOGGLE) },
988        { &oddEntry    ,   "odd"     , cb_setPageMark, (XtPointer)(SPM_ODD|SPM_TOGGLE)     },
989        { &evenEntry   ,   "even"    , cb_setPageMark, (XtPointer)(SPM_EVEN|SPM_TOGGLE)    },
990        { &unmarkEntry ,   "unmark"  , cb_setPageMark, (XtPointer)(SPM_ALL|SPM_UNMARK)     },
991        { NULL, NULL, NULL, NULL },
992      };
993      main_createMenu(m,cont_child,&cont_child_num);
994    }
995 
996    {
997      MenuEntry m[] = {
998        { &orientationButton, "orientationButton", NULL, NULL},
999        { &orientationMenu,   "menu", NULL, NULL},
1000        { &autoOrientEntry,   "automatic", cb_setOrientation, (XtPointer)O_AUTOMATIC},
1001        { NULL,               "line", NULL, NULL },
1002        { &portraitEntry,     "portrait", cb_setOrientation, (XtPointer)O_PORTRAIT},
1003        { &landscapeEntry,    "landscape", cb_setOrientation, (XtPointer)O_LANDSCAPE},
1004        { &upsidedownEntry,   "upsidedown",cb_setOrientation , (XtPointer)O_UPSIDEDOWN},
1005        { &seascapeEntry,     "seascape", cb_setOrientation, (XtPointer)O_SEASCAPE},
1006        { NULL,               "line", NULL, NULL },
1007        { &swapEntry,         "swap", cb_setOrientation, (XtPointer)O_SWAP_LANDSCAPE},
1008        { NULL, NULL, NULL, NULL },
1009      };
1010      main_createMenu(m,cont_child,&cont_child_num);
1011    }
1012 
1013    {
1014 							n=0;
1015      XtSetArg(args[n], XtNresize, True);		n++;
1016      pagemediaButton = XtCreateWidget("pagemediaButton",mbuttonWidgetClass,main_control,args,n);
1017      cont_child[cont_child_num] = pagemediaButton; cont_child_num++;
1018    }
1019 
1020    {
1021            					n=0;
1022      XtSetArg(args[n], XtNresize, False);	n++;
1023      processButton = XtCreateWidget("processButton", mbuttonWidgetClass,main_control,args,n);
1024      cont_child[cont_child_num] = processButton; cont_child_num++;
1025      processMenu=NULL;
1026    }
1027 
1028 							n=0;
1029      scaleButton = XtCreateWidget("scaleButton",mbuttonWidgetClass,main_control,args,n);
1030      cont_child[cont_child_num] =scaleButton; cont_child_num++;
1031      main_createScaleMenu();
1032 
1033 /*### Optional Widgets ##############################################################*/
1034 
1035     {
1036        char *layout;
1037        char *widgetname;
1038 
1039        layout = resource_getResource(gv_database,gv_class,gv_name,"control.layout","Aaa.Layout");
1040 #if 0
1041        if (!layout) {
1042           fprintf(stderr,"  %s: Error, layout resource not found\n",versionIdentification[0]);
1043 	  clean_safe_tempdir();
1044           exit(EXIT_STATUS_ERROR);
1045        }
1046 #endif
1047 
1048        {
1049           int i=0;
1050           struct { Widget		*widget;
1051                    Bool 		*show;
1052                    String		name;
1053                    XtCallbackProc	callback;
1054                    XtPointer		client_data;
1055           } b[] = {
1056             { &w_nextPage          , &show_nextPage          , "nextPage"      , NULL             , (XtPointer)NULL },
1057             { &w_prevPage          , &show_prevPage          , "prevPage"      , NULL             , (XtPointer)NULL },
1058             { &w_toggleCurrentPage , &show_toggleCurrentPage , "toggleCurrent" , cb_setPageMark   , (XtPointer)(SPM_CURRENT|SPM_TOGGLE) },
1059             { &w_toggleEvenPages   , &show_toggleEvenPages   , "toggleEven"    , cb_setPageMark   , (XtPointer)(SPM_EVEN|SPM_TOGGLE)    },
1060             { &w_toggleOddPages    , &show_toggleOddPages    , "toggleOdd"     , cb_setPageMark   , (XtPointer)(SPM_ODD|SPM_TOGGLE)     },
1061             { &w_unmarkAllPages    , &show_unmarkAllPages    , "unmarkAll"     , cb_setPageMark   , (XtPointer)(SPM_ALL|SPM_UNMARK)     },
1062             { &w_printMarkedPages  , &show_printMarkedPages  , "printMarked"   , cb_print         , (XtPointer)(PAGE_MODE_MARKED|PAGE_MODE_CURRENT)},
1063             { &w_printAllPages     , &show_printAllPages     , "printAll"      , cb_print         , (XtPointer)PAGE_MODE_ALL           },
1064             { &w_saveMarkedPages   , &show_saveMarkedPages   , "saveMarked"    , cb_save          , (XtPointer)(PAGE_MODE_MARKED|PAGE_MODE_CURRENT)},
1065             { &w_saveAllPages      , &show_saveAllPages      , "saveAll"       , cb_save          , (XtPointer)PAGE_MODE_ALL            },
1066             { &w_openFile          , &show_openFile          , "openFile"      , cb_openFile      , (XtPointer)NULL },
1067             { &w_autoResize        , &show_autoResize        , "autoResize"    , cb_autoResize    , (XtPointer)1 },
1068             { &w_showThisPage      , &show_showThisPage      , "redisplay"     , cb_redisplay     , (XtPointer)NULL },
1069             { &w_updateFile        , &show_updateFile        , "updateFile"    , cb_checkFile     , (XtPointer)CHECK_FILE_VERSION },
1070             { &w_checkFile         , &show_checkFile         , "checkFile"     , cb_checkFile     , (XtPointer)CHECK_FILE_DATE },
1071             { NULL                 , NULL                    , NULL            , NULL             ,  NULL },
1072           };
1073           INFMESSAGE(optional widgets: buttons)
1074 						n=0;
1075           XtSetArg(args[n], XtNresize, True);	n++;
1076           while (b[i].widget) {
1077              INFSMESSAGE(creating widget,b[i].name)
1078              *(b[i].show) = strstr(layout,b[i].name) ? True : False;
1079              if (*(b[i].show)) {
1080                 *(b[i].widget) = XtCreateWidget(b[i].name,buttonWidgetClass,main_control,args,n);
1081                 if (b[i].callback) XtAddCallback(*(b[i].widget),XtNcallback,b[i].callback,b[i].client_data);
1082                 cont_child[cont_child_num] = *(b[i].widget); cont_child_num++;
1083              }
1084              ++i;
1085           }
1086 #define   SET_BITMAP(w,s,b)\
1087 	    if ((s) && (b)!= None) {\
1088 							n=0;\
1089               XtSetArg(args[n], XtNbitmap, (b));	n++;\
1090 	      XtSetValues((w),args,n);\
1091 	    }
1092           SET_BITMAP(w_toggleCurrentPage,show_toggleCurrentPage,app_res.mark_current_bitmap)
1093           SET_BITMAP(w_toggleEvenPages,show_toggleEvenPages,app_res.mark_even_bitmap)
1094           SET_BITMAP(w_toggleOddPages,show_toggleOddPages,app_res.mark_odd_bitmap)
1095           SET_BITMAP(w_unmarkAllPages,show_unmarkAllPages,app_res.mark_unmark_bitmap)
1096 #undef SET_BITMAP
1097           cb_autoResize(sizeEntry,NULL,NULL);
1098        }
1099 
1100 
1101        INFMESSAGE(optional widgets: informational widgets)
1102 #      define _mw_(widget,show,name)						\
1103          widgetname=name;							\
1104          show = strstr(layout,widgetname) ? True : False;			\
1105          if (show) {								\
1106             widget = XtCreateWidget(widgetname,mbuttonWidgetClass,main_control,args,n);\
1107             cont_child[cont_child_num] = widget; cont_child_num++;		\
1108          }
1109 
1110 	      						n=0;
1111 	XtSetArg(args[n], XtNresize, True);		n++;
1112        _mw_( titlebutton , show_title   , "titleButton" );
1113        _mw_( datebutton  , show_date    , "dateButton"  );
1114 
1115        widgetname="locator";
1116        show_locator = strstr(layout,widgetname) ? True : False;
1117        if (show_locator) {
1118           char buf[MAX_LOCATOR_LENGTH];
1119           sprintf(buf,app_res.locator_format,9999,9999);
1120           XtSetArg(args[n], XtNlabel,buf);		n++;
1121           locator = XtCreateWidget(widgetname,labelWidgetClass,main_control,args,n);
1122           cont_child[cont_child_num] =locator; cont_child_num++;
1123        }
1124 #      undef _mw_
1125 
1126 
1127        INFMESSAGE(panner)
1128        widgetname="pannerFrame";
1129        show_panner = strstr(layout,widgetname) ? True : False;
1130        if (show_panner) {
1131 
1132   									n=0;
1133           pannerFrame = XtCreateWidget("pannerFrame",frameWidgetClass,main_control,args,n);
1134           cont_child[cont_child_num] = pannerFrame; cont_child_num++;
1135   									n=0;
1136           panner = XtCreateManagedWidget("panner", compositeWidgetClass,pannerFrame, args, n);
1137          	      							n=0;
1138           XtSetArg(args[n], XtNresize,False);				n++;
1139           XtSetArg(args[n], XtNlabel,"");			      	n++;
1140           slider = XtCreateManagedWidget("slider", labelWidgetClass,panner, args, n);
1141        }
1142 
1143     } /* end of optional widgets */
1144 
1145 /*### Table of Contents ###########################################################*/
1146 
1147     INFMESSAGE(table of contents)
1148 
1149 
1150   									n=0;
1151           newtocFrame = XtCreateWidget("newtocFrame",frameWidgetClass,main_control,args,n);
1152           cont_child[cont_child_num] = newtocFrame; cont_child_num++;
1153   									n=0;
1154           newtocClip = XtCreateManagedWidget("newtocClip", clipWidgetClass,newtocFrame, args, n);
1155   									n=0;
1156           newtocControl = XtCreateManagedWidget("newtocControl", aaaWidgetClass,newtocClip, args, n);
1157          	      							n=0;
1158           newtoc = XtCreateManagedWidget("newtoc", vlistWidgetClass,newtocControl, args, n);
1159 	  XtAddCallback(newtoc, XtNreportCallback,cb_newtocVisibleAdjust, (XtPointer)NULL);
1160 									n=0;
1161           newtocScroll = XtCreateWidget("newtocScroll", scrollbarWidgetClass,main_control, args, n);
1162 	     XtAddCallback(newtocScroll, XtNscrollProc,cb_newtocScrollbar, (XtPointer)1);
1163              XtAddCallback(newtocScroll, XtNjumpProc,cb_newtocScrollbar, (XtPointer)2);
1164 
1165           cont_child[cont_child_num] = newtocScroll; cont_child_num++;
1166 
1167 /*### The Page View ###########################################################*/
1168 
1169    INFMESSAGE(viewport)
1170 
1171 									n=0;
1172    viewFrame = XtCreateWidget("viewFrame", frameWidgetClass,main_control,args,n);
1173    cont_child[cont_child_num] = viewFrame; cont_child_num++;
1174 
1175 									n=0;
1176    viewClip = XtCreateManagedWidget("viewClip", clipWidgetClass,viewFrame,args,n);
1177            if (show_panner) XtAddCallback(viewClip, XtNreportCallback,cb_adjustSlider,(XtPointer)NULL);
1178             XtAddCallback(viewClip, XtNreportCallback,cb_pageAdjustNotify,(XtPointer)NULL);
1179 
1180 									n=0;
1181    viewControl = XtCreateManagedWidget("viewControl", aaaWidgetClass,viewClip,args,n);
1182 
1183    {
1184       Boolean b;
1185 									n=0;
1186             XtSetArg(args[n], XtNinterpreter,gv_gs_interpreter);	n++;
1187             b = gv_gs_safeDir ? True : False;
1188             XtSetArg(args[n], XtNsafeDir,b);                            n++;
1189             b = gv_gs_safer ? True : False;
1190             XtSetArg(args[n], XtNsafer,b);                              n++;
1191             b = gv_gs_quiet ? True : False;
1192             XtSetArg(args[n], XtNquiet,b);                              n++;
1193             XtSetArg(args[n], XtNinfoVerbose,gv_infoVerbose);           n++;
1194             b = app_res.use_bpixmap ? True : False;
1195             XtSetArg(args[n], XtNuseBackingPixmap,b);                   n++;
1196             XtSetArg(args[n], XtNarguments,gv_gs_arguments);            n++;
1197             XtSetArg(args[n], XtNlxdpi, (1000*default_xdpi));		n++;
1198             XtSetArg(args[n], XtNlydpi, (1000*default_ydpi));		n++;
1199      page = XtCreateManagedWidget("page", ghostviewWidgetClass,viewControl, args,n);
1200             num_ghosts++;
1201 
1202             XtAddCallback(page, XtNcallback, cb_track, (XtPointer)NULL);
1203             XtAddCallback(page, XtNdestroyCallback, cb_destroyGhost, (XtPointer)page);
1204             XtAddCallback(page, XtNmessageCallback, cb_message, (XtPointer)page);
1205             XtAddCallback(page, XtNoutputCallback,cb_appendInfoPopup, (XtPointer)NULL);
1206    }
1207 /*### checking gv_filename and opening psfile #############################*/
1208 
1209    INFMESSAGE(checking gv_filename and opening psfile)
1210 
1211    if (argc == optind + 1)
1212      {
1213        gv_filename=XtNewString(argv[optind]);
1214      }
1215 
1216    if (gv_filename && strcmp(gv_filename, "-")) {
1217       if (misc_changeFile(gv_filename)) {
1218 	open_fail_error(errno,GV_ERROR_OPEN_FAIL,gv_filename,1);
1219 	clean_safe_tempdir();
1220 	exit(EXIT_STATUS_ERROR);
1221       } else {
1222         XtFree(gv_filename_old);
1223         gv_filename_old = NULL;
1224       }
1225    }
1226 
1227 /*### remaining initialization #####################################################*/
1228 
1229     INFMESSAGE(remaining initialization)
1230 
1231 #ifdef USE_SIGNAL_HANDLER
1232     signal_setSignalHandlers(1);
1233 #endif
1234 
1235     GhostviewDisableInterpreter(page);
1236 
1237     gv_pagemedia = MEDIA_ID_INVALID;
1238     setup_ghostview();
1239 
1240     {
1241        int o;
1242        gv_orientation_old         = O_UNSPECIFIED;
1243        o = doc_convStringToDocOrient(app_res.default_orientation);
1244        if (o == O_AUTOMATIC) {
1245           gv_orientation_auto     = 1;
1246           gv_orientation_auto_old = 0;
1247           gv_orientation          = O_UNSPECIFIED;
1248        } else {
1249           gv_orientation_auto     = 0;
1250           gv_orientation_auto_old = 1;
1251           gv_orientation          = o;
1252        }
1253     }
1254 
1255     gv_fallback_orientation = doc_convStringToDocOrient(app_res.fallback_orientation);
1256     if (gv_fallback_orientation != O_PORTRAIT   && gv_fallback_orientation != O_LANDSCAPE &&
1257         gv_fallback_orientation != O_UPSIDEDOWN && gv_fallback_orientation != O_SEASCAPE)
1258         gv_fallback_orientation = O_PORTRAIT;
1259 
1260     gv_fallback_pagemedia   = doc_convStringToPageMedia(NULL,app_res.fallback_pagemedia);
1261     if (gv_fallback_pagemedia == MEDIA_ID_INVALID) gv_fallback_pagemedia = doc_convStringToPageMedia(NULL,"A4");
1262     if (gv_fallback_pagemedia == MEDIA_ID_INVALID) {
1263       gv_fallback_pagemedia=1;
1264       while (!gv_medias[gv_fallback_pagemedia]->used) gv_fallback_pagemedia++;
1265     }
1266 
1267     gv_swap_landscape_old = -1;
1268     if (app_res.swap_landscape) gv_swap_landscape = 1;
1269     else                        gv_swap_landscape = 0;
1270 
1271     gv_exiting = 0;
1272 
1273     number = doc_convStringToPage(doc,app_res.page);
1274     number = doc_putPageInRange(doc,number);
1275 
1276 
1277 /*### managing the children ######################################################*/
1278 
1279     INFMESSAGE(managing children of control)
1280     XtManageChildren((WidgetList)cont_child,cont_child_num);
1281     INFMESSAGE(managing control)
1282     XtManageChild(main_control);
1283     XtSetMappedWhenManaged(toplevel, False);
1284     INFMESSAGE(realizing toplevel)
1285     XtRealizeWidget(toplevel);
1286     XSetWMProtocols(gv_display, XtWindow(toplevel), &wm_delete_window, 1);
1287 
1288 /*### Creating the File Selection Popup ###########################################*/
1289 
1290     INFMESSAGE(creating file selection popup)
1291                               				n=0;
1292             XtSetArg(args[n], XtNallowShellResize,True);n++;
1293     FileSel_popup = XtCreatePopupShell("fileSelPopup",transientShellWidgetClass,toplevel,args,n);
1294                               				n=0;
1295             XtSetArg(args[n], XtNbuttons,  2);		n++;
1296             XtSetArg(args[n], XtNpreferredButton, 2);	n++;
1297             XtSetArg(args[n], XtNreverseScrolling,app_res.reverse_scrolling);n++;
1298             if (app_res.scratch_dir) {
1299                XtSetArg(args[n], XtNtmpDir, app_res.scratch_dir); n++;
1300             }
1301     FileSel = XtCreateManagedWidget("fileSel",file_selectionWidgetClass,FileSel_popup,args,n);
1302 	XtAddCallback(XtNameToWidget(FileSel,"button1"), XtNcallback,cb_popdownPopup,FileSel_popup);
1303 	XtAddCallback(XtNameToWidget(FileSel,"button1"), XtNcallback,cb_popdownNotePopup,(XtPointer)NULL);
1304 
1305     XtRealizeWidget(FileSel_popup);
1306     XSetWMProtocols(gv_display,XtWindow(FileSel_popup),&wm_delete_window,1);
1307 
1308                                                 n=0;
1309     XtSetArg(args[n], XtNfilters, &gv_filters);	n++;
1310     XtSetArg(args[n], XtNdirs,    &gv_dirs);	n++;
1311     XtSetArg(args[n], XtNfilter,  &gv_filter);	n++;
1312     XtGetValues(FileSel,args,n);
1313     gv_filters = XtNewString(gv_filters);
1314     gv_dirs    = XtNewString(gv_dirs);
1315     gv_filter  = XtNewString(gv_filter);
1316 
1317 /*### now we become visible ######################################################*/
1318 
1319     INFMESSAGE(switching off resize for buttons and labels)
1320 							n=0;
1321 	XtSetArg(args[0], XtNresize, False);		n++;
1322     if (show_nextPage)	        XtSetValues(w_nextPage,args,n);
1323     if (show_prevPage)	        XtSetValues(w_prevPage,args,n);
1324     if (show_toggleCurrentPage)	XtSetValues(w_toggleCurrentPage,args,n);
1325     if (show_toggleEvenPages)	XtSetValues(w_toggleEvenPages,args,n);
1326     if (show_toggleOddPages)	XtSetValues(w_toggleOddPages,args,n);
1327     if (show_unmarkAllPages)	XtSetValues(w_unmarkAllPages,args,n);
1328     if (show_saveMarkedPages)	XtSetValues(w_saveMarkedPages,args,n);
1329     if (show_printMarkedPages)	XtSetValues(w_printMarkedPages,args,n);
1330     if (show_printAllPages)	XtSetValues(w_printAllPages,args,n);
1331     if (show_openFile)		XtSetValues(w_openFile,args,n);
1332     if (show_autoResize)	XtSetValues(w_autoResize,args,n);
1333     if (show_showThisPage)	XtSetValues(w_showThisPage,args,n);
1334     if (show_updateFile)	XtSetValues(w_updateFile,args,n);
1335     if (show_checkFile)		XtSetValues(w_checkFile,args,n);
1336     if (show_locator) {
1337        				XtSetArg(args[n], XtNlabel,"");		n++;
1338 				XtSetValues(locator,args,n);
1339     }
1340 
1341     process_menu(NULL,PROCESS_MENU_HIDE); /* hide the process button */
1342 
1343     setup_layout_ghostview();
1344 
1345     if (gv_filename) current_page=number;
1346     show_page(REQUEST_SETUP,NULL);
1347     cb_watchFile(watchFileEntry,NULL,NULL);
1348 
1349     /* must allow control to resize */
1350     AaaWidgetAllowResize((AaaWidget)main_control,True,True);
1351 
1352     if (fullscreen_p) {
1353       Atom net_wm_state;
1354 
1355       net_wm_state = XInternAtom(XtDisplay(toplevel), "_NET_WM_STATE", True);
1356       if (net_wm_state != None) {
1357         Atom wm_fullstate;
1358         wm_fullstate = XInternAtom(XtDisplay(toplevel), "_NET_WM_STATE_FULLSCREEN", False);
1359 
1360         XtRealizeWidget(toplevel);
1361         XChangeProperty(XtDisplay(toplevel), XtWindow(toplevel),
1362                         net_wm_state, XA_ATOM, 32, PropModeReplace,
1363                         (unsigned char *)&wm_fullstate, 1);
1364       }
1365     }
1366 
1367     INFMESSAGE(mapping toplevel)
1368     XtMapWidget(toplevel);
1369     cb_showTitle(toplevel, NULL, NULL);
1370   }
1371 
1372   INFMESSAGE(waiting for events now)
1373   XtAppMainLoop(app_con);
1374 
1375   /* should never get here */
1376   return 1;
1377 }
1378 
1379 /*--------------------------------------------------
1380     main_createMenu
1381 --------------------------------------------------*/
1382 
main_createMenu(m,list,numP)1383 static void main_createMenu(m,list,numP)
1384   MenuEntry *m;
1385   Widget   *list;
1386   Cardinal *numP;
1387 {
1388   Arg args[1];
1389   Cardinal n;
1390   int i;
1391 
1392   BEGINMESSAGE(main_createMenu)
1393   SMESSAGE(m[0].name)
1394 
1395 							n=0;
1396   *(m[0].widgetP) = XtCreateManagedWidget(m[0].name,mbuttonWidgetClass,main_control,args,n);
1397     list[*numP] = *(m[0].widgetP); (*numP)++;
1398 
1399 							n=0;
1400   *(m[1].widgetP) = XtCreatePopupShell(m[1].name, simpleMenuWidgetClass,*(m[0].widgetP),args,n);
1401 
1402   i=2;
1403   while (m[i].name) {
1404     if (!strcmp(m[i].name,"line")) {
1405       XtCreateManagedWidget("line", smeLineObjectClass,*(m[1].widgetP),args,n);
1406     } else {
1407       *(m[i].widgetP) = XtCreateManagedWidget(m[i].name, smeBSBObjectClass,*(m[1].widgetP),args,n);
1408       if (m[i].callback) XtAddCallback(*(m[i].widgetP), XtNcallback,m[i].callback,m[i].client_data);
1409     }
1410     ++i;
1411   }
1412   ENDMESSAGE(main_createMenu)
1413 }
1414 
1415 /*##################################################
1416     main_setInternResource
1417 ##################################################*/
1418 
main_setInternResource(db,sP,name)1419 void main_setInternResource(db,sP,name)
1420   XrmDatabase db;
1421   String *sP;
1422   char *name;
1423 {
1424   BEGINMESSAGE(main_setInternResource)
1425   *sP = resource_getResource(db,gv_class,gv_class,name,NULL);
1426   if (!*sP) *sP="";
1427   *sP = XtNewString(*sP);
1428   ENDMESSAGE(main_setInternResource)
1429 }
1430 
1431 /*##################################################
1432     main_setGhostscriptResources
1433 ##################################################*/
1434 
main_setGhostscriptResources(db)1435 void main_setGhostscriptResources(db)
1436   XrmDatabase db;
1437 {
1438   char *s;
1439 
1440   BEGINMESSAGE(main_setGhostscriptResources)
1441   main_setInternResource(db,&gv_gs_interpreter,"gsInterpreter");
1442   main_setInternResource(db,&gv_gs_cmd_scan_pdf,"gsCmdScanPDF");
1443   main_setInternResource(db,&gv_gs_cmd_conv_pdf,"gsCmdConvPDF");
1444   main_setInternResource(db,&gv_gs_x11_device,"gsX11Device");
1445   main_setInternResource(db,&gv_gs_x11_alpha_device,"gsX11AlphaDevice");
1446 
1447   main_setInternResource(db,&gv_gs_arguments,"gsArguments");
1448   s = resource_getResource(db,gv_class,gv_name,"arguments","Arguments");
1449   if (s) gv_gs_arguments = s;
1450 
1451   s = resource_getResource(db,gv_class,gv_name,"gsSafeDir",NULL);
1452   if (!strcasecmp(s,"true"))  gv_gs_safeDir = 1; else gv_gs_safeDir = 0;
1453 
1454   s = resource_getResource(db,gv_class,gv_name,"gsSafer",NULL);
1455   if (s && !strcasecmp(s,"true"))  gv_gs_safer = 1; else gv_gs_safer = 0;
1456   s = resource_getResource(db,gv_class,gv_name,"safer","Safer");
1457   if (s) {
1458     if (!strcasecmp(s,"true"))  gv_gs_safer = 1;
1459     else if (!strcasecmp(s,"false"))  gv_gs_safer = 0;
1460   }
1461 
1462   s = resource_getResource(db,gv_class,gv_name,"gsQuiet",NULL);
1463   if (s && !strcasecmp(s,"true"))  gv_gs_quiet = 1; else gv_gs_quiet = 0;
1464   s = resource_getResource(db,gv_class,gv_name,"quiet","Quiet");
1465   if (s) {
1466     if (!strcasecmp(s,"true"))  gv_gs_quiet = 1;
1467     else if (!strcasecmp(s,"false"))  gv_gs_quiet = 0;
1468   }
1469 
1470   s = resource_getResource(db,gv_class,gv_name,"infoVerbose",NULL);
1471   if (!strcasecmp(s, "Silent"))      gv_infoVerbose=0;
1472   else if (!strcasecmp(s, "Errors")) gv_infoVerbose=1;
1473   else if (!strcasecmp(s, "All"))    gv_infoVerbose=2;
1474   else gv_infoVerbose = 1;
1475 
1476   s = resource_getResource(db,gv_class,gv_name,"xinerama",NULL);
1477   if (!strcasecmp(s, "Off"))      gv_xinerama=0;
1478   else if (!strcasecmp(s, "On")) gv_xinerama=1;
1479   else if (!strcasecmp(s, "Auto"))    gv_xinerama=-1;
1480   else gv_xinerama = 0;
1481 
1482   ENDMESSAGE(main_setGhostscriptResources)
1483 }
1484 
1485 /*##################################################
1486    main_setResolutions
1487 ##################################################*/
1488 
main_setResolutions(query)1489 void main_setResolutions(query)
1490   int query;
1491 {
1492   int checkXinerama = 1;
1493   int sizeX, sizeY;
1494   float ratio;
1495 
1496   BEGINMESSAGE(main_setResolutions)
1497   if (query) scale_getScreenSize(gv_display,gv_screen,gv_database,gv_class,gv_name,&gv_screen_width,&gv_screen_height);
1498 
1499   if (debug_p) printf("Your detected screen size is: %i mm x %i mm\n", gv_screen_width, gv_screen_height);
1500 
1501   /* Some Xinerama implementations summarize the size over all displays.
1502      In this case you must use the summarized resolution, too.
1503 
1504      Other systems return the size of one (which?) display.
1505      In this case you have to ask Xinerama about the size of one display.
1506   */
1507 
1508   ratio = (float) gv_screen_width / (float) gv_screen_height;
1509   if ( ratio >= 2 || ratio < 1 ) /* does not look like a single monitor */
1510   {
1511      checkXinerama = 0;
1512      if (debug_p) printf ("That does not look like a single monitor, as the ratio is %.2f.\n", ratio);
1513   }
1514   else
1515      if (debug_p) printf ("That looks like a single monitor, as the ratio is %.2f.\n", ratio);
1516 
1517   sizeX = WidthOfScreen(gv_screen);
1518   sizeY = HeightOfScreen(gv_screen);
1519   if (debug_p) printf("Your detected screen resolution is: %i x %i\n", sizeX, sizeY);
1520 
1521 #if HAVE_LIBXINERAMA
1522   /* In case we do not have Xinerama at all */
1523   if (gv_xinerama == 0)
1524      checkXinerama = 0;
1525   else if (gv_xinerama == 1)
1526      checkXinerama = 1;
1527   if (!XineramaIsActive(gv_display))
1528      checkXinerama = 0;
1529 
1530   if (checkXinerama)
1531   {
1532     int num_heads;
1533     XineramaScreenInfo *head_info;
1534     head_info = (XineramaScreenInfo *) XineramaQueryScreens(gv_display,&num_heads);
1535     sizeX = head_info[0].width;
1536     sizeY = head_info[0].height;
1537     if (debug_p) printf("Xinerama's resolution of screen 0 is: %i x %i\n", sizeX, sizeY);
1538   }
1539 #endif
1540 
1541   gv_real_xdpi = 72.0 * 72.0 * (float)gv_screen_width  / (25.4 * sizeX);
1542   gv_real_ydpi = 72.0 * 72.0 * (float)gv_screen_height / (25.4 * sizeY);
1543   gv_pixel_xdpi = 72.0;
1544   gv_pixel_ydpi = 72.0;
1545   IIMESSAGE(gv_screen_width,gv_screen_height)
1546   FMESSAGE(gv_real_xdpi) FMESSAGE(gv_real_ydpi)
1547   FMESSAGE(gv_pixel_xdpi) FMESSAGE(gv_pixel_ydpi)
1548   ENDMESSAGE(main_setResolutions)
1549 }
1550 
1551 /*##################################################
1552    main_createScaleMenu
1553 ##################################################*/
1554 
main_createScaleMenu(void)1555 void main_createScaleMenu(void)
1556 {
1557   Arg args[1];
1558   Cardinal n;
1559   int i;
1560   Boolean have_line = False;
1561 
1562   BEGINMESSAGE(main_createScaleMenu)
1563 							n=0;
1564   scaleMenu = XtCreatePopupShell("menu", simpleMenuWidgetClass,scaleButton,args,n);
1565   for (i=0; gv_scales[i]; i++);
1566   scaleEntry = (Widget*) XtMalloc(i*sizeof(Widget));
1567   for (i=0; gv_scales[i]; i++) {
1568     if (!have_line && !gv_scales[i]->is_base) {
1569       XtCreateManagedWidget("line", smeLineObjectClass,scaleMenu,NULL,(Cardinal)0);
1570       have_line=True;
1571     }
1572     scaleEntry[i] = XtCreateManagedWidget(gv_scales[i]->name, smeBSBObjectClass,scaleMenu,args,n);
1573     if (gv_scales[i]->is_base) XtAddCallback(scaleEntry[i], XtNcallback,cb_setScale,(XtPointer)(intptr_t)(i|SCALE_BAS));
1574     else XtAddCallback(scaleEntry[i], XtNcallback,cb_setScale,(XtPointer)(intptr_t)(i|SCALE_ABS));
1575   }
1576   ENDMESSAGE(main_createScaleMenu)
1577 }
1578 
1579 
1580 
1581 
1582 
1583 
1584 
1585