1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * Gimp-Python - allows the writing of Gimp plugins in Python.
3  * Copyright (C) 1997-2002  James Henstridge <james@daa.com.au>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22 
23 #undef GIMP_DISABLE_DEPRECATED
24 #define GIMP_DISABLE_DEPRECATION_WARNINGS
25 #include "pygimp.h"
26 
27 #include "pygimpcolor-api.h"
28 
29 #include <sysmodule.h>
30 
31 #include <glib-object.h>
32 
33 #include <pygobject.h>
34 
35 #include "pygimp-util.h"
36 
37 #include "pygimp-intl.h"
38 
39 #include "libgimp/gimpui.h"
40 
41 #include <gtk/gtk.h>
42 
43 #include <gegl.h>
44 
45 
46 PyObject *pygimp_error;
47 
48 #ifndef PG_DEBUG
49 # define PG_DEBUG 0
50 #endif
51 
52 
53 /* End of code for pdbFunc objects */
54 /* -------------------------------------------------------- */
55 
56 GimpPlugInInfo PLUG_IN_INFO = {
57     NULL, /* init_proc */
58     NULL, /* quit_proc */
59     NULL, /* query_proc */
60     NULL  /* run_proc */
61 };
62 
63 static PyObject *callbacks[] = {
64     NULL, NULL, NULL, NULL
65 };
66 
67 typedef struct _ProgressData ProgressData;
68 
69 struct _ProgressData
70 {
71   PyObject *start, *end, *text, *value;
72   PyObject *user_data;
73 };
74 
75 
76 static void
pygimp_init_proc(void)77 pygimp_init_proc(void)
78 {
79     PyObject *r;
80 
81     r = PyObject_CallFunction(callbacks[0], "()");
82 
83     if (!r) {
84         PyErr_Print();
85         PyErr_Clear();
86         return;
87     }
88 
89     Py_DECREF(r);
90 }
91 
92 static void
pygimp_quit_proc(void)93 pygimp_quit_proc(void)
94 {
95     PyObject *r;
96 
97     r = PyObject_CallFunction(callbacks[1], "()");
98 
99     if (!r) {
100         PyErr_Print();
101         PyErr_Clear();
102         return;
103     }
104 
105     Py_DECREF(r);
106 }
107 
108 static void
pygimp_query_proc(void)109 pygimp_query_proc(void)
110 {
111     PyObject *r;
112 
113     r = PyObject_CallFunction(callbacks[2], "()");
114 
115     if (!r) {
116         PyErr_Print();
117         PyErr_Clear();
118         return;
119     }
120 
121     Py_DECREF(r);
122 }
123 
124 static void
pygimp_run_proc(const char * name,int nparams,const GimpParam * params,int * nreturn_vals,GimpParam ** return_vals)125 pygimp_run_proc(const char *name, int nparams, const GimpParam *params,
126                 int *nreturn_vals, GimpParam **return_vals)
127 {
128     PyObject *args, *ret;
129     GimpParamDef *pd, *rv;
130     GimpPDBProcType t;
131     char *b, *h, *a, *c, *d;
132     int np, nrv;
133 
134     gimp_procedural_db_proc_info(name, &b, &h, &a, &c, &d, &t, &np, &nrv,
135                                  &pd, &rv);
136     g_free(b); g_free(h); g_free(a); g_free(c); g_free(d); g_free(pd);
137 
138 #if PG_DEBUG > 0
139     g_printerr("Params for %s:", name);
140     print_GParam(nparams, params);
141 #endif
142 
143     args = pygimp_param_to_tuple(nparams, params);
144 
145     if (args == NULL) {
146         PyErr_Clear();
147 
148         *nreturn_vals = 1;
149         *return_vals = g_new(GimpParam, 1);
150         (*return_vals)[0].type = GIMP_PDB_STATUS;
151         (*return_vals)[0].data.d_status = GIMP_PDB_CALLING_ERROR;
152 
153         return;
154     }
155 
156     ret = PyObject_CallFunction(callbacks[3], "(sO)", name, args);
157     Py_DECREF(args);
158 
159     if (ret == NULL) {
160         PyErr_Print();
161         PyErr_Clear();
162 
163         *nreturn_vals = 1;
164         *return_vals = g_new(GimpParam, 1);
165         (*return_vals)[0].type = GIMP_PDB_STATUS;
166         (*return_vals)[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
167 
168         return;
169     }
170 
171     *return_vals = pygimp_param_from_tuple(ret, rv, nrv);
172     g_free(rv);
173 
174     if (*return_vals == NULL) {
175         PyErr_Clear();
176 
177         *nreturn_vals = 1;
178         *return_vals = g_new(GimpParam, 1);
179         (*return_vals)[0].type = GIMP_PDB_STATUS;
180         (*return_vals)[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
181 
182         return;
183     }
184 
185     Py_DECREF(ret);
186 
187     *nreturn_vals = nrv + 1;
188     (*return_vals)[0].type = GIMP_PDB_STATUS;
189     (*return_vals)[0].data.d_status = GIMP_PDB_SUCCESS;
190 }
191 
192 static PyObject *
pygimp_main(PyObject * self,PyObject * args)193 pygimp_main(PyObject *self, PyObject *args)
194 {
195     PyObject *av;
196     int argc, i;
197     char **argv;
198     PyObject *ip;  // init proc
199     PyObject *qp;  // quit proc
200     PyObject *query;  // query proc
201     PyObject *rp;  // run proc
202 
203     if (!PyArg_ParseTuple(args, "OOOO:main", &ip, &qp, &query, &rp))
204         return NULL;
205 
206 #define Arg_Check(v) (PyCallable_Check(v) || (v) == Py_None)
207 
208     if (!Arg_Check(ip) || !Arg_Check(qp) || !Arg_Check(query) ||
209         !Arg_Check(rp)) {
210         PyErr_SetString(pygimp_error, "arguments must be callable");
211         return NULL;
212     }
213 
214 #undef Arg_Check
215 
216     if (query == Py_None) {
217         PyErr_SetString(pygimp_error, "a query procedure must be provided");
218         return NULL;
219     }
220 
221     if (ip != Py_None) {
222         callbacks[0] = ip;
223         PLUG_IN_INFO.init_proc = pygimp_init_proc;
224     }
225 
226     if (qp != Py_None) {
227         callbacks[1] = qp;
228         PLUG_IN_INFO.quit_proc = pygimp_quit_proc;
229     }
230 
231     if (query != Py_None) {
232         callbacks[2] = query;
233         PLUG_IN_INFO.query_proc = pygimp_query_proc;
234     }
235 
236     if (rp != Py_None) {
237         callbacks[3] = rp;
238         PLUG_IN_INFO.run_proc = pygimp_run_proc;
239     }
240 
241     av = PySys_GetObject("argv");
242 
243     argc = PyList_Size(av);
244     argv = g_new(char *, argc);
245 
246     for (i = 0; i < argc; i++)
247         argv[i] = g_strdup(PyString_AsString(PyList_GetItem(av, i)));
248 
249     gimp_main(&PLUG_IN_INFO, argc, argv);
250 
251     if (argv != NULL) {
252         for (i = 0; i < argc; i++)
253             if (argv[i] != NULL)
254                 g_free(argv[i]);
255 
256         g_free(argv);
257     }
258 
259     Py_INCREF(Py_None);
260     return Py_None;
261 }
262 
263 static PyObject *
pygimp_quit(PyObject * self)264 pygimp_quit(PyObject *self)
265 {
266     gimp_quit();
267 
268     Py_INCREF(Py_None);
269     return Py_None;
270 }
271 
272 static PyObject *
pygimp_message(PyObject * self,PyObject * args)273 pygimp_message(PyObject *self, PyObject *args)
274 {
275     char *msg;
276 
277     if (!PyArg_ParseTuple(args, "s:message", &msg))
278         return NULL;
279 
280     gimp_message(msg);
281 
282     Py_INCREF(Py_None);
283     return Py_None;
284 }
285 
286 static PyObject *
pygimp_exit(PyObject * self,PyObject * args,PyObject * kwargs)287 pygimp_exit(PyObject *self, PyObject *args, PyObject *kwargs)
288 {
289     gboolean force = FALSE;
290     int nreturn_vals;
291     GimpParam *return_vals;
292 
293     static char *kwlist[] = { "force", NULL };
294 
295     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:exit", kwlist, &force))
296         return NULL;
297 
298     return_vals = gimp_run_procedure("gimp-quit",
299                                      &nreturn_vals,
300                                      GIMP_PDB_INT32, force,
301                                      GIMP_PDB_END);
302 
303     if (return_vals[0].data.d_status != GIMP_PDB_SUCCESS) {
304         PyErr_SetString(pygimp_error, "error while exiting");
305         return NULL;
306     }
307 
308     gimp_destroy_params(return_vals, nreturn_vals);
309 
310     Py_INCREF(Py_None);
311     return Py_None;
312 }
313 
314 static PyObject *
pygimp_set_data(PyObject * self,PyObject * args)315 pygimp_set_data(PyObject *self, PyObject *args)
316 {
317     char *id, *data;
318     int bytes, nreturn_vals;
319     GimpParam *return_vals;
320 
321     if (!PyArg_ParseTuple(args, "ss#:set_data", &id, &data, &bytes))
322         return NULL;
323 
324     return_vals = gimp_run_procedure("gimp-procedural-db-set-data",
325                                      &nreturn_vals,
326                                      GIMP_PDB_STRING, id,
327                                      GIMP_PDB_INT32, bytes,
328                                      GIMP_PDB_INT8ARRAY, data,
329                                      GIMP_PDB_END);
330 
331     if (return_vals[0].data.d_status != GIMP_PDB_SUCCESS) {
332         PyErr_SetString(pygimp_error, "error occurred while storing");
333         return NULL;
334     }
335 
336     gimp_destroy_params(return_vals, nreturn_vals);
337 
338     Py_INCREF(Py_None);
339     return Py_None;
340 }
341 
342 static PyObject *
pygimp_get_data(PyObject * self,PyObject * args)343 pygimp_get_data(PyObject *self, PyObject *args)
344 {
345     char *id;
346     int nreturn_vals;
347     GimpParam *return_vals;
348     PyObject *s;
349 
350     if (!PyArg_ParseTuple(args, "s:get_data", &id))
351         return NULL;
352 
353     return_vals = gimp_run_procedure("gimp-procedural-db-get-data",
354                                      &nreturn_vals,
355                                      GIMP_PDB_STRING, id,
356                                      GIMP_PDB_END);
357 
358     if (return_vals[0].data.d_status != GIMP_PDB_SUCCESS) {
359         PyErr_SetString(pygimp_error, "no data for id");
360         return NULL;
361     }
362 
363     s = PyString_FromStringAndSize((char *)return_vals[2].data.d_int8array,
364                                    return_vals[1].data.d_int32);
365     gimp_destroy_params(return_vals, nreturn_vals);
366 
367     return s;
368 }
369 
370 static PyObject *
pygimp_progress_init(PyObject * self,PyObject * args)371 pygimp_progress_init(PyObject *self, PyObject *args)
372 {
373     char *msg = NULL;
374 
375     if (!PyArg_ParseTuple(args, "|s:progress_init", &msg))
376         return NULL;
377 
378     gimp_progress_init(msg);
379 
380     Py_INCREF(Py_None);
381     return Py_None;
382 }
383 
384 static PyObject *
pygimp_progress_update(PyObject * self,PyObject * args)385 pygimp_progress_update(PyObject *self, PyObject *args)
386 {
387     double p;
388 
389     if (!PyArg_ParseTuple(args, "d:progress_update", &p))
390         return NULL;
391 
392     gimp_progress_update(p);
393 
394     Py_INCREF(Py_None);
395     return Py_None;
396 }
397 
398 static void
pygimp_progress_start(const gchar * message,gboolean cancelable,gpointer data)399 pygimp_progress_start(const gchar *message, gboolean cancelable, gpointer data)
400 {
401     ProgressData *pdata = data;
402     PyObject *r;
403 
404     if (pdata->user_data) {
405         r = PyObject_CallFunction(pdata->start, "siO", message, cancelable,
406                                   pdata->user_data);
407         Py_DECREF(pdata->user_data);
408     } else
409         r = PyObject_CallFunction(pdata->start, "si", message, cancelable);
410 
411     if (!r) {
412         PyErr_Print();
413         PyErr_Clear();
414         return;
415     }
416 
417     Py_DECREF(r);
418 }
419 
420 static void
pygimp_progress_end(gpointer data)421 pygimp_progress_end(gpointer data)
422 {
423     ProgressData *pdata = data;
424     PyObject *r;
425 
426     if (pdata->user_data) {
427         r = PyObject_CallFunction(pdata->end, "O", pdata->user_data);
428         Py_DECREF(pdata->user_data);
429     } else
430         r = PyObject_CallFunction(pdata->end, NULL);
431 
432     if (!r) {
433         PyErr_Print();
434         PyErr_Clear();
435         return;
436     }
437 
438     Py_DECREF(r);
439 }
440 
441 static void
pygimp_progress_text(const gchar * message,gpointer data)442 pygimp_progress_text(const gchar *message, gpointer data)
443 {
444     ProgressData *pdata = data;
445     PyObject *r;
446 
447     if (pdata->user_data) {
448         r = PyObject_CallFunction(pdata->text, "sO", message, pdata->user_data);
449         Py_DECREF(pdata->user_data);
450     } else
451         r = PyObject_CallFunction(pdata->text, "s", message);
452 
453     if (!r) {
454         PyErr_Print();
455         PyErr_Clear();
456         return;
457     }
458 
459     Py_DECREF(r);
460 }
461 
462 static void
pygimp_progress_value(gdouble percentage,gpointer data)463 pygimp_progress_value(gdouble percentage, gpointer data)
464 {
465     ProgressData *pdata = data;
466     PyObject *r;
467 
468     if (pdata->user_data) {
469         r = PyObject_CallFunction(pdata->value, "dO", percentage,
470                                   pdata->user_data);
471         Py_DECREF(pdata->user_data);
472     } else
473         r = PyObject_CallFunction(pdata->value, "d", percentage);
474 
475     if (!r) {
476         PyErr_Print();
477         PyErr_Clear();
478         return;
479     }
480 
481     Py_DECREF(r);
482 }
483 
484 static PyObject *
pygimp_progress_install(PyObject * self,PyObject * args,PyObject * kwargs)485 pygimp_progress_install(PyObject *self, PyObject *args, PyObject *kwargs)
486 {
487     GimpProgressVtable vtable = { 0, };
488     const gchar *ret;
489     ProgressData *pdata;
490     static char *kwlist[] = { "start", "end", "text", "value", "data", NULL };
491 
492     pdata = g_new0(ProgressData, 1);
493 
494     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOO|O:progress_install",
495                                      kwlist,
496                                      &pdata->start, &pdata->end,
497                                      &pdata->text, &pdata->value,
498                                      &pdata->user_data))
499         goto cleanup;
500 
501 #define PROCESS_FUNC(n) G_STMT_START {                                  \
502     if (!PyCallable_Check(pdata->n)) {                                  \
503         PyErr_SetString(pygimp_error, #n "argument must be callable");  \
504         goto cleanup;                                                   \
505     }                                                                   \
506     Py_INCREF(pdata->n);                                                \
507 } G_STMT_END
508 
509     PROCESS_FUNC(start);
510     PROCESS_FUNC(end);
511     PROCESS_FUNC(text);
512     PROCESS_FUNC(value);
513 
514     Py_XINCREF(pdata->user_data);
515 
516 #undef PROCESS_FUNC
517 
518     vtable.start     = pygimp_progress_start;
519     vtable.end       = pygimp_progress_end;
520     vtable.set_text  = pygimp_progress_text;
521     vtable.set_value = pygimp_progress_value;
522 
523     ret = gimp_progress_install_vtable(&vtable, pdata);
524 
525     if (!ret) {
526         PyErr_SetString(pygimp_error,
527                         "error occurred while installing progress functions");
528 
529         Py_DECREF(pdata->start);
530         Py_DECREF(pdata->end);
531         Py_DECREF(pdata->text);
532         Py_DECREF(pdata->value);
533 
534         goto cleanup;
535     }
536 
537     return PyString_FromString(ret);
538 
539 cleanup:
540     g_free(pdata);
541     return NULL;
542 }
543 
544 static PyObject *
pygimp_progress_uninstall(PyObject * self,PyObject * args)545 pygimp_progress_uninstall(PyObject *self, PyObject *args)
546 {
547     ProgressData *pdata;
548     gchar *callback;
549 
550     if (!PyArg_ParseTuple(args, "s:progress_uninstall", &callback))
551         return NULL;
552 
553     pdata = gimp_progress_uninstall(callback);
554 
555     if (!pdata) {
556         PyErr_SetString(pygimp_error,
557                         "error occurred while uninstalling progress functions");
558         return NULL;
559     }
560 
561     Py_DECREF(pdata->start);
562     Py_DECREF(pdata->end);
563     Py_DECREF(pdata->text);
564     Py_DECREF(pdata->value);
565 
566     Py_XDECREF(pdata->user_data);
567 
568     g_free(pdata);
569 
570     Py_INCREF(Py_None);
571     return Py_None;
572 }
573 
574 static PyObject *
pygimp_image_list(PyObject * self)575 pygimp_image_list(PyObject *self)
576 {
577     gint32 *imgs;
578     int nimgs, i;
579     PyObject *ret;
580 
581     imgs = gimp_image_list(&nimgs);
582     ret = PyList_New(nimgs);
583 
584     for (i = 0; i < nimgs; i++)
585         PyList_SetItem(ret, i, (PyObject *)pygimp_image_new(imgs[i]));
586 
587     g_free(imgs);
588 
589     return ret;
590 }
591 
592 static PyObject *
pygimp_install_procedure(PyObject * self,PyObject * args)593 pygimp_install_procedure(PyObject *self, PyObject *args)
594 {
595     char *name, *blurb, *help, *author, *copyright, *date, *menu_path,
596          *image_types, *n, *d;
597     GimpParamDef *params, *return_vals;
598     int type, nparams, nreturn_vals, i;
599     PyObject *pars, *rets;
600 
601     if (!PyArg_ParseTuple(args, "sssssszziOO:install_procedure",
602                           &name, &blurb, &help,
603                           &author, &copyright, &date, &menu_path, &image_types,
604                           &type, &pars, &rets))
605         return NULL;
606 
607     if (!PySequence_Check(pars) || !PySequence_Check(rets)) {
608         PyErr_SetString(PyExc_TypeError, "last two args must be sequences");
609         return NULL;
610     }
611 
612     nparams = PySequence_Length(pars);
613     nreturn_vals = PySequence_Length(rets);
614     params = g_new(GimpParamDef, nparams);
615 
616     for (i = 0; i < nparams; i++) {
617         if (!PyArg_ParseTuple(PySequence_GetItem(pars, i), "iss",
618                               &(params[i].type), &n, &d)) {
619             g_free(params);
620             return NULL;
621         }
622 
623         params[i].name = g_strdup(n);
624         params[i].description = g_strdup(d);
625     }
626 
627     return_vals = g_new(GimpParamDef, nreturn_vals);
628 
629     for (i = 0; i < nreturn_vals; i++) {
630         if (!PyArg_ParseTuple(PySequence_GetItem(rets, i), "iss",
631                               &(return_vals[i].type), &n, &d)) {
632             g_free(params); g_free(return_vals);
633             return NULL;
634         }
635 
636         return_vals[i].name = g_strdup(n);
637         return_vals[i].description = g_strdup(d);
638     }
639 
640     gimp_install_procedure(name, blurb, help, author, copyright, date,
641                            menu_path, image_types, type, nparams, nreturn_vals,
642                            params, return_vals);
643 
644     Py_INCREF(Py_None);
645     return Py_None;
646 }
647 
648 static PyObject *
pygimp_install_temp_proc(PyObject * self,PyObject * args)649 pygimp_install_temp_proc(PyObject *self, PyObject *args)
650 {
651     char *name, *blurb, *help, *author, *copyright, *date, *menu_path,
652         *image_types, *n, *d;
653     GimpParamDef *params, *return_vals;
654     int type, nparams, nreturn_vals, i;
655     PyObject *pars, *rets;
656 
657     if (!PyArg_ParseTuple(args, "sssssszziOO:install_temp_proc",
658                           &name, &blurb, &help,
659                           &author, &copyright, &date, &menu_path, &image_types,
660                           &type, &pars, &rets))
661         return NULL;
662 
663     if (!PySequence_Check(pars) || !PySequence_Check(rets)) {
664         PyErr_SetString(PyExc_TypeError, "last two args must be sequences");
665         return NULL;
666     }
667 
668     nparams = PySequence_Length(pars);
669     nreturn_vals = PySequence_Length(rets);
670     params = g_new(GimpParamDef, nparams);
671 
672     for (i = 0; i < nparams; i++) {
673         if (!PyArg_ParseTuple(PySequence_GetItem(pars, i), "iss",
674                               &(params[i].type), &n, &d)) {
675             g_free(params);
676             return NULL;
677         }
678 
679         params[i].name = g_strdup(n);
680         params[i].description = g_strdup(d);
681     }
682 
683     return_vals = g_new(GimpParamDef, nreturn_vals);
684 
685     for (i = 0; i < nreturn_vals; i++) {
686         if (!PyArg_ParseTuple(PySequence_GetItem(rets, i), "iss",
687                               &(return_vals[i].type), &n, &d)) {
688             g_free(params); g_free(return_vals);
689             return NULL;
690         }
691 
692         return_vals[i].name = g_strdup(n);
693         return_vals[i].description = g_strdup(d);
694     }
695 
696     gimp_install_temp_proc(name, blurb, help, author, copyright, date,
697                            menu_path, image_types, type,
698                            nparams, nreturn_vals, params, return_vals,
699                            pygimp_run_proc);
700 
701     Py_INCREF(Py_None);
702     return Py_None;
703 }
704 
705 static PyObject *
pygimp_uninstall_temp_proc(PyObject * self,PyObject * args)706 pygimp_uninstall_temp_proc(PyObject *self, PyObject *args)
707 {
708     char *name;
709 
710     if (!PyArg_ParseTuple(args, "s:uninstall_temp_proc", &name))
711         return NULL;
712 
713     gimp_uninstall_temp_proc(name);
714 
715     Py_INCREF(Py_None);
716     return Py_None;
717 }
718 
719 static PyObject *
pygimp_register_magic_load_handler(PyObject * self,PyObject * args)720 pygimp_register_magic_load_handler(PyObject *self, PyObject *args)
721 {
722     char *name, *extensions, *prefixes, *magics;
723 
724     if (!PyArg_ParseTuple(args, "ssss:register_magic_load_handler",
725                           &name, &extensions, &prefixes, &magics))
726         return NULL;
727 
728     gimp_register_magic_load_handler(name, extensions, prefixes, magics);
729 
730     Py_INCREF(Py_None);
731     return Py_None;
732 }
733 
734 static PyObject *
pygimp_register_load_handler(PyObject * self,PyObject * args)735 pygimp_register_load_handler(PyObject *self, PyObject *args)
736 {
737     char *name, *extensions, *prefixes;
738 
739     if (!PyArg_ParseTuple(args, "sss:register_load_handler",
740                           &name, &extensions, &prefixes))
741         return NULL;
742 
743     gimp_register_load_handler(name, extensions, prefixes);
744 
745     Py_INCREF(Py_None);
746     return Py_None;
747 }
748 
749 static PyObject *
pygimp_register_save_handler(PyObject * self,PyObject * args)750 pygimp_register_save_handler(PyObject *self, PyObject *args)
751 {
752     char *name, *extensions, *prefixes;
753 
754     if (!PyArg_ParseTuple(args, "sss:register_save_handler",
755                           &name, &extensions, &prefixes))
756         return NULL;
757 
758     gimp_register_save_handler(name, extensions, prefixes);
759 
760     Py_INCREF(Py_None);
761     return Py_None;
762 }
763 
764 static PyObject *
pygimp_domain_register(PyObject * self,PyObject * args)765 pygimp_domain_register(PyObject *self, PyObject *args)
766 {
767     char *name, *path = NULL;
768 
769     if (!PyArg_ParseTuple(args, "s|s:domain_register", &name, &path))
770         return NULL;
771 
772     gimp_plugin_domain_register(name, path);
773 
774     Py_INCREF(Py_None);
775     return Py_None;
776 }
777 
778 static PyObject *
pygimp_menu_register(PyObject * self,PyObject * args)779 pygimp_menu_register(PyObject *self, PyObject *args)
780 {
781     char *name, *path;
782 
783     if (!PyArg_ParseTuple(args, "ss:menu_register", &name, &path))
784         return NULL;
785 
786     gimp_plugin_menu_register(name, path);
787 
788     Py_INCREF(Py_None);
789     return Py_None;
790 }
791 
792 static PyObject *
pygimp_gamma(PyObject * self)793 pygimp_gamma(PyObject *self)
794 {
795     return PyFloat_FromDouble(gimp_gamma());
796 }
797 
798 static PyObject *
pygimp_gtkrc(PyObject * self)799 pygimp_gtkrc(PyObject *self)
800 {
801     return PyString_FromString(gimp_gtkrc());
802 }
803 
804 static PyObject *
pygimp_personal_rc_file(PyObject * self,PyObject * args,PyObject * kwargs)805 pygimp_personal_rc_file(PyObject *self, PyObject *args, PyObject *kwargs)
806 {
807     char *basename, *filename;
808     PyObject *ret;
809 
810     static char *kwlist[] = { "basename", NULL };
811 
812     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
813                                      "s:personal_rc_file", kwlist,
814                                      &basename))
815         return NULL;
816 
817     filename = gimp_personal_rc_file(basename);
818     ret = PyString_FromString(filename);
819     g_free(filename);
820 
821     return ret;
822 }
823 
824 static PyObject *
pygimp_context_push(PyObject * self)825 pygimp_context_push(PyObject *self)
826 {
827     gimp_context_push();
828     Py_INCREF(Py_None);
829     return Py_None;
830 }
831 
832 static PyObject *
pygimp_context_pop(PyObject * self)833 pygimp_context_pop(PyObject *self)
834 {
835     gimp_context_pop();
836     Py_INCREF(Py_None);
837     return Py_None;
838 }
839 
840 static PyObject *
pygimp_get_background(PyObject * self)841 pygimp_get_background(PyObject *self)
842 {
843     GimpRGB rgb;
844 
845     gimp_context_get_background(&rgb);
846     return pygimp_rgb_new(&rgb);
847 }
848 
849 static PyObject *
pygimp_get_foreground(PyObject * self)850 pygimp_get_foreground(PyObject *self)
851 {
852     GimpRGB rgb;
853 
854     gimp_context_get_foreground(&rgb);
855     return pygimp_rgb_new(&rgb);
856 }
857 
858 static PyObject *
pygimp_set_background(PyObject * self,PyObject * args)859 pygimp_set_background(PyObject *self, PyObject *args)
860 {
861     PyObject *color;
862     GimpRGB rgb;
863 
864     if (PyArg_ParseTuple(args, "O:set_background", &color)) {
865         if (!pygimp_rgb_from_pyobject(color, &rgb))
866             return NULL;
867     } else {
868         PyErr_Clear();
869         if (!pygimp_rgb_from_pyobject(args, &rgb))
870             return NULL;
871     }
872 
873     gimp_context_set_background(&rgb);
874 
875     Py_INCREF(Py_None);
876     return Py_None;
877 }
878 
879 static PyObject *
pygimp_set_foreground(PyObject * self,PyObject * args)880 pygimp_set_foreground(PyObject *self, PyObject *args)
881 {
882     PyObject *color;
883     GimpRGB rgb;
884 
885     if (PyArg_ParseTuple(args, "O:set_foreground", &color)) {
886         if (!pygimp_rgb_from_pyobject(color, &rgb))
887             return NULL;
888     } else {
889         PyErr_Clear();
890         if (!pygimp_rgb_from_pyobject(args, &rgb))
891             return NULL;
892     }
893 
894     gimp_context_set_foreground(&rgb);
895 
896     Py_INCREF(Py_None);
897     return Py_None;
898 }
899 
900 static PyObject *
pygimp_gradients_get_list(PyObject * self,PyObject * args,PyObject * kwargs)901 pygimp_gradients_get_list(PyObject *self, PyObject *args, PyObject *kwargs)
902 {
903     char **list, *filter = NULL;
904     int num, i;
905     PyObject *ret;
906 
907     static char *kwlist[] = { "filter", NULL };
908 
909     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
910                                      "|s:gradients_get_list", kwlist,
911                                      &filter))
912         return NULL;
913 
914     list = gimp_gradients_get_list(filter, &num);
915 
916     ret = PyList_New(num);
917 
918     for (i = 0; i < num; i++) {
919         PyList_SetItem(ret, i, PyString_FromString(list[i]));
920     }
921 
922     g_strfreev(list);
923 
924     return ret;
925 }
926 
927 static PyObject *
pygimp_context_get_gradient(PyObject * self)928 pygimp_context_get_gradient(PyObject *self)
929 {
930     char *name;
931     PyObject *ret;
932 
933     name = gimp_context_get_gradient();
934     ret = PyString_FromString(name);
935     g_free(name);
936 
937     return ret;
938 }
939 
940 static PyObject *
pygimp_gradients_get_gradient(PyObject * self)941 pygimp_gradients_get_gradient(PyObject *self)
942 {
943     if (PyErr_Warn(PyExc_DeprecationWarning, "use gimp.context_get_gradient") < 0)
944         return NULL;
945 
946     return pygimp_context_get_gradient(self);
947 }
948 
949 static PyObject *
pygimp_context_set_gradient(PyObject * self,PyObject * args)950 pygimp_context_set_gradient(PyObject *self, PyObject *args)
951 {
952     char *actv;
953 
954     if (!PyArg_ParseTuple(args, "s:gradients_set_gradient", &actv))
955         return NULL;
956 
957     gimp_context_set_gradient(actv);
958 
959     Py_INCREF(Py_None);
960     return Py_None;
961 }
962 
963 static PyObject *
pygimp_gradients_set_gradient(PyObject * self,PyObject * args)964 pygimp_gradients_set_gradient(PyObject *self, PyObject *args)
965 {
966     if (PyErr_Warn(PyExc_DeprecationWarning, "use gimp.context_set_gradient") < 0)
967         return NULL;
968 
969     return pygimp_context_set_gradient(self, args);
970 }
971 
972 static PyObject *
pygimp_gradient_get_uniform_samples(PyObject * self,PyObject * args)973 pygimp_gradient_get_uniform_samples(PyObject *self, PyObject *args)
974 {
975     int num, reverse = FALSE;
976     char *name;
977     int nsamp;
978     double *samp;
979     int i, j;
980     PyObject *ret;
981 
982     if (!PyArg_ParseTuple(args, "si|i:gradient_get_uniform_samples",
983                           &name, &num, &reverse))
984         return NULL;
985 
986     if (!gimp_gradient_get_uniform_samples(name, num, reverse, &nsamp, &samp)) {
987         PyErr_SetString(pygimp_error, "gradient_get_uniform_samples failed");
988         return NULL;
989     }
990 
991     ret = PyList_New(num);
992     for (i = 0, j = 0; i < num; i++, j += 4)
993         PyList_SetItem(ret, i, Py_BuildValue("(dddd)", samp[j],
994                                              samp[j+1], samp[j+2], samp[j+3]));
995 
996     g_free(samp);
997 
998     return ret;
999 }
1000 
1001 static PyObject *
pygimp_gradient_get_custom_samples(PyObject * self,PyObject * args)1002 pygimp_gradient_get_custom_samples(PyObject *self, PyObject *args)
1003 {
1004     int num, reverse = FALSE;
1005     char *name;
1006     int nsamp;
1007     double *pos, *samp;
1008     int i, j;
1009     PyObject *ret, *item;
1010     gboolean success;
1011 
1012     if (!PyArg_ParseTuple(args, "sO|i:gradient_get_custom_samples",
1013                           &name, &ret, &reverse))
1014         return NULL;
1015 
1016     if (!PySequence_Check(ret)) {
1017         PyErr_SetString(PyExc_TypeError,
1018                         "second arg must be a sequence");
1019         return NULL;
1020     }
1021 
1022     num = PySequence_Length(ret);
1023     pos = g_new(gdouble, num);
1024 
1025     for (i = 0; i < num; i++) {
1026         item = PySequence_GetItem(ret, i);
1027 
1028         if (!PyFloat_Check(item)) {
1029             PyErr_SetString(PyExc_TypeError,
1030                             "second arg must be a sequence of floats");
1031             g_free(pos);
1032             return NULL;
1033         }
1034 
1035         pos[i] = PyFloat_AsDouble(item);
1036     }
1037 
1038     success = gimp_gradient_get_custom_samples(name, num, pos, reverse,
1039                                                &nsamp, &samp);
1040     g_free(pos);
1041 
1042     if (!success) {
1043         PyErr_SetString(pygimp_error, "gradient_get_custom_samples failed");
1044         return NULL;
1045     }
1046 
1047     ret = PyList_New(num);
1048     for (i = 0, j = 0; i < num; i++, j += 4)
1049         PyList_SetItem(ret, i, Py_BuildValue("(dddd)", samp[j],
1050                                              samp[j+1], samp[j+2], samp[j+3]));
1051 
1052     g_free(samp);
1053 
1054     return ret;
1055 }
1056 
1057 static PyObject *
pygimp_gradients_sample_uniform(PyObject * self,PyObject * args)1058 pygimp_gradients_sample_uniform(PyObject *self, PyObject *args)
1059 {
1060     char *name;
1061     PyObject *arg_list, *str, *new_args, *ret;
1062 
1063     if (PyErr_Warn(PyExc_DeprecationWarning,
1064                    "use gimp.gradient_get_uniform_samples") < 0)
1065         return NULL;
1066 
1067     arg_list = PySequence_List(args);
1068 
1069     name = gimp_context_get_gradient();
1070 
1071     str = PyString_FromString(name);
1072     g_free(name);
1073 
1074     PyList_Insert(arg_list, 0, str);
1075     Py_XDECREF(str);
1076 
1077     new_args = PyList_AsTuple(arg_list);
1078     Py_XDECREF(arg_list);
1079 
1080     ret = pygimp_gradient_get_uniform_samples(self, new_args);
1081     Py_XDECREF(new_args);
1082 
1083     return ret;
1084 }
1085 
1086 static PyObject *
pygimp_gradients_sample_custom(PyObject * self,PyObject * args)1087 pygimp_gradients_sample_custom(PyObject *self, PyObject *args)
1088 {
1089     char *name;
1090     PyObject *arg_list, *str, *new_args, *ret;
1091 
1092     if (PyErr_Warn(PyExc_DeprecationWarning,
1093                    "use gimp.gradient_get_custom_samples") < 0)
1094         return NULL;
1095 
1096     arg_list = PySequence_List(args);
1097 
1098     name = gimp_context_get_gradient();
1099 
1100     str = PyString_FromString(name);
1101     g_free(name);
1102 
1103     PyList_Insert(arg_list, 0, str);
1104     Py_XDECREF(str);
1105 
1106     new_args = PyList_AsTuple(arg_list);
1107     Py_XDECREF(arg_list);
1108 
1109     ret = pygimp_gradient_get_custom_samples(self, new_args);
1110 
1111     return ret;
1112 }
1113 
1114 static PyObject *
pygimp_delete(PyObject * self,PyObject * args)1115 pygimp_delete(PyObject *self, PyObject *args)
1116 {
1117     PyGimpImage *img;
1118 
1119     if (!PyArg_ParseTuple(args, "O:delete", &img))
1120         return NULL;
1121 
1122     if (pygimp_image_check(img))
1123         gimp_image_delete(img->ID);
1124     else if (pygimp_drawable_check(img))
1125         gimp_item_delete(img->ID);
1126     else if (pygimp_display_check(img))
1127         gimp_display_delete(img->ID);
1128 
1129     Py_INCREF(Py_None);
1130     return Py_None;
1131 }
1132 
1133 
1134 static PyObject *
pygimp_displays_flush(PyObject * self)1135 pygimp_displays_flush(PyObject *self)
1136 {
1137     gimp_displays_flush();
1138 
1139     Py_INCREF(Py_None);
1140     return Py_None;
1141 }
1142 
1143 static PyObject *
pygimp_displays_reconnect(PyObject * self,PyObject * args)1144 pygimp_displays_reconnect(PyObject *self, PyObject *args)
1145 {
1146     PyGimpImage *old_img, *new_img;
1147 
1148     if (!PyArg_ParseTuple(args, "O!O!:displays_reconnect",
1149                           &PyGimpImage_Type, &old_img,
1150                           &PyGimpImage_Type, &new_img))
1151         return NULL;
1152 
1153     if (!gimp_displays_reconnect (old_img->ID, new_img->ID)) {
1154         PyErr_Format(pygimp_error,
1155                      "could not reconnect the displays of image (ID %d) "
1156                      "to image (ID %d)",
1157                      old_img->ID, new_img->ID);
1158         return NULL;
1159     }
1160 
1161     Py_INCREF(Py_None);
1162     return Py_None;
1163 }
1164 
1165 static PyObject *
pygimp_tile_cache_size(PyObject * self,PyObject * args)1166 pygimp_tile_cache_size(PyObject *self, PyObject *args)
1167 {
1168     unsigned long k;
1169 
1170     if (!PyArg_ParseTuple(args, "l:tile_cache_size", &k))
1171         return NULL;
1172 
1173     gimp_tile_cache_size(k);
1174 
1175     Py_INCREF(Py_None);
1176     return Py_None;
1177 }
1178 
1179 
1180 static PyObject *
pygimp_tile_cache_ntiles(PyObject * self,PyObject * args)1181 pygimp_tile_cache_ntiles(PyObject *self, PyObject *args)
1182 {
1183     unsigned long n;
1184 
1185     if (!PyArg_ParseTuple(args, "l:tile_cache_ntiles", &n))
1186         return NULL;
1187 
1188     gimp_tile_cache_ntiles(n);
1189 
1190     Py_INCREF(Py_None);
1191     return Py_None;
1192 }
1193 
1194 
1195 static PyObject *
pygimp_tile_width(PyObject * self)1196 pygimp_tile_width(PyObject *self)
1197 {
1198     return PyInt_FromLong(gimp_tile_width());
1199 }
1200 
1201 
1202 static PyObject *
pygimp_tile_height(PyObject * self)1203 pygimp_tile_height(PyObject *self)
1204 {
1205     return PyInt_FromLong(gimp_tile_height());
1206 }
1207 
1208 static PyObject *
pygimp_extension_ack(PyObject * self)1209 pygimp_extension_ack(PyObject *self)
1210 {
1211     gimp_extension_ack();
1212 
1213     Py_INCREF(Py_None);
1214     return Py_None;
1215 }
1216 
1217 static PyObject *
pygimp_extension_enable(PyObject * self)1218 pygimp_extension_enable(PyObject *self)
1219 {
1220     gimp_extension_enable();
1221 
1222     Py_INCREF(Py_None);
1223     return Py_None;
1224 }
1225 
1226 static PyObject *
pygimp_extension_process(PyObject * self,PyObject * args)1227 pygimp_extension_process(PyObject *self, PyObject *args)
1228 {
1229     guint timeout;
1230 
1231     if (!PyArg_ParseTuple(args, "I:extension_process", &timeout))
1232         return NULL;
1233 
1234     gimp_extension_process(timeout);
1235 
1236     Py_INCREF(Py_None);
1237     return Py_None;
1238 }
1239 
1240 static PyObject *
pygimp_parasite_find(PyObject * self,PyObject * args)1241 pygimp_parasite_find(PyObject *self, PyObject *args)
1242 {
1243     char *name;
1244 
1245     if (!PyArg_ParseTuple(args, "s:parasite_find", &name))
1246         return NULL;
1247 
1248     return pygimp_parasite_new(gimp_get_parasite(name));
1249 }
1250 
1251 static PyObject *
pygimp_parasite_attach(PyObject * self,PyObject * args)1252 pygimp_parasite_attach(PyObject *self, PyObject *args)
1253 {
1254     PyGimpParasite *parasite;
1255 
1256     if (!PyArg_ParseTuple(args, "O!:parasite_attach",
1257                           &PyGimpParasite_Type, &parasite))
1258         return NULL;
1259 
1260     if (!gimp_attach_parasite(parasite->para)) {
1261         PyErr_Format(pygimp_error, "could not attach parasite '%s'",
1262                      gimp_parasite_name(parasite->para));
1263         return NULL;
1264     }
1265 
1266     Py_INCREF(Py_None);
1267     return Py_None;
1268 }
1269 
1270 static PyObject *
pygimp_attach_new_parasite(PyObject * self,PyObject * args)1271 pygimp_attach_new_parasite(PyObject *self, PyObject *args)
1272 {
1273     GimpParasite *parasite;
1274     char *name, *data;
1275     int flags, size;
1276 
1277     if (!PyArg_ParseTuple(args, "sis#:attach_new_parasite", &name, &flags,
1278                           &data, &size))
1279         return NULL;
1280 
1281     parasite = gimp_parasite_new (name, flags, size, data);
1282 
1283     if (!gimp_attach_parasite (parasite)) {
1284         PyErr_Format(pygimp_error, "could not attach new parasite '%s'", name);
1285         gimp_parasite_free (parasite);
1286         return NULL;
1287     }
1288 
1289     gimp_parasite_free (parasite);
1290 
1291     Py_INCREF(Py_None);
1292     return Py_None;
1293 }
1294 
1295 static PyObject *
pygimp_parasite_detach(PyObject * self,PyObject * args)1296 pygimp_parasite_detach(PyObject *self, PyObject *args)
1297 {
1298     char *name;
1299 
1300     if (!PyArg_ParseTuple(args, "s:parasite_detach", &name))
1301         return NULL;
1302 
1303     if (!gimp_detach_parasite(name)) {
1304         PyErr_Format(pygimp_error, "could not detach parasite '%s'", name);
1305         return NULL;
1306     }
1307 
1308     Py_INCREF(Py_None);
1309     return Py_None;
1310 }
1311 
1312 static PyObject *
pygimp_parasite_list(PyObject * self)1313 pygimp_parasite_list(PyObject *self)
1314 {
1315     gint num_parasites;
1316     gchar **parasites;
1317     PyObject *ret;
1318     gint i;
1319 
1320     parasites = gimp_get_parasite_list (&num_parasites);
1321 
1322     ret = PyTuple_New(num_parasites);
1323 
1324     for (i = 0; i < num_parasites; i++)
1325         PyTuple_SetItem(ret, i, PyString_FromString(parasites[i]));
1326 
1327     g_strfreev(parasites);
1328     return ret;
1329 }
1330 
1331 static PyObject *
pygimp_show_tool_tips(PyObject * self)1332 pygimp_show_tool_tips(PyObject *self)
1333 {
1334     return PyBool_FromLong(gimp_show_tool_tips());
1335 }
1336 
1337 static PyObject *
pygimp_show_help_button(PyObject * self)1338 pygimp_show_help_button(PyObject *self)
1339 {
1340     return PyBool_FromLong(gimp_show_help_button());
1341 }
1342 
1343 static PyObject *
pygimp_check_size(PyObject * self)1344 pygimp_check_size(PyObject *self)
1345 {
1346     return PyInt_FromLong(gimp_check_size());
1347 }
1348 
1349 static PyObject *
pygimp_check_type(PyObject * self)1350 pygimp_check_type(PyObject *self)
1351 {
1352     return PyInt_FromLong(gimp_check_type());
1353 }
1354 
1355 static PyObject *
pygimp_default_display(PyObject * self)1356 pygimp_default_display(PyObject *self)
1357 {
1358     return pygimp_display_new(gimp_default_display());
1359 }
1360 
1361 static PyObject *
pygimp_wm_class(PyObject * self)1362 pygimp_wm_class(PyObject *self)
1363 {
1364     return PyString_FromString(gimp_wm_class());
1365 }
1366 
1367 static PyObject *
pygimp_display_name(PyObject * self)1368 pygimp_display_name(PyObject *self)
1369 {
1370     return PyString_FromString(gimp_display_name());
1371 }
1372 
1373 static PyObject *
pygimp_monitor_number(PyObject * self)1374 pygimp_monitor_number(PyObject *self)
1375 {
1376     return PyInt_FromLong(gimp_monitor_number());
1377 }
1378 
1379 static PyObject *
pygimp_get_progname(PyObject * self)1380 pygimp_get_progname(PyObject *self)
1381 {
1382     return PyString_FromString(gimp_get_progname());
1383 }
1384 
1385 static PyObject *
pygimp_user_directory(PyObject * self,PyObject * args,PyObject * kwargs)1386 pygimp_user_directory(PyObject *self, PyObject *args, PyObject *kwargs)
1387 {
1388     GimpUserDirectory type;
1389     const char *user_dir;
1390     PyObject *py_type, *ret;
1391 
1392     static char *kwlist[] = { "type", NULL };
1393 
1394     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1395                                      "O:user_directory", kwlist,
1396                                      &py_type))
1397         return NULL;
1398 
1399     if (pyg_enum_get_value(GIMP_TYPE_USER_DIRECTORY, py_type, (gpointer)&type))
1400         return NULL;
1401 
1402     /* GimpUserDirectory and GUserDirectory are compatible */
1403     user_dir = g_get_user_special_dir((GUserDirectory)type);
1404 
1405     if (user_dir) {
1406         ret = PyString_FromString(user_dir);
1407     } else {
1408         Py_INCREF(Py_None);
1409 	ret = Py_None;
1410     }
1411 
1412     return ret;
1413 }
1414 
1415 static PyObject *
pygimp_fonts_refresh(PyObject * self)1416 pygimp_fonts_refresh(PyObject *self)
1417 {
1418     if (!gimp_fonts_refresh()) {
1419         PyErr_SetString(pygimp_error, "could not refresh fonts");
1420         return NULL;
1421     }
1422 
1423     Py_INCREF(Py_None);
1424     return Py_None;
1425 }
1426 
1427 static PyObject *
pygimp_checks_get_shades(PyObject * self,PyObject * args,PyObject * kwargs)1428 pygimp_checks_get_shades(PyObject *self, PyObject *args, PyObject *kwargs)
1429 {
1430     int type;
1431     guchar light, dark;
1432     static char *kwlist[] = { "type", NULL };
1433 
1434     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1435                                      "i:checks_get_shades", kwlist,
1436                                      &type))
1437         return NULL;
1438 
1439     if (type < GIMP_CHECK_TYPE_LIGHT_CHECKS ||
1440         type > GIMP_CHECK_TYPE_BLACK_ONLY) {
1441         PyErr_SetString(PyExc_ValueError, "Invalid check type");
1442         return NULL;
1443     }
1444 
1445     gimp_checks_get_shades(type, &light, &dark);
1446 
1447     return Py_BuildValue("(ii)", light, dark);
1448 }
1449 
1450 static PyObject *
pygimp_fonts_get_list(PyObject * self,PyObject * args,PyObject * kwargs)1451 pygimp_fonts_get_list(PyObject *self, PyObject *args, PyObject *kwargs)
1452 {
1453     char **list, *filter = NULL;
1454     int num, i;
1455     PyObject *ret;
1456 
1457     static char *kwlist[] = { "filter", NULL };
1458 
1459     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1460                                      "|s:fonts_get_list", kwlist,
1461                                      &filter))
1462         return NULL;
1463 
1464     list = gimp_fonts_get_list(filter, &num);
1465 
1466     if (num == 0) {
1467         PyErr_SetString(pygimp_error, "could not get font list");
1468         return NULL;
1469     }
1470 
1471     ret = PyList_New(num);
1472 
1473     for (i = 0; i < num; i++) {
1474         PyList_SetItem(ret, i, PyString_FromString(list[i]));
1475     }
1476 
1477     g_strfreev(list);
1478 
1479     return ret;
1480 }
1481 
1482 static PyObject *
vectors_to_objects(int num_vectors,int * vectors)1483 vectors_to_objects(int num_vectors, int *vectors)
1484 {
1485     PyObject *ret;
1486     int i;
1487 
1488     ret = PyList_New(num_vectors);
1489     if (ret == NULL)
1490         goto done;
1491 
1492     for (i = 0; i < num_vectors; i++)
1493         PyList_SetItem(ret, i, pygimp_vectors_new(vectors[i]));
1494 
1495 done:
1496     g_free(vectors);
1497     return ret;
1498 }
1499 
1500 static PyObject *
pygimp_vectors_import_from_file(PyObject * self,PyObject * args,PyObject * kwargs)1501 pygimp_vectors_import_from_file(PyObject *self, PyObject *args, PyObject *kwargs)
1502 {
1503     PyGimpImage *img;
1504     PyObject *py_file;
1505     gboolean merge = FALSE, scale = FALSE;
1506     int *vectors, num_vectors;
1507     gboolean success;
1508 
1509     static char *kwlist[] = { "image", "svg_file", "merge", "scale", NULL };
1510 
1511     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1512                                      "O!O|ii:vectors_import_from_file", kwlist,
1513                                      &PyGimpImage_Type, &img, &py_file,
1514                                      &merge, &scale))
1515         return NULL;
1516 
1517     if (PyString_Check(py_file)) {
1518         success = gimp_vectors_import_from_file(img->ID,
1519                                                 PyString_AsString(py_file),
1520                                                 merge, scale,
1521                                                 &num_vectors, &vectors);
1522     } else {
1523         PyObject *chunk_size, *buffer, *read_method;
1524 
1525         chunk_size = PyInt_FromLong(16 * 1024);
1526         if (chunk_size == NULL)
1527             return NULL;
1528 
1529         buffer = PyString_FromString("");
1530         if (buffer == NULL) {
1531             Py_DECREF(chunk_size);
1532             return NULL;
1533         }
1534 
1535         read_method = PyString_FromString("read");
1536         if (read_method == NULL || !PyCallable_Check(read_method)) {
1537             Py_XDECREF(read_method);
1538             PyErr_SetString(PyExc_TypeError,
1539                             "svg_file must be an object that has a \"read\" "
1540                             "method, or a filename (str)");
1541             return NULL;
1542         }
1543 
1544         while (1) {
1545             PyObject *chunk;
1546             chunk = PyObject_CallMethodObjArgs(py_file, read_method,
1547                                                chunk_size, NULL);
1548 
1549             if (!chunk || !PyString_Check(chunk)) {
1550                 Py_XDECREF(chunk);
1551                 Py_DECREF(chunk_size);
1552                 Py_DECREF(buffer);
1553                 Py_DECREF(read_method);
1554                 return NULL;
1555             }
1556 
1557             if (PyString_GET_SIZE(chunk) != 0) {
1558                 PyString_ConcatAndDel(&buffer, chunk);
1559                 if (buffer == NULL) {
1560                     Py_DECREF(chunk_size);
1561                     Py_DECREF(read_method);
1562                     return NULL;
1563                 }
1564             } else {
1565                 Py_DECREF(chunk);
1566                 break;
1567             }
1568         }
1569 
1570         success = gimp_vectors_import_from_string(img->ID,
1571                                                   PyString_AsString(buffer),
1572                                                   PyString_Size(buffer),
1573                                                   merge, scale,
1574                                                   &num_vectors, &vectors);
1575 
1576         Py_DECREF(chunk_size);
1577         Py_DECREF(buffer);
1578         Py_DECREF(read_method);
1579     }
1580 
1581     if (!success) {
1582         PyErr_Format(pygimp_error,
1583                      "Vectors import failed: %s", gimp_get_pdb_error());
1584         return NULL;
1585     }
1586 
1587     return vectors_to_objects(num_vectors, vectors);
1588 }
1589 
1590 static PyObject *
pygimp_vectors_import_from_string(PyObject * self,PyObject * args,PyObject * kwargs)1591 pygimp_vectors_import_from_string(PyObject *self, PyObject *args, PyObject *kwargs)
1592 {
1593     PyGimpImage *img;
1594     const char *svg_string;
1595     int length;
1596     gboolean merge = FALSE, scale = FALSE;
1597     int *vectors, num_vectors;
1598     gboolean success;
1599 
1600     static char *kwlist[] = { "image", "svg_string", "merge", "scale", NULL };
1601 
1602     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1603                                      "O!s#|ii:vectors_import_from_string", kwlist,
1604                                      &PyGimpImage_Type, &img,
1605                                      &svg_string, &length,
1606                                      &merge, &scale))
1607         return NULL;
1608 
1609     success = gimp_vectors_import_from_string(img->ID, svg_string, length,
1610                                               merge, scale,
1611                                               &num_vectors, &vectors);
1612 
1613     if (!success) {
1614         PyErr_Format(pygimp_error,
1615                      "Vectors import failed: %s", gimp_get_pdb_error());
1616         return NULL;
1617     }
1618 
1619     return vectors_to_objects(num_vectors, vectors);
1620 }
1621 
1622 static PyObject *
id2image(PyObject * self,PyObject * args)1623 id2image(PyObject *self, PyObject *args)
1624 {
1625     int id;
1626 
1627     if (!PyArg_ParseTuple(args, "i:_id2image", &id))
1628         return NULL;
1629 
1630     if (id >= 0)
1631         return pygimp_image_new(id);
1632 
1633     Py_INCREF(Py_None);
1634     return Py_None;
1635 }
1636 
1637 static PyObject *
id2drawable(PyObject * self,PyObject * args)1638 id2drawable(PyObject *self, PyObject *args)
1639 {
1640     int id;
1641 
1642     if (!PyArg_ParseTuple(args, "i:_id2drawable", &id))
1643         return NULL;
1644 
1645     if (id >= 0)
1646         return pygimp_drawable_new(NULL, id);
1647 
1648     Py_INCREF(Py_None);
1649     return Py_None;
1650 }
1651 
1652 static PyObject *
id2display(PyObject * self,PyObject * args)1653 id2display(PyObject *self, PyObject *args)
1654 {
1655     int id;
1656 
1657     if (!PyArg_ParseTuple(args, "i:_id2display", &id))
1658         return NULL;
1659 
1660     if (id >= 0)
1661         return pygimp_display_new(id);
1662 
1663     Py_INCREF(Py_None);
1664     return Py_None;
1665 }
1666 
1667 static PyObject *
id2vectors(PyObject * self,PyObject * args)1668 id2vectors(PyObject *self, PyObject *args)
1669 {
1670     int id;
1671 
1672     if (!PyArg_ParseTuple(args, "i:_id2vectors", &id))
1673         return NULL;
1674 
1675     if (id >= 0)
1676         return pygimp_vectors_new(id);
1677 
1678     Py_INCREF(Py_None);
1679     return Py_None;
1680 }
1681 
1682 static PyObject *
pygimp_export_image(PyObject * self,PyObject * args,PyObject * kwargs)1683 pygimp_export_image (PyObject *self, PyObject *args, PyObject *kwargs)
1684 {
1685     PyGimpImage *img;
1686     PyGimpDrawable *drw = NULL;
1687     gchar *format_name = NULL;
1688     unsigned int capabilities = -1;
1689     GimpExportReturn result;
1690     gint32  img_id;
1691     gint32  drw_id;
1692     PyObject *return_values;
1693 
1694     static char *kwlist[] = { "image", "drawable", "format_name", "capabilities", NULL };
1695     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|OsI:export_image", kwlist,
1696                                     &PyGimpImage_Type, &img,
1697                                     &drw,
1698                                     &format_name,
1699                                     &capabilities))
1700         return NULL;
1701     if (capabilities == -1) {
1702          PyErr_SetString(PyExc_TypeError,
1703                          "the \"capabilities\" (4th) parameter must be set with "
1704                          "a combination of the "
1705                          "EXPORT_CAN_HANDLE_*/EXPORT_NEEDS_ALPHA values. "
1706                          "(check developer documentation on the C function "
1707                          "gimp_export_image for details)"
1708                          );
1709         return NULL;
1710     }
1711 
1712     /* If no drawable is given, assume the active drawable */
1713     if (drw == NULL) {
1714         drw = (PyGimpDrawable *)PyObject_GetAttrString((PyObject *)img,
1715                                                        "active_drawable");
1716         if ((PyObject *)drw == Py_None) {
1717             PyErr_SetString(PyExc_ValueError,
1718                             "No active drawable in the image and no drawable "
1719                             " specified for export."
1720                            );
1721             return NULL;
1722         }
1723     }
1724     img_id = img->ID;
1725     drw_id = drw->ID;
1726 
1727     result = gimp_export_image(&img_id, &drw_id, format_name, capabilities);
1728 
1729     if (img_id != img->ID) {
1730         img = (PyGimpImage *)pygimp_image_new(img_id);
1731     }
1732     else {
1733         Py_INCREF(img);
1734     }
1735     if (drw_id != drw->ID) {
1736         drw = (PyGimpDrawable *)pygimp_drawable_new(NULL, drw_id);
1737     }
1738     else {
1739         Py_INCREF(drw);
1740     }
1741 
1742     return_values = PyTuple_New(3);
1743     PyTuple_SetItem(return_values, 0, PyInt_FromLong(result));
1744     PyTuple_SetItem(return_values, 1, (PyObject *)img);
1745     PyTuple_SetItem(return_values, 2, (PyObject *)drw);
1746 
1747     return return_values;
1748 }
1749 
1750 static PyObject *
pygimp_export_dialog_new(PyObject * self,PyObject * args,PyObject * kwargs)1751 pygimp_export_dialog_new (PyObject *self, PyObject *args, PyObject *kwargs)
1752 {
1753     gchar *format_name;
1754     gchar *role = NULL;
1755     gchar *help_id = NULL;
1756     GtkWidget *dialog = NULL;
1757 
1758     static char *kwlist[] = { "format_name", "role", "help_id", NULL };
1759     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss:export_dialog", kwlist,
1760                                      &format_name,
1761                                      &role,
1762                                      &help_id))
1763         return NULL;
1764 
1765     if (role == NULL) {
1766         role = "gimp_export_image";
1767     }
1768 
1769     dialog = gimp_export_dialog_new(format_name, role, help_id);
1770 
1771     /* pyobject_new handles NULL values */
1772 
1773     return pygobject_new((GObject *)dialog);
1774 
1775 }
1776 
1777 /* No need to expose "gimp_export_dialog_get_content_area",
1778  * because one just have to call the "get_content_area" method
1779  * on the returned export_dialog
1780  */
1781 
1782 
1783 /* List of methods defined in the module */
1784 
1785 static struct PyMethodDef gimp_methods[] = {
1786     {"main",    (PyCFunction)pygimp_main,       METH_VARARGS},
1787     {"quit",    (PyCFunction)pygimp_quit,       METH_NOARGS},
1788     {"message", (PyCFunction)pygimp_message,    METH_VARARGS},
1789     {"exit",    (PyCFunction)pygimp_exit,       METH_VARARGS | METH_KEYWORDS},
1790     {"set_data",        (PyCFunction)pygimp_set_data,   METH_VARARGS},
1791     {"get_data",        (PyCFunction)pygimp_get_data,   METH_VARARGS},
1792     {"progress_init",   (PyCFunction)pygimp_progress_init,      METH_VARARGS},
1793     {"progress_update", (PyCFunction)pygimp_progress_update,    METH_VARARGS},
1794     {"progress_install",        (PyCFunction)pygimp_progress_install,   METH_VARARGS | METH_KEYWORDS},
1795     {"progress_uninstall",      (PyCFunction)pygimp_progress_uninstall, METH_VARARGS},
1796     {"image_list",      (PyCFunction)pygimp_image_list, METH_NOARGS},
1797     {"install_procedure",       (PyCFunction)pygimp_install_procedure,  METH_VARARGS},
1798     {"install_temp_proc",       (PyCFunction)pygimp_install_temp_proc,  METH_VARARGS},
1799     {"uninstall_temp_proc",     (PyCFunction)pygimp_uninstall_temp_proc,        METH_VARARGS},
1800     {"register_magic_load_handler",     (PyCFunction)pygimp_register_magic_load_handler,        METH_VARARGS},
1801     {"register_load_handler",   (PyCFunction)pygimp_register_load_handler,      METH_VARARGS},
1802     {"register_save_handler",   (PyCFunction)pygimp_register_save_handler,      METH_VARARGS},
1803     {"domain_register",         (PyCFunction)pygimp_domain_register,    METH_VARARGS},
1804     {"menu_register",           (PyCFunction)pygimp_menu_register,      METH_VARARGS},
1805     {"gamma",   (PyCFunction)pygimp_gamma,      METH_NOARGS},
1806     {"gtkrc",   (PyCFunction)pygimp_gtkrc,      METH_NOARGS},
1807     {"personal_rc_file",        (PyCFunction)pygimp_personal_rc_file, METH_VARARGS | METH_KEYWORDS},
1808     {"context_push", (PyCFunction)pygimp_context_push, METH_NOARGS},
1809     {"context_pop", (PyCFunction)pygimp_context_pop, METH_NOARGS},
1810     {"get_background",  (PyCFunction)pygimp_get_background,     METH_NOARGS},
1811     {"get_foreground",  (PyCFunction)pygimp_get_foreground,     METH_NOARGS},
1812     {"set_background",  (PyCFunction)pygimp_set_background,     METH_VARARGS},
1813     {"set_foreground",  (PyCFunction)pygimp_set_foreground,     METH_VARARGS},
1814     {"gradients_get_list",      (PyCFunction)pygimp_gradients_get_list, METH_VARARGS | METH_KEYWORDS},
1815     {"context_get_gradient",    (PyCFunction)pygimp_context_get_gradient,       METH_NOARGS},
1816     {"context_set_gradient",    (PyCFunction)pygimp_context_set_gradient,       METH_VARARGS},
1817     {"gradients_get_gradient",  (PyCFunction)pygimp_gradients_get_gradient,     METH_NOARGS},
1818     {"gradients_set_gradient",  (PyCFunction)pygimp_gradients_set_gradient,     METH_VARARGS},
1819     {"gradient_get_uniform_samples",    (PyCFunction)pygimp_gradient_get_uniform_samples,       METH_VARARGS},
1820     {"gradient_get_custom_samples",     (PyCFunction)pygimp_gradient_get_custom_samples,        METH_VARARGS},
1821     {"gradients_sample_uniform",        (PyCFunction)pygimp_gradients_sample_uniform,   METH_VARARGS},
1822     {"gradients_sample_custom", (PyCFunction)pygimp_gradients_sample_custom,    METH_VARARGS},
1823     {"delete", (PyCFunction)pygimp_delete, METH_VARARGS},
1824     {"displays_flush", (PyCFunction)pygimp_displays_flush, METH_NOARGS},
1825     {"displays_reconnect", (PyCFunction)pygimp_displays_reconnect, METH_VARARGS},
1826     {"tile_cache_size", (PyCFunction)pygimp_tile_cache_size, METH_VARARGS},
1827     {"tile_cache_ntiles", (PyCFunction)pygimp_tile_cache_ntiles, METH_VARARGS},
1828     {"tile_width", (PyCFunction)pygimp_tile_width, METH_NOARGS},
1829     {"tile_height", (PyCFunction)pygimp_tile_height, METH_NOARGS},
1830     {"extension_ack", (PyCFunction)pygimp_extension_ack, METH_NOARGS},
1831     {"extension_enable", (PyCFunction)pygimp_extension_enable, METH_NOARGS},
1832     {"extension_process", (PyCFunction)pygimp_extension_process, METH_VARARGS},
1833     {"parasite_find",      (PyCFunction)pygimp_parasite_find,      METH_VARARGS},
1834     {"parasite_attach",    (PyCFunction)pygimp_parasite_attach,    METH_VARARGS},
1835     {"attach_new_parasite",(PyCFunction)pygimp_attach_new_parasite,METH_VARARGS},
1836     {"parasite_detach",    (PyCFunction)pygimp_parasite_detach,    METH_VARARGS},
1837     {"parasite_list",    (PyCFunction)pygimp_parasite_list,    METH_NOARGS},
1838     {"show_tool_tips",  (PyCFunction)pygimp_show_tool_tips,  METH_NOARGS},
1839     {"show_help_button",  (PyCFunction)pygimp_show_help_button,  METH_NOARGS},
1840     {"check_size",  (PyCFunction)pygimp_check_size,  METH_NOARGS},
1841     {"check_type",  (PyCFunction)pygimp_check_type,  METH_NOARGS},
1842     {"default_display",  (PyCFunction)pygimp_default_display,  METH_NOARGS},
1843     {"wm_class", (PyCFunction)pygimp_wm_class,  METH_NOARGS},
1844     {"display_name", (PyCFunction)pygimp_display_name,  METH_NOARGS},
1845     {"monitor_number", (PyCFunction)pygimp_monitor_number,      METH_NOARGS},
1846     {"get_progname", (PyCFunction)pygimp_get_progname,  METH_NOARGS},
1847     {"user_directory", (PyCFunction)pygimp_user_directory, METH_VARARGS | METH_KEYWORDS},
1848     {"fonts_refresh", (PyCFunction)pygimp_fonts_refresh,        METH_NOARGS},
1849     {"fonts_get_list", (PyCFunction)pygimp_fonts_get_list,      METH_VARARGS | METH_KEYWORDS},
1850     {"checks_get_shades", (PyCFunction)pygimp_checks_get_shades, METH_VARARGS | METH_KEYWORDS},
1851     {"vectors_import_from_file", (PyCFunction)pygimp_vectors_import_from_file, METH_VARARGS | METH_KEYWORDS},
1852     {"vectors_import_from_string", (PyCFunction)pygimp_vectors_import_from_string, METH_VARARGS | METH_KEYWORDS},
1853     {"_id2image", (PyCFunction)id2image, METH_VARARGS},
1854     {"_id2drawable", (PyCFunction)id2drawable, METH_VARARGS},
1855     {"_id2display", (PyCFunction)id2display, METH_VARARGS},
1856     {"_id2vectors", (PyCFunction)id2vectors, METH_VARARGS},
1857     {"export_image", (PyCFunction)pygimp_export_image, METH_VARARGS | METH_KEYWORDS},
1858     {"export_dialog", (PyCFunction)pygimp_export_dialog_new, METH_VARARGS | METH_KEYWORDS},
1859     {NULL,       (PyCFunction)NULL, 0, NULL}            /* sentinel */
1860 };
1861 
1862 
1863 static struct _PyGimp_Functions pygimp_api_functions = {
1864     &PyGimpImage_Type,
1865     pygimp_image_new,
1866     &PyGimpDisplay_Type,
1867     pygimp_display_new,
1868     &PyGimpItem_Type,
1869     pygimp_item_new,
1870     &PyGimpDrawable_Type,
1871     pygimp_drawable_new,
1872     &PyGimpLayer_Type,
1873     pygimp_layer_new,
1874     &PyGimpGroupLayer_Type,
1875     pygimp_group_layer_new,
1876     &PyGimpChannel_Type,
1877     pygimp_channel_new,
1878     &PyGimpVectors_Type,
1879     pygimp_vectors_new,
1880 };
1881 
1882 
1883 /* Initialization function for the module (*must* be called initgimp) */
1884 
1885 static char gimp_module_documentation[] =
1886 "This module provides interfaces to allow you to write gimp plug-ins"
1887 ;
1888 
1889 void initgimp(void);
1890 
1891 PyMODINIT_FUNC
initgimp(void)1892 initgimp(void)
1893 {
1894     PyObject *m;
1895 
1896     PyGimpPDB_Type.ob_type = &PyType_Type;
1897     PyGimpPDB_Type.tp_alloc = PyType_GenericAlloc;
1898     PyGimpPDB_Type.tp_new = PyType_GenericNew;
1899     if (PyType_Ready(&PyGimpPDB_Type) < 0)
1900         return;
1901 
1902     PyGimpPDBFunction_Type.ob_type = &PyType_Type;
1903     PyGimpPDBFunction_Type.tp_alloc = PyType_GenericAlloc;
1904     PyGimpPDBFunction_Type.tp_new = PyType_GenericNew;
1905     if (PyType_Ready(&PyGimpPDBFunction_Type) < 0)
1906         return;
1907 
1908     PyGimpImage_Type.ob_type = &PyType_Type;
1909     PyGimpImage_Type.tp_alloc = PyType_GenericAlloc;
1910     PyGimpImage_Type.tp_new = PyType_GenericNew;
1911     if (PyType_Ready(&PyGimpImage_Type) < 0)
1912         return;
1913 
1914     PyGimpDisplay_Type.ob_type = &PyType_Type;
1915     PyGimpDisplay_Type.tp_alloc = PyType_GenericAlloc;
1916     PyGimpDisplay_Type.tp_new = PyType_GenericNew;
1917     if (PyType_Ready(&PyGimpDisplay_Type) < 0)
1918         return;
1919 
1920     PyGimpLayer_Type.ob_type = &PyType_Type;
1921     PyGimpLayer_Type.tp_alloc = PyType_GenericAlloc;
1922     PyGimpLayer_Type.tp_new = PyType_GenericNew;
1923     if (PyType_Ready(&PyGimpLayer_Type) < 0)
1924         return;
1925 
1926     PyGimpGroupLayer_Type.ob_type = &PyType_Type;
1927     PyGimpGroupLayer_Type.tp_alloc = PyType_GenericAlloc;
1928     PyGimpGroupLayer_Type.tp_new = PyType_GenericNew;
1929     if (PyType_Ready(&PyGimpGroupLayer_Type) < 0)
1930         return;
1931 
1932     PyGimpChannel_Type.ob_type = &PyType_Type;
1933     PyGimpChannel_Type.tp_alloc = PyType_GenericAlloc;
1934     PyGimpChannel_Type.tp_new = PyType_GenericNew;
1935     if (PyType_Ready(&PyGimpChannel_Type) < 0)
1936         return;
1937 
1938     PyGimpTile_Type.ob_type = &PyType_Type;
1939     PyGimpTile_Type.tp_alloc = PyType_GenericAlloc;
1940     if (PyType_Ready(&PyGimpTile_Type) < 0)
1941         return;
1942 
1943     PyGimpPixelRgn_Type.ob_type = &PyType_Type;
1944     PyGimpPixelRgn_Type.tp_alloc = PyType_GenericAlloc;
1945     if (PyType_Ready(&PyGimpPixelRgn_Type) < 0)
1946         return;
1947 
1948     PyGimpParasite_Type.ob_type = &PyType_Type;
1949     PyGimpParasite_Type.tp_alloc = PyType_GenericAlloc;
1950     PyGimpParasite_Type.tp_new = PyType_GenericNew;
1951     if (PyType_Ready(&PyGimpParasite_Type) < 0)
1952         return;
1953 
1954     PyGimpVectorsStroke_Type.ob_type = &PyType_Type;
1955     PyGimpVectorsStroke_Type.tp_alloc = PyType_GenericAlloc;
1956     PyGimpVectorsStroke_Type.tp_new = PyType_GenericNew;
1957     if (PyType_Ready(&PyGimpVectorsStroke_Type) < 0)
1958         return;
1959 
1960     PyGimpVectorsBezierStroke_Type.ob_type = &PyType_Type;
1961     PyGimpVectorsBezierStroke_Type.tp_alloc = PyType_GenericAlloc;
1962     PyGimpVectorsBezierStroke_Type.tp_new = PyType_GenericNew;
1963     if (PyType_Ready(&PyGimpVectorsBezierStroke_Type) < 0)
1964         return;
1965 
1966     PyGimpVectors_Type.ob_type = &PyType_Type;
1967     PyGimpVectors_Type.tp_alloc = PyType_GenericAlloc;
1968     PyGimpVectors_Type.tp_new = PyType_GenericNew;
1969     if (PyType_Ready(&PyGimpVectors_Type) < 0)
1970         return;
1971 
1972     PyGimpPixelFetcher_Type.ob_type = &PyType_Type;
1973     PyGimpPixelFetcher_Type.tp_alloc = PyType_GenericAlloc;
1974     PyGimpPixelFetcher_Type.tp_new = PyType_GenericNew;
1975     if (PyType_Ready(&PyGimpPixelFetcher_Type) < 0)
1976         return;
1977 
1978     pygimp_init_pygobject();
1979     init_pygimpcolor();
1980 
1981     /* initialize i18n support */
1982     bindtextdomain (GETTEXT_PACKAGE "-python", gimp_locale_directory ());
1983 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1984     bind_textdomain_codeset (GETTEXT_PACKAGE "-python", "UTF-8");
1985 #endif
1986 
1987     /* set the default python encoding to utf-8 */
1988     PyUnicode_SetDefaultEncoding("utf-8");
1989 
1990     /* initialize gegl */
1991     gegl_init(0, NULL);
1992 
1993     /* Create the module and add the functions */
1994     m = Py_InitModule4("gimp", gimp_methods,
1995                        gimp_module_documentation,
1996                        NULL, PYTHON_API_VERSION);
1997 
1998     /* Add some symbolic constants to the module */
1999     pygimp_error = PyErr_NewException("gimp.error", PyExc_RuntimeError, NULL);
2000     PyModule_AddObject(m, "error", pygimp_error);
2001 
2002     PyModule_AddObject(m, "pdb", pygimp_pdb_new());
2003 
2004     /* export the types used in gimpmodule */
2005     Py_INCREF(&PyGimpImage_Type);
2006     PyModule_AddObject(m, "Image", (PyObject *)&PyGimpImage_Type);
2007 
2008     Py_INCREF(&PyGimpItem_Type);
2009     PyModule_AddObject(m, "Item", (PyObject *)&PyGimpItem_Type);
2010 
2011     Py_INCREF(&PyGimpDrawable_Type);
2012     PyModule_AddObject(m, "Drawable", (PyObject *)&PyGimpDrawable_Type);
2013 
2014     Py_INCREF(&PyGimpLayer_Type);
2015     PyModule_AddObject(m, "Layer", (PyObject *)&PyGimpLayer_Type);
2016 
2017     Py_INCREF(&PyGimpGroupLayer_Type);
2018     PyModule_AddObject(m, "GroupLayer", (PyObject *)&PyGimpGroupLayer_Type);
2019 
2020     Py_INCREF(&PyGimpChannel_Type);
2021     PyModule_AddObject(m, "Channel", (PyObject *)&PyGimpChannel_Type);
2022 
2023     Py_INCREF(&PyGimpDisplay_Type);
2024     PyModule_AddObject(m, "Display", (PyObject *)&PyGimpDisplay_Type);
2025 
2026     Py_INCREF(&PyGimpTile_Type);
2027     PyModule_AddObject(m, "Tile", (PyObject *)&PyGimpTile_Type);
2028 
2029     Py_INCREF(&PyGimpPixelRgn_Type);
2030     PyModule_AddObject(m, "PixelRgn", (PyObject *)&PyGimpPixelRgn_Type);
2031 
2032     Py_INCREF(&PyGimpParasite_Type);
2033     PyModule_AddObject(m, "Parasite", (PyObject *)&PyGimpParasite_Type);
2034 
2035     Py_INCREF(&PyGimpVectorsBezierStroke_Type);
2036     PyModule_AddObject(m, "VectorsBezierStroke", (PyObject *)&PyGimpVectorsBezierStroke_Type);
2037 
2038     Py_INCREF(&PyGimpVectors_Type);
2039     PyModule_AddObject(m, "Vectors", (PyObject *)&PyGimpVectors_Type);
2040 
2041     Py_INCREF(&PyGimpPixelFetcher_Type);
2042     PyModule_AddObject(m, "PixelFetcher", (PyObject *)&PyGimpPixelFetcher_Type);
2043 
2044     /* for other modules */
2045     pygimp_api_functions.pygimp_error = pygimp_error;
2046 
2047     PyModule_AddObject(m, "_PyGimp_API",
2048                        PyCObject_FromVoidPtr(&pygimp_api_functions, NULL));
2049 
2050     PyModule_AddObject(m, "version",
2051                        Py_BuildValue("(iii)",
2052                                      gimp_major_version,
2053                                      gimp_minor_version,
2054                                      gimp_micro_version));
2055 
2056     /* Some environment constants */
2057     PyModule_AddObject(m, "directory",
2058                        PyString_FromString(gimp_directory()));
2059     PyModule_AddObject(m, "data_directory",
2060                        PyString_FromString(gimp_data_directory()));
2061     PyModule_AddObject(m, "locale_directory",
2062                        PyString_FromString(gimp_locale_directory()));
2063     PyModule_AddObject(m, "sysconf_directory",
2064                        PyString_FromString(gimp_sysconf_directory()));
2065     PyModule_AddObject(m, "plug_in_directory",
2066                        PyString_FromString(gimp_plug_in_directory()));
2067 
2068     /* Check for errors */
2069     if (PyErr_Occurred())
2070         Py_FatalError("can't initialize module gimp");
2071 }
2072