1
//========================================================================
5
// Copyright 2002 Glyph & Cog, LLC
7
//========================================================================
11
#ifdef USE_GCC_PRAGMAS
12
#pragma implementation
18
#include "XPDFViewer.h"
22
// these macro defns conflict with xpdf's Object class
23
#ifdef LESSTIF_VERSION
31
//------------------------------------------------------------------------
33
#define remoteCmdSize 512
35
//------------------------------------------------------------------------
37
static String fallbackResources[] = {
38
"*XmTextField.fontList: -*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1",
39
"*.fontList: -*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
40
"*XmTextField.translations: #override\\n"
41
" Ctrl<Key>a:beginning-of-line()\\n"
42
" Ctrl<Key>b:backward-character()\\n"
43
" Ctrl<Key>d:delete-next-character()\\n"
44
" Ctrl<Key>e:end-of-line()\\n"
45
" Ctrl<Key>f:forward-character()\\n"
46
" Ctrl<Key>u:beginning-of-line()delete-to-end-of-line()\\n"
47
" Ctrl<Key>k:delete-to-end-of-line()\\n",
51
static XrmOptionDescRec xOpts[] = {
52
{"-display", ".display", XrmoptionSepArg, NULL},
53
{"-foreground", "*Foreground", XrmoptionSepArg, NULL},
54
{"-fg", "*Foreground", XrmoptionSepArg, NULL},
55
{"-background", "*Background", XrmoptionSepArg, NULL},
56
{"-bg", "*Background", XrmoptionSepArg, NULL},
57
{"-geometry", ".geometry", XrmoptionSepArg, NULL},
58
{"-g", ".geometry", XrmoptionSepArg, NULL},
59
{"-font", "*.fontList", XrmoptionSepArg, NULL},
60
{"-fn", "*.fontList", XrmoptionSepArg, NULL},
61
{"-title", ".title", XrmoptionSepArg, NULL},
62
{"-cmap", ".installCmap", XrmoptionNoArg, (XPointer)"on"},
63
{"-rgb", ".rgbCubeSize", XrmoptionSepArg, NULL},
64
{"-rv", ".reverseVideo", XrmoptionNoArg, (XPointer)"true"},
65
{"-papercolor", ".paperColor", XrmoptionSepArg, NULL},
66
{"-z", ".initialZoom", XrmoptionSepArg, NULL}
69
#define nXOpts (sizeof(xOpts) / sizeof(XrmOptionDescRec))
71
struct XPDFAppResources {
82
static Bool defInstallCmap = False;
83
static int defRGBCubeSize = defaultRGBCube;
84
static Bool defReverseVideo = False;
85
static Bool defViKeys = False;
87
static XtResource xResources[] = {
88
{ "geometry", "Geometry", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, geometry), XtRString, (XtPointer)NULL },
89
{ "title", "Title", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, title), XtRString, (XtPointer)NULL },
90
{ "installCmap", "InstallCmap", XtRBool, sizeof(Bool), XtOffsetOf(XPDFAppResources, installCmap), XtRBool, (XtPointer)&defInstallCmap },
91
{ "rgbCubeSize", "RgbCubeSize", XtRInt, sizeof(int), XtOffsetOf(XPDFAppResources, rgbCubeSize), XtRInt, (XtPointer)&defRGBCubeSize },
92
{ "reverseVideo", "ReverseVideo", XtRBool, sizeof(Bool), XtOffsetOf(XPDFAppResources, reverseVideo), XtRBool, (XtPointer)&defReverseVideo },
93
{ "paperColor", "PaperColor", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, paperColor), XtRString, (XtPointer)NULL },
94
{ "initialZoom", "InitialZoom", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, initialZoom), XtRString, (XtPointer)NULL },
95
{ "viKeys", "ViKeys", XtRBool, sizeof(Bool), XtOffsetOf(XPDFAppResources, viKeys), XtRBool, (XtPointer)&defViKeys }
98
#define nXResources (sizeof(xResources) / sizeof(XtResource))
100
//------------------------------------------------------------------------
102
//------------------------------------------------------------------------
104
#if 0 //~ for debugging
105
static int xErrorHandler(Display *display, XErrorEvent *ev) {
106
printf("X error:\n");
107
printf(" resource ID = %08lx\n", ev->resourceid);
108
printf(" serial = %lu\n", ev->serial);
109
printf(" error_code = %d\n", ev->error_code);
110
printf(" request_code = %d\n", ev->request_code);
111
printf(" minor_code = %d\n", ev->minor_code);
117
XPDFApp::XPDFApp(int *argc, char *argv[]) {
118
appShell = XtAppInitialize(&appContext, xpdfAppName, xOpts, nXOpts,
119
argc, argv, fallbackResources, NULL, 0);
120
display = XtDisplay(appShell);
121
screenNum = XScreenNumberOfScreen(XtScreen(appShell));
123
XtVaSetValues(XmGetXmDisplay(XtDisplay(appShell)),
124
XmNenableButtonTab, True, NULL);
127
// Drag-and-drop appears to be buggy -- I'm seeing weird crashes
128
// deep in the Motif code when I destroy widgets in the XpdfForms
129
// code. Xpdf doesn't use it, so just turn it off.
130
XtVaSetValues(XmGetXmDisplay(XtDisplay(appShell)),
131
XmNdragInitiatorProtocolStyle, XmDRAG_NONE,
132
XmNdragReceiverProtocolStyle, XmDRAG_NONE,
136
#if 0 //~ for debugging
137
XSynchronize(display, True);
138
XSetErrorHandler(&xErrorHandler);
148
viewers = new GList();
152
void XPDFApp::getResources() {
153
XPDFAppResources resources;
157
XtGetApplicationResources(appShell, &resources, xResources, nXResources,
159
geometry = resources.geometry ? new GString(resources.geometry)
161
title = resources.title ? new GString(resources.title) : (GString *)NULL;
162
installCmap = (GBool)resources.installCmap;
163
rgbCubeSize = resources.rgbCubeSize;
164
reverseVideo = (GBool)resources.reverseVideo;
165
paperColor = reverseVideo ? BlackPixel(display, screenNum) :
166
WhitePixel(display, screenNum);
167
if (resources.paperColor) {
168
XtVaGetValues(appShell, XmNcolormap, &colormap, NULL);
169
if (XAllocNamedColor(display, colormap, resources.paperColor,
171
paperColor = xcol.pixel;
173
error(-1, "Couldn't allocate color '%s'", resources.paperColor);
176
initialZoom = resources.initialZoom ? new GString(resources.initialZoom)
178
viKeys = (GBool)resources.viKeys;
181
XPDFApp::~XPDFApp() {
182
deleteGList(viewers, XPDFViewer);
194
XPDFViewer *XPDFApp::open(GString *fileName, int page,
195
GString *ownerPassword, GString *userPassword) {
198
viewer = new XPDFViewer(this, fileName, page, NULL,
199
ownerPassword, userPassword);
200
if (!viewer->isOk()) {
204
if (remoteAtom != None) {
205
remoteViewer = viewer;
206
remoteWin = viewer->getWindow();
207
XtAddEventHandler(remoteWin, PropertyChangeMask, False,
208
&remoteMsgCbk, this);
209
XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin), CurrentTime);
211
viewers->append(viewer);
215
XPDFViewer *XPDFApp::openAtDest(GString *fileName, GString *dest,
216
GString *ownerPassword,
217
GString *userPassword) {
220
viewer = new XPDFViewer(this, fileName, 1, dest,
221
ownerPassword, userPassword);
222
if (!viewer->isOk()) {
226
if (remoteAtom != None) {
227
remoteViewer = viewer;
228
remoteWin = viewer->getWindow();
229
XtAddEventHandler(remoteWin, PropertyChangeMask, False,
230
&remoteMsgCbk, this);
231
XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin), CurrentTime);
233
viewers->append(viewer);
237
void XPDFApp::close(XPDFViewer *viewer, GBool closeLast) {
240
if (viewers->getLength() == 1) {
241
if (viewer != (XPDFViewer *)viewers->get(0)) {
250
for (i = 0; i < viewers->getLength(); ++i) {
251
if (((XPDFViewer *)viewers->get(i)) == viewer) {
253
if (remoteAtom != None && remoteViewer == viewer) {
254
remoteViewer = (XPDFViewer *)viewers->get(viewers->getLength() - 1);
255
remoteWin = remoteViewer->getWindow();
256
XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin),
266
void XPDFApp::quit() {
267
if (remoteAtom != None) {
268
XSetSelectionOwner(display, remoteAtom, None, CurrentTime);
270
while (viewers->getLength() > 0) {
271
delete (XPDFViewer *)viewers->del(0);
273
XtAppSetExitFlag(appContext);
276
void XPDFApp::run() {
277
XtAppMainLoop(appContext);
280
void XPDFApp::setRemoteName(char *remoteName) {
281
remoteAtom = XInternAtom(display, remoteName, False);
282
remoteXWin = XGetSelectionOwner(display, remoteAtom);
285
GBool XPDFApp::remoteServerRunning() {
286
return remoteXWin != None;
289
void XPDFApp::remoteOpen(GString *fileName, int page, GBool raise) {
290
char cmd[remoteCmdSize];
292
sprintf(cmd, "%c %d %.200s",
293
raise ? 'D' : 'd', page, fileName->getCString());
294
XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
295
PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1);
299
void XPDFApp::remoteOpenAtDest(GString *fileName, GString *dest, GBool raise) {
300
char cmd[remoteCmdSize];
302
sprintf(cmd, "%c +%.256s %.200s",
303
raise ? 'D' : 'd', dest->getCString(), fileName->getCString());
304
XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
305
PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1);
309
void XPDFApp::remoteRaise() {
310
XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
311
PropModeReplace, (Guchar *)"r", 2);
315
void XPDFApp::remoteQuit() {
316
XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
317
PropModeReplace, (Guchar *)"q", 2);
321
void XPDFApp::remoteMsgCbk(Widget widget, XtPointer ptr,
322
XEvent *event, Boolean *cont) {
323
XPDFApp *app = (XPDFApp *)ptr;
333
if (event->xproperty.atom != app->remoteAtom) {
340
if (XGetWindowProperty(app->display, XtWindow(app->remoteWin),
341
app->remoteAtom, 0, remoteCmdSize/4,
342
True, app->remoteAtom,
343
&type, &format, &size, &remain,
344
(Guchar **)&cmd) != Success) {
352
if (cmd[0] == 'D' || cmd[0] == 'r'){
353
XMapRaised(app->display, XtWindow(app->remoteWin));
354
XFlush(app->display);
357
// display file / page
358
if (cmd[0] == 'd' || cmd[0] == 'D') {
368
destName = new GString(p + 1);
373
fileName = new GString(q);
374
app->remoteViewer->open(fileName, page, destName);
377
XFree((XPointer)cmd);
383
} else if (cmd[0] == 'q') {