1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup pythonintern
*
* This file extends RNA types from `bpy.types` with C/Python API methods and attributes.
*
* We should avoid adding code here, and prefer:
* - `source/blender/makesrna/intern/rna_context.c` using the RNA C API.
* - `release/scripts/modules/bpy_types.py` when additions c an be written in Python.
*
* Otherwise functions can be added here as a last resort.
*/
#include <Python.h>
#include <descrobject.h>
#include "RNA_types.h"
#include "BLI_utildefines.h"
#include "bpy_library.h"
#include "bpy_rna.h"
#include "bpy_rna_callback.h"
#include "bpy_rna_context.h"
#include "bpy_rna_data.h"
#include "bpy_rna_id_collection.h"
#include "bpy_rna_text.h"
#include "bpy_rna_types_capi.h"
#include "bpy_rna_ui.h"
#include "bpy_rna_operator.h"
#include "../generic/py_capi_utils.h"
#include "RNA_access.h"
#include "RNA_prototypes.h"
#include "MEM_guardedalloc.h"
#include "WM_api.h"
/* -------------------------------------------------------------------- */
/** \name Blend Data
* \{ */
static struct PyMethodDef pyrna_blenddata_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_user_map_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_batch_remove_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_orphans_purge_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_rna_data_context_method_def */
{NULL, NULL, 0, NULL},
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Blend Data Libraries
* \{ */
static struct PyMethodDef pyrna_blenddatalibraries_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_library_load_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_library_write_method_def */
{NULL, NULL, 0, NULL},
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name UI Layout
* \{ */
static struct PyMethodDef pyrna_uilayout_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_rna_uilayout_introspect_method_def */
{NULL, NULL, 0, NULL},
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Operator
* \{ */
static struct PyMethodDef pyrna_operator_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_rna_operator_poll_message_set */
{NULL, NULL, 0, NULL},
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Text Editor
* \{ */
static struct PyMethodDef pyrna_text_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_rna_region_as_string_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_rna_region_from_string_method_def */
{NULL, NULL, 0, NULL},
};
/* -------------------------------------------------------------------- */
/** \name Window Manager Clipboard Property
*
* Avoid using the RNA API because this value may change between checking its length
* and creating the buffer, causing writes past the allocated length.
* \{ */
static PyObject *pyrna_WindowManager_clipboard_get(PyObject *UNUSED(self), void *UNUSED(flag))
{
int text_len = 0;
char *text = WM_clipboard_text_get(false, &text_len);
PyObject *result = PyC_UnicodeFromByteAndSize(text ? text : "", text_len);
if (text != NULL) {
MEM_freeN(text);
}
return result;
}
static int pyrna_WindowManager_clipboard_set(PyObject *UNUSED(self),
PyObject *value,
void *UNUSED(flag))
{
PyObject *value_coerce = NULL;
const char *text = PyC_UnicodeAsByte(value, &value_coerce);
if (text == NULL) {
return -1;
}
WM_clipboard_text_set(text, false);
Py_XDECREF(value_coerce);
return 0;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Window Manager Type
* \{ */
static struct PyMethodDef pyrna_windowmanager_methods[] = {
{"draw_cursor_add",
(PyCFunction)pyrna_callback_classmethod_add,
METH_VARARGS | METH_CLASS,
""},
{"draw_cursor_remove",
(PyCFunction)pyrna_callback_classmethod_remove,
METH_VARARGS | METH_CLASS,
""},
{NULL, NULL, 0, NULL},
};
static struct PyGetSetDef pyrna_windowmanager_getset[] = {
{"clipboard",
pyrna_WindowManager_clipboard_get,
pyrna_WindowManager_clipboard_set,
NULL,
NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Context Type
* \{ */
static struct PyMethodDef pyrna_context_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_rna_context_temp_override_method_def */
{NULL, NULL, 0, NULL},
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Space Type
* \{ */
PyDoc_STRVAR(
pyrna_draw_handler_add_doc,
".. method:: draw_handler_add(callback, args, region_type, draw_type)\n"
"\n"
" Add a new draw handler to this space type.\n"
" It will be called every time the specified region in the space type will be drawn.\n"
" Note: All arguments are positional only for now.\n"
"\n"
" :param callback:\n"
" A function that will be called when the region is drawn.\n"
" It gets the specified arguments as input.\n"
" :type callback: function\n"
" :param args: Arguments that will be passed to the callback.\n"
" :type args: tuple\n"
" :param region_type: The region type the callback draws in; usually ``WINDOW``. "
"(:class:`bpy.types.Region.type`)\n"
" :type region_type: str\n"
" :param draw_type: Usually ``POST_PIXEL`` for 2D drawing and ``POST_VIEW`` for 3D drawing. "
"In some cases ``PRE_VIEW`` can be used. ``BACKDROP`` can be used for backdrops in the node "
"editor.\n"
" :type draw_type: str\n"
" :return: Handler that can be removed later on.\n"
" :rtype: object");
PyDoc_STRVAR(pyrna_draw_handler_remove_doc,
".. method:: draw_handler_remove(handler, region_type)\n"
"\n"
" Remove a draw handler that was added previously.\n"
"\n"
" :param handler: The draw handler that should be removed.\n"
" :type handler: object\n"
" :param region_type: Region type the callback was added to.\n"
" :type region_type: str\n");
static struct PyMethodDef pyrna_space_methods[] = {
{"draw_handler_add",
(PyCFunction)pyrna_callback_classmethod_add,
METH_VARARGS | METH_CLASS,
pyrna_draw_handler_add_doc},
{"draw_handler_remove",
(PyCFunction)pyrna_callback_classmethod_remove,
METH_VARARGS | METH_CLASS,
pyrna_draw_handler_remove_doc},
{NULL, NULL, 0, NULL},
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public API
* \{ */
void BPY_rna_types_extend_capi(void)
{
/* BlendData */
ARRAY_SET_ITEMS(pyrna_blenddata_methods,
BPY_rna_id_collection_user_map_method_def,
BPY_rna_id_collection_batch_remove_method_def,
BPY_rna_id_collection_orphans_purge_method_def,
BPY_rna_data_context_method_def);
BLI_assert(ARRAY_SIZE(pyrna_blenddata_methods) == 5);
pyrna_struct_type_extend_capi(&RNA_BlendData, pyrna_blenddata_methods, NULL);
/* BlendDataLibraries */
ARRAY_SET_ITEMS(
pyrna_blenddatalibraries_methods, BPY_library_load_method_def, BPY_library_write_method_def);
BLI_assert(ARRAY_SIZE(pyrna_blenddatalibraries_methods) == 3);
pyrna_struct_type_extend_capi(&RNA_BlendDataLibraries, pyrna_blenddatalibraries_methods, NULL);
/* uiLayout */
ARRAY_SET_ITEMS(pyrna_uilayout_methods, BPY_rna_uilayout_introspect_method_def);
BLI_assert(ARRAY_SIZE(pyrna_uilayout_methods) == 2);
pyrna_struct_type_extend_capi(&RNA_UILayout, pyrna_uilayout_methods, NULL);
/* Space */
pyrna_struct_type_extend_capi(&RNA_Space, pyrna_space_methods, NULL);
/* Text Editor */
ARRAY_SET_ITEMS(pyrna_text_methods,
BPY_rna_region_as_string_method_def,
BPY_rna_region_from_string_method_def);
BLI_assert(ARRAY_SIZE(pyrna_text_methods) == 3);
pyrna_struct_type_extend_capi(&RNA_Text, pyrna_text_methods, NULL);
/* wmOperator */
ARRAY_SET_ITEMS(pyrna_operator_methods, BPY_rna_operator_poll_message_set_method_def);
BLI_assert(ARRAY_SIZE(pyrna_operator_methods) == 2);
pyrna_struct_type_extend_capi(&RNA_Operator, pyrna_operator_methods, NULL);
/* WindowManager */
pyrna_struct_type_extend_capi(
&RNA_WindowManager, pyrna_windowmanager_methods, pyrna_windowmanager_getset);
/* Context */
bpy_rna_context_types_init();
ARRAY_SET_ITEMS(pyrna_context_methods, BPY_rna_context_temp_override_method_def);
pyrna_struct_type_extend_capi(&RNA_Context, pyrna_context_methods, NULL);
}
/** \} */
|