a49a534c61fb14236a864bb369abbdd01b9d83c5
[blender-staging.git] / source / blender / python / intern / bpy_rna_callback.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25
26 #include "bpy_rna.h"
27 #include "bpy_util.h"
28
29 #include "DNA_screen_types.h"
30 #include "BKE_context.h"
31 #include "ED_space_api.h"
32
33 /* use this to stop other capsules from being mis-used */
34 #define RNA_CAPSULE_ID "RNA_HANDLE"
35 #define RNA_CAPSULE_ID_INVALID "RNA_HANDLE_REMOVED"
36
37 void cb_region_draw(const bContext *C, ARegion *ar, void *customdata)
38 {
39         PyObject *cb_func, *cb_args, *result;
40         PyGILState_STATE gilstate;
41
42         bpy_context_set((bContext *)C, &gilstate);
43
44         cb_func= PyTuple_GET_ITEM((PyObject *)customdata, 0);
45         cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
46         result = PyObject_CallObject(cb_func, cb_args);
47
48         if(result) {
49                 Py_DECREF(result);
50         }
51         else {
52                 PyErr_Print();
53                 PyErr_Clear();
54         }
55
56         bpy_context_clear((bContext *)C, &gilstate);
57 }
58
59 PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
60 {
61         void *handle;
62
63         PyObject *cb_func, *cb_args;
64         char *cb_event_str= NULL;
65         int cb_event;
66
67         if (!PyArg_ParseTuple(args, "OO|s:bpy_struct.callback_add", &cb_func, &cb_args, &cb_event_str))
68                 return NULL;
69
70         if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
71
72                 static EnumPropertyItem region_draw_mode_items[] = {
73                         {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""},
74                         {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
75                         {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
76                         {0, NULL, 0, NULL, NULL}};
77
78                 if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
79                         return NULL;
80
81                 handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event);
82                 Py_INCREF(args);
83         }
84         else {
85                 PyErr_SetString(PyExc_TypeError, "callback_add(): type does not suppport callbacks");
86                 return NULL;
87         }
88
89         return PyCapsule_New((void *)handle, RNA_CAPSULE_ID, NULL);
90 }
91
92 PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
93 {
94         PyObject *py_handle;
95         void *handle;
96         void *customdata;
97
98         if (!PyArg_ParseTuple(args, "O!:callback_remove", &PyCapsule_Type, &py_handle))
99                 return NULL;
100
101         handle= PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
102
103         if(handle==NULL) {
104                 PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed.");
105                 return NULL;
106         }
107
108         if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
109                 customdata= ED_region_draw_cb_customdata(handle);
110                 Py_DECREF((PyObject *)customdata);
111
112                 ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
113         }
114
115         /* dont allow reuse */
116         PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
117
118         Py_RETURN_NONE;
119 }