39494678a125fbdf753acfc054adbb422fe7d105
[blender-staging.git] / source / blender / python / intern / bpy_app.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 #include "bpy_app.h"
26
27 #include "BLI_path_util.h"
28
29 #include "BKE_utildefines.h"
30 #include "BKE_blender.h"
31 #include "BKE_global.h"
32 #include "structseq.h"
33
34 #include "../generic/py_capi_utils.h"
35
36 #ifdef BUILD_DATE
37 extern char build_date[];
38 extern char build_time[];
39 extern char build_rev[];
40 extern char build_platform[];
41 extern char build_type[];
42 extern char build_cflags[];
43 extern char build_cxxflags[];
44 extern char build_linkflags[];
45 #endif
46
47 static PyTypeObject BlenderAppType;
48
49 static PyStructSequence_Field app_info_fields[] = {
50         {"version", "The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)"},
51         {"version_string", "The Blender version formatted as a string"},
52         {"binary_path", "The location of blenders executable, useful for utilities that spawn new instances"},
53         {"background", "Boolean, True when blender is running without a user interface (started with -b)"},
54
55         /* buildinfo */
56         {"build_date", "The date this blender instance was built"},
57         {"build_time", "The time this blender instance was built"},
58         {"build_revision", "The subversion revision this blender instance was built with"},
59         {"build_platform", "The platform this blender instance was built for"},
60         {"build_type", "The type of build (Release, Debug)"},
61         {"build_cflags", ""},
62         {"build_cxxflags", ""},
63         {"build_linkflags", ""},
64         {0}
65 };
66
67 static PyStructSequence_Desc app_info_desc = {
68         "bpy.app",     /* name */
69         "This module contains application values that remain unchanged during runtime.",    /* doc */
70         app_info_fields,    /* fields */
71         (sizeof(app_info_fields)/sizeof(PyStructSequence_Field)) - 1
72 };
73
74 static PyObject *make_app_info(void)
75 {
76         extern char bprogname[]; /* argv[0] from creator.c */
77
78         PyObject *app_info;
79         int pos = 0;
80
81         app_info = PyStructSequence_New(&BlenderAppType);
82         if (app_info == NULL) {
83                 return NULL;
84         }
85
86 #define SetIntItem(flag) \
87         PyStructSequence_SET_ITEM(app_info, pos++, PyLong_FromLong(flag))
88 #define SetStrItem(str) \
89         PyStructSequence_SET_ITEM(app_info, pos++, PyUnicode_FromString(str))
90 #define SetObjItem(obj) \
91         PyStructSequence_SET_ITEM(app_info, pos++, obj)
92
93         SetObjItem(Py_BuildValue("(iii)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
94         SetObjItem(PyUnicode_FromFormat("%d.%02d (sub %d)", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION));
95         SetStrItem(bprogname);
96         SetObjItem(PyBool_FromLong(G.background));
97
98         /* build info */
99 #ifdef BUILD_DATE
100         SetStrItem(build_date);
101         SetStrItem(build_time);
102         SetStrItem(build_rev);
103         SetStrItem(build_platform);
104         SetStrItem(build_type);
105         SetStrItem(build_cflags);
106         SetStrItem(build_cxxflags);
107         SetStrItem(build_linkflags);
108 #else
109         SetStrItem("Unknown");
110         SetStrItem("Unknown");
111         SetStrItem("Unknown");
112         SetStrItem("Unknown");
113         SetStrItem("Unknown");
114         SetStrItem("Unknown");
115         SetStrItem("Unknown");
116         SetStrItem("Unknown");
117 #endif
118
119 #undef SetIntItem
120 #undef SetStrItem
121 #undef SetObjItem
122
123         if (PyErr_Occurred()) {
124                 Py_CLEAR(app_info);
125                 return NULL;
126         }
127         return app_info;
128 }
129
130 /* a few getsets because it makes sense for them to be in bpy.app even though
131  * they are not static */
132 static PyObject *bpy_app_debug_get(PyObject *UNUSED(self), void *UNUSED(closure))
133 {
134         return PyBool_FromLong(G.f & G_DEBUG);
135 }
136
137 static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure))
138 {
139         int param= PyObject_IsTrue(value);
140
141         if(param < 0) {
142                 PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
143                 return -1;
144         }
145         
146         if(param)       G.f |=  G_DEBUG;
147         else            G.f &= ~G_DEBUG;
148         
149         return 0;
150 }
151
152 static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure))
153 {
154         extern char btempdir[];
155         return PyC_UnicodeFromByte(btempdir);
156 }
157
158 PyGetSetDef bpy_app_debug_getset= {"debug", bpy_app_debug_get, bpy_app_debug_set, "Boolean, set when blender is running in debug mode (started with -d)", NULL};
159 PyGetSetDef bpy_app_tempdir_getset= {"tempdir", bpy_app_tempdir_get, NULL, "String, the temp directory used by blender (read-only)", NULL};
160
161 static void py_struct_seq_getset_init(void)
162 {
163         /* tricky dynamic members, not to py-spec! */
164         
165         PyDict_SetItemString(BlenderAppType.tp_dict, bpy_app_debug_getset.name, PyDescr_NewGetSet(&BlenderAppType, &bpy_app_debug_getset));
166         PyDict_SetItemString(BlenderAppType.tp_dict, bpy_app_tempdir_getset.name, PyDescr_NewGetSet(&BlenderAppType, &bpy_app_tempdir_getset));
167 }
168 /* end dynamic bpy.app */
169
170
171 PyObject *BPY_app_struct(void)
172 {
173         PyObject *ret;
174         
175         PyStructSequence_InitType(&BlenderAppType, &app_info_desc);
176
177         ret= make_app_info();
178
179         /* prevent user from creating new instances */
180         BlenderAppType.tp_init = NULL;
181         BlenderAppType.tp_new = NULL;
182
183         /* kindof a hack ontop of PyStructSequence */
184         py_struct_seq_getset_init();
185
186         return ret;
187 }
188