From 12c90826669839b90332588c05bba6c0a383a8b7 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Mon, 30 Aug 2021 21:31:56 -0600 Subject: [PATCH] added the Python backing code for managing resources --- src/Makefile | 2 +- src/ep_devctxt.c | 2 +- src/ep_init.h | 5 +- src/ep_resources.c | 234 +++++++++++++++++++++++++++++++++++++++++++++ src/ep_types.h | 17 +++- src/ep_upiwin.c | 6 ++ 6 files changed, 260 insertions(+), 6 deletions(-) create mode 100644 src/ep_resources.c diff --git a/src/Makefile b/src/Makefile index c923ee6..a691e29 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,7 @@ RESOURCES=../resources SPLASHSCREEN=splash-erbosoft.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ - ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ + ep_resources.o ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ resources.o bitmap.o stockobj.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ i_freehand.o i_line.o i_rect.o i_fillrect.o i_undo.o i_clear.o sysresources.o LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lzip -lpthread -ldl -lutil -lm diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 07c47b6..32910b4 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -359,7 +359,7 @@ PyTypeObject DevCtxtType = { HRESULT Epython_register_devctxt(PyObject *module) { if (PyType_Ready(&DevCtxtType) < 0) - return E_FAIL; + return E_FAIL; Py_INCREF(&DevCtxtType); if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0) { diff --git a/src/ep_init.h b/src/ep_init.h index 340b1bf..23c0e7e 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -1,12 +1,12 @@ /* * UPIWIN - Micro Pi Windowing Framework Kernel * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -35,6 +35,7 @@ extern PyObject *Epython_init_upiwin_tmp_module(void); extern HRESULT Epython_register_devctxt(PyObject *module); extern HRESULT Epython_register_bitmap(PyObject *module); +extern HRESULT Epython_register_resources(PyObject *module); extern HRESULT Epython_setup(void); extern HRESULT Epython_run(void); diff --git a/src/ep_resources.c b/src/ep_resources.c new file mode 100644 index 0000000..903c70e --- /dev/null +++ b/src/ep_resources.c @@ -0,0 +1,234 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ +#include +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" +#include "scode.h" +#include "log.h" +#include "resources.h" +#include "ep_init.h" +#include "ep_types.h" + + +static PyObject *resfile_load_classmethod(ResFileType *cls, PyObject *args) +{ + const char *filename; + PyObject *rc = NULL, *args, *kwargs; + ResFileObject *presfile; + HRESULT hr; + HRESFILE handle; + + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + hr = Rsrc_load_file((PCSTR)filename, &handle); + if (SUCCEEDED(hr)) + { + args = PyTuple_New(0); + if (args) + { + kwargs = PyDict_New(); + if (kwargs) + { + rc = PyType_GenericNew(&ResFileType, args, kwargs); + if (rc) + { + presfile = (ResFileObject *)rc; + presfile->hresfile = handle; + } + Py_DECREF(kwargs); + } + Py_DECREF(args); + } + + if (!rc) + { + Rsrc_close_file(handle); + PyErr_SetString(PyExc_RuntimeError, "unable to create new resource file object"); + } + } + else + PyErr_Format(PyExc_RuntimeError, "unable to load resource file '%s' (%08x)", filename, hr); + return rc; +} + +static PyObject *resfile_close(ResFileObject *self, PyObject *args) +{ + if (self->hresfile) + Rsrc_close_file(self->hresfile); + self->hresfile = (HRESFILE)NULL; + return NULL; +} + +static PyObject *resfile_find_resource(ResFileObject *self, PyObject *args) +{ + const char *name; + PyObject *rc = NULL, *args, *kwargs; + ResourceObject *pres; + HRSRC hrsrc; + HRESULT hr; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + hr = Rsrc_find_resource(self->hresfile, (PCSTR)name, NULL, &hrsrc); + if (SUCCEEDED(hr)) + { + args = PyTuple_New(0); + if (args) + { + kwargs = PyDict_New(); + if (kwargs) + { + rc = PyType_GenericNew(&ResourceType, args, kwargs); + if (rc) + { + pres = (ResourceObject *)rc; + pres->hrsrc = hrsrc; + } + Py_DECREF(kwargs); + } + Py_DECREF(args); + } + + if (!rc) + { + Rsrc_free_resource(hrsrc); + PyErr_SetString(PyExc_RuntimeError, "unable to create new resource object"); + } + } + else + PyErr_Format(PyExc_RuntimeError, "unable to load resource file '%s' (%08x)", filename, hr); + return rc; +} + +static PyMethodDef ResFileMethods[] = { + {"load", (PyCFunction)resfile_load_classmethod, METH_VARARGS|METH_CLASS, + "Load a resource file."}, + {"close", (PyCFunction)resfile_close, METH_VARARGS, + "Close the resource file."}, + {"find_resource", (PyCFunction)resfile_find_resource, METH_VARARGS, + "Find a resource within the resource file."}, + {NULL, NULL, 0, NULL} +}; + +static void resfile_dealloc(ResFileObject *self) +{ + if (self->hresfile) + Rsrc_close_file(self->hresfile); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int resfile_init(ResFileObject *self, PyObject *args, PyObject *kwds) +{ + self->hresfile = (HRESFILE)NULL; + return 0; +} + +PyTypeObject ResFileType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "upiwin.ResFile", + .tp_doc = "Resource file object", + .tp_basicsize = sizeof(ResFileObject), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = PyType_GenericNew, + .tp_init = (initproc)resfile_init, + .tp_dealloc = (destructor)resfile_dealloc, + .tp_methods = ResFileMethods +}; + +static PyObject *resource_close(ResourceObject *self, PyObject *args) +{ + if (self->hrsrc) + Rsrc_free_resource(self->hrsrc); + self->hrsrc = (HRESFILE)NULL; + return NULL; +} + +static PyMethodDef ResourceMethods[] = { + {"close", (PyCFunction)resource_close, METH_VARARGS, + "Close and free the resource."}, + {NULL, NULL, 0, NULL} +}; + +static PyObject *resource_get_size(ResourceObject *self, void *closure) +{ + if (!(self->hrsrc)) + { + PyErr_SetString(PyExc_RuntimeError, "bad resource object"); + return NULL; + } + return PyLong_FromUnsignedLong(Rsrc_sizeof_resource(self->hrsrc)); +} + +static PyGetSetDef ResourceProperties[] = { + {"size", (getter)resource_get_size, NULL, "Size of the resource in bytes", NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static void resource_dealloc(ResourceObject *self) +{ + if (self->hrsrc) + Rsrc_free_resource(self->hrsrc); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int resource_init(ResourceObject *self, PyObject *args, PyObject *kwds) +{ + self->hrsrc = (HRSRC)NULL; + return 0; +} + +PyTypeObject ResourceType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "upiwin.Resource", + .tp_doc = "Resource object", + .tp_basicsize = sizeof(ResourceObject), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = PyType_GenericNew, + .tp_init = (initproc)resource_init, + .tp_dealloc = (destructor)resource_dealloc, + .tp_methods = ResourceMethods, + .tp_getset = ResourceProperties +}; + +HRESULT Epython_register_resources(PyObject *module) +{ + if (PyType_Ready(&ResFileType) < 0) + return E_FAIL; + if (PyType_Ready(&ResourceType) < 0) + return E_FAIL; + + Py_INCREF(&ResFileType); + if (PyModule_AddObject(module, "ResFile", (PyObject *)(&ResFileType)) < 0) + { + Py_DECREF(&ResFileType); + return E_FAIL; + } + + Py_INCREF(&ResourceType); + if (PyModule_AddObject(module, "Resource", (PyObject *)(&ResourceType)) < 0) + { + Py_DECREF(&ResourceType); + return E_FAIL; + } + return S_OK; +} diff --git a/src/ep_types.h b/src/ep_types.h index 751cc5a..ca5f155 100755 --- a/src/ep_types.h +++ b/src/ep_types.h @@ -1,12 +1,12 @@ /* * UPIWIN - Micro Pi Windowing Framework Kernel * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -27,6 +27,7 @@ #include "gfxobj.h" #include "devctxt.h" #include "bitmap.h" +#include "resources.h" typedef struct tagBitmapObject { PyObject_HEAD @@ -39,8 +40,20 @@ typedef struct tagDevCtxtObject { BitmapObject *selected_bitmap; } DevCtxtObject; +typedef struct tagResFileObject { + PyObject_HEAD + HRESFILE hresfile; +} ResFileObject; + +typedef struct tagResourceObject { + PyObject_HEAD + HRSRC hrsrc; +} ResourceObject; + extern PyTypeObject DevCtxtType; extern PyTypeObject BitmapType; +extern PyTypeObject ResFileType; +extern PyTypeObject ResourceType; extern PyObject *Epython_wrap_bitmap(PBITMAP pbmp); diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 30be19c..4934473 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -117,6 +117,12 @@ PyObject *Epython_init_upiwin_module(void) return NULL; } + if (FAILED(Epython_register_resources(module))) + { + Py_DECREF(module); + return NULL; + } + /* set up the module state */ pstate = (PUPIWIN_STATE)PyModule_GetState(module); pstate->backlight_on = TRUE;