Start work on replacing glfw ctypes bindings

This commit is contained in:
Kovid Goyal 2016-11-29 15:50:58 +05:30
parent 1a1c647793
commit b1869c8369
5 changed files with 99 additions and 14 deletions

View File

@ -16,6 +16,12 @@ static PyMethodDef module_methods[] = {
{"parse_bytes_dump", (PyCFunction)parse_bytes_dump, METH_VARARGS, ""}, {"parse_bytes_dump", (PyCFunction)parse_bytes_dump, METH_VARARGS, ""},
{"read_bytes", (PyCFunction)read_bytes, METH_VARARGS, ""}, {"read_bytes", (PyCFunction)read_bytes, METH_VARARGS, ""},
{"read_bytes_dump", (PyCFunction)read_bytes_dump, METH_VARARGS, ""}, {"read_bytes_dump", (PyCFunction)read_bytes_dump, METH_VARARGS, ""},
{"glfw_set_error_callback", (PyCFunction)glfw_set_error_callback, METH_O, ""},
{"glfw_init", (PyCFunction)glfw_init, METH_NOARGS, ""},
{"glfw_terminate", (PyCFunction)glfw_terminate, METH_NOARGS, ""},
{"glfw_window_hint", (PyCFunction)glfw_window_hint, METH_VARARGS, ""},
{"glfw_swap_interval", (PyCFunction)glfw_swap_interval, METH_VARARGS, ""},
{"glfw_wait_events", (PyCFunction)glfw_wait_events, METH_NOARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };

View File

@ -7,8 +7,79 @@
#include "data-types.h" #include "data-types.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#define MAX_WINDOWS 255
/* static PyObject* window_weakrefs[MAX_WINDOWS + 1] = {0}; */
#define CALLBACK(name, fmt, ...) \
if ((name) != NULL) { \
PyGILState_STATE _pystate = PyGILState_Ensure(); \
PyObject *_pyret = PyObject_CallFunction((name), fmt, __VA_ARGS__); \
PyGILState_Release(_pystate); \
if (_pyret == NULL) { PyErr_Print(); PyErr_Clear(); return; } \
Py_CLEAR(_pyret); \
}
// Library Setup {{{
static PyObject *error_callback = NULL;
static void
cb_error_callback(int error, const char* description) {
CALLBACK(error_callback, "is", error, description) else fprintf(stderr, "[glfw error]: %s\n", description);
}
PyObject*
glfw_set_error_callback(PyObject UNUSED *self, PyObject *callback) {
Py_CLEAR(error_callback);
error_callback = callback;
Py_INCREF(callback);
Py_RETURN_NONE;
}
PyObject*
glfw_init(PyObject UNUSED *self) {
PyObject *ans = glfwInit() ? Py_True: Py_False;
Py_INCREF(ans);
return ans;
}
PyObject*
glfw_terminate(PyObject UNUSED *self) {
glfwTerminate();
Py_RETURN_NONE;
}
PyObject*
glfw_window_hint(PyObject UNUSED *self, PyObject *args) {
int hint, value;
if (!PyArg_ParseTuple(args, "ii", &hint, &value)) return NULL;
glfwWindowHint(hint, value);
Py_RETURN_NONE;
}
PyObject*
glfw_swap_interval(PyObject UNUSED *self, PyObject *args) {
int value;
if (!PyArg_ParseTuple(args, "i", &value)) return NULL;
glfwSwapInterval(value);
Py_RETURN_NONE;
}
PyObject*
glfw_wait_events(PyObject UNUSED *self) {
Py_BEGIN_ALLOW_THREADS;
glfwWaitEvents();
Py_END_ALLOW_THREADS;
Py_RETURN_NONE;
}
// }}}
// constants {{{
bool bool
init_glfw(PyObject *m) { init_glfw(PyObject *m) {
PyEval_InitThreads();
glfwSetErrorCallback(cb_error_callback);
#define ADDC(n) if(PyModule_AddIntConstant(m, #n, n) != 0) return false; #define ADDC(n) if(PyModule_AddIntConstant(m, #n, n) != 0) return false;
ADDC(GLFW_RELEASE); ADDC(GLFW_RELEASE);
ADDC(GLFW_PRESS); ADDC(GLFW_PRESS);
@ -264,5 +335,4 @@ init_glfw(PyObject *m) {
return true; return true;
#undef ADDC #undef ADDC
} }
// }}}

View File

@ -9,3 +9,9 @@
bool init_glfw(PyObject *m); bool init_glfw(PyObject *m);
PyObject* glfw_set_error_callback(PyObject UNUSED *self, PyObject *callback);
PyObject* glfw_init(PyObject UNUSED *self);
PyObject* glfw_terminate(PyObject UNUSED *self);
PyObject* glfw_window_hint(PyObject UNUSED *self, PyObject *args);
PyObject* glfw_swap_interval(PyObject UNUSED *self, PyObject *args);
PyObject* glfw_wait_events(PyObject UNUSED *self);

View File

@ -17,7 +17,9 @@ from .fast_data_types import (
glewInit, enable_automatic_opengl_error_checking, glClear, glClearColor, glewInit, enable_automatic_opengl_error_checking, glClear, glClearColor,
GL_COLOR_BUFFER_BIT, GLFW_CONTEXT_VERSION_MAJOR, GL_COLOR_BUFFER_BIT, GLFW_CONTEXT_VERSION_MAJOR,
GLFW_CONTEXT_VERSION_MINOR, GLFW_OPENGL_PROFILE, GLFW_CONTEXT_VERSION_MINOR, GLFW_OPENGL_PROFILE,
GLFW_OPENGL_FORWARD_COMPAT, GLFW_OPENGL_CORE_PROFILE, GLFW_SAMPLES GLFW_OPENGL_FORWARD_COMPAT, GLFW_OPENGL_CORE_PROFILE, GLFW_SAMPLES,
glfw_set_error_callback, glfw_init, glfw_terminate, glfw_window_hint,
glfw_swap_interval, glfw_wait_events
) )
import glfw import glfw
@ -40,21 +42,21 @@ def option_parser():
def setup_opengl(): def setup_opengl():
glfw.glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GL_VERSION[0]) glfw_window_hint(GLFW_CONTEXT_VERSION_MAJOR, GL_VERSION[0])
glfw.glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GL_VERSION[1]) glfw_window_hint(GLFW_CONTEXT_VERSION_MINOR, GL_VERSION[1])
glfw.glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE) glfw_window_hint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
glfw.glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, True) glfw_window_hint(GLFW_OPENGL_FORWARD_COMPAT, True)
glfw.glfwWindowHint(GLFW_SAMPLES, 0) glfw_window_hint(GLFW_SAMPLES, 0)
def clear_buffers(window, opts): def clear_buffers(window, opts):
bg = opts.background bg = opts.background
glClearColor(bg.red / 255, bg.green / 255, bg.blue / 255, 1) glClearColor(bg.red / 255, bg.green / 255, bg.blue / 255, 1)
glfw.glfwSwapInterval(0) glfw_swap_interval(0)
glClear(GL_COLOR_BUFFER_BIT) glClear(GL_COLOR_BUFFER_BIT)
glfw.glfwSwapBuffers(window) glfw.glfwSwapBuffers(window)
glClear(GL_COLOR_BUFFER_BIT) glClear(GL_COLOR_BUFFER_BIT)
glfw.glfwSwapInterval(1) glfw_swap_interval(1)
def run_app(opts, args): def run_app(opts, args):
@ -74,7 +76,7 @@ def run_app(opts, args):
while not glfw.glfwWindowShouldClose(window): while not glfw.glfwWindowShouldClose(window):
tabs.render() tabs.render()
glfw.glfwSwapBuffers(window) glfw.glfwSwapBuffers(window)
glfw.glfwWaitEvents() glfw_wait_events()
finally: finally:
tabs.destroy() tabs.destroy()
finally: finally:
@ -96,9 +98,9 @@ def main():
exec(args.cmd) exec(args.cmd)
return return
opts = load_config(args.config) opts = load_config(args.config)
glfw.glfwSetErrorCallback(on_glfw_error) glfw_set_error_callback(on_glfw_error)
enable_automatic_opengl_error_checking(False) enable_automatic_opengl_error_checking(False)
if not glfw.glfwInit(): if not glfw_init():
raise SystemExit('GLFW initialization failed') raise SystemExit('GLFW initialization failed')
try: try:
if args.profile: if args.profile:
@ -120,5 +122,5 @@ def main():
else: else:
run_app(opts, args) run_app(opts, args)
finally: finally:
glfw.glfwTerminate() glfw_terminate()
os.closerange(3, 100) os.closerange(3, 100)

View File

@ -382,4 +382,5 @@ class TabManager(Thread):
del self.tabs del self.tabs
self.sprites.destroy() self.sprites.destroy()
del self.sprites del self.sprites
del self.glfw_window
# }}} # }}}