4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@ecs.soton.ac.uk>.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* type.c - code for dealing with filetypes */
39 #include "gui_support.h"
45 /* Static prototypes */
46 static char *import_extensions(guchar
*line
);
48 /* Maps extensions to MIME_types (eg 'png'-> MIME_type *) */
49 static GHashTable
*extension_hash
= NULL
;
50 static char *current_type
= NULL
; /* (used while reading file) */
52 /* Most things on Unix are text files, so this is the default type */
53 MIME_type text_plain
= {"text", "plain", NULL
};
57 ChoicesList
*paths
, *next
;
59 extension_hash
= g_hash_table_new(g_str_hash
, g_str_equal
);
61 paths
= choices_find_load_all("guess", "MIME-types");
65 parse_file(paths
->path
, import_extensions
);
73 /* Add one entry to the extension_hash table */
74 static void add_ext(char *type_name
, char *ext
)
80 slash
= strchr(type_name
, '/');
81 g_return_if_fail(slash
!= NULL
); /* XXX: Report nicely */
82 len
= slash
- type_name
;
84 new = g_new(MIME_type
, 1);
85 new->media_type
= g_malloc(sizeof(char) * (len
+ 1));
86 memcpy(new->media_type
, type_name
, len
);
87 new->media_type
[len
] = '\0';
89 new->subtype
= g_strdup(slash
+ 1);
92 g_hash_table_insert(extension_hash
, g_strdup(ext
), new);
95 /* Parse one line from the file and add entries to extension_hash */
96 static char *import_extensions(guchar
*line
)
99 if (*line
== '\0' || *line
== '#')
100 return NULL
; /* Comment */
105 return "Missing MIME-type";
106 while (*line
&& isspace(*line
))
109 if (strncmp(line
, "ext:", 4) == 0)
116 while (*line
&& isspace(*line
))
121 while (*line
&& !isspace(*line
))
125 add_ext(current_type
, ext
);
133 while (*line
&& *line
!= ':' && !isspace(*line
))
137 while (*line
&& isspace(*line
))
140 return "Trailing chars after MIME-type";
141 current_type
= g_strdup(type
);
146 char *basetype_name(DirItem
*item
)
148 if (item
->flags
& ITEM_FLAG_SYMLINK
)
150 else if (item
->flags
& ITEM_FLAG_MOUNT_POINT
)
151 return "Mount point";
152 else if (item
->flags
& ITEM_FLAG_APPDIR
)
155 switch (item
->base_type
)
161 case TYPE_CHAR_DEVICE
:
163 case TYPE_BLOCK_DEVICE
:
174 /* MIME-type guessing */
176 /* Returns a pointer to the MIME-type string, or NULL if we have
179 MIME_type
*type_from_path(char *path
)
183 dot
= strrchr(path
, '.');
187 type
= g_hash_table_lookup(extension_hash
, dot
+ 1);
195 /* Actions for types */
197 gboolean
type_open(char *path
, MIME_type
*type
)
199 char *argv
[] = {NULL
, NULL
, NULL
};
202 gboolean retval
= TRUE
;
207 type_name
= g_strconcat(type
->media_type
, "_", type
->subtype
, NULL
);
208 open
= choices_find_path_load_shared(type_name
, "MIME-types");
212 open
= choices_find_path_load_shared(type
->media_type
,
218 if (stat(open
, &info
))
220 report_error("ROX-Filer", g_strerror(errno
));
224 if (S_ISDIR(info
.st_mode
))
225 argv
[0] = g_strconcat(open
, "/AppRun", NULL
);
229 if (!spawn_full(argv
, home_dir
))
231 report_error("ROX-Filer",
232 "Failed to fork() child process");
242 /* Return the image for this type, loading it if needed.
243 * Places to check are: (eg type="text_plain", base="text")
244 * 1. Choices:MIME-icons/<type>
245 * 2. Choices:MIME-icons/<base>
246 * 3. Unknown type icon.
248 * Note: You must pixmap_unref() the image afterwards.
250 MaskedPixmap
*type_to_icon(MIME_type
*type
)
256 g_return_val_if_fail(type
!= NULL
, default_pixmap
+ TYPE_UNKNOWN
);
259 /* Already got an image? */
262 /* Yes - don't recheck too often */
263 if (abs(now
- type
->image_time
) < 2)
265 pixmap_ref(type
->image
);
268 pixmap_unref(type
->image
);
272 type_name
= g_strconcat(type
->media_type
, "_",
273 type
->subtype
, ".xpm", NULL
);
274 path
= choices_find_path_load_shared(type_name
, "MIME-icons");
277 strcpy(type_name
+ strlen(type
->media_type
), ".xpm");
278 path
= choices_find_path_load_shared(type_name
, "MIME-icons");
284 type
->image
= g_fscache_lookup(pixmap_cache
, path
);
288 type
->image
= default_pixmap
+ TYPE_UNKNOWN
;
289 pixmap_ref(type
->image
);
292 type
->image_time
= now
;
294 pixmap_ref(type
->image
);
298 GdkAtom
type_to_atom(MIME_type
*type
)
303 g_return_val_if_fail(type
!= NULL
, GDK_NONE
);
305 str
= g_strconcat(type
->media_type
, "/", type
->subtype
, NULL
);
306 retval
= gdk_atom_intern(str
, FALSE
);