Blender  V2.59
bpy_rna_callback.c
Go to the documentation of this file.
00001 /*
00002  * $Id: bpy_rna_callback.c 35624 2011-03-19 11:12:48Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * Contributor(s): Campbell Barton
00021  *
00022  * ***** END GPL LICENSE BLOCK *****
00023  */
00024 
00030 #include <Python.h>
00031 
00032 #include "RNA_types.h"
00033 
00034 #include "bpy_rna.h"
00035 #include "bpy_rna_callback.h"
00036 #include "bpy_util.h"
00037 
00038 #include "BLI_utildefines.h"
00039 
00040 #include "DNA_screen_types.h"
00041 
00042 #include "RNA_access.h"
00043 
00044 #include "BKE_context.h"
00045 #include "ED_space_api.h"
00046 
00047 /* use this to stop other capsules from being mis-used */
00048 #define RNA_CAPSULE_ID "RNA_HANDLE"
00049 #define RNA_CAPSULE_ID_INVALID "RNA_HANDLE_REMOVED"
00050 
00051 static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customdata)
00052 {
00053         PyObject *cb_func, *cb_args, *result;
00054         PyGILState_STATE gilstate;
00055 
00056         bpy_context_set((bContext *)C, &gilstate);
00057 
00058         cb_func= PyTuple_GET_ITEM((PyObject *)customdata, 0);
00059         cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
00060         result= PyObject_CallObject(cb_func, cb_args);
00061 
00062         if(result) {
00063                 Py_DECREF(result);
00064         }
00065         else {
00066                 PyErr_Print();
00067                 PyErr_Clear();
00068         }
00069 
00070         bpy_context_clear((bContext *)C, &gilstate);
00071 }
00072 
00073 PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
00074 {
00075         void *handle;
00076 
00077         PyObject *cb_func, *cb_args;
00078         char *cb_event_str= NULL;
00079         int cb_event;
00080 
00081         if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str))
00082                 return NULL;
00083         
00084         if(!PyCallable_Check(cb_func)) {
00085                 PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable");
00086                 return NULL;
00087         }
00088 
00089         if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
00090                 if(cb_event_str) {
00091                         static EnumPropertyItem region_draw_mode_items[]= {
00092                                 {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
00093                                 {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
00094                                 {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
00095                                 {0, NULL, 0, NULL, NULL}};
00096         
00097                         if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
00098                                 return NULL;
00099                 }
00100                 else {
00101                         cb_event= REGION_DRAW_POST_PIXEL;
00102                 }
00103 
00104                 handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event);
00105                 Py_INCREF(args);
00106         }
00107         else {
00108                 PyErr_SetString(PyExc_TypeError, "callback_add(): type does not suppport callbacks");
00109                 return NULL;
00110         }
00111 
00112         return PyCapsule_New((void *)handle, RNA_CAPSULE_ID, NULL);
00113 }
00114 
00115 PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
00116 {
00117         PyObject *py_handle;
00118         void *handle;
00119         void *customdata;
00120 
00121         if (!PyArg_ParseTuple(args, "O!:callback_remove", &PyCapsule_Type, &py_handle))
00122                 return NULL;
00123 
00124         handle= PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
00125 
00126         if(handle==NULL) {
00127                 PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed");
00128                 return NULL;
00129         }
00130 
00131         if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
00132                 customdata= ED_region_draw_cb_customdata(handle);
00133                 Py_DECREF((PyObject *)customdata);
00134 
00135                 ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
00136         }
00137 
00138         /* dont allow reuse */
00139         PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
00140 
00141         Py_RETURN_NONE;
00142 }