]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/XPDFViewer.cc
Initial revision
[evince.git] / pdf / xpdf / XPDFViewer.cc
1 //========================================================================
2 //
3 // XPDFViewer.cc
4 //
5 // Copyright 2002 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <X11/cursorfont.h>
19 #ifdef HAVE_X11_XPM_H
20 #include <X11/xpm.h>
21 #endif
22 #include "gmem.h"
23 #include "gfile.h"
24 #include "GString.h"
25 #include "GList.h"
26 #include "Error.h"
27 #include "GlobalParams.h"
28 #include "PDFDoc.h"
29 #include "ErrorCodes.h"
30 #include "Outline.h"
31 #include "UnicodeMap.h"
32 #ifndef DISABLE_OUTLINE
33 #define Object XtObject
34 #include "XPDFTree.h"
35 #undef Object
36 #endif
37 #include "XPDFApp.h"
38 #include "XPDFViewer.h"
39 #include "XPixmapOutputDev.h"
40 #include "PSOutputDev.h"
41 #include "config.h"
42
43 // these macro defns conflict with xpdf's Object class
44 #ifdef LESSTIF_VERSION
45 #undef XtDisplay
46 #undef XtScreen
47 #undef XtWindow
48 #undef XtParent
49 #undef XtIsRealized
50 #endif
51
52 #if XmVERSION <= 1
53 #define XmSET   True
54 #define XmUNSET False
55 #endif
56
57 //------------------------------------------------------------------------
58 // GUI includes
59 //------------------------------------------------------------------------
60
61 #include "xpdfIcon.xpm"
62 #include "leftArrow.xbm"
63 #include "leftArrowDis.xbm"
64 #include "dblLeftArrow.xbm"
65 #include "dblLeftArrowDis.xbm"
66 #include "rightArrow.xbm"
67 #include "rightArrowDis.xbm"
68 #include "dblRightArrow.xbm"
69 #include "dblRightArrowDis.xbm"
70 #include "backArrow.xbm"
71 #include "backArrowDis.xbm"
72 #include "forwardArrow.xbm"
73 #include "forwardArrowDis.xbm"
74 #include "find.xbm"
75 #include "findDis.xbm"
76 #include "print.xbm"
77 #include "printDis.xbm"
78 #include "about.xbm"
79 #include "about-text.h"
80
81 //------------------------------------------------------------------------
82
83 XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName,
84                        int pageA, GString *destName,
85                        GString *ownerPassword, GString *userPassword) {
86   LinkDest *dest;
87   int pg, z;
88   GString *dir;
89
90   app = appA;
91   win = NULL;
92   core = NULL;
93   password = NULL;
94   ok = gFalse;
95 #ifndef DISABLE_OUTLINE
96   outlineLabels = NULL;
97   outlineLabelsLength = outlineLabelsSize = 0;
98 #endif
99
100   // do Motif-specific initialization and create the window;
101   // this also creates the core object
102   initWindow();
103   initAboutDialog();
104   initOpenDialog();
105   initFindDialog();
106   initSaveAsDialog();
107   initPrintDialog();
108   initPasswordDialog();
109
110   dest = NULL; // make gcc happy
111   pg = pageA; // make gcc happy
112
113   if (fileName) {
114     if (loadFile(fileName, ownerPassword, userPassword)) {
115       getPageAndDest(pageA, destName, &pg, &dest);
116       if (pg > 0) {
117         core->resizeToPage(pg);
118       }
119       dir = makePathAbsolute(grabPath(fileName->getCString()));
120       setOpenDialogDir(dir->getCString());
121       setSaveAsDialogDir(dir->getCString());
122       delete dir;
123     } else {
124       return;
125     }
126   }
127
128   // map the window -- we do this after calling resizeToPage to avoid
129   // an annoying on-screen resize
130   mapWindow();
131
132   // display the first page
133   z = app->getFullScreen() ? zoomPage : core->getZoom();
134   if (dest) {
135     displayDest(dest, z, core->getRotate(), gTrue);
136     delete dest;
137   } else {
138     displayPage(pg, z, core->getRotate(), gTrue, gTrue);
139   }
140
141   ok = gTrue;
142 }
143
144 XPDFViewer::~XPDFViewer() {
145   delete core;
146   XmFontListFree(aboutBigFont);
147   XmFontListFree(aboutVersionFont);
148   XmFontListFree(aboutFixedFont);
149   closeWindow();
150 #ifndef DISABLE_OUTLINE
151   if (outlineLabels) {
152     gfree(outlineLabels);
153   }
154 #endif
155   if (password) {
156     delete password;
157   }
158 }
159
160 void XPDFViewer::open(GString *fileName, int pageA, GString *destName) {
161   LinkDest *dest;
162   int pg, z;
163
164   if (!core->getDoc() || fileName->cmp(core->getDoc()->getFileName())) {
165     if (!loadFile(fileName, NULL, NULL)) {
166       return;
167     }
168   }
169   getPageAndDest(pageA, destName, &pg, &dest);
170   z = app->getFullScreen() ? zoomPage : core->getZoom();
171   if (dest) {
172     displayDest(dest, z, core->getRotate(), gTrue);
173     delete dest;
174   } else {
175     displayPage(pg, z, core->getRotate(), gTrue, gTrue);
176   }
177 }
178
179 void XPDFViewer::clear() {
180   char *title;
181   XmString s;
182
183   core->clear();
184
185   // set up title, number-of-pages display
186   title = app->getTitle() ? app->getTitle()->getCString()
187                           : (char *)xpdfAppName;
188   XtVaSetValues(win, XmNtitle, title, XmNiconName, title, NULL);
189   s = XmStringCreateLocalized("");
190   XtVaSetValues(pageNumText, XmNlabelString, s, NULL);
191   XmStringFree(s);
192   s = XmStringCreateLocalized(" of 0");
193   XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
194   XmStringFree(s);
195
196   // disable buttons
197   XtVaSetValues(prevTenPageBtn, XmNsensitive, False, NULL);
198   XtVaSetValues(prevPageBtn, XmNsensitive, False, NULL);
199   XtVaSetValues(nextTenPageBtn, XmNsensitive, False, NULL);
200   XtVaSetValues(nextPageBtn, XmNsensitive, False, NULL);
201 }
202
203 //------------------------------------------------------------------------
204 // load / display
205 //------------------------------------------------------------------------
206
207 GBool XPDFViewer::loadFile(GString *fileName, GString *ownerPassword,
208                            GString *userPassword) {
209   return core->loadFile(fileName, ownerPassword, userPassword) == errNone;
210 }
211
212 void XPDFViewer::reloadFile() {
213   int pg;
214
215   if (!core->getDoc()) {
216     return;
217   }
218   pg = core->getPageNum();
219   loadFile(core->getDoc()->getFileName());
220   if (pg > core->getDoc()->getNumPages()) {
221     pg = core->getDoc()->getNumPages();
222   }
223   displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gFalse);
224 }
225
226 void XPDFViewer::displayPage(int pageA, int zoomA, int rotateA,
227                              GBool scrollToTop, GBool addToHist) {
228   core->displayPage(pageA, zoomA, rotateA, scrollToTop, addToHist);
229 }
230
231 void XPDFViewer::displayDest(LinkDest *dest, int zoomA, int rotateA,
232                              GBool addToHist) {
233   core->displayDest(dest, zoomA, rotateA, addToHist);
234 }
235
236 void XPDFViewer::getPageAndDest(int pageA, GString *destName,
237                                 int *pageOut, LinkDest **destOut) {
238   Ref pageRef;
239
240   // find the page number for a named destination
241   *pageOut = pageA;
242   *destOut = NULL;
243   if (destName && (*destOut = core->getDoc()->findDest(destName))) {
244     if ((*destOut)->isPageRef()) {
245       pageRef = (*destOut)->getPageRef();
246       *pageOut = core->getDoc()->findPage(pageRef.num, pageRef.gen);
247     } else {
248       *pageOut = (*destOut)->getPageNum();
249     }
250   }
251
252   if (*pageOut <= 0) {
253     *pageOut = 1;
254   }
255   if (*pageOut > core->getDoc()->getNumPages()) {
256     *pageOut = core->getDoc()->getNumPages();
257   }
258 }
259
260 //------------------------------------------------------------------------
261 // password dialog
262 //------------------------------------------------------------------------
263
264 GString *XPDFViewer::reqPasswordCbk(void *data, GBool again) {
265   XPDFViewer *viewer = (XPDFViewer *)data;
266
267   viewer->getPassword(again);
268   return viewer->password;
269 }
270
271 //------------------------------------------------------------------------
272 // actions
273 //------------------------------------------------------------------------
274
275 void XPDFViewer::actionCbk(void *data, char *action) {
276   XPDFViewer *viewer = (XPDFViewer *)data;
277
278   if (!strcmp(action, "Quit")) {
279     viewer->app->quit();
280   }
281 }
282
283 //------------------------------------------------------------------------
284 // keyboard/mouse input
285 //------------------------------------------------------------------------
286
287 void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key,
288                              Guint modifiers) {
289   XPDFViewer *viewer = (XPDFViewer *)data;
290   int z;
291
292   if (s[0]) {
293     switch (s[0]) {
294     case 'O':
295     case 'o':
296       viewer->mapOpenDialog(gFalse);
297       break;
298     case 'R':
299     case 'r':
300       viewer->reloadFile();
301       break;
302     case 'F':
303     case 'f':
304     case '\006':                // ctrl-F
305       if (viewer->core->getDoc()) {
306         XtManageChild(viewer->findDialog);
307       }
308       break;
309     case '\007':                // ctrl-G
310       if (viewer->core->getDoc()) {
311         XPDFViewer::findFindCbk(None, viewer, NULL);
312       }
313       break;
314     case '\020':                // ctrl-P
315       if (viewer->core->getDoc()) {
316         XtManageChild(viewer->printDialog);
317       }
318       break;
319     case 'N':
320     case 'n':
321       viewer->core->gotoNextPage(1, !(modifiers & Mod5Mask));
322       break;
323     case 'P':
324     case 'p':
325       viewer->core->gotoPrevPage(1, !(modifiers & Mod5Mask), gFalse);
326       break;
327     case ' ':
328       if (viewer->app->getFullScreen()) {
329         viewer->core->gotoNextPage(1, gTrue);
330       } else {
331         viewer->core->scrollPageDown();
332       }
333       break;
334     case '\b':                  // bs
335     case '\177':                // del
336       if (viewer->app->getFullScreen()) {
337         viewer->core->gotoPrevPage(1, gTrue, gFalse);
338       } else {
339         viewer->core->scrollPageUp();
340       }
341       break;
342     case 'v':
343       viewer->core->goForward();
344       break;
345     case 'b':
346       viewer->core->goBackward();
347       break;
348     case 'g':
349       if (!viewer->app->getFullScreen()) {
350         XmTextFieldSetSelection(
351             viewer->pageNumText, 0,
352             strlen(XmTextFieldGetString(viewer->pageNumText)),
353             XtLastTimestampProcessed(viewer->display));
354         XmProcessTraversal(viewer->pageNumText, XmTRAVERSE_CURRENT);
355       }
356       break;
357     case 'h':                   // vi-style left
358       if (!viewer->app->getFullScreen() && viewer->app->getViKeys()) {
359         viewer->core->scrollLeft();
360       }
361       break;
362     case 'l':                   // vi-style right
363       if (!viewer->app->getFullScreen() && viewer->app->getViKeys()) {
364         viewer->core->scrollRight();
365       }
366       break;
367     case 'k':                   // vi-style up
368       if (!viewer->app->getFullScreen() && viewer->app->getViKeys()) {
369         viewer->core->scrollUp();
370       }
371       break;
372     case 'j':                   // vi-style down
373       if (!viewer->app->getFullScreen() && viewer->app->getViKeys()) {
374         viewer->core->scrollDown();
375       }
376       break;
377     case '0':
378       if (!viewer->app->getFullScreen() &&
379           viewer->core->getZoom() != defZoom) {
380         XtVaSetValues(viewer->zoomMenu,
381                       XmNmenuHistory, viewer->getZoomMenuBtn(defZoom),
382                       NULL);
383         viewer->displayPage(viewer->core->getPageNum(), defZoom,
384                             viewer->core->getRotate(), gTrue, gFalse);
385       }
386       break;
387     case '+':
388       if (!viewer->app->getFullScreen() &&
389           viewer->core->getZoom() >= minZoom &&
390           viewer->core->getZoom() < maxZoom) {
391         z = viewer->core->getZoom() + 1;
392         XtVaSetValues(viewer->zoomMenu,
393                       XmNmenuHistory, viewer->getZoomMenuBtn(z),
394                       NULL);
395         viewer->displayPage(viewer->core->getPageNum(), z,
396                             viewer->core->getRotate(), gTrue, gFalse);
397       }
398       break;
399     case '-':
400       if (!viewer->app->getFullScreen() &&
401           viewer->core->getZoom() > minZoom &&
402           viewer->core->getZoom() <= maxZoom) {
403         z = viewer->core->getZoom() - 1;
404         XtVaSetValues(viewer->zoomMenu,
405                       XmNmenuHistory, viewer->getZoomMenuBtn(z),
406                       NULL);
407         viewer->displayPage(viewer->core->getPageNum(), z,
408                             viewer->core->getRotate(), gTrue, gFalse);
409       }
410       break;
411     case 'z':
412       if (!viewer->app->getFullScreen() &&
413           viewer->core->getZoom() != zoomPage) {
414         XtVaSetValues(viewer->zoomMenu,
415                       XmNmenuHistory, viewer->getZoomMenuBtn(zoomPage),
416                       NULL);
417         viewer->displayPage(viewer->core->getPageNum(), zoomPage,
418                             viewer->core->getRotate(), gTrue, gFalse);
419       }
420       break;
421     case 'w':
422       if (!viewer->app->getFullScreen() &&
423           viewer->core->getZoom() != zoomWidth) {
424         XtVaSetValues(viewer->zoomMenu,
425                       XmNmenuHistory, viewer->getZoomMenuBtn(zoomWidth),
426                       NULL);
427         viewer->displayPage(viewer->core->getPageNum(), zoomWidth,
428                             viewer->core->getRotate(), gTrue, gFalse);
429       }
430       break;
431     case '\014':                // ^L
432       viewer->displayPage(viewer->core->getPageNum(), viewer->core->getZoom(),
433                           viewer->core->getRotate(), gFalse, gFalse);
434       break;
435     case '\027':                // ^W
436       viewer->app->close(viewer, gFalse);
437       break;
438     case '?':
439       XtManageChild(viewer->aboutDialog);
440       break;
441     case 'Q':
442     case 'q':
443       viewer->app->quit();
444       break;
445     }
446   }
447 }
448
449 void XPDFViewer::mouseCbk(void *data, XEvent *event) {
450   XPDFViewer *viewer = (XPDFViewer *)data;
451
452   if (event->type == ButtonPress && event->xbutton.button == 3) {
453     XmMenuPosition(viewer->popupMenu, &event->xbutton);
454     XtManageChild(viewer->popupMenu);
455   }
456 }
457
458 //------------------------------------------------------------------------
459 // GUI code: main window
460 //------------------------------------------------------------------------
461
462 void XPDFViewer::initWindow() {
463   Widget btn, label, menuPane, lastBtn;
464 #ifndef DISABLE_OUTLINE
465   Widget clipWin;
466 #endif
467   Colormap colormap;
468   XColor xcol;
469   Arg args[20];
470   int n;
471   char *title;
472   XmString s, s2, emptyString;
473   char buf[16];
474   int i;
475
476   display = XtDisplay(app->getAppShell());
477   screenNum = XScreenNumberOfScreen(XtScreen(app->getAppShell()));
478
479   // private colormap
480   if (app->getInstallCmap()) {
481     XtVaGetValues(app->getAppShell(), XmNcolormap, &colormap, NULL);
482     // ensure that BlackPixel and WhitePixel are reserved in the
483     // new colormap
484     xcol.red = xcol.green = xcol.blue = 0;
485     XAllocColor(display, colormap, &xcol);
486     xcol.red = xcol.green = xcol.blue = 65535;
487     XAllocColor(display, colormap, &xcol);
488     colormap = XCopyColormapAndFree(display, colormap);
489   }
490
491   // top-level window
492   n = 0;
493   title = app->getTitle() ? app->getTitle()->getCString()
494                           : (char *)xpdfAppName;
495   XtSetArg(args[n], XmNtitle, title); ++n;
496   XtSetArg(args[n], XmNiconName, title); ++n;
497   XtSetArg(args[n], XmNminWidth, 100); ++n;
498   XtSetArg(args[n], XmNminHeight, 100); ++n;
499   XtSetArg(args[n], XmNbaseWidth, 0); ++n;
500   XtSetArg(args[n], XmNbaseHeight, 0); ++n;
501   XtSetArg(args[n], XmNdeleteResponse, XmDO_NOTHING); ++n;
502   if (app->getFullScreen()) {
503     XtSetArg(args[n], XmNmwmDecorations, 0); ++n;
504     XtSetArg(args[n], XmNgeometry, "+0+0"); ++n;
505   } else if (app->getGeometry()) {
506     XtSetArg(args[n], XmNgeometry, app->getGeometry()->getCString()); ++n;
507   }
508   win = XtCreatePopupShell("win", topLevelShellWidgetClass,
509                            app->getAppShell(), args, n);
510   if (app->getInstallCmap()) {
511     XtVaSetValues(win, XmNcolormap, colormap, NULL);
512   }
513   XmAddWMProtocolCallback(win, XInternAtom(display, "WM_DELETE_WINDOW", False),
514                           &closeMsgCbk, this);
515
516   // form
517   n = 0;
518   form = XmCreateForm(win, "form", args, n);
519   XtManageChild(form);
520
521   // toolbar
522   n = 0;
523   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
524   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
525   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
526   toolBar = XmCreateForm(form, "toolBar", args, n);
527   XtManageChild(toolBar);
528
529   // create an empty string -- this is used for buttons that will get
530   // pixmaps later
531   emptyString = XmStringCreateLocalized("");
532
533   // page movement buttons
534   n = 0;
535   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
536   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
537   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
538   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
539   XtSetArg(args[n], XmNsensitive, False); ++n;
540   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
541   backBtn = XmCreatePushButton(toolBar, "back", args, n);
542   XtManageChild(backBtn);
543   XtAddCallback(backBtn, XmNactivateCallback,
544                 &backCbk, (XtPointer)this);
545   n = 0;
546   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
547   XtSetArg(args[n], XmNleftWidget, backBtn); ++n;
548   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
549   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
550   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
551   XtSetArg(args[n], XmNsensitive, False); ++n;
552   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
553   prevTenPageBtn = XmCreatePushButton(toolBar, "prevTenPage", args, n);
554   XtManageChild(prevTenPageBtn);
555   XtAddCallback(prevTenPageBtn, XmNactivateCallback,
556                 &prevTenPageCbk, (XtPointer)this);
557   n = 0;
558   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
559   XtSetArg(args[n], XmNleftWidget, prevTenPageBtn); ++n;
560   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
561   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
562   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
563   XtSetArg(args[n], XmNsensitive, False); ++n;
564   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
565   prevPageBtn = XmCreatePushButton(toolBar, "prevPage", args, n);
566   XtManageChild(prevPageBtn);
567   XtAddCallback(prevPageBtn, XmNactivateCallback,
568                 &prevPageCbk, (XtPointer)this);
569   n = 0;
570   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
571   XtSetArg(args[n], XmNleftWidget, prevPageBtn); ++n;
572   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
573   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
574   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
575   XtSetArg(args[n], XmNsensitive, False); ++n;
576   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
577   nextPageBtn = XmCreatePushButton(toolBar, "nextPage", args, n);
578   XtManageChild(nextPageBtn);
579   XtAddCallback(nextPageBtn, XmNactivateCallback,
580                 &nextPageCbk, (XtPointer)this);
581   n = 0;
582   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
583   XtSetArg(args[n], XmNleftWidget, nextPageBtn); ++n;
584   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
585   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
586   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
587   XtSetArg(args[n], XmNsensitive, False); ++n;
588   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
589   nextTenPageBtn = XmCreatePushButton(toolBar, "nextTenPage", args, n);
590   XtManageChild(nextTenPageBtn);
591   XtAddCallback(nextTenPageBtn, XmNactivateCallback,
592                 &nextTenPageCbk, (XtPointer)this);
593   n = 0;
594   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
595   XtSetArg(args[n], XmNleftWidget, nextTenPageBtn); ++n;
596   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
597   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
598   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
599   XtSetArg(args[n], XmNsensitive, False); ++n;
600   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
601   forwardBtn = XmCreatePushButton(toolBar, "forward", args, n);
602   XtManageChild(forwardBtn);
603   XtAddCallback(forwardBtn, XmNactivateCallback,
604                 &forwardCbk, (XtPointer)this);
605
606   // page number display
607   n = 0;
608   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
609   XtSetArg(args[n], XmNleftWidget, forwardBtn); ++n;
610   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
611   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
612   s = XmStringCreateLocalized("Page ");
613   XtSetArg(args[n], XmNlabelString, s); ++n;
614   label = XmCreateLabel(toolBar, "pageLabel", args, n);
615   XmStringFree(s);
616   XtManageChild(label);
617   n = 0;
618   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
619   XtSetArg(args[n], XmNleftWidget, label); ++n;
620   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
621   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
622   XtSetArg(args[n], XmNmarginWidth, 3); ++n;
623   XtSetArg(args[n], XmNmarginHeight, 3); ++n;
624   XtSetArg(args[n], XmNcolumns, 5); ++n;
625   pageNumText = XmCreateTextField(toolBar, "pageNum", args, n);
626   XtManageChild(pageNumText);
627   XtAddCallback(pageNumText, XmNactivateCallback,
628                 &pageNumCbk, (XtPointer)this);
629   n = 0;
630   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
631   XtSetArg(args[n], XmNleftWidget, pageNumText); ++n;
632   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
633   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
634   s = XmStringCreateLocalized(" of 00000");
635   XtSetArg(args[n], XmNlabelString, s); ++n;
636   XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
637   XtSetArg(args[n], XmNrecomputeSize, False); ++n;
638   pageCountLabel = XmCreateLabel(toolBar, "pageCountLabel", args, n);
639   XmStringFree(s);
640   XtManageChild(pageCountLabel);
641   s = XmStringCreateLocalized(" of 0");
642   XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
643   XmStringFree(s);
644
645   // zoom menu
646   n = 0;
647   menuPane = XmCreatePulldownMenu(toolBar, "zoomMenuPane", args, n);
648   for (i = minZoom; i <= maxZoom; ++i) {
649     n = 0;
650     sprintf(buf, "%s%d", i > 0 ? "+" : "", i);
651     s = XmStringCreateLocalized(buf);
652     XtSetArg(args[n], XmNlabelString, s); ++n;
653     XtSetArg(args[n], XmNuserData, (XtPointer)i); ++n;
654     sprintf(buf, "zoom%s%d", i < 0 ? "M" : "", i < 0 ? -i : i);
655     btn = XmCreatePushButton(menuPane, buf, args, n);
656     XmStringFree(s);
657     XtManageChild(btn);
658     XtAddCallback(btn, XmNactivateCallback,
659                   &zoomMenuCbk, (XtPointer)this);
660     zoomMenuBtns[i - minZoom] = btn;
661   }
662   n = 0;
663   s = XmStringCreateLocalized("fit page");
664   XtSetArg(args[n], XmNlabelString, s); ++n;
665   XtSetArg(args[n], XmNuserData, (XtPointer)zoomPage); ++n;
666   btn = XmCreatePushButton(menuPane, "zoomPage", args, n);
667   XmStringFree(s);
668   XtManageChild(btn);
669   XtAddCallback(btn, XmNactivateCallback,
670                 &zoomMenuCbk, (XtPointer)this);
671   zoomMenuBtns[maxZoom - minZoom + 1] = btn;
672   n = 0;
673   s = XmStringCreateLocalized("fit width");
674   XtSetArg(args[n], XmNlabelString, s); ++n;
675   XtSetArg(args[n], XmNuserData, (XtPointer)zoomWidth); ++n;
676   btn = XmCreatePushButton(menuPane, "zoomWidth", args, n);
677   XmStringFree(s);
678   XtManageChild(btn);
679   XtAddCallback(btn, XmNactivateCallback,
680                 &zoomMenuCbk, (XtPointer)this);
681   zoomMenuBtns[maxZoom - minZoom + 2] = btn;
682   n = 0;
683   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
684   XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
685   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
686   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
687   XtSetArg(args[n], XmNmarginWidth, 0); ++n;
688   XtSetArg(args[n], XmNmarginHeight, 0); ++n;
689   XtSetArg(args[n], XmNsubMenuId, menuPane); ++n;
690   zoomMenu = XmCreateOptionMenu(toolBar, "zoomMenu", args, n);
691   XtManageChild(zoomMenu);
692
693   // find/print/about buttons
694   n = 0;
695   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
696   XtSetArg(args[n], XmNleftWidget, zoomMenu); ++n;
697   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
698   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
699   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
700   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
701   findBtn = XmCreatePushButton(toolBar, "find", args, n);
702   XtManageChild(findBtn);
703   XtAddCallback(findBtn, XmNactivateCallback,
704                 &findCbk, (XtPointer)this);
705   n = 0;
706   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
707   XtSetArg(args[n], XmNleftWidget, findBtn); ++n;
708   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
709   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
710   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
711   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
712   printBtn = XmCreatePushButton(toolBar, "print", args, n);
713   XtManageChild(printBtn);
714   XtAddCallback(printBtn, XmNactivateCallback,
715                 &printCbk, (XtPointer)this);
716   n = 0;
717   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
718   XtSetArg(args[n], XmNleftWidget, printBtn); ++n;
719   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
720   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
721   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
722   XtSetArg(args[n], XmNlabelString, emptyString); ++n;
723   aboutBtn = XmCreatePushButton(toolBar, "about", args, n);
724   XtManageChild(aboutBtn);
725   XtAddCallback(aboutBtn, XmNactivateCallback,
726                 &aboutCbk, (XtPointer)this);
727   lastBtn = aboutBtn;
728
729   // quit button
730   n = 0;
731   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
732   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
733   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
734   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
735   s = XmStringCreateLocalized("Quit");
736   XtSetArg(args[n], XmNlabelString, s); ++n;
737   quitBtn = XmCreatePushButton(toolBar, "quit", args, n);
738   XmStringFree(s);
739   XtManageChild(quitBtn);
740   XtAddCallback(quitBtn, XmNactivateCallback,
741                 &quitCbk, (XtPointer)this);
742
743   // link label
744   n = 0;
745   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
746   XtSetArg(args[n], XmNleftWidget, lastBtn); ++n;
747   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
748   XtSetArg(args[n], XmNrightWidget, btn); ++n;
749   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
750   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
751   s = XmStringCreateLocalized("");
752   XtSetArg(args[n], XmNlabelString, s); ++n;
753   XtSetArg(args[n], XmNrecomputeSize, True); ++n;
754   XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
755   linkLabel = XmCreateLabel(toolBar, "linkLabel", args, n);
756   XmStringFree(s);
757   XtManageChild(linkLabel);
758
759 #ifndef DISABLE_OUTLINE
760   if (app->getFullScreen()) {
761 #endif
762
763     // core
764     core = new XPDFCore(win, form, app->getPaperColor(),
765                         app->getFullScreen(), app->getReverseVideo(),
766                         app->getInstallCmap(), app->getRGBCubeSize());
767     core->setUpdateCbk(&updateCbk, this);
768     core->setActionCbk(&actionCbk, this);
769     core->setKeyPressCbk(&keyPressCbk, this);
770     core->setMouseCbk(&mouseCbk, this);
771     core->setReqPasswordCbk(&reqPasswordCbk, this);
772     n = 0;
773     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
774     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
775     XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
776     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
777     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
778     XtSetValues(core->getWidget(), args, n);
779
780 #ifndef DISABLE_OUTLINE
781   } else {
782
783     // paned window
784     n = 0;
785     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
786     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
787     XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
788     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
789     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
790     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
791     panedWin = XmCreatePanedWindow(form, "panedWin", args, n);
792     XtManageChild(panedWin);
793
794     // scrolled window for outline container
795     n = 0;
796     XtSetArg(args[n], XmNpositionIndex, 0); ++n;
797     XtSetArg(args[n], XmNallowResize, True); ++n;
798     XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
799     XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
800     XtSetArg(args[n], XmNwidth, 1); ++n;
801     XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
802     outlineScroll = XmCreateScrolledWindow(panedWin, "outlineScroll", args, n);
803     XtManageChild(outlineScroll);
804     XtVaGetValues(outlineScroll, XmNclipWindow, &clipWin, NULL);
805     XtVaSetValues(clipWin, XmNbackground, app->getPaperColor(), NULL);
806
807     // outline tree
808     n = 0;
809     XtSetArg(args[n], XmNbackground, app->getPaperColor()); ++n;
810     outlineTree = XPDFCreateTree(outlineScroll, "outlineTree", args, n);
811     XtManageChild(outlineTree);
812     XtAddCallback(outlineTree, XPDFNselectionCallback, &outlineSelectCbk,
813                   (XtPointer)this);
814
815     // core
816     core = new XPDFCore(win, panedWin, app->getPaperColor(),
817                         app->getFullScreen(), app->getReverseVideo(),
818                         app->getInstallCmap(), app->getRGBCubeSize());
819     core->setUpdateCbk(&updateCbk, this);
820     core->setActionCbk(&actionCbk, this);
821     core->setKeyPressCbk(&keyPressCbk, this);
822     core->setMouseCbk(&mouseCbk, this);
823     core->setReqPasswordCbk(&reqPasswordCbk, this);
824     n = 0;
825     XtSetArg(args[n], XmNpositionIndex, 1); ++n;
826     XtSetArg(args[n], XmNallowResize, True); ++n;
827     XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
828     XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
829     XtSetValues(core->getWidget(), args, n);
830   }
831 #endif
832
833   // set the zoom menu to match the initial zoom setting
834   XtVaSetValues(zoomMenu, XmNmenuHistory,
835                 getZoomMenuBtn(core->getZoom()), NULL);
836
837   // set traversal order
838   XtVaSetValues(core->getDrawAreaWidget(),
839                 XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL);
840   XtVaSetValues(backBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
841                 NULL);
842   XtVaSetValues(prevTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
843                 NULL);
844   XtVaSetValues(prevPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
845                 NULL);
846   XtVaSetValues(nextPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
847                 NULL);
848   XtVaSetValues(nextTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
849                 NULL);
850   XtVaSetValues(forwardBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
851                 NULL);
852   XtVaSetValues(pageNumText, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
853                 NULL);
854   XtVaSetValues(zoomMenu, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
855                 NULL);
856   XtVaSetValues(findBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
857                 NULL);
858   XtVaSetValues(printBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
859                 NULL);
860   XtVaSetValues(aboutBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
861                 NULL);
862   XtVaSetValues(quitBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
863                 NULL);
864
865   // popup menu
866   n = 0;
867   XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); ++n;
868   popupMenu = XmCreatePopupMenu(core->getDrawAreaWidget(), "popupMenu",
869                                 args, n);
870   n = 0;
871   s = XmStringCreateLocalized("Open...");
872   XtSetArg(args[n], XmNlabelString, s); ++n;
873   s2 = XmStringCreateLocalized("O");
874   XtSetArg(args[n], XmNacceleratorText, s2); ++n;
875   btn = XmCreatePushButton(popupMenu, "open", args, n);
876   XmStringFree(s);
877   XmStringFree(s2);
878   XtManageChild(btn);
879   XtAddCallback(btn, XmNactivateCallback,
880                 &openCbk, (XtPointer)this);
881   n = 0;
882   s = XmStringCreateLocalized("Open in new window...");
883   XtSetArg(args[n], XmNlabelString, s); ++n;
884   btn = XmCreatePushButton(popupMenu, "openInNewWindow", args, n);
885   XmStringFree(s);
886   XtManageChild(btn);
887   XtAddCallback(btn, XmNactivateCallback,
888                 &openInNewWindowCbk, (XtPointer)this);
889   n = 0;
890   s = XmStringCreateLocalized("Reload");
891   XtSetArg(args[n], XmNlabelString, s); ++n;
892   s2 = XmStringCreateLocalized("R");
893   XtSetArg(args[n], XmNacceleratorText, s2); ++n;
894   btn = XmCreatePushButton(popupMenu, "reload", args, n);
895   XmStringFree(s);
896   XmStringFree(s2);
897   XtManageChild(btn);
898   XtAddCallback(btn, XmNactivateCallback,
899                 &reloadCbk, (XtPointer)this);
900   n = 0;
901   s = XmStringCreateLocalized("Save as...");
902   XtSetArg(args[n], XmNlabelString, s); ++n;
903   btn = XmCreatePushButton(popupMenu, "saveAs", args, n);
904   XmStringFree(s);
905   XtManageChild(btn);
906   XtAddCallback(btn, XmNactivateCallback,
907                 &saveAsCbk, (XtPointer)this);
908   n = 0;
909   btn = XmCreateSeparator(popupMenu, "sep1", args, n);
910   XtManageChild(btn);
911   n = 0;
912   s = XmStringCreateLocalized("Rotate counterclockwise");
913   XtSetArg(args[n], XmNlabelString, s); ++n;
914   btn = XmCreatePushButton(popupMenu, "rotateCCW", args, n);
915   XmStringFree(s);
916   XtManageChild(btn);
917   XtAddCallback(btn, XmNactivateCallback,
918                 &rotateCCWCbk, (XtPointer)this);
919   n = 0;
920   s = XmStringCreateLocalized("Rotate clockwise");
921   XtSetArg(args[n], XmNlabelString, s); ++n;
922   btn = XmCreatePushButton(popupMenu, "rotateCW", args, n);
923   XmStringFree(s);
924   XtManageChild(btn);
925   XtAddCallback(btn, XmNactivateCallback,
926                 &rotateCWCbk, (XtPointer)this);
927   n = 0;
928   btn = XmCreateSeparator(popupMenu, "sep2", args, n);
929   XtManageChild(btn);
930   n = 0;
931   s = XmStringCreateLocalized("Close");
932   XtSetArg(args[n], XmNlabelString, s); ++n;
933   s2 = XmStringCreateLocalized("Ctrl+W");
934   XtSetArg(args[n], XmNacceleratorText, s2); ++n;
935   btn = XmCreatePushButton(popupMenu, "close", args, n);
936   XmStringFree(s);
937   XmStringFree(s2);
938   XtManageChild(btn);
939   XtAddCallback(btn, XmNactivateCallback,
940                 &closeCbk, (XtPointer)this);
941   n = 0;
942   s = XmStringCreateLocalized("Quit");
943   XtSetArg(args[n], XmNlabelString, s); ++n;
944   s2 = XmStringCreateLocalized("Q");
945   XtSetArg(args[n], XmNacceleratorText, s2); ++n;
946   btn = XmCreatePushButton(popupMenu, "quit", args, n);
947   XmStringFree(s);
948   XmStringFree(s2);
949   XtManageChild(btn);
950   XtAddCallback(btn, XmNactivateCallback,
951                 &quitCbk, (XtPointer)this);
952
953   XmStringFree(emptyString);
954 }
955
956 void XPDFViewer::mapWindow() {
957 #ifdef HAVE_X11_XPM_H
958   Pixmap iconPixmap;
959 #endif
960   int depth;
961   Pixel bg, arm;
962
963   // show the window
964   XtPopup(win, XtGrabNone);
965   core->takeFocus();
966
967   // create the icon
968 #ifdef HAVE_X11_XPM_H
969   if (XpmCreatePixmapFromData(display, XtWindow(win), xpdfIcon,
970                               &iconPixmap, NULL, NULL) == XpmSuccess) {
971     XtVaSetValues(win, XmNiconPixmap, iconPixmap, NULL);
972   }
973 #endif
974
975   // set button bitmaps (must be done after the window is mapped)
976   XtVaGetValues(backBtn, XmNdepth, &depth,
977                 XmNbackground, &bg, XmNarmColor, &arm, NULL);
978   XtVaSetValues(backBtn, XmNlabelType, XmPIXMAP,
979                 XmNlabelPixmap,
980                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
981                                             (char *)backArrow_bits,
982                                             backArrow_width,
983                                             backArrow_height,
984                                             BlackPixel(display, screenNum),
985                                             bg, depth),
986                 XmNarmPixmap,
987                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
988                                             (char *)backArrow_bits,
989                                             backArrow_width,
990                                             backArrow_height,
991                                             BlackPixel(display, screenNum),
992                                             arm, depth),
993                 XmNlabelInsensitivePixmap,
994                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
995                                             (char *)backArrowDis_bits,
996                                             backArrowDis_width,
997                                             backArrowDis_height,
998                                             BlackPixel(display, screenNum),
999                                             bg, depth),
1000                 NULL);
1001   XtVaSetValues(prevTenPageBtn, XmNlabelType, XmPIXMAP,
1002                 XmNlabelPixmap,
1003                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1004                                             (char *)dblLeftArrow_bits,
1005                                             dblLeftArrow_width,
1006                                             dblLeftArrow_height,
1007                                             BlackPixel(display, screenNum),
1008                                             bg, depth),
1009                 XmNarmPixmap,
1010                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1011                                             (char *)dblLeftArrow_bits,
1012                                             dblLeftArrow_width,
1013                                             dblLeftArrow_height,
1014                                             BlackPixel(display, screenNum),
1015                                             arm, depth),
1016                 XmNlabelInsensitivePixmap,
1017                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1018                                             (char *)dblLeftArrowDis_bits,
1019                                             dblLeftArrowDis_width,
1020                                             dblLeftArrowDis_height,
1021                                             BlackPixel(display, screenNum),
1022                                             bg, depth),
1023                 NULL);
1024   XtVaSetValues(prevPageBtn, XmNlabelType, XmPIXMAP,
1025                 XmNlabelPixmap,
1026                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1027                                             (char *)leftArrow_bits,
1028                                             leftArrow_width,
1029                                             leftArrow_height,
1030                                             BlackPixel(display, screenNum),
1031                                             bg, depth),
1032                 XmNarmPixmap,
1033                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1034                                             (char *)leftArrow_bits,
1035                                             leftArrow_width,
1036                                             leftArrow_height,
1037                                             BlackPixel(display, screenNum),
1038                                             arm, depth),
1039                 XmNlabelInsensitivePixmap,
1040                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1041                                             (char *)leftArrowDis_bits,
1042                                             leftArrowDis_width,
1043                                             leftArrowDis_height,
1044                                             BlackPixel(display, screenNum),
1045                                             bg, depth),
1046                 NULL);
1047   XtVaSetValues(nextPageBtn, XmNlabelType, XmPIXMAP,
1048                 XmNlabelPixmap,
1049                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1050                                             (char *)rightArrow_bits,
1051                                             rightArrow_width,
1052                                             rightArrow_height,
1053                                             BlackPixel(display, screenNum),
1054                                             bg, depth),
1055                 XmNarmPixmap,
1056                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1057                                             (char *)rightArrow_bits,
1058                                             rightArrow_width,
1059                                             rightArrow_height,
1060                                             BlackPixel(display, screenNum),
1061                                             arm, depth),
1062                 XmNlabelInsensitivePixmap,
1063                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1064                                             (char *)rightArrowDis_bits,
1065                                             rightArrowDis_width,
1066                                             rightArrowDis_height,
1067                                             BlackPixel(display, screenNum),
1068                                             bg, depth),
1069                 NULL);
1070   XtVaSetValues(nextTenPageBtn, XmNlabelType, XmPIXMAP,
1071                 XmNlabelPixmap,
1072                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1073                                             (char *)dblRightArrow_bits,
1074                                             dblRightArrow_width,
1075                                             dblRightArrow_height,
1076                                             BlackPixel(display, screenNum),
1077                                             bg, depth),
1078                 XmNarmPixmap,
1079                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1080                                             (char *)dblRightArrow_bits,
1081                                             dblRightArrow_width,
1082                                             dblRightArrow_height,
1083                                             BlackPixel(display, screenNum),
1084                                             arm, depth),
1085                 XmNlabelInsensitivePixmap,
1086                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1087                                             (char *)dblRightArrowDis_bits,
1088                                             dblRightArrowDis_width,
1089                                             dblRightArrowDis_height,
1090                                             BlackPixel(display, screenNum),
1091                                             bg, depth),
1092                 NULL);
1093   XtVaSetValues(forwardBtn, XmNlabelType, XmPIXMAP,
1094                 XmNlabelPixmap,
1095                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1096                                             (char *)forwardArrow_bits,
1097                                             forwardArrow_width,
1098                                             forwardArrow_height,
1099                                             BlackPixel(display, screenNum),
1100                                             bg, depth),
1101                 XmNarmPixmap,
1102                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1103                                             (char *)forwardArrow_bits,
1104                                             forwardArrow_width,
1105                                             forwardArrow_height,
1106                                             BlackPixel(display, screenNum),
1107                                             arm, depth),
1108                 XmNlabelInsensitivePixmap,
1109                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1110                                             (char *)forwardArrowDis_bits,
1111                                             forwardArrowDis_width,
1112                                             forwardArrowDis_height,
1113                                             BlackPixel(display, screenNum),
1114                                             bg, depth),
1115                 NULL);
1116   XtVaSetValues(findBtn, XmNlabelType, XmPIXMAP,
1117                 XmNlabelPixmap,
1118                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1119                                             (char *)find_bits,
1120                                             find_width,
1121                                             find_height,
1122                                             BlackPixel(display, screenNum),
1123                                             bg, depth),
1124                 XmNarmPixmap,
1125                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1126                                             (char *)find_bits,
1127                                             find_width,
1128                                             find_height,
1129                                             BlackPixel(display, screenNum),
1130                                             arm, depth),
1131                 XmNlabelInsensitivePixmap,
1132                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1133                                             (char *)findDis_bits,
1134                                             findDis_width,
1135                                             findDis_height,
1136                                             BlackPixel(display, screenNum),
1137                                             bg, depth),
1138                 NULL);
1139   XtVaSetValues(printBtn, XmNlabelType, XmPIXMAP,
1140                 XmNlabelPixmap,
1141                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1142                                             (char *)print_bits,
1143                                             print_width,
1144                                             print_height,
1145                                             BlackPixel(display, screenNum),
1146                                             bg, depth),
1147                 XmNarmPixmap,
1148                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1149                                             (char *)print_bits,
1150                                             print_width,
1151                                             print_height,
1152                                             BlackPixel(display, screenNum),
1153                                             arm, depth),
1154                 XmNlabelInsensitivePixmap,
1155                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1156                                             (char *)printDis_bits,
1157                                             printDis_width,
1158                                             printDis_height,
1159                                             BlackPixel(display, screenNum),
1160                                             bg, depth),
1161                 NULL);
1162   XtVaSetValues(aboutBtn, XmNlabelType, XmPIXMAP,
1163                 XmNlabelPixmap,
1164                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1165                                             (char *)about_bits,
1166                                             about_width,
1167                                             about_height,
1168                                             BlackPixel(display, screenNum),
1169                                             bg, depth),
1170                 XmNarmPixmap,
1171                 XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
1172                                             (char *)about_bits,
1173                                             about_width,
1174                                             about_height,
1175                                             BlackPixel(display, screenNum),
1176                                             arm, depth),
1177                 NULL);
1178 }
1179
1180 void XPDFViewer::closeWindow() {
1181   XtPopdown(win);
1182   XtDestroyWidget(win);
1183 }
1184
1185 Widget XPDFViewer::getZoomMenuBtn(int z) {
1186   if (z >= minZoom && z <= maxZoom) {
1187     return zoomMenuBtns[z - minZoom];
1188   }
1189   if (z == zoomPage) {
1190     return zoomMenuBtns[maxZoom - minZoom + 1];
1191   }
1192   if (z == zoomWidth) {
1193     return zoomMenuBtns[maxZoom - minZoom + 2];
1194   }
1195   return zoomMenuBtns[0];
1196 }
1197
1198 void XPDFViewer::prevPageCbk(Widget widget, XtPointer ptr,
1199                              XtPointer callData) {
1200   XPDFViewer *viewer = (XPDFViewer *)ptr;
1201
1202   viewer->core->gotoPrevPage(1, gTrue, gFalse);
1203   viewer->core->takeFocus();
1204 }
1205
1206 void XPDFViewer::prevTenPageCbk(Widget widget, XtPointer ptr,
1207                                 XtPointer callData) {
1208   XPDFViewer *viewer = (XPDFViewer *)ptr;
1209
1210   viewer->core->gotoPrevPage(10, gTrue, gFalse);
1211   viewer->core->takeFocus();
1212 }
1213
1214 void XPDFViewer::nextPageCbk(Widget widget, XtPointer ptr,
1215                              XtPointer callData) {
1216   XPDFViewer *viewer = (XPDFViewer *)ptr;
1217
1218   viewer->core->gotoNextPage(1, gTrue);
1219   viewer->core->takeFocus();
1220 }
1221
1222 void XPDFViewer::nextTenPageCbk(Widget widget, XtPointer ptr,
1223                                 XtPointer callData) {
1224   XPDFViewer *viewer = (XPDFViewer *)ptr;
1225
1226   viewer->core->gotoNextPage(10, gTrue);
1227   viewer->core->takeFocus();
1228 }
1229
1230 void XPDFViewer::backCbk(Widget widget, XtPointer ptr,
1231                          XtPointer callData) {
1232   XPDFViewer *viewer = (XPDFViewer *)ptr;
1233
1234   viewer->core->goBackward();
1235   viewer->core->takeFocus();
1236 }
1237
1238 void XPDFViewer::forwardCbk(Widget widget, XtPointer ptr,
1239                             XtPointer callData) {
1240   XPDFViewer *viewer = (XPDFViewer *)ptr;
1241
1242   viewer->core->goForward();
1243   viewer->core->takeFocus();
1244 }
1245
1246 void XPDFViewer::zoomMenuCbk(Widget widget, XtPointer ptr,
1247                              XtPointer callData) {
1248   XPDFViewer *viewer = (XPDFViewer *)ptr;
1249   XtPointer userData;
1250
1251   XtVaGetValues(widget, XmNuserData, &userData, NULL);
1252   if ((int)userData != viewer->core->getZoom()) {
1253     viewer->displayPage(viewer->core->getPageNum(), (int)userData,
1254                         viewer->core->getRotate(), gTrue, gFalse);
1255   }
1256   viewer->core->takeFocus();
1257 }
1258
1259 void XPDFViewer::findCbk(Widget widget, XtPointer ptr,
1260                          XtPointer callData) {
1261   XPDFViewer *viewer = (XPDFViewer *)ptr;
1262
1263   if (!viewer->core->getDoc()) {
1264     return;
1265   }
1266   XtManageChild(viewer->findDialog);
1267 }
1268
1269 void XPDFViewer::printCbk(Widget widget, XtPointer ptr,
1270                           XtPointer callData) {
1271   XPDFViewer *viewer = (XPDFViewer *)ptr;
1272
1273   if (!viewer->core->getDoc()) {
1274     return;
1275   }
1276   XtManageChild(viewer->printDialog);
1277 }
1278
1279 void XPDFViewer::aboutCbk(Widget widget, XtPointer ptr,
1280                           XtPointer callData) {
1281   XPDFViewer *viewer = (XPDFViewer *)ptr;
1282
1283   XtManageChild(viewer->aboutDialog);
1284 }
1285
1286 void XPDFViewer::quitCbk(Widget widget, XtPointer ptr,
1287                          XtPointer callData) {
1288   XPDFViewer *viewer = (XPDFViewer *)ptr;
1289
1290   viewer->app->quit();
1291 }
1292
1293 void XPDFViewer::openCbk(Widget widget, XtPointer ptr,
1294                          XtPointer callData) {
1295   XPDFViewer *viewer = (XPDFViewer *)ptr;
1296
1297   viewer->mapOpenDialog(gFalse);
1298 }
1299
1300 void XPDFViewer::openInNewWindowCbk(Widget widget, XtPointer ptr,
1301                                     XtPointer callData) {
1302   XPDFViewer *viewer = (XPDFViewer *)ptr;
1303
1304   viewer->mapOpenDialog(gTrue);
1305 }
1306
1307 void XPDFViewer::reloadCbk(Widget widget, XtPointer ptr,
1308                          XtPointer callData) {
1309   XPDFViewer *viewer = (XPDFViewer *)ptr;
1310
1311   viewer->reloadFile();
1312 }
1313
1314 void XPDFViewer::saveAsCbk(Widget widget, XtPointer ptr,
1315                            XtPointer callData) {
1316   XPDFViewer *viewer = (XPDFViewer *)ptr;
1317
1318   if (!viewer->core->getDoc()) {
1319     return;
1320   }
1321   viewer->mapSaveAsDialog();
1322 }
1323
1324 void XPDFViewer::rotateCCWCbk(Widget widget, XtPointer ptr,
1325                               XtPointer callData) {
1326   XPDFViewer *viewer = (XPDFViewer *)ptr;
1327   int r;
1328
1329   r = viewer->core->getRotate();
1330   r = (r == 0) ? 270 : r - 90;
1331   viewer->displayPage(viewer->core->getPageNum(), viewer->core->getZoom(),
1332                       r, gTrue, gFalse);
1333 }
1334
1335 void XPDFViewer::rotateCWCbk(Widget widget, XtPointer ptr,
1336                              XtPointer callData) {
1337   XPDFViewer *viewer = (XPDFViewer *)ptr;
1338   int r;
1339
1340   r = viewer->core->getRotate();
1341   r = (r == 270) ? 0 : r + 90;
1342   viewer->displayPage(viewer->core->getPageNum(), viewer->core->getZoom(),
1343                       r, gTrue, gFalse);
1344 }
1345
1346 void XPDFViewer::closeCbk(Widget widget, XtPointer ptr,
1347                           XtPointer callData) {
1348   XPDFViewer *viewer = (XPDFViewer *)ptr;
1349
1350   viewer->app->close(viewer, gFalse);
1351 }
1352
1353 void XPDFViewer::closeMsgCbk(Widget widget, XtPointer ptr,
1354                              XtPointer callData) {
1355   XPDFViewer *viewer = (XPDFViewer *)ptr;
1356
1357   viewer->app->close(viewer, gTrue);
1358 }
1359
1360 void XPDFViewer::pageNumCbk(Widget widget, XtPointer ptr,
1361                             XtPointer callData) {
1362   XPDFViewer *viewer = (XPDFViewer *)ptr;
1363   char *s, *p;
1364   int pg;
1365   char buf[20];
1366
1367   if (!viewer->core->getDoc()) {
1368     goto err;
1369   }
1370   s = XmTextFieldGetString(viewer->pageNumText);
1371   for (p = s; *p; ++p) {
1372     if (!isdigit(*p)) {
1373       goto err;
1374     }
1375   }
1376   pg = atoi(s);
1377   if (pg < 1 || pg > viewer->core->getDoc()->getNumPages()) {
1378     goto err;
1379   }
1380   viewer->displayPage(pg, viewer->core->getZoom(),
1381                       viewer->core->getRotate(), gFalse, gTrue);
1382   viewer->core->takeFocus();
1383   return;
1384
1385  err:
1386   XBell(viewer->display, 0);
1387   sprintf(buf, "%d", viewer->core->getPageNum());
1388   XmTextFieldSetString(viewer->pageNumText, buf);
1389 }
1390
1391 void XPDFViewer::updateCbk(void *data, GString *fileName,
1392                            int pageNum, int numPages, char *linkLabel) {
1393   XPDFViewer *viewer = (XPDFViewer *)data;
1394   GString *title;
1395   char buf[20];
1396   XmString s;
1397
1398   if (fileName) {
1399     if (!(title = viewer->app->getTitle())) {
1400       title = (new GString(xpdfAppName))->append(": ")->append(fileName);
1401     }
1402     XtVaSetValues(viewer->win, XmNtitle, title->getCString(),
1403                   XmNiconName, title->getCString(), NULL);
1404     if (!viewer->app->getTitle()) {
1405       delete title;
1406     }
1407 #ifndef DISABLE_OUTLINE
1408     if (!viewer->app->getFullScreen()) {
1409       viewer->setupOutline();
1410     }
1411 #endif
1412     viewer->setupPrintDialog();
1413   }
1414
1415   if (pageNum >= 0) {
1416     s = XmStringCreateLocalized("");
1417     XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
1418     XmStringFree(s);
1419     sprintf(buf, "%d", pageNum);
1420     XmTextFieldSetString(viewer->pageNumText, buf);
1421     XtVaSetValues(viewer->prevTenPageBtn, XmNsensitive,
1422                   pageNum > 1, NULL);
1423     XtVaSetValues(viewer->prevPageBtn, XmNsensitive,
1424                   pageNum > 1, NULL);
1425     XtVaSetValues(viewer->nextTenPageBtn, XmNsensitive,
1426                   pageNum < viewer->core->getDoc()->getNumPages(), NULL);
1427     XtVaSetValues(viewer->nextPageBtn, XmNsensitive,
1428                   pageNum < viewer->core->getDoc()->getNumPages(), NULL);
1429     XtVaSetValues(viewer->backBtn, XmNsensitive,
1430                   viewer->core->canGoBack(), NULL);
1431     XtVaSetValues(viewer->forwardBtn, XmNsensitive,
1432                   viewer->core->canGoForward(), NULL);
1433   }
1434
1435   if (numPages >= 0) {
1436     sprintf(buf, " of %d", numPages);
1437     s = XmStringCreateLocalized(buf);
1438     XtVaSetValues(viewer->pageCountLabel, XmNlabelString, s, NULL);
1439     XmStringFree(s);
1440   }
1441
1442   if (linkLabel) {
1443     s = XmStringCreateLocalized(linkLabel);
1444     XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
1445     XmStringFree(s);
1446   }
1447 }
1448
1449
1450 //------------------------------------------------------------------------
1451 // GUI code: outline
1452 //------------------------------------------------------------------------
1453
1454 #ifndef DISABLE_OUTLINE
1455
1456 void XPDFViewer::setupOutline() {
1457   GList *items;
1458   UnicodeMap *uMap;
1459   GString *enc;
1460   int i;
1461
1462   // unmanage and destroy the old labels
1463   if (outlineLabels) {
1464     XtUnmanageChildren(outlineLabels, outlineLabelsLength);
1465     for (i = 0; i < outlineLabelsLength; ++i) {
1466       XtDestroyWidget(outlineLabels[i]);
1467     }
1468     gfree(outlineLabels);
1469     outlineLabels = NULL;
1470     outlineLabelsLength = outlineLabelsSize = 0;
1471   }
1472
1473   // create the new labels
1474   items = core->getDoc()->getOutline()->getItems();
1475   if (items && items->getLength() > 0) {
1476     enc = new GString("Latin1");
1477     uMap = globalParams->getUnicodeMap(enc);
1478     delete enc;
1479     setupOutlineItems(items, NULL, uMap);
1480     uMap->decRefCnt();
1481   }
1482
1483   // manage the new labels
1484   XtManageChildren(outlineLabels, outlineLabelsLength);
1485 }
1486
1487 void XPDFViewer::setupOutlineItems(GList *items, Widget parent,
1488                                    UnicodeMap *uMap) {
1489   OutlineItem *item;
1490   GList *kids;
1491   Widget label;
1492   Arg args[20];
1493   GString *title;
1494   char buf[8];
1495   XmString s;
1496   int i, j, n;
1497
1498   for (i = 0; i < items->getLength(); ++i) {
1499     item = (OutlineItem *)items->get(i);
1500     title = new GString();
1501     for (j = 0; j < item->getTitleLength(); ++j) {
1502       n = uMap->mapUnicode(item->getTitle()[j], buf, sizeof(buf));
1503       title->append(buf, n);
1504     }
1505     n = 0;
1506     XtSetArg(args[n], XPDFNentryPosition, i); ++n;
1507     if (parent) {
1508       XtSetArg(args[n], XPDFNentryParent, parent); ++n;
1509     }
1510     XtSetArg(args[n], XPDFNentryExpanded, item->isOpen()); ++n;
1511     s = XmStringCreateLocalized(title->getCString());
1512     delete title;
1513     XtSetArg(args[n], XmNlabelString, s); ++n;
1514     XtSetArg(args[n], XmNuserData, item); ++n;
1515     XtSetArg(args[n], XmNmarginWidth, 0); ++n;
1516     XtSetArg(args[n], XmNmarginHeight, 2); ++n;
1517     XtSetArg(args[n], XmNshadowThickness, 0); ++n;
1518     XtSetArg(args[n], XmNforeground,
1519              app->getReverseVideo() ? WhitePixel(display, screenNum)
1520                                     : BlackPixel(display, screenNum)); ++n;
1521     XtSetArg(args[n], XmNbackground, app->getPaperColor()); ++n;
1522     label = XmCreateLabelGadget(outlineTree, "label", args, n);
1523     XmStringFree(s);
1524     if (outlineLabelsLength == outlineLabelsSize) {
1525       outlineLabelsSize += 64;
1526       outlineLabels = (Widget *)grealloc(outlineLabels,
1527                                          outlineLabelsSize * sizeof(Widget *));
1528     }
1529     outlineLabels[outlineLabelsLength++] = label;
1530     item->open();
1531     if ((kids = item->getKids())) {
1532       setupOutlineItems(kids, label, uMap);
1533     }
1534   }
1535 }
1536
1537 void XPDFViewer::outlineSelectCbk(Widget widget, XtPointer ptr,
1538                                   XtPointer callData) {
1539   XPDFViewer *viewer = (XPDFViewer *)ptr;
1540   XPDFTreeSelectCallbackStruct *data =
1541       (XPDFTreeSelectCallbackStruct *)callData;
1542   OutlineItem *item;
1543
1544   XtVaGetValues(data->selectedItem, XmNuserData, &item, NULL);
1545   if (item) {
1546     viewer->core->doAction(item->getAction());
1547   }
1548   viewer->core->takeFocus();
1549 }
1550
1551 #endif // !DISABLE_OUTLINE
1552
1553 //------------------------------------------------------------------------
1554 // GUI code: "about" dialog
1555 //------------------------------------------------------------------------
1556
1557 void XPDFViewer::initAboutDialog() {
1558   Widget scrolledWin, col, label, sep, closeBtn;
1559   Arg args[20];
1560   int n, i;
1561   XmString s;
1562   char buf[20];
1563
1564   //----- dialog
1565   n = 0;
1566   s = XmStringCreateLocalized(xpdfAppName ": About");
1567   XtSetArg(args[n], XmNdialogTitle, s); ++n;
1568   XtSetArg(args[n], XmNwidth, 450); ++n;
1569   XtSetArg(args[n], XmNheight, 300); ++n;
1570   aboutDialog = XmCreateFormDialog(win, "aboutDialog", args, n);
1571   XmStringFree(s);
1572
1573   //----- "close" button
1574   n = 0;
1575   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1576   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1577   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1578   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
1579   closeBtn = XmCreatePushButton(aboutDialog, "Close", args, n);
1580   XtManageChild(closeBtn);
1581   n = 0;
1582   XtSetArg(args[n], XmNdefaultButton, closeBtn); ++n;
1583   XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
1584   XtSetValues(aboutDialog, args, n);
1585
1586   //----- scrolled window and RowColumn
1587   n = 0;
1588   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1589   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
1590   XtSetArg(args[n], XmNbottomWidget, closeBtn); ++n;
1591   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1592   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1593   XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
1594   scrolledWin = XmCreateScrolledWindow(aboutDialog, "scrolledWin", args, n);
1595   XtManageChild(scrolledWin);
1596   n = 0;
1597   XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
1598   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
1599   col = XmCreateRowColumn(scrolledWin, "col", args, n);
1600   XtManageChild(col);
1601
1602   //----- fonts
1603   aboutBigFont = XmFontListAppendEntry(NULL,
1604       XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONT,
1605           XLoadQueryFont(display,
1606               "-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1")));
1607   aboutVersionFont = XmFontListAppendEntry(NULL,
1608       XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONT,
1609           XLoadQueryFont(display,
1610               "-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1")));
1611   aboutFixedFont = XmFontListAppendEntry(NULL,
1612       XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONT,
1613           XLoadQueryFont(display,
1614               "-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1")));
1615
1616   //----- heading
1617   n = 0;
1618   s = XmStringCreateLocalized("Xpdf");
1619   XtSetArg(args[n], XmNlabelString, s); ++n;
1620   XtSetArg(args[n], XmNfontList, aboutBigFont); ++n;
1621   label = XmCreateLabel(col, "h0", args, n);
1622   XmStringFree(s);
1623   XtManageChild(label);
1624   n = 0;
1625   s = XmStringCreateLocalized("Version " xpdfVersion);
1626   XtSetArg(args[n], XmNlabelString, s); ++n;
1627   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1628   label = XmCreateLabel(col, "h1", args, n);
1629   XmStringFree(s);
1630   XtManageChild(label);
1631   n = 0;
1632   s = XmStringCreateLocalized(xpdfCopyright);
1633   XtSetArg(args[n], XmNlabelString, s); ++n;
1634   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1635   label = XmCreateLabel(col, "h2", args, n);
1636   XmStringFree(s);
1637   XtManageChild(label);
1638   n = 0;
1639   s = XmStringCreateLocalized(" ");
1640   XtSetArg(args[n], XmNlabelString, s); ++n;
1641   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1642   label = XmCreateLabel(col, "h3", args, n);
1643   XmStringFree(s);
1644   XtManageChild(label);
1645   n = 0;
1646   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1647   sep = XmCreateSeparator(col, "sep", args, n);
1648   XtManageChild(sep);
1649   n = 0;
1650   s = XmStringCreateLocalized(" ");
1651   XtSetArg(args[n], XmNlabelString, s); ++n;
1652   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1653   label = XmCreateLabel(col, "h4", args, n);
1654   XmStringFree(s);
1655   XtManageChild(label);
1656   n = 0;
1657
1658   //----- text
1659   for (i = 0; aboutWinText[i]; ++i) {
1660     n = 0;
1661     s = XmStringCreateLocalized(aboutWinText[i]);
1662     XtSetArg(args[n], XmNlabelString, s); ++n;
1663     XtSetArg(args[n], XmNfontList, aboutFixedFont); ++n;
1664     sprintf(buf, "t%d", i);
1665     label = XmCreateLabel(col, buf, args, n);
1666     XtManageChild(label);
1667     XmStringFree(s);
1668   }
1669 }
1670
1671 //------------------------------------------------------------------------
1672 // GUI code: "open" dialog
1673 //------------------------------------------------------------------------
1674
1675 void XPDFViewer::initOpenDialog() {
1676   Arg args[20];
1677   int n;
1678   XmString s1, s2, s3;
1679
1680   n = 0;
1681   s1 = XmStringCreateLocalized("Open");
1682   XtSetArg(args[n], XmNokLabelString, s1); ++n;
1683   s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
1684   XtSetArg(args[n], XmNpattern, s2); ++n;
1685   s3 = XmStringCreateLocalized(xpdfAppName ": Open");
1686   XtSetArg(args[n], XmNdialogTitle, s3); ++n;
1687   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
1688   XtSetArg(args[n], XmNautoUnmanage, True); ++n;
1689   openDialog = XmCreateFileSelectionDialog(win, "openDialog", args, n);
1690   XmStringFree(s1);
1691   XmStringFree(s2);
1692   XmStringFree(s3);
1693   XtUnmanageChild(XmFileSelectionBoxGetChild(openDialog,
1694                                              XmDIALOG_HELP_BUTTON));
1695   XtAddCallback(openDialog, XmNokCallback,
1696                 &openOkCbk, (XtPointer)this);
1697 }
1698
1699 void XPDFViewer::setOpenDialogDir(char *dir) {
1700   XmString s;
1701
1702   s = XmStringCreateLocalized(dir);
1703   XtVaSetValues(openDialog, XmNdirectory, s, NULL);
1704   XmStringFree(s);
1705 }
1706
1707 void XPDFViewer::mapOpenDialog(GBool openInNewWindowA) {
1708   openInNewWindow = openInNewWindowA;
1709   XmFileSelectionDoSearch(openDialog, NULL);
1710   XtManageChild(openDialog);
1711 }
1712
1713 void XPDFViewer::openOkCbk(Widget widget, XtPointer ptr,
1714                            XtPointer callData) {
1715   XPDFViewer *viewer = (XPDFViewer *)ptr;
1716   XmFileSelectionBoxCallbackStruct *data =
1717     (XmFileSelectionBoxCallbackStruct *)callData;
1718   char *fileName;
1719   XmStringContext context;
1720   XmStringCharSet charSet;
1721   XmStringDirection dir;
1722   Boolean sep;
1723   GString *fileNameStr;
1724
1725   XmStringInitContext(&context, data->value);
1726   if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
1727     fileNameStr = new GString(fileName);
1728     if (viewer->openInNewWindow) {
1729       viewer->app->open(fileNameStr);
1730     } else {
1731       if (viewer->loadFile(fileNameStr)) {
1732         viewer->displayPage(1, viewer->core->getZoom(),
1733                             viewer->core->getRotate(), gTrue, gTrue);
1734       }
1735     }
1736     delete fileNameStr;
1737     XtFree(charSet);
1738     XtFree(fileName);
1739   }
1740   XmStringFreeContext(context);
1741 }
1742
1743 //------------------------------------------------------------------------
1744 // GUI code: "find" dialog
1745 //------------------------------------------------------------------------
1746
1747 void XPDFViewer::initFindDialog() {
1748   Widget row1, label, okBtn, closeBtn;
1749   Arg args[20];
1750   int n;
1751   XmString s;
1752
1753   //----- dialog
1754   n = 0;
1755   s = XmStringCreateLocalized(xpdfAppName ": Find");
1756   XtSetArg(args[n], XmNdialogTitle, s); ++n;
1757   XtSetArg(args[n], XmNnavigationType, XmNONE); ++n;
1758   XtSetArg(args[n], XmNautoUnmanage, False); ++n;
1759   findDialog = XmCreateFormDialog(win, "findDialog", args, n);
1760   XmStringFree(s);
1761
1762   //----- top row: search string entry
1763   n = 0;
1764   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1765   XtSetArg(args[n], XmNtopOffset, 4); ++n;
1766   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1767   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1768   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1769   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
1770   row1 = XmCreateRowColumn(findDialog, "row1", args, n);
1771   XtManageChild(row1);
1772   n = 0;
1773   s = XmStringCreateLocalized("Find text: ");
1774   XtSetArg(args[n], XmNlabelString, s); ++n;
1775   label = XmCreateLabel(row1, "label", args, n);
1776   XmStringFree(s);
1777   XtManageChild(label);
1778   n = 0;
1779   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
1780   findText = XmCreateTextField(row1, "text", args, n);
1781   XtManageChild(findText);
1782
1783   //----- "find" and "close" buttons
1784   n = 0;
1785   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1786   XtSetArg(args[n], XmNtopWidget, row1); ++n;
1787   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1788   XtSetArg(args[n], XmNleftOffset, 4); ++n;
1789   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1790   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
1791   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
1792   okBtn = XmCreatePushButton(findDialog, "Find", args, n);
1793   XtManageChild(okBtn);
1794   XtAddCallback(okBtn, XmNactivateCallback,
1795                 &findFindCbk, (XtPointer)this);
1796   n = 0;
1797   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1798   XtSetArg(args[n], XmNtopWidget, row1); ++n;
1799   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1800   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1801   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1802   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
1803   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
1804   closeBtn = XmCreatePushButton(findDialog, "Close", args, n);
1805   XtManageChild(closeBtn);
1806   XtAddCallback(closeBtn, XmNactivateCallback,
1807                 &findCloseCbk, (XtPointer)this);
1808   n = 0;
1809   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
1810   XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
1811   XtSetArg(args[n], XmNinitialFocus, findText); ++n;
1812   XtSetValues(findDialog, args, n);
1813 }
1814
1815 void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
1816                              XtPointer callData) {
1817   XPDFViewer *viewer = (XPDFViewer *)ptr;
1818
1819   viewer->core->find(XmTextFieldGetString(viewer->findText));
1820 }
1821
1822 void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr,
1823                               XtPointer callData) {
1824   XPDFViewer *viewer = (XPDFViewer *)ptr;
1825
1826   XtUnmanageChild(viewer->findDialog);
1827 }
1828
1829 //------------------------------------------------------------------------
1830 // GUI code: "save as" dialog
1831 //------------------------------------------------------------------------
1832
1833 void XPDFViewer::initSaveAsDialog() {
1834   Arg args[20];
1835   int n;
1836   XmString s1, s2, s3;
1837
1838   n = 0;
1839   s1 = XmStringCreateLocalized("Save");
1840   XtSetArg(args[n], XmNokLabelString, s1); ++n;
1841   s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
1842   XtSetArg(args[n], XmNpattern, s2); ++n;
1843   s3 = XmStringCreateLocalized(xpdfAppName ": Save as");
1844   XtSetArg(args[n], XmNdialogTitle, s3); ++n;
1845   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
1846   XtSetArg(args[n], XmNautoUnmanage, True); ++n;
1847   saveAsDialog = XmCreateFileSelectionDialog(win, "saveAsDialog", args, n);
1848   XmStringFree(s1);
1849   XmStringFree(s2);
1850   XmStringFree(s3);
1851   XtUnmanageChild(XmFileSelectionBoxGetChild(saveAsDialog,
1852                                              XmDIALOG_HELP_BUTTON));
1853   XtAddCallback(saveAsDialog, XmNokCallback,
1854                 &saveAsOkCbk, (XtPointer)this);
1855 }
1856
1857 void XPDFViewer::setSaveAsDialogDir(char *dir) {
1858   XmString s;
1859
1860   s = XmStringCreateLocalized(dir);
1861   XtVaSetValues(saveAsDialog, XmNdirectory, s, NULL);
1862   XmStringFree(s);
1863 }
1864
1865 void XPDFViewer::mapSaveAsDialog() {
1866   XmFileSelectionDoSearch(saveAsDialog, NULL);
1867   XtManageChild(saveAsDialog);
1868 }
1869
1870 void XPDFViewer::saveAsOkCbk(Widget widget, XtPointer ptr,
1871                              XtPointer callData) {
1872   XPDFViewer *viewer = (XPDFViewer *)ptr;
1873   XmFileSelectionBoxCallbackStruct *data =
1874     (XmFileSelectionBoxCallbackStruct *)callData;
1875   char *fileName;
1876   GString *fileNameStr;
1877   XmStringContext context;
1878   XmStringCharSet charSet;
1879   XmStringDirection dir;
1880   Boolean sep;
1881
1882   XmStringInitContext(&context, data->value);
1883   if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
1884     fileNameStr = new GString(fileName);
1885     viewer->core->getDoc()->saveAs(fileNameStr);
1886     delete fileNameStr;
1887     XtFree(charSet);
1888     XtFree(fileName);
1889   }
1890   XmStringFreeContext(context);
1891 }
1892
1893 //------------------------------------------------------------------------
1894 // GUI code: "print" dialog
1895 //------------------------------------------------------------------------
1896
1897 void XPDFViewer::initPrintDialog() {
1898   Widget sep1, sep2, row, label1, label2, okBtn, cancelBtn;
1899   Arg args[20];
1900   int n;
1901   XmString s;
1902
1903   //----- dialog
1904   n = 0;
1905   s = XmStringCreateLocalized(xpdfAppName ": Print");
1906   XtSetArg(args[n], XmNdialogTitle, s); ++n;
1907   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
1908   printDialog = XmCreateFormDialog(win, "printDialog", args, n);
1909   XmStringFree(s);
1910
1911   //----- "print with command"
1912   n = 0;
1913   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1914   XtSetArg(args[n], XmNtopOffset, 4); ++n;
1915   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1916   XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
1917   XtSetArg(args[n], XmNset, XmSET); ++n;
1918   s = XmStringCreateLocalized("Print with command:");
1919   XtSetArg(args[n], XmNlabelString, s); ++n;
1920   printWithCmdBtn = XmCreateToggleButton(printDialog, "printWithCmd", args, n);
1921   XmStringFree(s);
1922   XtManageChild(printWithCmdBtn);
1923   XtAddCallback(printWithCmdBtn, XmNvalueChangedCallback,
1924                 &printWithCmdBtnCbk, (XtPointer)this);
1925   n = 0;
1926   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1927   XtSetArg(args[n], XmNtopWidget, printWithCmdBtn); ++n;
1928   XtSetArg(args[n], XmNtopOffset, 2); ++n;
1929   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1930   XtSetArg(args[n], XmNleftOffset, 16); ++n;
1931   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1932   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1933   XtSetArg(args[n], XmNcolumns, 40); ++n;
1934   printCmdText = XmCreateTextField(printDialog, "printCmd", args, n);
1935   XtManageChild(printCmdText);
1936
1937   //----- "print with command"
1938   n = 0;
1939   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1940   XtSetArg(args[n], XmNtopWidget, printCmdText); ++n;
1941   XtSetArg(args[n], XmNtopOffset, 4); ++n;
1942   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1943   XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
1944   XtSetArg(args[n], XmNset, XmUNSET); ++n;
1945   s = XmStringCreateLocalized("Print to file:");
1946   XtSetArg(args[n], XmNlabelString, s); ++n;
1947   printToFileBtn = XmCreateToggleButton(printDialog, "printToFile", args, n);
1948   XmStringFree(s);
1949   XtManageChild(printToFileBtn);
1950   XtAddCallback(printToFileBtn, XmNvalueChangedCallback,
1951                 &printToFileBtnCbk, (XtPointer)this);
1952   n = 0;
1953   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1954   XtSetArg(args[n], XmNtopWidget, printToFileBtn); ++n;
1955   XtSetArg(args[n], XmNtopOffset, 2); ++n;
1956   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1957   XtSetArg(args[n], XmNleftOffset, 16); ++n;
1958   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1959   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1960   XtSetArg(args[n], XmNcolumns, 40); ++n;
1961   XtSetArg(args[n], XmNsensitive, False); ++n;
1962   printFileText = XmCreateTextField(printDialog, "printFile", args, n);
1963   XtManageChild(printFileText);
1964
1965   //----- separator
1966   n = 0;
1967   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1968   XtSetArg(args[n], XmNtopWidget, printFileText); ++n;
1969   XtSetArg(args[n], XmNtopOffset, 8); ++n;
1970   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1971   XtSetArg(args[n], XmNleftOffset, 8); ++n;
1972   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1973   XtSetArg(args[n], XmNrightOffset, 8); ++n;
1974   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1975   sep1 = XmCreateSeparator(printDialog, "sep1", args, n);
1976   XtManageChild(sep1);
1977
1978   //----- page range
1979   n = 0;
1980   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1981   XtSetArg(args[n], XmNtopWidget, sep1); ++n;
1982   XtSetArg(args[n], XmNtopOffset, 8); ++n;
1983   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1984   XtSetArg(args[n], XmNleftOffset, 4); ++n;
1985   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1986   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
1987   row = XmCreateRowColumn(printDialog, "row", args, n);
1988   XtManageChild(row);
1989   n = 0;
1990   s = XmStringCreateLocalized("Pages:");
1991   XtSetArg(args[n], XmNlabelString, s); ++n;
1992   label1 = XmCreateLabel(row, "label1", args, n);
1993   XmStringFree(s);
1994   XtManageChild(label1);
1995   n = 0;
1996   XtSetArg(args[n], XmNcolumns, 5); ++n;
1997   printFirstPage = XmCreateTextField(row, "printFirstPage", args, n);
1998   XtManageChild(printFirstPage);
1999   n = 0;
2000   s = XmStringCreateLocalized("to");
2001   XtSetArg(args[n], XmNlabelString, s); ++n;
2002   label2 = XmCreateLabel(row, "label2", args, n);
2003   XmStringFree(s);
2004   XtManageChild(label2);
2005   n = 0;
2006   XtSetArg(args[n], XmNcolumns, 5); ++n;
2007   printLastPage = XmCreateTextField(row, "printLastPage", args, n);
2008   XtManageChild(printLastPage);
2009
2010   //----- separator
2011   n = 0;
2012   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2013   XtSetArg(args[n], XmNtopWidget, row); ++n;
2014   XtSetArg(args[n], XmNtopOffset, 8); ++n;
2015   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2016   XtSetArg(args[n], XmNleftOffset, 8); ++n;
2017   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2018   XtSetArg(args[n], XmNrightOffset, 8); ++n;
2019   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
2020   sep2 = XmCreateSeparator(printDialog, "sep2", args, n);
2021   XtManageChild(sep2);
2022
2023   //----- "print" and "cancel" buttons
2024   n = 0;
2025   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2026   XtSetArg(args[n], XmNtopWidget, sep2); ++n;
2027   XtSetArg(args[n], XmNtopOffset, 8); ++n;
2028   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2029   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2030   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2031   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2032   okBtn = XmCreatePushButton(printDialog, "Print", args, n);
2033   XtManageChild(okBtn);
2034   XtAddCallback(okBtn, XmNactivateCallback,
2035                 &printPrintCbk, (XtPointer)this);
2036   n = 0;
2037   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2038   XtSetArg(args[n], XmNtopWidget, sep2); ++n;
2039   XtSetArg(args[n], XmNtopOffset, 8); ++n;
2040   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2041   XtSetArg(args[n], XmNrightOffset, 4); ++n;
2042   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2043   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2044   cancelBtn = XmCreatePushButton(printDialog, "Cancel", args, n);
2045   XtManageChild(cancelBtn);
2046   n = 0;
2047   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
2048   XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
2049   XtSetValues(printDialog, args, n);
2050 }
2051
2052 void XPDFViewer::setupPrintDialog() {
2053   PDFDoc *doc;
2054   char buf[20];
2055   GString *pdfFileName, *psFileName;
2056   char *p;
2057
2058   doc = core->getDoc();
2059
2060   psFileName = globalParams->getPSFile();
2061   if (psFileName && psFileName->getChar(0) != '|') {
2062     XmTextFieldSetString(printFileText, psFileName->getCString());
2063   } else {
2064     pdfFileName = doc->getFileName();
2065     p = pdfFileName->getCString() + pdfFileName->getLength() - 4;
2066     if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
2067       psFileName = new GString(pdfFileName->getCString(),
2068                                pdfFileName->getLength() - 4);
2069     } else {
2070       psFileName = pdfFileName->copy();
2071     }
2072     psFileName->append(".ps");
2073     XmTextFieldSetString(printFileText, psFileName->getCString());
2074     delete psFileName;
2075   }
2076
2077   psFileName = globalParams->getPSFile();
2078   if (psFileName && psFileName->getChar(0) == '|') {
2079     XmTextFieldSetString(printCmdText,
2080                          psFileName->getCString() + 1);
2081   }
2082
2083   sprintf(buf, "%d", doc->getNumPages());
2084   XmTextFieldSetString(printFirstPage, "1");
2085   XmTextFieldSetString(printLastPage, buf);
2086 }
2087
2088 void XPDFViewer::printWithCmdBtnCbk(Widget widget, XtPointer ptr,
2089                                     XtPointer callData) {
2090   XPDFViewer *viewer = (XPDFViewer *)ptr;
2091   XmToggleButtonCallbackStruct *data =
2092       (XmToggleButtonCallbackStruct *)callData;
2093
2094   if (data->set != XmSET) {
2095     XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
2096   }
2097   XmToggleButtonSetState(viewer->printToFileBtn, False, False);
2098   XtVaSetValues(viewer->printCmdText, XmNsensitive, True, NULL);
2099   XtVaSetValues(viewer->printFileText, XmNsensitive, False, NULL);
2100 }
2101
2102 void XPDFViewer::printToFileBtnCbk(Widget widget, XtPointer ptr,
2103                                    XtPointer callData) {
2104   XPDFViewer *viewer = (XPDFViewer *)ptr;
2105   XmToggleButtonCallbackStruct *data =
2106       (XmToggleButtonCallbackStruct *)callData;
2107
2108   if (data->set != XmSET) {
2109     XmToggleButtonSetState(viewer->printToFileBtn, True, False);
2110   }
2111   XmToggleButtonSetState(viewer->printWithCmdBtn, False, False);
2112   XtVaSetValues(viewer->printFileText, XmNsensitive, True, NULL);
2113   XtVaSetValues(viewer->printCmdText, XmNsensitive, False, NULL);
2114 }
2115
2116 void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
2117                                XtPointer callData) {
2118   XPDFViewer *viewer = (XPDFViewer *)ptr;
2119   unsigned char withCmd;
2120   GString *psFileName;
2121   int firstPage, lastPage;
2122   PDFDoc *doc;
2123   PSOutputDev *psOut;
2124
2125   doc = viewer->core->getDoc();
2126   if (!doc->okToPrint()) {
2127     error(-1, "Printing this document is not allowed.");
2128     return;
2129   }
2130
2131   viewer->core->setBusyCursor(gTrue);
2132
2133   XtVaGetValues(viewer->printWithCmdBtn, XmNset, &withCmd, NULL);
2134   if (withCmd) {
2135     psFileName = new GString(XmTextFieldGetString(viewer->printCmdText));
2136     psFileName->insert(0, '|');
2137   } else {
2138     psFileName = new GString(XmTextFieldGetString(viewer->printFileText));
2139   }
2140
2141   firstPage = atoi(XmTextFieldGetString(viewer->printFirstPage));
2142   lastPage = atoi(XmTextFieldGetString(viewer->printLastPage));
2143   if (firstPage < 1) {
2144     firstPage = 1;
2145   } else if (firstPage > doc->getNumPages()) {
2146     firstPage = doc->getNumPages();
2147   }
2148   if (lastPage < firstPage) {
2149     lastPage = firstPage;
2150   } else if (lastPage > doc->getNumPages()) {
2151     lastPage = doc->getNumPages();
2152   }
2153
2154   psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
2155                           doc->getCatalog(), firstPage, lastPage,
2156                           psModePS);
2157   if (psOut->isOk()) {
2158     doc->displayPages(psOut, firstPage, lastPage, 72, 0, gFalse);
2159   }
2160   delete psOut;
2161   delete psFileName;
2162
2163   viewer->core->setBusyCursor(gFalse);
2164 }
2165
2166 //------------------------------------------------------------------------
2167 // GUI code: password dialog
2168 //------------------------------------------------------------------------
2169
2170 void XPDFViewer::initPasswordDialog() {
2171   Widget row, label, okBtn, cancelBtn;
2172   Arg args[20];
2173   int n;
2174   XmString s;
2175
2176   //----- dialog
2177   n = 0;
2178   s = XmStringCreateLocalized(xpdfAppName ": Password");
2179   XtSetArg(args[n], XmNdialogTitle, s); ++n;
2180   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
2181   passwordDialog = XmCreateFormDialog(win, "passwordDialog", args, n);
2182   XmStringFree(s);
2183
2184   //----- message
2185   n = 0;
2186   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
2187   XtSetArg(args[n], XmNtopOffset, 4); ++n;
2188   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2189   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2190   s = XmStringCreateLocalized(" ");
2191   XtSetArg(args[n], XmNlabelString, s); ++n;
2192   passwordMsg = XmCreateLabel(passwordDialog, "msg", args, n);
2193   XmStringFree(s);
2194   XtManageChild(passwordMsg);
2195
2196   //----- label and password entry
2197   n = 0;
2198   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2199   XtSetArg(args[n], XmNtopWidget, passwordMsg); ++n;
2200   XtSetArg(args[n], XmNtopOffset, 4); ++n;
2201   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2202   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2203   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2204   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2205   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
2206   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
2207   row = XmCreateRowColumn(passwordDialog, "row", args, n);
2208   XtManageChild(row);
2209   n = 0;
2210   s = XmStringCreateLocalized("Password: ");
2211   XtSetArg(args[n], XmNlabelString, s); ++n;
2212   label = XmCreateLabel(row, "label", args, n);
2213   XmStringFree(s);
2214   XtManageChild(label);
2215   n = 0;
2216   XtSetArg(args[n], XmNcolumns, 16); ++n;
2217   passwordText = XmCreateTextField(row, "text", args, n);
2218   XtManageChild(passwordText);
2219   XtAddCallback(passwordText, XmNmodifyVerifyCallback,
2220                 &passwordTextVerifyCbk, this);
2221
2222   //----- "Ok" and "Cancel" buttons
2223   n = 0;
2224   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2225   XtSetArg(args[n], XmNtopWidget, row); ++n;
2226   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2227   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2228   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2229   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2230   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
2231   okBtn = XmCreatePushButton(passwordDialog, "Ok", args, n);
2232   XtManageChild(okBtn);
2233   XtAddCallback(okBtn, XmNactivateCallback,
2234                 &passwordOkCbk, (XtPointer)this);
2235   n = 0;
2236   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2237   XtSetArg(args[n], XmNtopWidget, row); ++n;
2238   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2239   XtSetArg(args[n], XmNrightOffset, 4); ++n;
2240   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2241   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2242   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
2243   cancelBtn = XmCreatePushButton(passwordDialog, "Cancel", args, n);
2244   XtManageChild(cancelBtn);
2245   XtAddCallback(cancelBtn, XmNactivateCallback,
2246                 &passwordCancelCbk, (XtPointer)this);
2247   n = 0;
2248   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
2249   XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
2250   XtSetArg(args[n], XmNinitialFocus, passwordText); ++n;
2251   XtSetValues(passwordDialog, args, n);
2252 }
2253
2254 void XPDFViewer::passwordTextVerifyCbk(Widget widget, XtPointer ptr,
2255                                        XtPointer callData) {
2256   XPDFViewer *viewer = (XPDFViewer *)ptr;
2257   XmTextVerifyCallbackStruct *data =
2258       (XmTextVerifyCallbackStruct *)callData;
2259   int i, n;
2260
2261   i = (int)data->startPos;
2262   n = (int)data->endPos - i;
2263   if (i > viewer->password->getLength()) {
2264     i = viewer->password->getLength();
2265   }
2266   if (i + n > viewer->password->getLength()) {
2267     n = viewer->password->getLength() - i;
2268   }
2269   viewer->password->del(i, n);
2270   viewer->password->insert(i, data->text->ptr, data->text->length);
2271
2272   for (i = 0; i < data->text->length; ++i) {
2273     data->text->ptr[i] = '*';
2274   }
2275   data->doit = True;
2276 }
2277
2278 void XPDFViewer::passwordOkCbk(Widget widget, XtPointer ptr,
2279                                XtPointer callData) {
2280   XPDFViewer *viewer = (XPDFViewer *)ptr;
2281
2282   viewer->passwordDone = 1;
2283 }
2284
2285 void XPDFViewer::passwordCancelCbk(Widget widget, XtPointer ptr,
2286                                    XtPointer callData) {
2287   XPDFViewer *viewer = (XPDFViewer *)ptr;
2288
2289   viewer->passwordDone = -1;
2290 }
2291
2292 void XPDFViewer::getPassword(GBool again) {
2293   XmString s;
2294   XEvent event;
2295
2296   if (password) {
2297     delete password;
2298   }
2299   password = new GString();
2300
2301   XmTextFieldSetString(passwordText, "");
2302   s = XmStringCreateLocalized(
2303           again ? (char *)"Incorrect password.  Please try again."
2304                 : (char *)"This document requires a password.");
2305   XtVaSetValues(passwordMsg, XmNlabelString, s, NULL);
2306   XmStringFree(s);
2307   XtManageChild(passwordDialog);
2308   passwordDone = 0;
2309   do {
2310     XtAppNextEvent(app->getAppContext(), &event);
2311     XtDispatchEvent(&event);
2312   } while (!passwordDone);
2313
2314   if (passwordDone < 0) {
2315     delete password;
2316     password = NULL;
2317   }
2318 }