fileIO.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: fileIO.c /main/8 1996/10/21 17:31:11 mgreess $ */
  24. /*********************************************************************
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company
  26. * (c) Copyright 1993, 1994 International Business Machines Corp.
  27. * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
  28. * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
  29. * Novell, Inc.
  30. **********************************************************************/
  31. /******************************************************************************
  32. ** Program: dticon
  33. **
  34. ** Description: X11-based multi-color icon editor
  35. **
  36. ** File: fileIO.c, which contains the following subroutines or
  37. ** functions:
  38. ** Do_FileIO()
  39. ** Read_File()
  40. ** Write_File()
  41. ** Display_XPMFile()
  42. ** Display_XBMFile()
  43. ** Dump_AttribStruct()
  44. **
  45. ******************************************************************************
  46. **
  47. ** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
  48. ** All rights are reserved. Copying or reproduction of this program,
  49. ** except for archival purposes, is prohibited without prior written
  50. ** consent of Hewlett-Packard Company.
  51. **
  52. ** Hewlett-Packard makes no representations about the suitibility of this
  53. ** software for any purpose. It is provided "as is" without express or
  54. ** implied warranty.
  55. **
  56. ******************************************************************************/
  57. #include <sys/param.h>
  58. #include <sys/stat.h>
  59. #include <Xm/Xm.h>
  60. #include <Xm/TextF.h>
  61. #include <Xm/FileSB.h>
  62. #include <Xm/ToggleBG.h>
  63. #include <stdio.h>
  64. #include <string.h>
  65. #include <unistd.h>
  66. #include "externals.h"
  67. #include "main.h"
  68. #include "utils.h"
  69. #include "process.h"
  70. #ifdef __TOOLTALK
  71. #include <Tt/tttk.h>
  72. extern void ReplyToMessage( );
  73. extern Tt_message replyMsg;
  74. #endif
  75. extern XtPointer _XmStringUngenerate (
  76. XmString string,
  77. XmStringTag tag,
  78. XmTextType tag_type,
  79. XmTextType output_type);
  80. extern Widget formatMenu_xpm_tb, formatMenu_xbm_tb;
  81. extern Window tablet_win;
  82. extern Widget editMenu_deleteHS_pb;
  83. Boolean Read_File(), Write_File();
  84. Pixmap pix_ret, shape_ret, mask_ret;
  85. int successFormat, x_hot, y_hot;
  86. unsigned int width_ret, height_ret;
  87. extern GC scratch_gc;
  88. extern void PixelTableClear();
  89. extern void send_tt_saved();
  90. extern void Display_XPMFile(int, int);
  91. extern void Display_XBMFile(int, int);
  92. char *tmpSave; /* Save the file path being saved */
  93. char dummy[256]; /* mask file for use in main */
  94. extern int SaveMeNot;
  95. extern int SavedOnce;
  96. /***************************************************************************
  97. * *
  98. * Routine: Do_FileIO *
  99. * *
  100. * Purpose: To read/write the current icon from/to the filename *
  101. * selected in the file selection box. *
  102. * *
  103. * If fileIOMode is FILE_READ, this file should be read in. *
  104. * If the read attempt fails, an error dialog pops up to *
  105. * inform the user. *
  106. * *
  107. * If fileIOMode is FILE_WRITE, the currently loaded icon *
  108. * should be written to the named file, using the current file *
  109. * format (specified by 'fileFormat'). As with FILE_READ, if *
  110. * the write attempt fails, an error dialog pops up to inform *
  111. * the user. *
  112. * *
  113. ***************************************************************************/
  114. void
  115. Do_FileIO(
  116. Widget wid,
  117. XtPointer client_unused,
  118. XmFileSelectionBoxCallbackStruct *callback_data )
  119. {
  120. int unmanageFileIO = True;
  121. struct stat statbuf; /* Information on a file. */
  122. #ifdef DEBUG
  123. if (debug)
  124. stat_out("Entering Do_FileIO\n");
  125. #endif
  126. pix_ret = 0;
  127. shape_ret = 0;
  128. mask_ret = 0;
  129. /* get file name */
  130. if (SaveMeNot){
  131. tmpSave = (char *) _XmStringUngenerate(
  132. callback_data->value, NULL,
  133. XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
  134. }
  135. if (fileIOMode == FILE_READ) {
  136. if (!Read_File(tmpSave))
  137. {
  138. unmanageFileIO = False;
  139. DoErrorDialog( (GETSTR(16,2, "The file cannot be accessed\nor contains invalid data")) );
  140. }
  141. else {
  142. if (successFormat == FORMAT_XPM) {
  143. X_Hot = xpm_ReadAttribs.x_hotspot;
  144. Y_Hot = xpm_ReadAttribs.y_hotspot;
  145. Display_XPMFile(xpm_ReadAttribs.width, xpm_ReadAttribs.height);
  146. }
  147. else if (successFormat == FORMAT_XBM) {
  148. X_Hot = x_hot;
  149. Y_Hot = y_hot;
  150. Display_XBMFile(width_ret, height_ret);
  151. }
  152. Dirty = False;
  153. SavedOnce = True; /* Implicitly saved, since we loaded the file */
  154. /*
  155. Turn off the HotSpot thing in the File menu.
  156. */
  157. if ( X_Hot == -1 )
  158. XtSetSensitive((Widget) editMenu_deleteHS_pb, False );
  159. if (unmanageFileIO)
  160. XtUnmanageChild(fileIODialog);
  161. } /* else */
  162. } /* if(FileIOMode...) */
  163. if (fileIOMode == FILE_WRITE) {
  164. if (stat(tmpSave, &statbuf) == 0 && SaveMeNot)
  165. {
  166. DialogFlag=SAVE_AS;
  167. DoQueryDialog( GETSTR(16,25, "File already exists.\n\nOK to overwrite the file?") );
  168. }
  169. else
  170. {
  171. if (!Write_File(tmpSave))
  172. {
  173. unmanageFileIO = False;
  174. DoErrorDialog( (GETSTR(16,4, "Unable to write data to file")) );
  175. }
  176. else{
  177. if (!SaveMeNot)
  178. SaveMeNot = True;
  179. Dirty = False;
  180. SavedOnce = True;
  181. if (unmanageFileIO)
  182. XtUnmanageChild(fileIODialog);
  183. }
  184. }
  185. }
  186. #ifdef DEBUG
  187. if (debug)
  188. stat_out("Leaving Do_FileIO\n");
  189. #endif
  190. }
  191. /***************************************************************************
  192. * *
  193. * Routine: Read_File *
  194. * *
  195. * Purpose: To read the contents of the specified file and create either *
  196. * a multi-color icon (if the file is an XPM file) or a bi- *
  197. * color icon (if the file is an XBM file). Further, if the *
  198. * file is an XBM file, attempt to find a matching mask file *
  199. * and read it as well, using to result to determine which *
  200. * pixels should be set to transparent. *
  201. * *
  202. ***************************************************************************/
  203. Boolean
  204. Read_File(
  205. char *fnameIn )
  206. {
  207. char *base_name = NULL, *suffix = NULL,
  208. fname[MAXPATHLEN], *tmp = NULL, *tmp2 = NULL;
  209. unsigned int mask_width_ret = 0, mask_height_ret = 0;
  210. int mask_x_hot = 0, mask_y_hot = 0, first = 0;
  211. struct stat statBuf = {};
  212. fname[0] = 0;
  213. #ifdef DEBUG
  214. if (debug)
  215. stat_out("Entering Read_File\n");
  216. #endif
  217. if ( !fnameIn || !(*fnameIn) )
  218. return False;
  219. tmp = strchr(fnameIn, ':');
  220. tmp2 = strchr(fnameIn, '/');
  221. /*** - convert from "<host>:/..." to a path on the locale host. ***/
  222. if (tmp && tmp2 && (tmp2 == tmp+1))
  223. {
  224. char *netfile, *localfile;
  225. tmp[0] = '\0';
  226. netfile = tt_host_file_netfile(fnameIn, tmp+1);
  227. localfile = tt_netfile_file(netfile);
  228. strncpy(fname, localfile, MAXPATHLEN);
  229. tmp[0] = ':';
  230. tt_free(netfile);
  231. tt_free(localfile);
  232. }
  233. else /* wasn't in form "<host>:/<path>" so use name as is... */
  234. {
  235. snprintf(fname, sizeof(fname), "%s", fnameIn);
  236. }
  237. /*** - if we got a NULL base_name, return FALSE ***/
  238. base_name = strrchr(fname, '/');
  239. if (fname[0])
  240. base_name = (base_name ? base_name + 1 : fname);
  241. if (!base_name)
  242. return (False);
  243. /*** - if it's not a regular file, don't use it ***/
  244. if (stat(fname, &statBuf) == 0) /* success */
  245. {
  246. if ( (statBuf.st_mode & S_IFMT) == S_IFDIR ||
  247. (statBuf.st_mode & S_IFMT) == S_IFCHR ||
  248. (statBuf.st_mode & S_IFMT) == S_IFBLK )
  249. {
  250. return False;
  251. }
  252. if (statBuf.st_size == 0)
  253. {
  254. Process_Clear();
  255. Process_Resize();
  256. snprintf(last_fname, sizeof(last_fname), "%s", fname);
  257. ChangeTitle();
  258. successFormat = FORMAT_NONE;
  259. return True;
  260. }
  261. }
  262. else
  263. {
  264. return False; /* file doesn't exist, return failure */
  265. }
  266. /*** before we do anything else, make sure ***/
  267. /*** the editor interface refreshes itself ***/
  268. XmUpdateDisplay(mainWindow);
  269. pix_ret = 0;
  270. shape_ret = 0;
  271. mask_ret = 0;
  272. xpm_ReadAttribs.valuemask = READ_FLAGS;
  273. xpm_ReadAttribs.colorsymbols = colorSymbols;
  274. xpm_ReadAttribs.numsymbols = NUM_PENS;
  275. /*** if the file ends in .pm or .xpm, try reading it as an ***/
  276. /*** XPM file first. Then try XBM format if XPM fails. ***/
  277. /*** ***/
  278. /*** if the file ends in .bm or .xbm, try reading it as an ***/
  279. /*** XBM file first. Then try XPM format if XBM fails. ***/
  280. /*** ***/
  281. /*** if the file doesn't match any of these suffixes, try ***/
  282. /*** reading it as an XPM file first. Then try XBM format ***/
  283. /*** if XPM fails. ***/
  284. /*** FIRST, does a suffix exist? ***/
  285. suffix = strrchr(base_name, '.');
  286. if ((suffix) && ((int)strlen(suffix) > 1))
  287. suffix++;
  288. if (suffix) {
  289. if (!strcmp(suffix, "bm") || !strcmp(suffix, "xbm"))
  290. first = FORMAT_XBM;
  291. else
  292. first = FORMAT_XPM;
  293. }
  294. else
  295. first = FORMAT_XPM;
  296. /*** try to read the XPM/XBM file, in the order ***/
  297. /*** specified by the 'first' format. ***/
  298. if (first == FORMAT_XPM) {
  299. status = XpmReadFileToPixmap(dpy, tablet_win,
  300. fname, &pix_ret, &shape_ret, &xpm_ReadAttribs);
  301. #ifdef DEBUG
  302. if (debug) {
  303. if (debug_image)
  304. XDestroyImage(debug_image);
  305. if (debug_shape)
  306. XDestroyImage(debug_shape);
  307. debug_status = XpmReadFileToImage(dpy, fname,
  308. &debug_image, &debug_shape, &xpm_ReadAttribs);
  309. }
  310. #endif
  311. if (status != XpmSuccess) {
  312. status = XReadBitmapFile(dpy, tablet_win,
  313. fname, &width_ret, &height_ret, &pix_ret, &x_hot,
  314. &y_hot);
  315. if (status != BitmapSuccess) {
  316. #ifdef DEBUG
  317. if (debug)
  318. stat_out("Leaving Read_File - XPM/XBM read attempt failed.\n");
  319. #endif
  320. return (False);
  321. }
  322. else
  323. successFormat = FORMAT_XBM;
  324. }
  325. else
  326. successFormat = FORMAT_XPM;
  327. }
  328. else {
  329. status = XReadBitmapFile(dpy, tablet_win, fname,
  330. &width_ret, &height_ret, &pix_ret, &x_hot, &y_hot);
  331. if (status != BitmapSuccess) {
  332. status = XpmReadFileToPixmap(dpy, tablet_win,
  333. fname, &pix_ret, &shape_ret, &xpm_ReadAttribs);
  334. if (status != XpmSuccess) {
  335. #ifdef DEBUG
  336. if (debug)
  337. stat_out("Leaving Read_File - XBM/XPM read attempt failed.\n");
  338. #endif
  339. return (False);
  340. }
  341. else
  342. successFormat = FORMAT_XPM;
  343. }
  344. else
  345. successFormat = FORMAT_XBM;
  346. }
  347. /*** If we got this far, we successfully read in a file. ***/
  348. /*** If the 'successFormat' is FORMAT_XBM, try to find ***/
  349. /*** and accompanying mask file and load it too. The ***/
  350. /*** format for a mask file name is: ***/
  351. /*** <pathname><base_name>_m<suffix> (optional suffix)***/
  352. if (successFormat == FORMAT_XBM) {
  353. /*** does a suffix exist? ***/
  354. if (suffix) {
  355. strncpy(dummy, fname, ((suffix-fname)-1));
  356. dummy[(int) (suffix-fname)-1] = '\0';
  357. strcat(dummy, "_m.");
  358. strcat(dummy, suffix);
  359. #ifdef DEBUG
  360. if (debug) {
  361. stat_out(" full-filename = '%s'\n", fname);
  362. stat_out(" suffix = '%s'\n", suffix);
  363. }
  364. #endif
  365. }
  366. else {
  367. snprintf(dummy, sizeof(dummy), "%s_m", fname);
  368. }
  369. #ifdef DEBUG
  370. if (debug)
  371. stat_out(" mask-file = '%s'\n", dummy);
  372. #endif
  373. status = XReadBitmapFile(dpy, tablet_win, dummy,
  374. &mask_width_ret, &mask_height_ret, &mask_ret,
  375. &mask_x_hot, &mask_y_hot);
  376. if (status == BitmapSuccess) {
  377. if ((width_ret != mask_width_ret) || (height_ret != mask_height_ret)) {
  378. XFreePixmap(dpy, mask_ret);
  379. mask_ret = 0;
  380. }
  381. }
  382. else
  383. mask_ret = 0;
  384. }
  385. snprintf(last_fname, sizeof(last_fname), "%s", fname);
  386. ChangeTitle();
  387. #ifdef DEBUG
  388. if (debug) {
  389. stat_out("Finished Reading file '%s'\n", last_fname);
  390. stat_out("Leaving Read_File\n");
  391. }
  392. #endif
  393. return (True);
  394. }
  395. /***************************************************************************
  396. * *
  397. * Routine: Write_File *
  398. * *
  399. * Purpose: To write the current icon to the specified filename as *
  400. * either an XPM file or XBM file, depending on the current *
  401. * value of the fileFormat flag. Further, if the current *
  402. * fileFormat is FORMAT_XBM, create a second XBM file which *
  403. * contains a mask for the XBM file just written. *
  404. * *
  405. ***************************************************************************/
  406. Boolean
  407. Write_File(
  408. char *fnameIn )
  409. {
  410. extern int tt_tmpfile_fd;
  411. int i, j;
  412. int mask_needed = False;
  413. Boolean SUN;
  414. char *base_name, *suffix, fname[MAXPATHLEN], *tmp, *tmp2, *vend;
  415. Pixmap scratch_pix;
  416. XImage *scratch_shape, *scratch_mask;
  417. struct stat statbuf; /* Information on a file. */
  418. #ifdef DEBUG
  419. if (debug)
  420. stat_out("Entering Write_File\n");
  421. #endif
  422. SUN = False; /* Assume machine other than SUN */
  423. if ( !fnameIn || !(*fnameIn) )
  424. return False;
  425. tmp = strchr(fnameIn, ':');
  426. tmp2 = strchr(fnameIn, '/');
  427. /*** - convert from "<host>:/..." to a path on the locale host. ***/
  428. if (tmp && tmp2 && (tmp2 == tmp+1))
  429. {
  430. char *netfile, *localfile;
  431. tmp[0] = '\0';
  432. netfile = tt_host_file_netfile(fnameIn, tmp+1);
  433. localfile = tt_netfile_file(netfile);
  434. strncpy(fname, localfile, MAXPATHLEN - 1);
  435. fname[MAXPATHLEN - 1] = 0;
  436. tmp[0] = ':';
  437. tt_free(netfile);
  438. tt_free(localfile);
  439. }
  440. else /* wasn't in form "<host>:/<path>" so use name as is... */
  441. {
  442. snprintf(fname, sizeof(fname), "%s", fnameIn);
  443. }
  444. base_name = strrchr(fname, '/');
  445. if (fname[0]) {
  446. base_name = (base_name ? base_name + 1 : fname);
  447. }
  448. snprintf(last_fname, sizeof(last_fname), "%s", fname);
  449. ChangeTitle();
  450. #ifdef DEBUG
  451. if (debug)
  452. stat_out("Writing file '%s'\n", last_fname);
  453. #endif
  454. if (fileFormat == FORMAT_XPM) {
  455. xpm_WriteAttribs.x_hotspot = X_Hot;
  456. xpm_WriteAttribs.y_hotspot = Y_Hot;
  457. xpm_WriteAttribs.width = icon_width;
  458. xpm_WriteAttribs.height = icon_height;
  459. xpm_WriteAttribs.cpp = 1;
  460. xpm_WriteAttribs.colorsymbols = colorSymbols;
  461. xpm_WriteAttribs.numsymbols = NUM_PENS;
  462. xpm_WriteAttribs.ncolors = NUM_PENS;
  463. xpm_WriteAttribs.valuemask = WRITE_FLAGS;
  464. #ifdef DEBUG
  465. if (debug)
  466. Dump_AttribStruct(&xpm_WriteAttribs);
  467. #endif
  468. status = XpmWriteFileFromPixmap(dpy, fname, color_icon, 0,
  469. &xpm_WriteAttribs);
  470. /*******
  471. status = XpmWriteFileFromPixmap(dpy, fname, color_icon, NULL, NULL);
  472. ********/
  473. if (status != XpmSuccess) {
  474. #ifdef DEBUG
  475. if (debug) {
  476. stat_out("Leaving Write_File - XPM write failed. ");
  477. switch (status) {
  478. case XpmOpenFailed : stat_out("(XpmOpenFailed)\n"); break;
  479. case XpmNoMemory : stat_out("(XpmNoMemory)\n"); break;
  480. default : stat_out("(UNKNOWN cause)\n"); break;
  481. }
  482. }
  483. #endif
  484. return (False);
  485. }
  486. }
  487. else {
  488. /*** FIRST, does a suffix exist? ***/
  489. suffix = strrchr(base_name, '.');
  490. if ((suffix) && ((int)strlen(suffix) > 1))
  491. suffix++;
  492. /*** SECOND, is it a valid suffix? ***/
  493. if (suffix) {
  494. if (strcmp(suffix, "bm") && strcmp(suffix, "xbm"))
  495. suffix = NULL;
  496. }
  497. /*** THIRD, construct the mask filename ***/
  498. if (suffix) {
  499. strncpy(dummy, fname, ((suffix-fname)-1));
  500. dummy[(int) (suffix-fname)-1] = '\0';
  501. strcat(dummy, "_m.");
  502. strcat(dummy, suffix);
  503. }
  504. else {
  505. snprintf(dummy, sizeof(dummy), "%s_m", fname);
  506. }
  507. /*** FOURTH, construct XImages for the shape and mask bitmaps ***/
  508. mask_needed = False;
  509. scratch_shape = XGetImage(dpy, mono_icon, 0, 0, icon_width, icon_height,
  510. AllPlanes, format);
  511. scratch_mask = XGetImage(dpy, mono_icon, 0, 0, icon_width, icon_height,
  512. AllPlanes, format);
  513. if (!scratch_shape || !scratch_mask) {
  514. if (scratch_shape)
  515. XDestroyImage(scratch_shape);
  516. if (scratch_mask)
  517. XDestroyImage(scratch_mask);
  518. return (False);
  519. }
  520. /* is this a SUN machine? */
  521. /* if so use special code else use old code */
  522. vend = ServerVendor(dpy);
  523. if ( strncmp( vend, "Sun", 3) == 0) {
  524. SUN = TRUE;
  525. for (i=0; i<icon_width; i++)
  526. for (j=0; j<icon_height; j++)
  527. if (XGetPixel(scratch_shape, i, j) == Transparent) {
  528. XPutPixel(scratch_shape, i, j, white_pixel);
  529. mask_needed = True;
  530. }
  531. for (i=0; i<icon_width; i++)
  532. for (j=0; j<icon_height; j++)
  533. if (XGetPixel(scratch_mask, i, j) != Transparent)
  534. XPutPixel(scratch_mask, i, j, black_pixel);
  535. else
  536. XPutPixel(scratch_mask, i, j, white_pixel);
  537. }else {
  538. for (i=0; i<icon_width; i++)
  539. for (j=0; j<icon_height; j++)
  540. if (XGetPixel(scratch_shape, i, j) == Transparent) {
  541. XPutPixel(scratch_shape, i, j, black_pixel);
  542. mask_needed = True;
  543. }
  544. for (i=0; i<icon_width; i++)
  545. for (j=0; j<icon_height; j++)
  546. if (XGetPixel(scratch_mask, i, j) != Transparent)
  547. XPutPixel(scratch_mask, i, j, white_pixel);
  548. else
  549. XPutPixel(scratch_mask, i, j, black_pixel);
  550. }
  551. /*** FIFTH, write out the shape and mask bitmaps ***/
  552. scratch_pix = XCreatePixmap(dpy, root, icon_width, icon_height,
  553. DefaultDepth(dpy, screen));
  554. if (!scratch_pix) {
  555. if (scratch_shape)
  556. XDestroyImage(scratch_shape);
  557. if (scratch_mask)
  558. XDestroyImage(scratch_mask);
  559. return (False);
  560. }
  561. /* don't set GXcopyInverte for SUN machines */
  562. if (!SUN)
  563. XSetFunction(dpy, Mono_gc, GXcopyInverted);
  564. XPutImage(dpy, scratch_pix, Mono_gc, scratch_shape, 0, 0, 0, 0,
  565. icon_width, icon_height);
  566. XSetFunction(dpy, Mono_gc, GXcopy);
  567. status = XWriteBitmapFile(dpy, fname, scratch_pix, icon_width, icon_height,
  568. X_Hot, Y_Hot);
  569. if (status != BitmapSuccess)
  570. {
  571. XDestroyImage(scratch_shape);
  572. XDestroyImage(scratch_mask);
  573. XFreePixmap(dpy, scratch_pix);
  574. return (False);
  575. }
  576. if (mask_needed) {
  577. XPutImage(dpy, scratch_pix, Mono_gc, scratch_mask, 0, 0, 0, 0,
  578. icon_width, icon_height);
  579. status = XWriteBitmapFile(dpy, dummy, scratch_pix, icon_width,
  580. icon_height, X_Hot, Y_Hot);
  581. if (status != BitmapSuccess)
  582. {
  583. XDestroyImage(scratch_shape);
  584. XDestroyImage(scratch_mask);
  585. XFreePixmap(dpy, scratch_pix);
  586. return (False);
  587. }
  588. } /***TAG***/
  589. XFreePixmap(dpy, scratch_pix);
  590. XDestroyImage(scratch_shape);
  591. XDestroyImage(scratch_mask);
  592. } /* else */
  593. /* Don't know if this is needed....
  594. if ( SUN )
  595. {
  596. SUN = False;
  597. black_pixel = 0;
  598. white_pixel = 1;
  599. }
  600. */
  601. #ifdef DEBUG
  602. if (debug)
  603. stat_out("Leaving Write_File\n");
  604. #endif
  605. if( (fileFormat != FORMAT_XPM) && (!mask_needed) && (stat(tmpSave, &statbuf) == 0) )
  606. unlink(dummy);
  607. #ifdef __TOOLTALK
  608. if (tt_tmpfile_fd != -1)
  609. send_tt_saved();
  610. #endif
  611. return (True);
  612. }
  613. /***************************************************************************
  614. * *
  615. * Routine: Display_XPMFile *
  616. * *
  617. * Purpose: Assuming that we have successfully read in an XPM file, use *
  618. * the data from the file to render the proper rasters to the *
  619. * color_icon and mono_icon (and their corresponding widgets). *
  620. * *
  621. * Rendering the color icon is straight-forward, since the *
  622. * pixmap generated by Read_File() is already correct. For *
  623. * the mono icon, we extract an XImage for the entire color *
  624. * pixmap, and then convert each pixel individually to one *
  625. * three values: black, white, or transparent. For each pixel, *
  626. * the following test is performed: 1st) compare it to each *
  627. * static color. If a match is found, convert the pixel to *
  628. * the appropriate mono equivalent. 2nd) if the 1st step fails *
  629. * to find a match, try the same comparisons against the *
  630. * dynamic colors. 3rd) if the 2nd step also fails, use the *
  631. * PixelTableLookup() function. *
  632. * *
  633. * Once the coversion process is complete, both the color_icon *
  634. * and mono_icon (and their corresponding widgets) can be *
  635. * rendered. *
  636. * *
  637. ***************************************************************************/
  638. void
  639. Display_XPMFile(
  640. int width,
  641. int height )
  642. {
  643. int converted, i, j, k;
  644. int pixelTableIndex;
  645. XImage *scratch_img, *mono_img, *mask_img;
  646. Pixel cpixel, mpixel;
  647. #ifdef DEBUG
  648. int reset_debug;
  649. #endif
  650. #ifdef DEBUG
  651. if (debug)
  652. stat_out("Entering Display_XPMFile\n");
  653. reset_debug=False;
  654. #endif
  655. /*** resize the color and mono icon windows, and the tablet ***/
  656. /*** to their (new) correct height and width. ***/
  657. Init_Icons(width, height, DO_NOT_SAVE);
  658. /*** Grab an image for both (potentially modified) ***/
  659. /*** color and mono conversions ***/
  660. scratch_img = XGetImage(dpy, pix_ret, 0, 0, width, height,
  661. AllPlanes, format);
  662. mono_img = XGetImage(dpy, pix_ret, 0, 0, width, height,
  663. AllPlanes, format);
  664. mask_img = NULL;
  665. if (shape_ret)
  666. mask_img = XGetImage(dpy, shape_ret, 0, 0, width, height,
  667. AllPlanes, format);
  668. #ifdef DEBUG
  669. if (debug) {
  670. debug = False;
  671. reset_debug = True;
  672. }
  673. #endif
  674. PixelTableClear(); /* force new pixel table now */
  675. for (i=0; i<width; i++)
  676. for (j=0; j<height; j++) {
  677. converted = False;
  678. cpixel = XGetPixel(scratch_img, i, j);
  679. if (mask_img) {
  680. mpixel = XGetPixel(mask_img, i, j);
  681. if (!mpixel) {
  682. cpixel = Transparent;
  683. XPutPixel(scratch_img, i, j, cpixel);
  684. }
  685. } /* if(mask_img) */
  686. for (k = 0; k < NUM_STATICS; k++)
  687. if (cpixel == StaticPen[k]) {
  688. XPutPixel(mono_img, i, j, StaticMono[k]);
  689. converted = True;
  690. } /* if(cpixel...) */
  691. if (!converted) {
  692. for (k = 0; k < NUM_DYNAMICS; k++)
  693. if (cpixel == DynamicPen[k]) {
  694. XPutPixel(mono_img, i, j, DynamicMono[k]);
  695. converted = True;
  696. } /* if(cpixel...) */
  697. } /* if(!converted) */
  698. if (!converted) {
  699. pixelTableIndex = PixelTableLookup (cpixel, False);
  700. XPutPixel(mono_img, i, j, PIXEL_TABLE_MONO(pixelTableIndex));
  701. } /* if(!converted) */
  702. } /* for(j...) */
  703. #ifdef DEBUG
  704. if (reset_debug) {
  705. debug = True;
  706. reset_debug = False;
  707. }
  708. #endif
  709. XPutImage(dpy, color_icon, Color_gc, scratch_img,
  710. 0, 0, 0, 0, width, height);
  711. XPutImage(dpy, mono_icon, Mono_gc, mono_img,
  712. 0, 0, 0, 0, width, height);
  713. /*** this following stuff all gets done regardless ***/
  714. XCopyArea(dpy, color_icon, XtWindow(iconImage),
  715. Color_gc, 0, 0, width, height, 0, 0);
  716. XCopyArea(dpy, mono_icon, XtWindow(monoImage),
  717. Mono_gc, 0, 0, width, height, 0, 0);
  718. icon_width = width;
  719. icon_height = height;
  720. fileFormat = FORMAT_XPM;
  721. XmToggleButtonGadgetSetState(formatMenu_xpm_tb, True, True);
  722. /* This line is not really needed since an Exposed event will be generated */
  723. Repaint_Exposed_Tablet();
  724. XDestroyImage(scratch_img);
  725. XFreePixmap(dpy, pix_ret);
  726. if (shape_ret)
  727. XFreePixmap(dpy, shape_ret);
  728. #ifdef DEBUG
  729. if (debug)
  730. stat_out("Leaving Display_XPMFile\n");
  731. #endif
  732. }
  733. /***************************************************************************
  734. * *
  735. * Routine: Display_XBMFile *
  736. * *
  737. * Purpose: Assuming that we have successfully read in an X bitmap file *
  738. * (and, potentially, a mask file as well), use the data from *
  739. * the file(s) to render the proper rasters to the color_icon *
  740. * and mono_icon (and their corresponding widgets). *
  741. * *
  742. * Rendering the bitmap is straight-forward (create a scratch *
  743. * pixmap of the correct depth and copy-plane the just-read *
  744. * bitmap onto it). If there is a mask bitmap as well, then *
  745. * the scratch pixmap must be modified such that for every *
  746. * 0 bit in the mask bitmap, the corresponding pixel of the *
  747. * scratch pixmap should be set to the Transparent pixel. *
  748. * Once this is done, the scratch pixmap is copied to both *
  749. * the color_icon and mono_icon (since, for bitmaps, they're *
  750. * identical). Then free the scratch pixmap. *
  751. * *
  752. ***************************************************************************/
  753. void
  754. Display_XBMFile(
  755. int width,
  756. int height )
  757. {
  758. int i, j;
  759. XImage *test_img, *scratch_img;
  760. Pixmap scratch_pix;
  761. #ifdef DEBUG
  762. if (debug)
  763. stat_out("Entering Display_XBMFile\n");
  764. #endif
  765. scratch_pix = XCreatePixmap(dpy, root, width, height,
  766. DefaultDepth(dpy, screen));
  767. Init_Icons(width, height, DO_NOT_SAVE);
  768. XSetBackground(dpy, scratch_gc, white_pixel);
  769. XFillRectangle(dpy, scratch_pix, scratch_gc, 0, 0, width, height);
  770. XSetForeground(dpy, scratch_gc, black_pixel);
  771. XCopyPlane(dpy, pix_ret, scratch_pix, scratch_gc, 0, 0,
  772. width, height, 0, 0, 1);
  773. if (mask_ret) {
  774. test_img = XGetImage(dpy, mask_ret, 0, 0, width, height,
  775. AllPlanes, format);
  776. scratch_img = XGetImage(dpy, scratch_pix, 0, 0, width, height,
  777. AllPlanes, format);
  778. for (i=0; i<width; i++)
  779. for (j=0; j<height; j++)
  780. if (!XGetPixel(test_img, i, j))
  781. XPutPixel(scratch_img, i, j, Transparent);
  782. XPutImage(dpy, scratch_pix, scratch_gc, scratch_img,
  783. 0, 0, 0, 0, width, height);
  784. } /* if(mask_ret) */
  785. XCopyArea(dpy, scratch_pix, color_icon, Color_gc, 0, 0,
  786. width, height, 0, 0);
  787. XCopyArea(dpy, scratch_pix, mono_icon, Mono_gc, 0, 0,
  788. width, height, 0, 0);
  789. XCopyArea(dpy, color_icon, XtWindow(iconImage),
  790. Color_gc, 0, 0, width, height, 0, 0);
  791. XCopyArea(dpy, mono_icon, XtWindow(monoImage),
  792. Mono_gc, 0, 0, width, height, 0, 0);
  793. icon_width = width;
  794. icon_height = height;
  795. fileFormat = FORMAT_XBM;
  796. XmToggleButtonGadgetSetState(formatMenu_xbm_tb, True, True);
  797. /* This line is not really needed since an Exposed event will be generated */
  798. Repaint_Exposed_Tablet();
  799. if (mask_ret) {
  800. XDestroyImage(test_img);
  801. XDestroyImage(scratch_img);
  802. }
  803. XFreePixmap(dpy, scratch_pix);
  804. XFreePixmap(dpy, pix_ret);
  805. if (mask_ret)
  806. XFreePixmap(dpy, mask_ret);
  807. #ifdef DEBUG
  808. if (debug)
  809. stat_out("Leaving Display_XBMFile\n");
  810. #endif
  811. }
  812. /***************************************************************************
  813. * *
  814. * Routine: SetFileIODialogInfo *
  815. * *
  816. * Purpose: Set FileIODialog information... title, path, etc. *
  817. * *
  818. ***************************************************************************/
  819. void
  820. SetFileIODialogInfo( void )
  821. {
  822. static int currentTitle = SAVE_AS; /* initial title is for Save_As... */
  823. static XmString saveTitle = NULL;
  824. static XmString openTitle = NULL;
  825. static XmString saveLabel = NULL;
  826. static XmString openLabel = NULL;
  827. static XmString OpenOKLabel = NULL;
  828. static XmString SaveOKLabel = NULL;
  829. static char *untitledStr = NULL;
  830. static Widget textWidget = NULL;
  831. static char newName[MAX_FNAME];
  832. static char dirStr[MAX_FNAME];
  833. static char tmpStr[MAX_FNAME];
  834. Arg args[10];
  835. int n,dirlen=0,filelen=0,tst, ln;
  836. char *strOrig = NULL;
  837. XmString tmpXmStr;
  838. char tmp[MAX_FNAME];
  839. char *tmp1= NULL;
  840. char *tmp2= NULL;
  841. int c;
  842. int startSelect, endSelect;
  843. if (DialogFlag == OPEN) /* Dialog is for File-Open menu item */
  844. {
  845. /* set title to "Icon Editor - Open File" if needed */
  846. if (!openTitle)
  847. openTitle = GETXMSTR(2,8, "Icon Editor - Open File");
  848. n = 0;
  849. XtSetArg (args[n], XmNdialogTitle, openTitle); n++;
  850. XtSetValues (fileIODialog, args, n);
  851. currentTitle = OPEN;
  852. /* set selection label to "Open File" */
  853. if (!openLabel)
  854. openLabel = GETXMSTR(2,17, "Enter file name:");
  855. n = 0;
  856. XtSetArg (args[n], XmNselectionLabelString, openLabel); n++;
  857. OpenOKLabel = GETXMSTR(2,22, "Open");
  858. XtSetArg (args[n], XmNokLabelString, OpenOKLabel); n++;
  859. XtSetValues (fileIODialog, args, n);
  860. }
  861. else /* Dialog is for File-Save or File-Save_As menu item */
  862. {
  863. /* set title to "Icon Editor - Save As" if needed */
  864. if (!saveTitle)
  865. saveTitle = GETXMSTR(2,6, "Icon Editor - Save As");
  866. n = 0;
  867. XtSetArg (args[n], XmNdialogTitle, saveTitle); n++;
  868. XtSetValues (fileIODialog, args, n);
  869. currentTitle = SAVE_AS;
  870. /* set selection label to "Enter file name:" */
  871. if (!saveLabel)
  872. saveLabel = GETXMSTR(2,16, "Enter file name:");
  873. n = 0;
  874. XtSetArg (args[n], XmNselectionLabelString, saveLabel); n++;
  875. SaveOKLabel = GETXMSTR(2,24, "Save");
  876. XtSetArg (args[n], XmNokLabelString, SaveOKLabel); n++;
  877. XtSetValues (fileIODialog, args, n);
  878. }
  879. /* */
  880. /* set string to "UNTITLED" with appropriate suffix */
  881. /* when apropriate */
  882. if (!untitledStr)
  883. untitledStr = GETSTR(2,20, "UNTITLED");
  884. if (!textWidget)
  885. textWidget = XmFileSelectionBoxGetChild(fileIODialog, XmDIALOG_TEXT);
  886. strOrig = XmTextFieldGetString(textWidget);
  887. dirStr[0] = '\0';
  888. newName[0]='\0';
  889. tmpStr[0]='\0';
  890. startSelect = 0;
  891. /* prepare to test */
  892. tmp1 = strrchr(strOrig, '.');
  893. snprintf(tmpStr, sizeof(tmpStr), "%s.m.pm", untitledStr);
  894. tst=strcmp(last_fname, tmpStr);
  895. if ( tst==0 ) {/* untitled */
  896. if ( tmp1 ) { /* previous string exists */
  897. if (currentTitle != SAVE_AS) {
  898. snprintf(newName, sizeof(newName), "%s", strOrig);
  899. } else {
  900. snprintf(newName, sizeof(newName), "%s.m.pm", untitledStr);
  901. }
  902. /* Update the FSB */
  903. XmFileSelectionDoSearch(fileIODialog,(XmString)NULL);
  904. }
  905. else { /* First time arownd */
  906. if (strOrig && strOrig[0]!='\0')
  907. snprintf(newName, sizeof(newName), "%s", strOrig);
  908. else {
  909. snprintf(newName, sizeof(newName), "%s.m.pm", untitledStr);
  910. }
  911. XSync(dpy, 0);
  912. /* rebuild last file name */
  913. last_fname[0] = '\0';
  914. strcpy(last_fname, dirStr);
  915. strcat(last_fname, newName);
  916. }
  917. }
  918. else { /* not untitled */
  919. tmp1= strrchr(last_fname, '/');
  920. /*
  921. * Check if any '/' characters found
  922. */
  923. if (tmp1)
  924. {
  925. /*
  926. * Strip path into directory name and file name
  927. */
  928. c = tmp1[1];
  929. tmp2 = strchr(tmp1, c);
  930. if(tmp2) {
  931. snprintf(newName, sizeof(newName), "%s", tmp2);
  932. }
  933. /* make and insert the directory name */
  934. ln = strlen(last_fname) - strlen(tmp1);
  935. strncpy(dirStr, last_fname, ln);
  936. dirStr[ln] = '\0';
  937. }
  938. else
  939. {
  940. /*
  941. * Path is a simple filename
  942. * Set filename to be path name
  943. * Set directory name = "."
  944. */
  945. strcpy(newName, last_fname);
  946. dirStr[0] = '.';
  947. dirStr[1] = '\0';
  948. }
  949. tmpXmStr = XmStringCreateLocalized (dirStr);
  950. n = 0;
  951. XtSetArg (args[n], XmNdirectory, tmpXmStr); n++;
  952. XtSetValues (fileIODialog, args, n);
  953. XmStringFree(tmpXmStr);
  954. }
  955. ln=0;
  956. /* set the Highlighted string */
  957. newName[strlen(newName)+1] ='\0';
  958. tmp1 = strchr(newName, '.');
  959. if (tmp1 && tmp1[0]!='\0') ln = (int)strlen(tmp1);
  960. endSelect = strlen(newName)- ln;
  961. /* now set the text field and set selection for highlighted portion */
  962. XmTextFieldSetString(textWidget, newName);
  963. XmTextFieldSetSelection(textWidget, startSelect, endSelect, CurrentTime);
  964. XSync(dpy, 0);
  965. XmProcessTraversal(textWidget, XmTRAVERSE_CURRENT);
  966. XSync(dpy, 0);
  967. XtFree(strOrig);
  968. /* if file lists are being used, re-scan the directory contents */
  969. /* if (xrdb.useFileLists)
  970. XmFileSelectionDoSearch(fileIODialog, NULL);*/
  971. }
  972. #ifdef DEBUG
  973. /***************************************************************************
  974. * *
  975. * Routine: Dump_AttribStruct #ifdef DEBUG only (for bba) *
  976. * *
  977. * Purpose: Print out the entier contents of the XpmAttributes struct. *
  978. * *
  979. ***************************************************************************/
  980. int
  981. Dump_AttribStruct(
  982. XpmAttributes *xpma )
  983. {
  984. int i, j;
  985. if (xpma->valuemask) {
  986. stat_out(" valuemask: (");
  987. if (xpma->valuemask & XpmVisual)
  988. stat_out("XpmVisual|");
  989. if (xpma->valuemask & XpmColormap)
  990. stat_out("XpmColormap|");
  991. if (xpma->valuemask & XpmDepth)
  992. stat_out("XpmDepth|");
  993. if (xpma->valuemask & XpmSize)
  994. stat_out("XpmSize|");
  995. if (xpma->valuemask & XpmHotspot)
  996. stat_out("XpmHotspot|");
  997. if (xpma->valuemask & XpmCharsPerPixel)
  998. stat_out("XpmCharsPerPixel|");
  999. if (xpma->valuemask & XpmColorSymbols)
  1000. stat_out("XpmColorSymbols|");
  1001. if (xpma->valuemask & XpmRgbFilename)
  1002. stat_out("XpmRgbFilename|");
  1003. if (xpma->valuemask & XpmInfos)
  1004. stat_out("XpmInfos");
  1005. stat_out(")\n");
  1006. }
  1007. else
  1008. stat_out(" valuemask: NULL\n");
  1009. stat_out(" Colormap: %d\n", xpma->colormap);
  1010. stat_out(" depth: %d\n", xpma->depth);
  1011. stat_out(" width: %d\n", xpma->width);
  1012. stat_out(" height: %d\n", xpma->height);
  1013. stat_out(" x_hotspot: %d\n", xpma->x_hotspot);
  1014. stat_out(" y_hotspot: %d\n", xpma->y_hotspot);
  1015. stat_out(" cpp: %d\n", xpma->cpp);
  1016. stat_out(" npixels: %d\n", xpma->npixels);
  1017. if (xpma->npixels) {
  1018. stat_out(" Pixels: ");
  1019. for (i=0; i<xpma->npixels; i++) {
  1020. stat_out("%d, ", xpma->pixels[i]);
  1021. if (i%10 == 0)
  1022. stat_out("\n");
  1023. }
  1024. stat_out("\n");
  1025. }
  1026. stat_out(" numsymbols: %d\n", xpma->numsymbols);
  1027. if (xpma->numsymbols) {
  1028. for (i=0; i<xpma->numsymbols; i++)
  1029. stat_out(" %18s | %18s | %d\n", xpma->colorsymbols[i].name,
  1030. xpma->colorsymbols[i].value, xpma->colorsymbols[i].pixel);
  1031. }
  1032. stat_out(" rgb_fname: \"%s\"\n",((xpma->rgb_fname)?(xpma->rgb_fname):"(nil)"));
  1033. stat_out(" ---------------------------------\n");
  1034. stat_out(" ncolors: %d\n", xpma->ncolors);
  1035. if (xpma->ncolors) {
  1036. for (i=0; i<xpma->ncolors; i++)
  1037. if (xpma->colorTable[i][0] != NULL)
  1038. stat_out(" %3d \"%1s\" \"%18s\" \"%5s\" \"%5s\" \"%5s\" \"%5s\"\n",
  1039. i+1,
  1040. ((xpma->colorTable[i][0])?(xpma->colorTable[i][0]):"(nil)"),
  1041. ((xpma->colorTable[i][1])?(xpma->colorTable[i][1]):"(nil)"),
  1042. ((xpma->colorTable[i][2])?(xpma->colorTable[i][2]):"(nil)"),
  1043. ((xpma->colorTable[i][3])?(xpma->colorTable[i][3]):"(nil)"),
  1044. ((xpma->colorTable[i][4])?(xpma->colorTable[i][4]):"(nil)"),
  1045. ((xpma->colorTable[i][5])?(xpma->colorTable[i][5]):"(nil)")
  1046. );
  1047. }
  1048. stat_out(" hints_cmt: \"%s\"\n",((xpma->hints_cmt)?(xpma->hints_cmt):"(nil)"));
  1049. stat_out(" colors_cmt: \"%s\"\n",((xpma->colors_cmt)?(xpma->colors_cmt):"(nil)"));
  1050. stat_out(" pixels_cmt: \"%s\"\n",((xpma->pixels_cmt)?(xpma->pixels_cmt):"(nil)"));
  1051. stat_out(" mask_pixel: 0x%x\n",xpma->mask_pixel);
  1052. }
  1053. #endif