home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / pippy-0.6beta-src.tar.gz / pippy-0.6beta-src.tar / pippy-0.6beta-src / src / Modules / palmformmodule.c < prev    next >
C/C++ Source or Header  |  2000-12-27  |  11KB  |  503 lines

  1. /*
  2.   palmform module
  3.  
  4.   This module provides an interface to the PalmOS form objects
  5.   and functions.
  6.  
  7.   METHODS
  8.  
  9.   draw()               # FrmDrawForm
  10.   handleEvent()        # FrmHandleEvent
  11.   setEventHandler()    # FrmSetEventHandler - would actually register globally so
  12.                        # that FrmDispatchEvent will work properly
  13.   setActive()          # FrmSetActive
  14.   setFocus (fieldIndex)# FrmSetFocus
  15.  
  16.  
  17.   MODULE FUNCTIONS
  18.  
  19.   getActiveForm()      # FrmGetActiveForm
  20.   initForm(formId)     # FrmInitForm
  21.   goto()               # FrmGotoForm
  22.  
  23.  
  24. */
  25. #include "kludge.h"
  26. #include "structmember.h"
  27. #include "_palmutils.h"
  28. #include "PalmCompatibility.h"
  29. #include "set_a4.h"
  30. #include "GLib_interface.h"
  31. #include "palmeventmodule.h"
  32.  
  33. #define SHOW(flag, msg)
  34. /* #define SHOW(flag, msg) ErrFatalDisplayIf(flag, msg) */
  35.  
  36. static PyObject *palmform_error;
  37.  
  38. #define PalmFormObject_Check(op) ((op)->ob_type == &PalmForm_Type)
  39.  
  40. /* Palm Form Object */
  41. typedef struct {
  42.     PyObject_HEAD
  43.  
  44. /* Palm Database Object */
  45.     FormType *form;
  46. } palmformobject;
  47.  
  48. static PyTypeObject PalmForm_Type;
  49.  
  50. static PyObject *
  51. newform(FormType *form)
  52. {
  53.     /* NOTE: For the time being, form objects will not take possession of
  54.        the actual form - they simply behave as FormType containers.  I
  55.        think that this is only a problem if the FrmDeleteForm function
  56.        gets implemented.  Then, ownership becomes more important.
  57.     */
  58.  
  59.     palmformobject *frm;
  60.  
  61.     if (!( frm = PyObject_NEW(palmformobject, &PalmForm_Type) ))
  62.         return NULL;
  63.  
  64.     frm->form = form;
  65.  
  66.     return (PyObject *) frm;
  67. }
  68.  
  69. static void
  70. formobj_dealloc(palmformobject *frm)
  71. {
  72. /*     free(frm->form); */
  73.     frm->form = NULL;
  74.     PyMem_DEL(frm);
  75. }
  76.  
  77. static PyObject*
  78. formobj_draw(palmformobject *frm, PyObject *args)
  79. {
  80.         
  81.     if (!PyArg_ParseTuple(args, ""))
  82.         return NULL;
  83.     
  84.     FrmDrawForm (frm->form);
  85.  
  86.     Py_INCREF(Py_None);
  87.     return Py_None;
  88. }    
  89. static PyObject*
  90. formobj_handleEvent(palmformobject *frm, PyObject *args)
  91. {
  92.     EventType *event;
  93.     PyObject *eventWrapper;
  94.     Boolean res;
  95.  
  96.     if (!PyArg_ParseTuple(args, "O", &eventWrapper))
  97.         return NULL;
  98.     if (!PalmEventObject_Check(eventWrapper)) {
  99.         PyErr_SetString(PyExc_ValueError, "Expecting a PalmEventObject");
  100.         return NULL;
  101.     }
  102.  
  103.     event = (EventType *) ((palmeventobject *)eventWrapper)->event;
  104.     res = FrmHandleEvent (frm->form, event);
  105.  
  106.     return Py_BuildValue("i", (res ? 1 : 0));
  107. }    
  108.  
  109.  
  110. /* Handlers are stored using linked-list that behaves like a stack */
  111.  
  112. typedef struct _handler_item {
  113.     UInt16 formID;
  114.     PyObject *callback;
  115.     struct _handler_item *next;
  116. } handler_item;
  117.  
  118. handler_item *handlers = NULL;
  119.  
  120. static int
  121. _addHandler(UInt16 formId, PyObject *func)
  122. {
  123.     handler_item *h;
  124.     int status = -1;
  125.  
  126.     /* check for a handler with the same formId and replace */
  127.     h = handlers;
  128.     while (h != NULL) {
  129.         if (h->formID == formId)
  130.             break;
  131.         h = h->next;
  132.     }
  133.     if (h == NULL) {
  134.         h = (handler_item*) malloc(sizeof(handler_item));
  135.         if (!h)
  136.             return status;
  137.  
  138.         /* insert new item at the front of the list */
  139.         if (handlers == NULL) {
  140.             handlers = h;
  141.             handlers->next = NULL;
  142.             status = 0;
  143.         }
  144.         else {
  145.             h->next = handlers;
  146.             handlers = h;
  147.             status = 0;
  148.         }
  149.     }
  150.     else {
  151.         Py_DECREF(h->callback);
  152.         status = 0;
  153.     }
  154.  
  155.     h->formID = formId;
  156.     h->callback = func;
  157.     Py_INCREF(h->callback);
  158.  
  159.     return status;
  160. }
  161.  
  162. static Boolean
  163. _genericEventHandler(EventType *evt)
  164. {
  165.     handler_item *h;
  166.     UInt16 targetID;
  167.     PyObject *res, *event;
  168.  
  169.     SET_A4_FOR_GLIB('PyLb');
  170.     
  171.     h = handlers;
  172. /*     targetID = evt->data.frmLoad.formID; */
  173.     SHOW(1, "Getting formID");
  174.     targetID = FrmGetActiveFormID();
  175.     SHOW(1, "Got formID");
  176.     while (h != NULL) {
  177.         /* all forms have the formID as their first item, 
  178.            so we'll just use frmLoad to get it */
  179.         if (h->formID == targetID)
  180.             break;
  181.         printf("h->formID, targetID = %d %d\n", h->formID,targetID);
  182.         h = h->next;
  183.     }
  184.  
  185.     if (h == NULL) {
  186.         RESTORE_A4;
  187.         return false;  /* unable to find handler - really should abort */
  188.     }
  189.  
  190.     if ((event = Palm_WrapNewEvent(evt)) == NULL) {
  191.         PyErr_SetString(palmform_error,
  192.                 "Problem wrapping event - memory error?");
  193.         RESTORE_A4;
  194.         return false;
  195.     }
  196.     SHOW(1, "Calling function");
  197.     if (h->callback == NULL)
  198.         SHOW(1, "Callback function is null");
  199.     res = PyEval_CallObject(h->callback, Py_BuildValue("(O)", event));
  200.     SHOW(1, "Done calling function");
  201.     
  202.     /* When the Python event loop is finally working, the following
  203.        PyErr_* calls should be eliminated and the checks for errors
  204.        placed in the event loop itself. */
  205.     if (res == NULL) {
  206.                  SHOW(1, "Got an error calling function");
  207.         PyErr_Print();
  208.         PyErr_Clear();
  209.         RESTORE_A4;
  210.         return false;
  211.     }
  212.     RESTORE_A4;
  213.     return true;
  214.  
  215. }
  216.  
  217.  
  218. static PyObject*
  219. formobj_setEventHandler(palmformobject *frm, PyObject *args)
  220. {
  221.     PyObject *func;
  222.  
  223.     if (!PyArg_ParseTuple(args, "O", &func))
  224.         return NULL;
  225.     if (!PyCallable_Check(func)) {
  226.         PyErr_SetString(PyExc_ValueError, "Object must be callable");
  227.         return NULL;
  228.     }
  229.     if ( _addHandler( FrmGetFormId(frm->form), func ) == -1) {
  230.         PyErr_SetString(PyExc_MemoryError, "Out of memory");
  231.         return NULL;
  232.     }
  233.     FrmSetEventHandler (frm->form, _genericEventHandler);
  234.     Py_INCREF(Py_None);
  235.     return Py_None;
  236. }
  237.  
  238. static PyObject*
  239. formobj_setActive(palmformobject *frm, PyObject *args)
  240. {
  241.     if (!PyArg_ParseTuple(args, ""))
  242.         return NULL;
  243.  
  244.     FrmSetActiveForm (frm->form);
  245.  
  246.     Py_INCREF(Py_None);
  247.     return Py_None;
  248. }    
  249. static PyObject*
  250. formobj_setFocus(palmformobject *frm, PyObject *args)
  251. {
  252.     Py_INCREF(Py_None);
  253.     return Py_None;
  254. }    
  255.  
  256.  
  257.  
  258. /* form object methods */
  259. static PyMethodDef formobj_methods[] = {
  260.     {"draw",        (PyCFunction)formobj_draw, METH_VARARGS},
  261.     {"handleEvent",        (PyCFunction)formobj_handleEvent, METH_VARARGS},
  262.     {"setEventHandler",    (PyCFunction)formobj_setEventHandler, METH_VARARGS},
  263.     {"setActive",        (PyCFunction)formobj_setActive, METH_VARARGS},
  264.     {"setFocus",        (PyCFunction)formobj_setFocus, METH_VARARGS},
  265.     {NULL,               NULL}        /* sentinel */
  266. };
  267.  
  268. /* form object attributes read directly from the form structure */
  269. #define OFF(x) offsetof(FormType, x)
  270. static struct memberlist formobj_memberlist[] = {
  271.     {"formId",    T_INT,            OFF(formId)},
  272.     {"numObjects",    T_INT,            OFF(numObjects)},
  273.     {NULL}    /* Sentinel */
  274. };
  275.  
  276. /* the following was taken from structmember.c and modified */
  277. static PyObject *
  278. listmethods(mlist)
  279.     PyMethodDef *mlist;
  280. {
  281.     int i, n;
  282.     PyObject *v;
  283.     for (n = 0; mlist[n].ml_name != NULL; n++)
  284.         ;
  285.     v = PyList_New(n);
  286.     if (v != NULL) {
  287.         for (i = 0; i < n; i++)
  288.             PyList_SetItem(v, i,
  289.                        PyString_FromString(mlist[i].ml_name));
  290.         if (PyErr_Occurred()) {
  291.             Py_DECREF(v);
  292.             v = NULL;
  293.         }
  294.         else {
  295.             PyList_Sort(v);
  296.         }
  297.     }
  298.     return v;
  299. }
  300.  
  301. static PyObject *
  302. formobj_getattr(palmformobject *frm, PyObject *name)
  303. {
  304.     char *sname = PyString_AsString(name);
  305.     PyObject *res;
  306.  
  307.     if (strcmp(sname, "__members__") == 0)
  308.         return listmethods(formobj_methods);
  309.  
  310.     res = PyMember_Get((char*)frm->form, formobj_memberlist, sname);
  311.     if (res == NULL)
  312.         res = Py_FindMethod(formobj_methods, (PyObject *) frm, sname);
  313.  
  314.     return res;
  315. }
  316.  
  317. static PyTypeObject PalmForm_Type = {
  318.     PyObject_HEAD_INIT(NULL)
  319.     0,
  320.     "palmformobject",
  321.     sizeof(palmformobject),
  322.     0,
  323.     (destructor)formobj_dealloc, /*tp_dealloc*/
  324.     0,            /*tp_print*/
  325.     0,                      /*tp_getattr*/
  326.     0,                      /*tp_setattr*/
  327.     0,            /*tp_compare*/
  328.     0,            /*tp_repr*/
  329.     0,            /*tp_as_number*/
  330.     0,            /*tp_as_sequence*/
  331.     0,            /*tp_as_mapping*/
  332.     0,                      /*tp_hash*/
  333.     0,            /*tp_call*/
  334.     0,            /*tp_str*/
  335.     (getattrofunc)formobj_getattr, /*tp_setattro*/
  336.     0,            /*tp_setattro*/
  337. };
  338.  
  339. /* Module functions */
  340. static PyObject *
  341. palmform_getActiveForm(PyObject *self, PyObject *args)
  342. {
  343.     FormType *form;
  344.  
  345.     if (!PyArg_ParseTuple(args, ""))
  346.         return NULL;
  347.     
  348.     form = FrmGetActiveForm();
  349.     if (form == NULL) 
  350.         return NULL;
  351.  
  352.     return newform(form);
  353. }
  354. static PyObject *
  355. palmform_setActiveForm(PyObject *self, PyObject *args)
  356. {
  357.     palmformobject *frm;
  358.  
  359.     if (!PyArg_ParseTuple(args, "O:setActiveForm", &frm))
  360.         return NULL;
  361.  
  362.     FrmSetActiveForm (frm->form);
  363.  
  364.     Py_INCREF(Py_None);
  365.     return Py_None;
  366. }
  367. static PyObject *
  368. palmform_initForm(PyObject *self, PyObject *args)
  369. {
  370.     int resId;
  371.     FormType *form;
  372.  
  373.     if (!PyArg_ParseTuple(args, "i:initForm", &resId))
  374.         return NULL;
  375.  
  376.     form = FrmInitForm(resId);
  377.     if (form == NULL)
  378.         return NULL;
  379.  
  380.     return newform(form);
  381. }
  382. static PyObject *
  383. palmform_gotoForm(PyObject *self, PyObject *args)
  384. {
  385.     int formId;
  386.     if (!PyArg_ParseTuple(args, "i:form", &formId))
  387.         return NULL;
  388.     
  389.     FrmGotoForm (formId);
  390.  
  391.     Py_INCREF(Py_None);
  392.     return Py_None;
  393. }
  394.  
  395. static PyObject *
  396. palmform_alert(PyObject *self, PyObject *args)
  397. {
  398.     int alertId, res;
  399.     if (!PyArg_ParseTuple(args, "i:alert", &alertId))
  400.         return NULL;
  401.     
  402.     res = FrmAlert(alertId);
  403.     return PyInt_FromLong( (long) res );
  404. }
  405.  
  406. static PyObject *
  407. palmform_closeAllForms(PyObject *self, PyObject *args)
  408. {
  409.     if (!PyArg_ParseTuple(args, ""))
  410.         return NULL;
  411.     
  412.     FrmCloseAllForms();
  413.     Py_INCREF(Py_None);
  414.     return Py_None;
  415. }
  416. static PyObject *
  417. palmform_saveAllForms(PyObject *self, PyObject *args)
  418. {
  419.     if (!PyArg_ParseTuple(args, ""))
  420.         return NULL;
  421.     
  422.     FrmSaveAllForms();
  423.     Py_INCREF(Py_None);
  424.     return Py_None;
  425. }
  426.  
  427. static PyObject*
  428. palmform_dispatchEvent(PyObject *self, PyObject *args)
  429. {
  430.     Boolean result;
  431.     PyObject *eventWrapper;
  432.     EventType *event;
  433.     Err err;
  434.  
  435.     if (!PyArg_ParseTuple(args, "O", &eventWrapper))
  436.         return NULL;
  437.     if (!PalmEventObject_Check(eventWrapper)) {
  438.         PyErr_SetString(PyExc_ValueError, "Expecting a PalmEventObject");
  439.         return NULL;
  440.     }
  441.  
  442.     event = (EventType *) ((palmeventobject *)eventWrapper)->event;
  443.     result = FrmDispatchEvent(event);
  444.  
  445.     return Py_BuildValue("i", (result ? 1 : 0));
  446. }
  447.  
  448.  
  449. static PyMethodDef palmform_methods[] = {
  450.     {"getActiveForm",    (PyCFunction)palmform_getActiveForm, METH_VARARGS},
  451.     {"setActiveForm",    (PyCFunction)palmform_setActiveForm, METH_VARARGS},
  452.     {"initForm",            (PyCFunction)palmform_initForm, METH_VARARGS},
  453.     {"alert",            (PyCFunction)palmform_alert, METH_VARARGS},
  454.     {"gotoForm",            (PyCFunction)palmform_gotoForm, METH_VARARGS},
  455.     {"closeAllForms",    (PyCFunction)palmform_closeAllForms, METH_VARARGS},
  456.     {"saveAllForms",    (PyCFunction)palmform_saveAllForms, METH_VARARGS},
  457.     {"dispatchEvent",    (PyCFunction)palmform_dispatchEvent, METH_VARARGS},
  458.     {NULL,               NULL}        /* sentinel */
  459. };
  460.  
  461. static PyObject *palmeventmodule;
  462.  
  463. static void
  464. _cleanup(void)
  465. {
  466.     handler_item *h = handlers, *next;
  467.     
  468.     /* clean up the event handlers */
  469.     if (h != NULL)
  470.         while (h->next) {
  471.             next = h->next;
  472.             Py_DECREF(h->callback);
  473.             free(h);
  474.             h = next;
  475.         }
  476.  
  477.     /* decref palmevent module - no longer needed */
  478.     Py_DECREF(palmeventmodule);
  479. }
  480.  
  481.  
  482. void initpalmform(void) {
  483.     PyObject *m, *d;
  484.  
  485.     m = Py_InitModule3("palmform", palmform_methods, NULL);
  486.     d = PyModule_GetDict(m);
  487.     palmform_error = PyErr_NewException("palmform.error", NULL, NULL);
  488.     if (palmform_error == NULL)
  489.         return;
  490.  
  491.     PyDict_SetItemString(d, "error", palmform_error);
  492.  
  493.     /* Import the palmevent module so that events may be 
  494.        used. */
  495.     palmeventmodule = PyImport_ImportModule("palmevent");
  496.  
  497.     if (PyErr_Occurred)
  498.         PyErr_Clear();
  499.  
  500.     Py_AtExit(_cleanup);
  501.  
  502. }
  503.