| 48 | | //Python Function declarations |
|---|
| 49 | | void initcwiidmodule(void); |
|---|
| 50 | | |
|---|
| 51 | | static int Wiimote_constructor(PyObject* self, PyObject* args); |
|---|
| 52 | | PyObject* Wiimote_read(PyObject* self, PyObject* args); |
|---|
| 53 | | PyObject* Wiimote_write(PyObject* self, PyObject* args); |
|---|
| 54 | | PyObject* Wiimote_command(PyObject* self, PyObject* args); |
|---|
| 55 | | PyObject* Wiimote_disconnect(PyObject* self, PyObject* args); |
|---|
| 56 | | PyObject* Wiimote_enable(PyObject* self, PyObject* args); |
|---|
| 57 | | PyObject* Wiimote_disable(PyObject* self, PyObject* args); |
|---|
| 58 | | PyObject* Wiimote_get_mesg(PyObject* self, PyObject* args); |
|---|
| 59 | | PyObject* Wiimote_set_callback(PyObject* self, PyObject* args); |
|---|
| 60 | | PyObject* Wiimote_get_state(PyObject* self, PyObject* args); |
|---|
| 61 | | |
|---|
| 62 | | |
|---|
| 63 | | //Types |
|---|
| 64 | | |
|---|
| | 50 | /* Python Function declarations */ |
|---|
| | 51 | PyMODINIT_FUNC initcwiid(void); |
|---|
| | 52 | |
|---|
| | 53 | static int Wiimote_init(PyObject *self, PyObject *args, PyObject *kwds); |
|---|
| | 54 | static PyObject *Wiimote_read(PyObject *self, PyObject *args); |
|---|
| | 55 | static PyObject *Wiimote_write(PyObject *self, PyObject *args); |
|---|
| | 56 | static PyObject *Wiimote_command(PyObject *self, PyObject *args); |
|---|
| | 57 | static PyObject *Wiimote_disconnect(PyObject *self, PyObject *args); |
|---|
| | 58 | static PyObject *Wiimote_enable(PyObject *self, PyObject *args); |
|---|
| | 59 | static PyObject *Wiimote_disable(PyObject *self, PyObject *args); |
|---|
| | 60 | static PyObject *Wiimote_get_mesg(PyObject *self, PyObject *args); |
|---|
| | 61 | static PyObject *Wiimote_set_callback(PyObject *self, PyObject *args); |
|---|
| | 62 | static PyObject *Wiimote_get_state(PyObject *self, PyObject *args); |
|---|
| | 63 | |
|---|
| | 64 | #define CONST_MACRO(a) {#a, CWIID_##a} |
|---|
| | 65 | struct cwiid_constant { |
|---|
| | 66 | char *name; |
|---|
| | 67 | int value; |
|---|
| | 68 | }; |
|---|
| | 69 | static struct cwiid_constant cwiid_constants[] = { |
|---|
| | 70 | CONST_MACRO(FLAG_MESG_IFC), |
|---|
| | 71 | CONST_MACRO(FLAG_CONTINUOUS), |
|---|
| | 72 | CONST_MACRO(FLAG_REPEAT_BTN), |
|---|
| | 73 | CONST_MACRO(FLAG_NONBLOCK), |
|---|
| | 74 | CONST_MACRO(RPT_STATUS), |
|---|
| | 75 | CONST_MACRO(RPT_BTN), |
|---|
| | 76 | CONST_MACRO(RPT_ACC), |
|---|
| | 77 | CONST_MACRO(RPT_IR), |
|---|
| | 78 | CONST_MACRO(RPT_NUNCHUK), |
|---|
| | 79 | CONST_MACRO(RPT_CLASSIC), |
|---|
| | 80 | CONST_MACRO(RPT_EXT), |
|---|
| | 81 | CONST_MACRO(LED1_ON), |
|---|
| | 82 | CONST_MACRO(LED2_ON), |
|---|
| | 83 | CONST_MACRO(LED3_ON), |
|---|
| | 84 | CONST_MACRO(LED4_ON), |
|---|
| | 85 | CONST_MACRO(BTN_2), |
|---|
| | 86 | CONST_MACRO(BTN_1), |
|---|
| | 87 | CONST_MACRO(BTN_B), |
|---|
| | 88 | CONST_MACRO(BTN_A), |
|---|
| | 89 | CONST_MACRO(BTN_MINUS), |
|---|
| | 90 | CONST_MACRO(BTN_HOME), |
|---|
| | 91 | CONST_MACRO(BTN_LEFT), |
|---|
| | 92 | CONST_MACRO(BTN_RIGHT), |
|---|
| | 93 | CONST_MACRO(BTN_DOWN), |
|---|
| | 94 | CONST_MACRO(BTN_UP), |
|---|
| | 95 | CONST_MACRO(BTN_PLUS), |
|---|
| | 96 | CONST_MACRO(NUNCHUK_BTN_Z), |
|---|
| | 97 | CONST_MACRO(NUNCHUK_BTN_C), |
|---|
| | 98 | CONST_MACRO(CLASSIC_BTN_UP), |
|---|
| | 99 | CONST_MACRO(CLASSIC_BTN_LEFT), |
|---|
| | 100 | CONST_MACRO(CLASSIC_BTN_ZR), |
|---|
| | 101 | CONST_MACRO(CLASSIC_BTN_X), |
|---|
| | 102 | CONST_MACRO(CLASSIC_BTN_A), |
|---|
| | 103 | CONST_MACRO(CLASSIC_BTN_Y), |
|---|
| | 104 | CONST_MACRO(CLASSIC_BTN_B), |
|---|
| | 105 | CONST_MACRO(CLASSIC_BTN_ZL), |
|---|
| | 106 | CONST_MACRO(CLASSIC_BTN_R), |
|---|
| | 107 | CONST_MACRO(CLASSIC_BTN_PLUS), |
|---|
| | 108 | CONST_MACRO(CLASSIC_BTN_HOME), |
|---|
| | 109 | CONST_MACRO(CLASSIC_BTN_MINUS), |
|---|
| | 110 | CONST_MACRO(CLASSIC_BTN_L), |
|---|
| | 111 | CONST_MACRO(CLASSIC_BTN_DOWN), |
|---|
| | 112 | CONST_MACRO(CLASSIC_BTN_RIGHT), |
|---|
| | 113 | CONST_MACRO(RW_EEPROM), |
|---|
| | 114 | CONST_MACRO(RW_REG), |
|---|
| | 115 | CONST_MACRO(RW_DECODE), |
|---|
| | 116 | CONST_MACRO(MAX_READ_LEN), |
|---|
| | 117 | CONST_MACRO(X), |
|---|
| | 118 | CONST_MACRO(Y), |
|---|
| | 119 | CONST_MACRO(Z), |
|---|
| | 120 | CONST_MACRO(IR_SRC_COUNT), |
|---|
| | 121 | CONST_MACRO(IR_X_MAX), |
|---|
| | 122 | CONST_MACRO(IR_Y_MAX), |
|---|
| | 123 | CONST_MACRO(BATTERY_MAX), |
|---|
| | 124 | CONST_MACRO(CLASSIC_L_STICK_MAX), |
|---|
| | 125 | CONST_MACRO(CLASSIC_R_STICK_MAX), |
|---|
| | 126 | CONST_MACRO(CLASSIC_LR_MAX), |
|---|
| | 127 | CONST_MACRO(CMD_STATUS), |
|---|
| | 128 | CONST_MACRO(CMD_LED), |
|---|
| | 129 | CONST_MACRO(CMD_RUMBLE), |
|---|
| | 130 | CONST_MACRO(CMD_RPT_MODE), |
|---|
| | 131 | CONST_MACRO(MESG_STATUS), |
|---|
| | 132 | CONST_MACRO(MESG_BTN), |
|---|
| | 133 | CONST_MACRO(MESG_ACC), |
|---|
| | 134 | CONST_MACRO(MESG_IR), |
|---|
| | 135 | CONST_MACRO(MESG_NUNCHUK), |
|---|
| | 136 | CONST_MACRO(MESG_CLASSIC), |
|---|
| | 137 | CONST_MACRO(MESG_ERROR), |
|---|
| | 138 | CONST_MACRO(MESG_UNKNOWN), |
|---|
| | 139 | CONST_MACRO(EXT_NONE), |
|---|
| | 140 | CONST_MACRO(EXT_NUNCHUK), |
|---|
| | 141 | CONST_MACRO(EXT_CLASSIC), |
|---|
| | 142 | CONST_MACRO(EXT_UNKNOWN), |
|---|
| | 143 | CONST_MACRO(ERROR_DISCONNECT), |
|---|
| | 144 | CONST_MACRO(ERROR_COMM), |
|---|
| | 145 | {NULL, 0} |
|---|
| | 146 | }; |
|---|
| | 147 | |
|---|
| | 148 | /* Types */ |
|---|
| 92 | | //Our type methods |
|---|
| 93 | | static PyMethodDef cwiidMethods[] = |
|---|
| 94 | | { |
|---|
| 95 | | |
|---|
| 96 | | //{"__init__", constructorwii, METH_VARARGS, "cwiid(function)"}, |
|---|
| 97 | | {"read", Wiimote_read, METH_VARARGS, "read from wiimote"}, |
|---|
| 98 | | {"write", Wiimote_write, METH_VARARGS, "write to wiimote"}, |
|---|
| 99 | | {"command", Wiimote_command, METH_VARARGS, "send wiimote command"}, |
|---|
| 100 | | {"enable", Wiimote_enable, METH_VARARGS, "enable flags on wiimote"}, |
|---|
| 101 | | {"disable", Wiimote_disable, METH_VARARGS, "disable flags on wiimote"}, |
|---|
| 102 | | {"get_mesg", Wiimote_get_mesg, METH_VARARGS, "blocking call to get messages"}, |
|---|
| 103 | | {"set_callback", Wiimote_set_callback, METH_VARARGS, "setup a mesg processing callback"}, |
|---|
| 104 | | {"get_state", Wiimote_get_state, METH_VARARGS, "polling interface"}, |
|---|
| 105 | | {"disconnect", Wiimote_disconnect, METH_VARARGS, "disconnect wiimote"}, |
|---|
| 106 | | {NULL, NULL} |
|---|
| | 177 | /* Our type methods */ |
|---|
| | 178 | static PyMethodDef Wiimote_Methods[] = |
|---|
| | 179 | { |
|---|
| | 180 | /* {"__init__", constructorwii, METH_VARARGS, "cwiid(function)"}, */ |
|---|
| | 181 | {"read", Wiimote_read, METH_VARARGS, "read from wiimote"}, |
|---|
| | 182 | {"write", Wiimote_write, METH_VARARGS, "write to wiimote"}, |
|---|
| | 183 | {"command", Wiimote_command, METH_VARARGS, "send wiimote command"}, |
|---|
| | 184 | {"enable", Wiimote_enable, METH_VARARGS, "enable flags on wiimote"}, |
|---|
| | 185 | {"disable", Wiimote_disable, METH_VARARGS, "disable flags on wiimote"}, |
|---|
| | 186 | {"get_mesg", Wiimote_get_mesg, METH_VARARGS, "blocking call to get messages"}, |
|---|
| | 187 | {"set_callback", Wiimote_set_callback, METH_VARARGS, "setup a mesg processing callback"}, |
|---|
| | 188 | {"get_state", Wiimote_get_state, METH_VARARGS, "polling interface"}, |
|---|
| | 189 | {"disconnect", Wiimote_disconnect, METH_VARARGS, "disconnect wiimote"}, |
|---|
| | 190 | {NULL, NULL} |
|---|
| 116 | | //Defines a new type in python |
|---|
| 117 | | static PyTypeObject WiimoteType= { |
|---|
| 118 | | PyObject_HEAD_INIT(NULL) |
|---|
| 119 | | 0, /*ob_size*/ |
|---|
| 120 | | "cwiidmodule.Wiimote", /*tp_name*/ |
|---|
| 121 | | sizeof(cwiidmodule), /*tp_basicsize*/ |
|---|
| 122 | | 0, /*tp_itemsize*/ |
|---|
| 123 | | (destructor)cwiidmodule_dealloc, /*tp_dealloc*/ |
|---|
| 124 | | 0, /*tp_print*/ |
|---|
| 125 | | 0, /*tp_getattr*/ |
|---|
| 126 | | 0, /*tp_setattr*/ |
|---|
| 127 | | 0, /*tp_compare*/ |
|---|
| 128 | | 0, /*tp_repr*/ |
|---|
| 129 | | 0, /*tp_as_number*/ |
|---|
| 130 | | 0, /*tp_as_sequence*/ |
|---|
| 131 | | 0, /*tp_as_mapping*/ |
|---|
| 132 | | 0, /*tp_hash */ |
|---|
| 133 | | 0, /*tp_call*/ |
|---|
| 134 | | 0, /*tp_str*/ |
|---|
| 135 | | 0, /*tp_getattro*/ |
|---|
| 136 | | 0, /*tp_setattro*/ |
|---|
| 137 | | 0, /*tp_as_buffer*/ |
|---|
| 138 | | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ |
|---|
| 139 | | "cwiid c-python interface",/* tp_doc */ |
|---|
| 140 | | 0, /* tp_traverse */ |
|---|
| 141 | | 0, /* tp_clear */ |
|---|
| 142 | | 0, /* tp_richcompare */ |
|---|
| 143 | | 0, /* tp_weaklistoffset */ |
|---|
| 144 | | 0, /* tp_iter */ |
|---|
| 145 | | 0, /* tp_iternext */ |
|---|
| 146 | | cwiidMethods, /* tp_methods */ |
|---|
| 147 | | cwiidMembers, /* tp_members */ |
|---|
| 148 | | 0, /* tp_getset */ |
|---|
| 149 | | 0, /* tp_base */ |
|---|
| 150 | | 0, /* tp_dict */ |
|---|
| 151 | | 0, /* tp_descr_get */ |
|---|
| 152 | | 0, /* tp_descr_set */ |
|---|
| 153 | | 0, /* tp_dictoffset */ |
|---|
| 154 | | (initproc)Wiimote_constructor, /* tp_init */ |
|---|
| 155 | | 0, /* tp_alloc */ |
|---|
| 156 | | cwiidmodule_new, /* tp_new */ |
|---|
| | 200 | /* Defines a new type in python */ |
|---|
| | 201 | static PyTypeObject Wiimote_Type = { |
|---|
| | 202 | PyObject_HEAD_INIT(NULL) |
|---|
| | 203 | 0, /* ob_size */ |
|---|
| | 204 | "cwiid.Wiimote", /* tp_name */ |
|---|
| | 205 | sizeof(Wiimote), /* tp_basicsize */ |
|---|
| | 206 | 0, /* tp_itemsize */ |
|---|
| | 207 | Wiimote_dealloc, /* tp_dealloc */ |
|---|
| | 208 | 0, /* tp_print */ |
|---|
| | 209 | 0, /* tp_getattr */ |
|---|
| | 210 | 0, /* tp_setattr */ |
|---|
| | 211 | 0, /* tp_compare */ |
|---|
| | 212 | 0, /* tp_repr */ |
|---|
| | 213 | 0, /* tp_as_number */ |
|---|
| | 214 | 0, /* tp_as_sequence */ |
|---|
| | 215 | 0, /* tp_as_mapping */ |
|---|
| | 216 | 0, /* tp_hash */ |
|---|
| | 217 | 0, /* tp_call */ |
|---|
| | 218 | 0, /* tp_str */ |
|---|
| | 219 | 0, /* tp_getattro */ |
|---|
| | 220 | 0, /* tp_setattro */ |
|---|
| | 221 | 0, /* tp_as_buffer */ |
|---|
| | 222 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
|---|
| | 223 | "cwiid c-python interface", /* tp_doc */ |
|---|
| | 224 | 0, /* tp_traverse */ |
|---|
| | 225 | 0, /* tp_clear */ |
|---|
| | 226 | 0, /* tp_richcompare */ |
|---|
| | 227 | 0, /* tp_weaklistoffset */ |
|---|
| | 228 | 0, /* tp_iter */ |
|---|
| | 229 | 0, /* tp_iternext */ |
|---|
| | 230 | Wiimote_Methods, /* tp_methods */ |
|---|
| | 231 | Wiimote_Members, /* tp_members */ |
|---|
| | 232 | 0, /* tp_getset */ |
|---|
| | 233 | 0, /* tp_base */ |
|---|
| | 234 | 0, /* tp_dict */ |
|---|
| | 235 | 0, /* tp_descr_get */ |
|---|
| | 236 | 0, /* tp_descr_set */ |
|---|
| | 237 | 0, /* tp_dictoffset */ |
|---|
| | 238 | Wiimote_init, /* tp_init */ |
|---|
| | 239 | 0, /* tp_alloc */ |
|---|
| | 240 | Wiimote_new, /* tp_new */ |
|---|
| 159 | | //Allocate and deallocate functions |
|---|
| 160 | | static void |
|---|
| 161 | | cwiidmodule_dealloc(cwiidmodule* self) |
|---|
| 162 | | { |
|---|
| 163 | | cwiid_disconnect(self->wiimote); |
|---|
| 164 | | Py_XDECREF(self->callback); |
|---|
| 165 | | self->ob_type->tp_free((PyObject*)self); |
|---|
| 166 | | } |
|---|
| 167 | | |
|---|
| 168 | | static PyObject* |
|---|
| 169 | | cwiidmodule_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|---|
| 170 | | { |
|---|
| 171 | | cwiidmodule* self; |
|---|
| 172 | | |
|---|
| 173 | | self = (cwiidmodule*) type->tp_alloc(type, 0); |
|---|
| 174 | | |
|---|
| 175 | | return (PyObject*) self; |
|---|
| 176 | | } |
|---|
| 177 | | |
|---|
| 178 | | PyMODINIT_FUNC |
|---|
| 179 | | initcwiidmodule(void) |
|---|
| 180 | | { |
|---|
| 181 | | PyObject* m; |
|---|
| 182 | | |
|---|
| 183 | | if (PyType_Ready(&WiimoteType) <0 ) |
|---|
| 184 | | return; |
|---|
| 185 | | |
|---|
| 186 | | //Open the cwiid library |
|---|
| 187 | | dlopen("libcwiid.so", RTLD_LAZY); |
|---|
| 188 | | if (!(m = Py_InitModule3("cwiidmodule", modMethods, |
|---|
| 189 | | "Module for accessing the wiimote through cwiid"))) |
|---|
| 190 | | return; |
|---|
| 191 | | |
|---|
| 192 | | Py_INCREF(&WiimoteType); |
|---|
| 193 | | PyModule_AddObject(m, "Wiimote", (PyObject*)&WiimoteType); |
|---|
| 194 | | |
|---|
| 195 | | } |
|---|
| 196 | | |
|---|
| 197 | | int |
|---|
| 198 | | cwiid_start(cwiidmodule* self, int flags) |
|---|
| 199 | | { |
|---|
| 200 | | cwiid_wiimote_t* theMote; |
|---|
| 201 | | btAddr = *BDADDR_ANY; |
|---|
| 202 | | |
|---|
| 203 | | //Set up wiimote |
|---|
| 204 | | if(!(theMote = cwiid_connect(&btAddr, flags))) |
|---|
| 205 | | { |
|---|
| 206 | | return -1; |
|---|
| 207 | | } |
|---|
| 208 | | cwiid_set_data(theMote,(void*)self); //keep pyobject with wiimote |
|---|
| 209 | | self->wiimote = theMote; //keep wiimote with pyobject |
|---|
| 210 | | self->callback = Py_None; |
|---|
| 211 | | return 0; |
|---|
| 212 | | } |
|---|
| 213 | | |
|---|
| 214 | | static int |
|---|
| 215 | | Wiimote_constructor(PyObject* self, PyObject* args) |
|---|
| 216 | | { |
|---|
| 217 | | PyObject* pyFlags; |
|---|
| 218 | | |
|---|
| 219 | | //Get out parameters |
|---|
| 220 | | if (PyArg_UnpackTuple(args, "constructor", 1, 1, &pyFlags)) |
|---|
| 221 | | { |
|---|
| 222 | | if (!PyInt_Check(pyFlags)) |
|---|
| 223 | | { |
|---|
| 224 | | PyErr_SetString(PyExc_TypeError, "Parameter must be int"); |
|---|
| 225 | | return 0; |
|---|
| 226 | | } |
|---|
| 227 | | } |
|---|
| 228 | | |
|---|
| 229 | | if(cwiid_start((cwiidmodule*)self, PyInt_AsLong(pyFlags))<0) |
|---|
| 230 | | { |
|---|
| 231 | | PyErr_SetString(PyExc_IOError, "Could not connect to wiimote"); |
|---|
| 232 | | } |
|---|
| 233 | | PyEval_InitThreads(); |
|---|
| 234 | | |
|---|
| 235 | | return 0; |
|---|
| 236 | | } |
|---|
| 237 | | |
|---|
| 238 | | |
|---|
| 239 | | PyObject* |
|---|
| 240 | | Wiimote_read(PyObject* self, PyObject* args) |
|---|
| 241 | | { |
|---|
| 242 | | return notImplemented(); |
|---|
| 243 | | } |
|---|
| 244 | | |
|---|
| 245 | | PyObject* |
|---|
| 246 | | Wiimote_write(PyObject* self, PyObject* args) |
|---|
| 247 | | { |
|---|
| 248 | | return notImplemented(); |
|---|
| 249 | | } |
|---|
| 250 | | |
|---|
| 251 | | PyObject* |
|---|
| 252 | | Wiimote_command(PyObject* self, PyObject* args) |
|---|
| 253 | | { |
|---|
| 254 | | //Python types |
|---|
| 255 | | PyObject* pycommand; |
|---|
| 256 | | PyObject* pyflags; |
|---|
| 257 | | |
|---|
| 258 | | //C types |
|---|
| 259 | | enum cwiid_command command; |
|---|
| 260 | | uint8_t flags; |
|---|
| 261 | | |
|---|
| 262 | | PyArg_UnpackTuple(args, "command", 2, 2, &pycommand, &pyflags); |
|---|
| 263 | | if(!(PyInt_Check(pycommand) && PyInt_Check(pyflags))) |
|---|
| 264 | | { |
|---|
| 265 | | PyErr_SetString(PyExc_TypeError, "command and flags must be ints"); |
|---|
| 266 | | } |
|---|
| 267 | | |
|---|
| 268 | | //marshal everything over |
|---|
| 269 | | command = (enum cwiid_command) PyInt_AsLong(pycommand); |
|---|
| 270 | | flags = (uint8_t) PyInt_AsLong(pyflags); |
|---|
| 271 | | |
|---|
| 272 | | |
|---|
| 273 | | //finally, send the command to the wiimote |
|---|
| 274 | | cwiid_command(((cwiidmodule*)self)->wiimote, command, flags); |
|---|
| 275 | | //PyGILState_Release(gstate); |
|---|
| 276 | | |
|---|
| 277 | | Py_RETURN_NONE; |
|---|
| 278 | | } |
|---|
| 279 | | |
|---|
| 280 | | PyObject* |
|---|
| 281 | | Wiimote_disconnect(PyObject* self, PyObject* args) |
|---|
| 282 | | { |
|---|
| 283 | | return notImplemented(); |
|---|
| 284 | | } |
|---|
| 285 | | |
|---|
| 286 | | PyObject* |
|---|
| 287 | | Wiimote_enable(PyObject* self, PyObject* args) |
|---|
| 288 | | { |
|---|
| 289 | | return notImplemented(); |
|---|
| 290 | | } |
|---|
| 291 | | |
|---|
| 292 | | PyObject* |
|---|
| 293 | | Wiimote_disable(PyObject* self, PyObject* args) |
|---|
| 294 | | { |
|---|
| 295 | | return notImplemented(); |
|---|
| 296 | | } |
|---|
| 297 | | |
|---|
| 298 | | PyObject* |
|---|
| 299 | | Wiimote_get_mesg(PyObject* self, PyObject* args) |
|---|
| 300 | | { |
|---|
| 301 | | union cwiid_mesg** mesgs; |
|---|
| 302 | | int mesg_count; |
|---|
| 303 | | |
|---|
| 304 | | //get the messages from Mr. Wiimote |
|---|
| 305 | | |
|---|
| 306 | | return processMesgs(mesg_count, *mesgs); |
|---|
| 307 | | } |
|---|
| 308 | | |
|---|
| 309 | | PyObject* |
|---|
| 310 | | Wiimote_set_callback(PyObject* self, PyObject* args) |
|---|
| 311 | | { |
|---|
| 312 | | PyObject* pyCallback; |
|---|
| 313 | | |
|---|
| 314 | | PyArg_UnpackTuple(args, "set_callback", 1, 1, &pyCallback); |
|---|
| 315 | | if (!PyCallable_Check(pyCallback)) |
|---|
| 316 | | { |
|---|
| 317 | | PyErr_SetString(PyExc_TypeError, "callback must be callable!"); |
|---|
| 318 | | } |
|---|
| | 243 | PyMODINIT_FUNC initcwiid(void) |
|---|
| | 244 | { |
|---|
| | 245 | PyObject *m, *value; |
|---|
| | 246 | struct cwiid_constant *constant; |
|---|
| | 247 | |
|---|
| | 248 | if (PyType_Ready(&Wiimote_Type) < 0) { |
|---|
| | 249 | return; |
|---|
| | 250 | } |
|---|
| | 251 | |
|---|
| | 252 | /* Open the cwiid library */ |
|---|
| | 253 | if (!(m = Py_InitModule3("cwiid", modMethods, |
|---|
| | 254 | "Module for accessing the wiimote through cwiid"))) { |
|---|
| | 255 | return; |
|---|
| | 256 | } |
|---|
| | 257 | |
|---|
| | 258 | Py_INCREF(&Wiimote_Type); |
|---|
| | 259 | PyModule_AddObject(m, "Wiimote", (PyObject*)&Wiimote_Type); |
|---|
| | 260 | |
|---|
| | 261 | for (constant = cwiid_constants; constant->name; constant++) { |
|---|
| | 262 | /* No way to report errors from here, so just ignore them and hope |
|---|
| | 263 | * for segfault */ |
|---|
| | 264 | Py_INCREF(value = Py_BuildValue("i", constant->value)); |
|---|
| | 265 | PyModule_AddObject(m, constant->name, value); |
|---|
| | 266 | } |
|---|
| | 267 | } |
|---|
| | 268 | |
|---|
| | 269 | /* Allocate and deallocate functions */ |
|---|
| | 270 | static PyObject * |
|---|
| | 271 | Wiimote_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|---|
| | 272 | { |
|---|
| | 273 | Wiimote* self; |
|---|
| | 274 | |
|---|
| | 275 | self = (Wiimote *) type->tp_alloc(type, 0); |
|---|
| | 276 | |
|---|
| | 277 | return (PyObject*) self; |
|---|
| | 278 | } |
|---|
| | 279 | |
|---|
| | 280 | static void Wiimote_dealloc(PyObject *self) |
|---|
| | 281 | { |
|---|
| | 282 | Wiimote *wm = (Wiimote *)self; |
|---|
| | 283 | |
|---|
| | 284 | cwiid_disconnect(wm->wiimote); |
|---|
| | 285 | Py_XDECREF(wm->callback); |
|---|
| | 286 | self->ob_type->tp_free((PyObject*)self); |
|---|
| | 287 | } |
|---|
| | 288 | |
|---|
| | 289 | static int cwiid_start(Wiimote *self, int flags) |
|---|
| | 290 | { |
|---|
| | 291 | cwiid_wiimote_t *theMote; |
|---|
| | 292 | btAddr = *BDADDR_ANY; |
|---|
| | 293 | |
|---|
| | 294 | /* Set up wiimote */ |
|---|
| | 295 | if(!(theMote = cwiid_connect(&btAddr, flags))) { |
|---|
| | 296 | return -1; |
|---|
| | 297 | } |
|---|
| | 298 | cwiid_set_data(theMote,(void *)self); /* keep pyobject with wiimote */ |
|---|
| | 299 | self->wiimote = theMote; /* keep wiimote with pyobject */ |
|---|
| | 300 | self->callback = Py_None; |
|---|
| | 301 | return 0; |
|---|
| | 302 | } |
|---|
| | 303 | |
|---|
| | 304 | static int Wiimote_init(PyObject* self, PyObject* args, PyObject *kwds) |
|---|
| | 305 | { |
|---|
| | 306 | PyObject* pyFlags; |
|---|
| | 307 | |
|---|
| | 308 | /* Get out parameters */ |
|---|
| | 309 | if (PyArg_UnpackTuple(args, "constructor", 1, 1, &pyFlags)) { |
|---|
| | 310 | if (!PyInt_Check(pyFlags)) { |
|---|
| | 311 | PyErr_SetString(PyExc_TypeError, "Parameter must be int"); |
|---|
| | 312 | return 0; |
|---|
| | 313 | } |
|---|
| | 314 | } |
|---|
| | 315 | |
|---|
| | 316 | if (cwiid_start((Wiimote *)self, PyInt_AsLong(pyFlags)) < 0) { |
|---|
| | 317 | PyErr_SetString(PyExc_IOError, "Could not connect to wiimote"); |
|---|
| | 318 | } |
|---|
| | 319 | PyEval_InitThreads(); |
|---|
| | 320 | |
|---|
| | 321 | return 0; |
|---|
| | 322 | } |
|---|
| | 323 | |
|---|
| | 324 | static PyObject *Wiimote_read(PyObject *self, PyObject *args) |
|---|
| | 325 | { |
|---|
| | 326 | return notImplemented(); |
|---|
| | 327 | } |
|---|
| | 328 | |
|---|
| | 329 | static PyObject *Wiimote_write(PyObject *self, PyObject *args) |
|---|
| | 330 | { |
|---|
| | 331 | return notImplemented(); |
|---|
| | 332 | } |
|---|
| | 333 | |
|---|
| | 334 | static PyObject *Wiimote_command(PyObject *self, PyObject *args) |
|---|
| | 335 | { |
|---|
| | 336 | /* Python types */ |
|---|
| | 337 | PyObject *pycommand; |
|---|
| | 338 | PyObject *pyflags; |
|---|
| | 339 | |
|---|
| | 340 | /* C types */ |
|---|
| | 341 | enum cwiid_command command; |
|---|
| | 342 | uint8_t flags; |
|---|
| | 343 | |
|---|
| | 344 | PyArg_UnpackTuple(args, "command", 2, 2, &pycommand, &pyflags); |
|---|
| | 345 | if(!(PyInt_Check(pycommand) && PyInt_Check(pyflags))) { |
|---|
| | 346 | PyErr_SetString(PyExc_TypeError, "command and flags must be ints"); |
|---|
| | 347 | } |
|---|
| | 348 | |
|---|
| | 349 | /* marshal everything over */ |
|---|
| | 350 | command = (enum cwiid_command) PyInt_AsLong(pycommand); |
|---|
| | 351 | flags = (uint8_t) PyInt_AsLong(pyflags); |
|---|
| | 352 | |
|---|
| | 353 | /* finally, send the command to the wiimote */ |
|---|
| | 354 | cwiid_command(((Wiimote *)self)->wiimote, command, flags); |
|---|
| | 355 | /* PyGILState_Release(gstate); */ |
|---|
| | 356 | |
|---|
| | 357 | Py_RETURN_NONE; |
|---|
| | 358 | } |
|---|
| | 359 | |
|---|
| | 360 | static PyObject *Wiimote_disconnect(PyObject *self, PyObject *args) |
|---|
| | 361 | { |
|---|
| | 362 | return notImplemented(); |
|---|
| | 363 | } |
|---|
| | 364 | |
|---|
| | 365 | static PyObject *Wiimote_enable(PyObject *self, PyObject *args) |
|---|
| | 366 | { |
|---|
| | 367 | return notImplemented(); |
|---|
| | 368 | } |
|---|
| | 369 | |
|---|
| | 370 | static PyObject *Wiimote_disable(PyObject *self, PyObject *args) |
|---|
| | 371 | { |
|---|
| | 372 | return notImplemented(); |
|---|
| | 373 | } |
|---|
| | 374 | |
|---|
| | 375 | static PyObject *Wiimote_get_mesg(PyObject *self, PyObject *args) |
|---|
| | 376 | { |
|---|
| | 377 | union cwiid_mesg **mesgs; |
|---|
| | 378 | int mesg_count; |
|---|
| | 379 | |
|---|
| | 380 | /* get the messages from Mr. Wiimote */ |
|---|
| | 381 | |
|---|
| | 382 | return processMesgs(mesg_count, *mesgs); |
|---|
| | 383 | } |
|---|
| | 384 | |
|---|
| | 385 | static PyObject *Wiimote_set_callback(PyObject *self, PyObject *args) |
|---|
| | 386 | { |
|---|
| | 387 | PyObject *pyCallback; |
|---|
| | 388 | |
|---|
| | 389 | PyArg_UnpackTuple(args, "set_callback", 1, 1, &pyCallback); |
|---|
| | 390 | if (!PyCallable_Check(pyCallback)) { |
|---|
| | 391 | PyErr_SetString(PyExc_TypeError, "callback must be callable!"); |
|---|
| | 392 | } |
|---|
| 321 | | //Set this callback as an attribute in the class |
|---|
| 322 | | if (((cwiidmodule*)self)->callback== Py_None)//wasn't a callback before |
|---|
| 323 | | { |
|---|
| 324 | | cwiid_set_mesg_callback(((cwiidmodule*)self)->wiimote, |
|---|
| 325 | | (cwiid_mesg_callback_t*) callbackBridge); |
|---|
| 326 | | } |
|---|
| 327 | | ((cwiidmodule*)self)->callback = pyCallback; |
|---|
| 328 | | |
|---|
| 329 | | Py_RETURN_NONE; |
|---|
| 330 | | } |
|---|
| 331 | | |
|---|
| 332 | | PyObject* |
|---|
| 333 | | Wiimote_get_state(PyObject* self, PyObject* args) |
|---|
| 334 | | { |
|---|
| 335 | | return notImplemented(); |
|---|
| 336 | | } |
|---|
| 337 | | |
|---|
| 338 | | static PyObject* |
|---|
| 339 | | notImplemented() |
|---|
| 340 | | { |
|---|
| 341 | | PyErr_SetString(PyExc_NotImplementedError, "This has not yet been implemented"); |
|---|
| 342 | | |
|---|
| 343 | | Py_RETURN_NONE; |
|---|
| 344 | | } |
|---|
| 345 | | |
|---|
| 346 | | void |
|---|
| 347 | | callbackBridge(cwiid_wiimote_t* wiimote, |
|---|
| 348 | | int mesg_count, union cwiid_mesg mesg[]) |
|---|
| 349 | | { |
|---|
| 350 | | PyObject* argTuple; |
|---|
| 351 | | PyObject* pyself; |
|---|
| 352 | | //PyObject* pyCallback; |
|---|
| 353 | | PyGILState_STATE gstate; |
|---|
| 354 | | |
|---|
| 355 | | gstate = PyGILState_Ensure(); |
|---|
| 356 | | |
|---|
| 357 | | argTuple = processMesgs(mesg_count, mesg); |
|---|
| 358 | | |
|---|
| 359 | | //Put id and the list of messages as the arguments to the callback |
|---|
| 360 | | pyself = (PyObject*) cwiid_get_data(wiimote); |
|---|
| 361 | | if (PyMethod_Check(((cwiidmodule*)pyself)->callback)) |
|---|
| 362 | | { |
|---|
| 363 | | //Sorry for the ugliness here. |
|---|
| 364 | | //After determining that the callback is a method in a class, |
|---|
| 365 | | //this line calls that function object with self and the argtuple |
|---|
| 366 | | //as arguments. |
|---|
| 367 | | PyObject_CallFunction( |
|---|
| 368 | | PyMethod_Function(((cwiidmodule*)pyself)->callback),"(OO)", |
|---|
| 369 | | PyMethod_Class(((cwiidmodule*)pyself)->callback), argTuple |
|---|
| 370 | | ); |
|---|
| 371 | | } |
|---|
| 372 | | else |
|---|
| 373 | | PyObject_CallFunction(((cwiidmodule*)pyself)->callback, |
|---|
| 374 | | "(O)",argTuple); |
|---|
| 375 | | |
|---|
| 376 | | Py_XDECREF(argTuple); //actually need to decref the entire structure |
|---|
| 377 | | PyGILState_Release(gstate); |
|---|
| | 395 | /* Set this callback as an attribute in the class */ |
|---|
| | 396 | /* wasn't a callback before */ |
|---|
| | 397 | if (((Wiimote *)self)->callback== Py_None) { |
|---|
| | 398 | cwiid_set_mesg_callback(((Wiimote *)self)->wiimote, |
|---|
| | 399 | (cwiid_mesg_callback_t *) callbackBridge); |
|---|
| | 400 | } |
|---|
| | 401 | ((Wiimote *)self)->callback = pyCallback; |
|---|
| | 402 | |
|---|
| | 403 | Py_RETURN_NONE; |
|---|
| | 404 | } |
|---|
| | 405 | |
|---|
| | 406 | static PyObject *Wiimote_get_state(PyObject *self, PyObject *args) |
|---|
| | 407 | { |
|---|
| | 408 | return notImplemented(); |
|---|
| | 409 | } |
|---|
| | 410 | |
|---|
| | 411 | static PyObject *notImplemented() |
|---|
| | 412 | { |
|---|
| | 413 | PyErr_SetString(PyExc_NotImplementedError, "This has not yet been implemented"); |
|---|
| | 414 | |
|---|
| | 415 | Py_RETURN_NONE; |
|---|
| | 416 | } |
|---|
| | 417 | |
|---|
| | 418 | static void |
|---|
| | 419 | callbackBridge(cwiid_wiimote_t *wiimote, int mesg_count, |
|---|
| | 420 | union cwiid_mesg mesg[]) |
|---|
| | 421 | { |
|---|
| | 422 | PyObject *argTuple; |
|---|
| | 423 | PyObject *pyself; |
|---|
| | 424 | /* PyObject *pyCallback; */ |
|---|
| | 425 | PyGILState_STATE gstate; |
|---|
| | 426 | |
|---|
| | 427 | gstate = PyGILState_Ensure(); |
|---|
| | 428 | |
|---|
| | 429 | argTuple = processMesgs(mesg_count, mesg); |
|---|
| | 430 | |
|---|
| | 431 | /* Put id and the list of messages as the arguments to the callback */ |
|---|
| | 432 | pyself = (PyObject *) cwiid_get_data(wiimote); |
|---|
| | 433 | if (PyMethod_Check(((Wiimote *)pyself)->callback)) { |
|---|
| | 434 | /* Sorry for the ugliness here. |
|---|
| | 435 | * After determining that the callback is a method in a class, |
|---|
| | 436 | * this line calls that function object with self and the argtuple |
|---|
| | 437 | * as arguments. */ |
|---|
| | 438 | PyObject_CallFunction( |
|---|
| | 439 | PyMethod_Function(((Wiimote *)pyself)->callback),"(OO)", |
|---|
| | 440 | PyMethod_Class(((Wiimote *)pyself)->callback), argTuple |
|---|
| | 441 | ); |
|---|
| | 442 | } |
|---|
| | 443 | else { |
|---|
| | 444 | PyObject_CallFunction(((Wiimote *)pyself)->callback, |
|---|
| | 445 | "(O)",argTuple); |
|---|
| | 446 | } |
|---|
| | 447 | |
|---|
| | 448 | Py_XDECREF(argTuple); /* actually need to decref the entire structure */ |
|---|
| | 449 | PyGILState_Release(gstate); |
|---|
| 393 | | static PyObject* |
|---|
| 394 | | processMesgs(int mesg_count, union cwiid_mesg mesg[]) |
|---|
| 395 | | { |
|---|
| 396 | | PyObject* mesglist; //List of message tuples |
|---|
| 397 | | PyObject* amesg; //A single message (type, [arguments]) |
|---|
| 398 | | PyObject* mesgVal; //Dictionary of arguments for a message |
|---|
| 399 | | |
|---|
| 400 | | int i; |
|---|
| 401 | | |
|---|
| 402 | | mesglist = PyList_New(0); |
|---|
| 403 | | Py_XINCREF(mesglist); |
|---|
| 404 | | for (i = 0; i < mesg_count; i++) |
|---|
| 405 | | { |
|---|
| 406 | | |
|---|
| 407 | | mesgVal = PyDict_New(); |
|---|
| 408 | | Py_XINCREF(mesgVal); |
|---|
| 409 | | switch (mesg[i].type) { |
|---|
| 410 | | case CWIID_MESG_STATUS: |
|---|
| 411 | | PyDict_SetItemString(mesgVal, "battery", |
|---|
| 412 | | Py_BuildValue("B", mesg[i].status_mesg.battery)); |
|---|
| 413 | | switch (mesg[i].status_mesg.ext_type) |
|---|
| 414 | | { |
|---|
| 415 | | case CWIID_EXT_NONE: |
|---|
| 416 | | PyDict_SetItemString(mesgVal, "extension", |
|---|
| 417 | | Py_BuildValue("s","none")); |
|---|
| 418 | | break; |
|---|
| 419 | | case CWIID_EXT_NUNCHUK: |
|---|
| 420 | | PyDict_SetItemString(mesgVal, "extension", |
|---|
| 421 | | Py_BuildValue("s","nunchuck")); |
|---|
| 422 | | break; |
|---|
| 423 | | case CWIID_EXT_CLASSIC: |
|---|
| 424 | | PyDict_SetItemString(mesgVal, "extension", |
|---|
| 425 | | Py_BuildValue("s","classic")); |
|---|
| 426 | | break; |
|---|
| 427 | | default: |
|---|
| 428 | | break; |
|---|
| 429 | | } |
|---|
| 430 | | break; |
|---|
| 431 | | case CWIID_MESG_BTN: |
|---|
| 432 | | PyDict_SetItemString(mesgVal, "buttons", |
|---|
| 433 | | Py_BuildValue("H", mesg[i].btn_mesg.buttons)); |
|---|
| 434 | | break; |
|---|
| 435 | | case CWIID_MESG_ACC: |
|---|
| 436 | | PyDict_SetItemString(mesgVal, "x", |
|---|
| 437 | | Py_BuildValue("B", mesg[i].acc_mesg.acc[0])); |
|---|
| 438 | | PyDict_SetItemString(mesgVal, "y", |
|---|
| 439 | | Py_BuildValue("B", mesg[i].acc_mesg.acc[1])); |
|---|
| 440 | | PyDict_SetItemString(mesgVal, "z", |
|---|
| 441 | | Py_BuildValue("B", mesg[i].acc_mesg.acc[2])); |
|---|
| 442 | | break; |
|---|
| 443 | | case CWIID_MESG_IR: |
|---|
| 444 | | break; |
|---|
| 445 | | case CWIID_MESG_NUNCHUK: |
|---|
| 446 | | break; |
|---|
| 447 | | case CWIID_MESG_CLASSIC: |
|---|
| 448 | | break; |
|---|
| 449 | | case CWIID_MESG_ERROR: |
|---|
| 450 | | switch(mesg[i].error_mesg.error) |
|---|
| 451 | | { |
|---|
| 452 | | case CWIID_ERROR_DISCONNECT: |
|---|
| 453 | | PyDict_SetItemString(mesgVal, "error", |
|---|
| 454 | | Py_BuildValue("s", |
|---|
| 455 | | "Wiimote was disconnected")); |
|---|
| 456 | | break; |
|---|
| 457 | | case CWIID_ERROR_COMM: |
|---|
| 458 | | PyDict_SetItemString(mesgVal, "error", |
|---|
| 459 | | Py_BuildValue("s", |
|---|
| 460 | | "Communication error occurred")); |
|---|
| 461 | | break; |
|---|
| 462 | | default: |
|---|
| 463 | | PyDict_SetItemString(mesgVal, "error", |
|---|
| 464 | | Py_BuildValue("s","An Unknown error occurred")); |
|---|
| 465 | | break; |
|---|
| 466 | | } |
|---|
| 467 | | break; |
|---|
| 468 | | default: |
|---|
| 469 | | PyDict_SetItemString(mesgVal, "error", |
|---|
| 470 | | Py_BuildValue("s","Unknown message arrived")); |
|---|
| 471 | | break; |
|---|
| 472 | | } |
|---|
| 473 | | |
|---|
| 474 | | //Finally Put the type next to the message in a tuple and |
|---|
| 475 | | //append them to the list of messages |
|---|
| 476 | | amesg = Py_BuildValue("(iO)", mesg[i].type, mesgVal); |
|---|
| 477 | | Py_XINCREF(amesg); |
|---|
| 478 | | PyList_Append(mesglist, amesg); |
|---|
| 479 | | } |
|---|
| 480 | | |
|---|
| 481 | | return mesglist; |
|---|
| 482 | | } |
|---|
| | 465 | static PyObject *processMesgs(int mesg_count, union cwiid_mesg mesg[]) |
|---|
| | 466 | { |
|---|
| | 467 | PyObject *mesglist; /* List of message tuples */ |
|---|
| | 468 | PyObject *amesg; /* A single message (type, [arguments]) */ |
|---|
| | 469 | PyObject *mesgVal; /* Dictionary of arguments for a message */ |
|---|
| | 470 | |
|---|
| | 471 | int i; |
|---|
| | 472 | |
|---|
| | 473 | mesglist = PyList_New(0); |
|---|
| | 474 | Py_XINCREF(mesglist); |
|---|
| | 475 | for (i = 0; i < mesg_count; i++) |
|---|
| | 476 | { |
|---|
| | 477 | mesgVal = PyDict_New(); |
|---|
| | 478 | Py_XINCREF(mesgVal); |
|---|
| | 479 | switch (mesg[i].type) { |
|---|
| | 480 | case CWIID_MESG_STATUS: |
|---|
| | 481 | PyDict_SetItemString(mesgVal, "battery", |
|---|
| | 482 | Py_BuildValue("B", mesg[i].status_mesg.battery)); |
|---|
| | 483 | switch (mesg[i].status_mesg.ext_type) { |
|---|
| | 484 | case CWIID_EXT_NONE: |
|---|
| | 485 | PyDict_SetItemString(mesgVal, "extension", |
|---|
| | 486 | Py_BuildValue("s","none")); |
|---|
| | 487 | break; |
|---|
| | 488 | case CWIID_EXT_NUNCHUK: |
|---|
| | 489 | PyDict_SetItemString(mesgVal, "extension", |
|---|
| | 490 | Py_BuildValue("s","nunchuck")); |
|---|
| | 491 | break; |
|---|
| | 492 | case CWIID_EXT_CLASSIC: |
|---|
| | 493 | PyDict_SetItemString(mesgVal, "extension", |
|---|
| | 494 | Py_BuildValue("s","classic")); |
|---|
| | 495 | break; |
|---|
| | 496 | default: |
|---|
| | 497 | break; |
|---|
| | 498 | } |
|---|
| | 499 | break; |
|---|
| | 500 | case CWIID_MESG_BTN: |
|---|
| | 501 | PyDict_SetItemString(mesgVal, "buttons", |
|---|
| | 502 | Py_BuildValue("H", mesg[i].btn_mesg.buttons)); |
|---|
| | 503 | break; |
|---|
| | 504 | case CWIID_MESG_ACC: |
|---|
| | 505 | PyDict_SetItemString(mesgVal, "x", |
|---|
| | 506 | Py_BuildValue("B", mesg[i].acc_mesg.acc[0])); |
|---|
| | 507 | PyDict_SetItemString(mesgVal, "y", |
|---|
| | 508 | Py_BuildValue("B", mesg[i].acc_mesg.acc[1])); |
|---|
| | 509 | PyDict_SetItemString(mesgVal, "z", |
|---|
| | 510 | Py_BuildValue("B", mesg[i].acc_mesg.acc[2])); |
|---|
| | 511 | break; |
|---|
| | 512 | case CWIID_MESG_IR: |
|---|
| | 513 | break; |
|---|
| | 514 | case CWIID_MESG_NUNCHUK: |
|---|
| | 515 | break; |
|---|
| | 516 | case CWIID_MESG_CLASSIC: |
|---|
| | 517 | break; |
|---|
| | 518 | case CWIID_MESG_ERROR: |
|---|
| | 519 | switch(mesg[i].error_mesg.error) { |
|---|
| | 520 | case CWIID_ERROR_DISCONNECT: |
|---|
| | 521 | PyDict_SetItemString(mesgVal, "error", |
|---|
| | 522 | Py_BuildValue("s", "Wiimote was disconnected")); |
|---|
| | 523 | break; |
|---|
| | 524 | case CWIID_ERROR_COMM: |
|---|
| | 525 | PyDict_SetItemString(mesgVal, "error", |
|---|
| | 526 | Py_BuildValue("s", "Communication error occurred")); |
|---|
| | 527 | break; |
|---|
| | 528 | default: |
|---|
| | 529 | PyDict_SetItemString(mesgVal, "error", |
|---|
| | 530 | Py_BuildValue("s","An Unknown error occurred")); |
|---|
| | 531 | break; |
|---|
| | 532 | } |
|---|
| | 533 | break; |
|---|
| | 534 | default: |
|---|
| | 535 | PyDict_SetItemString(mesgVal, "error", |
|---|
| | 536 | Py_BuildValue("s","Unknown message arrived")); |
|---|
| | 537 | break; |
|---|
| | 538 | } |
|---|
| | 539 | |
|---|
| | 540 | /* Finally Put the type next to the message in a tuple and |
|---|
| | 541 | * append them to the list of messages */ |
|---|
| | 542 | amesg = Py_BuildValue("(iO)", mesg[i].type, mesgVal); |
|---|
| | 543 | Py_XINCREF(amesg); |
|---|
| | 544 | PyList_Append(mesglist, amesg); |
|---|
| | 545 | } |
|---|
| | 546 | |
|---|
| | 547 | return mesglist; |
|---|
| | 548 | } |
|---|