4 * ROX-Filer, filer for the ROX desktop project
5 * By Thomas Leonard, <tal197@ecs.soton.ac.uk>.
8 /* type.c - code for dealing with filetypes */
21 #include "gui_support.h"
27 /* Static prototypes */
28 static char *import_extensions(char *line
);
30 /* Maps extensions to MIME_types (eg 'png'-> MIME_type *) */
31 static GHashTable
*extension_hash
= NULL
;
32 static char *current_type
= NULL
; /* (used while reading file) */
34 /* Most things on Unix are text files, so this is the default type */
35 static MIME_type text_plain
= {"text", "plain"};
41 extension_hash
= g_hash_table_new(g_str_hash
, g_str_equal
);
43 path
= choices_find_path_load_shared("guess", "MIME-types");
47 parse_file(path
, import_extensions
);
51 /* Add one entry to the extension_hash table */
52 static void add_ext(char *type_name
, char *ext
)
58 slash
= strchr(type_name
, '/');
59 g_return_if_fail(slash
!= NULL
); /* XXX: Report nicely */
60 len
= slash
- type_name
;
62 new = g_malloc(sizeof(MIME_type
));
63 new->media_type
= g_malloc(sizeof(char) * (len
+ 1));
64 memcpy(new->media_type
, type_name
, len
);
65 new->media_type
[len
] = '\0';
67 new->subtype
= g_strdup(slash
+ 1);
70 printf("Type = '%s', subtype = '%s', ext = '%s'\n",
71 new->media_type
, new->subtype
, ext
);
72 g_hash_table_insert(extension_hash
, g_strdup(ext
), new);
75 /* Parse one line from the file and add entries to extension_hash */
76 static char *import_extensions(char *line
)
79 if (*line
== '\0' || *line
== '#')
80 return NULL
; /* Comment */
85 return "Missing MIME-type";
86 while (*line
&& isspace(*line
))
89 if (strncmp(line
, "ext:", 4) == 0)
96 while (*line
&& isspace(*line
))
101 while (*line
&& !isspace(*line
))
105 add_ext(current_type
, ext
);
113 while (*line
&& !isspace(*line
))
117 while (*line
&& isspace(*line
))
120 return "Trailing chars after MIME-type";
121 current_type
= g_strdup(type
);
126 char *basetype_name(FileItem
*item
)
128 if (item
->flags
& ITEM_FLAG_SYMLINK
)
130 else if (item
->flags
& ITEM_FLAG_MOUNT_POINT
)
131 return "Mount point";
132 else if (item
->flags
& ITEM_FLAG_APPDIR
)
135 switch (item
->base_type
)
141 case TYPE_CHAR_DEVICE
:
143 case TYPE_BLOCK_DEVICE
:
154 /* MIME-type guessing */
156 /* Returns a pointer to the MIME-type string, or NULL if we have
159 MIME_type
*type_from_path(char *path
)
163 dot
= strrchr(path
, '.');
167 type
= g_hash_table_lookup(extension_hash
, dot
+ 1);
175 /* Actions for types */
177 gboolean
type_open(char *path
, MIME_type
*type
)
179 char *argv
[] = {NULL
, path
, NULL
};
183 type_name
= g_strconcat(type
->media_type
, "_", type
->subtype
, NULL
);
184 open
= choices_find_path_load_shared(type_name
, "MIME-types");
189 argv
[0] = g_strconcat(open
, "/AppRun", NULL
);
191 if (!spawn_full(argv
, getenv("HOME"), 0))
192 report_error("ROX-Filer",
193 "Failed to fork() child process");
200 /* Return the image for this type, loading it if needed.
201 * Places to check are: (eg type="text_plain", base="text")
202 * 1. Choices/MIME-types/<type>/MIME-icons/<type>
203 * 2. Choices/MIME-types/<type>/MIME-icons/<base>
204 * 3. Choices/MIME-types/<base>/MIME-icons/<base> [ TODO ]
205 * 4. $APP_DIR/MIME-icons/<base>
206 * 5. Unknown type icon.
208 MaskedPixmap
*type_to_icon(GtkWidget
*window
, MIME_type
*type
)
213 g_return_val_if_fail(type
!= NULL
, default_pixmap
+ TYPE_UNKNOWN
);
215 /* Already got an image? TODO: Is it out-of-date? */
219 type_name
= g_strconcat(type
->media_type
, "_", type
->subtype
, NULL
);
221 /* 1 and 2 : Check for icon provided by specific handler */
222 open
= choices_find_path_load_shared(type_name
, "MIME-types");
225 /* 1 : Exact type provided */
226 path
= g_strconcat(open
, "/MIME-icons/", type_name
, ".xpm",
228 type
->image
= load_pixmap_from(window
, path
);
233 /* 2 : Base type provided */
234 path
= g_strconcat(open
, "/MIME-icons/",
235 type
->media_type
, ".xpm", NULL
);
236 type
->image
= load_pixmap_from(window
, path
);
246 /* 4 : Load a default icon from our own application dir */
248 path
= g_strconcat(getenv("APP_DIR"), "/MIME-icons/", type
->media_type
,
250 type
->image
= load_pixmap_from(window
, path
);
256 /* 5 : Use the unknown type icon */
258 type
->image
= default_pixmap
+ TYPE_UNKNOWN
;