fileIO.c 38 KB

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