themes: Workaround for bug where a background color of RGB 0,0,0 in Black color schem...
[ntk.git] / src / Fl_File_Icon2.cxx
blob0b114ae639ed5659a2b27804c04a30d75cf48a79
1 //
2 // "$Id: Fl_File_Icon2.cxx 8063 2010-12-19 21:20:10Z 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.
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.
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.
25 // Please report all bugs and problems on the following page:
27 // http://www.fltk.org/str.php
29 // Contents:
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.
42 // Include necessary header files...
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <FL/fl_utf8.h>
48 #include "flstring.h"
49 #include <ctype.h>
50 #include <errno.h>
51 #include <FL/math.h>
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #if defined(WIN32) && !defined(__CYGWIN__)
55 # include <io.h>
56 # define F_OK 0
57 // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
58 // on Windows, which is supposed to be POSIX compliant...
59 # define access _access
60 #else
61 # include <unistd.h>
62 #endif // WIN32
64 #include <FL/Fl_File_Icon.H>
65 #include <FL/Fl_Shared_Image.H>
66 #include <FL/Fl_Widget.H>
67 #include <FL/fl_draw.H>
68 #include <FL/filename.H>
72 // Define missing POSIX/XPG4 macros as needed...
75 #ifndef S_ISDIR
76 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
77 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
78 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
79 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
80 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
81 #endif /* !S_ISDIR */
85 // Local functions...
88 static void load_kde_icons(const char *directory, const char *icondir);
89 static void load_kde_mimelnk(const char *filename, const char *icondir);
90 static char *kde_to_fltk_pattern(const char *kdepattern);
91 static char *get_kde_val(char *str, const char *key);
95 // Local globals...
98 static const char *kdedir = NULL;
102 Loads the specified icon image. The format is deduced from the filename.
103 \param[in] f filename
105 void
106 Fl_File_Icon::load(const char *f) // I - File to read from
108 int i; // Load status...
109 const char *ext; // File extension
112 ext = fl_filename_ext(f);
114 if (ext && strcmp(ext, ".fti") == 0)
115 i = load_fti(f);
116 else
117 i = load_image(f);
119 if (i)
121 Fl::warning("Fl_File_Icon::load(): Unable to load icon file \"%s\".", f);
122 return;
128 Loads an SGI icon file.
129 \param[in] fti icon filename
130 \return 0 on success, non-zero on error
132 int // O - 0 on success, non-zero on error
133 Fl_File_Icon::load_fti(const char *fti) // I - File to read from
135 FILE *fp; // File pointer
136 int ch; // Current character
137 char command[255], // Command string ("vertex", etc.)
138 params[255], // Parameter string ("10.0,20.0", etc.)
139 *ptr; // Pointer into strings
140 int outline; // Outline polygon
143 // Try to open the file...
144 if ((fp = fl_fopen(fti, "rb")) == NULL)
146 Fl::error("Fl_File_Icon::load_fti(): Unable to open \"%s\" - %s",
147 fti, strerror(errno));
148 return -1;
151 // Read the entire file, adding data as needed...
152 outline = 0;
154 while ((ch = getc(fp)) != EOF)
156 // Skip whitespace
157 if (isspace(ch))
158 continue;
160 // Skip comments starting with "#"...
161 if (ch == '#')
163 while ((ch = getc(fp)) != EOF)
164 if (ch == '\n')
165 break;
167 if (ch == EOF)
168 break;
169 else
170 continue;
173 // OK, this character better be a letter...
174 if (!isalpha(ch))
176 Fl::error("Fl_File_Icon::load_fti(): Expected a letter at file position %ld (saw '%c')",
177 ftell(fp) - 1, ch);
178 break;
181 // Scan the command name...
182 ptr = command;
183 *ptr++ = ch;
185 while ((ch = getc(fp)) != EOF)
187 if (ch == '(')
188 break;
189 else if (ptr < (command + sizeof(command) - 1))
190 *ptr++ = ch;
193 *ptr++ = '\0';
195 // Make sure we stopped on a parenthesis...
196 if (ch != '(')
198 Fl::error("Fl_File_Icon::load_fti(): Expected a ( at file position %ld (saw '%c')",
199 ftell(fp) - 1, ch);
200 break;
203 // Scan the parameters...
204 ptr = params;
206 while ((ch = getc(fp)) != EOF)
208 if (ch == ')')
209 break;
210 else if (ptr < (params + sizeof(params) - 1))
211 *ptr++ = ch;
214 *ptr++ = '\0';
216 // Make sure we stopped on a parenthesis...
217 if (ch != ')')
219 Fl::error("Fl_File_Icon::load_fti(): Expected a ) at file position %ld (saw '%c')",
220 ftell(fp) - 1, ch);
221 break;
224 // Make sure the next character is a semicolon...
225 if ((ch = getc(fp)) != ';')
227 Fl::error("Fl_File_Icon::load_fti(): Expected a ; at file position %ld (saw '%c')",
228 ftell(fp) - 1, ch);
229 break;
232 // Now process the command...
233 if (strcmp(command, "color") == 0)
235 // Set the color; for negative colors blend the two primaries to
236 // produce a composite color. Also, the following symbolic color
237 // names are understood:
239 // name FLTK color
240 // ------------- ----------
241 // iconcolor FL_ICON_COLOR; mapped to the icon color in
242 // Fl_File_Icon::draw()
243 // shadowcolor FL_DARK3
244 // outlinecolor FL_BLACK
245 if (strcmp(params, "iconcolor") == 0)
246 add_color(FL_ICON_COLOR);
247 else if (strcmp(params, "shadowcolor") == 0)
248 add_color(FL_DARK3);
249 else if (strcmp(params, "outlinecolor") == 0)
250 add_color(FL_BLACK);
251 else
253 int c = atoi(params); // Color value
256 if (c < 0)
258 // Composite color; compute average...
259 c = -c;
260 add_color(fl_color_average((Fl_Color)(c >> 4),
261 (Fl_Color)(c & 15), 0.5f));
263 else
264 add_color((Fl_Color)c);
267 else if (strcmp(command, "bgnline") == 0)
268 add(LINE);
269 else if (strcmp(command, "bgnclosedline") == 0)
270 add(CLOSEDLINE);
271 else if (strcmp(command, "bgnpolygon") == 0)
272 add(POLYGON);
273 else if (strcmp(command, "bgnoutlinepolygon") == 0)
275 add(OUTLINEPOLYGON);
276 outline = add(0) - data_;
277 add(0);
279 else if (strcmp(command, "endoutlinepolygon") == 0 && outline)
281 unsigned cval; // Color value
283 // Set the outline color; see above for valid values...
284 if (strcmp(params, "iconcolor") == 0)
285 cval = FL_ICON_COLOR;
286 else if (strcmp(params, "shadowcolor") == 0)
287 cval = FL_DARK3;
288 else if (strcmp(params, "outlinecolor") == 0)
289 cval = FL_BLACK;
290 else
292 int c = atoi(params); // Color value
295 if (c < 0)
297 // Composite color; compute average...
298 c = -c;
299 cval = fl_color_average((Fl_Color)(c >> 4), (Fl_Color)(c & 15), 0.5f);
301 else
302 cval = c;
305 // Store outline color...
306 data_[outline] = cval >> 16;
307 data_[outline + 1] = cval;
309 outline = 0;
310 add(END);
312 else if (strncmp(command, "end", 3) == 0)
313 add(END);
314 else if (strcmp(command, "vertex") == 0)
316 float x, y; // Coordinates of vertex
319 if (sscanf(params, "%f,%f", &x, &y) != 2)
320 break;
322 add_vertex((short)(int)rint(x * 100.0), (short)(int)rint(y * 100.0));
324 else
326 Fl::error("Fl_File_Icon::load_fti(): Unknown command \"%s\" at file position %ld.",
327 command, ftell(fp) - 1);
328 break;
332 // Close the file and return...
333 fclose(fp);
335 #ifdef DEBUG
336 printf("Icon File \"%s\":\n", fti);
337 for (int i = 0; i < num_data_; i ++)
338 printf(" %d,\n", data_[i]);
339 #endif /* DEBUG */
341 return 0;
346 Load an image icon file from an image filename.
347 \param[in] ifile image filename
348 \return 0 on success, non-zero on error
350 int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
352 Fl_Shared_Image *img; // Image file
355 img = Fl_Shared_Image::get(ifile);
356 if (!img || !img->count() || !img->w() || !img->h()) return -1;
358 if (img->count() == 1) {
359 int x, y; // X & Y in image
360 int startx; // Starting X coord
361 Fl_Color c, // Current color
362 temp; // Temporary color
363 const uchar *row; // Pointer into image
366 // Loop through grayscale or RGB image...
367 for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld())
369 for (x = 0, startx = 0, c = (Fl_Color)-1;
370 x < img->w();
371 x ++, row += img->d())
373 switch (img->d())
375 case 1 :
376 temp = fl_rgb_color(row[0], row[0], row[0]);
377 break;
378 case 2 :
379 if (row[1] > 127)
380 temp = fl_rgb_color(row[0], row[0], row[0]);
381 else
382 temp = (Fl_Color)-1;
383 break;
384 case 3 :
385 temp = fl_rgb_color(row[0], row[1], row[2]);
386 break;
387 default :
388 if (row[3] > 127)
389 temp = fl_rgb_color(row[0], row[1], row[2]);
390 else
391 temp = (Fl_Color)-1;
392 break;
395 if (temp != c)
397 if (x > startx && c != (Fl_Color)-1)
399 add_color(c);
400 add(POLYGON);
401 add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
402 add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
403 add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
404 add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
405 add(END);
408 c = temp;
409 startx = x;
413 if (x > startx && c != (Fl_Color)-1)
415 add_color(c);
416 add(POLYGON);
417 add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
418 add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
419 add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
420 add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
421 add(END);
424 } else {
425 int i, j; // Looping vars
426 int ch; // Current character
427 int newch; // New character
428 int bg; // Background color
429 char val[16]; // Color value
430 const char *lineptr, // Pointer into line
431 *const*ptr; // Pointer into data array
432 int ncolors, // Number of colors
433 chars_per_color; // Characters per color
434 Fl_Color *colors; // Colors
435 int red, green, blue; // Red, green, and blue values
436 int x, y; // X & Y in image
437 int startx; // Starting X coord
440 // Get the pixmap data...
441 ptr = img->data();
442 sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
444 colors = new Fl_Color[1 << (chars_per_color * 8)];
446 // Read the colormap...
447 memset(colors, 0, sizeof(Fl_Color) << (chars_per_color * 8));
448 bg = ' ';
450 ptr ++;
452 if (ncolors < 0) {
453 // Read compressed colormap...
454 const uchar *cmapptr;
456 ncolors = -ncolors;
458 for (i = 0, cmapptr = (const uchar *)*ptr; i < ncolors; i ++, cmapptr += 4)
459 colors[cmapptr[0]] = fl_rgb_color(cmapptr[1], cmapptr[2], cmapptr[3]);
461 ptr ++;
462 } else {
463 for (i = 0; i < ncolors; i ++, ptr ++) {
464 // Get the color's character
465 lineptr = *ptr;
466 ch = *lineptr++;
468 if (chars_per_color > 1) ch = (ch << 8) | *lineptr++;
470 // Get the color value...
471 if ((lineptr = strstr(lineptr, "c ")) == NULL) {
472 // No color; make this black...
473 colors[ch] = FL_BLACK;
474 } else if (lineptr[2] == '#') {
475 // Read the RGB triplet...
476 lineptr += 3;
477 for (j = 0; j < 12; j ++)
478 if (!isxdigit(lineptr[j]))
479 break;
481 switch (j) {
482 case 0 :
483 bg = ch;
484 default :
485 red = green = blue = 0;
486 break;
488 case 3 :
489 val[0] = lineptr[0];
490 val[1] = '\0';
491 red = 255 * strtol(val, NULL, 16) / 15;
493 val[0] = lineptr[1];
494 val[1] = '\0';
495 green = 255 * strtol(val, NULL, 16) / 15;
497 val[0] = lineptr[2];
498 val[1] = '\0';
499 blue = 255 * strtol(val, NULL, 16) / 15;
500 break;
502 case 6 :
503 case 9 :
504 case 12 :
505 j /= 3;
507 val[0] = lineptr[0];
508 val[1] = lineptr[1];
509 val[2] = '\0';
510 red = strtol(val, NULL, 16);
512 val[0] = lineptr[j + 0];
513 val[1] = lineptr[j + 1];
514 val[2] = '\0';
515 green = strtol(val, NULL, 16);
517 val[0] = lineptr[2 * j + 0];
518 val[1] = lineptr[2 * j + 1];
519 val[2] = '\0';
520 blue = strtol(val, NULL, 16);
521 break;
524 colors[ch] = fl_rgb_color((uchar)red, (uchar)green, (uchar)blue);
525 } else {
526 // Read a color name...
527 if (strncasecmp(lineptr + 2, "white", 5) == 0) colors[ch] = FL_WHITE;
528 else if (strncasecmp(lineptr + 2, "black", 5) == 0) colors[ch] = FL_BLACK;
529 else if (strncasecmp(lineptr + 2, "none", 4) == 0) {
530 colors[ch] = FL_BLACK;
531 bg = ch;
532 } else colors[ch] = FL_GRAY;
537 // Read the image data...
538 for (y = 0; y < img->h(); y ++, ptr ++) {
539 lineptr = *ptr;
540 startx = 0;
541 ch = bg;
543 for (x = 0; x < img->w(); x ++) {
544 newch = *lineptr++;
546 if (chars_per_color > 1) newch = (newch << 8) | *lineptr++;
548 if (newch != ch) {
549 if (ch != bg) {
550 add_color(colors[ch]);
551 add(POLYGON);
552 add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
553 add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
554 add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
555 add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
556 add(END);
559 ch = newch;
560 startx = x;
564 if (ch != bg) {
565 add_color(colors[ch]);
566 add(POLYGON);
567 add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
568 add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
569 add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
570 add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
571 add(END);
575 // Free the colormap...
576 delete[] colors;
579 img->release();
581 #ifdef DEBUG
582 printf("Icon File \"%s\":\n", xpm);
583 for (i = 0; i < num_data_; i ++)
584 printf(" %d,\n", data_[i]);
585 #endif // DEBUG
587 return 0;
592 Loads all system-defined icons. This call is useful when using the
593 FileChooser widget and should be used when the application starts:
595 \code
596 Fl_File_Icon::load_system_icons();
597 \endcode
599 void
600 Fl_File_Icon::load_system_icons(void) {
601 int i; // Looping var
602 Fl_File_Icon *icon; // New icons
603 char filename[FL_PATH_MAX]; // Filename
604 char icondir[FL_PATH_MAX]; // Icon directory
605 static int init = 0; // Have the icons been initialized?
606 const char * const icondirs[] = {
607 "Bluecurve", // Icon directories to look for, in order
608 "crystalsvg",
609 "default.kde",
610 "hicolor",
611 NULL
613 static short plain[] = { // Plain file icon
614 COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
615 VERTEX, 2000, 1000, VERTEX, 2000, 9000,
616 VERTEX, 6000, 9000, VERTEX, 8000, 7000,
617 VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
618 VERTEX, 6000, 9000, VERTEX, 6000, 7000,
619 VERTEX, 8000, 7000, END,
620 COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
621 VERTEX, 8000, 7000, VERTEX, 8000, 1000,
622 VERTEX, 2000, 1000, END, LINE, VERTEX, 3000, 7000,
623 VERTEX, 5000, 7000, END, LINE, VERTEX, 3000, 6000,
624 VERTEX, 5000, 6000, END, LINE, VERTEX, 3000, 5000,
625 VERTEX, 7000, 5000, END, LINE, VERTEX, 3000, 4000,
626 VERTEX, 7000, 4000, END, LINE, VERTEX, 3000, 3000,
627 VERTEX, 7000, 3000, END, LINE, VERTEX, 3000, 2000,
628 VERTEX, 7000, 2000, END,
631 static short image[] = { // Image file icon
632 COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
633 VERTEX, 2000, 1000, VERTEX, 2000, 9000,
634 VERTEX, 6000, 9000, VERTEX, 8000, 7000,
635 VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
636 VERTEX, 6000, 9000, VERTEX, 6000, 7000,
637 VERTEX, 8000, 7000, END,
638 COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
639 VERTEX, 8000, 7000, VERTEX, 8000, 1000,
640 VERTEX, 2000, 1000, END,
641 COLOR, 0, FL_RED, POLYGON, VERTEX, 3500, 2500,
642 VERTEX, 3000, 3000, VERTEX, 3000, 4000,
643 VERTEX, 3500, 4500, VERTEX, 4500, 4500,
644 VERTEX, 5000, 4000, VERTEX, 5000, 3000,
645 VERTEX, 4500, 2500, END,
646 COLOR, 0, FL_GREEN, POLYGON, VERTEX, 5500, 2500,
647 VERTEX, 5000, 3000, VERTEX, 5000, 4000,
648 VERTEX, 5500, 4500, VERTEX, 6500, 4500,
649 VERTEX, 7000, 4000, VERTEX, 7000, 3000,
650 VERTEX, 6500, 2500, END,
651 COLOR, 0, FL_BLUE, POLYGON, VERTEX, 4500, 3500,
652 VERTEX, 4000, 4000, VERTEX, 4000, 5000,
653 VERTEX, 4500, 5500, VERTEX, 5500, 5500,
654 VERTEX, 6000, 5000, VERTEX, 6000, 4000,
655 VERTEX, 5500, 3500, END,
658 static short dir[] = { // Directory icon
659 COLOR, -1, -1, POLYGON, VERTEX, 1000, 1000,
660 VERTEX, 1000, 7500, VERTEX, 9000, 7500,
661 VERTEX, 9000, 1000, END,
662 POLYGON, VERTEX, 1000, 7500, VERTEX, 2500, 9000,
663 VERTEX, 5000, 9000, VERTEX, 6500, 7500, END,
664 COLOR, 0, FL_WHITE, LINE, VERTEX, 1500, 1500,
665 VERTEX, 1500, 7000, VERTEX, 9000, 7000, END,
666 COLOR, 0, FL_BLACK, LINE, VERTEX, 9000, 7500,
667 VERTEX, 9000, 1000, VERTEX, 1000, 1000, END,
668 COLOR, 0, FL_GRAY, LINE, VERTEX, 1000, 1000,
669 VERTEX, 1000, 7500, VERTEX, 2500, 9000,
670 VERTEX, 5000, 9000, VERTEX, 6500, 7500,
671 VERTEX, 9000, 7500, END,
676 // Add symbols if they haven't been added already...
677 if (!init) {
678 // This method requires the images library...
679 fl_register_images();
681 if (!kdedir) {
682 // Figure out where KDE is installed...
683 if ((kdedir = getenv("KDEDIR")) == NULL) {
684 if (!access("/opt/kde", F_OK)) kdedir = "/opt/kde";
685 else if (!access("/usr/local/share/mimelnk", F_OK)) kdedir = "/usr/local";
686 else kdedir = "/usr";
690 snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
692 if (!access(filename, F_OK)) {
693 // Load KDE icons...
694 icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
696 for (i = 0; icondirs[i]; i ++) {
697 snprintf(icondir, sizeof(icondir), "%s/share/icons/%s", kdedir,
698 icondirs[i]);
700 if (!access(icondir, F_OK)) break;
703 if (icondirs[i]) {
704 snprintf(filename, sizeof(filename), "%s/16x16/mimetypes/unknown.png",
705 icondir);
706 } else {
707 snprintf(filename, sizeof(filename), "%s/share/icons/unknown.xpm",
708 kdedir);
711 if (!access(filename, F_OK)) icon->load_image(filename);
713 icon = new Fl_File_Icon("*", Fl_File_Icon::LINK);
715 snprintf(filename, sizeof(filename), "%s/16x16/filesystems/link.png",
716 icondir);
718 if (!access(filename, F_OK)) icon->load_image(filename);
720 snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
721 load_kde_icons(filename, icondir);
722 } else if (!access("/usr/share/icons/folder.xpm", F_OK)) {
723 // Load GNOME icons...
724 icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
725 icon->load_image("/usr/share/icons/page.xpm");
727 icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
728 icon->load_image("/usr/share/icons/folder.xpm");
729 } else if (!access("/usr/dt/appconfig/icons", F_OK)) {
730 // Load CDE icons...
731 icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
732 icon->load_image("/usr/dt/appconfig/icons/C/Dtdata.m.pm");
734 icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
735 icon->load_image("/usr/dt/appconfig/icons/C/DtdirB.m.pm");
737 icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
738 icon->load_image("/usr/dt/appconfig/icons/C/Dtcore.m.pm");
740 icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
741 icon->load_image("/usr/dt/appconfig/icons/C/Dtimage.m.pm");
743 icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
744 icon->load_image("/usr/dt/appconfig/icons/C/Dtps.m.pm");
746 icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
747 icon->load_image("/usr/dt/appconfig/icons/C/DtPrtpr.m.pm");
748 } else if (!access("/usr/lib/filetype", F_OK)) {
749 // Load SGI icons...
750 icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
751 icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
753 icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
754 icon->load_fti("/usr/lib/filetype/iconlib/generic.folder.closed.fti");
756 icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
757 icon->load_fti("/usr/lib/filetype/default/iconlib/CoreFile.fti");
759 icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
760 icon->load_fti("/usr/lib/filetype/system/iconlib/ImageFile.fti");
762 if (!access("/usr/lib/filetype/install/iconlib/acroread.doc.fti", F_OK)) {
763 icon = new Fl_File_Icon("*.{eps|ps}", Fl_File_Icon::PLAIN);
764 icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
766 icon = new Fl_File_Icon("*.pdf", Fl_File_Icon::PLAIN);
767 icon->load_fti("/usr/lib/filetype/install/iconlib/acroread.doc.fti");
768 } else {
769 icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
770 icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
773 if (!access("/usr/lib/filetype/install/iconlib/html.fti", F_OK)) {
774 icon = new Fl_File_Icon("*.{htm|html|shtml}", Fl_File_Icon::PLAIN);
775 icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
776 icon->load_fti("/usr/lib/filetype/install/iconlib/html.fti");
779 if (!access("/usr/lib/filetype/install/iconlib/color.ps.idle.fti", F_OK)) {
780 icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
781 icon->load_fti("/usr/lib/filetype/install/iconlib/color.ps.idle.fti");
783 } else {
784 // Create the default icons...
785 new Fl_File_Icon("*", Fl_File_Icon::PLAIN, sizeof(plain) / sizeof(plain[0]), plain);
786 new Fl_File_Icon("*.{bm|bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN,
787 sizeof(image) / sizeof(image[0]), image);
788 new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY, sizeof(dir) / sizeof(dir[0]), dir);
791 // Mark things as initialized...
792 init = 1;
794 #ifdef DEBUG
795 int count;
796 Fl_File_Icon *temp;
797 for (count = 0, temp = first_; temp; temp = temp->next_, count ++);
798 printf("count of Fl_File_Icon's is %d...\n", count);
799 #endif // DEBUG
805 // 'load_kde_icons()' - Load KDE icon files.
808 static void
809 load_kde_icons(const char *directory, // I - Directory to load
810 const char *icondir) { // I - Location of icons
811 int i; // Looping var
812 int n; // Number of entries in directory
813 dirent **entries; // Entries in directory
814 char full[FL_PATH_MAX]; // Full name of file
817 entries = (dirent **)0;
818 n = fl_filename_list(directory, &entries);
820 for (i = 0; i < n; i ++) {
821 if (entries[i]->d_name[0] != '.') {
822 snprintf(full, sizeof(full), "%s/%s", directory, entries[i]->d_name);
824 if (fl_filename_isdir(full)) load_kde_icons(full, icondir);
825 else load_kde_mimelnk(full, icondir);
828 free((void *)entries[i]);
831 free((void*)entries);
836 // 'load_kde_mimelnk()' - Load a KDE "mimelnk" file.
839 static void
840 load_kde_mimelnk(const char *filename, // I - mimelnk filename
841 const char *icondir) { // I - Location of icons
842 FILE *fp;
843 char tmp[1024];
844 char iconfilename[FL_PATH_MAX];
845 char pattern[1024];
846 char mimetype[1024];
847 char *val;
848 char full_iconfilename[FL_PATH_MAX];
849 Fl_File_Icon *icon;
852 mimetype[0] = '\0';
853 pattern[0] = '\0';
854 iconfilename[0] = '\0';
856 if ((fp = fl_fopen(filename, "rb")) != NULL) {
857 while (fgets(tmp, sizeof(tmp), fp)) {
858 if ((val = get_kde_val(tmp, "Icon")) != NULL)
859 strlcpy(iconfilename, val, sizeof(iconfilename));
860 else if ((val = get_kde_val(tmp, "MimeType")) != NULL)
861 strlcpy(mimetype, val, sizeof(mimetype));
862 else if ((val = get_kde_val(tmp, "Patterns")) != NULL)
863 strlcpy(pattern, val, sizeof(pattern));
866 fclose(fp);
868 #ifdef DEBUG
869 printf("%s: Icon=\"%s\", MimeType=\"%s\", Patterns=\"%s\"\n", filename,
870 iconfilename, mimetype, pattern);
871 #endif // DEBUG
873 if (!pattern[0] && strncmp(mimetype, "inode/", 6)) return;
875 if (iconfilename[0]) {
876 if (iconfilename[0] == '/') {
877 strlcpy(full_iconfilename, iconfilename, sizeof(full_iconfilename));
878 } else if (!access(icondir, F_OK)) {
879 // KDE 3.x and 2.x icons
880 int i; // Looping var
881 static const char *paths[] = { // Subdirs to look in...
882 "16x16/actions",
883 "16x16/apps",
884 "16x16/devices",
885 "16x16/filesystems",
886 "16x16/mimetypes",
888 "20x20/actions",
889 "20x20/apps",
890 "20x20/devices",
891 "20x20/filesystems",
892 "20x20/mimetypes",
894 "22x22/actions",
895 "22x22/apps",
896 "22x22/devices",
897 "22x22/filesystems",
898 "22x22/mimetypes",
900 "24x24/actions",
901 "24x24/apps",
902 "24x24/devices",
903 "24x24/filesystems",
904 "24x24/mimetypes",
906 "32x32/actions",
907 "32x32/apps",
908 "32x32/devices",
909 "32x32/filesystems",
910 "32x32/mimetypes",
912 "36x36/actions",
913 "36x36/apps",
914 "36x36/devices",
915 "36x36/filesystems",
916 "36x36/mimetypes",
918 "48x48/actions",
919 "48x48/apps",
920 "48x48/devices",
921 "48x48/filesystems",
922 "48x48/mimetypes",
924 "64x64/actions",
925 "64x64/apps",
926 "64x64/devices",
927 "64x64/filesystems",
928 "64x64/mimetypes",
930 "96x96/actions",
931 "96x96/apps",
932 "96x96/devices",
933 "96x96/filesystems",
934 "96x96/mimetypes"
935 */ };
937 for (i = 0; i < (int)(sizeof(paths) / sizeof(paths[0])); i ++) {
938 snprintf(full_iconfilename, sizeof(full_iconfilename),
939 "%s/%s/%s.png", icondir, paths[i], iconfilename);
941 if (!access(full_iconfilename, F_OK)) break;
944 if (i >= (int)(sizeof(paths) / sizeof(paths[0]))) return;
945 } else {
946 // KDE 1.x icons
947 snprintf(full_iconfilename, sizeof(full_iconfilename),
948 "%s/%s", tmp, iconfilename);
950 if (access(full_iconfilename, F_OK)) return;
953 if (strncmp(mimetype, "inode/", 6) == 0) {
954 if (!strcmp(mimetype + 6, "directory"))
955 icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
956 else if (!strcmp(mimetype + 6, "blockdevice"))
957 icon = new Fl_File_Icon("*", Fl_File_Icon::DEVICE);
958 else if (!strcmp(mimetype + 6, "fifo"))
959 icon = new Fl_File_Icon("*", Fl_File_Icon::FIFO);
960 else return;
961 } else {
962 icon = new Fl_File_Icon(kde_to_fltk_pattern(pattern),
963 Fl_File_Icon::PLAIN);
966 icon->load(full_iconfilename);
973 // 'kde_to_fltk_pattern()' - Convert a KDE pattern to a FLTK pattern.
976 static char *
977 kde_to_fltk_pattern(const char *kdepattern) {
978 char *pattern,
979 *patptr;
982 pattern = (char *)malloc(strlen(kdepattern) + 3);
983 strcpy(pattern, "{");
984 strcpy(pattern + 1, kdepattern);
986 if (pattern[strlen(pattern) - 1] == ';') pattern[strlen(pattern) - 1] = '\0';
988 strcat(pattern, "}");
990 for (patptr = pattern; *patptr; patptr ++) {
991 if (*patptr == ';') *patptr = '|';
994 return (pattern);
999 // 'get_kde_val()' - Get a KDE value.
1002 static char *
1003 get_kde_val(char *str,
1004 const char *key) {
1005 while (*str == *key) {
1006 str ++;
1007 key ++;
1010 if (*key == '\0' && *str == '=') {
1011 if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0';
1013 return (str + 1);
1016 return ((char *)0);
1021 // End of "$Id: Fl_File_Icon2.cxx 8063 2010-12-19 21:20:10Z matt $".