"Fossies" - the Fresh Open Source Software Archive 
Member "xpdf-4.04/xpdf-qt/XpdfApp.cc" (18 Apr 2022, 14925 Bytes) of package /linux/misc/xpdf-4.04.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "XpdfApp.cc" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
4.03_vs_4.04.
1 //========================================================================
2 //
3 // XpdfApp.cc
4 //
5 // Copyright 2015 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <QFileInfo>
14 #include <QLocalSocket>
15 #ifdef _WIN32
16 # include <shlobj.h>
17 #endif
18 #include "config.h"
19 #include "parseargs.h"
20 #include "GString.h"
21 #include "GList.h"
22 #include "gfile.h"
23 #include "GlobalParams.h"
24 #include "XpdfViewer.h"
25 #include "XpdfApp.h"
26 #include "gmempp.h"
27
28 //------------------------------------------------------------------------
29 // command line options
30 //------------------------------------------------------------------------
31
32 static GBool openArg = gFalse;
33 static GBool reverseVideoArg = gFalse;
34 static char paperColorArg[256] = "";
35 static char matteColorArg[256] = "";
36 static char fsMatteColorArg[256] = "";
37 static char initialZoomArg[256] = "";
38 static int rotateArg = 0;
39 static char antialiasArg[16] = "";
40 static char vectorAntialiasArg[16] = "";
41 static char textEncArg[128] = "";
42 static char passwordArg[33] = "";
43 static GBool fullScreen = gFalse;
44 static char remoteServerArg[256] = "";
45 static char tabStateFile[256] = "";
46 static char cfgFileArg[256] = "";
47 static GBool printCommandsArg = gFalse;
48 static GBool printVersionArg = gFalse;
49 static GBool printHelpArg = gFalse;
50
51 static ArgDesc argDesc[] = {
52 {"-open", argFlag, &openArg, 0, "open file using a default remote server"},
53 {"-rv", argFlag, &reverseVideoArg, 0, "reverse video"},
54 {"-papercolor", argString, paperColorArg, sizeof(paperColorArg), "color of paper background"},
55 {"-mattecolor", argString, matteColorArg, sizeof(matteColorArg), "color of matte background"},
56 {"-fsmattecolor", argString, fsMatteColorArg, sizeof(fsMatteColorArg), "color of matte background in full-screen mode"},
57 {"-z", argString, initialZoomArg, sizeof(initialZoomArg), "initial zoom level (percent, 'page', 'width')"},
58 {"-rot", argInt, &rotateArg, 0, "initial page rotation: 0, 90, 180, or 270"},
59 {"-aa", argString, antialiasArg, sizeof(antialiasArg), "enable font anti-aliasing: yes, no"},
60 {"-aaVector", argString, vectorAntialiasArg, sizeof(vectorAntialiasArg), "enable vector anti-aliasing: yes, no"},
61 {"-enc", argString, textEncArg, sizeof(textEncArg), "output text encoding name"},
62 {"-pw", argString, passwordArg, sizeof(passwordArg), "password (for encrypted files)"},
63 {"-fullscreen", argFlag, &fullScreen, 0, "run in full-screen (presentation) mode"},
64 {"-remote", argString, remoteServerArg, sizeof(remoteServerArg), "remote server mode - remaining args are commands"},
65 {"-cmd", argFlag, &printCommandsArg, 0, "print commands as they're executed"},
66 {"-tabstate", argString, tabStateFile, sizeof(tabStateFile), "file for saving/loading tab state"},
67 {"-cfg", argString, cfgFileArg, sizeof(cfgFileArg), "configuration file to use in place of .xpdfrc"},
68 {"-v", argFlag, &printVersionArg, 0, "print copyright and version info"},
69 {"-h", argFlag, &printHelpArg, 0, "print usage information"},
70 {"-help", argFlag, &printHelpArg, 0, "print usage information"},
71 {"--help", argFlag, &printHelpArg, 0, "print usage information"},
72 {"-?", argFlag, &printHelpArg, 0, "print usage information"},
73 {NULL}
74 };
75
76 //------------------------------------------------------------------------
77 // XpdfApp
78 //------------------------------------------------------------------------
79
80 static void mungeOpenFileName(const char *fileName, GString *cmd);
81
82 XpdfApp::XpdfApp(int &argc, char **argv):
83 QApplication(argc, argv)
84 {
85 XpdfViewer *viewer;
86 QLocalSocket *sock;
87 QString sockName;
88 const char *fileName, *dest;
89 GString *color, *cmd;
90 GBool ok;
91 int pg, i;
92
93 setApplicationName("XpdfReader");
94 setApplicationVersion(xpdfVersion);
95
96 ok = parseArgs(argDesc, &argc, argv);
97 if (!ok || printVersionArg || printHelpArg) {
98 fprintf(stderr, "xpdf version %s [www.xpdfreader.com]\n", xpdfVersion);
99 fprintf(stderr, "%s\n", xpdfCopyright);
100 if (!printVersionArg) {
101 printUsage("xpdf", "[<PDF-file> [:<page> | +<dest>]] ...", argDesc);
102 }
103 ::exit(99);
104 }
105
106 //--- set up GlobalParams; handle command line arguments
107 GlobalParams::defaultTextEncoding = "UCS-2";
108 globalParams = new GlobalParams(cfgFileArg);
109 #ifdef _WIN32
110 QString dir = applicationDirPath();
111 globalParams->setBaseDir(dir.toLocal8Bit().constData());
112 dir += "/t1fonts";
113 globalParams->setupBaseFonts(dir.toLocal8Bit().constData());
114 #else
115 globalParams->setupBaseFonts(NULL);
116 #endif
117 if (initialZoomArg[0]) {
118 globalParams->setInitialZoom(initialZoomArg);
119 }
120 reverseVideo = reverseVideoArg;
121 if (paperColorArg[0]) {
122 paperColor = QColor(paperColorArg);
123 } else {
124 color = globalParams->getPaperColor();
125 paperColor = QColor(color->getCString());
126 delete color;
127 }
128 if (reverseVideo) {
129 paperColor = QColor(255 - paperColor.red(),
130 255 - paperColor.green(),
131 255 - paperColor.blue());
132 }
133 if (matteColorArg[0]) {
134 matteColor = QColor(matteColorArg);
135 } else {
136 color = globalParams->getMatteColor();
137 matteColor = QColor(color->getCString());
138 delete color;
139 }
140 if (fsMatteColorArg[0]) {
141 fsMatteColor = QColor(fsMatteColorArg);
142 } else {
143 color = globalParams->getFullScreenMatteColor();
144 fsMatteColor = QColor(color->getCString());
145 delete color;
146 }
147 color = globalParams->getSelectionColor();
148 selectionColor = QColor(color->getCString());
149 delete color;
150 if (antialiasArg[0]) {
151 if (!globalParams->setAntialias(antialiasArg)) {
152 fprintf(stderr, "Bad '-aa' value on command line\n");
153 }
154 }
155 if (vectorAntialiasArg[0]) {
156 if (!globalParams->setVectorAntialias(vectorAntialiasArg)) {
157 fprintf(stderr, "Bad '-aaVector' value on command line\n");
158 }
159 }
160 if (textEncArg[0]) {
161 globalParams->setTextEncoding(textEncArg);
162 }
163 if (tabStateFile[0]) {
164 globalParams->setTabStateFile(tabStateFile);
165 }
166 if (printCommandsArg) {
167 globalParams->setPrintCommands(gTrue);
168 }
169
170 errorEventType = QEvent::registerEventType();
171
172 viewers = new GList();
173
174 //--- remote server mode
175 if (remoteServerArg[0]) {
176 sock = new QLocalSocket(this);
177 sockName = "xpdf_";
178 sockName += remoteServerArg;
179 sock->connectToServer(sockName, QIODevice::WriteOnly);
180 if (sock->waitForConnected(5000)) {
181 for (i = 1; i < argc; ++i) {
182 sock->write(argv[i]);
183 sock->write("\n");
184 }
185 while (sock->bytesToWrite()) {
186 sock->waitForBytesWritten(5000);
187 }
188 delete sock;
189 ::exit(0);
190 } else {
191 delete sock;
192 viewer = newWindow(gFalse, remoteServerArg);
193 for (i = 1; i < argc; ++i) {
194 viewer->execCmd(argv[i], NULL);
195 }
196 return;
197 }
198 }
199
200 //--- default remote server
201 if (openArg) {
202 sock = new QLocalSocket(this);
203 sockName = "xpdf_default";
204 sock->connectToServer(sockName, QIODevice::WriteOnly);
205 if (sock->waitForConnected(5000)) {
206 if (argc >= 2) {
207 cmd = new GString("openFileIn(");
208 mungeOpenFileName(argv[1], cmd);
209 cmd->append(",tab)\nraise\n");
210 sock->write(cmd->getCString());
211 delete cmd;
212 while (sock->bytesToWrite()) {
213 sock->waitForBytesWritten(5000);
214 }
215 }
216 delete sock;
217 ::exit(0);
218 } else {
219 delete sock;
220 if (argc >= 2) {
221 // on Windows: xpdf.cc converts command line args to UTF-8
222 // on Linux: command line args are in the local 8-bit charset
223 #ifdef _WIN32
224 QString qFileName = QString::fromUtf8(argv[1]);
225 #else
226 QString qFileName = QString::fromLocal8Bit(argv[1]);
227 #endif
228 openInNewWindow(qFileName, 1, "", rotateArg, passwordArg,
229 fullScreen, "default");
230 } else {
231 newWindow(fullScreen, "default");
232 }
233 return;
234 }
235 }
236
237 //--- load PDF file(s) requested on the command line
238 if (argc >= 2) {
239 i = 1;
240 while (i < argc) {
241 pg = -1;
242 dest = "";
243 if (i+1 < argc && argv[i+1][0] == ':') {
244 fileName = argv[i];
245 pg = atoi(argv[i+1] + 1);
246 i += 2;
247 } else if (i+1 < argc && argv[i+1][0] == '+') {
248 fileName = argv[i];
249 dest = argv[i+1] + 1;
250 i += 2;
251 } else {
252 fileName = argv[i];
253 ++i;
254 }
255 // on Windows: xpdf.cc converts command line args to UTF-8
256 // on Linux: command line args are in the local 8-bit charset
257 #ifdef _WIN32
258 QString qFileName = QString::fromUtf8(fileName);
259 #else
260 QString qFileName = QString::fromLocal8Bit(fileName);
261 #endif
262 if (viewers->getLength() > 0) {
263 ok = ((XpdfViewer *)viewers->get(0))
264 ->openInNewTab(qFileName, pg, dest, rotateArg,
265 passwordArg, gFalse);
266 } else {
267 ok = openInNewWindow(qFileName, pg, dest, rotateArg,
268 passwordArg, fullScreen);
269 }
270 }
271 } else {
272 newWindow(fullScreen);
273 }
274 }
275
276 // Process the file name for the "-open" flag: convert a relative path
277 // to absolute, and add escape chars as needed. Append the modified
278 // name to [cmd].
279 static void mungeOpenFileName(const char *fileName, GString *cmd) {
280 GString *path = new GString(fileName);
281 makePathAbsolute(path);
282 for (int i = 0; i < path->getLength(); ++i) {
283 char c = path->getChar(i);
284 if (c == '(' || c == ')' || c == ',' || c == '\x01') {
285 cmd->append('\x01');
286 }
287 cmd->append(c);
288 }
289 delete path;
290 }
291
292 XpdfApp::~XpdfApp() {
293 delete viewers;
294 delete globalParams;
295 }
296
297 int XpdfApp::getNumViewers() {
298 return viewers->getLength();
299 }
300
301 XpdfViewer *XpdfApp::newWindow(GBool fullScreen,
302 const char *remoteServerName) {
303 XpdfViewer *viewer = new XpdfViewer(this, fullScreen);
304 viewers->append(viewer);
305 if (remoteServerName) {
306 viewer->startRemoteServer(remoteServerName);
307 }
308 viewer->tweakSize();
309 viewer->show();
310 return viewer;
311 }
312
313 GBool XpdfApp::openInNewWindow(QString fileName, int page, QString dest,
314 int rotate, QString password, GBool fullScreen,
315 const char *remoteServerName) {
316 XpdfViewer *viewer;
317
318 viewer = XpdfViewer::create(this, fileName, page, dest, rotate,
319 password, fullScreen);
320 if (!viewer) {
321 return gFalse;
322 }
323 viewers->append(viewer);
324 if (remoteServerName) {
325 viewer->startRemoteServer(remoteServerName);
326 }
327 viewer->tweakSize();
328 viewer->show();
329 return gTrue;
330 }
331
332 void XpdfApp::closeWindowOrQuit(XpdfViewer *viewer) {
333 int i;
334
335 viewer->close();
336 for (i = 0; i < viewers->getLength(); ++i) {
337 if ((XpdfViewer *)viewers->get(i) == viewer) {
338 viewers->del(i);
339 break;
340 }
341 }
342 }
343
344 void XpdfApp::quit() {
345 XpdfViewer *viewer;
346
347 while (viewers->getLength()) {
348 viewer = (XpdfViewer *)viewers->del(0);
349 viewer->close();
350 }
351 QApplication::quit();
352 }
353
354 //------------------------------------------------------------------------
355
356 void XpdfApp::startUpdatePagesFile() {
357 if (!globalParams->getSavePageNumbers()) {
358 return;
359 }
360 readPagesFile();
361 savedPagesFileChanged = gFalse;
362 }
363
364 void XpdfApp::updatePagesFile(const QString &fileName, int pageNumber) {
365 if (!globalParams->getSavePageNumbers()) {
366 return;
367 }
368 if (fileName.isEmpty()) {
369 return;
370 }
371 QString canonicalFileName = QFileInfo(fileName).canonicalFilePath();
372 if (canonicalFileName.isEmpty()) {
373 return;
374 }
375 XpdfSavedPageNumber s(canonicalFileName, pageNumber);
376 for (int i = 0; i < maxSavedPageNumbers; ++i) {
377 XpdfSavedPageNumber next = savedPageNumbers[i];
378 savedPageNumbers[i] = s;
379 if (next.fileName == canonicalFileName) {
380 break;
381 }
382 s = next;
383 }
384 savedPagesFileChanged = gTrue;
385 }
386
387 void XpdfApp::finishUpdatePagesFile() {
388 if (!globalParams->getSavePageNumbers()) {
389 return;
390 }
391 if (savedPagesFileChanged) {
392 writePagesFile();
393 }
394 }
395
396 int XpdfApp::getSavedPageNumber(const QString &fileName) {
397 if (!globalParams->getSavePageNumbers()) {
398 return 1;
399 }
400 readPagesFile();
401 QString canonicalFileName = QFileInfo(fileName).canonicalFilePath();
402 if (canonicalFileName.isEmpty()) {
403 return 1;
404 }
405 for (int i = 0; i < maxSavedPageNumbers; ++i) {
406 if (savedPageNumbers[i].fileName == canonicalFileName) {
407 return savedPageNumbers[i].pageNumber;
408 }
409 }
410 return 1;
411 }
412
413 void XpdfApp::readPagesFile() {
414 // construct the file name (first time only)
415 if (savedPagesFileName.isEmpty()) {
416 #ifdef _WIN32
417 char path[MAX_PATH];
418 if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL,
419 SHGFP_TYPE_CURRENT, path) != S_OK) {
420 return;
421 }
422 savedPagesFileName = QString::fromLocal8Bit(path);
423 savedPagesFileName.append("/xpdf");
424 CreateDirectory(savedPagesFileName.toLocal8Bit().constData(), NULL);
425 savedPagesFileName.append("/xpdf.pages");
426 #else
427 GString *path = getHomeDir();
428 savedPagesFileName = QString::fromUtf8(path->getCString());
429 delete path;
430 savedPagesFileName.append("/.xpdf.pages");
431 #endif
432 }
433
434 // no change since last read, so no need to re-read
435 if (savedPagesFileTimestamp.isValid() &&
436 QFileInfo(savedPagesFileName).lastModified() == savedPagesFileTimestamp) {
437 return;
438 }
439
440 // mark all entries invalid
441 for (int i = 0; i < maxSavedPageNumbers; ++i) {
442 savedPageNumbers[i].fileName.clear();
443 savedPageNumbers[i].pageNumber = 1;
444 }
445
446 // read the file
447 FILE *f = openFile(savedPagesFileName.toUtf8().constData(), "rb");
448 if (!f) {
449 return;
450 }
451 char buf[1024];
452 if (!fgets(buf, sizeof(buf), f) ||
453 strcmp(buf, "xpdf.pages-1\n") != 0) {
454 fclose(f);
455 return;
456 }
457 int i = 0;
458 while (i < maxSavedPageNumbers && fgets(buf, sizeof(buf), f)) {
459 int n = (int)strlen(buf);
460 if (n > 0 && buf[n-1] == '\n') {
461 buf[n-1] = '\0';
462 }
463 char *p = buf;
464 while (*p != ' ' && *p) {
465 ++p;
466 }
467 if (!*p) {
468 continue;
469 }
470 *p++ = '\0';
471 savedPageNumbers[i].pageNumber = atoi(buf);
472 savedPageNumbers[i].fileName = QString::fromUtf8(p);
473 ++i;
474 }
475 fclose(f);
476
477 // save the timestamp
478 savedPagesFileTimestamp = QFileInfo(savedPagesFileName).lastModified();
479 }
480
481 void XpdfApp::writePagesFile() {
482 if (savedPagesFileName.isEmpty()) {
483 return;
484 }
485 FILE *f = openFile(savedPagesFileName.toUtf8().constData(), "wb");
486 if (!f) {
487 return;
488 }
489 fprintf(f, "xpdf.pages-1\n");
490 for (int i = 0; i < maxSavedPageNumbers; ++i) {
491 if (!savedPageNumbers[i].fileName.isEmpty()) {
492 fprintf(f, "%d %s\n",
493 savedPageNumbers[i].pageNumber,
494 savedPageNumbers[i].fileName.toUtf8().constData());
495 }
496 }
497 fclose(f);
498 savedPagesFileTimestamp = QFileInfo(savedPagesFileName).lastModified();
499 }