blob: bc894479dee1f8ce1188498fc776bffbfefa2d49 [file] [log] [blame]
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +00001/*
2 * Interface to the ncurses panel library
3 *
4 * Original version by Thomas Gellekum
5 */
6
7/* Release Number */
8
9static char *PyCursesVersion = "2.1";
10
11/* Includes */
12
13#include "Python.h"
14
15#include "py_curses.h"
16
17#include <panel.h>
18
19static PyObject *PyCursesError;
20
21
22/* Utility Functions */
23
24/*
Antoine Pitrouc83ea132010-05-09 14:46:46 +000025 * Check the return code from a curses function and return None
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000026 * or raise an exception as appropriate.
27 */
28
29static PyObject *
30PyCursesCheckERR(int code, char *fname)
31{
32 if (code != ERR) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000033 Py_INCREF(Py_None);
34 return Py_None;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000035 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000036 if (fname == NULL) {
37 PyErr_SetString(PyCursesError, catchall_ERR);
38 } else {
39 PyErr_Format(PyCursesError, "%s() returned ERR", fname);
40 }
41 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000042 }
43}
44
45/*****************************************************************************
46 The Panel Object
47******************************************************************************/
48
49/* Definition of the panel object and panel type */
50
51typedef struct {
52 PyObject_HEAD
53 PANEL *pan;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000054 PyCursesWindowObject *wo; /* for reference counts */
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000055} PyCursesPanelObject;
56
57PyTypeObject PyCursesPanel_Type;
58
Antoine Pitrouc83ea132010-05-09 14:46:46 +000059#define PyCursesPanel_Check(v) (Py_TYPE(v) == &PyCursesPanel_Type)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000060
61/* Some helper functions. The problem is that there's always a window
62 associated with a panel. To ensure that Python's GC doesn't pull
63 this window from under our feet we need to keep track of references
64 to the corresponding window object within Python. We can't use
65 dupwin(oldwin) to keep a copy of the curses WINDOW because the
66 contents of oldwin is copied only once; code like
67
68 win = newwin(...)
69 pan = win.panel()
70 win.addstr(some_string)
71 pan.window().addstr(other_string)
72
73 will fail. */
74
75/* We keep a linked list of PyCursesPanelObjects, lop. A list should
76 suffice, I don't expect more than a handful or at most a few
77 dozens of panel objects within a typical program. */
78typedef struct _list_of_panels {
79 PyCursesPanelObject *po;
80 struct _list_of_panels *next;
81} list_of_panels;
82
83/* list anchor */
84static list_of_panels *lop;
85
86/* Insert a new panel object into lop */
87static int
88insert_lop(PyCursesPanelObject *po)
89{
90 list_of_panels *new;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000091
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000092 if ((new = (list_of_panels *)malloc(sizeof(list_of_panels))) == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 PyErr_NoMemory();
94 return -1;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +000095 }
96 new->po = po;
97 new->next = lop;
98 lop = new;
99 return 0;
100}
101
102/* Remove the panel object from lop */
103static void
104remove_lop(PyCursesPanelObject *po)
105{
106 list_of_panels *temp, *n;
107
108 temp = lop;
109 if (temp->po == po) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000110 lop = temp->next;
111 free(temp);
112 return;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000113 }
Thomas Wouters47f003d2006-03-07 13:38:14 +0000114 while (temp->next == NULL || temp->next->po != po) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 if (temp->next == NULL) {
116 PyErr_SetString(PyExc_RuntimeError,
117 "remove_lop: can't find Panel Object");
118 return;
119 }
120 temp = temp->next;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000121 }
122 n = temp->next->next;
123 free(temp->next);
124 temp->next = n;
125 return;
126}
127
128/* Return the panel object that corresponds to pan */
129static PyCursesPanelObject *
130find_po(PANEL *pan)
131{
132 list_of_panels *temp;
133 for (temp = lop; temp->po->pan != pan; temp = temp->next)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000134 if (temp->next == NULL) return NULL; /* not found!? */
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000135 return temp->po;
136}
137
138/* Function Prototype Macros - They are ugly but very, very useful. ;-)
139
140 X - function name
141 TYPE - parameter Type
142 ERGSTR - format string for construction of the return value
143 PARSESTR - format string for argument parsing */
144
145#define Panel_NoArgNoReturnFunction(X) \
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000146static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
147{ return PyCursesCheckERR(X(self->pan), # X); }
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000148
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000149#define Panel_NoArgTrueFalseFunction(X) \
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000150static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000151{ \
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000152 if (X (self->pan) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
153 else { Py_INCREF(Py_True); return Py_True; } }
154
155#define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
Fred Drake4e36d582000-12-23 05:46:23 +0000156static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000157{ \
158 TYPE arg1, arg2; \
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000159 if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000160 return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); }
161
162/* ------------- PANEL routines --------------- */
163
164Panel_NoArgNoReturnFunction(bottom_panel)
165Panel_NoArgNoReturnFunction(hide_panel)
166Panel_NoArgNoReturnFunction(show_panel)
167Panel_NoArgNoReturnFunction(top_panel)
168Panel_NoArgTrueFalseFunction(panel_hidden)
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000169Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x")
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000170
171/* Allocation and deallocation of Panel Objects */
172
173static PyObject *
174PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo)
175{
176 PyCursesPanelObject *po;
177
178 po = PyObject_NEW(PyCursesPanelObject, &PyCursesPanel_Type);
179 if (po == NULL) return NULL;
180 po->pan = pan;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000181 if (insert_lop(po) < 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000182 po->wo = NULL;
183 Py_DECREF(po);
184 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000185 }
Victor Stinner2379bb62010-03-03 21:53:41 +0000186 po->wo = wo;
187 Py_INCREF(wo);
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000188 return (PyObject *)po;
189}
190
191static void
192PyCursesPanel_Dealloc(PyCursesPanelObject *po)
193{
Serhiy Storchaka22d89422016-05-09 00:11:59 +0300194 PyObject *obj = (PyObject *) panel_userptr(po->pan);
195 if (obj) {
196 (void)set_panel_userptr(po->pan, NULL);
197 Py_DECREF(obj);
198 }
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000199 (void)del_panel(po->pan);
Victor Stinner2379bb62010-03-03 21:53:41 +0000200 if (po->wo != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000201 Py_DECREF(po->wo);
202 remove_lop(po);
Victor Stinner2379bb62010-03-03 21:53:41 +0000203 }
Michael W. Hudsoncf6bfe42002-01-30 15:47:34 +0000204 PyObject_DEL(po);
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000205}
206
207/* panel_above(NULL) returns the bottom panel in the stack. To get
208 this behaviour we use curses.panel.bottom_panel(). */
209static PyObject *
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000210PyCursesPanel_above(PyCursesPanelObject *self)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000211{
212 PANEL *pan;
213 PyCursesPanelObject *po;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000214
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000215 pan = panel_above(self->pan);
216
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000217 if (pan == NULL) { /* valid output, it means the calling panel
218 is on top of the stack */
219 Py_INCREF(Py_None);
220 return Py_None;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000221 }
222 po = find_po(pan);
223 if (po == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000224 PyErr_SetString(PyExc_RuntimeError,
225 "panel_above: can't find Panel Object");
226 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000227 }
228 Py_INCREF(po);
229 return (PyObject *)po;
230}
231
232/* panel_below(NULL) returns the top panel in the stack. To get
Andrew M. Kuchlingae89af92001-01-19 15:35:26 +0000233 this behaviour we use curses.panel.top_panel(). */
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000234static PyObject *
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000235PyCursesPanel_below(PyCursesPanelObject *self)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000236{
237 PANEL *pan;
238 PyCursesPanelObject *po;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000239
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000240 pan = panel_below(self->pan);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000241
242 if (pan == NULL) { /* valid output, it means the calling panel
243 is on the bottom of the stack */
244 Py_INCREF(Py_None);
245 return Py_None;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000246 }
247 po = find_po(pan);
248 if (po == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000249 PyErr_SetString(PyExc_RuntimeError,
250 "panel_below: can't find Panel Object");
251 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000252 }
253 Py_INCREF(po);
254 return (PyObject *)po;
255}
256
257static PyObject *
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000258PyCursesPanel_window(PyCursesPanelObject *self)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000259{
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000260 Py_INCREF(self->wo);
261 return (PyObject *)self->wo;
262}
263
264static PyObject *
265PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
266{
267 PyCursesPanelObject *po;
268 PyCursesWindowObject *temp;
269 int rtn;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000270
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000271 if (PyTuple_Size(args) != 1) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 PyErr_SetString(PyExc_TypeError, "replace requires one argument");
273 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000274 }
275 if (!PyArg_ParseTuple(args, "O!;window object",
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 &PyCursesWindow_Type, &temp))
277 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000278
279 po = find_po(self->pan);
280 if (po == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000281 PyErr_SetString(PyExc_RuntimeError,
282 "replace_panel: can't find Panel Object");
283 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000284 }
285
286 rtn = replace_panel(self->pan, temp->win);
287 if (rtn == ERR) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000288 PyErr_SetString(PyCursesError, "replace_panel() returned ERR");
289 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000290 }
Serhiy Storchaka5951f232015-12-24 10:35:35 +0200291 Py_INCREF(temp);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +0300292 Py_SETREF(po->wo, temp);
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000293 Py_INCREF(Py_None);
294 return Py_None;
295}
296
297static PyObject *
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000298PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000299{
Andrew Kuchlinga49dcc52013-06-15 13:53:10 -0400300 PyObject *oldobj;
Andrew Kuchlingaa6c2972013-06-22 12:33:05 -0400301 int rc;
Andrew Kuchlinga49dcc52013-06-15 13:53:10 -0400302 PyCursesInitialised;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000303 Py_INCREF(obj);
Andrew Kuchlingaa6c2972013-06-22 12:33:05 -0400304 oldobj = (PyObject *) panel_userptr(self->pan);
305 rc = set_panel_userptr(self->pan, (void*)obj);
306 if (rc == ERR) {
307 /* In case of an ncurses error, decref the new object again */
308 Py_DECREF(obj);
309 }
310 Py_XDECREF(oldobj);
311 return PyCursesCheckERR(rc, "set_panel_userptr");
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000312}
313
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000314static PyObject *
315PyCursesPanel_userptr(PyCursesPanelObject *self)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000316{
317 PyObject *obj;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000318 PyCursesInitialised;
Fred Drake4e36d582000-12-23 05:46:23 +0000319 obj = (PyObject *) panel_userptr(self->pan);
Neal Norwitz5e3d8622006-01-09 06:24:35 +0000320 if (obj == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000321 PyErr_SetString(PyCursesError, "no userptr set");
322 return NULL;
Neal Norwitz5e3d8622006-01-09 06:24:35 +0000323 }
324
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000325 Py_INCREF(obj);
326 return obj;
327}
328
329
330/* Module interface */
331
332static PyMethodDef PyCursesPanel_Methods[] = {
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000333 {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS},
334 {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS},
335 {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS},
336 {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS},
337 {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS},
338 {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS},
Neal Norwitz01b26942002-03-31 14:55:17 +0000339 {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS},
Martin v. Löwisc0e16712002-01-17 23:08:27 +0000340 {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O},
341 {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS},
342 {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS},
343 {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS},
344 {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000345 {NULL, NULL} /* sentinel */
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000346};
347
348static PyObject *
349PyCursesPanel_GetAttr(PyCursesPanelObject *self, char *name)
350{
351 return Py_FindMethod(PyCursesPanel_Methods, (PyObject *)self, name);
352}
353
354/* -------------------------------------------------------*/
355
356PyTypeObject PyCursesPanel_Type = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000357 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000358 "_curses_panel.curses panel", /*tp_name*/
359 sizeof(PyCursesPanelObject), /*tp_basicsize*/
360 0, /*tp_itemsize*/
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000361 /* methods */
362 (destructor)PyCursesPanel_Dealloc, /*tp_dealloc*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000363 0, /*tp_print*/
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000364 (getattrfunc)PyCursesPanel_GetAttr, /*tp_getattr*/
365 (setattrfunc)0, /*tp_setattr*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000366 0, /*tp_compare*/
367 0, /*tp_repr*/
368 0, /*tp_as_number*/
369 0, /*tp_as_sequence*/
370 0, /*tp_as_mapping*/
371 0, /*tp_hash*/
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000372};
373
374/* Wrapper for panel_above(NULL). This function returns the bottom
375 panel of the stack, so it's renamed to bottom_panel().
376 panel.above() *requires* a panel object in the first place which
377 may be undesirable. */
378static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000379PyCurses_bottom_panel(PyObject *self)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000380{
381 PANEL *pan;
382 PyCursesPanelObject *po;
383
384 PyCursesInitialised;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000385
386 pan = panel_above(NULL);
387
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000388 if (pan == NULL) { /* valid output, it means
389 there's no panel at all */
390 Py_INCREF(Py_None);
391 return Py_None;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000392 }
393 po = find_po(pan);
394 if (po == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000395 PyErr_SetString(PyExc_RuntimeError,
396 "panel_above: can't find Panel Object");
397 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000398 }
399 Py_INCREF(po);
400 return (PyObject *)po;
401}
402
403static PyObject *
404PyCurses_new_panel(PyObject *self, PyObject *args)
405{
406 PyCursesWindowObject *win;
407 PANEL *pan;
408
Fred Drake4e36d582000-12-23 05:46:23 +0000409 if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win))
410 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000411 pan = new_panel(win->win);
412 if (pan == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000413 PyErr_SetString(PyCursesError, catchall_NULL);
414 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000415 }
416 return (PyObject *)PyCursesPanel_New(pan, win);
417}
418
419
420/* Wrapper for panel_below(NULL). This function returns the top panel
421 of the stack, so it's renamed to top_panel(). panel.below()
422 *requires* a panel object in the first place which may be
423 undesirable. */
424static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000425PyCurses_top_panel(PyObject *self)
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000426{
427 PANEL *pan;
428 PyCursesPanelObject *po;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000429
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000430 PyCursesInitialised;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000431
432 pan = panel_below(NULL);
433
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000434 if (pan == NULL) { /* valid output, it means
435 there's no panel at all */
436 Py_INCREF(Py_None);
437 return Py_None;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000438 }
439 po = find_po(pan);
440 if (po == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000441 PyErr_SetString(PyExc_RuntimeError,
442 "panel_below: can't find Panel Object");
443 return NULL;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000444 }
445 Py_INCREF(po);
446 return (PyObject *)po;
447}
448
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000449static PyObject *PyCurses_update_panels(PyObject *self)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000450{
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000451 PyCursesInitialised;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000452 update_panels();
453 Py_INCREF(Py_None);
454 return Py_None;
455}
456
457
458/* List of functions defined in the module */
459
460static PyMethodDef PyCurses_methods[] = {
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000461 {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS},
462 {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS},
463 {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS},
464 {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000465 {NULL, NULL} /* sentinel */
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000466};
467
468/* Initialization function for the module */
469
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000470PyMODINIT_FUNC
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000471init_curses_panel(void)
472{
473 PyObject *m, *d, *v;
474
Fred Drake2174f802001-01-27 18:58:04 +0000475 /* Initialize object type */
Christian Heimese93237d2007-12-19 02:37:44 +0000476 Py_TYPE(&PyCursesPanel_Type) = &PyType_Type;
Guido van Rossuma120ffc2001-01-22 15:29:14 +0000477
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000478 import_curses();
Fred Drake2174f802001-01-27 18:58:04 +0000479
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000480 /* Create the module and add the functions */
481 m = Py_InitModule("_curses_panel", PyCurses_methods);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000482 if (m == NULL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000483 return;
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000484 d = PyModule_GetDict(m);
485
486 /* For exception _curses_panel.error */
487 PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL);
488 PyDict_SetItemString(d, "error", PyCursesError);
489
490 /* Make the version available */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000491 v = PyString_FromString(PyCursesVersion);
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000492 PyDict_SetItemString(d, "version", v);
493 PyDict_SetItemString(d, "__version__", v);
494 Py_DECREF(v);
Andrew M. Kuchling7b59ed22000-12-22 21:54:12 +0000495}