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