Imported from antiword-0.37.tar.gz.
[antiword.git] / main_ros.c
blob8f4f3161e4364fef7817d51784b65b383dc3dbda
1 /*
2 * main_ros.c
4 * Released under GPL
6 * Copyright (C) 1998-2005 A.J. van Os
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Description:
23 * The main program of !Antiword (RISC OS version)
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "DeskLib:Dialog2.h"
30 #include "DeskLib:Error.h"
31 #include "DeskLib:Event.h"
32 #include "DeskLib:EventMsg.h"
33 #include "DeskLib:Handler.h"
34 #include "DeskLib:Menu.h"
35 #include "DeskLib:Resource.h"
36 #include "DeskLib:Screen.h"
37 #include "DeskLib:Template.h"
38 #include "DeskLib:Window.h"
39 #if defined(__GNUC__)
40 #include "flexlib:flex.h"
41 #endif /* __GNUC__ */
42 #include "version.h"
43 #include "antiword.h"
46 /* The name of this program */
47 static char *szTask = "!Antiword";
49 /* The window handle of the choices window */
50 static window_handle tChoicesWindow = 0;
52 /* Dummy diagram with the iconbar menu pointer */
53 static diagram_type tDummyDiagram;
55 /* Program information Box */
56 static dialog2_block *pInfoBox = NULL;
58 /* Info box fields */
59 #define PURPOSE_INFO_FIELD 2
60 #define AUTHOR_INFO_FIELD 3
61 #define VERSION_INFO_FIELD 4
62 #define STATUS_INFO_FIELD 5
64 /* Iconbar menu fields */
65 #define ICONBAR_INFO_FIELD 0
66 #define ICONBAR_CHOICES_FIELD 1
67 #define ICONBAR_QUIT_FIELD 2
71 * bBarInfo - Show iconbar information
73 static BOOL
74 bBarInfo(event_pollblock *pEvent, void *pvReference)
76 diagram_type *pDiag;
78 TRACE_MSG("bBarInfo");
80 fail(pEvent == NULL);
81 fail(pEvent->type != event_SEND);
82 fail(pEvent->data.message.header.action != message_MENUWARN);
83 fail(pvReference == NULL);
85 pDiag = (diagram_type *)pvReference;
87 if (menu_currentopen != pDiag->pSaveMenu ||
88 pEvent->data.message.data.menuwarn.selection[0] != ICONBAR_INFO_FIELD) {
89 return FALSE;
92 Dialog2_OpenDialogMenuLeaf(pEvent, pInfoBox);
93 return TRUE;
94 } /* end of bBarInfo */
97 * vBarInfoSetText - Set the iconbar infobox text
99 static void
100 vBarInfoSetText(dialog2_block *pBox)
102 TRACE_MSG("vBarInfoSetText");
104 fail(pBox == NULL);
105 fail(pBox != pInfoBox);
107 Icon_SetText(pBox->window, PURPOSE_INFO_FIELD, PURPOSESTRING);
108 Icon_SetText(pBox->window, AUTHOR_INFO_FIELD, AUTHORSTRING);
109 Icon_SetText(pBox->window, VERSION_INFO_FIELD, VERSIONSTRING);
110 Icon_SetText(pBox->window, STATUS_INFO_FIELD, STATUSSTRING);
111 } /* end of vBarInfoSetText */
114 * bMouseButtonClick - respond to mouse button click
116 static BOOL
117 bMouseButtonClick(event_pollblock *pEvent, void *pvReference)
119 diagram_type *pDiag;
120 menu_ptr pMenu;
121 int iPosY;
123 TRACE_MSG("bMouseButtonClick");
125 fail(pEvent == NULL);
126 fail(pEvent->type != event_CLICK);
127 fail(pvReference == NULL);
129 pDiag = (diagram_type *)pvReference;
131 if (pEvent->data.mouse.button.data.menu) {
132 pMenu = pDiag->pSaveMenu;
133 iPosY = (pMenu == tDummyDiagram.pSaveMenu) ?
134 -1 : pEvent->data.mouse.pos.y;
135 Menu_Show(pMenu, pEvent->data.mouse.pos.x, iPosY);
136 return TRUE;
138 if (pEvent->data.mouse.window == pDiag->tMainWindow &&
139 pEvent->data.mouse.icon == -1) {
140 vMainButtonClick(&pEvent->data.mouse);
141 return TRUE;
143 if (pEvent->data.mouse.window == pDiag->tScaleWindow &&
144 pEvent->data.mouse.icon >= 0) {
145 vScaleButtonClick(&pEvent->data.mouse, pDiag);
146 return TRUE;
148 return FALSE;
149 } /* end of bMouseButtonClick */
152 * bAutoRedrawWindow - the redraw is handled by the WIMP
154 static BOOL
155 bAutoRedrawWindow(event_pollblock *pEvent, void *pvReference)
157 return TRUE;
158 } /* end of bAutoRedrawWindow */
160 static BOOL
161 bSaveSelect(event_pollblock *pEvent, void *pvReference)
163 TRACE_MSG("bSaveSelect");
165 fail(pEvent == NULL);
166 fail(pEvent->type != event_MENU);
167 fail(pvReference == NULL);
169 DBG_DEC(pEvent->data.selection[0]);
171 switch (pEvent->data.selection[0]) {
172 case SAVEMENU_SCALEVIEW:
173 return bScaleOpenAction(pEvent, pvReference);
174 case SAVEMENU_SAVEDRAW:
175 return bSaveDrawfile(pEvent, pvReference);
176 case SAVEMENU_SAVETEXT:
177 return bSaveTextfile(pEvent, pvReference);
178 default:
179 DBG_DEC(pEvent->data.selection[0]);
180 return FALSE;
182 } /* end of bSaveSelect */
185 * Create the window for the text from the given file
187 static diagram_type *
188 pCreateTextWindow(const char *szFilename)
190 diagram_type *pDiag;
192 TRACE_MSG("pCreateTextWindow");
194 fail(szFilename == NULL || szFilename[0] == '\0');
196 /* Create the diagram */
197 pDiag = pCreateDiagram(szTask+1, szFilename);
198 if (pDiag == NULL) {
199 werr(0, "Sorry, no new diagram object");
200 return NULL;
203 /* Prepare a save menu for this diagram */
204 pDiag->pSaveMenu = Menu_New(szTask+1,
205 ">Scale view,"
206 ">Save (Drawfile) F3,"
207 ">Save (Text only) \213F3");
208 if (pDiag->pSaveMenu == NULL) {
209 werr(1, "Sorry, no Savemenu object");
211 Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SCALEVIEW,
212 TRUE, bScaleOpenAction, pDiag);
213 Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SAVEDRAW,
214 TRUE, bSaveDrawfile, pDiag);
215 Menu_Warn(pDiag->pSaveMenu, SAVEMENU_SAVETEXT,
216 TRUE, bSaveTextfile, pDiag);
218 /* Claim events for the main window */
219 Event_Claim(event_REDRAW, pDiag->tMainWindow, icon_ANY,
220 bRedrawMainWindow, pDiag);
221 Event_Claim(event_CLOSE, pDiag->tMainWindow, icon_ANY,
222 bDestroyDiagram, pDiag);
223 Event_Claim(event_CLICK, pDiag->tMainWindow, icon_ANY,
224 bMouseButtonClick, pDiag);
225 Event_Claim(event_KEY, pDiag->tMainWindow, icon_ANY,
226 bMainKeyPressed, pDiag);
228 /* Claim events for the scale window */
229 Event_Claim(event_REDRAW, pDiag->tScaleWindow, icon_ANY,
230 bAutoRedrawWindow, NULL);
231 Event_Claim(event_CLICK, pDiag->tScaleWindow, icon_ANY,
232 bMouseButtonClick, pDiag);
233 Event_Claim(event_KEY, pDiag->tScaleWindow, icon_ANY,
234 bScaleKeyPressed, pDiag);
236 /* Set the window title */
237 vSetTitle(pDiag);
238 return pDiag;
239 } /* end of pCreateTextWindow */
242 * vProcessFile - process one file
244 static void
245 vProcessFile(const char *szFilename, int iFiletype)
247 options_type tOptions;
248 FILE *pFile;
249 diagram_type *pDiag;
250 long lFilesize;
251 int iWordVersion;
253 TRACE_MSG("vProcessFile");
255 fail(szFilename == NULL || szFilename[0] == '\0');
257 DBG_MSG(szFilename);
259 pFile = fopen(szFilename, "rb");
260 if (pFile == NULL) {
261 werr(0, "I can't open '%s' for reading", szFilename);
262 return;
265 lFilesize = lGetFilesize(szFilename);
266 if (lFilesize < 0) {
267 (void)fclose(pFile);
268 werr(0, "I can't get the size of '%s'", szFilename);
269 return;
272 iWordVersion = iGuessVersionNumber(pFile, lFilesize);
273 if (iWordVersion < 0 || iWordVersion == 3) {
274 if (bIsRtfFile(pFile)) {
275 werr(0, "%s is not a Word Document."
276 " It is probably a Rich Text Format file",
277 szFilename);
278 } if (bIsWordPerfectFile(pFile)) {
279 werr(0, "%s is not a Word Document."
280 " It is probably a Word Perfect file",
281 szFilename);
282 } else {
283 werr(0, "%s is not a Word Document.", szFilename);
285 (void)fclose(pFile);
286 return;
288 /* Reset any reading done during file-testing */
289 rewind(pFile);
291 if (iFiletype != FILETYPE_MSWORD) {
292 vGetOptions(&tOptions);
293 if (tOptions.bAutofiletypeAllowed) {
294 vSetFiletype(szFilename, FILETYPE_MSWORD);
298 pDiag = pCreateTextWindow(szFilename);
299 if (pDiag == NULL) {
300 (void)fclose(pFile);
301 return;
304 (void)bWordDecryptor(pFile, lFilesize, pDiag);
305 Error_CheckFatal(Drawfile_VerifyDiagram(&pDiag->tInfo));
306 vShowDiagram(pDiag);
307 TRACE_MSG("After vShowDiagram");
309 TRACE_MSG("before debug print");
310 DBG_HEX(pFile);
311 TRACE_MSG("before fclose");
312 (void)fclose(pFile);
313 TRACE_MSG("after fclose");
314 } /* end of vProcessFile */
317 * vSendAck - send an acknowledge
319 static void
320 vSendAck(event_pollblock *pEvent)
322 message_block tMessage;
324 TRACE_MSG("vSendAck");
326 fail(pEvent == NULL);
327 fail(pEvent->type != event_SEND && pEvent->type != event_SENDWANTACK);
328 fail(pEvent->data.message.header.action != message_DATALOAD &&
329 pEvent->data.message.header.action != message_DATAOPEN);
331 tMessage.header.action = message_DATALOADACK;
332 tMessage.header.size = sizeof(tMessage);
333 tMessage.header.yourref = pEvent->data.message.header.myref;
334 Error_CheckFatal(Wimp_SendMessage(event_SEND, &tMessage,
335 pEvent->data.message.header.sender, 0));
336 } /* end of vSendAck */
338 static BOOL
339 bEventMsgHandler(event_pollblock *pEvent, void *pvReference)
341 TRACE_MSG("bEventMsgHandler");
343 fail(pEvent == NULL);
345 switch (pEvent->type) {
346 case event_SEND:
347 case event_SENDWANTACK:
348 switch (pEvent->data.message.header.action) {
349 case message_CLOSEDOWN:
350 exit(EXIT_SUCCESS);
351 break;
352 case message_DATALOAD:
353 case message_DATAOPEN:
354 vProcessFile(
355 pEvent->data.message.data.dataload.filename,
356 pEvent->data.message.data.dataload.filetype);
357 vSendAck(pEvent);
358 break;
359 default:
360 DBG_DEC(pEvent->data.message.header.action);
361 break;
363 return TRUE;
364 default:
365 DBG_DEC(pEvent->type);
366 return FALSE;
368 } /* end of bEventMsgHandler */
371 * bMenuSelect - select from the iconbar menu
373 static BOOL
374 bMenuSelect(event_pollblock *pEvent, void *pvReference)
376 TRACE_MSG("bMenuSelect");
378 fail(pEvent == NULL);
379 fail(pEvent->type != event_MENU);
381 DBG_DEC(pEvent->data.selection[0]);
383 switch (pEvent->data.selection[0]) {
384 case ICONBAR_INFO_FIELD:
385 return bBarInfo(pEvent, pvReference);
386 case ICONBAR_CHOICES_FIELD:
387 vChoicesOpenAction(tChoicesWindow);
388 Window_BringToFront(tChoicesWindow);
389 break;
390 case ICONBAR_QUIT_FIELD:
391 TRACE_MSG("before exit");
392 exit(EXIT_SUCCESS);
393 break;
394 default:
395 DBG_DEC(pEvent->data.selection[0]);
396 break;
398 return TRUE;
399 } /* end of bMenuSelect */
402 * bMenuClick - respond to an menu click
404 static BOOL
405 bMenuClick(event_pollblock *pEvent, void *pvReference)
407 TRACE_MSG("bMenuClick");
409 fail(pEvent == NULL);
410 fail(pEvent->type != event_MENU);
412 if (menu_currentopen == tDummyDiagram.pSaveMenu) {
413 return bMenuSelect(pEvent, pvReference);
414 } else if (pvReference == NULL) {
415 return FALSE;
417 return bSaveSelect(pEvent, pvReference);
418 } /* end of bMenuClick */
420 static void
421 vTemplates(void)
423 TRACE_MSG("vTemplates");
425 Template_Initialise();
426 Template_LoadFile("Templates");
428 tChoicesWindow = Window_Create("Choices", template_TITLEMIN);
429 if (tChoicesWindow == 0) {
430 werr(1, "I can't find the 'Choices' template");
433 /* Claim events for the choices window */
434 Event_Claim(event_REDRAW, tChoicesWindow, icon_ANY,
435 bAutoRedrawWindow, NULL);
436 Event_Claim(event_CLICK, tChoicesWindow, icon_ANY,
437 bChoicesMouseClick, NULL);
438 Event_Claim(event_KEY, tChoicesWindow, icon_ANY,
439 bChoicesKeyPressed, NULL);
440 } /* end of vTemplates */
442 static void
443 vInitialise(void)
445 int aiMessages[] = {0};
446 icon_handle tBarIcon;
449 TRACE_MSG("vInitialise");
451 Resource_Initialise(szTask+1);
452 Event_Initialise3(szTask+1, 310, aiMessages);
453 EventMsg_Initialise();
454 Screen_CacheModeInfo();
455 #if defined(__GNUC__)
456 flex_init(szTask+1, 0, 0);
457 flex_set_budge(1);
458 #endif /* __GNUC__ */
459 vTemplates();
461 /* Prepare iconbar menu */
462 tDummyDiagram.tInfo.data = NULL;
463 tDummyDiagram.tInfo.length = 0;
464 tDummyDiagram.pSaveMenu = Menu_New(szTask+1, ">Info,Choices...,Quit");
465 if (tDummyDiagram.pSaveMenu == NULL) {
466 werr(1, "Sorry, no Barmenu object");
468 pInfoBox = Dialog2_CreateDialogBlock("ProgInfo", -1, -1,
469 vBarInfoSetText, NULL, NULL);
471 if (pInfoBox == NULL) {
472 werr(1, "Sorry, no Infobox object");
474 Menu_Warn(tDummyDiagram.pSaveMenu, ICONBAR_INFO_FIELD,
475 TRUE, bBarInfo, &tDummyDiagram);
477 /* Create an icon on the icon bar */
478 tBarIcon = Icon_BarIcon(szTask, iconbar_RIGHT);
479 Event_Claim(event_CLICK, window_ICONBAR, tBarIcon,
480 bMouseButtonClick, &tDummyDiagram);
482 /* Generic claims */
483 Event_Claim(event_OPEN, window_ANY, icon_ANY,
484 Handler_OpenWindow, NULL);
485 Event_Claim(event_CLOSE, window_ANY, icon_ANY,
486 Handler_CloseWindow, NULL);
487 Event_Claim(event_MENU, window_ANY, icon_ANY,
488 bMenuClick, NULL);
489 EventMsg_Claim(message_DATALOAD, window_ICONBAR,
490 bEventMsgHandler, NULL);
491 EventMsg_Claim(message_MODECHANGE, window_ANY,
492 Handler_ModeChange, NULL);
493 } /* end of vInitialise */
496 main(int argc, char **argv)
498 int iFirst, iFiletype;
500 TRACE_MSG("main");
502 vInitialise();
503 iFirst = iReadOptions(argc, argv);
504 if (iFirst != 1) {
505 return EXIT_FAILURE;
508 if (argc > 1) {
509 iFiletype = iGetFiletype(argv[1]);
510 if (iFiletype < 0) {
511 return EXIT_FAILURE;
513 vProcessFile(argv[1], iFiletype);
514 TRACE_MSG("main after vProcessFile");
517 for (;;) {
518 Event_Poll();
520 } /* end of main */