1 /* $XConsortium: fileIO.c /main/8 1996/10/21 17:31:11 mgreess $ */
2 /*********************************************************************
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
6 * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
8 **********************************************************************/
9 /******************************************************************************
12 ** Description: X11-based multi-color icon editor
14 ** File: fileIO.c, which contains the following subroutines or
21 ** Dump_AttribStruct()
23 ******************************************************************************
25 ** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
26 ** All rights are reserved. Copying or reproduction of this program,
27 ** except for archival purposes, is prohibited without prior written
28 ** consent of Hewlett-Packard Company.
30 ** Hewlett-Packard makes no representations about the suitibility of this
31 ** software for any purpose. It is provided "as is" without express or
34 ******************************************************************************/
36 #include <stdlib.h> /* for getenv() function prototype */
38 #include <sys/param.h>
42 #include <Xm/FileSB.h>
45 #include "externals.h"
50 extern void ReplyToMessage( );
51 extern Tt_message replyMsg;
54 extern XtPointer _XmStringUngenerate (
58 XmTextType output_type);
60 extern Widget formatMenu_xpm_tb, formatMenu_xbm_tb;
61 extern Window tablet_win;
62 extern Widget editMenu_deleteHS_pb;
63 Boolean Read_File(), Write_File();
64 Pixmap pix_ret, shape_ret, mask_ret;
65 int successFormat, x_hot, y_hot;
66 unsigned int width_ret, height_ret;
69 extern void PixelTableClear();
70 extern int PixelTableLookup();
71 extern void send_tt_saved();
72 extern void Display_XPMFile(int, int);
73 extern void Display_XBMFile(int, int);
76 char *tmpSave; /* Save the file path being saved */
77 char dummy[256]; /* mask file for use in main */
81 /***************************************************************************
83 * Routine: Do_FileIO *
85 * Purpose: To read/write the current icon from/to the filename *
86 * selected in the file selection box. *
88 * If fileIOMode is FILE_READ, this file should be read in. *
89 * If the read attempt fails, an error dialog pops up to *
92 * If fileIOMode is FILE_WRITE, the currently loaded icon *
93 * should be written to the named file, using the current file *
94 * format (specified by 'fileFormat'). As with FILE_READ, if *
95 * the write attempt fails, an error dialog pops up to inform *
98 ***************************************************************************/
103 XtPointer client_unused,
104 XmFileSelectionBoxCallbackStruct *callback_data )
106 int unmanageFileIO = True;
107 struct stat statbuf; /* Information on a file. */
111 stat_out("Entering Do_FileIO\n");
119 tmpSave = (char *) _XmStringUngenerate(
120 callback_data->value, NULL,
121 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
124 if (fileIOMode == FILE_READ) {
125 if (!Read_File(tmpSave))
127 unmanageFileIO = False;
128 DoErrorDialog( (GETSTR(16,2, "The file cannot be accessed\nor contains invalid data")) );
131 if (successFormat == FORMAT_XPM) {
132 X_Hot = xpm_ReadAttribs.x_hotspot;
133 Y_Hot = xpm_ReadAttribs.y_hotspot;
134 Display_XPMFile(xpm_ReadAttribs.width, xpm_ReadAttribs.height);
136 else if (successFormat == FORMAT_XBM) {
139 Display_XBMFile(width_ret, height_ret);
142 SavedOnce = True; /* Implicitly saved, since we loaded the file */
144 Turn off the HotSpot thing in the File menu.
147 XtSetSensitive((Widget) editMenu_deleteHS_pb, False );
150 XtUnmanageChild(fileIODialog);
152 } /* if(FileIOMode...) */
154 if (fileIOMode == FILE_WRITE) {
155 if (stat(tmpSave, &statbuf) == 0 && SaveMeNot)
158 DoQueryDialog( GETSTR(16,25, "File already exists.\n\nOK to overwrite the file?") );
162 if (!Write_File(tmpSave))
164 unmanageFileIO = False;
165 DoErrorDialog( (GETSTR(16,4, "Unable to write data to file")) );
173 XtUnmanageChild(fileIODialog);
180 stat_out("Leaving Do_FileIO\n");
185 /***************************************************************************
187 * Routine: Read_File *
189 * Purpose: To read the contents of the specified file and create either *
190 * a multi-color icon (if the file is an XPM file) or a bi- *
191 * color icon (if the file is an XBM file). Further, if the *
192 * file is an XBM file, attempt to find a matching mask file *
193 * and read it as well, using to result to determine which *
194 * pixels should be set to transparent. *
196 ***************************************************************************/
202 char *base_name, *suffix, fname[MAXPATHLEN+1], *tmp, *tmp2;
203 unsigned int mask_width_ret, mask_height_ret;
204 int mask_x_hot, mask_y_hot, first;
209 stat_out("Entering Read_File\n");
212 if ( !fnameIn || !(*fnameIn) )
215 tmp = strchr(fnameIn, ':');
216 tmp2 = strchr(fnameIn, '/');
218 /*** - convert from "<host>:/..." to a path on the locale host. ***/
219 if (tmp && tmp2 && (tmp2 == tmp+1))
221 char *netfile, *localfile;
224 netfile = tt_host_file_netfile(fnameIn, tmp+1);
225 localfile = tt_netfile_file(netfile);
227 strncpy(fname, localfile, MAXPATHLEN);
233 else /* wasn't in form "<host>:/<path>" so use name as is... */
235 strcpy(fname, fnameIn);
238 /*** - if we got a NULL base_name, return FALSE ***/
239 base_name = strrchr(fname, '/');
241 base_name = (base_name ? base_name + 1 : fname);
245 /*** - if it's not a regular file, don't use it ***/
246 if (stat(fname, &statBuf) == 0) /* success */
248 if ( (statBuf.st_mode & S_IFMT) == S_IFDIR ||
249 (statBuf.st_mode & S_IFMT) == S_IFCHR ||
250 (statBuf.st_mode & S_IFMT) == S_IFBLK )
254 if (statBuf.st_size == 0)
258 strcpy(last_fname, fname);
260 successFormat = FORMAT_NONE;
266 return False; /* file doesn't exist, return failure */
270 /*** before we do anything else, make sure ***/
271 /*** the editor interface refreshes itself ***/
273 XmUpdateDisplay(mainWindow);
278 xpm_ReadAttribs.valuemask = READ_FLAGS;
279 xpm_ReadAttribs.colorsymbols = colorSymbols;
280 xpm_ReadAttribs.numsymbols = NUM_PENS;
283 /*** if the file ends in .pm or .xpm, try reading it as an ***/
284 /*** XPM file first. Then try XBM format if XPM fails. ***/
286 /*** if the file ends in .bm or .xbm, try reading it as an ***/
287 /*** XBM file first. Then try XPM format if XBM fails. ***/
289 /*** if the file doesn't match any of these suffixes, try ***/
290 /*** reading it as an XPM file first. Then try XBM format ***/
291 /*** if XPM fails. ***/
293 /*** FIRST, does a suffix exist? ***/
294 suffix = strrchr(base_name, '.');
295 if ((suffix) && ((int)strlen(suffix) > 1))
298 if (!strcmp(suffix, "bm") || !strcmp(suffix, "xbm"))
306 /*** try to read the XPM/XBM file, in the order ***/
307 /*** specified by the 'first' format. ***/
308 if (first == FORMAT_XPM) {
309 status = _DtXpmReadFileToPixmap(dpy, tablet_win,
310 fname, &pix_ret, &shape_ret, &xpm_ReadAttribs);
315 XDestroyImage(debug_image);
317 XDestroyImage(debug_shape);
318 debug_status = _DtXpmReadFileToImage(dpy, fname,
319 &debug_image, &debug_shape, &xpm_ReadAttribs);
323 if (status != XpmSuccess) {
324 status = XReadBitmapFile(dpy, tablet_win,
325 fname, &width_ret, &height_ret, &pix_ret, &x_hot,
327 if (status != BitmapSuccess) {
330 stat_out("Leaving Read_File - XPM/XBM read attempt failed.\n");
335 successFormat = FORMAT_XBM;
338 successFormat = FORMAT_XPM;
341 status = XReadBitmapFile(dpy, tablet_win, fname,
342 &width_ret, &height_ret, &pix_ret, &x_hot, &y_hot);
343 if (status != BitmapSuccess) {
344 status = _DtXpmReadFileToPixmap(dpy, tablet_win,
345 fname, &pix_ret, &shape_ret, &xpm_ReadAttribs);
346 if (status != XpmSuccess) {
349 stat_out("Leaving Read_File - XBM/XPM read attempt failed.\n");
354 successFormat = FORMAT_XPM;
357 successFormat = FORMAT_XBM;
360 /*** If we got this far, we successfully read in a file. ***/
361 /*** If the 'successFormat' is FORMAT_XBM, try to find ***/
362 /*** and accompanying mask file and load it too. The ***/
363 /*** format for a mask file name is: ***/
364 /*** <pathname><base_name>_m<suffix> (optional suffix)***/
365 if (successFormat == FORMAT_XBM) {
366 /*** does a suffix exist? ***/
368 strncpy(dummy, fname, ((suffix-fname)-1));
369 dummy[(int) (suffix-fname)-1] = NULL;
370 strcat(dummy, "_m.");
371 strcat(dummy, suffix);
374 stat_out(" full-filename = '%s'\n", fname);
375 stat_out(" suffix = '%s'\n", suffix);
380 strcpy(dummy, fname);
385 stat_out(" mask-file = '%s'\n", dummy);
387 status = XReadBitmapFile(dpy, tablet_win, dummy,
388 &mask_width_ret, &mask_height_ret, &mask_ret,
389 &mask_x_hot, &mask_y_hot);
390 if (status == BitmapSuccess) {
391 if ((width_ret != mask_width_ret) || (height_ret != mask_height_ret)) {
392 XFreePixmap(dpy, mask_ret);
400 strcpy(last_fname, fname);
405 stat_out("Finished Reading file '%s'\n", last_fname);
406 stat_out("Leaving Read_File\n");
414 /***************************************************************************
416 * Routine: Write_File *
418 * Purpose: To write the current icon to the specified filename as *
419 * either an XPM file or XBM file, depending on the current *
420 * value of the fileFormat flag. Further, if the current *
421 * fileFormat is FORMAT_XBM, create a second XBM file which *
422 * contains a mask for the XBM file just written. *
424 ***************************************************************************/
429 extern int tt_tmpfile_fd;
433 char *base_name, *suffix, fname[256], *tmp, *tmp2, *vend;
435 XImage *scratch_shape, *scratch_mask;
436 struct stat statbuf; /* Information on a file. */
441 stat_out("Entering Write_File\n");
443 SUN = False; /* Assume machine other than SUN */
444 if ( !fnameIn || !(*fnameIn) )
447 tmp = strchr(fnameIn, ':');
448 tmp2 = strchr(fnameIn, '/');
450 /*** - convert from "<host>:/..." to a path on the locale host. ***/
451 if (tmp && tmp2 && (tmp2 == tmp+1))
453 char *netfile, *localfile;
456 netfile = tt_host_file_netfile(fnameIn, tmp+1);
457 localfile = tt_netfile_file(netfile);
459 strncpy(fname, localfile, MAXPATHLEN);
465 else /* wasn't in form "<host>:/<path>" so use name as is... */
467 strcpy(fname, fnameIn);
471 base_name = strrchr(fname, '/');
473 base_name = (base_name ? base_name + 1 : fname);
476 strcpy(last_fname, fname);
481 stat_out("Writing file '%s'\n", last_fname);
484 if (fileFormat == FORMAT_XPM) {
485 xpm_WriteAttribs.x_hotspot = X_Hot;
486 xpm_WriteAttribs.y_hotspot = Y_Hot;
487 xpm_WriteAttribs.width = icon_width;
488 xpm_WriteAttribs.height = icon_height;
489 xpm_WriteAttribs.cpp = 1;
490 xpm_WriteAttribs.colorsymbols = colorSymbols;
491 xpm_WriteAttribs.numsymbols = NUM_PENS;
492 xpm_WriteAttribs.ncolors = NUM_PENS;
493 xpm_WriteAttribs.valuemask = WRITE_FLAGS;
496 Dump_AttribStruct(&xpm_WriteAttribs);
498 status = _DtXpmWriteFileFromPixmap(dpy, fname, color_icon, NULL,
502 status = _DtXpmWriteFileFromPixmap(dpy, fname, color_icon, NULL, NULL);
504 if (status != XpmSuccess) {
507 stat_out("Leaving Write_File - XPM write failed. ");
509 case XpmOpenFailed : stat_out("(XpmOpenFailed)\n"); break;
510 case XpmNoMemory : stat_out("(XpmNoMemory)\n"); break;
511 default : stat_out("(UNKNOWN cause)\n"); break;
519 /*** FIRST, does a suffix exist? ***/
520 suffix = strrchr(base_name, '.');
521 if ((suffix) && ((int)strlen(suffix) > 1))
523 /*** SECOND, is it a valid suffix? ***/
525 if (strcmp(suffix, "bm") && strcmp(suffix, "xbm"))
528 /*** THIRD, construct the mask filename ***/
530 strncpy(dummy, fname, ((suffix-fname)-1));
531 dummy[(int) (suffix-fname)-1] = NULL;
532 strcat(dummy, "_m.");
533 strcat(dummy, suffix);
536 strcpy(dummy, fname);
539 /*** FOURTH, construct XImages for the shape and mask bitmaps ***/
541 scratch_shape = XGetImage(dpy, mono_icon, 0, 0, icon_width, icon_height,
543 scratch_mask = XGetImage(dpy, mono_icon, 0, 0, icon_width, icon_height,
545 if (!scratch_shape || !scratch_mask) {
547 XDestroyImage(scratch_shape);
549 XDestroyImage(scratch_mask);
553 /* is this a SUN machine? */
554 /* if so use special code else use old code */
555 vend = ServerVendor(dpy);
556 if ( strncmp( vend, "Sun", 3) == 0) {
558 for (i=0; i<icon_width; i++)
559 for (j=0; j<icon_height; j++)
560 if (XGetPixel(scratch_shape, i, j) == Transparent) {
561 XPutPixel(scratch_shape, i, j, white_pixel);
564 for (i=0; i<icon_width; i++)
565 for (j=0; j<icon_height; j++)
566 if (XGetPixel(scratch_mask, i, j) != Transparent)
567 XPutPixel(scratch_mask, i, j, black_pixel);
569 XPutPixel(scratch_mask, i, j, white_pixel);
571 for (i=0; i<icon_width; i++)
572 for (j=0; j<icon_height; j++)
573 if (XGetPixel(scratch_shape, i, j) == Transparent) {
574 XPutPixel(scratch_shape, i, j, black_pixel);
577 for (i=0; i<icon_width; i++)
578 for (j=0; j<icon_height; j++)
579 if (XGetPixel(scratch_mask, i, j) != Transparent)
580 XPutPixel(scratch_mask, i, j, white_pixel);
582 XPutPixel(scratch_mask, i, j, black_pixel);
586 /*** FIFTH, write out the shape and mask bitmaps ***/
587 scratch_pix = XCreatePixmap(dpy, root, icon_width, icon_height,
588 DefaultDepth(dpy, screen));
591 XDestroyImage(scratch_shape);
593 XDestroyImage(scratch_mask);
596 /* don't set GXcopyInverte for SUN machines */
598 XSetFunction(dpy, Mono_gc, GXcopyInverted);
599 XPutImage(dpy, scratch_pix, Mono_gc, scratch_shape, 0, 0, 0, 0,
600 icon_width, icon_height);
601 XSetFunction(dpy, Mono_gc, GXcopy);
602 status = XWriteBitmapFile(dpy, fname, scratch_pix, icon_width, icon_height,
604 if (status != BitmapSuccess)
606 XDestroyImage(scratch_shape);
607 XDestroyImage(scratch_mask);
608 XFreePixmap(dpy, scratch_pix);
612 XPutImage(dpy, scratch_pix, Mono_gc, scratch_mask, 0, 0, 0, 0,
613 icon_width, icon_height);
614 status = XWriteBitmapFile(dpy, dummy, scratch_pix, icon_width,
615 icon_height, X_Hot, Y_Hot);
616 if (status != BitmapSuccess)
618 XDestroyImage(scratch_shape);
619 XDestroyImage(scratch_mask);
620 XFreePixmap(dpy, scratch_pix);
624 XFreePixmap(dpy, scratch_pix);
625 XDestroyImage(scratch_shape);
626 XDestroyImage(scratch_mask);
629 /* Don't know if this is needed....
640 stat_out("Leaving Write_File\n");
642 if( (fileFormat != FORMAT_XPM) && (!mask_needed) && (stat(tmpSave, &statbuf) == 0) )
645 if (tt_tmpfile_fd != -1)
652 /***************************************************************************
654 * Routine: Display_XPMFile *
656 * Purpose: Assuming that we have successfully read in an XPM file, use *
657 * the data from the file to render the proper rasters to the *
658 * color_icon and mono_icon (and their corresponding widgets). *
660 * Rendering the color icon is straight-forward, since the *
661 * pixmap generated by Read_File() is already correct. For *
662 * the mono icon, we extract an XImage for the entire color *
663 * pixmap, and then convert each pixel individually to one *
664 * three values: black, white, or transparent. For each pixel, *
665 * the following test is performed: 1st) compare it to each *
666 * static color. If a match is found, convert the pixel to *
667 * the appropriate mono equivalent. 2nd) if the 1st step fails *
668 * to find a match, try the same comparisons against the *
669 * dynamic colors. 3rd) if the 2nd step also fails, use the *
670 * PixelTableLookup() function. *
672 * Once the coversion process is complete, both the color_icon *
673 * and mono_icon (and their corresponding widgets) can be *
676 ***************************************************************************/
683 int converted, i, j, k;
685 XImage *scratch_img, *mono_img, *mask_img;
686 Pixel cpixel, mpixel;
693 stat_out("Entering Display_XPMFile\n");
697 /*** resize the color and mono icon windows, and the tablet ***/
698 /*** to their (new) correct height and width. ***/
699 Init_Icons(width, height, DO_NOT_SAVE);
701 /*** Grab an image for both (potentially modified) ***/
702 /*** color and mono conversions ***/
703 scratch_img = XGetImage(dpy, pix_ret, 0, 0, width, height,
705 mono_img = XGetImage(dpy, pix_ret, 0, 0, width, height,
709 mask_img = XGetImage(dpy, shape_ret, 0, 0, width, height,
717 PixelTableClear; /* force new pixel table now */
718 for (i=0; i<width; i++)
719 for (j=0; j<height; j++) {
721 cpixel = XGetPixel(scratch_img, i, j);
723 mpixel = XGetPixel(mask_img, i, j);
725 cpixel = Transparent;
726 XPutPixel(scratch_img, i, j, cpixel);
729 for (k = 0; k < NUM_STATICS; k++)
730 if (cpixel == StaticPen[k]) {
731 XPutPixel(mono_img, i, j, StaticMono[k]);
733 } /* if(cpixel...) */
735 for (k = 0; k < NUM_DYNAMICS; k++)
736 if (cpixel == DynamicPen[k]) {
737 XPutPixel(mono_img, i, j, DynamicMono[k]);
739 } /* if(cpixel...) */
740 } /* if(!converted) */
742 pixelTableIndex = PixelTableLookup (cpixel, False);
743 XPutPixel(mono_img, i, j, PIXEL_TABLE_MONO(pixelTableIndex));
744 } /* if(!converted) */
753 XPutImage(dpy, color_icon, Color_gc, scratch_img,
754 0, 0, 0, 0, width, height);
755 XPutImage(dpy, mono_icon, Mono_gc, mono_img,
756 0, 0, 0, 0, width, height);
758 /*** this following stuff all gets done regardless ***/
760 XCopyArea(dpy, color_icon, XtWindow(iconImage),
761 Color_gc, 0, 0, width, height, 0, 0);
762 XCopyArea(dpy, mono_icon, XtWindow(monoImage),
763 Mono_gc, 0, 0, width, height, 0, 0);
765 icon_height = height;
766 fileFormat = FORMAT_XPM;
767 XmToggleButtonGadgetSetState(formatMenu_xpm_tb, True, True);
768 /* This line is not realy needed since an Exposed event will be generated */
769 Repaint_Exposed_Tablet();
770 XDestroyImage(scratch_img);
771 XFreePixmap(dpy, pix_ret);
773 XFreePixmap(dpy, shape_ret);
777 stat_out("Leaving Display_XPMFile\n");
782 /***************************************************************************
784 * Routine: Display_XBMFile *
786 * Purpose: Assuming that we have successfully read in an X bitmap file *
787 * (and, potentially, a mask file as well), use the data from *
788 * the file(s) to render the proper rasters to the color_icon *
789 * and mono_icon (and their corresponding widgets). *
791 * Rendering the bitmap is straight-forward (create a scratch *
792 * pixmap of the correct depth and copy-plane the just-read *
793 * bitmap onto it). If there is a mask bitmap as well, then *
794 * the scratch pixmap must be modified such that for every *
795 * 0 bit in the mask bitmap, the corresponding pixel of the *
796 * scratch pixmap should be set to the Transparent pixel. *
797 * Once this is done, the scratch pixmap is copied to both *
798 * the color_icon and mono_icon (since, for bitmaps, they're *
799 * identical). Then free the scratch pixmap. *
801 ***************************************************************************/
809 XImage *test_img, *scratch_img;
814 stat_out("Entering Display_XBMFile\n");
817 scratch_pix = XCreatePixmap(dpy, root, width, height,
818 DefaultDepth(dpy, screen));
819 Init_Icons(width, height, DO_NOT_SAVE);
820 XSetBackground(dpy, scratch_gc, white_pixel);
821 XFillRectangle(dpy, scratch_pix, scratch_gc, 0, 0, width, height);
822 XSetForeground(dpy, scratch_gc, black_pixel);
823 XCopyPlane(dpy, pix_ret, scratch_pix, scratch_gc, 0, 0,
824 width, height, 0, 0, 1);
826 test_img = XGetImage(dpy, mask_ret, 0, 0, width, height,
828 scratch_img = XGetImage(dpy, scratch_pix, 0, 0, width, height,
830 for (i=0; i<width; i++)
831 for (j=0; j<height; j++)
832 if (!XGetPixel(test_img, i, j))
833 XPutPixel(scratch_img, i, j, Transparent);
834 XPutImage(dpy, scratch_pix, scratch_gc, scratch_img,
835 0, 0, 0, 0, width, height);
837 XCopyArea(dpy, scratch_pix, color_icon, Color_gc, 0, 0,
838 width, height, 0, 0);
839 XCopyArea(dpy, scratch_pix, mono_icon, Mono_gc, 0, 0,
840 width, height, 0, 0);
841 XCopyArea(dpy, color_icon, XtWindow(iconImage),
842 Color_gc, 0, 0, width, height, 0, 0);
843 XCopyArea(dpy, mono_icon, XtWindow(monoImage),
844 Mono_gc, 0, 0, width, height, 0, 0);
846 icon_height = height;
847 fileFormat = FORMAT_XBM;
848 XmToggleButtonGadgetSetState(formatMenu_xbm_tb, True, True);
849 /* This line is not realy needed since an Exposed event will be generated */
850 Repaint_Exposed_Tablet();
852 XDestroyImage(test_img);
853 XDestroyImage(scratch_img);
855 XFreePixmap(dpy, scratch_pix);
856 XFreePixmap(dpy, pix_ret);
858 XFreePixmap(dpy, mask_ret);
862 stat_out("Leaving Display_XBMFile\n");
867 /***************************************************************************
869 * Routine: SetFileIODialogInfo *
871 * Purpose: Set FileIODialog information... title, path, etc. *
873 ***************************************************************************/
875 SetFileIODialogInfo( void )
877 static int currentTitle = SAVE_AS; /* initial title is for Save_As... */
878 static XmString saveTitle = NULL;
879 static XmString openTitle = NULL;
880 static XmString saveLabel = NULL;
881 static XmString openLabel = NULL;
882 static XmString OpenOKLabel = NULL;
883 static XmString SaveOKLabel = NULL;
885 static char *untitledStr = NULL;
886 static Widget textWidget = NULL;
887 static char newName[MAX_FNAME];
888 static char dirStr[MAX_FNAME];
889 static char tmpStr[MAX_FNAME];
892 int n,dirlen=0,filelen=0,tst, ln;
893 char *strOrig = NULL;
899 int startSelect, endSelect;
901 if (DialogFlag == OPEN) /* Dialog is for File-Open menu item */
903 /* set title to "Icon Editor - Open File" if needed */
905 openTitle = GETXMSTR(2,8, "Icon Editor - Open File");
907 XtSetArg (args[n], XmNdialogTitle, openTitle); n++;
908 XtSetValues (fileIODialog, args, n);
911 /* set selection label to "Open File" */
913 openLabel = GETXMSTR(2,17, "Enter file name:");
915 XtSetArg (args[n], XmNselectionLabelString, openLabel); n++;
916 OpenOKLabel = GETXMSTR(2,22, "Open");
917 XtSetArg (args[n], XmNokLabelString, OpenOKLabel); n++;
918 XtSetValues (fileIODialog, args, n);
920 else /* Dialog is for File-Save or File-Save_As menu item */
922 /* set title to "Icon Editor - Save As" if needed */
924 saveTitle = GETXMSTR(2,6, "Icon Editor - Save As");
926 XtSetArg (args[n], XmNdialogTitle, saveTitle); n++;
927 XtSetValues (fileIODialog, args, n);
928 currentTitle = SAVE_AS;
930 /* set selection label to "Enter file name:" */
932 saveLabel = GETXMSTR(2,16, "Enter file name:");
934 XtSetArg (args[n], XmNselectionLabelString, saveLabel); n++;
935 SaveOKLabel = GETXMSTR(2,24, "Save");
936 XtSetArg (args[n], XmNokLabelString, SaveOKLabel); n++;
937 XtSetValues (fileIODialog, args, n);
940 /* set string to "UNTITLED" with appropriate suffix */
941 /* when apropriate */
944 untitledStr = GETSTR(2,20, "UNTITLED");
946 textWidget = XmFileSelectionBoxGetChild(fileIODialog, XmDIALOG_TEXT);
947 strOrig = XmTextFieldGetString(textWidget);
954 /* prepare to test */
955 tmp1 = strrchr(strOrig, '.');
957 strcat(tmpStr, untitledStr);
958 strcat(tmpStr, ".m.pm");
959 tst=strcmp(last_fname, tmpStr);
961 if ( tst==0 ) {/* untitled */
962 if ( tmp1 ) { /* previous string exists */
963 if (currentTitle != SAVE_AS) strcat(newName, strOrig);
965 strcat(newName, untitledStr);
966 strcat(newName, ".m.pm");}
968 XmFileSelectionDoSearch(fileIODialog,(XmString)NULL);
971 else { /* First time arownd */
972 if (strOrig && strOrig[0]!='\0')
973 strcat(newName, strOrig);
975 strcat(newName, untitledStr);
976 strcat(newName, ".m.pm");
980 /* rebuild last file name */
981 last_fname[0] = '\0';
982 strcpy(last_fname, dirStr);
983 strcat(last_fname, newName);
986 else { /* not untitled */
987 tmp1= strrchr(last_fname, '/');
990 * Check if any '/' characters found
995 * Strip path into directory name and file name
998 tmp2 = strchr(tmp1, c);
999 strcpy(newName, tmp2);
1001 /* make and insert the directory name */
1002 ln = strlen(last_fname) - strlen(tmp1);
1003 strncpy(dirStr, last_fname, ln);
1009 * Path is a simple filename
1010 * Set filename to be path name
1011 * Set directory name = "."
1013 strcpy(newName, last_fname);
1018 tmpXmStr = XmStringCreateLocalized (dirStr);
1020 XtSetArg (args[n], XmNdirectory, tmpXmStr); n++;
1021 XtSetValues (fileIODialog, args, n);
1022 XmStringFree(tmpXmStr);
1025 /* set the Highlighted string */
1026 newName[strlen(newName)+1] ='\0';
1027 tmp1 = strchr(newName, '.');
1028 if (tmp1 && tmp1[0]!='\0') ln = (int)strlen(tmp1);
1029 endSelect = strlen(newName)- ln;
1031 /* now set the text field and set selection for highlighted portion */
1032 XmTextFieldSetString(textWidget, newName);
1033 XmTextFieldSetSelection(textWidget, startSelect, endSelect, CurrentTime);
1036 XmProcessTraversal(textWidget, XmTRAVERSE_CURRENT);
1041 /* if file lists are being used, re-scan the directory contents */
1042 /* if (xrdb.useFileLists)
1043 XmFileSelectionDoSearch(fileIODialog, NULL);*/
1049 /***************************************************************************
1051 * Routine: Dump_AttribStruct #ifdef DEBUG only (for bba) *
1053 * Purpose: Print out the entier contents of the XpmAttributes struct. *
1055 ***************************************************************************/
1058 XpmAttributes *xpma )
1062 if (xpma->valuemask) {
1063 stat_out(" valuemask: (");
1064 if (xpma->valuemask & XpmVisual)
1065 stat_out("XpmVisual|");
1066 if (xpma->valuemask & XpmColormap)
1067 stat_out("XpmColormap|");
1068 if (xpma->valuemask & XpmDepth)
1069 stat_out("XpmDepth|");
1070 if (xpma->valuemask & XpmSize)
1071 stat_out("XpmSize|");
1072 if (xpma->valuemask & XpmHotspot)
1073 stat_out("XpmHotspot|");
1074 if (xpma->valuemask & XpmCharsPerPixel)
1075 stat_out("XpmCharsPerPixel|");
1076 if (xpma->valuemask & XpmColorSymbols)
1077 stat_out("XpmColorSymbols|");
1078 if (xpma->valuemask & XpmRgbFilename)
1079 stat_out("XpmRgbFilename|");
1080 if (xpma->valuemask & XpmInfos)
1081 stat_out("XpmInfos");
1085 stat_out(" valuemask: NULL\n");
1087 stat_out(" Colormap: %d\n", xpma->colormap);
1088 stat_out(" depth: %d\n", xpma->depth);
1089 stat_out(" width: %d\n", xpma->width);
1090 stat_out(" height: %d\n", xpma->height);
1091 stat_out(" x_hotspot: %d\n", xpma->x_hotspot);
1092 stat_out(" y_hotspot: %d\n", xpma->y_hotspot);
1093 stat_out(" cpp: %d\n", xpma->cpp);
1094 stat_out(" npixels: %d\n", xpma->npixels);
1095 if (xpma->npixels) {
1096 stat_out(" Pixels: ");
1097 for (i=0; i<xpma->npixels; i++) {
1098 stat_out("%d, ", xpma->pixels[i]);
1104 stat_out(" numsymbols: %d\n", xpma->numsymbols);
1105 if (xpma->numsymbols) {
1106 for (i=0; i<xpma->numsymbols; i++)
1107 stat_out(" %18s | %18s | %d\n", xpma->colorsymbols[i].name,
1108 xpma->colorsymbols[i].value, xpma->colorsymbols[i].pixel);
1110 stat_out(" rgb_fname: \"%s\"\n",((xpma->rgb_fname)?(xpma->rgb_fname):"(nil)"));
1111 stat_out(" ---------------------------------\n");
1112 stat_out(" ncolors: %d\n", xpma->ncolors);
1113 if (xpma->ncolors) {
1114 for (i=0; i<xpma->ncolors; i++)
1115 if (xpma->colorTable[i][0] != NULL)
1116 stat_out(" %3d \"%1s\" \"%18s\" \"%5s\" \"%5s\" \"%5s\" \"%5s\"\n",
1118 ((xpma->colorTable[i][0])?(xpma->colorTable[i][0]):"(nil)"),
1119 ((xpma->colorTable[i][1])?(xpma->colorTable[i][1]):"(nil)"),
1120 ((xpma->colorTable[i][2])?(xpma->colorTable[i][2]):"(nil)"),
1121 ((xpma->colorTable[i][3])?(xpma->colorTable[i][3]):"(nil)"),
1122 ((xpma->colorTable[i][4])?(xpma->colorTable[i][4]):"(nil)"),
1123 ((xpma->colorTable[i][5])?(xpma->colorTable[i][5]):"(nil)")
1126 stat_out(" hints_cmt: \"%s\"\n",((xpma->hints_cmt)?(xpma->hints_cmt):"(nil)"));
1127 stat_out(" colors_cmt: \"%s\"\n",((xpma->colors_cmt)?(xpma->colors_cmt):"(nil)"));
1128 stat_out(" pixels_cmt: \"%s\"\n",((xpma->pixels_cmt)?(xpma->pixels_cmt):"(nil)"));
1129 stat_out(" mask_pixel: 0x%x\n",xpma->mask_pixel);