| 298 | | /* Allocate and deallocate functions */ |
|---|
| 299 | | static PyObject * |
|---|
| 300 | | Wiimote_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|---|
| 301 | | { |
|---|
| 302 | | Wiimote* self; |
|---|
| 303 | | |
|---|
| 304 | | if (!(self = (Wiimote *) type->tp_alloc(type, 0))) { |
|---|
| 305 | | return NULL; |
|---|
| 306 | | } |
|---|
| 307 | | |
|---|
| 308 | | self->wiimote = NULL; |
|---|
| 309 | | Py_INCREF(self->callback = Py_None); |
|---|
| 310 | | |
|---|
| 311 | | return (PyObject*) self; |
|---|
| 312 | | } |
|---|
| 313 | | |
|---|
| 314 | | static void Wiimote_dealloc(Wiimote *self) |
|---|
| 315 | | { |
|---|
| 316 | | if (self->wiimote) { |
|---|
| 317 | | cwiid_disconnect(self->wiimote); |
|---|
| 318 | | } |
|---|
| 319 | | Py_XDECREF(self->callback); |
|---|
| 320 | | self->ob_type->tp_free((PyObject *)self); |
|---|
| 321 | | } |
|---|
| 322 | | |
|---|
| 323 | | static int cwiid_start(Wiimote *self, int flags) |
|---|
| 324 | | { |
|---|
| 325 | | cwiid_wiimote_t *theMote; |
|---|
| 326 | | bdaddr_t bdaddr = *BDADDR_ANY; |
|---|
| 327 | | |
|---|
| 328 | | /* Set up wiimote */ |
|---|
| 329 | | if(!(theMote = cwiid_connect(&bdaddr, flags))) { |
|---|
| 330 | | PyErr_SetString(PyExc_IOError, "Could not connect to wiimote"); |
|---|
| 331 | | return -1; |
|---|
| 332 | | } |
|---|
| 333 | | cwiid_set_data(theMote,self); /* keep pyobject with wiimote */ |
|---|
| 334 | | self->wiimote = theMote; /* keep wiimote with pyobject */ |
|---|
| 335 | | return 0; |
|---|
| 336 | | } |
|---|
| 337 | | |
|---|
| 338 | | static int Wiimote_init(Wiimote* self, PyObject* args, PyObject *kwds) |
|---|
| 339 | | { |
|---|
| 340 | | static char *kwlist[] = { "flags", NULL }; |
|---|
| 341 | | int flags = 0; |
|---|
| 342 | | |
|---|
| 343 | | if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &flags)) { |
|---|
| 344 | | return -1; |
|---|
| 345 | | } |
|---|
| 346 | | |
|---|
| 347 | | if (cwiid_start(self, flags)) { |
|---|
| 348 | | return -1; |
|---|
| 349 | | } |
|---|
| 350 | | |
|---|
| 351 | | return 0; |
|---|
| 352 | | } |
|---|
| 353 | | |
|---|
| 354 | | static PyObject *Wiimote_read(Wiimote *self, PyObject *args, PyObject *kwds) |
|---|
| 355 | | { |
|---|
| 356 | | static char *kwlist[] = { "flags", "offset", "len", NULL }; |
|---|
| 357 | | unsigned char flags; |
|---|
| 358 | | unsigned int offset; |
|---|
| 359 | | unsigned int len; |
|---|
| 360 | | void *buf; |
|---|
| 361 | | PyObject *pyRetBuf; |
|---|
| 362 | | |
|---|
| 363 | | if (!PyArg_ParseTupleAndKeywords(args, kwds, "BII", kwlist, &flags, |
|---|
| 364 | | &offset, &len)) { |
|---|
| 365 | | return NULL; |
|---|
| 366 | | } |
|---|
| 367 | | |
|---|
| 368 | | if (!(pyRetBuf = PyBuffer_New(len))) { |
|---|
| 369 | | return NULL; |
|---|
| 370 | | } |
|---|
| 371 | | if (PyObject_AsWriteBuffer(pyRetBuf, &buf, (int *)&len)) { |
|---|
| 372 | | Py_DECREF(pyRetBuf); |
|---|
| 373 | | return NULL; |
|---|
| 374 | | } |
|---|
| 375 | | if (cwiid_read(self->wiimote,flags,offset,len,buf)) { |
|---|
| 376 | | PyErr_SetString(PyExc_IOError, "Wiimote read error"); |
|---|
| 377 | | Py_DECREF(pyRetBuf); |
|---|
| 378 | | return NULL; |
|---|
| 379 | | } |
|---|
| 380 | | |
|---|
| 381 | | return pyRetBuf; |
|---|
| 382 | | } |
|---|
| 383 | | |
|---|
| 384 | | static PyObject *Wiimote_write(Wiimote *self, PyObject *args, PyObject *kwds) |
|---|
| 385 | | { |
|---|
| 386 | | static char *kwlist[] = { "flags", "offset", "buffer", NULL }; |
|---|
| 387 | | unsigned char flags; |
|---|
| 388 | | unsigned int offset; |
|---|
| 389 | | void *buf; |
|---|
| 390 | | int len; |
|---|
| 391 | | |
|---|
| 392 | | if (!PyArg_ParseTupleAndKeywords(args, kwds, "BIt#", kwlist, &flags, |
|---|
| 393 | | &offset, &buf, &len)) { |
|---|
| 394 | | return NULL; |
|---|
| 395 | | } |
|---|
| 396 | | |
|---|
| 397 | | if (cwiid_write(self->wiimote, flags, offset, len, buf)) { |
|---|
| 398 | | PyErr_SetString(PyExc_IOError, "Wiimote write error"); |
|---|
| 399 | | return NULL; |
|---|
| 400 | | } |
|---|
| 401 | | |
|---|
| 402 | | Py_RETURN_NONE; |
|---|
| 403 | | } |
|---|
| 404 | | |
|---|
| 405 | | static PyObject *Wiimote_command(Wiimote *self, PyObject *args) |
|---|
| 406 | | { |
|---|
| 407 | | /* Python types */ |
|---|
| 408 | | PyObject *pycommand; |
|---|
| 409 | | PyObject *pyflags; |
|---|
| 410 | | |
|---|
| 411 | | /* C types */ |
|---|
| 412 | | enum cwiid_command command; |
|---|
| 413 | | uint8_t flags; |
|---|
| 414 | | |
|---|
| 415 | | PyArg_UnpackTuple(args, "command", 2, 2, &pycommand, &pyflags); |
|---|
| 416 | | if(!(PyInt_Check(pycommand) && PyInt_Check(pyflags))) { |
|---|
| 417 | | PyErr_SetString(PyExc_TypeError, "command and flags must be ints"); |
|---|
| 418 | | } |
|---|
| 419 | | |
|---|
| 420 | | /* marshal everything over */ |
|---|
| 421 | | command = (enum cwiid_command) PyInt_AsLong(pycommand); |
|---|
| 422 | | flags = (uint8_t) PyInt_AsLong(pyflags); |
|---|
| 423 | | |
|---|
| 424 | | /* finally, send the command to the wiimote */ |
|---|
| 425 | | cwiid_command(self->wiimote, command, flags); |
|---|
| 426 | | /* PyGILState_Release(gstate); */ |
|---|
| 427 | | |
|---|
| 428 | | Py_RETURN_NONE; |
|---|
| 429 | | } |
|---|
| 430 | | |
|---|
| 431 | | static PyObject *Wiimote_disconnect(Wiimote *self) |
|---|
| 432 | | { |
|---|
| 433 | | if (cwiid_disconnect(self->wiimote)) { |
|---|
| 434 | | PyErr_SetString(PyExc_IOError, "Wiimote disconnect error"); |
|---|
| 435 | | self->wiimote = NULL; |
|---|
| 436 | | return NULL; |
|---|
| 437 | | } |
|---|
| 438 | | self->wiimote = NULL; |
|---|
| 439 | | |
|---|
| 440 | | Py_RETURN_NONE; |
|---|
| 441 | | } |
|---|
| 442 | | |
|---|
| 443 | | static PyObject *Wiimote_enable(Wiimote *self, PyObject *args, PyObject *kwds) |
|---|
| 444 | | { |
|---|
| 445 | | static char *kwlist[] = { "flags", NULL }; |
|---|
| 446 | | int flags; |
|---|
| 447 | | |
|---|
| 448 | | if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &flags)) { |
|---|
| 449 | | return NULL; |
|---|
| 450 | | } |
|---|
| 451 | | |
|---|
| 452 | | if (cwiid_enable(self->wiimote, flags)) { |
|---|
| 453 | | PyErr_SetString(PyExc_IOError, "cwiid_enable error"); |
|---|
| 454 | | return NULL; |
|---|
| 455 | | } |
|---|
| 456 | | |
|---|
| 457 | | Py_RETURN_NONE; |
|---|
| 458 | | } |
|---|
| 459 | | |
|---|
| 460 | | static PyObject * |
|---|
| 461 | | Wiimote_disable(Wiimote *self, PyObject *args, PyObject *kwds) |
|---|
| 462 | | { |
|---|
| 463 | | static char *kwlist[] = { "flags", NULL }; |
|---|
| 464 | | int flags; |
|---|
| 465 | | |
|---|
| 466 | | if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &flags)) { |
|---|
| 467 | | return NULL; |
|---|
| 468 | | } |
|---|
| 469 | | |
|---|
| 470 | | if (cwiid_disable(self->wiimote, flags)) { |
|---|
| 471 | | PyErr_SetString(PyExc_IOError, "cwiid_disable error"); |
|---|
| 472 | | return NULL; |
|---|
| 473 | | } |
|---|
| 474 | | |
|---|
| 475 | | Py_RETURN_NONE; |
|---|
| 476 | | } |
|---|
| 477 | | |
|---|
| 478 | | static PyObject *Wiimote_get_mesg(Wiimote *self, PyObject *args) |
|---|
| 479 | | { |
|---|
| 480 | | union cwiid_mesg *mesg; |
|---|
| 481 | | int mesg_count; |
|---|
| 482 | | |
|---|
| 483 | | /* get the messages from Mr. Wiimote */ |
|---|
| 484 | | if (cwiid_get_mesg(self->wiimote, &mesg_count, &mesg)) { |
|---|
| 485 | | if (errno == EAGAIN) { |
|---|
| 486 | | Py_RETURN_NONE; |
|---|
| 487 | | } |
|---|
| 488 | | else { |
|---|
| 489 | | PyErr_SetString(PyExc_IOError, "get_mesg error"); |
|---|
| 490 | | return NULL; |
|---|
| 491 | | } |
|---|
| 492 | | } |
|---|
| 493 | | |
|---|
| 494 | | return processMesgs(mesg_count, mesg); |
|---|
| 495 | | } |
|---|
| 496 | | |
|---|
| 497 | | static PyObject *Wiimote_set_callback(Wiimote *self, PyObject *args) |
|---|
| 498 | | { |
|---|
| 499 | | PyObject *pyCallback; |
|---|
| 500 | | |
|---|
| 501 | | PyArg_UnpackTuple(args, "set_callback", 1, 1, &pyCallback); |
|---|
| 502 | | if (!PyCallable_Check(pyCallback)) { |
|---|
| 503 | | PyErr_SetString(PyExc_TypeError, "callback must be callable!"); |
|---|
| 504 | | } |
|---|
| 505 | | Py_XINCREF(pyCallback); |
|---|
| 506 | | |
|---|
| 507 | | /* Set this callback as an attribute in the class */ |
|---|
| 508 | | /* wasn't a callback before */ |
|---|
| 509 | | if (self->callback== Py_None) { |
|---|
| 510 | | cwiid_set_mesg_callback(self->wiimote, |
|---|
| 511 | | (cwiid_mesg_callback_t *) callbackBridge); |
|---|
| 512 | | } |
|---|
| 513 | | self->callback = pyCallback; |
|---|
| 514 | | |
|---|
| 515 | | Py_RETURN_NONE; |
|---|
| 516 | | } |
|---|
| 517 | | |
|---|
| 518 | | static PyObject *Wiimote_get_state(Wiimote* self, void *closure) |
|---|
| 519 | | { |
|---|
| 520 | | struct cwiid_state state; |
|---|
| 521 | | PyObject *PyState; |
|---|
| 522 | | |
|---|
| 523 | | if (cwiid_get_state(self->wiimote, &state)) { |
|---|
| 524 | | PyErr_SetString(PyExc_IOError, "get state error"); |
|---|
| 525 | | return NULL; |
|---|
| 526 | | } |
|---|
| 527 | | |
|---|
| 528 | | PyState = Py_BuildValue("{s:B,s:B,s:B,s:B,s:i,s:i}", |
|---|
| 529 | | "rpt_mode", state.rpt_mode, |
|---|
| 530 | | "led", state.led, |
|---|
| 531 | | "rumble", state.rumble, |
|---|
| 532 | | "battery", state.battery, |
|---|
| 533 | | "ext_type", state.ext_type, |
|---|
| 534 | | "error", state.error); |
|---|
| 535 | | |
|---|
| 536 | | if (state.rpt_mode & CWIID_RPT_BTN) { |
|---|
| 537 | | PyObject *PyBtn = Py_BuildValue("I", state.buttons); |
|---|
| 538 | | if (!PyBtn) { |
|---|
| 539 | | Py_DECREF(PyState); |
|---|
| 540 | | return NULL; |
|---|
| 541 | | } |
|---|
| 542 | | if (PyDict_SetItemString(PyState, "buttons", PyBtn)) { |
|---|
| 543 | | Py_DECREF(PyState); |
|---|
| 544 | | Py_DECREF(PyBtn); |
|---|
| 545 | | return NULL; |
|---|
| 546 | | } |
|---|
| 547 | | Py_DECREF(PyBtn); |
|---|
| 548 | | } |
|---|
| 549 | | |
|---|
| 550 | | if (state.rpt_mode & CWIID_RPT_ACC) { |
|---|
| 551 | | PyObject *PyAcc = Py_BuildValue("{s:B,s:B,s:B}", |
|---|
| 552 | | "x", state.acc[CWIID_X], |
|---|
| 553 | | "y", state.acc[CWIID_Y], |
|---|
| 554 | | "z", state.acc[CWIID_Z]); |
|---|
| 555 | | if (!PyAcc) { |
|---|
| 556 | | Py_DECREF(PyState); |
|---|
| 557 | | return NULL; |
|---|
| 558 | | } |
|---|
| 559 | | if (PyDict_SetItemString(PyState, "acc", PyAcc)) { |
|---|
| 560 | | Py_DECREF(PyState); |
|---|
| 561 | | Py_DECREF(PyAcc); |
|---|
| 562 | | return NULL; |
|---|
| 563 | | } |
|---|
| 564 | | Py_DECREF(PyAcc); |
|---|
| 565 | | } |
|---|
| 566 | | |
|---|
| 567 | | if (state.rpt_mode & CWIID_RPT_IR) { |
|---|
| 568 | | int i; |
|---|
| 569 | | PyObject *PyIr = PyList_New(CWIID_IR_SRC_COUNT); |
|---|
| 570 | | |
|---|
| 571 | | if (!PyIr) { |
|---|
| 572 | | Py_DECREF(PyState); |
|---|
| 573 | | return NULL; |
|---|
| 574 | | } |
|---|
| 575 | | |
|---|
| 576 | | if (PyDict_SetItemString(PyState, "ir_src", PyIr)) { |
|---|
| 577 | | Py_DECREF(PyState); |
|---|
| 578 | | Py_DECREF(PyIr); |
|---|
| 579 | | return NULL; |
|---|
| 580 | | } |
|---|
| 581 | | |
|---|
| 582 | | Py_DECREF(PyIr); |
|---|
| 583 | | |
|---|
| 584 | | for (i=0; i < CWIID_IR_SRC_COUNT; i++) { |
|---|
| 585 | | PyObject *PyIrSrc; |
|---|
| 586 | | PyObject *PySize; |
|---|
| 587 | | |
|---|
| 588 | | if (state.ir_src[i].valid) { |
|---|
| 589 | | PyIrSrc = Py_BuildValue("{s:{s:I,s:I}}", |
|---|
| 590 | | "pos", |
|---|
| 591 | | "x", state.ir_src[i].pos[CWIID_X], |
|---|
| 592 | | "y", state.ir_src[i].pos[CWIID_Y]); |
|---|
| 593 | | if (!PyIrSrc) { |
|---|
| 594 | | Py_DECREF(PyState); |
|---|
| 595 | | return NULL; |
|---|
| 596 | | } |
|---|
| 597 | | |
|---|
| 598 | | if (state.ir_src[i].size != -1) { |
|---|
| 599 | | if (!(PySize = PyInt_FromLong( |
|---|
| 600 | | (long)state.ir_src[i].size))) { |
|---|
| 601 | | Py_DECREF(PyState); |
|---|
| 602 | | Py_DECREF(PyIrSrc); |
|---|
| 603 | | return NULL; |
|---|
| 604 | | } |
|---|
| 605 | | if (PyDict_SetItemString(PyIrSrc, "size", PySize)) { |
|---|
| 606 | | Py_DECREF(PyState); |
|---|
| 607 | | Py_DECREF(PyIrSrc); |
|---|
| 608 | | Py_DECREF(PySize); |
|---|
| 609 | | return NULL; |
|---|
| 610 | | } |
|---|
| 611 | | |
|---|
| 612 | | Py_DECREF(PySize); |
|---|
| 613 | | } |
|---|
| 614 | | } |
|---|
| 615 | | else { |
|---|
| 616 | | Py_INCREF(PyIrSrc = Py_None); |
|---|
| 617 | | } |
|---|
| 618 | | |
|---|
| 619 | | PyList_SET_ITEM(PyIr, i, PyIrSrc); |
|---|
| 620 | | } |
|---|
| 621 | | } |
|---|
| 622 | | |
|---|
| 623 | | switch (state.ext_type) { |
|---|
| 624 | | PyObject *PyExt; |
|---|
| 625 | | case CWIID_EXT_NUNCHUK: |
|---|
| 626 | | if (state.rpt_mode & CWIID_RPT_NUNCHUK) { |
|---|
| 627 | | PyExt = Py_BuildValue("{s:{s:B,s:B},s:{s:B,s:B,s:B},s:I}", |
|---|
| 628 | | "stick", |
|---|
| 629 | | "x", state.ext.nunchuk.stick[CWIID_X], |
|---|
| 630 | | "y", state.ext.nunchuk.stick[CWIID_Y], |
|---|
| 631 | | "acc", |
|---|
| 632 | | "x", state.ext.nunchuk.acc[CWIID_X], |
|---|
| 633 | | "y", state.ext.nunchuk.acc[CWIID_Y], |
|---|
| 634 | | "z", state.ext.nunchuk.acc[CWIID_Z], |
|---|
| 635 | | "buttons", state.ext.nunchuk.buttons); |
|---|
| 636 | | |
|---|
| 637 | | if (!PyExt) { |
|---|
| 638 | | Py_DECREF(PyState); |
|---|
| 639 | | return NULL; |
|---|
| 640 | | } |
|---|
| 641 | | |
|---|
| 642 | | if (PyDict_SetItemString(PyState, "nunchuk", PyExt)) { |
|---|
| 643 | | Py_DECREF(PyState); |
|---|
| 644 | | Py_DECREF(PyExt); |
|---|
| 645 | | return NULL; |
|---|
| 646 | | } |
|---|
| 647 | | |
|---|
| 648 | | Py_DECREF(PyExt); |
|---|
| 649 | | } |
|---|
| 650 | | break; |
|---|
| 651 | | case CWIID_EXT_CLASSIC: |
|---|
| 652 | | if (state.rpt_mode & CWIID_RPT_CLASSIC) { |
|---|
| 653 | | PyExt = Py_BuildValue("{s:{s:B,s:B},s:{s:B,s:B},s:B,s:B,s:I}", |
|---|
| 654 | | "l_stick", |
|---|
| 655 | | "x", state.ext.classic.l_stick[CWIID_X], |
|---|
| 656 | | "y", state.ext.classic.l_stick[CWIID_Y], |
|---|
| 657 | | "r_stick", |
|---|
| 658 | | "x", state.ext.classic.r_stick[CWIID_X], |
|---|
| 659 | | "y", state.ext.classic.r_stick[CWIID_Y], |
|---|
| 660 | | "l", state.ext.classic.l, |
|---|
| 661 | | "r", state.ext.classic.r, |
|---|
| 662 | | "buttons", state.ext.classic.buttons); |
|---|
| 663 | | |
|---|
| 664 | | if (!PyExt) { |
|---|
| 665 | | Py_DECREF(PyState); |
|---|
| 666 | | return NULL; |
|---|
| 667 | | } |
|---|
| 668 | | |
|---|
| 669 | | if (PyDict_SetItemString(PyState, "classic", PyExt)) { |
|---|
| 670 | | Py_DECREF(PyState); |
|---|
| 671 | | Py_DECREF(PyExt); |
|---|
| 672 | | return NULL; |
|---|
| 673 | | } |
|---|
| 674 | | |
|---|
| 675 | | Py_DECREF(PyExt); |
|---|
| 676 | | } |
|---|
| 677 | | break; |
|---|
| 678 | | default: |
|---|
| 679 | | break; |
|---|
| 680 | | } |
|---|
| 681 | | |
|---|
| 682 | | return PyState; |
|---|
| 683 | | } |
|---|
| 684 | | |
|---|
| 685 | | static void |
|---|
| 686 | | callbackBridge(cwiid_wiimote_t *wiimote, int mesg_count, |
|---|
| 687 | | union cwiid_mesg mesg[]) |
|---|
| 688 | | { |
|---|
| 689 | | PyObject *argTuple; |
|---|
| 690 | | PyObject *pyself; |
|---|
| 691 | | /* PyObject *pyCallback; */ |
|---|
| 692 | | PyGILState_STATE gstate; |
|---|
| 693 | | |
|---|
| 694 | | gstate = PyGILState_Ensure(); |
|---|
| 695 | | |
|---|
| 696 | | argTuple = processMesgs(mesg_count, mesg); |
|---|
| 697 | | |
|---|
| 698 | | /* Put id and the list of messages as the arguments to the callback */ |
|---|
| 699 | | pyself = (PyObject *) cwiid_get_data(wiimote); |
|---|
| 700 | | if (PyMethod_Check(((Wiimote *)pyself)->callback)) { |
|---|
| 701 | | /* Sorry for the ugliness here. |
|---|
| 702 | | * After determining that the callback is a method in a class, |
|---|
| 703 | | * this line calls that function object with self and the argtuple |
|---|
| 704 | | * as arguments. */ |
|---|
| 705 | | PyObject_CallFunction( |
|---|
| 706 | | PyMethod_Function(((Wiimote *)pyself)->callback),"(OO)", |
|---|
| 707 | | PyMethod_Class(((Wiimote *)pyself)->callback), argTuple |
|---|
| 708 | | ); |
|---|
| 709 | | } |
|---|
| 710 | | else { |
|---|
| 711 | | PyObject_CallFunction(((Wiimote *)pyself)->callback, |
|---|
| 712 | | "(O)",argTuple); |
|---|
| 713 | | } |
|---|
| 714 | | |
|---|
| 715 | | Py_XDECREF(argTuple); /* actually need to decref the entire structure */ |
|---|
| 716 | | PyGILState_Release(gstate); |
|---|
| 717 | | } |
|---|
| 718 | | |
|---|
| 719 | | /* This is the function responsible for marshaling the cwiid messages from |
|---|
| 720 | | * C to python. It's rather complicated since it uses a complex C union |
|---|
| 721 | | * to store the data and multiple enumerations to figure out what data is |
|---|
| 722 | | * actually being sent. Neither of these common C types really translate |
|---|
| 723 | | * well into Python. I've done my best to translate it to python as follows: |
|---|
| 724 | | * |
|---|
| 725 | | * Python callback takes arg (mesgs). The mesgs is a list of |
|---|
| 726 | | * mesg tuples which contain the mesg type and a dict of the arguments. |
|---|
| 727 | | * |
|---|
| 728 | | * Ex: |
|---|
| 729 | | * mesgs =>[(CWIID_BTN_MESG,{"buttons":btnMask}), |
|---|
| 730 | | * (CWIID_ACC_MESG,{"x":xVal, "y":yVal, "z":zVal})] |
|---|
| 731 | | */ |
|---|
| 732 | | static PyObject *processMesgs(int mesg_count, union cwiid_mesg mesg[]) |
|---|
| 733 | | { |
|---|
| 734 | | PyObject *mesglist; /* List of message tuples */ |
|---|
| 735 | | PyObject *amesg; /* A single message (type, [arguments]) */ |
|---|
| 736 | | PyObject *mesgVal; /* Dictionary of arguments for a message */ |
|---|
| 737 | | PyObject *PyIrList; |
|---|
| 738 | | int i, j; |
|---|
| 739 | | |
|---|
| 740 | | if (!(mesglist = PyList_New(mesg_count))) { |
|---|
| 741 | | return NULL; |
|---|
| 742 | | } |
|---|
| 743 | | |
|---|
| 744 | | for (i = 0; i < mesg_count; i++) { |
|---|
| 745 | | switch (mesg[i].type) { |
|---|
| 746 | | case CWIID_MESG_STATUS: |
|---|
| 747 | | mesgVal = Py_BuildValue("{s:B,s:i}", |
|---|
| 748 | | "battery", mesg[i].status_mesg.battery, |
|---|
| 749 | | "ext_type", mesg[i].status_mesg.ext_type); |
|---|
| 750 | | break; |
|---|
| 751 | | case CWIID_MESG_BTN: |
|---|
| 752 | | mesgVal = Py_BuildValue("{s:I}", |
|---|
| 753 | | "buttons", mesg[i].btn_mesg.buttons); |
|---|
| 754 | | break; |
|---|
| 755 | | case CWIID_MESG_ACC: |
|---|
| 756 | | mesgVal = Py_BuildValue("{s:{s:B,s:B,s:B}}", |
|---|
| 757 | | "acc", |
|---|
| 758 | | "x", mesg[i].acc_mesg.acc[CWIID_X], |
|---|
| 759 | | "y", mesg[i].acc_mesg.acc[CWIID_Y], |
|---|
| 760 | | "z", mesg[i].acc_mesg.acc[CWIID_Z]); |
|---|
| 761 | | break; |
|---|
| 762 | | case CWIID_MESG_IR: |
|---|
| 763 | | mesgVal = NULL; |
|---|
| 764 | | |
|---|
| 765 | | if (!(PyIrList = PyList_New(CWIID_IR_SRC_COUNT))) { |
|---|
| 766 | | break; |
|---|
| 767 | | } |
|---|
| 768 | | |
|---|
| 769 | | for (j=0; j < CWIID_IR_SRC_COUNT; j++) { |
|---|
| 770 | | PyObject *PyIrSrc; |
|---|
| 771 | | PyObject *PySize; |
|---|
| 772 | | |
|---|
| 773 | | if (mesg[i].ir_mesg.src[j].valid) { |
|---|
| 774 | | PyIrSrc = Py_BuildValue("{s:{s:I,s:I}}", |
|---|
| 775 | | "pos", |
|---|
| 776 | | "x", mesg[i].ir_mesg.src[j].pos[CWIID_X], |
|---|
| 777 | | "y", mesg[i].ir_mesg.src[j].pos[CWIID_Y]); |
|---|
| 778 | | |
|---|
| 779 | | if (!PyIrSrc) { |
|---|
| 780 | | Py_DECREF(PyIrList); |
|---|
| 781 | | PyIrList = NULL; |
|---|
| 782 | | break; |
|---|
| 783 | | } |
|---|
| 784 | | |
|---|
| 785 | | if (mesg[i].ir_mesg.src[j].size != -1) { |
|---|
| 786 | | if (!(PySize = PyInt_FromLong( |
|---|
| 787 | | (long)mesg[i].ir_mesg.src[j].size))) { |
|---|
| 788 | | Py_DECREF(PyIrList); |
|---|
| 789 | | Py_DECREF(PyIrSrc); |
|---|
| 790 | | PyIrList = NULL; |
|---|
| 791 | | break; |
|---|
| 792 | | } |
|---|
| 793 | | if (PyDict_SetItemString(PyIrSrc, "size", PySize)) { |
|---|
| 794 | | Py_DECREF(PyIrList); |
|---|
| 795 | | Py_DECREF(PyIrSrc); |
|---|
| 796 | | Py_DECREF(PySize); |
|---|
| 797 | | PyIrList = NULL; |
|---|
| 798 | | break; |
|---|
| 799 | | } |
|---|
| 800 | | |
|---|
| 801 | | Py_DECREF(PySize); |
|---|
| 802 | | } |
|---|
| 803 | | } |
|---|
| 804 | | else { |
|---|
| 805 | | Py_INCREF(PyIrSrc = Py_None); |
|---|
| 806 | | } |
|---|
| 807 | | PyList_SET_ITEM(PyIrList, j, PyIrSrc); |
|---|
| 808 | | } |
|---|
| 809 | | |
|---|
| 810 | | if (!PyIrList) { |
|---|
| 811 | | break; |
|---|
| 812 | | } |
|---|
| 813 | | |
|---|
| 814 | | mesgVal = Py_BuildValue("{s:O}", "src", PyIrList); |
|---|
| 815 | | Py_DECREF(PyIrList); |
|---|
| 816 | | break; |
|---|
| 817 | | case CWIID_MESG_NUNCHUK: |
|---|
| 818 | | mesgVal = Py_BuildValue("{s:{s:B,s:B},s:{s:B,s:B,s:B},s:I}", |
|---|
| 819 | | "stick", |
|---|
| 820 | | "x", mesg[i].nunchuk_mesg.stick[CWIID_X], |
|---|
| 821 | | "y", mesg[i].nunchuk_mesg.stick[CWIID_Y], |
|---|
| 822 | | "acc", |
|---|
| 823 | | "x", mesg[i].nunchuk_mesg.acc[CWIID_X], |
|---|
| 824 | | "y", mesg[i].nunchuk_mesg.acc[CWIID_Y], |
|---|
| 825 | | "z", mesg[i].nunchuk_mesg.acc[CWIID_Z], |
|---|
| 826 | | "buttons", mesg[i].nunchuk_mesg.buttons); |
|---|
| 827 | | break; |
|---|
| 828 | | case CWIID_MESG_CLASSIC: |
|---|
| 829 | | mesgVal = Py_BuildValue("{s:{s:B,s:B},s:{s:B,s:B},s:B,s:B,s:I}", |
|---|
| 830 | | "l_stick", |
|---|
| 831 | | "x", mesg[i].classic_mesg.l_stick[CWIID_X], |
|---|
| 832 | | "y", mesg[i].classic_mesg.l_stick[CWIID_Y], |
|---|
| 833 | | "r_stick", |
|---|
| 834 | | "x", mesg[i].classic_mesg.r_stick[CWIID_X], |
|---|
| 835 | | "y", mesg[i].classic_mesg.r_stick[CWIID_Y], |
|---|
| 836 | | "l", mesg[i].classic_mesg.l, |
|---|
| 837 | | "r", mesg[i].classic_mesg.r, |
|---|
| 838 | | "buttons", mesg[i].classic_mesg.buttons); |
|---|
| 839 | | break; |
|---|
| 840 | | case CWIID_MESG_ERROR: |
|---|
| 841 | | mesgVal = Py_BuildValue("{s:i}", |
|---|
| 842 | | "error",mesg[i].error_mesg.error); |
|---|
| 843 | | break; |
|---|
| 844 | | default: |
|---|
| 845 | | Py_INCREF(mesgVal = Py_None); |
|---|
| 846 | | break; |
|---|
| 847 | | } |
|---|
| 848 | | |
|---|
| 849 | | if (!mesgVal) { |
|---|
| 850 | | return NULL; |
|---|
| 851 | | } |
|---|
| 852 | | |
|---|
| 853 | | /* Finally Put the type next to the message in a tuple and |
|---|
| 854 | | * append them to the list of messages */ |
|---|
| 855 | | if (!(amesg = Py_BuildValue("(iO)", mesg[i].type, mesgVal))) { |
|---|
| 856 | | Py_DECREF(mesgVal); |
|---|
| 857 | | return NULL; |
|---|
| 858 | | } |
|---|
| 859 | | Py_DECREF(mesgVal); |
|---|
| 860 | | PyList_SET_ITEM(mesglist, i, amesg); |
|---|
| 861 | | } |
|---|
| 862 | | |
|---|
| 863 | | return mesglist; |
|---|
| 864 | | } |
|---|