Changeset 104

Show
Ignore:
Timestamp:
05/07/07 19:41:21 (2 years ago)
Author:
dsmith
Message:

cwiidpy branch changes

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/cwiidpy/Makefile

    r103 r104  
    11#Copyright (C) 2007 Justin M. Tulloss 
    22 
     3NAME = cwiidmodule 
    34SOURCES = cwiidmodule.c 
    45 
     6SO_NAME = $(NAME).so 
     7OBJECTS = $(SOURCES:.c=.o) 
     8 
    59LDLIBS += -lcwiid 
    6 CFLAGS = -fpic -Wall -g -I /usr/include/python2.4 
     10CFLAGS = -fpic -Wall -g -I/usr/include/python2.4 
    711LDFLAGS = -shared -fpic 
    8 NAME = cwiidmodule 
    9 OBJ = $(NAME).o 
    10 CC = gcc 
    1112 
    12 $(NAME): $(OBJ) 
    13         $(CC) $(LDFLAGS) -o $(NAME).so $(LDLIBS) $(OBJ) 
    14  
    15 $(NAME).o: $(SOURCES) 
    16         $(CC) $(CFLAGS) -c $(SOURCES) 
     13$(SO_NAME): $(OBJECTS) 
     14        $(CC) $(LDFLAGS) $(OBJECTS) -o $(NAME).so $(LDLIBS) -o $(SO_NAME) 
    1715 
    1816clean: 
  • branches/cwiidpy/cwiidmodule.c

    r103 r104  
    2020 * 
    2121 * ChangeLog: 
     22 * 2007-05-07 L. Donnie Smith <cwiid@abstrakraft.org> 
     23 * * C-style comments 
     24 * * changed struct name to Wiimote 
     25 * * removed dlopen, unused includes 
     26 * * spaces to tabs 
     27 * * stylistic changes to match CWiid code 
     28 * * removed function casts to catch function type errors 
     29 * 
    2230 * 2007-05-07 Justin M. Tulloss <jmtulloss@gmail.com> 
    2331 * * Refactored according to dsmith's wishes, removed unnecessary locks 
     
    3038 */ 
    3139 
    32 //Apparently this has to be first for every python interpreter extension 
     40/* Apparently this has to be first for every python interpreter extension */ 
    3341#include "Python.h" 
    3442 
    35 //Standard Includes 
    36 #include <stdio.h> 
    37 #include <string.h> 
    38 #include <errno.h> 
    39 #include <limits.h> 
     43/* Standard Includes */ 
    4044#include <stdlib.h> 
    41 #include <dlfcn.h> 
    42 #include <pthread.h> 
    43  
    44 //Interesting includes 
     45 
     46/* Interesting includes */ 
    4547#include "cwiid.h" 
    4648#include "structmember.h" 
    4749 
    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 */ 
     51PyMODINIT_FUNC initcwiid(void); 
     52 
     53static int Wiimote_init(PyObject *self, PyObject *args, PyObject *kwds); 
     54static PyObject *Wiimote_read(PyObject *self, PyObject *args); 
     55static PyObject *Wiimote_write(PyObject *self, PyObject *args); 
     56static PyObject *Wiimote_command(PyObject *self, PyObject *args); 
     57static PyObject *Wiimote_disconnect(PyObject *self, PyObject *args); 
     58static PyObject *Wiimote_enable(PyObject *self, PyObject *args); 
     59static PyObject *Wiimote_disable(PyObject *self, PyObject *args); 
     60static PyObject *Wiimote_get_mesg(PyObject *self, PyObject *args); 
     61static PyObject *Wiimote_set_callback(PyObject *self, PyObject *args); 
     62static PyObject *Wiimote_get_state(PyObject *self, PyObject *args); 
     63 
     64#define CONST_MACRO(a) {#a, CWIID_##a} 
     65struct cwiid_constant { 
     66        char *name; 
     67        int value; 
     68}; 
     69static 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 */ 
    65149typedef struct { 
    66     PyObject_HEAD 
    67     cwiid_wiimote_t* wiimote; 
    68     PyObject* callback; 
    69 }cwiidmodule; 
    70  
    71 //Type private functions 
    72 static void cwiidmodule_dealloc(cwiidmodule* self); 
    73 static PyObject* 
    74     cwiidmodule_new(PyTypeObject *type, PyObject *args, PyObject *kwds); 
    75  
    76 //Helper functions 
    77 void callbackBridge(cwiid_wiimote_t* wiimote, 
    78     int mesg_count, union cwiid_mesg mesg[]); 
    79 static PyObject* processMesgs(int mesg_count, union cwiid_mesg mesg[]); 
    80 static int cwiid_start(cwiidmodule* self, int flags); 
    81 static PyObject* notImplemented(); 
     150        PyObject_HEAD 
     151        cwiid_wiimote_t *wiimote; 
     152        PyObject *callback; 
     153} Wiimote; 
     154 
     155/* Type private functions */ 
     156static PyObject * 
     157        Wiimote_new(PyTypeObject *type, PyObject *args, PyObject *kwds); 
     158static void Wiimote_dealloc(PyObject *self); 
     159 
     160/* Helper functions */ 
     161static void 
     162        callbackBridge(cwiid_wiimote_t *wiimote, int mesg_count, 
     163                       union cwiid_mesg mesg[]); 
     164static PyObject *processMesgs(int mesg_count, union cwiid_mesg mesg[]); 
     165static int cwiid_start(Wiimote *self, int flags); 
     166static PyObject *notImplemented(); 
    82167 
    83168static bdaddr_t btAddr; 
    84169 
    85170 
    86 //Associates cwiid functions with python ones 
     171/* Associates cwiid functions with python ones */ 
    87172static PyMethodDef modMethods[] =  
    88173{ 
    89     {NULL, NULL} 
     174       {NULL, NULL} 
    90175}; 
    91176 
    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 */ 
     178static 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} 
    107191}; 
    108192 
    109 static PyMemberDef cwiidMembers[] = { 
    110     {"_wiimote", T_OBJECT_EX, offsetof(cwiidmodule, wiimote), 0, "wiimote"}, 
    111     {"_callback", T_OBJECT_EX,offsetof(cwiidmodule, callback),0,"callback"}, 
    112     {NULL} 
     193static PyMemberDef Wiimote_Members[] = { 
     194       {"_wiimote", T_OBJECT_EX, offsetof(Wiimote, wiimote), 0, "wiimote"}, 
     195       {"_callback", T_OBJECT_EX,offsetof(Wiimote, callback),0,"callback"}, 
     196       {NULL} 
    113197}; 
    114198 
    115199 
    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 */ 
     201static 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 */ 
    157241}; 
    158242 
    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     } 
     243PyMODINIT_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 */ 
     270static 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 
     280static 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 
     289static 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 
     304static 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 
     324static PyObject *Wiimote_read(PyObject *self, PyObject *args) 
     325
     326        return notImplemented(); 
     327
     328 
     329static PyObject *Wiimote_write(PyObject *self, PyObject *args) 
     330
     331        return notImplemented(); 
     332
     333 
     334static 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 
     360static PyObject *Wiimote_disconnect(PyObject *self, PyObject *args) 
     361
     362        return notImplemented(); 
     363
     364 
     365static PyObject *Wiimote_enable(PyObject *self, PyObject *args) 
     366
     367        return notImplemented(); 
     368
     369 
     370static PyObject *Wiimote_disable(PyObject *self, PyObject *args) 
     371
     372        return notImplemented(); 
     373
     374 
     375static 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 
     385static 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        } 
    319393        Py_XINCREF(pyCallback); 
    320394 
    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 
     406static PyObject *Wiimote_get_state(PyObject *self, PyObject *args) 
     407
     408        return notImplemented(); 
     409
     410 
     411static PyObject *notImplemented() 
     412
     413        PyErr_SetString(PyExc_NotImplementedError, "This has not yet been implemented"); 
     414 
     415        Py_RETURN_NONE; 
     416
     417 
     418static 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); 
    378450} 
    379451 
     
    391463 *          (CWIID_ACC_MESG,{"x":xVal, "y":yVal, "z":zVal})] 
    392464 */ 
    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 
     465static 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