1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimppluginmanager-file.c
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "config.h"
21
22 #include <string.h>
23
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 #include <gegl.h>
26
27 #include "plug-in-types.h"
28
29 #include "core/gimp.h"
30 #include "core/gimpparamspecs.h"
31
32 #include "gimpplugin.h"
33 #include "gimpplugindef.h"
34 #include "gimppluginmanager.h"
35 #include "gimppluginmanager-file.h"
36 #include "gimppluginmanager-file-procedure.h"
37 #include "gimppluginprocedure.h"
38
39
40 static gboolean file_procedure_in_group (GimpPlugInProcedure *file_proc,
41 GimpFileProcedureGroup group);
42
43
44 /* public functions */
45
46 gboolean
gimp_plug_in_manager_register_load_handler(GimpPlugInManager * manager,const gchar * name,const gchar * extensions,const gchar * prefixes,const gchar * magics)47 gimp_plug_in_manager_register_load_handler (GimpPlugInManager *manager,
48 const gchar *name,
49 const gchar *extensions,
50 const gchar *prefixes,
51 const gchar *magics)
52 {
53 GimpPlugInProcedure *file_proc;
54 GimpProcedure *procedure;
55 GSList *list;
56
57 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
58 g_return_val_if_fail (name != NULL, FALSE);
59
60 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
61 list = manager->current_plug_in->plug_in_def->procedures;
62 else
63 list = manager->plug_in_procedures;
64
65 file_proc = gimp_plug_in_procedure_find (list, name);
66
67 if (! file_proc)
68 {
69 gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
70 "attempt to register nonexistent load handler \"%s\"",
71 name);
72 return FALSE;
73 }
74
75 procedure = GIMP_PROCEDURE (file_proc);
76
77 if ((procedure->num_args < 3) ||
78 (procedure->num_values < 1) ||
79 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
80 ! G_IS_PARAM_SPEC_STRING (procedure->args[1]) ||
81 ! G_IS_PARAM_SPEC_STRING (procedure->args[2]) ||
82 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0]))
83 {
84 gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
85 "load handler \"%s\" does not take the standard "
86 "load handler args", name);
87 return FALSE;
88 }
89
90 gimp_plug_in_procedure_set_file_proc (file_proc,
91 extensions, prefixes, magics);
92
93 if (! g_slist_find (manager->load_procs, file_proc))
94 manager->load_procs = g_slist_prepend (manager->load_procs, file_proc);
95
96 return TRUE;
97 }
98
99 gboolean
gimp_plug_in_manager_register_save_handler(GimpPlugInManager * manager,const gchar * name,const gchar * extensions,const gchar * prefixes)100 gimp_plug_in_manager_register_save_handler (GimpPlugInManager *manager,
101 const gchar *name,
102 const gchar *extensions,
103 const gchar *prefixes)
104 {
105 GimpPlugInProcedure *file_proc;
106 GimpProcedure *procedure;
107 GSList *list;
108
109 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
110 g_return_val_if_fail (name != NULL, FALSE);
111
112 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
113 list = manager->current_plug_in->plug_in_def->procedures;
114 else
115 list = manager->plug_in_procedures;
116
117 file_proc = gimp_plug_in_procedure_find (list, name);
118
119 if (! file_proc)
120 {
121 gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
122 "attempt to register nonexistent save handler \"%s\"",
123 name);
124 return FALSE;
125 }
126
127 procedure = GIMP_PROCEDURE (file_proc);
128
129 if ((procedure->num_args < 5) ||
130 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
131 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) ||
132 ! GIMP_IS_PARAM_SPEC_DRAWABLE_ID (procedure->args[2]) ||
133 ! G_IS_PARAM_SPEC_STRING (procedure->args[3]) ||
134 ! G_IS_PARAM_SPEC_STRING (procedure->args[4]))
135 {
136 gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
137 "save handler \"%s\" does not take the standard "
138 "save handler args", name);
139 return FALSE;
140 }
141
142 gimp_plug_in_procedure_set_file_proc (file_proc,
143 extensions, prefixes, NULL);
144
145 if (file_procedure_in_group (file_proc, GIMP_FILE_PROCEDURE_GROUP_SAVE))
146 {
147 if (! g_slist_find (manager->save_procs, file_proc))
148 manager->save_procs = g_slist_prepend (manager->save_procs, file_proc);
149 }
150
151 if (file_procedure_in_group (file_proc, GIMP_FILE_PROCEDURE_GROUP_EXPORT))
152 {
153 if (! g_slist_find (manager->export_procs, file_proc))
154 manager->export_procs = g_slist_prepend (manager->export_procs, file_proc);
155 }
156
157 return TRUE;
158 }
159
160 gboolean
gimp_plug_in_manager_register_priority(GimpPlugInManager * manager,const gchar * name,gint priority)161 gimp_plug_in_manager_register_priority (GimpPlugInManager *manager,
162 const gchar *name,
163 gint priority)
164 {
165 GimpPlugInProcedure *file_proc;
166 GSList *list;
167
168 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
169 g_return_val_if_fail (name != NULL, FALSE);
170
171 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
172 list = manager->current_plug_in->plug_in_def->procedures;
173 else
174 list = manager->plug_in_procedures;
175
176 file_proc = gimp_plug_in_procedure_find (list, name);
177
178 if (! file_proc)
179 return FALSE;
180
181 gimp_plug_in_procedure_set_priority (file_proc, priority);
182
183 return TRUE;
184 }
185
186 gboolean
gimp_plug_in_manager_register_mime_types(GimpPlugInManager * manager,const gchar * name,const gchar * mime_types)187 gimp_plug_in_manager_register_mime_types (GimpPlugInManager *manager,
188 const gchar *name,
189 const gchar *mime_types)
190 {
191 GimpPlugInProcedure *file_proc;
192 GSList *list;
193
194 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
195 g_return_val_if_fail (name != NULL, FALSE);
196 g_return_val_if_fail (mime_types != NULL, FALSE);
197
198 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
199 list = manager->current_plug_in->plug_in_def->procedures;
200 else
201 list = manager->plug_in_procedures;
202
203 file_proc = gimp_plug_in_procedure_find (list, name);
204
205 if (! file_proc)
206 return FALSE;
207
208 gimp_plug_in_procedure_set_mime_types (file_proc, mime_types);
209
210 return TRUE;
211 }
212
213 gboolean
gimp_plug_in_manager_register_handles_uri(GimpPlugInManager * manager,const gchar * name)214 gimp_plug_in_manager_register_handles_uri (GimpPlugInManager *manager,
215 const gchar *name)
216 {
217 GimpPlugInProcedure *file_proc;
218 GSList *list;
219
220 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
221 g_return_val_if_fail (name != NULL, FALSE);
222
223 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
224 list = manager->current_plug_in->plug_in_def->procedures;
225 else
226 list = manager->plug_in_procedures;
227
228 file_proc = gimp_plug_in_procedure_find (list, name);
229
230 if (! file_proc)
231 return FALSE;
232
233 gimp_plug_in_procedure_set_handles_uri (file_proc);
234
235 return TRUE;
236 }
237
238 gboolean
gimp_plug_in_manager_register_handles_raw(GimpPlugInManager * manager,const gchar * name)239 gimp_plug_in_manager_register_handles_raw (GimpPlugInManager *manager,
240 const gchar *name)
241 {
242 GimpPlugInProcedure *file_proc;
243 GSList *list;
244
245 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
246 g_return_val_if_fail (name != NULL, FALSE);
247
248 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
249 list = manager->current_plug_in->plug_in_def->procedures;
250 else
251 list = manager->plug_in_procedures;
252
253 file_proc = gimp_plug_in_procedure_find (list, name);
254
255 if (! file_proc)
256 return FALSE;
257
258 gimp_plug_in_procedure_set_handles_raw (file_proc);
259
260 return TRUE;
261 }
262
263 gboolean
gimp_plug_in_manager_register_thumb_loader(GimpPlugInManager * manager,const gchar * load_proc,const gchar * thumb_proc)264 gimp_plug_in_manager_register_thumb_loader (GimpPlugInManager *manager,
265 const gchar *load_proc,
266 const gchar *thumb_proc)
267 {
268 GimpPlugInProcedure *file_proc;
269 GSList *list;
270
271 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
272 g_return_val_if_fail (load_proc, FALSE);
273 g_return_val_if_fail (thumb_proc, FALSE);
274
275 if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
276 list = manager->current_plug_in->plug_in_def->procedures;
277 else
278 list = manager->plug_in_procedures;
279
280 file_proc = gimp_plug_in_procedure_find (list, load_proc);
281
282 if (! file_proc)
283 return FALSE;
284
285 gimp_plug_in_procedure_set_thumb_loader (file_proc, thumb_proc);
286
287 return TRUE;
288 }
289
290 GSList *
gimp_plug_in_manager_get_file_procedures(GimpPlugInManager * manager,GimpFileProcedureGroup group)291 gimp_plug_in_manager_get_file_procedures (GimpPlugInManager *manager,
292 GimpFileProcedureGroup group)
293 {
294 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
295
296 switch (group)
297 {
298 case GIMP_FILE_PROCEDURE_GROUP_NONE:
299 return NULL;
300
301 case GIMP_FILE_PROCEDURE_GROUP_OPEN:
302 return manager->display_load_procs;
303
304 case GIMP_FILE_PROCEDURE_GROUP_SAVE:
305 return manager->display_save_procs;
306
307 case GIMP_FILE_PROCEDURE_GROUP_EXPORT:
308 return manager->display_export_procs;
309
310 default:
311 g_return_val_if_reached (NULL);
312 }
313 }
314
315 GimpPlugInProcedure *
gimp_plug_in_manager_file_procedure_find(GimpPlugInManager * manager,GimpFileProcedureGroup group,GFile * file,GError ** error)316 gimp_plug_in_manager_file_procedure_find (GimpPlugInManager *manager,
317 GimpFileProcedureGroup group,
318 GFile *file,
319 GError **error)
320 {
321 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
322 g_return_val_if_fail (G_IS_FILE (file), NULL);
323 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
324
325 switch (group)
326 {
327 case GIMP_FILE_PROCEDURE_GROUP_OPEN:
328 return file_procedure_find (manager->load_procs, file, error);
329
330 case GIMP_FILE_PROCEDURE_GROUP_SAVE:
331 return file_procedure_find (manager->save_procs, file, error);
332
333 case GIMP_FILE_PROCEDURE_GROUP_EXPORT:
334 return file_procedure_find (manager->export_procs, file, error);
335
336 default:
337 g_return_val_if_reached (NULL);
338 }
339 }
340
341 GimpPlugInProcedure *
gimp_plug_in_manager_file_procedure_find_by_prefix(GimpPlugInManager * manager,GimpFileProcedureGroup group,GFile * file)342 gimp_plug_in_manager_file_procedure_find_by_prefix (GimpPlugInManager *manager,
343 GimpFileProcedureGroup group,
344 GFile *file)
345 {
346 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
347 g_return_val_if_fail (G_IS_FILE (file), NULL);
348
349 switch (group)
350 {
351 case GIMP_FILE_PROCEDURE_GROUP_OPEN:
352 return file_procedure_find_by_prefix (manager->load_procs, file);
353
354 case GIMP_FILE_PROCEDURE_GROUP_SAVE:
355 return file_procedure_find_by_prefix (manager->save_procs, file);
356
357 case GIMP_FILE_PROCEDURE_GROUP_EXPORT:
358 return file_procedure_find_by_prefix (manager->export_procs, file);
359
360 default:
361 g_return_val_if_reached (NULL);
362 }
363 }
364
365 GimpPlugInProcedure *
gimp_plug_in_manager_file_procedure_find_by_extension(GimpPlugInManager * manager,GimpFileProcedureGroup group,GFile * file)366 gimp_plug_in_manager_file_procedure_find_by_extension (GimpPlugInManager *manager,
367 GimpFileProcedureGroup group,
368 GFile *file)
369 {
370 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
371 g_return_val_if_fail (G_IS_FILE (file), NULL);
372
373 switch (group)
374 {
375 case GIMP_FILE_PROCEDURE_GROUP_OPEN:
376 return file_procedure_find_by_extension (manager->load_procs, file);
377
378 case GIMP_FILE_PROCEDURE_GROUP_SAVE:
379 return file_procedure_find_by_extension (manager->save_procs, file);
380
381 case GIMP_FILE_PROCEDURE_GROUP_EXPORT:
382 return file_procedure_find_by_extension (manager->export_procs, file);
383
384 default:
385 g_return_val_if_reached (NULL);
386 }
387 }
388
389 GimpPlugInProcedure *
gimp_plug_in_manager_file_procedure_find_by_mime_type(GimpPlugInManager * manager,GimpFileProcedureGroup group,const gchar * mime_type)390 gimp_plug_in_manager_file_procedure_find_by_mime_type (GimpPlugInManager *manager,
391 GimpFileProcedureGroup group,
392 const gchar *mime_type)
393 {
394 g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
395 g_return_val_if_fail (mime_type != NULL, NULL);
396
397 switch (group)
398 {
399 case GIMP_FILE_PROCEDURE_GROUP_OPEN:
400 return file_procedure_find_by_mime_type (manager->load_procs, mime_type);
401
402 case GIMP_FILE_PROCEDURE_GROUP_SAVE:
403 return file_procedure_find_by_mime_type (manager->save_procs, mime_type);
404
405 case GIMP_FILE_PROCEDURE_GROUP_EXPORT:
406 return file_procedure_find_by_mime_type (manager->export_procs, mime_type);
407
408 default:
409 g_return_val_if_reached (NULL);
410 }
411 }
412
413
414 /* private functions */
415
416 static gboolean
file_procedure_in_group(GimpPlugInProcedure * file_proc,GimpFileProcedureGroup group)417 file_procedure_in_group (GimpPlugInProcedure *file_proc,
418 GimpFileProcedureGroup group)
419 {
420 const gchar *name = gimp_object_get_name (file_proc);
421 gboolean is_xcf_save = FALSE;
422 gboolean is_filter = FALSE;
423
424 is_xcf_save = (strcmp (name, "gimp-xcf-save") == 0);
425
426 is_filter = (strcmp (name, "file-gz-save") == 0 ||
427 strcmp (name, "file-bz2-save") == 0 ||
428 strcmp (name, "file-xz-save") == 0);
429
430 switch (group)
431 {
432 case GIMP_FILE_PROCEDURE_GROUP_NONE:
433 return FALSE;
434
435 case GIMP_FILE_PROCEDURE_GROUP_SAVE:
436 /* Only .xcf shall pass */
437 return is_xcf_save || is_filter;
438
439 case GIMP_FILE_PROCEDURE_GROUP_EXPORT:
440 /* Anything but .xcf shall pass */
441 return ! is_xcf_save;
442
443 case GIMP_FILE_PROCEDURE_GROUP_OPEN:
444 /* No filter applied for Open */
445 return TRUE;
446
447 default:
448 case GIMP_FILE_PROCEDURE_GROUP_ANY:
449 return TRUE;
450 }
451 }
452