r110: Added a option for using RISC OS mouse bindings to the options box, although
[rox-filer.git] / ROX-Filer / src / type.c
blob4688641e4da1d1b4072eacda29e3dace8deb0805
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 1999, 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)
10 * any later version.
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
15 * more details.
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 */
24 #include <glib.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <ctype.h>
31 #include "string.h"
32 #include "filer.h"
33 #include "pixmaps.h"
34 #include "apps.h"
35 #include "gui_support.h"
36 #include "choices.h"
37 #include "type.h"
38 #include "support.h"
39 #include "options.h"
41 /* Static prototypes */
42 static char *import_extensions(char *line);
44 /* Maps extensions to MIME_types (eg 'png'-> MIME_type *) */
45 static GHashTable *extension_hash = NULL;
46 static char *current_type = NULL; /* (used while reading file) */
48 /* Most things on Unix are text files, so this is the default type */
49 MIME_type text_plain = {"text", "plain"};
51 void type_init()
53 ChoicesList *paths, *next;
55 extension_hash = g_hash_table_new(g_str_hash, g_str_equal);
57 paths = choices_find_load_all("guess", "MIME-types");
58 while (paths)
60 current_type = NULL;
61 parse_file(paths->path, import_extensions);
62 next = paths->next;
63 g_free(paths->path);
64 g_free(paths);
65 paths = next;
69 /* Add one entry to the extension_hash table */
70 static void add_ext(char *type_name, char *ext)
72 MIME_type *new;
73 char *slash;
74 int len;
76 slash = strchr(type_name, '/');
77 g_return_if_fail(slash != NULL); /* XXX: Report nicely */
78 len = slash - type_name;
80 new = g_malloc(sizeof(MIME_type));
81 new->media_type = g_malloc(sizeof(char) * (len + 1));
82 memcpy(new->media_type, type_name, len);
83 new->media_type[len] = '\0';
85 new->subtype = g_strdup(slash + 1);
86 new->image = NULL;
88 g_hash_table_insert(extension_hash, g_strdup(ext), new);
91 /* Parse one line from the file and add entries to extension_hash */
92 static char *import_extensions(char *line)
95 if (*line == '\0' || *line == '#')
96 return NULL; /* Comment */
98 if (isspace(*line))
100 if (!current_type)
101 return "Missing MIME-type";
102 while (*line && isspace(*line))
103 line++;
105 if (strncmp(line, "ext:", 4) == 0)
107 char *ext;
108 line += 4;
110 for (;;)
112 while (*line && isspace(*line))
113 line++;
114 if (*line == '\0')
115 break;
116 ext = line;
117 while (*line && !isspace(*line))
118 line++;
119 if (*line)
120 *line++ = '\0';
121 add_ext(current_type, ext);
124 /* else ignore */
126 else
128 char *type = line;
129 while (*line && !isspace(*line))
130 line++;
131 if (*line)
132 *line++ = '\0';
133 while (*line && isspace(*line))
134 line++;
135 if (*line)
136 return "Trailing chars after MIME-type";
137 current_type = g_strdup(type);
139 return NULL;
142 char *basetype_name(FileItem *item)
144 if (item->flags & ITEM_FLAG_SYMLINK)
145 return "Sym link";
146 else if (item->flags & ITEM_FLAG_MOUNT_POINT)
147 return "Mount point";
148 else if (item->flags & ITEM_FLAG_APPDIR)
149 return "App dir";
151 switch (item->base_type)
153 case TYPE_FILE:
154 return "File";
155 case TYPE_DIRECTORY:
156 return "Dir";
157 case TYPE_CHAR_DEVICE:
158 return "Char dev";
159 case TYPE_BLOCK_DEVICE:
160 return "Block dev";
161 case TYPE_PIPE:
162 return "Pipe";
163 case TYPE_SOCKET:
164 return "Socket";
167 return "Unknown";
170 /* MIME-type guessing */
172 /* Returns a pointer to the MIME-type string, or NULL if we have
173 * no opinion.
175 MIME_type *type_from_path(char *path)
177 char *dot;
179 dot = strrchr(path, '.');
180 if (dot)
182 MIME_type *type;
183 type = g_hash_table_lookup(extension_hash, dot + 1);
184 if (type)
185 return type;
188 return &text_plain;
191 /* Actions for types */
193 gboolean type_open(char *path, MIME_type *type)
195 char *argv[] = {NULL, NULL, NULL};
196 char *open;
197 char *type_name;
199 argv[1] = path;
201 type_name = g_strconcat(type->media_type, "_", type->subtype, NULL);
202 open = choices_find_path_load_shared(type_name, "MIME-types");
203 g_free(type_name);
204 if (!open)
206 open = choices_find_path_load_shared(type->media_type,
207 "MIME-types");
208 if (!open)
209 return FALSE;
212 argv[0] = g_strconcat(open, "/AppRun", NULL);
214 if (!spawn_full(argv, getenv("HOME"), 0))
215 report_error("ROX-Filer",
216 "Failed to fork() child process");
218 g_free(argv[0]);
220 return TRUE;
223 /* Return the image for this type, loading it if needed.
224 * Places to check are: (eg type="text_plain", base="text")
225 * 1. Choices:MIME-icons/<type>
226 * 2. Choices:MIME-icons/<base>
227 * 3. Unknown type icon.
229 MaskedPixmap *type_to_icon(GtkWidget *window, MIME_type *type)
231 char *path;
232 char *type_name;
234 g_return_val_if_fail(type != NULL, default_pixmap + TYPE_UNKNOWN);
236 /* Already got an image? TODO: Is it out-of-date? */
237 if (type->image)
238 return type->image;
240 type_name = g_strconcat(type->media_type, "_",
241 type->subtype, ".xpm", NULL);
242 path = choices_find_path_load_shared(type_name, "MIME-icons");
243 if (!path)
245 strcpy(type_name + strlen(type->media_type), ".xpm");
246 path = choices_find_path_load_shared(type_name, "MIME-icons");
249 g_free(type_name);
251 if (path)
252 type->image = load_pixmap_from(window, path);
254 if (!type->image)
255 type->image = default_pixmap + TYPE_UNKNOWN;
257 return type->image;
260 GdkAtom type_to_atom(MIME_type *type)
262 char *str;
263 GdkAtom retval;
265 g_return_val_if_fail(type != NULL, GDK_NONE);
267 str = g_strconcat(type->media_type, "/", type->subtype, NULL);
268 retval = gdk_atom_intern(str, FALSE);
269 g_free(str);
271 return retval;