]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/XPDFViewer.cc
Import of Xpdf 2.01 for merge
[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   XmFontListEntry entry;
1564
1565   //----- dialog
1566   n = 0;
1567   s = XmStringCreateLocalized(xpdfAppName ": About");
1568   XtSetArg(args[n], XmNdialogTitle, s); ++n;
1569   XtSetArg(args[n], XmNwidth, 450); ++n;
1570   XtSetArg(args[n], XmNheight, 300); ++n;
1571   aboutDialog = XmCreateFormDialog(win, "aboutDialog", args, n);
1572   XmStringFree(s);
1573
1574   //----- "close" button
1575   n = 0;
1576   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1577   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1578   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1579   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
1580   closeBtn = XmCreatePushButton(aboutDialog, "Close", args, n);
1581   XtManageChild(closeBtn);
1582   n = 0;
1583   XtSetArg(args[n], XmNdefaultButton, closeBtn); ++n;
1584   XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
1585   XtSetValues(aboutDialog, args, n);
1586
1587   //----- scrolled window and RowColumn
1588   n = 0;
1589   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1590   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
1591   XtSetArg(args[n], XmNbottomWidget, closeBtn); ++n;
1592   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1593   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1594   XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
1595   scrolledWin = XmCreateScrolledWindow(aboutDialog, "scrolledWin", args, n);
1596   XtManageChild(scrolledWin);
1597   n = 0;
1598   XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
1599   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
1600   col = XmCreateRowColumn(scrolledWin, "col", args, n);
1601   XtManageChild(col);
1602
1603   //----- fonts
1604   entry = XmFontListEntryLoad(
1605                 display,
1606                 "-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1",
1607                 XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
1608   aboutBigFont = XmFontListAppendEntry(NULL, entry);
1609   XmFontListEntryFree(&entry);
1610   entry = XmFontListEntryLoad(
1611                 display,
1612                 "-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1",
1613                 XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
1614   aboutVersionFont = XmFontListAppendEntry(NULL, entry);
1615   XmFontListEntryFree(&entry);
1616   entry = XmFontListEntryLoad(
1617                 display,
1618                 "-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1",
1619                 XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
1620   aboutFixedFont = XmFontListAppendEntry(NULL, entry);
1621   XmFontListEntryFree(&entry);
1622
1623   //----- heading
1624   n = 0;
1625   s = XmStringCreateLocalized("Xpdf");
1626   XtSetArg(args[n], XmNlabelString, s); ++n;
1627   XtSetArg(args[n], XmNfontList, aboutBigFont); ++n;
1628   label = XmCreateLabel(col, "h0", args, n);
1629   XmStringFree(s);
1630   XtManageChild(label);
1631   n = 0;
1632   s = XmStringCreateLocalized("Version " xpdfVersion);
1633   XtSetArg(args[n], XmNlabelString, s); ++n;
1634   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1635   label = XmCreateLabel(col, "h1", args, n);
1636   XmStringFree(s);
1637   XtManageChild(label);
1638   n = 0;
1639   s = XmStringCreateLocalized(xpdfCopyright);
1640   XtSetArg(args[n], XmNlabelString, s); ++n;
1641   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1642   label = XmCreateLabel(col, "h2", args, n);
1643   XmStringFree(s);
1644   XtManageChild(label);
1645   n = 0;
1646   s = XmStringCreateLocalized(" ");
1647   XtSetArg(args[n], XmNlabelString, s); ++n;
1648   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1649   label = XmCreateLabel(col, "h3", args, n);
1650   XmStringFree(s);
1651   XtManageChild(label);
1652   n = 0;
1653   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1654   sep = XmCreateSeparator(col, "sep", args, n);
1655   XtManageChild(sep);
1656   n = 0;
1657   s = XmStringCreateLocalized(" ");
1658   XtSetArg(args[n], XmNlabelString, s); ++n;
1659   XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
1660   label = XmCreateLabel(col, "h4", args, n);
1661   XmStringFree(s);
1662   XtManageChild(label);
1663   n = 0;
1664
1665   //----- text
1666   for (i = 0; aboutWinText[i]; ++i) {
1667     n = 0;
1668     s = XmStringCreateLocalized(aboutWinText[i]);
1669     XtSetArg(args[n], XmNlabelString, s); ++n;
1670     XtSetArg(args[n], XmNfontList, aboutFixedFont); ++n;
1671     sprintf(buf, "t%d", i);
1672     label = XmCreateLabel(col, buf, args, n);
1673     XtManageChild(label);
1674     XmStringFree(s);
1675   }
1676 }
1677
1678 //------------------------------------------------------------------------
1679 // GUI code: "open" dialog
1680 //------------------------------------------------------------------------
1681
1682 void XPDFViewer::initOpenDialog() {
1683   Arg args[20];
1684   int n;
1685   XmString s1, s2, s3;
1686
1687   n = 0;
1688   s1 = XmStringCreateLocalized("Open");
1689   XtSetArg(args[n], XmNokLabelString, s1); ++n;
1690   s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
1691   XtSetArg(args[n], XmNpattern, s2); ++n;
1692   s3 = XmStringCreateLocalized(xpdfAppName ": Open");
1693   XtSetArg(args[n], XmNdialogTitle, s3); ++n;
1694   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
1695   XtSetArg(args[n], XmNautoUnmanage, True); ++n;
1696   openDialog = XmCreateFileSelectionDialog(win, "openDialog", args, n);
1697   XmStringFree(s1);
1698   XmStringFree(s2);
1699   XmStringFree(s3);
1700   XtUnmanageChild(XmFileSelectionBoxGetChild(openDialog,
1701                                              XmDIALOG_HELP_BUTTON));
1702   XtAddCallback(openDialog, XmNokCallback,
1703                 &openOkCbk, (XtPointer)this);
1704 }
1705
1706 void XPDFViewer::setOpenDialogDir(char *dir) {
1707   XmString s;
1708
1709   s = XmStringCreateLocalized(dir);
1710   XtVaSetValues(openDialog, XmNdirectory, s, NULL);
1711   XmStringFree(s);
1712 }
1713
1714 void XPDFViewer::mapOpenDialog(GBool openInNewWindowA) {
1715   openInNewWindow = openInNewWindowA;
1716   XmFileSelectionDoSearch(openDialog, NULL);
1717   XtManageChild(openDialog);
1718 }
1719
1720 void XPDFViewer::openOkCbk(Widget widget, XtPointer ptr,
1721                            XtPointer callData) {
1722   XPDFViewer *viewer = (XPDFViewer *)ptr;
1723   XmFileSelectionBoxCallbackStruct *data =
1724     (XmFileSelectionBoxCallbackStruct *)callData;
1725   char *fileName;
1726   XmStringContext context;
1727   XmStringCharSet charSet;
1728   XmStringDirection dir;
1729   Boolean sep;
1730   GString *fileNameStr;
1731
1732   XmStringInitContext(&context, data->value);
1733   if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
1734     fileNameStr = new GString(fileName);
1735     if (viewer->openInNewWindow) {
1736       viewer->app->open(fileNameStr);
1737     } else {
1738       if (viewer->loadFile(fileNameStr)) {
1739         viewer->displayPage(1, viewer->core->getZoom(),
1740                             viewer->core->getRotate(), gTrue, gTrue);
1741       }
1742     }
1743     delete fileNameStr;
1744     XtFree(charSet);
1745     XtFree(fileName);
1746   }
1747   XmStringFreeContext(context);
1748 }
1749
1750 //------------------------------------------------------------------------
1751 // GUI code: "find" dialog
1752 //------------------------------------------------------------------------
1753
1754 void XPDFViewer::initFindDialog() {
1755   Widget row1, label, okBtn, closeBtn;
1756   Arg args[20];
1757   int n;
1758   XmString s;
1759
1760   //----- dialog
1761   n = 0;
1762   s = XmStringCreateLocalized(xpdfAppName ": Find");
1763   XtSetArg(args[n], XmNdialogTitle, s); ++n;
1764   XtSetArg(args[n], XmNnavigationType, XmNONE); ++n;
1765   XtSetArg(args[n], XmNautoUnmanage, False); ++n;
1766   findDialog = XmCreateFormDialog(win, "findDialog", args, n);
1767   XmStringFree(s);
1768
1769   //----- top row: search string entry
1770   n = 0;
1771   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1772   XtSetArg(args[n], XmNtopOffset, 4); ++n;
1773   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1774   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1775   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1776   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
1777   row1 = XmCreateRowColumn(findDialog, "row1", args, n);
1778   XtManageChild(row1);
1779   n = 0;
1780   s = XmStringCreateLocalized("Find text: ");
1781   XtSetArg(args[n], XmNlabelString, s); ++n;
1782   label = XmCreateLabel(row1, "label", args, n);
1783   XmStringFree(s);
1784   XtManageChild(label);
1785   n = 0;
1786   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
1787   findText = XmCreateTextField(row1, "text", args, n);
1788   XtManageChild(findText);
1789
1790   //----- "find" and "close" buttons
1791   n = 0;
1792   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1793   XtSetArg(args[n], XmNtopWidget, row1); ++n;
1794   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1795   XtSetArg(args[n], XmNleftOffset, 4); ++n;
1796   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1797   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
1798   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
1799   okBtn = XmCreatePushButton(findDialog, "Find", args, n);
1800   XtManageChild(okBtn);
1801   XtAddCallback(okBtn, XmNactivateCallback,
1802                 &findFindCbk, (XtPointer)this);
1803   n = 0;
1804   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1805   XtSetArg(args[n], XmNtopWidget, row1); ++n;
1806   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1807   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1808   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
1809   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
1810   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
1811   closeBtn = XmCreatePushButton(findDialog, "Close", args, n);
1812   XtManageChild(closeBtn);
1813   XtAddCallback(closeBtn, XmNactivateCallback,
1814                 &findCloseCbk, (XtPointer)this);
1815   n = 0;
1816   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
1817   XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
1818   XtSetArg(args[n], XmNinitialFocus, findText); ++n;
1819   XtSetValues(findDialog, args, n);
1820 }
1821
1822 void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
1823                              XtPointer callData) {
1824   XPDFViewer *viewer = (XPDFViewer *)ptr;
1825
1826   XDefineCursor(viewer->display, XtWindow(viewer->findDialog),
1827                 viewer->core->getBusyCursor());
1828   viewer->core->find(XmTextFieldGetString(viewer->findText));
1829   XUndefineCursor(viewer->display, XtWindow(viewer->findDialog));
1830 }
1831
1832 void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr,
1833                               XtPointer callData) {
1834   XPDFViewer *viewer = (XPDFViewer *)ptr;
1835
1836   XtUnmanageChild(viewer->findDialog);
1837 }
1838
1839 //------------------------------------------------------------------------
1840 // GUI code: "save as" dialog
1841 //------------------------------------------------------------------------
1842
1843 void XPDFViewer::initSaveAsDialog() {
1844   Arg args[20];
1845   int n;
1846   XmString s1, s2, s3;
1847
1848   n = 0;
1849   s1 = XmStringCreateLocalized("Save");
1850   XtSetArg(args[n], XmNokLabelString, s1); ++n;
1851   s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
1852   XtSetArg(args[n], XmNpattern, s2); ++n;
1853   s3 = XmStringCreateLocalized(xpdfAppName ": Save as");
1854   XtSetArg(args[n], XmNdialogTitle, s3); ++n;
1855   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
1856   XtSetArg(args[n], XmNautoUnmanage, True); ++n;
1857   saveAsDialog = XmCreateFileSelectionDialog(win, "saveAsDialog", args, n);
1858   XmStringFree(s1);
1859   XmStringFree(s2);
1860   XmStringFree(s3);
1861   XtUnmanageChild(XmFileSelectionBoxGetChild(saveAsDialog,
1862                                              XmDIALOG_HELP_BUTTON));
1863   XtAddCallback(saveAsDialog, XmNokCallback,
1864                 &saveAsOkCbk, (XtPointer)this);
1865 }
1866
1867 void XPDFViewer::setSaveAsDialogDir(char *dir) {
1868   XmString s;
1869
1870   s = XmStringCreateLocalized(dir);
1871   XtVaSetValues(saveAsDialog, XmNdirectory, s, NULL);
1872   XmStringFree(s);
1873 }
1874
1875 void XPDFViewer::mapSaveAsDialog() {
1876   XmFileSelectionDoSearch(saveAsDialog, NULL);
1877   XtManageChild(saveAsDialog);
1878 }
1879
1880 void XPDFViewer::saveAsOkCbk(Widget widget, XtPointer ptr,
1881                              XtPointer callData) {
1882   XPDFViewer *viewer = (XPDFViewer *)ptr;
1883   XmFileSelectionBoxCallbackStruct *data =
1884     (XmFileSelectionBoxCallbackStruct *)callData;
1885   char *fileName;
1886   GString *fileNameStr;
1887   XmStringContext context;
1888   XmStringCharSet charSet;
1889   XmStringDirection dir;
1890   Boolean sep;
1891
1892   XmStringInitContext(&context, data->value);
1893   if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
1894     fileNameStr = new GString(fileName);
1895     viewer->core->getDoc()->saveAs(fileNameStr);
1896     delete fileNameStr;
1897     XtFree(charSet);
1898     XtFree(fileName);
1899   }
1900   XmStringFreeContext(context);
1901 }
1902
1903 //------------------------------------------------------------------------
1904 // GUI code: "print" dialog
1905 //------------------------------------------------------------------------
1906
1907 void XPDFViewer::initPrintDialog() {
1908   Widget sep1, sep2, row, label1, label2, okBtn, cancelBtn;
1909   Arg args[20];
1910   int n;
1911   XmString s;
1912
1913   //----- dialog
1914   n = 0;
1915   s = XmStringCreateLocalized(xpdfAppName ": Print");
1916   XtSetArg(args[n], XmNdialogTitle, s); ++n;
1917   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
1918   printDialog = XmCreateFormDialog(win, "printDialog", args, n);
1919   XmStringFree(s);
1920
1921   //----- "print with command"
1922   n = 0;
1923   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
1924   XtSetArg(args[n], XmNtopOffset, 4); ++n;
1925   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1926   XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
1927   XtSetArg(args[n], XmNset, XmSET); ++n;
1928   s = XmStringCreateLocalized("Print with command:");
1929   XtSetArg(args[n], XmNlabelString, s); ++n;
1930   printWithCmdBtn = XmCreateToggleButton(printDialog, "printWithCmd", args, n);
1931   XmStringFree(s);
1932   XtManageChild(printWithCmdBtn);
1933   XtAddCallback(printWithCmdBtn, XmNvalueChangedCallback,
1934                 &printWithCmdBtnCbk, (XtPointer)this);
1935   n = 0;
1936   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1937   XtSetArg(args[n], XmNtopWidget, printWithCmdBtn); ++n;
1938   XtSetArg(args[n], XmNtopOffset, 2); ++n;
1939   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1940   XtSetArg(args[n], XmNleftOffset, 16); ++n;
1941   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1942   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1943   XtSetArg(args[n], XmNcolumns, 40); ++n;
1944   printCmdText = XmCreateTextField(printDialog, "printCmd", args, n);
1945   XtManageChild(printCmdText);
1946
1947   //----- "print with command"
1948   n = 0;
1949   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1950   XtSetArg(args[n], XmNtopWidget, printCmdText); ++n;
1951   XtSetArg(args[n], XmNtopOffset, 4); ++n;
1952   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1953   XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
1954   XtSetArg(args[n], XmNset, XmUNSET); ++n;
1955   s = XmStringCreateLocalized("Print to file:");
1956   XtSetArg(args[n], XmNlabelString, s); ++n;
1957   printToFileBtn = XmCreateToggleButton(printDialog, "printToFile", args, n);
1958   XmStringFree(s);
1959   XtManageChild(printToFileBtn);
1960   XtAddCallback(printToFileBtn, XmNvalueChangedCallback,
1961                 &printToFileBtnCbk, (XtPointer)this);
1962   n = 0;
1963   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1964   XtSetArg(args[n], XmNtopWidget, printToFileBtn); ++n;
1965   XtSetArg(args[n], XmNtopOffset, 2); ++n;
1966   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1967   XtSetArg(args[n], XmNleftOffset, 16); ++n;
1968   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1969   XtSetArg(args[n], XmNrightOffset, 4); ++n;
1970   XtSetArg(args[n], XmNcolumns, 40); ++n;
1971   XtSetArg(args[n], XmNsensitive, False); ++n;
1972   printFileText = XmCreateTextField(printDialog, "printFile", args, n);
1973   XtManageChild(printFileText);
1974
1975   //----- separator
1976   n = 0;
1977   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1978   XtSetArg(args[n], XmNtopWidget, printFileText); ++n;
1979   XtSetArg(args[n], XmNtopOffset, 8); ++n;
1980   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1981   XtSetArg(args[n], XmNleftOffset, 8); ++n;
1982   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
1983   XtSetArg(args[n], XmNrightOffset, 8); ++n;
1984   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1985   sep1 = XmCreateSeparator(printDialog, "sep1", args, n);
1986   XtManageChild(sep1);
1987
1988   //----- page range
1989   n = 0;
1990   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
1991   XtSetArg(args[n], XmNtopWidget, sep1); ++n;
1992   XtSetArg(args[n], XmNtopOffset, 8); ++n;
1993   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
1994   XtSetArg(args[n], XmNleftOffset, 4); ++n;
1995   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
1996   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
1997   row = XmCreateRowColumn(printDialog, "row", args, n);
1998   XtManageChild(row);
1999   n = 0;
2000   s = XmStringCreateLocalized("Pages:");
2001   XtSetArg(args[n], XmNlabelString, s); ++n;
2002   label1 = XmCreateLabel(row, "label1", args, n);
2003   XmStringFree(s);
2004   XtManageChild(label1);
2005   n = 0;
2006   XtSetArg(args[n], XmNcolumns, 5); ++n;
2007   printFirstPage = XmCreateTextField(row, "printFirstPage", args, n);
2008   XtManageChild(printFirstPage);
2009   n = 0;
2010   s = XmStringCreateLocalized("to");
2011   XtSetArg(args[n], XmNlabelString, s); ++n;
2012   label2 = XmCreateLabel(row, "label2", args, n);
2013   XmStringFree(s);
2014   XtManageChild(label2);
2015   n = 0;
2016   XtSetArg(args[n], XmNcolumns, 5); ++n;
2017   printLastPage = XmCreateTextField(row, "printLastPage", args, n);
2018   XtManageChild(printLastPage);
2019
2020   //----- separator
2021   n = 0;
2022   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2023   XtSetArg(args[n], XmNtopWidget, row); ++n;
2024   XtSetArg(args[n], XmNtopOffset, 8); ++n;
2025   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2026   XtSetArg(args[n], XmNleftOffset, 8); ++n;
2027   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2028   XtSetArg(args[n], XmNrightOffset, 8); ++n;
2029   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
2030   sep2 = XmCreateSeparator(printDialog, "sep2", args, n);
2031   XtManageChild(sep2);
2032
2033   //----- "print" and "cancel" buttons
2034   n = 0;
2035   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2036   XtSetArg(args[n], XmNtopWidget, sep2); ++n;
2037   XtSetArg(args[n], XmNtopOffset, 8); ++n;
2038   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2039   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2040   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2041   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2042   okBtn = XmCreatePushButton(printDialog, "Print", args, n);
2043   XtManageChild(okBtn);
2044   XtAddCallback(okBtn, XmNactivateCallback,
2045                 &printPrintCbk, (XtPointer)this);
2046   n = 0;
2047   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2048   XtSetArg(args[n], XmNtopWidget, sep2); ++n;
2049   XtSetArg(args[n], XmNtopOffset, 8); ++n;
2050   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2051   XtSetArg(args[n], XmNrightOffset, 4); ++n;
2052   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2053   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2054   cancelBtn = XmCreatePushButton(printDialog, "Cancel", args, n);
2055   XtManageChild(cancelBtn);
2056   n = 0;
2057   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
2058   XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
2059   XtSetValues(printDialog, args, n);
2060 }
2061
2062 void XPDFViewer::setupPrintDialog() {
2063   PDFDoc *doc;
2064   char buf[20];
2065   GString *pdfFileName, *psFileName, *psFileName2;
2066   char *p;
2067
2068   doc = core->getDoc();
2069   psFileName = globalParams->getPSFile();
2070
2071   if (psFileName && psFileName->getChar(0) != '|') {
2072     XmTextFieldSetString(printFileText, psFileName->getCString());
2073   } else {
2074     pdfFileName = doc->getFileName();
2075     p = pdfFileName->getCString() + pdfFileName->getLength() - 4;
2076     if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
2077       psFileName2 = new GString(pdfFileName->getCString(),
2078                                 pdfFileName->getLength() - 4);
2079     } else {
2080       psFileName2 = pdfFileName->copy();
2081     }
2082     psFileName2->append(".ps");
2083     XmTextFieldSetString(printFileText, psFileName2->getCString());
2084     delete psFileName2;
2085   }
2086
2087   if (psFileName && psFileName->getChar(0) == '|') {
2088     XmTextFieldSetString(printCmdText,
2089                          psFileName->getCString() + 1);
2090   }
2091
2092   if (psFileName) {
2093     delete psFileName;
2094   }
2095
2096   sprintf(buf, "%d", doc->getNumPages());
2097   XmTextFieldSetString(printFirstPage, "1");
2098   XmTextFieldSetString(printLastPage, buf);
2099 }
2100
2101 void XPDFViewer::printWithCmdBtnCbk(Widget widget, XtPointer ptr,
2102                                     XtPointer callData) {
2103   XPDFViewer *viewer = (XPDFViewer *)ptr;
2104   XmToggleButtonCallbackStruct *data =
2105       (XmToggleButtonCallbackStruct *)callData;
2106
2107   if (data->set != XmSET) {
2108     XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
2109   }
2110   XmToggleButtonSetState(viewer->printToFileBtn, False, False);
2111   XtVaSetValues(viewer->printCmdText, XmNsensitive, True, NULL);
2112   XtVaSetValues(viewer->printFileText, XmNsensitive, False, NULL);
2113 }
2114
2115 void XPDFViewer::printToFileBtnCbk(Widget widget, XtPointer ptr,
2116                                    XtPointer callData) {
2117   XPDFViewer *viewer = (XPDFViewer *)ptr;
2118   XmToggleButtonCallbackStruct *data =
2119       (XmToggleButtonCallbackStruct *)callData;
2120
2121   if (data->set != XmSET) {
2122     XmToggleButtonSetState(viewer->printToFileBtn, True, False);
2123   }
2124   XmToggleButtonSetState(viewer->printWithCmdBtn, False, False);
2125   XtVaSetValues(viewer->printFileText, XmNsensitive, True, NULL);
2126   XtVaSetValues(viewer->printCmdText, XmNsensitive, False, NULL);
2127 }
2128
2129 void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
2130                                XtPointer callData) {
2131   XPDFViewer *viewer = (XPDFViewer *)ptr;
2132   unsigned char withCmd;
2133   GString *psFileName;
2134   int firstPage, lastPage;
2135   PDFDoc *doc;
2136   PSOutputDev *psOut;
2137
2138   doc = viewer->core->getDoc();
2139   if (!doc->okToPrint()) {
2140     error(-1, "Printing this document is not allowed.");
2141     return;
2142   }
2143
2144   viewer->core->setBusyCursor(gTrue);
2145
2146   XtVaGetValues(viewer->printWithCmdBtn, XmNset, &withCmd, NULL);
2147   if (withCmd) {
2148     psFileName = new GString(XmTextFieldGetString(viewer->printCmdText));
2149     psFileName->insert(0, '|');
2150   } else {
2151     psFileName = new GString(XmTextFieldGetString(viewer->printFileText));
2152   }
2153
2154   firstPage = atoi(XmTextFieldGetString(viewer->printFirstPage));
2155   lastPage = atoi(XmTextFieldGetString(viewer->printLastPage));
2156   if (firstPage < 1) {
2157     firstPage = 1;
2158   } else if (firstPage > doc->getNumPages()) {
2159     firstPage = doc->getNumPages();
2160   }
2161   if (lastPage < firstPage) {
2162     lastPage = firstPage;
2163   } else if (lastPage > doc->getNumPages()) {
2164     lastPage = doc->getNumPages();
2165   }
2166
2167   psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
2168                           doc->getCatalog(), firstPage, lastPage,
2169                           psModePS);
2170   if (psOut->isOk()) {
2171     doc->displayPages(psOut, firstPage, lastPage, 72, 0, gFalse);
2172   }
2173   delete psOut;
2174   delete psFileName;
2175
2176   viewer->core->setBusyCursor(gFalse);
2177 }
2178
2179 //------------------------------------------------------------------------
2180 // GUI code: password dialog
2181 //------------------------------------------------------------------------
2182
2183 void XPDFViewer::initPasswordDialog() {
2184   Widget row, label, okBtn, cancelBtn;
2185   Arg args[20];
2186   int n;
2187   XmString s;
2188
2189   //----- dialog
2190   n = 0;
2191   s = XmStringCreateLocalized(xpdfAppName ": Password");
2192   XtSetArg(args[n], XmNdialogTitle, s); ++n;
2193   XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
2194   passwordDialog = XmCreateFormDialog(win, "passwordDialog", args, n);
2195   XmStringFree(s);
2196
2197   //----- message
2198   n = 0;
2199   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
2200   XtSetArg(args[n], XmNtopOffset, 4); ++n;
2201   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2202   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2203   s = XmStringCreateLocalized(" ");
2204   XtSetArg(args[n], XmNlabelString, s); ++n;
2205   passwordMsg = XmCreateLabel(passwordDialog, "msg", args, n);
2206   XmStringFree(s);
2207   XtManageChild(passwordMsg);
2208
2209   //----- label and password entry
2210   n = 0;
2211   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2212   XtSetArg(args[n], XmNtopWidget, passwordMsg); ++n;
2213   XtSetArg(args[n], XmNtopOffset, 4); ++n;
2214   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2215   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2216   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2217   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2218   XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
2219   XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
2220   row = XmCreateRowColumn(passwordDialog, "row", args, n);
2221   XtManageChild(row);
2222   n = 0;
2223   s = XmStringCreateLocalized("Password: ");
2224   XtSetArg(args[n], XmNlabelString, s); ++n;
2225   label = XmCreateLabel(row, "label", args, n);
2226   XmStringFree(s);
2227   XtManageChild(label);
2228   n = 0;
2229   XtSetArg(args[n], XmNcolumns, 16); ++n;
2230   passwordText = XmCreateTextField(row, "text", args, n);
2231   XtManageChild(passwordText);
2232   XtAddCallback(passwordText, XmNmodifyVerifyCallback,
2233                 &passwordTextVerifyCbk, this);
2234
2235   //----- "Ok" and "Cancel" buttons
2236   n = 0;
2237   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2238   XtSetArg(args[n], XmNtopWidget, row); ++n;
2239   XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
2240   XtSetArg(args[n], XmNleftOffset, 4); ++n;
2241   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2242   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2243   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
2244   okBtn = XmCreatePushButton(passwordDialog, "Ok", args, n);
2245   XtManageChild(okBtn);
2246   XtAddCallback(okBtn, XmNactivateCallback,
2247                 &passwordOkCbk, (XtPointer)this);
2248   n = 0;
2249   XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
2250   XtSetArg(args[n], XmNtopWidget, row); ++n;
2251   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
2252   XtSetArg(args[n], XmNrightOffset, 4); ++n;
2253   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
2254   XtSetArg(args[n], XmNbottomOffset, 4); ++n;
2255   XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
2256   cancelBtn = XmCreatePushButton(passwordDialog, "Cancel", args, n);
2257   XtManageChild(cancelBtn);
2258   XtAddCallback(cancelBtn, XmNactivateCallback,
2259                 &passwordCancelCbk, (XtPointer)this);
2260   n = 0;
2261   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
2262   XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
2263   XtSetArg(args[n], XmNinitialFocus, passwordText); ++n;
2264   XtSetValues(passwordDialog, args, n);
2265 }
2266
2267 void XPDFViewer::passwordTextVerifyCbk(Widget widget, XtPointer ptr,
2268                                        XtPointer callData) {
2269   XPDFViewer *viewer = (XPDFViewer *)ptr;
2270   XmTextVerifyCallbackStruct *data =
2271       (XmTextVerifyCallbackStruct *)callData;
2272   int i, n;
2273
2274   i = (int)data->startPos;
2275   n = (int)data->endPos - i;
2276   if (i > viewer->password->getLength()) {
2277     i = viewer->password->getLength();
2278   }
2279   if (i + n > viewer->password->getLength()) {
2280     n = viewer->password->getLength() - i;
2281   }
2282   viewer->password->del(i, n);
2283   viewer->password->insert(i, data->text->ptr, data->text->length);
2284
2285   for (i = 0; i < data->text->length; ++i) {
2286     data->text->ptr[i] = '*';
2287   }
2288   data->doit = True;
2289 }
2290
2291 void XPDFViewer::passwordOkCbk(Widget widget, XtPointer ptr,
2292                                XtPointer callData) {
2293   XPDFViewer *viewer = (XPDFViewer *)ptr;
2294
2295   viewer->passwordDone = 1;
2296 }
2297
2298 void XPDFViewer::passwordCancelCbk(Widget widget, XtPointer ptr,
2299                                    XtPointer callData) {
2300   XPDFViewer *viewer = (XPDFViewer *)ptr;
2301
2302   viewer->passwordDone = -1;
2303 }
2304
2305 void XPDFViewer::getPassword(GBool again) {
2306   XmString s;
2307   XEvent event;
2308
2309   if (password) {
2310     delete password;
2311   }
2312   password = new GString();
2313
2314   XmTextFieldSetString(passwordText, "");
2315   s = XmStringCreateLocalized(
2316           again ? (char *)"Incorrect password.  Please try again."
2317                 : (char *)"This document requires a password.");
2318   XtVaSetValues(passwordMsg, XmNlabelString, s, NULL);
2319   XmStringFree(s);
2320   XtManageChild(passwordDialog);
2321   passwordDone = 0;
2322   do {
2323     XtAppNextEvent(app->getAppContext(), &event);
2324     XtDispatchEvent(&event);
2325   } while (!passwordDone);
2326
2327   if (passwordDone < 0) {
2328     delete password;
2329     password = NULL;
2330   }
2331 }