Include SDL information in system info text.
[blender.git] / source / blender / python / intern / bpy_app_sdl.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Sergey Sharybin, Sybren A. Stuvel
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/intern/bpy_app_sdl.c
24  *  \ingroup pythonintern
25  */
26
27 #include <Python.h>
28 #include "BLI_utildefines.h"
29
30 #include "bpy_app_sdl.h"
31
32 #ifdef WITH_SDL
33 #  include "SDL.h"
34 #  ifdef WITH_SDL_DYNLOAD
35 #    include "sdlew.h"
36 #  endif
37 #endif
38
39 static PyTypeObject BlenderAppSDLType;
40
41 static PyStructSequence_Field app_sdl_info_fields[] = {
42         {(char *)"supported", (char *)("Boolean, True when Blender is built with SDL support")},
43         {(char *)"version", (char *)("The SDL version as a tuple of 3 numbers")},
44         {(char *)"version_string", (char *)("The SDL version formatted as a string")},
45         {(char *)"available", (char *)("Boolean, True when SDL is available. This is False when "
46                                        "either *supported* is False, or *dynload* is True and "
47                                        "Blender cannot find the correct library.")},
48     {NULL}
49 };
50
51 static PyStructSequence_Desc app_sdl_info_desc = {
52         (char *)"bpy.app.sdl",     /* name */
53         (char *)"This module contains information about SDL blender is linked against",    /* doc */
54         app_sdl_info_fields,    /* fields */
55         ARRAY_SIZE(app_sdl_info_fields) - 1
56 };
57
58 static PyObject *make_sdl_info(void)
59 {
60         PyObject *sdl_info;
61         int pos = 0;
62 #ifdef WITH_SDL
63         bool sdl_available = false;
64         SDL_version version = {0, 0, 0};
65 #endif
66
67         sdl_info = PyStructSequence_New(&BlenderAppSDLType);
68         if (sdl_info == NULL) {
69                 return NULL;
70         }
71
72 #define SetStrItem(str) \
73         PyStructSequence_SET_ITEM(sdl_info, pos++, PyUnicode_FromString(str))
74
75 #define SetObjItem(obj) \
76         PyStructSequence_SET_ITEM(sdl_info, pos++, obj)
77
78 #ifdef WITH_SDL
79         SetObjItem(PyBool_FromLong(1));
80
81 # ifdef WITH_SDL_DYNLOAD
82         if (sdlewInit() == SDLEW_SUCCESS) {
83                 SDL_GetVersion(&version);
84                 sdl_available = true;
85         }
86 # else // WITH_SDL_DYNLOAD=OFF
87         sdl_available = true;
88 #  if SDL_MAJOR_VERSION >= 2
89         SDL_GetVersion(&version);
90 #  else
91         SDL_VERSION(&version);
92 #  endif
93 # endif
94
95         SetObjItem(Py_BuildValue("(iii)", version.major, version.minor, version.patch));
96         if (sdl_available) {
97                 SetObjItem(PyUnicode_FromFormat("%d.%d.%d", version.major, version.minor, version.patch));
98         }
99         else {
100                 SetStrItem("Unknown");
101         }
102         SetObjItem(PyBool_FromLong(sdl_available));
103
104 #else // WITH_SDL=OFF
105         SetObjItem(PyBool_FromLong(0));
106         SetObjItem(Py_BuildValue("(iii)", 0, 0, 0));
107         SetStrItem("Unknown");
108         SetObjItem(PyBool_FromLong(0));
109 #endif
110
111         if (PyErr_Occurred()) {
112                 Py_CLEAR(sdl_info);
113                 return NULL;
114         }
115
116 #undef SetStrItem
117 #undef SetObjItem
118
119         return sdl_info;
120 }
121
122 PyObject *BPY_app_sdl_struct(void)
123 {
124         PyObject *ret;
125
126         PyStructSequence_InitType(&BlenderAppSDLType, &app_sdl_info_desc);
127
128         ret = make_sdl_info();
129
130         /* prevent user from creating new instances */
131         BlenderAppSDLType.tp_init = NULL;
132         BlenderAppSDLType.tp_new = NULL;
133         BlenderAppSDLType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
134
135         return ret;
136 }