[made it work, a python binding to the phidget21.linux.2.1.0 library warner@lothar.com**20060826022313] { addfile ./ChangeLog addfile ./INSTALL addfile ./Makefile addfile ./README addfile ./_phidgetmodule.c addfile ./phidget.py addfile ./setup.py adddir ./test addfile ./test/test_phidget.py hunk ./Makefile 1 + +all: + ./setup.py build_ext -i -I ../phidget21.linux.2.1.0 -L ../phidget21.linux.2.1.0 -R ../phidget21.linux.2.1.0 + +clean: + rm -f _phidgetmodule.so + rm -rf build + +.PHONY: test +test: + PYTHONPATH=. test/test_phidget.py + +load: + PYTHONPATH=. python -c 'import phidget' + +prog: test.c + gcc -g -I ../phidget21.linux.2.1.0 -L ../phidget21.linux.2.1.0 -o prog test.c -lphidget21 -lm + +run: prog + LD_LIBRARY_PATH=../phidget21.linux.2.1.0 ./prog hunk ./_phidgetmodule.c 1 + +#include +#include +#include + +#include "phidget21.h" + +static PyObject *PhidgetError; + +static PyTypeObject PHIDGETHANDLEType; +static PyTypeObject PHIDGETIFKITHANDLEType; +static PyTypeObject PHIDGETTEXTLCDHANDLEType; + +static char * +getErrorDescription(int ErrorCode) +{ + char *description; + + // this returns a pointer to a static string + CPhidget_getErrorDescription(ErrorCode, &description); + return description; +} + +static PyObject * +raisePhidgetError(int ErrorCode) +{ + PyErr_SetString(PhidgetError, getErrorDescription(ErrorCode)); + return NULL; +} + +// ------------ CPhidgetHandle + +// this is the generic one. If you have one of these, all you can do is find +// out things about the device: name, serial number. +typedef struct { + PyObject_HEAD; + CPhidgetHandle phid; +} phidgethandle_t; + +static PyObject * +wrap_phidgethandle(CPhidgetHandle phid) +{ + // wrap an existing CPhidgetHandle with a python object. This can be used + // by the callback wrapper for things like + // CPhidgetManager_set_AttachHandler() so that the python callback + // receives a reference that they can actually use. + phidgethandle_t *self; + self = (phidgethandle_t *)PyObject_New(phidgethandle_t, + &PHIDGETHANDLEType); + if (!self) + return NULL; + self->phid = phid; + return (PyObject *)self; +} + + +static void +phidgethandle_dealloc(phidgethandle_t *self) { + printf("CPhidget_close(%p)\n", self->phid); + CPhidget_close(self->phid); + CPhidget_delete(self->phid); + PyObject_Del(self); +} + +static PyObject * +phidget_getDeviceName(PyObject *self, PyObject *args) { + const char *name; + int rc; + phidgethandle_t *pself = (phidgethandle_t *)self; + + if (!PyArg_ParseTuple(args,"")) return NULL; + if (!CPhidget_isAttached(pself->phid)) { + PyErr_SetString(PhidgetError, "Phidget not attached"); + return NULL; + } + printf("CPhidget_getDeviceName(%p)\n", pself->phid); + rc = CPhidget_getDeviceName(pself->phid, &name); + if (rc == EPHIDGET_OK) { + // 'name' seems to point to a static string + return PyString_FromString(name); + } + PyErr_SetString(PhidgetError, getErrorDescription(rc)); + return NULL; +} + +static PyObject * +phidget_getSerialNumber(PyObject *self, PyObject *args) { + long serialNumber; + int rc; + phidgethandle_t *pself = (phidgethandle_t *)self; + + if (!PyArg_ParseTuple(args,"")) return NULL; + if (!CPhidget_isAttached(pself->phid)) { + PyErr_SetString(PhidgetError, "Phidget not attached"); + return NULL; + } + rc = CPhidget_getSerialNumber(pself->phid, &serialNumber); + if (rc == EPHIDGET_OK) { + return PyInt_FromLong(serialNumber); + } + PyErr_SetString(PhidgetError, getErrorDescription(rc)); + return NULL; +} + +static PyObject * +phidget_getDeviceVersion(PyObject *self, PyObject *args) { + long devVer; + int rc; + phidgethandle_t *pself = (phidgethandle_t *)self; + + if (!PyArg_ParseTuple(args,"")) return NULL; + if (!CPhidget_isAttached(pself->phid)) { + PyErr_SetString(PhidgetError, "Phidget not attached"); + return NULL; + } + rc = CPhidget_getDeviceVersion(pself->phid, &devVer); + if (rc == EPHIDGET_OK) { + return PyInt_FromLong(devVer); + } + PyErr_SetString(PhidgetError, getErrorDescription(rc)); + return NULL; +} + +static PyObject * +phidget_getDeviceStatus(PyObject *self, PyObject *args) { + // True if device is attached, else False + long status; + int rc; + phidgethandle_t *pself = (phidgethandle_t *)self; + + if (!PyArg_ParseTuple(args,"")) return NULL; + rc = CPhidget_getDeviceStatus(pself->phid, &status); + if (rc == EPHIDGET_OK) { + return PyBool_FromLong(status); + } + PyErr_SetString(PhidgetError, getErrorDescription(rc)); + return NULL; +} + +static PyObject * +phidget_getLibraryVersion(PyObject *self, PyObject *args) { + const char *version; + + if (!PyArg_ParseTuple(args,"")) return NULL; + CPhidget_getLibraryVersion(&version); + // probably points to a static string + return PyString_FromString(version); +} + + +static char *phidget_open_kwlist[] = {"serial", "block", NULL}; + +static PyObject * +phidget_open(PyObject *self, PyObject *args, PyObject *kwargs) { + int rc, serial=-1, block=0; + long status; + phidgethandle_t *pself = (phidgethandle_t *)self; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", phidget_open_kwlist, + &serial, &block)) + return NULL; + rc = CPhidget_open(pself->phid, serial); + if (rc) + return raisePhidgetError(rc); + if (block) { + do { + CPhidget_getDeviceStatus(pself->phid, &status); + } while (!status); + } + Py_INCREF(Py_None); + return Py_None; +} + + +static PyMethodDef phidgethandle_methods[] = { + {"getDeviceName", (PyCFunction)phidget_getDeviceName, METH_VARARGS}, + {"getSerialNumber", (PyCFunction)phidget_getSerialNumber, METH_VARARGS}, + {"getDeviceVersion", (PyCFunction)phidget_getDeviceVersion, METH_VARARGS}, + {"getDeviceStatus", (PyCFunction)phidget_getDeviceStatus, METH_VARARGS}, + {"open", (PyCFunction)phidget_open, METH_VARARGS|METH_KEYWORDS}, +#if 0 + //{"close", (PyCFunction)phidget_close, METH_VARARGS}, // auto + {"set_OnDetach_Handler", (PyCFunction)phidget_set_OnDetach_Handler, METH_VARARGS}, + {"set_OnAttach_Handler", (PyCFunction)phidget_set_OnAttach_Handler, METH_VARARGS}, + {"set_OnError_Handler", (PyCFunction)phidget_set_OnError_Handler, METH_VARARGS}, + {"getTag", (PyCFunction)phidget_getTag, METH_VARARGS}, + {"setTag", (PyCFunction)phidget_setTag, METH_VARARGS}, +#endif + {NULL, NULL} +}; + +static PyObject * +phidgethandle_getattr(phidgethandle_t *self, char *name) { + return Py_FindMethod(phidgethandle_methods, (PyObject *)self, name); +} + +static PyTypeObject PHIDGETHANDLEType = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "phidget.handle", /*tp_name*/ + sizeof(phidgethandle_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) phidgethandle_dealloc, /*tp_dealloc*/ + 0, /*print*/ + (getattrfunc)phidgethandle_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "CPhidgetHandle wrapper", /*tp_doc*/ +}; + + +// ------------ CPhidgetInterfaceKitHandle + +typedef struct { + PyObject_HEAD; + CPhidgetInterfaceKitHandle phid; +} phidgetifkithandle_t; + +static PyObject * +phidgetifkithandle_new(PyTypeObject *type, PyObject *args, PyObject* kwargs) +{ + // this creates a new CPhidgetInterfaceKitHandle and wraps it with a + // python object. + int rc; + phidgetifkithandle_t *self; + + self = (phidgetifkithandle_t *)PyObject_New(phidgetifkithandle_t, + &PHIDGETIFKITHANDLEType); + if (!self) + return NULL; + rc = CPhidgetInterfaceKit_create(&(self->phid)); + if (rc) + return raisePhidgetError(rc); + + return (PyObject *)self; +} + +static PyObject * +ifkit_getNumInputs(phidgetifkithandle_t *self, PyObject *args) { + int rc, numInputs; + if (!PyArg_ParseTuple(args,"")) return NULL; + rc = CPhidgetInterfaceKit_getNumInputs(self->phid, &numInputs); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(numInputs); +} + +static PyObject * +ifkit_getNumOutputs(phidgetifkithandle_t *self, PyObject *args) { + int rc, numOutputs; + if (!PyArg_ParseTuple(args,"")) return NULL; + rc = CPhidgetInterfaceKit_getNumOutputs(self->phid, &numOutputs); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(numOutputs); +} + +static PyObject * +ifkit_getNumSensors(phidgetifkithandle_t *self, PyObject *args) { + int rc, numSensors; + if (!PyArg_ParseTuple(args,"")) return NULL; + rc = CPhidgetInterfaceKit_getNumSensors(self->phid, &numSensors); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(numSensors); +} + +static PyObject * +ifkit_getInputState(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, pVal; + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + printf("getInputState[%d] on %p\n", index, self->phid); + rc = CPhidgetInterfaceKit_getInputState(self->phid, index, &pVal); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(pVal); +} + +static PyObject * +ifkit_getSensorValue(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, pVal; + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + rc = CPhidgetInterfaceKit_getSensorValue(self->phid, index, &pVal); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(pVal); +} + +static PyObject * +ifkit_getSensorRawValue(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, pVal; + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + rc = CPhidgetInterfaceKit_getSensorRawValue(self->phid, index, &pVal); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(pVal); +} + +static PyObject * +ifkit_setSensorChangeTrigger(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, newVal; + if (!PyArg_ParseTuple(args, "ii", &index, &newVal)) + return NULL; + rc = CPhidgetInterfaceKit_setSensorChangeTrigger(self->phid, + index, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +ifkit_getSensorChangeTrigger(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, pVal; + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + rc = CPhidgetInterfaceKit_getSensorChangeTrigger(self->phid, index, &pVal); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(pVal); +} + + + +static PyObject * +ifkit_setOutputState(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, newVal; + if (!PyArg_ParseTuple(args, "ii", &index, &newVal)) + return NULL; + rc = CPhidgetInterfaceKit_setOutputState(self->phid, index, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +ifkit_getOutputState(phidgetifkithandle_t *self, PyObject *args) { + int rc, index, pVal; + if (!PyArg_ParseTuple(args, "i", &index)) + return NULL; + rc = CPhidgetInterfaceKit_getOutputState(self->phid, index, &pVal); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(pVal); +} + +static PyObject * +ifkit_setRatiometric(phidgetifkithandle_t *self, PyObject *args) { + // this is board-wide + int rc, newVal; + if (!PyArg_ParseTuple(args, "i", &newVal)) + return NULL; + rc = CPhidgetInterfaceKit_setRatiometric(self->phid, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +ifkit_getRatiometric(phidgetifkithandle_t *self, PyObject *args) { + int rc, newVal; + if (!PyArg_ParseTuple(args, "")) + return NULL; + rc = CPhidgetInterfaceKit_getRatiometric(self->phid, &newVal); + if (rc) + return raisePhidgetError(rc); + return PyBool_FromLong(newVal); +} + + +static PyMethodDef ifkit_methods[] = { + // these are the generic methods which work on all phidget handles + {"getDeviceName", (PyCFunction)phidget_getDeviceName, METH_VARARGS}, + {"getSerialNumber", (PyCFunction)phidget_getSerialNumber, METH_VARARGS}, + {"getDeviceVersion", (PyCFunction)phidget_getDeviceVersion, METH_VARARGS}, + {"getDeviceStatus", (PyCFunction)phidget_getDeviceStatus, METH_VARARGS}, + {"open", (PyCFunction)phidget_open, METH_VARARGS|METH_KEYWORDS}, +#if 0 + {"close", (PyCFunction)phidget_close, METH_VARARGS}, + {"set_OnDetach_Handler", (PyCFunction)phidget_set_OnDetach_Handler, METH_VARARGS}, + {"set_OnAttach_Handler", (PyCFunction)phidget_set_OnAttach_Handler, METH_VARARGS}, + {"set_OnError_Handler", (PyCFunction)phidget_set_OnError_Handler, METH_VARARGS}, + {"getTag", (PyCFunction)phidget_getTag, METH_VARARGS}, + {"setTag", (PyCFunction)phidget_setTag, METH_VARARGS}, +#endif + + // these are interfacekit -specific methods + {"getNumInputs", (PyCFunction)ifkit_getNumInputs, METH_VARARGS}, + {"getNumOutputs", (PyCFunction)ifkit_getNumOutputs, METH_VARARGS}, + {"getNumSensors", (PyCFunction)ifkit_getNumSensors, METH_VARARGS}, + + {"getOutputState", (PyCFunction)ifkit_getOutputState, METH_VARARGS}, + {"setOutputState", (PyCFunction)ifkit_setOutputState, METH_VARARGS}, + {"getSensorChangeTrigger", (PyCFunction)ifkit_getSensorChangeTrigger, + METH_VARARGS}, + {"setSensorChangeTrigger", (PyCFunction)ifkit_setSensorChangeTrigger, + METH_VARARGS}, + {"getInputState", (PyCFunction)ifkit_getInputState, METH_VARARGS}, + {"getSensorValue", (PyCFunction)ifkit_getSensorValue, METH_VARARGS}, + {"getSensorRawValue", (PyCFunction)ifkit_getSensorRawValue, METH_VARARGS}, + {"getRatiometric", (PyCFunction)ifkit_getRatiometric, METH_VARARGS}, + {"setRatiometric", (PyCFunction)ifkit_setRatiometric, METH_VARARGS}, + +#if 0 + {"set_OnInputChange_Handler", + (PyCFunction)ifkit_set_OnInputChange_Handler, METH_VARARGS}, + {"set_OnOutputChange_Handler", + (PyCFunction)ifkit_set_OnOutputChange_Handler, METH_VARARGS}, + {"set_OnSensorChange_Handler", + (PyCFunction)ifkit_set_OnSensorChange_Handler, METH_VARARGS}, +#endif + + {NULL, NULL} +}; + +static PyObject * +ifkit_getattr(phidgethandle_t *self, char *name) { + return Py_FindMethod(ifkit_methods, (PyObject *)self, name); +} + +static PyTypeObject PHIDGETIFKITHANDLEType = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "phidget.ifkithandle", /*tp_name*/ + sizeof(phidgetifkithandle_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) phidgethandle_dealloc, /*tp_dealloc*/ // generic + 0, /*print*/ + (getattrfunc)ifkit_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "CPhidgetInterfaceKitHandle wrapper", /*tp_doc*/ +}; + + +// ---------------- CPhidgetTextLCD + +typedef struct { + PyObject_HEAD; + CPhidgetTextLCDHandle phid; +} phidgettextlcdhandle_t; + +static PyObject * +phidgettextlcdhandle_new(PyTypeObject *type, PyObject *args, PyObject* kwargs) +{ + // this creates a new CPhidgetTextLCDHandle and wraps it with a python + // object. + int rc; + phidgettextlcdhandle_t *self; + + self = (phidgettextlcdhandle_t *)PyObject_New(phidgettextlcdhandle_t, + &PHIDGETTEXTLCDHANDLEType); + if (!self) + return NULL; + rc = CPhidgetTextLCD_create(&(self->phid)); + if (rc) + return raisePhidgetError(rc); + + return (PyObject *)self; +} + +static PyObject * +textlcd_getNumRows(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, numRows; + if (!PyArg_ParseTuple(args,"")) return NULL; + rc = CPhidgetTextLCD_getNumRows(self->phid, &numRows); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(numRows); +} + +static PyObject * +textlcd_getNumColumns(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, numColumns; + if (!PyArg_ParseTuple(args,"")) return NULL; + rc = CPhidgetTextLCD_getNumColumns(self->phid, &numColumns); + if (rc) + return raisePhidgetError(rc); + return PyInt_FromLong(numColumns); +} + +static PyObject * +textlcd_setBacklight(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, newVal; + if (!PyArg_ParseTuple(args, "i", &newVal)) + return NULL; + rc = CPhidgetTextLCD_setBacklight(self->phid, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +textlcd_setContrast(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, newVal; + if (!PyArg_ParseTuple(args, "i", &newVal)) + return NULL; + rc = CPhidgetTextLCD_setContrast(self->phid, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +textlcd_setCursorOn(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, newVal; + if (!PyArg_ParseTuple(args, "i", &newVal)) + return NULL; + rc = CPhidgetTextLCD_setCursorOn(self->phid, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +textlcd_setCursorBlink(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, newVal; + if (!PyArg_ParseTuple(args, "i", &newVal)) + return NULL; + rc = CPhidgetTextLCD_setCursorBlink(self->phid, newVal); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +textlcd_setCustomCharacter(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, Index, Val1, Val2; + if (!PyArg_ParseTuple(args, "iii", &Index, &Val1, &Val2)) + return NULL; + rc = CPhidgetTextLCD_setCustomCharacter(self->phid, Index, Val1, Val2); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +textlcd_setDisplayString(phidgettextlcdhandle_t *self, PyObject *args) { + int rc, Row; + char *displayString; + if (!PyArg_ParseTuple(args, "is", &Row, &displayString)) + return NULL; + rc = CPhidgetTextLCD_setDisplayString(self->phid, Row, displayString); + if (rc) + return raisePhidgetError(rc); + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef textlcd_methods[] = { + // these are the generic methods which work on all phidget handles + {"getDeviceName", (PyCFunction)phidget_getDeviceName, METH_VARARGS}, + {"getSerialNumber", (PyCFunction)phidget_getSerialNumber, METH_VARARGS}, + {"getDeviceVersion", (PyCFunction)phidget_getDeviceVersion, METH_VARARGS}, + {"getDeviceStatus", (PyCFunction)phidget_getDeviceStatus, METH_VARARGS}, + {"open", (PyCFunction)phidget_open, METH_VARARGS|METH_KEYWORDS}, +#if 0 + {"close", (PyCFunction)phidget_close, METH_VARARGS}, + {"set_OnDetach_Handler", (PyCFunction)phidget_set_OnDetach_Handler, METH_VARARGS}, + {"set_OnAttach_Handler", (PyCFunction)phidget_set_OnAttach_Handler, METH_VARARGS}, + {"set_OnError_Handler", (PyCFunction)phidget_set_OnError_Handler, METH_VARARGS}, + {"getTag", (PyCFunction)phidget_getTag, METH_VARARGS}, + {"setTag", (PyCFunction)phidget_setTag, METH_VARARGS}, +#endif + // these are textlcd -specific methods + + {"getNumRows", (PyCFunction)textlcd_getNumRows, METH_VARARGS}, + {"getNumColumns", (PyCFunction)textlcd_getNumColumns, METH_VARARGS}, + {"setBacklight", (PyCFunction)textlcd_setBacklight, METH_VARARGS}, + {"setContrast", (PyCFunction)textlcd_setContrast, METH_VARARGS}, + {"setCursorOn", (PyCFunction)textlcd_setCursorOn, METH_VARARGS}, + {"setCursorBlink", (PyCFunction)textlcd_setCursorBlink, METH_VARARGS}, + {"setCustomCharacter", (PyCFunction)textlcd_setCustomCharacter, + METH_VARARGS}, + {"setCursorBlink", (PyCFunction)textlcd_setCursorBlink, METH_VARARGS}, + {"setDisplayString", (PyCFunction)textlcd_setDisplayString, METH_VARARGS}, + + {NULL, NULL} +}; + +static PyObject * +textlcd_getattr(phidgethandle_t *self, char *name) { + return Py_FindMethod(textlcd_methods, (PyObject *)self, name); +} + +static PyTypeObject PHIDGETTEXTLCDHANDLEType = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "phidget.textlcdhandle", /*tp_name*/ + sizeof(phidgettextlcdhandle_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) phidgethandle_dealloc, /*tp_dealloc*/ // generic + 0, /*print*/ + (getattrfunc)textlcd_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "CPhidgetTextLCDHandle wrapper", /*tp_doc*/ +}; + + + + +// CPhidgetManager stuff. This object watches the bus for new devices. There +// can only be one such object in any given process. There is an +// initialization function which we call automatically if the object gets +// used. + + + + +static int +gotAttach(CPhidgetHandle phid, void *ptr) +{ + PyObject *cb = ptr; + char *id; + long serial, version; + PyObject *result; + PyGILState_STATE gstate; + + printf("gotAttach called\n"); + + CPhidget_getSerialNumber(phid, &serial); + CPhidget_getDeviceVersion(phid, &version); + CPhidget_getDeviceType((CPhidgetHandle)phid,(const char **)&id); + + //printf("serial was %ld, type is %s\n", serial, id); + + gstate = PyGILState_Ensure(); + + /* Perform Python actions here. */ + result = PyObject_CallFunction(cb, "iis", serial, version, id); + Py_DECREF(result); + /* evaluate result */ + + /* Release the thread. No Python API allowed beyond this point. */ + PyGILState_Release(gstate); + + // free id + + return 0; +} + + +static PyObject * +manager_set_AttachHandler(PyObject *self, PyObject *args) +{ + PyObject *cb; + + if (!PyArg_ParseTuple(args, "O", &cb)) + return NULL; + + Py_INCREF(cb); + CPhidgetManager_set_AttachHandler(gotAttach, cb); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +manager_getAttachedDevices(PyObject *self, PyObject *args) +{ + PyObject *retval, *one_device; + CPhidgetHandle *devices; + int count, rc, i; + + // the CPhidgetManager_getAttachedDevices() function will allocate an + // array and populate it with a bunch of CPhidgetHandle pointers. We are + // responsible for freeing the array. It puts the the length of the array + // it allocated in 'count'. + + if (!PyArg_ParseTuple(args,"")) return NULL; + retval = PyList_New(0); + if (!retval) return NULL; + + rc = CPhidgetManager_getAttachedDevices(&devices, &count); + if (rc == EPHIDGET_OK) { + for (i=0; i