]> git.ipfire.org Git - thirdparty/newt.git/blame - snack.c
0.52.24
[thirdparty/newt.git] / snack.c
CommitLineData
d638bf45 1
05ace545 2#include "Python.h"
d638bf45 3#include "config.h"
4
5#ifdef HAVE_ALLOCA_H
6#include <alloca.h>
7#endif
8
80d03bd8 9#include <errno.h>
10#include <fcntl.h>
11#include <sys/stat.h>
12#include <sys/time.h>
13#include <unistd.h>
14
ba3eb78a 15#include "structmember.h"
feef2cb5 16#include "nls.h"
80d03bd8 17#include "newt.h"
ce11acc8 18#include "newt_pr.h"
80d03bd8 19
ba3eb78a
MK
20#if PY_MAJOR_VERSION >= 3
21 #define PyInt_FromLong PyLong_FromLong
22 #define PyInt_AsLong PyLong_AsLong
23 #define PyString_FromString PyUnicode_FromString
24 #define MOD_ERROR_VAL NULL
25 #define MOD_SUCCESS_VAL(val) val
26 #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
27#else
28 #define MOD_ERROR_VAL
29 #define MOD_SUCCESS_VAL(val)
30 #define MOD_INIT(name) void init##name(void)
31#endif
32
80d03bd8 33typedef struct snackWidget_s snackWidget;
34typedef struct snackGrid_s snackGrid;
35typedef struct snackForm_s snackForm;
36
5d678658 37struct callbackStruct {
06cf519e 38 PyObject * cb, * data;
39};
40
d7e202d6 41/* Integer to pointer, 64-bit-sane */
42#define I2P(x) ((void *)(long)(x))
43
1dfa0cfa 44static struct callbackStruct suspend;
72b71fa6 45static struct callbackStruct helpCallback;
1dfa0cfa 46
80d03bd8 47static void emptyDestructor(PyObject * s);
48
49static snackWidget * buttonWidget(PyObject * s, PyObject * args);
f954a19b 50static snackWidget * compactbuttonWidget(PyObject * s, PyObject * args);
80d03bd8 51static PyObject * centeredWindow(PyObject * s, PyObject * args);
52static snackWidget * checkboxWidget(PyObject * s, PyObject * args);
53static PyObject * choiceWindow(PyObject * s, PyObject * args);
54static snackWidget * entryWidget(PyObject * s, PyObject * args);
75fb0452 55static PyObject * drawRootText(PyObject * s, PyObject * args);
f1aef30b 56static PyObject * doResume(PyObject * s, PyObject * args);
57static PyObject * doSuspend(PyObject * s, PyObject * args);
58static PyObject * doSuspend(PyObject * s, PyObject * args);
80d03bd8 59static snackForm * formCreate(PyObject * s, PyObject * args);
60static snackGrid * gridCreate(PyObject * s, PyObject * args);
61static PyObject * gridWrappedWindow(PyObject * s, PyObject * args);
62static PyObject * finishScreen(PyObject * s, PyObject * args);
63static PyObject * initScreen(PyObject * s, PyObject * args);
64static snackWidget * labelWidget(PyObject * s, PyObject * args);
6e25d997 65static snackWidget * listboxWidget(PyObject * s, PyObject * args);
80d03bd8 66static PyObject * messageWindow(PyObject * s, PyObject * args);
67static PyObject * openWindow(PyObject * s, PyObject * args);
75fb0452 68static PyObject * popHelpLine(PyObject * s, PyObject * args);
80d03bd8 69static PyObject * popWindow(PyObject * s, PyObject * args);
e5df813b 70static PyObject * popWindowNoRefresh(PyObject * s, PyObject * args);
75fb0452 71static PyObject * pushHelpLine(PyObject * s, PyObject * args);
80d03bd8 72static snackWidget * radioButtonWidget(PyObject * s, PyObject * args);
73static PyObject * refreshScreen(PyObject * s, PyObject * args);
3c3bb3d8 74static PyObject * setColor(PyObject * s, PyObject * args);
06cf519e 75static PyObject * scaleWidget(PyObject * s, PyObject * args);
76static PyObject * scaleSet(snackWidget * s, PyObject * args);
9f0ab2ac 77static PyObject * screenSize(PyObject * s, PyObject * args);
06cf519e 78static PyObject * setSuspendCallback(PyObject * s, PyObject * args);
72b71fa6 79static PyObject * setHelpCallback(PyObject * s, PyObject * args);
6e25d997 80static PyObject * reflowText(PyObject * s, PyObject * args);
81static snackWidget * textWidget(PyObject * s, PyObject * args);
80d03bd8 82static PyObject * ternaryWindow(PyObject * s, PyObject * args);
615bc463 83static snackWidget * checkboxTreeWidget(PyObject * s, PyObject * args, PyObject * kwargs);
ce11acc8 84static PyObject * pywstrlen(PyObject * s, PyObject * args);
ba3eb78a
MK
85static PyObject * widget_get_checkboxValue(PyObject *self, void *closure);
86static PyObject * widget_get_radioValue(PyObject *self, void *closure);
80d03bd8 87
88static PyMethodDef snackModuleMethods[] = {
89 { "button", (PyCFunction) buttonWidget, METH_VARARGS, NULL },
f954a19b 90 { "compactbutton", (PyCFunction) compactbuttonWidget, METH_VARARGS, NULL },
80d03bd8 91 { "checkbox", (PyCFunction) checkboxWidget, METH_VARARGS, NULL },
92 { "choice", choiceWindow, METH_VARARGS, NULL },
93 { "centeredwindow", centeredWindow, METH_VARARGS, NULL },
75fb0452 94 { "drawroottext", drawRootText, METH_VARARGS, NULL },
80d03bd8 95 { "entry", (PyCFunction) entryWidget, METH_VARARGS, NULL },
96 { "finish", finishScreen, METH_VARARGS, NULL },
97 { "form", (PyCFunction) formCreate, METH_VARARGS, NULL },
98 { "grid", (PyCFunction) gridCreate, METH_VARARGS, NULL },
99 { "gridwrappedwindow", gridWrappedWindow, METH_VARARGS, NULL },
72b71fa6 100 { "helpcallback", setHelpCallback, METH_VARARGS, NULL },
80d03bd8 101 { "init", initScreen, METH_VARARGS, NULL },
102 { "label", (PyCFunction) labelWidget, METH_VARARGS, NULL },
6e25d997 103 { "listbox", (PyCFunction) listboxWidget, METH_VARARGS, NULL },
80d03bd8 104 { "message", messageWindow, METH_VARARGS, NULL },
105 { "openwindow", openWindow, METH_VARARGS, NULL },
75fb0452 106 { "pophelpline", popHelpLine, METH_VARARGS, NULL },
80d03bd8 107 { "popwindow", popWindow, METH_VARARGS, NULL },
e5df813b 108 { "popwindownorefresh", popWindowNoRefresh, METH_VARARGS, NULL },
75fb0452 109 { "pushhelpline", pushHelpLine, METH_VARARGS, NULL },
80d03bd8 110 { "radiobutton", (PyCFunction) radioButtonWidget, METH_VARARGS, NULL },
6e25d997 111 { "reflow", (PyCFunction) reflowText, METH_VARARGS, NULL },
80d03bd8 112 { "refresh", refreshScreen, METH_VARARGS, NULL },
3c3bb3d8 113 { "setcolor", setColor, METH_VARARGS, NULL },
f1aef30b 114 { "resume", doResume, METH_VARARGS, NULL },
06cf519e 115 { "scale", scaleWidget, METH_VARARGS, NULL },
9f0ab2ac 116 { "size", screenSize, METH_VARARGS, NULL },
f1aef30b 117 { "suspend", doSuspend, METH_VARARGS, NULL },
06cf519e 118 { "suspendcallback", setSuspendCallback, METH_VARARGS, NULL },
80d03bd8 119 { "ternary", ternaryWindow, METH_VARARGS, NULL },
6e25d997 120 { "textbox", (PyCFunction) textWidget, METH_VARARGS, NULL },
615bc463 121 { "checkboxtree", (PyCFunction) checkboxTreeWidget, METH_VARARGS | METH_KEYWORDS, NULL },
ce11acc8 122 { "wstrlen", (PyCFunction) pywstrlen, METH_VARARGS | METH_KEYWORDS, NULL },
80d03bd8 123 { NULL }
124} ;
125
ba3eb78a
MK
126#if PY_MAJOR_VERSION >= 3
127static struct PyModuleDef moduledef = {
128 PyModuleDef_HEAD_INIT,
129 "_snack", /* m_name */
130 NULL, /* m_doc */
131 -1, /* m_size */
132 snackModuleMethods, /* m_methods */
133 NULL, /* m_reload */
134 NULL, /* m_traverse */
135 NULL, /* m_clear */
136 NULL, /* m_free */
137 };
138#endif
139
140static struct PyGetSetDef widget_getset[] = {
141 { "checkboxValue", widget_get_checkboxValue, 0, NULL, NULL },
142 { "radioValue", widget_get_radioValue, 0, NULL, NULL },
143 { NULL }
144};
145
80d03bd8 146struct snackGrid_s {
cf4cf78f 147 PyObject_HEAD
80d03bd8 148 newtGrid grid;
149} ;
150
80d03bd8 151static PyObject * gridPlace(snackGrid * s, PyObject * args);
152static PyObject * gridSetField(snackGrid * s, PyObject * args);
153
154static PyMethodDef gridMethods[] = {
155 { "place", (PyCFunction) gridPlace, METH_VARARGS, NULL },
156 { "setfield", (PyCFunction) gridSetField, METH_VARARGS, NULL },
157 { NULL }
158};
159
160static PyTypeObject snackGridType = {
ba3eb78a 161 PyVarObject_HEAD_INIT(&PyType_Type, 0)
80d03bd8 162 "snackgrid", /* tp_name */
163 sizeof(snackGrid), /* tp_size */
164 0, /* tp_itemsize */
6f481af2 165 emptyDestructor, /* tp_dealloc */
80d03bd8 166 0, /* tp_print */
ba3eb78a 167 0, /* tp_getattr */
80d03bd8 168 0, /* tp_setattr */
169 0, /* tp_compare */
170 0, /* tp_repr */
171 0, /* tp_as_number */
172 0, /* tp_as_sequence */
6f481af2 173 0, /* tp_as_mapping */
ba3eb78a
MK
174 0, /* tp_hash */
175 0, /* tp_call */
176 0, /* tp_str */
177 PyObject_GenericGetAttr, /* tp_getattro */
178 0, /* tp_setattro */
179 0, /* tp_as_buffer */
180 Py_TPFLAGS_DEFAULT, /* tp_flags */
181 0, /* tp_doc */
182 0, /* tp_traverse */
183 0, /* tp_clear */
184 0, /* tp_richcompare */
185 0, /* tp_weaklistoffset */
186 0, /* tp_iter */
187 0, /* tp_iternext */
188 gridMethods /* tp_methods */
80d03bd8 189};
190
191struct snackForm_s {
cf4cf78f 192 PyObject_HEAD
80d03bd8 193 newtComponent fo;
194} ;
195
80d03bd8 196static PyObject * formAdd(snackForm * s, PyObject * args);
bd38d47e 197static PyObject * formDraw(snackForm * s, PyObject * args);
80d03bd8 198static PyObject * formRun(snackForm * s, PyObject * args);
ea59ae12 199static PyObject * formHotKey(snackForm * s, PyObject * args);
5d678658 200static PyObject * formSetCurrent(snackForm * form, PyObject * args);
73390860 201static PyObject * formSetTimer(snackForm * form, PyObject * args);
d7e202d6 202static PyObject * formWatchFD(snackForm * form, PyObject * args);
80d03bd8 203
204static PyMethodDef formMethods[] = {
205 { "add", (PyCFunction) formAdd, METH_VARARGS, NULL },
bd38d47e 206 { "draw", (PyCFunction) formDraw, METH_VARARGS, NULL },
80d03bd8 207 { "run", (PyCFunction) formRun, METH_VARARGS, NULL },
ea59ae12 208 { "addhotkey", (PyCFunction) formHotKey, METH_VARARGS, NULL },
5d678658 209 { "setcurrent", (PyCFunction) formSetCurrent, METH_VARARGS, NULL },
73390860 210 { "settimer", (PyCFunction) formSetTimer, METH_VARARGS, NULL },
d7e202d6 211 { "watchfd", (PyCFunction) formWatchFD, METH_VARARGS, NULL },
80d03bd8 212 { NULL }
213};
214
215static PyTypeObject snackFormType = {
ba3eb78a 216 PyVarObject_HEAD_INIT(&PyType_Type, 0)
80d03bd8 217 "snackform", /* tp_name */
218 sizeof(snackForm), /* tp_size */
219 0, /* tp_itemsize */
6f481af2 220 emptyDestructor, /* tp_dealloc */
80d03bd8 221 0, /* tp_print */
ba3eb78a 222 0, /* tp_getattr */
80d03bd8 223 0, /* tp_setattr */
224 0, /* tp_compare */
225 0, /* tp_repr */
226 0, /* tp_as_number */
227 0, /* tp_as_sequence */
6f481af2 228 0, /* tp_as_mapping */
ba3eb78a
MK
229 0, /* tp_hash */
230 0, /* tp_call */
231 0, /* tp_str */
232 PyObject_GenericGetAttr, /* tp_getattro */
233 0, /* tp_setattro */
234 0, /* tp_as_buffer */
235 Py_TPFLAGS_DEFAULT, /* tp_flags */
236 0, /* tp_doc */
237 0, /* tp_traverse */
238 0, /* tp_clear */
239 0, /* tp_richcompare */
240 0, /* tp_weaklistoffset */
241 0, /* tp_iter */
242 0, /* tp_iternext */
243 formMethods /* tp_methods */
80d03bd8 244};
245
246struct snackWidget_s {
cf4cf78f 247 PyObject_HEAD
80d03bd8 248 newtComponent co;
249 char achar;
250 void * apointer;
6e25d997 251 int anint;
5d678658 252 struct callbackStruct scs;
80d03bd8 253} ;
254
6a703ca8 255static PyObject * widgetAddCallback(snackWidget * s, PyObject * args);
1dfa0cfa 256static void widgetDestructor(PyObject * s);
80d03bd8 257static PyObject * widgetEntrySetValue(snackWidget * s, PyObject * args);
522d3500 258static PyObject * widgetLabelText(snackWidget * s, PyObject * args);
92567bd5 259static PyObject * widgetLabelSetColors(snackWidget * s, PyObject * args);
6e25d997 260static PyObject * widgetListboxSetW(snackWidget * s, PyObject * args);
261static PyObject * widgetListboxAdd(snackWidget * s, PyObject * args);
a507b3ec 262static PyObject * widgetListboxIns(snackWidget * s, PyObject * args);
263static PyObject * widgetListboxDel(snackWidget * s, PyObject * args);
6e25d997 264static PyObject * widgetListboxGet(snackWidget * s, PyObject * args);
67faee66 265static PyObject * widgetListboxGetSel(snackWidget * s, PyObject * args);
99438c19 266static PyObject * widgetListboxSet(snackWidget * s, PyObject * args);
50c9056c 267static PyObject * widgetListboxClear(snackWidget * s, PyObject * args);
36f926a6 268static PyObject * widgetTextboxText(snackWidget * s, PyObject * args);
7dc27ce1 269static PyObject * widgetTextboxHeight(snackWidget * s, PyObject * args);
75d40644 270static PyObject * widgetCheckboxTreeAddItem(snackWidget * s, PyObject * args);
5d678658 271static PyObject * widgetCheckboxTreeGetSel(snackWidget * s, PyObject * args);
2b6641b1 272static PyObject * widgetCheckboxTreeGetCur(snackWidget * s, PyObject * args);
c895490d 273static PyObject * widgetCheckboxTreeSetEntry(snackWidget * s, PyObject * args);
d8c97d41 274static PyObject * widgetCheckboxTreeSetWidth(snackWidget * s, PyObject * args);
5160fc22 275static PyObject * widgetCheckboxTreeSetCurrent(snackWidget * s, PyObject * args);
c895490d 276static PyObject * widgetCheckboxTreeSetEntryValue(snackWidget * s, PyObject * args);
277static PyObject * widgetCheckboxTreeGetEntryValue(snackWidget * s, PyObject * args);
5d678658 278static PyObject * widgetEntrySetFlags(snackWidget * s, PyObject * args);
c573c71b 279static PyObject * widgetCheckboxSetFlags(snackWidget * s, PyObject * args);
870ff9eb 280static PyObject * widgetCheckboxSetValue(snackWidget * s, PyObject * args);
80d03bd8 281
282static PyMethodDef widgetMethods[] = {
6a703ca8 283 { "setCallback", (PyCFunction) widgetAddCallback, METH_VARARGS, NULL },
92567bd5 284 { "labelSetColors", (PyCFunction) widgetLabelSetColors, METH_VARARGS, NULL },
522d3500 285 { "labelText", (PyCFunction) widgetLabelText, METH_VARARGS, NULL },
36f926a6 286 { "textboxText", (PyCFunction) widgetTextboxText, METH_VARARGS, NULL },
7dc27ce1 287 { "textboxHeight", (PyCFunction) widgetTextboxHeight, METH_VARARGS, NULL },
80d03bd8 288 { "entrySetValue", (PyCFunction) widgetEntrySetValue, METH_VARARGS, NULL },
6e25d997 289 { "listboxAddItem", (PyCFunction) widgetListboxAdd, METH_VARARGS, NULL },
a507b3ec 290 { "listboxInsertItem", (PyCFunction) widgetListboxIns, METH_VARARGS, NULL },
6e25d997 291 { "listboxGetCurrent", (PyCFunction) widgetListboxGet, METH_VARARGS, NULL },
67faee66 292 { "listboxGetSelection", (PyCFunction) widgetListboxGetSel, METH_VARARGS, NULL },
99438c19 293 { "listboxSetCurrent", (PyCFunction) widgetListboxSet, METH_VARARGS, NULL },
6e25d997 294 { "listboxSetWidth", (PyCFunction) widgetListboxSetW, METH_VARARGS, NULL },
a507b3ec 295 { "listboxDeleteItem", (PyCFunction) widgetListboxDel, METH_VARARGS, NULL },
50c9056c 296 { "listboxClear", (PyCFunction) widgetListboxClear, METH_VARARGS, NULL },
06cf519e 297 { "scaleSet", (PyCFunction) scaleSet, METH_VARARGS, NULL },
75d40644 298 { "checkboxtreeAddItem", (PyCFunction) widgetCheckboxTreeAddItem,
f06c5a99 299 METH_VARARGS, NULL },
2b6641b1 300 { "checkboxtreeGetCurrent", (PyCFunction) widgetCheckboxTreeGetCur,
301 METH_VARARGS, NULL },
c895490d 302 { "checkboxtreeGetEntryValue", (PyCFunction) widgetCheckboxTreeGetEntryValue,
303 METH_VARARGS, NULL },
304 { "checkboxtreeSetEntry", (PyCFunction) widgetCheckboxTreeSetEntry,
305 METH_VARARGS, NULL },
d8c97d41 306 { "checkboxtreeSetWidth", (PyCFunction) widgetCheckboxTreeSetWidth, METH_VARARGS, NULL },
5160fc22 307 { "checkboxtreeSetCurrent", (PyCFunction) widgetCheckboxTreeSetCurrent,
308 METH_VARARGS, NULL },
c895490d 309 { "checkboxtreeSetEntryValue", (PyCFunction) widgetCheckboxTreeSetEntryValue,
310 METH_VARARGS, NULL },
f06c5a99 311 { "checkboxtreeGetSelection", (PyCFunction) widgetCheckboxTreeGetSel,
615bc463 312 METH_VARARGS, NULL },
5d678658 313 { "entrySetFlags", (PyCFunction) widgetEntrySetFlags, METH_VARARGS, NULL },
c573c71b 314 { "checkboxSetFlags", (PyCFunction) widgetCheckboxSetFlags, METH_VARARGS, NULL },
870ff9eb 315 { "checkboxSetValue", (PyCFunction) widgetCheckboxSetValue, METH_VARARGS, NULL },
80d03bd8 316 { NULL }
317};
318
ba3eb78a 319static PyMemberDef widget_members[] = {
7cdac0c4
ML
320 { "key",
321#if SIZEOF_VOID_P == SIZEOF_LONG
322 T_LONG,
323#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
324 T_LONGLONG,
325#else
326#error unsupported pointer size
327#endif
328 offsetof(snackWidget, co), 0, NULL },
ba3eb78a
MK
329 { "entryValue", T_STRING, offsetof(snackWidget, apointer), 0, NULL },
330 { NULL }
331};
332
80d03bd8 333static PyTypeObject snackWidgetType = {
ba3eb78a 334 PyVarObject_HEAD_INIT(&PyType_Type, 0)
80d03bd8 335 "snackwidget", /* tp_name */
336 sizeof(snackWidget), /* tp_size */
337 0, /* tp_itemsize */
6f481af2 338 widgetDestructor, /* tp_dealloc */
80d03bd8 339 0, /* tp_print */
ba3eb78a 340 0, /* tp_getattr */
80d03bd8 341 0, /* tp_setattr */
342 0, /* tp_compare */
343 0, /* tp_repr */
344 0, /* tp_as_number */
345 0, /* tp_as_sequence */
6f481af2 346 0, /* tp_as_mapping */
ba3eb78a
MK
347 0, /* tp_hash */
348 0, /* tp_call */
349 0, /* tp_str */
350 PyObject_GenericGetAttr, /* tp_getattro */
351 0, /* tp_setattro */
352 0, /* tp_as_buffer */
353 Py_TPFLAGS_DEFAULT, /* tp_flags */
354 0, /* tp_doc */
355 0, /* tp_traverse */
356 0, /* tp_clear */
357 0, /* tp_richcompare */
358 0, /* tp_weaklistoffset */
359 0, /* tp_iter */
360 0, /* tp_iternext */
361 widgetMethods, /* tp_methods */
362 widget_members, /* tp_members */
363 widget_getset /* tp_getset */
80d03bd8 364};
365
1dfa0cfa 366static snackWidget * snackWidgetNew (void) {
367 snackWidget * widget;
368
369 widget = PyObject_NEW(snackWidget, &snackWidgetType);
c104daae
ML
370 if (!widget)
371 return NULL;
1dfa0cfa 372
373 widget->scs.cb = NULL;
374 widget->scs.data = NULL;
375
376 return widget;
377}
378
80d03bd8 379static PyObject * initScreen(PyObject * s, PyObject * args) {
1dfa0cfa 380 suspend.cb = NULL;
381 suspend.data = NULL;
382
80d03bd8 383 newtInit();
384 newtCls();
385
386 Py_INCREF(Py_None);
387 return Py_None;
388}
389
390static PyObject * finishScreen(PyObject * s, PyObject * args) {
dd66cfb7 391 Py_XDECREF (suspend.cb);
392 Py_XDECREF (suspend.data);
393
80d03bd8 394 newtFinished();
395 Py_INCREF(Py_None);
396 return Py_None;
397}
398
399static PyObject * refreshScreen(PyObject * s, PyObject * args) {
400 newtRefresh();
401 Py_INCREF(Py_None);
402 return Py_None;
403}
404
3c3bb3d8 405static PyObject * setColor(PyObject * s, PyObject * args) {
406 char * fg, * bg;
407 int colorset;
408 if (!PyArg_ParseTuple(args, "iss", &colorset, &fg, &bg))
409 return NULL;
410
411 newtSetColor(colorset, fg, bg);
412
413 Py_INCREF(Py_None);
414 return Py_None;
415}
416
06cf519e 417static PyObject * scaleWidget(PyObject * s, PyObject * args) {
418 snackWidget * widget;
419 int width, fullAmount;
420
421 if (!PyArg_ParseTuple(args, "ii", &width, &fullAmount)) return NULL;
422
1dfa0cfa 423 widget = snackWidgetNew ();
c104daae
ML
424 if (!widget)
425 return NULL;
06cf519e 426 widget->co = newtScale(-1, -1, width, fullAmount);
427
428 return (PyObject *) widget;
429}
430
431static PyObject * scaleSet(snackWidget * s, PyObject * args) {
432 int amount;
433
434 if (!PyArg_ParseTuple(args, "i", &amount)) return NULL;
435
436 newtScaleSet(s->co, amount);
437
438 Py_INCREF(Py_None);
439 return Py_None;
440}
441
9f0ab2ac 442static PyObject * screenSize(PyObject * s, PyObject * args) {
443 int width, height;
444
445 if (!PyArg_ParseTuple(args, ""))
6f481af2 446 return NULL;
9f0ab2ac 447
448 newtGetScreenSize(&width, &height);
449
450 return Py_BuildValue("(ii)", width, height);
451}
452
72b71fa6 453static void helpCallbackMarshall(newtComponent co, void * data) {
454 PyObject * args, * result;
455
de8e0658
JK
456 PyGILState_STATE _state = PyGILState_Ensure();
457
72b71fa6 458 args = Py_BuildValue("(O)", data);
08ff22f5 459 result = PyObject_CallObject(helpCallback.cb, args);
72b71fa6 460 Py_DECREF (args);
461 Py_XDECREF(result);
462
de8e0658
JK
463 PyGILState_Release(_state);
464
72b71fa6 465 return;
466}
467
5d678658 468static void suspendCallbackMarshall(void * data) {
469 struct callbackStruct * scs = data;
470 PyObject * args, * result;
471
de8e0658
JK
472 PyGILState_STATE _state = PyGILState_Ensure();
473
1dfa0cfa 474 if (scs->data) {
6f481af2 475 args = Py_BuildValue("(O)", scs->data);
08ff22f5 476 result = PyObject_CallObject(scs->cb, args);
6f481af2 477 Py_DECREF (args);
1dfa0cfa 478 } else
08ff22f5 479 result = PyObject_CallObject(scs->cb, NULL);
1dfa0cfa 480
481 if (!result) {
6f481af2 482 PyErr_Print();
483 PyErr_Clear();
1dfa0cfa 484 }
5d678658 485
5d678658 486 Py_XDECREF(result);
487
de8e0658
JK
488 PyGILState_Release(_state);
489
5d678658 490 return;
491}
492
493static void callbackMarshall(newtComponent co, void * data) {
494 struct callbackStruct * scs = data;
06cf519e 495 PyObject * args, * result;
496
de8e0658
JK
497 PyGILState_STATE _state = PyGILState_Ensure();
498
1dfa0cfa 499 if (scs->data) {
6f481af2 500 args = Py_BuildValue("(O)", scs->data);
08ff22f5 501 result = PyObject_CallObject(scs->cb, args);
6f481af2 502 Py_DECREF (args);
1dfa0cfa 503 } else
08ff22f5 504 result = PyObject_CallObject(scs->cb, NULL);
1ea8f607 505
5d678658 506 if (!result) {
6f481af2 507 PyErr_Print();
508 PyErr_Clear();
5d678658 509 }
510
1ea8f607 511 Py_XDECREF(result);
06cf519e 512
de8e0658
JK
513 PyGILState_Release(_state);
514
1ea8f607 515 return;
06cf519e 516}
517
518static PyObject * setSuspendCallback(PyObject * s, PyObject * args) {
1dfa0cfa 519 if (!PyArg_ParseTuple(args, "O|O", &suspend.cb, &suspend.data))
6f481af2 520 return NULL;
06cf519e 521
1dfa0cfa 522 Py_INCREF (suspend.cb);
523 Py_XINCREF (suspend.data);
524
525 newtSetSuspendCallback(suspendCallbackMarshall, &suspend);
06cf519e 526
527 Py_INCREF(Py_None);
528 return Py_None;
529}
530
72b71fa6 531static PyObject * setHelpCallback(PyObject * s, PyObject * args) {
532 if (!PyArg_ParseTuple(args, "O", &helpCallback.cb))
6f481af2 533 return NULL;
72b71fa6 534
535 /*if (helpCallback.cb) {
6f481af2 536 Py_DECREF (helpCallback.cb);
72b71fa6 537 }*/
538
539 Py_INCREF (helpCallback.cb);
540
541 newtSetHelpCallback(helpCallbackMarshall);
542
543 Py_INCREF(Py_None);
544 return Py_None;
545}
546
75fb0452 547static PyObject * drawRootText(PyObject * s, PyObject * args) {
548 int left, top;
549 char * text;
550
551 if (!PyArg_ParseTuple(args, "iis", &left, &top, &text))
6f481af2 552 return NULL;
75fb0452 553
ec65dcfe 554 newtDrawRootText(left, top, text);
75fb0452 555
556 Py_INCREF(Py_None);
557 return Py_None;
558}
559
f1aef30b 560static PyObject * doSuspend(PyObject * s, PyObject * args) {
561 newtSuspend();
562
563 Py_INCREF(Py_None);
564 return Py_None;
565}
566
567static PyObject * doResume(PyObject * s, PyObject * args) {
568 newtResume();
569
570 Py_INCREF(Py_None);
571 return Py_None;
572}
573
75fb0452 574static PyObject * popHelpLine(PyObject * s, PyObject * args) {
575 newtPopHelpLine();
576 Py_INCREF(Py_None);
577 return Py_None;
578}
579
580static PyObject * pushHelpLine(PyObject * s, PyObject * args) {
581 char * text;
582
583 if (!PyArg_ParseTuple(args, "s", &text))
6f481af2 584 return NULL;
75fb0452 585
586 if (!strcmp(text, "*default*"))
6f481af2 587 newtPushHelpLine(NULL);
75fb0452 588 else
6f481af2 589 newtPushHelpLine(text);
75fb0452 590
591 Py_INCREF(Py_None);
592 return Py_None;
593}
594
6e25d997 595static PyObject * reflowText(PyObject * s, PyObject * args) {
596 char * text, * new;
597 int width, minus = 5, plus = 5;
598 int realWidth, realHeight;
599 PyObject * tuple;
600
601 if (!PyArg_ParseTuple(args, "si|ii", &text, &width, &minus, &plus))
6f481af2 602 return NULL;
6e25d997 603
604 new = newtReflowText(text, width, minus, plus, &realWidth, &realHeight);
605
606 tuple = Py_BuildValue("(sii)", new, realWidth, realHeight);
607 free(new);
608
609 return tuple;
610}
611
80d03bd8 612static PyObject * centeredWindow(PyObject * s, PyObject * args) {
613 int width, height;
614 char * title;
615
616 if (!PyArg_ParseTuple(args, "iis", &width, &height, &title))
6f481af2 617 return NULL;
80d03bd8 618
619 newtCenteredWindow(width, height, title);
620
621 Py_INCREF(Py_None);
622 return Py_None;
623}
624
625static PyObject * gridWrappedWindow(PyObject * s, PyObject * args) {
626 snackGrid * grid;
627 char * title;
2b6641b1 628 int x = -1, y = -1;
80d03bd8 629
2b6641b1 630 if (!PyArg_ParseTuple(args, "O!s|ii", &snackGridType, &grid, &title,
6f481af2 631 &x, &y))
632 return NULL;
80d03bd8 633
2b6641b1 634 if (y == -1)
6f481af2 635 newtGridWrappedWindow(grid->grid, title);
2b6641b1 636 else
6f481af2 637 newtGridWrappedWindowAt(grid->grid, title, x, y);
80d03bd8 638
639 Py_INCREF(Py_None);
640 return Py_None;
641}
642
643static PyObject * openWindow(PyObject * s, PyObject * args) {
644 int left, top, width, height;
645 char * title;
646
647 if (!PyArg_ParseTuple(args, "iiiis", &left, &top, &width, &height, &title))
6f481af2 648 return NULL;
80d03bd8 649
650 newtOpenWindow(left, top, width, height, title);
651
652 Py_INCREF(Py_None);
653 return Py_None;
654}
655
656static PyObject * popWindow(PyObject * s, PyObject * args) {
657 newtPopWindow();
658 Py_INCREF(Py_None);
659 return Py_None;
660}
661
e5df813b 662static PyObject * popWindowNoRefresh(PyObject * s, PyObject * args) {
663 newtPopWindowNoRefresh();
664 Py_INCREF(Py_None);
665 return Py_None;
666}
667
80d03bd8 668static PyObject * messageWindow(PyObject * s, PyObject * args) {
669 char * title, * text;
670 char * okbutton = "Ok";
671
672 if (!PyArg_ParseTuple(args, "ss|s", &title, &text, &okbutton))
6f481af2 673 return NULL;
80d03bd8 674
de8e0658 675 Py_BEGIN_ALLOW_THREADS
80d03bd8 676 newtWinMessage(title, okbutton, text);
de8e0658 677 Py_END_ALLOW_THREADS
80d03bd8 678
679 Py_INCREF(Py_None);
680 return Py_None;
681}
682
683static PyObject * choiceWindow(PyObject * s, PyObject * args) {
684 char * title, * text;
685 char * okbutton = "Ok";
686 char * cancelbutton = "Cancel";
687 int rc;
688
689 if (!PyArg_ParseTuple(args, "ss|ss", &title, &text, &okbutton,
6f481af2 690 &cancelbutton))
691 return NULL;
80d03bd8 692
de8e0658 693 Py_BEGIN_ALLOW_THREADS
80d03bd8 694 rc = newtWinChoice(title, okbutton, cancelbutton, text);
de8e0658 695 Py_END_ALLOW_THREADS
80d03bd8 696
93a3a267 697 return Py_BuildValue("i", rc);
80d03bd8 698}
699
700static PyObject * ternaryWindow(PyObject * s, PyObject * args) {
701 char * title, * text, * button1, * button2, * button3;
702 int rc;
703
704 if (!PyArg_ParseTuple(args, "sssss", &title, &text, &button1, &button2,
6f481af2 705 &button3))
706 return NULL;
80d03bd8 707
de8e0658 708 Py_BEGIN_ALLOW_THREADS
80d03bd8 709 rc = newtWinTernary(title, button1, button2, button3, text);
de8e0658 710 Py_END_ALLOW_THREADS
80d03bd8 711
712 return Py_BuildValue("i", rc);
713}
714
715static snackWidget * buttonWidget(PyObject * s, PyObject * args) {
716 snackWidget * widget;
717 char * label;
718
719 if (!PyArg_ParseTuple(args, "s", &label)) return NULL;
720
1dfa0cfa 721 widget = snackWidgetNew ();
c104daae
ML
722 if (!widget)
723 return NULL;
80d03bd8 724 widget->co = newtButton(-1, -1, label);
725
726 return widget;
727}
728
f954a19b 729static snackWidget * compactbuttonWidget(PyObject * s, PyObject * args) {
730 snackWidget * widget;
731 char * label;
732
733 if (!PyArg_ParseTuple(args, "s", &label)) return NULL;
734
735 widget = snackWidgetNew ();
c104daae
ML
736 if (!widget)
737 return NULL;
f954a19b 738 widget->co = newtCompactButton(-1, -1, label);
739
740 return widget;
741}
742
80d03bd8 743static snackWidget * labelWidget(PyObject * s, PyObject * args) {
744 char * label;
745 snackWidget * widget;
746
747 if (!PyArg_ParseTuple(args, "s", &label)) return NULL;
748
1dfa0cfa 749 widget = snackWidgetNew ();
c104daae
ML
750 if (!widget)
751 return NULL;
80d03bd8 752 widget->co = newtLabel(-1, -1, label);
753
754 return widget;
755}
756
522d3500 757static PyObject * widgetLabelText(snackWidget * s, PyObject * args) {
758 char * label;
759
760 if (!PyArg_ParseTuple(args, "s", &label)) return NULL;
761
762 newtLabelSetText(s->co, label);
763
764 Py_INCREF(Py_None);
765 return Py_None;
766}
767
92567bd5
JB
768static PyObject * widgetLabelSetColors(snackWidget * s, PyObject * args) {
769 int colorset;
770
771 if (!PyArg_ParseTuple(args, "i", &colorset)) return NULL;
772
773 newtLabelSetColors(s->co, colorset);
774
775 Py_INCREF(Py_None);
776 return Py_None;
777}
778
36f926a6 779static PyObject * widgetTextboxText(snackWidget * s, PyObject * args) {
780 char * text;
781
782 if (!PyArg_ParseTuple(args, "s", &text)) return NULL;
783
784 newtTextboxSetText(s->co, text);
785
786 Py_INCREF(Py_None);
787 return Py_None;
788}
789
7dc27ce1
ML
790static PyObject * widgetTextboxHeight(snackWidget * s, PyObject * args) {
791 int height;
792
793 if (!PyArg_ParseTuple(args, "i", &height)) return NULL;
794
795 newtTextboxSetHeight(s->co, height);
796
797 Py_INCREF(Py_None);
798 return Py_None;
799}
800
6e25d997 801static snackWidget * listboxWidget(PyObject * s, PyObject * args) {
802 snackWidget * widget;
803 int height;
67faee66 804 int doScroll = 0, returnExit = 0, showCursor = 0, multiple = 0, border = 0;
6e25d997 805
67faee66 806 if (!PyArg_ParseTuple(args, "i|iiiii", &height, &doScroll, &returnExit,
807 &showCursor, &multiple, &border))
6f481af2 808 return NULL;
6e25d997 809
1dfa0cfa 810 widget = snackWidgetNew ();
c104daae
ML
811 if (!widget)
812 return NULL;
6e25d997 813 widget->co = newtListbox(-1, -1, height,
6f481af2 814 (doScroll ? NEWT_FLAG_SCROLL : 0) |
815 (returnExit ? NEWT_FLAG_RETURNEXIT : 0) |
67faee66 816 (showCursor ? NEWT_FLAG_SHOWCURSOR : 0) |
817 (multiple ? NEWT_FLAG_MULTIPLE : 0) |
818 (border ? NEWT_FLAG_BORDER : 0)
6f481af2 819 );
a507b3ec 820 widget->anint = 1;
6e25d997 821
822 return widget;
823}
824
825static snackWidget * textWidget(PyObject * s, PyObject * args) {
826 char * text;
827 int width, height;
828 int scrollBar = 0;
36f926a6 829 int wrap = 0;
6e25d997 830 snackWidget * widget;
831
36f926a6 832 if (!PyArg_ParseTuple(args, "iis|ii", &width, &height, &text, &scrollBar, &wrap))
6f481af2 833 return NULL;
6e25d997 834
1dfa0cfa 835 widget = snackWidgetNew ();
c104daae
ML
836 if (!widget)
837 return NULL;
6e25d997 838 widget->co = newtTextbox(-1, -1, width, height,
6f481af2 839 (scrollBar ? NEWT_FLAG_SCROLL : 0) |
840 (wrap ? NEWT_FLAG_WRAP : 0));
6e25d997 841 newtTextboxSetText(widget->co, text);
842
843 return widget;
844}
845
80d03bd8 846static snackWidget * radioButtonWidget(PyObject * s, PyObject * args) {
847 snackWidget * widget, * group;
848 char * text;
849 int isOn;
850
851 if (!PyArg_ParseTuple(args, "sOi", &text, &group, &isOn))
6f481af2 852 return NULL;
80d03bd8 853
1dfa0cfa 854 widget = snackWidgetNew ();
c104daae
ML
855 if (!widget)
856 return NULL;
80d03bd8 857
858 if ((PyObject *) group == Py_None)
6f481af2 859 widget->co = newtRadiobutton(-1, -1, text, isOn, NULL);
80d03bd8 860 else
6f481af2 861 widget->co = newtRadiobutton(-1, -1, text, isOn, group->co);
80d03bd8 862
863 return widget;
864}
865
866static snackWidget * checkboxWidget(PyObject * s, PyObject * args) {
867 snackWidget * widget;
868 char * text;
869 int isOn;
870
871 if (!PyArg_ParseTuple(args, "si", &text, &isOn)) return NULL;
872
1dfa0cfa 873 widget = snackWidgetNew ();
c104daae
ML
874 if (!widget)
875 return NULL;
80d03bd8 876 widget->co = newtCheckbox(-1, -1, text, isOn ? '*' : ' ', NULL,
6f481af2 877 &widget->achar);
80d03bd8 878
879 return widget;
880}
881
c573c71b 882static PyObject * widgetCheckboxSetFlags(snackWidget * s, PyObject * args) {
883 int flag, sense;
884
885 if (!PyArg_ParseTuple(args, "ii", &flag, &sense)) return NULL;
886
887 newtCheckboxSetFlags(s->co, flag, sense);
888
889 Py_INCREF(Py_None);
890 return Py_None;
891}
892
870ff9eb 893static PyObject * widgetCheckboxSetValue(snackWidget * s, PyObject * args) {
894 char *value;
895
896 if (!PyArg_ParseTuple(args, "s", &value)) return NULL;
897
898 newtCheckboxSetValue(s->co, *value);
899
900 Py_INCREF(Py_None);
901 return Py_None;
902}
c573c71b 903
80d03bd8 904static snackWidget * entryWidget(PyObject * s, PyObject * args) {
905 snackWidget * widget;
906 int width;
907 char * initial;
20fb366a 908 int isHidden, isScrolled, returnExit, isPassword;
80d03bd8 909
20fb366a 910 if (!PyArg_ParseTuple(args, "isiiii", &width, &initial,
6f481af2 911 &isHidden, &isPassword, &isScrolled, &returnExit)) return NULL;
80d03bd8 912
1dfa0cfa 913 widget = snackWidgetNew ();
c104daae
ML
914 if (!widget)
915 return NULL;
d78245ab 916 widget->co = newtEntry(-1, -1, initial, width,
917 (const char **) &widget->apointer,
6f481af2 918 (isHidden ? NEWT_FLAG_HIDDEN : 0) |
919 (isPassword ? NEWT_FLAG_PASSWORD : 0) |
920 (returnExit ? NEWT_FLAG_RETURNEXIT : 0) |
921 (isScrolled ? NEWT_FLAG_SCROLL : 0));
80d03bd8 922
923 return widget;
924}
925
926static snackForm * formCreate(PyObject * s, PyObject * args) {
927 snackForm * form;
72b71fa6 928 PyObject * help = Py_None;
929
930 if (!PyArg_ParseTuple(args, "|O", &help)) return NULL;
931
932 if (help == Py_None)
6f481af2 933 help = NULL;
80d03bd8 934
935 form = PyObject_NEW(snackForm, &snackFormType);
72b71fa6 936 form->fo = newtForm(NULL, help, 0);
80d03bd8 937
938 return form;
939}
940
941static snackGrid * gridCreate(PyObject * s, PyObject * args) {
942 int rows, cols;
943 snackGrid * grid;
944
945 if (!PyArg_ParseTuple(args, "ii", &cols, &rows)) return NULL;
946
947 grid = PyObject_NEW(snackGrid, &snackGridType);
948 grid->grid = newtCreateGrid(cols, rows);
949
950 return grid;
951}
952
80d03bd8 953static PyObject * gridPlace(snackGrid * grid, PyObject * args) {
954 int x, y;
955
956 if (!PyArg_ParseTuple(args, "ii", &x, &y)) return NULL;
957
958 newtGridPlace(grid->grid, x, y);
959
960 Py_INCREF(Py_None);
961 return Py_None;
962}
963
964static PyObject * gridSetField(snackGrid * grid, PyObject * args) {
965 snackWidget * w;
6e25d997 966 snackGrid * g;
80d03bd8 967 int x, y;
968 int pLeft = 0, pTop = 0, pRight = 0, pBottom = 0;
6e25d997 969 int anchorFlags = 0, growFlags = 0;
80d03bd8 970
6e25d997 971 if (!PyArg_ParseTuple(args, "iiO|(iiii)ii", &x, &y,
6f481af2 972 &w, &pLeft, &pTop, &pRight, &pBottom,
973 &anchorFlags, &growFlags))
974 return NULL;
80d03bd8 975
ba3eb78a 976 if (Py_TYPE(w) == &snackWidgetType) {
6f481af2 977 newtGridSetField(grid->grid, x, y, NEWT_GRID_COMPONENT,
978 w->co, pLeft, pTop, pRight, pBottom, anchorFlags,
979 growFlags);
6e25d997 980 } else {
6f481af2 981 g = (snackGrid *) w;
982 newtGridSetField(grid->grid, x, y, NEWT_GRID_SUBGRID,
983 g->grid, pLeft, pTop, pRight, pBottom, anchorFlags,
984 growFlags);
6e25d997 985 }
80d03bd8 986
987 Py_INCREF(Py_None);
988 return Py_None;
989}
990
bd38d47e 991static PyObject * formDraw(snackForm * s, PyObject * args) {
992 newtDrawForm(s->fo);
993
994 Py_INCREF(Py_None);
995 return Py_None;
996}
997
80d03bd8 998static PyObject * formAdd(snackForm * s, PyObject * args) {
999 snackWidget * w;
1000 int size = PyTuple_Size(args), i;
1001
1002 if (!size) {
6f481af2 1003 /* this is a hack, I should give an error directly */
1004 if (!PyArg_ParseTuple(args, "O!", &snackWidgetType, &w))
1005 return NULL;
80d03bd8 1006 }
1007
1008 for (i = 0; i < size; i++) {
6f481af2 1009 w = (snackWidget *) PyTuple_GET_ITEM(args, i);
1010 newtFormAddComponent(s->fo, w->co);
80d03bd8 1011 }
1012
1013 Py_INCREF(Py_None);
1014 return Py_None;
1015}
1016
1017static PyObject * formRun(snackForm * s, PyObject * args) {
ea59ae12 1018 struct newtExitStruct result;
1019
de8e0658 1020 Py_BEGIN_ALLOW_THREADS
ea59ae12 1021 newtFormRun(s->fo, &result);
de8e0658 1022 Py_END_ALLOW_THREADS
ea59ae12 1023
1024 if (result.reason == NEWT_EXIT_HOTKEY)
6f481af2 1025 return Py_BuildValue("(si)", "hotkey", result.u.key);
73390860 1026 else if (result.reason == NEWT_EXIT_TIMER)
6f481af2 1027 return Py_BuildValue("(si)", "timer", 0);
d7e202d6 1028 else if (result.reason == NEWT_EXIT_FDREADY)
6f481af2 1029 return Py_BuildValue("(si)", "fdready", result.u.watch);
508a125b 1030 else if (result.reason == NEWT_EXIT_COMPONENT)
7cdac0c4
ML
1031#if SIZEOF_VOID_P <= SIZEOF_LONG
1032 return Py_BuildValue("(sl)", "widget", (long)result.u.co);
1033#else
1034 return Py_BuildValue("(sL)", "widget", (long long)result.u.co);
1035#endif
508a125b
ML
1036 else
1037 return Py_BuildValue("(si)", "error", 0);
ea59ae12 1038}
1039
1040static PyObject * formHotKey(snackForm * s, PyObject * args) {
1041 int key;
1042
1043 if (!PyArg_ParseTuple(args, "i", &key))
6f481af2 1044 return NULL;
ea59ae12 1045
1046 newtFormAddHotKey(s->fo, key);
80d03bd8 1047
1048 Py_INCREF(Py_None);
1049 return Py_None;
1050}
1051
73390860 1052static PyObject * formSetTimer(snackForm * form, PyObject * args) {
1053 int millisecs;
1054
1055 if (!PyArg_ParseTuple(args, "i", &millisecs))
6f481af2 1056 return NULL;
73390860 1057
1058 newtFormSetTimer(form->fo, millisecs);
1059
1060 Py_INCREF(Py_None);
1061 return Py_None;
1062}
1063
d7e202d6 1064static PyObject * formWatchFD(snackForm * form, PyObject * args) {
1065 int fd, fdflags;
1066
1067 if (!PyArg_ParseTuple(args, "ii", &fd, &fdflags))
6f481af2 1068 return NULL;
d7e202d6 1069
1070 newtFormWatchFd(form->fo, fd, fdflags);
1071
1072 Py_INCREF(Py_None);
1073 return Py_None;
1074}
1075
5d678658 1076static PyObject * formSetCurrent(snackForm * form, PyObject * args) {
1077 snackWidget * w;
1078
1079 if (!PyArg_ParseTuple(args, "O", &w))
6f481af2 1080 return NULL;
5d678658 1081
1082 newtFormSetCurrent(form->fo, w->co);
1083
1084 Py_INCREF(Py_None);
1085 return Py_None;
1086}
1087
ba3eb78a
MK
1088static PyObject * widget_get_checkboxValue(PyObject *self, void *closure)
1089{
1090 snackWidget *w = (snackWidget *)self;
80d03bd8 1091
6f481af2 1092 return Py_BuildValue("i", w->achar == ' ' ? 0 : 1);
ba3eb78a
MK
1093}
1094
1095static PyObject * widget_get_radioValue(PyObject *self, void *closure)
1096{
1097 snackWidget *w = (snackWidget *)self;
80d03bd8 1098
ddc56f06
ML
1099#if SIZEOF_VOID_P <= SIZEOF_LONG
1100 return Py_BuildValue("l", (long)newtRadioGetCurrent(w->co));
1101#else
1102 return Py_BuildValue("L", (long long)newtRadioGetCurrent(w->co));
1103#endif
80d03bd8 1104}
1105
1dfa0cfa 1106static void widgetDestructor(PyObject * o) {
1107 snackWidget * s = (snackWidget *) o;
1108
1109 Py_XDECREF (s->scs.cb);
1110 Py_XDECREF (s->scs.data);
bd0f4c32 1111
1112 PyObject_Free(o);
1dfa0cfa 1113}
1114
6a703ca8 1115static PyObject * widgetAddCallback(snackWidget * s, PyObject * args) {
1dfa0cfa 1116 s->scs.cb = NULL;
1117 s->scs.data = NULL;
1118
5d678658 1119 if (!PyArg_ParseTuple(args, "O|O", &s->scs.cb, &s->scs.data))
6f481af2 1120 return NULL;
6a703ca8 1121
1dfa0cfa 1122 Py_INCREF (s->scs.cb);
1123 Py_XINCREF (s->scs.data);
1124
5d678658 1125 newtComponentAddCallback(s->co, callbackMarshall, &s->scs);
6a703ca8 1126
1127 Py_INCREF(Py_None);
1128 return Py_None;
1129}
1130
80d03bd8 1131static PyObject * widgetEntrySetValue(snackWidget * s, PyObject * args) {
1132 char * val;
cee7c393 1133 int cursorAtEnd = 1;
80d03bd8 1134
cee7c393 1135 if (!PyArg_ParseTuple(args, "s|i", &val, &cursorAtEnd))
6f481af2 1136 return NULL;
80d03bd8 1137
cee7c393 1138 newtEntrySet(s->co, val, cursorAtEnd);
80d03bd8 1139
1140 Py_INCREF(Py_None);
1141 return Py_None;
1142}
1143
5d678658 1144static PyObject * widgetEntrySetFlags(snackWidget * s, PyObject * args) {
1145 int flag, sense;
1146
1147 if (!PyArg_ParseTuple(args, "ii", &flag, &sense)) return NULL;
1148
1149 newtEntrySetFlags(s->co, flag, sense);
1150
1151 Py_INCREF(Py_None);
1152 return Py_None;
1153}
1154
1155
6e25d997 1156static PyObject * widgetListboxAdd(snackWidget * s, PyObject * args) {
1157 char * text;
1158
1159 if (!PyArg_ParseTuple(args, "s", &text))
6f481af2 1160 return NULL;
6e25d997 1161
d7e202d6 1162 newtListboxAddEntry(s->co, text, I2P(s->anint));
6e25d997 1163
1164 return PyInt_FromLong(s->anint++);
1165}
1166
a507b3ec 1167static PyObject * widgetListboxIns(snackWidget * s, PyObject * args) {
1168 char * text;
1169 int key;
1170
1171 if (!PyArg_ParseTuple(args, "si", &text, &key))
6f481af2 1172 return NULL;
a507b3ec 1173
d7e202d6 1174 newtListboxInsertEntry(s->co, text, I2P(s->anint), I2P(key));
a507b3ec 1175
1176 return PyInt_FromLong(s->anint++);
1177}
1178
1179static PyObject * widgetListboxDel(snackWidget * s, PyObject * args) {
1180 int key;
1181
1182 if (!PyArg_ParseTuple(args, "i", &key))
6f481af2 1183 return NULL;
a507b3ec 1184
d7e202d6 1185 newtListboxDeleteEntry(s->co, I2P(key));
a507b3ec 1186
1187 Py_INCREF(Py_None);
1188 return Py_None;
1189}
1190
6e25d997 1191static PyObject * widgetListboxGet(snackWidget * s, PyObject * args) {
1192 if (!PyArg_ParseTuple(args, ""))
6f481af2 1193 return NULL;
6e25d997 1194
1195 return PyInt_FromLong((long) newtListboxGetCurrent(s->co));
1196}
1197
67faee66 1198static PyObject * widgetListboxGetSel(snackWidget * s, PyObject * args) {
1199 void ** selection;
1200 int numselected;
1201 int i;
c104daae 1202 PyObject * sel, * int_obj;
67faee66 1203
1204 if (!PyArg_ParseTuple(args, ""))
1205 return NULL;
1206
1207 selection = (void **) newtListboxGetSelection(s->co, &numselected);
1208
1209 sel = PyList_New(0);
1210
1211 if (!selection) {
c104daae 1212 return sel;
67faee66 1213 }
1214
67faee66 1215 for (i = 0; i < numselected; i++) {
c104daae
ML
1216 int_obj = PyInt_FromLong((long) selection[i]);
1217 PyList_Append(sel, int_obj);
1218 Py_DECREF(int_obj);
67faee66 1219 }
1220 free(selection);
1221
1222 return sel;
1223}
1224
99438c19 1225static PyObject * widgetListboxSet(snackWidget * s, PyObject * args) {
1226 int index;
1227
1228 if (!PyArg_ParseTuple(args, "i", &index))
6f481af2 1229 return NULL;
99438c19 1230
d7e202d6 1231 newtListboxSetCurrentByKey(s->co, I2P(index));
99438c19 1232
1233 Py_INCREF(Py_None);
1234 return Py_None;
1235}
1236
6e25d997 1237static PyObject * widgetListboxSetW(snackWidget * s, PyObject * args) {
1238 int width;
1239
1240 if (!PyArg_ParseTuple(args, "i", &width))
6f481af2 1241 return NULL;
6e25d997 1242
1243 newtListboxSetWidth(s->co, width);
1244
1245 Py_INCREF(Py_None);
1246 return Py_None;
1247}
1248
50c9056c 1249static PyObject * widgetListboxClear(snackWidget * s, PyObject * args) {
1250 if (!PyArg_ParseTuple(args, ""))
1251 return NULL;
1252
1253 newtListboxClear(s->co);
1254
1255 Py_INCREF(Py_None);
1256 return Py_None;
1257}
1258
80d03bd8 1259static void emptyDestructor(PyObject * s) {
1260}
1261
615bc463 1262static snackWidget * checkboxTreeWidget(PyObject * s, PyObject * args, PyObject * kwargs) {
f06c5a99 1263 int height;
1264 int scrollBar = 0;
615bc463 1265 int hide_checkbox = 0;
1266 int unselectable = 0;
1267 int flags;
f06c5a99 1268 snackWidget * widget;
615bc463 1269 const char *kw[] = {"height", "scrollbar", "hide_checkbox", "unselectable", NULL};
f06c5a99 1270
615bc463 1271 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii", (char **) kw,
6f481af2 1272 &height, &scrollBar, &hide_checkbox, &unselectable))
1273 return NULL;
f06c5a99 1274
615bc463 1275 flags = (scrollBar ? NEWT_FLAG_SCROLL : 0) |
6f481af2 1276 (hide_checkbox ? NEWT_CHECKBOXTREE_HIDE_BOX : 0) |
1277 (unselectable ? NEWT_CHECKBOXTREE_UNSELECTABLE : 0);
615bc463 1278
1dfa0cfa 1279 widget = snackWidgetNew ();
c104daae
ML
1280 if (!widget)
1281 return NULL;
615bc463 1282 widget->co = newtCheckboxTree(-1, -1, height, flags);
f06c5a99 1283
1284 widget->anint = 1;
1285
1286 return widget;
1287}
1288
75d40644 1289static PyObject * widgetCheckboxTreeAddItem(snackWidget * s, PyObject * args) {
f06c5a99 1290 char * text;
f06c5a99 1291 int selected = 0;
75d40644 1292 PyObject * pathList, * o;
1293 int len;
1294 int * path;
1295 int i;
1296
1297 if (!PyArg_ParseTuple(args, "sOi", &text, &pathList, &selected))
6f481af2 1298 return NULL;
f06c5a99 1299
75d40644 1300 len = PyTuple_Size(pathList);
1301 path = alloca(sizeof(*path) * (len + 1));
1302 for (i = 0; i < len; i++) {
1303 o = PyTuple_GetItem(pathList, i);
6f481af2 1304 path[i] = PyInt_AsLong(o);
75d40644 1305 }
1306 path[len] = NEWT_ARG_LAST;
1307
d7e202d6 1308 newtCheckboxTreeAddArray(s->co, text, I2P(s->anint),
6f481af2 1309 selected ? NEWT_FLAG_SELECTED : 0, path);
f06c5a99 1310
1311 return PyInt_FromLong(s->anint++);
1312}
1313
2b6641b1 1314static PyObject * widgetCheckboxTreeGetCur(snackWidget * s, PyObject * args) {
1315 if (!PyArg_ParseTuple(args, ""))
6f481af2 1316 return NULL;
2b6641b1 1317
d7e202d6 1318 return PyInt_FromLong((long)newtCheckboxTreeGetCurrent(s->co));
2b6641b1 1319}
1320
c895490d 1321static PyObject * widgetCheckboxTreeSetEntry(snackWidget * s, PyObject * args) {
1322 int data;
1323 char *text;
1324
1325 if (!PyArg_ParseTuple(args, "is", &data, &text)) return NULL;
1326
d7e202d6 1327 newtCheckboxTreeSetEntry(s->co, I2P(data), text);
c895490d 1328
1329 Py_INCREF(Py_None);
d8c97d41 1330 return Py_None;
1331}
1332
1333static PyObject * widgetCheckboxTreeSetWidth(snackWidget * s, PyObject * args) {
1334 int width;
1335
1336 if (!PyArg_ParseTuple(args, "i", &width))
6f481af2 1337 return NULL;
d8c97d41 1338
1339 newtCheckboxTreeSetWidth(s->co, width);
1340
1341 Py_INCREF(Py_None);
c895490d 1342 return Py_None;
1343}
1344
5160fc22 1345static PyObject * widgetCheckboxTreeSetCurrent(snackWidget * s, PyObject * args) {
1346 int data;
1347
1348 if (!PyArg_ParseTuple(args, "i", &data)) return NULL;
1349
d7e202d6 1350 newtCheckboxTreeSetCurrent(s->co, I2P(data));
5160fc22 1351
1352 Py_INCREF(Py_None);
1353 return Py_None;
1354}
1355
c895490d 1356static PyObject * widgetCheckboxTreeSetEntryValue(snackWidget * s, PyObject * args) {
1357 int data;
1358 int isOn = 1;
1359
1360 if (!PyArg_ParseTuple(args, "i|i", &data, &isOn)) return NULL;
1361
d7e202d6 1362 newtCheckboxTreeSetEntryValue(s->co, I2P(data),
6f481af2 1363 isOn ? NEWT_CHECKBOXTREE_SELECTED :
1364 NEWT_CHECKBOXTREE_UNSELECTED);
c895490d 1365
1366 Py_INCREF(Py_None);
1367 return Py_None;
1368}
1369
1370static PyObject * widgetCheckboxTreeGetEntryValue(snackWidget * s, PyObject * args) {
1371 int data;
1372 int isOn = 0;
1373 int isBranch = 0;
1374 char selection;
1375
1376 if (!PyArg_ParseTuple(args, "i", &data)) return NULL;
1377
d7e202d6 1378 selection = newtCheckboxTreeGetEntryValue(s->co, I2P(data));
c895490d 1379
c104daae
ML
1380 if (selection == -1) {
1381 PyErr_SetString(PyExc_KeyError, "unknown entry");
1382 return NULL;
1383 }
c895490d 1384
1385 switch (selection) {
1386 case NEWT_CHECKBOXTREE_EXPANDED:
6f481af2 1387 isOn = 1;
c895490d 1388 case NEWT_CHECKBOXTREE_COLLAPSED:
6f481af2 1389 isBranch = 1;
1390 break;
c895490d 1391 case NEWT_CHECKBOXTREE_UNSELECTED:
6f481af2 1392 break;
c895490d 1393 default:
6f481af2 1394 isOn = 1;
1395 break;
c895490d 1396 }
1397 return Py_BuildValue("(ii)", isBranch, isOn);
1398}
1399
5a6729cf 1400static PyObject * widgetCheckboxTreeGetSel(snackWidget * s,
6f481af2 1401 PyObject * args) {
f06c5a99 1402 void ** selection;
1403 int numselected;
5a6729cf 1404 int i;
c104daae 1405 PyObject * sel, * int_obj;
f06c5a99 1406
2b6641b1 1407 if (!PyArg_ParseTuple(args, ""))
6f481af2 1408 return NULL;
2b6641b1 1409
72b71fa6 1410 selection = (void **) newtCheckboxTreeGetSelection(s->co, &numselected);
f06c5a99 1411
788ec656 1412 sel = PyList_New(0);
1413
5a6729cf 1414 if (!selection) {
6f481af2 1415 return sel;
f06c5a99 1416 }
1417
5a6729cf 1418 for (i = 0; i < numselected; i++) {
c104daae
ML
1419 int_obj = PyInt_FromLong((long) selection[i]);
1420 PyList_Append(sel, int_obj);
1421 Py_DECREF(int_obj);
5a6729cf 1422 }
1423 free(selection);
f06c5a99 1424
5a6729cf 1425 return sel;
f06c5a99 1426}
1427
ce11acc8 1428static PyObject * pywstrlen(PyObject * s, PyObject * args)
1429{
1430 char *str;
1431 int len = -1;
1432
1433 if (!PyArg_ParseTuple(args, "s|i", &str, &len)) return NULL;
1434
1435 return PyInt_FromLong(wstrlen(str, len));
1436}
1437
c104daae
ML
1438static void setitemstring_decref(PyObject * dict,
1439 const char * s, PyObject * o)
1440{
1441 PyDict_SetItemString(dict, s, o);
1442 Py_DECREF(o);
1443}
1444
ba3eb78a
MK
1445MOD_INIT(_snack)
1446{
6e25d997 1447 PyObject * d, * m;
1448
ba3eb78a
MK
1449#if PY_MAJOR_VERSION >= 3
1450 m = PyModule_Create(&moduledef);
1451#else
6e25d997 1452 m = Py_InitModule("_snack", snackModuleMethods);
ba3eb78a
MK
1453#endif
1454
1455 if (!m)
1456 return MOD_ERROR_VAL;
1457
6e25d997 1458 d = PyModule_GetDict(m);
1459
c104daae
ML
1460 setitemstring_decref(d, "ANCHOR_LEFT", PyInt_FromLong(NEWT_ANCHOR_LEFT));
1461 setitemstring_decref(d, "ANCHOR_TOP", PyInt_FromLong(NEWT_ANCHOR_TOP));
1462 setitemstring_decref(d, "ANCHOR_RIGHT", PyInt_FromLong(NEWT_ANCHOR_RIGHT));
1463 setitemstring_decref(d, "ANCHOR_BOTTOM",
6f481af2 1464 PyInt_FromLong(NEWT_ANCHOR_BOTTOM));
c104daae
ML
1465 setitemstring_decref(d, "GRID_GROWX", PyInt_FromLong(NEWT_GRID_FLAG_GROWX));
1466 setitemstring_decref(d, "GRID_GROWY", PyInt_FromLong(NEWT_GRID_FLAG_GROWY));
1467
1468 setitemstring_decref(d, "FD_READ", PyInt_FromLong(NEWT_FD_READ));
1469 setitemstring_decref(d, "FD_WRITE", PyInt_FromLong(NEWT_FD_WRITE));
1470 setitemstring_decref(d, "FD_EXCEPT", PyInt_FromLong(NEWT_FD_EXCEPT));
1471
1472 setitemstring_decref(d, "FORM_EXIT_HOTKEY", PyString_FromString("hotkey"));
1473 setitemstring_decref(d, "FORM_EXIT_WIDGET", PyString_FromString("widget"));
1474 setitemstring_decref(d, "FORM_EXIT_TIMER", PyString_FromString("timer"));
1475 setitemstring_decref(d, "FORM_EXIT_FDREADY", PyString_FromString("fdready"));
508a125b 1476 setitemstring_decref(d, "FORM_EXIT_ERROR", PyString_FromString("error"));
c104daae
ML
1477
1478 setitemstring_decref(d, "KEY_TAB", PyInt_FromLong(NEWT_KEY_TAB));
1479 setitemstring_decref(d, "KEY_ENTER", PyInt_FromLong(NEWT_KEY_ENTER));
1480 setitemstring_decref(d, "KEY_SUSPEND", PyInt_FromLong(NEWT_KEY_SUSPEND));
1481 setitemstring_decref(d, "KEY_UP", PyInt_FromLong(NEWT_KEY_UP));
1482 setitemstring_decref(d, "KEY_DOWN", PyInt_FromLong(NEWT_KEY_DOWN));
1483 setitemstring_decref(d, "KEY_LEFT", PyInt_FromLong(NEWT_KEY_LEFT));
1484 setitemstring_decref(d, "KEY_RIGHT", PyInt_FromLong(NEWT_KEY_RIGHT));
1485 setitemstring_decref(d, "KEY_BACKSPACE", PyInt_FromLong(NEWT_KEY_BKSPC));
1486 setitemstring_decref(d, "KEY_DELETE", PyInt_FromLong(NEWT_KEY_DELETE));
1487 setitemstring_decref(d, "KEY_HOME", PyInt_FromLong(NEWT_KEY_HOME));
1488 setitemstring_decref(d, "KEY_END", PyInt_FromLong(NEWT_KEY_END));
1489 setitemstring_decref(d, "KEY_UNTAB", PyInt_FromLong(NEWT_KEY_UNTAB));
1490 setitemstring_decref(d, "KEY_PAGEUP", PyInt_FromLong(NEWT_KEY_PGUP));
1491 setitemstring_decref(d, "KEY_PAGEGDOWN", PyInt_FromLong(NEWT_KEY_PGDN));
1492 setitemstring_decref(d, "KEY_INSERT", PyInt_FromLong(NEWT_KEY_INSERT));
1493 setitemstring_decref(d, "KEY_F1", PyInt_FromLong(NEWT_KEY_F1));
1494 setitemstring_decref(d, "KEY_F2", PyInt_FromLong(NEWT_KEY_F2));
1495 setitemstring_decref(d, "KEY_F3", PyInt_FromLong(NEWT_KEY_F3));
1496 setitemstring_decref(d, "KEY_F4", PyInt_FromLong(NEWT_KEY_F4));
1497 setitemstring_decref(d, "KEY_F5", PyInt_FromLong(NEWT_KEY_F5));
1498 setitemstring_decref(d, "KEY_F6", PyInt_FromLong(NEWT_KEY_F6));
1499 setitemstring_decref(d, "KEY_F7", PyInt_FromLong(NEWT_KEY_F7));
1500 setitemstring_decref(d, "KEY_F8", PyInt_FromLong(NEWT_KEY_F8));
1501 setitemstring_decref(d, "KEY_F9", PyInt_FromLong(NEWT_KEY_F9));
1502 setitemstring_decref(d, "KEY_F10", PyInt_FromLong(NEWT_KEY_F10));
1503 setitemstring_decref(d, "KEY_F11", PyInt_FromLong(NEWT_KEY_F11));
1504 setitemstring_decref(d, "KEY_F12", PyInt_FromLong(NEWT_KEY_F12));
1505 setitemstring_decref(d, "KEY_ESC", PyInt_FromLong(NEWT_KEY_ESCAPE));
d861e991 1506 setitemstring_decref(d, "KEY_RESIZE", PyInt_FromLong(NEWT_KEY_RESIZE));
c104daae
ML
1507
1508 setitemstring_decref(d, "FLAG_DISABLED", PyInt_FromLong(NEWT_FLAG_DISABLED));
1509 setitemstring_decref(d, "FLAGS_SET", PyInt_FromLong(NEWT_FLAGS_SET));
1510 setitemstring_decref(d, "FLAGS_RESET", PyInt_FromLong(NEWT_FLAGS_RESET));
1511 setitemstring_decref(d, "FLAGS_TOGGLE", PyInt_FromLong(NEWT_FLAGS_TOGGLE));
1512
1513 setitemstring_decref(d, "COLORSET_ROOT", PyInt_FromLong(NEWT_COLORSET_ROOT));
1514 setitemstring_decref(d, "COLORSET_BORDER", PyInt_FromLong(NEWT_COLORSET_BORDER));
1515 setitemstring_decref(d, "COLORSET_WINDOW", PyInt_FromLong(NEWT_COLORSET_WINDOW));
1516 setitemstring_decref(d, "COLORSET_SHADOW", PyInt_FromLong(NEWT_COLORSET_SHADOW));
1517 setitemstring_decref(d, "COLORSET_TITLE", PyInt_FromLong(NEWT_COLORSET_TITLE));
1518 setitemstring_decref(d, "COLORSET_BUTTON", PyInt_FromLong(NEWT_COLORSET_BUTTON));
1519 setitemstring_decref(d, "COLORSET_ACTBUTTON", PyInt_FromLong(NEWT_COLORSET_ACTBUTTON));
1520 setitemstring_decref(d, "COLORSET_CHECKBOX", PyInt_FromLong(NEWT_COLORSET_CHECKBOX));
1521 setitemstring_decref(d, "COLORSET_ACTCHECKBOX", PyInt_FromLong(NEWT_COLORSET_ACTCHECKBOX));
1522 setitemstring_decref(d, "COLORSET_ENTRY", PyInt_FromLong(NEWT_COLORSET_ENTRY));
1523 setitemstring_decref(d, "COLORSET_LABEL", PyInt_FromLong(NEWT_COLORSET_LABEL));
1524 setitemstring_decref(d, "COLORSET_LISTBOX", PyInt_FromLong(NEWT_COLORSET_LISTBOX));
1525 setitemstring_decref(d, "COLORSET_ACTLISTBOX", PyInt_FromLong(NEWT_COLORSET_ACTLISTBOX));
1526 setitemstring_decref(d, "COLORSET_TEXTBOX", PyInt_FromLong(NEWT_COLORSET_TEXTBOX));
1527 setitemstring_decref(d, "COLORSET_ACTTEXTBOX", PyInt_FromLong(NEWT_COLORSET_ACTTEXTBOX));
1528 setitemstring_decref(d, "COLORSET_HELPLINE", PyInt_FromLong(NEWT_COLORSET_HELPLINE));
1529 setitemstring_decref(d, "COLORSET_ROOTTEXT", PyInt_FromLong(NEWT_COLORSET_ROOTTEXT));
1530 setitemstring_decref(d, "COLORSET_EMPTYSCALE", PyInt_FromLong(NEWT_COLORSET_EMPTYSCALE));
1531 setitemstring_decref(d, "COLORSET_FULLSCALE", PyInt_FromLong(NEWT_COLORSET_FULLSCALE));
1532 setitemstring_decref(d, "COLORSET_DISENTRY", PyInt_FromLong(NEWT_COLORSET_DISENTRY));
1533 setitemstring_decref(d, "COLORSET_COMPACTBUTTON", PyInt_FromLong(NEWT_COLORSET_COMPACTBUTTON));
1534 setitemstring_decref(d, "COLORSET_ACTSELLISTBOX", PyInt_FromLong(NEWT_COLORSET_ACTSELLISTBOX));
1535 setitemstring_decref(d, "COLORSET_SELLISTBOX", PyInt_FromLong(NEWT_COLORSET_SELLISTBOX));
ba3eb78a
MK
1536
1537 return MOD_SUCCESS_VAL(m);
80d03bd8 1538}