Fl_File_Icon2.cxx 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. //
  2. // "$Id: Fl_File_Icon2.cxx 7903 2010-11-28 21:06:39Z matt $"
  3. //
  4. // Fl_File_Icon system icon routines.
  5. //
  6. // KDE icon code donated by Maarten De Boer.
  7. //
  8. // Copyright 1999-2010 by Michael Sweet.
  9. //
  10. // This library is free software; you can redistribute it and/or
  11. // modify it under the terms of the GNU Library General Public
  12. // License as published by the Free Software Foundation; either
  13. // version 2 of the License, or (at your option) any later version.
  14. //
  15. // This library is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. // Library General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU Library General Public
  21. // License along with this library; if not, write to the Free Software
  22. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  23. // USA.
  24. //
  25. // Please report all bugs and problems on the following page:
  26. //
  27. // http://www.fltk.org/str.php
  28. //
  29. // Contents:
  30. //
  31. // Fl_File_Icon::load() - Load an icon file...
  32. // Fl_File_Icon::load_fti() - Load an SGI-format FTI file...
  33. // Fl_File_Icon::load_image() - Load an image icon file...
  34. // Fl_File_Icon::load_system_icons() - Load the standard system icons/filetypes.
  35. // load_kde_icons() - Load KDE icon files.
  36. // load_kde_mimelnk() - Load a KDE "mimelnk" file.
  37. // kde_to_fltk_pattern() - Convert a KDE pattern to a FLTK pattern.
  38. // get_kde_val() - Get a KDE value.
  39. //
  40. //
  41. // Include necessary header files...
  42. //
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <FL/fl_utf8.h>
  46. #include "flstring.h"
  47. #include <ctype.h>
  48. #include <errno.h>
  49. #include <FL/math.h>
  50. #include <sys/types.h>
  51. #include <sys/stat.h>
  52. #if defined(WIN32) && !defined(__CYGWIN__)
  53. # include <io.h>
  54. # define F_OK 0
  55. // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
  56. // on Windows, which is supposed to be POSIX compliant...
  57. # define access _access
  58. #else
  59. # include <unistd.h>
  60. #endif // WIN32
  61. #include <FL/Fl_File_Icon.H>
  62. #include <FL/Fl_Shared_Image.H>
  63. #include <FL/Fl_Widget.H>
  64. #include <FL/fl_draw.H>
  65. #include <FL/filename.H>
  66. //
  67. // Define missing POSIX/XPG4 macros as needed...
  68. //
  69. #ifndef S_ISDIR
  70. # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
  71. # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
  72. # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
  73. # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
  74. # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
  75. #endif /* !S_ISDIR */
  76. //
  77. // Local functions...
  78. //
  79. static void load_kde_icons(const char *directory, const char *icondir);
  80. static void load_kde_mimelnk(const char *filename, const char *icondir);
  81. static char *kde_to_fltk_pattern(const char *kdepattern);
  82. static char *get_kde_val(char *str, const char *key);
  83. //
  84. // Local globals...
  85. //
  86. static const char *kdedir = NULL;
  87. /**
  88. Loads the specified icon image. The format is deduced from the filename.
  89. \param[in] f filename
  90. */
  91. void
  92. Fl_File_Icon::load(const char *f) // I - File to read from
  93. {
  94. int i; // Load status...
  95. const char *ext; // File extension
  96. ext = fl_filename_ext(f);
  97. if (ext && strcmp(ext, ".fti") == 0)
  98. i = load_fti(f);
  99. else
  100. i = load_image(f);
  101. if (i)
  102. {
  103. Fl::warning("Fl_File_Icon::load(): Unable to load icon file \"%s\".", f);
  104. return;
  105. }
  106. }
  107. /**
  108. Loads an SGI icon file.
  109. \param[in] fti icon filename
  110. \return 0 on success, non-zero on error
  111. */
  112. int // O - 0 on success, non-zero on error
  113. Fl_File_Icon::load_fti(const char *fti) // I - File to read from
  114. {
  115. FILE *fp; // File pointer
  116. int ch; // Current character
  117. char command[255], // Command string ("vertex", etc.)
  118. params[255], // Parameter string ("10.0,20.0", etc.)
  119. *ptr; // Pointer into strings
  120. int outline; // Outline polygon
  121. // Try to open the file...
  122. if ((fp = fl_fopen(fti, "rb")) == NULL)
  123. {
  124. Fl::error("Fl_File_Icon::load_fti(): Unable to open \"%s\" - %s",
  125. fti, strerror(errno));
  126. return -1;
  127. }
  128. // Read the entire file, adding data as needed...
  129. outline = 0;
  130. while ((ch = getc(fp)) != EOF)
  131. {
  132. // Skip whitespace
  133. if (isspace(ch))
  134. continue;
  135. // Skip comments starting with "#"...
  136. if (ch == '#')
  137. {
  138. while ((ch = getc(fp)) != EOF)
  139. if (ch == '\n')
  140. break;
  141. if (ch == EOF)
  142. break;
  143. else
  144. continue;
  145. }
  146. // OK, this character better be a letter...
  147. if (!isalpha(ch))
  148. {
  149. Fl::error("Fl_File_Icon::load_fti(): Expected a letter at file position %ld (saw '%c')",
  150. ftell(fp) - 1, ch);
  151. break;
  152. }
  153. // Scan the command name...
  154. ptr = command;
  155. *ptr++ = ch;
  156. while ((ch = getc(fp)) != EOF)
  157. {
  158. if (ch == '(')
  159. break;
  160. else if (ptr < (command + sizeof(command) - 1))
  161. *ptr++ = ch;
  162. }
  163. *ptr++ = '\0';
  164. // Make sure we stopped on a parenthesis...
  165. if (ch != '(')
  166. {
  167. Fl::error("Fl_File_Icon::load_fti(): Expected a ( at file position %ld (saw '%c')",
  168. ftell(fp) - 1, ch);
  169. break;
  170. }
  171. // Scan the parameters...
  172. ptr = params;
  173. while ((ch = getc(fp)) != EOF)
  174. {
  175. if (ch == ')')
  176. break;
  177. else if (ptr < (params + sizeof(params) - 1))
  178. *ptr++ = ch;
  179. }
  180. *ptr++ = '\0';
  181. // Make sure we stopped on a parenthesis...
  182. if (ch != ')')
  183. {
  184. Fl::error("Fl_File_Icon::load_fti(): Expected a ) at file position %ld (saw '%c')",
  185. ftell(fp) - 1, ch);
  186. break;
  187. }
  188. // Make sure the next character is a semicolon...
  189. if ((ch = getc(fp)) != ';')
  190. {
  191. Fl::error("Fl_File_Icon::load_fti(): Expected a ; at file position %ld (saw '%c')",
  192. ftell(fp) - 1, ch);
  193. break;
  194. }
  195. // Now process the command...
  196. if (strcmp(command, "color") == 0)
  197. {
  198. // Set the color; for negative colors blend the two primaries to
  199. // produce a composite color. Also, the following symbolic color
  200. // names are understood:
  201. //
  202. // name FLTK color
  203. // ------------- ----------
  204. // iconcolor FL_ICON_COLOR; mapped to the icon color in
  205. // Fl_File_Icon::draw()
  206. // shadowcolor FL_DARK3
  207. // outlinecolor FL_BLACK
  208. if (strcmp(params, "iconcolor") == 0)
  209. add_color(FL_ICON_COLOR);
  210. else if (strcmp(params, "shadowcolor") == 0)
  211. add_color(FL_DARK3);
  212. else if (strcmp(params, "outlinecolor") == 0)
  213. add_color(FL_BLACK);
  214. else
  215. {
  216. int c = atoi(params); // Color value
  217. if (c < 0)
  218. {
  219. // Composite color; compute average...
  220. c = -c;
  221. add_color(fl_color_average((Fl_Color)(c >> 4),
  222. (Fl_Color)(c & 15), 0.5f));
  223. }
  224. else
  225. add_color((Fl_Color)c);
  226. }
  227. }
  228. else if (strcmp(command, "bgnline") == 0)
  229. add(LINE);
  230. else if (strcmp(command, "bgnclosedline") == 0)
  231. add(CLOSEDLINE);
  232. else if (strcmp(command, "bgnpolygon") == 0)
  233. add(POLYGON);
  234. else if (strcmp(command, "bgnoutlinepolygon") == 0)
  235. {
  236. add(OUTLINEPOLYGON);
  237. outline = add(0) - data_;
  238. add(0);
  239. }
  240. else if (strcmp(command, "endoutlinepolygon") == 0 && outline)
  241. {
  242. unsigned cval; // Color value
  243. // Set the outline color; see above for valid values...
  244. if (strcmp(params, "iconcolor") == 0)
  245. cval = FL_ICON_COLOR;
  246. else if (strcmp(params, "shadowcolor") == 0)
  247. cval = FL_DARK3;
  248. else if (strcmp(params, "outlinecolor") == 0)
  249. cval = FL_BLACK;
  250. else
  251. {
  252. int c = atoi(params); // Color value
  253. if (c < 0)
  254. {
  255. // Composite color; compute average...
  256. c = -c;
  257. cval = fl_color_average((Fl_Color)(c >> 4), (Fl_Color)(c & 15), 0.5f);
  258. }
  259. else
  260. cval = c;
  261. }
  262. // Store outline color...
  263. data_[outline] = cval >> 16;
  264. data_[outline + 1] = cval;
  265. outline = 0;
  266. add(END);
  267. }
  268. else if (strncmp(command, "end", 3) == 0)
  269. add(END);
  270. else if (strcmp(command, "vertex") == 0)
  271. {
  272. float x, y; // Coordinates of vertex
  273. if (sscanf(params, "%f,%f", &x, &y) != 2)
  274. break;
  275. add_vertex((short)(int)rint(x * 100.0), (short)(int)rint(y * 100.0));
  276. }
  277. else
  278. {
  279. Fl::error("Fl_File_Icon::load_fti(): Unknown command \"%s\" at file position %ld.",
  280. command, ftell(fp) - 1);
  281. break;
  282. }
  283. }
  284. // Close the file and return...
  285. fclose(fp);
  286. #ifdef DEBUG
  287. printf("Icon File \"%s\":\n", fti);
  288. for (int i = 0; i < num_data_; i ++)
  289. printf(" %d,\n", data_[i]);
  290. #endif /* DEBUG */
  291. return 0;
  292. }
  293. /**
  294. Load an image icon file from an image filename.
  295. \param[in] ifile image filename
  296. \return 0 on success, non-zero on error
  297. */
  298. int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
  299. {
  300. Fl_Shared_Image *img; // Image file
  301. img = Fl_Shared_Image::get(ifile);
  302. if (!img || !img->count() || !img->w() || !img->h()) return -1;
  303. if (img->count() == 1) {
  304. int x, y; // X & Y in image
  305. int startx; // Starting X coord
  306. Fl_Color c, // Current color
  307. temp; // Temporary color
  308. const uchar *row; // Pointer into image
  309. // Loop through grayscale or RGB image...
  310. for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld())
  311. {
  312. for (x = 0, startx = 0, c = (Fl_Color)-1;
  313. x < img->w();
  314. x ++, row += img->d())
  315. {
  316. switch (img->d())
  317. {
  318. case 1 :
  319. temp = fl_rgb_color(row[0], row[0], row[0]);
  320. break;
  321. case 2 :
  322. if (row[1] > 127)
  323. temp = fl_rgb_color(row[0], row[0], row[0]);
  324. else
  325. temp = (Fl_Color)-1;
  326. break;
  327. case 3 :
  328. temp = fl_rgb_color(row[0], row[1], row[2]);
  329. break;
  330. default :
  331. if (row[3] > 127)
  332. temp = fl_rgb_color(row[0], row[1], row[2]);
  333. else
  334. temp = (Fl_Color)-1;
  335. break;
  336. }
  337. if (temp != c)
  338. {
  339. if (x > startx && c != (Fl_Color)-1)
  340. {
  341. add_color(c);
  342. add(POLYGON);
  343. add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  344. add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  345. add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  346. add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  347. add(END);
  348. }
  349. c = temp;
  350. startx = x;
  351. }
  352. }
  353. if (x > startx && c != (Fl_Color)-1)
  354. {
  355. add_color(c);
  356. add(POLYGON);
  357. add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  358. add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  359. add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  360. add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  361. add(END);
  362. }
  363. }
  364. } else {
  365. int i, j; // Looping vars
  366. int ch; // Current character
  367. int newch; // New character
  368. int bg; // Background color
  369. char val[16]; // Color value
  370. const char *lineptr, // Pointer into line
  371. *const*ptr; // Pointer into data array
  372. int ncolors, // Number of colors
  373. chars_per_color; // Characters per color
  374. Fl_Color *colors; // Colors
  375. int red, green, blue; // Red, green, and blue values
  376. int x, y; // X & Y in image
  377. int startx; // Starting X coord
  378. // Get the pixmap data...
  379. ptr = img->data();
  380. sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
  381. colors = new Fl_Color[1 << (chars_per_color * 8)];
  382. // Read the colormap...
  383. memset(colors, 0, sizeof(Fl_Color) << (chars_per_color * 8));
  384. bg = ' ';
  385. ptr ++;
  386. if (ncolors < 0) {
  387. // Read compressed colormap...
  388. const uchar *cmapptr;
  389. ncolors = -ncolors;
  390. for (i = 0, cmapptr = (const uchar *)*ptr; i < ncolors; i ++, cmapptr += 4)
  391. colors[cmapptr[0]] = fl_rgb_color(cmapptr[1], cmapptr[2], cmapptr[3]);
  392. ptr ++;
  393. } else {
  394. for (i = 0; i < ncolors; i ++, ptr ++) {
  395. // Get the color's character
  396. lineptr = *ptr;
  397. ch = *lineptr++;
  398. if (chars_per_color > 1) ch = (ch << 8) | *lineptr++;
  399. // Get the color value...
  400. if ((lineptr = strstr(lineptr, "c ")) == NULL) {
  401. // No color; make this black...
  402. colors[ch] = FL_BLACK;
  403. } else if (lineptr[2] == '#') {
  404. // Read the RGB triplet...
  405. lineptr += 3;
  406. for (j = 0; j < 12; j ++)
  407. if (!isxdigit(lineptr[j]))
  408. break;
  409. switch (j) {
  410. case 0 :
  411. bg = ch;
  412. default :
  413. red = green = blue = 0;
  414. break;
  415. case 3 :
  416. val[0] = lineptr[0];
  417. val[1] = '\0';
  418. red = 255 * strtol(val, NULL, 16) / 15;
  419. val[0] = lineptr[1];
  420. val[1] = '\0';
  421. green = 255 * strtol(val, NULL, 16) / 15;
  422. val[0] = lineptr[2];
  423. val[1] = '\0';
  424. blue = 255 * strtol(val, NULL, 16) / 15;
  425. break;
  426. case 6 :
  427. case 9 :
  428. case 12 :
  429. j /= 3;
  430. val[0] = lineptr[0];
  431. val[1] = lineptr[1];
  432. val[2] = '\0';
  433. red = strtol(val, NULL, 16);
  434. val[0] = lineptr[j + 0];
  435. val[1] = lineptr[j + 1];
  436. val[2] = '\0';
  437. green = strtol(val, NULL, 16);
  438. val[0] = lineptr[2 * j + 0];
  439. val[1] = lineptr[2 * j + 1];
  440. val[2] = '\0';
  441. blue = strtol(val, NULL, 16);
  442. break;
  443. }
  444. colors[ch] = fl_rgb_color((uchar)red, (uchar)green, (uchar)blue);
  445. } else {
  446. // Read a color name...
  447. if (strncasecmp(lineptr + 2, "white", 5) == 0) colors[ch] = FL_WHITE;
  448. else if (strncasecmp(lineptr + 2, "black", 5) == 0) colors[ch] = FL_BLACK;
  449. else if (strncasecmp(lineptr + 2, "none", 4) == 0) {
  450. colors[ch] = FL_BLACK;
  451. bg = ch;
  452. } else colors[ch] = FL_GRAY;
  453. }
  454. }
  455. }
  456. // Read the image data...
  457. for (y = 0; y < img->h(); y ++, ptr ++) {
  458. lineptr = *ptr;
  459. startx = 0;
  460. ch = bg;
  461. for (x = 0; x < img->w(); x ++) {
  462. newch = *lineptr++;
  463. if (chars_per_color > 1) newch = (newch << 8) | *lineptr++;
  464. if (newch != ch) {
  465. if (ch != bg) {
  466. add_color(colors[ch]);
  467. add(POLYGON);
  468. add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  469. add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  470. add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  471. add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  472. add(END);
  473. }
  474. ch = newch;
  475. startx = x;
  476. }
  477. }
  478. if (ch != bg) {
  479. add_color(colors[ch]);
  480. add(POLYGON);
  481. add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  482. add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
  483. add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  484. add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
  485. add(END);
  486. }
  487. }
  488. // Free the colormap...
  489. delete[] colors;
  490. }
  491. img->release();
  492. #ifdef DEBUG
  493. printf("Icon File \"%s\":\n", xpm);
  494. for (i = 0; i < num_data_; i ++)
  495. printf(" %d,\n", data_[i]);
  496. #endif // DEBUG
  497. return 0;
  498. }
  499. /**
  500. Loads all system-defined icons. This call is useful when using the
  501. FileChooser widget and should be used when the application starts:
  502. \code
  503. Fl_File_Icon::load_system_icons();
  504. \endcode
  505. */
  506. void
  507. Fl_File_Icon::load_system_icons(void) {
  508. int i; // Looping var
  509. Fl_File_Icon *icon; // New icons
  510. char filename[1024]; // Filename
  511. char icondir[1024]; // Icon directory
  512. static int init = 0; // Have the icons been initialized?
  513. const char * const icondirs[] = {
  514. "Bluecurve", // Icon directories to look for, in order
  515. "crystalsvg",
  516. "default.kde",
  517. "hicolor",
  518. NULL
  519. };
  520. static short plain[] = { // Plain file icon
  521. COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
  522. VERTEX, 2000, 1000, VERTEX, 2000, 9000,
  523. VERTEX, 6000, 9000, VERTEX, 8000, 7000,
  524. VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
  525. VERTEX, 6000, 9000, VERTEX, 6000, 7000,
  526. VERTEX, 8000, 7000, END,
  527. COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
  528. VERTEX, 8000, 7000, VERTEX, 8000, 1000,
  529. VERTEX, 2000, 1000, END, LINE, VERTEX, 3000, 7000,
  530. VERTEX, 5000, 7000, END, LINE, VERTEX, 3000, 6000,
  531. VERTEX, 5000, 6000, END, LINE, VERTEX, 3000, 5000,
  532. VERTEX, 7000, 5000, END, LINE, VERTEX, 3000, 4000,
  533. VERTEX, 7000, 4000, END, LINE, VERTEX, 3000, 3000,
  534. VERTEX, 7000, 3000, END, LINE, VERTEX, 3000, 2000,
  535. VERTEX, 7000, 2000, END,
  536. END
  537. };
  538. static short image[] = { // Image file icon
  539. COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
  540. VERTEX, 2000, 1000, VERTEX, 2000, 9000,
  541. VERTEX, 6000, 9000, VERTEX, 8000, 7000,
  542. VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
  543. VERTEX, 6000, 9000, VERTEX, 6000, 7000,
  544. VERTEX, 8000, 7000, END,
  545. COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
  546. VERTEX, 8000, 7000, VERTEX, 8000, 1000,
  547. VERTEX, 2000, 1000, END,
  548. COLOR, 0, FL_RED, POLYGON, VERTEX, 3500, 2500,
  549. VERTEX, 3000, 3000, VERTEX, 3000, 4000,
  550. VERTEX, 3500, 4500, VERTEX, 4500, 4500,
  551. VERTEX, 5000, 4000, VERTEX, 5000, 3000,
  552. VERTEX, 4500, 2500, END,
  553. COLOR, 0, FL_GREEN, POLYGON, VERTEX, 5500, 2500,
  554. VERTEX, 5000, 3000, VERTEX, 5000, 4000,
  555. VERTEX, 5500, 4500, VERTEX, 6500, 4500,
  556. VERTEX, 7000, 4000, VERTEX, 7000, 3000,
  557. VERTEX, 6500, 2500, END,
  558. COLOR, 0, FL_BLUE, POLYGON, VERTEX, 4500, 3500,
  559. VERTEX, 4000, 4000, VERTEX, 4000, 5000,
  560. VERTEX, 4500, 5500, VERTEX, 5500, 5500,
  561. VERTEX, 6000, 5000, VERTEX, 6000, 4000,
  562. VERTEX, 5500, 3500, END,
  563. END
  564. };
  565. static short dir[] = { // Directory icon
  566. COLOR, -1, -1, POLYGON, VERTEX, 1000, 1000,
  567. VERTEX, 1000, 7500, VERTEX, 9000, 7500,
  568. VERTEX, 9000, 1000, END,
  569. POLYGON, VERTEX, 1000, 7500, VERTEX, 2500, 9000,
  570. VERTEX, 5000, 9000, VERTEX, 6500, 7500, END,
  571. COLOR, 0, FL_WHITE, LINE, VERTEX, 1500, 1500,
  572. VERTEX, 1500, 7000, VERTEX, 9000, 7000, END,
  573. COLOR, 0, FL_BLACK, LINE, VERTEX, 9000, 7500,
  574. VERTEX, 9000, 1000, VERTEX, 1000, 1000, END,
  575. COLOR, 0, FL_GRAY, LINE, VERTEX, 1000, 1000,
  576. VERTEX, 1000, 7500, VERTEX, 2500, 9000,
  577. VERTEX, 5000, 9000, VERTEX, 6500, 7500,
  578. VERTEX, 9000, 7500, END,
  579. END
  580. };
  581. // Add symbols if they haven't been added already...
  582. if (!init) {
  583. // This method requires the images library...
  584. fl_register_images();
  585. if (!kdedir) {
  586. // Figure out where KDE is installed...
  587. if ((kdedir = getenv("KDEDIR")) == NULL) {
  588. if (!access("/opt/kde", F_OK)) kdedir = "/opt/kde";
  589. else if (!access("/usr/local/share/mimelnk", F_OK)) kdedir = "/usr/local";
  590. else kdedir = "/usr";
  591. }
  592. }
  593. snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
  594. if (!access(filename, F_OK)) {
  595. // Load KDE icons...
  596. icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
  597. for (i = 0; icondirs[i]; i ++) {
  598. snprintf(icondir, sizeof(icondir), "%s/share/icons/%s", kdedir,
  599. icondirs[i]);
  600. if (!access(icondir, F_OK)) break;
  601. }
  602. if (icondirs[i]) {
  603. snprintf(filename, sizeof(filename), "%s/16x16/mimetypes/unknown.png",
  604. icondir);
  605. } else {
  606. snprintf(filename, sizeof(filename), "%s/share/icons/unknown.xpm",
  607. kdedir);
  608. }
  609. if (!access(filename, F_OK)) icon->load_image(filename);
  610. icon = new Fl_File_Icon("*", Fl_File_Icon::LINK);
  611. snprintf(filename, sizeof(filename), "%s/16x16/filesystems/link.png",
  612. icondir);
  613. if (!access(filename, F_OK)) icon->load_image(filename);
  614. snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
  615. load_kde_icons(filename, icondir);
  616. } else if (!access("/usr/share/icons/folder.xpm", F_OK)) {
  617. // Load GNOME icons...
  618. icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
  619. icon->load_image("/usr/share/icons/page.xpm");
  620. icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
  621. icon->load_image("/usr/share/icons/folder.xpm");
  622. } else if (!access("/usr/dt/appconfig/icons", F_OK)) {
  623. // Load CDE icons...
  624. icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
  625. icon->load_image("/usr/dt/appconfig/icons/C/Dtdata.m.pm");
  626. icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
  627. icon->load_image("/usr/dt/appconfig/icons/C/DtdirB.m.pm");
  628. icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
  629. icon->load_image("/usr/dt/appconfig/icons/C/Dtcore.m.pm");
  630. icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
  631. icon->load_image("/usr/dt/appconfig/icons/C/Dtimage.m.pm");
  632. icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
  633. icon->load_image("/usr/dt/appconfig/icons/C/Dtps.m.pm");
  634. icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
  635. icon->load_image("/usr/dt/appconfig/icons/C/DtPrtpr.m.pm");
  636. } else if (!access("/usr/lib/filetype", F_OK)) {
  637. // Load SGI icons...
  638. icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
  639. icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
  640. icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
  641. icon->load_fti("/usr/lib/filetype/iconlib/generic.folder.closed.fti");
  642. icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
  643. icon->load_fti("/usr/lib/filetype/default/iconlib/CoreFile.fti");
  644. icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
  645. icon->load_fti("/usr/lib/filetype/system/iconlib/ImageFile.fti");
  646. if (!access("/usr/lib/filetype/install/iconlib/acroread.doc.fti", F_OK)) {
  647. icon = new Fl_File_Icon("*.{eps|ps}", Fl_File_Icon::PLAIN);
  648. icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
  649. icon = new Fl_File_Icon("*.pdf", Fl_File_Icon::PLAIN);
  650. icon->load_fti("/usr/lib/filetype/install/iconlib/acroread.doc.fti");
  651. } else {
  652. icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
  653. icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
  654. }
  655. if (!access("/usr/lib/filetype/install/iconlib/html.fti", F_OK)) {
  656. icon = new Fl_File_Icon("*.{htm|html|shtml}", Fl_File_Icon::PLAIN);
  657. icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
  658. icon->load_fti("/usr/lib/filetype/install/iconlib/html.fti");
  659. }
  660. if (!access("/usr/lib/filetype/install/iconlib/color.ps.idle.fti", F_OK)) {
  661. icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
  662. icon->load_fti("/usr/lib/filetype/install/iconlib/color.ps.idle.fti");
  663. }
  664. } else {
  665. // Create the default icons...
  666. new Fl_File_Icon("*", Fl_File_Icon::PLAIN, sizeof(plain) / sizeof(plain[0]), plain);
  667. new Fl_File_Icon("*.{bm|bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN,
  668. sizeof(image) / sizeof(image[0]), image);
  669. new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY, sizeof(dir) / sizeof(dir[0]), dir);
  670. }
  671. // Mark things as initialized...
  672. init = 1;
  673. #ifdef DEBUG
  674. int count;
  675. Fl_File_Icon *temp;
  676. for (count = 0, temp = first_; temp; temp = temp->next_, count ++);
  677. printf("count of Fl_File_Icon's is %d...\n", count);
  678. #endif // DEBUG
  679. }
  680. }
  681. //
  682. // 'load_kde_icons()' - Load KDE icon files.
  683. //
  684. static void
  685. load_kde_icons(const char *directory, // I - Directory to load
  686. const char *icondir) { // I - Location of icons
  687. int i; // Looping var
  688. int n; // Number of entries in directory
  689. dirent **entries; // Entries in directory
  690. char full[1024]; // Full name of file
  691. entries = (dirent **)0;
  692. n = fl_filename_list(directory, &entries);
  693. for (i = 0; i < n; i ++) {
  694. if (entries[i]->d_name[0] != '.') {
  695. snprintf(full, sizeof(full), "%s/%s", directory, entries[i]->d_name);
  696. if (fl_filename_isdir(full)) load_kde_icons(full, icondir);
  697. else load_kde_mimelnk(full, icondir);
  698. }
  699. free((void *)entries[i]);
  700. }
  701. free((void*)entries);
  702. }
  703. //
  704. // 'load_kde_mimelnk()' - Load a KDE "mimelnk" file.
  705. //
  706. static void
  707. load_kde_mimelnk(const char *filename, // I - mimelnk filename
  708. const char *icondir) { // I - Location of icons
  709. FILE *fp;
  710. char tmp[1024];
  711. char iconfilename[1024];
  712. char pattern[1024];
  713. char mimetype[1024];
  714. char *val;
  715. char full_iconfilename[1024];
  716. Fl_File_Icon *icon;
  717. mimetype[0] = '\0';
  718. pattern[0] = '\0';
  719. iconfilename[0] = '\0';
  720. if ((fp = fl_fopen(filename, "rb")) != NULL) {
  721. while (fgets(tmp, sizeof(tmp), fp)) {
  722. if ((val = get_kde_val(tmp, "Icon")) != NULL)
  723. strlcpy(iconfilename, val, sizeof(iconfilename));
  724. else if ((val = get_kde_val(tmp, "MimeType")) != NULL)
  725. strlcpy(mimetype, val, sizeof(mimetype));
  726. else if ((val = get_kde_val(tmp, "Patterns")) != NULL)
  727. strlcpy(pattern, val, sizeof(pattern));
  728. }
  729. fclose(fp);
  730. #ifdef DEBUG
  731. printf("%s: Icon=\"%s\", MimeType=\"%s\", Patterns=\"%s\"\n", filename,
  732. iconfilename, mimetype, pattern);
  733. #endif // DEBUG
  734. if (!pattern[0] && strncmp(mimetype, "inode/", 6)) return;
  735. if (iconfilename[0]) {
  736. if (iconfilename[0] == '/') {
  737. strlcpy(full_iconfilename, iconfilename, sizeof(full_iconfilename));
  738. } else if (!access(icondir, F_OK)) {
  739. // KDE 3.x and 2.x icons
  740. int i; // Looping var
  741. static const char *paths[] = { // Subdirs to look in...
  742. "16x16/actions",
  743. "16x16/apps",
  744. "16x16/devices",
  745. "16x16/filesystems",
  746. "16x16/mimetypes",
  747. /*
  748. "20x20/actions",
  749. "20x20/apps",
  750. "20x20/devices",
  751. "20x20/filesystems",
  752. "20x20/mimetypes",
  753. "22x22/actions",
  754. "22x22/apps",
  755. "22x22/devices",
  756. "22x22/filesystems",
  757. "22x22/mimetypes",
  758. "24x24/actions",
  759. "24x24/apps",
  760. "24x24/devices",
  761. "24x24/filesystems",
  762. "24x24/mimetypes",
  763. */
  764. "32x32/actions",
  765. "32x32/apps",
  766. "32x32/devices",
  767. "32x32/filesystems",
  768. "32x32/mimetypes",
  769. /*
  770. "36x36/actions",
  771. "36x36/apps",
  772. "36x36/devices",
  773. "36x36/filesystems",
  774. "36x36/mimetypes",
  775. "48x48/actions",
  776. "48x48/apps",
  777. "48x48/devices",
  778. "48x48/filesystems",
  779. "48x48/mimetypes",
  780. "64x64/actions",
  781. "64x64/apps",
  782. "64x64/devices",
  783. "64x64/filesystems",
  784. "64x64/mimetypes",
  785. "96x96/actions",
  786. "96x96/apps",
  787. "96x96/devices",
  788. "96x96/filesystems",
  789. "96x96/mimetypes"
  790. */ };
  791. for (i = 0; i < (int)(sizeof(paths) / sizeof(paths[0])); i ++) {
  792. snprintf(full_iconfilename, sizeof(full_iconfilename),
  793. "%s/%s/%s.png", icondir, paths[i], iconfilename);
  794. if (!access(full_iconfilename, F_OK)) break;
  795. }
  796. if (i >= (int)(sizeof(paths) / sizeof(paths[0]))) return;
  797. } else {
  798. // KDE 1.x icons
  799. snprintf(full_iconfilename, sizeof(full_iconfilename),
  800. "%s/%s", tmp, iconfilename);
  801. if (access(full_iconfilename, F_OK)) return;
  802. }
  803. if (strncmp(mimetype, "inode/", 6) == 0) {
  804. if (!strcmp(mimetype + 6, "directory"))
  805. icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
  806. else if (!strcmp(mimetype + 6, "blockdevice"))
  807. icon = new Fl_File_Icon("*", Fl_File_Icon::DEVICE);
  808. else if (!strcmp(mimetype + 6, "fifo"))
  809. icon = new Fl_File_Icon("*", Fl_File_Icon::FIFO);
  810. else return;
  811. } else {
  812. icon = new Fl_File_Icon(kde_to_fltk_pattern(pattern),
  813. Fl_File_Icon::PLAIN);
  814. }
  815. icon->load(full_iconfilename);
  816. }
  817. }
  818. }
  819. //
  820. // 'kde_to_fltk_pattern()' - Convert a KDE pattern to a FLTK pattern.
  821. //
  822. static char *
  823. kde_to_fltk_pattern(const char *kdepattern) {
  824. char *pattern,
  825. *patptr;
  826. pattern = (char *)malloc(strlen(kdepattern) + 3);
  827. strcpy(pattern, "{");
  828. strcpy(pattern + 1, kdepattern);
  829. if (pattern[strlen(pattern) - 1] == ';') pattern[strlen(pattern) - 1] = '\0';
  830. strcat(pattern, "}");
  831. for (patptr = pattern; *patptr; patptr ++) {
  832. if (*patptr == ';') *patptr = '|';
  833. }
  834. return (pattern);
  835. }
  836. //
  837. // 'get_kde_val()' - Get a KDE value.
  838. //
  839. static char *
  840. get_kde_val(char *str,
  841. const char *key) {
  842. while (*str == *key) {
  843. str ++;
  844. key ++;
  845. }
  846. if (*key == '\0' && *str == '=') {
  847. if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0';
  848. return (str + 1);
  849. }
  850. return ((char *)0);
  851. }
  852. //
  853. // End of "$Id: Fl_File_Icon2.cxx 7903 2010-11-28 21:06:39Z matt $".
  854. //