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/import.c,v 1.52 2011/06/14 03:22:14 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_IMPORT_C_
22 
23 #include "tgifdefs.h"
24 #include "cmdids.h"
25 
26 #include "attr.e"
27 #include "auxtext.e"
28 #include "box.e"
29 #include "choice.e"
30 #include "choose.e"
31 #include "cmd.e"
32 #include "color.e"
33 #include "cursor.e"
34 #include "cutpaste.e"
35 #include "dialog.e"
36 #include "drawing.e"
37 #include "dup.e"
38 #include "eps.e"
39 #include "file.e"
40 #include "font.e"
41 #include "grid.e"
42 #include "imgproc.e"
43 #include "import.e"
44 #include "mainloop.e"
45 #include "mainmenu.e"
46 #include "mark.e"
47 #include "msg.e"
48 #include "menu.e"
49 #include "move.e"
50 #include "names.e"
51 #include "navigate.e"
52 #include "obj.e"
53 #include "page.e"
54 #include "pngtrans.e"
55 #include "raster.e"
56 #include "rect.e"
57 #include "remote.e"
58 #include "scroll.e"
59 #include "select.e"
60 #include "setup.e"
61 #include "special.e"
62 #include "stretch.e"
63 #include "strtbl.e"
64 #include "text.e"
65 #include "util.e"
66 #include "xbitmap.e"
67 #include "xpixmap.e"
68 #include "z_intrf.e"
69 
70 typedef struct ImportInfoRec {
71    char *name, *ext, *cmd;
72    struct ImportInfoRec *next;
73 } *ImportInfoPtr;
74 
75 static struct ImportInfoRec *topImportInfo=NULL, *botImportInfo=NULL;
76 static int gnMaxImportFilters=0;
77 static int showFileNameOnBrowse=TRUE;
78 
79 static int thumbnailW=160;
80 static int thumbnailH=120;
81 static int thumbnailPadding=8;
82 static int thumbnailXGap=16;
83 static int thumbnailYGap=0;
84 static int thumbnailX=32;
85 static int thumbnailY=32;
86 
MillisecondSleep(ms)87 void MillisecondSleep(ms)
88    int ms;
89 {
90    struct timeval timeout;
91    fd_set fdset;
92 
93    timeout.tv_sec = 0;
94    timeout.tv_usec = ms*1000;
95    FD_ZERO(&fdset);
96 #ifdef __hpux
97    select(0, (int*)&fdset, NULL, NULL, &timeout);
98 #else /* !__hpux */
99    select(0, &fdset, NULL, NULL, &timeout);
100 #endif /* __hpux */
101 }
102 
ExtensionMatch(Spec,DirName)103 int ExtensionMatch(Spec, DirName)
104    char *Spec, *DirName;
105 {
106    char *c_ptr, other_ext_str[MAXSTRING];
107    int len;
108 
109    if (Spec == NULL || *Spec == '\0') return FALSE;
110    len = strlen(DirName);
111    strcpy(other_ext_str, Spec);
112    for (c_ptr=strtok(other_ext_str,";"); c_ptr != NULL;
113          c_ptr=strtok(NULL, ";")) {
114       int other_ext_len=strlen(c_ptr);
115 
116       if (len > other_ext_len &&
117             UtilStrICmp(c_ptr, &DirName[len-other_ext_len]) == 0) {
118          return TRUE;
119       }
120    }
121    return FALSE;
122 }
123 
SetUpExtStr(cbBuf,pszExt,pszOtherExt)124 char *SetUpExtStr(cbBuf, pszExt, pszOtherExt)
125    int cbBuf;
126    char *pszExt, *pszOtherExt;
127    /* pszExt="gif;GIF", pszOtherExt=".jpg;.jpeg" */
128 {
129    char *c_ptr, *buf=(char*)malloc(cbBuf*sizeof(char)), *start_ptr, *dest_ptr;
130 
131    if (buf == NULL) {
132       FailAllocMessage();
133       return NULL;
134    }
135    *buf = '\0';
136    dest_ptr = buf;
137 
138    start_ptr = pszExt;
139    while (*start_ptr == ' ') start_ptr++;
140    c_ptr = strchr(start_ptr, ';');
141    while (start_ptr != NULL) {
142       if (c_ptr != NULL) *c_ptr = '\0';
143       if(dest_ptr == buf) {
144          sprintf(dest_ptr, ".%s", start_ptr);
145       } else {
146          sprintf(dest_ptr, ";.%s", start_ptr);
147       }
148       dest_ptr = (&dest_ptr[strlen(dest_ptr)]);
149       if (c_ptr != NULL) *c_ptr++ = ';';
150       if (c_ptr == NULL) break;
151       start_ptr = c_ptr;
152       while (*start_ptr == ' ') start_ptr++;
153       c_ptr = strchr(start_ptr, ';');
154    }
155    if (dest_ptr == buf) {
156       strcpy(buf, pszOtherExt);
157    } else if (*pszOtherExt == '\0') {
158       *dest_ptr = '\0';
159    } else {
160       sprintf(dest_ptr, ";%s", pszOtherExt);
161    }
162    return buf;
163 }
164 
CleanUpImport()165 void CleanUpImport()
166 {
167    struct ImportInfoRec *next_import;
168 
169    while (topImportInfo != NULL) {
170       next_import = topImportInfo->next;
171 
172       if(topImportInfo->name != NULL) free(topImportInfo->name);
173       if(topImportInfo->ext != NULL) free(topImportInfo->ext);
174       if(topImportInfo->cmd != NULL) free(topImportInfo->cmd);
175       free(topImportInfo);
176       topImportInfo = next_import;
177    }
178    topImportInfo = botImportInfo = NULL;
179 }
180 
181 #define INVALID_FILTER_SPEC_DEFAULT 0
182 #define INVALID_FILTER_SPEC_MISSING_PERC_S 1
183 #define INVALID_FILTER_SPEC_TOO_MANY_PERC_S 2
184 
185 static
InvalidFilterSpecMsg(pszEntry,pszValue,nExplain)186 void InvalidFilterSpecMsg(pszEntry, pszValue, nExplain)
187    char *pszEntry, *pszValue;
188    int nExplain;
189 {
190    switch (nExplain) {
191    case INVALID_FILTER_SPEC_DEFAULT:
192       sprintf(gszMsgBox, TgLoadString(STID_BAD_FLTR_SPEC_DEF),
193             TOOL_NAME, pszEntry, pszValue);
194       break;
195    case INVALID_FILTER_SPEC_MISSING_PERC_S:
196       sprintf(gszMsgBox, TgLoadString(STID_BAD_FLTR_SPEC_MISS_PERC_S),
197             TOOL_NAME, pszEntry, pszValue);
198       break;
199    case INVALID_FILTER_SPEC_TOO_MANY_PERC_S:
200       sprintf(gszMsgBox, TgLoadString(STID_BAD_FLTR_SPEC_MANY_PERC_S),
201             TOOL_NAME, pszEntry, pszValue);
202       break;
203    }
204    MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
205 }
206 
207 static
CountPercentS(buf)208 int CountPercentS(buf)
209    char *buf;
210 {
211    int count=0;
212    char *c_ptr;
213 
214    for (c_ptr=strstr(buf, "%s"); c_ptr != NULL; c_ptr=strstr(++c_ptr, "%s")) {
215       count++;
216    }
217    return count;
218 }
219 
220 static
FindBlank(pszStr,ppszEnd)221 char *FindBlank(pszStr, ppszEnd)
222    char *pszStr, **ppszEnd;
223 {
224    char *c_ptr=pszStr, ch;
225 
226    if (!(*c_ptr == '"' || *c_ptr == '\'')) {
227       *ppszEnd = strchr(pszStr, ' ');
228       return pszStr;
229    }
230    for (ch=(*c_ptr++); *c_ptr != '\0'; c_ptr++) {
231       if (*c_ptr == '\\') {
232          c_ptr++;
233       } else if (*c_ptr == ch) {
234          *ppszEnd = c_ptr;
235          return &pszStr[1];
236       }
237    }
238    *ppszEnd = NULL;
239    return pszStr;
240 }
241 
InitImport()242 void InitImport()
243 {
244    char *c_ptr;
245    int max_filters=0;
246 
247    showFileNameOnBrowse = TRUE;
248    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ShowFileNameOnBrowse")) !=
249          NULL) {
250       if (UtilStrICmp(c_ptr, "false") == 0) {
251          showFileNameOnBrowse = FALSE;
252       }
253    }
254    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"MaxImportFilters")) != NULL) {
255       max_filters = atoi(c_ptr);
256       if (max_filters <= 0) {
257          sprintf(gszMsgBox, TgLoadString(STID_BAD_XDEF_MUST_BE_GT_0),
258                TOOL_NAME, "MaxImportFilters", c_ptr);
259          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
260       }
261    }
262    gnMaxImportFilters = 0;
263    if (max_filters > 0) {
264       int i;
265 
266       for (i=0; i < max_filters; i++) {
267          char buf[80];
268 
269          sprintf(buf, "ImportFilter%1d", i);
270          if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,buf)) == NULL) {
271             sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_XDEF_CONT_LOOK_FLTR),
272                   TOOL_NAME, buf);
273             if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) != MB_ID_YES) {
274                break;
275             }
276          } else {
277             char *name_ptr=UtilStrDup(c_ptr), *dup_buf=UtilStrDup(c_ptr);
278             char *ext_ptr;
279 
280             if (name_ptr == NULL || dup_buf == NULL) FailAllocMessage();
281             for (c_ptr=name_ptr; *c_ptr != '\0'; c_ptr++) {
282                if (*c_ptr == '\t' || *c_ptr == '\n' || *c_ptr == '\r') {
283                   *c_ptr = ' ';
284                }
285             }
286             for (c_ptr=dup_buf; *c_ptr != '\0'; c_ptr++) {
287                if (*c_ptr == '\t' || *c_ptr == '\n' || *c_ptr == '\r') {
288                   *c_ptr = ' ';
289                }
290             }
291             UtilTrimBlanks(name_ptr);
292             name_ptr = FindBlank(name_ptr, &ext_ptr);
293             if (ext_ptr == NULL) {
294                InvalidFilterSpecMsg(buf, dup_buf, INVALID_FILTER_SPEC_DEFAULT);
295             } else {
296                char *cmd_ptr;
297 
298                *ext_ptr++ = '\0';
299                UtilTrimBlanks(ext_ptr);
300                ext_ptr = FindBlank(ext_ptr, &cmd_ptr);
301                if (cmd_ptr == NULL) {
302                   InvalidFilterSpecMsg(buf, dup_buf,
303                         INVALID_FILTER_SPEC_DEFAULT);
304                } else {
305                   int len, count;
306 
307                   *cmd_ptr++ = '\0';
308                   UtilTrimBlanks(cmd_ptr);
309                   len = strlen(cmd_ptr);
310                   if (len >= 2 &&
311                         ((*cmd_ptr == '"' && cmd_ptr[len-1] == '"') ||
312                         (*cmd_ptr == '\'' && cmd_ptr[len-1] == '\''))) {
313                      cmd_ptr[len-1] = '\0';
314                      cmd_ptr++;
315                      UtilTrimBlanks(cmd_ptr);
316                   }
317                   count = CountPercentS(cmd_ptr);
318                   if (count < 1) {
319                      InvalidFilterSpecMsg(buf, dup_buf,
320                            INVALID_FILTER_SPEC_MISSING_PERC_S);
321                   } else if (count > 1) {
322                      InvalidFilterSpecMsg(buf, dup_buf,
323                            INVALID_FILTER_SPEC_TOO_MANY_PERC_S);
324                   } else {
325                      struct ImportInfoRec *pii=(struct ImportInfoRec*)malloc(
326                            sizeof(struct ImportInfoRec));
327 
328                      if (pii == NULL) FailAllocMessage();
329                      memset(pii, 0, sizeof(struct ImportInfoRec));
330                      pii->next = NULL;
331                      pii->name = UtilStrDup(name_ptr);
332                      pii->ext = UtilStrDup(ext_ptr);
333                      pii->cmd = UtilStrDup(cmd_ptr);
334                      if (pii->name==NULL || pii->ext==NULL || pii->cmd==NULL) {
335                         FailAllocMessage();
336                         if (pii->name != NULL) free(pii->name);
337                         if (pii->ext != NULL) free(pii->ext);
338                         if (pii->cmd != NULL) free(pii->cmd);
339                      } else {
340                         if (botImportInfo != NULL) {
341                            botImportInfo->next = pii;
342                         } else {
343                            topImportInfo = pii;
344                         }
345                         botImportInfo = pii;
346                         gnMaxImportFilters++;
347                      }
348                   }
349                }
350             }
351             if (name_ptr != NULL) free(name_ptr);
352             if (dup_buf != NULL) free(dup_buf);
353          }
354       }
355    }
356    thumbnailW = 160;
357    thumbnailH = 120;
358    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThumbnailGeometry")) != NULL) {
359       int w=0, h=0;
360 
361       if (ParseWHSpec(c_ptr, &w, &h) && w >= 40 && h >= 30) {
362          if (w >= 40 && h >= 30) {
363             thumbnailW = w;
364             thumbnailH = h;
365          } else {
366             fprintf(stderr, TgLoadString(STID_INVALID_GEOM_USE_ALT_GEOM),
367                   TOOL_NAME, "ThumbnailGeometry", c_ptr, "40x30", "160x120");
368             fprintf(stderr, "\n");
369          }
370       }
371    }
372    thumbnailPadding = 8;
373    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThumbnailPadding")) != NULL) {
374       int padding=0;
375 
376       UtilTrimBlanks(c_ptr);
377       if (sscanf(c_ptr, "%d", &padding) != 1) {
378          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
379                TOOL_NAME, "ThumbnailPadding", c_ptr, 8);
380          fprintf(stderr, "\n");
381       } else if (padding < 0 || padding > 100) {
382          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_RNG_USE_ALT_VAL),
383                TOOL_NAME, "ThumbnailPadding", c_ptr, 0, 100, 8);
384          fprintf(stderr, "\n");
385       } else {
386          thumbnailPadding = padding;
387       }
388    }
389    thumbnailXGap = 16;
390    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThumbnailXGap")) != NULL) {
391       int gap=0;
392 
393       UtilTrimBlanks(c_ptr);
394       if (sscanf(c_ptr, "%d", &gap) != 1) {
395          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
396                TOOL_NAME, "ThumbnailXGap", c_ptr, 16);
397          fprintf(stderr, "\n");
398       } else if (gap < 0) {
399          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
400                TOOL_NAME, "ThumbnailXGap", c_ptr, 16);
401          fprintf(stderr, "\n");
402       } else {
403          thumbnailXGap = gap;
404       }
405    }
406    thumbnailYGap = 0;
407    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThumbnailYGap")) != NULL) {
408       int gap=0;
409 
410       UtilTrimBlanks(c_ptr);
411       if (sscanf(c_ptr, "%d", &gap) != 1) {
412          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
413                TOOL_NAME, "ThumbnailYGap", c_ptr, 16);
414          fprintf(stderr, "\n");
415       } else if (gap < 0) {
416          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
417                TOOL_NAME, "ThumbnailYGap", c_ptr, 16);
418          fprintf(stderr, "\n");
419       } else {
420          thumbnailYGap = gap;
421       }
422    }
423    thumbnailX = 32;
424    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThumbnailX")) != NULL) {
425       int x=0;
426 
427       UtilTrimBlanks(c_ptr);
428       if (sscanf(c_ptr, "%d", &x) != 1) {
429          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
430                TOOL_NAME, "ThumbnailX", c_ptr, 32);
431          fprintf(stderr, "\n");
432       } else {
433          thumbnailX = x;
434       }
435    }
436    thumbnailY = 32;
437    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThumbnailY")) != NULL) {
438       int y=0;
439 
440       UtilTrimBlanks(c_ptr);
441       if (sscanf(c_ptr, "%d", &y) != 1) {
442          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
443                TOOL_NAME, "ThumbnailY", c_ptr, 32);
444          fprintf(stderr, "\n");
445       } else {
446          thumbnailY = y;
447       }
448    }
449 }
450 
451 static
ImportGivenXBitmapFile(remote_file,tmp_fname,xbm_fname,stid_success,stid_failure,pn_image_w,pn_image_h)452 int ImportGivenXBitmapFile(remote_file, tmp_fname, xbm_fname, stid_success,
453       stid_failure, pn_image_w, pn_image_h)
454    int remote_file, stid_success, stid_failure, *pn_image_w, *pn_image_h;
455    char *tmp_fname, *xbm_fname;
456 {
457    char *rest=NULL, mag_spec[MAXSTRING+1];
458    unsigned int tmp_w, tmp_h;
459    int rc=0, short_name=FALSE, x=0, y=0, w=0, h=0;
460    int x_hot=0, y_hot=0, orig_w=0, orig_h=0;
461    float mag=(float)0;
462    Pixmap orig_bitmap=None, bitmap=None;
463    XImage *image=NULL;
464    struct ObjRec *obj_ptr=NULL;
465 
466    if (pn_image_w != NULL) *pn_image_w = 0;
467    if (pn_image_h != NULL) *pn_image_h = 0;
468    SetWatchCursor(drawWindow);
469    SetWatchCursor(mainWindow);
470    rc = XReadBitmapFile(mainDisplay, mainWindow,
471          (remote_file ? tmp_fname : xbm_fname), &tmp_w, &tmp_h,
472          &orig_bitmap, &x_hot, &y_hot);
473    orig_w = tmp_w; orig_h = tmp_h;
474    SetDefaultCursor(mainWindow);
475    ShowCursor();
476 
477    if (remote_file) {
478       short_name = FALSE;
479    } else {
480       if ((short_name=IsPrefix(bootDir, xbm_fname, &rest))) ++rest;
481    }
482    if (rc != BitmapSuccess) {
483       sprintf(gszMsgBox, TgLoadString(stid_failure),
484             (short_name ? rest : xbm_fname));
485       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
486       if (remote_file) unlink(tmp_fname);
487       return FALSE;
488    }
489    x = 0;
490    y = 0;
491    w = orig_w;
492    h = orig_h;
493    mag = 1.0;
494    if (askForXBmSpec) {
495       sprintf(gszMsgBox, TgLoadString(STID_ENTER_GEOM_SPEC_ORIG_SIZE),
496             orig_w, orig_h);
497       *mag_spec = '\0';
498       Dialog(gszMsgBox, TgLoadCachedString(CSTID_DLG_ACCEPT_CONTINUE),
499             mag_spec);
500       if (*mag_spec != '\0') {
501          ParseCutSpec(mag_spec, orig_w, orig_h, &mag, &x, &y, &w, &h);
502       }
503       if (x==0 && y==0 && w==orig_w && h==orig_h && mag==1.0) {
504          bitmap = orig_bitmap;
505       } else {
506          orig_w = w;
507          orig_h = h;
508          if (!ExtractBitmap(orig_bitmap, NULL, x, y, w, h, &bitmap, &image)) {
509             if (remote_file) unlink(tmp_fname);
510             XFreePixmap(mainDisplay, orig_bitmap);
511             return FALSE;
512          }
513          XFreePixmap(mainDisplay, orig_bitmap);
514          w = (int)(((float)w) * mag);
515          h = (int)(((float)h) * mag);
516       }
517    } else {
518       bitmap = orig_bitmap;
519    }
520    obj_ptr = CreateXBmObj(orig_w, orig_h, w, h, bitmap, image);
521    AddObj(NULL, topObj, obj_ptr);
522    PlaceTopObj(obj_ptr, NULL, NULL);
523 
524    SelectTopObj();
525    RecordNewObjCmd();
526    SetFileModified(TRUE);
527    justDupped = FALSE;
528 
529    if (!importFromLibrary && !remote_file) SetCurImportDir(xbm_fname);
530 
531    if (stid_success != INVALID) {
532       sprintf(gszMsgBox, TgLoadString(stid_success),
533             orig_w, orig_h, (short_name ? rest : xbm_fname));
534       Msg(gszMsgBox);
535    }
536    if (pn_image_w != NULL) *pn_image_w = orig_w;
537    if (pn_image_h != NULL) *pn_image_h = orig_h;
538 
539    return TRUE;
540 }
541 
ImportXBitmapFile()542 void ImportXBitmapFile()
543 {
544    char xbm_fname[MAXPATHLENGTH+1], tmp_fname[MAXPATHLENGTH+1];
545    int remote_file=FALSE;
546    XEvent ev;
547 
548    MakeQuiescent();
549 
550    importingFile = TRUE;
551    *xbm_fname = *tmp_fname = '\0';
552    if (importFromLibrary) {
553       char name[MAXSTRING+1], path[MAXSTRING+1];
554 
555       if (SelectFromLibrary(TgLoadString(STID_SEL_XBM_FILE_TO_IMPORT),
556             XBM_FILE_EXT, name, path) == INVALID) {
557          importingFile = FALSE;
558          return;
559       }
560       sprintf(xbm_fname, "%s%c%s", path, DIR_SEP, name);
561    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_XBM_FILE_TO_IMPORT),
562          XBM_FILE_EXT, xbm_fname) == INVALID) {
563       importingFile = FALSE;
564       return;
565    } else if (FileIsRemote(xbm_fname)) {
566       int is_html=FALSE;
567 
568       if (!DownloadRemoteFile(xbm_fname, NULL, NULL, &is_html, tmp_fname, NULL,
569             0) || *tmp_fname == '\0') {
570          importingFile = FALSE;
571          return;
572       }
573       remote_file = TRUE;
574    }
575    XSync(mainDisplay, False);
576    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
577       ExposeEventHandler(&ev, TRUE);
578    }
579    ImportGivenXBitmapFile(remote_file, tmp_fname, xbm_fname,
580          STID_GIVEN_XBM_SIZE_FILE_IMPORTED, STID_CANNOT_IMPORT_XBM_FILE,
581          NULL, NULL);
582 
583    if (remote_file) unlink(tmp_fname);
584    importingFile = FALSE;
585 }
586 
587 static
ImportGivenXPixmapFile(remote_file,tmp_fname,xpm_fname,stid_success,stid_failure,pn_image_w,pn_image_h)588 int ImportGivenXPixmapFile(remote_file, tmp_fname, xpm_fname, stid_success,
589       stid_failure, pn_image_w, pn_image_h)
590    int remote_file, stid_success, stid_failure, *pn_image_w, *pn_image_h;
591    char *tmp_fname, *xpm_fname;
592 {
593    char *rest=NULL;
594    int rc=0, ncolors=0, chars_per_pixel=0, *pixels=NULL, short_name=FALSE;
595    int first_pixel_is_bg=FALSE, image_w=0, image_h=0, w=0, h=0;
596    Pixmap pixmap=None, bitmap=None;
597    XImage *image=NULL, *bitmap_image=NULL;
598    char *color_char, **color_str=NULL, *xpm_data=NULL;
599    struct ObjRec *obj_ptr=NULL;
600 
601    if (pn_image_w != NULL) *pn_image_w = 0;
602    if (pn_image_h != NULL) *pn_image_h = 0;
603    SetWatchCursor(drawWindow);
604    SetWatchCursor(mainWindow);
605    rc = MyReadPixmapFile(remote_file ? tmp_fname : xpm_fname,
606          &image_w, &image_h, &w, &h, &pixmap, &image, &bitmap, &bitmap_image,
607          &ncolors, &chars_per_pixel, &first_pixel_is_bg, &color_char,
608          &color_str, &pixels, &xpm_data);
609    SetDefaultCursor(mainWindow);
610    ShowCursor();
611 
612    if (remote_file) {
613       short_name = FALSE;
614    } else {
615       if ((short_name=IsPrefix(bootDir, xpm_fname, &rest))) ++rest;
616    }
617    if (rc != BitmapSuccess) {
618       if (stid_failure != INVALID) {
619          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_XPM_FILE),
620                (short_name ? rest : xpm_fname));
621          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
622       }
623       return FALSE;
624    }
625    obj_ptr = CreateXPmObj(image_w, image_h, w, h, pixmap, image, bitmap,
626          bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg, color_char,
627          color_str, pixels, xpm_data);
628    AddObj(NULL, topObj, obj_ptr);
629    PlaceTopObj(obj_ptr, NULL, NULL);
630 
631    SelectTopObj();
632    RecordNewObjCmd();
633    SetFileModified(TRUE);
634    justDupped = FALSE;
635    if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
636       RedrawColorWindow();
637    }
638    if (!importFromLibrary && !remote_file && tmp_fname != NULL) {
639       SetCurImportDir(xpm_fname);
640    }
641    if (stid_success != INVALID) {
642       sprintf(gszMsgBox, TgLoadString(STID_GIVEN_XPM_SIZE_FILE_IMPORTED),
643             image_w, image_h, (short_name ? rest : xpm_fname));
644       Msg(gszMsgBox);
645    }
646    if (pn_image_w != NULL) *pn_image_w = image_w;
647    if (pn_image_h != NULL) *pn_image_h = image_h;
648 
649    return TRUE;
650 }
651 
ImportXPixmapFile()652 void ImportXPixmapFile()
653 {
654    char xpm_fname[MAXPATHLENGTH+1], tmp_fname[MAXPATHLENGTH+1];
655    int remote_file=FALSE;
656    XEvent ev;
657 
658    MakeQuiescent();
659 
660    importingFile = TRUE;
661    *xpm_fname = *tmp_fname = '\0';
662    if (importFromLibrary) {
663       char name[MAXSTRING+1], path[MAXSTRING+1];
664 
665       if (SelectFromLibrary(TgLoadString(STID_SEL_XPM_FILE_TO_IMPORT),
666             XPM_FILE_EXT, name, path) == INVALID) {
667          importingFile = FALSE;
668          return;
669       }
670       sprintf(xpm_fname, "%s%c%s", path, DIR_SEP, name);
671    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_XPM_FILE_TO_IMPORT),
672          XPM_FILE_EXT, xpm_fname) == INVALID) {
673       importingFile = FALSE;
674       return;
675    } else if (FileIsRemote(xpm_fname)) {
676       int is_html=FALSE;
677 
678       if (!DownloadRemoteFile(xpm_fname, NULL, NULL, &is_html, tmp_fname, NULL,
679             0) || *tmp_fname == '\0') {
680          importingFile = FALSE;
681          return;
682       }
683       remote_file = TRUE;
684    }
685    XSync(mainDisplay, False);
686    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
687       ExposeEventHandler(&ev, TRUE);
688    }
689    ImportGivenXPixmapFile(remote_file, tmp_fname, xpm_fname,
690          STID_GIVEN_XPM_SIZE_FILE_IMPORTED, STID_CANNOT_IMPORT_XPM_FILE,
691          NULL, NULL);
692 
693    if (remote_file) unlink(tmp_fname);
694    importingFile = FALSE;
695 }
696 
ImportEPSFile(Embed,psz_fname_spec)697 void ImportEPSFile(Embed, psz_fname_spec)
698    int Embed;
699    char *psz_fname_spec;
700 {
701    char eps_fname[MAXPATHLENGTH+1], *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
702    char **lines=NULL, write_date[32];
703    int i, rc, short_name, num_lines=0, epsf_level, image_w, image_h;
704    int remote_file=FALSE;
705    float llx, lly, urx, ury;
706    Pixmap bitmap=None;
707    XImage *image=NULL;
708    XEvent ev;
709    struct ObjRec *obj_ptr=NULL;
710 
711    MakeQuiescent();
712 
713    importingFile = TRUE;
714    *eps_fname = *tmp_fname = '\0';
715    if (psz_fname_spec != NULL && strcmp(psz_fname_spec, "-1") != 0) {
716       int len=strlen(psz_fname_spec);
717 
718       if (len > 0 && psz_fname_spec[len-1] == ')') {
719          psz_fname_spec[len-1] = '\0';
720          UtilStrCpyN(tmp_fname, sizeof(tmp_fname), psz_fname_spec);
721          psz_fname_spec[len-1] = ')';
722       } else {
723          UtilStrCpyN(tmp_fname, sizeof(tmp_fname), psz_fname_spec);
724       }
725       if (*tmp_fname == DIR_SEP) {
726          strcpy(eps_fname, tmp_fname);
727       } else if (curDirIsLocal) {
728          sprintf(eps_fname, "%s%c%s", curDir, DIR_SEP, tmp_fname);
729       } else {
730          sprintf(eps_fname, "%s%c%s", curLocalDir, DIR_SEP, tmp_fname);
731       }
732       *tmp_fname = '\0';
733    } else {
734       if (importFromLibrary) {
735          char name[MAXSTRING+1], path[MAXSTRING+1];
736 
737          if (SelectFromLibrary(TgLoadString(STID_SEL_EPS_FILE_TO_IMPORT),
738                EPSF_FILE_EXT, name, path) == INVALID) {
739             importingFile = FALSE;
740             return;
741          }
742          sprintf(eps_fname, "%s%c%s", path, DIR_SEP, name);
743       } else if (SelectFileNameToImport(
744             TgLoadString(STID_SEL_EPS_FILE_TO_IMPORT), EPSF_FILE_EXT,
745             eps_fname) == INVALID) {
746          importingFile = FALSE;
747          return;
748       }
749    }
750    if (FileIsRemote(eps_fname)) {
751       int is_html=FALSE;
752 
753       if (!Embed) {
754          sprintf(gszMsgBox, TgLoadString(STID_IMPORT_REM_FILE_EMBED_INSTEAD),
755                "EPS", "EPS");
756          if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) != MB_ID_YES) {
757             importingFile = FALSE;
758             return;
759          }
760          Embed = TRUE;
761       }
762       if (!DownloadRemoteFile(eps_fname, NULL, NULL, &is_html, tmp_fname,
763            NULL, 0) || *tmp_fname == '\0') {
764          importingFile = FALSE;
765          return;
766       }
767       remote_file = TRUE;
768    }
769    XSync(mainDisplay, False);
770    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
771       ExposeEventHandler(&ev, TRUE);
772    }
773    SetWatchCursor(drawWindow);
774    SetWatchCursor(mainWindow);
775    rc = MyReadEPSFile(remote_file ? tmp_fname : eps_fname, &image_w, &image_h,
776          &bitmap, &image, (Embed ? &num_lines : NULL), (Embed ? &lines : NULL),
777          &epsf_level, &llx, &lly, &urx, &ury, write_date);
778 
779    if (remote_file) {
780       short_name = FALSE;
781    } else {
782       if ((short_name=IsPrefix(bootDir, eps_fname, &rest))) ++rest;
783    }
784    if (rc != BitmapSuccess) {
785       SetDefaultCursor(mainWindow);
786       ShowCursor();
787       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_GIVEN_EPS),
788             (short_name ? rest : eps_fname));
789       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
790       if (remote_file) unlink(tmp_fname);
791       importingFile = FALSE;
792       return;
793    }
794 
795    if (Embed) saveEPSLines = TRUE;
796    if (short_name) {
797       obj_ptr = CreateEPSObj(rest, image_w, image_h, bitmap, image,
798             num_lines, lines, epsf_level, &llx, &lly, &urx, &ury, write_date);
799    } else {
800       obj_ptr = CreateEPSObj(remote_file ? tmp_fname : eps_fname,
801             image_w, image_h, bitmap, image, num_lines, lines, epsf_level,
802             &llx, &lly, &urx, &ury, write_date);
803    }
804    saveEPSLines = FALSE;
805 
806    if (!Embed && lines != NULL) {
807       for (i=0; i < num_lines; i++) {
808          if (lines[i] != NULL) free(lines[i]);
809       }
810       free(lines);
811    }
812    if (strcmp(defaultEPSScalingStr,"1") != 0) {
813       ScaleAnEPSObj(obj_ptr, &defaultEPSScaling);
814    }
815    SetDefaultCursor(mainWindow);
816    ShowCursor();
817 
818    AddObj(NULL, topObj, obj_ptr);
819    if (psz_fname_spec == NULL) {
820       PlaceTopObj(obj_ptr, NULL, NULL);
821    } else {
822       MoveObj(obj_ptr, 0-obj_ptr->obbox.ltx, 0-obj_ptr->obbox.lty);
823    }
824    SelectTopObj();
825    RecordNewObjCmd();
826    SetFileModified(TRUE);
827    justDupped = FALSE;
828 
829    if (!importFromLibrary && !remote_file) SetCurImportDir(eps_fname);
830 
831    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_EPS_FILE_IMPORTED),
832          (short_name ? rest : eps_fname));
833    Msg(gszMsgBox);
834    if (remote_file) unlink(tmp_fname);
835    importingFile = FALSE;
836 }
837 
838 static char gifToXpmCmd[MAXSTRING+1];
839 static char pngToXpmCmd[MAXSTRING+1];
840 static char jpegToXpmCmd[MAXSTRING+1];
841 static char jpegToPpm6Cmd[MAXSTRING+1];
842 static char pngToPpm6Cmd[MAXSTRING+1];
843 static char gifToPpm6Cmd[MAXSTRING+1];
844 static char pbmToXbmCmd[MAXSTRING+1];
845 static char pgmToXpmCmd[MAXSTRING+1];
846 static char ppmToXpmCmd[MAXSTRING+1];
847 static char gifAnimExplodeCmd[MAXSTRING+1];
848 
849 static char defGifToXpm[]="giftopnm %s | ppmtoxpm";
850 static char defPngToXpm[]=
851       "pngtopnm %s | pnmdepth 255 | ppmquant 222 | ppmtoxpm";
852 static char defJpegToXpm[]="djpeg -gif -color 222 %s | giftopnm | ppmtoxpm";
853 static char defJpegToPpm6[]="djpeg -ppm \"%s\"";
854 static char defPngToPpm6[]="pngtopnm \"%s\"";
855 static char defGifToPpm6[]="giftopnm \"%s\"";
856 static char defPbmToXbm[]="pbmtoxbm %s";
857 static char defPgmToXpm[]="ppmtoxpm %s";
858 static char defPpmToXpm[]="ppmquant 222 %s | ppmtoxpm";
859 
860 static
InitGifToXpm()861 void InitGifToXpm()
862 {
863    static int nInitialized=FALSE;
864 
865    if (!nInitialized) {
866       char *c_ptr;
867 
868       nInitialized = TRUE;
869       if (mainDisplay != NULL &&
870             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GifToXpm")) != NULL) {
871          int count=0;
872 
873          strcpy(gifToXpmCmd, c_ptr);
874          for (c_ptr=strstr(gifToXpmCmd,"%s"); c_ptr!=NULL;
875                c_ptr=strstr(++c_ptr,"%s")) {
876             count++;
877          }
878          if (count != 1) {
879             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
880                   TOOL_NAME, "GifToXpm", gifToXpmCmd, defGifToXpm);
881             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
882             strcpy(gifToXpmCmd, defGifToXpm);
883          }
884       } else {
885          strcpy(gifToXpmCmd, defGifToXpm);
886       }
887       if (mainDisplay != NULL &&
888             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PngToXpm")) != NULL) {
889          int count=0;
890 
891          strcpy(pngToXpmCmd, c_ptr);
892          for (c_ptr=strstr(pngToXpmCmd,"%s"); c_ptr!=NULL;
893                c_ptr=strstr(++c_ptr,"%s")) {
894             count++;
895          }
896          if (count != 1) {
897             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
898                   TOOL_NAME, "PngToXpm", pngToXpmCmd, defPngToXpm);
899             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
900             strcpy(pngToXpmCmd, defPngToXpm);
901          }
902       } else {
903          strcpy(pngToXpmCmd, defPngToXpm);
904       }
905       if (mainDisplay != NULL &&
906             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"JpegToXpm")) != NULL) {
907          int count=0;
908 
909          strcpy(jpegToXpmCmd, c_ptr);
910          for (c_ptr=strstr(jpegToXpmCmd,"%s"); c_ptr!=NULL;
911                c_ptr=strstr(++c_ptr,"%s")) {
912             count++;
913          }
914          if (count != 1) {
915             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
916                   TOOL_NAME, "JpegToXpm", jpegToXpmCmd, defJpegToXpm);
917             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
918             strcpy(jpegToXpmCmd, defJpegToXpm);
919          }
920       } else {
921          strcpy(jpegToXpmCmd, defJpegToXpm);
922       }
923       if (mainDisplay != NULL &&
924             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"JpegToPpm6")) != NULL) {
925          int count=0;
926 
927          strcpy(jpegToPpm6Cmd, c_ptr);
928          for (c_ptr=strstr(jpegToPpm6Cmd,"%s"); c_ptr!=NULL;
929                c_ptr=strstr(++c_ptr,"%s")) {
930             count++;
931          }
932          if (count != 1) {
933             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
934                   TOOL_NAME, "JpegToPpm6", jpegToPpm6Cmd, defJpegToPpm6);
935             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
936             strcpy(jpegToPpm6Cmd, defJpegToPpm6);
937          }
938       } else {
939          strcpy(jpegToPpm6Cmd, defJpegToPpm6);
940       }
941       if (mainDisplay != NULL &&
942             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PngToPpm6")) != NULL) {
943          int count=0;
944 
945          strcpy(pngToPpm6Cmd, c_ptr);
946          for (c_ptr=strstr(pngToPpm6Cmd,"%s"); c_ptr!=NULL;
947                c_ptr=strstr(++c_ptr,"%s")) {
948             count++;
949          }
950          if (count != 1) {
951             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
952                   TOOL_NAME, "PngToPpm6", pngToPpm6Cmd, defPngToPpm6);
953             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
954             strcpy(pngToPpm6Cmd, defPngToPpm6);
955          }
956       } else {
957          strcpy(pngToPpm6Cmd, defPngToPpm6);
958       }
959       if (mainDisplay != NULL &&
960             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GifToPpm6")) != NULL) {
961          int count=0;
962 
963          strcpy(gifToPpm6Cmd, c_ptr);
964          for (c_ptr=strstr(gifToPpm6Cmd,"%s"); c_ptr!=NULL;
965                c_ptr=strstr(++c_ptr,"%s")) {
966             count++;
967          }
968          if (count != 1) {
969             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
970                   TOOL_NAME, "GifToPpm6", gifToPpm6Cmd, defPngToPpm6);
971             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
972             strcpy(gifToPpm6Cmd, defGifToPpm6);
973          }
974       } else {
975          strcpy(gifToPpm6Cmd, defGifToPpm6);
976       }
977       if (mainDisplay != NULL &&
978             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PbmToXbm")) != NULL) {
979          int count=0;
980 
981          strcpy(pbmToXbmCmd, c_ptr);
982          for (c_ptr=strstr(pbmToXbmCmd,"%s"); c_ptr!=NULL;
983                c_ptr=strstr(++c_ptr,"%s")) {
984             count++;
985          }
986          if (count != 1) {
987             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
988                   TOOL_NAME, "PbmToXbm", pbmToXbmCmd, defPbmToXbm);
989             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
990             strcpy(pbmToXbmCmd, defPbmToXbm);
991          }
992       } else {
993          strcpy(pbmToXbmCmd, defPbmToXbm);
994       }
995       if (mainDisplay != NULL &&
996             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PgmToXpm")) != NULL) {
997          int count=0;
998 
999          strcpy(pgmToXpmCmd, c_ptr);
1000          for (c_ptr=strstr(pgmToXpmCmd,"%s"); c_ptr!=NULL;
1001                c_ptr=strstr(++c_ptr,"%s")) {
1002             count++;
1003          }
1004          if (count != 1) {
1005             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
1006                   TOOL_NAME, "PgmToXpm", pgmToXpmCmd, defPgmToXpm);
1007             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1008             strcpy(pgmToXpmCmd, defPgmToXpm);
1009          }
1010       } else {
1011          strcpy(pgmToXpmCmd, defPgmToXpm);
1012       }
1013       if (mainDisplay != NULL &&
1014             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PpmToXpm")) != NULL) {
1015          int count=0;
1016 
1017          strcpy(ppmToXpmCmd, c_ptr);
1018          for (c_ptr=strstr(ppmToXpmCmd,"%s"); c_ptr!=NULL;
1019                c_ptr=strstr(++c_ptr,"%s")) {
1020             count++;
1021          }
1022          if (count != 1) {
1023             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
1024                   TOOL_NAME, "PpmToXpm", ppmToXpmCmd, defPpmToXpm);
1025             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1026             strcpy(ppmToXpmCmd, defPpmToXpm);
1027          }
1028       } else {
1029          strcpy(ppmToXpmCmd, defPpmToXpm);
1030       }
1031       if (mainDisplay != NULL &&
1032             (c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GifAnimExplode")) !=
1033             NULL) {
1034          strcpy(gifAnimExplodeCmd, c_ptr);
1035          UtilTrimBlanks(gifAnimExplodeCmd);
1036          if (strstr(gifAnimExplodeCmd, "%s") != NULL) {
1037             sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
1038                   TOOL_NAME, "GifAnimExplode", gifAnimExplodeCmd,
1039                   "gifsicle -eU");
1040             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1041             strcpy(gifAnimExplodeCmd, "gifsicle -eU");
1042          }
1043       } else {
1044          strcpy(gifAnimExplodeCmd, "gifsicle -eU");
1045       }
1046    }
1047 }
1048 
ConvertGifToXpm(pszGifPath,pszXpmPath,xpm_path_sz)1049 int ConvertGifToXpm(pszGifPath, pszXpmPath, xpm_path_sz)
1050    char *pszGifPath, *pszXpmPath;
1051    int xpm_path_sz;
1052 {
1053    FILE *pFile=NULL, *pPipe=NULL;
1054    char *pszCmd=NULL, szBuf[MAXSTRING];
1055    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
1056 
1057    InitGifToXpm();
1058    if (MkTempFile(pszXpmPath, xpm_path_sz, tmpDir, TOOL_NAME) == NULL) {
1059       return FALSE;
1060    }
1061    pszCmd = (char*)malloc(
1062          (strlen(gifToXpmCmd)+strlen(pszGifPath)+10)*sizeof(char));
1063    if (pszCmd == NULL) {
1064       FailAllocMessage();
1065       return FALSE;
1066    }
1067    sprintf(pszCmd, gifToXpmCmd, pszGifPath);
1068    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
1069       free(pszCmd);
1070       return FALSE;
1071    }
1072    if ((pFile=fopen(pszXpmPath,"w")) == NULL) {
1073       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
1074             pszXpmPath);
1075       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1076       free(pszCmd);
1077       return FALSE;
1078    }
1079    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
1080          pszCmd);
1081    SetStringStatus(gszMsgBox);
1082    XSync(mainDisplay, False);
1083    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
1084       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
1085       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1086       free(pszCmd);
1087       fclose(pFile);
1088       unlink(pszXpmPath);
1089       return FALSE;
1090    }
1091    if (!watch_cursor) {
1092       SetWatchCursor(drawWindow);
1093       SetWatchCursor(mainWindow);
1094    }
1095    writeFileFailed = FALSE;
1096    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
1097       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
1098          writeFileFailed = TRUE;
1099          break;
1100       }
1101    }
1102    pclose(pPipe);
1103    if (!watch_cursor) {
1104       SetDefaultCursor(mainWindow);
1105       ShowCursor();
1106    }
1107    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
1108    free(pszCmd);
1109    fclose(pFile);
1110    if (writeFileFailed) {
1111       FailToWriteFileMessage(pszXpmPath);
1112       unlink(pszXpmPath);
1113       return FALSE;
1114    }
1115    return TRUE;
1116 }
1117 
ConvertPngToXpm(pszPngPath,pszXpmPath,xpm_path_sz)1118 int ConvertPngToXpm(pszPngPath, pszXpmPath, xpm_path_sz)
1119    char *pszPngPath, *pszXpmPath;
1120    int xpm_path_sz;
1121 {
1122    FILE *pFile=NULL, *pPipe=NULL;
1123    char *pszCmd=NULL, szBuf[MAXSTRING];
1124    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
1125 
1126    InitGifToXpm();
1127    if (*pszXpmPath == '\0' && xpm_path_sz > 0) {
1128       if (MkTempFile(pszXpmPath, xpm_path_sz, tmpDir, TOOL_NAME) == NULL) {
1129          return FALSE;
1130       }
1131    }
1132    pszCmd = (char*)malloc(
1133          (strlen(pngToXpmCmd)+strlen(pszPngPath)+10)*sizeof(char));
1134    if (pszCmd == NULL) {
1135       FailAllocMessage();
1136       return FALSE;
1137    }
1138    sprintf(pszCmd, pngToXpmCmd, pszPngPath);
1139    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
1140       free(pszCmd);
1141       return FALSE;
1142    }
1143    if ((pFile=fopen(pszXpmPath,"w")) == NULL) {
1144       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
1145             pszXpmPath);
1146       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1147       free(pszCmd);
1148       return FALSE;
1149    }
1150    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
1151          pszCmd);
1152    SetStringStatus(gszMsgBox);
1153    XSync(mainDisplay, False);
1154    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
1155       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
1156       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1157       free(pszCmd);
1158       fclose(pFile);
1159       unlink(pszXpmPath);
1160       return FALSE;
1161    }
1162    if (!watch_cursor) {
1163       SetWatchCursor(drawWindow);
1164       SetWatchCursor(mainWindow);
1165    }
1166    writeFileFailed = FALSE;
1167    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
1168       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
1169          writeFileFailed = TRUE;
1170          break;
1171       }
1172    }
1173    pclose(pPipe);
1174    if (!watch_cursor) {
1175       SetDefaultCursor(mainWindow);
1176       ShowCursor();
1177    }
1178    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
1179    free(pszCmd);
1180    fclose(pFile);
1181    if (writeFileFailed) {
1182       FailToWriteFileMessage(pszXpmPath);
1183       unlink(pszXpmPath);
1184       return FALSE;
1185    }
1186    return TRUE;
1187 }
1188 
ConvertJpegToXpm(pszJpegPath,pszXpmPath,xpm_path_sz)1189 int ConvertJpegToXpm(pszJpegPath, pszXpmPath, xpm_path_sz)
1190    char *pszJpegPath, *pszXpmPath;
1191    int xpm_path_sz;
1192 {
1193    FILE *pFile=NULL, *pPipe=NULL;
1194    char *pszCmd=NULL, szBuf[MAXSTRING];
1195    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
1196 
1197    InitGifToXpm();
1198    if (*pszXpmPath == '\0' && xpm_path_sz > 0) {
1199       if (MkTempFile(pszXpmPath, xpm_path_sz, tmpDir, TOOL_NAME) == NULL) {
1200          return FALSE;
1201       }
1202    }
1203    pszCmd = (char*)malloc(
1204          (strlen(jpegToXpmCmd)+strlen(pszJpegPath)+10)*sizeof(char));
1205    if (pszCmd == NULL) {
1206       FailAllocMessage();
1207       return FALSE;
1208    }
1209    sprintf(pszCmd, jpegToXpmCmd, pszJpegPath);
1210    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
1211       free(pszCmd);
1212       return FALSE;
1213    }
1214    if ((pFile=fopen(pszXpmPath,"w")) == NULL) {
1215       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
1216             pszXpmPath);
1217       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1218       free(pszCmd);
1219       return FALSE;
1220    }
1221    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
1222          pszCmd);
1223    SetStringStatus(gszMsgBox);
1224    if (mainDisplay != NULL) XSync(mainDisplay, False);
1225    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
1226       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
1227       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1228       free(pszCmd);
1229       fclose(pFile);
1230       unlink(pszXpmPath);
1231       return FALSE;
1232    }
1233    if (!watch_cursor) {
1234       SetWatchCursor(drawWindow);
1235       SetWatchCursor(mainWindow);
1236    }
1237    writeFileFailed = FALSE;
1238    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
1239       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
1240          writeFileFailed = TRUE;
1241          break;
1242       }
1243    }
1244    pclose(pPipe);
1245    if (!watch_cursor) {
1246       SetDefaultCursor(mainWindow);
1247       ShowCursor();
1248    }
1249    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
1250    free(pszCmd);
1251    fclose(pFile);
1252    if (writeFileFailed) {
1253       FailToWriteFileMessage(pszXpmPath);
1254       unlink(pszXpmPath);
1255       return FALSE;
1256    }
1257    return TRUE;
1258 }
1259 
ConvertImageFileToPpm6(pszImageFilePath,pszPpm6Path,ppm6_path_sz,format)1260 int ConvertImageFileToPpm6(pszImageFilePath, pszPpm6Path, ppm6_path_sz, format)
1261    char *pszImageFilePath, *pszPpm6Path;
1262    int ppm6_path_sz, format;
1263 {
1264    FILE *pFile=NULL, *pPipe=NULL;
1265    char *pszCmd=NULL, szBuf[MAXSTRING], *psz_convert_cmd=NULL;
1266    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
1267 
1268    InitGifToXpm();
1269    if (MkTempFile(pszPpm6Path, ppm6_path_sz, tmpDir, TOOL_NAME) == NULL) {
1270       return FALSE;
1271    }
1272    switch (format) {
1273    case JPEG_FILE:
1274       if (PRTGIF && !cmdLineOpenDisplay && *cmdLineJpegToPpm6Cmd != '\0') {
1275          psz_convert_cmd = cmdLineJpegToPpm6Cmd;
1276       } else {
1277          psz_convert_cmd = jpegToPpm6Cmd;
1278       }
1279       break;
1280    case PNG_FILE:
1281       psz_convert_cmd = pngToPpm6Cmd;
1282       break;
1283    case GIF_FILE:
1284       psz_convert_cmd = gifToPpm6Cmd;
1285       break;
1286    }
1287    pszCmd = (char*)malloc(
1288          (strlen(psz_convert_cmd)+strlen(pszImageFilePath)+10)*sizeof(char));
1289    if (pszCmd == NULL) {
1290       FailAllocMessage();
1291       return FALSE;
1292    }
1293    sprintf(pszCmd, psz_convert_cmd, pszImageFilePath);
1294    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
1295       free(pszCmd);
1296       return FALSE;
1297    }
1298    if ((pFile=fopen(pszPpm6Path,"w")) == NULL) {
1299       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
1300             pszPpm6Path);
1301       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1302       free(pszCmd);
1303       return FALSE;
1304    }
1305    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
1306          pszCmd);
1307    SetStringStatus(gszMsgBox);
1308    if (mainDisplay != NULL) XSync(mainDisplay, False);
1309    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
1310       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
1311       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1312       free(pszCmd);
1313       fclose(pFile);
1314       unlink(pszPpm6Path);
1315       return FALSE;
1316    }
1317    if (!watch_cursor) {
1318       SetWatchCursor(drawWindow);
1319       SetWatchCursor(mainWindow);
1320    }
1321    writeFileFailed = FALSE;
1322    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
1323       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
1324          writeFileFailed = TRUE;
1325          break;
1326       }
1327    }
1328    pclose(pPipe);
1329    if (!watch_cursor) {
1330       SetDefaultCursor(mainWindow);
1331       ShowCursor();
1332    }
1333    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
1334    free(pszCmd);
1335    fclose(pFile);
1336    if (writeFileFailed) {
1337       FailToWriteFileMessage(pszPpm6Path);
1338       unlink(pszPpm6Path);
1339       return FALSE;
1340    }
1341    return TRUE;
1342 }
1343 
ConvertJpegToPpm6(pszJpegPath,pszPpm6Path,ppm6_path_sz)1344 int ConvertJpegToPpm6(pszJpegPath, pszPpm6Path, ppm6_path_sz)
1345    char *pszJpegPath, *pszPpm6Path;
1346    int ppm6_path_sz;
1347 {
1348    return ConvertImageFileToPpm6(pszJpegPath, pszPpm6Path, ppm6_path_sz,
1349          JPEG_FILE);
1350 }
1351 
ConvertPngToPpm6(pszPngPath,pszPpm6Path,ppm6_path_sz)1352 int ConvertPngToPpm6(pszPngPath, pszPpm6Path, ppm6_path_sz)
1353    char *pszPngPath, *pszPpm6Path;
1354    int ppm6_path_sz;
1355 {
1356    return ConvertImageFileToPpm6(pszPngPath, pszPpm6Path, ppm6_path_sz,
1357          PNG_FILE);
1358 }
1359 
ConvertGifToPpm6(pszGifPath,pszPpm6Path,ppm6_path_sz)1360 int ConvertGifToPpm6(pszGifPath, pszPpm6Path, ppm6_path_sz)
1361    char *pszGifPath, *pszPpm6Path;
1362    int ppm6_path_sz;
1363 {
1364    return ConvertImageFileToPpm6(pszGifPath, pszPpm6Path, ppm6_path_sz,
1365          GIF_FILE);
1366 }
1367 
1368 #define IMPORTING_JPEG 0
1369 #define IMPORTING_PPM  1
1370 #define IMPORTING_PNG  2
1371 
1372 static
FinishImport(remote_file,remote_tmp_fname,local_fname,which,pn_image_w,pn_image_h)1373 int FinishImport(remote_file, remote_tmp_fname, local_fname, which, pn_image_w,
1374       pn_image_h)
1375    int remote_file, *pn_image_w, *pn_image_h;
1376    char *remote_tmp_fname, *local_fname;
1377 {
1378    char xpm_fname[MAXPATHLENGTH+1], *rest=NULL, *psz_format=NULL;
1379    int rc=0, short_name=FALSE, image_w=0, image_h=0;
1380    XEvent ev;
1381 
1382    switch (which) {
1383    case IMPORTING_JPEG: psz_format = "JPEG"; break;
1384    case IMPORTING_PPM: psz_format = "PPM"; break;
1385    case IMPORTING_PNG: psz_format = "PNG"; break;
1386    }
1387    XSync(mainDisplay, False);
1388    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
1389       ExposeEventHandler(&ev, TRUE);
1390    }
1391    if (remote_file) {
1392       short_name = FALSE;
1393    } else {
1394       if ((short_name=IsPrefix(bootDir, local_fname, &rest))) ++rest;
1395    }
1396    SetWatchCursor(drawWindow);
1397    SetWatchCursor(mainWindow);
1398    SaveStatusStrings();
1399    if (fullTrueColorMode && HasZlibSupport()) {
1400       struct ObjRec *obj_ptr=NULL;
1401       struct XPmRec *xpm_ptr=NULL;
1402       char ppm6_fname[MAXPATHLENGTH+1];
1403       char deflated_fname[MAXPATHLENGTH+1];
1404 
1405       switch (which) {
1406       case IMPORTING_JPEG:
1407          rc = ConvertJpegToPpm6((remote_file ? remote_tmp_fname : local_fname),
1408                ppm6_fname, sizeof(ppm6_fname));
1409          if (rc) {
1410             ResetPngHeaderInfo(&gPngHeaderInfo);
1411             obj_ptr = CreatePpmTrueObjFromFile(ppm6_fname);
1412             unlink(ppm6_fname);
1413          }
1414          if (obj_ptr == NULL) {
1415             RestoreStatusStrings();
1416             SetDefaultCursor(mainWindow);
1417             ShowCursor();
1418             if (remote_file) unlink(remote_tmp_fname);
1419             importingFile = FALSE;
1420             return FALSE;
1421          }
1422          xpm_ptr = obj_ptr->detail.xpm;
1423          xpm_ptr->real_type = PPM_TRUE;
1424          xpm_ptr->ppm_data_compress = PPM_JPEG_COMPRESS;
1425          xpm_ptr->ppm_data = ReadFileIntoBuf(
1426                (remote_file ? remote_tmp_fname : local_fname),
1427                &xpm_ptr->ppm_data_size);
1428          xpm_ptr->ppm_mask_data = NULL;
1429          xpm_ptr->ppm_mask_size = 0;
1430          break;
1431       case IMPORTING_PPM:
1432          ResetPngHeaderInfo(&gPngHeaderInfo);
1433          obj_ptr = CreatePpmTrueObjFromFile(remote_file ? remote_tmp_fname :
1434                local_fname);
1435          if (obj_ptr != NULL &&
1436                MkTempFile(deflated_fname, sizeof(deflated_fname), tmpDir,
1437                TOOL_NAME) != NULL &&
1438                DeflateFile((remote_file ? remote_tmp_fname : local_fname),
1439                deflated_fname)) {
1440          } else {
1441             if (obj_ptr != NULL) FreeObj(obj_ptr);
1442             RestoreStatusStrings();
1443             SetDefaultCursor(mainWindow);
1444             ShowCursor();
1445             if (remote_file) unlink(remote_tmp_fname);
1446             importingFile = FALSE;
1447             return FALSE;
1448          }
1449          xpm_ptr = obj_ptr->detail.xpm;
1450          xpm_ptr->real_type = PPM_TRUE;
1451          xpm_ptr->ppm_data_compress = PPM_DATA_DEFLATED;
1452          xpm_ptr->ppm_data = ReadFileIntoBuf(deflated_fname,
1453                &xpm_ptr->ppm_data_size);
1454          xpm_ptr->ppm_mask_data = NULL;
1455          xpm_ptr->ppm_mask_size = 0;
1456          unlink(deflated_fname);
1457          break;
1458       case IMPORTING_PNG:
1459          rc = ConvertPngToPpm6((remote_file ? remote_tmp_fname : local_fname),
1460                ppm6_fname, sizeof(ppm6_fname));
1461          if (rc) {
1462             ResetPngHeaderInfo(&gPngHeaderInfo);
1463             if (PngFileGetTransColorInit(&gPngHeaderInfo,
1464                   (remote_file ? remote_tmp_fname : local_fname)) &&
1465                   PngFileGetTransColor(&gPngHeaderInfo)) {
1466             }
1467             obj_ptr = CreatePpmTrueObjFromFile(ppm6_fname);
1468          }
1469          if (obj_ptr != NULL &&
1470                MkTempFile(deflated_fname, sizeof(deflated_fname), tmpDir,
1471                TOOL_NAME) != NULL && DeflateFile(ppm6_fname, deflated_fname)) {
1472             /* nothing to do here */
1473          } else {
1474             unlink(ppm6_fname);
1475             if (obj_ptr != NULL) FreeObj(obj_ptr);
1476             RestoreStatusStrings();
1477             SetDefaultCursor(mainWindow);
1478             ShowCursor();
1479             if (remote_file) unlink(remote_tmp_fname);
1480             importingFile = FALSE;
1481             return FALSE;
1482          }
1483          unlink(ppm6_fname);
1484          xpm_ptr = obj_ptr->detail.xpm;
1485          xpm_ptr->real_type = PPM_TRUE;
1486          xpm_ptr->ppm_data_compress = PPM_DATA_DEFLATED;
1487          xpm_ptr->ppm_data = ReadFileIntoBuf(deflated_fname,
1488                &xpm_ptr->ppm_data_size);
1489          xpm_ptr->ppm_mask_data = NULL;
1490          xpm_ptr->ppm_mask_size = 0;
1491          if (gPngHeaderInfo.valid && gPngHeaderInfo.trans_color_pixel_found) {
1492             xpm_ptr->has_transparent_color = TRUE;
1493             xpm_ptr->transparent_color[0] = gPngHeaderInfo.trans_color_pixel_red;
1494             xpm_ptr->transparent_color[1] = gPngHeaderInfo.trans_color_pixel_green;
1495             xpm_ptr->transparent_color[2] = gPngHeaderInfo.trans_color_pixel_blue;
1496          }
1497          unlink(deflated_fname);
1498          break;
1499       }
1500       RestoreStatusStrings();
1501       SetDefaultCursor(mainWindow);
1502       ShowCursor();
1503       if (obj_ptr == NULL) {
1504          sprintf(gszMsgBox, TgLoadString(STID_CANT_IMPORT_GIVEN_TYPE_FILE),
1505                psz_format, (short_name ? rest : local_fname));
1506          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1507          if (remote_file) unlink(remote_tmp_fname);
1508          importingFile = FALSE;
1509          return FALSE;
1510       }
1511       AddObj(NULL, topObj, obj_ptr);
1512       PlaceTopObj(obj_ptr, NULL, NULL);
1513 
1514       SelectTopObj();
1515       RecordNewObjCmd();
1516       SetFileModified(TRUE);
1517       justDupped = FALSE;
1518 
1519       if (!importFromLibrary && !remote_file) {
1520          SetCurImportDir(local_fname);
1521       }
1522       if (pn_image_w != NULL) *pn_image_w = xpm_ptr->image_w;
1523       if (pn_image_h != NULL) *pn_image_h = xpm_ptr->image_h;
1524 
1525       return TRUE;
1526    }
1527    *xpm_fname = '\0';
1528    switch (which) {
1529    case IMPORTING_JPEG:
1530       rc = ConvertJpegToXpm((remote_file ? remote_tmp_fname : local_fname),
1531             xpm_fname, sizeof(xpm_fname));
1532       break;
1533    case IMPORTING_PPM:
1534       rc = ConvertPpmToXpm((remote_file ? remote_tmp_fname : local_fname),
1535             xpm_fname, sizeof(xpm_fname));
1536       break;
1537    case IMPORTING_PNG:
1538       rc = ConvertPngToXpm((remote_file ? remote_tmp_fname : local_fname),
1539             xpm_fname, sizeof(xpm_fname));
1540       break;
1541    }
1542    RestoreStatusStrings();
1543    SetDefaultCursor(mainWindow);
1544    ShowCursor();
1545    if (!rc) {
1546       if (remote_file) unlink(remote_tmp_fname);
1547       importingFile = FALSE;
1548       return FALSE;
1549    }
1550    if (!ImportGivenXPixmapFile(FALSE, NULL, xpm_fname, INVALID, INVALID,
1551          &image_w, &image_h)) {
1552       sprintf(gszMsgBox, TgLoadString(STID_CANT_IMPORT_GIVEN_TYPE_FILE),
1553             psz_format, (short_name ? rest : local_fname));
1554       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1555       unlink(xpm_fname);
1556       if (remote_file) unlink(remote_tmp_fname);
1557       importingFile = FALSE;
1558       return FALSE;
1559    }
1560    unlink(xpm_fname);
1561 
1562    return TRUE;
1563 }
1564 
ImportPNGFile()1565 void ImportPNGFile()
1566 {
1567    char *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
1568    char szPngPath[MAXPATHLENGTH+1];
1569    int short_name=FALSE, image_w=0, image_h=0, remote_file=FALSE;
1570 
1571    MakeQuiescent();
1572 
1573    importingFile = TRUE;
1574    *szPngPath = *tmp_fname = '\0';
1575    if (importFromLibrary) {
1576       char name[MAXSTRING+1], path[MAXSTRING+1];
1577 
1578       if (SelectFromLibrary(TgLoadString(STID_SEL_PNG_FILE_TO_IMPORT),
1579             "png", name, path) == INVALID) {
1580          importingFile = FALSE;
1581          return;
1582       }
1583       sprintf(szPngPath, "%s%c%s", path, DIR_SEP, name);
1584    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_PNG_FILE_TO_IMPORT),
1585          "png", szPngPath) == INVALID) {
1586       importingFile = FALSE;
1587       return;
1588    } else if (FileIsRemote(szPngPath)) {
1589       int is_html=FALSE;
1590 
1591       if (!DownloadRemoteFile(szPngPath, NULL, NULL, &is_html, tmp_fname, NULL,
1592            0) || *tmp_fname == '\0') {
1593          importingFile = FALSE;
1594          return;
1595       }
1596       remote_file = TRUE;
1597    }
1598    if (!FinishImport(remote_file, tmp_fname, szPngPath, IMPORTING_PNG,
1599          &image_w, &image_h)) {
1600       if (remote_file) unlink(tmp_fname);
1601       importingFile = FALSE;
1602       return;
1603    }
1604    if (!importFromLibrary && !remote_file) SetCurImportDir(szPngPath);
1605 
1606    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_PNG_SIZE_FILE_IMPORTED),
1607          image_w, image_h, (short_name ? rest : szPngPath));
1608    Msg(gszMsgBox);
1609 
1610    if (remote_file) unlink(tmp_fname);
1611    importingFile = FALSE;
1612 }
1613 
ImportJPEGFile(Embed,psz_fname_spec)1614 void ImportJPEGFile(Embed, psz_fname_spec)
1615    int Embed;
1616    char *psz_fname_spec;
1617 {
1618    char *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
1619    char szJpegPath[MAXPATHLENGTH+1];
1620    int short_name=FALSE, image_w=0, image_h=0, remote_file=FALSE;
1621 
1622    MakeQuiescent();
1623 
1624    importingFile = TRUE;
1625    *szJpegPath = *tmp_fname = '\0';
1626    if (importFromLibrary) {
1627       char name[MAXSTRING+1], path[MAXSTRING+1];
1628 
1629       if (SelectFromLibrary(TgLoadString(STID_SEL_JPEG_FILE_TO_IMPORT),
1630             "jpeg", name, path) == INVALID) {
1631          importingFile = FALSE;
1632          return;
1633       }
1634       sprintf(szJpegPath, "%s%c%s", path, DIR_SEP, name);
1635    } else if (SelectFileNameToImport(TgLoadString(Embed ?
1636          STID_SEL_JPEG_FILE_TO_IMPORT : STID_SEL_JPEG_FILE_TO_LINKTO),
1637          "jpeg", szJpegPath) == INVALID) {
1638       importingFile = FALSE;
1639       return;
1640    } else if (FileIsRemote(szJpegPath)) {
1641       int is_html=FALSE;
1642 
1643       if (!Embed) {
1644          sprintf(gszMsgBox, TgLoadString(STID_IMPORT_REM_FILE_EMBED_INSTEAD),
1645                "JPEG", "JPEG");
1646          if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) != MB_ID_YES) {
1647             importingFile = FALSE;
1648             return;
1649          }
1650          Embed = TRUE;
1651       }
1652       if (!DownloadRemoteFile(szJpegPath, NULL, NULL, &is_html, tmp_fname, NULL,
1653            0) || *tmp_fname == '\0') {
1654          importingFile = FALSE;
1655          return;
1656       }
1657       remote_file = TRUE;
1658    }
1659    if (!FinishImport(remote_file, tmp_fname, szJpegPath, IMPORTING_JPEG,
1660          &image_w, &image_h)) {
1661       if (remote_file) unlink(tmp_fname);
1662       importingFile = FALSE;
1663       return;
1664    }
1665    if (!Embed) {
1666       topObj->detail.xpm->real_type = XPM_JPEG;
1667       topObj->detail.xpm->linked_jpeg = TRUE;
1668       topObj->detail.xpm->filename = UtilStrDup(short_name ? rest : szJpegPath);
1669    }
1670    if (!importFromLibrary && !remote_file) SetCurImportDir(szJpegPath);
1671 
1672    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_JPEG_SIZE_FILE_IMPORTED),
1673          image_w, image_h, (short_name ? rest : szJpegPath));
1674    Msg(gszMsgBox);
1675 
1676    if (remote_file) unlink(tmp_fname);
1677    importingFile = FALSE;
1678 }
1679 
ImportGIFFile()1680 void ImportGIFFile()
1681 {
1682    char file_name[MAXPATHLENGTH+1], *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
1683    char szGifPath[MAXPATHLENGTH+1];
1684    int rc, short_name=FALSE, image_w=0, image_h=0, remote_file=FALSE;
1685    XEvent ev;
1686 
1687    MakeQuiescent();
1688 
1689    importingFile = TRUE;
1690    *szGifPath = *tmp_fname = *file_name = '\0';
1691    if (importFromLibrary) {
1692       char name[MAXSTRING+1], path[MAXSTRING+1];
1693 
1694       if (SelectFromLibrary(TgLoadString(STID_SEL_GIF_FILE_TO_IMPORT),
1695             "gif", name, path) == INVALID) {
1696          importingFile = FALSE;
1697          return;
1698       }
1699       sprintf(szGifPath, "%s%c%s", path, DIR_SEP, name);
1700    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_GIF_FILE_TO_IMPORT),
1701          "gif", szGifPath) == INVALID) {
1702       importingFile = FALSE;
1703       return;
1704    } else if (FileIsRemote(szGifPath)) {
1705       int is_html=FALSE;
1706 
1707       if (!DownloadRemoteFile(szGifPath, NULL, NULL, &is_html, tmp_fname, NULL,
1708            0) || *tmp_fname == '\0') {
1709          importingFile = FALSE;
1710          return;
1711       }
1712       remote_file = TRUE;
1713    }
1714    XSync(mainDisplay, False);
1715    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
1716       ExposeEventHandler(&ev, TRUE);
1717    }
1718    SetWatchCursor(drawWindow);
1719    SetWatchCursor(mainWindow);
1720    SaveStatusStrings();
1721    if (fullTrueColorMode && HasZlibSupport()) {
1722       struct ObjRec *obj_ptr=NULL;
1723       struct XPmRec *xpm_ptr=NULL;
1724       char ppm6_fname[MAXPATHLENGTH+1];
1725       char deflated_fname[MAXPATHLENGTH+1];
1726 
1727       rc = ConvertGifToPpm6((remote_file ? tmp_fname : szGifPath),
1728             ppm6_fname, sizeof(ppm6_fname));
1729       if (rc) {
1730          ResetPngHeaderInfo(&gPngHeaderInfo);
1731          if (PngFileGetTransColorInit(&gPngHeaderInfo,
1732                (remote_file ? tmp_fname : szGifPath)) &&
1733                PngFileGetTransColor(&gPngHeaderInfo)) {
1734          }
1735          obj_ptr = CreatePpmTrueObjFromFile(ppm6_fname);
1736       }
1737       if (obj_ptr != NULL &&
1738             MkTempFile(deflated_fname, sizeof(deflated_fname), tmpDir,
1739             TOOL_NAME) != NULL && DeflateFile(ppm6_fname, deflated_fname)) {
1740          /* nothing to do here */
1741       } else {
1742          unlink(ppm6_fname);
1743          if (obj_ptr != NULL) FreeObj(obj_ptr);
1744          RestoreStatusStrings();
1745          SetDefaultCursor(mainWindow);
1746          ShowCursor();
1747          if (remote_file) unlink(tmp_fname);
1748          importingFile = FALSE;
1749          return;
1750       }
1751       unlink(ppm6_fname);
1752       xpm_ptr = obj_ptr->detail.xpm;
1753       xpm_ptr->real_type = PPM_TRUE;
1754       xpm_ptr->ppm_data_compress = PPM_DATA_DEFLATED;
1755       xpm_ptr->ppm_data = ReadFileIntoBuf(deflated_fname,
1756             &xpm_ptr->ppm_data_size);
1757       xpm_ptr->ppm_mask_data = NULL;
1758       xpm_ptr->ppm_mask_size = 0;
1759       if (gPngHeaderInfo.valid && gPngHeaderInfo.trans_color_pixel_found) {
1760          xpm_ptr->has_transparent_color = TRUE;
1761          xpm_ptr->transparent_color[0] = gPngHeaderInfo.trans_color_pixel_red;
1762          xpm_ptr->transparent_color[1] = gPngHeaderInfo.trans_color_pixel_green;
1763          xpm_ptr->transparent_color[2] = gPngHeaderInfo.trans_color_pixel_blue;
1764       }
1765       unlink(deflated_fname);
1766 
1767       RestoreStatusStrings();
1768       SetDefaultCursor(mainWindow);
1769       ShowCursor();
1770       if (obj_ptr == NULL) {
1771          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_GIVEN_GIF),
1772                (short_name ? rest : szGifPath));
1773          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1774          if (remote_file) unlink(tmp_fname);
1775          importingFile = FALSE;
1776          return;
1777       }
1778       AddObj(NULL, topObj, obj_ptr);
1779       PlaceTopObj(obj_ptr, NULL, NULL);
1780 
1781       SelectTopObj();
1782       RecordNewObjCmd();
1783       SetFileModified(TRUE);
1784       justDupped = FALSE;
1785 
1786       if (!importFromLibrary && !remote_file) {
1787          SetCurImportDir(szGifPath);
1788       }
1789       sprintf(gszMsgBox, TgLoadString(STID_GIVEN_GIF_SIZE_FILE_IMPORTED),
1790             xpm_ptr->image_w, xpm_ptr->image_h,
1791             (short_name ? rest : szGifPath));
1792       Msg(gszMsgBox);
1793 
1794       return;
1795    }
1796    *file_name = '\0';
1797    rc = ConvertGifToXpm((remote_file ? tmp_fname : szGifPath), file_name,
1798          sizeof(file_name));
1799    RestoreStatusStrings();
1800    SetDefaultCursor(mainWindow);
1801    ShowCursor();
1802    if (!rc) {
1803       if (remote_file) unlink(tmp_fname);
1804       importingFile = FALSE;
1805       return;
1806    }
1807    if (remote_file) {
1808       short_name = FALSE;
1809    } else {
1810       if ((short_name=IsPrefix(bootDir, szGifPath, &rest))) ++rest;
1811    }
1812    if (!ImportGivenXPixmapFile(FALSE, NULL, file_name, INVALID, INVALID,
1813          &image_w, &image_h)) {
1814       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_GIVEN_GIF),
1815             (short_name ? rest : szGifPath));
1816       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1817       unlink(file_name);
1818       if (remote_file) unlink(tmp_fname);
1819       importingFile = FALSE;
1820       return;
1821    }
1822    unlink(file_name);
1823 
1824    if (!importFromLibrary && !remote_file) SetCurImportDir(szGifPath);
1825 
1826    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_GIF_SIZE_FILE_IMPORTED),
1827          image_w, image_h, (short_name ? rest : szGifPath));
1828    Msg(gszMsgBox);
1829 
1830    if (remote_file) unlink(tmp_fname);
1831    importingFile = FALSE;
1832 }
1833 
ConvertPbmToXbm(pszPbmPath,pszXbmPath,xbm_path_sz)1834 int ConvertPbmToXbm(pszPbmPath, pszXbmPath, xbm_path_sz)
1835    char *pszPbmPath, *pszXbmPath;
1836    int xbm_path_sz;
1837 {
1838    FILE *pFile=NULL, *pPipe=NULL;
1839    char *pszCmd=NULL, szBuf[MAXSTRING];
1840    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;;
1841 
1842    InitGifToXpm();
1843    if (MkTempFile(pszXbmPath, xbm_path_sz, tmpDir, TOOL_NAME) == NULL) {
1844       return FALSE;
1845    }
1846    pszCmd = (char*)malloc(
1847          (strlen(pbmToXbmCmd)+strlen(pszPbmPath)+10)*sizeof(char));
1848    if (pszCmd == NULL) {
1849       FailAllocMessage();
1850       return FALSE;
1851    }
1852    sprintf(pszCmd, pbmToXbmCmd, pszPbmPath);
1853    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
1854       free(pszCmd);
1855       return FALSE;
1856    }
1857    if ((pFile=fopen(pszXbmPath,"w")) == NULL) {
1858       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
1859             pszXbmPath);
1860       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1861       free(pszCmd);
1862       return FALSE;
1863    }
1864    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
1865          pszCmd);
1866    SetStringStatus(gszMsgBox);
1867    XSync(mainDisplay, False);
1868    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
1869       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
1870       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1871       free(pszCmd);
1872       fclose(pFile);
1873       unlink(pszXbmPath);
1874       return FALSE;
1875    }
1876    if (!watch_cursor) {
1877       SetWatchCursor(drawWindow);
1878       SetWatchCursor(mainWindow);
1879    }
1880    writeFileFailed = FALSE;
1881    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
1882       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
1883          writeFileFailed = TRUE;
1884          break;
1885       }
1886    }
1887    pclose(pPipe);
1888    if (!watch_cursor) {
1889       SetDefaultCursor(mainWindow);
1890       ShowCursor();
1891    }
1892    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
1893    free(pszCmd);
1894    fclose(pFile);
1895    if (writeFileFailed) {
1896       FailToWriteFileMessage(pszXbmPath);
1897       unlink(pszXbmPath);
1898       return FALSE;
1899    }
1900    return TRUE;
1901 }
1902 
ImportPBMFile()1903 void ImportPBMFile()
1904 {
1905    char file_name[MAXPATHLENGTH+1], *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
1906    char szPbmPath[MAXPATHLENGTH+1];
1907    int rc, short_name=FALSE, image_w=0, image_h=0, remote_file=FALSE;
1908    XEvent ev;
1909 
1910    MakeQuiescent();
1911 
1912    importingFile = TRUE;
1913    *szPbmPath = *tmp_fname = '\0';
1914    if (importFromLibrary) {
1915       char name[MAXSTRING+1], path[MAXSTRING+1];
1916 
1917       if (SelectFromLibrary(TgLoadString(STID_SEL_PBM_FILE_TO_IMPORT),
1918             "pbm", name, path) == INVALID) {
1919          importingFile = FALSE;
1920          return;
1921       }
1922       sprintf(szPbmPath, "%s%c%s", path, DIR_SEP, name);
1923    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_PBM_FILE_TO_IMPORT),
1924          "pbm", szPbmPath) == INVALID) {
1925       importingFile = FALSE;
1926       return;
1927    } else if (FileIsRemote(szPbmPath)) {
1928       int is_html=FALSE;
1929 
1930       if (!DownloadRemoteFile(szPbmPath, NULL, NULL, &is_html, tmp_fname, NULL,
1931            0) || *tmp_fname == '\0') {
1932          importingFile = FALSE;
1933          return;
1934       }
1935       remote_file = TRUE;
1936    }
1937    XSync(mainDisplay, False);
1938    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
1939       ExposeEventHandler(&ev, TRUE);
1940    }
1941    SetWatchCursor(drawWindow);
1942    SetWatchCursor(mainWindow);
1943    SaveStatusStrings();
1944    rc = ConvertPbmToXbm((remote_file ? tmp_fname : szPbmPath), file_name,
1945          sizeof(file_name));
1946    RestoreStatusStrings();
1947    SetDefaultCursor(mainWindow);
1948    ShowCursor();
1949    if (!rc) {
1950       if (remote_file) unlink(tmp_fname);
1951       importingFile = FALSE;
1952       return;
1953    }
1954    if (remote_file) {
1955       short_name = FALSE;
1956    } else {
1957       if ((short_name=IsPrefix(bootDir, szPbmPath, &rest))) ++rest;
1958    }
1959    if (!ImportGivenXBitmapFile(FALSE, NULL, file_name, INVALID, INVALID,
1960          &image_w, &image_h)) {
1961       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_GIVEN_PBM),
1962             (short_name ? rest : szPbmPath));
1963       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1964       unlink(file_name);
1965       if (remote_file) unlink(tmp_fname);
1966       importingFile = FALSE;
1967       return;
1968    }
1969    unlink(file_name);
1970 
1971    if (!importFromLibrary && !remote_file) SetCurImportDir(szPbmPath);
1972 
1973    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_PBM_SIZE_FILE_IMPORTED),
1974          image_w, image_h, (short_name ? rest : szPbmPath));
1975    Msg(gszMsgBox);
1976 
1977    if (remote_file) unlink(tmp_fname);
1978    importingFile = FALSE;
1979 }
1980 
ConvertPgmToXpm(pszPgmPath,pszXpmPath,xpm_path_sz)1981 int ConvertPgmToXpm(pszPgmPath, pszXpmPath, xpm_path_sz)
1982    char *pszPgmPath, *pszXpmPath;
1983    int xpm_path_sz;
1984 {
1985    FILE *pFile=NULL, *pPipe=NULL;
1986    char *pszCmd=NULL, szBuf[MAXSTRING];
1987    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
1988 
1989    InitGifToXpm();
1990    if (MkTempFile(pszXpmPath, xpm_path_sz, tmpDir, TOOL_NAME) == NULL) {
1991       return FALSE;
1992    }
1993    pszCmd = (char*)malloc(
1994          (strlen(pgmToXpmCmd)+strlen(pszPgmPath)+10)*sizeof(char));
1995    if (pszCmd == NULL) {
1996       FailAllocMessage();
1997       return FALSE;
1998    }
1999    sprintf(pszCmd, pgmToXpmCmd, pszPgmPath);
2000    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
2001       free(pszCmd);
2002       return FALSE;
2003    }
2004    if ((pFile=fopen(pszXpmPath,"w")) == NULL) {
2005       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
2006             pszXpmPath);
2007       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2008       free(pszCmd);
2009       return FALSE;
2010    }
2011    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
2012          pszCmd);
2013    SetStringStatus(gszMsgBox);
2014    XSync(mainDisplay, False);
2015    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
2016       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
2017       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2018       free(pszCmd);
2019       fclose(pFile);
2020       unlink(pszXpmPath);
2021       return FALSE;
2022    }
2023    if (!watch_cursor) {
2024       SetWatchCursor(drawWindow);
2025       SetWatchCursor(mainWindow);
2026    }
2027    writeFileFailed = FALSE;
2028    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
2029       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
2030          writeFileFailed = TRUE;
2031          break;
2032       }
2033    }
2034    pclose(pPipe);
2035    if (!watch_cursor) {
2036       SetDefaultCursor(mainWindow);
2037       ShowCursor();
2038    }
2039    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
2040    free(pszCmd);
2041    fclose(pFile);
2042    if (writeFileFailed) {
2043       FailToWriteFileMessage(pszXpmPath);
2044       unlink(pszXpmPath);
2045       return FALSE;
2046    }
2047    return TRUE;
2048 }
2049 
ImportPGMFile()2050 void ImportPGMFile()
2051 {
2052    char file_name[MAXPATHLENGTH+1], *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
2053    char szPgmPath[MAXPATHLENGTH+1];
2054    int rc, short_name=FALSE, image_w=0, image_h=0, remote_file=FALSE;
2055    XEvent ev;
2056 
2057    MakeQuiescent();
2058 
2059    importingFile = TRUE;
2060    *szPgmPath = *tmp_fname = '\0';
2061    if (importFromLibrary) {
2062       char name[MAXSTRING+1], path[MAXSTRING+1];
2063 
2064       if (SelectFromLibrary(TgLoadString(STID_SEL_PGM_FILE_TO_IMPORT),
2065             "pgm", name, path) == INVALID) {
2066          importingFile = FALSE;
2067          return;
2068       }
2069       sprintf(szPgmPath, "%s%c%s", path, DIR_SEP, name);
2070    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_PGM_FILE_TO_IMPORT),
2071          "pgm", szPgmPath) == INVALID) {
2072       importingFile = FALSE;
2073       return;
2074    } else if (FileIsRemote(szPgmPath)) {
2075       int is_html=FALSE;
2076 
2077       if (!DownloadRemoteFile(szPgmPath, NULL, NULL, &is_html, tmp_fname, NULL,
2078            0) || *tmp_fname == '\0') {
2079          importingFile = FALSE;
2080          return;
2081       }
2082       remote_file = TRUE;
2083    }
2084    XSync(mainDisplay, False);
2085    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
2086       ExposeEventHandler(&ev, TRUE);
2087    }
2088    SetWatchCursor(drawWindow);
2089    SetWatchCursor(mainWindow);
2090    SaveStatusStrings();
2091    rc = ConvertPgmToXpm((remote_file ? tmp_fname : szPgmPath), file_name,
2092          sizeof(file_name));
2093    RestoreStatusStrings();
2094    SetDefaultCursor(mainWindow);
2095    ShowCursor();
2096    if (!rc) {
2097       if (remote_file) unlink(tmp_fname);
2098       importingFile = FALSE;
2099       return;
2100    }
2101    if (remote_file) {
2102       short_name = FALSE;
2103    } else {
2104       if ((short_name=IsPrefix(bootDir, szPgmPath, &rest))) ++rest;
2105    }
2106    if (!ImportGivenXPixmapFile(FALSE, NULL, file_name, INVALID, INVALID,
2107          &image_w, &image_h)) {
2108       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_GIVEN_PGM),
2109             (short_name ? rest : szPgmPath));
2110       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2111       unlink(file_name);
2112       if (remote_file) unlink(tmp_fname);
2113       importingFile = FALSE;
2114       return;
2115    }
2116    unlink(file_name);
2117 
2118    if (!importFromLibrary && !remote_file) SetCurImportDir(szPgmPath);
2119 
2120    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_PGM_SIZE_FILE_IMPORTED),
2121          image_w, image_h, (short_name ? rest : szPgmPath));
2122    Msg(gszMsgBox);
2123 
2124    if (remote_file) unlink(tmp_fname);
2125    importingFile = FALSE;
2126 }
2127 
ConvertPpmToXpm(pszPpmPath,pszXpmPath,xpm_path_sz)2128 int ConvertPpmToXpm(pszPpmPath, pszXpmPath, xpm_path_sz)
2129    char *pszPpmPath, *pszXpmPath;
2130    int xpm_path_sz;
2131 {
2132    FILE *pFile=NULL, *pPipe=NULL;
2133    char *pszCmd=NULL, szBuf[MAXSTRING];
2134    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
2135 
2136    InitGifToXpm();
2137    if (MkTempFile(pszXpmPath, xpm_path_sz, tmpDir, TOOL_NAME) == NULL) {
2138       return FALSE;
2139    }
2140    pszCmd = (char*)malloc(
2141          (strlen(ppmToXpmCmd)+strlen(pszPpmPath)+10)*sizeof(char));
2142    if (pszCmd == NULL) {
2143       FailAllocMessage();
2144       return FALSE;
2145    }
2146    sprintf(pszCmd, ppmToXpmCmd, pszPpmPath);
2147    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
2148       free(pszCmd);
2149       return FALSE;
2150    }
2151    if ((pFile=fopen(pszXpmPath,"w")) == NULL) {
2152       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
2153             pszXpmPath);
2154       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2155       free(pszCmd);
2156       return FALSE;
2157    }
2158    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
2159          pszCmd);
2160    SetStringStatus(gszMsgBox);
2161    XSync(mainDisplay, False);
2162    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
2163       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
2164       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2165       free(pszCmd);
2166       fclose(pFile);
2167       unlink(pszXpmPath);
2168       return FALSE;
2169    }
2170    if (!watch_cursor) {
2171       SetWatchCursor(drawWindow);
2172       SetWatchCursor(mainWindow);
2173    }
2174    writeFileFailed = FALSE;
2175    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
2176       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
2177          writeFileFailed = TRUE;
2178          break;
2179       }
2180    }
2181    pclose(pPipe);
2182    if (!watch_cursor) {
2183       SetDefaultCursor(mainWindow);
2184       ShowCursor();
2185    }
2186    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
2187    free(pszCmd);
2188    fclose(pFile);
2189    if (writeFileFailed) {
2190       FailToWriteFileMessage(pszXpmPath);
2191       unlink(pszXpmPath);
2192       return FALSE;
2193    }
2194    return TRUE;
2195 }
2196 
ImportPPMFile()2197 void ImportPPMFile()
2198 {
2199    char *rest=NULL, tmp_fname[MAXPATHLENGTH+1];
2200    char szPpmPath[MAXPATHLENGTH+1];
2201    int short_name=FALSE, image_w=0, image_h=0, remote_file=FALSE;
2202 
2203    MakeQuiescent();
2204 
2205    importingFile = TRUE;
2206    *szPpmPath = *tmp_fname = '\0';
2207    if (importFromLibrary) {
2208       char name[MAXSTRING+1], path[MAXSTRING+1];
2209 
2210       if (SelectFromLibrary(TgLoadString(STID_SEL_PPM_FILE_TO_IMPORT),
2211             "ppm", name, path) == INVALID) {
2212          importingFile = FALSE;
2213          return;
2214       }
2215       sprintf(szPpmPath, "%s%c%s", path, DIR_SEP, name);
2216    } else if (SelectFileNameToImport(TgLoadString(STID_SEL_PPM_FILE_TO_IMPORT),
2217          "ppm", szPpmPath) == INVALID) {
2218       importingFile = FALSE;
2219       return;
2220    } else if (FileIsRemote(szPpmPath)) {
2221       int is_html=FALSE;
2222 
2223       if (!DownloadRemoteFile(szPpmPath, NULL, NULL, &is_html, tmp_fname, NULL,
2224            0) || *tmp_fname == '\0') {
2225          importingFile = FALSE;
2226          return;
2227       }
2228       remote_file = TRUE;
2229    }
2230    if (!FinishImport(remote_file, tmp_fname, szPpmPath, IMPORTING_PPM, &image_w,
2231          &image_h)) {
2232       if (remote_file) unlink(tmp_fname);
2233       importingFile = FALSE;
2234       return;
2235    }
2236    if (!importFromLibrary && !remote_file) SetCurImportDir(szPpmPath);
2237 
2238    sprintf(gszMsgBox, TgLoadString(STID_GIVEN_PPM_SIZE_FILE_IMPORTED),
2239          image_w, image_h, (short_name ? rest : szPpmPath));
2240    Msg(gszMsgBox);
2241 
2242    if (remote_file) unlink(tmp_fname);
2243    importingFile = FALSE;
2244 }
2245 
ImportFilterListing(pnEntries)2246 DspList *ImportFilterListing(pnEntries)
2247    int *pnEntries;
2248 {
2249    int i;
2250    struct ImportInfoRec *pii=topImportInfo;
2251    DspList *pdl, *dsp_ptr;
2252 
2253    if (gnMaxImportFilters == 0) return NULL;
2254    pdl = (DspList*)malloc(gnMaxImportFilters*sizeof(DspList));
2255    if (pdl == NULL) {
2256       FailAllocMessage();
2257       return NULL;
2258    }
2259    for (i=0, dsp_ptr=pdl; i < gnMaxImportFilters; i++, dsp_ptr++) {
2260       sprintf(gszMsgBox, "%s (%s)", pii->name, pii->ext);
2261       UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), gszMsgBox);
2262       UtilStrCpyN(dsp_ptr->pathstr, sizeof(dsp_ptr->pathstr), pii->cmd);
2263       dsp_ptr->directory = FALSE;
2264       dsp_ptr->next = ((i == gnMaxImportFilters-1) ? NULL : (&dsp_ptr[1]));
2265       pii = pii->next;
2266    }
2267    if (pnEntries != NULL) *pnEntries = gnMaxImportFilters;
2268    return pdl;
2269 }
2270 
2271 static
ChooseAnImportFilter(top_str,entries,num_entries)2272 int ChooseAnImportFilter(top_str, entries, num_entries)
2273    char *top_str, **entries;
2274    int num_entries;
2275 {
2276    char win_name[128];
2277    int selected_index=INVALID;
2278 
2279    ResetNamesInfo();
2280    NamesSetTitle(top_str);
2281    NamesAddButton(TgLoadCachedString(CSTID_OK), BUTTON_OK);
2282    NamesAddButton(TgLoadCachedString(CSTID_CANCEL), BUTTON_CANCEL);
2283    NamesSetEntries(NULL, entries, num_entries, NULL, TRUE, INVALID, 0);
2284    NamesSetStyle(NAMES_COMPLEX_SELECT_NAME, NAMES_LOOP_ONCE);
2285    sprintf(win_name, "%s - %s", TOOL_NAME, top_str);
2286    if (Names(win_name, &selected_index, NULL, 0, NULL) == BUTTON_OK) {
2287       return selected_index;
2288    }
2289    return INVALID;
2290 }
2291 
2292 static
SelectAnImportFilter(pszSelected)2293 int SelectAnImportFilter(pszSelected)
2294    char *pszSelected;
2295 {
2296    int num_entries=0, index=0;
2297    DspList *dsp_ptr=ImportFilterListing(&num_entries);
2298    char **entries;
2299 
2300    if (pszSelected != NULL) *pszSelected = '\0';
2301    if (dsp_ptr == NULL) {
2302       sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_ANY_IMP_FLTR_SPEC),
2303             TOOL_NAME, "MaxImportFilters", TOOL_NAME, "ImportFilter#");
2304       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2305       return INVALID;
2306    }
2307    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
2308    if (entries == NULL) {
2309       free(dsp_ptr);
2310       return INVALID;
2311    }
2312    if ((index=ChooseAnImportFilter(TgLoadString(STID_SEL_AN_IMPORT_FILTER),
2313          entries, num_entries)) == INVALID) {
2314       if (pszSelected != NULL) *pszSelected = '\0';
2315    } else {
2316       if (pszSelected != NULL) {
2317          strcpy(pszSelected, entries[index]);
2318       }
2319    }
2320    free(*entries);
2321    free(entries);
2322    free(dsp_ptr);
2323    return index;
2324 }
2325 
2326 static
ConvertAnyToXpm(pii,pszAnyPath,pszXpmPath,xpm_path_sz)2327 int ConvertAnyToXpm(pii, pszAnyPath, pszXpmPath, xpm_path_sz)
2328    struct ImportInfoRec *pii;
2329    char *pszAnyPath, *pszXpmPath;
2330    int xpm_path_sz;
2331 {
2332    FILE *pFile=NULL, *pPipe=NULL;
2333    char *pszCmd=NULL, szBuf[MAXSTRING];
2334    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
2335 
2336    if (MkTempFile(pszXpmPath, xpm_path_sz, tmpDir, TOOL_NAME) == NULL) {
2337       return FALSE;
2338    }
2339    pszCmd =
2340          (char*)malloc((strlen(pii->cmd)+strlen(pszAnyPath)+10)*sizeof(char));
2341    if (pszCmd == NULL) {
2342       FailAllocMessage();
2343       return FALSE;
2344    }
2345    sprintf(pszCmd, pii->cmd, pszAnyPath);
2346    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
2347       free(pszCmd);
2348       return FALSE;
2349    }
2350    if ((pFile=fopen(pszXpmPath,"w")) == NULL) {
2351       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
2352             pszXpmPath);
2353       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2354       free(pszCmd);
2355       return FALSE;
2356    }
2357    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
2358          pszCmd);
2359    SetStringStatus(gszMsgBox);
2360    XSync(mainDisplay, False);
2361    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
2362       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
2363       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2364       free(pszCmd);
2365       fclose(pFile);
2366       unlink(pszXpmPath);
2367       return FALSE;
2368    }
2369    if (!watch_cursor) {
2370       SetWatchCursor(drawWindow);
2371       SetWatchCursor(mainWindow);
2372    }
2373    writeFileFailed = FALSE;
2374    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
2375       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
2376          writeFileFailed = TRUE;
2377          break;
2378       }
2379    }
2380    pclose(pPipe);
2381    if (!watch_cursor) {
2382       SetDefaultCursor(mainWindow);
2383       ShowCursor();
2384    }
2385    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
2386    free(pszCmd);
2387    fclose(pFile);
2388    if (writeFileFailed) {
2389       FailToWriteFileMessage(pszXpmPath);
2390       unlink(pszXpmPath);
2391       return FALSE;
2392    }
2393    return TRUE;
2394 }
2395 
2396 static int gnEnableFailedImportMsgBox=TRUE;
2397 
GetEnableFailedImportMsgBox()2398 int GetEnableFailedImportMsgBox()
2399 {
2400    return gnEnableFailedImportMsgBox;
2401 }
2402 
SetEnableFailedImportMsgBox(int enable)2403 int SetEnableFailedImportMsgBox(int enable)
2404 {
2405    int saved_enable_failed_import_msgbox=gnEnableFailedImportMsgBox;
2406 
2407    gnEnableFailedImportMsgBox = enable;
2408    return saved_enable_failed_import_msgbox;
2409 }
2410 
2411 static
ReadFourBytes(psz_path,magic_buf,magic_buf_sz)2412 int ReadFourBytes(psz_path, magic_buf, magic_buf_sz)
2413    char *psz_path, *magic_buf;
2414    int magic_buf_sz;
2415 {
2416    FILE *fp=fopen(psz_path, "r");
2417    int rc=TRUE;
2418 
2419    if (fp == NULL) {
2420       return FailToOpenMessage(psz_path, "r", NULL);
2421    }
2422    if (fread(magic_buf, sizeof(char), magic_buf_sz, fp) != magic_buf_sz) {
2423       rc = FALSE;
2424    }
2425    fclose(fp);
2426 
2427    return rc;
2428 }
2429 
2430 static
DoImportOtherFile(pii,psz_path)2431 int DoImportOtherFile(pii, psz_path)
2432    struct ImportInfoRec *pii;
2433    char *psz_path;
2434 {
2435    char szTop[MAXSTRING+1], tmp_fname[MAXPATHLENGTH+1];
2436    char szOtherPath[MAXPATHLENGTH+1], szXpmPath[MAXPATHLENGTH+1], magic_buf[4];
2437    int rc, ncolors, chars_per_pixel, *pixels=NULL, short_name=FALSE;
2438    int first_pixel_is_bg, image_w, image_h, w, h, remote_file=FALSE, ppm=FALSE;
2439    Pixmap pixmap=None, bitmap=None;
2440    XImage *image=NULL, *bitmap_image=NULL;
2441    char *color_char=NULL, **color_str=NULL, *xpm_data=NULL, *rest=NULL;
2442    struct ObjRec *obj_ptr=NULL;
2443    XEvent ev;
2444 
2445    importingFile = TRUE;
2446    *szOtherPath = *tmp_fname = '\0';
2447    if (psz_path != NULL) {
2448       UtilStrCpyN(szOtherPath, sizeof(szOtherPath), psz_path);
2449    } else {
2450       MakeQuiescent();
2451 
2452       sprintf(szTop, TgLoadString(STID_SEL_A_TYPE_FILE_TO_IMPORT), pii->name);
2453       if (importFromLibrary) {
2454          char name[MAXSTRING+1], dir_name[MAXSTRING+1];
2455 
2456          if (SelectFromLibrary(szTop, pii->ext, name, dir_name) == INVALID) {
2457             importingFile = FALSE;
2458             return FALSE;
2459          }
2460          sprintf(szOtherPath, "%s%c%s", dir_name, DIR_SEP, name);
2461       } else if (SelectFileNameToImport(szTop, pii->ext, szOtherPath) ==
2462             INVALID) {
2463          importingFile = FALSE;
2464          return FALSE;
2465       } else if (FileIsRemote(szOtherPath)) {
2466          int is_html=FALSE;
2467 
2468          if (!DownloadRemoteFile(szOtherPath, NULL, NULL, &is_html, tmp_fname,
2469                NULL, 0) || *tmp_fname == '\0') {
2470             importingFile = FALSE;
2471             return FALSE;
2472          }
2473          remote_file = TRUE;
2474       }
2475       XSync(mainDisplay, False);
2476       if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
2477          ExposeEventHandler(&ev, TRUE);
2478       }
2479    }
2480    SetWatchCursor(drawWindow);
2481    SetWatchCursor(mainWindow);
2482    SaveStatusStrings();
2483    rc = ConvertAnyToXpm(pii, (remote_file ? tmp_fname : szOtherPath), szXpmPath,
2484          sizeof(szXpmPath));
2485    RestoreStatusStrings();
2486    SetDefaultCursor(mainWindow);
2487    ShowCursor();
2488    if (!rc) return FALSE;
2489 
2490    if (ReadFourBytes(szXpmPath, magic_buf, sizeof(magic_buf))) {
2491       if (magic_buf[0] == 'P' && (magic_buf[1] == '3' ||
2492             magic_buf[1] == '5' || magic_buf[1] == '6')) {
2493          ppm = TRUE;
2494       }
2495       SetWatchCursor(drawWindow);
2496       SetWatchCursor(mainWindow);
2497       if (ppm) {
2498          char deflated_fname[MAXPATHLENGTH+1];
2499 
2500          ResetPngHeaderInfo(&gPngHeaderInfo);
2501          obj_ptr = CreatePpmTrueObjFromFile(szXpmPath);
2502          if (obj_ptr != NULL &&
2503                MkTempFile(deflated_fname, sizeof(deflated_fname), tmpDir,
2504                TOOL_NAME) != NULL &&
2505                DeflateFile(szXpmPath, deflated_fname)) {
2506             struct XPmRec *xpm_ptr=obj_ptr->detail.xpm;
2507 
2508             xpm_ptr->real_type = PPM_TRUE;
2509             xpm_ptr->ppm_data_compress = PPM_DATA_DEFLATED;
2510             xpm_ptr->ppm_data = ReadFileIntoBuf(deflated_fname,
2511                   &xpm_ptr->ppm_data_size);
2512             xpm_ptr->ppm_mask_data = NULL;
2513             xpm_ptr->ppm_mask_size = 0;
2514             unlink(deflated_fname);
2515 
2516             rc = BitmapSuccess;
2517          } else {
2518             rc = BitmapFileInvalid;
2519          }
2520       } else {
2521          rc = MyReadPixmapFile(szXpmPath, &image_w, &image_h, &w, &h, &pixmap,
2522                &image, &bitmap, &bitmap_image, &ncolors, &chars_per_pixel,
2523                &first_pixel_is_bg, &color_char, &color_str, &pixels, &xpm_data);
2524       }
2525       SetDefaultCursor(mainWindow);
2526       ShowCursor();
2527    } else {
2528       rc = BitmapFileInvalid;
2529    }
2530    if (remote_file) {
2531       short_name = FALSE;
2532    } else {
2533       if ((short_name=IsPrefix(bootDir, szOtherPath, &rest))) ++rest;
2534    }
2535    if (rc != BitmapSuccess) {
2536       sprintf(gszMsgBox, TgLoadString(STID_CANT_IMPORT_GIVEN_TYPE_FILE),
2537             pii->name, (short_name ? rest : szOtherPath));
2538       if (gnEnableFailedImportMsgBox) {
2539          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2540       }
2541       unlink(szXpmPath);
2542       if (remote_file) unlink(tmp_fname);
2543       importingFile = FALSE;
2544       return FALSE;
2545    }
2546    unlink(szXpmPath);
2547    if (!ppm) {
2548       obj_ptr = CreateXPmObj(image_w, image_h, w, h, pixmap, image, bitmap,
2549             bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg, color_char,
2550             color_str, pixels, xpm_data);
2551    }
2552    AddObj(NULL, topObj, obj_ptr);
2553 
2554    if (psz_path == NULL) {
2555       PlaceTopObj(obj_ptr, NULL, NULL);
2556 
2557       SelectTopObj();
2558       RecordNewObjCmd();
2559       SetFileModified(TRUE);
2560       justDupped = FALSE;
2561       if (!importFromLibrary && !remote_file) SetCurImportDir(szOtherPath);
2562 
2563       sprintf(gszMsgBox, TgLoadString(STID_GIVEN_TYPE_SIZE_FILE_IMPORTED),
2564             pii->name, image_w, image_h, (short_name ? rest : szOtherPath));
2565       Msg(gszMsgBox);
2566    }
2567    if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
2568       RedrawColorWindow();
2569    }
2570    if (remote_file) unlink(tmp_fname);
2571    importingFile = FALSE;
2572 
2573    return TRUE;
2574 }
2575 
ImportOtherFile()2576 void ImportOtherFile()
2577 {
2578    int i, index;
2579    struct ImportInfoRec *pii;
2580    XEvent ev;
2581 
2582    if ((index=SelectAnImportFilter(NULL)) == INVALID) {
2583       return;
2584    }
2585    for (i=0, pii=topImportInfo; i < index && pii != NULL; i++, pii=pii->next) {
2586    }
2587    if (pii == NULL) return;
2588 
2589    XSync(mainDisplay, False);
2590    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
2591       ExposeEventHandler(&ev, TRUE);
2592    }
2593    DoImportOtherFile(pii, NULL);
2594 }
2595 
ImportOtherFileType(pszName)2596 void ImportOtherFileType(pszName)
2597    char *pszName;
2598 {
2599    char *paren_ptr=(pszName == NULL ? NULL : strchr(pszName, ')'));
2600    struct ImportInfoRec *pii;
2601 
2602    if (paren_ptr == NULL) {
2603       sprintf(gszMsgBox, TgLoadString(STID_INVALID_FMT_IN_SHORTCUT_SPEC),
2604             "ImportOtherFileType", (pszName == NULL ? "" : pszName));
2605       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2606       return;
2607    }
2608    *paren_ptr = '\0';
2609    for (pii=topImportInfo; pii != NULL; pii=pii->next) {
2610       if (strcmp(pii->name, pszName) == 0) {
2611          break;
2612       }
2613    }
2614    if (pii == NULL) {
2615       sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_NAMED_IMP_FLTR), pszName);
2616       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2617       return;
2618    }
2619    DoImportOtherFile(pii, NULL);
2620 }
2621 
ImportSpecifiedFileType(psz_path,psz_filter)2622 int ImportSpecifiedFileType(psz_path, psz_filter)
2623    char *psz_path, *psz_filter;
2624 {
2625    struct ImportInfoRec *pii=NULL;
2626 
2627    for (pii=topImportInfo; pii != NULL; pii=pii->next) {
2628       if (strcmp(pii->name, psz_filter) == 0) {
2629          break;
2630       }
2631    }
2632    if (pii == NULL) {
2633       sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_NAMED_IMP_FLTR),
2634             psz_filter);
2635       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2636       return FALSE;
2637    }
2638    return DoImportOtherFile(pii, psz_path);
2639 }
2640 
ConvertOtherToXpm(pszFile,pszFormat,pszXpmPath,xpm_path_sz)2641 int ConvertOtherToXpm(pszFile, pszFormat, pszXpmPath, xpm_path_sz)
2642    char *pszFile, *pszFormat, *pszXpmPath;
2643    int xpm_path_sz;
2644 {
2645    struct ImportInfoRec *pii=NULL;
2646 
2647    for (pii=topImportInfo; pii != NULL; pii=pii->next) {
2648       if (strcmp(pii->name, pszFormat) == 0) {
2649          break;
2650       }
2651    }
2652    if (pii == NULL) {
2653       sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_NAMED_IMP_FLTR),
2654             pszFormat);
2655       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2656       return FALSE;
2657    }
2658    return ConvertAnyToXpm(pii, pszFile, pszXpmPath, xpm_path_sz);
2659 }
2660 
ImportGIFToXPixmapDeck()2661 void ImportGIFToXPixmapDeck()
2662 {
2663    char szTop[MAXSTRING+1], cmd[MAXSTRING<<1], part_fname_format[MAXSTRING];
2664    char gif_fname[MAXPATHLENGTH+1], name[MAXSTRING], tmp_fname[MAXPATHLENGTH+1];
2665    int i=0, import_other_index=0, rc=0, placed=FALSE;
2666    int ltx=0, lty=0, rbx=0, rby=0, remote_file=FALSE, real_remote_file=FALSE;
2667    XEvent ev;
2668    struct ImportInfoRec ii;
2669    struct ObjRec *saved_top_obj=topObj, *saved_bot_obj=botObj;
2670    struct AttrRec *exec_attr=NULL;
2671 
2672    MakeQuiescent();
2673 
2674    memset(&ii, 0, sizeof(struct ImportInfoRec));
2675 
2676    /* pick an animated GIF file */
2677    sprintf(szTop, TgLoadString(STID_SEL_ANIM_GIF_FILE_TO_IMPORT));
2678    importingFile = TRUE;
2679    *gif_fname = *tmp_fname = '\0';
2680    if (importFromLibrary) {
2681       char name[MAXSTRING+1], dir_name[MAXSTRING+1];
2682 
2683       if (SelectFromLibrary(szTop, "gif", name, dir_name) == INVALID) {
2684          importingFile = FALSE;
2685          return;
2686       }
2687       sprintf(gif_fname, "%s%c%s", dir_name, DIR_SEP, name);
2688    } else if (SelectFileNameToImport(szTop, "gif", gif_fname) == INVALID) {
2689       importingFile = FALSE;
2690       return;
2691    } else if (FileIsRemote(gif_fname)) {
2692       int is_html=FALSE;
2693 
2694       if (!DownloadRemoteFile(gif_fname, NULL, NULL, &is_html, tmp_fname, NULL,
2695             0) || *tmp_fname == '\0') {
2696          importingFile = FALSE;
2697          return;
2698       }
2699       remote_file = real_remote_file = TRUE;
2700    }
2701    XSync(mainDisplay, False);
2702    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
2703       ExposeEventHandler(&ev, TRUE);
2704    }
2705    if (!remote_file) {
2706       if (MkTempFile(tmp_fname, sizeof(tmp_fname), tmpDir, TOOL_NAME) == NULL) {
2707          importingFile = FALSE;
2708          return;
2709       }
2710       if (UtilCopyFile(gif_fname, tmp_fname) != TG_REMOTE_STATUS_OK) {
2711          sprintf(gszMsgBox, TgLoadString(STID_CANT_CREATE_NAMED_TMP_FILE),
2712                tmp_fname);
2713          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2714          importingFile = FALSE;
2715          return;
2716       }
2717       remote_file = TRUE;
2718    }
2719    /* explode the animated GIF file into parts */
2720    InitGifToXpm();
2721    sprintf(cmd, "cd %s; %s %s", tmpDir, gifAnimExplodeCmd,
2722          (remote_file ? tmp_fname : gif_fname));
2723    SetWatchCursor(drawWindow);
2724    SetWatchCursor(mainWindow);
2725    rc = ExecuteCmd(cmd, FALSE);
2726    SetDefaultCursor(mainWindow);
2727    ShowCursor();
2728    if (!rc) {
2729       sprintf(gszMsgBox, TgLoadString(STID_CANT_EXEC_CMD_IMPORT_ANIM_GIF), cmd);
2730       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2731       if (remote_file) unlink(tmp_fname);
2732       importingFile = FALSE;
2733       return;
2734    }
2735    /* determine how many to import */
2736    strcpy(name, tmp_fname);
2737    /* pick a GIF import filter */
2738    if (gnMaxImportFilters > 0) {
2739       struct ImportInfoRec *pii=NULL;
2740 
2741       switch (MsgBox(TgLoadString(STID_Q_LIKE_TO_USE_AN_IMP_FLTR_GIF),
2742             TOOL_NAME, YNC_MB)) {
2743       case MB_ID_YES:
2744          if ((import_other_index=SelectAnImportFilter(NULL)) == INVALID) {
2745             if (remote_file) unlink(tmp_fname);
2746             importingFile = FALSE;
2747             return;
2748          }
2749          for (i=0, pii=topImportInfo; i < import_other_index && pii != NULL;
2750                i++, pii=pii->next) {
2751          }
2752          if (pii == NULL) {
2753             if (remote_file) unlink(tmp_fname);
2754             importingFile = FALSE;
2755             return;
2756          }
2757 
2758          XSync(mainDisplay, False);
2759          if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
2760             ExposeEventHandler(&ev, TRUE);
2761          }
2762          memcpy(&ii, pii, sizeof(struct ImportInfoRec));
2763          ii.name = NULL;
2764          ii.next = NULL;
2765          break;
2766       case MB_ID_NO:
2767          ii.ext = "gif";
2768          ii.cmd = gifToXpmCmd;
2769          break;
2770       case MB_ID_CANCEL:
2771          if (remote_file) unlink(tmp_fname);
2772          importingFile = FALSE;
2773          return;
2774       }
2775    } else {
2776       ii.ext = "gif";
2777       ii.cmd = gifToXpmCmd;
2778    }
2779    curPage->top = curPage->bot = topObj = botObj = NULL;
2780    /* import the GIF parts */
2781    strcpy(part_fname_format, "%s.%1d");
2782    SaveStatusStrings();
2783    SetWatchCursor(drawWindow);
2784    SetWatchCursor(mainWindow);
2785    for (i=0; ; i++) {
2786       char part_fname[MAXPATHLENGTH], xpm_fname[MAXPATHLENGTH];
2787       char *color_char=NULL, **color_str=NULL, *xpm_data=NULL;
2788       int image_w=0, image_h=0, w=0, h=0, ncolors=0, chars_per_pixel=0;
2789       int first_pixel_is_bg=FALSE, *pixels=NULL;
2790       Pixmap pixmap=None, bitmap=None;
2791       XImage *image=NULL, *bitmap_image=NULL;
2792       struct ObjRec *obj_ptr=NULL;
2793       struct SelRec *sel_ptr=NULL;
2794 
2795       *xpm_fname = '\0';
2796       sprintf(part_fname, part_fname_format, name, i);
2797       if (i == 0) {
2798          if (!UtilPathExists(part_fname)) {
2799             strcpy(part_fname_format, "%s.%03d");
2800             sprintf(part_fname, part_fname_format, name, i);
2801             if (!UtilPathExists(part_fname)) {
2802                if (i == 0 &&
2803                      !FindProgramInPath(gifAnimExplodeCmd, NULL, TRUE)) {
2804                   char *psz=strchr(gifAnimExplodeCmd, ' ');
2805 
2806                   if (psz != NULL) *psz = '\0';
2807                   sprintf(gszMsgBox,
2808                         TgLoadString(STID_CANT_IMP_ANIM_GIF_DIR_OR_PATH),
2809                         part_fname, tmpDir, gifAnimExplodeCmd);
2810                   if (psz != NULL) *psz = ' ';
2811                   MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2812                } else {
2813                   sprintf(gszMsgBox,
2814                         TgLoadString(STID_CANT_IMP_ANIM_GIF_TMP_DIR),
2815                         part_fname, tmpDir);
2816                   MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2817                }
2818                break;
2819             }
2820          }
2821       } else if (!UtilPathExists(part_fname)) {
2822          /* got all the GIF parts */
2823          break;
2824       }
2825       rc = ConvertAnyToXpm(&ii, part_fname, xpm_fname, sizeof(xpm_fname));
2826       if (!rc) {
2827          unlink(part_fname);
2828          break;
2829       }
2830       unlink(part_fname);
2831       rc = MyReadPixmapFile(xpm_fname, &image_w, &image_h, &w, &h, &pixmap,
2832             &image, &bitmap, &bitmap_image, &ncolors, &chars_per_pixel,
2833             &first_pixel_is_bg, &color_char, &color_str, &pixels, &xpm_data);
2834       if (rc != BitmapSuccess) {
2835          sprintf(gszMsgBox, TgLoadString(STID_CANT_IMP_GIVEN_ANIM_GIF),
2836                part_fname);
2837          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2838          unlink(xpm_fname);
2839          break;
2840       }
2841       unlink(xpm_fname);
2842       obj_ptr = CreateXPmObj(image_w, image_h, w, h, pixmap, image, bitmap,
2843             bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg,
2844             color_char, color_str, pixels, xpm_data);
2845       AddObj(botObj, NULL, obj_ptr);
2846       if (!placed) {
2847          PlaceTopObj(obj_ptr, NULL, NULL);
2848          placed = TRUE;
2849          ltx = obj_ptr->bbox.ltx; lty = obj_ptr->bbox.lty;
2850          rbx = obj_ptr->bbox.rbx; rby = obj_ptr->bbox.rby;
2851       } else {
2852          MoveObj(obj_ptr, ltx-obj_ptr->bbox.ltx, lty-obj_ptr->bbox.lty);
2853          if (obj_ptr->bbox.rbx > rbx) rbx = obj_ptr->bbox.rbx;
2854          if (obj_ptr->bbox.rby > rby) rby = obj_ptr->bbox.rby;
2855       }
2856       DrawObj(drawWindow, obj_ptr);
2857       sel_ptr = SelectThisObject(obj_ptr);
2858       AddSel(botSel, NULL, sel_ptr);
2859    }
2860    SetDefaultCursor(mainWindow);
2861    ShowCursor();
2862    if (remote_file) unlink(tmp_fname);
2863 
2864    if (topObj != NULL) {
2865       curPage->top = topObj;
2866    } else {
2867       curPage->top = topObj = saved_top_obj;
2868    }
2869    if (botObj != NULL) {
2870       botObj->next = saved_top_obj;
2871    }
2872    if (saved_top_obj != NULL) {
2873       saved_top_obj->prev = botObj;
2874    }
2875    if (saved_bot_obj != NULL) {
2876       curPage->bot = botObj = saved_bot_obj;
2877    } else {
2878       curPage->bot = botObj;
2879    }
2880    if (topSel == NULL) {
2881       RestoreStatusStrings();
2882       return;
2883    }
2884    UpdSelBBox();
2885    if (topSel == botSel) {
2886       sprintf(gszMsgBox, TgLoadString(STID_ONLY_ONE_GIF_COMP_EXTRACTED),
2887             gif_fname);
2888       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2889       RecordNewObjCmd();
2890    } else {
2891       int saved_history_depth=historyDepth;
2892 
2893       HighLightForward();
2894 
2895       historyDepth = 0;
2896       GroupSelObj(TRUE, TRUE, TRUE);
2897       historyDepth = saved_history_depth;
2898 
2899       HighLightReverse();
2900       exec_attr = AddAttrByNameAndValue(topObj, "exec=",
2901             "flip_deck(infinite,10,linear)");
2902       exec_attr->shown = FALSE;
2903       MoveObj(exec_attr->obj, ltx, lty);
2904       UpdTextBBox(exec_attr->obj);
2905       AdjObjBBox(topObj);
2906       UpdSelBBox();
2907       RecordNewObjCmd();
2908    }
2909    RedrawAnArea(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
2910          rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1));
2911    SetFileModified(TRUE);
2912    HighLightForward();
2913    if (!importFromLibrary && !real_remote_file) {
2914       SetCurImportDir(gif_fname);
2915    }
2916    if (colorLayers && needToRedrawColorWindow) {
2917       RedrawColorWindow();
2918    }
2919    importingFile = FALSE;
2920    if (exec_attr != NULL) {
2921       sprintf(gszMsgBox, TgLoadString(STID_ANIMATING_GIVEN), gif_fname);
2922       TwoLineMsg(gszMsgBox, TgLoadString(STID_PRESS_ESC_TO_STOP));
2923       DoExecLoop(topObj, exec_attr);
2924       Msg(TgLoadString(STID_GIF_ANIMATION_STOPPED));
2925    }
2926    RestoreStatusStrings();
2927 }
2928 
2929 /* ----------------------- Browse Functions ----------------------- */
2930 
2931 static int origBrowseX=0, origBrowseY=0, maxBrowseX=0, maxBrowseY=0;
2932 static int curBrowseX=0, curBrowseY=0, curBrowseRowHeight=0;
2933 static int savedDirNameLen=0;
2934 static int browseObjType=INVALID;
2935 static char savedDirName[MAXPATHLENGTH+1];
2936 
2937 static
InitBrowse(pszDir,ObjType)2938 void InitBrowse(pszDir, ObjType)
2939    char *pszDir;
2940    int ObjType;
2941 {
2942    browseObjType = ObjType;
2943    if (ObjType == OBJ_ICON) {
2944       curBrowseX = origBrowseX = thumbnailX;
2945       maxBrowseX = paperWidth - curBrowseX;
2946       curBrowseY = origBrowseY = thumbnailY;
2947       maxBrowseY = paperHeight - curBrowseY;
2948       curBrowseRowHeight = 0;
2949    } else {
2950       curBrowseX = origBrowseX = drawOrigX+ABS_SIZE(EIGHTH_INCH);
2951       maxBrowseX = drawOrigX+drawWinW;
2952       curBrowseY = origBrowseY = drawOrigY+ABS_SIZE(EIGHTH_INCH);
2953       maxBrowseY = drawOrigY+drawWinH;
2954       curBrowseRowHeight = 0;
2955    }
2956    if (pszDir != NULL) {
2957       strcpy(savedDirName, pszDir);
2958       savedDirNameLen = strlen(savedDirName);
2959    }
2960 }
2961 
2962 static
CheckExecInterrupt()2963 int CheckExecInterrupt()
2964 {
2965    XEvent ev;
2966 
2967    while (XCheckMaskEvent(mainDisplay, StructureNotifyMask, &ev)) {
2968       if (iconWindowShown) {
2969          if ((ev.xany.window == iconBaseWindow && ev.type == UnmapNotify) ||
2970                (ev.xany.window == mainWindow && ev.type == MapNotify)) {
2971             XPutBackEvent(mainDisplay, &ev);
2972             return TRUE;
2973          }
2974       } else if ((ev.xany.window == iconBaseWindow && ev.type == MapNotify) ||
2975             (ev.xany.window == mainWindow && ev.type == UnmapNotify)) {
2976          XPutBackEvent(mainDisplay, &ev);
2977          return TRUE;
2978       } else if (ev.type == ConfigureNotify) {
2979          Reconfigure(FALSE);
2980          if (browseObjType != OBJ_ICON) {
2981             maxBrowseX = drawOrigX+drawWinW;
2982          }
2983       }
2984    }
2985    while (XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
2986       if (iconWindowShown) {
2987          if (ev.xany.window == mainWindow && ev.type == VisibilityNotify &&
2988                ev.xvisibility.state == VisibilityUnobscured) {
2989             XPutBackEvent(mainDisplay, &ev);
2990             return TRUE;
2991          } else {
2992             ExposeEventHandler(&ev, TRUE);
2993          }
2994       } else {
2995          if (ev.xany.window == iconBaseWindow && ev.type == VisibilityNotify &&
2996                ev.xvisibility.state == VisibilityUnobscured) {
2997             XPutBackEvent(mainDisplay, &ev);
2998             return TRUE;
2999          } else {
3000             ExposeEventHandler(&ev, TRUE);
3001          }
3002       }
3003    }
3004    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
3005       ExposeEventHandler(&ev, TRUE);
3006       while (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) ;
3007    }
3008    if (ESCPressed() || CheckInterrupt(TRUE)) {
3009       return TRUE;
3010    }
3011    while (XCheckMaskEvent(mainDisplay, ButtonPressMask|KeyPressMask, &ev)) ;
3012    return FALSE;
3013 }
3014 
3015 static
ImportForThumbnails(fname,p_bbox_w,p_bbox_h)3016 struct ObjRec *ImportForThumbnails(fname, p_bbox_w, p_bbox_h)
3017    char *fname;
3018    int *p_bbox_w, *p_bbox_h;
3019 {
3020    struct ObjRec *imported_obj=NULL;
3021    struct ObjRec *saved_top_obj=topObj, *saved_bot_obj=botObj;
3022    struct BBRec saved_draw_win_bbox;
3023 
3024    (*p_bbox_w) = (*p_bbox_h) = 0;
3025    curPage->top = curPage->bot = topObj = botObj = NULL;
3026 
3027    importingFile = TRUE;
3028    pastingFile = TRUE;
3029    memcpy(&saved_draw_win_bbox, &drawWinBBox, sizeof(struct BBRec));
3030    drawWinBBox.ltx = drawWinBBox.rbx = drawOrigX-128;
3031    drawWinBBox.lty = drawWinBBox.rby = drawOrigY-128;
3032    if (ImportGivenFile(fname, FALSE, FALSE) == TRUE) {
3033       if (numObjSelected > 0) {
3034          struct BoxRec *box_ptr=NULL;
3035          struct ObjRec *obj_ptr=NULL;
3036          int changed=FALSE;
3037 
3038          for (obj_ptr=topObj; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
3039             if (obj_ptr->type == OBJ_SYM) {
3040                obj_ptr->type = OBJ_GROUP;
3041                AdjObjBBox(obj_ptr);
3042                changed = TRUE;
3043             }
3044          }
3045          if (changed) {
3046             UpdSelBBox();
3047          }
3048          CreateBoxObj(selLtX, selLtY, selRbX, selRbY, TRUE);
3049          box_ptr = topObj->detail.b;
3050          box_ptr->fill = NONEPAT;
3051          box_ptr->pen = NONEPAT;
3052          RemoveAllSel();
3053          SelAllObj(FALSE, FALSE);
3054          GroupSelObj(FALSE, FALSE, FALSE);
3055 
3056          imported_obj = topObj;
3057          *p_bbox_w = imported_obj->bbox.rbx-imported_obj->bbox.ltx;
3058          *p_bbox_h = imported_obj->bbox.rby-imported_obj->bbox.lty;
3059 #ifdef _TGIF_DBG /* debug, do not translate */
3060          TgAssert(topObj == botObj,
3061                "too many objects found in ImportForThumbnails()", NULL);
3062 #endif /* _TGIF_DBG */
3063          RemoveAllSel();
3064       }
3065       MakeQuiescent();
3066    }
3067    memcpy(&drawWinBBox, &saved_draw_win_bbox, sizeof(struct BBRec));
3068    importingFile = FALSE;
3069    pastingFile = FALSE;
3070 
3071    curPage->top = topObj = saved_top_obj;
3072    curPage->bot = botObj = saved_bot_obj;
3073 
3074    return imported_obj;
3075 }
3076 
3077 static
RegenerateImageFile(pszPath)3078 int RegenerateImageFile(pszPath)
3079    char *pszPath;
3080 {
3081    int saved_colordump=colorDump, saved_wheretoprint=whereToPrint;
3082 
3083    *gszImageProcXPmFile = '\0';
3084    gnConvolving = FALSE;
3085 
3086    colorDump = TRUE;
3087    whereToPrint = XBM_FILE;
3088    gnInImageProc = TRUE;
3089 
3090    SetWatchCursor(drawWindow);
3091    SetWatchCursor(mainWindow);
3092    DumpXBitmapFile(gnInImageProc, FALSE, TRUE);
3093    SetDefaultCursor(mainWindow);
3094    ShowCursor();
3095 
3096    gnInImageProc = FALSE;
3097    whereToPrint = saved_wheretoprint;
3098    colorDump = saved_colordump;
3099    if (*gszImageProcXPmFile == '\0') return FALSE;
3100    strcpy(pszPath, gszImageProcXPmFile);
3101    return TRUE;
3102 }
3103 
3104 static
MyRegenerateImage(obj_ptr)3105 struct ObjRec *MyRegenerateImage(obj_ptr)
3106    struct ObjRec *obj_ptr;
3107 {
3108    int image_w=0, image_h=0, w=0, h=0, short_name=FALSE, rc=INVALID;
3109    int ltx=0, lty=0;
3110    int ncolors=0, chars_per_pixel=0, first_pixel_is_bg=0, *pixels=NULL;
3111    char *color_char=NULL, **color_str=NULL, *xpm_data=NULL, *rest=NULL;
3112    char szPath[MAXPATHLENGTH+1];
3113    Pixmap pixmap=None, bitmap=None;
3114    XImage *image=NULL, *bitmap_image=NULL;
3115    struct ObjRec *new_obj=NULL;
3116 
3117    ltx = obj_ptr->obbox.ltx;
3118    lty = obj_ptr->obbox.lty;
3119 
3120    AddObj(NULL, topObj, obj_ptr);
3121    PushPageInfo();
3122 
3123    rc = RegenerateImageFile(szPath);
3124 
3125    DelAllObj();
3126    PopPageInfo();
3127    if (!rc) {
3128       return NULL;
3129    }
3130    SetWatchCursor(drawWindow);
3131    SetWatchCursor(mainWindow);
3132    rc = MyReadPixmapFile(szPath, &image_w, &image_h, &w, &h, &pixmap,
3133          &image, &bitmap, &bitmap_image, &ncolors, &chars_per_pixel,
3134          &first_pixel_is_bg, &color_char, &color_str, &pixels, &xpm_data);
3135    SetDefaultCursor(mainWindow);
3136    ShowCursor();
3137 
3138    if ((short_name=IsPrefix(bootDir, szPath, &rest))) ++rest;
3139    if (rc != BitmapSuccess) {
3140       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_XPM_FILE),
3141             (short_name ? rest : szPath));
3142       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3143       unlink(szPath);
3144       return NULL;
3145    }
3146    unlink(szPath);
3147    new_obj = CreateXPmObj(image_w, image_h, w, h, pixmap, image, bitmap,
3148          bitmap_image, ncolors, chars_per_pixel, first_pixel_is_bg, color_char,
3149          color_str, pixels, xpm_data);
3150    MoveObj(new_obj, ltx-new_obj->obbox.ltx, lty-new_obj->obbox.lty);
3151    new_obj->tmp_parent = NULL;
3152    SetFileModified(TRUE);
3153    justDupped = FALSE;
3154 
3155    return new_obj;
3156 }
3157 
3158 static
GenerateXpmThumbnail(imported_obj)3159 struct ObjRec *GenerateXpmThumbnail(imported_obj)
3160    struct ObjRec *imported_obj;
3161 {
3162    struct ObjRec *saved_top_obj=topObj, *saved_bot_obj=botObj, *new_obj=NULL;
3163    double orig_aspect_ratio=(double)0, aspect_ratio=(double)0;
3164    struct BBRec saved_draw_win_bbox;
3165    int bbox_w=(imported_obj->bbox.rbx-imported_obj->bbox.ltx);
3166    int bbox_h=(imported_obj->bbox.rby-imported_obj->bbox.lty);
3167    int final_w=0, final_h=0;
3168 
3169    curPage->top = curPage->bot = topObj = botObj = NULL;
3170 
3171    aspect_ratio = (((double)thumbnailW)/((double)thumbnailH));
3172    orig_aspect_ratio = (((double)bbox_w)/((double)bbox_h));
3173 
3174    memcpy(&saved_draw_win_bbox, &drawWinBBox, sizeof(struct BBRec));
3175    drawWinBBox.ltx = drawWinBBox.rbx = drawOrigX-128;
3176    drawWinBBox.lty = drawWinBBox.rby = drawOrigY-128;
3177 
3178    if (bbox_w <= thumbnailW && bbox_h <= thumbnailH) {
3179       /* do not scale */
3180       final_w = thumbnailW;
3181       final_h = thumbnailH;
3182    } else {
3183       double scale=(double)0;
3184 
3185       if (orig_aspect_ratio > aspect_ratio) {
3186          final_w = thumbnailW;
3187          final_h = round(((double)thumbnailW) / orig_aspect_ratio);
3188          scale = ((double)bbox_w) / ((double)thumbnailW);
3189       } else {
3190          final_h = thumbnailH;
3191          final_w = round(((double)thumbnailH) * orig_aspect_ratio);
3192          scale = ((double)bbox_h) / ((double)thumbnailH);
3193       }
3194       ScaleObjLikeScaleEverything(imported_obj, scale, FALSE);
3195    }
3196    new_obj = MyRegenerateImage(imported_obj); /* imported_obj is freed here */
3197    if (new_obj != NULL) {
3198       struct BoxRec *box_ptr=NULL;
3199       int obj_w=(new_obj->obbox.rbx-new_obj->obbox.ltx);
3200       int obj_h=(new_obj->obbox.rby-new_obj->obbox.lty);
3201       int new_ltx=((thumbnailW+(thumbnailPadding<<1)-obj_w)>>1);
3202       int new_lty=((thumbnailH+(thumbnailPadding<<1)-obj_h)>>1);
3203 
3204       CreateBoxObj(0, 0, thumbnailW+(thumbnailPadding<<1),
3205             thumbnailH+(thumbnailPadding<<1), TRUE);
3206       box_ptr = topObj->detail.b;
3207       box_ptr->fill = BACKPAT;
3208       box_ptr->pen = SOLIDPAT;
3209       box_ptr->dash = 0;
3210       box_ptr->width = 0;
3211       strcpy(box_ptr->width_spec, "0");
3212       AdjObjBBox(topObj);
3213       MoveObj(new_obj, new_ltx-new_obj->obbox.ltx, new_lty-new_obj->obbox.lty);
3214 
3215       AddObj(NULL, topObj, new_obj);
3216       SelAllObj(FALSE, FALSE);
3217       GroupSelObj(FALSE, FALSE, FALSE);
3218 
3219       RemoveAllSel();
3220       new_obj = topObj;
3221       UnlinkObj(topObj);
3222    }
3223    memcpy(&drawWinBBox, &saved_draw_win_bbox, sizeof(struct BBRec));
3224 
3225    curPage->top = topObj = saved_top_obj;
3226    curPage->bot = botObj = saved_bot_obj;
3227 
3228    return new_obj;
3229 }
3230 
3231 static
BrowseDir(DirName,ExtStr,ExtStrLen,ObjType,pii)3232 int BrowseDir(DirName, ExtStr, ExtStrLen, ObjType, pii)
3233    char *DirName, *ExtStr;
3234    int ExtStrLen, ObjType;
3235    struct ImportInfoRec *pii;
3236    /* returns TRUE if interrupted */
3237 {
3238    char name[MAXPATHLENGTH+1];
3239    int interrupted=FALSE, esave_len=0;
3240 #ifdef VMS
3241    int len;
3242 #endif /* VMS */
3243    DIR *dirp;
3244    DIR_ENTRY *d;
3245 
3246    if ((dirp=opendir(DirName)) == NULL) return interrupted;
3247    esave_len = strlen("EmergencySave.");
3248    if (pii == NULL) {
3249       sprintf(gszMsgBox, TgLoadString(STID_BROWSING_DIR_FOR_TYPE_FILES),
3250             DirName, ExtStr);
3251    } else {
3252       sprintf(gszMsgBox, TgLoadString(STID_BROWSING_DIR_FOR_TYPE_FILES),
3253             DirName, pii->name);
3254    }
3255    Msg(gszMsgBox);
3256    while ((d=readdir(dirp)) != NULL) {
3257       int ncolors, chars_per_pixel, first_pixel_is_bg, * pixels;
3258       int image_w=0, image_h=0, w=0, h=0, x_hot, y_hot, rc=INVALID;
3259       unsigned int tmp_w, tmp_h;
3260       char *color_char, **color_str, *xpm_data=NULL;
3261       Pixmap bitmap=None, pixmap=None;
3262       XImage *image=NULL, *bitmap_image=NULL;
3263       struct ObjRec *imported_obj=NULL;
3264 
3265       if (CheckExecInterrupt()) {
3266          interrupted = TRUE;
3267          break;
3268       }
3269       if (!ExtensionMatch(ExtStr, d->d_name)) {
3270          continue;
3271       }
3272       if (strncmp(d->d_name, "EmergencySave.", esave_len) == 0) {
3273          continue;
3274       }
3275       sprintf(name, "%s%c%s", DirName, DIR_SEP, d->d_name);
3276       sprintf(gszMsgBox, TgLoadCachedString(CSTID_OPENING_GIVEN),
3277             &name[savedDirNameLen+1]);
3278       SetStringStatus(gszMsgBox);
3279       if (ObjType == OBJ_XBM) {
3280          rc = XReadBitmapFile(mainDisplay, mainWindow, name, &tmp_w, &tmp_h,
3281                &bitmap, &x_hot, &y_hot);
3282          w = (int)tmp_w; h = (int)tmp_h;
3283       } else if (ObjType == OBJ_XPM) {
3284          if (pii != NULL) {
3285             char szXpmPath[MAXPATHLENGTH+1];
3286 
3287             SaveStatusStrings();
3288             rc = ConvertAnyToXpm(pii, name, szXpmPath, sizeof(szXpmPath));
3289             RestoreStatusStrings();
3290             if (!rc) continue;
3291             rc = MyReadPixmapFile(szXpmPath, &image_w, &image_h, &w, &h,
3292                   &pixmap, &image, &bitmap, &bitmap_image, &ncolors,
3293                   &chars_per_pixel, &first_pixel_is_bg, &color_char,
3294                   &color_str, &pixels, &xpm_data);
3295             unlink(szXpmPath);
3296          } else {
3297             rc = MyReadPixmapFile(name, &image_w, &image_h, &w, &h,
3298                   &pixmap, &image, &bitmap, &bitmap_image, &ncolors,
3299                   &chars_per_pixel, &first_pixel_is_bg, &color_char,
3300                   &color_str, &pixels, &xpm_data);
3301          }
3302       } else if (ObjType == OBJ_ICON) {
3303          imported_obj = ImportForThumbnails(name, (int*)&tmp_w, (int*)&tmp_h);
3304          if (imported_obj == NULL) continue;
3305          rc = BitmapSuccess;
3306          w = (int)tmp_w;
3307          h = (int)tmp_h;
3308       } else {
3309       }
3310       if (rc == BitmapSuccess) {
3311          struct ObjRec *obj_ptr=NULL;
3312          int short_name;
3313          char *rest=NULL;
3314 
3315          if (ObjType == OBJ_XBM) {
3316             obj_ptr = CreateXBmObj(w, h, w, h, bitmap, NULL);
3317          } else if (ObjType == OBJ_XPM) {
3318             obj_ptr = CreateXPmObj(image_w, image_h, w, h, pixmap, image,
3319                   bitmap, bitmap_image, ncolors, chars_per_pixel,
3320                   first_pixel_is_bg, color_char, color_str, pixels, xpm_data);
3321          } else if (ObjType == OBJ_ICON) {
3322             obj_ptr = GenerateXpmThumbnail(imported_obj);
3323             /* imported_obj is deleted in GenerateXpmThumbnail() */
3324             if (obj_ptr == NULL) {
3325                continue;
3326             }
3327             w = (int)(obj_ptr->obbox.rbx-obj_ptr->obbox.ltx);
3328             h = (int)(obj_ptr->obbox.rby-obj_ptr->obbox.lty);
3329          } else {
3330          }
3331          if ((short_name=IsPrefix((curDirIsLocal ? curDir : curLocalDir), name,
3332                &rest))) {
3333             ++rest;
3334          }
3335          if (ObjType == OBJ_ICON) {
3336             if (imported_obj->type != OBJ_TEXT) {
3337                AddAttrByNameAndValue(obj_ptr, "href=",
3338                      (short_name ? rest : name));
3339             }
3340          } else {
3341             AddAttrByNameAndValue(obj_ptr, "file_name=",
3342                   (short_name ? rest : name));
3343          }
3344          if (showFileNameOnBrowse && obj_ptr->fattr != NULL &&
3345                obj_ptr->fattr == obj_ptr->lattr) {
3346             struct AttrRec *attr_ptr=obj_ptr->fattr;
3347             int attr_h, attr_w, attr_ltx, attr_lty;
3348 
3349             attr_ptr->shown = TRUE;
3350             attr_ptr->nameshown = FALSE;
3351             UpdAttr(attr_ptr);
3352             AdjObjBBox(attr_ptr->obj);
3353             attr_w = attr_ptr->obj->obbox.rbx-attr_ptr->obj->obbox.ltx;
3354             attr_h = attr_ptr->obj->bbox.rby-attr_ptr->obj->bbox.lty;
3355             attr_ltx = ((obj_ptr->obbox.ltx+obj_ptr->obbox.rbx)>>1)-(attr_w>>1);
3356             attr_lty = obj_ptr->bbox.rby;
3357             MoveObj(attr_ptr->obj, attr_ltx-attr_ptr->obj->obbox.ltx,
3358                   attr_lty-attr_ptr->obj->obbox.lty);
3359             if (attr_w > w && ObjType != OBJ_ICON) w = attr_w;
3360             h += attr_h;
3361          }
3362          AdjObjBBox(obj_ptr);
3363          if (ObjType == OBJ_ICON) {
3364             if (curBrowseX+w > maxBrowseX-origBrowseX) {
3365                curBrowseX = origBrowseX;
3366                curBrowseY += curBrowseRowHeight+thumbnailYGap;
3367                while (curBrowseY > maxBrowseY) {
3368                   ForceScrollDown(TRUE);
3369                   maxBrowseY = drawOrigY+drawWinH;
3370                }
3371                curBrowseRowHeight = h;
3372             } else if (h > curBrowseRowHeight) {
3373                curBrowseRowHeight = h;
3374             }
3375          } else {
3376             if (curBrowseX+w > maxBrowseX) {
3377                curBrowseX = origBrowseX;
3378                curBrowseY += curBrowseRowHeight;
3379                while (curBrowseY > maxBrowseY) {
3380                   ForceScrollDown(TRUE);
3381                   maxBrowseY = drawOrigY+drawWinH;
3382                }
3383                curBrowseRowHeight = h;
3384             } else if (h > curBrowseRowHeight) {
3385                curBrowseRowHeight = h;
3386             }
3387          }
3388          obj_ptr->tmp_parent = NULL;
3389          AddObj(NULL, topObj, obj_ptr);
3390 
3391          MoveObj(topObj, curBrowseX-topObj->obbox.ltx,
3392                curBrowseY-topObj->obbox.lty);
3393          numRedrawBBox = 0;
3394          DrawObj(drawWindow, topObj);
3395          RecordNewObjCmd();
3396          SetFileModified(TRUE);
3397          justDupped = FALSE;
3398          XSync(mainDisplay, False);
3399          if (ObjType == OBJ_ICON) {
3400             curBrowseX += w + thumbnailXGap;
3401          } else {
3402             curBrowseX += w;
3403          }
3404       } else {
3405       }
3406    }
3407    closedir(dirp);
3408    if ((dirp=opendir(DirName)) == NULL) return interrupted;
3409    while (!interrupted && (d=readdir(dirp)) != NULL) {
3410       if (CheckExecInterrupt()) {
3411          interrupted = TRUE;
3412          break;
3413       }
3414 #ifdef VMS
3415       len = strlen(d->d_name);
3416       if (len > 4 && (strcmp(".dir", &d->d_name[len-4]) == 0)) {
3417          sprintf(name, "%s%c%s", DirName, DIR_SEP, d->d_name);
3418          if (BrowseDir(name, ExtStr, ExtStrLen, ObjType, pii)) {
3419             interrupted = TRUE;
3420             break;
3421          }
3422       }
3423 #endif /* VMS */
3424       if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
3425          struct stat stat_buf;
3426 
3427          sprintf(name, "%s%c%s", DirName, DIR_SEP, d->d_name);
3428          if (stat(name, &stat_buf) == 0 && (stat_buf.st_mode & S_IFDIR)) {
3429             int skip=FALSE;
3430 
3431 #ifndef _NO_LSTAT
3432             if (lstat(name, &stat_buf) == 0 &&
3433                   ((stat_buf.st_mode & S_IFLNK) == S_IFLNK)) {
3434                sprintf(gszMsgBox, TgLoadString(STID_SKIP_GIVEN_FILE_SYM_LINK),
3435                      &name[savedDirNameLen+1]);
3436                Msg(gszMsgBox);
3437                skip = TRUE;
3438             }
3439 #endif /* _NO_LSTAT */
3440             if (!interrupted && !skip &&
3441                   BrowseDir(name, ExtStr, ExtStrLen, ObjType, pii)) {
3442                interrupted = TRUE;
3443                break;
3444             }
3445          }
3446       }
3447    }
3448    closedir(dirp);
3449    return interrupted;
3450 }
3451 
3452 static
StartBrowse(DirName,ExtStr,ExtStrLen,ObjType,pii)3453 void StartBrowse(DirName, ExtStr, ExtStrLen, ObjType, pii)
3454    char *DirName, *ExtStr;
3455    int ExtStrLen, ObjType;
3456    struct ImportInfoRec *pii;
3457 {
3458    int saved_text_just=textJust;
3459 
3460    if (!CurFontCheck()) {
3461       MsgBox(TgLoadString(STID_CHECK_FONT_FAILED_FOR_BROWSE), TOOL_NAME,
3462             INFO_MB);
3463       return;
3464    }
3465    SetWatchCursor(drawWindow);
3466    SetWatchCursor(mainWindow);
3467    MakeQuiescent();
3468    SaveStatusStrings();
3469    InitBrowse(DirName, ObjType);
3470    StartCompositeCmd();
3471    ShowInterrupt(1);
3472    textJust = JUST_C;
3473    if (BrowseDir(DirName, ExtStr, ExtStrLen, ObjType, pii)) {
3474       Msg(TgLoadString(STID_USER_INTR));
3475    }
3476    textJust = saved_text_just;
3477    if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
3478       RedrawColorWindow();
3479    }
3480    HideInterrupt();
3481    EndCompositeCmd();
3482    RestoreStatusStrings();
3483    SetDefaultCursor(mainWindow);
3484    ShowCursor();
3485    XFlush(mainDisplay);
3486 }
3487 
CreateThumbnails()3488 void CreateThumbnails()
3489 {
3490    static char stszObjFileExt[20], stszGzObjFileExt[20];
3491    static char stszSymFileExt[20], stszPinFileExt[20];
3492    static int initialized=FALSE;
3493    char buf[MAXSTRING];
3494    int len=0;
3495 
3496    MakeQuiescent();
3497 
3498    if (firstCmd != NULL) {
3499       if (!OkToFlushUndoBuffer(
3500             TgLoadString(STID_CREATE_THUMBNAIL_CAUSE_FLUSH))) {
3501          SetCurChoice(curChoiceBeforeMakeQuiescent);
3502          return;
3503       }
3504    }
3505    if (!initialized) {
3506       sprintf(stszObjFileExt, ".%s", OBJ_FILE_EXT);
3507       sprintf(stszGzObjFileExt, ".%s.gz", OBJ_FILE_EXT);
3508       sprintf(stszSymFileExt, ".%s", SYM_FILE_EXT);
3509       sprintf(stszPinFileExt, ".%s", PIN_FILE_EXT);
3510       initialized = TRUE;
3511    }
3512    sprintf(buf, "%s;%s;%s;%s", stszObjFileExt, stszGzObjFileExt,
3513          stszSymFileExt, stszPinFileExt);
3514    len = strlen(buf);
3515    if (strcmp(OBJ_FILE_EXT,"obj") != 0) {
3516       strcat(buf, ";.obj");
3517    }
3518    strcat(buf, ";.obj.gz;.tgo;.tgo.gz");
3519    StartBrowse((curDirIsLocal ? curDir : curLocalDir), buf, strlen(buf),
3520          OBJ_ICON, NULL);
3521    CleanUpCmds();
3522 }
3523 
BrowseXBitmap()3524 void BrowseXBitmap()
3525 {
3526    StartBrowse((curDirIsLocal ? curDir : curLocalDir), XBM_FILE_EXT,
3527          strlen(XBM_FILE_EXT), OBJ_XBM, NULL);
3528 }
3529 
BrowseXPixmap()3530 void BrowseXPixmap()
3531 {
3532    StartBrowse((curDirIsLocal ? curDir : curLocalDir), XPM_FILE_EXT,
3533          strlen(XPM_FILE_EXT), OBJ_XPM, NULL);
3534 }
3535 
BrowseOther()3536 void BrowseOther()
3537 {
3538    int i, index;
3539    char *ext_str;
3540    struct ImportInfoRec *pii;
3541    XEvent ev;
3542 
3543    sprintf(gszMsgBox, TgLoadString(STID_WORKING_DIR_IS_GIVEN),
3544          (curDirIsLocal ? curDir : curLocalDir));
3545    SetStringStatus(gszMsgBox);
3546    if ((index=SelectAnImportFilter(NULL)) == INVALID) {
3547       return;
3548    }
3549    for (i=0, pii=topImportInfo; i < index && pii != NULL; i++, pii=pii->next) {
3550    }
3551    if (pii == NULL) return;
3552    XSync(mainDisplay, False);
3553    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
3554       ExposeEventHandler(&ev, TRUE);
3555    }
3556    if ((ext_str=SetUpExtStr((strlen(pii->ext)<<1)+3, pii->ext, "")) != NULL) {
3557       StartBrowse((curDirIsLocal ? curDir : curLocalDir), ext_str,
3558             strlen(pii->ext), OBJ_XPM, pii);
3559       free(ext_str);
3560    }
3561 }
3562 
BrowseOtherType(pszName)3563 void BrowseOtherType(pszName)
3564    char *pszName;
3565 {
3566    char *paren_ptr=(pszName == NULL ? NULL : strchr(pszName, ')')), *ext_str;
3567    struct ImportInfoRec *pii;
3568 
3569    if (paren_ptr == NULL) {
3570       sprintf(gszMsgBox, TgLoadString(STID_INVALID_FMT_IN_SHORTCUT_SPEC),
3571             "ImportOtherFileType", (pszName == NULL ? "" : pszName));
3572       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3573       return;
3574    }
3575    *paren_ptr = '\0';
3576    for (pii=topImportInfo; pii != NULL; pii=pii->next) {
3577       if (strcmp(pii->name, pszName) == 0) {
3578          break;
3579       }
3580    }
3581    if (pii == NULL) {
3582       sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_NAMED_IMP_FLTR), pszName);
3583       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3584       return;
3585    }
3586    if ((ext_str=SetUpExtStr((strlen(pii->ext)<<1)+3, pii->ext, "")) != NULL) {
3587       StartBrowse((curDirIsLocal ? curDir : curLocalDir), ext_str,
3588             strlen(pii->ext), OBJ_XPM, pii);
3589       free(ext_str);
3590    }
3591 }
3592 
3593 /* ----------------------- Screen Capture Functions ----------------------- */
3594 
3595 static
FlushAllRedrawEvents()3596 void FlushAllRedrawEvents()
3597 {
3598    XEvent ev;
3599 
3600    XFlush(mainDisplay);
3601    XSync(mainDisplay, False);
3602    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev) ||
3603          XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
3604       ExposeEventHandler(&ev, TRUE);
3605    }
3606 }
3607 
3608 static int hideDuringCapture=FALSE;
3609 
3610 static XImage *capturedImage=NULL;
3611 static Colormap *installedColormaps=NULL;
3612 static int numInstalledColormaps=0;
3613 static int capturedWidth=0, capturedHeight=0;
3614 
3615 static
CaptureCleanUp()3616 void CaptureCleanUp()
3617 {
3618    if (capturedImage != NULL) XDestroyImage(capturedImage);
3619    if (installedColormaps != NULL) XFree(installedColormaps);
3620    capturedImage = NULL;
3621    installedColormaps = NULL;
3622    numInstalledColormaps = 0;
3623    capturedWidth = capturedHeight = 0;
3624 }
3625 
3626 static
EnumPopupMenuProcToHide(menu_index,win,pUserData)3627 int EnumPopupMenuProcToHide(menu_index, win, pUserData)
3628    int menu_index;
3629    Window win;
3630    void *pUserData;
3631    /* return FALSE will stop the enumeration */
3632 {
3633    XUnmapWindow(mainDisplay, win);
3634    return TRUE;
3635 }
3636 
3637 static
BeginHideDuringCapture()3638 void BeginHideDuringCapture()
3639 {
3640    CaptureCleanUp();
3641 
3642    MakeQuiescent();
3643    if (hideDuringCapture) {
3644       EnumPopupMenuWindow(EnumPopupMenuProcToHide, NULL);
3645       XUnmapWindow(mainDisplay, mainWindow);
3646       FlushAllRedrawEvents();
3647    } else {
3648       SetWatchCursor(drawWindow);
3649       SetWatchCursor(mainWindow);
3650    }
3651    XBell(mainDisplay, 0);
3652 }
3653 
3654 static
EnumPopupMenuProcToShow(menu_index,win,pUserData)3655 int EnumPopupMenuProcToShow(menu_index, win, pUserData)
3656    int menu_index;
3657    Window win;
3658    void *pUserData;
3659    /* return FALSE will stop the enumeration */
3660 {
3661    XMapWindow(mainDisplay, win);
3662    return TRUE;
3663 }
3664 
3665 static
EnumPopupMenuProcToUpdate(menu_index,win,pUserData)3666 int EnumPopupMenuProcToUpdate(menu_index, win, pUserData)
3667    int menu_index;
3668    Window win;
3669    void *pUserData;
3670    /* return FALSE will stop the enumeration */
3671 {
3672    UpdatePinnedMenu(menu_index);
3673    return TRUE;
3674 }
3675 
3676 static
EndHideDuringCapture()3677 void EndHideDuringCapture()
3678 {
3679    if (hideDuringCapture) {
3680       XEvent ev;
3681 
3682       EnumPopupMenuWindow(EnumPopupMenuProcToShow, NULL);
3683       XMapWindow(mainDisplay, mainWindow);
3684       XSync(mainDisplay, False);
3685       while (XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
3686          ExposeEventHandler(&ev, TRUE);
3687       }
3688       EnumPopupMenuWindow(EnumPopupMenuProcToUpdate, NULL);
3689    } else {
3690       SetDefaultCursor(mainWindow);
3691       ShowCursor();
3692    }
3693    ShowCurChoiceMouseStatus(curChoice, 0, FALSE);
3694    XBell(mainDisplay, 0);
3695    XSync(mainDisplay, False);
3696    MillisecondSleep(120);
3697    XBell(mainDisplay, 0);
3698 }
3699 
CreatePpmTrueObjFromImage(image,image_w,image_h,ppm_data,data_size)3700 struct ObjRec *CreatePpmTrueObjFromImage(image, image_w, image_h,
3701       ppm_data, data_size)
3702    XImage *image;
3703    int image_w, image_h;
3704    char *ppm_data;
3705    unsigned int data_size;
3706 {
3707    Pixmap pixmap=None, bitmap=None;
3708    XImage *bitmap_image=NULL;
3709    struct ObjRec *obj_ptr=NULL;
3710    struct XPmRec *xpm_ptr=NULL;
3711 
3712    pixmap = XCreatePixmap(mainDisplay, mainWindow, image_w, image_h, mainDepth);
3713    bitmap = XCreatePixmap(mainDisplay, dummyBitmap, image_w, image_h, 1);
3714    if (pixmap == None || bitmap == None) {
3715       if (pixmap != None) XFreePixmap(mainDisplay, pixmap);
3716       if (bitmap != None) XFreePixmap(mainDisplay, bitmap);
3717       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
3718             image_w, image_h);
3719       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3720       return NULL;
3721    }
3722    XSetForeground(mainDisplay, xbmGC, 1);
3723    XFillRectangle(mainDisplay, bitmap, xbmGC, 0, 0, image_w, image_h);
3724    XSetForeground(mainDisplay, xbmGC, 0);
3725    bitmap_image =  XGetImage(mainDisplay, bitmap, 0, 0, image_w, image_h, 1,
3726             ZPixmap);
3727    XPutImage(mainDisplay, pixmap, xpmGC, image, 0, 0, 0, 0, image_w, image_h);
3728    image = XGetImage(mainDisplay, pixmap, 0, 0, image_w, image_h, AllPlanes,
3729          ZPixmap);
3730    if (image == NULL || bitmap_image == NULL) {
3731       XFreePixmap(mainDisplay, pixmap);
3732       XFreePixmap(mainDisplay, bitmap);
3733       if (image != NULL) XDestroyImage(image);
3734       if (bitmap_image != NULL) XDestroyImage(bitmap_image);
3735       MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME, INFO_MB);
3736       return NULL;
3737    }
3738    obj_ptr = CreateXPmObj(image_w, image_h, image_w, image_h, pixmap, image,
3739          bitmap, bitmap_image, 0, 0, FALSE, NULL, NULL, NULL, NULL);
3740    xpm_ptr = obj_ptr->detail.xpm;
3741    xpm_ptr->real_type = PPM_TRUE;
3742    xpm_ptr->ppm_data_compress = PPM_DATA_DEFLATED;
3743    xpm_ptr->ppm_data = ppm_data;
3744    xpm_ptr->ppm_data_size = data_size;
3745    xpm_ptr->ppm_mask_data = NULL;
3746    xpm_ptr->ppm_mask_size = 0;
3747 
3748    return obj_ptr;
3749 }
3750 
3751 static
ImportCapturedImage()3752 void ImportCapturedImage()
3753 {
3754    int no_image=FALSE;
3755    unsigned int data_size=0;
3756    char tmp_fname[MAXPATHLENGTH], ext[MAXPATHLENGTH], *ppm_data=NULL;
3757    Colormap saved_colormap=None;
3758 
3759    SetWatchCursor(drawWindow);
3760    SetWatchCursor(mainWindow);
3761 
3762    if (MkTempFile(tmp_fname, sizeof(tmp_fname), tmpDir, TOOL_NAME) == NULL) {
3763       return;
3764    }
3765    if (installedColormaps != NULL) {
3766       saved_colormap = mainColormap;
3767       mainColormap = (*installedColormaps);
3768    }
3769    if (!DumpXImageToFile(capturedImage, capturedWidth, capturedHeight,
3770          tmp_fname, ext)) {
3771       no_image = TRUE;
3772    } else if (strcmp(ext, ".ppm.z") == 0) {
3773       char deflated_fname[MAXPATHLENGTH];
3774 
3775       snprintf(deflated_fname, sizeof(deflated_fname), "%s%s", tmp_fname, ext);
3776       ppm_data = ReadFileIntoBuf(deflated_fname, &data_size);
3777       unlink(deflated_fname);
3778    }
3779    if (saved_colormap != None) {
3780       mainColormap = saved_colormap;
3781    }
3782    SetDefaultCursor(mainWindow);
3783    ShowCursor();
3784 
3785    if (!no_image) {
3786       if (ppm_data == NULL) {
3787          ImportGivenXPixmapFile(FALSE, NULL, tmp_fname,
3788                STID_GIVEN_XPM_SIZE_FILE_IMPORTED, STID_CANNOT_IMPORT_XPM_FILE,
3789                NULL, NULL);
3790       } else {
3791          struct ObjRec *obj_ptr=CreatePpmTrueObjFromImage(capturedImage,
3792                capturedWidth, capturedHeight, ppm_data, data_size);
3793 
3794          if (obj_ptr != NULL) {
3795             AddObj(NULL, topObj, obj_ptr);
3796             PlaceTopObj(obj_ptr, NULL, NULL);
3797 
3798             SelectTopObj();
3799             RecordNewObjCmd();
3800             SetFileModified(TRUE);
3801             justDupped = FALSE;
3802             if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
3803                RedrawColorWindow();
3804             }
3805          }
3806       }
3807    }
3808    CaptureCleanUp();
3809 
3810    unlink(tmp_fname);
3811 }
3812 
3813 static
CaptureUpdateBox(OrigX,OrigY,end_x,end_y)3814 void CaptureUpdateBox(OrigX, OrigY, end_x, end_y)
3815    int OrigX, OrigY, end_x, end_y;
3816 {
3817    char buf[80];
3818    int w=abs(OrigX-end_x), h=abs(OrigY-end_y);
3819 
3820    SelBox(rootWindow, revDefaultGC, OrigX, OrigY, end_x, end_y);
3821    sprintf(buf, "%dx%d", w, h);
3822    XDrawString(mainDisplay, rootWindow, revDefaultGC, end_x+18,
3823          end_y+defaultFontAsc, buf, strlen(buf));
3824 }
3825 
3826 static
ContinueScreenCapture(OrigX,OrigY)3827 void ContinueScreenCapture(OrigX, OrigY)
3828    int OrigX, OrigY;
3829 {
3830    int done=FALSE;
3831    int end_x=OrigX, end_y=OrigY;
3832 
3833    XSetSubwindowMode(mainDisplay, revDefaultGC, IncludeInferiors);
3834    XGrabPointer(mainDisplay, rootWindow, FALSE,
3835          PointerMotionMask | ButtonReleaseMask,
3836          GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
3837    CaptureUpdateBox(OrigX, OrigY, end_x, end_y);
3838    while (!done) {
3839       XEvent input;
3840 
3841       XNextEvent(mainDisplay, &input);
3842 
3843       if (input.type == ButtonRelease) {
3844          XUngrabPointer(mainDisplay, CurrentTime);
3845          CaptureUpdateBox(OrigX, OrigY, end_x, end_y);
3846          done = TRUE;
3847       } else if (input.type == MotionNotify) {
3848          XEvent ev;
3849          int cur_x=input.xmotion.x, cur_y=input.xmotion.y;
3850 
3851          if (cur_x != end_x || cur_y != end_y) {
3852             CaptureUpdateBox(OrigX, OrigY, end_x, end_y);
3853             end_x = cur_x;
3854             end_y = cur_y;
3855             CaptureUpdateBox(OrigX, OrigY, end_x, end_y);
3856          }
3857          while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ;
3858       }
3859    }
3860    XSetSubwindowMode(mainDisplay, revDefaultGC, ClipByChildren);
3861    XSync(mainDisplay, False);
3862 
3863    if (OrigX != end_x && OrigY != end_y) {
3864       struct BBRec bbox;
3865       int dest_w=0, dest_h=0;
3866 
3867       SetBBRec(&bbox, OrigX, OrigY, end_x, end_y);
3868       dest_w = bbox.rbx - bbox.ltx;
3869       dest_h = bbox.rby - bbox.lty;
3870 
3871       capturedImage = XGetImage(mainDisplay, rootWindow, bbox.ltx, bbox.lty,
3872             dest_w, dest_h, AllPlanes, ZPixmap);
3873       if (capturedImage == NULL) {
3874          FailAllocMessage();
3875       } else {
3876          capturedWidth = dest_w;
3877          capturedHeight = dest_h;
3878          installedColormaps = XListInstalledColormaps(mainDisplay, rootWindow,
3879                &numInstalledColormaps);
3880          if (numInstalledColormaps == 0) {
3881             if (installedColormaps != NULL) XFree(installedColormaps);
3882             installedColormaps = NULL;
3883          } else if (numInstalledColormaps > 1) {
3884             TwoLineMsg(TgLoadString(STID_MORE_THAN_ONE_CMAP_INSTALLED),
3885                   TgLoadString(STID_FIRST_ONE_ON_LIST_USED));
3886          }
3887       }
3888    }
3889 }
3890 
ScreenCapture()3891 void ScreenCapture()
3892 {
3893    int mouse_x=0, mouse_y=0;
3894 
3895    if (!colorDisplay && mainDepth <= 1) return;
3896 
3897    BeginHideDuringCapture();
3898    SetMouseStatus(TgLoadString(STID_SPECIFY_AREA),
3899          TgLoadCachedString(CSTID_CANCEL), TgLoadCachedString(CSTID_CANCEL));
3900    if (CornerLoop(&mouse_x, &mouse_y) == Button1) {
3901       ContinueScreenCapture(mouse_x, mouse_y);
3902    }
3903    EndHideDuringCapture();
3904    if (capturedImage != NULL) {
3905       ImportCapturedImage();
3906    }
3907 }
3908 
3909 static
DoFullScreenCapture()3910 void DoFullScreenCapture()
3911 {
3912    struct BBRec bbox;
3913    int dpy_w=DisplayWidth(mainDisplay,mainScreen);
3914    int dpy_h=DisplayHeight(mainDisplay,mainScreen);
3915 
3916    SetBBRec(&bbox, 0, 0, dpy_w, dpy_h);
3917 
3918    capturedImage = XGetImage(mainDisplay, rootWindow, bbox.ltx, bbox.lty,
3919          dpy_w, dpy_h, AllPlanes, ZPixmap);
3920    if (capturedImage == NULL) {
3921       FailAllocMessage();
3922    } else {
3923       capturedWidth = dpy_w;
3924       capturedHeight = dpy_h;
3925       installedColormaps = XListInstalledColormaps(mainDisplay, rootWindow,
3926             &numInstalledColormaps);
3927       if (numInstalledColormaps == 0) {
3928          if (installedColormaps != NULL) XFree(installedColormaps);
3929          installedColormaps = NULL;
3930       } else if (numInstalledColormaps > 1) {
3931          TwoLineMsg(TgLoadString(STID_MORE_THAN_ONE_CMAP_INSTALLED),
3932                TgLoadString(STID_FIRST_ONE_ON_LIST_USED));
3933       }
3934    }
3935 }
3936 
FullScreenCapture()3937 void FullScreenCapture()
3938 {
3939    if (!colorDisplay && mainDepth <= 1) return;
3940 
3941    if (MsgBox(TgLoadString(STID_OK_TO_FULL_SCREEN_CAPTURE_YNC), TOOL_NAME,
3942          YNC_MB) != MB_ID_YES) {
3943       return;
3944    }
3945    FlushAllRedrawEvents();
3946    BeginHideDuringCapture();
3947    DoFullScreenCapture();
3948    EndHideDuringCapture();
3949    if (capturedImage != NULL) {
3950       ImportCapturedImage();
3951    }
3952 }
3953 
DelayedFullScreenCapture()3954 void DelayedFullScreenCapture()
3955 {
3956    char spec[80];
3957    int delay=0;
3958 
3959    if (!colorDisplay && mainDepth <= 1) return;
3960 
3961    *spec = '\0';
3962    if (Dialog(TgLoadString(STID_SPECIFY_DELAY_FULL_SCR_CAP), NULL, spec) ==
3963          INVALID) {
3964       return;
3965    }
3966    UtilTrimBlanks(spec);
3967    if (*spec == '\0') return;
3968 
3969    if (sscanf(spec, "%d", &delay) != 1) {
3970       sprintf(gszMsgBox, TgLoadString(STID_INVALID_SPEC_NUM_EXPECTED), spec);
3971       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3972       return;
3973    }
3974    FlushAllRedrawEvents();
3975    BeginHideDuringCapture();
3976    if (delay != 0) {
3977       sleep(delay);
3978    }
3979    DoFullScreenCapture();
3980    EndHideDuringCapture();
3981    if (capturedImage != NULL) {
3982       ImportCapturedImage();
3983    }
3984 }
3985 
ToggleHideDuringCapture()3986 void ToggleHideDuringCapture()
3987 {
3988    if (!colorDisplay && mainDepth <= 1) return;
3989 
3990    hideDuringCapture = !hideDuringCapture;
3991    sprintf(gszMsgBox, TgLoadString(hideDuringCapture ?
3992          STID_WILL_HIDE_TOOL_WHILE_CAPTURE : STID_WILL_SHOW_TOOL_WHILE_CAPTURE),
3993          TOOL_NAME);
3994    Msg(gszMsgBox);
3995 }
3996 
RefreshScreenCaptureMenu(menu)3997 int RefreshScreenCaptureMenu(menu)
3998    TgMenu *menu;
3999 {
4000    int ok=TRUE;
4001 
4002    if (!colorDisplay && mainDepth <= 1) {
4003       /* Screen Capture */
4004       ok &= TgEnableMenuItemById(menu, CMDID_SCREENCAPTURE, FALSE);
4005       /* Full Screen Capture */
4006       ok &= TgEnableMenuItemById(menu, CMDID_FULLSCREENCAPTURE, FALSE);
4007       /* Delayed Full Screen Capture */
4008       ok &= TgEnableMenuItemById(menu, CMDID_DELAYEDFULLSCREENCAPTURE, FALSE);
4009       /* Hide During Capture */
4010       ok &= TgEnableMenuItemById(menu, CMDID_TOGGLEHIDEDURINGCAPTURE, FALSE);
4011    }
4012    /* Hide During Capture */
4013    ok &= TgSetMenuItemCheckById(menu, CMDID_TOGGLEHIDEDURINGCAPTURE,
4014          hideDuringCapture);
4015 
4016    return ok;
4017 }
4018 
CreateScreenCaptureMenu(parent_menu,x,y,menu_info,status_str_xlated)4019 TgMenu *CreateScreenCaptureMenu(parent_menu, x, y, menu_info, status_str_xlated)
4020    TgMenu *parent_menu;
4021    int x, y;
4022    TgMenuInfo *menu_info;
4023    int status_str_xlated; /* ignored, always 0 */
4024 {
4025    TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, x, y, menu_info, FALSE);
4026 
4027    if (menu != NULL) {
4028       if (!RefreshScreenCaptureMenu(menu)) {
4029          return TgDestroyMenu(menu, TRUE);
4030       }
4031       menu->refresh_proc = ((RefreshMenuFunc*)RefreshScreenCaptureMenu);
4032    }
4033    return menu;
4034 }
4035 
ToggleAutoEPSPreviewBitmap()4036 void ToggleAutoEPSPreviewBitmap()
4037 {
4038    autoEPSPreviewBitmap = !autoEPSPreviewBitmap;
4039    sprintf(gszMsgBox, TgLoadString(autoEPSPreviewBitmap ?
4040          STID_WILL_AUTO_GEN_PREVIEW_BITMAP : STID_WONT_AUTO_GEN_PREVIEW_BITMAP),
4041          TOOL_NAME);
4042    Msg(gszMsgBox);
4043 }
4044 
RefreshImportMenu(menu)4045 int RefreshImportMenu(menu)
4046    TgMenu *menu;
4047 {
4048    int ok=TRUE;
4049 
4050    /* Auto EPS Preview Bitmap */
4051    ok &= TgSetMenuItemCheckById(menu, CMDID_TOGGLEAUTOEPSPREVIEWBITMAP,
4052          autoEPSPreviewBitmap);
4053 
4054    return ok;
4055 }
4056 
CreateImportMenu(parent_menu,x,y,menu_info,status_str_xlated)4057 TgMenu *CreateImportMenu(parent_menu, x, y, menu_info, status_str_xlated)
4058    TgMenu *parent_menu;
4059    int x, y;
4060    TgMenuInfo *menu_info;
4061    int status_str_xlated; /* ignored, always 0 */
4062 {
4063    TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, x, y, menu_info, FALSE);
4064 
4065    if (menu != NULL) {
4066       if (!RefreshImportMenu(menu)) {
4067          return TgDestroyMenu(menu, TRUE);
4068       }
4069       menu->refresh_proc = ((RefreshMenuFunc*)RefreshImportMenu);
4070    }
4071    return menu;
4072 }
4073