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 #define NO_IMPORT_PYGOBJECT
24 #include <pygobject.h>
25
26 #include "pygimp.h"
27
28 #define NO_IMPORT_PYGIMPCOLOR
29 #include "pygimpcolor-api.h"
30
31 #include <structmember.h>
32
33 #include <glib-object.h>
34 #include <glib/gprintf.h>
35
36 #ifndef PG_DEBUG
37 # define PG_DEBUG 0
38 #endif
39
40 /* ----------------------------------------------------- */
41
42 /* Declarations for objects of type pdb */
43
44 typedef struct {
45 PyObject_HEAD
46 } PyGimpPDB;
47
48
49 /* ---------------------------------------------------------------- */
50
51 /* Declarations for objects of type pdbFunc */
52
53 typedef struct {
54 PyObject_HEAD
55 char *name;
56 PyObject *proc_name, *proc_blurb, *proc_help, *proc_author,
57 *proc_copyright, *proc_date, *proc_type, *py_params,
58 *py_return_vals;
59 int nparams, nreturn_vals;
60 GimpParamDef *params, *return_vals;
61 } PyGimpPDBFunction;
62
63 static PyObject *pygimp_pdb_function_new_from_proc_db(char *name);
64
65 /* ---------------------------------------------------------------- */
66
67 /* routines to convert between Python tuples and gimp GimpParam's */
68
69 #if PG_DEBUG > 0
70
71 static void
pygimp_param_print(int nparams,GimpParam * params)72 pygimp_param_print(int nparams, GimpParam *params)
73 {
74 int i;
75
76 for (i = 0; i < nparams; i++) {
77 g_printf("param_print: type: %d, PDB_ITEM: %d\n", params[i].type, GIMP_PDB_ITEM);
78 switch(params[i].type) {
79 case GIMP_PDB_INT32:
80 g_printerr("%i. int %i\n", i,
81 params[i].data.d_int32);
82 break;
83 case GIMP_PDB_INT16:
84 g_printerr("%i. int %i\n", i,
85 params[i].data.d_int16);
86 break;
87 case GIMP_PDB_INT8:
88 g_printerr("%i. int %u\n", i,
89 params[i].data.d_int8);
90 break;
91 case GIMP_PDB_FLOAT:
92 g_printerr("%i. float %f\n", i,
93 params[i].data.d_float);
94 break;
95 case GIMP_PDB_STRING:
96 g_printerr("%i. string %s\n", i,
97 params[i].data.d_string);
98 break;
99 case GIMP_PDB_INT32ARRAY:
100 case GIMP_PDB_INT16ARRAY:
101 case GIMP_PDB_INT8ARRAY:
102 case GIMP_PDB_FLOATARRAY:
103 case GIMP_PDB_STRINGARRAY:
104 g_printerr("%i. array of type %i %s\n", i,
105 params[i].type,
106 params[i].data.d_int32array == NULL ? "(null)":"");
107 break;
108 case GIMP_PDB_STATUS:
109 g_printerr("%i. status %i\n", i,
110 params[i].data.d_status);
111 break;
112 default:
113 g_printerr("%i. other %i\n", i,
114 params[i].data.d_int32);
115 break;
116 }
117 }
118 }
119
120 #endif
121
122 PyObject *
pygimp_param_to_tuple(int nparams,const GimpParam * params)123 pygimp_param_to_tuple(int nparams, const GimpParam *params)
124 {
125 PyObject *args, *tmp;
126 int i, j, n;
127
128 args = PyTuple_New(nparams);
129 for (i = 0; i < nparams && params[i].type != GIMP_PDB_END; i++) {
130 PyObject *value = NULL;
131
132 #if PG_DEBUG > 1
133 g_printf("param_to_tuple: type: %d, PDB_ITEM: %d\n", params[i].type, GIMP_PDB_ITEM);
134 #endif
135
136 switch(params[i].type) {
137 case GIMP_PDB_INT32:
138 value = PyInt_FromLong(params[i].data.d_int32);
139 break;
140 case GIMP_PDB_INT16:
141 value = PyInt_FromLong(params[i].data.d_int16);
142 break;
143 case GIMP_PDB_INT8:
144 value = PyInt_FromLong(params[i].data.d_int8);
145 break;
146 case GIMP_PDB_FLOAT:
147 value = PyFloat_FromDouble(params[i].data.d_float);
148 break;
149 case GIMP_PDB_STRING:
150 if (params[i].data.d_string == NULL) {
151 Py_INCREF(Py_None);
152 value = Py_None;
153 } else
154 value = PyString_FromString(params[i].data.d_string);
155 break;
156
157 /* For these to work, the previous argument must have
158 * been an integer
159 */
160 case GIMP_PDB_INT32ARRAY:
161 if (params[i].data.d_int32array == NULL) {
162 value = PyTuple_New(0);
163 break;
164 }
165 if ((tmp=PyTuple_GetItem(args, i-1)) == NULL) {
166 Py_DECREF(args);
167 return NULL;
168 }
169 if (!PyInt_Check(tmp)) {
170 PyErr_SetString(PyExc_TypeError,
171 "count type must be integer");
172 Py_DECREF(args);
173 return NULL;
174 }
175 n = PyInt_AsLong(tmp);
176 value = PyTuple_New(n);
177 for (j = 0; j < n; j++)
178 PyTuple_SetItem(value, j,
179 PyInt_FromLong(params[i].data.d_int32array[j]));
180 break;
181 case GIMP_PDB_INT16ARRAY:
182 if (params[i].data.d_int16array == NULL) {
183 value = PyTuple_New(0);
184 break;
185 }
186 if ((tmp=PyTuple_GetItem(args, i-1)) == NULL) {
187 Py_DECREF(args);
188 return NULL;
189 }
190 if (!PyInt_Check(tmp)) {
191 PyErr_SetString(PyExc_TypeError,
192 "count type must be integer");
193 Py_DECREF(args);
194 return NULL;
195 }
196 n = PyInt_AsLong(tmp);
197 value = PyTuple_New(n);
198 for (j = 0; j < n; j++)
199 PyTuple_SetItem(value, j,
200 PyInt_FromLong(params[i].data.d_int16array[j]));
201 break;
202 case GIMP_PDB_INT8ARRAY:
203 if (params[i].data.d_int8array == NULL) {
204 value = PyTuple_New(0);
205 break;
206 }
207 if ((tmp=PyTuple_GetItem(args, i-1)) == NULL) {
208 Py_DECREF(args);
209 return NULL;
210 }
211 if (!PyInt_Check(tmp)) {
212 PyErr_SetString(PyExc_TypeError,
213 "count type must be integer");
214 Py_DECREF(args);
215 return NULL;
216 }
217 n = PyInt_AsLong(tmp);
218 value = PyTuple_New(n);
219 for (j = 0; j < n; j++)
220 PyTuple_SetItem(value, j,
221 PyInt_FromLong(params[i].data.d_int8array[j]));
222 break;
223 case GIMP_PDB_FLOATARRAY:
224 if (params[i].data.d_floatarray == NULL) {
225 value = PyTuple_New(0);
226 break;
227 }
228 if ((tmp=PyTuple_GetItem(args, i-1)) == NULL) {
229 Py_DECREF(args);
230 return NULL;
231 }
232 if (!PyInt_Check(tmp)) {
233 PyErr_SetString(PyExc_TypeError,
234 "count type must be integer");
235 Py_DECREF(args);
236 return NULL;
237 }
238 n = PyInt_AsLong(tmp);
239 value = PyTuple_New(n);
240 for (j = 0; j < n; j++)
241 PyTuple_SetItem(value, j,
242 PyFloat_FromDouble(params[i].data.d_floatarray[j]));
243 break;
244 case GIMP_PDB_STRINGARRAY:
245 if (params[i].data.d_stringarray == NULL) {
246 value = PyTuple_New(0);
247 break;
248 }
249 if ((tmp=PyTuple_GetItem(args, i-1)) == NULL) {
250 Py_DECREF(args);
251 return NULL;
252 }
253 if (!PyInt_Check(tmp)) {
254 PyErr_SetString(PyExc_TypeError,
255 "count type must be integer");
256 Py_DECREF(args);
257 return NULL;
258 }
259 n = PyInt_AsLong(tmp);
260 value = PyTuple_New(n);
261 for (j = 0; j < n; j++)
262 PyTuple_SetItem(value, j,
263 params[i].data.d_stringarray[j] ?
264 PyString_FromString(params[i].data.d_stringarray[j]) :
265 PyString_FromString(""));
266 break;
267 case GIMP_PDB_COLOR:
268 value = pygimp_rgb_new(¶ms[i].data.d_color);
269 break;
270 /*
271 GIMP_PDB_REGION is deprecated in libgimpbase/gimpbaseenums.h
272 and conflicts with GIMP_PDB_ITEM
273 case GIMP_PDB_REGION:
274 value = Py_BuildValue("(iiii)",
275 (int) params[i].data.d_region.x,
276 (int) params[i].data.d_region.y,
277 (int) params[i].data.d_region.width,
278 (int) params[i].data.d_region.height);
279 break;
280 */
281 case GIMP_PDB_DISPLAY:
282 value = pygimp_display_new(params[i].data.d_display);
283 break;
284 case GIMP_PDB_IMAGE:
285 value = pygimp_image_new(params[i].data.d_image);
286 break;
287 case GIMP_PDB_LAYER:
288 value = pygimp_layer_new(params[i].data.d_layer);
289 break;
290 case GIMP_PDB_CHANNEL:
291 value = pygimp_channel_new(params[i].data.d_channel);
292 break;
293 case GIMP_PDB_ITEM:
294 value = pygimp_item_new(params[i].data.d_item);
295 break;
296 case GIMP_PDB_DRAWABLE:
297 value = pygimp_drawable_new(NULL, params[i].data.d_drawable);
298 break;
299 case GIMP_PDB_SELECTION:
300 value = pygimp_channel_new(params[i].data.d_selection);
301 break;
302 case GIMP_PDB_COLORARRAY:
303 if (params[i].data.d_colorarray == NULL) {
304 value = PyTuple_New(0);
305 break;
306 }
307 if ((tmp=PyTuple_GetItem(args, i-1)) == NULL) {
308 Py_DECREF(args);
309 return NULL;
310 }
311 if (!PyInt_Check(tmp)) {
312 PyErr_SetString(PyExc_TypeError,
313 "count type must be integer");
314 Py_DECREF(args);
315 return NULL;
316 }
317 n = PyInt_AsLong(tmp);
318 value = PyTuple_New(n);
319 for (j = 0; j < n; j++)
320 PyTuple_SetItem(value, j,
321 pygimp_rgb_new(¶ms[i].data.d_colorarray[j]));
322 break;
323 case GIMP_PDB_VECTORS:
324 value = pygimp_vectors_new(params[i].data.d_vectors);
325 break;
326 case GIMP_PDB_PARASITE:
327 value = pygimp_parasite_new(gimp_parasite_copy(
328 &(params[i].data.d_parasite)));
329 break;
330 case GIMP_PDB_STATUS:
331 value = PyInt_FromLong(params[i].data.d_status);
332 break;
333 case GIMP_PDB_END:
334 break;
335 }
336 PyTuple_SetItem(args, i, value);
337 }
338 return args;
339 }
340
341 GimpParam *
pygimp_param_from_tuple(PyObject * args,const GimpParamDef * ptype,int nparams)342 pygimp_param_from_tuple(PyObject *args, const GimpParamDef *ptype, int nparams)
343 {
344 PyObject *tuple, *item, *x, *y;
345 GimpParam *ret;
346 int i, j, len;
347 gint32 *i32a; gint16 *i16a; guint8 *i8a; gdouble *fa; gchar **sa;
348
349 if (nparams == 0)
350 tuple = PyTuple_New(0);
351 else if (!PyTuple_Check(args) && nparams == 1)
352 tuple = Py_BuildValue("(O)", args);
353 else {
354 Py_INCREF(args);
355 tuple = args;
356 }
357 if (!PyTuple_Check(tuple)) {
358 PyErr_SetString(PyExc_TypeError, "wrong type of parameter");
359 Py_DECREF(tuple);
360 return NULL;
361 }
362
363 if (PyTuple_Size(tuple) != nparams) {
364 PyErr_SetString(PyExc_TypeError, "wrong number of parameters");
365 Py_DECREF(tuple);
366 return NULL;
367 }
368
369 ret = g_new(GimpParam, nparams+1);
370 for (i = 0; i <= nparams; i++)
371 ret[i].type = GIMP_PDB_STATUS;
372 #define check(expr) if (expr) { \
373 PyErr_SetString(PyExc_TypeError, "wrong parameter type"); \
374 Py_DECREF(tuple); \
375 gimp_destroy_params(ret, nparams); \
376 return NULL; \
377 }
378 #define arraycheck(expr, ar) if (expr) { \
379 PyErr_SetString(PyExc_TypeError, "subscript of wrong type"); \
380 Py_DECREF(tuple); \
381 gimp_destroy_params(ret, nparams); \
382 g_free(ar); \
383 return NULL; \
384 }
385 for (i = 1; i <= nparams; i++) {
386 item = PyTuple_GetItem(tuple, i-1);
387 #if PG_DEBUG > 1
388 g_printf("param_from_tuple: type: %d, PDB_ITEM: %d\n", ptype[i-1].type, GIMP_PDB_ITEM);
389 #endif
390 switch (ptype[i-1].type) {
391 case GIMP_PDB_INT32:
392 check((x = PyNumber_Int(item)) == NULL);
393 ret[i].data.d_int32 = (gint32)PyInt_AsLong(x);
394 Py_DECREF(x);
395 break;
396 case GIMP_PDB_INT16:
397 check((x = PyNumber_Int(item)) == NULL);
398 ret[i].data.d_int16 = (gint16)PyInt_AsLong(x);
399 Py_DECREF(x);
400 break;
401 case GIMP_PDB_INT8:
402 check((x = PyNumber_Int(item)) == NULL);
403 ret[i].data.d_int8 = (guint8)PyInt_AsLong(x);
404 Py_DECREF(x);
405 break;
406 case GIMP_PDB_FLOAT:
407 check((x = PyNumber_Float(item)) == NULL);
408 ret[i].data.d_float = PyFloat_AsDouble(x);
409 Py_DECREF(x);
410 break;
411 case GIMP_PDB_STRING:
412 if (item == Py_None) {
413 ret[i].data.d_string = NULL;
414 break;
415 }
416 check((x = PyObject_Str(item)) == NULL);
417 ret[i].data.d_string = g_strdup(PyString_AsString(x));
418 Py_DECREF(x);
419 break;
420 case GIMP_PDB_INT32ARRAY:
421 check(!PySequence_Check(item));
422 len = PySequence_Length(item);
423 i32a = g_new(gint32, len);
424 for (j = 0; j < len; j++) {
425 x = PySequence_GetItem(item, j);
426 arraycheck((y=PyNumber_Int(x))==NULL,
427 i32a);
428 i32a[j] = PyInt_AsLong(y);
429 Py_DECREF(y);
430 }
431 ret[i].data.d_int32array = i32a;
432 break;
433 case GIMP_PDB_INT16ARRAY:
434 check(!PySequence_Check(item));
435 len = PySequence_Length(item);
436 i16a = g_new(gint16, len);
437 for (j = 0; j < len; j++) {
438 x = PySequence_GetItem(item, j);
439 arraycheck((y=PyNumber_Int(x))==NULL,
440 i16a);
441 i16a[j] = PyInt_AsLong(y);
442 Py_DECREF(y);
443 }
444 ret[i].data.d_int16array = i16a;
445 break;
446 case GIMP_PDB_INT8ARRAY:
447 check(!PySequence_Check(item));
448 len = PySequence_Length(item);
449 i8a = g_new(guint8, len);
450 for (j = 0; j < len; j++) {
451 x = PySequence_GetItem(item, j);
452 arraycheck((y=PyNumber_Int(x))==NULL,
453 i8a);
454 i8a[j] = PyInt_AsLong(y);
455 Py_DECREF(y);
456 }
457 ret[i].data.d_int8array = i8a;
458 break;
459 case GIMP_PDB_FLOATARRAY:
460 check(!PySequence_Check(item));
461 len = PySequence_Length(item);
462 fa = g_new(gdouble, len);
463 for (j = 0; j < len; j++) {
464 x = PySequence_GetItem(item, j);
465 arraycheck((y=PyNumber_Float(x))==NULL,
466 fa);
467 fa[j] = PyFloat_AsDouble(y);
468 Py_DECREF(y);
469 }
470 ret[i].data.d_floatarray = fa;
471 break;
472 case GIMP_PDB_STRINGARRAY:
473 check(!PySequence_Check(item));
474 len = PySequence_Length(item);
475 sa = g_new(gchar *, len);
476 for (j = 0; j < len; j++) {
477 x = PySequence_GetItem(item, j);
478 if (x == Py_None) {
479 sa[j] = NULL;
480 continue;
481 }
482 arraycheck((y=PyObject_Str(x))==NULL,
483 sa);
484 sa[j] = g_strdup(PyString_AsString(y));
485 Py_DECREF(y);
486 }
487 ret[i].data.d_stringarray = sa;
488 break;
489 case GIMP_PDB_COLOR:
490 {
491 GimpRGB rgb;
492
493 if (!pygimp_rgb_from_pyobject(item, &rgb)) {
494 Py_DECREF(tuple);
495 gimp_destroy_params(ret, nparams);
496 return NULL;
497 }
498
499 ret[i].data.d_color = rgb;
500 }
501 break;
502 /*
503 case GIMP_PDB_REGION:
504 check(!PySequence_Check(item) ||
505 PySequence_Length(item) < 4);
506 x = PySequence_GetItem(item, 0);
507 y = PySequence_GetItem(item, 1);
508 w = PySequence_GetItem(item, 2);
509 h = PySequence_GetItem(item, 3);
510 check(!PyInt_Check(x) || !PyInt_Check(y) ||
511 !PyInt_Check(w) || !PyInt_Check(h));
512 ret[i].data.d_region.x = PyInt_AsLong(x);
513 ret[i].data.d_region.y = PyInt_AsLong(y);
514 ret[i].data.d_region.width = PyInt_AsLong(w);
515 ret[i].data.d_region.height = PyInt_AsLong(h);
516 break;
517 */
518 case GIMP_PDB_DISPLAY:
519 if (item == Py_None) {
520 ret[i].data.d_display = -1;
521 break;
522 }
523 check(!pygimp_display_check(item));
524 ret[i].data.d_display = ((PyGimpDisplay *)item)->ID;
525 break;
526 case GIMP_PDB_IMAGE:
527 if (item == Py_None) {
528 ret[i].data.d_image = -1;
529 break;
530 }
531 check(!pygimp_image_check(item));
532 ret[i].data.d_image = ((PyGimpImage *)item)->ID;
533 break;
534 case GIMP_PDB_LAYER:
535 if (item == Py_None) {
536 ret[i].data.d_layer = -1;
537 break;
538 }
539 check(!pygimp_layer_check(item));
540 ret[i].data.d_layer = ((PyGimpLayer *)item)->ID;
541 break;
542 case GIMP_PDB_CHANNEL:
543 if (item == Py_None) {
544 ret[i].data.d_channel = -1;
545 break;
546 }
547 check(!pygimp_channel_check(item));
548 ret[i].data.d_channel = ((PyGimpChannel *)item)->ID;
549 break;
550 case GIMP_PDB_ITEM:
551 if (item == Py_None) {
552 ret[i].data.d_channel = -1;
553 break;
554 }
555 check(!pygimp_item_check(item));
556 ret[i].data.d_item = ((PyGimpItem *)item)->ID;
557 break;
558 case GIMP_PDB_DRAWABLE:
559 if (item == Py_None) {
560 ret[i].data.d_channel = -1;
561 break;
562 }
563 check(!pygimp_drawable_check(item));
564 ret[i].data.d_channel = ((PyGimpDrawable *)item)->ID;
565 break;
566 case GIMP_PDB_SELECTION:
567 if (item == Py_None) {
568 ret[i].data.d_channel = -1;
569 break;
570 }
571 check(!pygimp_channel_check(item));
572 ret[i].data.d_selection = ((PyGimpChannel *)item)->ID;
573 break;
574 case GIMP_PDB_COLORARRAY:
575 {
576 GimpRGB *rgb;
577
578 check(!PySequence_Check(item));
579 len = PySequence_Length(item);
580 rgb = g_new(GimpRGB, len);
581 for (j = 0; j < len; j++) {
582 if (!pygimp_rgb_from_pyobject(item, &rgb[j])) {
583 Py_DECREF(tuple);
584 g_free(rgb);
585 gimp_destroy_params(ret, nparams);
586 return NULL;
587 }
588 }
589 ret[i].data.d_colorarray = rgb;
590 }
591 break;
592 case GIMP_PDB_VECTORS:
593 if (item == Py_None) {
594 ret[i].data.d_vectors = -1;
595 break;
596 }
597 check(!pygimp_vectors_check(item));
598 ret[i].data.d_vectors = ((PyGimpVectors *)item)->ID;
599 break;
600 case GIMP_PDB_PARASITE:
601 /* can't do anything, since size of GimpParasite is not known */
602 break;
603 case GIMP_PDB_STATUS:
604 check(!PyInt_Check(item));
605 ret[i].data.d_status = PyInt_AsLong(item);
606 break;
607 case GIMP_PDB_END:
608 break;
609 }
610 #undef check
611 #undef arraycheck
612 ret[i].type = ptype[i-1].type;
613 }
614
615 Py_DECREF(tuple);
616 return ret;
617 }
618
619 /* ---------------------------------------------------------------- */
620
621 static PyObject *
pdb_query(PyGimpPDB * self,PyObject * args)622 pdb_query(PyGimpPDB *self, PyObject *args)
623 {
624 char *n=".*", *b=".*", *h=".*", *a=".*", *c=".*", *d=".*", *t=".*";
625 int num, i;
626 char **names;
627 PyObject *ret;
628
629 if (!PyArg_ParseTuple(args, "|zzzzzzz:gimp.pdb.query", &n, &b, &h, &a,
630 &c, &d, &t))
631 return NULL;
632
633 gimp_procedural_db_query(n, b, h, a, c, d, t, &num, &names);
634
635 ret = PyList_New(num);
636
637 for (i = 0; i < num; i++)
638 PyList_SetItem(ret, i, PyString_FromString(names[i]));
639
640 g_strfreev(names);
641
642 return ret;
643 }
644
645 static PyMethodDef pdb_methods[] = {
646 {"query", (PyCFunction)pdb_query, METH_VARARGS},
647 {NULL, NULL} /* sentinel */
648 };
649
650 /* ---------- */
651
652
653 PyObject *
pygimp_pdb_new(void)654 pygimp_pdb_new(void)
655 {
656 PyGimpPDB *self = PyObject_NEW(PyGimpPDB, &PyGimpPDB_Type);
657
658 if (self == NULL)
659 return NULL;
660
661 return (PyObject *)self;
662 }
663
664
665 static void
pdb_dealloc(PyGimpPDB * self)666 pdb_dealloc(PyGimpPDB *self)
667 {
668 PyObject_DEL(self);
669 }
670
671 static PyObject *
pdb_repr(PyGimpPDB * self)672 pdb_repr(PyGimpPDB *self)
673 {
674 return PyString_FromString("<gimp procedural database>");
675 }
676
677 /* Code to access pdb objects as mappings */
678
679 static PyObject *
pdb_subscript(PyGimpPDB * self,PyObject * key)680 pdb_subscript(PyGimpPDB *self, PyObject *key)
681 {
682 PyObject *r;
683
684 if (!PyString_Check(key)) {
685 PyErr_SetString(PyExc_TypeError, "Subscript must be a string");
686 return NULL;
687 }
688
689 r = (PyObject *)pygimp_pdb_function_new_from_proc_db(PyString_AsString(key));
690
691 if (r == NULL) {
692 PyErr_Clear();
693 PyErr_SetObject(PyExc_KeyError, key);
694 }
695
696 return r;
697 }
698
699 static PyMappingMethods pdb_as_mapping = {
700 (lenfunc)0, /*mp_length*/
701 (binaryfunc)pdb_subscript, /*mp_subscript*/
702 (objobjargproc)0, /*mp_ass_subscript*/
703 };
704
705 /* -------------------------------------------------------- */
706
707 static PyObject *
build_procedure_list(void)708 build_procedure_list(void)
709 {
710 int num, i;
711 char **names, *name, *p;
712 PyObject *ret;
713
714 gimp_procedural_db_query(".*", ".*", ".*", ".*", ".*", ".*", ".*",
715 &num, &names);
716
717 ret = PyList_New(num);
718
719 for (i = 0; i < num; i++) {
720 name = g_strdup(names[i]);
721 for (p = name; *p != '\0'; p++) {
722 if (*p == '-')
723 *p = '_';
724 }
725 PyList_SetItem(ret, i, PyString_FromString(name));
726 }
727
728 g_strfreev(names);
729
730 return ret;
731 }
732
733 static PyObject *
pdb_getattro(PyGimpPDB * self,PyObject * attr)734 pdb_getattro(PyGimpPDB *self, PyObject *attr)
735 {
736 char *attr_name;
737 PyObject *ret;
738
739 attr_name = PyString_AsString(attr);
740 if (!attr_name) {
741 PyErr_Clear();
742 return PyObject_GenericGetAttr((PyObject *)self, attr);
743 }
744
745 if (attr_name[0] == '_') {
746 if (!strcmp(attr_name, "__members__")) {
747 return build_procedure_list();
748 } else {
749 return PyObject_GenericGetAttr((PyObject *)self, attr);
750 }
751 }
752
753 ret = PyObject_GenericGetAttr((PyObject *)self, attr);
754 if (ret)
755 return ret;
756
757 PyErr_Clear();
758
759 return pygimp_pdb_function_new_from_proc_db(attr_name);
760 }
761
762 PyTypeObject PyGimpPDB_Type = {
763 PyObject_HEAD_INIT(NULL)
764 0, /* ob_size */
765 "gimp.PDB", /* tp_name */
766 sizeof(PyGimpPDB), /* tp_basicsize */
767 0, /* tp_itemsize */
768 /* methods */
769 (destructor)pdb_dealloc, /* tp_dealloc */
770 (printfunc)0, /* tp_print */
771 (getattrfunc)0, /* tp_getattr */
772 (setattrfunc)0, /* tp_setattr */
773 (cmpfunc)0, /* tp_compare */
774 (reprfunc)pdb_repr, /* tp_repr */
775 0, /* tp_as_number */
776 0, /* tp_as_sequence */
777 &pdb_as_mapping, /* tp_as_mapping */
778 (hashfunc)0, /* tp_hash */
779 (ternaryfunc)0, /* tp_call */
780 (reprfunc)0, /* tp_str */
781 (getattrofunc)pdb_getattro, /* tp_getattro */
782 (setattrofunc)0, /* tp_setattro */
783 0, /* tp_as_buffer */
784 Py_TPFLAGS_DEFAULT, /* tp_flags */
785 NULL, /* Documentation string */
786 (traverseproc)0, /* tp_traverse */
787 (inquiry)0, /* tp_clear */
788 (richcmpfunc)0, /* tp_richcompare */
789 0, /* tp_weaklistoffset */
790 (getiterfunc)0, /* tp_iter */
791 (iternextfunc)0, /* tp_iternext */
792 pdb_methods, /* tp_methods */
793 0, /* tp_members */
794 0, /* tp_getset */
795 (PyTypeObject *)0, /* tp_base */
796 (PyObject *)0, /* tp_dict */
797 0, /* tp_descr_get */
798 0, /* tp_descr_set */
799 0, /* tp_dictoffset */
800 (initproc)0, /* tp_init */
801 (allocfunc)0, /* tp_alloc */
802 (newfunc)0, /* tp_new */
803 };
804
805 /* End of code for pdb objects */
806 /* -------------------------------------------------------- */
807
808
809 static PyObject *
pygimp_pdb_function_new_from_proc_db(char * name)810 pygimp_pdb_function_new_from_proc_db(char *name)
811 {
812 PyObject *ret;
813 char *b,*h,*a,*c,*d;
814 int np, nr;
815 GimpPDBProcType pt;
816 GimpParamDef *p, *r;
817
818 if (!gimp_procedural_db_proc_info (name, &b, &h, &a, &c, &d, &pt,
819 &np, &nr, &p, &r)) {
820 PyErr_SetString(pygimp_error, "procedure not found");
821 return NULL;
822 }
823
824 ret = pygimp_pdb_function_new(name, b, h, a, c, d, pt, np, nr, p, r);
825
826 g_free(b); g_free(h); g_free(a); g_free(c); g_free(d);
827
828 return ret;
829 }
830
831 static void
pf_dealloc(PyGimpPDBFunction * self)832 pf_dealloc(PyGimpPDBFunction *self)
833 {
834 g_free(self->name);
835
836 Py_DECREF(self->proc_name);
837 Py_DECREF(self->proc_blurb);
838 Py_DECREF(self->proc_help);
839 Py_DECREF(self->proc_author);
840 Py_DECREF(self->proc_copyright);
841 Py_DECREF(self->proc_date);
842 Py_DECREF(self->proc_type);
843 Py_DECREF(self->py_params);
844 Py_DECREF(self->py_return_vals);
845
846 gimp_destroy_paramdefs(self->params, self->nparams);
847 gimp_destroy_paramdefs(self->return_vals, self->nreturn_vals);
848
849 PyObject_DEL(self);
850 }
851
852 #define OFF(x) offsetof(PyGimpPDBFunction, x)
853 static struct PyMemberDef pf_members[] = {
854 {"proc_name", T_OBJECT, OFF(proc_name), RO},
855 {"proc_blurb", T_OBJECT, OFF(proc_blurb), RO},
856 {"proc_help", T_OBJECT, OFF(proc_help), RO},
857 {"proc_author", T_OBJECT, OFF(proc_author), RO},
858 {"proc_copyright", T_OBJECT, OFF(proc_copyright), RO},
859 {"proc_date", T_OBJECT, OFF(proc_date), RO},
860 {"proc_type", T_OBJECT, OFF(proc_type), RO},
861 {"nparams", T_INT, OFF(nparams), RO},
862 {"nreturn_vals", T_INT, OFF(nreturn_vals), RO},
863 {"params", T_OBJECT, OFF(py_params), RO},
864 {"return_vals", T_OBJECT, OFF(py_return_vals), RO},
865 {NULL} /* Sentinel */
866 };
867 #undef OFF
868
869 static PyObject *
pf_repr(PyGimpPDBFunction * self)870 pf_repr(PyGimpPDBFunction *self)
871 {
872 return PyString_FromFormat("<pdb function '%s'>",
873 PyString_AsString(self->proc_name));
874 }
875
876 static PyObject *
pf_call(PyGimpPDBFunction * self,PyObject * args,PyObject * kwargs)877 pf_call(PyGimpPDBFunction *self, PyObject *args, PyObject *kwargs)
878 {
879 GimpParam *params, *ret;
880 int nret;
881 PyObject *t = NULL, *r;
882 GimpRunMode run_mode = GIMP_RUN_NONINTERACTIVE;
883
884 #if PG_DEBUG > 0
885 g_printerr("--- %s --- ", PyString_AsString(self->proc_name));
886 #endif
887
888 if (kwargs) {
889 Py_ssize_t len, pos;
890 PyObject *key, *val;
891
892 len = PyDict_Size(kwargs);
893
894 if (len == 1) {
895 pos = 0;
896 PyDict_Next(kwargs, &pos, &key, &val);
897
898 if (!PyString_Check(key)) {
899 PyErr_SetString(PyExc_TypeError,
900 "keyword argument name is not a string");
901 return NULL;
902 }
903
904 if (strcmp(PyString_AsString(key), "run_mode") != 0) {
905 PyErr_SetString(PyExc_TypeError,
906 "only 'run_mode' keyword argument accepted");
907 return NULL;
908 }
909
910 if (pyg_enum_get_value(GIMP_TYPE_RUN_MODE, val, (gpointer)&run_mode))
911 return NULL;
912 } else if (len != 0) {
913 PyErr_SetString(PyExc_TypeError,
914 "expecting at most one keyword argument");
915 return NULL;
916 }
917 }
918
919 if (self->nparams > 0 && !strcmp(self->params[0].name, "run-mode")) {
920 params = pygimp_param_from_tuple(args, self->params + 1,
921 self->nparams - 1);
922
923 if (params == NULL)
924 return NULL;
925
926 params[0].type = self->params[0].type;
927 params[0].data.d_int32 = run_mode;
928
929 #if PG_DEBUG > 1
930 pygimp_param_print(self->nparams, params);
931 #endif
932
933 ret = gimp_run_procedure2(self->name, &nret, self->nparams, params);
934 } else {
935 params = pygimp_param_from_tuple(args, self->params, self->nparams);
936
937 if (params == NULL)
938 return NULL;
939
940 #if PG_DEBUG > 1
941 pygimp_param_print(self->nparams, params+1);
942 #endif
943
944 ret = gimp_run_procedure2(self->name, &nret, self->nparams, params + 1);
945 }
946
947 gimp_destroy_params(params, self->nparams);
948
949 if (!ret) {
950 PyErr_SetString(pygimp_error, "no status returned");
951 #if PG_DEBUG >= 1
952 g_printerr("ret == NULL\n");
953 #endif
954 return NULL;
955 }
956
957 switch(ret[0].data.d_status) {
958 case GIMP_PDB_SUCCESS:
959 #if PG_DEBUG > 0
960 g_printerr("success\n");
961 #endif
962 t = pygimp_param_to_tuple(nret-1, ret+1);
963 gimp_destroy_params(ret, nret);
964
965 if (t == NULL) {
966 PyErr_SetString(pygimp_error, "could not make return value");
967 return NULL;
968 }
969 break;
970
971 case GIMP_PDB_EXECUTION_ERROR:
972 #if PG_DEBUG > 0
973 g_printerr("execution error\n");
974 #endif
975 PyErr_SetString(PyExc_RuntimeError, gimp_get_pdb_error());
976 gimp_destroy_params(ret, nret);
977 return NULL;
978
979 case GIMP_PDB_CALLING_ERROR:
980 #if PG_DEBUG > 0
981 g_printerr("calling error\n");
982 #endif
983 PyErr_SetString(PyExc_RuntimeError, gimp_get_pdb_error());
984 gimp_destroy_params(ret, nret);
985 return NULL;
986
987 case GIMP_PDB_CANCEL:
988 #if PG_DEBUG > 0
989 g_printerr("cancel\n");
990 #endif
991 PyErr_SetString(PyExc_RuntimeError, gimp_get_pdb_error());
992 gimp_destroy_params(ret, nret);
993 return NULL;
994
995 default:
996 #if PG_DEBUG > 0
997 g_printerr("unknown - %i (type %i)\n",
998 ret[0].data.d_status, ret[0].type);
999 #endif
1000 PyErr_SetString(pygimp_error, "unknown return code");
1001 return NULL;
1002 }
1003
1004 if (PyTuple_Size(t) == 1) {
1005 r = PyTuple_GetItem(t, 0);
1006 Py_INCREF(r);
1007 Py_DECREF(t);
1008 return r;
1009 }
1010
1011 if (PyTuple_Size(t) == 0) {
1012 r = Py_None;
1013 Py_INCREF(r);
1014 Py_DECREF(t);
1015 return r;
1016 }
1017
1018 return t;
1019 }
1020
1021
1022 PyTypeObject PyGimpPDBFunction_Type = {
1023 PyObject_HEAD_INIT(NULL)
1024 0, /* ob_size */
1025 "gimp.PDBFunction", /* tp_name */
1026 sizeof(PyGimpPDBFunction), /* tp_basicsize */
1027 0, /* tp_itemsize */
1028 /* methods */
1029 (destructor)pf_dealloc, /* tp_dealloc */
1030 (printfunc)0, /* tp_print */
1031 (getattrfunc)0, /* tp_getattr */
1032 (setattrfunc)0, /* tp_setattr */
1033 (cmpfunc)0, /* tp_compare */
1034 (reprfunc)pf_repr, /* tp_repr */
1035 0, /* tp_as_number */
1036 0, /* tp_as_sequence */
1037 0, /* tp_as_mapping */
1038 (hashfunc)0, /* tp_hash */
1039 (ternaryfunc)pf_call, /* tp_call */
1040 (reprfunc)0, /* tp_str */
1041 (getattrofunc)0, /* tp_getattro */
1042 (setattrofunc)0, /* tp_setattro */
1043 0, /* tp_as_buffer */
1044 Py_TPFLAGS_DEFAULT, /* tp_flags */
1045 NULL, /* Documentation string */
1046 (traverseproc)0, /* tp_traverse */
1047 (inquiry)0, /* tp_clear */
1048 (richcmpfunc)0, /* tp_richcompare */
1049 0, /* tp_weaklistoffset */
1050 (getiterfunc)0, /* tp_iter */
1051 (iternextfunc)0, /* tp_iternext */
1052 0, /* tp_methods */
1053 pf_members, /* tp_members */
1054 0, /* tp_getset */
1055 (PyTypeObject *)0, /* tp_base */
1056 (PyObject *)0, /* tp_dict */
1057 0, /* tp_descr_get */
1058 0, /* tp_descr_set */
1059 0, /* tp_dictoffset */
1060 (initproc)0, /* tp_init */
1061 (allocfunc)0, /* tp_alloc */
1062 (newfunc)0, /* tp_new */
1063 };
1064
1065 PyObject *
pygimp_pdb_function_new(const char * name,const char * blurb,const char * help,const char * author,const char * copyright,const char * date,GimpPDBProcType proc_type,int n_params,int n_return_vals,GimpParamDef * params,GimpParamDef * return_vals)1066 pygimp_pdb_function_new(const char *name, const char *blurb, const char *help,
1067 const char *author, const char *copyright,
1068 const char *date, GimpPDBProcType proc_type,
1069 int n_params, int n_return_vals,
1070 GimpParamDef *params, GimpParamDef *return_vals)
1071 {
1072 PyGimpPDBFunction *self;
1073 int i;
1074
1075 self = PyObject_NEW(PyGimpPDBFunction, &PyGimpPDBFunction_Type);
1076
1077 if (self == NULL)
1078 return NULL;
1079
1080 self->name = g_strdup(name);
1081 self->proc_name = PyString_FromString(name ? name : "");
1082 self->proc_blurb = PyString_FromString(blurb ? blurb : "");
1083 self->proc_help = PyString_FromString(help ? help : "");
1084 self->proc_author = PyString_FromString(author ? author : "");
1085 self->proc_copyright = PyString_FromString(copyright ? copyright : "");
1086 self->proc_date = PyString_FromString(date ? date : "");
1087 self->proc_type = PyInt_FromLong(proc_type);
1088 self->nparams = n_params;
1089 self->nreturn_vals = n_return_vals;
1090 self->params = params;
1091 self->return_vals = return_vals;
1092
1093 self->py_params = PyTuple_New(n_params);
1094 for (i = 0; i < n_params; i++)
1095 PyTuple_SetItem(self->py_params, i,
1096 Py_BuildValue("(iss)",
1097 params[i].type,
1098 params[i].name,
1099 params[i].description));
1100
1101 self->py_return_vals = PyTuple_New(n_return_vals);
1102 for (i = 0; i < n_return_vals; i++)
1103 PyTuple_SetItem(self->py_return_vals, i,
1104 Py_BuildValue("(iss)",
1105 return_vals[i].type,
1106 return_vals[i].name,
1107 return_vals[i].description));
1108
1109 return (PyObject *)self;
1110 }
1111