options.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. /*
  2. * options.c
  3. * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  4. *
  5. * Description:
  6. * Read and write the options
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #if defined(__riscos)
  12. #include "DeskLib:Error.h"
  13. #include "DeskLib:Wimp.h"
  14. #else
  15. #include <stdlib.h>
  16. #if defined(__dos) || defined(N_PLAT_NLM)
  17. extern int getopt(int, char **, const char *);
  18. #else
  19. #include <unistd.h>
  20. #endif /* __dos */
  21. #endif /* __riscos */
  22. #include "antiword.h"
  23. #if defined(__riscos)
  24. #define PARAGRAPH_BREAK "set paragraph_break=%d"
  25. #define AUTOFILETYPE "set autofiletype_allowed=%d"
  26. #define USE_OUTLINEFONTS "set use_outlinefonts=%d"
  27. #define SHOW_IMAGES "set show_images=%d"
  28. #define HIDE_HIDDEN_TEXT "set hide_hidden_text=%d"
  29. #define SCALE_FACTOR_START "set scale_factor_start=%d"
  30. #else
  31. #define LEAFNAME_SIZE (32+1)
  32. #endif /* __riscos */
  33. /* Current values for options */
  34. static options_type tOptionsCurr;
  35. #if defined(__riscos)
  36. /* Temporary values for options */
  37. static options_type tOptionsTemp;
  38. #else
  39. typedef struct papersize_tag {
  40. char szName[16]; /* Papersize name */
  41. USHORT usWidth; /* In points */
  42. USHORT usHeight; /* In points */
  43. } papersize_type;
  44. static const papersize_type atPaperSizes[] = {
  45. { "10x14", 720, 1008 },
  46. { "a3", 842, 1191 },
  47. { "a4", 595, 842 },
  48. { "a5", 420, 595 },
  49. { "b4", 729, 1032 },
  50. { "b5", 516, 729 },
  51. { "executive", 540, 720 },
  52. { "folio", 612, 936 },
  53. { "legal", 612, 1008 },
  54. { "letter", 612, 792 },
  55. { "note", 540, 720 },
  56. { "quarto", 610, 780 },
  57. { "statement", 396, 612 },
  58. { "tabloid", 792, 1224 },
  59. { "", 0, 0 },
  60. };
  61. #endif /* __riscos */
  62. /* Default values for options */
  63. static const options_type tOptionsDefault = {
  64. DEFAULT_SCREEN_WIDTH,
  65. #if defined(__riscos)
  66. conversion_draw,
  67. #else
  68. conversion_text,
  69. #endif /* __riscos */
  70. TRUE,
  71. TRUE,
  72. FALSE,
  73. encoding_latin_1,
  74. INT_MAX,
  75. INT_MAX,
  76. level_default,
  77. #if defined(__riscos)
  78. TRUE,
  79. DEFAULT_SCALE_FACTOR,
  80. #endif /* __riscos */
  81. };
  82. #if !defined(__riscos)
  83. /*
  84. * bCorrectPapersize - see if the papersize is correct
  85. *
  86. * TRUE if the papersize is correct, otherwise FALSE
  87. */
  88. static BOOL
  89. bCorrectPapersize(const char *szName, conversion_type eConversionType)
  90. {
  91. const papersize_type *pPaperSize;
  92. for (pPaperSize = atPaperSizes;
  93. pPaperSize->szName[0] != '\0';
  94. pPaperSize++) {
  95. if (!STRCEQ(pPaperSize->szName, szName)) {
  96. continue;
  97. }
  98. DBG_DEC(pPaperSize->usWidth);
  99. DBG_DEC(pPaperSize->usHeight);
  100. tOptionsCurr.eConversionType = eConversionType;
  101. tOptionsCurr.iPageHeight = (int)pPaperSize->usHeight;
  102. tOptionsCurr.iPageWidth = (int)pPaperSize->usWidth;
  103. return TRUE;
  104. }
  105. return FALSE;
  106. } /* end of bCorrectPapersize */
  107. /*
  108. * szCreateSuffix - create a suffix for the file
  109. *
  110. * Returns the suffix
  111. */
  112. static const char *
  113. szCreateSuffix(const char *szLeafname)
  114. {
  115. const char *pcDot;
  116. pcDot = strrchr(szLeafname, '.');
  117. if (pcDot != NULL && STRCEQ(pcDot, ".txt")) {
  118. /* There is already a .txt suffix, no need for another one */
  119. return "";
  120. }
  121. return ".txt";
  122. } /* end of szCreateSuffix */
  123. /*
  124. * eMappingFile2Encoding - convert the mapping file to an encoding
  125. */
  126. static encoding_type
  127. eMappingFile2Encoding(const char *szLeafname)
  128. {
  129. char szMappingFile[LEAFNAME_SIZE+4];
  130. fail(szLeafname == NULL);
  131. if (strlen(szLeafname) + 4 >= sizeof(szMappingFile)) {
  132. DBG_MSG(szLeafname);
  133. return encoding_latin_1;
  134. }
  135. sprintf(szMappingFile, "%s%s", szLeafname, szCreateSuffix(szLeafname));
  136. DBG_MSG(szMappingFile);
  137. if (STRCEQ(szMappingFile, MAPPING_FILE_UTF_8)) {
  138. return encoding_utf_8;
  139. }
  140. if (STRCEQ(szMappingFile, MAPPING_FILE_CP852) ||
  141. STRCEQ(szMappingFile, MAPPING_FILE_CP1250) ||
  142. STRCEQ(szMappingFile, MAPPING_FILE_8859_2)) {
  143. return encoding_latin_2;
  144. }
  145. if (STRCEQ(szMappingFile, MAPPING_FILE_KOI8_R) ||
  146. STRCEQ(szMappingFile, MAPPING_FILE_KOI8_U) ||
  147. STRCEQ(szMappingFile, MAPPING_FILE_CP866) ||
  148. STRCEQ(szMappingFile, MAPPING_FILE_CP1251) ||
  149. STRCEQ(szMappingFile, MAPPING_FILE_8859_5)) {
  150. return encoding_cyrillic;
  151. }
  152. return encoding_latin_1;
  153. } /* end of eMappingFile2Encoding */
  154. #endif /* !__riscos */
  155. /*
  156. * pOpenCharacterMappingFile - open the mapping file
  157. *
  158. * Returns the file pointer or NULL
  159. */
  160. static FILE *
  161. pOpenCharacterMappingFile(const char *szLeafname)
  162. {
  163. #if !defined(__riscos)
  164. FILE *pFile;
  165. const char *szHome, *szAntiword, *szSuffix;
  166. size_t tFilenameLen;
  167. char szMappingFile[PATH_MAX+1];
  168. #endif /* !__riscos */
  169. if (szLeafname == NULL || szLeafname[0] == '\0') {
  170. return NULL;
  171. }
  172. DBG_MSG(szLeafname);
  173. #if defined(__riscos)
  174. return fopen(szLeafname, "r");
  175. #else
  176. /* Set the suffix */
  177. szSuffix = szCreateSuffix(szLeafname);
  178. /* Set length */
  179. tFilenameLen = strlen(szLeafname) + strlen(szSuffix);
  180. /* Try the environment version of the mapping file */
  181. szAntiword = szGetAntiwordDirectory();
  182. if (szAntiword != NULL && szAntiword[0] != '\0') {
  183. if (strlen(szAntiword) + tFilenameLen <
  184. sizeof(szMappingFile) -
  185. sizeof(FILE_SEPARATOR)) {
  186. sprintf(szMappingFile,
  187. "%s" FILE_SEPARATOR "%s%s",
  188. szAntiword, szLeafname, szSuffix);
  189. DBG_MSG(szMappingFile);
  190. pFile = fopen(szMappingFile, "r");
  191. if (pFile != NULL) {
  192. return pFile;
  193. }
  194. } else {
  195. werr(0, "Environment mappingfilename ignored");
  196. }
  197. }
  198. /* Try the local version of the mapping file */
  199. szHome = szGetHomeDirectory();
  200. if (strlen(szHome) + tFilenameLen <
  201. sizeof(szMappingFile) -
  202. sizeof(ANTIWORD_DIR) -
  203. 2 * sizeof(FILE_SEPARATOR)) {
  204. sprintf(szMappingFile,
  205. "%s" FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR "%s%s",
  206. szHome, szLeafname, szSuffix);
  207. DBG_MSG(szMappingFile);
  208. pFile = fopen(szMappingFile, "r");
  209. if (pFile != NULL) {
  210. return pFile;
  211. }
  212. } else {
  213. werr(0, "Local mappingfilename too long, ignored");
  214. }
  215. /* Try the global version of the mapping file */
  216. if (tFilenameLen <
  217. sizeof(szMappingFile) -
  218. sizeof(GLOBAL_ANTIWORD_DIR) -
  219. sizeof(FILE_SEPARATOR)) {
  220. sprintf(szMappingFile,
  221. GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s%s",
  222. szLeafname, szSuffix);
  223. DBG_MSG(szMappingFile);
  224. pFile = fopen(szMappingFile, "r");
  225. if (pFile != NULL) {
  226. return pFile;
  227. }
  228. } else {
  229. werr(0, "Global mappingfilename too long, ignored");
  230. }
  231. werr(0, "I can't open your mapping file (%s%s)\n"
  232. "It is not in '%s" FILE_SEPARATOR ANTIWORD_DIR "' nor in '"
  233. GLOBAL_ANTIWORD_DIR "'.", szLeafname, szSuffix, szHome);
  234. return NULL;
  235. #endif /* __riscos */
  236. } /* end of pOpenCharacterMappingFile */
  237. /*
  238. * vCloseCharacterMappingFile - close the mapping file
  239. */
  240. static void
  241. vCloseCharacterMappingFile(FILE *pFile)
  242. {
  243. (void)fclose(pFile);
  244. } /* end of pCloseCharacterMappingFile */
  245. /*
  246. * iReadOptions - read options
  247. *
  248. * returns: -1: error
  249. * 0: help
  250. * >0: index first file argument
  251. */
  252. int
  253. iReadOptions(int argc, char **argv)
  254. {
  255. #if defined(__riscos)
  256. FILE *pFile;
  257. const char *szAlphabet;
  258. int iAlphabet;
  259. char szLine[81];
  260. #else
  261. extern char *optarg;
  262. extern int optind;
  263. char *pcChar, *szTmp;
  264. int iChar;
  265. char szLeafname[LEAFNAME_SIZE];
  266. #endif /* __riscos */
  267. FILE *pCharacterMappingFile;
  268. int iTmp;
  269. BOOL bSuccess;
  270. DBG_MSG("iReadOptions");
  271. /* Defaults */
  272. tOptionsCurr = tOptionsDefault;
  273. #if defined(__riscos)
  274. /* Choices file */
  275. pFile = fopen("<AntiWord$ChoicesFile>", "r");
  276. DBG_MSG_C(pFile == NULL, "Choices file not found");
  277. DBG_HEX_C(pFile != NULL, pFile);
  278. if (pFile != NULL) {
  279. while (fgets(szLine, (int)sizeof(szLine), pFile) != NULL) {
  280. DBG_MSG(szLine);
  281. if (szLine[0] == '#' ||
  282. szLine[0] == '\r' ||
  283. szLine[0] == '\n') {
  284. continue;
  285. }
  286. if (sscanf(szLine, PARAGRAPH_BREAK, &iTmp) == 1 &&
  287. (iTmp == 0 ||
  288. (iTmp >= MIN_SCREEN_WIDTH &&
  289. iTmp <= MAX_SCREEN_WIDTH))) {
  290. tOptionsCurr.iParagraphBreak = iTmp;
  291. DBG_DEC(tOptionsCurr.iParagraphBreak);
  292. } else if (sscanf(szLine, AUTOFILETYPE, &iTmp)
  293. == 1) {
  294. tOptionsCurr.bAutofiletypeAllowed =
  295. iTmp != 0;
  296. DBG_DEC(tOptionsCurr.bAutofiletypeAllowed);
  297. } else if (sscanf(szLine, USE_OUTLINEFONTS, &iTmp)
  298. == 1) {
  299. tOptionsCurr.eConversionType =
  300. iTmp == 0 ?
  301. conversion_text : conversion_draw;
  302. DBG_DEC(tOptionsCurr.eConversionType);
  303. } else if (sscanf(szLine, SHOW_IMAGES, &iTmp)
  304. == 1) {
  305. tOptionsCurr.eImageLevel = iTmp != 0 ?
  306. level_default : level_no_images;
  307. } else if (sscanf(szLine, HIDE_HIDDEN_TEXT, &iTmp)
  308. == 1) {
  309. tOptionsCurr.bHideHiddenText = iTmp != 0;
  310. DBG_DEC(tOptionsCurr.bHideHiddenText);
  311. } else if (sscanf(szLine, SCALE_FACTOR_START, &iTmp)
  312. == 1) {
  313. if (iTmp >= MIN_SCALE_FACTOR &&
  314. iTmp <= MAX_SCALE_FACTOR) {
  315. tOptionsCurr.iScaleFactor = iTmp;
  316. DBG_DEC(tOptionsCurr.iScaleFactor);
  317. }
  318. }
  319. }
  320. (void)fclose(pFile);
  321. }
  322. iAlphabet = iReadCurrentAlphabetNumber();
  323. switch (iAlphabet) {
  324. case 101: /* ISO-8859-1 aka Latin1 */
  325. szAlphabet = "<AntiWord$Latin1>";
  326. break;
  327. case 112: /* ISO-8859-15 aka Latin9 */
  328. szAlphabet = "<AntiWord$Latin9>";
  329. break;
  330. default:
  331. werr(0, "Alphabet '%d' is not supported", iAlphabet);
  332. return -1;
  333. }
  334. pCharacterMappingFile = pOpenCharacterMappingFile(szAlphabet);
  335. if (pCharacterMappingFile != NULL) {
  336. bSuccess = bReadCharacterMappingTable(pCharacterMappingFile);
  337. vCloseCharacterMappingFile(pCharacterMappingFile);
  338. } else {
  339. bSuccess = FALSE;
  340. }
  341. return bSuccess ? 1 : -1;
  342. #else
  343. /* Environment */
  344. szTmp = getenv("COLUMNS");
  345. if (szTmp != NULL) {
  346. DBG_MSG(szTmp);
  347. iTmp = (int)strtol(szTmp, &pcChar, 10);
  348. if (*pcChar == '\0') {
  349. iTmp -= 4; /* This is for the edge */
  350. if (iTmp < MIN_SCREEN_WIDTH) {
  351. iTmp = MIN_SCREEN_WIDTH;
  352. } else if (iTmp > MAX_SCREEN_WIDTH) {
  353. iTmp = MAX_SCREEN_WIDTH;
  354. }
  355. tOptionsCurr.iParagraphBreak = iTmp;
  356. DBG_DEC(tOptionsCurr.iParagraphBreak);
  357. }
  358. }
  359. strncpy(szLeafname, szGetDefaultMappingFile(), sizeof(szLeafname) - 1);
  360. szLeafname[sizeof(szLeafname) - 1] = '\0';
  361. /* Command line */
  362. while ((iChar = getopt(argc, argv, "La:fhi:m:p:rstw:x:")) != -1) {
  363. switch (iChar) {
  364. case 'L':
  365. tOptionsCurr.bUseLandscape = TRUE;
  366. break;
  367. case 'a':
  368. if (!bCorrectPapersize(optarg, conversion_pdf)) {
  369. werr(0, "-a without a valid papersize");
  370. return -1;
  371. }
  372. break;
  373. case 'f':
  374. tOptionsCurr.eConversionType = conversion_fmt_text;
  375. break;
  376. case 'h':
  377. return 0;
  378. case 'i':
  379. iTmp = (int)strtol(optarg, &pcChar, 10);
  380. if (*pcChar != '\0') {
  381. break;
  382. }
  383. switch (iTmp) {
  384. case 0:
  385. tOptionsCurr.eImageLevel = level_gs_special;
  386. break;
  387. case 1:
  388. tOptionsCurr.eImageLevel = level_no_images;
  389. break;
  390. case 2:
  391. tOptionsCurr.eImageLevel = level_ps_2;
  392. break;
  393. case 3:
  394. tOptionsCurr.eImageLevel = level_ps_3;
  395. break;
  396. default:
  397. tOptionsCurr.eImageLevel = level_default;
  398. break;
  399. }
  400. DBG_DEC(tOptionsCurr.eImageLevel);
  401. break;
  402. case 'm':
  403. if (tOptionsCurr.eConversionType == conversion_xml) {
  404. werr(0, "XML doesn't need a mapping file");
  405. break;
  406. }
  407. strncpy(szLeafname, optarg, sizeof(szLeafname) - 1);
  408. szLeafname[sizeof(szLeafname) - 1] = '\0';
  409. DBG_MSG(szLeafname);
  410. break;
  411. case 'p':
  412. if (!bCorrectPapersize(optarg, conversion_ps)) {
  413. werr(0, "-p without a valid papersize");
  414. return -1;
  415. }
  416. break;
  417. case 'r':
  418. tOptionsCurr.bRemoveRemovedText = FALSE;
  419. break;
  420. case 's':
  421. tOptionsCurr.bHideHiddenText = FALSE;
  422. break;
  423. case 't':
  424. tOptionsCurr.eConversionType = conversion_text;
  425. break;
  426. case 'w':
  427. iTmp = (int)strtol(optarg, &pcChar, 10);
  428. if (*pcChar == '\0') {
  429. if (iTmp != 0 && iTmp < MIN_SCREEN_WIDTH) {
  430. iTmp = MIN_SCREEN_WIDTH;
  431. } else if (iTmp > MAX_SCREEN_WIDTH) {
  432. iTmp = MAX_SCREEN_WIDTH;
  433. }
  434. tOptionsCurr.iParagraphBreak = iTmp;
  435. DBG_DEC(tOptionsCurr.iParagraphBreak);
  436. }
  437. break;
  438. case 'x':
  439. if (STREQ(optarg, "db")) {
  440. tOptionsCurr.iParagraphBreak = 0;
  441. tOptionsCurr.eConversionType = conversion_xml;
  442. strcpy(szLeafname, MAPPING_FILE_UTF_8);
  443. } else {
  444. werr(0, "-x %s is not supported", optarg);
  445. return -1;
  446. }
  447. break;
  448. default:
  449. return -1;
  450. }
  451. }
  452. tOptionsCurr.eEncoding = eMappingFile2Encoding(szLeafname);
  453. DBG_DEC(tOptionsCurr.eEncoding);
  454. if (tOptionsCurr.eConversionType == conversion_ps &&
  455. tOptionsCurr.eEncoding == encoding_utf_8) {
  456. werr(0,
  457. "The combination PostScript and UTF-8 is not supported");
  458. return -1;
  459. }
  460. if (tOptionsCurr.eConversionType == conversion_pdf &&
  461. tOptionsCurr.eEncoding == encoding_utf_8) {
  462. werr(0,
  463. "The combination PDF and UTF-8 is not supported");
  464. return -1;
  465. }
  466. if (tOptionsCurr.eConversionType == conversion_pdf &&
  467. tOptionsCurr.eEncoding == encoding_cyrillic) {
  468. werr(0,
  469. "The combination PDF and Cyrillic is not supported");
  470. return -1;
  471. }
  472. if (tOptionsCurr.eConversionType == conversion_ps ||
  473. tOptionsCurr.eConversionType == conversion_pdf) {
  474. /* PostScript or PDF mode */
  475. if (tOptionsCurr.bUseLandscape) {
  476. /* Swap the page height and width */
  477. iTmp = tOptionsCurr.iPageHeight;
  478. tOptionsCurr.iPageHeight = tOptionsCurr.iPageWidth;
  479. tOptionsCurr.iPageWidth = iTmp;
  480. }
  481. /* The paragraph break depends on the width of the paper */
  482. tOptionsCurr.iParagraphBreak = iMilliPoints2Char(
  483. (long)tOptionsCurr.iPageWidth * 1000 -
  484. lDrawUnits2MilliPoints(
  485. PS_LEFT_MARGIN + PS_RIGHT_MARGIN));
  486. DBG_DEC(tOptionsCurr.iParagraphBreak);
  487. }
  488. pCharacterMappingFile = pOpenCharacterMappingFile(szLeafname);
  489. if (pCharacterMappingFile != NULL) {
  490. bSuccess = bReadCharacterMappingTable(pCharacterMappingFile);
  491. vCloseCharacterMappingFile(pCharacterMappingFile);
  492. } else {
  493. bSuccess = FALSE;
  494. }
  495. return bSuccess ? optind : -1;
  496. #endif /* __riscos */
  497. } /* end of iReadOptions */
  498. /*
  499. * vGetOptions - get a copy of the current option values
  500. */
  501. void
  502. vGetOptions(options_type *pOptions)
  503. {
  504. fail(pOptions == NULL);
  505. *pOptions = tOptionsCurr;
  506. } /* end of vGetOptions */
  507. #if defined(__riscos)
  508. /*
  509. * vWriteOptions - write the current options to the Options file
  510. */
  511. static void
  512. vWriteOptions(void)
  513. {
  514. FILE *pFile;
  515. char *szOptionsFile;
  516. TRACE_MSG("vWriteOptions");
  517. szOptionsFile = getenv("AntiWord$ChoicesSave");
  518. if (szOptionsFile == NULL) {
  519. werr(0, "Warning: Name of the Choices file not found");
  520. return;
  521. }
  522. if (!bMakeDirectory(szOptionsFile)) {
  523. werr(0,
  524. "Warning: I can't make a directory for the Choices file");
  525. return;
  526. }
  527. pFile = fopen(szOptionsFile, "w");
  528. if (pFile == NULL) {
  529. werr(0, "Warning: I can't write the Choices file");
  530. return;
  531. }
  532. (void)fprintf(pFile, PARAGRAPH_BREAK"\n",
  533. tOptionsCurr.iParagraphBreak);
  534. (void)fprintf(pFile, AUTOFILETYPE"\n",
  535. tOptionsCurr.bAutofiletypeAllowed);
  536. (void)fprintf(pFile, USE_OUTLINEFONTS"\n",
  537. tOptionsCurr.eConversionType == conversion_text ? 0 : 1);
  538. (void)fprintf(pFile, SHOW_IMAGES"\n",
  539. tOptionsCurr.eImageLevel == level_no_images ? 0 : 1);
  540. (void)fprintf(pFile, HIDE_HIDDEN_TEXT"\n",
  541. tOptionsCurr.bHideHiddenText);
  542. (void)fprintf(pFile, SCALE_FACTOR_START"\n",
  543. tOptionsCurr.iScaleFactor);
  544. (void)fclose(pFile);
  545. } /* end of vWriteOptions */
  546. /*
  547. * vChoicesOpenAction - action to be taken when the Choices window opens
  548. */
  549. void
  550. vChoicesOpenAction(window_handle tWindow)
  551. {
  552. TRACE_MSG("vChoicesOpenAction");
  553. tOptionsTemp = tOptionsCurr;
  554. if (tOptionsTemp.iParagraphBreak == 0) {
  555. vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, FALSE);
  556. vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, TRUE);
  557. vUpdateWriteableNumber(tWindow, CHOICES_BREAK_WRITEABLE,
  558. DEFAULT_SCREEN_WIDTH);
  559. } else {
  560. vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE);
  561. vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, FALSE);
  562. vUpdateWriteableNumber(tWindow,
  563. CHOICES_BREAK_WRITEABLE,
  564. tOptionsTemp.iParagraphBreak);
  565. }
  566. vUpdateRadioButton(tWindow, CHOICES_AUTOFILETYPE_BUTTON,
  567. tOptionsTemp.bAutofiletypeAllowed);
  568. vUpdateRadioButton(tWindow, CHOICES_HIDDEN_TEXT_BUTTON,
  569. tOptionsTemp.bHideHiddenText);
  570. if (tOptionsTemp.eConversionType == conversion_draw) {
  571. vUpdateRadioButton(tWindow,
  572. CHOICES_WITH_IMAGES_BUTTON,
  573. tOptionsTemp.eImageLevel != level_no_images);
  574. vUpdateRadioButton(tWindow,
  575. CHOICES_NO_IMAGES_BUTTON,
  576. tOptionsTemp.eImageLevel == level_no_images);
  577. vUpdateRadioButton(tWindow,
  578. CHOICES_TEXTONLY_BUTTON, FALSE);
  579. } else {
  580. vUpdateRadioButton(tWindow,
  581. CHOICES_WITH_IMAGES_BUTTON, FALSE);
  582. vUpdateRadioButton(tWindow,
  583. CHOICES_NO_IMAGES_BUTTON, FALSE);
  584. vUpdateRadioButton(tWindow,
  585. CHOICES_TEXTONLY_BUTTON, TRUE);
  586. }
  587. vUpdateWriteableNumber(tWindow,
  588. CHOICES_SCALE_WRITEABLE, tOptionsTemp.iScaleFactor);
  589. TRACE_MSG("end of vChoicesOpenAction");
  590. } /* end of vChoicesOpenAction */
  591. /*
  592. * vDefaultButtonAction - action when the default button is clicked
  593. */
  594. static void
  595. vDefaultButtonAction(window_handle tWindow)
  596. {
  597. TRACE_MSG("vDefaultButtonAction");
  598. tOptionsTemp = tOptionsDefault;
  599. vUpdateRadioButton(tWindow, CHOICES_BREAK_BUTTON, TRUE);
  600. vUpdateRadioButton(tWindow, CHOICES_NO_BREAK_BUTTON, FALSE);
  601. vUpdateWriteableNumber(tWindow, CHOICES_BREAK_WRITEABLE,
  602. tOptionsTemp.iParagraphBreak);
  603. vUpdateRadioButton(tWindow, CHOICES_AUTOFILETYPE_BUTTON,
  604. tOptionsTemp.bAutofiletypeAllowed);
  605. vUpdateRadioButton(tWindow, CHOICES_HIDDEN_TEXT_BUTTON,
  606. tOptionsTemp.bHideHiddenText);
  607. vUpdateRadioButton(tWindow, CHOICES_WITH_IMAGES_BUTTON,
  608. tOptionsTemp.eConversionType == conversion_draw &&
  609. tOptionsTemp.eImageLevel != level_no_images);
  610. vUpdateRadioButton(tWindow, CHOICES_NO_IMAGES_BUTTON,
  611. tOptionsTemp.eConversionType == conversion_draw &&
  612. tOptionsTemp.eImageLevel == level_no_images);
  613. vUpdateRadioButton(tWindow, CHOICES_TEXTONLY_BUTTON,
  614. tOptionsTemp.eConversionType == conversion_text);
  615. vUpdateWriteableNumber(tWindow, CHOICES_SCALE_WRITEABLE,
  616. tOptionsTemp.iScaleFactor);
  617. } /* end of vDefaultButtonAction */
  618. /*
  619. * vApplyButtonAction - action to be taken when the OK button is clicked
  620. */
  621. static void
  622. vApplyButtonAction(void)
  623. {
  624. TRACE_MSG("vApplyButtonAction");
  625. tOptionsCurr = tOptionsTemp;
  626. } /* end of vApplyButtonAction */
  627. /*
  628. * vSaveButtonAction - action to be taken when the save button is clicked
  629. */
  630. static void
  631. vSaveButtonAction(void)
  632. {
  633. TRACE_MSG("vSaveButtonAction");
  634. vApplyButtonAction();
  635. vWriteOptions();
  636. } /* end of vSaveButtonAction */
  637. /*
  638. * vSetParagraphBreak - set the paragraph break to the given number
  639. */
  640. static void
  641. vSetParagraphBreak(window_handle tWindow, int iNumber)
  642. {
  643. tOptionsTemp.iParagraphBreak = iNumber;
  644. if (tOptionsTemp.iParagraphBreak == 0) {
  645. return;
  646. }
  647. vUpdateWriteableNumber(tWindow,
  648. CHOICES_BREAK_WRITEABLE,
  649. tOptionsTemp.iParagraphBreak);
  650. } /* end of vSetParagraphBreak */
  651. /*
  652. * vChangeParagraphBreak - change the paragraph break with the given number
  653. */
  654. static void
  655. vChangeParagraphBreak(window_handle tWindow, int iNumber)
  656. {
  657. int iTmp;
  658. iTmp = tOptionsTemp.iParagraphBreak + iNumber;
  659. if (iTmp < MIN_SCREEN_WIDTH || iTmp > MAX_SCREEN_WIDTH) {
  660. /* Ignore */
  661. return;
  662. }
  663. tOptionsTemp.iParagraphBreak = iTmp;
  664. vUpdateWriteableNumber(tWindow,
  665. CHOICES_BREAK_WRITEABLE,
  666. tOptionsTemp.iParagraphBreak);
  667. } /* end of vChangeParagraphBreak */
  668. /*
  669. * vChangeAutofiletype - invert the permission to autofiletype
  670. */
  671. static void
  672. vChangeAutofiletype(window_handle tWindow)
  673. {
  674. tOptionsTemp.bAutofiletypeAllowed =
  675. !tOptionsTemp.bAutofiletypeAllowed;
  676. vUpdateRadioButton(tWindow,
  677. CHOICES_AUTOFILETYPE_BUTTON,
  678. tOptionsTemp.bAutofiletypeAllowed);
  679. } /* end of vChangeAutofiletype */
  680. /*
  681. * vChangeHiddenText - invert the hide/show hidden text
  682. */
  683. static void
  684. vChangeHiddenText(window_handle tWindow)
  685. {
  686. tOptionsTemp.bHideHiddenText = !tOptionsTemp.bHideHiddenText;
  687. vUpdateRadioButton(tWindow,
  688. CHOICES_HIDDEN_TEXT_BUTTON,
  689. tOptionsTemp.bHideHiddenText);
  690. } /* end of vChangeHiddenText */
  691. /*
  692. * vUseFontsImages - use outline fonts, show images
  693. */
  694. static void
  695. vUseFontsImages(BOOL bUseOutlineFonts, BOOL bShowImages)
  696. {
  697. tOptionsTemp.eConversionType =
  698. bUseOutlineFonts ? conversion_draw : conversion_text;
  699. tOptionsTemp.eImageLevel =
  700. bUseOutlineFonts && bShowImages ?
  701. level_default : level_no_images;
  702. } /* end of vUseFontsImages */
  703. /*
  704. * vSetScaleFactor - set the scale factor to the given number
  705. */
  706. static void
  707. vSetScaleFactor(window_handle tWindow, int iNumber)
  708. {
  709. tOptionsTemp.iScaleFactor = iNumber;
  710. vUpdateWriteableNumber(tWindow,
  711. CHOICES_SCALE_WRITEABLE,
  712. tOptionsTemp.iScaleFactor);
  713. } /* end of vSetScaleFactor */
  714. /*
  715. * vChangeScaleFactor - change the scale factor with the given number
  716. */
  717. static void
  718. vChangeScaleFactor(window_handle tWindow, int iNumber)
  719. {
  720. int iTmp;
  721. iTmp = tOptionsTemp.iScaleFactor + iNumber;
  722. if (iTmp < MIN_SCALE_FACTOR || iTmp > MAX_SCALE_FACTOR) {
  723. /* Ignore */
  724. return;
  725. }
  726. tOptionsTemp.iScaleFactor = iTmp;
  727. vUpdateWriteableNumber(tWindow,
  728. CHOICES_SCALE_WRITEABLE,
  729. tOptionsTemp.iScaleFactor);
  730. } /* end of vChangeScaleFactor */
  731. /*
  732. * bChoicesMouseClick - handle a mouse click in the Choices window
  733. */
  734. BOOL
  735. bChoicesMouseClick(event_pollblock *pEvent, void *pvReference)
  736. {
  737. icon_handle tAction;
  738. mouse_block *pMouse;
  739. BOOL bCloseWindow;
  740. TRACE_MSG("bChoicesMouseClick");
  741. fail(pEvent == NULL);
  742. fail(pEvent->type != event_CLICK);
  743. pMouse = &pEvent->data.mouse;
  744. if (!pMouse->button.data.select && !pMouse->button.data.adjust) {
  745. /* Not handled here */
  746. DBG_HEX(pMouse->button.value);
  747. return FALSE;
  748. }
  749. /* Which action should be taken */
  750. tAction = pMouse->icon;
  751. if (pMouse->button.data.adjust) {
  752. /* The adjust button reverses the direction */
  753. switch (pMouse->icon) {
  754. case CHOICES_BREAK_UP_BUTTON:
  755. tAction = CHOICES_BREAK_DOWN_BUTTON;
  756. break;
  757. case CHOICES_BREAK_DOWN_BUTTON:
  758. tAction = CHOICES_BREAK_UP_BUTTON;
  759. break;
  760. case CHOICES_SCALE_UP_BUTTON:
  761. tAction = CHOICES_SCALE_DOWN_BUTTON;
  762. break;
  763. case CHOICES_SCALE_DOWN_BUTTON:
  764. tAction = CHOICES_SCALE_UP_BUTTON;
  765. break;
  766. default:
  767. break;
  768. }
  769. }
  770. /* Actions */
  771. bCloseWindow = FALSE;
  772. switch (tAction) {
  773. case CHOICES_DEFAULT_BUTTON:
  774. vDefaultButtonAction(pMouse->window);
  775. break;
  776. case CHOICES_SAVE_BUTTON:
  777. vSaveButtonAction();
  778. break;
  779. case CHOICES_CANCEL_BUTTON:
  780. bCloseWindow = TRUE;
  781. break;
  782. case CHOICES_APPLY_BUTTON:
  783. vApplyButtonAction();
  784. bCloseWindow = TRUE;
  785. break;
  786. case CHOICES_BREAK_BUTTON:
  787. vSetParagraphBreak(pMouse->window, DEFAULT_SCREEN_WIDTH);
  788. break;
  789. case CHOICES_BREAK_UP_BUTTON:
  790. vChangeParagraphBreak(pMouse->window, 1);
  791. break;
  792. case CHOICES_BREAK_DOWN_BUTTON:
  793. vChangeParagraphBreak(pMouse->window, -1);
  794. break;
  795. case CHOICES_NO_BREAK_BUTTON:
  796. vSetParagraphBreak(pMouse->window, 0);
  797. break;
  798. case CHOICES_AUTOFILETYPE_BUTTON:
  799. vChangeAutofiletype(pMouse->window);
  800. break;
  801. case CHOICES_HIDDEN_TEXT_BUTTON:
  802. vChangeHiddenText(pMouse->window);
  803. break;
  804. case CHOICES_WITH_IMAGES_BUTTON:
  805. vUseFontsImages(TRUE, TRUE);
  806. break;
  807. case CHOICES_NO_IMAGES_BUTTON:
  808. vUseFontsImages(TRUE, FALSE);
  809. break;
  810. case CHOICES_TEXTONLY_BUTTON:
  811. vUseFontsImages(FALSE, FALSE);
  812. break;
  813. case CHOICES_SCALE_UP_BUTTON:
  814. vChangeScaleFactor(pMouse->window, 5);
  815. break;
  816. case CHOICES_SCALE_DOWN_BUTTON:
  817. vChangeScaleFactor(pMouse->window, -5);
  818. break;
  819. default:
  820. DBG_DEC(pMouse->icon);
  821. break;
  822. }
  823. if (bCloseWindow) {
  824. Error_CheckFatal(Wimp_CloseWindow(pMouse->window));
  825. }
  826. return TRUE;
  827. } /* end of bChoicesMouseClick */
  828. /*
  829. * bChoicesKeyPressed - handle a key in the Choices window
  830. */
  831. BOOL
  832. bChoicesKeyPressed(event_pollblock *pEvent, void *pvReference)
  833. {
  834. icon_block tIcon;
  835. caret_block *pCaret;
  836. char *pcChar;
  837. int iNumber;
  838. DBG_MSG("bChoicesKeyPressed");
  839. fail(pEvent == NULL);
  840. fail(pEvent->type != event_KEY);
  841. if (pEvent->data.key.code != '\r') {
  842. Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
  843. return TRUE;
  844. }
  845. pCaret = &pEvent->data.key.caret;
  846. Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon));
  847. if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
  848. werr(1, "Icon %d must be indirected text", (int)pCaret->icon);
  849. }
  850. iNumber = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10);
  851. switch(pCaret->icon) {
  852. case CHOICES_BREAK_WRITEABLE:
  853. if (*pcChar != '\0' && *pcChar != '\r') {
  854. DBG_DEC(*pcChar);
  855. iNumber = DEFAULT_SCREEN_WIDTH;
  856. } else if (iNumber < MIN_SCREEN_WIDTH) {
  857. iNumber = MIN_SCREEN_WIDTH;
  858. } else if (iNumber > MAX_SCREEN_WIDTH) {
  859. iNumber = MAX_SCREEN_WIDTH;
  860. }
  861. vSetParagraphBreak(pCaret->window, iNumber);
  862. break;
  863. case CHOICES_SCALE_WRITEABLE:
  864. if (*pcChar != '\0' && *pcChar != '\r') {
  865. DBG_DEC(*pcChar);
  866. iNumber = DEFAULT_SCALE_FACTOR;
  867. } else if (iNumber < MIN_SCALE_FACTOR) {
  868. iNumber = MIN_SCALE_FACTOR;
  869. } else if (iNumber > MAX_SCALE_FACTOR) {
  870. iNumber = MAX_SCALE_FACTOR;
  871. }
  872. vSetScaleFactor(pCaret->window, iNumber);
  873. break;
  874. default:
  875. DBG_DEC(pCaret->icon);
  876. break;
  877. }
  878. return TRUE;
  879. } /* end of bChoicesKeyPressed */
  880. #endif /* __riscos */