updated tx/pytx/torc sorting code...now torc can remember sorting settings
[tore.git] / pytx / pytx.c
blob38f961fd6b7fb747a92dc96fb1e4d89fe7a482c9
1 #include <Python.h>
3 #include "txlist.h"
4 #include "txbox.h"
5 #include "txops.h"
6 #include "txobj.h"
8 /* -------------------------------------------------*/
9 typedef struct {
10 PyObject *text_cb;
11 PyObject *idle_cb;
12 PyObject *bind_cb;
13 PyObject *cmpr_cb;
14 PyObject *size_cb;
15 PyObject *rsze_cb;
16 } PyTXList_Funcs;
18 typedef struct {
19 PyObject_HEAD
20 TXObj tx_obj;
21 void *data;
22 } PyTX_Obj;
24 /* object functions */
26 static PyObject *PyTXObj_draw(PyTX_Obj *self) {
27 tx_obj_draw(&(self->tx_obj));
28 Py_INCREF(Py_None);
29 return Py_None;
32 static PyObject *PyTXObj_flag_set(PyTX_Obj *self, PyObject *args) {
33 int flag, set;
35 PyArg_ParseTuple(args, "ii", &flag, &set);
37 tx_obj_flag_set(&(self->tx_obj), flag, set);
39 Py_INCREF(Py_None);
40 return Py_None;
43 static PyObject *PyTXObj_flag_toggle(PyTX_Obj *self, PyObject *args) {
44 PyObject *result;
45 int flag;
47 PyArg_ParseTuple(args, "i", &flag);
49 flag = tx_obj_flag_toggle(&(self->tx_obj), flag);
50 result = PyInt_FromLong(flag);
52 Py_INCREF(result);
53 return result;
56 static PyObject *PyTXObj_flag_get(PyTX_Obj *self, PyObject *args) {
57 PyObject *result;
58 int flag;
60 PyArg_ParseTuple(args, "i", &flag);
62 flag = tx_obj_flag_get(&(self->tx_obj), flag);
63 result = PyInt_FromLong(flag);
65 Py_INCREF(result);
66 return result;
69 static PyObject *PyTXObj_reset(PyTX_Obj *self) {
70 tx_obj_reset(&(self->tx_obj));
71 Py_INCREF(Py_None);
72 return Py_None;
75 /* list functions */
76 static void PyTXList_free(PyTX_Obj* self) {
77 self->ob_type->tp_free((PyObject*)self);
80 static void *data_cb(TXObj *obj, void *o, void *d) {
81 if (d&&o) {
82 Py_DECREF((PyObject*)o);
84 Py_INCREF((PyObject*)d);
85 return d;
88 char *text_cb(TXObj *obj, char *o, void *d) {
89 PyObject *result, *params;
90 PyTXList_Funcs *funcs = (PyTXList_Funcs*)obj->data;
91 char *text;
93 if (d) free (o);
95 params = Py_BuildValue("(OO)", obj->bind, d);
96 result = PyEval_CallObject(funcs->text_cb, params);
97 text = PyString_AsString(result);
99 Py_DECREF(result);
100 Py_DECREF(params);
101 return strdup(text);
104 int cmpr_cb(TXObj *obj, const struct list_head *a, const struct list_head *b) {
105 TX_EXT(TX_List, list);
106 PyObject *o1, *o2;
108 struct Row *ra = list_entry(a, struct Row, node);
109 struct Row *rb = list_entry(b, struct Row, node);
111 o1 = PyList_GetItem(ra->data, list->cols.sort);
112 o2 = PyList_GetItem(rb->data, list->cols.sort);
114 return list->asc ? PyObject_Compare(o1, o2) : PyObject_Compare(o2, o1);
117 void idle_cb(TXObj *obj) {
118 PyObject *params, *result;
119 PyTXList_Funcs *funcs = (PyTXList_Funcs*)obj->data;
121 params = Py_BuildValue("(O)", obj->bind);
122 result = PyEval_CallObject(funcs->idle_cb, params);
124 Py_DECREF(params);
125 Py_DECREF(result);
128 void bind_cb(TXObj *obj, int ch, int key) {
129 PyObject *params, *result;
130 PyTXList_Funcs *funcs = (PyTXList_Funcs*)obj->data;
132 params = Py_BuildValue("(Oii)", obj->bind, ch, key);
133 result = PyEval_CallObject(funcs->bind_cb, params);
135 Py_DECREF(result);
136 Py_DECREF(params);
139 void rsze_cb(TXObj *obj) {
140 PyObject *params, *result;
142 PyTXList_Funcs *funcs = (PyTXList_Funcs*)obj->data;
144 params = Py_BuildValue("(O)", obj->bind);
145 result = PyEval_CallObject(funcs->rsze_cb, params);
147 Py_DECREF(result);
148 Py_DECREF(params);
151 int size_cb(TXObj *obj, int s, int d) {
152 int size;
154 PyObject *result, *params;
155 PyTXList_Funcs *funcs = (PyTXList_Funcs*)obj->data;
158 params = Py_BuildValue("(Oii)", obj->bind, s, d);
159 result = PyEval_CallObject(funcs->size_cb, params);
160 size = (int)PyInt_AsLong(result);
162 Py_DECREF(result);
163 Py_DECREF(params);
165 return size;
168 int getc_cb(TXObj *obj) {
169 int key;
171 Py_BEGIN_ALLOW_THREADS
172 key = getch();
173 Py_END_ALLOW_THREADS
175 return key;
178 static int PyTXList_init(PyTX_Obj *self, PyObject *args, PyObject *kwds) {
179 int flags;
180 PyObject *cb;
181 PyTXList_Funcs *funcs;
182 PyArg_ParseTuple(args, "|i", &flags);
183 tx_obj_init(&(self->tx_obj), TX_LIST, PyTuple_Size(args) ? flags : 0);
185 tx_obj_getc_cb_set(&(self->tx_obj), getc_cb);
187 self->tx_obj.bind = self;
188 self->tx_obj.data = calloc(1, sizeof(PyTXList_Funcs));
189 assert(self->tx_obj.data);
190 funcs = self->tx_obj.data;
192 cb = PyDict_GetItemString(self->ob_type->tp_dict, "text_cb");
193 if (cb && PyFunction_Check(cb)) {
194 tx_list_data_cb_set(&(self->tx_obj), data_cb);
195 funcs->text_cb = cb;
198 cb = PyDict_GetItemString(self->ob_type->tp_dict, "idle_cb");
199 if (cb && PyFunction_Check(cb)) {
200 tx_obj_idle_cb_set(&(self->tx_obj), idle_cb);
201 funcs->idle_cb = cb;
204 cb = PyDict_GetItemString(self->ob_type->tp_dict, "bind_cb");
205 if (cb && PyFunction_Check(cb)) {
206 tx_list_bind_cb_set(&(self->tx_obj), bind_cb);
207 funcs->bind_cb = cb;
210 tx_list_cmpr_cb_set(&(self->tx_obj), cmpr_cb);
212 /* FIXME: restore previous cmpr_cb for custom compare */
213 cb = PyDict_GetItemString(self->ob_type->tp_dict, "cmpr_cb");
214 if (cb && PyFunction_Check(cb)) {
215 tx_list_cmpr_cb_set(&(self->tx_obj), cmpr_cb);
216 funcs->cmpr_cb = cb;
219 cb = PyDict_GetItemString(self->ob_type->tp_dict, "size_cb");
220 if (cb && PyFunction_Check(cb)) {
221 tx_obj_size_cb_set(&(self->tx_obj), size_cb);
222 funcs->size_cb = cb;
225 cb = PyDict_GetItemString(self->ob_type->tp_dict, "rsze_cb");
226 if (cb && PyFunction_Check(cb)) {
227 tx_obj_rsze_cb_set(&(self->tx_obj), rsze_cb);
228 funcs->rsze_cb = cb;
231 return 0;
234 char **cols_cb(TXObj *obj, char *o, void *d) {
235 PyObject *result, *params, *item;
236 int ncols, i;
237 char **cols;
239 PyTXList_Funcs *funcs = (PyTXList_Funcs*)obj->data;
241 if (o&&d) free (o);
243 params = Py_BuildValue("(OO)", obj->bind, d);
244 result = PyEval_CallObject(funcs->text_cb, params);
246 ncols = PyList_Size(result);
247 cols = malloc(sizeof(char *) * ncols);
248 assert(cols);
250 for (i=0; i < ncols; ++i) {
251 item = PyList_GetItem(result, i);
252 cols[i] = PyString_AsString(item);
255 Py_DECREF(params);
256 Py_DECREF(result);
257 return cols;
260 static PyObject *PyTXList_columns_width_set(PyTX_Obj *self, PyObject *args) {
261 PyObject *py_widths;
262 int i, ncols, *widths;
264 PyArg_ParseTuple(args, "O", &py_widths);
266 ncols = PyList_Size(py_widths);
267 widths = malloc(sizeof(int) * ncols);
268 assert(widths);
270 for (i = 0; i < ncols; ++i)
271 widths[i] = PyInt_AsLong(PyList_GetItem(py_widths, i));
273 tx_list_columns_width_set(&(self->tx_obj), ncols, widths);
274 free(widths);
276 widths = tx_list_columns_width_get(&(self->tx_obj));
277 for (i = 0; i < ncols; ++i)
278 PyList_SetItem(py_widths, i, PyInt_FromLong(widths[i]));
280 /* set cols_cb upon setting widths */
281 tx_list_cols_cb_set(&(self->tx_obj), cols_cb);
283 /* give object access to list array */
284 PyDict_SetItemString(self->ob_type->tp_dict, "widths", py_widths);
286 Py_INCREF(py_widths);
287 Py_INCREF(Py_None);
288 return Py_None;
292 static PyObject *PyTXList_columns_title_set(PyTX_Obj *self, PyObject *args) {
293 PyObject *py_titles, *title;
294 int i, ncols;
295 char **titles;
297 PyArg_ParseTuple(args, "O", &py_titles);
299 ncols = PyList_Size(py_titles);
300 titles = malloc(sizeof(char*) * ncols);
301 assert(titles);
303 for (i = 0; i < ncols; ++i) {
304 title = PyList_GetItem(py_titles, i);
305 titles[i] = strdup(PyString_AsString(title));
308 tx_list_columns_title_set(&(self->tx_obj), ncols, titles);
309 free(titles);
311 Py_INCREF(Py_None);
312 Py_INCREF(py_titles);
313 return Py_None;
316 static PyObject *PyTXList_scroll(PyTX_Obj *self, PyObject *args) {
317 int scroll;
319 PyArg_ParseTuple(args, "i", &scroll);
320 tx_list_scroll(&(self->tx_obj), scroll);
322 Py_INCREF(Py_None);
323 return Py_None;
326 static PyObject *PyTXList_add(PyTX_Obj *self, PyObject *args) {
327 int key;
328 PyObject *obj;
329 PyTXList_Funcs *funcs = self->tx_obj.data;
331 PyArg_ParseTuple(args, funcs->text_cb?"iO":"is", &key, &obj);
333 tx_list_row_sync(&(self->tx_obj), key, obj);
335 Py_INCREF(Py_None);
336 return Py_None;
339 static PyObject *PyTXList_remove(PyTX_Obj *self, PyObject *args) {
340 int key;
342 PyArg_ParseTuple(args, "i", &key);
344 tx_list_row_remove(&(self->tx_obj), key);
346 Py_INCREF(Py_None);
347 return Py_None;
350 static PyObject *PyTXList_sort_set(PyTX_Obj *self, PyObject *args, PyObject *kwargs) {
351 int col = -1;
352 int asc = -1;
353 char *kwlist[] = {"col", "asc", NULL };
355 PyArg_ParseTupleAndKeywords(args, kwargs,"|ii", kwlist, &col, &asc);
356 if (col != -1) tx_list_column_sort_set(&(self->tx_obj), col);
357 if (asc != -1) tx_list_sort_asc_set(&(self->tx_obj), asc);
359 Py_INCREF(Py_None);
360 return Py_None;
363 static PyObject *PyTXList_sort_get(PyTX_Obj *self) {
364 PyObject *result;
365 int asc, col;
367 col = tx_list_column_sort_get(&(self->tx_obj));
368 asc = tx_list_sort_asc_get(&(self->tx_obj));
370 result = PyTuple_Pack(2, PyInt_FromLong(col), PyInt_FromLong(asc));
372 Py_INCREF(result);
373 return result;
376 static PyObject *PyTXList_sort(PyTX_Obj *self, PyObject *args) {
377 tx_list_sort(&(self->tx_obj));
379 Py_INCREF(Py_None);
380 return Py_None;
383 static PyObject *PyTXList_clear(PyTX_Obj *self) {
384 tx_list_clear(&(self->tx_obj));
386 Py_INCREF(Py_None);
387 return Py_None;
390 static PyObject *PyTXList_sync(PyTX_Obj *self) {
391 tx_list_sync(&(self->tx_obj));
393 Py_INCREF(Py_None);
394 return Py_None;
397 static PyObject *PyTXList_selected(PyTX_Obj *self, PyObject *args) {
398 PyObject *result;
399 int key;
401 if (PyTuple_Size(args)) {
402 PyArg_ParseTuple(args, "i", &key);
403 tx_list_selected_set(&(self->tx_obj), key);
404 Py_INCREF(Py_None);
405 return Py_None;
408 key = tx_list_selected_get(&(self->tx_obj));
409 result = PyInt_FromLong(key);
411 Py_INCREF(result);
412 return result;
415 static PyMethodDef PyTXList_methods[] = {
416 {"flag_set", (PyCFunction)(PyTXObj_flag_set), METH_VARARGS, NULL},
417 {"flag_get", (PyCFunction)(PyTXObj_flag_get), METH_VARARGS, NULL},
418 {"flag_toggle", (PyCFunction)(PyTXObj_flag_toggle), METH_VARARGS, NULL},
419 {"draw", (PyCFunction)(PyTXObj_draw), METH_NOARGS, NULL},
420 {"reset", (PyCFunction)(PyTXObj_reset), METH_NOARGS, NULL},
421 {"add", (PyCFunction)(PyTXList_add), METH_VARARGS, NULL},
422 {"remove", (PyCFunction)(PyTXList_remove), METH_VARARGS, NULL},
423 {"scroll", (PyCFunction)(PyTXList_scroll), METH_VARARGS, NULL},
424 {"selected", (PyCFunction)(PyTXList_selected), METH_VARARGS, NULL},
425 {"sort", (PyCFunction)(PyTXList_sort), METH_NOARGS, NULL},
426 {"sort_get", (PyCFunction)(PyTXList_sort_get), METH_NOARGS, NULL},
427 {"sort_set", (PyCFunction)(PyTXList_sort_set), METH_VARARGS|METH_KEYWORDS, NULL},
428 {"clear", (PyCFunction)(PyTXList_clear), METH_NOARGS, NULL},
429 {"sync", (PyCFunction)(PyTXList_sync), METH_NOARGS, NULL},
430 {"widths_set", (PyCFunction)(PyTXList_columns_width_set), METH_KEYWORDS, NULL},
431 {"titles_set", (PyCFunction)(PyTXList_columns_title_set), METH_KEYWORDS, NULL},
432 {NULL} /* Sentinel */
435 static PyTypeObject PyTXList_Type = {
436 PyObject_HEAD_INIT(NULL)
437 0, /*ob_size*/
438 "pytx.List", /*tp_name*/
439 sizeof(PyTX_Obj), /*tp_basicsize*/
440 0, /*tp_itemsize*/
441 (destructor)PyTXList_free, /*tp_dealloc*/
442 0, /*tp_print*/
443 0, /*tp_getattr*/
444 0, /*tp_setattr*/
445 0, /*tp_compare*/
446 0, /*tp_repr*/
447 0, /*tp_as_number*/
448 0, /*tp_as_sequence*/
449 0, /*tp_as_mapping*/
450 0, /*tp_hash */
451 0, /*tp_call*/
452 0, /*tp_str*/
453 0, /*tp_getattro*/
454 0, /*tp_setattro*/
455 0, /*tp_as_buffer*/
456 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
457 NULL, /* tp_doc */
458 0, /* tp_traverse */
459 0, /* tp_clear */
460 0, /* tp_richcompare */
461 0, /* tp_weaklistoffset */
462 0, /* tp_iter */
463 0, /* tp_iternext */
464 PyTXList_methods, /* tp_methods */
465 0, /* tp_members */
466 0, /* tp_getset */
467 0, /* tp_base */
468 0, /* tp_dict */
469 0, /* tp_descr_get */
470 0, /* tp_descr_set */
471 0, /* tp_dictoffset */
472 (initproc)PyTXList_init, /* tp_init */
473 0, /* tp_alloc */
474 0, /* tp_new */
477 /* ---------------------------------------------------------- */
479 static void PyTXBox_free(PyTX_Obj* self) {
480 self->ob_type->tp_free((PyObject*)self);
483 static int PyTXBox_init(PyTX_Obj *self, PyObject *args, PyObject *kwds) {
484 int flags, align;
485 /* FIXME: ensure we have selected VERT or HORZ */
486 PyArg_ParseTuple(args, "i|i", &align, &flags);
487 tx_obj_init(&(self->tx_obj), TX_BOX, PyTuple_Size(args) == 1 ? align : align|flags);
488 return 0;
491 static PyObject *PyTXBox_add(PyTX_Obj *self, PyObject *args) {
492 PyTX_Obj *add;
493 PyArg_ParseTuple(args, "O", &add);
495 tx_box_add(&(self->tx_obj), &(add->tx_obj));
497 self->tx_obj.bind = self;
498 tx_obj_getc_cb_set(&(self->tx_obj), getc_cb);
500 Py_INCREF(Py_None);
501 return Py_None;
504 static PyObject *PyTXBox_adjust(PyTX_Obj *self) {
505 tx_box_adjust(&(self->tx_obj));
507 Py_INCREF(Py_None);
508 return Py_None;
513 static PyMethodDef PyTXBox_methods[] = {
514 {"add", (PyCFunction)(PyTXBox_add), METH_VARARGS, NULL},
515 {"draw", (PyCFunction)(PyTXObj_draw), METH_NOARGS, NULL},
516 {"adjust", (PyCFunction)(PyTXBox_adjust), METH_NOARGS, NULL},
517 {NULL} /* Sentinel */
521 static PyTypeObject PyTXBox_Type = {
522 PyObject_HEAD_INIT(NULL)
523 0, /*ob_size*/
524 "pytx.Box", /*tp_name*/
525 sizeof(PyTX_Obj), /*tp_basicsize*/
526 0, /*tp_itemsize*/
527 (destructor)PyTXBox_free, /*tp_dealloc*/
528 0, /*tp_print*/
529 0, /*tp_getattr*/
530 0, /*tp_setattr*/
531 0, /*tp_compare*/
532 0, /*tp_repr*/
533 0, /*tp_as_number*/
534 0, /*tp_as_sequence*/
535 0, /*tp_as_mapping*/
536 0, /*tp_hash */
537 0, /*tp_call*/
538 0, /*tp_str*/
539 0, /*tp_getattro*/
540 0, /*tp_setattro*/
541 0, /*tp_as_buffer*/
542 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
543 NULL, /* tp_doc */
544 0, /* tp_traverse */
545 0, /* tp_clear */
546 0, /* tp_richcompare */
547 0, /* tp_weaklistoffset */
548 0, /* tp_iter */
549 0, /* tp_iternext */
550 PyTXBox_methods, /* tp_methods */
551 0, /* tp_members */
552 0, /* tp_getset */
553 0, /* tp_base */
554 0, /* tp_dict */
555 0, /* tp_descr_get */
556 0, /* tp_descr_set */
557 0, /* tp_dictoffset */
558 (initproc)PyTXBox_init, /* tp_init */
559 0, /* tp_alloc */
560 0, /* tp_new */
563 /* ---------------------------------------------------------*/
565 static PyObject *PyTX_init(PyObject *self) {
566 tx_init();
568 Py_INCREF(Py_None);
569 return Py_None;
572 static PyObject *PyTX_emergency(PyObject *self) {
573 tx_ungetc(EMERGENCY);
575 Py_INCREF(Py_None);
576 return Py_None;
579 static PyObject *PyTX_free(PyObject *self) {
580 tx_free();
582 Py_INCREF(Py_None);
583 return Py_None;
586 static PyObject *PyTX_adjust(PyTX_Obj *self) {
587 tx_obj_map(tx_obj_root, tx_obj_resize);
589 Py_INCREF(Py_None);
590 return Py_None;
593 static PyObject *PyTX_operate(PyTX_Obj *self) {
594 tx_obj_operate(tx_obj_focus);
596 Py_INCREF(Py_None);
597 return Py_None;
600 static PyMethodDef PyTX_functions[] = {
601 {"init", (PyCFunction)(PyTX_init), METH_NOARGS, NULL},
602 {"free", (PyCFunction)(PyTX_free), METH_NOARGS, NULL},
603 {"operate", (PyCFunction)(PyTX_operate), METH_VARARGS, NULL},
604 {"adjust", (PyCFunction)(PyTX_adjust), METH_VARARGS, NULL},
605 {"emergency", (PyCFunction)(PyTX_emergency), METH_NOARGS, NULL},
606 {NULL, NULL, 0, NULL }
609 DL_EXPORT(void) initpytx(void) {
610 Py_InitModule("pytx", PyTX_functions);
611 PyObject *m, *d;
612 m = Py_InitModule3("pytx", PyTX_functions, NULL);
614 PyTXList_Type.tp_new = PyType_GenericNew;
615 if (PyType_Ready(&PyTXList_Type) < 0)return;
616 Py_INCREF(&PyTXList_Type);
617 PyModule_AddObject(m, "List", (PyObject *)&PyTXList_Type);
619 PyTXBox_Type.tp_new = PyType_GenericNew;
620 if (PyType_Ready(&PyTXBox_Type) < 0) return;
621 Py_INCREF(&PyTXBox_Type);
622 PyModule_AddObject(m, "Box", (PyObject *)&PyTXBox_Type);
624 d = PyModule_GetDict(m);
625 PyDict_SetItemString(d, "BORDER", PyInt_FromLong(TX_OBJ_BORDER));
626 PyDict_SetItemString(d, "FOCUS", PyInt_FromLong(TX_OBJ_FOCUS));
627 PyDict_SetItemString(d, "ROOT", PyInt_FromLong(TX_OBJ_ROOT));
629 PyDict_SetItemString(d, "SCROLL", PyInt_FromLong(TX_LIST_SCROLL));
630 PyDict_SetItemString(d, "SEPARATOR", PyInt_FromLong(TX_LIST_SEPARATOR));
631 PyDict_SetItemString(d, "TITLES", PyInt_FromLong(TX_LIST_TITLE));
632 PyDict_SetItemString(d, "HIGHLIGHT", PyInt_FromLong(TX_LIST_HLIGHT));
634 PyDict_SetItemString(d, "VERT", PyInt_FromLong(TX_BOX_VERT));
635 PyDict_SetItemString(d, "HORZ", PyInt_FromLong(TX_BOX_HORZ));