static const char PyCursesVersion[] = "2.1";
#include "Python.h"
#include "py_curses.h"
#include <panel.h>
typedef struct {
PyObject *PyCursesError;
PyTypeObject *PyCursesPanel_Type;
} _curses_panel_state;
static inline _curses_panel_state *
get_curses_panel_state(PyObject *module)
{
void *state = PyModule_GetState(module);
assert(state != NULL);
return (_curses_panel_state *)state;
}
static int
_curses_panel_clear(PyObject *mod)
{
_curses_panel_state *state = get_curses_panel_state(mod);
Py_CLEAR(state->PyCursesError);
Py_CLEAR(state->PyCursesPanel_Type);
return 0;
}
static int
_curses_panel_traverse(PyObject *mod, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(mod));
_curses_panel_state *state = get_curses_panel_state(mod);
Py_VISIT(state->PyCursesError);
Py_VISIT(state->PyCursesPanel_Type);
return 0;
}
static void
_curses_panel_free(void *mod)
{
_curses_panel_clear((PyObject *) mod);
}
static PyObject *
PyCursesCheckERR(_curses_panel_state *state, int code, const char *fname)
{
if (code != ERR) {
Py_RETURN_NONE;
}
else {
if (fname == NULL) {
PyErr_SetString(state->PyCursesError, catchall_ERR);
}
else {
PyErr_Format(state->PyCursesError, "%s() returned ERR", fname);
}
return NULL;
}
}
typedef struct {
PyObject_HEAD
PANEL *pan;
PyCursesWindowObject *wo;
} PyCursesPanelObject;
typedef struct _list_of_panels {
PyCursesPanelObject *po;
struct _list_of_panels *next;
} list_of_panels;
static list_of_panels *lop;
static int
insert_lop(PyCursesPanelObject *po)
{
list_of_panels *new;
if ((new = (list_of_panels *)PyMem_Malloc(sizeof(list_of_panels))) == NULL) {
PyErr_NoMemory();
return -1;
}
new->po = po;
new->next = lop;
lop = new;
return 0;
}
static void
remove_lop(PyCursesPanelObject *po)
{
list_of_panels *temp, *n;
temp = lop;
if (temp->po == po) {
lop = temp->next;
PyMem_Free(temp);
return;
}
while (temp->next == NULL || temp->next->po != po) {
if (temp->next == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"remove_lop: can't find Panel Object");
return;
}
temp = temp->next;
}
n = temp->next->next;
PyMem_Free(temp->next);
temp->next = n;
return;
}
static PyCursesPanelObject *
find_po(PANEL *pan)
{
list_of_panels *temp;
for (temp = lop; temp->po->pan != pan; temp = temp->next)
if (temp->next == NULL) return NULL;
return temp->po;
}
#include "clinic/_curses_panel.c.h"
static PyObject *
_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
return PyCursesCheckERR(state, bottom_panel(self->pan), "bottom");
}
static PyObject *
_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
return PyCursesCheckERR(state, hide_panel(self->pan), "hide");
}
static PyObject *
_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
return PyCursesCheckERR(state, show_panel(self->pan), "show");
}
static PyObject *
_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
return PyCursesCheckERR(state, top_panel(self->pan), "top");
}
static PyObject *
PyCursesPanel_New(_curses_panel_state *state, PANEL *pan,
PyCursesWindowObject *wo)
{
PyCursesPanelObject *po = PyObject_New(PyCursesPanelObject,
state->PyCursesPanel_Type);
if (po == NULL) {
return NULL;
}
po->pan = pan;
if (insert_lop(po) < 0) {
po->wo = NULL;
Py_DECREF(po);
return NULL;
}
po->wo = (PyCursesWindowObject*)Py_NewRef(wo);
return (PyObject *)po;
}
static void
PyCursesPanel_Dealloc(PyCursesPanelObject *po)
{
PyObject *tp, *obj;
tp = (PyObject *) Py_TYPE(po);
obj = (PyObject *) panel_userptr(po->pan);
if (obj) {
(void)set_panel_userptr(po->pan, NULL);
Py_DECREF(obj);
}
(void)del_panel(po->pan);
if (po->wo != NULL) {
Py_DECREF(po->wo);
remove_lop(po);
}
PyObject_Free(po);
Py_DECREF(tp);
}
static PyObject *
_curses_panel_panel_above_impl(PyCursesPanelObject *self)
{
PANEL *pan;
PyCursesPanelObject *po;
pan = panel_above(self->pan);
if (pan == NULL) {
Py_RETURN_NONE;
}
po = find_po(pan);
if (po == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"panel_above: can't find Panel Object");
return NULL;
}
return Py_NewRef(po);
}
static PyObject *
_curses_panel_panel_below_impl(PyCursesPanelObject *self)
{
PANEL *pan;
PyCursesPanelObject *po;
pan = panel_below(self->pan);
if (pan == NULL) {
Py_RETURN_NONE;
}
po = find_po(pan);
if (po == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"panel_below: can't find Panel Object");
return NULL;
}
return Py_NewRef(po);
}
static PyObject *
_curses_panel_panel_hidden_impl(PyCursesPanelObject *self)
{
if (panel_hidden(self->pan))
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
static PyObject *
_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls,
int y, int x)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
return PyCursesCheckERR(state, move_panel(self->pan, y, x), "move_panel");
}
static PyObject *
_curses_panel_panel_window_impl(PyCursesPanelObject *self)
{
return Py_NewRef(self->wo);
}
static PyObject *
_curses_panel_panel_replace_impl(PyCursesPanelObject *self,
PyTypeObject *cls,
PyCursesWindowObject *win)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
PyCursesPanelObject *po = find_po(self->pan);
if (po == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"replace_panel: can't find Panel Object");
return NULL;
}
int rtn = replace_panel(self->pan, win->win);
if (rtn == ERR) {
PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR");
return NULL;
}
Py_SETREF(po->wo, (PyCursesWindowObject*)Py_NewRef(win));
Py_RETURN_NONE;
}
static PyObject *
_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
PyTypeObject *cls, PyObject *obj)
{
PyCursesInitialised;
Py_INCREF(obj);
PyObject *oldobj = (PyObject *) panel_userptr(self->pan);
int rc = set_panel_userptr(self->pan, (void*)obj);
if (rc == ERR) {
Py_DECREF(obj);
}
else {
Py_XDECREF(oldobj);
}
_curses_panel_state *state = PyType_GetModuleState(cls);
return PyCursesCheckERR(state, rc, "set_panel_userptr");
}
static PyObject *
_curses_panel_panel_userptr_impl(PyCursesPanelObject *self,
PyTypeObject *cls)
{
_curses_panel_state *state = PyType_GetModuleState(cls);
PyCursesInitialised;
PyObject *obj = (PyObject *) panel_userptr(self->pan);
if (obj == NULL) {
PyErr_SetString(state->PyCursesError, "no userptr set");
return NULL;
}
return Py_NewRef(obj);
}
static PyMethodDef PyCursesPanel_Methods[] = {
_CURSES_PANEL_PANEL_ABOVE_METHODDEF
_CURSES_PANEL_PANEL_BELOW_METHODDEF
_CURSES_PANEL_PANEL_BOTTOM_METHODDEF
_CURSES_PANEL_PANEL_HIDDEN_METHODDEF
_CURSES_PANEL_PANEL_HIDE_METHODDEF
_CURSES_PANEL_PANEL_MOVE_METHODDEF
_CURSES_PANEL_PANEL_REPLACE_METHODDEF
_CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF
_CURSES_PANEL_PANEL_SHOW_METHODDEF
_CURSES_PANEL_PANEL_TOP_METHODDEF
_CURSES_PANEL_PANEL_USERPTR_METHODDEF
_CURSES_PANEL_PANEL_WINDOW_METHODDEF
{NULL, NULL}
};
static PyType_Slot PyCursesPanel_Type_slots[] = {
{Py_tp_dealloc, PyCursesPanel_Dealloc},
{Py_tp_methods, PyCursesPanel_Methods},
{0, 0},
};
static PyType_Spec PyCursesPanel_Type_spec = {
.name = "_curses_panel.panel",
.basicsize = sizeof(PyCursesPanelObject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
.slots = PyCursesPanel_Type_slots
};
static PyObject *
_curses_panel_bottom_panel_impl(PyObject *module)
{
PANEL *pan;
PyCursesPanelObject *po;
PyCursesInitialised;
pan = panel_above(NULL);
if (pan == NULL) {
Py_RETURN_NONE;
}
po = find_po(pan);
if (po == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"panel_above: can't find Panel Object");
return NULL;
}
return Py_NewRef(po);
}
static PyObject *
_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win)
{
_curses_panel_state *state = get_curses_panel_state(module);
PANEL *pan = new_panel(win->win);
if (pan == NULL) {
PyErr_SetString(state->PyCursesError, catchall_NULL);
return NULL;
}
return (PyObject *)PyCursesPanel_New(state, pan, win);
}
static PyObject *
_curses_panel_top_panel_impl(PyObject *module)
{
PANEL *pan;
PyCursesPanelObject *po;
PyCursesInitialised;
pan = panel_below(NULL);
if (pan == NULL) {
Py_RETURN_NONE;
}
po = find_po(pan);
if (po == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"panel_below: can't find Panel Object");
return NULL;
}
return Py_NewRef(po);
}
static PyObject *
_curses_panel_update_panels_impl(PyObject *module)
{
PyCursesInitialised;
update_panels();
Py_RETURN_NONE;
}
static PyMethodDef PyCurses_methods[] = {
_CURSES_PANEL_BOTTOM_PANEL_METHODDEF
_CURSES_PANEL_NEW_PANEL_METHODDEF
_CURSES_PANEL_TOP_PANEL_METHODDEF
_CURSES_PANEL_UPDATE_PANELS_METHODDEF
{NULL, NULL}
};
static int
_curses_panel_exec(PyObject *mod)
{
_curses_panel_state *state = get_curses_panel_state(mod);
state->PyCursesPanel_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
mod, &PyCursesPanel_Type_spec, NULL);
if (state->PyCursesPanel_Type == NULL) {
return -1;
}
if (PyModule_AddType(mod, state->PyCursesPanel_Type) < 0) {
return -1;
}
import_curses();
if (PyErr_Occurred()) {
return -1;
}
state->PyCursesError = PyErr_NewException(
"_curses_panel.error", NULL, NULL);
if (PyModule_AddObject(mod, "error", Py_NewRef(state->PyCursesError)) < 0) {
Py_DECREF(state->PyCursesError);
return -1;
}
PyObject *v = PyUnicode_FromString(PyCursesVersion);
if (v == NULL) {
return -1;
}
PyObject *d = PyModule_GetDict(mod);
if (PyDict_SetItemString(d, "version", v) < 0) {
Py_DECREF(v);
return -1;
}
if (PyDict_SetItemString(d, "__version__", v) < 0) {
Py_DECREF(v);
return -1;
}
Py_DECREF(v);
return 0;
}
static PyModuleDef_Slot _curses_slots[] = {
{Py_mod_exec, _curses_panel_exec},
{Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
{0, NULL}
};
static struct PyModuleDef _curses_panelmodule = {
PyModuleDef_HEAD_INIT,
.m_name = "_curses_panel",
.m_size = sizeof(_curses_panel_state),
.m_methods = PyCurses_methods,
.m_slots = _curses_slots,
.m_traverse = _curses_panel_traverse,
.m_clear = _curses_panel_clear,
.m_free = _curses_panel_free
};
PyMODINIT_FUNC
PyInit__curses_panel(void)
{
return PyModuleDef_Init(&_curses_panelmodule);
}