Skip to content

Commit

Permalink
Implement display.gl_get_proc
Browse files Browse the repository at this point in the history
  • Loading branch information
yunline committed Jan 8, 2025
1 parent 8a7bbf2 commit 925b29f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
3 changes: 2 additions & 1 deletion buildconfig/stubs/pygame/display.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Iterable
from typing import Optional, Union, overload, Literal
from typing import Optional, Union, overload, Literal, Any
from typing_extensions import deprecated # added in 3.13

from pygame.constants import FULLSCREEN
Expand Down Expand Up @@ -70,6 +70,7 @@ def mode_ok(
) -> int: ...
def gl_get_attribute(flag: int, /) -> int: ...
def gl_set_attribute(flag: int, value: int, /) -> None: ...
def gl_get_proc(proc_name: str) -> Any: ...
def get_active() -> bool: ...
def iconify() -> bool: ...
def toggle_fullscreen() -> int: ...
Expand Down
41 changes: 41 additions & 0 deletions src_c/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -2938,6 +2938,33 @@ pg_message_box(PyObject *self, PyObject *arg, PyObject *kwargs)
return NULL;
}

static PyObject *pg_proc_from_address = NULL;

static PyObject *
pg_gl_get_proc(PyObject *self, PyObject *arg)
{
if (!PyUnicode_Check(arg)) {
return RAISE(PyExc_TypeError, "'proc_name' should be a string");
}
const char *proc_name = PyUnicode_AsUTF8(arg);
if (!proc_name) {
return NULL;
}
unsigned long long proc_addr =
(unsigned long long)SDL_GL_GetProcAddress(proc_name);
if (!proc_addr) {
return RAISE(pgExc_SDLError, SDL_GetError());
}
PyObject *proc_from_address_args = Py_BuildValue("(K)", proc_addr);
if (!proc_from_address_args) {
return NULL;
}
if (!pg_proc_from_address) {
return RAISE(PyExc_TypeError, "'_proc_from_address' object is NULL");
}
return PyObject_CallObject(pg_proc_from_address, proc_from_address_args);
}

static PyMethodDef _pg_display_methods[] = {
{"init", (PyCFunction)pg_display_init, METH_NOARGS, DOC_DISPLAY_INIT},
{"quit", (PyCFunction)pg_display_quit, METH_NOARGS, DOC_DISPLAY_QUIT},
Expand Down Expand Up @@ -3015,6 +3042,7 @@ static PyMethodDef _pg_display_methods[] = {
METH_VARARGS | METH_KEYWORDS, DOC_DISPLAY_SETALLOWSCREENSAVER},
{"message_box", (PyCFunction)pg_message_box, METH_VARARGS | METH_KEYWORDS,
DOC_DISPLAY_MESSAGEBOX},
{"gl_get_proc", (PyCFunction)pg_gl_get_proc, METH_O, "doc"},
{NULL, NULL, 0, NULL}};

#ifndef PYPY_VERSION
Expand Down Expand Up @@ -3065,6 +3093,19 @@ MODINIT_DEFINE(display)
return NULL;
}

/* load _ffi module for display.get_gl_proc function */
PyObject *pg_ffi_module = PyImport_ImportModule("pygame._ffi");
if (!pg_ffi_module) {
return NULL;
}

pg_proc_from_address =
PyObject_GetAttrString(pg_ffi_module, "_proc_from_address");
if (!pg_proc_from_address) {
return NULL;
}
Py_DECREF(pg_ffi_module);

/* create the module */
module = PyModule_Create(&_module);
if (module == NULL) {
Expand Down
4 changes: 4 additions & 0 deletions src_py/_ffi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import ctypes

def _proc_from_address(addr):
return ctypes.CFUNCTYPE(None)(addr)
1 change: 1 addition & 0 deletions src_py/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ python_sources = files(
'_camera_opencv.py',
'_data_classes.py',
'_debug.py',
'_ffi.py',
'_sprite.py',
'camera.py',
'colordict.py',
Expand Down

0 comments on commit 925b29f

Please sign in to comment.