/* * 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 *wrap_resource_file_handle(HRESFILE handle) { PyObject *rc = NULL, *args, *kwargs; ResFileObject *presfile; 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); } return rc; } static PyObject *resfile_load_classmethod(ResFileType *cls, PyObject *args) { const char *filename; PyObject *rc = NULL; HRESULT hr; HRESFILE handle; if (!PyArg_ParseTuple(args, "s", &filename)) return NULL; hr = Rsrc_load_file((PCSTR)filename, &handle); if (SUCCEEDED(hr)) { rc = wrap_resource_file_handle(handle); 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 *wrap_resource_handle(HRSRC hrsrc) { PyObject *rc = NULL, *args, *kwargs; ResourceObject *pres; 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); } return rc; } static PyObject *resfile_find_resource(ResFileObject *self, PyObject *args) { const char *name; PyObject *rc = NULL; 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)) { rc = wrap_resource_handle(hrsrc); 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 ''%s' (%08x)", name, 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; }