1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/mainloop.c,v 1.37 2011/05/16 16:21:58 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_MAINLOOP_C_
22 
23 #include "tgifdefs.h"
24 #include "expfdefs.h"
25 #include "patchlvl.h"
26 #include "cmdids.h"
27 
28 #ifdef USE_XT_INITIALIZE
29 #include <X11/Intrinsic.h>
30 #endif /* USE_XT_INITIALIZE */
31 
32 #include "animate.e"
33 #include "attr.e"
34 #include "auxtext.e"
35 #include "chat.e"
36 #include "choice.e"
37 #include "cmd.e"
38 #include "color.e"
39 #include "cursor.e"
40 #include "cutpaste.e"
41 #include "dialog.e"
42 #include "drawing.e"
43 #include "edit.e"
44 #include "eps.e"
45 #include "exec.e"
46 #include "expr.e"
47 #include "file.e"
48 #include "font.e"
49 #include "ftp.e"
50 #include "grid.e"
51 #include "help.e"
52 #include "http.e"
53 #include "imgproc.e"
54 #include "import.e"
55 #include "ini.e"
56 #include "inmethod.e"
57 #include "mainloop.e"
58 #include "mainmenu.e"
59 #include "mark.e"
60 #include "markup.e"
61 #include "menu.e"
62 #include "miniline.e"
63 #include "msg.e"
64 #include "names.e"
65 #include "navigate.e"
66 #include "obj.e"
67 #include "page.e"
68 #include "pin.e"
69 #include "ps.e"
70 #include "raster.e"
71 #include "remote.e"
72 #include "ruler.e"
73 #include "scroll.e"
74 #include "select.e"
75 #include "setup.e"
76 #include "shape.e"
77 #include "shortcut.e"
78 #include "special.e"
79 #include "stk.e"
80 #include "strtbl.e"
81 #include "tangram2.e"
82 #include "text.e"
83 #include "tgcwheel.e"
84 #include "tginssym.e"
85 #include "tidget.e"
86 #include "util.e"
87 #include "version.e"
88 #include "wb.e"
89 #include "xbitmap.e"
90 #include "xpixmap.e"
91 #include "xprtfltr.e"
92 
93 #ifdef USE_XT_INITIALIZE
94 Widget		toplevel=(Widget)0;
95 #endif /* USE_XT_INITIALIZE */
96 
97 int	x11R6OrAbove=FALSE;
98 int	origArgC=0;
99 char	**origArgV=NULL;
100 
101 int	cmdLineBW=FALSE;
102 int	cmdLineRV=INVALID;
103 int	cmdLineCWO=FALSE;
104 int	cmdLineBtn1Warp=FALSE;
105 char	*cmdLineForeground=NULL;
106 char	*cmdLineBackground=NULL;
107 char	*cmdLineBorder=NULL;
108 int	cmdLineMerge=FALSE;
109 int	cmdLineMergeArgc=0;
110 char	**cmdLineMergeArgv=NULL;
111 int	geometrySpecified=FALSE;
112 int	exitNormally=FALSE;
113 char	geometrySpec[80];
114 char	*displayName=NULL;
115 int	initializingMain=FALSE;
116 int	cmdLineUseXlib=FALSE;
117 int	cmdLineVersion=FALSE;
118 int	cmdLineNoModeWindow=FALSE;
119 int	cmdLineNoChatWindow=FALSE;
120 
121 KeyOrBtnEvInfo	lastKeyOrBtnEvInfo;
122 
123 int			numExtraWins=0;
124 struct WinInfoRec	*extraWinInfo=NULL;
125 
126 PageInfo	mergingPageInfo;
127 
128 static int	maxExtraWins=0;
129 static int	quitDraw=TRUE;
130 
131 static int	useXlib=FALSE;
132 
AddExtraWinInfo(win,mapped,raise,expose_handler,ev_handler,cleanup_routine,userdata)133 int AddExtraWinInfo(win, mapped, raise, expose_handler, ev_handler,
134       cleanup_routine, userdata)
135    Window win;
136    int mapped, raise;
137    void (*expose_handler)();
138    int (*ev_handler)();
139    void (*cleanup_routine)();
140    void *userdata;
141 {
142    register int i;
143 
144    for (i = 0; i < numExtraWins; i++) {
145       if (extraWinInfo[i].window == None) {
146          break;
147       }
148    }
149    if (i == numExtraWins && numExtraWins == maxExtraWins) {
150       maxExtraWins += 10;
151       extraWinInfo = (struct WinInfoRec *)realloc(extraWinInfo,
152             maxExtraWins*sizeof(struct WinInfoRec));
153    }
154    extraWinInfo[i].window = win;
155    extraWinInfo[i].mapped = mapped;
156    extraWinInfo[i].raise = raise;
157    extraWinInfo[i].expose_handler = expose_handler;
158    extraWinInfo[i].ev_handler = ev_handler;
159    extraWinInfo[i].cleanup = cleanup_routine;
160    extraWinInfo[i].userdata = userdata;
161    return ((i==numExtraWins) ? numExtraWins++ : i);
162 }
163 
164 static
InitExtraWinInfo()165 void InitExtraWinInfo()
166 {
167    extraWinInfo = (struct WinInfoRec *)malloc(10*sizeof(struct WinInfoRec));
168    if (extraWinInfo == NULL) FailAllocMessage();
169    memset(extraWinInfo, 0, 10*sizeof(struct WinInfoRec));
170    maxExtraWins += 10;
171 }
172 
173 static
CleanUpExtraWinInfo()174 void CleanUpExtraWinInfo()
175 {
176    register int i;
177 
178    if (extraWinInfo != NULL) {
179       for (i = 0; i < numExtraWins; i++) {
180          if (extraWinInfo[i].window != None) {
181             (*(extraWinInfo[i].cleanup))(&extraWinInfo[i]);
182          }
183       }
184       free(extraWinInfo);
185    }
186    numExtraWins = 0;
187    maxExtraWins = 0;
188    extraWinInfo = NULL;
189 }
190 
191 static
InitLastKeyOrBtnEvInfo()192 void InitLastKeyOrBtnEvInfo()
193 {
194    memset(&lastKeyOrBtnEvInfo, 0, sizeof(KeyOrBtnEvInfo));
195 }
196 
CleanUpTalkToSelfFiledes()197 void CleanUpTalkToSelfFiledes()
198 {
199    if (talkToSelfFiledesInitialized) {
200        if (talkToSelfFiledes[0] != (-1)) close(talkToSelfFiledes[0]);
201        if (talkToSelfFiledes[1] != (-1)) close(talkToSelfFiledes[1]);
202    }
203    talkToSelfFiledesInitialized = FALSE;
204    talkToSelfFiledes[0] = talkToSelfFiledes[1] = (-1);
205 }
206 
InitTalkToSelfFiledes()207 int InitTalkToSelfFiledes()
208 {
209    talkToSelfFiledesInitialized = FALSE;
210    talkToSelfFiledes[0] = talkToSelfFiledes[1] = (-1);
211 
212    if (pipe(talkToSelfFiledes) != 0) {
213       sprintf(gszMsgBox, TgLoadString(STID_CREATE_SELF_PIPE_FAIL), TOOL_NAME);
214       fprintf(stderr, "%s\n", gszMsgBox);
215       return FALSE;
216    }
217    talkToSelfFiledesInitialized = TRUE;
218 
219    return TRUE;
220 }
221 
222 static
MySetLocale(category,new_locale)223 char *MySetLocale(category, new_locale)
224    int category;
225    char *new_locale;
226 {
227 #ifndef _NO_LOCALE_SUPPORT
228    return setlocale(category, new_locale);
229 #else /* _NO_LOCALE_SUPPORT */
230    return NULL;
231 #endif /* ~_NO_LOCALE_SUPPORT */
232 }
233 
234 static
ExecWithFile(CmdName,FileName)235 void ExecWithFile(CmdName, FileName)
236    char *CmdName, *FileName;
237 {
238    char s[255];
239 
240 #ifdef _BACKGROUND_DONT_FORK
241    /* do not translate -- program constants */
242    sprintf(s, "xterm -bd red -e %s %s", CmdName, FileName);
243    strcat(s, " &");
244    (void)system(s);
245 #else /* ~_BACKGROUND_DONT_FORK */
246    int pid;
247 
248    /* do not translate -- program constants */
249    sprintf(s, "xterm -bd red -e %s %s", CmdName, FileName);
250    pid = fork();
251    if (pid == 0) {
252       (void)system(s);
253       exit(0);
254    }
255 #endif /* _BACKGROUND_DONT_FORK */
256 }
257 
DeallocStrings(FStr,Str1,Menu1,Str2,Menu2,Str3,Menu3)258 void DeallocStrings(FStr, Str1, Menu1, Str2, Menu2, Str3, Menu3)
259    char **FStr, **Str1, **Menu1, **Str2, **Menu2, **Str3, **Menu3;
260 {
261    free(*FStr);
262    free(*Str1);
263    free(*Menu1);
264    free(*Str2);
265    free(*Menu2);
266    free(*Str3);
267    free(*Menu3);
268 }
269 
270 static
AllocStrings(FStr,Str1,Menu1,Str2,Menu2,Str3,Menu3)271 void AllocStrings(FStr, Str1, Menu1, Str2, Menu2, Str3, Menu3)
272    char **FStr, **Str1, **Menu1, **Str2, **Menu2, **Str3, **Menu3;
273 {
274    char *s;
275 
276    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
277    *FStr = s; **FStr = '\0';
278    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
279    *Str1 = s; **Str1 = '\0';
280    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
281    *Menu1 = s; **Menu1 = '\0';
282    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
283    *Str2 = s; **Str2 = '\0';
284    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
285    *Menu2 = s; **Menu2 = '\0';
286    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
287    *Str3 = s; **Str3 = '\0';
288    if((s=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
289    *Menu3 = s; **Menu3 = '\0';
290 }
291 
292 /*
293  * static
294  * int MyErrorHandler(display, event)
295  *    Display *display;
296  *    XErrorEvent *event;
297  * {
298  *    if (event->type == 0) return TRUE;
299  *    printf("\tError: type -- %1d\n", event->type);
300  *    exit(-1);
301  * }
302  */
303 
304 static
CleanUpMergeArgs()305 void CleanUpMergeArgs()
306 {
307    if (cmdLineMergeArgv != NULL) {
308       int i=0;
309 
310       for (i=0; i < cmdLineMergeArgc; i++) {
311          UtilFree(cmdLineMergeArgv[i]);
312       }
313       free(cmdLineMergeArgv);
314    }
315    cmdLineMergeArgc = 0;
316    cmdLineMergeArgv = NULL;
317 }
318 
CleanUp()319 void CleanUp()
320 {
321    tgCleanUpProfile();
322    CleanUpChat();
323    CleanUpWhiteBoard();
324 
325    TieLooseEnds();
326 
327    if (cmdLineTgrm2) {
328       CleanUpTangram2();
329    }
330    CleanUpMiniLines();
331    CleanUpCutPaste();
332    CleanUpProperties();
333    CleanUpExportFilters();
334    ResetPSInfo();
335    CleanUpEdit();
336    CleanUpMark();
337    CleanUpShape();
338    CleanUpHelp();
339    CleanUpImport();
340    CleanUpImageProc();
341    CleanUpExec();
342    CleanUpCmds();
343    CleanUpExpr();
344    CleanUpNavigate();
345    CleanUpRemote();
346 
347    CleanUpExtraWinInfo();
348    CleanUpDrawingWindow();
349    CleanUpPS();
350    CleanUpInputMethods();
351    CleanUpPins();
352    CleanUpPage();
353    CleanUpStk();
354    CleanUpStatus();
355    CleanUpChoices();
356 
357    CleanUpScrolls();
358    CleanUpCursors();
359 
360    CleanUpNames();
361    CleanUpRuler();
362    CleanUpRasters();
363    CleanUpFonts();
364    CleanUpMenu();
365    CleanUpText();
366    CleanUpColors();
367    CleanUpFiles();
368    CleanUpGrids();
369    CleanUpCutBuffer();
370    CleanUpXBm();
371    CleanUpXPm();
372    CleanUpMsg();
373    CleanUpShortCut();
374    CleanUpHtml();
375    CleanUpRecentFiles();
376    CleanUpMeasureTooltip();
377    CleanUpSpecial();
378    CleanUpAttr();
379    CleanUpTalkToSelfFiledes();
380    CleanUpInsertSymbol();
381    CleanUpColorWheel();
382    CleanUpTidget();
383 
384    if (iconWindowCreated) {
385       XDestroyWindow(mainDisplay, iconBaseWindow);
386       iconWindowCreated = FALSE;
387    }
388    CleanUpResiduals();
389    CleanUpStrTable();
390 
391    XDestroyWindow(mainDisplay, mainWindow);
392    mainWindow = None;
393 #ifndef DONT_FREE_COLORMAP
394    if (newColormapUsed) {
395       XFreeColormap(mainDisplay, mainColormap);
396       newColormapUsed = FALSE;
397    }
398 #endif /* ~DONT_FREE_COLORMAP */
399 }
400 
ExposeEventHandler(input,recursive)401 void ExposeEventHandler(input, recursive)
402    XEvent *input;
403    int recursive;
404 {
405    int i=0;
406    XEvent ev;
407    TidgetInfo *handling_pti=NULL;
408 
409    if (input->xany.window == choiceWindow) {
410       while (XCheckWindowEvent(mainDisplay, choiceWindow, ExposureMask, &ev)) ;
411       RedrawChoiceWindow();
412    } else if (input->xany.window == drawWindow) {
413       while (XCheckWindowEvent(mainDisplay, drawWindow, ExposureMask, &ev)) ;
414       if (topSel != NULL || curChoice==VERTEXMODE || SomethingDirty() ||
415             showCrossHair) {
416          ClearAndRedrawDrawWindow();
417       } else {
418          RedrawDrawWindow(botObj);
419          RedrawCurText();
420       }
421    } else if (input->xany.window == vRuleWindow) {
422       while (XCheckWindowEvent(mainDisplay, vRuleWindow, ExposureMask, &ev)) ;
423       RedrawVRulerWindow();
424    } else if (input->xany.window == hRuleWindow) {
425       while (XCheckWindowEvent(mainDisplay, hRuleWindow, ExposureMask, &ev)) ;
426       RedrawHRulerWindow();
427    } else if (input->xany.window == iconWindow && input->type == Expose) {
428       while (XCheckWindowEvent(mainDisplay, iconWindow, ExposureMask, &ev)) ;
429       RedrawIconWindow();
430    } else if (input->xany.window == titleWindow) {
431       while (XCheckWindowEvent(mainDisplay, titleWindow, ExposureMask, &ev)) ;
432       RedrawTitleWindow();
433    } else if (input->xany.window == menubarWindow) {
434       while (XCheckWindowEvent(mainDisplay,menubarWindow,ExposureMask,&ev)) ;
435       RedrawMenubarWindow();
436    } else if (input->xany.window == msgWindow) {
437       while (XCheckWindowEvent(mainDisplay, msgWindow, ExposureMask, &ev)) ;
438       RedrawMsg(TRUE);
439    } else if (input->xany.window == vSBarWindow) {
440       while (XCheckWindowEvent(mainDisplay, vSBarWindow, ExposureMask, &ev)) ;
441       RedrawVScrollWindow();
442    } else if (input->xany.window == hSBarWindow) {
443       while (XCheckWindowEvent(mainDisplay, hSBarWindow, ExposureMask, &ev)) ;
444       RedrawHScrollWindow();
445    } else if (input->xany.window == userRedrawWindow) {
446       while (XCheckWindowEvent(mainDisplay,userRedrawWindow,ExposureMask,&ev)) ;
447       RedrawUserRedrawWindow();
448    } else if (input->xany.window == statusWindow) {
449       while (XCheckWindowEvent(mainDisplay, statusWindow, ExposureMask, &ev)) ;
450       RedrawStatusWindow();
451    } else if (IsChatWindowEvent(input, &handling_pti)) {
452       ChatEventHandler(input, handling_pti);
453    } else if (input->xany.window == modeWindow) {
454       while (XCheckWindowEvent(mainDisplay, modeWindow, ExposureMask, &ev)) ;
455       RedrawModeWindow();
456    } else if (input->xany.window == dummyWindow1) {
457       while (XCheckWindowEvent(mainDisplay, dummyWindow1, ExposureMask, &ev)) ;
458       RedrawDummyWindow1();
459    } else if (input->xany.window == pageWindow) {
460       RedrawPageWindow();
461    } else if (input->xany.window == pageDummyWindow) {
462       RedrawPageDummyWindow();
463    } else if (input->xany.window == colorWindow) {
464       RedrawColorWindow();
465    } else if (input->xany.window == colorDummyWindow) {
466       RedrawColorDummyWindow();
467    } else if (input->xany.window==mainWindow && input->type==VisibilityNotify &&
468          input->xvisibility.state==VisibilityUnobscured) {
469       XEvent tmp_ev;
470 
471       while (XCheckWindowEvent(mainDisplay, mainWindow, VisibilityChangeMask,
472             &tmp_ev)) ;
473       if (iconWindowShown) {
474          UnIconify();
475       } else {
476          if (pinnedMainMenu) XMapRaised(mainDisplay, mainMenuWindow);
477          for (i = 0; i < numExtraWins; i++) {
478             if (extraWinInfo[i].window != None && extraWinInfo[i].mapped &&
479                   extraWinInfo[i].raise) {
480                XMapRaised(mainDisplay, extraWinInfo[i].window);
481             }
482          }
483       }
484    } else if (TidgetManagerHandleEvent(input)) {
485       /* input has been handled by the TidgetManager */
486    } else {
487       for (i = 0; i < numExtraWins; i++) {
488          if (input->xany.window == extraWinInfo[i].window &&
489                extraWinInfo[i].window != None) {
490             while (XCheckWindowEvent(mainDisplay, extraWinInfo[i].window,
491                   ExposureMask, &ev)) ;
492             (*(extraWinInfo[i].expose_handler))(input, &extraWinInfo[i]);
493             break;
494          }
495       }
496    }
497    if (recursive) {
498       while (XCheckMaskEvent(mainDisplay, ExposureMask, &ev) ||
499             XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
500          ExposeEventHandler(&ev, FALSE);
501       }
502    }
503 }
504 
GzipFile(fname,gzipped_fname)505 int GzipFile(fname, gzipped_fname)
506    char *fname, *gzipped_fname;
507 {
508    int rc=TRUE;
509    FILE *pfp=NULL, *out_fp=NULL;
510    char *compress_cmd=NULL, *cmd=NULL;
511 
512    if ((out_fp=fopen(gzipped_fname, "w")) == NULL) {
513       return FailToOpenMessage(gzipped_fname, "w", NULL);
514    }
515    SaveStatusStrings();
516    compress_cmd = gzipCmd;
517 
518    cmd = (char*)malloc((strlen(fname)+strlen(compress_cmd)+20) * sizeof(char));
519    if (cmd == NULL) FailAllocMessage();
520 
521    if (strstr(compress_cmd, "%s") == NULL) {
522       sprintf(cmd, "%s %s", compress_cmd, fname);
523    } else {
524       sprintf(cmd, compress_cmd, fname);
525    }
526    if (!FindProgramInPath(cmd, NULL, FALSE)) {
527       fclose(out_fp);
528       free(cmd);
529       RestoreStatusStrings();
530       return FALSE;
531    }
532    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
533          gzipCmd);
534    SetStringStatus(gszMsgBox);
535 
536    if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
537       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), cmd);
538       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
539       fclose(out_fp);
540       rc = FALSE;
541    } else {
542       int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
543 
544       if (!watch_cursor) {
545          SetWatchCursor(drawWindow);
546          SetWatchCursor(mainWindow);
547       }
548       writeFileFailed = FALSE;
549       while ((bytes_read=fread(gszMsgBox, sizeof(char), sizeof(gszMsgBox),
550             pfp)) > 0) {
551          if ((int)fwrite(gszMsgBox, sizeof(char), bytes_read, out_fp) <= 0) {
552             writeFileFailed = TRUE;
553             break;
554          }
555       }
556       pclose(pfp);
557       if (!watch_cursor) {
558          SetDefaultCursor(mainWindow);
559          ShowCursor();
560       }
561       fclose(out_fp);
562       if (writeFileFailed) {
563          FailToWriteFileMessage(gzipped_fname);
564          rc = FALSE;
565       }
566    }
567    RestoreStatusStrings();
568    return rc;
569 }
570 
GunzipFileIntoTemp(gzipped_fname)571 char *GunzipFileIntoTemp(gzipped_fname)
572    char *gzipped_fname;
573 {
574    FILE *pfp=NULL, *out_fp=NULL;
575    char *uncompress_cmd=gunzipCmd, *tmp_fname=NULL, *cmd=NULL;
576 
577    tmp_fname = (char*)malloc((strlen(tmpDir)+20)*sizeof(char));
578    if (tmp_fname == NULL) {
579       FailAllocMessage();
580       return NULL;
581    }
582    if (MkTempFile(tmp_fname, (strlen(tmpDir)+19)*sizeof(char), tmpDir,
583          TOOL_NAME) == NULL) {
584       return NULL;
585    }
586    if ((out_fp=fopen(tmp_fname, "w")) == NULL) {
587       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
588             tmp_fname);
589       if (PRTGIF) {
590          fprintf(stderr, "%s\n", gszMsgBox);
591       } else {
592          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
593       }
594       return NULL;
595    }
596    SaveStatusStrings();
597    uncompress_cmd = gunzipCmd;
598 
599    cmd = (char*)malloc((strlen(gzipped_fname)+strlen(uncompress_cmd)+20) *
600          sizeof(char));
601    if (cmd == NULL) FailAllocMessage();
602 
603    if (strstr(uncompress_cmd, "%s") == NULL) {
604       sprintf(cmd, "%s %s", uncompress_cmd, gzipped_fname);
605    } else {
606       sprintf(cmd, uncompress_cmd, gzipped_fname);
607    }
608    if (!FindProgramInPath(cmd, NULL, FALSE)) {
609       fclose(out_fp);
610       unlink(tmp_fname);
611       free(cmd);
612       RestoreStatusStrings();
613       return NULL;
614    }
615    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
616          gunzipCmd);
617    if (PRTGIF) {
618       fprintf(stderr, "%s\n", gszMsgBox);
619    } else {
620       SetStringStatus(gszMsgBox);
621    }
622    if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
623       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), cmd);
624       if (PRTGIF) {
625          fprintf(stderr, "%s\n", gszMsgBox);
626       } else {
627          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
628       }
629       fclose(out_fp);
630       unlink(tmp_fname);
631       tmp_fname = NULL;
632    } else {
633       int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
634 
635       if (!watch_cursor) {
636          SetWatchCursor(drawWindow);
637          SetWatchCursor(mainWindow);
638       }
639       writeFileFailed = FALSE;
640       while ((bytes_read=fread(gszMsgBox, sizeof(char), sizeof(gszMsgBox),
641             pfp)) > 0) {
642          if ((int)fwrite(gszMsgBox, sizeof(char), bytes_read, out_fp) <= 0) {
643             writeFileFailed = TRUE;
644             break;
645          }
646       }
647       pclose(pfp);
648       if (!watch_cursor) {
649          SetDefaultCursor(mainWindow);
650          ShowCursor();
651       }
652       fclose(out_fp);
653       if (writeFileFailed) {
654          FailToWriteFileMessage(tmp_fname);
655          unlink(tmp_fname);
656          tmp_fname = NULL;
657       }
658    }
659    RestoreStatusStrings();
660    return tmp_fname;
661 }
662 
663 #ifdef USE_XAPPLRESDIR
664 static
FindXApplResDir(psz_srch_path,psz_target_dir,cb_target_dir)665 int FindXApplResDir(psz_srch_path, psz_target_dir, cb_target_dir)
666    char *psz_srch_path, *psz_target_dir;
667    int cb_target_dir;
668 {
669    char *c_ptr, *buf=UtilStrDup(psz_srch_path);
670 
671    if (buf == NULL) return FALSE;
672 
673    for (c_ptr=strtok(buf, ":"); c_ptr != NULL; c_ptr=strtok(NULL, ":")) {
674       int len=strlen(c_ptr);
675       char path[MAXPATHLENGTH+1];
676       FILE *fp;
677 
678       if (len > 0 && c_ptr[len-1] == DIR_SEP) c_ptr[--len] = DIR_SEP;
679       sprintf(path, "%s%c%s", c_ptr, DIR_SEP, TOOL_NAME);
680       if ((fp=fopen(path, "r")) != NULL) {
681          UtilStrCpyN(psz_target_dir, cb_target_dir, c_ptr);
682          UtilFree(buf);
683          return TRUE;
684       }
685    }
686    UtilFree(buf);
687    return FALSE;
688 }
689 #endif /* USE_XAPPLRESDIR */
690 
691 #ifndef _NO_LOCALE_SUPPORT
692 #ifdef ENABLE_NLS
693 static
InitLocale()694 void InitLocale()
695 {
696    char *c_ptr=NULL;
697 
698    c_ptr = MySetLocale(LC_ALL, "");
699    if (c_ptr == NULL) {
700       fprintf(stderr, "%s\n", TgLoadString(STID_CANNOT_SET_LOCALE_ENV_VARS));
701    }
702    if (x11R6OrAbove) {
703       if (useXlib) {
704          if (!XSupportsLocale()) {
705             fprintf(stderr, "%s\n",
706                   TgLoadString(STID_XLIB_CANT_SET_LOCALE_ENV_VARS));
707             MySetLocale(LC_ALL, "C");
708          }
709          if (!XSetLocaleModifiers("")) {
710             if (getenv("LANG") != NULL) {
711                fprintf(stderr, "%s\n",
712                      TgLoadString(STID_CANT_SET_LOCALE_MODIFIERS));
713             }
714          }
715       } else {
716 #ifdef USE_XT_INITIALIZE
717          if (XtSetLanguageProc(NULL, NULL, NULL) == NULL) {
718             fprintf(stderr, "%s\n",
719                   TgLoadString(STID_XT_CANNOT_SET_LOCALE_ENV_VARS));
720             MySetLocale(LC_ALL, "C");
721          }
722 #endif /* USE_XT_INITIALIZE */
723       }
724    }
725    MySetLocale(LC_ALL, NULL);
726 
727    /*
728     * Some locale uses "," as decimal point.  That won't work in
729     *       saving files or generating EPS files.  Must use "."
730     *       as decimal point.
731     * From this point on, setlocale() should NEVER be called again!
732     */
733    setlocale(LC_NUMERIC, "C");
734 }
735 
736 static
InitLocale2()737 void InitLocale2()
738 {
739    DIR *dirp=NULL;
740    char package[80], *c_ptr=NULL, locale_dir[MAXPATHLENGTH];
741 
742    *locale_dir = '\0';
743    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"LocaleDir")) != NULL) {
744       strcpy(locale_dir, c_ptr);
745    } else {
746       strcpy(locale_dir, LOCALEDIR);
747    }
748    UtilTrimBlanks(locale_dir);
749 
750    strcpy(package, TOOL_NAME);
751    UtilStrLower(package);
752 
753    if ((dirp=opendir(locale_dir)) == NULL) {
754       fprintf(stderr, TgLoadString(STID_LOCALE_DIR_NOT_EXIST_USE_XDEF),
755             locale_dir, TOOL_NAME, "LocaleDir");
756       fprintf(stderr, "\n");
757    } else {
758       closedir(dirp);
759       bindtextdomain(package, locale_dir);
760       textdomain(package);
761    }
762 }
763 #endif /* ENABLE_NLS */
764 #endif /* ~_NO_LOCALE_SUPPORT */
765 
766 static
JustLoadAFile(pszFile,pnNeedToCheckAutoExec,nAttemptToMerge,pnAbortMerge)767 int JustLoadAFile(pszFile, pnNeedToCheckAutoExec, nAttemptToMerge, pnAbortMerge)
768    char *pszFile;
769    int *pnNeedToCheckAutoExec, nAttemptToMerge, *pnAbortMerge;
770    /*
771     * return FALSE if nAttemptToMerge is TRUE and pszFile is in
772     *       TILED page mode
773     * return TRUE otherwise
774     */
775 {
776    int short_name=FALSE, obj_file=TRUE;
777    int tmp_linenum=0;
778    char tmp_filename[MAXPATHLENGTH+1], tmp_filefullpath[MAXPATHLENGTH+1];
779    char full_name[MAXPATHLENGTH+1], *rest=NULL;
780    char file_name[MAXPATHLENGTH+1], gzipped_fname[MAXPATHLENGTH+1];
781    int rc=0, gzipped_obj_file=FALSE;
782    int file_is_remote=FALSE, remote_buf_sz=0, is_html=FALSE;
783    char remote_fname[MAXPATHLENGTH+1], *tmp_remote_fname=NULL;
784    char *remote_buf=NULL, *page_spec=NULL;
785    struct ObjRec *obj_ptr=NULL;
786    FILE *fp=NULL;
787 
788    *remote_fname = *gzipped_fname = '\0';
789 
790    if (FileIsRemote(pszFile)) {
791       if (!FormNewFileName(curDir, pszFile, NULL, remote_fname, &page_spec)) {
792          sprintf(gszMsgBox, TgLoadString(STID_INVALID_REMOTE_FNAME), pszFile);
793          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
794          *pszFile = '\0';
795       } else {
796          char *content_type=NULL;
797          char final_url[MAXPATHLENGTH+1];
798 
799          *final_url = '\0';
800          SaveStatusStrings();
801          rc = LoadRemoteFileInMem(remote_fname, &remote_buf,
802                &content_type, &remote_buf_sz, &is_html, TRUE,
803                final_url, sizeof(final_url));
804          RestoreStatusStrings();
805          if (rc && remote_buf != NULL &&
806                (tmp_remote_fname=WriteRemoteFileIntoTemp(remote_buf,
807                remote_buf_sz, NULL)) != NULL) {
808             if (*final_url != '\0') {
809                UtilStrCpyN(pszFile, MAXPATHLENGTH+1, final_url);
810                UtilStrCpyN(remote_fname, MAXPATHLENGTH+1, final_url);
811             }
812             if (FileNameHasExtension(remote_fname, OBJ_FILE_TYPE,
813                   &gzipped_obj_file, NULL)) {
814                file_is_remote = TRUE;
815             } else if (UseExternalViewer(is_html, remote_fname, content_type,
816                   tmp_remote_fname) != FALSE) {
817                unlink(tmp_remote_fname);
818                FreeRemoteBuf(tmp_remote_fname);
819                if (remote_buf != NULL) FreeRemoteBuf(remote_buf);
820                remote_buf = tmp_remote_fname = NULL;
821                file_is_remote = FALSE;
822                *pszFile = '\0';
823             } else {
824                file_is_remote = TRUE;
825             }
826          } else {
827             if (remote_buf != NULL) FreeRemoteBuf(remote_buf);
828             remote_buf = NULL;
829             *pszFile = '\0';
830          }
831          if (content_type != NULL) FreeRemoteBuf(content_type);
832       }
833    }
834    *file_name = '\0';
835    if (file_is_remote) {
836       if ((fp=fopen(tmp_remote_fname, "r")) == NULL) {
837          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_READ_TMP_FILE),
838                tmp_remote_fname);
839          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
840 
841          unlink(tmp_remote_fname);
842          FreeRemoteBuf(tmp_remote_fname);
843          FreeRemoteBuf(remote_buf);
844          remote_buf = tmp_remote_fname = NULL;
845          file_is_remote = FALSE;
846       } else {
847       if (FileNameHasExtension(remote_fname, SYM_FILE_TYPE, NULL, NULL)) {
848             obj_file = FALSE;
849          } else if (FileNameHasExtension(remote_fname, PIN_FILE_TYPE,
850                NULL, NULL)) {
851             obj_file = FALSE;
852          } else {
853             obj_file = TRUE;
854          }
855       }
856    } else {
857       if (FileNameHasExtension(pszFile, OBJ_FILE_TYPE, &gzipped_obj_file,
858             NULL)) {
859          if (gzipped_obj_file) {
860             char *tmp_fname=NULL;
861 
862             if ((tmp_fname=GunzipFileIntoTemp(pszFile)) == NULL) {
863                *file_name = '\0';
864             } else {
865                strcpy(gzipped_fname, pszFile);
866                strcpy(file_name, tmp_fname);
867                free(tmp_fname);
868             }
869          } else {
870             strcpy(file_name, pszFile);
871          }
872       } else if (FileNameHasExtension(pszFile, SYM_FILE_TYPE, NULL, NULL)) {
873          strcpy(file_name, pszFile);
874          obj_file = FALSE;
875       } else if (FileNameHasExtension(pszFile, PIN_FILE_TYPE, NULL, NULL)) {
876          strcpy(file_name, pszFile);
877          obj_file = FALSE;
878       } else {
879          sprintf(file_name, "%s.%s", pszFile, OBJ_FILE_EXT);
880       }
881       if (*gzipped_fname == '\0') {
882          if ((short_name=IsPrefix(bootDir, file_name, &rest))) ++rest;
883       } else {
884          if ((short_name=IsPrefix(bootDir, gzipped_fname, &rest))) ++rest;
885       }
886    }
887    if (*file_name != '\0' && (fp=fopen(file_name, "r")) == NULL) {
888       DelAllPages();
889       lastPageNum = 1;
890       InitPage();
891 
892       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_READING),
893             (short_name ? rest : file_name));
894       Msg(gszMsgBox);
895 
896       if (*file_name == DIR_SEP) {
897          strcpy(full_name, file_name);
898       } else {
899          sprintf(full_name, "%s%c%s", curDir, DIR_SEP, file_name);
900       }
901       if (!cmdLineMerge) {
902          if (obj_file) {
903             SetCurDir(full_name);
904             *curSymDir = '\0';
905          } else {
906             SetCurSymDir(full_name);
907          }
908          curFileDefined = TRUE;
909       }
910       SetFileModified(FALSE);
911       sprintf(gszMsgBox, TgLoadString(STID_CUR_EMPTY_FILE_IS),
912             (short_name ? rest : file_name));
913       Msg(gszMsgBox);
914    } else if (file_is_remote || *file_name != '\0') {
915       int read_status;
916 
917       SetFileModified(FALSE);
918       SaveStatusStrings();
919       if (file_is_remote) {
920          sprintf(gszMsgBox, TgLoadCachedString(CSTID_LOADING_FILE),
921                remote_fname);
922       } else {
923          if (short_name) {
924             sprintf(gszMsgBox, TgLoadCachedString(CSTID_LOADING_FILE), rest);
925          } else {
926             if (*gzipped_fname == '\0') {
927                sprintf(gszMsgBox, TgLoadCachedString(CSTID_LOADING_FILE),
928                      file_name);
929             } else {
930                sprintf(gszMsgBox, TgLoadCachedString(CSTID_LOADING_FILE),
931                      gzipped_fname);
932             }
933          }
934          if (*gzipped_fname == '\0') {
935             if (*file_name == DIR_SEP) {
936                strcpy(full_name, file_name);
937             } else {
938                sprintf(full_name, "%s%c%s", curDir, DIR_SEP, file_name);
939             }
940          } else {
941             if (*gzipped_fname == DIR_SEP) {
942                strcpy(full_name, gzipped_fname);
943             } else {
944                sprintf(full_name, "%s%c%s", curDir, DIR_SEP,
945                      gzipped_fname);
946             }
947          }
948       }
949       SetStringStatus(gszMsgBox);
950 
951       strcpy(tmp_filefullpath, scanFileFullPath);
952       strcpy(tmp_filename, scanFileName);
953       tmp_linenum = scanLineNum;
954       UtilStrCpyN(scanFileFullPath, sizeof(scanFileFullPath),
955             (file_is_remote ? remote_fname : full_name));
956       if (file_is_remote) {
957          strcpy(scanFileName, tmp_remote_fname);
958       } else {
959          strcpy(scanFileName, (short_name ? rest : file_name));
960       }
961       scanLineNum = 0;
962 
963       SetWatchCursor(drawWindow);
964       SetWatchCursor(mainWindow);
965 
966       readingPageNum = loadedCurPageNum = 0;
967       foundGoodStateObject = FALSE;
968       while ((read_status=ReadObj(fp, &obj_ptr)) == TRUE) {
969          if (obj_ptr != NULL) {
970             obj_ptr->tmp_parent = NULL;
971             AdjForOldVersion(obj_ptr);
972             AddObj(NULL, topObj, obj_ptr);
973          }
974       }
975       strcpy(scanFileFullPath, tmp_filefullpath);
976       strcpy(scanFileName, tmp_filename);
977       scanLineNum = tmp_linenum;
978 
979       fclose(fp);
980 
981       if (!mergingFile && loadedCurPageNum <= 0) {
982          DelAllPages();
983          loadedCurPageNum = curPageNum = lastPageNum = 1;
984          InitPage();
985       }
986       if (read_status == INVALID) {
987          sprintf(gszMsgBox, TgLoadString(STID_FILE_VER_ABORT_OPEN),
988                fileVersion, TOOL_NAME, homePageURL);
989          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
990       } else {
991          if (loadedCurPageNum > 0 && curPage != NULL) {
992             GotoPageNum(loadedCurPageNum);
993          }
994          CheckFileAttrsInLoad();
995 
996          curFileDefined = TRUE;
997          if (file_is_remote) {
998             if (!cmdLineMerge) {
999                SetCurDir(remote_fname);
1000             }
1001             if (!foundGoodStateObject) PasteString(remote_buf, TRUE, TRUE);
1002          } else {
1003             if (*gzipped_fname == '\0') {
1004                if (*file_name == DIR_SEP) {
1005                   strcpy(full_name, file_name);
1006                } else {
1007                   sprintf(full_name, "%s%c%s", curDir, DIR_SEP, file_name);
1008                }
1009             } else {
1010                if (*gzipped_fname == DIR_SEP) {
1011                   strcpy(full_name, gzipped_fname);
1012                } else {
1013                   sprintf(full_name, "%s%c%s", curDir, DIR_SEP,
1014                         gzipped_fname);
1015                }
1016             }
1017             if (!cmdLineMerge) {
1018                if (obj_file) {
1019                   SetCurDir(full_name);
1020                   *curSymDir = '\0';
1021                } else {
1022                   SetCurSymDir(full_name);
1023                }
1024             }
1025          }
1026          if (file_is_remote) {
1027             sprintf(gszMsgBox, TgLoadCachedString(CSTID_CUR_FILE_IS),
1028                   remote_fname);
1029             RedrawDrawWindow(botObj);
1030          } else if (short_name) {
1031             sprintf(gszMsgBox, TgLoadCachedString(CSTID_CUR_FILE_IS), rest);
1032          } else {
1033             sprintf(gszMsgBox, TgLoadCachedString(CSTID_CUR_FILE_IS),
1034                   (*gzipped_fname == '\0' ? file_name : gzipped_fname));
1035          }
1036          Msg(gszMsgBox);
1037       }
1038       RestoreStatusStrings();
1039 
1040       GotoPageNum(loadedCurPageNum);
1041       SetDefaultCursor(mainWindow);
1042       SetDefaultCursor(drawWindow);
1043 
1044       if (file_is_remote) {
1045          unlink(tmp_remote_fname);
1046          if (tmp_remote_fname != NULL) FreeRemoteBuf(tmp_remote_fname);
1047          if (remote_buf != NULL) FreeRemoteBuf(remote_buf);
1048          remote_buf = tmp_remote_fname = NULL;
1049          if (!nAttemptToMerge && !mergingFile) CommitNavigate();
1050       } else {
1051          if (*gzipped_fname != '\0') {
1052             unlink(file_name);
1053          }
1054       }
1055       if (foundGoodStateObject && !nAttemptToMerge && !mergingFile) {
1056          struct AttrRec *exec_attr=FindFileAttrWithName("auto_exec=");
1057 
1058          if (!nAttemptToMerge && !mergingFile) CommitNavigate();
1059          if (exec_attr != NULL) {
1060             XSync(mainDisplay, False);
1061             if (pnNeedToCheckAutoExec != NULL) *pnNeedToCheckAutoExec = TRUE;
1062          }
1063       }
1064    }
1065    if (page_spec != NULL) {
1066       int new_page_num=(-1);
1067 
1068       if (!GetPageNumFromPageSpec(page_spec, &new_page_num)) {
1069          sprintf(gszMsgBox, TgLoadString(STID_INVALID_PAGE_SPECIFIED_FOR),
1070                pszFile);
1071          Msg(gszMsgBox);
1072       } else if (new_page_num != curPageNum) {
1073          GotoPageNum(new_page_num);
1074       }
1075    }
1076    if (page_spec != NULL) free(page_spec);
1077 
1078    if (pageLayoutMode == PAGE_TILE && nAttemptToMerge && pnAbortMerge != NULL) {
1079       if (file_is_remote) {
1080          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_MERGE_WITH_TILED_PAGE),
1081                remote_fname);
1082       } else if (short_name) {
1083          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_MERGE_WITH_TILED_PAGE),
1084                rest);
1085       } else {
1086          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_MERGE_WITH_TILED_PAGE),
1087                (*gzipped_fname == '\0' ? file_name : gzipped_fname));
1088       }
1089       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1090       *pnAbortMerge = TRUE;
1091    }
1092    return TRUE;
1093 }
1094 
1095 static
SigchldHandler(sig)1096 void SigchldHandler(sig)
1097    int sig;
1098 {
1099    int status;
1100 
1101    /* wait for all the zombie processes to terminate */
1102    while(waitpid(-1, &status, WNOHANG) > 0);
1103 }
1104 
JustInit(pszFile,pnNeedToCheckAutoExec)1105 int JustInit(pszFile, pnNeedToCheckAutoExec)
1106    char *pszFile;
1107    int *pnNeedToCheckAutoExec;
1108 {
1109    int cannot_opendisplay=FALSE, allow_open=TRUE;
1110 
1111 #ifdef USE_XT_INITIALIZE
1112    useXlib = cmdLineUseXlib;
1113 #else /* ~USE_XT_INITIALIZE */
1114 #ifdef USE_XAPPLRESDIR
1115    FILE *xenv_fp=NULL;
1116    char *c_ptr=NULL, *xEnvStr=NULL, tmp_buf[MAXPATHLENGTH+1];
1117    int len=0;
1118 
1119 #ifdef XAPPLOADDIR_DEF
1120    if (getenv("XENVIRONMENT") == NULL) {
1121       if (((c_ptr=getenv("XAPPLRESDIR")) == NULL)) {
1122          UtilStrCpyN(tmp_buf, sizeof(tmp_buf), XAPPLOADDIR_DEF);
1123       } else if (!FindXApplResDir(c_ptr, tmp_buf, sizeof(tmp_buf))) {
1124          UtilStrCpyN(tmp_buf, sizeof(tmp_buf), XAPPLOADDIR_DEF);
1125       }
1126       c_ptr = tmp_buf;
1127       len = strlen(c_ptr);
1128 #else /* ~XAPPLOADDIR_DEF */
1129    if ((getenv("XENVIRONMENT") == NULL) &&
1130          ((c_ptr=getenv("XAPPLRESDIR")) != NULL) && ((len=strlen(c_ptr)) > 0)) {
1131       if (FindXApplResDir(c_ptr, tmp_buf, sizeof(tmp_buf))) {
1132          c_ptr = tmp_buf;
1133       }
1134       len = strlen(c_ptr);
1135 #endif /* XAPPLOADDIR_DEF */
1136       xEnvStr = (char*)malloc(
1137             (strlen("XENVIRONMENT=")+strlen(TOOL_NAME)+len+3)*sizeof(char));
1138       if (xEnvStr == NULL) FailAllocMessage();
1139       sprintf(xEnvStr, "%s%s%s", c_ptr,
1140             ((c_ptr[len-1] == DIR_SEP) ? "" : DIR_SEP_STR), TOOL_NAME);
1141       if ((xenv_fp=fopen(xEnvStr, "r")) != NULL) {
1142          fclose(xenv_fp);
1143          sprintf(xEnvStr, "XENVIRONMENT=%s%s%s", c_ptr,
1144                ((c_ptr[len-1] == DIR_SEP) ? "" : DIR_SEP_STR), TOOL_NAME);
1145          if (putenv(xEnvStr)) {
1146             sprintf(gszMsgBox, TgLoadString(STID_WARN_CANT_PUTENV_GIVEN),
1147                   xEnvStr);
1148             Msg(gszMsgBox);
1149             *xEnvStr = '\0';
1150             free(xEnvStr);
1151             xEnvStr = NULL;
1152          }
1153       }
1154    }
1155 #endif /* USE_XAPPLRESDIR */
1156    useXlib = TRUE;
1157 #endif /* USE_XT_INITIALIZE */
1158 
1159 #ifndef _NO_LOCALE_SUPPORT
1160    MySetLocale(LC_ALL, "C");
1161    MySetLocale(LC_NUMERIC, "C");
1162 #ifdef ENABLE_NLS
1163    InitLocale();
1164 #endif /* ENABLE_NLS */
1165 #endif /* ~_NO_LOCALE_SUPPORT */
1166 
1167    if (useXlib) {
1168       cannot_opendisplay = ((mainDisplay=XOpenDisplay(displayName)) == 0);
1169    } else {
1170 #ifdef USE_XT_INITIALIZE
1171       toplevel = XtInitialize(TOOL_NAME, TOOL_NAME, NULL, 0, &origArgC,
1172             origArgV);
1173       cannot_opendisplay = (toplevel == NULL ||
1174             (mainDisplay=XtDisplay(toplevel)) == 0);
1175 #endif /* USE_XT_INITIALIZE */
1176    }
1177    if (cannot_opendisplay) {
1178       if (displayName == NULL) {
1179          fprintf(stderr, "%s\n", TgLoadString(STID_CANT_OPEN_DISPLAY_ABORT));
1180          exit(-1);
1181       } else {
1182          fprintf(stderr, TgLoadString(STID_CANT_OPEN_GIVEN_DPY_ABORT),
1183                displayName);
1184          fprintf(stderr, "\n");
1185          exit(-1);
1186       }
1187    }
1188    mainScreen = DefaultScreen(mainDisplay);
1189    mainColormap = DefaultColormap(mainDisplay, mainScreen);
1190    mainDepth = DefaultDepth(mainDisplay, mainScreen);
1191    mainVisual = DefaultVisual(mainDisplay, mainScreen);
1192    rootWindow = RootWindow(mainDisplay, mainScreen);
1193 
1194 #ifdef NOT_DEFINED /* debug, do not translate */
1195    fprintf(stderr,"mainDepth               =%d\n",mainDepth);
1196    fprintf(stderr,"mainVisual->class       =%d\n",mainVisual->class);
1197    fprintf(stderr,"mainVisual->red_mask    =0x%08lx\n",mainVisual->red_mask);
1198    fprintf(stderr,"mainVisual->green_mask  =0x%08lx\n",mainVisual->green_mask);
1199    fprintf(stderr,"mainVisual->blue_mask   =0x%08lx\n",mainVisual->blue_mask);
1200    fprintf(stderr,"mainVisual->bits_per_rgb=%d\n",mainVisual->bits_per_rgb);
1201    fprintf(stderr,"mainVisual->map_entries =%d\n",mainVisual->map_entries);
1202 #endif /* NOT_DEFINED */
1203 
1204    XSetErrorHandler(EmergencySaveForX);
1205    XSetIOErrorHandler(IOEmergencySaveForX);
1206    signal(SIGHUP, EmergencySave);
1207    signal(SIGFPE, EmergencySave);
1208 #ifndef linux
1209    signal(SIGBUS, EmergencySave);
1210 #endif /* ~linux */
1211    signal(SIGSEGV, EmergencySave);
1212    signal(SIGCHLD, SigchldHandler);
1213 
1214 #ifndef _NO_LOCALE_SUPPORT
1215 #ifdef ENABLE_NLS
1216    InitLocale2();
1217 #endif /* ENABLE_NLS */
1218 #endif /* ~_NO_LOCALE_SUPPORT */
1219 
1220    InitWhiteBoard();
1221 
1222    Setup();
1223    InitExtraWinInfo();
1224    InitLastKeyOrBtnEvInfo();
1225    quitDraw = FALSE;
1226    prTgifFoundColorInfo = FALSE;
1227 
1228    InitWhiteBoard2();
1229    if (pszFile == NULL) {
1230       /* Only gets here if PRTGIF of UrlDump() */
1231       DelAllPages();
1232       lastPageNum = 1;
1233       InitPage();
1234       return TRUE;
1235    }
1236    initializingMain = TRUE;
1237 
1238    if (gstWBInfo.do_whiteboard) {
1239       static int initialized=FALSE;
1240 
1241 #ifdef _TGIF_DBG /* debug, do not translate */
1242       TgAssert(!initialized,
1243             "Whiteboard initialized too many times in JustInit()", NULL);
1244 #endif /* _TGIF_DBG */
1245       if (gstWBInfo.join_session_in_progress) {
1246          allow_open = FALSE;
1247       }
1248       initialized = TRUE;
1249    }
1250    if (!allow_open) {
1251       char *fname=NULL;
1252 
1253       *gszMsgBox = '\0';
1254       if (cmdLineMerge && cmdLineMergeArgc > 0 && cmdLineMergeArgv != NULL) {
1255          fname = cmdLineMergeArgv[0];
1256          sprintf(gszMsgBox, TgLoadString(STID_JOIN_WB_IN_PROGRESS_IGNORED),
1257                fname);
1258          cmdLineMerge = FALSE;
1259       } else if (*pszFile != '\0') {
1260          fname = pszFile;
1261          sprintf(gszMsgBox, TgLoadString(STID_JOIN_WB_IN_PROGRESS_IGNORED),
1262                fname);
1263          *pszFile = '\0';
1264       }
1265       if (fname != NULL) {
1266          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1267          UtilFree(fname);
1268       }
1269    }
1270    if (cmdLineMerge && cmdLineMergeArgc > 0 && cmdLineMergeArgv != NULL) {
1271       int arg_index=0, abort_merge=FALSE, num_argc=cmdLineMergeArgc;
1272       int identical=FALSE;
1273       char **ppsz_html_export_template=(char**)malloc(cmdLineMergeArgc*
1274             sizeof(char*));
1275 
1276       if (ppsz_html_export_template == NULL) FailAllocMessage();
1277       memset(ppsz_html_export_template, 0, cmdLineMergeArgc*sizeof(char*));
1278 
1279       if (JustLoadAFile(cmdLineMergeArgv[0], NULL, TRUE, &abort_merge)) {
1280          ppsz_html_export_template[0] = UtilStrDup(gszHhtmlExportTemplate);
1281          if (ppsz_html_export_template[0] == NULL) FailAllocMessage();
1282 
1283          if (!abort_merge) {
1284             PageInfo pi;
1285 
1286             memset(&pi, 0, sizeof(PageInfo));
1287             GetPageInfo(&pi);
1288 
1289             CleanUpComments();
1290 
1291             firstPage = lastPage = curPage = NULL;
1292             topObj = botObj = NULL;
1293             DelAllPages();
1294             lastPageNum = 1;
1295             InitPage();
1296 
1297             mergingFile = TRUE;
1298             for (arg_index=1; arg_index < cmdLineMergeArgc; arg_index++) {
1299                if (!JustLoadAFile(cmdLineMergeArgv[arg_index], NULL, FALSE,
1300                      NULL)) {
1301                   break;
1302                }
1303                ppsz_html_export_template[arg_index] =
1304                      UtilStrDup(gszHhtmlExportTemplate);
1305                if (ppsz_html_export_template[arg_index] == NULL) {
1306                   FailAllocMessage();
1307                }
1308                CleanUpComments();
1309 
1310                firstPage->prev = pi.last_page;
1311                if (pi.last_page == NULL) {
1312                   pi.first_page = firstPage;
1313                } else {
1314                   pi.last_page->next = firstPage;
1315                }
1316                pi.last_page = lastPage;
1317                pi.last_page_num += lastPageNum;
1318 
1319                firstPage = lastPage = curPage = NULL;
1320                topObj = botObj = NULL;
1321 
1322                DelAllPages();
1323                lastPageNum = 1;
1324                InitPage();
1325             }
1326             mergingFile = FALSE;
1327             DelAllPages();
1328 
1329             curPageNum = pi.cur_page_num;
1330             lastPageNum = pi.last_page_num;
1331             firstPage = pi.first_page;
1332             lastPage = pi.last_page;
1333             curPage = pi.cur_page;
1334             topObj = curPage->top;
1335             botObj = curPage->bot;
1336          }
1337       }
1338       CleanUpMergeArgs();
1339       ClearFileInfo(FALSE);
1340       SetFileModified(TRUE);
1341 
1342       identical = TRUE;
1343       for (arg_index=1; arg_index < num_argc; arg_index++) {
1344          if (strcmp(ppsz_html_export_template[0],
1345                ppsz_html_export_template[arg_index]) != 0) {
1346             identical = FALSE;
1347             break;
1348          }
1349       }
1350       if (!identical) {
1351          UtilStrCpyN(gszMsgBox, sizeof(gszMsgBox),
1352                TgLoadString(STID_NO_HTML_TEMPLATE_FILE));
1353          Msg(gszMsgBox);
1354       } else if (*ppsz_html_export_template[0] != '\0') {
1355          UtilStrCpyN(gszHhtmlExportTemplate, sizeof(gszHhtmlExportTemplate),
1356             ppsz_html_export_template[0]);
1357          sprintf(gszMsgBox, TgLoadString(STID_HTML_TEMPLATE_SET_TO_GIVEN),
1358                gszHhtmlExportTemplate);
1359          Msg(gszMsgBox);
1360       }
1361       for (arg_index=0; arg_index < num_argc; arg_index++) {
1362          UtilFree(ppsz_html_export_template[arg_index]);
1363       }
1364       free(ppsz_html_export_template);
1365    } else if (*pszFile != '\0') {
1366       JustLoadAFile(pszFile, pnNeedToCheckAutoExec, FALSE, NULL);
1367    } else {
1368       if (allow_open) {
1369          DelAllPages();
1370          lastPageNum = 1;
1371          InitPage();
1372       } else {
1373          SetFileModified(TRUE);
1374       }
1375    }
1376    SetDefaultDrawWinClipRecs();
1377    UpdateDirInfo();
1378 
1379    initializingMain = FALSE;
1380 
1381    return TRUE;
1382 }
1383 
HandleDataInMBuff()1384 void HandleDataInMBuff()
1385 {
1386    if (gstWBInfo.do_whiteboard) {
1387       TryHandleWBInputData();
1388    }
1389 }
1390 
1391 static
GetAnXEvent(pXEvent)1392 int GetAnXEvent(pXEvent)
1393    XEvent *pXEvent;
1394 {
1395    if (gstWBInfo.do_whiteboard) {
1396       int rc=TRUE;
1397 
1398       gstWBInfo.BlockRemoteCmdDepth--;
1399 #ifdef DEBUG0
1400       fprintf(stderr,"BlockRemoteCmdDepth (GetAnXEvent): %d\n",
1401             gstWBInfo.BlockRemoteCmdDepth);
1402 #endif /* DEBUG0 */
1403       if (XPending(mainDisplay)) {
1404          if (gnInputMethod != TGIM_NONE && tgIMExpectNextEvent(mainDisplay,
1405                drawWindow)) {
1406             if (!tgIMHandleNextEvent(mainDisplay, drawWindow, pXEvent)) {
1407             }
1408          } else {
1409             XNextEvent(mainDisplay, pXEvent);
1410          }
1411       } else {
1412          struct timeval timeout;
1413          fd_set fdset;
1414          int select_width=XConnectionNumber(mainDisplay)+1, status=0, nfds=0;
1415 
1416          nfds = max(select_width, (int)(talkToSelfFiledes[0]+1));
1417 
1418          timeout.tv_sec = 15;
1419          timeout.tv_usec = 0;
1420 
1421          FD_ZERO(&fdset);
1422          FD_SET(select_width-1, &fdset); /* X file descriptor */
1423          FD_SET(talkToSelfFiledes[0], &fdset); /* pipe */
1424 #ifdef __hpux
1425          status = select(nfds, (int*)&fdset, NULL, NULL, &timeout);
1426 #else /* !__hpux */
1427          status = select(nfds, &fdset, NULL, NULL, &timeout);
1428 #endif /* __hpux */
1429          if (status < 0) {
1430             if (errno == EINTR) {
1431                /* interrupted by a system call, not a problem */
1432             } else {
1433                sprintf(gszMsgBox,
1434                      TgLoadString(STID_FUNC_SELECT_SYS_CALL_FAILED),
1435                      "GetAnXEvent()"),
1436                fprintf(stderr, "%s\n", gszMsgBox);
1437             }
1438             rc = FALSE;
1439          } else if (status == 0) {
1440             /* timeout */
1441             rc = FALSE;
1442          } else if (status == 1) {
1443             if (FD_ISSET(talkToSelfFiledes[0], &fdset)) {
1444                char buf[2];
1445 
1446                if (read(talkToSelfFiledes[0], buf, 1) != 1) {
1447                   sprintf(gszMsgBox,
1448                         TgLoadString(STID_READ_FROM_SELF_PIPE_FAIL), 1,
1449                         TOOL_NAME),
1450                   fprintf(stderr, "%s\n", gszMsgBox);
1451                } else {
1452                   if (*buf == 'a') {
1453                      SendCommandToSelf(CMDID_DATA_IN_MBUFF, 0);
1454                   } else if (*buf == 'c') {
1455                      /*
1456                       * Get current tgwb state and establish
1457                       *         a TCP conection to send the data.
1458                       */
1459                      HandleNewUserRequest();
1460                   } else {
1461                      sprintf(gszMsgBox,
1462                            TgLoadString(STID_UNRECOG_BYTE_FROM_SELF_PIPE), *buf,
1463                            TOOL_NAME),
1464                      fprintf(stderr, "%s\n", gszMsgBox);
1465                   }
1466                }
1467                rc = FALSE;
1468             } else if (FD_ISSET(select_width-1, &fdset)) {
1469                if (gnInputMethod != TGIM_NONE && tgIMExpectNextEvent(mainDisplay,
1470                      drawWindow)) {
1471                   if (!tgIMHandleNextEvent(mainDisplay, drawWindow, pXEvent)) {
1472                   }
1473                } else {
1474                   XNextEvent(mainDisplay, pXEvent);
1475                }
1476             } else {
1477                rc = FALSE;
1478             }
1479          } else {
1480             sprintf(gszMsgBox, TgLoadString(STID_FUNC_INVALID_RC_FOR_SELECT),
1481                   "GetAnXEvent()", status);
1482             fprintf(stderr, "%s\n", gszMsgBox);
1483             rc = FALSE;
1484          }
1485       }
1486       gstWBInfo.BlockRemoteCmdDepth++;
1487 #ifdef DEBUG0
1488       fprintf(stderr,"BlockRemoteCmdDepth (GetAnXEvent): %d\n",
1489             gstWBInfo.BlockRemoteCmdDepth);
1490 #endif /* DEBUG0 */
1491       if (!rc) return FALSE;
1492    } else {
1493       if (gnInputMethod != TGIM_NONE && tgIMExpectNextEvent(mainDisplay,
1494             drawWindow)) {
1495          if (!tgIMHandleNextEvent(mainDisplay, drawWindow, pXEvent)) {
1496          }
1497       } else {
1498          XNextEvent(mainDisplay, pXEvent);
1499       }
1500    }
1501    return TRUE;
1502 }
1503 
TryProcessAnXEvent(pnNeedToCheckAutoExec)1504 int TryProcessAnXEvent(pnNeedToCheckAutoExec)
1505    int *pnNeedToCheckAutoExec;
1506 {
1507    XEvent input;
1508    int rc=0, drawtext_cursorshown_keypress_processed=FALSE;
1509    TidgetInfo *handling_pti=NULL;
1510 
1511    exitNormally = FALSE;
1512    if (pnNeedToCheckAutoExec != NULL && (*pnNeedToCheckAutoExec) &&
1513          XPending(mainDisplay) <= 0) {
1514       struct AttrRec *exec_attr=FindFileAttrWithName("auto_exec=");
1515 
1516       *pnNeedToCheckAutoExec = FALSE;
1517       if (exec_attr != NULL) {
1518          DoExecLoop(NULL, exec_attr);
1519       }
1520    }
1521    if (!GetAnXEvent(&input)) {
1522       return 0;
1523    }
1524 
1525    /* set the lastKeyOrBtnEvInfo */
1526    if (input.type == KeyPress) {
1527       SetLastKeyEvInfo(&input.xkey);
1528    } else if (input.type == ButtonPress) {
1529       SetLastBtnEvInfo(&input.xbutton);
1530    }
1531 
1532    if (input.type == FocusIn) {
1533       if (curChoice == DRAWTEXT && textCursorShown) {
1534          tgIMFocusIn(mainDisplay, input.xany.window);
1535       }
1536    } else if (input.type == FocusOut) {
1537       if (curChoice == DRAWTEXT && textCursorShown) {
1538          tgIMFocusOut(mainDisplay, input.xany.window);
1539       }
1540    } else if (input.type == KeyRelease) {
1541       return 0;
1542    } else if (input.type == KeyPress) {
1543       if (TidgetManagerWantAllKeyPressEvents()) {
1544          TidgetManagerHandleAllKeyPressEvent(&input);
1545          return 0;
1546       }
1547       rc = ShortHand(&input);
1548       switch (rc) {
1549       case BAD: /* <CONTROL> or <META> */ return 0;
1550       case INVALID:
1551          if (curChoice != DRAWTEXT || !textCursorShown) {
1552             escPressed = FALSE;
1553          }
1554          break;
1555       default: return rc;
1556       }
1557    }
1558 
1559    if (input.xany.window == choiceWindow) {
1560       if ((rc=ChoiceEventHandler(&input)) != INVALID) {
1561          return rc;
1562       }
1563    } else if (input.xany.window == drawWindow) {
1564       if (input.type == ButtonPress) {
1565          if (gstWBInfo.do_whiteboard) {
1566             gstWBInfo.BlockRemoteCmdDepth++;
1567          }
1568       }
1569       if (curChoice == DRAWTEXT && textCursorShown && input.type == KeyPress) {
1570           drawtext_cursorshown_keypress_processed = TRUE;
1571       }
1572       rc = DrawingEventHandler(&input);
1573       if (input.type == ButtonPress) {
1574          if (gstWBInfo.do_whiteboard) {
1575             gstWBInfo.BlockRemoteCmdDepth--;
1576             TryHandleWBInputData();
1577          }
1578       }
1579       if (rc != INVALID) {
1580          return rc;
1581       }
1582    } else if (input.xany.window == mainWindow) {
1583       rc = mainWinEventHandler(&input);
1584       switch (rc) {
1585       case BAD: /* <CONTROL> or <META> */ return 0;
1586       case INVALID: break;
1587       default: return rc;
1588       }
1589    } else if (input.xany.window == vRuleWindow ||
1590          input.xany.window == hRuleWindow) {
1591       RulersEventHandler(&input);
1592    } else if (input.xany.window == iconWindow ||
1593          input.xany.window == iconBaseWindow) {
1594       IconEventHandler(&input);
1595    } else if (input.xany.window == titleWindow) {
1596       TitleEventHandler(&input);
1597    } else if (menubarWindow != None && input.xany.window == menubarWindow) {
1598       if ((rc=MenubarEventHandler(&input)) != INVALID) {
1599          return rc;
1600       }
1601    } else if (input.xany.window == msgWindow) {
1602       MsgEventHandler(&input);
1603    } else if (input.xany.window == vSBarWindow ||
1604          input.xany.window == hSBarWindow) {
1605       ScrollEventHandler(&input);
1606    } else if (userRedrawWindow != None &&
1607          input.xany.window == userRedrawWindow) {
1608       UserRedrawEventHandler(&input);
1609    } else if (statusWindow != None && input.xany.window == statusWindow) {
1610       StatusEventHandler(&input);
1611    } else if (chatWindow != None && IsChatWindowEvent(&input, &handling_pti)) {
1612       ChatEventHandler(&input, handling_pti);
1613       if (curChoice == DRAWTEXT && textCursorShown && input.type == KeyPress) {
1614           drawtext_cursorshown_keypress_processed = TRUE;
1615       }
1616    } else if (modeWindow != None && input.xany.window == modeWindow) {
1617       if ((rc=ModeEventHandler(&input)) != INVALID) {
1618          return rc;
1619       }
1620    } else if (input.xany.window == dummyWindow1 ||
1621          input.xany.window == dummyWindow2) {
1622       DummiesEventHandler(&input);
1623    } else if (input.xany.type == MappingNotify) {
1624       XRefreshKeyboardMapping(&(input.xmapping));
1625    } else if (input.xany.window == pageWindow) {
1626       PageEventHandler(&input);
1627    } else if (input.xany.window == pageDummyWindow) {
1628       PageDummyEventHandler(&input);
1629    } else if (input.xany.window == colorWindow) {
1630       ColorEventHandler(&input);
1631    } else if (input.xany.window == colorDummyWindow) {
1632       ColorDummyEventHandler(&input);
1633    } else if (TidgetManagerHandleEvent(&input)) {
1634       /* input has been handled by the TidgetManager */
1635    } else {
1636       int i=0;
1637 
1638       for (i=0; i < numExtraWins; i++) {
1639          if (input.xany.window == extraWinInfo[i].window &&
1640                extraWinInfo[i].window != None) {
1641             if ((rc=(*(extraWinInfo[i].ev_handler))(&input,
1642                   &extraWinInfo[i])) != INVALID) {
1643                return rc;
1644             }
1645             break;
1646          }
1647       }
1648    }
1649 #ifndef _NO_ENTER_TEXT_EVERYWHERE
1650    if (curChoice == DRAWTEXT && textCursorShown && input.type == KeyPress &&
1651          !drawtext_cursorshown_keypress_processed) {
1652       rc = DrawingEventHandler(&input);
1653       if (rc != INVALID) {
1654          return rc;
1655       }
1656    }
1657 #endif /* ~_NO_ENTER_TEXT_EVERYWHERE */
1658    return 0;
1659 }
1660 
1661 static XComposeStatus c_stat;
1662 
TryProcessAnAbortXEvent(esc_to_abort,pf_abort_callback,p_void)1663 int TryProcessAnAbortXEvent(esc_to_abort, pf_abort_callback, p_void)
1664    int esc_to_abort;
1665    AbortCallbackFunc *pf_abort_callback;
1666    void *p_void;
1667 {
1668    XEvent input;
1669 
1670    exitNormally = FALSE;
1671    if (!GetAnXEvent(&input)) {
1672       return FALSE;
1673    }
1674    if (input.type == KeyPress || input.type == KeyRelease) {
1675       char s[80];
1676       int has_ch=0;
1677       XKeyEvent *key_ev=NULL;
1678       KeySym key_sym=(KeySym)0;
1679 
1680       key_ev = (&(input.xkey));
1681       has_ch = XLookupString(key_ev, s, sizeof(s), &key_sym, &c_stat);
1682       if (has_ch > 0) s[has_ch] = '\0';
1683       TranslateKeys(s, &key_sym);
1684       if (esc_to_abort && CharIsESC(key_ev, s, key_sym, &has_ch)) {
1685          if (pf_abort_callback == NULL || (pf_abort_callback)(p_void)) {
1686             return TRUE;
1687          }
1688       } else if (!esc_to_abort && has_ch) {
1689          unsigned int state=key_ev->state;
1690 
1691          if ((state & ControlMask) && (!(state & METAMASK)) && s[0] == '\003') {
1692             if (pf_abort_callback == NULL || (pf_abort_callback)(p_void)) {
1693                return TRUE;
1694             }
1695          }
1696       }
1697    } else if (input.type == MotionNotify) {
1698       while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &input)) ;
1699    } else if (input.type == Expose || input.type == VisibilityNotify) {
1700       ExposeEventHandler(&input, TRUE);
1701       while (XCheckMaskEvent(mainDisplay, ExposureMask | VisibilityChangeMask,
1702             &input)) {
1703       }
1704    } else if (input.type == ConfigureNotify) {
1705       Reconfigure(FALSE);
1706    }
1707    return FALSE;
1708 }
1709 
MainLoop(Op,FileName,FuncStr,Str1,Menu1,Str2,Menu2,Str3,Menu3)1710 void MainLoop(Op, FileName, FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3)
1711    char *Op, *FileName, **FuncStr;
1712    char **Str1, **Menu1, **Str2, **Menu2, **Str3, **Menu3;
1713 {
1714    char *c_ptr=NULL, file_name[MAXPATHLENGTH+1];
1715    int need_to_check_auto_exec=FALSE;
1716 
1717 /* printf("--> MainLoop(%s, %s, ...)\n", Op, FileName); */
1718 
1719    /* do not translate -- program constants */
1720    if (strcmp(Op, "init") == 0 || strcmp(Op, "justinit") == 0) {
1721       char szMsg1[80], szMsg2[80];
1722 
1723       GetTgifVersionAndPatchLevel(szMsg1, sizeof(szMsg1));
1724       sprintf(szMsg2, "%s (%s)", copyrightString, authorEmailString);
1725       TwoLineMsg(szMsg1, szMsg2);
1726       if (cmdLineVersion) {
1727          fprintf(stderr, "%s\n", szMsg1);
1728          fprintf(stderr, "%s\n", szMsg2);
1729       }
1730       fflush(stderr);
1731 
1732       exitNormally = FALSE;
1733 
1734 #ifdef X_PROTOCOL
1735 #ifdef XlibSpecificationRelease
1736       x11R6OrAbove = (X_PROTOCOL >= 11 && XlibSpecificationRelease >= 6);
1737 #endif /* XlibSpecificationRelease */
1738 #endif /* X_PROTOCOL */
1739 
1740       JustInit(FileName, &need_to_check_auto_exec);
1741       if (*cmdLineFileToExec != '\0') {
1742          SendCommandToSelf(CMDID_STARTEXECCMDSFROMFILE, 0);
1743       }
1744    }
1745    SaveDrawWinInfo();
1746 
1747    if (strcmp(Op, "justinit") == 0) {
1748       XSync(mainDisplay, False);
1749       AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1750       strcpy(*FuncStr, "");
1751       return;
1752    }
1753    if (strcmp(Op, "save") == 0) {
1754       SaveFile();
1755       AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1756       strcpy(*FuncStr, "");
1757       return;
1758    }
1759    if (strcmp(Op, "vi") == 0) {
1760       ExecWithFile("vi", FileName);
1761    }
1762    if (strcmp(Op, "less") == 0) {
1763       ExecWithFile("less", FileName);
1764    }
1765    if (strcmp(Op, "quit") == 0) {
1766       CleanUp();
1767       quitDraw = TRUE;
1768       XFlush(mainDisplay);
1769       XSync(mainDisplay, True);
1770       if (useXlib) {
1771          XCloseDisplay(mainDisplay);
1772          mainDisplay = NULL;
1773       } else {
1774 #ifdef USE_XT_INITIALIZE
1775          XtDestroyWidget(toplevel);
1776          toplevel = (Widget)0;
1777 #endif /* USE_XT_INITIALIZE */
1778       }
1779       exitNormally = TRUE;
1780       AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1781       strcpy(*FuncStr, "Quit");
1782       strcpy(*Str1, "");
1783       return;
1784    }
1785    if (strcmp(Op, "msg") == 0) {
1786       Msg(FileName);
1787       AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1788       strcpy(*FuncStr, "");
1789       return;
1790    }
1791    if (strcmp(Op, "dialog") == 0) {
1792       *file_name = '\0';
1793       Dialog(FileName, "", file_name);
1794       AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1795       strcpy(*FuncStr, file_name);
1796       strcpy(*Str1, "");
1797       return;
1798    }
1799    if (strcmp(Op, "mainmenu") == 0 && quitDraw) {
1800       AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1801       strcpy(*FuncStr, "Fail");
1802       strcpy(*Str1, "");
1803       return;
1804    }
1805    while (TRUE) {
1806       int rc=TryProcessAnXEvent(&need_to_check_auto_exec);
1807 
1808       if (rc != 0) {
1809          AllocStrings(FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
1810          strcpy(*FuncStr, fileMenuStr[rc]);
1811          strcpy(*Str1, curDomainName);
1812          sprintf(*Menu1, "tmpmodel.%s", OBJ_FILE_EXT);
1813          strcpy(*Str2, "");
1814          for (c_ptr = *FuncStr; *c_ptr != '\0'; c_ptr++) {
1815             if (*c_ptr == ' ') {
1816                *c_ptr = '\0';
1817                break;
1818             }
1819          }
1820          return;
1821       }
1822    }
1823 }
1824 
UrlDump(pszUrl)1825 void UrlDump(pszUrl)
1826    char *pszUrl;
1827 {
1828    int saved_http_debug=debugHttp;
1829    int saved_ftp_debug=debugFtp;
1830 
1831    debugHttp = 99;
1832    debugFtp = (-99);
1833    if (FileIsRemote(pszUrl)) {
1834       char tmp_fname[MAXPATHLENGTH+1], *content_type=NULL, *page_spec=NULL;
1835       int is_html=FALSE;
1836 
1837       *tmp_fname = '\0';
1838       if (cmdLineDumpURL && cmdLineDumpURLWithHeader &&
1839             cmdLineDumpURLHeaderOnly) {
1840          gettingHttpHeaderOnly = TRUE;
1841       }
1842       if (cmdLineParseHtml) {
1843          cmdLineDumpURL = FALSE;
1844          debugHttp = saved_http_debug;
1845          InitHtml();
1846       } else {
1847          if (cmdLineOpenDisplay) {
1848             JustInit(NULL, NULL);
1849          }
1850       }
1851       DownloadRemoteFile(pszUrl, &content_type, &page_spec,
1852             &is_html, tmp_fname, NULL, 0);
1853       gettingHttpHeaderOnly = FALSE;
1854       if (content_type != NULL) FreeRemoteBuf(content_type);
1855       if (page_spec != NULL) UtilFree(page_spec);
1856       if (*tmp_fname != '\0') unlink(tmp_fname);
1857    } else {
1858       FILE *fp=fopen(pszUrl, "r");
1859 
1860       if (fp == NULL) {
1861          fprintf(stderr, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_READING),
1862                pszUrl);
1863          fprintf(stderr, "\n");
1864       } else {
1865          char *buf;
1866 
1867          while ((buf=UtilGetALine(fp)) != NULL) {
1868             fprintf(stdout, "%s\n", buf);
1869             UtilFree(buf);
1870          }
1871          fclose(fp);
1872       }
1873    }
1874    debugHttp = saved_http_debug;
1875    debugFtp = saved_ftp_debug;
1876 }
1877 
DosEpsFilter(pszUrl)1878 void DosEpsFilter(pszUrl)
1879    char *pszUrl;
1880 {
1881    if (MyReadEPSFile(pszUrl, NULL, NULL, NULL, NULL, NULL,
1882          NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
1883    }
1884 }
1885 
1886 static
HandleSimpleEvent(input)1887 void HandleSimpleEvent(input)
1888    XEvent input;
1889 {
1890    if ((input.type & (PointerMotionMask | EnterWindowMask | LeaveWindowMask))
1891          != 0) {
1892       return;
1893    }
1894    if (input.xany.window == drawWindow) {
1895       DrawingEventHandler(&input);
1896    } else if (input.xany.window == choiceWindow) {
1897       ChoiceEventHandler(&input);
1898    } else if (input.xany.window==iconWindow ||
1899          input.xany.window==iconBaseWindow) {
1900       IconEventHandler(&input);
1901    } else if (input.xany.window == titleWindow) {
1902       TitleEventHandler(&input);
1903    } else if (input.xany.window == msgWindow) {
1904       MsgEventHandler(&input);
1905    } else if (input.xany.window==vSBarWindow ||
1906          input.xany.window==hSBarWindow) {
1907       ScrollEventHandler(&input);
1908    } else if (input.xany.window == hRuleWindow) {
1909       RedrawHRulerWindow();
1910    } else if (input.xany.window == vRuleWindow) {
1911       RedrawVRulerWindow();
1912    }
1913 }
1914 
1915 static
AllocReturnStr(ReturnStr)1916 void AllocReturnStr(ReturnStr)
1917    char **ReturnStr;
1918 {
1919    if((*ReturnStr=(char*)malloc(80*sizeof(char))) == NULL) FailAllocMessage();
1920 }
1921 
Animate(TypeStr,PolyId,SpeedStr,ColorStr,ReturnStr)1922 void Animate(TypeStr, PolyId, SpeedStr, ColorStr, ReturnStr)
1923    char *TypeStr, *PolyId, *SpeedStr, *ColorStr;
1924    char **ReturnStr;
1925 {
1926    struct ObjRec *obj_ptr;
1927    char s[80];
1928    int i, poly_id, speed, pixel, clicked = FALSE;
1929    XEvent input;
1930    XButtonEvent *button_event;
1931 
1932    AllocReturnStr(ReturnStr);
1933    strcpy(*ReturnStr, "");
1934 
1935    while (XPending(mainDisplay) != 0) {
1936       XPeekEvent(mainDisplay, &input);
1937       if ((input.type & (PointerMotionMask | ExposureMask | EnterWindowMask |
1938             LeaveWindowMask)) != 0) {
1939          XNextEvent(mainDisplay, &input);
1940          HandleSimpleEvent(input);
1941       } else {
1942          if (input.type == ButtonPress) clicked = TRUE;
1943          /* do not translate -- program constants */
1944          strcpy(*ReturnStr, "Interrupt");
1945          break;
1946       }
1947    }
1948    /* do not translate -- program constants */
1949    printf("--> Animate(%s, %s, %s, %s)\n",TypeStr,PolyId,SpeedStr,ColorStr);
1950    if (strcmp(TypeStr, "waitclick") == 0) {
1951       Msg(TgLoadString(STID_LEFT_STEP_MID_RUN_RIGHT_STOP));
1952       if (!clicked) {
1953          while (TRUE) {
1954             if (XPending(mainDisplay) != 0) {
1955                XNextEvent(mainDisplay, &input);
1956                if (input.type == ButtonPress) {
1957                   break;
1958                }
1959             }
1960          }
1961       } else {
1962          XNextEvent(mainDisplay, &input);
1963       }
1964 
1965       button_event = &(input.xbutton);
1966       /* do not translate -- program constants */
1967       switch (button_event->button) {
1968       case Button1 : strcpy(*ReturnStr, "Left"); break;
1969       case Button2 : strcpy(*ReturnStr, "Middle"); break;
1970       case Button3 : strcpy(*ReturnStr, "Right"); break;
1971       }
1972       Msg("");
1973    } else {
1974       poly_id = atoi(PolyId);
1975       for (obj_ptr=topObj; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
1976          if (obj_ptr->type == OBJ_POLY && obj_ptr->id == poly_id) {
1977             break;
1978          }
1979       }
1980       /* do not translate -- program constants */
1981       if (obj_ptr == NULL) {
1982          sprintf(s, TgLoadString(STID_CANT_FIND_POLY_WITH_GIVEN_ID), poly_id);
1983          Msg(s);
1984       } else if (strcmp(TypeStr, "send") == 0) {
1985          speed = atoi(SpeedStr);
1986          pixel = (colorDisplay) ? xorColorPixels[obj_ptr->color] : 1;
1987          AnimateSend(obj_ptr->detail.p, speed, pixel);
1988       } else if (strcmp(TypeStr, "flash") == 0) {
1989          if (colorDisplay) {
1990             strcpy(s, ColorStr);
1991          } else {
1992             strcpy(s, "white");
1993          }
1994          for (i = 0; i < maxColors; i++) {
1995             if (strcmp(colorMenuItems[i], s) == 0) {
1996                AnimateFlashColor(obj_ptr, i);
1997                break;
1998             }
1999          }
2000       }
2001    }
2002 }
2003 
2004 static
MyFormat(Str)2005 void MyFormat(Str)
2006    char *Str;
2007 {
2008    register char *c_ptr=Str, *period_ptr=NULL;
2009    register int i;
2010 
2011    for ( ; *c_ptr != '\0'; c_ptr++) {
2012       if (*c_ptr >= '0' && *c_ptr <= '9') {
2013          continue;
2014       } else if (*c_ptr == '.') {
2015          if (period_ptr != NULL) return;
2016          period_ptr = c_ptr;
2017          continue;
2018       } else {
2019          return;
2020       }
2021    }
2022 
2023    if (period_ptr == NULL) return;
2024    for (c_ptr = period_ptr, i = 0; *c_ptr != '\0' && i < 7; c_ptr++, i++) ;
2025    if (*c_ptr != '\0') *c_ptr = '\0';
2026 }
2027 
UpdAttrVal(ObjId,AttrName,AttrColor,AttrVal,ReturnStr)2028 void UpdAttrVal(ObjId, AttrName, AttrColor, AttrVal, ReturnStr)
2029    char *ObjId, *AttrName, *AttrColor, *AttrVal;
2030    char **ReturnStr;
2031 {
2032    struct ObjRec *obj_ptr;
2033    struct AttrRec *attr_ptr;
2034    char s[MAXSTRING];
2035    int obj_id;
2036    XEvent input;
2037    XButtonEvent *button_event;
2038 
2039    AllocReturnStr(ReturnStr);
2040    strcpy(*ReturnStr, "");
2041 
2042    while (XPending(mainDisplay) != 0) {
2043       XPeekEvent(mainDisplay, &input);
2044       if ((input.type & (PointerMotionMask | ExposureMask | EnterWindowMask |
2045             LeaveWindowMask)) != 0) {
2046          XNextEvent(mainDisplay, &input);
2047          HandleSimpleEvent(input);
2048       } else {
2049          /* do not translate -- program constants */
2050          strcpy(*ReturnStr, "Interrupt");
2051          button_event = &(input.xbutton);
2052          switch (button_event->button) {
2053          case Button1 : strcpy(*ReturnStr, "Left"); break;
2054          case Button2 : strcpy(*ReturnStr, "Middle"); break;
2055          case Button3 : strcpy(*ReturnStr, "Right"); break;
2056          }
2057          break;
2058       }
2059    }
2060    /* do not translate -- program constants */
2061    printf("--> UpdAttrVal(%s, %s, %s, %s)\n", ObjId, AttrName,
2062          AttrColor, AttrVal);
2063 
2064    obj_id = atoi(ObjId);
2065 
2066    for (obj_ptr=topObj; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
2067       if (obj_ptr->id == obj_id) {
2068          break;
2069       }
2070    }
2071    if (obj_ptr == NULL) {
2072       sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_OBJ_WITH_GIVEN_ID),
2073             obj_id);
2074       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2075    } else {
2076       attr_ptr = obj_ptr->fattr;
2077       for ( ; attr_ptr != NULL; attr_ptr=attr_ptr->next) {
2078          if (strcmp(AttrName, attr_ptr->attr_name.s) == 0 &&
2079                strcmp(AttrColor, colorMenuItems[attr_ptr->obj->color]) == 0) {
2080             break;
2081          }
2082       }
2083       if (attr_ptr == NULL) {
2084          sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_ATTR_NAME_AND_COLOR),
2085                AttrName, AttrColor);
2086          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2087       } else {
2088          struct DynStrRec *dyn_str_ptr=NULL;
2089 
2090          DynStrSet(&attr_ptr->attr_value, AttrVal);
2091          MyFormat(attr_ptr->attr_value.s);
2092          if (attr_ptr->nameshown) {
2093             sprintf(s, "%s%s", attr_ptr->attr_name.s, attr_ptr->attr_value.s);
2094          } else {
2095             strcpy(s, attr_ptr->attr_value.s);
2096          }
2097          if (attr_ptr->shown) RepaintFirstStr(attr_ptr->obj, s);
2098          dyn_str_ptr = GetTextFirstDynStr(attr_ptr->obj);
2099 
2100          DynStrSet(dyn_str_ptr, s);
2101       }
2102    }
2103 }
2104 
SetLastKeyEvInfo(key_ev)2105 void SetLastKeyEvInfo(key_ev)
2106     XKeyEvent *key_ev;
2107 {
2108    lastKeyOrBtnEvInfo.type = key_ev->type;
2109    lastKeyOrBtnEvInfo.send_event = key_ev->send_event;
2110    lastKeyOrBtnEvInfo.display = key_ev->display;
2111    lastKeyOrBtnEvInfo.window = key_ev->window;
2112    memcpy(&lastKeyOrBtnEvInfo.time, &key_ev->time, sizeof(Time));
2113    lastKeyOrBtnEvInfo.x = key_ev->x;
2114    lastKeyOrBtnEvInfo.y = key_ev->y;
2115    lastKeyOrBtnEvInfo.keycode_or_button = key_ev->keycode;
2116    lastKeyOrBtnEvInfo.state = key_ev->state;
2117 }
2118 
SetLastBtnEvInfo(button_ev)2119 void SetLastBtnEvInfo(button_ev)
2120     XButtonEvent *button_ev;
2121 {
2122    lastKeyOrBtnEvInfo.type = button_ev->type;
2123    lastKeyOrBtnEvInfo.send_event = button_ev->send_event;
2124    lastKeyOrBtnEvInfo.display = button_ev->display;
2125    lastKeyOrBtnEvInfo.window = button_ev->window;
2126    memcpy(&lastKeyOrBtnEvInfo.time, &button_ev->time, sizeof(Time));
2127    lastKeyOrBtnEvInfo.x = button_ev->x;
2128    lastKeyOrBtnEvInfo.y = button_ev->y;
2129    lastKeyOrBtnEvInfo.keycode_or_button = button_ev->button;
2130    lastKeyOrBtnEvInfo.state = button_ev->state;
2131 }
2132 
2133