upiwin/src/ep_resources.c

248 lines
6.2 KiB
C

/*
* 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 <string.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#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(PyTypeObject *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;
}