]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/XPDFViewer.cc
Import of Xpdf 2.03
[evince.git] / pdf / xpdf / XPDFViewer.cc
index 83f8c7789adb9482ee49a03bd1eb4f9bfb15d1cf..56fb7b51762c7cac9ded7ac2f864a45ad51367e3 100644 (file)
@@ -2,7 +2,7 @@
 //
 // XPDFViewer.cc
 //
-// Copyright 2002 Glyph & Cog, LLC
+// Copyright 2002-2003 Glyph & Cog, LLC
 //
 //========================================================================
 
 #ifdef HAVE_X11_XPM_H
 #include <X11/xpm.h>
 #endif
+#if defined(__sgi) && (XmVERSION <= 1)
+#define Object XtObject
+#include <Sgm/HPanedW.h>
+#undef Object
+#endif
 #include "gmem.h"
 #include "gfile.h"
 #include "GString.h"
 
 //------------------------------------------------------------------------
 
+struct ZoomMenuInfo {
+  char *label;
+  double zoom;
+};
+
+static ZoomMenuInfo zoomMenuInfo[nZoomMenuItems] = {
+  { "400%",      400 },
+  { "200%",      200 },
+  { "150%",      150 },
+  { "125%",      125 },
+  { "100%",      100 },
+  { "50%",        50 },
+  { "25%",        25 },
+  { "12.5%",      12.5 },
+  { "fit page",  zoomPage },
+  { "fit width", zoomWidth }
+};
+
+#define maxZoomIdx   0
+#define defZoomIdx   3
+#define minZoomIdx   7
+#define zoomPageIdx  8
+#define zoomWidthIdx 9
+
+//------------------------------------------------------------------------
+
 XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName,
                       int pageA, GString *destName,
                       GString *ownerPassword, GString *userPassword) {
   LinkDest *dest;
-  int pg, z;
+  int pg;
+  double z;
   GString *dir;
 
   app = appA;
@@ -113,6 +145,13 @@ XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName,
   if (fileName) {
     if (loadFile(fileName, ownerPassword, userPassword)) {
       getPageAndDest(pageA, destName, &pg, &dest);
+#ifndef DISABLE_OUTLINE
+      if (!app->getFullScreen() &&
+         core->getDoc()->getOutline()->getItems() &&
+         core->getDoc()->getOutline()->getItems()->getLength() > 0) {
+       XtVaSetValues(outlineScroll, XmNwidth, 175, NULL);
+      }
+#endif
       if (pg > 0) {
        core->resizeToPage(pg);
       }
@@ -159,7 +198,8 @@ XPDFViewer::~XPDFViewer() {
 
 void XPDFViewer::open(GString *fileName, int pageA, GString *destName) {
   LinkDest *dest;
-  int pg, z;
+  int pg;
+  double z;
 
   if (!core->getDoc() || fileName->cmp(core->getDoc()->getFileName())) {
     if (!loadFile(fileName, NULL, NULL)) {
@@ -198,6 +238,11 @@ void XPDFViewer::clear() {
   XtVaSetValues(prevPageBtn, XmNsensitive, False, NULL);
   XtVaSetValues(nextTenPageBtn, XmNsensitive, False, NULL);
   XtVaSetValues(nextPageBtn, XmNsensitive, False, NULL);
+
+  // remove the old outline
+#ifndef DISABLE_OUTLINE
+  setupOutline();
+#endif
 }
 
 //------------------------------------------------------------------------
@@ -223,12 +268,12 @@ void XPDFViewer::reloadFile() {
   displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gFalse);
 }
 
-void XPDFViewer::displayPage(int pageA, int zoomA, int rotateA,
+void XPDFViewer::displayPage(int pageA, double zoomA, int rotateA,
                             GBool scrollToTop, GBool addToHist) {
   core->displayPage(pageA, zoomA, rotateA, scrollToTop, addToHist);
 }
 
-void XPDFViewer::displayDest(LinkDest *dest, int zoomA, int rotateA,
+void XPDFViewer::displayDest(LinkDest *dest, double zoomA, int rotateA,
                             GBool addToHist) {
   core->displayDest(dest, zoomA, rotateA, addToHist);
 }
@@ -308,7 +353,7 @@ void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key,
       break;
     case '\007':               // ctrl-G
       if (viewer->core->getDoc()) {
-       XPDFViewer::findFindCbk(None, viewer, NULL);
+       viewer->doFind(gTrue);
       }
       break;
     case '\020':               // ctrl-P
@@ -377,43 +422,39 @@ void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key,
     case '0':
       if (!viewer->app->getFullScreen() &&
          viewer->core->getZoom() != defZoom) {
-       XtVaSetValues(viewer->zoomMenu,
-                     XmNmenuHistory, viewer->getZoomMenuBtn(defZoom),
-                     NULL);
+       viewer->setZoomIdx(defZoomIdx);
        viewer->displayPage(viewer->core->getPageNum(), defZoom,
                            viewer->core->getRotate(), gTrue, gFalse);
       }
       break;
     case '+':
-      if (!viewer->app->getFullScreen() &&
-         viewer->core->getZoom() >= minZoom &&
-         viewer->core->getZoom() < maxZoom) {
-       z = viewer->core->getZoom() + 1;
-       XtVaSetValues(viewer->zoomMenu,
-                     XmNmenuHistory, viewer->getZoomMenuBtn(z),
-                     NULL);
-       viewer->displayPage(viewer->core->getPageNum(), z,
-                           viewer->core->getRotate(), gTrue, gFalse);
+      if (!viewer->app->getFullScreen()) {
+       z = viewer->getZoomIdx();
+       if (z <= minZoomIdx && z > maxZoomIdx) {
+         --z;
+         viewer->setZoomIdx(z);
+         viewer->displayPage(viewer->core->getPageNum(),
+                             zoomMenuInfo[z].zoom,
+                             viewer->core->getRotate(), gTrue, gFalse);
+       }
       }
       break;
     case '-':
-      if (!viewer->app->getFullScreen() &&
-         viewer->core->getZoom() > minZoom &&
-         viewer->core->getZoom() <= maxZoom) {
-       z = viewer->core->getZoom() - 1;
-       XtVaSetValues(viewer->zoomMenu,
-                     XmNmenuHistory, viewer->getZoomMenuBtn(z),
-                     NULL);
-       viewer->displayPage(viewer->core->getPageNum(), z,
-                           viewer->core->getRotate(), gTrue, gFalse);
+      if (!viewer->app->getFullScreen()) {
+       z = viewer->getZoomIdx();
+       if (z < minZoomIdx && z >= maxZoomIdx) {
+         ++z;
+         viewer->setZoomIdx(z);
+         viewer->displayPage(viewer->core->getPageNum(),
+                             zoomMenuInfo[z].zoom,
+                             viewer->core->getRotate(), gTrue, gFalse);
+       }
       }
       break;
     case 'z':
       if (!viewer->app->getFullScreen() &&
          viewer->core->getZoom() != zoomPage) {
-       XtVaSetValues(viewer->zoomMenu,
-                     XmNmenuHistory, viewer->getZoomMenuBtn(zoomPage),
-                     NULL);
+       viewer->setZoomIdx(zoomPageIdx);
        viewer->displayPage(viewer->core->getPageNum(), zoomPage,
                            viewer->core->getRotate(), gTrue, gFalse);
       }
@@ -421,9 +462,7 @@ void XPDFViewer::keyPressCbk(void *data, char *s, KeySym key,
     case 'w':
       if (!viewer->app->getFullScreen() &&
          viewer->core->getZoom() != zoomWidth) {
-       XtVaSetValues(viewer->zoomMenu,
-                     XmNmenuHistory, viewer->getZoomMenuBtn(zoomWidth),
-                     NULL);
+       viewer->setZoomIdx(zoomWidthIdx);
        viewer->displayPage(viewer->core->getPageNum(), zoomWidth,
                            viewer->core->getRotate(), gTrue, gFalse);
       }
@@ -452,6 +491,11 @@ void XPDFViewer::mouseCbk(void *data, XEvent *event) {
   if (event->type == ButtonPress && event->xbutton.button == 3) {
     XmMenuPosition(viewer->popupMenu, &event->xbutton);
     XtManageChild(viewer->popupMenu);
+
+    // this is magic (taken from DDD) - weird things happen if this
+    // call isn't made (this is done in two different places, in hopes
+    // of squashing this stupid bug)
+    XtUngrabButton(viewer->core->getDrawAreaWidget(), AnyButton, AnyModifier);
   }
 }
 
@@ -460,7 +504,7 @@ void XPDFViewer::mouseCbk(void *data, XEvent *event) {
 //------------------------------------------------------------------------
 
 void XPDFViewer::initWindow() {
-  Widget btn, label, menuPane, lastBtn;
+  Widget btn, label, lastBtn, zoomWidget;
 #ifndef DISABLE_OUTLINE
   Widget clipWin;
 #endif
@@ -470,7 +514,6 @@ void XPDFViewer::initWindow() {
   int n;
   char *title;
   XmString s, s2, emptyString;
-  char buf[16];
   int i;
 
   display = XtDisplay(app->getAppShell());
@@ -643,43 +686,50 @@ void XPDFViewer::initWindow() {
   XmStringFree(s);
 
   // zoom menu
+#if USE_COMBO_BOX
+  XmString st[nZoomMenuItems];
+  n = 0;
+  XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
+  XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
+  XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
+  XtSetArg(args[n], XmNmarginWidth, 0); ++n;
+  XtSetArg(args[n], XmNmarginHeight, 0); ++n;
+  XtSetArg(args[n], XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); ++n;
+  XtSetArg(args[n], XmNpositionMode, XmONE_BASED); ++n;
+  XtSetArg(args[n], XmNcolumns, 7); ++n;
+  for (i = 0; i < nZoomMenuItems; ++i) {
+    st[i] = XmStringCreateLocalized(zoomMenuInfo[i].label);
+  }
+  XtSetArg(args[n], XmNitems, st); ++n;
+  XtSetArg(args[n], XmNitemCount, nZoomMenuItems); ++n;
+  zoomComboBox = XmCreateComboBox(toolBar, "zoomComboBox", args, n);
+  for (i = 0; i < nZoomMenuItems; ++i) {
+    XmStringFree(st[i]);
+  }
+  XtAddCallback(zoomComboBox, XmNselectionCallback,
+               &zoomComboBoxCbk, (XtPointer)this);
+  XtManageChild(zoomComboBox);
+  zoomWidget = zoomComboBox;
+#else
+  Widget menuPane;
+  char buf[16];
   n = 0;
   menuPane = XmCreatePulldownMenu(toolBar, "zoomMenuPane", args, n);
-  for (i = minZoom; i <= maxZoom; ++i) {
+  for (i = 0; i < nZoomMenuItems; ++i) {
     n = 0;
-    sprintf(buf, "%s%d", i > 0 ? "+" : "", i);
-    s = XmStringCreateLocalized(buf);
+    s = XmStringCreateLocalized(zoomMenuInfo[i].label);
     XtSetArg(args[n], XmNlabelString, s); ++n;
     XtSetArg(args[n], XmNuserData, (XtPointer)i); ++n;
-    sprintf(buf, "zoom%s%d", i < 0 ? "M" : "", i < 0 ? -i : i);
+    sprintf(buf, "zoom%d", i);
     btn = XmCreatePushButton(menuPane, buf, args, n);
     XmStringFree(s);
     XtManageChild(btn);
     XtAddCallback(btn, XmNactivateCallback,
                  &zoomMenuCbk, (XtPointer)this);
-    zoomMenuBtns[i - minZoom] = btn;
+    zoomMenuBtns[i] = btn;
   }
   n = 0;
-  s = XmStringCreateLocalized("fit page");
-  XtSetArg(args[n], XmNlabelString, s); ++n;
-  XtSetArg(args[n], XmNuserData, (XtPointer)zoomPage); ++n;
-  btn = XmCreatePushButton(menuPane, "zoomPage", args, n);
-  XmStringFree(s);
-  XtManageChild(btn);
-  XtAddCallback(btn, XmNactivateCallback,
-               &zoomMenuCbk, (XtPointer)this);
-  zoomMenuBtns[maxZoom - minZoom + 1] = btn;
-  n = 0;
-  s = XmStringCreateLocalized("fit width");
-  XtSetArg(args[n], XmNlabelString, s); ++n;
-  XtSetArg(args[n], XmNuserData, (XtPointer)zoomWidth); ++n;
-  btn = XmCreatePushButton(menuPane, "zoomWidth", args, n);
-  XmStringFree(s);
-  XtManageChild(btn);
-  XtAddCallback(btn, XmNactivateCallback,
-               &zoomMenuCbk, (XtPointer)this);
-  zoomMenuBtns[maxZoom - minZoom + 2] = btn;
-  n = 0;
   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
   XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
@@ -689,11 +739,13 @@ void XPDFViewer::initWindow() {
   XtSetArg(args[n], XmNsubMenuId, menuPane); ++n;
   zoomMenu = XmCreateOptionMenu(toolBar, "zoomMenu", args, n);
   XtManageChild(zoomMenu);
+  zoomWidget = zoomMenu;
+#endif
 
   // find/print/about buttons
   n = 0;
   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
-  XtSetArg(args[n], XmNleftWidget, zoomMenu); ++n;
+  XtSetArg(args[n], XmNleftWidget, zoomWidget); ++n;
   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
   XtSetArg(args[n], XmNmarginWidth, 6); ++n;
@@ -745,7 +797,7 @@ void XPDFViewer::initWindow() {
   XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
   XtSetArg(args[n], XmNleftWidget, lastBtn); ++n;
   XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
-  XtSetArg(args[n], XmNrightWidget, btn); ++n;
+  XtSetArg(args[n], XmNrightWidget, quitBtn); ++n;
   XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
   XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
   s = XmStringCreateLocalized("");
@@ -788,7 +840,11 @@ void XPDFViewer::initWindow() {
     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
+#if defined(__sgi) && (XmVERSION <= 1)
+    panedWin = SgCreateHorzPanedWindow(form, "panedWin", args, n);
+#else
     panedWin = XmCreatePanedWindow(form, "panedWin", args, n);
+#endif
     XtManageChild(panedWin);
 
     // scrolled window for outline container
@@ -797,7 +853,9 @@ void XPDFViewer::initWindow() {
     XtSetArg(args[n], XmNallowResize, True); ++n;
     XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
     XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
+#if !(defined(__sgi) && (XmVERSION <= 1))
     XtSetArg(args[n], XmNwidth, 1); ++n;
+#endif
     XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
     outlineScroll = XmCreateScrolledWindow(panedWin, "outlineScroll", args, n);
     XtManageChild(outlineScroll);
@@ -831,8 +889,7 @@ void XPDFViewer::initWindow() {
 #endif
 
   // set the zoom menu to match the initial zoom setting
-  XtVaSetValues(zoomMenu, XmNmenuHistory,
-               getZoomMenuBtn(core->getZoom()), NULL);
+  setZoomVal(core->getZoom());
 
   // set traversal order
   XtVaSetValues(core->getDrawAreaWidget(),
@@ -851,7 +908,7 @@ void XPDFViewer::initWindow() {
                NULL);
   XtVaSetValues(pageNumText, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
                NULL);
-  XtVaSetValues(zoomMenu, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
+  XtVaSetValues(zoomWidget, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
                NULL);
   XtVaSetValues(findBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
                NULL);
@@ -864,7 +921,12 @@ void XPDFViewer::initWindow() {
 
   // popup menu
   n = 0;
+#if XmVersion < 1002
+  // older versions of Motif need this, newer ones choke on it,
+  // sometimes not displaying the menu at all, maybe depending on the
+  // state of the NumLock key (taken from DDD)
   XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); ++n;
+#endif
   popupMenu = XmCreatePopupMenu(core->getDrawAreaWidget(), "popupMenu",
                                args, n);
   n = 0;
@@ -950,6 +1012,10 @@ void XPDFViewer::initWindow() {
   XtAddCallback(btn, XmNactivateCallback,
                &quitCbk, (XtPointer)this);
 
+  // this is magic (taken from DDD) - weird things happen if this
+  // call isn't made
+  XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
+
   XmStringFree(emptyString);
 }
 
@@ -958,7 +1024,7 @@ void XPDFViewer::mapWindow() {
   Pixmap iconPixmap;
 #endif
   int depth;
-  Pixel bg, arm;
+  Pixel fg, bg, arm;
 
   // show the window
   XtPopup(win, XtGrabNone);
@@ -974,29 +1040,27 @@ void XPDFViewer::mapWindow() {
 
   // set button bitmaps (must be done after the window is mapped)
   XtVaGetValues(backBtn, XmNdepth, &depth,
-               XmNbackground, &bg, XmNarmColor, &arm, NULL);
+               XmNforeground, &fg, XmNbackground, &bg,
+               XmNarmColor, &arm, NULL);
   XtVaSetValues(backBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)backArrow_bits,
                                            backArrow_width,
                                            backArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)backArrow_bits,
                                            backArrow_width,
                                            backArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)backArrowDis_bits,
                                            backArrowDis_width,
                                            backArrowDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(prevTenPageBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1004,22 +1068,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)dblLeftArrow_bits,
                                            dblLeftArrow_width,
                                            dblLeftArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)dblLeftArrow_bits,
                                            dblLeftArrow_width,
                                            dblLeftArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)dblLeftArrowDis_bits,
                                            dblLeftArrowDis_width,
                                            dblLeftArrowDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(prevPageBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1027,22 +1088,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)leftArrow_bits,
                                            leftArrow_width,
                                            leftArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)leftArrow_bits,
                                            leftArrow_width,
                                            leftArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)leftArrowDis_bits,
                                            leftArrowDis_width,
                                            leftArrowDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(nextPageBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1050,22 +1108,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)rightArrow_bits,
                                            rightArrow_width,
                                            rightArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)rightArrow_bits,
                                            rightArrow_width,
                                            rightArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)rightArrowDis_bits,
                                            rightArrowDis_width,
                                            rightArrowDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(nextTenPageBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1073,22 +1128,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)dblRightArrow_bits,
                                            dblRightArrow_width,
                                            dblRightArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)dblRightArrow_bits,
                                            dblRightArrow_width,
                                            dblRightArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)dblRightArrowDis_bits,
                                            dblRightArrowDis_width,
                                            dblRightArrowDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(forwardBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1096,22 +1148,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)forwardArrow_bits,
                                            forwardArrow_width,
                                            forwardArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)forwardArrow_bits,
                                            forwardArrow_width,
                                            forwardArrow_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)forwardArrowDis_bits,
                                            forwardArrowDis_width,
                                            forwardArrowDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(findBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1119,22 +1168,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)find_bits,
                                            find_width,
                                            find_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)find_bits,
                                            find_width,
                                            find_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)findDis_bits,
                                            findDis_width,
                                            findDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(printBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1142,22 +1188,19 @@ void XPDFViewer::mapWindow() {
                                            (char *)print_bits,
                                            print_width,
                                            print_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)print_bits,
                                            print_width,
                                            print_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                XmNlabelInsensitivePixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)printDis_bits,
                                            printDis_width,
                                            printDis_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                NULL);
   XtVaSetValues(aboutBtn, XmNlabelType, XmPIXMAP,
                XmNlabelPixmap,
@@ -1165,15 +1208,13 @@ void XPDFViewer::mapWindow() {
                                            (char *)about_bits,
                                            about_width,
                                            about_height,
-                                           BlackPixel(display, screenNum),
-                                           bg, depth),
+                                           fg, bg, depth),
                XmNarmPixmap,
                XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
                                            (char *)about_bits,
                                            about_width,
                                            about_height,
-                                           BlackPixel(display, screenNum),
-                                           arm, depth),
+                                           fg, arm, depth),
                NULL);
 }
 
@@ -1182,17 +1223,67 @@ void XPDFViewer::closeWindow() {
   XtDestroyWidget(win);
 }
 
-Widget XPDFViewer::getZoomMenuBtn(int z) {
-  if (z >= minZoom && z <= maxZoom) {
-    return zoomMenuBtns[z - minZoom];
+int XPDFViewer::getZoomIdx() {
+#if USE_COMBO_BOX
+  int z;
+
+  XtVaGetValues(zoomComboBox, XmNselectedPosition, &z, NULL);
+  return z - 1;
+#else
+  Widget w;
+  int i;
+
+  XtVaGetValues(zoomMenu, XmNmenuHistory, &w, NULL);
+  for (i = 0; i < nZoomMenuItems; ++i) {
+    if (w == zoomMenuBtns[i]) {
+      return i;
+    }
+  }
+  // this should never happen
+  return 0;
+#endif
+}
+
+void XPDFViewer::setZoomIdx(int idx) {
+#if USE_COMBO_BOX
+  XtVaSetValues(zoomComboBox, XmNselectedPosition, idx + 1, NULL);
+#else
+  XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[idx], NULL);
+#endif
+}
+
+void XPDFViewer::setZoomVal(double z) {
+#if USE_COMBO_BOX
+  char buf[32];
+  XmString s;
+  int i;
+
+  for (i = 0; i < nZoomMenuItems; ++i) {
+    if (z == zoomMenuInfo[i].zoom) {
+      XtVaSetValues(zoomComboBox, XmNselectedPosition, i + 1, NULL);
+      return;
+    }
   }
-  if (z == zoomPage) {
-    return zoomMenuBtns[maxZoom - minZoom + 1];
+  sprintf(buf, "%d", (int)z);
+  s = XmStringCreateLocalized(buf);
+  XtVaSetValues(zoomComboBox, XmNselectedItem, s, NULL);
+  XmStringFree(s);
+#else
+  int i;
+
+  for (i = 0; i < nZoomMenuItems; ++i) {
+    if (z == zoomMenuInfo[i].zoom) {
+      XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
+      return;
+    }
   }
-  if (z == zoomWidth) {
-    return zoomMenuBtns[maxZoom - minZoom + 2];
+  for (i = maxZoomIdx; i < minZoomIdx; ++i) {
+    if (z > zoomMenuInfo[i].zoom) {
+      break;
+    }
   }
-  return zoomMenuBtns[0];
+  XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
+#endif
 }
 
 void XPDFViewer::prevPageCbk(Widget widget, XtPointer ptr,
@@ -1243,19 +1334,65 @@ void XPDFViewer::forwardCbk(Widget widget, XtPointer ptr,
   viewer->core->takeFocus();
 }
 
+#if USE_COMBO_BOX
+
+void XPDFViewer::zoomComboBoxCbk(Widget widget, XtPointer ptr,
+                                XtPointer callData) {
+  XPDFViewer *viewer = (XPDFViewer *)ptr;
+  XmComboBoxCallbackStruct *data = (XmComboBoxCallbackStruct *)callData;
+  double z;
+  char *s;
+  XmStringContext context;
+  XmStringCharSet charSet;
+  XmStringDirection dir;
+  Boolean sep;
+
+  z = viewer->core->getZoom();
+  if (data->item_position == 0) {
+    XmStringInitContext(&context, data->item_or_text);
+    if (XmStringGetNextSegment(context, &s, &charSet, &dir, &sep)) {
+      z = atof(s);
+      if (z <= 1) {
+       z = defZoom;
+      }
+      XtFree(charSet);
+      XtFree(s);
+    }
+    XmStringFreeContext(context);
+  } else {
+    z = zoomMenuInfo[data->item_position - 1].zoom;
+  }
+  // only redraw if this was triggered by an event; otherwise
+  // the caller is responsible for doing the redraw
+  if (z != viewer->core->getZoom() && data->event) {
+    viewer->displayPage(viewer->core->getPageNum(), z,
+                       viewer->core->getRotate(), gTrue, gFalse);
+  }
+  viewer->core->takeFocus();
+}
+
+#else // USE_COMBO_BOX
+
 void XPDFViewer::zoomMenuCbk(Widget widget, XtPointer ptr,
                             XtPointer callData) {
   XPDFViewer *viewer = (XPDFViewer *)ptr;
+  XmPushButtonCallbackStruct *data = (XmPushButtonCallbackStruct *)callData;
   XtPointer userData;
+  double z;
 
   XtVaGetValues(widget, XmNuserData, &userData, NULL);
-  if ((int)userData != viewer->core->getZoom()) {
-    viewer->displayPage(viewer->core->getPageNum(), (int)userData,
+  z = zoomMenuInfo[(int)userData].zoom;
+  // only redraw if this was triggered by an event; otherwise
+  // the caller is responsible for doing the redraw
+  if (z != viewer->core->getZoom() && data->event) {
+    viewer->displayPage(viewer->core->getPageNum(), z,
                        viewer->core->getRotate(), gTrue, gFalse);
   }
   viewer->core->takeFocus();
 }
 
+#endif // USE_COMBO_BOX
+
 void XPDFViewer::findCbk(Widget widget, XtPointer ptr,
                         XtPointer callData) {
   XPDFViewer *viewer = (XPDFViewer *)ptr;
@@ -1389,7 +1526,7 @@ void XPDFViewer::pageNumCbk(Widget widget, XtPointer ptr,
 }
 
 void XPDFViewer::updateCbk(void *data, GString *fileName,
-                          int pageNum, int numPages, char *linkLabel) {
+                          int pageNum, int numPages, char *linkString) {
   XPDFViewer *viewer = (XPDFViewer *)data;
   GString *title;
   char buf[20];
@@ -1439,8 +1576,8 @@ void XPDFViewer::updateCbk(void *data, GString *fileName,
     XmStringFree(s);
   }
 
-  if (linkLabel) {
-    s = XmStringCreateLocalized(linkLabel);
+  if (linkString) {
+    s = XmStringCreateLocalized(linkString);
     XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
     XmStringFree(s);
   }
@@ -1470,18 +1607,21 @@ void XPDFViewer::setupOutline() {
     outlineLabelsLength = outlineLabelsSize = 0;
   }
 
-  // create the new labels
-  items = core->getDoc()->getOutline()->getItems();
-  if (items && items->getLength() > 0) {
-    enc = new GString("Latin1");
-    uMap = globalParams->getUnicodeMap(enc);
-    delete enc;
-    setupOutlineItems(items, NULL, uMap);
-    uMap->decRefCnt();
-  }
+  if (core->getDoc()) {
 
-  // manage the new labels
-  XtManageChildren(outlineLabels, outlineLabelsLength);
+    // create the new labels
+    items = core->getDoc()->getOutline()->getItems();
+    if (items && items->getLength() > 0) {
+      enc = new GString("Latin1");
+      uMap = globalParams->getUnicodeMap(enc);
+      delete enc;
+      setupOutlineItems(items, NULL, uMap);
+      uMap->decRefCnt();
+    }
+
+    // manage the new labels
+    XtManageChildren(outlineLabels, outlineLabelsLength);
+  }
 }
 
 void XPDFViewer::setupOutlineItems(GList *items, Widget parent,
@@ -1560,7 +1700,6 @@ void XPDFViewer::initAboutDialog() {
   int n, i;
   XmString s;
   char buf[20];
-  XmFontListEntry entry;
 
   //----- dialog
   n = 0;
@@ -1601,24 +1740,12 @@ void XPDFViewer::initAboutDialog() {
   XtManageChild(col);
 
   //----- fonts
-  entry = XmFontListEntryLoad(
-               display,
-               "-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1",
-               XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
-  aboutBigFont = XmFontListAppendEntry(NULL, entry);
-  XmFontListEntryFree(&entry);
-  entry = XmFontListEntryLoad(
-               display,
-               "-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1",
-               XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
-  aboutVersionFont = XmFontListAppendEntry(NULL, entry);
-  XmFontListEntryFree(&entry);
-  entry = XmFontListEntryLoad(
-               display,
-               "-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1",
-               XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
-  aboutFixedFont = XmFontListAppendEntry(NULL, entry);
-  XmFontListEntryFree(&entry);
+  aboutBigFont =
+    createFontList("-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1");
+  aboutVersionFont =
+    createFontList("-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1");
+  aboutFixedFont =
+    createFontList("-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1");
 
   //----- heading
   n = 0;
@@ -1815,7 +1942,9 @@ void XPDFViewer::initFindDialog() {
   n = 0;
   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
   XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
+#if XmVersion > 1001
   XtSetArg(args[n], XmNinitialFocus, findText); ++n;
+#endif
   XtSetValues(findDialog, args, n);
 }
 
@@ -1823,10 +1952,17 @@ void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
                             XtPointer callData) {
   XPDFViewer *viewer = (XPDFViewer *)ptr;
 
-  XDefineCursor(viewer->display, XtWindow(viewer->findDialog),
-               viewer->core->getBusyCursor());
-  viewer->core->find(XmTextFieldGetString(viewer->findText));
-  XUndefineCursor(viewer->display, XtWindow(viewer->findDialog));
+  viewer->doFind(gFalse);
+}
+
+void XPDFViewer::doFind(GBool next) {
+  if (XtWindow(findDialog)) {
+    XDefineCursor(display, XtWindow(findDialog), core->getBusyCursor());
+  }
+  core->find(XmTextFieldGetString(findText), next);
+  if (XtWindow(findDialog)) {
+    XUndefineCursor(display, XtWindow(findDialog));
+  }
 }
 
 void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr,
@@ -1909,6 +2045,7 @@ void XPDFViewer::initPrintDialog() {
   Arg args[20];
   int n;
   XmString s;
+  GString *psFileName;
 
   //----- dialog
   n = 0;
@@ -2057,6 +2194,17 @@ void XPDFViewer::initPrintDialog() {
   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
   XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
   XtSetValues(printDialog, args, n);
+
+  //----- initial values
+  if ((psFileName = globalParams->getPSFile())) {
+    if (psFileName->getChar(0) == '|') {
+      XmTextFieldSetString(printCmdText,
+                          psFileName->getCString() + 1);
+    } else {
+      XmTextFieldSetString(printFileText, psFileName->getCString());
+    }
+    delete psFileName;
+  }
 }
 
 void XPDFViewer::setupPrintDialog() {
@@ -2067,10 +2215,7 @@ void XPDFViewer::setupPrintDialog() {
 
   doc = core->getDoc();
   psFileName = globalParams->getPSFile();
-
-  if (psFileName && psFileName->getChar(0) != '|') {
-    XmTextFieldSetString(printFileText, psFileName->getCString());
-  } else {
+  if (!psFileName || psFileName->getChar(0) == '|') {
     pdfFileName = doc->getFileName();
     p = pdfFileName->getCString() + pdfFileName->getLength() - 4;
     if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
@@ -2083,12 +2228,6 @@ void XPDFViewer::setupPrintDialog() {
     XmTextFieldSetString(printFileText, psFileName2->getCString());
     delete psFileName2;
   }
-
-  if (psFileName && psFileName->getChar(0) == '|') {
-    XmTextFieldSetString(printCmdText,
-                        psFileName->getCString() + 1);
-  }
-
   if (psFileName) {
     delete psFileName;
   }
@@ -2168,7 +2307,7 @@ void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
                          doc->getCatalog(), firstPage, lastPage,
                          psModePS);
   if (psOut->isOk()) {
-    doc->displayPages(psOut, firstPage, lastPage, 72, 0, gFalse);
+    doc->displayPages(psOut, firstPage, lastPage, 72, 72, 0, gFalse);
   }
   delete psOut;
   delete psFileName;
@@ -2260,7 +2399,9 @@ void XPDFViewer::initPasswordDialog() {
   n = 0;
   XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
   XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
+#if XmVersion > 1001
   XtSetArg(args[n], XmNinitialFocus, passwordText); ++n;
+#endif
   XtSetValues(passwordDialog, args, n);
 }
 
@@ -2329,3 +2470,43 @@ void XPDFViewer::getPassword(GBool again) {
     password = NULL;
   }
 }
+
+//------------------------------------------------------------------------
+// Motif support
+//------------------------------------------------------------------------
+
+XmFontList XPDFViewer::createFontList(char *xlfd) {
+  XmFontList fontList;
+
+#if XmVersion <= 1001
+
+  XFontStruct *font;
+  String params;
+  Cardinal nParams;
+
+  font = XLoadQueryFont(display, xlfd);
+  if (font) {
+    fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
+  } else {
+    params = (String)xlfd;
+    nParams = 1;
+    XtAppWarningMsg(app->getAppContext(),
+                   "noSuchFont", "CvtStringToXmFontList",
+                   "XtToolkitError", "No such font: %s",
+                   &params, &nParams);
+    fontList = NULL;
+  }
+
+#else
+
+  XmFontListEntry entry;
+
+  entry = XmFontListEntryLoad(display, xlfd,
+                             XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
+  fontList = XmFontListAppendEntry(NULL, entry);
+  XmFontListEntryFree(&entry);
+
+#endif
+
+  return fontList;
+}