fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_File_Icon2.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_File_Icon2.cxx 8063 2010-12-19 21:20:10Z matt $"
00003 //
00004 // Fl_File_Icon system icon routines.
00005 //
00006 // KDE icon code donated by Maarten De Boer.
00007 //
00008 // Copyright 1999-2010 by Michael Sweet.
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Library General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Library General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Library General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA.
00024 //
00025 // Please report all bugs and problems on the following page:
00026 //
00027 //     http://www.fltk.org/str.php
00028 //
00029 // Contents:
00030 //
00031 //   Fl_File_Icon::load()              - Load an icon file...
00032 //   Fl_File_Icon::load_fti()          - Load an SGI-format FTI file...
00033 //   Fl_File_Icon::load_image()        - Load an image icon file...
00034 //   Fl_File_Icon::load_system_icons() - Load the standard system icons/filetypes.
00035 //   load_kde_icons()                  - Load KDE icon files.
00036 //   load_kde_mimelnk()                - Load a KDE "mimelnk" file.
00037 //   kde_to_fltk_pattern()             - Convert a KDE pattern to a FLTK pattern.
00038 //   get_kde_val()                     - Get a KDE value.
00039 //
00040 
00041 //
00042 // Include necessary header files...
00043 //
00044 
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <FL/fl_utf8.h>
00048 #include "flstring.h"
00049 #include <ctype.h>
00050 #include <errno.h>
00051 #include <FL/math.h>
00052 #include <sys/types.h>
00053 #include <sys/stat.h>
00054 #if defined(WIN32) && !defined(__CYGWIN__)
00055 #  include <io.h>
00056 #  define F_OK  0
00057 // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
00058 // on Windows, which is supposed to be POSIX compliant...
00059 #  define access _access
00060 #else
00061 #  include <unistd.h>
00062 #endif // WIN32
00063 
00064 #include <FL/Fl_File_Icon.H>
00065 #include <FL/Fl_Shared_Image.H>
00066 #include <FL/Fl_Widget.H>
00067 #include <FL/fl_draw.H>
00068 #include <FL/filename.H>
00069 
00070 
00071 //
00072 // Define missing POSIX/XPG4 macros as needed...
00073 //
00074 
00075 #ifndef S_ISDIR
00076 #  define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
00077 #  define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
00078 #  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
00079 #  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
00080 #  define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
00081 #endif /* !S_ISDIR */
00082 
00083 
00084 //
00085 // Local functions...
00086 //
00087 
00088 static void     load_kde_icons(const char *directory, const char *icondir);
00089 static void     load_kde_mimelnk(const char *filename, const char *icondir);
00090 static char     *kde_to_fltk_pattern(const char *kdepattern);
00091 static char     *get_kde_val(char *str, const char *key);
00092 
00093 
00094 //
00095 // Local globals...
00096 //
00097 
00098 static const char *kdedir = NULL;
00099 
00100 
00105 void
00106 Fl_File_Icon::load(const char *f)       // I - File to read from
00107 {
00108   int           i;                      // Load status...
00109   const char    *ext;                   // File extension
00110 
00111 
00112   ext = fl_filename_ext(f);
00113 
00114   if (ext && strcmp(ext, ".fti") == 0)
00115     i = load_fti(f);
00116   else
00117     i = load_image(f);
00118 
00119   if (i)
00120   {
00121     Fl::warning("Fl_File_Icon::load(): Unable to load icon file \"%s\".", f);
00122     return;
00123   }
00124 }
00125 
00126 
00132 int                                     // O - 0 on success, non-zero on error
00133 Fl_File_Icon::load_fti(const char *fti) // I - File to read from
00134 {
00135   FILE  *fp;                    // File pointer
00136   int   ch;                     // Current character
00137   char  command[255],           // Command string ("vertex", etc.)
00138         params[255],            // Parameter string ("10.0,20.0", etc.)
00139         *ptr;                   // Pointer into strings
00140   int   outline;                // Outline polygon
00141 
00142 
00143   // Try to open the file...
00144   if ((fp = fl_fopen(fti, "rb")) == NULL)
00145   {
00146     Fl::error("Fl_File_Icon::load_fti(): Unable to open \"%s\" - %s",
00147               fti, strerror(errno));
00148     return -1;
00149   }
00150 
00151   // Read the entire file, adding data as needed...
00152   outline = 0;
00153 
00154   while ((ch = getc(fp)) != EOF)
00155   {
00156     // Skip whitespace
00157     if (isspace(ch))
00158       continue;
00159 
00160     // Skip comments starting with "#"...
00161     if (ch == '#')
00162     {
00163       while ((ch = getc(fp)) != EOF)
00164         if (ch == '\n')
00165           break;
00166 
00167       if (ch == EOF)
00168         break;
00169       else
00170         continue;
00171     }
00172 
00173     // OK, this character better be a letter...
00174     if (!isalpha(ch))
00175     {
00176       Fl::error("Fl_File_Icon::load_fti(): Expected a letter at file position %ld (saw '%c')",
00177                 ftell(fp) - 1, ch);
00178       break;
00179     }
00180 
00181     // Scan the command name...
00182     ptr    = command;
00183     *ptr++ = ch;
00184 
00185     while ((ch = getc(fp)) != EOF)
00186     {
00187       if (ch == '(')
00188         break;
00189       else if (ptr < (command + sizeof(command) - 1))
00190         *ptr++ = ch;
00191     }
00192 
00193     *ptr++ = '\0';
00194 
00195     // Make sure we stopped on a parenthesis...
00196     if (ch != '(')
00197     {
00198       Fl::error("Fl_File_Icon::load_fti(): Expected a ( at file position %ld (saw '%c')",
00199                 ftell(fp) - 1, ch);
00200       break;
00201     }
00202 
00203     // Scan the parameters...
00204     ptr = params;
00205 
00206     while ((ch = getc(fp)) != EOF)
00207     {
00208       if (ch == ')')
00209         break;
00210       else if (ptr < (params + sizeof(params) - 1))
00211         *ptr++ = ch;
00212     }
00213 
00214     *ptr++ = '\0';
00215 
00216     // Make sure we stopped on a parenthesis...
00217     if (ch != ')')
00218     {
00219       Fl::error("Fl_File_Icon::load_fti(): Expected a ) at file position %ld (saw '%c')",
00220                 ftell(fp) - 1, ch);
00221       break;
00222     }
00223 
00224     // Make sure the next character is a semicolon...
00225     if ((ch = getc(fp)) != ';')
00226     {
00227       Fl::error("Fl_File_Icon::load_fti(): Expected a ; at file position %ld (saw '%c')",
00228                 ftell(fp) - 1, ch);
00229       break;
00230     }
00231 
00232     // Now process the command...
00233     if (strcmp(command, "color") == 0)
00234     {
00235       // Set the color; for negative colors blend the two primaries to
00236       // produce a composite color.  Also, the following symbolic color
00237       // names are understood:
00238       //
00239       //     name           FLTK color
00240       //     -------------  ----------
00241       //     iconcolor      FL_ICON_COLOR; mapped to the icon color in
00242       //                    Fl_File_Icon::draw()
00243       //     shadowcolor    FL_DARK3
00244       //     outlinecolor   FL_BLACK
00245       if (strcmp(params, "iconcolor") == 0)
00246         add_color(FL_ICON_COLOR);
00247       else if (strcmp(params, "shadowcolor") == 0)
00248         add_color(FL_DARK3);
00249       else if (strcmp(params, "outlinecolor") == 0)
00250         add_color(FL_BLACK);
00251       else
00252       {
00253         int c = atoi(params);   // Color value
00254 
00255 
00256         if (c < 0)
00257         {
00258           // Composite color; compute average...
00259           c = -c;
00260           add_color(fl_color_average((Fl_Color)(c >> 4),
00261                                      (Fl_Color)(c & 15), 0.5f));
00262         }
00263         else
00264           add_color((Fl_Color)c);
00265       }
00266     }
00267     else if (strcmp(command, "bgnline") == 0)
00268       add(LINE);
00269     else if (strcmp(command, "bgnclosedline") == 0)
00270       add(CLOSEDLINE);
00271     else if (strcmp(command, "bgnpolygon") == 0)
00272       add(POLYGON);
00273     else if (strcmp(command, "bgnoutlinepolygon") == 0)
00274     {
00275       add(OUTLINEPOLYGON);
00276       outline = add(0) - data_;
00277       add(0);
00278     }
00279     else if (strcmp(command, "endoutlinepolygon") == 0 && outline)
00280     {
00281       unsigned cval; // Color value
00282 
00283       // Set the outline color; see above for valid values...
00284       if (strcmp(params, "iconcolor") == 0)
00285         cval = FL_ICON_COLOR;
00286       else if (strcmp(params, "shadowcolor") == 0)
00287         cval = FL_DARK3;
00288       else if (strcmp(params, "outlinecolor") == 0)
00289         cval = FL_BLACK;
00290       else
00291       {
00292         int c = atoi(params);   // Color value
00293 
00294 
00295         if (c < 0)
00296         {
00297           // Composite color; compute average...
00298           c = -c;
00299           cval = fl_color_average((Fl_Color)(c >> 4), (Fl_Color)(c & 15), 0.5f);
00300         }
00301         else
00302           cval = c;
00303       }
00304 
00305       // Store outline color...
00306       data_[outline]     = cval >> 16;
00307       data_[outline + 1] = cval;
00308 
00309       outline = 0;
00310       add(END);
00311     }
00312     else if (strncmp(command, "end", 3) == 0)
00313       add(END);
00314     else if (strcmp(command, "vertex") == 0)
00315     {
00316       float x, y;               // Coordinates of vertex
00317 
00318 
00319       if (sscanf(params, "%f,%f", &x, &y) != 2)
00320         break;
00321 
00322       add_vertex((short)(int)rint(x * 100.0), (short)(int)rint(y * 100.0));
00323     }
00324     else
00325     {
00326       Fl::error("Fl_File_Icon::load_fti(): Unknown command \"%s\" at file position %ld.",
00327                 command, ftell(fp) - 1);
00328       break;
00329     }
00330   }
00331 
00332   // Close the file and return...
00333   fclose(fp);
00334 
00335 #ifdef DEBUG
00336   printf("Icon File \"%s\":\n", fti);
00337   for (int i = 0; i < num_data_; i ++)
00338     printf("    %d,\n", data_[i]);
00339 #endif /* DEBUG */
00340 
00341   return 0;
00342 }
00343 
00344 
00350 int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
00351 {
00352   Fl_Shared_Image       *img;           // Image file
00353 
00354 
00355   img = Fl_Shared_Image::get(ifile);
00356   if (!img || !img->count() || !img->w() || !img->h()) return -1;
00357 
00358   if (img->count() == 1) {
00359     int         x, y;           // X & Y in image
00360     int         startx;         // Starting X coord
00361     Fl_Color    c,              // Current color
00362                 temp;           // Temporary color
00363     const uchar *row;           // Pointer into image
00364 
00365 
00366     // Loop through grayscale or RGB image...
00367     for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld())
00368     {
00369       for (x = 0, startx = 0, c = (Fl_Color)-1;
00370            x < img->w();
00371            x ++, row += img->d())
00372       {
00373         switch (img->d())
00374         {
00375           case 1 :
00376               temp = fl_rgb_color(row[0], row[0], row[0]);
00377               break;
00378           case 2 :
00379               if (row[1] > 127)
00380                 temp = fl_rgb_color(row[0], row[0], row[0]);
00381               else
00382                 temp = (Fl_Color)-1;
00383               break;
00384           case 3 :
00385               temp = fl_rgb_color(row[0], row[1], row[2]);
00386               break;
00387           default :
00388               if (row[3] > 127)
00389                 temp = fl_rgb_color(row[0], row[1], row[2]);
00390               else
00391                 temp = (Fl_Color)-1;
00392               break;
00393         }
00394 
00395         if (temp != c)
00396         {
00397           if (x > startx && c != (Fl_Color)-1)
00398           {
00399             add_color(c);
00400             add(POLYGON);
00401             add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
00402             add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
00403             add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
00404             add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
00405             add(END);
00406           }
00407 
00408           c      = temp;
00409           startx = x;
00410         }
00411       }
00412 
00413       if (x > startx && c != (Fl_Color)-1)
00414       {
00415         add_color(c);
00416         add(POLYGON);
00417         add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
00418         add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
00419         add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
00420         add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
00421         add(END);
00422       }
00423     }
00424   } else {
00425     int         i, j;                   // Looping vars
00426     int         ch;                     // Current character
00427     int         newch;                  // New character
00428     int         bg;                     // Background color
00429     char        val[16];                // Color value
00430     const char  *lineptr,               // Pointer into line
00431                 *const*ptr;             // Pointer into data array
00432     int         ncolors,                // Number of colors
00433                 chars_per_color;        // Characters per color
00434     Fl_Color    *colors;                // Colors
00435     int         red, green, blue;       // Red, green, and blue values
00436     int         x, y;                   // X & Y in image
00437     int         startx;                 // Starting X coord
00438 
00439 
00440     // Get the pixmap data...
00441     ptr = img->data();
00442     sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
00443 
00444     colors = new Fl_Color[1 << (chars_per_color * 8)];
00445 
00446     // Read the colormap...
00447     memset(colors, 0, sizeof(Fl_Color) << (chars_per_color * 8));
00448     bg = ' ';
00449 
00450     ptr ++;
00451 
00452     if (ncolors < 0) {
00453       // Read compressed colormap...
00454       const uchar *cmapptr;
00455 
00456       ncolors = -ncolors;
00457 
00458       for (i = 0, cmapptr = (const uchar *)*ptr; i < ncolors; i ++, cmapptr += 4)
00459         colors[cmapptr[0]] = fl_rgb_color(cmapptr[1], cmapptr[2], cmapptr[3]);
00460 
00461       ptr ++;
00462     } else {
00463       for (i = 0; i < ncolors; i ++, ptr ++) {
00464         // Get the color's character
00465         lineptr = *ptr;
00466         ch      = *lineptr++;
00467 
00468         if (chars_per_color > 1) ch = (ch << 8) | *lineptr++;
00469 
00470         // Get the color value...
00471         if ((lineptr = strstr(lineptr, "c ")) == NULL) {
00472           // No color; make this black...
00473           colors[ch] = FL_BLACK;
00474         } else if (lineptr[2] == '#') {
00475           // Read the RGB triplet...
00476           lineptr += 3;
00477           for (j = 0; j < 12; j ++)
00478             if (!isxdigit(lineptr[j]))
00479               break;
00480 
00481           switch (j) {
00482             case 0 :
00483                 bg = ch;
00484             default :
00485                 red = green = blue = 0;
00486                 break;
00487 
00488             case 3 :
00489                 val[0] = lineptr[0];
00490                 val[1] = '\0';
00491                 red = 255 * strtol(val, NULL, 16) / 15;
00492 
00493                 val[0] = lineptr[1];
00494                 val[1] = '\0';
00495                 green = 255 * strtol(val, NULL, 16) / 15;
00496 
00497                 val[0] = lineptr[2];
00498                 val[1] = '\0';
00499                 blue = 255 * strtol(val, NULL, 16) / 15;
00500                 break;
00501 
00502             case 6 :
00503             case 9 :
00504             case 12 :
00505                 j /= 3;
00506 
00507                 val[0] = lineptr[0];
00508                 val[1] = lineptr[1];
00509                 val[2] = '\0';
00510                 red = strtol(val, NULL, 16);
00511 
00512                 val[0] = lineptr[j + 0];
00513                 val[1] = lineptr[j + 1];
00514                 val[2] = '\0';
00515                 green = strtol(val, NULL, 16);
00516 
00517                 val[0] = lineptr[2 * j + 0];
00518                 val[1] = lineptr[2 * j + 1];
00519                 val[2] = '\0';
00520                 blue = strtol(val, NULL, 16);
00521                 break;
00522           }
00523 
00524           colors[ch] = fl_rgb_color((uchar)red, (uchar)green, (uchar)blue);
00525         } else {
00526           // Read a color name...
00527           if (strncasecmp(lineptr + 2, "white", 5) == 0) colors[ch] = FL_WHITE;
00528           else if (strncasecmp(lineptr + 2, "black", 5) == 0) colors[ch] = FL_BLACK;
00529           else if (strncasecmp(lineptr + 2, "none", 4) == 0) {
00530             colors[ch] = FL_BLACK;
00531             bg = ch;
00532           } else colors[ch] = FL_GRAY;
00533         }
00534       }
00535     }
00536 
00537     // Read the image data...
00538     for (y = 0; y < img->h(); y ++, ptr ++) {
00539       lineptr = *ptr;
00540       startx  = 0;
00541       ch      = bg;
00542 
00543       for (x = 0; x < img->w(); x ++) {
00544         newch = *lineptr++;
00545 
00546         if (chars_per_color > 1) newch = (newch << 8) | *lineptr++;
00547 
00548         if (newch != ch) {
00549           if (ch != bg) {
00550             add_color(colors[ch]);
00551             add(POLYGON);
00552             add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
00553             add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
00554             add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
00555             add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
00556             add(END);
00557           }
00558 
00559           ch     = newch;
00560           startx = x;
00561         }
00562       }
00563 
00564       if (ch != bg) {
00565         add_color(colors[ch]);
00566         add(POLYGON);
00567         add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
00568         add_vertex(x * 9000 / img->w() + 1000,      9500 - y * 9000 / img->h());
00569         add_vertex(x * 9000 / img->w() + 1000,      9500 - (y + 1) * 9000 / img->h());
00570         add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
00571         add(END);
00572       }
00573     }
00574 
00575     // Free the colormap...
00576     delete[] colors;
00577   }
00578 
00579   img->release();
00580 
00581 #ifdef DEBUG
00582   printf("Icon File \"%s\":\n", xpm);
00583   for (i = 0; i < num_data_; i ++)
00584     printf("    %d,\n", data_[i]);
00585 #endif // DEBUG
00586 
00587   return 0;
00588 }
00589 
00590 
00599 void
00600 Fl_File_Icon::load_system_icons(void) {
00601   int           i;              // Looping var
00602   Fl_File_Icon  *icon;          // New icons
00603   char          filename[FL_PATH_MAX];  // Filename
00604   char          icondir[FL_PATH_MAX];   // Icon directory
00605   static int    init = 0;       // Have the icons been initialized?
00606   const char * const icondirs[] = {
00607                   "Bluecurve",  // Icon directories to look for, in order
00608                   "crystalsvg",
00609                   "default.kde",
00610                   "hicolor",
00611                   NULL
00612                 };
00613   static short  plain[] = {     // Plain file icon
00614                   COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
00615                   VERTEX, 2000, 1000, VERTEX, 2000, 9000,
00616                   VERTEX, 6000, 9000, VERTEX, 8000, 7000,
00617                   VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
00618                   VERTEX, 6000, 9000, VERTEX, 6000, 7000,
00619                   VERTEX, 8000, 7000, END,
00620                   COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
00621                   VERTEX, 8000, 7000, VERTEX, 8000, 1000,
00622                   VERTEX, 2000, 1000, END, LINE, VERTEX, 3000, 7000,
00623                   VERTEX, 5000, 7000, END, LINE, VERTEX, 3000, 6000,
00624                   VERTEX, 5000, 6000, END, LINE, VERTEX, 3000, 5000,
00625                   VERTEX, 7000, 5000, END, LINE, VERTEX, 3000, 4000,
00626                   VERTEX, 7000, 4000, END, LINE, VERTEX, 3000, 3000,
00627                   VERTEX, 7000, 3000, END, LINE, VERTEX, 3000, 2000,
00628                   VERTEX, 7000, 2000, END, 
00629                   END
00630                 };
00631   static short  image[] = {     // Image file icon
00632                   COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY,
00633                   VERTEX, 2000, 1000, VERTEX, 2000, 9000,
00634                   VERTEX, 6000, 9000, VERTEX, 8000, 7000,
00635                   VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY,
00636                   VERTEX, 6000, 9000, VERTEX, 6000, 7000,
00637                   VERTEX, 8000, 7000, END,
00638                   COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000,
00639                   VERTEX, 8000, 7000, VERTEX, 8000, 1000,
00640                   VERTEX, 2000, 1000, END,
00641                   COLOR, 0, FL_RED, POLYGON, VERTEX, 3500, 2500,
00642                   VERTEX, 3000, 3000, VERTEX, 3000, 4000,
00643                   VERTEX, 3500, 4500, VERTEX, 4500, 4500,
00644                   VERTEX, 5000, 4000, VERTEX, 5000, 3000,
00645                   VERTEX, 4500, 2500, END,
00646                   COLOR, 0, FL_GREEN, POLYGON, VERTEX, 5500, 2500,
00647                   VERTEX, 5000, 3000, VERTEX, 5000, 4000,
00648                   VERTEX, 5500, 4500, VERTEX, 6500, 4500,
00649                   VERTEX, 7000, 4000, VERTEX, 7000, 3000,
00650                   VERTEX, 6500, 2500, END,
00651                   COLOR, 0, FL_BLUE, POLYGON, VERTEX, 4500, 3500,
00652                   VERTEX, 4000, 4000, VERTEX, 4000, 5000,
00653                   VERTEX, 4500, 5500, VERTEX, 5500, 5500,
00654                   VERTEX, 6000, 5000, VERTEX, 6000, 4000,
00655                   VERTEX, 5500, 3500, END,
00656                   END
00657                 };
00658   static short  dir[] = {       // Directory icon
00659                   COLOR, -1, -1, POLYGON, VERTEX, 1000, 1000,
00660                   VERTEX, 1000, 7500,  VERTEX, 9000, 7500,
00661                   VERTEX, 9000, 1000, END,
00662                   POLYGON, VERTEX, 1000, 7500, VERTEX, 2500, 9000,
00663                   VERTEX, 5000, 9000, VERTEX, 6500, 7500, END,
00664                   COLOR, 0, FL_WHITE, LINE, VERTEX, 1500, 1500,
00665                   VERTEX, 1500, 7000, VERTEX, 9000, 7000, END,
00666                   COLOR, 0, FL_BLACK, LINE, VERTEX, 9000, 7500,
00667                   VERTEX, 9000, 1000, VERTEX, 1000, 1000, END,
00668                   COLOR, 0, FL_GRAY, LINE, VERTEX, 1000, 1000,
00669                   VERTEX, 1000, 7500, VERTEX, 2500, 9000,
00670                   VERTEX, 5000, 9000, VERTEX, 6500, 7500,
00671                   VERTEX, 9000, 7500, END,
00672                   END
00673                 };
00674 
00675 
00676   // Add symbols if they haven't been added already...
00677   if (!init) {
00678     // This method requires the images library...
00679     fl_register_images();
00680 
00681     if (!kdedir) {
00682       // Figure out where KDE is installed...
00683       if ((kdedir = getenv("KDEDIR")) == NULL) {
00684         if (!access("/opt/kde", F_OK)) kdedir = "/opt/kde";
00685         else if (!access("/usr/local/share/mimelnk", F_OK)) kdedir = "/usr/local";
00686         else kdedir = "/usr";
00687       }
00688     }
00689 
00690     snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
00691 
00692     if (!access(filename, F_OK)) {
00693       // Load KDE icons...
00694       icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
00695 
00696       for (i = 0; icondirs[i]; i ++) {
00697         snprintf(icondir, sizeof(icondir), "%s/share/icons/%s", kdedir,
00698                  icondirs[i]);
00699 
00700         if (!access(icondir, F_OK)) break;
00701       }
00702 
00703       if (icondirs[i]) {
00704         snprintf(filename, sizeof(filename), "%s/16x16/mimetypes/unknown.png",
00705                  icondir);
00706       } else {
00707         snprintf(filename, sizeof(filename), "%s/share/icons/unknown.xpm",
00708                  kdedir);
00709       }
00710 
00711       if (!access(filename, F_OK)) icon->load_image(filename);
00712 
00713       icon = new Fl_File_Icon("*", Fl_File_Icon::LINK);
00714 
00715       snprintf(filename, sizeof(filename), "%s/16x16/filesystems/link.png",
00716                icondir);
00717 
00718       if (!access(filename, F_OK)) icon->load_image(filename);
00719 
00720       snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir);
00721       load_kde_icons(filename, icondir);
00722     } else if (!access("/usr/share/icons/folder.xpm", F_OK)) {
00723       // Load GNOME icons...
00724       icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
00725       icon->load_image("/usr/share/icons/page.xpm");
00726 
00727       icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
00728       icon->load_image("/usr/share/icons/folder.xpm");
00729     } else if (!access("/usr/dt/appconfig/icons", F_OK)) {
00730       // Load CDE icons...
00731       icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
00732       icon->load_image("/usr/dt/appconfig/icons/C/Dtdata.m.pm");
00733 
00734       icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
00735       icon->load_image("/usr/dt/appconfig/icons/C/DtdirB.m.pm");
00736 
00737       icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
00738       icon->load_image("/usr/dt/appconfig/icons/C/Dtcore.m.pm");
00739 
00740       icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
00741       icon->load_image("/usr/dt/appconfig/icons/C/Dtimage.m.pm");
00742 
00743       icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
00744       icon->load_image("/usr/dt/appconfig/icons/C/Dtps.m.pm");
00745 
00746       icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
00747       icon->load_image("/usr/dt/appconfig/icons/C/DtPrtpr.m.pm");
00748     } else if (!access("/usr/lib/filetype", F_OK)) {
00749       // Load SGI icons...
00750       icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN);
00751       icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
00752 
00753       icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
00754       icon->load_fti("/usr/lib/filetype/iconlib/generic.folder.closed.fti");
00755 
00756       icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN);
00757       icon->load_fti("/usr/lib/filetype/default/iconlib/CoreFile.fti");
00758 
00759       icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN);
00760       icon->load_fti("/usr/lib/filetype/system/iconlib/ImageFile.fti");
00761 
00762       if (!access("/usr/lib/filetype/install/iconlib/acroread.doc.fti", F_OK)) {
00763         icon = new Fl_File_Icon("*.{eps|ps}", Fl_File_Icon::PLAIN);
00764         icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
00765 
00766         icon = new Fl_File_Icon("*.pdf", Fl_File_Icon::PLAIN);
00767         icon->load_fti("/usr/lib/filetype/install/iconlib/acroread.doc.fti");
00768       } else {
00769         icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN);
00770         icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti");
00771       }
00772 
00773       if (!access("/usr/lib/filetype/install/iconlib/html.fti", F_OK)) {
00774         icon = new Fl_File_Icon("*.{htm|html|shtml}", Fl_File_Icon::PLAIN);
00775         icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti");
00776         icon->load_fti("/usr/lib/filetype/install/iconlib/html.fti");
00777       }
00778 
00779       if (!access("/usr/lib/filetype/install/iconlib/color.ps.idle.fti", F_OK)) {
00780         icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN);
00781         icon->load_fti("/usr/lib/filetype/install/iconlib/color.ps.idle.fti");
00782       }
00783     } else {
00784       // Create the default icons...
00785       new Fl_File_Icon("*", Fl_File_Icon::PLAIN, sizeof(plain) / sizeof(plain[0]), plain);
00786       new Fl_File_Icon("*.{bm|bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN,
00787                    sizeof(image) / sizeof(image[0]), image);
00788       new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY, sizeof(dir) / sizeof(dir[0]), dir);
00789     }
00790 
00791     // Mark things as initialized...
00792     init = 1;
00793 
00794 #ifdef DEBUG
00795     int count;
00796     Fl_File_Icon *temp;
00797     for (count = 0, temp = first_; temp; temp = temp->next_, count ++);
00798     printf("count of Fl_File_Icon's is %d...\n", count);
00799 #endif // DEBUG
00800   }
00801 }
00802 
00803 
00804 //
00805 // 'load_kde_icons()' - Load KDE icon files.
00806 //
00807 
00808 static void
00809 load_kde_icons(const char *directory,   // I - Directory to load
00810                const char *icondir) {   // I - Location of icons
00811   int           i;                      // Looping var
00812   int           n;                      // Number of entries in directory
00813   dirent        **entries;              // Entries in directory
00814   char          full[FL_PATH_MAX];      // Full name of file
00815 
00816 
00817   entries = (dirent **)0;
00818   n       = fl_filename_list(directory, &entries);
00819 
00820   for (i = 0; i < n; i ++) {
00821     if (entries[i]->d_name[0] != '.') {
00822       snprintf(full, sizeof(full), "%s/%s", directory, entries[i]->d_name);
00823 
00824       if (fl_filename_isdir(full)) load_kde_icons(full, icondir);
00825       else load_kde_mimelnk(full, icondir);
00826     }
00827 
00828     free((void *)entries[i]);
00829   }
00830 
00831   free((void*)entries);
00832 }
00833 
00834 
00835 //
00836 // 'load_kde_mimelnk()' - Load a KDE "mimelnk" file.
00837 //
00838 
00839 static void
00840 load_kde_mimelnk(const char *filename,  // I - mimelnk filename
00841                  const char *icondir) { // I - Location of icons
00842   FILE          *fp;
00843   char          tmp[1024];
00844   char          iconfilename[FL_PATH_MAX];
00845   char          pattern[1024];
00846   char          mimetype[1024];
00847   char          *val;
00848   char          full_iconfilename[FL_PATH_MAX];
00849   Fl_File_Icon  *icon;
00850 
00851 
00852   mimetype[0]     = '\0';
00853   pattern[0]      = '\0';
00854   iconfilename[0] = '\0';
00855 
00856   if ((fp = fl_fopen(filename, "rb")) != NULL) {
00857     while (fgets(tmp, sizeof(tmp), fp)) {
00858       if ((val = get_kde_val(tmp, "Icon")) != NULL)
00859         strlcpy(iconfilename, val, sizeof(iconfilename));
00860       else if ((val = get_kde_val(tmp, "MimeType")) != NULL)
00861         strlcpy(mimetype, val, sizeof(mimetype));
00862       else if ((val = get_kde_val(tmp, "Patterns")) != NULL)
00863         strlcpy(pattern, val, sizeof(pattern));
00864     }
00865 
00866     fclose(fp);
00867 
00868 #ifdef DEBUG
00869     printf("%s: Icon=\"%s\", MimeType=\"%s\", Patterns=\"%s\"\n", filename,
00870            iconfilename, mimetype, pattern);
00871 #endif // DEBUG
00872 
00873     if (!pattern[0] && strncmp(mimetype, "inode/", 6)) return;
00874 
00875     if (iconfilename[0]) {
00876       if (iconfilename[0] == '/') {
00877         strlcpy(full_iconfilename, iconfilename, sizeof(full_iconfilename));
00878       } else if (!access(icondir, F_OK)) {
00879         // KDE 3.x and 2.x icons
00880         int             i;              // Looping var
00881         static const char *paths[] = {  // Subdirs to look in...
00882           "16x16/actions",
00883           "16x16/apps",
00884           "16x16/devices",
00885           "16x16/filesystems",
00886           "16x16/mimetypes",
00887 /*
00888           "20x20/actions",
00889           "20x20/apps",
00890           "20x20/devices",
00891           "20x20/filesystems",
00892           "20x20/mimetypes",
00893 
00894           "22x22/actions",
00895           "22x22/apps",
00896           "22x22/devices",
00897           "22x22/filesystems",
00898           "22x22/mimetypes",
00899 
00900           "24x24/actions",
00901           "24x24/apps",
00902           "24x24/devices",
00903           "24x24/filesystems",
00904           "24x24/mimetypes",
00905 */
00906           "32x32/actions",
00907           "32x32/apps",
00908           "32x32/devices",
00909           "32x32/filesystems",
00910           "32x32/mimetypes",
00911 /*
00912           "36x36/actions",
00913           "36x36/apps",
00914           "36x36/devices",
00915           "36x36/filesystems",
00916           "36x36/mimetypes",
00917 
00918           "48x48/actions",
00919           "48x48/apps",
00920           "48x48/devices",
00921           "48x48/filesystems",
00922           "48x48/mimetypes",
00923 
00924           "64x64/actions",
00925           "64x64/apps",
00926           "64x64/devices",
00927           "64x64/filesystems",
00928           "64x64/mimetypes",
00929 
00930           "96x96/actions",
00931           "96x96/apps",
00932           "96x96/devices",
00933           "96x96/filesystems",
00934           "96x96/mimetypes"
00935 */      };
00936 
00937         for (i = 0; i < (int)(sizeof(paths) / sizeof(paths[0])); i ++) {
00938           snprintf(full_iconfilename, sizeof(full_iconfilename),
00939                    "%s/%s/%s.png", icondir, paths[i], iconfilename);
00940 
00941           if (!access(full_iconfilename, F_OK)) break;
00942         }
00943 
00944         if (i >= (int)(sizeof(paths) / sizeof(paths[0]))) return;
00945       } else {
00946         // KDE 1.x icons
00947         snprintf(full_iconfilename, sizeof(full_iconfilename),
00948                  "%s/%s", tmp, iconfilename);
00949 
00950         if (access(full_iconfilename, F_OK)) return;
00951       }
00952 
00953       if (strncmp(mimetype, "inode/", 6) == 0) {
00954         if (!strcmp(mimetype + 6, "directory"))
00955           icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY);
00956         else if (!strcmp(mimetype + 6, "blockdevice"))
00957           icon = new Fl_File_Icon("*", Fl_File_Icon::DEVICE);
00958         else if (!strcmp(mimetype + 6, "fifo"))
00959           icon = new Fl_File_Icon("*", Fl_File_Icon::FIFO);
00960         else return;
00961       } else {
00962         icon = new Fl_File_Icon(kde_to_fltk_pattern(pattern),
00963                                 Fl_File_Icon::PLAIN);
00964       }
00965 
00966       icon->load(full_iconfilename);
00967     }
00968   }
00969 }
00970 
00971 
00972 //
00973 // 'kde_to_fltk_pattern()' - Convert a KDE pattern to a FLTK pattern.
00974 //
00975 
00976 static char *
00977 kde_to_fltk_pattern(const char *kdepattern) {
00978   char  *pattern,
00979         *patptr;
00980 
00981 
00982   pattern = (char *)malloc(strlen(kdepattern) + 3);
00983   strcpy(pattern, "{");
00984   strcpy(pattern + 1, kdepattern);
00985 
00986   if (pattern[strlen(pattern) - 1] == ';') pattern[strlen(pattern) - 1] = '\0';
00987 
00988   strcat(pattern, "}");
00989 
00990   for (patptr = pattern; *patptr; patptr ++) {
00991     if (*patptr == ';') *patptr = '|';
00992   }
00993 
00994   return (pattern);
00995 }
00996 
00997 
00998 //
00999 // 'get_kde_val()' - Get a KDE value.
01000 //
01001 
01002 static char *
01003 get_kde_val(char       *str,
01004             const char *key) {
01005   while (*str == *key) {
01006     str ++;
01007     key ++;
01008   }
01009 
01010   if (*key == '\0' && *str == '=') {
01011     if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0';
01012 
01013     return (str + 1);
01014   }
01015 
01016   return ((char *)0);
01017 }
01018 
01019 
01020 //
01021 // End of "$Id: Fl_File_Icon2.cxx 8063 2010-12-19 21:20:10Z matt $".
01022 //