From 4b9b3d91d63e9ee89391264bdf46b46a278fbc5e Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sat, 7 Jun 2025 18:31:57 -0500 Subject: [PATCH 1/8] Split off declarations of base module to header and exposed everything externally for potential unit tests --- src_c/base.c | 337 ++++++++++++++++++++++----------------------------- src_c/base.h | 215 ++++++++++++++++++++++++++++++++ 2 files changed, 358 insertions(+), 194 deletions(-) create mode 100644 src_c/base.h diff --git a/src_c/base.c b/src_c/base.c index 654e73404a..db0c459e45 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -19,165 +19,114 @@ Pete Shinners pete@shinners.org */ -#define NO_PYGAME_C_API -#define PYGAMEAPI_BASE_INTERNAL - -#include "pygame.h" - -#include -#include "doc/pygame_doc.h" -#include "pgarrinter.h" -#include "pgcompat.h" - -/* This file controls all the initialization of - * the module and the various SDL subsystems - */ - -/*platform specific init stuff*/ - -#ifdef MS_WIN32 /*python gives us MS_WIN32*/ -#define WIN32_LEAN_AND_MEAN -#define VC_EXTRALEAN -#include -extern int -SDL_RegisterApp(const char *, Uint32, void *); -#endif - -#if defined(macintosh) -#if (!defined(__MWERKS__) && !TARGET_API_MAC_CARBON) -QDGlobals pg_qd; -#endif -#endif - -#if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define PAI_MY_ENDIAN '<' -#define PAI_OTHER_ENDIAN '>' -#define BUF_OTHER_ENDIAN '>' -#else -#define PAI_MY_ENDIAN '>' -#define PAI_OTHER_ENDIAN '<' -#define BUF_OTHER_ENDIAN '<' -#endif -#define BUF_MY_ENDIAN '=' - -/* Extended array struct */ -typedef struct pg_capsule_interface_s { - PyArrayInterface inter; - Py_intptr_t imem[1]; -} pgCapsuleInterface; - -/* Py_buffer internal data for an array interface/struct */ -typedef struct pg_view_internals_s { - char format[4]; /* make 4 byte word sized */ - Py_ssize_t imem[1]; -} pgViewInternals; +#include "base.h" /* Custom exceptions */ -static PyObject *pgExc_BufferError = NULL; +PyObject *pgExc_BufferError = NULL; /* Only one instance of the state per process. */ -static PyObject *pg_quit_functions = NULL; -static int pg_is_init = 0; -static int pg_sdl_was_init = 0; +PyObject *pg_quit_functions = NULL; +int pg_is_init = 0; +int pg_sdl_was_init = 0; SDL_Window *pg_default_window = NULL; pgSurfaceObject *pg_default_screen = NULL; -static int pg_env_blend_alpha_SDL2 = 0; +int pg_env_blend_alpha_SDL2 = 0; -static void +void pg_install_parachute(void); -static void +void pg_uninstall_parachute(void); -static void +void pg_atexit_quit(void); -static int +int pgGetArrayStruct(PyObject *, PyObject **, PyArrayInterface **); -static PyObject * +PyObject * pgArrayStruct_AsDict(PyArrayInterface *); -static PyObject * +PyObject * pgBuffer_AsArrayInterface(Py_buffer *); -static PyObject * +PyObject * pgBuffer_AsArrayStruct(Py_buffer *); -static int +int _pg_buffer_is_byteswapped(Py_buffer *); -static void +void pgBuffer_Release(pg_buffer *); -static int +int pgObject_GetBuffer(PyObject *, pg_buffer *, int); -static inline PyObject * +inline PyObject * pgObject_getRectHelper(PyObject *, PyObject *const *, Py_ssize_t, PyObject *, char *); -static int +int pgGetArrayInterface(PyObject **, PyObject *); -static int +int pgArrayStruct_AsBuffer(pg_buffer *, PyObject *, PyArrayInterface *, int); -static int +int _pg_arraystruct_as_buffer(Py_buffer *, PyObject *, PyArrayInterface *, int); -static int +int _pg_arraystruct_to_format(char *, PyArrayInterface *, int); -static int +int pgDict_AsBuffer(pg_buffer *, PyObject *, int); -static int +int _pg_shape_check(PyObject *); -static int +int _pg_typestr_check(PyObject *); -static int +int _pg_strides_check(PyObject *); -static int +int _pg_data_check(PyObject *); -static int +int _pg_is_int_tuple(PyObject *); -static int +int _pg_values_as_buffer(Py_buffer *, int, PyObject *, PyObject *, PyObject *, PyObject *); -static int +int _pg_int_tuple_as_ssize_arr(PyObject *, Py_ssize_t *); -static int +int _pg_typestr_as_format(PyObject *, char *, Py_ssize_t *); -static PyObject * +PyObject * pg_view_get_typestr_obj(Py_buffer *); -static PyObject * +PyObject * pg_view_get_shape_obj(Py_buffer *); -static PyObject * +PyObject * pg_view_get_strides_obj(Py_buffer *); -static PyObject * +PyObject * pg_view_get_data_obj(Py_buffer *); -static char +char _pg_as_arrayinter_typekind(Py_buffer *); -static char +char _pg_as_arrayinter_byteorder(Py_buffer *); -static int +int _pg_as_arrayinter_flags(Py_buffer *); -static pgCapsuleInterface * +pgCapsuleInterface * _pg_new_capsuleinterface(Py_buffer *); -static void +void _pg_capsule_PyMem_Free(PyObject *); -static PyObject * +PyObject * _pg_shape_as_tuple(PyArrayInterface *); -static PyObject * +PyObject * _pg_typekind_as_str(PyArrayInterface *); -static PyObject * +PyObject * _pg_strides_as_tuple(PyArrayInterface *); -static PyObject * +PyObject * _pg_data_as_tuple(PyArrayInterface *); -static PyObject * +PyObject * pg_get_array_interface(PyObject *, PyObject *); -static void +void _pg_release_buffer_array(Py_buffer *); -static void +void _pg_release_buffer_generic(Py_buffer *); -static SDL_Window * +SDL_Window * pg_GetDefaultWindow(void); -static void +void pg_SetDefaultWindow(SDL_Window *); -static pgSurfaceObject * +pgSurfaceObject * pg_GetDefaultWindowSurface(void); -static void +void pg_SetDefaultWindowSurface(pgSurfaceObject *); -static int +int pg_EnvShouldBlendAlphaSDL2(void); /* compare compiled to linked, raise python error on incompatibility */ -static int +int pg_CheckSDLVersions(void) { #if SDL_VERSION_ATLEAST(3, 0, 0) @@ -246,7 +195,7 @@ pg_RegisterQuit(void (*func)(void)) } } -static PyObject * +PyObject * pg_register_quit(PyObject *self, PyObject *value) { if (!pg_quit_functions) { @@ -263,7 +212,7 @@ pg_register_quit(PyObject *self, PyObject *value) } /* init pygame modules, returns 1 if successful, 0 if fail, with PyErr set*/ -static int +int pg_mod_autoinit(const char *modname) { PyObject *module, *funcobj, *temp; @@ -296,7 +245,7 @@ pg_mod_autoinit(const char *modname) } /* try to quit pygame modules, errors silenced */ -static void +void pg_mod_autoquit(const char *modname) { PyObject *module, *funcobj, *temp; @@ -333,7 +282,7 @@ pg_mod_autoquit(const char *modname) Py_XDECREF(funcobj); } -static PyObject * +PyObject * pg_init(PyObject *self, PyObject *_null) { int i = 0, success = 0, fail = 0; @@ -374,7 +323,7 @@ pg_init(PyObject *self, PyObject *_null) return pg_tuple_couple_from_values_int(success, fail); } -static void +void pg_atexit_quit(void) { /* Maybe it is safe to call SDL_quit more than once after an SDL_Init, @@ -387,7 +336,7 @@ pg_atexit_quit(void) } } -static PyObject * +PyObject * pg_get_sdl_version(PyObject *self, PyObject *args, PyObject *kwargs) { int linked = 1; /* Default is linked version. */ @@ -398,7 +347,7 @@ pg_get_sdl_version(PyObject *self, PyObject *args, PyObject *kwargs) SDL_VERSION(&version); #endif - static char *keywords[] = {"linked", NULL}; + char *keywords[] = {"linked", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p", keywords, &linked)) { return NULL; /* Exception already set. */ @@ -417,13 +366,13 @@ pg_get_sdl_version(PyObject *self, PyObject *args, PyObject *kwargs) PG_FIND_VNUM_MICRO(version)); } -static PyObject * +PyObject * pg_get_sdl_byteorder(PyObject *self, PyObject *_null) { return PyLong_FromLong(SDL_BYTEORDER); } -static void +void _pg_quit(void) { Py_ssize_t num, i; @@ -491,21 +440,21 @@ _pg_quit(void) Py_END_ALLOW_THREADS; } -static PyObject * +PyObject * pg_quit(PyObject *self, PyObject *_null) { _pg_quit(); Py_RETURN_NONE; } -static PyObject * +PyObject * pg_base_get_init(PyObject *self, PyObject *_null) { return PyBool_FromLong(pg_is_init); } /* internal C API utility functions */ -static int +int pg_IntFromObj(PyObject *obj, int *val) { if (PyFloat_Check(obj)) { @@ -524,7 +473,7 @@ pg_IntFromObj(PyObject *obj, int *val) return 1; } -static int +int pg_IntFromObjIndex(PyObject *obj, int _index, int *val) { int result = 0; @@ -539,7 +488,7 @@ pg_IntFromObjIndex(PyObject *obj, int _index, int *val) return result; } -static int +int pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) { // First, lets check the size. This returns -1 if invalid and may set an @@ -602,7 +551,7 @@ pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) return 1; } -static int +int pg_FloatFromObj(PyObject *obj, float *val) { if (PyFloat_Check(obj)) { @@ -618,7 +567,7 @@ pg_FloatFromObj(PyObject *obj, float *val) return 1; } -static int +int pg_FloatFromObjIndex(PyObject *obj, int _index, float *val) { int result = 0; @@ -633,7 +582,7 @@ pg_FloatFromObjIndex(PyObject *obj, int _index, float *val) return result; } -static int +int pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) { // First, lets check the size. This returns -1 if invalid and may set an @@ -696,7 +645,7 @@ pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) return 1; } -static inline int +inline int pg_DoubleFromObj(PyObject *obj, double *val) { if (PyFloat_Check(obj)) { @@ -714,7 +663,7 @@ pg_DoubleFromObj(PyObject *obj, double *val) } /*Assumes obj is a Sequence, internal or conscious use only*/ -static inline int +inline int _pg_DoubleFromObjIndex(PyObject *obj, int index, double *val) { int result = 0; @@ -730,7 +679,7 @@ _pg_DoubleFromObjIndex(PyObject *obj, int index, double *val) return result; } -static inline int +inline int pg_TwoDoublesFromObj(PyObject *obj, double *val1, double *val2) { Py_ssize_t length; @@ -781,7 +730,7 @@ pg_TwoDoublesFromObj(PyObject *obj, double *val1, double *val2) return 1; } -static inline int +inline int pg_TwoDoublesFromFastcallArgs(PyObject *const *args, Py_ssize_t nargs, double *val1, double *val2) { @@ -795,7 +744,7 @@ pg_TwoDoublesFromFastcallArgs(PyObject *const *args, Py_ssize_t nargs, return 0; } -static int +int pg_UintFromObj(PyObject *obj, Uint32 *val) { if (PyNumber_Check(obj)) { @@ -816,7 +765,7 @@ pg_UintFromObj(PyObject *obj, Uint32 *val) return 0; } -static int +int pg_UintFromObjIndex(PyObject *obj, int _index, Uint32 *val) { int result = 0; @@ -832,7 +781,7 @@ pg_UintFromObjIndex(PyObject *obj, int _index, Uint32 *val) } /* You probably want to use the pg_RGBAFromObjEx function instead of this. */ -static int +int pg_RGBAFromObj(PyObject *obj, Uint8 *RGBA) { Py_ssize_t length; @@ -872,13 +821,13 @@ pg_RGBAFromObj(PyObject *obj, Uint8 *RGBA) return 1; } -static PyObject * +PyObject * pg_get_error(PyObject *self, PyObject *_null) { return PyUnicode_FromString(SDL_GetError()); } -static PyObject * +PyObject * pg_set_error(PyObject *s, PyObject *args) { char *errstring = NULL; @@ -900,7 +849,7 @@ pg_set_error(PyObject *s, PyObject *args) /*array interface*/ -static int +int pgGetArrayStruct(PyObject *obj, PyObject **cobj_p, PyArrayInterface **inter_p) { PyObject *cobj = PyObject_GetAttrString(obj, "__array_struct__"); @@ -929,7 +878,7 @@ pgGetArrayStruct(PyObject *obj, PyObject **cobj_p, PyArrayInterface **inter_p) return 0; } -static PyObject * +PyObject * pgArrayStruct_AsDict(PyArrayInterface *inter_p) { PyObject *dictobj = Py_BuildValue("{sisNsNsNsN}", "version", (int)3, @@ -957,7 +906,7 @@ pgArrayStruct_AsDict(PyArrayInterface *inter_p) return dictobj; } -static PyObject * +PyObject * pgBuffer_AsArrayInterface(Py_buffer *view_p) { return Py_BuildValue("{sisNsNsNsN}", "version", (int)3, "typestr", @@ -967,7 +916,7 @@ pgBuffer_AsArrayInterface(Py_buffer *view_p) pg_view_get_data_obj(view_p)); } -static PyObject * +PyObject * pgBuffer_AsArrayStruct(Py_buffer *view_p) { void *cinter_p = _pg_new_capsuleinterface(view_p); @@ -984,7 +933,7 @@ pgBuffer_AsArrayStruct(Py_buffer *view_p) return capsule; } -static pgCapsuleInterface * +pgCapsuleInterface * _pg_new_capsuleinterface(Py_buffer *view_p) { int ndim = view_p->ndim; @@ -1021,13 +970,13 @@ _pg_new_capsuleinterface(Py_buffer *view_p) return cinter_p; } -static void +void _pg_capsule_PyMem_Free(PyObject *capsule) { PyMem_Free(PyCapsule_GetPointer(capsule, 0)); } -static int +int _pg_as_arrayinter_flags(Py_buffer *view_p) { int inter_flags = PAI_ALIGNED; /* atomic int types always aligned */ @@ -1045,7 +994,7 @@ _pg_as_arrayinter_flags(Py_buffer *view_p) return inter_flags; } -static PyObject * +PyObject * pg_view_get_typestr_obj(Py_buffer *view) { return PyUnicode_FromFormat("%c%c%i", _pg_as_arrayinter_byteorder(view), @@ -1053,7 +1002,7 @@ pg_view_get_typestr_obj(Py_buffer *view) (int)view->itemsize); } -static PyObject * +PyObject * pg_view_get_shape_obj(Py_buffer *view) { PyObject *shapeobj = PyTuple_New(view->ndim); @@ -1074,7 +1023,7 @@ pg_view_get_shape_obj(Py_buffer *view) return shapeobj; } -static PyObject * +PyObject * pg_view_get_strides_obj(Py_buffer *view) { PyObject *shapeobj = PyTuple_New(view->ndim); @@ -1095,14 +1044,14 @@ pg_view_get_strides_obj(Py_buffer *view) return shapeobj; } -static PyObject * +PyObject * pg_view_get_data_obj(Py_buffer *view) { return Py_BuildValue("NN", PyLong_FromVoidPtr(view->buf), PyBool_FromLong((long)view->readonly)); } -static char +char _pg_as_arrayinter_typekind(Py_buffer *view) { char type = view->format ? view->format[0] : 'B'; @@ -1142,7 +1091,7 @@ _pg_as_arrayinter_typekind(Py_buffer *view) return typekind; } -static char +char _pg_as_arrayinter_byteorder(Py_buffer *view) { char format_0 = view->format ? view->format[0] : 'B'; @@ -1174,7 +1123,7 @@ _pg_as_arrayinter_byteorder(Py_buffer *view) return byteorder; } -static PyObject * +PyObject * _pg_shape_as_tuple(PyArrayInterface *inter_p) { PyObject *shapeobj = PyTuple_New((Py_ssize_t)inter_p->nd); @@ -1195,7 +1144,7 @@ _pg_shape_as_tuple(PyArrayInterface *inter_p) return shapeobj; } -static PyObject * +PyObject * _pg_typekind_as_str(PyArrayInterface *inter_p) { return PyUnicode_FromFormat( @@ -1207,7 +1156,7 @@ _pg_typekind_as_str(PyArrayInterface *inter_p) inter_p->typekind, inter_p->itemsize); } -static PyObject * +PyObject * _pg_strides_as_tuple(PyArrayInterface *inter_p) { PyObject *stridesobj = PyTuple_New((Py_ssize_t)inter_p->nd); @@ -1228,7 +1177,7 @@ _pg_strides_as_tuple(PyArrayInterface *inter_p) return stridesobj; } -static PyObject * +PyObject * _pg_data_as_tuple(PyArrayInterface *inter_p) { long readonly = (inter_p->flags & PAI_WRITEABLE) == 0; @@ -1237,7 +1186,7 @@ _pg_data_as_tuple(PyArrayInterface *inter_p) PyBool_FromLong(readonly)); } -static PyObject * +PyObject * pg_get_array_interface(PyObject *self, PyObject *arg) { PyObject *cobj; @@ -1252,7 +1201,7 @@ pg_get_array_interface(PyObject *self, PyObject *arg) return dictobj; } -static int +int pgObject_GetBuffer(PyObject *obj, pg_buffer *pg_view_p, int flags) { Py_buffer *view_p = (Py_buffer *)pg_view_p; @@ -1385,7 +1334,7 @@ pgObject_GetBuffer(PyObject *obj, pg_buffer *pg_view_p, int flags) return 0; } -static inline PyObject * +inline PyObject * pgObject_getRectHelper(PyObject *rect, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, char *type) { @@ -1411,7 +1360,7 @@ pgObject_getRectHelper(PyObject *rect, PyObject *const *args, Py_ssize_t nargs, return rect; } -static void +void pgBuffer_Release(pg_buffer *pg_view_p) { assert(pg_view_p && pg_view_p->release_buffer); @@ -1423,7 +1372,7 @@ pgBuffer_Release(pg_buffer *pg_view_p) PyErr_Restore(type, value, traceback); } -static void +void _pg_release_buffer_generic(Py_buffer *view_p) { if (view_p->obj) { @@ -1432,7 +1381,7 @@ _pg_release_buffer_generic(Py_buffer *view_p) } } -static void +void _pg_release_buffer_array(Py_buffer *view_p) { /* This is deliberately made safe for use on an uninitialized *view_p */ @@ -1443,14 +1392,14 @@ _pg_release_buffer_array(Py_buffer *view_p) _pg_release_buffer_generic(view_p); } -static int +int _pg_buffer_is_byteswapped(Py_buffer *view) { if (view->format) { switch (view->format[0]) { case '<': #if SDL_BYTEORDER == SDL_LIL_ENDIAN - /* Use macros to make static analyzer happy */ + /* Use macros to make analyzer happy */ return 0; #else return 1; @@ -1458,7 +1407,7 @@ _pg_buffer_is_byteswapped(Py_buffer *view) case '>': case '!': #if SDL_BYTEORDER == SDL_BIG_ENDIAN - /* Use macros to make static analyzer happy */ + /* Use macros to make analyzer happy */ return 0; #else return 1; @@ -1468,7 +1417,7 @@ _pg_buffer_is_byteswapped(Py_buffer *view) return 0; } -static int +int pgGetArrayInterface(PyObject **dict, PyObject *obj) { PyObject *inter = PyObject_GetAttrString(obj, "__array_interface__"); @@ -1491,7 +1440,7 @@ pgGetArrayInterface(PyObject **dict, PyObject *obj) return 0; } -static int +int pgArrayStruct_AsBuffer(pg_buffer *pg_view_p, PyObject *cobj, PyArrayInterface *inter_p, int flags) { @@ -1504,7 +1453,7 @@ pgArrayStruct_AsBuffer(pg_buffer *pg_view_p, PyObject *cobj, return 0; } -static int +int _pg_arraystruct_as_buffer(Py_buffer *view_p, PyObject *cobj, PyArrayInterface *inter_p, int flags) { @@ -1599,7 +1548,7 @@ _pg_arraystruct_as_buffer(Py_buffer *view_p, PyObject *cobj, return 0; } -static int +int _pg_arraystruct_to_format(char *format, PyArrayInterface *inter_p, int max_format_len) { @@ -1724,7 +1673,7 @@ _pg_arraystruct_to_format(char *format, PyArrayInterface *inter_p, return 0; } -static int +int pgDict_AsBuffer(pg_buffer *pg_view_p, PyObject *dict, int flags) { PyObject *shape = PyDict_GetItemString(dict, "shape"); @@ -1753,7 +1702,7 @@ pgDict_AsBuffer(pg_buffer *pg_view_p, PyObject *dict, int flags) return 0; } -static int +int _pg_shape_check(PyObject *op) { if (!op) { @@ -1773,7 +1722,7 @@ _pg_shape_check(PyObject *op) return 0; } -static int +int _pg_typestr_check(PyObject *op) { if (!op) { @@ -1803,7 +1752,7 @@ _pg_typestr_check(PyObject *op) return 0; } -static int +int _pg_data_check(PyObject *op) { PyObject *item; @@ -1830,7 +1779,7 @@ _pg_data_check(PyObject *op) return 0; } -static int +int _pg_strides_check(PyObject *op) { if (op && !_pg_is_int_tuple(op) /* Conditional && */) { @@ -1841,7 +1790,7 @@ _pg_strides_check(PyObject *op) return 0; } -static int +int _pg_is_int_tuple(PyObject *op) { Py_ssize_t i; @@ -1861,7 +1810,7 @@ _pg_is_int_tuple(PyObject *op) return 1; } -static int +int _pg_values_as_buffer(Py_buffer *view_p, int flags, PyObject *typestr, PyObject *shape, PyObject *data, PyObject *strides) { @@ -1976,7 +1925,7 @@ _pg_values_as_buffer(Py_buffer *view_p, int flags, PyObject *typestr, return 0; } -static int +int _pg_int_tuple_as_ssize_arr(PyObject *tp, Py_ssize_t *arr) { Py_ssize_t i; @@ -1991,7 +1940,7 @@ _pg_int_tuple_as_ssize_arr(PyObject *tp, Py_ssize_t *arr) return 0; } -static int +int _pg_typestr_as_format(PyObject *sp, char *format, Py_ssize_t *itemsize_p) { const char *typestr; @@ -2167,13 +2116,13 @@ _pg_typestr_as_format(PyObject *sp, char *format, Py_ssize_t *itemsize_p) } /*Default window(display)*/ -static SDL_Window * +SDL_Window * pg_GetDefaultWindow(void) { return pg_default_window; } -static void +void pg_SetDefaultWindow(SDL_Window *win) { /*Allows a window to be replaced by itself*/ @@ -2186,14 +2135,14 @@ pg_SetDefaultWindow(SDL_Window *win) pg_default_window = win; } -static pgSurfaceObject * +pgSurfaceObject * pg_GetDefaultWindowSurface(void) { /* return a borrowed reference*/ return pg_default_screen; } -static void +void pg_SetDefaultWindowSurface(pgSurfaceObject *screen) { /*a screen surface can be replaced with itself*/ @@ -2207,7 +2156,7 @@ pg_SetDefaultWindowSurface(pgSurfaceObject *screen) PG_PixelFormatEnum pg_default_convert_format = 0; -static PG_PixelFormatEnum +PG_PixelFormatEnum pg_GetDefaultConvertFormat(void) { if (pg_default_screen) { @@ -2216,20 +2165,20 @@ pg_GetDefaultConvertFormat(void) return pg_default_convert_format; } -static void +void pg_SetDefaultConvertFormat(PG_PixelFormatEnum format) { pg_default_convert_format = format; } -static int +int pg_EnvShouldBlendAlphaSDL2(void) { return pg_env_blend_alpha_SDL2; } /*error signal handlers(replacing SDL parachute)*/ -static void +void pygame_parachute(int sig) { #ifdef HAVE_SIGNAL_H @@ -2267,7 +2216,7 @@ pygame_parachute(int sig) #endif } -static int fatal_signals[] = { +int fatal_signals[] = { SIGSEGV, #ifdef SIGBUS SIGBUS, @@ -2281,8 +2230,8 @@ static int fatal_signals[] = { 0 /*end of list*/ }; -static int parachute_installed = 0; -static void +int parachute_installed = 0; +void pg_install_parachute(void) { #ifdef HAVE_SIGNAL_H @@ -2306,7 +2255,7 @@ pg_install_parachute(void) return; } -static void +void pg_uninstall_parachute(void) { #ifdef HAVE_SIGNAL_H @@ -2330,7 +2279,7 @@ pg_uninstall_parachute(void) /* bind functions to python */ -static PyMethodDef _base_methods[] = { +PyMethodDef _base_methods[] = { {"init", (PyCFunction)pg_init, METH_NOARGS, DOC_INIT}, {"quit", (PyCFunction)pg_quit, METH_NOARGS, DOC_QUIT}, {"get_init", (PyCFunction)pg_base_get_init, METH_NOARGS, DOC_GETINIT}, @@ -2349,8 +2298,8 @@ static PyMethodDef _base_methods[] = { #if defined(BUILD_STATIC) && defined(NO_PYGAME_C_API) // in case of wasm+dynamic loading it could be a trampoline in the globals // generated at runtime. -// when building static make global accessible symbol directly. -static PyObject *pgExc_SDLError; +// when building make global accessible symbol directly. +PyObject *pgExc_SDLError; #endif MODINIT_DEFINE(base) @@ -2361,17 +2310,17 @@ MODINIT_DEFINE(base) // only pointer via C-api will be used, no need to keep global. PyObject *pgExc_SDLError; #endif - static void *c_api[PYGAMEAPI_BASE_NUMSLOTS]; - - static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, - "base", - "", - -1, - _base_methods, - NULL, - NULL, - NULL, - NULL}; + void *c_api[PYGAMEAPI_BASE_NUMSLOTS]; + + struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, + "base", + "", + -1, + _base_methods, + NULL, + NULL, + NULL, + NULL}; /* import need modules. Do this first so if there is an error the module is not loaded. diff --git a/src_c/base.h b/src_c/base.h new file mode 100644 index 0000000000..ffd37e4781 --- /dev/null +++ b/src_c/base.h @@ -0,0 +1,215 @@ +#ifndef BASE_H +#define BASE_H + +#define NO_PYGAME_C_API +#define PYGAMEAPI_BASE_INTERNAL + +#include "pygame.h" + +#include +#include "doc/pygame_doc.h" +#include "pgarrinter.h" +#include "pgcompat.h" + +/* This file controls all the initialization of + * the module and the various SDL subsystems + */ + +/*platform specific init stuff*/ + +#ifdef MS_WIN32 /*python gives us MS_WIN32*/ +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN +#include +extern int +SDL_RegisterApp(const char *, Uint32, void *); +#endif + +#if defined(macintosh) +#if (!defined(__MWERKS__) && !TARGET_API_MAC_CARBON) +QDGlobals pg_qd; +#endif +#endif + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define PAI_MY_ENDIAN '<' +#define PAI_OTHER_ENDIAN '>' +#define BUF_OTHER_ENDIAN '>' +#else +#define PAI_MY_ENDIAN '>' +#define PAI_OTHER_ENDIAN '<' +#define BUF_OTHER_ENDIAN '<' +#endif +#define BUF_MY_ENDIAN '=' + +/* Extended array struct */ +typedef struct pg_capsule_interface_s { + PyArrayInterface inter; + Py_intptr_t imem[1]; +} pgCapsuleInterface; + +/* Py_buffer internal data for an array interface/struct */ +typedef struct pg_view_internals_s { + char format[4]; /* make 4 byte word sized */ + Py_ssize_t imem[1]; +} pgViewInternals; + +void +pg_install_parachute(void); +void +pg_uninstall_parachute(void); +void +pg_atexit_quit(void); +int +pgGetArrayStruct(PyObject *, PyObject **, PyArrayInterface **); +PyObject * +pgArrayStruct_AsDict(PyArrayInterface *); +PyObject * +pgBuffer_AsArrayInterface(Py_buffer *); +PyObject * +pgBuffer_AsArrayStruct(Py_buffer *); +int +_pg_buffer_is_byteswapped(Py_buffer *); +void +pgBuffer_Release(pg_buffer *); +int +pgObject_GetBuffer(PyObject *, pg_buffer *, int); +extern inline PyObject * +pgObject_getRectHelper(PyObject *, PyObject *const *, Py_ssize_t, PyObject *, + char *); +int +pgGetArrayInterface(PyObject **, PyObject *); +int +pgArrayStruct_AsBuffer(pg_buffer *, PyObject *, PyArrayInterface *, int); +int +_pg_arraystruct_as_buffer(Py_buffer *, PyObject *, PyArrayInterface *, int); +int +_pg_arraystruct_to_format(char *, PyArrayInterface *, int); +int +pgDict_AsBuffer(pg_buffer *, PyObject *, int); +int +_pg_shape_check(PyObject *); +int +_pg_typestr_check(PyObject *); +int +_pg_strides_check(PyObject *); +int +_pg_data_check(PyObject *); +int +_pg_is_int_tuple(PyObject *); +int +_pg_values_as_buffer(Py_buffer *, int, PyObject *, PyObject *, PyObject *, + PyObject *); +int +_pg_int_tuple_as_ssize_arr(PyObject *, Py_ssize_t *); +int +_pg_typestr_as_format(PyObject *, char *, Py_ssize_t *); +PyObject * +pg_view_get_typestr_obj(Py_buffer *); +PyObject * +pg_view_get_shape_obj(Py_buffer *); +PyObject * +pg_view_get_strides_obj(Py_buffer *); +PyObject * +pg_view_get_data_obj(Py_buffer *); +char +_pg_as_arrayinter_typekind(Py_buffer *); +char +_pg_as_arrayinter_byteorder(Py_buffer *); +int +_pg_as_arrayinter_flags(Py_buffer *); +pgCapsuleInterface * +_pg_new_capsuleinterface(Py_buffer *); +void +_pg_capsule_PyMem_Free(PyObject *); +PyObject * +_pg_shape_as_tuple(PyArrayInterface *); +PyObject * +_pg_typekind_as_str(PyArrayInterface *); +PyObject * +_pg_strides_as_tuple(PyArrayInterface *); +PyObject * +_pg_data_as_tuple(PyArrayInterface *); +PyObject * +pg_get_array_interface(PyObject *, PyObject *); +void +_pg_release_buffer_array(Py_buffer *); +void +_pg_release_buffer_generic(Py_buffer *); +SDL_Window * +pg_GetDefaultWindow(void); +void +pg_SetDefaultWindow(SDL_Window *); +pgSurfaceObject * +pg_GetDefaultWindowSurface(void); +void +pg_SetDefaultWindowSurface(pgSurfaceObject *); +int +pg_EnvShouldBlendAlphaSDL2(void); +int +pg_CheckSDLVersions(void); +void +pg_RegisterQuit(void (*func)(void)); +PyObject * +pg_register_quit(PyObject *self, PyObject *value); +int +pg_mod_autoinit(const char *modname); +void +pg_mod_autoquit(const char *modname); +PyObject * +pg_init(PyObject *self, PyObject *_null); +PyObject * +pg_get_sdl_version(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject * +pg_get_sdl_byteorder(PyObject *self, PyObject *_null); +void +_pg_quit(void); +PyObject * +pg_quit(PyObject *self, PyObject *_null); +PyObject * +pg_base_get_init(PyObject *self, PyObject *_null); +/* internal C API utility functions */ +int +pg_IntFromObj(PyObject *obj, int *val); +int +pg_IntFromObjIndex(PyObject *obj, int _index, int *val); +int +pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2); +int +pg_FloatFromObj(PyObject *obj, float *val); +int +pg_FloatFromObjIndex(PyObject *obj, int _index, float *val); +int +pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2); +extern inline int +pg_DoubleFromObj(PyObject *obj, double *val); +/*Assumes obj is a Sequence, internal or conscious use only*/ +extern inline int +_pg_DoubleFromObjIndex(PyObject *obj, int index, double *val); +extern inline int +pg_TwoDoublesFromObj(PyObject *obj, double *val1, double *val2); +extern inline int +pg_TwoDoublesFromFastcallArgs(PyObject *const *args, Py_ssize_t nargs, + double *val1, double *val2); +int +pg_UintFromObj(PyObject *obj, Uint32 *val); +int +pg_UintFromObjIndex(PyObject *obj, int _index, Uint32 *val); +/* You probably want to use the pg_RGBAFromObjEx function instead of this. */ +int +pg_RGBAFromObj(PyObject *obj, Uint8 *RGBA); +PyObject * +pg_get_error(PyObject *self, PyObject *_null); +PyObject * +pg_set_error(PyObject *s, PyObject *args); +/*error signal handlers(replacing SDL parachute)*/ +void +pygame_parachute(int sig); +void +pg_SetDefaultConvertFormat(PG_PixelFormatEnum format); +PG_PixelFormatEnum +pg_GetDefaultConvertFormat(void); + +MODINIT_DEFINE(base); + +#endif // #ifndef BASE_H From e29d1f06298db1429d21e7f5ede6a34153744156 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sat, 7 Jun 2025 19:31:06 -0500 Subject: [PATCH 2/8] Split off base declarations to base.h, and remove static linkage for future unit test purposes --- src_c/base.c | 274 ++++++------------------------------------------- src_c/base.h | 143 +++++++++++++++++++++++++- src_c/static.c | 2 +- 3 files changed, 169 insertions(+), 250 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index db0c459e45..04740d7c9a 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -1,3 +1,4 @@ + /* pygame-ce - Python Game Library Copyright (C) 2000-2001 Pete Shinners @@ -19,111 +20,23 @@ Pete Shinners pete@shinners.org */ +#define NO_PYGAME_C_API +#define PYGAMEAPI_BASE_INTERNAL + #include "base.h" +PG_PixelFormatEnum pg_default_convert_format = 0; + /* Custom exceptions */ -PyObject *pgExc_BufferError = NULL; +static PyObject *pgExc_BufferError = NULL; /* Only one instance of the state per process. */ -PyObject *pg_quit_functions = NULL; -int pg_is_init = 0; -int pg_sdl_was_init = 0; +static PyObject *pg_quit_functions = NULL; +static int pg_is_init = 0; +static int pg_sdl_was_init = 0; SDL_Window *pg_default_window = NULL; pgSurfaceObject *pg_default_screen = NULL; -int pg_env_blend_alpha_SDL2 = 0; - -void -pg_install_parachute(void); -void -pg_uninstall_parachute(void); -void -pg_atexit_quit(void); -int -pgGetArrayStruct(PyObject *, PyObject **, PyArrayInterface **); -PyObject * -pgArrayStruct_AsDict(PyArrayInterface *); -PyObject * -pgBuffer_AsArrayInterface(Py_buffer *); -PyObject * -pgBuffer_AsArrayStruct(Py_buffer *); -int -_pg_buffer_is_byteswapped(Py_buffer *); -void -pgBuffer_Release(pg_buffer *); -int -pgObject_GetBuffer(PyObject *, pg_buffer *, int); -inline PyObject * -pgObject_getRectHelper(PyObject *, PyObject *const *, Py_ssize_t, PyObject *, - char *); -int -pgGetArrayInterface(PyObject **, PyObject *); -int -pgArrayStruct_AsBuffer(pg_buffer *, PyObject *, PyArrayInterface *, int); -int -_pg_arraystruct_as_buffer(Py_buffer *, PyObject *, PyArrayInterface *, int); -int -_pg_arraystruct_to_format(char *, PyArrayInterface *, int); -int -pgDict_AsBuffer(pg_buffer *, PyObject *, int); -int -_pg_shape_check(PyObject *); -int -_pg_typestr_check(PyObject *); -int -_pg_strides_check(PyObject *); -int -_pg_data_check(PyObject *); -int -_pg_is_int_tuple(PyObject *); -int -_pg_values_as_buffer(Py_buffer *, int, PyObject *, PyObject *, PyObject *, - PyObject *); -int -_pg_int_tuple_as_ssize_arr(PyObject *, Py_ssize_t *); -int -_pg_typestr_as_format(PyObject *, char *, Py_ssize_t *); -PyObject * -pg_view_get_typestr_obj(Py_buffer *); -PyObject * -pg_view_get_shape_obj(Py_buffer *); -PyObject * -pg_view_get_strides_obj(Py_buffer *); -PyObject * -pg_view_get_data_obj(Py_buffer *); -char -_pg_as_arrayinter_typekind(Py_buffer *); -char -_pg_as_arrayinter_byteorder(Py_buffer *); -int -_pg_as_arrayinter_flags(Py_buffer *); -pgCapsuleInterface * -_pg_new_capsuleinterface(Py_buffer *); -void -_pg_capsule_PyMem_Free(PyObject *); -PyObject * -_pg_shape_as_tuple(PyArrayInterface *); -PyObject * -_pg_typekind_as_str(PyArrayInterface *); -PyObject * -_pg_strides_as_tuple(PyArrayInterface *); -PyObject * -_pg_data_as_tuple(PyArrayInterface *); -PyObject * -pg_get_array_interface(PyObject *, PyObject *); -void -_pg_release_buffer_array(Py_buffer *); -void -_pg_release_buffer_generic(Py_buffer *); -SDL_Window * -pg_GetDefaultWindow(void); -void -pg_SetDefaultWindow(SDL_Window *); -pgSurfaceObject * -pg_GetDefaultWindowSurface(void); -void -pg_SetDefaultWindowSurface(pgSurfaceObject *); -int -pg_EnvShouldBlendAlphaSDL2(void); +static int pg_env_blend_alpha_SDL2 = 0; /* compare compiled to linked, raise python error on incompatibility */ int @@ -347,7 +260,7 @@ pg_get_sdl_version(PyObject *self, PyObject *args, PyObject *kwargs) SDL_VERSION(&version); #endif - char *keywords[] = {"linked", NULL}; + static char *keywords[] = {"linked", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p", keywords, &linked)) { return NULL; /* Exception already set. */ @@ -645,105 +558,6 @@ pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) return 1; } -inline int -pg_DoubleFromObj(PyObject *obj, double *val) -{ - if (PyFloat_Check(obj)) { - *val = PyFloat_AS_DOUBLE(obj); - return 1; - } - - *val = (double)PyLong_AsLong(obj); - if (PyErr_Occurred()) { - PyErr_Clear(); - return 0; - } - - return 1; -} - -/*Assumes obj is a Sequence, internal or conscious use only*/ -inline int -_pg_DoubleFromObjIndex(PyObject *obj, int index, double *val) -{ - int result = 0; - - PyObject *item = PySequence_ITEM(obj, index); - if (!item) { - PyErr_Clear(); - return 0; - } - result = pg_DoubleFromObj(item, val); - Py_DECREF(item); - - return result; -} - -inline int -pg_TwoDoublesFromObj(PyObject *obj, double *val1, double *val2) -{ - Py_ssize_t length; - /*Faster path for tuples and lists*/ - if (pgSequenceFast_Check(obj)) { - length = PySequence_Fast_GET_SIZE(obj); - PyObject **f_arr = PySequence_Fast_ITEMS(obj); - if (length == 2) { - if (!pg_DoubleFromObj(f_arr[0], val1) || - !pg_DoubleFromObj(f_arr[1], val2)) { - return 0; - } - } - else if (length == 1) { - /* Handle case of ((x, y), ) 'nested sequence' */ - return pg_TwoDoublesFromObj(f_arr[0], val1, val2); - } - else { - return 0; - } - } - else if (PySequence_Check(obj)) { - length = PySequence_Length(obj); - if (length == 2) { - if (!_pg_DoubleFromObjIndex(obj, 0, val1)) { - return 0; - } - if (!_pg_DoubleFromObjIndex(obj, 1, val2)) { - return 0; - } - } - else if (length == 1 && !PyUnicode_Check(obj)) { - /* Handle case of ((x, y), ) 'nested sequence' */ - PyObject *tmp = PySequence_ITEM(obj, 0); - int ret = pg_TwoDoublesFromObj(tmp, val1, val2); - Py_DECREF(tmp); - return ret; - } - else { - PyErr_Clear(); - return 0; - } - } - else { - return 0; - } - - return 1; -} - -inline int -pg_TwoDoublesFromFastcallArgs(PyObject *const *args, Py_ssize_t nargs, - double *val1, double *val2) -{ - if (nargs == 1 && pg_TwoDoublesFromObj(args[0], val1, val2)) { - return 1; - } - else if (nargs == 2 && pg_DoubleFromObj(args[0], val1) && - pg_DoubleFromObj(args[1], val2)) { - return 1; - } - return 0; -} - int pg_UintFromObj(PyObject *obj, Uint32 *val) { @@ -1334,32 +1148,6 @@ pgObject_GetBuffer(PyObject *obj, pg_buffer *pg_view_p, int flags) return 0; } -inline PyObject * -pgObject_getRectHelper(PyObject *rect, PyObject *const *args, Py_ssize_t nargs, - PyObject *kwnames, char *type) -{ - if (nargs > 0) { - Py_DECREF(rect); - return PyErr_Format(PyExc_TypeError, - "get_%s only accepts keyword arguments", type); - } - - if (rect && kwnames) { - Py_ssize_t i, sequence_len; - PyObject **sequence_items; - sequence_items = PySequence_Fast_ITEMS(kwnames); - sequence_len = PyTuple_GET_SIZE(kwnames); - - for (i = 0; i < sequence_len; ++i) { - if ((PyObject_SetAttr(rect, sequence_items[i], args[i]) == -1)) { - Py_DECREF(rect); - return NULL; - } - } - } - return rect; -} - void pgBuffer_Release(pg_buffer *pg_view_p) { @@ -1399,7 +1187,7 @@ _pg_buffer_is_byteswapped(Py_buffer *view) switch (view->format[0]) { case '<': #if SDL_BYTEORDER == SDL_LIL_ENDIAN - /* Use macros to make analyzer happy */ + /* Use macros to make static analyzer happy */ return 0; #else return 1; @@ -1407,7 +1195,7 @@ _pg_buffer_is_byteswapped(Py_buffer *view) case '>': case '!': #if SDL_BYTEORDER == SDL_BIG_ENDIAN - /* Use macros to make analyzer happy */ + /* Use macros to make static analyzer happy */ return 0; #else return 1; @@ -2154,8 +1942,6 @@ pg_SetDefaultWindowSurface(pgSurfaceObject *screen) pg_default_screen = screen; } -PG_PixelFormatEnum pg_default_convert_format = 0; - PG_PixelFormatEnum pg_GetDefaultConvertFormat(void) { @@ -2216,7 +2002,7 @@ pygame_parachute(int sig) #endif } -int fatal_signals[] = { +static int fatal_signals[] = { SIGSEGV, #ifdef SIGBUS SIGBUS, @@ -2230,7 +2016,7 @@ int fatal_signals[] = { 0 /*end of list*/ }; -int parachute_installed = 0; +static int parachute_installed = 0; void pg_install_parachute(void) { @@ -2279,7 +2065,7 @@ pg_uninstall_parachute(void) /* bind functions to python */ -PyMethodDef _base_methods[] = { +static PyMethodDef _base_methods[] = { {"init", (PyCFunction)pg_init, METH_NOARGS, DOC_INIT}, {"quit", (PyCFunction)pg_quit, METH_NOARGS, DOC_QUIT}, {"get_init", (PyCFunction)pg_base_get_init, METH_NOARGS, DOC_GETINIT}, @@ -2298,8 +2084,8 @@ PyMethodDef _base_methods[] = { #if defined(BUILD_STATIC) && defined(NO_PYGAME_C_API) // in case of wasm+dynamic loading it could be a trampoline in the globals // generated at runtime. -// when building make global accessible symbol directly. -PyObject *pgExc_SDLError; +// when building static make global accessible symbol directly. +static PyObject *pgExc_SDLError; #endif MODINIT_DEFINE(base) @@ -2310,17 +2096,17 @@ MODINIT_DEFINE(base) // only pointer via C-api will be used, no need to keep global. PyObject *pgExc_SDLError; #endif - void *c_api[PYGAMEAPI_BASE_NUMSLOTS]; - - struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, - "base", - "", - -1, - _base_methods, - NULL, - NULL, - NULL, - NULL}; + static void *c_api[PYGAMEAPI_BASE_NUMSLOTS]; + + static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, + "base", + "", + -1, + _base_methods, + NULL, + NULL, + NULL, + NULL}; /* import need modules. Do this first so if there is an error the module is not loaded. diff --git a/src_c/base.h b/src_c/base.h index ffd37e4781..fd01631396 100644 --- a/src_c/base.h +++ b/src_c/base.h @@ -54,6 +54,10 @@ typedef struct pg_view_internals_s { Py_ssize_t imem[1]; } pgViewInternals; +extern PG_PixelFormatEnum pg_default_convert_format; +extern SDL_Window *pg_default_window; +extern pgSurfaceObject *pg_default_screen; + void pg_install_parachute(void); void @@ -74,7 +78,7 @@ void pgBuffer_Release(pg_buffer *); int pgObject_GetBuffer(PyObject *, pg_buffer *, int); -extern inline PyObject * +static inline PyObject * pgObject_getRectHelper(PyObject *, PyObject *const *, Py_ssize_t, PyObject *, char *); int @@ -181,14 +185,14 @@ int pg_FloatFromObjIndex(PyObject *obj, int _index, float *val); int pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2); -extern inline int +static inline int pg_DoubleFromObj(PyObject *obj, double *val); /*Assumes obj is a Sequence, internal or conscious use only*/ -extern inline int +static inline int _pg_DoubleFromObjIndex(PyObject *obj, int index, double *val); -extern inline int +static inline int pg_TwoDoublesFromObj(PyObject *obj, double *val1, double *val2); -extern inline int +static inline int pg_TwoDoublesFromFastcallArgs(PyObject *const *args, Py_ssize_t nargs, double *val1, double *val2); int @@ -202,14 +206,143 @@ PyObject * pg_get_error(PyObject *self, PyObject *_null); PyObject * pg_set_error(PyObject *s, PyObject *args); + /*error signal handlers(replacing SDL parachute)*/ void pygame_parachute(int sig); + void pg_SetDefaultConvertFormat(PG_PixelFormatEnum format); + PG_PixelFormatEnum pg_GetDefaultConvertFormat(void); MODINIT_DEFINE(base); +/*=======static inline function definitions=======*/ +static inline PyObject * +pgObject_getRectHelper(PyObject *rect, PyObject *const *args, Py_ssize_t nargs, + PyObject *kwnames, char *type) +{ + if (nargs > 0) { + Py_DECREF(rect); + return PyErr_Format(PyExc_TypeError, + "get_%s only accepts keyword arguments", type); + } + + if (rect && kwnames) { + Py_ssize_t i, sequence_len; + PyObject **sequence_items; + sequence_items = PySequence_Fast_ITEMS(kwnames); + sequence_len = PyTuple_GET_SIZE(kwnames); + + for (i = 0; i < sequence_len; ++i) { + if ((PyObject_SetAttr(rect, sequence_items[i], args[i]) == -1)) { + Py_DECREF(rect); + return NULL; + } + } + } + return rect; +} + +static inline int +pg_DoubleFromObj(PyObject *obj, double *val) +{ + if (PyFloat_Check(obj)) { + *val = PyFloat_AS_DOUBLE(obj); + return 1; + } + + *val = (double)PyLong_AsLong(obj); + if (PyErr_Occurred()) { + PyErr_Clear(); + return 0; + } + + return 1; +} + +/*Assumes obj is a Sequence, internal or conscious use only*/ +static inline int +_pg_DoubleFromObjIndex(PyObject *obj, int index, double *val) +{ + int result = 0; + + PyObject *item = PySequence_ITEM(obj, index); + if (!item) { + PyErr_Clear(); + return 0; + } + result = pg_DoubleFromObj(item, val); + Py_DECREF(item); + + return result; +} + +static inline int +pg_TwoDoublesFromObj(PyObject *obj, double *val1, double *val2) +{ + Py_ssize_t length; + /*Faster path for tuples and lists*/ + if (pgSequenceFast_Check(obj)) { + length = PySequence_Fast_GET_SIZE(obj); + PyObject **f_arr = PySequence_Fast_ITEMS(obj); + if (length == 2) { + if (!pg_DoubleFromObj(f_arr[0], val1) || + !pg_DoubleFromObj(f_arr[1], val2)) { + return 0; + } + } + else if (length == 1) { + /* Handle case of ((x, y), ) 'nested sequence' */ + return pg_TwoDoublesFromObj(f_arr[0], val1, val2); + } + else { + return 0; + } + } + else if (PySequence_Check(obj)) { + length = PySequence_Length(obj); + if (length == 2) { + if (!_pg_DoubleFromObjIndex(obj, 0, val1)) { + return 0; + } + if (!_pg_DoubleFromObjIndex(obj, 1, val2)) { + return 0; + } + } + else if (length == 1 && !PyUnicode_Check(obj)) { + /* Handle case of ((x, y), ) 'nested sequence' */ + PyObject *tmp = PySequence_ITEM(obj, 0); + int ret = pg_TwoDoublesFromObj(tmp, val1, val2); + Py_DECREF(tmp); + return ret; + } + else { + PyErr_Clear(); + return 0; + } + } + else { + return 0; + } + + return 1; +} + +static inline int +pg_TwoDoublesFromFastcallArgs(PyObject *const *args, Py_ssize_t nargs, + double *val1, double *val2) +{ + if (nargs == 1 && pg_TwoDoublesFromObj(args[0], val1, val2)) { + return 1; + } + else if (nargs == 2 && pg_DoubleFromObj(args[0], val1) && + pg_DoubleFromObj(args[1], val2)) { + return 1; + } + return 0; +} + #endif // #ifndef BASE_H diff --git a/src_c/static.c b/src_c/static.c index d40c30189c..ae98c0fc9d 100644 --- a/src_c/static.c +++ b/src_c/static.c @@ -396,7 +396,7 @@ PyInit_pygame_static() #endif // defined(BUILD_STATIC) -#include "base.c" +#include "base.h" #include "rect.c" #include "pgcompat_rect.c" From 612a7bf88e3dbcf330b8eed57b00af26898d7368 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sat, 7 Jun 2025 19:39:07 -0500 Subject: [PATCH 3/8] Should fix WASM build --- src_c/base.c | 9 +-------- src_c/base.h | 8 ++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index 04740d7c9a..f4cf4136c7 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -28,7 +28,7 @@ PG_PixelFormatEnum pg_default_convert_format = 0; /* Custom exceptions */ -static PyObject *pgExc_BufferError = NULL; +PyObject *pgExc_BufferError = NULL; /* Only one instance of the state per process. */ static PyObject *pg_quit_functions = NULL; @@ -2081,13 +2081,6 @@ static PyMethodDef _base_methods[] = { "return an array struct interface as an interface dictionary"}, {NULL, NULL, 0, NULL}}; -#if defined(BUILD_STATIC) && defined(NO_PYGAME_C_API) -// in case of wasm+dynamic loading it could be a trampoline in the globals -// generated at runtime. -// when building static make global accessible symbol directly. -static PyObject *pgExc_SDLError; -#endif - MODINIT_DEFINE(base) { PyObject *module, *apiobj, *atexit; diff --git a/src_c/base.h b/src_c/base.h index fd01631396..8fb0970eac 100644 --- a/src_c/base.h +++ b/src_c/base.h @@ -55,6 +55,7 @@ typedef struct pg_view_internals_s { } pgViewInternals; extern PG_PixelFormatEnum pg_default_convert_format; +extern PyObject *pgExc_BufferError; extern SDL_Window *pg_default_window; extern pgSurfaceObject *pg_default_screen; @@ -217,6 +218,13 @@ pg_SetDefaultConvertFormat(PG_PixelFormatEnum format); PG_PixelFormatEnum pg_GetDefaultConvertFormat(void); +#if defined(BUILD_STATIC) && defined(NO_PYGAME_C_API) +// in case of wasm+dynamic loading it could be a trampoline in the globals +// generated at runtime. +// when building static make global accessible symbol directly. +extern PyObject *pgExc_SDLError; +#endif + MODINIT_DEFINE(base); /*=======static inline function definitions=======*/ From 3fde045da55414cc5f326c60cfca55cdefb05180 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Mon, 9 Jun 2025 20:54:51 -0500 Subject: [PATCH 4/8] Test a static.c change --- src_c/base.c | 1 - src_c/static.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index f4cf4136c7..4a8710c4a7 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -1,4 +1,3 @@ - /* pygame-ce - Python Game Library Copyright (C) 2000-2001 Pete Shinners diff --git a/src_c/static.c b/src_c/static.c index ae98c0fc9d..dc5cd12b46 100644 --- a/src_c/static.c +++ b/src_c/static.c @@ -113,8 +113,6 @@ import_pygame_pixelarray(void) { } -PyMODINIT_FUNC -PyInit_base(void); PyMODINIT_FUNC PyInit_color(void); PyMODINIT_FUNC @@ -324,9 +322,6 @@ PyInit_pygame_static() // for correct input in wasm worker SDL_SetHint("SDL_EMSCRIPTEN_KEYBOARD_ELEMENT", "1"); - load_submodule("pygame", PyInit_base(), "base"); - - // load_submodule("pygame", PyInit_constants(), "constants"); // load_submodule("pygame", PyInit_pg_math(), "math"); From ea2bcb779ea7dd8feff74ccda9ef3ed2302ed007 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sat, 28 Jun 2025 18:52:25 -0500 Subject: [PATCH 5/8] WASM compatibility, courtesy of pmp-p Co-authored-by: pmp-p --- src_c/base.c | 18 ++++++++++++++++++ src_c/include/_pygame.h | 1 + src_c/static.c | 18 +++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src_c/base.c b/src_c/base.c index 9db70a5fc8..d6d764bd01 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -22,6 +22,18 @@ #define NO_PYGAME_C_API #define PYGAMEAPI_BASE_INTERNAL +#if defined(BUILD_STATIC) +#define CONTROLLER_NOPYX +#define PYGAMEAPI_RECT_INTERNAL +#define PYGAMEAPI_EVENT_INTERNAL +#define PYGAMEAPI_JOYSTICK_INTERNAL +#define PYGAMEAPI_BASE_INTERNAL +#define PYGAMEAPI_SURFACE_INTERNAL +#define PYGAMEAPI_BUFFERPROXY_INTERNAL +#define PYGAMEAPI_WINDOW_INTERNAL +#define PYGAMEAPI_RENDER_INTERNAL +#endif + #include "base.h" PG_PixelFormatEnum pg_default_convert_format = 0; @@ -29,6 +41,8 @@ PG_PixelFormatEnum pg_default_convert_format = 0; /* Custom exceptions */ PyObject *pgExc_BufferError = NULL; +PyObject *pgExc_SDLError; + /* Only one instance of the state per process. */ static PyObject *pg_quit_functions = NULL; static int pg_is_init = 0; @@ -2231,3 +2245,7 @@ MODINIT_DEFINE(base) Py_XDECREF(module); return NULL; } + +#if defined(__EMSCRIPTEN__) || defined(__wasi__) +#include "static.c" +#endif diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index c3bcc5ec55..4ae29da25a 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -208,6 +208,7 @@ typedef struct { #define pgRect_AsRect(x) (((pgRectObject *)x)->r) #define pgFRect_AsRect(x) (((pgFRectObject *)x)->r) + #ifndef PYGAMEAPI_RECT_INTERNAL #define pgRect_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(rect, 0)) diff --git a/src_c/static.c b/src_c/static.c index dc5cd12b46..8a01b0d913 100644 --- a/src_c/static.c +++ b/src_c/static.c @@ -11,9 +11,11 @@ #define PYGAMEAPI_WINDOW_INTERNAL #define PYGAMEAPI_RENDER_INTERNAL +#if 0 #define pgSurface_New(surface) (pgSurfaceObject *)pgSurface_New2((surface), 1) #define pgSurface_NewNoOwn(surface) \ (pgSurfaceObject *)pgSurface_New2((surface), 0) +#endif #include "pygame.h" #include "Python.h" @@ -49,6 +51,10 @@ import_pygame_surface(void) { } +#ifdef import_pygame_window +#undef import_pygame_window +#endif + void import_pygame_window(void) { @@ -89,6 +95,10 @@ import_pygame_event(void) { } +#ifdef import_pygame_joystick +#undef import_pygame_joystick +#endif + void import_pygame_joystick(void) { @@ -113,6 +123,8 @@ import_pygame_pixelarray(void) { } +PyMODINIT_FUNC +PyInit_base(void); PyMODINIT_FUNC PyInit_color(void); PyMODINIT_FUNC @@ -322,6 +334,10 @@ PyInit_pygame_static() // for correct input in wasm worker SDL_SetHint("SDL_EMSCRIPTEN_KEYBOARD_ELEMENT", "1"); + // base module is including current file + // all globals are accessible from here. + load_submodule("pygame", PyInit_base(), "base"); + load_submodule("pygame", PyInit_constants(), "constants"); // load_submodule("pygame", PyInit_pg_math(), "math"); @@ -391,7 +407,7 @@ PyInit_pygame_static() #endif // defined(BUILD_STATIC) -#include "base.h" +// #include "base.h" #include "rect.c" #include "pgcompat_rect.c" From 4659d3f2f03bd179a5cd744dfe32642847e93d83 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sat, 28 Jun 2025 19:15:45 -0500 Subject: [PATCH 6/8] re-include base.h for declarations to exist --- src_c/base.c | 3 --- src_c/static.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index d6d764bd01..aa018198fa 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -19,9 +19,6 @@ Pete Shinners pete@shinners.org */ -#define NO_PYGAME_C_API -#define PYGAMEAPI_BASE_INTERNAL - #if defined(BUILD_STATIC) #define CONTROLLER_NOPYX #define PYGAMEAPI_RECT_INTERNAL diff --git a/src_c/static.c b/src_c/static.c index 8a01b0d913..18ddabd781 100644 --- a/src_c/static.c +++ b/src_c/static.c @@ -407,7 +407,7 @@ PyInit_pygame_static() #endif // defined(BUILD_STATIC) -// #include "base.h" +#include "base.h" #include "rect.c" #include "pgcompat_rect.c" From 97c36b351e6fe9dff8337b6f4f21aeef188c8388 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sun, 29 Jun 2025 11:45:34 -0500 Subject: [PATCH 7/8] Moved static.c to base.c --- buildconfig/Setup.Emscripten.SDL2.in | 5 +- src_c/base.c | 515 +++++++++++++++++++++++++- src_c/static.c | 520 --------------------------- 3 files changed, 516 insertions(+), 524 deletions(-) delete mode 100644 src_c/static.c diff --git a/buildconfig/Setup.Emscripten.SDL2.in b/buildconfig/Setup.Emscripten.SDL2.in index 9c465102f1..74913d3f49 100644 --- a/buildconfig/Setup.Emscripten.SDL2.in +++ b/buildconfig/Setup.Emscripten.SDL2.in @@ -33,14 +33,13 @@ math src_c/math.c $(SDL) $(DEBUG) GFX = src_c/SDL_gfx/SDL_gfxPrimitives.c -static src_c/static.c $(SDL) $(FREETYPE) $(FONT) $(MIXER) $(IMAGE) $(PNG) $(JPEG) $(DEBUG) +static src_c/base.c $(SDL) $(FREETYPE) $(FONT) $(MIXER) $(IMAGE) $(PNG) $(JPEG) $(DEBUG) -# these should not be altered they already are in static.c merging file above +# these should not be altered they already are in base.c merging file above time src_c/void.c _freetype src_c/void.c imageext src_c/void.c image src_c/void.c -base src_c/void.c bufferproxy src_c/void.c color src_c/void.c controller src_c/void.c diff --git a/src_c/base.c b/src_c/base.c index aa018198fa..40008d38e6 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -2244,5 +2244,518 @@ MODINIT_DEFINE(base) } #if defined(__EMSCRIPTEN__) || defined(__wasi__) -#include "static.c" +#define NO_PYGAME_C_API + +#define CONTROLLER_NOPYX + +#define PYGAMEAPI_RECT_INTERNAL +#define PYGAMEAPI_EVENT_INTERNAL +#define PYGAMEAPI_JOYSTICK_INTERNAL +#define PYGAMEAPI_BASE_INTERNAL +#define PYGAMEAPI_SURFACE_INTERNAL +#define PYGAMEAPI_BUFFERPROXY_INTERNAL +#define PYGAMEAPI_WINDOW_INTERNAL +#define PYGAMEAPI_RENDER_INTERNAL + +#if 0 +#define pgSurface_New(surface) (pgSurfaceObject *)pgSurface_New2((surface), 1) +#define pgSurface_NewNoOwn(surface) \ + (pgSurfaceObject *)pgSurface_New2((surface), 0) +#endif + +#include + +#undef WITH_THREAD + +#if defined(BUILD_STATIC) +#undef import_pygame_base +#undef import_pygame_rect +#undef import_pygame_surface +#undef import_pygame_geometry +#undef import_pygame_color +#undef import_pygame_bufferproxy +#undef import_pygame_rwobject +#undef import_pygame_event + +void +import_pygame_base(void) +{ +} + +void +import_pygame_rect(void) +{ +} + +void +import_pygame_surface(void) +{ +} + +#ifdef import_pygame_window +#undef import_pygame_window +#endif + +void +import_pygame_window(void) +{ +} + +void +import_pygame_geometry(void) +{ +} + +void +import_pygame_color(void) +{ +} + +void +import_pygame_font(void) +{ +} + +void +import_pygame_freetype(void) +{ +} + +void +import_pygame_bufferproxy(void) +{ +} + +void +import_pygame_rwobject(void) +{ +} + +void +import_pygame_event(void) +{ +} + +#ifdef import_pygame_joystick +#undef import_pygame_joystick +#endif + +void +import_pygame_joystick(void) +{ +} + +#undef import_pygame_imageext +#undef import_pygame_render +#undef import_pygame_pixelarray + +void +import_pygame_imageext(void) +{ +} + +void +import_pygame_render(void) +{ +} + +void +import_pygame_pixelarray(void) +{ +} + +PyMODINIT_FUNC +PyInit_base(void); +PyMODINIT_FUNC +PyInit_color(void); +PyMODINIT_FUNC +PyInit_constants(void); +PyMODINIT_FUNC +PyInit_version(void); +PyMODINIT_FUNC +PyInit_rect(void); +PyMODINIT_FUNC +PyInit_geometry(void); +PyMODINIT_FUNC +PyInit_surflock(void); +PyMODINIT_FUNC +PyInit_rwobject(void); +PyMODINIT_FUNC +PyInit_bufferproxy(void); + +PyMODINIT_FUNC +PyInit_surface(void); +PyMODINIT_FUNC +PyInit_display(void); +PyMODINIT_FUNC +PyInit__freetype(void); +PyMODINIT_FUNC +PyInit_font(void); + +PyMODINIT_FUNC +PyInit_draw(void); +PyMODINIT_FUNC +PyInit_mouse(void); +PyMODINIT_FUNC +PyInit_key(void); +PyMODINIT_FUNC +PyInit_event(void); + +PyMODINIT_FUNC +PyInit_joystick(void); + +PyMODINIT_FUNC +PyInit_imageext(void); + +PyMODINIT_FUNC +PyInit_image(void); + +PyMODINIT_FUNC +PyInit_mask(void); + +PyMODINIT_FUNC +PyInit_mixer_music(void); + +PyMODINIT_FUNC +PyInit_pg_mixer(void); + +PyMODINIT_FUNC +PyInit_pg_math(void); + +PyMODINIT_FUNC +PyInit_pg_time(void); + +PyMODINIT_FUNC +PyInit_sdl2(void); + +PyMODINIT_FUNC +PyInit_mixer(void); + +PyMODINIT_FUNC +PyInit_system(void); + +#if defined(CONTROLLER_NOPYX) +PyMODINIT_FUNC +PyInit_controller(void); +#else +PyMODINIT_FUNC +PyInit_controller_old(void); +#endif + +PyMODINIT_FUNC +PyInit_transform(void); + +PyMODINIT_FUNC +PyInit_video(void); + +PyMODINIT_FUNC +PyInit__sprite(void); + +PyMODINIT_FUNC +PyInit_pixelcopy(void); + +PyMODINIT_FUNC +PyInit_newbuffer(void); + +PyMODINIT_FUNC +PyInit_gfxdraw(void); + +PyMODINIT_FUNC +PyInit_audio(void); + +PyMODINIT_FUNC +PyInit_pixelarray(void); + +PyMODINIT_FUNC +PyInit_window(void); + +PyMODINIT_FUNC +PyInit__render(void); + +// pygame_static module + +void +load_submodule(const char *parent, PyObject *mod, const char *alias) +{ + char fqn[1024]; + if (!mod) { + snprintf(fqn, sizeof(fqn), "ERROR: PyInit_%s failed for %s.%s", alias, + parent, alias); + puts(fqn); + PyErr_Print(); + PyErr_Clear(); + } + else { + snprintf(fqn, sizeof(fqn), "%s.%s", parent, alias); + PyObject *modules = PyImport_GetModuleDict(); + + PyObject *pmod = PyDict_GetItemString(modules, parent); + if (!pmod) { + snprintf(fqn, sizeof(fqn), "ERROR: Parent %s not found for %s.%s", + parent, parent, alias); + puts(fqn); + } + else { + PyDict_SetItemString(modules, fqn, mod); + PyDict_SetItemString(PyModule_GetDict(mod), "__name__", + PyUnicode_FromString(fqn)); + PyModule_AddObjectRef(pmod, alias, mod); + Py_XDECREF(mod); + } + } +} + +void +load_submodule_mphase(const char *parent, PyObject *mdef, PyObject *spec, + const char *alias) +{ + char fqn[1024]; + snprintf(fqn, sizeof(fqn), "%s.%s", parent, alias); + + PyObject *modules = PyImport_GetModuleDict(); + + Py_DECREF(PyObject_GetAttrString(spec, "name")); + PyObject_SetAttrString(spec, "name", PyUnicode_FromString(alias)); + PyObject *pmod = PyDict_GetItemString(modules, parent); + PyObject *mod = PyModule_FromDefAndSpec((PyModuleDef *)mdef, spec); + PyDict_SetItemString(PyModule_GetDict(mod), "__package__", + PyUnicode_FromString(parent)); + // TODO SET PACKAGE + PyModule_ExecDef(mod, (PyModuleDef *)mdef); + + if (pmod) { + PyDict_SetItemString(modules, fqn, mod); + PyDict_SetItemString(PyModule_GetDict(mod), "__name__", + PyUnicode_FromString(fqn)); + PyModule_AddObjectRef(pmod, alias, mod); + Py_XDECREF(mod); + } + if (!pmod || PyErr_Occurred()) { + snprintf(fqn, sizeof(fqn), "Error after init in : %s.%s\n", parent, + alias); + fputs(fqn, stderr); + PyErr_Print(); + PyErr_Clear(); + } +} + +static PyObject * +mod_pygame_import_cython(PyObject *self, PyObject *spec) +{ + load_submodule_mphase("pygame._sdl2", PyInit_sdl2(), spec, "sdl2"); + + load_submodule_mphase("pygame._sdl2", PyInit_mixer(), spec, "mixer"); +#if defined(CONTROLLER_NOPYX) + load_submodule("pygame._sdl2", PyInit_controller(), "controller"); +#else + load_submodule_mphase("pygame._sdl2", PyInit_controller_old(), spec, + "controller_old"); +#endif + load_submodule_mphase("pygame._sdl2", PyInit_audio(), spec, "audio"); + load_submodule_mphase("pygame._sdl2", PyInit_video(), spec, "video"); + + Py_RETURN_NONE; +} + +static PyMethodDef mod_pygame_static_methods[] = { + {"import_cython", (PyCFunction)mod_pygame_import_cython, METH_O, + "pygame._sdl2.sdl2"}, + {NULL, NULL, 0, NULL}}; + +static struct PyModuleDef mod_pygame_static = {PyModuleDef_HEAD_INIT, + "pygame_static", NULL, -1, + mod_pygame_static_methods}; + +PyMODINIT_FUNC +PyInit_pygame_static() +{ + // cannot fail here, and font_initialized is already set to 1 in font.c . + TTF_Init(); + + // for correct input in wasm worker + SDL_SetHint("SDL_EMSCRIPTEN_KEYBOARD_ELEMENT", "1"); + + // base module is including current file + // all globals are accessible from here. + load_submodule("pygame", PyInit_base(), "base"); + + load_submodule("pygame", PyInit_constants(), "constants"); + // + load_submodule("pygame", PyInit_pg_math(), "math"); + + // base, pygame.colordict + load_submodule("pygame", PyInit_color(), "color"); + + // base + load_submodule("pygame", PyInit_rect(), "rect"); + + // base, rect + load_submodule("pygame", PyInit_geometry(), "geometry"); + + load_submodule("pygame", PyInit_bufferproxy(), "bufferproxy"); + load_submodule("pygame", PyInit_surflock(), "surflock"); + + // base, color, rect, bufferproxy, surflock + load_submodule("pygame", PyInit_surface(), "surface"); + + load_submodule("pygame", PyInit_rwobject(), "rwobject"); + + // base, color, rect, bufferproxy, surflock, surface, rwobject + load_submodule("pygame", PyInit_imageext(), "imageext"); + // base, color, rect, bufferproxy, surflock, surface, rwobject + load_submodule("pygame", PyInit_image(), "image"); + + load_submodule("pygame", PyInit__freetype(), "_freetype"); + load_submodule("pygame", PyInit_font(), "font"); + load_submodule("pygame", PyInit_pixelcopy(), "pixelcopy"); + load_submodule("pygame", PyInit_newbuffer(), "newbuffer"); + + // base + load_submodule("pygame", PyInit_joystick(), "joystick"); + // base, joystick + load_submodule("pygame", PyInit_event(), "event"); + + // base, rect, event + load_submodule("pygame", PyInit_key(), "key"); + // base, event + load_submodule("pygame", PyInit_pg_time(), "time"); + + load_submodule("pygame", PyInit_transform(), "transform"); + load_submodule("pygame", PyInit_draw(), "draw"); + + load_submodule("pygame", PyInit_mask(), "mask"); + load_submodule("pygame", PyInit_mouse(), "mouse"); + + load_submodule("pygame", PyInit_pg_mixer(), "mixer"); + load_submodule("pygame.mixer", PyInit_mixer_music(), "music"); + + // base, color, rect, bufferproxy, surflock, surface + load_submodule("pygame", PyInit_window(), "window"); + + // base, color, rect, surflock, surface, window + load_submodule("pygame", PyInit_display(), "display"); + load_submodule("pygame", PyInit__render(), "_render"); + + load_submodule("pygame", PyInit_pixelarray(), "pixelarray"); + + // base, color, rect, bufferproxy, surflock, surface + load_submodule("pygame", PyInit_gfxdraw(), "gfxdraw"); + + load_submodule("pygame", PyInit_system(), "system"); + + return PyModule_Create(&mod_pygame_static); +} + +#endif // defined(BUILD_STATIC) + +#include "rect.c" +#include "pgcompat_rect.c" + +#undef pgSurface_Lock +#undef pgSurface_Unlock +#undef pgSurface_LockBy +#undef pgSurface_UnlockBy +#undef pgSurface_Prep +#undef pgSurface_Unprep + +#include "surflock.c" + +#undef pgColor_New +#undef pgColor_NewLength +#undef pg_RGBAFromObjEx +#undef pg_MappedColorFromObj +#undef pgColor_Type + +#include "color.c" + +#undef pgBufferProxy_New + +#include "bufferproxy.c" + +#undef pgSurface_Blit +#undef pgSurface_New +#undef pgSurface_Type +#undef pgSurface_SetSurface + +#include "surface.c" +#include "simd_blitters_avx2.c" +#include "simd_blitters_sse2.c" + +#include "window.c" + +#undef pgVidInfo_Type +#undef pgVidInfo_New + +#include "display.c" + +#include "draw.c" + +#undef pg_EncodeString +#undef pg_EncodeFilePath +#undef pgRWops_IsFileObject +#undef pgRWops_GetFileExtension +#undef pgRWops_FromFileObject +#undef pgRWops_FromObject + +#include "rwobject.c" + +#define pgSurface_New(surface) (pgSurfaceObject *)pgSurface_New2((surface), 1) +#include "render.c" +#include "image.c" + +#include "imageext.c" + +#include "mask.c" + +#undef pg_EnableKeyRepeat +#undef pg_GetKeyRepeat +#undef pgEvent_FillUserEvent +#undef pgEvent_Type +#undef pgEvent_New + +#include "joystick.c" + +#include "event.c" + +#include "mouse.c" + +#include "key.c" + +#include "time.c" + +#include "system.c" +#include "geometry.c" + +#include "_freetype.c" +#include "freetype/ft_wrap.c" +#include "freetype/ft_render.c" +#include "freetype/ft_render_cb.c" +#include "freetype/ft_cache.c" +#include "freetype/ft_layout.c" +#include "freetype/ft_unicode.c" + +#include "font.c" + +#include "mixer.c" + +#include "music.c" + +#include "gfxdraw.c" + +#include "alphablit.c" + +#include "surface_fill.c" +#include "pixelarray.c" +#include "pixelcopy.c" +#include "newbuffer.c" + +#include "_sdl2/controller.c" +#include "_sdl2/controller_old.c" +#include "_sdl2/touch.c" +#include "transform.c" +// that remove some warnings +#undef MAX +#undef MIN +#include "scale2x.c" + #endif diff --git a/src_c/static.c b/src_c/static.c deleted file mode 100644 index 18ddabd781..0000000000 --- a/src_c/static.c +++ /dev/null @@ -1,520 +0,0 @@ -#define NO_PYGAME_C_API - -#define CONTROLLER_NOPYX - -#define PYGAMEAPI_RECT_INTERNAL -#define PYGAMEAPI_EVENT_INTERNAL -#define PYGAMEAPI_JOYSTICK_INTERNAL -#define PYGAMEAPI_BASE_INTERNAL -#define PYGAMEAPI_SURFACE_INTERNAL -#define PYGAMEAPI_BUFFERPROXY_INTERNAL -#define PYGAMEAPI_WINDOW_INTERNAL -#define PYGAMEAPI_RENDER_INTERNAL - -#if 0 -#define pgSurface_New(surface) (pgSurfaceObject *)pgSurface_New2((surface), 1) -#define pgSurface_NewNoOwn(surface) \ - (pgSurfaceObject *)pgSurface_New2((surface), 0) -#endif - -#include "pygame.h" -#include "Python.h" - -#include - -#if defined(__EMSCRIPTEN__) -#undef WITH_THREAD -#endif - -#if defined(BUILD_STATIC) -#undef import_pygame_base -#undef import_pygame_rect -#undef import_pygame_surface -#undef import_pygame_geometry -#undef import_pygame_color -#undef import_pygame_bufferproxy -#undef import_pygame_rwobject -#undef import_pygame_event - -void -import_pygame_base(void) -{ -} - -void -import_pygame_rect(void) -{ -} - -void -import_pygame_surface(void) -{ -} - -#ifdef import_pygame_window -#undef import_pygame_window -#endif - -void -import_pygame_window(void) -{ -} - -void -import_pygame_geometry(void) -{ -} - -void -import_pygame_color(void) -{ -} - -void -import_pygame_font(void) -{ -} - -void -import_pygame_freetype(void) -{ -} - -void -import_pygame_bufferproxy(void) -{ -} - -void -import_pygame_rwobject(void) -{ -} - -void -import_pygame_event(void) -{ -} - -#ifdef import_pygame_joystick -#undef import_pygame_joystick -#endif - -void -import_pygame_joystick(void) -{ -} - -#undef import_pygame_imageext -#undef import_pygame_render -#undef import_pygame_pixelarray - -void -import_pygame_imageext(void) -{ -} - -void -import_pygame_render(void) -{ -} - -void -import_pygame_pixelarray(void) -{ -} - -PyMODINIT_FUNC -PyInit_base(void); -PyMODINIT_FUNC -PyInit_color(void); -PyMODINIT_FUNC -PyInit_constants(void); -PyMODINIT_FUNC -PyInit_version(void); -PyMODINIT_FUNC -PyInit_rect(void); -PyMODINIT_FUNC -PyInit_geometry(void); -PyMODINIT_FUNC -PyInit_surflock(void); -PyMODINIT_FUNC -PyInit_rwobject(void); -PyMODINIT_FUNC -PyInit_bufferproxy(void); - -PyMODINIT_FUNC -PyInit_surface(void); -PyMODINIT_FUNC -PyInit_display(void); -PyMODINIT_FUNC -PyInit__freetype(void); -PyMODINIT_FUNC -PyInit_font(void); - -PyMODINIT_FUNC -PyInit_draw(void); -PyMODINIT_FUNC -PyInit_mouse(void); -PyMODINIT_FUNC -PyInit_key(void); -PyMODINIT_FUNC -PyInit_event(void); - -PyMODINIT_FUNC -PyInit_joystick(void); - -PyMODINIT_FUNC -PyInit_imageext(void); - -PyMODINIT_FUNC -PyInit_image(void); - -PyMODINIT_FUNC -PyInit_mask(void); - -PyMODINIT_FUNC -PyInit_mixer_music(void); - -PyMODINIT_FUNC -PyInit_pg_mixer(void); - -PyMODINIT_FUNC -PyInit_pg_math(void); - -PyMODINIT_FUNC -PyInit_pg_time(void); - -PyMODINIT_FUNC -PyInit_sdl2(void); - -PyMODINIT_FUNC -PyInit_mixer(void); - -PyMODINIT_FUNC -PyInit_system(void); - -#if defined(CONTROLLER_NOPYX) -PyMODINIT_FUNC -PyInit_controller(void); -#else -PyMODINIT_FUNC -PyInit_controller_old(void); -#endif - -PyMODINIT_FUNC -PyInit_transform(void); - -PyMODINIT_FUNC -PyInit_video(void); - -PyMODINIT_FUNC -PyInit__sprite(void); - -PyMODINIT_FUNC -PyInit_pixelcopy(void); - -PyMODINIT_FUNC -PyInit_newbuffer(void); - -PyMODINIT_FUNC -PyInit_gfxdraw(void); - -PyMODINIT_FUNC -PyInit_audio(void); - -PyMODINIT_FUNC -PyInit_pixelarray(void); - -PyMODINIT_FUNC -PyInit_window(void); - -PyMODINIT_FUNC -PyInit__render(void); - -// pygame_static module - -void -load_submodule(const char *parent, PyObject *mod, const char *alias) -{ - char fqn[1024]; - if (!mod) { - snprintf(fqn, sizeof(fqn), "ERROR: PyInit_%s failed for %s.%s", alias, - parent, alias); - puts(fqn); - PyErr_Print(); - PyErr_Clear(); - } - else { - snprintf(fqn, sizeof(fqn), "%s.%s", parent, alias); - PyObject *modules = PyImport_GetModuleDict(); - - PyObject *pmod = PyDict_GetItemString(modules, parent); - if (!pmod) { - snprintf(fqn, sizeof(fqn), "ERROR: Parent %s not found for %s.%s", - parent, parent, alias); - puts(fqn); - } - else { - PyDict_SetItemString(modules, fqn, mod); - PyDict_SetItemString(PyModule_GetDict(mod), "__name__", - PyUnicode_FromString(fqn)); - PyModule_AddObjectRef(pmod, alias, mod); - Py_XDECREF(mod); - } - } -} - -void -load_submodule_mphase(const char *parent, PyObject *mdef, PyObject *spec, - const char *alias) -{ - char fqn[1024]; - snprintf(fqn, sizeof(fqn), "%s.%s", parent, alias); - - PyObject *modules = PyImport_GetModuleDict(); - - Py_DECREF(PyObject_GetAttrString(spec, "name")); - PyObject_SetAttrString(spec, "name", PyUnicode_FromString(alias)); - PyObject *pmod = PyDict_GetItemString(modules, parent); - PyObject *mod = PyModule_FromDefAndSpec((PyModuleDef *)mdef, spec); - PyDict_SetItemString(PyModule_GetDict(mod), "__package__", - PyUnicode_FromString(parent)); - // TODO SET PACKAGE - PyModule_ExecDef(mod, (PyModuleDef *)mdef); - - if (pmod) { - PyDict_SetItemString(modules, fqn, mod); - PyDict_SetItemString(PyModule_GetDict(mod), "__name__", - PyUnicode_FromString(fqn)); - PyModule_AddObjectRef(pmod, alias, mod); - Py_XDECREF(mod); - } - if (!pmod || PyErr_Occurred()) { - snprintf(fqn, sizeof(fqn), "Error after init in : %s.%s\n", parent, - alias); - fputs(fqn, stderr); - PyErr_Print(); - PyErr_Clear(); - } -} - -static PyObject * -mod_pygame_import_cython(PyObject *self, PyObject *spec) -{ - load_submodule_mphase("pygame._sdl2", PyInit_sdl2(), spec, "sdl2"); - - load_submodule_mphase("pygame._sdl2", PyInit_mixer(), spec, "mixer"); -#if defined(CONTROLLER_NOPYX) - load_submodule("pygame._sdl2", PyInit_controller(), "controller"); -#else - load_submodule_mphase("pygame._sdl2", PyInit_controller_old(), spec, - "controller_old"); -#endif - load_submodule_mphase("pygame._sdl2", PyInit_audio(), spec, "audio"); - load_submodule_mphase("pygame._sdl2", PyInit_video(), spec, "video"); - - Py_RETURN_NONE; -} - -static PyMethodDef mod_pygame_static_methods[] = { - {"import_cython", (PyCFunction)mod_pygame_import_cython, METH_O, - "pygame._sdl2.sdl2"}, - {NULL, NULL, 0, NULL}}; - -static struct PyModuleDef mod_pygame_static = {PyModuleDef_HEAD_INIT, - "pygame_static", NULL, -1, - mod_pygame_static_methods}; - -PyMODINIT_FUNC -PyInit_pygame_static() -{ - // cannot fail here, and font_initialized is already set to 1 in font.c . - TTF_Init(); - - // for correct input in wasm worker - SDL_SetHint("SDL_EMSCRIPTEN_KEYBOARD_ELEMENT", "1"); - - // base module is including current file - // all globals are accessible from here. - load_submodule("pygame", PyInit_base(), "base"); - - load_submodule("pygame", PyInit_constants(), "constants"); - // - load_submodule("pygame", PyInit_pg_math(), "math"); - - // base, pygame.colordict - load_submodule("pygame", PyInit_color(), "color"); - - // base - load_submodule("pygame", PyInit_rect(), "rect"); - - // base, rect - load_submodule("pygame", PyInit_geometry(), "geometry"); - - load_submodule("pygame", PyInit_bufferproxy(), "bufferproxy"); - load_submodule("pygame", PyInit_surflock(), "surflock"); - - // base, color, rect, bufferproxy, surflock - load_submodule("pygame", PyInit_surface(), "surface"); - - load_submodule("pygame", PyInit_rwobject(), "rwobject"); - - // base, color, rect, bufferproxy, surflock, surface, rwobject - load_submodule("pygame", PyInit_imageext(), "imageext"); - // base, color, rect, bufferproxy, surflock, surface, rwobject - load_submodule("pygame", PyInit_image(), "image"); - - load_submodule("pygame", PyInit__freetype(), "_freetype"); - load_submodule("pygame", PyInit_font(), "font"); - load_submodule("pygame", PyInit_pixelcopy(), "pixelcopy"); - load_submodule("pygame", PyInit_newbuffer(), "newbuffer"); - - // base - load_submodule("pygame", PyInit_joystick(), "joystick"); - // base, joystick - load_submodule("pygame", PyInit_event(), "event"); - - // base, rect, event - load_submodule("pygame", PyInit_key(), "key"); - // base, event - load_submodule("pygame", PyInit_pg_time(), "time"); - - load_submodule("pygame", PyInit_transform(), "transform"); - load_submodule("pygame", PyInit_draw(), "draw"); - - load_submodule("pygame", PyInit_mask(), "mask"); - load_submodule("pygame", PyInit_mouse(), "mouse"); - - load_submodule("pygame", PyInit_pg_mixer(), "mixer"); - load_submodule("pygame.mixer", PyInit_mixer_music(), "music"); - - // base, color, rect, bufferproxy, surflock, surface - load_submodule("pygame", PyInit_window(), "window"); - - // base, color, rect, surflock, surface, window - load_submodule("pygame", PyInit_display(), "display"); - load_submodule("pygame", PyInit__render(), "_render"); - - load_submodule("pygame", PyInit_pixelarray(), "pixelarray"); - - // base, color, rect, bufferproxy, surflock, surface - load_submodule("pygame", PyInit_gfxdraw(), "gfxdraw"); - - load_submodule("pygame", PyInit_system(), "system"); - - return PyModule_Create(&mod_pygame_static); -} - -#endif // defined(BUILD_STATIC) - -#include "base.h" - -#include "rect.c" -#include "pgcompat_rect.c" - -#undef pgSurface_Lock -#undef pgSurface_Unlock -#undef pgSurface_LockBy -#undef pgSurface_UnlockBy -#undef pgSurface_Prep -#undef pgSurface_Unprep - -#include "surflock.c" - -#undef pgColor_New -#undef pgColor_NewLength -#undef pg_RGBAFromObjEx -#undef pg_MappedColorFromObj -#undef pgColor_Type - -#include "color.c" - -#undef pgBufferProxy_New - -#include "bufferproxy.c" - -#undef pgSurface_Blit -#undef pgSurface_New -#undef pgSurface_Type -#undef pgSurface_SetSurface - -#include "surface.c" -#include "simd_blitters_avx2.c" -#include "simd_blitters_sse2.c" - -#include "window.c" - -#undef pgVidInfo_Type -#undef pgVidInfo_New - -#include "display.c" - -#include "draw.c" - -#undef pg_EncodeString -#undef pg_EncodeFilePath -#undef pgRWops_IsFileObject -#undef pgRWops_GetFileExtension -#undef pgRWops_FromFileObject -#undef pgRWops_FromObject - -#include "rwobject.c" - -#define pgSurface_New(surface) (pgSurfaceObject *)pgSurface_New2((surface), 1) -#include "render.c" -#include "image.c" - -#include "imageext.c" - -#include "mask.c" - -#undef pg_EnableKeyRepeat -#undef pg_GetKeyRepeat -#undef pgEvent_FillUserEvent -#undef pgEvent_Type -#undef pgEvent_New - -#include "joystick.c" - -#include "event.c" - -#include "mouse.c" - -#include "key.c" - -#include "time.c" - -#include "system.c" -#include "geometry.c" - -#include "_freetype.c" -#include "freetype/ft_wrap.c" -#include "freetype/ft_render.c" -#include "freetype/ft_render_cb.c" -#include "freetype/ft_cache.c" -#include "freetype/ft_layout.c" -#include "freetype/ft_unicode.c" - -#include "font.c" - -#include "mixer.c" - -#include "music.c" - -#include "gfxdraw.c" - -#include "alphablit.c" - -#include "surface_fill.c" -#include "pixelarray.c" -#include "pixelcopy.c" -#include "newbuffer.c" - -#include "_sdl2/controller.c" -#include "_sdl2/controller_old.c" -#include "_sdl2/touch.c" -#include "transform.c" -// that remove some warnings -#undef MAX -#undef MIN -#include "scale2x.c" From da198232219338ad02f07bdc31d2cacea81de708 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sun, 29 Jun 2025 12:30:49 -0500 Subject: [PATCH 8/8] Removed (probably) unnecessary declaration of pgExc_SDLError --- src_c/base.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index 40008d38e6..61fcd69dc2 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -38,8 +38,6 @@ PG_PixelFormatEnum pg_default_convert_format = 0; /* Custom exceptions */ PyObject *pgExc_BufferError = NULL; -PyObject *pgExc_SDLError; - /* Only one instance of the state per process. */ static PyObject *pg_quit_functions = NULL; static int pg_is_init = 0;