summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc1680
1 files changed, 0 insertions, 1680 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc
deleted file mode 100644
index 9a3725f53fc..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc
+++ /dev/null
@@ -1,1680 +0,0 @@
-//========================================================================
-//
-// XPDFCore.cc
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <string.h>
-#include "gmem.h"
-#include "GString.h"
-#include "GList.h"
-#include "Error.h"
-#include "GlobalParams.h"
-#include "PDFDoc.h"
-#include "Link.h"
-#include "ErrorCodes.h"
-#include "GfxState.h"
-#include "CoreOutputDev.h"
-#include "PSOutputDev.h"
-#include "TextOutputDev.h"
-#include "SplashBitmap.h"
-#include "SplashPattern.h"
-#include "XPDFApp.h"
-#include "XPDFCore.h"
-
-// these macro defns conflict with xpdf's Object class
-#ifdef LESSTIF_VERSION
-#undef XtDisplay
-#undef XtScreen
-#undef XtWindow
-#undef XtParent
-#undef XtIsRealized
-#endif
-
-//------------------------------------------------------------------------
-
-// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.
-static inline Guchar div255(int x) {
- return (Guchar)((x + (x >> 8) + 0x80) >> 8);
-}
-
-//------------------------------------------------------------------------
-
-GString *XPDFCore::currentSelection = NULL;
-XPDFCore *XPDFCore::currentSelectionOwner = NULL;
-Atom XPDFCore::targetsAtom;
-
-//------------------------------------------------------------------------
-// XPDFCoreTile
-//------------------------------------------------------------------------
-
-class XPDFCoreTile: public PDFCoreTile {
-public:
- XPDFCoreTile(int xDestA, int yDestA);
- virtual ~XPDFCoreTile();
- XImage *image;
-};
-
-XPDFCoreTile::XPDFCoreTile(int xDestA, int yDestA):
- PDFCoreTile(xDestA, yDestA)
-{
- image = NULL;
-}
-
-XPDFCoreTile::~XPDFCoreTile() {
- if (image) {
- gfree(image->data);
- image->data = NULL;
- XDestroyImage(image);
- }
-}
-
-//------------------------------------------------------------------------
-// XPDFCore
-//------------------------------------------------------------------------
-
-XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA,
- SplashColorPtr paperColorA, Gulong paperPixelA,
- Gulong mattePixelA, GBool fullScreenA, GBool reverseVideoA,
- GBool installCmap, int rgbCubeSizeA):
- PDFCore(splashModeRGB8, 4, reverseVideoA, paperColorA, !fullScreenA)
-{
- GString *initialZoom;
-
- shell = shellA;
- parentWidget = parentWidgetA;
- display = XtDisplay(parentWidget);
- screenNum = XScreenNumberOfScreen(XtScreen(parentWidget));
- targetsAtom = XInternAtom(display, "TARGETS", False);
-
- paperPixel = paperPixelA;
- mattePixel = mattePixelA;
- fullScreen = fullScreenA;
-
- setupX(installCmap, rgbCubeSizeA);
-
- scrolledWin = NULL;
- hScrollBar = NULL;
- vScrollBar = NULL;
- drawAreaFrame = NULL;
- drawArea = NULL;
-
- // get the initial zoom value
- if (fullScreen) {
- zoom = zoomPage;
- } else {
- initialZoom = globalParams->getInitialZoom();
- if (!initialZoom->cmp("page")) {
- zoom = zoomPage;
- } else if (!initialZoom->cmp("width")) {
- zoom = zoomWidth;
- } else {
- zoom = atoi(initialZoom->getCString());
- if (zoom <= 0) {
- zoom = defZoom;
- }
- }
- delete initialZoom;
- }
-
- linkAction = NULL;
-
- panning = gFalse;
-
- updateCbk = NULL;
- actionCbk = NULL;
- keyPressCbk = NULL;
- mouseCbk = NULL;
-
- // optional features default to on
- hyperlinksEnabled = gTrue;
- selectEnabled = gTrue;
-
- // do X-specific initialization and create the widgets
- initWindow();
- initPasswordDialog();
-}
-
-XPDFCore::~XPDFCore() {
- if (currentSelectionOwner == this && currentSelection) {
- delete currentSelection;
- currentSelection = NULL;
- currentSelectionOwner = NULL;
- }
- if (drawAreaGC) {
- XFreeGC(display, drawAreaGC);
- }
- if (scrolledWin) {
- XtDestroyWidget(scrolledWin);
- }
- if (busyCursor) {
- XFreeCursor(display, busyCursor);
- }
- if (linkCursor) {
- XFreeCursor(display, linkCursor);
- }
- if (selectCursor) {
- XFreeCursor(display, selectCursor);
- }
-}
-
-//------------------------------------------------------------------------
-// loadFile / displayPage / displayDest
-//------------------------------------------------------------------------
-
-int XPDFCore::loadFile(GString *fileName, GString *ownerPassword,
- GString *userPassword) {
- int err;
-
- err = PDFCore::loadFile(fileName, ownerPassword, userPassword);
- if (err == errNone) {
- // save the modification time
- modTime = getModTime(doc->getFileName()->getCString());
-
- // update the parent window
- if (updateCbk) {
- (*updateCbk)(updateCbkData, doc->getFileName(), -1,
- doc->getNumPages(), NULL);
- }
- }
- return err;
-}
-
-int XPDFCore::loadFile(BaseStream *stream, GString *ownerPassword,
- GString *userPassword) {
- int err;
-
- err = PDFCore::loadFile(stream, ownerPassword, userPassword);
- if (err == errNone) {
- // no file
- modTime = 0;
-
- // update the parent window
- if (updateCbk) {
- (*updateCbk)(updateCbkData, doc->getFileName(), -1,
- doc->getNumPages(), NULL);
- }
- }
- return err;
-}
-
-void XPDFCore::loadDoc(PDFDoc *docA) {
- PDFCore::loadDoc(docA);
-
- // save the modification time
- if (doc->getFileName()) {
- modTime = getModTime(doc->getFileName()->getCString());
- }
-
- // update the parent window
- if (updateCbk) {
- (*updateCbk)(updateCbkData, doc->getFileName(), -1,
- doc->getNumPages(), NULL);
- }
-}
-
-void XPDFCore::resizeToPage(int pg) {
- Dimension width, height;
- double width1, height1;
- Dimension topW, topH, topBorder, daW, daH;
- Dimension displayW, displayH;
-
- displayW = DisplayWidth(display, screenNum);
- displayH = DisplayHeight(display, screenNum);
- if (fullScreen) {
- width = displayW;
- height = displayH;
- } else {
- if (!doc || pg <= 0 || pg > doc->getNumPages()) {
- width1 = 612;
- height1 = 792;
- } else if (doc->getPageRotate(pg) == 90 ||
- doc->getPageRotate(pg) == 270) {
- width1 = doc->getPageCropHeight(pg);
- height1 = doc->getPageCropWidth(pg);
- } else {
- width1 = doc->getPageCropWidth(pg);
- height1 = doc->getPageCropHeight(pg);
- }
- if (zoom == zoomPage || zoom == zoomWidth) {
- width = (Dimension)(width1 * 0.01 * defZoom + 0.5);
- height = (Dimension)(height1 * 0.01 * defZoom + 0.5);
- } else {
- width = (Dimension)(width1 * 0.01 * zoom + 0.5);
- height = (Dimension)(height1 * 0.01 * zoom + 0.5);
- }
- if (continuousMode) {
- height += continuousModePageSpacing;
- }
- if (width > displayW - 100) {
- width = displayW - 100;
- }
- if (height > displayH - 100) {
- height = displayH - 100;
- }
- }
-
- if (XtIsRealized(shell)) {
- XtVaGetValues(shell, XmNwidth, &topW, XmNheight, &topH,
- XmNborderWidth, &topBorder, NULL);
- XtVaGetValues(drawArea, XmNwidth, &daW, XmNheight, &daH, NULL);
- XtVaSetValues(shell, XmNwidth, width + (topW - daW),
- XmNheight, height + (topH - daH), NULL);
- } else {
- XtVaSetValues(drawArea, XmNwidth, width, XmNheight, height, NULL);
- }
-}
-
-void XPDFCore::update(int topPageA, int scrollXA, int scrollYA,
- double zoomA, int rotateA, GBool force,
- GBool addToHist, GBool adjustScrollX) {
- int oldPage;
-
- oldPage = topPage;
- PDFCore::update(topPageA, scrollXA, scrollYA, zoomA, rotateA,
- force, addToHist, adjustScrollX);
- linkAction = NULL;
- if (doc && topPage != oldPage) {
- if (updateCbk) {
- (*updateCbk)(updateCbkData, NULL, topPage, -1, "");
- }
- }
-}
-
-GBool XPDFCore::checkForNewFile() {
- time_t newModTime;
-
- if (doc->getFileName()) {
- newModTime = getModTime(doc->getFileName()->getCString());
- if (newModTime != modTime) {
- modTime = newModTime;
- return gTrue;
- }
- }
- return gFalse;
-}
-
-//------------------------------------------------------------------------
-// page/position changes
-//------------------------------------------------------------------------
-
-GBool XPDFCore::gotoNextPage(int inc, GBool top) {
- if (!PDFCore::gotoNextPage(inc, top)) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-GBool XPDFCore::gotoPrevPage(int dec, GBool top, GBool bottom) {
- if (!PDFCore::gotoPrevPage(dec, top, bottom)) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-GBool XPDFCore::goForward() {
- if (!PDFCore::goForward()) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-GBool XPDFCore::goBackward() {
- if (!PDFCore::goBackward()) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-void XPDFCore::startPan(int wx, int wy) {
- panning = gTrue;
- panMX = wx;
- panMY = wy;
-}
-
-void XPDFCore::endPan(int wx, int wy) {
- panning = gFalse;
-}
-
-//------------------------------------------------------------------------
-// selection
-//------------------------------------------------------------------------
-
-void XPDFCore::startSelection(int wx, int wy) {
- int pg, x, y;
-
- takeFocus();
- if (doc && doc->getNumPages() > 0) {
- if (selectEnabled) {
- if (cvtWindowToDev(wx, wy, &pg, &x, &y)) {
- setSelection(pg, x, y, x, y);
- setCursor(selectCursor);
- dragging = gTrue;
- }
- }
- }
-}
-
-void XPDFCore::endSelection(int wx, int wy) {
- int pg, x, y;
- GBool ok;
-
- if (doc && doc->getNumPages() > 0) {
- ok = cvtWindowToDev(wx, wy, &pg, &x, &y);
- if (dragging) {
- dragging = gFalse;
- setCursor(None);
- if (ok) {
- moveSelection(pg, x, y);
- }
-#ifndef NO_TEXT_SELECT
- if (selectULX != selectLRX &&
- selectULY != selectLRY) {
- if (doc->okToCopy()) {
- copySelection();
- } else {
- error(errNotAllowed, -1,
- "Copying of text from this document is not allowed.");
- }
- }
-#endif
- }
- }
-}
-
-// X's copy-and-paste mechanism is brain damaged. Xt doesn't help
-// any, but doesn't make it too much worse, either. Motif, on the
-// other hand, adds significant complexity to the mess. So here we
-// blow off the Motif junk and stick to plain old Xt. The next two
-// functions (copySelection and convertSelectionCbk) implement the
-// magic needed to deal with Xt's mechanism. Note that this requires
-// global variables (currentSelection and currentSelectionOwner).
-
-void XPDFCore::copySelection() {
- int pg;
- double ulx, uly, lrx, lry;
-
- if (!doc->okToCopy()) {
- return;
- }
- if (getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
- //~ for multithreading: need a mutex here
- if (currentSelection) {
- delete currentSelection;
- }
- currentSelection = extractText(pg, ulx, uly, lrx, lry);
- currentSelectionOwner = this;
- XtOwnSelection(drawArea, XA_PRIMARY, XtLastTimestampProcessed(display),
- &convertSelectionCbk, NULL, NULL);
- }
-}
-
-Boolean XPDFCore::convertSelectionCbk(Widget widget, Atom *selection,
- Atom *target, Atom *type,
- XtPointer *value, unsigned long *length,
- int *format) {
- Atom *array;
-
- // send back a list of supported conversion targets
- if (*target == targetsAtom) {
- if (!(array = (Atom *)XtMalloc(sizeof(Atom)))) {
- return False;
- }
- array[0] = XA_STRING;
- *value = (XtPointer)array;
- *type = XA_ATOM;
- *format = 32;
- *length = 1;
- return True;
-
- // send the selected text
- } else if (*target == XA_STRING) {
- //~ for multithreading: need a mutex here
- *value = XtNewString(currentSelection->getCString());
- *length = currentSelection->getLength();
- *type = XA_STRING;
- *format = 8; // 8-bit elements
- return True;
- }
-
- return False;
-}
-
-//------------------------------------------------------------------------
-// hyperlinks
-//------------------------------------------------------------------------
-
-void XPDFCore::doAction(LinkAction *action) {
- LinkActionKind kind;
- LinkDest *dest;
- GString *namedDest;
- char *s;
- GString *fileName, *fileName2;
- GString *cmd;
- GString *actionName;
- Object movieAnnot, obj1, obj2;
- GString *msg;
- int i;
-
- switch (kind = action->getKind()) {
-
- // GoTo / GoToR action
- case actionGoTo:
- case actionGoToR:
- if (kind == actionGoTo) {
- dest = NULL;
- namedDest = NULL;
- if ((dest = ((LinkGoTo *)action)->getDest())) {
- dest = dest->copy();
- } else if ((namedDest = ((LinkGoTo *)action)->getNamedDest())) {
- namedDest = namedDest->copy();
- }
- } else {
- dest = NULL;
- namedDest = NULL;
- if ((dest = ((LinkGoToR *)action)->getDest())) {
- dest = dest->copy();
- } else if ((namedDest = ((LinkGoToR *)action)->getNamedDest())) {
- namedDest = namedDest->copy();
- }
- s = ((LinkGoToR *)action)->getFileName()->getCString();
- //~ translate path name for VMS (deal with '/')
- if (isAbsolutePath(s) || !doc->getFileName()) {
- fileName = new GString(s);
- } else {
- fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s);
- }
- if (loadFile(fileName) != errNone) {
- if (dest) {
- delete dest;
- }
- if (namedDest) {
- delete namedDest;
- }
- delete fileName;
- return;
- }
- delete fileName;
- }
- if (namedDest) {
- dest = doc->findDest(namedDest);
- delete namedDest;
- }
- if (dest) {
- displayDest(dest, zoom, rotate, gTrue);
- delete dest;
- } else {
- if (kind == actionGoToR) {
- displayPage(1, zoom, 0, gFalse, gTrue);
- }
- }
- break;
-
- // Launch action
- case actionLaunch:
- fileName = ((LinkLaunch *)action)->getFileName();
- s = fileName->getCString();
- if (!strcmp(s + fileName->getLength() - 4, ".pdf") ||
- !strcmp(s + fileName->getLength() - 4, ".PDF")) {
- //~ translate path name for VMS (deal with '/')
- if (isAbsolutePath(s) || !doc->getFileName()) {
- fileName = fileName->copy();
- } else {
- fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s);
- }
- if (loadFile(fileName) != errNone) {
- delete fileName;
- return;
- }
- delete fileName;
- displayPage(1, zoom, rotate, gFalse, gTrue);
- } else {
- fileName = fileName->copy();
- if (((LinkLaunch *)action)->getParams()) {
- fileName->append(' ');
- fileName->append(((LinkLaunch *)action)->getParams());
- }
-#ifdef VMS
- fileName->insert(0, "spawn/nowait ");
-#elif defined(__EMX__)
- fileName->insert(0, "start /min /n ");
-#else
- fileName->append(" &");
-#endif
- if (globalParams->getLaunchCommand()) {
- fileName->insert(0, ' ');
- fileName->insert(0, globalParams->getLaunchCommand());
- system(fileName->getCString());
- } else {
- msg = new GString("About to execute the command:\n");
- msg->append(fileName);
- if (doQuestionDialog("Launching external application", msg)) {
- system(fileName->getCString());
- }
- delete msg;
- }
- delete fileName;
- }
- break;
-
- // URI action
- case actionURI:
- if (!(cmd = globalParams->getURLCommand())) {
- error(errConfig, -1, "No urlCommand defined in config file");
- break;
- }
- runCommand(cmd, ((LinkURI *)action)->getURI());
- break;
-
- // Named action
- case actionNamed:
- actionName = ((LinkNamed *)action)->getName();
- if (!actionName->cmp("NextPage")) {
- gotoNextPage(1, gTrue);
- } else if (!actionName->cmp("PrevPage")) {
- gotoPrevPage(1, gTrue, gFalse);
- } else if (!actionName->cmp("FirstPage")) {
- if (topPage != 1) {
- displayPage(1, zoom, rotate, gTrue, gTrue);
- }
- } else if (!actionName->cmp("LastPage")) {
- if (topPage != doc->getNumPages()) {
- displayPage(doc->getNumPages(), zoom, rotate, gTrue, gTrue);
- }
- } else if (!actionName->cmp("GoBack")) {
- goBackward();
- } else if (!actionName->cmp("GoForward")) {
- goForward();
- } else if (!actionName->cmp("Quit")) {
- if (actionCbk) {
- (*actionCbk)(actionCbkData, actionName->getCString());
- }
- } else {
- error(errSyntaxError, -1,
- "Unknown named action: '{0:t}'", actionName);
- }
- break;
-
- // Movie action
- case actionMovie:
- if (!(cmd = globalParams->getMovieCommand())) {
- error(errConfig, -1, "No movieCommand defined in config file");
- break;
- }
- if (((LinkMovie *)action)->hasAnnotRef()) {
- doc->getXRef()->fetch(((LinkMovie *)action)->getAnnotRef()->num,
- ((LinkMovie *)action)->getAnnotRef()->gen,
- &movieAnnot);
- } else {
- //~ need to use the correct page num here
- doc->getCatalog()->getPage(topPage)->getAnnots(&obj1);
- if (obj1.isArray()) {
- for (i = 0; i < obj1.arrayGetLength(); ++i) {
- if (obj1.arrayGet(i, &movieAnnot)->isDict()) {
- if (movieAnnot.dictLookup("Subtype", &obj2)->isName("Movie")) {
- obj2.free();
- break;
- }
- obj2.free();
- }
- movieAnnot.free();
- }
- obj1.free();
- }
- }
- if (movieAnnot.isDict()) {
- if (movieAnnot.dictLookup("Movie", &obj1)->isDict()) {
- if (obj1.dictLookup("F", &obj2)) {
- if ((fileName = LinkAction::getFileSpecName(&obj2))) {
- if (!isAbsolutePath(fileName->getCString()) &&
- doc->getFileName()) {
- fileName2 = appendToPath(
- grabPath(doc->getFileName()->getCString()),
- fileName->getCString());
- delete fileName;
- fileName = fileName2;
- }
- runCommand(cmd, fileName);
- delete fileName;
- }
- obj2.free();
- }
- obj1.free();
- }
- }
- movieAnnot.free();
- break;
-
- // unsupported action types
- case actionJavaScript:
- case actionSubmitForm:
- case actionHide:
- error(errSyntaxError, -1, "Unsupported link action type");
- break;
-
- // unknown action type
- case actionUnknown:
- error(errSyntaxError, -1, "Unknown link action type: '{0:t}'",
- ((LinkUnknown *)action)->getAction());
- break;
- }
-}
-
-// Run a command, given a <cmdFmt> string with one '%s' in it, and an
-// <arg> string to insert in place of the '%s'.
-void XPDFCore::runCommand(GString *cmdFmt, GString *arg) {
- GString *cmd;
- char *s;
-
- if ((s = strstr(cmdFmt->getCString(), "%s"))) {
- cmd = mungeURL(arg);
- cmd->insert(0, cmdFmt->getCString(),
- s - cmdFmt->getCString());
- cmd->append(s + 2);
- } else {
- cmd = cmdFmt->copy();
- }
-#ifdef VMS
- cmd->insert(0, "spawn/nowait ");
-#elif defined(__EMX__)
- cmd->insert(0, "start /min /n ");
-#else
- cmd->append(" &");
-#endif
- system(cmd->getCString());
- delete cmd;
-}
-
-// Escape any characters in a URL which might cause problems when
-// calling system().
-GString *XPDFCore::mungeURL(GString *url) {
- static const char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789"
- "-_.~/?:@&=+,#%";
- GString *newURL;
- char c;
- char buf[4];
- int i;
-
- newURL = new GString();
- for (i = 0; i < url->getLength(); ++i) {
- c = url->getChar(i);
- if (strchr(allowed, c)) {
- newURL->append(c);
- } else {
- sprintf(buf, "%%%02x", c & 0xff);
- newURL->append(buf);
- }
- }
- return newURL;
-}
-
-//------------------------------------------------------------------------
-// find
-//------------------------------------------------------------------------
-
-GBool XPDFCore::find(char *s, GBool caseSensitive, GBool next,
- GBool backward, GBool wholeWord, GBool onePageOnly) {
- if (!PDFCore::find(s, caseSensitive, next,
- backward, wholeWord, onePageOnly)) {
- XBell(display, 0);
- return gFalse;
- }
-#ifndef NO_TEXT_SELECT
- copySelection();
-#endif
- return gTrue;
-}
-
-GBool XPDFCore::findU(Unicode *u, int len, GBool caseSensitive,
- GBool next, GBool backward,
- GBool wholeWord, GBool onePageOnly) {
- if (!PDFCore::findU(u, len, caseSensitive, next,
- backward, wholeWord, onePageOnly)) {
- XBell(display, 0);
- return gFalse;
- }
-#ifndef NO_TEXT_SELECT
- copySelection();
-#endif
- return gTrue;
-}
-
-//------------------------------------------------------------------------
-// misc access
-//------------------------------------------------------------------------
-
-void XPDFCore::setBusyCursor(GBool busy) {
- setCursor(busy ? busyCursor : None);
-}
-
-void XPDFCore::takeFocus() {
- XmProcessTraversal(drawArea, XmTRAVERSE_CURRENT);
-}
-
-//------------------------------------------------------------------------
-// GUI code
-//------------------------------------------------------------------------
-
-void XPDFCore::setupX(GBool installCmap, int rgbCubeSizeA) {
- XVisualInfo visualTempl;
- XVisualInfo *visualList;
- Gulong mask;
- int nVisuals;
- XColor xcolor;
- XColor *xcolors;
- int r, g, b, n, m;
- GBool ok;
-
- // for some reason, querying XmNvisual doesn't work (even if done
- // after the window is mapped)
- visual = DefaultVisual(display, screenNum);
- XtVaGetValues(shell, XmNcolormap, &colormap, NULL);
-
- // check for TrueColor visual
- //~ this should scan the list, not just look at the first one
- visualTempl.visualid = XVisualIDFromVisual(visual);
- visualList = XGetVisualInfo(display, VisualIDMask,
- &visualTempl, &nVisuals);
- if (nVisuals < 1) {
- // this shouldn't happen
- XFree((XPointer)visualList);
- visualList = XGetVisualInfo(display, VisualNoMask, &visualTempl,
- &nVisuals);
- }
- depth = visualList->depth;
- if (visualList->c_class == TrueColor) {
- trueColor = gTrue;
- for (mask = visualList->red_mask, rShift = 0;
- mask && !(mask & 1);
- mask >>= 1, ++rShift) ;
- for (rDiv = 8; mask; mask >>= 1, --rDiv) ;
- for (mask = visualList->green_mask, gShift = 0;
- mask && !(mask & 1);
- mask >>= 1, ++gShift) ;
- for (gDiv = 8; mask; mask >>= 1, --gDiv) ;
- for (mask = visualList->blue_mask, bShift = 0;
- mask && !(mask & 1);
- mask >>= 1, ++bShift) ;
- for (bDiv = 8; mask; mask >>= 1, --bDiv) ;
- } else {
- trueColor = gFalse;
- }
- XFree((XPointer)visualList);
-
- // allocate a color cube
- if (!trueColor) {
-
- // set colors in private colormap
- if (installCmap) {
- for (rgbCubeSize = xMaxRGBCube; rgbCubeSize >= 2; --rgbCubeSize) {
- m = rgbCubeSize * rgbCubeSize * rgbCubeSize;
- if (XAllocColorCells(display, colormap, False, NULL, 0, colors, m)) {
- break;
- }
- }
- if (rgbCubeSize >= 2) {
- m = rgbCubeSize * rgbCubeSize * rgbCubeSize;
- xcolors = (XColor *)gmallocn(m, sizeof(XColor));
- n = 0;
- for (r = 0; r < rgbCubeSize; ++r) {
- for (g = 0; g < rgbCubeSize; ++g) {
- for (b = 0; b < rgbCubeSize; ++b) {
- xcolors[n].pixel = colors[n];
- xcolors[n].red = (r * 65535) / (rgbCubeSize - 1);
- xcolors[n].green = (g * 65535) / (rgbCubeSize - 1);
- xcolors[n].blue = (b * 65535) / (rgbCubeSize - 1);
- xcolors[n].flags = DoRed | DoGreen | DoBlue;
- ++n;
- }
- }
- }
- XStoreColors(display, colormap, xcolors, m);
- gfree(xcolors);
- } else {
- rgbCubeSize = 1;
- colors[0] = BlackPixel(display, screenNum);
- colors[1] = WhitePixel(display, screenNum);
- }
-
- // allocate colors in shared colormap
- } else {
- if (rgbCubeSize > xMaxRGBCube) {
- rgbCubeSize = xMaxRGBCube;
- }
- ok = gFalse;
- for (rgbCubeSize = rgbCubeSizeA; rgbCubeSize >= 2; --rgbCubeSize) {
- ok = gTrue;
- n = 0;
- for (r = 0; r < rgbCubeSize && ok; ++r) {
- for (g = 0; g < rgbCubeSize && ok; ++g) {
- for (b = 0; b < rgbCubeSize && ok; ++b) {
- if (n == 0) {
- colors[n] = BlackPixel(display, screenNum);
- ++n;
- } else {
- xcolor.red = (r * 65535) / (rgbCubeSize - 1);
- xcolor.green = (g * 65535) / (rgbCubeSize - 1);
- xcolor.blue = (b * 65535) / (rgbCubeSize - 1);
- if (XAllocColor(display, colormap, &xcolor)) {
- colors[n++] = xcolor.pixel;
- } else {
- ok = gFalse;
- }
- }
- }
- }
- }
- if (ok) {
- break;
- }
- XFreeColors(display, colormap, &colors[1], n-1, 0);
- }
- if (!ok) {
- rgbCubeSize = 1;
- colors[0] = BlackPixel(display, screenNum);
- colors[1] = WhitePixel(display, screenNum);
- }
- }
- }
-}
-
-void XPDFCore::initWindow() {
- Arg args[20];
- int n;
-
- // create the cursors
- busyCursor = XCreateFontCursor(display, XC_watch);
- linkCursor = XCreateFontCursor(display, XC_hand2);
- selectCursor = XCreateFontCursor(display, XC_cross);
- currentCursor = 0;
-
- // create the scrolled window and scrollbars
- n = 0;
- XtSetArg(args[n], XmNscrollingPolicy, XmAPPLICATION_DEFINED); ++n;
- XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n;
- scrolledWin = XmCreateScrolledWindow(parentWidget, "scroll", args, n);
- XtManageChild(scrolledWin);
- n = 0;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- XtSetArg(args[n], XmNminimum, 0); ++n;
- XtSetArg(args[n], XmNmaximum, 1); ++n;
- XtSetArg(args[n], XmNsliderSize, 1); ++n;
- XtSetArg(args[n], XmNvalue, 0); ++n;
- XtSetArg(args[n], XmNincrement, 1); ++n;
- XtSetArg(args[n], XmNpageIncrement, 1); ++n;
- hScrollBar = XmCreateScrollBar(scrolledWin, "hScrollBar", args, n);
- if (!fullScreen) {
- XtManageChild(hScrollBar);
- }
- XtAddCallback(hScrollBar, XmNvalueChangedCallback,
- &hScrollChangeCbk, (XtPointer)this);
-#ifndef DISABLE_SMOOTH_SCROLL
- XtAddCallback(hScrollBar, XmNdragCallback,
- &hScrollDragCbk, (XtPointer)this);
-#endif
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
- XtSetArg(args[n], XmNminimum, 0); ++n;
- XtSetArg(args[n], XmNmaximum, 1); ++n;
- XtSetArg(args[n], XmNsliderSize, 1); ++n;
- XtSetArg(args[n], XmNvalue, 0); ++n;
- XtSetArg(args[n], XmNincrement, 1); ++n;
- XtSetArg(args[n], XmNpageIncrement, 1); ++n;
- vScrollBar = XmCreateScrollBar(scrolledWin, "vScrollBar", args, n);
- if (!fullScreen) {
- XtManageChild(vScrollBar);
- }
- XtAddCallback(vScrollBar, XmNvalueChangedCallback,
- &vScrollChangeCbk, (XtPointer)this);
-#ifndef DISABLE_SMOOTH_SCROLL
- XtAddCallback(vScrollBar, XmNdragCallback,
- &vScrollDragCbk, (XtPointer)this);
-#endif
-
- // create the drawing area
- n = 0;
- XtSetArg(args[n], XmNshadowType, XmSHADOW_IN); ++n;
- XtSetArg(args[n], XmNmarginWidth, 0); ++n;
- XtSetArg(args[n], XmNmarginHeight, 0); ++n;
- if (fullScreen) {
- XtSetArg(args[n], XmNshadowThickness, 0); ++n;
- }
- drawAreaFrame = XmCreateFrame(scrolledWin, "drawAreaFrame", args, n);
- XtManageChild(drawAreaFrame);
- n = 0;
- XtSetArg(args[n], XmNresizePolicy, XmRESIZE_ANY); ++n;
- XtSetArg(args[n], XmNwidth, 700); ++n;
- XtSetArg(args[n], XmNheight, 500); ++n;
- drawArea = XmCreateDrawingArea(drawAreaFrame, "drawArea", args, n);
- XtManageChild(drawArea);
- XtAddCallback(drawArea, XmNresizeCallback, &resizeCbk, (XtPointer)this);
- XtAddCallback(drawArea, XmNexposeCallback, &redrawCbk, (XtPointer)this);
- XtAddCallback(drawArea, XmNinputCallback, &inputCbk, (XtPointer)this);
- resizeCbk(drawArea, this, NULL);
-
- // set up mouse motion translations
- XtOverrideTranslations(drawArea, XtParseTranslationTable(
- "<Btn1Down>:DrawingAreaInput()\n"
- "<Btn1Up>:DrawingAreaInput()\n"
- "<Btn1Motion>:DrawingAreaInput()\n"
- "<Motion>:DrawingAreaInput()"));
-
- // can't create a GC until the window gets mapped
- drawAreaGC = NULL;
-}
-
-void XPDFCore::hScrollChangeCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(data->value, core->scrollY);
-}
-
-void XPDFCore::hScrollDragCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(data->value, core->scrollY);
-}
-
-void XPDFCore::vScrollChangeCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(core->scrollX, data->value);
-}
-
-void XPDFCore::vScrollDragCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(core->scrollX, data->value);
-}
-
-void XPDFCore::resizeCbk(Widget widget, XtPointer ptr, XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XEvent event;
- Widget top;
- Window rootWin;
- int x1, y1;
- Guint w1, h1, bw1, depth1;
- Arg args[2];
- int n;
- Dimension w, h;
- int sx, sy;
-
- // find the top-most widget which has an associated window, and look
- // for a pending ConfigureNotify in the event queue -- if there is
- // one, and it specifies a different width or height, that means
- // we're still resizing, and we want to skip the current event
- for (top = core->parentWidget;
- XtParent(top) && XtWindow(XtParent(top));
- top = XtParent(top)) ;
- if (XCheckTypedWindowEvent(core->display, XtWindow(top),
- ConfigureNotify, &event)) {
- XPutBackEvent(core->display, &event);
- XGetGeometry(core->display, event.xconfigure.window,
- &rootWin, &x1, &y1, &w1, &h1, &bw1, &depth1);
- if ((Guint)event.xconfigure.width != w1 ||
- (Guint)event.xconfigure.height != h1) {
- return;
- }
- }
-
- n = 0;
- XtSetArg(args[n], XmNwidth, &w); ++n;
- XtSetArg(args[n], XmNheight, &h); ++n;
- XtGetValues(core->drawArea, args, n);
- core->drawAreaWidth = (int)w;
- core->drawAreaHeight = (int)h;
- if (core->zoom == zoomPage || core->zoom == zoomWidth) {
- sx = sy = -1;
- } else {
- sx = core->scrollX;
- sy = core->scrollY;
- }
- core->update(core->topPage, sx, sy, core->zoom, core->rotate, gTrue, gFalse,
- gFalse);
-}
-
-void XPDFCore::redrawCbk(Widget widget, XtPointer ptr, XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmDrawingAreaCallbackStruct *data = (XmDrawingAreaCallbackStruct *)callData;
- int x, y, w, h;
-
- if (data->reason == XmCR_EXPOSE) {
- x = data->event->xexpose.x;
- y = data->event->xexpose.y;
- w = data->event->xexpose.width;
- h = data->event->xexpose.height;
- } else {
- x = 0;
- y = 0;
- w = core->drawAreaWidth;
- h = core->drawAreaHeight;
- }
- core->redrawWindow(x, y, w, h, gFalse);
-}
-
-void XPDFCore::inputCbk(Widget widget, XtPointer ptr, XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmDrawingAreaCallbackStruct *data = (XmDrawingAreaCallbackStruct *)callData;
- LinkAction *action;
- int pg, x, y;
- double xu, yu;
- const char *s;
- KeySym key;
- GBool ok;
-
- switch (data->event->type) {
- case ButtonPress:
- if (*core->mouseCbk) {
- (*core->mouseCbk)(core->mouseCbkData, data->event);
- }
- break;
- case ButtonRelease:
- if (*core->mouseCbk) {
- (*core->mouseCbk)(core->mouseCbkData, data->event);
- }
- break;
- case MotionNotify:
- if (core->doc && core->doc->getNumPages() > 0) {
- ok = core->cvtWindowToDev(data->event->xmotion.x, data->event->xmotion.y,
- &pg, &x, &y);
- if (core->dragging) {
- if (ok) {
- core->moveSelection(pg, x, y);
- }
- } else if (core->hyperlinksEnabled) {
- core->cvtDevToUser(pg, x, y, &xu, &yu);
- if (ok && (action = core->findLink(pg, xu, yu))) {
- core->setCursor(core->linkCursor);
- if (action != core->linkAction) {
- core->linkAction = action;
- if (core->updateCbk) {
- s = "";
- switch (action->getKind()) {
- case actionGoTo:
- s = "[internal link]";
- break;
- case actionGoToR:
- s = ((LinkGoToR *)action)->getFileName()->getCString();
- break;
- case actionLaunch:
- s = ((LinkLaunch *)action)->getFileName()->getCString();
- break;
- case actionURI:
- s = ((LinkURI *)action)->getURI()->getCString();
- break;
- case actionNamed:
- s = ((LinkNamed *)action)->getName()->getCString();
- break;
- case actionMovie:
- s = "[movie]";
- break;
- case actionJavaScript:
- case actionSubmitForm:
- case actionHide:
- case actionUnknown:
- s = "[unknown link]";
- break;
- }
- (*core->updateCbk)(core->updateCbkData, NULL, -1, -1, s);
- }
- }
- } else {
- core->setCursor(None);
- if (core->linkAction) {
- core->linkAction = NULL;
- if (core->updateCbk) {
- (*core->updateCbk)(core->updateCbkData, NULL, -1, -1, "");
- }
- }
- }
- }
- }
- if (core->panning) {
- core->scrollTo(core->scrollX - (data->event->xmotion.x - core->panMX),
- core->scrollY - (data->event->xmotion.y - core->panMY));
- core->panMX = data->event->xmotion.x;
- core->panMY = data->event->xmotion.y;
- }
- break;
- case KeyPress:
- if (core->keyPressCbk) {
- key = XLookupKeysym(&data->event->xkey,
- (data->event->xkey.state & ShiftMask) ? 1 : 0);
- (*core->keyPressCbk)(core->keyPressCbkData,
- key, data->event->xkey.state, data->event);
- }
- break;
- }
-}
-
-PDFCoreTile *XPDFCore::newTile(int xDestA, int yDestA) {
- return new XPDFCoreTile(xDestA, yDestA);
-}
-
-void XPDFCore::updateTileData(PDFCoreTile *tileA, int xSrc, int ySrc,
- int width, int height, GBool composited) {
- XPDFCoreTile *tile = (XPDFCoreTile *)tileA;
- XImage *image;
- SplashColorPtr dataPtr, p;
- Gulong pixel;
- Guchar *ap;
- Guchar alpha, alpha1;
- int w, h, bw, x, y, r, g, b, gray;
- int *errDownR, *errDownG, *errDownB;
- int errRightR, errRightG, errRightB;
- int errDownRightR, errDownRightG, errDownRightB;
- int r0, g0, b0, re, ge, be;
-
- if (!tile->image) {
- w = tile->xMax - tile->xMin;
- h = tile->yMax - tile->yMin;
- image = XCreateImage(display, visual, depth, ZPixmap, 0, NULL, w, h, 8, 0);
- image->data = (char *)gmallocn(h, image->bytes_per_line);
- tile->image = image;
- } else {
- image = (XImage *)tile->image;
- }
-
- //~ optimize for known XImage formats
- bw = tile->bitmap->getRowSize();
- dataPtr = tile->bitmap->getDataPtr();
-
- if (trueColor) {
- for (y = 0; y < height; ++y) {
- p = dataPtr + (ySrc + y) * bw + xSrc * 3;
- if (!composited && tile->bitmap->getAlphaPtr()) {
- ap = tile->bitmap->getAlphaPtr() +
- (ySrc + y) * tile->bitmap->getWidth() + xSrc;
- } else {
- ap = NULL;
- }
- for (x = 0; x < width; ++x) {
- r = splashRGB8R(p);
- g = splashRGB8G(p);
- b = splashRGB8B(p);
- if (ap) {
- alpha = *ap++;
- alpha1 = 255 - alpha;
- r = div255(alpha1 * paperColor[0] + alpha * r);
- g = div255(alpha1 * paperColor[1] + alpha * g);
- b = div255(alpha1 * paperColor[2] + alpha * b);
- }
- r >>= rDiv;
- g >>= gDiv;
- b >>= bDiv;
- pixel = ((Gulong)r << rShift) +
- ((Gulong)g << gShift) +
- ((Gulong)b << bShift);
- XPutPixel(image, xSrc + x, ySrc + y, pixel);
- p += 3;
- }
- }
- } else if (rgbCubeSize == 1) {
- //~ this should really use splashModeMono, with non-clustered dithering
- for (y = 0; y < height; ++y) {
- p = dataPtr + (ySrc + y) * bw + xSrc * 3;
- if (!composited && tile->bitmap->getAlphaPtr()) {
- ap = tile->bitmap->getAlphaPtr() +
- (ySrc + y) * tile->bitmap->getWidth() + xSrc;
- } else {
- ap = NULL;
- }
- for (x = 0; x < width; ++x) {
- r = splashRGB8R(p);
- g = splashRGB8G(p);
- b = splashRGB8B(p);
- if (ap) {
- alpha = *ap++;
- alpha1 = 255 - alpha;
- r = div255(alpha1 * paperColor[0] + alpha * r);
- g = div255(alpha1 * paperColor[1] + alpha * g);
- b = div255(alpha1 * paperColor[2] + alpha * b);
- }
- gray = (int)(0.299 * r + 0.587 * g + 0.114 * b + 0.5);
- if (gray < 128) {
- pixel = colors[0];
- } else {
- pixel = colors[1];
- }
- XPutPixel(image, xSrc + x, ySrc + y, pixel);
- p += 3;
- }
- }
- } else {
- // do Floyd-Steinberg dithering on the whole bitmap
- errDownR = (int *)gmallocn(width + 2, sizeof(int));
- errDownG = (int *)gmallocn(width + 2, sizeof(int));
- errDownB = (int *)gmallocn(width + 2, sizeof(int));
- errRightR = errRightG = errRightB = 0;
- errDownRightR = errDownRightG = errDownRightB = 0;
- memset(errDownR, 0, (width + 2) * sizeof(int));
- memset(errDownG, 0, (width + 2) * sizeof(int));
- memset(errDownB, 0, (width + 2) * sizeof(int));
- for (y = 0; y < height; ++y) {
- p = dataPtr + (ySrc + y) * bw + xSrc * 3;
- if (!composited && tile->bitmap->getAlphaPtr()) {
- ap = tile->bitmap->getAlphaPtr() +
- (ySrc + y) * tile->bitmap->getWidth() + xSrc;
- } else {
- ap = NULL;
- }
- for (x = 0; x < width; ++x) {
- r = splashRGB8R(p);
- g = splashRGB8G(p);
- b = splashRGB8B(p);
- if (ap) {
- alpha = *ap++;
- alpha1 = 255 - alpha;
- r = div255(alpha1 * paperColor[0] + alpha * r);
- g = div255(alpha1 * paperColor[1] + alpha * g);
- b = div255(alpha1 * paperColor[2] + alpha * b);
- }
- r0 = r + errRightR + errDownR[x+1];
- g0 = g + errRightG + errDownG[x+1];
- b0 = b + errRightB + errDownB[x+1];
- if (r0 < 0) {
- r = 0;
- } else if (r0 >= 255) {
- r = rgbCubeSize - 1;
- } else {
- r = div255(r0 * (rgbCubeSize - 1));
- }
- if (g0 < 0) {
- g = 0;
- } else if (g0 >= 255) {
- g = rgbCubeSize - 1;
- } else {
- g = div255(g0 * (rgbCubeSize - 1));
- }
- if (b0 < 0) {
- b = 0;
- } else if (b0 >= 255) {
- b = rgbCubeSize - 1;
- } else {
- b = div255(b0 * (rgbCubeSize - 1));
- }
- re = r0 - ((r << 8) - r) / (rgbCubeSize - 1);
- ge = g0 - ((g << 8) - g) / (rgbCubeSize - 1);
- be = b0 - ((b << 8) - b) / (rgbCubeSize - 1);
- errRightR = (re * 7) >> 4;
- errRightG = (ge * 7) >> 4;
- errRightB = (be * 7) >> 4;
- errDownR[x] += (re * 3) >> 4;
- errDownG[x] += (ge * 3) >> 4;
- errDownB[x] += (be * 3) >> 4;
- errDownR[x+1] = ((re * 5) >> 4) + errDownRightR;
- errDownG[x+1] = ((ge * 5) >> 4) + errDownRightG;
- errDownB[x+1] = ((be * 5) >> 4) + errDownRightB;
- errDownRightR = re >> 4;
- errDownRightG = ge >> 4;
- errDownRightB = be >> 4;
- pixel = colors[(r * rgbCubeSize + g) * rgbCubeSize + b];
- XPutPixel(image, xSrc + x, ySrc + y, pixel);
- p += 3;
- }
- }
- gfree(errDownR);
- gfree(errDownG);
- gfree(errDownB);
- }
-}
-
-void XPDFCore::redrawRect(PDFCoreTile *tileA, int xSrc, int ySrc,
- int xDest, int yDest, int width, int height,
- GBool composited) {
- XPDFCoreTile *tile = (XPDFCoreTile *)tileA;
- Window drawAreaWin;
- XGCValues gcValues;
-
- // create a GC for the drawing area
- drawAreaWin = XtWindow(drawArea);
- if (!drawAreaGC) {
- gcValues.foreground = mattePixel;
- drawAreaGC = XCreateGC(display, drawAreaWin, GCForeground, &gcValues);
- }
-
- // draw the document
- if (tile) {
- XPutImage(display, drawAreaWin, drawAreaGC, tile->image,
- xSrc, ySrc, xDest, yDest, width, height);
-
- // draw the background
- } else {
- XFillRectangle(display, drawAreaWin, drawAreaGC,
- xDest, yDest, width, height);
- }
-
- XFlush(display);
-}
-
-void XPDFCore::updateScrollbars() {
- Arg args[20];
- int n;
- int maxPos;
-
- if (pages->getLength() > 0) {
- if (continuousMode) {
- maxPos = maxPageW;
- } else {
- maxPos = ((PDFCorePage *)pages->get(0))->w;
- }
- } else {
- maxPos = 1;
- }
- if (maxPos < drawAreaWidth) {
- maxPos = drawAreaWidth;
- }
- n = 0;
- XtSetArg(args[n], XmNvalue, scrollX); ++n;
- XtSetArg(args[n], XmNmaximum, maxPos); ++n;
- XtSetArg(args[n], XmNsliderSize, drawAreaWidth); ++n;
- XtSetArg(args[n], XmNincrement, 16); ++n;
- XtSetArg(args[n], XmNpageIncrement, drawAreaWidth); ++n;
- XtSetValues(hScrollBar, args, n);
-
- if (pages->getLength() > 0) {
- if (continuousMode) {
- maxPos = totalDocH;
- } else {
- maxPos = ((PDFCorePage *)pages->get(0))->h;
- }
- } else {
- maxPos = 1;
- }
- if (maxPos < drawAreaHeight) {
- maxPos = drawAreaHeight;
- }
- n = 0;
- XtSetArg(args[n], XmNvalue, scrollY); ++n;
- XtSetArg(args[n], XmNmaximum, maxPos); ++n;
- XtSetArg(args[n], XmNsliderSize, drawAreaHeight); ++n;
- XtSetArg(args[n], XmNincrement, 16); ++n;
- XtSetArg(args[n], XmNpageIncrement, drawAreaHeight); ++n;
- XtSetValues(vScrollBar, args, n);
-}
-
-void XPDFCore::setCursor(Cursor cursor) {
- Window topWin;
-
- if (cursor == currentCursor) {
- return;
- }
- if (!(topWin = XtWindow(shell))) {
- return;
- }
- if (cursor == None) {
- XUndefineCursor(display, topWin);
- } else {
- XDefineCursor(display, topWin, cursor);
- }
- XFlush(display);
- currentCursor = cursor;
-}
-
-GBool XPDFCore::doQuestionDialog(const char *title, GString *msg) {
- return doDialog(XmDIALOG_QUESTION, gTrue, title, msg);
-}
-
-void XPDFCore::doInfoDialog(const char *title, GString *msg) {
- doDialog(XmDIALOG_INFORMATION, gFalse, title, msg);
-}
-
-void XPDFCore::doErrorDialog(const char *title, GString *msg) {
- doDialog(XmDIALOG_ERROR, gFalse, title, msg);
-}
-
-GBool XPDFCore::doDialog(int type, GBool hasCancel,
- const char *title, GString *msg) {
- Widget dialog, scroll, text;
- XtAppContext appContext;
- Arg args[20];
- int n;
- XmString s1, s2;
- XEvent event;
-
- n = 0;
- XtSetArg(args[n], XmNdialogType, type); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- s1 = XmStringCreateLocalized((char *)title);
- XtSetArg(args[n], XmNdialogTitle, s1); ++n;
- s2 = NULL; // make gcc happy
- if (msg->getLength() <= 80) {
- s2 = XmStringCreateLocalized(msg->getCString());
- XtSetArg(args[n], XmNmessageString, s2); ++n;
- }
- dialog = XmCreateMessageDialog(drawArea, "questionDialog", args, n);
- XmStringFree(s1);
- if (msg->getLength() <= 80) {
- XmStringFree(s2);
- } else {
- n = 0;
- XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
- if (drawAreaWidth > 300) {
- XtSetArg(args[n], XmNwidth, drawAreaWidth - 100); ++n;
- }
- scroll = XmCreateScrolledWindow(dialog, "scroll", args, n);
- XtManageChild(scroll);
- n = 0;
- XtSetArg(args[n], XmNeditable, False); ++n;
- XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); ++n;
- XtSetArg(args[n], XmNvalue, msg->getCString()); ++n;
- XtSetArg(args[n], XmNshadowThickness, 0); ++n;
- text = XmCreateText(scroll, "text", args, n);
- XtManageChild(text);
- }
- XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
- XtAddCallback(dialog, XmNokCallback,
- &dialogOkCbk, (XtPointer)this);
- if (hasCancel) {
- XtAddCallback(dialog, XmNcancelCallback,
- &dialogCancelCbk, (XtPointer)this);
- } else {
- XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
- }
-
- XtManageChild(dialog);
-
- appContext = XtWidgetToApplicationContext(dialog);
- dialogDone = 0;
- do {
- XtAppNextEvent(appContext, &event);
- XtDispatchEvent(&event);
- } while (!dialogDone);
-
- XtUnmanageChild(dialog);
- XtDestroyWidget(dialog);
-
- return dialogDone > 0;
-}
-
-void XPDFCore::dialogOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = 1;
-}
-
-void XPDFCore::dialogCancelCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = -1;
-}
-
-//------------------------------------------------------------------------
-// password dialog
-//------------------------------------------------------------------------
-
-void XPDFCore::initPasswordDialog() {
- Widget row, label, okBtn, cancelBtn;
- Arg args[20];
- int n;
- XmString s;
-
- //----- dialog
- n = 0;
- s = XmStringCreateLocalized(xpdfAppName ": Password");
- XtSetArg(args[n], XmNdialogTitle, s); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- passwordDialog = XmCreateFormDialog(drawArea, "passwordDialog", args, n);
- XmStringFree(s);
-
- //----- message
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- s = XmStringCreateLocalized("This document requires a password.");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(passwordDialog, "msg", args, n);
- XmStringFree(s);
- XtManageChild(label);
-
- //----- label and password entry
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, label); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
- row = XmCreateRowColumn(passwordDialog, "row", args, n);
- XtManageChild(row);
- n = 0;
- s = XmStringCreateLocalized("Password: ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(row, "label", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- XtSetArg(args[n], XmNcolumns, 16); ++n;
- passwordText = XmCreateTextField(row, "text", args, n);
- XtManageChild(passwordText);
- XtAddCallback(passwordText, XmNmodifyVerifyCallback,
- &passwordTextVerifyCbk, this);
-
- //----- "Ok" and "Cancel" buttons
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- okBtn = XmCreatePushButton(passwordDialog, "Ok", args, n);
- XtManageChild(okBtn);
- XtAddCallback(okBtn, XmNactivateCallback,
- &passwordOkCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- cancelBtn = XmCreatePushButton(passwordDialog, "Cancel", args, n);
- XtManageChild(cancelBtn);
- XtAddCallback(cancelBtn, XmNactivateCallback,
- &passwordCancelCbk, (XtPointer)this);
- 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);
-}
-
-void XPDFCore::passwordTextVerifyCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmTextVerifyCallbackStruct *data =
- (XmTextVerifyCallbackStruct *)callData;
- int i, n;
-
- i = (int)data->startPos;
- n = (int)data->endPos - i;
- if (i > core->password->getLength()) {
- i = core->password->getLength();
- }
- if (i + n > core->password->getLength()) {
- n = core->password->getLength() - i;
- }
- core->password->del(i, n);
- core->password->insert(i, data->text->ptr, data->text->length);
-
- for (i = 0; i < data->text->length; ++i) {
- data->text->ptr[i] = '*';
- }
- data->doit = True;
-}
-
-void XPDFCore::passwordOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = 1;
-}
-
-void XPDFCore::passwordCancelCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = -1;
-}
-
-GString *XPDFCore::getPassword() {
- XtAppContext appContext;
- XEvent event;
-
- // NB: set <password> before calling XmTextFieldSetString, because
- // SetString will trigger a call to passwordTextVerifyCbk, which
- // expects <password> to be valid
- password = new GString();
- XmTextFieldSetString(passwordText, "");
- XtManageChild(passwordDialog);
-
- appContext = XtWidgetToApplicationContext(passwordDialog);
- dialogDone = 0;
- do {
- XtAppNextEvent(appContext, &event);
- XtDispatchEvent(&event);
- } while (!dialogDone);
- XtUnmanageChild(passwordDialog);
-
- if (dialogDone < 0) {
- delete password;
- return NULL;
- }
- return password;
-}