1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
14 #include <X11/cursorfont.h>
15 #include <X11/keysym.h>
18 #include "parseargs.h"
31 #include "XOutputDev.h"
32 #include "LTKOutputDev.h"
33 #include "PSOutputDev.h"
34 #include "TextOutputDev.h"
39 #ifdef XlibSpecificationRelease
40 #if XlibSpecificationRelease < 5
41 typedef char *XPointer;
44 typedef char *XPointer;
47 // hack around old X includes which are missing these symbols
49 #define XK_Page_Up 0xFF55
52 #define XK_Page_Down 0xFF56
55 //------------------------------------------------------------------------
56 // misc constants / enums
57 //------------------------------------------------------------------------
59 #define remoteCmdLength 256
69 //------------------------------------------------------------------------
71 //------------------------------------------------------------------------
73 // loadFile / displayPage
74 static GBool loadFile(GString *fileName);
75 static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist);
77 // key press and menu callbacks
78 static void keyPressCbk(LTKWindow *win1, KeySym key, Guint modifiers,
80 static void menuCbk(LTKMenuItem *item);
83 static void buttonPressCbk(LTKWidget *canvas1, int n,
84 int mx, int my, int button, GBool dblClick);
85 static void buttonReleaseCbk(LTKWidget *canvas1, int n,
86 int mx, int my, int button, GBool click);
87 static void doLink(int mx, int my);
88 static void mouseMoveCbk(LTKWidget *widget, int widgetNum, int mx, int my);
89 static void mouseDragCbk(LTKWidget *widget, int widgetNum,
90 int mx, int my, int button);
93 static void nextPageCbk(LTKWidget *button, int n, GBool on);
94 static void nextTenPageCbk(LTKWidget *button, int n, GBool on);
95 static void prevPageCbk(LTKWidget *button, int n, GBool on);
96 static void prevTenPageCbk(LTKWidget *button, int n, GBool on);
97 static void backCbk(LTKWidget *button, int n, GBool on);
98 static void forwardCbk(LTKWidget *button, int n, GBool on);
99 static void pageNumCbk(LTKWidget *textIn, int n, GString *text);
100 static void zoomMenuCbk(LTKMenuItem *item);
101 static void postScriptCbk(LTKWidget *button, int n, GBool on);
102 static void aboutCbk(LTKWidget *button, int n, GBool on);
103 static void quitCbk(LTKWidget *button, int n, GBool on);
105 // scrollbar callbacks
106 static void scrollVertCbk(LTKWidget *scrollbar, int n, int val);
107 static void scrollHorizCbk(LTKWidget *scrollbar, int n, int val);
110 static void layoutCbk(LTKWindow *win1);
111 static void updateScrollbars();
112 static void propChangeCbk(LTKWindow *win1, Atom atom);
115 static void setSelection(int newXMin, int newYMin, int newXMax, int newYMax);
118 static void mapOpenDialog();
119 static void openButtonCbk(LTKWidget *button, int n, GBool on);
120 static void openSelectCbk(LTKWidget *widget, int n, GString *name);
123 static void mapSaveDialog();
124 static void saveButtonCbk(LTKWidget *button, int n, GBool on);
125 static void saveSelectCbk(LTKWidget *widget, int n, GString *name);
127 // "PostScript" dialog
128 static void mapPSDialog();
129 static void psButtonCbk(LTKWidget *button, int n, GBool on);
132 static void mapAboutWin();
133 static void closeAboutCbk(LTKWidget *button, int n, GBool on);
136 static void findCbk(LTKWidget *button, int n, GBool on);
137 static void mapFindWin();
138 static void findButtonCbk(LTKWidget *button, int n, GBool on);
139 static void doFind(char *s);
142 static void killCbk(LTKWindow *win1);
144 //------------------------------------------------------------------------
145 // command line options
146 //------------------------------------------------------------------------
148 static XrmOptionDescRec opts[] = {
149 {"-display", ".display", XrmoptionSepArg, NULL},
150 {"-foreground", ".foreground", XrmoptionSepArg, NULL},
151 {"-fg", ".foreground", XrmoptionSepArg, NULL},
152 {"-background", ".background", XrmoptionSepArg, NULL},
153 {"-bg", ".background", XrmoptionSepArg, NULL},
154 {"-geometry", ".geometry", XrmoptionSepArg, NULL},
155 {"-g", ".geometry", XrmoptionSepArg, NULL},
156 {"-font", ".font", XrmoptionSepArg, NULL},
157 {"-fn", ".font", XrmoptionSepArg, NULL},
158 {"-cmap", ".installCmap", XrmoptionNoArg, (XPointer)"on"},
159 {"-rgb", ".rgbCubeSize", XrmoptionSepArg, NULL},
160 {"-papercolor", ".paperColor", XrmoptionSepArg, NULL},
162 {"-eucjp", ".eucjp", XrmoptionNoArg, (XPointer)"off"},
165 {"-t1lib", ".t1libControl", XrmoptionSepArg, NULL},
167 {"-z", ".initialZoom", XrmoptionSepArg, NULL},
168 {"-ps", ".psFile", XrmoptionSepArg, NULL},
169 {"-paperw", ".psPaperWidth", XrmoptionSepArg, NULL},
170 {"-paperh", ".psPaperHeight", XrmoptionSepArg, NULL},
171 {"-level1", ".psLevel1", XrmoptionNoArg, (XPointer)"false"},
175 GBool printCommands = gFalse;
176 static GBool printHelp = gFalse;
177 static char remoteName[100] = "xpdf_";
178 static GBool doRemoteRaise = gFalse;
179 static GBool doRemoteQuit = gFalse;
180 static GBool viKeys = gFalse;
182 static ArgDesc argDesc[] = {
183 {"-err", argFlag, &errorsToTTY, 0,
184 "send error messages to /dev/tty instead of stderr"},
185 {"-z", argStringDummy, NULL, 0,
186 "initial zoom level (-5..5, page, width)"},
187 {"-g", argStringDummy, NULL, 0,
188 "initial window geometry"},
189 {"-geometry", argStringDummy, NULL, 0,
190 "initial window geometry"},
191 {"-remote", argString, remoteName + 5, sizeof(remoteName) - 5,
192 "start/contact xpdf remote server with specified name"},
193 {"-raise", argFlag, &doRemoteRaise, 0,
194 "raise xpdf remote server window (with -remote only)"},
195 {"-quit", argFlag, &doRemoteQuit, 0,
196 "kill xpdf remote server (with -remote only)"},
197 {"-cmap", argFlagDummy, NULL, 0,
198 "install a private colormap"},
199 {"-rgb", argIntDummy, NULL, 0,
200 "biggest RGB cube to allocate (default is 5)"},
201 {"-papercolor", argStringDummy, NULL, 0,
202 "color of paper background"},
204 {"-eucjp", argStringDummy, NULL, 0,
205 "convert Japanese text to EUC-JP"},
208 {"-t1lib", argStringDummy, NULL, 0,
209 "t1lib font control: none, plain, low, high"},
211 {"-ps", argStringDummy, NULL, 0,
212 "default PostScript file/command name"},
213 {"-paperw", argIntDummy, NULL, 0,
214 "paper width, in points"},
215 {"-paperh", argIntDummy, NULL, 0,
216 "paper height, in points"},
217 {"-level1", argFlagDummy, NULL, 0,
218 "generate Level 1 PostScript"},
219 {"-cmd", argFlag, &printCommands, 0,
220 "print commands as they're executed"},
221 {"-q", argFlag, &errQuiet, 0,
222 "don't print any messages or errors"},
223 {"-h", argFlag, &printHelp, 0,
224 "print usage information"},
225 {"-help", argFlag, &printHelp, 0,
226 "print usage information"},
230 //------------------------------------------------------------------------
232 //------------------------------------------------------------------------
234 // zoom factor is 1.2 (similar to DVI magsteps)
238 #define zoomWidth 101
239 static int zoomDPI[maxZoom - minZoom + 1] = {
242 86, 104, 124, 149, 179
245 #define defZoomStr "1"
249 static LTKOutputDev *out;
256 static LinkAction *linkAction; // mouse pointer is over this link
257 static int // coordinates of current selection:
258 selectXMin, selectYMin, // (xMin==xMax || yMin==yMax) means there
259 selectXMax, selectYMax; // is no selection
260 static GBool lastDragLeft; // last dragged selection edge was left/right
261 static GBool lastDragTop; // last dragged selection edge was top/bottom
262 static int panMX, panMY; // last mouse position for pan
268 #define historySize 50
269 static History // page history queue
270 history[historySize];
271 static int historyCur; // currently displayed page
272 static int historyBLen; // number of valid entries backward from
274 static int historyFLen; // number of valid entries forward from
277 static GString *defPSFileName;
278 static GString *psFileName;
279 static int psFirstPage, psLastPage;
281 static GString *fileReqDir; // current directory for file requesters
283 static GString *urlCommand; // command to execute for URI links
286 static Display *display;
287 static LTKWindow *win;
288 static LTKMenu *zoomMenu;
289 static LTKScrollingCanvas *canvas;
290 static LTKScrollbar *hScrollbar, *vScrollbar;
291 static LTKTextIn *pageNumText;
292 static LTKLabel *numPagesLabel;
293 static LTKLabel *linkLabel;
294 static LTKMenuButton *zoomMenuBtn;
295 static LTKWindow *aboutWin;
296 static LTKWindow *psDialog;
297 static LTKWindow *openDialog;
298 static LTKWindow *saveDialog;
299 static LTKWindow *findWin;
300 static Atom remoteAtom;
303 //------------------------------------------------------------------------
305 //------------------------------------------------------------------------
307 #include "xpdfIcon.xpm"
308 #include "leftArrow.xbm"
309 #include "dblLeftArrow.xbm"
310 #include "rightArrow.xbm"
311 #include "dblRightArrow.xbm"
312 #include "backArrow.xbm"
313 #include "forwardArrow.xbm"
315 #include "postscript.xbm"
317 #include "xpdf-ltk.h"
319 //------------------------------------------------------------------------
321 //------------------------------------------------------------------------
323 int main(int argc, char *argv[]) {
326 char cmd[remoteCmdLength];
330 unsigned long paperColor;
348 fileReqDir = getCurrentDir();
352 paperWidth = paperHeight = -1;
353 ok = parseArgs(argDesc, &argc, argv);
359 initParams(xpdfConfigFile);
361 // create LTKApp (and parse X-related args)
362 app = new LTKApp("xpdf", opts, &argc, argv);
363 app->setKillCbk(&killCbk);
364 display = app->getDisplay();
366 // check command line
368 ok = ok && remoteName[5] && !doRemoteQuit && argc >= 1 && argc <= 3;
369 else if (doRemoteQuit)
370 ok = ok && remoteName[5] && argc == 1;
372 ok = ok && argc >= 1 && argc <= 3;
373 if (!ok || printHelp) {
374 fprintf(stderr, "xpdf version %s\n", xpdfVersion);
375 fprintf(stderr, "%s\n", xpdfCopyright);
376 printUsage("xpdf", "[<PDF-file> [<page>]]", argDesc);
381 name = new GString(argv[1]);
389 // look for already-running remote server
391 remoteAtom = XInternAtom(display, remoteName, False);
392 xwin = XGetSelectionOwner(display, remoteAtom);
395 sprintf(cmd, "%c %d %.200s", doRemoteRaise ? 'D' : 'd',
396 pg, name->getCString());
397 XChangeProperty(display, xwin, remoteAtom, remoteAtom, 8,
398 PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1);
400 } else if (doRemoteRaise) {
401 XChangeProperty(display, xwin, remoteAtom, remoteAtom, 8,
402 PropModeReplace, (Guchar *)"r", 2);
403 } else if (doRemoteQuit) {
404 XChangeProperty(display, xwin, remoteAtom, remoteAtom, 8,
405 PropModeReplace, (Guchar *)"q", 2);
415 fprintf(errFile, "xpdf version %s\n", xpdfVersion);
416 fprintf(errFile, "%s\n", xpdfCopyright);
420 historyCur = historySize - 1;
421 historyBLen = historyFLen = 0;
422 for (i = 0; i < historySize; ++i)
423 history[i].fileName = NULL;
426 defPSFileName = app->getStringResource("psFile", NULL);
428 if (!loadFile(name)) {
433 fileReqDir = makePathAbsolute(grabPath(name->getCString()));
436 // check for legal page number
437 if (doc && (pg < 1 || pg > doc->getNumPages()))
442 zoomMenu = makeZoomMenu();
443 win = makeWindow(app);
445 canvas = (LTKScrollingCanvas *)win->findWidget("canvas");
446 hScrollbar = (LTKScrollbar *)win->findWidget("hScrollbar");
447 vScrollbar = (LTKScrollbar *)win->findWidget("vScrollbar");
448 pageNumText = (LTKTextIn *)win->findWidget("pageNum");
449 numPagesLabel = (LTKLabel *)win->findWidget("numPages");
450 linkLabel = (LTKLabel *)win->findWidget("link");
451 zoomMenuBtn = (LTKMenuButton *)win->findWidget("zoom");
452 win->setKeyCbk(&keyPressCbk);
453 win->setLayoutCbk(&layoutCbk);
454 canvas->setButtonPressCbk(&buttonPressCbk);
455 canvas->setButtonReleaseCbk(&buttonReleaseCbk);
456 canvas->setMouseMoveCbk(&mouseMoveCbk);
457 canvas->setMouseDragCbk(&mouseDragCbk);
458 hScrollbar->setRepeatPeriod(0);
459 vScrollbar->setRepeatPeriod(0);
462 paperWidth = app->getIntResource("psPaperWidth", defPaperWidth);
463 paperHeight = app->getIntResource("psPaperHeight", defPaperHeight);
464 psOutLevel1 = app->getBoolResource("psLevel1", gFalse);
465 urlCommand = app->getStringResource("urlCommand", NULL);
466 installCmap = app->getBoolResource("installCmap", gFalse);
468 win->setInstallCmap(gTrue);
469 rgbCubeSize = app->getIntResource("rgbCubeSize", defaultRGBCube);
470 paperColor = app->getColorResource("paperColor", "white",
471 WhitePixel(display, app->getScreenNum()),
474 useEUCJP = app->getBoolResource("eucjp", gFalse);
479 t1libControl = app->getStringResource("t1libControl", "low");
481 t1Courier = app->getStringResource("t1Courier", NULL);
482 t1CourierBold = app->getStringResource("t1CourierBold", NULL);
483 t1CourierBoldOblique = app->getStringResource("t1CourierBoldOblique", NULL);
484 t1CourierOblique = app->getStringResource("t1CourierOblique", NULL);
485 t1Helvetica = app->getStringResource("t1Helvetica", NULL);
486 t1HelveticaBold = app->getStringResource("t1HelveticaBold", NULL);
487 t1HelveticaBoldOblique =
488 app->getStringResource("t1HelveticaBoldOblique", NULL);
489 t1HelveticaOblique = app->getStringResource("t1HelveticaOblique", NULL);
490 t1Symbol = app->getStringResource("t1Symbol", NULL);
491 t1TimesBold = app->getStringResource("t1TimesBold", NULL);
492 t1TimesBoldItalic = app->getStringResource("t1TimesBoldItalic", NULL);
493 t1TimesItalic = app->getStringResource("t1TimesItalic", NULL);
494 t1TimesRoman = app->getStringResource("t1TimesRoman", NULL);
495 t1ZapfDingbats = app->getStringResource("t1ZapfDingbats", NULL);
497 japan12Font = app->getStringResource("japaneseFont", NULL);
499 zoomStr = app->getStringResource("initialZoom", defZoomStr);
500 if (!zoomStr->cmp("page")) {
502 i = maxZoom - minZoom + 2;
503 } else if (!zoomStr->cmp("width")) {
505 i = maxZoom - minZoom + 3;
507 zoom = atoi(zoomStr->getCString());
510 else if (zoom > maxZoom)
515 zoomMenuBtn->setInitialMenuItem(zoomMenu->getItem(i));
516 viKeys = app->getBoolResource("viKeys", gFalse);
521 app->getGeometryResource("geometry", &x, &y, &width, &height);
522 if (width == 0 || height == 0) {
523 if (!doc || doc->getNumPages() == 0) {
526 } else if (doc->getPageRotate(pg) == 90 || doc->getPageRotate(pg) == 270) {
527 width = (int)(doc->getPageHeight(pg) + 0.5);
528 height = (int)(doc->getPageWidth(pg) + 0.5);
530 width = (int)(doc->getPageWidth(pg) + 0.5);
531 height = (int)(doc->getPageHeight(pg) + 0.5);
533 if (zoom == zoomPage || zoom == zoomWidth) {
534 width = (width * zoomDPI[defZoom - minZoom]) / 72 + 28;
535 height = (height * zoomDPI[defZoom - minZoom]) / 72 + 56;
537 width = (width * zoomDPI[zoom - minZoom]) / 72 + 28;
538 height = (height * zoomDPI[zoom - minZoom]) / 72 + 56;
540 if (width > (Guint)app->getDisplayWidth() - 100) {
541 width = app->getDisplayWidth() - 100;
543 if (height > (Guint)app->getDisplayHeight() - 100) {
544 height = app->getDisplayHeight() - 100;
548 // finish setting up window
549 sprintf(s, "of %d", doc ? doc->getNumPages() : 0);
550 numPagesLabel->setText(s);
552 title = new GString("xpdf: ");
555 title = new GString("xpdf");
557 win->setTitle(title);
558 win->layout(x, y, width, height);
565 gcValues.foreground = BlackPixel(display, win->getScreenNum()) ^
566 WhitePixel(display, win->getScreenNum());
567 gcValues.function = GXxor;
568 selectGC = XCreateGC(display, win->getXWindow(),
569 GCForeground | GCFunction, &gcValues);
571 // set up remote server
572 if (remoteAtom != None) {
573 win->setPropChangeCbk(&propChangeCbk);
574 xwin = win->getXWindow();
575 XSetSelectionOwner(display, remoteAtom, xwin, CurrentTime);
578 // create output device
579 out = new LTKOutputDev(win, paperColor);
582 // display first page
583 displayPage(pg, zoom, 0, gTrue);
592 // release remote control atom
593 if (remoteAtom != None)
594 XSetSelectionOwner(display, remoteAtom, None, CurrentTime);
613 delete defPSFileName;
625 delete t1CourierBold;
626 if (t1CourierBoldOblique)
627 delete t1CourierBoldOblique;
628 if (t1CourierOblique)
629 delete t1CourierOblique;
633 delete t1HelveticaBold;
634 if (t1HelveticaBoldOblique)
635 delete t1HelveticaBoldOblique;
636 if (t1HelveticaOblique)
637 delete t1HelveticaOblique;
642 if (t1TimesBoldItalic)
643 delete t1TimesBoldItalic;
645 delete t1TimesItalic;
649 delete t1ZapfDingbats;
654 for (i = 0; i < historySize; ++i) {
655 if (history[i].fileName)
656 delete history[i].fileName;
660 // check for memory leaks
661 Object::memCheck(errFile ? errFile : stderr);
662 gMemReport(errFile ? errFile : stderr);
667 //------------------------------------------------------------------------
668 // loadFile / displayPage
669 //------------------------------------------------------------------------
671 static GBool loadFile(GString *fileName) {
679 win->setBusyCursor(gTrue);
682 newDoc = new PDFDoc(fileName);
683 if (!newDoc->isOk()) {
686 win->setBusyCursor(gFalse);
690 // replace old document
697 // nothing displayed yet
700 // init PostScript output params
704 psFileName = defPSFileName->copy();
706 p = fileName->getCString() + fileName->getLength() - 4;
707 if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF"))
708 psFileName = new GString(fileName->getCString(),
709 fileName->getLength() - 4);
711 psFileName = fileName->copy();
712 psFileName->append(".ps");
715 psLastPage = doc->getNumPages();
717 // set up title, number-of-pages display; back to normal cursor
719 title = new GString("xpdf: ");
720 title->append(fileName);
721 win->setTitle(title);
722 sprintf(s, "of %d", doc->getNumPages());
723 numPagesLabel->setText(s);
724 win->setBusyCursor(gFalse);
731 static void displayPage(int page1, int zoom1, int rotate1, GBool addToHist) {
732 double hDPI, vDPI, dpi;
737 // check for document
738 if (!doc || doc->getNumPages() == 0)
743 win->setBusyCursor(gTrue);
745 // new page/zoom/rotate values
750 // initialize mouse-related stuff
752 win->setDefaultCursor();
753 linkLabel->setText(NULL);
754 selectXMin = selectXMax = 0;
755 selectYMin = selectYMax = 0;
756 lastDragLeft = lastDragTop = gTrue;
759 rot = rotate + doc->getPageRotate(page);
764 if (zoom == zoomPage) {
765 if (rot == 90 || rot == 270) {
766 hDPI = ((win->getWidth() - 28) / doc->getPageHeight(page)) * 72;
767 vDPI = ((win->getHeight() - 56) / doc->getPageWidth(page)) * 72;
769 hDPI = ((win->getWidth() - 28) / doc->getPageWidth(page)) * 72;
770 vDPI = ((win->getHeight() - 56) / doc->getPageHeight(page)) * 72;
772 dpi = (hDPI < vDPI) ? hDPI : vDPI;
773 } else if (zoom == zoomWidth) {
774 if (rot == 90 || rot == 270) {
775 dpi = ((win->getWidth() - 28) / doc->getPageHeight(page)) * 72;
777 dpi = ((win->getWidth() - 28) / doc->getPageWidth(page)) * 72;
780 dpi = zoomDPI[zoom - minZoom];
782 doc->displayPage(out, page, dpi, rotate, gTrue);
785 // update page number display
786 sprintf(s, "%d", page);
787 pageNumText->setText(s);
791 if (++historyCur == historySize)
793 h = &history[historyCur];
796 h->fileName = doc->getFileName()->copy();
798 if (historyBLen < historySize)
803 // back to regular cursor
804 win->setBusyCursor(gFalse);
807 //------------------------------------------------------------------------
808 // key press and menu callbacks
809 //------------------------------------------------------------------------
811 static void keyPressCbk(LTKWindow *win1, KeySym key, Guint modifiers,
825 nextPageCbk(NULL, 0, gTrue);
829 prevPageCbk(NULL, 0, gTrue);
832 if (vScrollbar->getPos() >=
833 canvas->getRealHeight() - canvas->getHeight()) {
834 nextPageCbk(NULL, 0, gTrue);
836 vScrollbar->setPos(vScrollbar->getPos() + canvas->getHeight(),
837 canvas->getHeight());
838 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
843 if (vScrollbar->getPos() == 0) {
844 prevPageCbk(NULL, 0, gTrue);
845 vScrollbar->setPos(canvas->getRealHeight() - canvas->getHeight(),
846 canvas->getHeight());
847 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
849 vScrollbar->setPos(vScrollbar->getPos() - canvas->getHeight(),
850 canvas->getHeight());
851 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
854 case 'h': // vi-style left
856 hScrollbar->setPos(hScrollbar->getPos() - 16, canvas->getWidth());
857 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
860 case 'l': // vi-style right
862 hScrollbar->setPos(hScrollbar->getPos() + 16, canvas->getWidth());
863 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
866 case 'k': // vi-style up
868 vScrollbar->setPos(vScrollbar->getPos() - 16, canvas->getHeight());
869 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
872 case 'j': // vi-style down
874 vScrollbar->setPos(vScrollbar->getPos() + 16, canvas->getHeight());
875 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
880 displayPage(page, zoom, rotate, gFalse);
884 quitCbk(NULL, 0, gTrue);
891 hScrollbar->setPos(0, canvas->getWidth());
892 vScrollbar->setPos(0, canvas->getHeight());
893 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
897 hScrollbar->setPos(canvas->getRealWidth() - canvas->getWidth(),
899 vScrollbar->setPos(canvas->getRealHeight() - canvas->getHeight(),
900 canvas->getHeight());
901 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
905 if (vScrollbar->getPos() == 0) {
906 prevPageCbk(NULL, 0, gTrue);
907 vScrollbar->setPos(canvas->getRealHeight() - canvas->getHeight(),
908 canvas->getHeight());
909 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
911 vScrollbar->setPos(vScrollbar->getPos() - canvas->getHeight(),
912 canvas->getHeight());
913 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
917 case XK_KP_Page_Down:
918 if (vScrollbar->getPos() >=
919 canvas->getRealHeight() - canvas->getHeight()) {
920 nextPageCbk(NULL, 0, gTrue);
922 vScrollbar->setPos(vScrollbar->getPos() + canvas->getHeight(),
923 canvas->getHeight());
924 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
929 hScrollbar->setPos(hScrollbar->getPos() - 16, canvas->getWidth());
930 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
934 hScrollbar->setPos(hScrollbar->getPos() + 16, canvas->getWidth());
935 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
939 vScrollbar->setPos(vScrollbar->getPos() - 16, canvas->getHeight());
940 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
944 vScrollbar->setPos(vScrollbar->getPos() + 16, canvas->getHeight());
945 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
951 static void menuCbk(LTKMenuItem *item) {
954 switch (item->getItemNum()) {
964 r = (rotate == 0) ? 270 : rotate - 90;
965 displayPage(page, zoom, r, gFalse);
968 case menuRotateRight:
970 r = (rotate == 270) ? 0 : rotate + 90;
971 displayPage(page, zoom, r, gFalse);
980 //------------------------------------------------------------------------
982 //------------------------------------------------------------------------
984 static void buttonPressCbk(LTKWidget *canvas1, int n,
985 int mx, int my, int button, GBool dblClick) {
986 if (!doc || doc->getNumPages() == 0)
989 setSelection(mx, my, mx, my);
990 } else if (button == 2) {
991 panMX = mx - hScrollbar->getPos();
992 panMY = my - vScrollbar->getPos();
996 static void buttonReleaseCbk(LTKWidget *canvas1, int n,
997 int mx, int my, int button, GBool click) {
1000 if (!doc || doc->getNumPages() == 0)
1005 if (selectXMin < selectXMax && selectYMin < selectYMax) {
1006 #ifndef NO_TEXT_SELECT
1007 if (doc->okToCopy()) {
1008 s = out->getText(selectXMin, selectYMin, selectXMax, selectYMax);
1009 win->setSelection(NULL, s);
1011 error(-1, "Copying of text from this document is not allowed.");
1017 setSelection(mx, my, mx, my);
1023 static void doLink(int mx, int my) {
1024 LinkActionKind kind;
1025 LinkAction *action = NULL;
1034 LTKButtonDialog *dialog;
1037 out->cvtDevToUser(mx, my, &x, &y);
1038 if ((action = doc->findLink(x, y))) {
1039 switch (kind = action->getKind()) {
1041 // GoTo / GoToR action
1044 if (kind == actionGoTo) {
1047 if ((dest = ((LinkGoTo *)action)->getDest()))
1048 dest = dest->copy();
1049 else if ((namedDest = ((LinkGoTo *)action)->getNamedDest()))
1050 namedDest = namedDest->copy();
1054 if ((dest = ((LinkGoToR *)action)->getDest()))
1055 dest = dest->copy();
1056 else if ((namedDest = ((LinkGoToR *)action)->getNamedDest()))
1057 namedDest = namedDest->copy();
1058 s = ((LinkGoToR *)action)->getFileName()->getCString();
1059 //~ translate path name for VMS (deal with '/')
1060 if (isAbsolutePath(s))
1061 fileName = new GString(s);
1063 fileName = appendToPath(
1064 grabPath(doc->getFileName()->getCString()), s);
1065 if (!loadFile(fileName)) {
1074 dest = doc->findDest(namedDest);
1078 if (kind == actionGoToR)
1079 displayPage(1, zoom, 0, gTrue);
1081 if (dest->isPageRef()) {
1082 pageRef = dest->getPageRef();
1083 pg = doc->findPage(pageRef.num, pageRef.gen);
1085 pg = dest->getPageNum();
1087 if (pg > 0 && pg != page)
1088 displayPage(pg, zoom, rotate, gTrue);
1090 displayPage(1, zoom, rotate, gTrue);
1091 switch (dest->getKind()) {
1093 out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy);
1094 if (dest->getChangeLeft() || dest->getChangeTop()) {
1095 if (dest->getChangeLeft())
1096 hScrollbar->setPos(dx, canvas->getWidth());
1097 if (dest->getChangeTop())
1098 vScrollbar->setPos(dy, canvas->getHeight());
1099 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1101 //~ what is the zoom parameter?
1106 hScrollbar->setPos(0, canvas->getWidth());
1107 vScrollbar->setPos(0, canvas->getHeight());
1108 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1113 out->cvtUserToDev(0, dest->getTop(), &dx, &dy);
1114 hScrollbar->setPos(0, canvas->getWidth());
1115 vScrollbar->setPos(dy, canvas->getHeight());
1116 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1121 out->cvtUserToDev(dest->getLeft(), 0, &dx, &dy);
1122 hScrollbar->setPos(dx, canvas->getWidth());
1123 vScrollbar->setPos(0, canvas->getHeight());
1124 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1128 out->cvtUserToDev(dest->getLeft(), dest->getTop(), &dx, &dy);
1129 hScrollbar->setPos(dx, canvas->getWidth());
1130 vScrollbar->setPos(dy, canvas->getHeight());
1131 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1140 fileName = ((LinkLaunch *)action)->getFileName();
1141 s = fileName->getCString();
1142 if (!strcmp(s + fileName->getLength() - 4, ".pdf") ||
1143 !strcmp(s + fileName->getLength() - 4, ".PDF")) {
1144 //~ translate path name for VMS (deal with '/')
1145 if (isAbsolutePath(s))
1146 fileName = fileName->copy();
1148 fileName = appendToPath(
1149 grabPath(doc->getFileName()->getCString()), s);
1150 if (!loadFile(fileName))
1152 displayPage(1, zoom, rotate, gTrue);
1154 fileName = fileName->copy();
1155 if (((LinkLaunch *)action)->getParams()) {
1156 fileName->append(' ');
1157 fileName->append(((LinkLaunch *)action)->getParams());
1160 fileName->insert(0, "spawn/nowait ");
1161 #elif defined(__EMX__)
1162 fileName->insert(0, "start /min /n ");
1164 fileName->append(" &");
1166 dialog = new LTKButtonDialog(win, "xpdf: Launch",
1167 "Execute the command:",
1168 fileName->getCString(),
1169 NULL, "Ok", "Cancel");
1171 system(fileName->getCString());
1180 for (s = urlCommand->getCString(); *s; ++s) {
1181 if (s[0] == '%' && s[1] == 's')
1185 fileName = new GString(urlCommand->getCString(),
1186 s - urlCommand->getCString());
1187 fileName->append(((LinkURI *)action)->getURI());
1188 fileName->append(s+2);
1190 fileName = urlCommand->copy();
1193 fileName->insert(0, "spawn/nowait ");
1194 #elif defined(__EMX__)
1195 fileName->insert(0, "start /min /n ");
1197 fileName->append(" &");
1199 system(fileName->getCString());
1202 fprintf(errFile, "URI: %s\n",
1203 ((LinkURI *)action)->getURI()->getCString());
1207 // unknown action type
1209 error(-1, "Unknown link action type: '%s'",
1210 ((LinkUnknown *)action)->getAction()->getCString());
1216 static void mouseMoveCbk(LTKWidget *widget, int widgetNum, int mx, int my) {
1221 if (!doc || doc->getNumPages() == 0)
1223 out->cvtDevToUser(mx, my, &x, &y);
1224 if ((action = doc->findLink(x, y))) {
1225 if (action != linkAction) {
1227 win->setCursor(XC_hand2);
1228 linkAction = action;
1230 switch (linkAction->getKind()) {
1232 s = "[internal link]";
1235 s = ((LinkGoToR *)linkAction)->getFileName()->getCString();
1238 s = ((LinkLaunch *)linkAction)->getFileName()->getCString();
1241 s = ((LinkURI *)action)->getURI()->getCString();
1244 s = "[unknown link]";
1247 linkLabel->setText(s);
1252 win->setDefaultCursor();
1253 linkLabel->setText(NULL);
1258 static void mouseDragCbk(LTKWidget *widget, int widgetNum,
1259 int mx, int my, int button) {
1261 int xMin, yMin, xMax, yMax;
1266 // clip mouse coords
1270 else if (x >= canvas->getRealWidth())
1271 x = canvas->getRealWidth() - 1;
1275 else if (y >= canvas->getRealHeight())
1276 y = canvas->getRealHeight() - 1;
1278 // move appropriate edges of selection
1280 if (x < selectXMax) {
1286 lastDragLeft = gFalse;
1289 if (x > selectXMin) {
1295 lastDragLeft = gTrue;
1299 if (y < selectYMax) {
1305 lastDragTop = gFalse;
1308 if (y > selectYMin) {
1314 lastDragTop = gTrue;
1318 // redraw the selection
1319 setSelection(xMin, yMin, xMax, yMax);
1322 } else if (button == 2) {
1323 mx -= hScrollbar->getPos();
1324 my -= vScrollbar->getPos();
1325 hScrollbar->setPos(hScrollbar->getPos() - (mx - panMX),
1326 canvas->getWidth());
1327 vScrollbar->setPos(vScrollbar->getPos() - (my - panMY),
1328 canvas->getHeight());
1329 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1335 //------------------------------------------------------------------------
1337 //------------------------------------------------------------------------
1339 static void nextPageCbk(LTKWidget *button, int n, GBool on) {
1340 if (!doc || doc->getNumPages() == 0)
1342 if (page < doc->getNumPages()) {
1343 vScrollbar->setPos(0, canvas->getHeight());
1344 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1345 displayPage(page + 1, zoom, rotate, gTrue);
1351 static void nextTenPageCbk(LTKWidget *button, int n, GBool on) {
1354 if (!doc || doc->getNumPages() == 0)
1356 if (page < doc->getNumPages()) {
1357 vScrollbar->setPos(0, canvas->getHeight());
1358 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1359 if ((pg = page + 10) > doc->getNumPages())
1360 pg = doc->getNumPages();
1361 displayPage(pg, zoom, rotate, gTrue);
1367 static void prevPageCbk(LTKWidget *button, int n, GBool on) {
1368 if (!doc || doc->getNumPages() == 0)
1371 vScrollbar->setPos(0, canvas->getHeight());
1372 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1373 displayPage(page - 1, zoom, rotate, gTrue);
1379 static void prevTenPageCbk(LTKWidget *button, int n, GBool on) {
1382 if (!doc || doc->getNumPages() == 0)
1385 vScrollbar->setPos(0, canvas->getHeight());
1386 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1387 if ((pg = page - 10) < 1)
1389 displayPage(pg, zoom, rotate, gTrue);
1395 static void backCbk(LTKWidget *button, int n, GBool on) {
1396 if (historyBLen <= 1) {
1400 if (--historyCur < 0)
1401 historyCur = historySize - 1;
1404 if (history[historyCur].fileName->cmp(doc->getFileName()) != 0) {
1405 if (!loadFile(history[historyCur].fileName->copy())) {
1410 displayPage(history[historyCur].page, zoom, rotate, gFalse);
1413 static void forwardCbk(LTKWidget *button, int n, GBool on) {
1414 if (historyFLen == 0) {
1418 if (++historyCur == historySize)
1422 if (history[historyCur].fileName->cmp(doc->getFileName()) != 0) {
1423 if (!loadFile(history[historyCur].fileName->copy())) {
1428 displayPage(history[historyCur].page, zoom, rotate, gFalse);
1431 static void pageNumCbk(LTKWidget *textIn, int n, GString *text) {
1435 if (!doc || doc->getNumPages() == 0)
1437 page1 = atoi(text->getCString());
1438 if (page1 >= 1 && page1 <= doc->getNumPages()) {
1440 displayPage(page1, zoom, rotate, gTrue);
1443 sprintf(s, "%d", page);
1444 pageNumText->setText(s);
1448 static void zoomMenuCbk(LTKMenuItem *item) {
1451 if (!doc || doc->getNumPages() == 0) {
1454 z = item->getItemNum();
1456 displayPage(page, z, rotate, gFalse);
1460 static void postScriptCbk(LTKWidget *button, int n, GBool on) {
1466 static void aboutCbk(LTKWidget *button, int n, GBool on) {
1470 static void quitCbk(LTKWidget *button, int n, GBool on) {
1474 //------------------------------------------------------------------------
1475 // scrollbar callbacks
1476 //------------------------------------------------------------------------
1478 static void scrollVertCbk(LTKWidget *scrollbar, int n, int val) {
1479 canvas->scroll(hScrollbar->getPos(), val);
1480 XSync(display, False);
1483 static void scrollHorizCbk(LTKWidget *scrollbar, int n, int val) {
1484 canvas->scroll(val, vScrollbar->getPos());
1485 XSync(display, False);
1488 //------------------------------------------------------------------------
1490 //------------------------------------------------------------------------
1492 static void layoutCbk(LTKWindow *win1) {
1493 if (page >= 0 && (zoom == zoomPage || zoom == zoomWidth)) {
1494 displayPage(page, zoom, rotate, gFalse);
1500 static void updateScrollbars() {
1501 hScrollbar->setLimits(0, canvas->getRealWidth() - 1);
1502 hScrollbar->setPos(hScrollbar->getPos(), canvas->getWidth());
1503 hScrollbar->setScrollDelta(16);
1504 vScrollbar->setLimits(0, canvas->getRealHeight() - 1);
1505 vScrollbar->setPos(vScrollbar->getPos(), canvas->getHeight());
1506 vScrollbar->setScrollDelta(16);
1507 canvas->scroll(hScrollbar->getPos(), vScrollbar->getPos());
1510 static void propChangeCbk(LTKWindow *win1, Atom atom) {
1515 Gulong size, remain;
1517 GString *newFileName;
1521 xwin = win1->getXWindow();
1522 if (XGetWindowProperty(display, xwin, remoteAtom,
1523 0, remoteCmdLength/4, True, remoteAtom,
1524 &type, &format, &size, &remain,
1525 (Guchar **)&cmd) != Success)
1531 if (cmd[0] == 'D' || cmd[0] == 'r'){
1536 // display file / page
1537 if (cmd[0] == 'd' || cmd[0] == 'D') {
1540 if (!(p = strchr(p, ' ')))
1542 newFileName = new GString(p + 1);
1543 XFree((XPointer)cmd);
1544 if (!doc || newFileName->cmp(doc->getFileName())) {
1545 if (!loadFile(newFileName))
1550 if (newPage != page && newPage >= 1 && newPage <= doc->getNumPages())
1551 displayPage(newPage, zoom, rotate, gTrue);
1554 } else if (cmd[0] == 'q') {
1559 //------------------------------------------------------------------------
1561 //------------------------------------------------------------------------
1563 static void setSelection(int newXMin, int newYMin, int newXMax, int newYMax) {
1565 GBool needRedraw, needScroll;
1566 GBool moveLeft, moveRight, moveTop, moveBottom;
1568 // erase old selection on canvas pixmap
1569 needRedraw = gFalse;
1570 if (selectXMin < selectXMax && selectYMin < selectYMax) {
1571 XFillRectangle(canvas->getDisplay(), canvas->getPixmap(),
1572 selectGC, selectXMin, selectYMin,
1573 selectXMax - selectXMin, selectYMax - selectYMin);
1577 // draw new selection on canvas pixmap
1578 if (newXMin < newXMax && newYMin < newYMax) {
1579 XFillRectangle(canvas->getDisplay(), canvas->getPixmap(),
1580 selectGC, newXMin, newYMin,
1581 newXMax - newXMin, newYMax - newYMin);
1585 // check which edges moved
1586 moveLeft = newXMin != selectXMin;
1587 moveTop = newYMin != selectYMin;
1588 moveRight = newXMax != selectXMax;
1589 moveBottom = newYMax != selectYMax;
1591 // redraw currently visible part of canvas
1594 canvas->redrawRect((newXMin < selectXMin) ? newXMin : selectXMin,
1595 (newYMin < selectYMin) ? newYMin : selectYMin,
1596 (newXMin > selectXMin) ? newXMin : selectXMin,
1597 (newYMax > selectYMax) ? newYMax : selectYMax);
1600 canvas->redrawRect((newXMax < selectXMax) ? newXMax : selectXMax,
1601 (newYMin < selectYMin) ? newYMin : selectYMin,
1602 (newXMax > selectXMax) ? newXMax : selectXMax,
1603 (newYMax > selectYMax) ? newYMax : selectYMax);
1606 canvas->redrawRect((newXMin < selectXMin) ? newXMin : selectXMin,
1607 (newYMin < selectYMin) ? newYMin : selectYMin,
1608 (newXMax > selectXMax) ? newXMax : selectXMax,
1609 (newYMin > selectYMin) ? newYMin : selectYMin);
1612 canvas->redrawRect((newXMin < selectXMin) ? newXMin : selectXMin,
1613 (newYMax < selectYMax) ? newYMax : selectYMax,
1614 (newXMax > selectXMax) ? newXMax : selectXMax,
1615 (newYMax > selectYMax) ? newYMax : selectYMax);
1619 // switch to new selection coords
1620 selectXMin = newXMin;
1621 selectXMax = newXMax;
1622 selectYMin = newYMin;
1623 selectYMax = newYMax;
1625 // scroll canvas if necessary
1626 needScroll = gFalse;
1627 w = canvas->getWidth();
1628 h = canvas->getHeight();
1629 x = hScrollbar->getPos();
1630 y = vScrollbar->getPos();
1631 if (moveLeft && selectXMin < x) {
1634 } else if (moveRight && selectXMax >= x + w) {
1637 } else if (moveLeft && selectXMin >= x + w) {
1640 } else if (moveRight && selectXMax < x) {
1644 if (moveTop && selectYMin < y) {
1647 } else if (moveBottom && selectYMax >= y + h) {
1650 } else if (moveTop && selectYMin >= y + h) {
1653 } else if (moveBottom && selectYMax < y) {
1658 hScrollbar->setPos(x, w);
1659 vScrollbar->setPos(y, h);
1660 canvas->scroll(x, y);
1664 //------------------------------------------------------------------------
1666 //------------------------------------------------------------------------
1668 static void mapOpenDialog() {
1669 openDialog = makeOpenDialog(app);
1670 ((LTKFileReq *)openDialog->findWidget("fileReq"))->setDir(fileReqDir);
1671 openDialog->layoutDialog(win, -1, -1);
1675 static void openButtonCbk(LTKWidget *button, int n, GBool on) {
1676 LTKFileReq *fileReq;
1681 fileReq = (LTKFileReq *)openDialog->findWidget("fileReq");
1682 if ((sel = fileReq->getSelection()))
1683 openSelectCbk(fileReq, 0, sel);
1690 fileReqDir = ((LTKFileReq *)openDialog->findWidget("fileReq"))->getDir();
1697 static void openSelectCbk(LTKWidget *widget, int n, GString *name) {
1700 name1 = name->copy();
1703 fileReqDir = ((LTKFileReq *)openDialog->findWidget("fileReq"))->getDir();
1707 if (loadFile(name1))
1708 displayPage(1, zoom, rotate, gTrue);
1711 //------------------------------------------------------------------------
1712 // "Save PDF" dialog
1713 //------------------------------------------------------------------------
1715 static void mapSaveDialog() {
1716 saveDialog = makeSaveDialog(app);
1717 ((LTKFileReq *)saveDialog->findWidget("fileReq"))->setDir(fileReqDir);
1718 saveDialog->layoutDialog(win, -1, -1);
1722 static void saveButtonCbk(LTKWidget *button, int n, GBool on) {
1723 LTKFileReq *fileReq;
1730 fileReq = (LTKFileReq *)saveDialog->findWidget("fileReq");
1731 if ((sel = fileReq->getSelection()))
1732 saveSelectCbk(fileReq, 0, sel);
1739 fileReqDir = ((LTKFileReq *)saveDialog->findWidget("fileReq"))->getDir();
1746 static void saveSelectCbk(LTKWidget *widget, int n, GString *name) {
1749 name1 = name->copy();
1752 fileReqDir = ((LTKFileReq *)saveDialog->findWidget("fileReq"))->getDir();
1756 win->setBusyCursor(gTrue);
1759 win->setBusyCursor(gFalse);
1762 //------------------------------------------------------------------------
1763 // "PostScript" dialog
1764 //------------------------------------------------------------------------
1766 static void mapPSDialog() {
1770 psDialog = makePostScriptDialog(app);
1771 sprintf(s, "%d", psFirstPage);
1772 widget = (LTKTextIn *)psDialog->findWidget("firstPage");
1774 sprintf(s, "%d", psLastPage);
1775 widget = (LTKTextIn *)psDialog->findWidget("lastPage");
1777 widget = (LTKTextIn *)psDialog->findWidget("fileName");
1778 widget->setText(psFileName->getCString());
1779 psDialog->layoutDialog(win, -1, -1);
1783 static void psButtonCbk(LTKWidget *button, int n, GBool on) {
1792 // extract params and close the dialog
1793 widget = (LTKTextIn *)psDialog->findWidget("firstPage");
1794 psFirstPage = atoi(widget->getText()->getCString());
1795 if (psFirstPage < 1)
1797 widget = (LTKTextIn *)psDialog->findWidget("lastPage");
1798 psLastPage = atoi(widget->getText()->getCString());
1799 if (psLastPage < psFirstPage)
1800 psLastPage = psFirstPage;
1801 else if (psLastPage > doc->getNumPages())
1802 psLastPage = doc->getNumPages();
1803 widget = (LTKTextIn *)psDialog->findWidget("fileName");
1806 psFileName = widget->getText()->copy();
1807 if (!(psFileName->getChar(0) == '|' ||
1808 psFileName->cmp("-") == 0))
1809 makePathAbsolute(psFileName);
1811 // do the PostScript output
1812 psDialog->setBusyCursor(gTrue);
1813 win->setBusyCursor(gTrue);
1814 if (doc->okToPrint()) {
1815 psOut = new PSOutputDev(psFileName->getCString(), doc->getCatalog(),
1816 psFirstPage, psLastPage, gTrue, gFalse);
1817 if (psOut->isOk()) {
1818 doc->displayPages(psOut, psFirstPage, psLastPage, 72, 0);
1822 error(-1, "Printing this document is not allowed.");
1826 win->setBusyCursor(gFalse);
1834 //------------------------------------------------------------------------
1836 //------------------------------------------------------------------------
1838 static void mapAboutWin() {
1842 aboutWin = makeAboutWindow(app);
1843 aboutWin->layout(-1, -1, -1, -1);
1848 static void closeAboutCbk(LTKWidget *button, int n, GBool on) {
1853 //------------------------------------------------------------------------
1855 //------------------------------------------------------------------------
1857 static void findCbk(LTKWidget *button, int n, GBool on) {
1858 if (!doc || doc->getNumPages() == 0)
1863 static void mapFindWin() {
1867 findWin = makeFindWindow(app);
1868 findWin->layout(-1, -1, -1, -1);
1873 static void findButtonCbk(LTKWidget *button, int n, GBool on) {
1876 if (!doc || doc->getNumPages() == 0)
1879 textIn = (LTKTextIn *)findWin->findWidget("text");
1880 doFind(textIn->getText()->getCString());
1887 static void doFind(char *s) {
1888 TextOutputDev *textOut;
1889 int xMin, yMin, xMax, yMax;
1890 double xMin1, yMin1, xMax1, yMax1;
1895 // check for zero-length string
1901 // set cursors to watch
1902 win->setBusyCursor(gTrue);
1903 findWin->setBusyCursor(gTrue);
1905 // search current page starting at current selection or top of page
1906 xMin = yMin = xMax = yMax = 0;
1907 if (selectXMin < selectXMax && selectYMin < selectYMax) {
1909 yMin = (selectYMin + selectYMax) / 2;
1914 if (out->findText(s, top, gTrue, &xMin, &yMin, &xMax, &yMax))
1917 // search following pages
1918 textOut = new TextOutputDev(NULL, useEUCJP, gFalse);
1919 if (!textOut->isOk()) {
1923 for (pg = page+1; pg <= doc->getNumPages(); ++pg) {
1924 doc->displayPage(textOut, pg, 72, 0, gFalse);
1925 if (textOut->findText(s, gTrue, gTrue, &xMin1, &yMin1, &xMax1, &yMax1))
1929 // search previous pages
1930 for (pg = 1; pg < page; ++pg) {
1931 doc->displayPage(textOut, pg, 72, 0, gFalse);
1932 if (textOut->findText(s, gTrue, gTrue, &xMin1, &yMin1, &xMax1, &yMax1))
1937 // search current page ending at current selection
1938 if (selectXMin < selectXMax && selectYMin < selectYMax) {
1940 yMax = (selectYMin + selectYMax) / 2;
1941 if (out->findText(s, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax))
1949 // found on a different page
1952 displayPage(pg, zoom, rotate, gTrue);
1953 if (!out->findText(s, gTrue, gTrue, &xMin, &yMin, &xMax, &yMax))
1954 goto done; // this can happen if coalescing is bad
1956 // found: change the selection
1958 setSelection(xMin, yMin, xMax, yMax);
1959 #ifndef NO_TEXT_SELECT
1960 if (doc->okToCopy()) {
1961 s1 = out->getText(selectXMin, selectYMin, selectXMax, selectYMax);
1962 win->setSelection(NULL, s1);
1967 // reset cursors to normal
1968 win->setBusyCursor(gFalse);
1969 findWin->setBusyCursor(gFalse);
1972 //------------------------------------------------------------------------
1973 // app kill callback
1974 //------------------------------------------------------------------------
1976 static void killCbk(LTKWindow *win1) {
1979 } else if (win1 == aboutWin) {
1982 } else if (win1 == psDialog) {
1985 } else if (win1 == openDialog) {
1988 } else if (win1 == saveDialog) {
1991 } else if (win1 == findWin) {