Changeset 124 for branches/dev
- Timestamp:
- 06/05/07 19:14:45 (1 year ago)
- Files:
-
- branches/dev/ChangeLog (modified) (1 diff)
- branches/dev/wminput/Makefile.in (modified) (1 diff)
- branches/dev/wminput/c_plugin.c (added)
- branches/dev/wminput/c_plugin.h (added)
- branches/dev/wminput/conf.c (modified) (11 diffs)
- branches/dev/wminput/conf.h (modified) (2 diffs)
- branches/dev/wminput/main.c (modified) (14 diffs)
- branches/dev/wminput/py_plugin.c (moved) (moved from branches/dev/wminput/pyplugin.c) (12 diffs)
- branches/dev/wminput/py_plugin.h (moved) (moved from branches/dev/wminput/pyplugin.h) (1 diff)
- branches/dev/wminput/util.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dev/ChangeLog
r123 r124 5 5 * overloaded Wiimote.init to accept CObject (existing wiimote), 6 6 and logic to avoid closing it on dealloc 7 8 wminput 9 * refactored to isolate plugin logic 10 * now imports python plugins without changing directories 7 11 8 12 2007-06-01 Nick <nickishappy@gmail.com> branches/dev/wminput/Makefile.in
r120 r124 5 5 APP_NAME = wminput 6 6 7 SOURCES = main.c conf.c pyplugin.c uinput.c action_enum.c parser.c lexer.c util.c 7 SOURCES = main.c conf.c c_plugin.c py_plugin.c uinput.c action_enum.c parser.c \ 8 lexer.c util.c 8 9 9 10 WMINPUT_CONFIG_DIR = $(CWIID_CONFIG_DIR)/wminput branches/dev/wminput/conf.c
r121 r124 16 16 * 17 17 * ChangeLog: 18 * 2007-06-05 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * refactored to isolate plugin logic 20 * 18 21 * 2007-06-03 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * fixed plugin->data malloc bug … … 35 38 */ 36 39 37 #include "Python.h"38 39 40 #include <stdint.h> 40 41 #include <stdio.h> … … 42 43 #include <string.h> 43 44 44 #include <sys/types.h>45 #include <sys/stat.h>46 #include <dlfcn.h>47 #include <unistd.h>48 49 45 #include "conf.h" 50 46 #include "util.h" 51 47 #include "y.tab.h" 52 #include "pyplugin.h" 48 #include "c_plugin.h" 49 #include "py_plugin.h" 53 50 54 51 extern FILE *yyin; … … 97 94 switch (conf->plugins[i].type) { 98 95 case PLUGIN_C: 99 dlclose(conf->plugins[i].handle);96 c_plugin_close(&conf->plugins[i]); 100 97 break; 101 98 case PLUGIN_PYTHON: 102 free(conf->plugins[i].info); 103 free(conf->plugins[i].data); 104 Py_DECREF((PyObject *)conf->plugins[i].PyInfo); 105 Py_DECREF((PyObject *)conf->plugins[i].init); 106 Py_DECREF((PyObject *)conf->plugins[i].exec); 107 Py_DECREF((PyObject *)conf->plugins[i].handle); 99 py_plugin_close(&conf->plugins[i]); 108 100 break; 109 101 } 110 }111 else {112 break;113 102 } 114 103 } … … 331 320 int i; 332 321 unsigned char param_found = 0; 333 PyObject *PyObj;334 322 335 323 if ((plugin = get_plugin(conf, name)) == NULL) { … … 351 339 switch (plugin->type) { 352 340 case PLUGIN_C: 353 switch (plugin->info->param_info[i].type) { 354 case WMPLUGIN_PARAM_INT: 355 *(int *)plugin->info->param_info[i].ptr = value; 356 break; 357 case WMPLUGIN_PARAM_FLOAT: 358 *(float *)plugin->info->param_info[i].ptr = value; 359 break; 360 default: 361 wminput_err("unknown parameter type: %s.%s", name, param); 341 if (c_plugin_param_int(plugin, i, value)) { 362 342 return -1; 363 break;364 }343 } 344 break; 365 345 case PLUGIN_PYTHON: 366 switch (plugin->info->param_info[i].type) { 367 case WMPLUGIN_PARAM_INT: 368 PyObj = PyInt_FromLong(value); 369 if (PyObject_SetAttrString(plugin->handle, 370 plugin->info->param_info[i].name, 371 PyObj)) { 372 PyErr_Print(); 373 return -1; 374 } 375 break; 376 case WMPLUGIN_PARAM_FLOAT: 377 PyObj = PyFloat_FromDouble((double)value); 378 if (PyObject_SetAttrString(plugin->handle, 379 plugin->info->param_info[i].name, 380 PyObj)) { 381 PyErr_Print(); 382 return -1; 383 } 384 break; 385 default: 386 wminput_err("unknown parameter type: %s.%s", name, param); 346 if (py_plugin_param_int(plugin, i, value)) { 387 347 return -1; 388 break;389 }348 } 349 break; 390 350 } 391 351 … … 399 359 int i; 400 360 unsigned char param_found = 0; 401 PyObject *PyObj;402 361 403 362 if ((plugin = get_plugin(conf, name)) == NULL) { … … 419 378 switch (plugin->type) { 420 379 case PLUGIN_C: 421 switch (plugin->info->param_info[i].type) { 422 case WMPLUGIN_PARAM_INT: 423 wminput_err("possible loss of precision: %s.%s " 424 "(cast float to int)", name, param); 425 *(int *)plugin->info->param_info[i].ptr = value; 426 break; 427 case WMPLUGIN_PARAM_FLOAT: 428 *(float *)plugin->info->param_info[i].ptr = value; 429 break; 430 default: 431 wminput_err("unknown parameter type: %s.%s", name, param); 380 if (c_plugin_param_float(plugin, i, value)) { 432 381 return -1; 433 break;434 }382 } 383 break; 435 384 case PLUGIN_PYTHON: 436 switch (plugin->info->param_info[i].type) { 437 case WMPLUGIN_PARAM_INT: 438 wminput_err("possible loss of precision: %s.%s " 439 "(cast float to int)", name, param); 440 PyObj = PyInt_FromLong((int)value); 441 if (PyObject_SetAttrString(plugin->handle, 442 plugin->info->param_info[i].name, 443 PyObj)) { 444 PyErr_Print(); 445 return -1; 446 } 447 break; 448 case WMPLUGIN_PARAM_FLOAT: 449 PyObj = PyFloat_FromDouble((double)value); 450 if (PyObject_SetAttrString(plugin->handle, 451 plugin->info->param_info[i].name, 452 PyObj)) { 453 PyErr_Print(); 454 return -1; 455 } 456 break; 457 default: 458 wminput_err("unknown parameter type: %s.%s", name, param); 385 if (py_plugin_param_float(plugin, i, value)) { 459 386 return -1; 460 break;461 }387 } 388 break; 462 389 } 463 390 … … 536 463 for (i=0; i < CONF_MAX_PLUGINS; i++) { 537 464 conf->plugins[i].name = NULL; 538 conf->plugins[i].PyInfo = NULL;539 465 conf->plugins[i].rpt_mode_flags = 0; 540 466 conf->plugins[i].prev_buttons = 0; … … 639 565 } 640 566 641 #define PLUGIN_PATHNAME_LEN 128642 567 struct plugin *get_plugin(struct conf *conf, const char *name) 643 568 { 644 569 int i; 645 char p athname[PLUGIN_PATHNAME_LEN];570 char plugin_found = 0; 646 571 struct plugin *plugin; 647 struct stat buf; 648 void *info; 649 650 /* TODO: replace PyErr_Print with wminput_err */ 572 651 573 for (i=0; i < CONF_MAX_PLUGINS; i++) { 652 574 if (!conf->plugins[i].name) { … … 662 584 return NULL; 663 585 } 664 else { 665 plugin = &conf->plugins[i]; 666 plugin->name = (char *)name; 667 668 for (i=0; conf->plugin_search_dirs[i]; i++) { 669 snprintf(pathname, PLUGIN_PATHNAME_LEN, "%s/%s.so", 670 conf->plugin_search_dirs[i], name); 671 if (!stat(pathname, &buf)) { 672 if (!(plugin->handle = dlopen(pathname, RTLD_NOW))) { 673 wminput_err(dlerror()); 674 } 675 else { 676 plugin->type = PLUGIN_C; 677 } 678 break; 679 } 680 if (!chdir(conf->plugin_search_dirs[i])) { 681 if ((plugin->handle = PyImport_ImportModule((char *)name))) { 682 plugin->type = PLUGIN_PYTHON; 683 break; 684 } 685 else { 686 /* TODO: print only syntax errors, not "module not found errors" */ 687 PyErr_Print(); 688 } 689 /* TODO: restore directory */ 690 } 691 } 692 693 if (!plugin->handle) { 694 wminput_err("plugin not found: %s", name); 695 free(plugin->name); 696 plugin->name = NULL; 697 return NULL; 698 } 699 700 switch (plugin->type) { 701 case PLUGIN_C: 702 if (!(info = dlsym(plugin->handle, "wmplugin_info"))) { 703 wminput_err("Unable to load plugin info function: %s", 704 dlerror()); 705 free(plugin->name); 706 plugin->name = NULL; 707 dlclose(plugin->handle); 708 return NULL; 709 } 710 if (!(plugin->info = (*(wmplugin_info_t *)info)())) { 711 wminput_err("Invalid plugin info from %s", plugin->name); 712 free(plugin->name); 713 plugin->name = NULL; 714 dlclose(plugin->handle); 715 return NULL; 716 } 717 if (!(plugin->init = dlsym(plugin->handle, "wmplugin_init"))) { 718 wminput_err("Unable to load plugin init function: %s", 719 dlerror()); 720 free(plugin->name); 721 plugin->name = NULL; 722 dlclose(plugin->handle); 723 return NULL; 724 } 725 if (!(plugin->exec = dlsym(plugin->handle, "wmplugin_exec"))) { 726 wminput_err("Unable to load plugin exec function: %s", 727 dlerror()); 728 free(plugin->name); 729 plugin->name = NULL; 730 dlclose(plugin->handle); 731 return NULL; 732 } 586 587 plugin = &conf->plugins[i]; 588 plugin->name = (char *)name; 589 590 for (i=0; conf->plugin_search_dirs[i]; i++) { 591 if (!c_plugin_open(plugin, conf->plugin_search_dirs[i])) { 592 plugin_found = 1; 733 593 break; 734 case PLUGIN_PYTHON: 735 if (!(info = PyObject_GetAttrString(plugin->handle, 736 "wmplugin_info"))) { 737 PyErr_Print(); 738 Py_DECREF((PyObject *)plugin->handle); 739 free(plugin->name); 740 plugin->name = NULL; 741 return NULL; 742 } 743 if (!PyCallable_Check(info)) { 744 wminput_err("Unable to load plugin info function: " 745 "not callable"); 746 Py_DECREF((PyObject *)info); 747 Py_DECREF((PyObject *)plugin->handle); 748 free(plugin->name); 749 plugin->name = NULL; 750 return NULL; 751 } 752 if (!(plugin->init = PyObject_GetAttrString(plugin->handle, 753 "wmplugin_init"))) { 754 PyErr_Print(); 755 Py_DECREF((PyObject *)info); 756 Py_DECREF((PyObject *)plugin->handle); 757 free(plugin->name); 758 plugin->name = NULL; 759 return NULL; 760 } 761 if (!PyCallable_Check(plugin->init)) { 762 wminput_err("Unable to load plugin init function: " 763 "not callable"); 764 Py_DECREF((PyObject *)info); 765 Py_DECREF((PyObject *)plugin->init); 766 Py_DECREF((PyObject *)plugin->handle); 767 free(plugin->name); 768 plugin->name = NULL; 769 return NULL; 770 } 771 if (!(plugin->exec = PyObject_GetAttrString(plugin->handle, 772 "wmplugin_exec"))) { 773 PyErr_Print(); 774 Py_DECREF((PyObject *)info); 775 Py_DECREF((PyObject *)plugin->init); 776 Py_DECREF((PyObject *)plugin->handle); 777 free(plugin->name); 778 plugin->name = NULL; 779 return NULL; 780 } 781 if (!PyCallable_Check(plugin->exec)) { 782 wminput_err("Unable to load plugin exec function: " 783 "not callable"); 784 Py_DECREF((PyObject *)info); 785 Py_DECREF((PyObject *)plugin->init); 786 Py_DECREF((PyObject *)plugin->exec); 787 Py_DECREF((PyObject *)plugin->handle); 788 free(plugin->name); 789 plugin->name = NULL; 790 return NULL; 791 } 792 if (python_info(info, plugin)) { 793 wminput_err("python_info error"); 794 Py_DECREF((PyObject *)info); 795 Py_DECREF((PyObject *)plugin->init); 796 Py_DECREF((PyObject *)plugin->exec); 797 Py_DECREF((PyObject *)plugin->handle); 798 free(plugin->name); 799 plugin->name = NULL; 800 return NULL; 801 } 802 if (!(plugin->data = malloc(sizeof *plugin->data))) { 803 wminput_err("malloc error"); 804 Py_DECREF((PyObject *)info); 805 Py_DECREF((PyObject *)plugin->init); 806 Py_DECREF((PyObject *)plugin->exec); 807 Py_DECREF((PyObject *)plugin->handle); 808 free(plugin->name); 809 plugin->name = NULL; 810 return NULL; 811 } 812 Py_DECREF((PyObject *)info); 594 } 595 if (!py_plugin_open(plugin, conf->plugin_search_dirs[i])) { 596 plugin_found = 1; 813 597 break; 814 598 } 815 599 } 816 600 601 if (!plugin_found) { 602 wminput_err("plugin not found: %s", name); 603 free(plugin->name); 604 plugin->name = NULL; 605 return NULL; 606 } 607 817 608 return plugin; 818 609 } branches/dev/wminput/conf.h
r118 r124 16 16 * 17 17 * ChangeLog: 18 * 2007-06-05 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * refactored to isolate plugin logic 20 * 18 21 * 2007-06-01 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * added python plugin support … … 143 146 struct plugin { 144 147 char *name; 148 enum plugin_type type; 149 uint8_t rpt_mode_flags; 145 150 struct wmplugin_info *info; 146 151 struct wmplugin_data *data; 147 void *PyInfo;148 enum plugin_type type;149 void *handle;150 void *init;151 void *exec;152 uint8_t rpt_mode_flags;153 152 uint16_t prev_buttons; 154 153 struct btn_map bmap[WMPLUGIN_MAX_BUTTON_COUNT]; 155 154 struct axis_map amap[WMPLUGIN_MAX_AXIS_COUNT]; 155 void *p; 156 156 }; 157 157 branches/dev/wminput/main.c
r120 r124 16 16 * 17 17 * ChangeLog: 18 * 2007-06-05 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * refactored to isolate plugin logic 20 * 18 21 * 2007-06-01 Nick <nickishappy@gmail.com> 19 22 * * reworked command-line options (added standard options, long options) … … 44 47 */ 45 48 46 #include "Python.h"47 48 49 #include <stdint.h> 49 50 #include <stdio.h> … … 61 62 #include "util.h" 62 63 #include "wmplugin.h" 63 #include "pyplugin.h" 64 #include "c_plugin.h" 65 #include "py_plugin.h" 64 66 65 67 struct conf conf; … … 75 77 /* Globals */ 76 78 cwiid_wiimote_t *wiimote; 77 PyObject *PyCWiidModule;78 PyObject *PyWiimote;79 static PyObject *(*ConvertMesgArray)(int, union cwiid_mesg[]);80 79 char init; 81 80 … … 110 109 struct uinput_listen_data uinput_listen_data; 111 110 pthread_t uinput_listen_thread; 112 PyObject *PyCObj;113 PyObject *(*Wiimote_FromC)(cwiid_wiimote_t *);114 111 115 112 init = 1; … … 158 155 } 159 156 160 /* Python Init */ 161 /* TODO: DECREF global objects and finalize on error and exit */ 162 Py_Initialize(); 163 if (initwmplugin()) { 164 return -1; 165 } 166 PyRun_SimpleString("import sys; sys.path.append('.')"); 167 if (!(PyCWiidModule = PyImport_ImportModule("cwiid"))) { 168 PyErr_Print(); 169 return -1; 170 } 171 172 if (!(PyCObj = PyObject_GetAttrString(PyCWiidModule, "Wiimote_FromC"))) { 173 PyErr_Print(); 174 return -1; 175 } 176 Wiimote_FromC = PyCObject_AsVoidPtr(PyCObj); 177 178 if (!(PyCObj = PyObject_GetAttrString(PyCWiidModule, 179 "ConvertMesgArray"))) { 180 PyErr_Print(); 181 return -1; 182 } 183 ConvertMesgArray = PyCObject_AsVoidPtr(PyCObj); 157 if (c_init()) { 158 return -1; 159 } 160 if (py_init()) { 161 return -1; 162 } 184 163 185 164 /* Load Config */ 165 /* Setup search directory arrays */ 186 166 if ((tmp = getenv("HOME")) == NULL) { 187 167 wminput_err("unable to find home directory"); … … 205 185 } 206 186 207 /* BDADDR */ 187 /* Determine BDADDR */ 188 /* priority: command-line option, environment variable, BDADDR_ANY */ 208 189 if (optind < argc) { 209 190 if (str2ba(argv[optind], &bdaddr)) { … … 229 210 } 230 211 231 /* Wiimote connect */ 212 /* TODO: fix wait_forever logic - currently assumes bdaddr is unspecified */ 213 /* Wiimote Connect */ 232 214 printf("Put Wiimote in discoverable mode now (press 1+2)...\n"); 233 215 if (wait_forever) { … … 249 231 } 250 232 251 if (!(PyWiimote = Wiimote_FromC(wiimote))) { 252 PyErr_Print(); 233 if (c_wiimote(wiimote)) { 234 conf_unload(&conf); 235 return -1; 236 } 237 if (py_wiimote(wiimote)) { 253 238 conf_unload(&conf); 254 239 return -1; … … 259 244 switch (conf.plugins[i].type) { 260 245 case PLUGIN_C: 261 if ( (*(wmplugin_init_t *)conf.plugins[i].init)(i, wiimote)) {246 if (c_plugin_init(&conf.plugins[i], i)) { 262 247 wminput_err("error on %s init", conf.plugins[i].name); 263 248 conf_unload(&conf); … … 267 252 break; 268 253 case PLUGIN_PYTHON: 269 if (py thon_init(&conf.plugins[i], i, PyWiimote)) {254 if (py_plugin_init(&conf.plugins[i], i)) { 270 255 wminput_err("error %s init", conf.plugins[i].name); 271 256 conf_unload(&conf); … … 327 312 } 328 313 314 py_deinit(); 315 329 316 return ret; 317 } 318 319 int wminput_set_report_mode() 320 { 321 unsigned char rpt_mode_flags; 322 int i; 323 324 rpt_mode_flags = conf.rpt_mode_flags; 325 326 for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) { 327 rpt_mode_flags |= conf.plugins[i].rpt_mode_flags; 328 } 329 330 if (cwiid_set_rpt_mode(wiimote, rpt_mode_flags)) { 331 wminput_err("error setting report mode"); 332 return -1; 333 } 334 335 return 0; 330 336 } 331 337 … … 336 342 if (!init) { 337 343 wminput_set_report_mode(); 338 }339 340 return 0;341 }342 343 int wminput_set_report_mode()344 {345 unsigned char rpt_mode_flags;346 int i;347 348 rpt_mode_flags = conf.rpt_mode_flags;349 350 for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) {351 rpt_mode_flags |= conf.plugins[i].rpt_mode_flags;352 }353 354 if (cwiid_set_rpt_mode(wiimote, rpt_mode_flags)) {355 wminput_err("error setting report mode");356 return -1;357 344 } 358 345 … … 646 633 switch (plugin->type) { 647 634 case PLUGIN_C: 648 if (!(plugin->data = 649 (*(wmplugin_exec_t *)plugin->exec)(plugin_mesg_count, 650 plugin_mesg))) { 635 if (c_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) { 651 636 return; 652 637 } 653 638 break; 654 639 case PLUGIN_PYTHON: 655 if (python_exec(plugin, ConvertMesgArray, plugin_mesg_count, 656 plugin_mesg)) { 640 if (py_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) { 657 641 return; 658 642 } branches/dev/wminput/py_plugin.c
r121 r124 16 16 * 17 17 * ChangeLog: 18 * 2007-06-05 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * relocated all python plugin logic here 20 * * now imports plugins without changing directories 21 * 18 22 * 2007-06-03 L. Donnie Smith <cwiid@abstrakraft.org> 19 23 * * added WMPLUGIN_ABS and WMPLUGIN_REL constants … … 28 32 #include <stdlib.h> 29 33 34 #include <unistd.h> 35 30 36 #include "structmember.h" 31 37 #include "cwiid.h" … … 37 43 /* TODO: print error messages */ 38 44 /* TODO: improve error checking */ 39 static PyObject *set_rpt_mode(PyObject *self, PyObject *args, PyObject *kwds) 40 { 41 static char *kwlist[] = {"id", "rpt_mode", NULL}; 42 int id, rpt_mode; 43 44 if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii:wmplugin:set_rpt_mode", 45 kwlist, &id, &rpt_mode)) { 46 return NULL; 47 } 48 49 if (wmplugin_set_rpt_mode(id, rpt_mode)) { 50 return NULL; 51 } 52 53 Py_RETURN_NONE; 54 } 55 56 /* CWiid constants, enumerations */ 45 46 struct py_plugin { 47 PyObject *PyInfo; 48 PyObject *handle; 49 PyObject *init; 50 PyObject *exec; 51 }; 52 53 static PyObject *PyCWiidModule = NULL; 54 static PyObject *PySysModule = NULL; 55 static PyObject *PyPath = NULL; 56 static PyObject *PyWiimote = NULL; 57 static PyObject *(*ConvertMesgArray)(int, union cwiid_mesg[]); 58 59 static int py_plugin_info(struct plugin *, PyObject *); 60 static PyObject *set_rpt_mode(PyObject *, PyObject *, PyObject *); 61 57 62 #define WMPLUGIN_CONST_MACRO(a) {#a, WMPLUGIN_##a} 58 63 static struct { … … 67 72 }; 68 73 69 /* Associates cwiid functions with python ones */70 74 static PyMethodDef Module_Methods[] = 71 75 { … … 75 79 }; 76 80 77 int initwmplugin(void)78 { 79 PyObject * Module;81 int py_init(void) 82 { 83 PyObject *PyObj, *PyWmPluginModule; 80 84 int i; 81 85 82 if (!(Module = Py_InitModule3("wmplugin", Module_Methods, 83 "plugin interface for wminput"))) { 84 PyErr_Print(); 85 return -1; 86 Py_Initialize(); 87 88 if (!(PyCWiidModule = PyImport_ImportModule("cwiid"))) { 89 PyErr_Print(); 90 goto ERR_HND; 91 } 92 93 if (!(PySysModule = PyImport_ImportModule("sys"))) { 94 PyErr_Print(); 95 goto ERR_HND; 96 } 97 98 if (!(PyPath = PyObject_GetAttrString(PySysModule, "path"))) { 99 PyErr_Print(); 100 goto ERR_HND; 101 } 102 103 if (!(PyObj = PyObject_GetAttrString(PyCWiidModule, 104 "ConvertMesgArray"))) { 105 PyErr_Print(); 106 goto ERR_HND; 107 } 108 ConvertMesgArray = PyCObject_AsVoidPtr(PyObj); 109 Py_DECREF(PyObj); 110 111 /* note: PyWmPluginModule is a borrowed reference - do not decref */ 112 if (!(PyWmPluginModule = Py_InitModule3("wmplugin", Module_Methods, 113 "plugin interface for wminput"))) { 114 PyErr_Print(); 115 goto ERR_HND; 86 116 } 87 117 88 118 for (i = 0; wmplugin_constants[i].name; i++) { 89 if (PyModule_AddIntConstant(Module, wmplugin_constants[i].name, 119 if (PyModule_AddIntConstant(PyWmPluginModule, 120 wmplugin_constants[i].name, 90 121 wmplugin_constants[i].value)) { 91 122 PyErr_Print(); 92 return -1; 93 } 94 } 95 96 return 0; 97 } 98 99 int python_info(PyObject *Info, struct plugin *plugin) 123 goto ERR_HND; 124 } 125 } 126 127 PyRun_SimpleString("import sys; sys.path.append('.')"); 128 129 return 0; 130 131 ERR_HND: 132 if (PyCWiidModule) { 133 Py_DECREF(PyCWiidModule); 134 PyCWiidModule = NULL; 135 } 136 137 if (PyPath) { 138 Py_DECREF(PyPath); 139 PyPath = NULL; 140 } 141 142 if (PySysModule) { 143 Py_DECREF(PySysModule); 144 PySysModule = NULL; 145 } 146 147 Py_Finalize(); 148 149 return -1; 150 } 151 152 int py_wiimote(cwiid_wiimote_t *wiimote) 153 { 154 PyObject *PyWiimoteType, *PyCObject, *PyArgs; 155 156 if (!(PyWiimoteType = PyObject_GetAttrString(PyCWiidModule, "Wiimote"))) { 157 PyErr_Print(); 158 return -1; 159 } 160 161 if (!(PyCObject = PyCObject_FromVoidPtr(wiimote, NULL))) { 162 PyErr_Print(); 163 Py_DECREF(PyWiimoteType); 164 return -1; 165 } 166 167 if (!(PyArgs = Py_BuildValue("(O)", PyCObject))) { 168 PyErr_Print(); 169 Py_DECREF(PyCObject); 170 Py_DECREF(PyWiimoteType); 171 return -1; 172 } 173 174 Py_DECREF(PyCObject); 175 176 if (!(PyWiimote = PyObject_CallObject(PyWiimoteType, PyArgs))) { 177 PyErr_Print(); 178 Py_DECREF(PyArgs); 179 Py_DECREF(PyWiimoteType); 180 return -1; 181 } 182 183 Py_DECREF(PyArgs); 184 Py_DECREF(PyWiimoteType); 185 186 return 0; 187 } 188 189 void py_deinit(void) 190 { 191 Py_DECREF(PyWiimote); 192 Py_DECREF(PyCWiidModule); 193 Py_DECREF(PyPath); 194 Py_DECREF(PySysModule); 195 Py_Finalize(); 196 } 197 198 int py_plugin_open(struct plugin *plugin, char *dir) 199 { 200 PyObject *handle, *info; 201 PyObject *PyStr; 202 203 if (!(PyStr = PyString_FromString(dir))) { 204 PyErr_Print(); 205 return -1; 206 } 207 208 if (PyList_Insert(PyPath, 0, PyStr)) { 209 Py_DECREF(PyStr); 210 return -1; 211 } 212 213 if (!(handle = PyImport_ImportModule(plugin->name))) { 214 /* TODO: print only syntax errors, not "module not found errors" */ 215 PyErr_Print(); 216 if (PySequence_DelItem(PyPath, 0)) { 217 PyErr_Print(); 218 } 219 Py_DECREF(PyStr); 220 return -1; 221 } 222 223 if (PySequence_DelItem(PyPath, 0)) { 224 PyErr_Print(); 225 } 226 Py_DECREF(PyStr); 227 228 if (!(plugin->p = malloc(sizeof(struct py_plugin)))) { 229 wminput_err("malloc error"); 230 return -1; 231 } 232 233 plugin->type = PLUGIN_PYTHON; 234 plugin->info = NULL; 235 plugin->data = NULL; 236 ((struct py_plugin *) plugin->p)->init = NULL; 237 ((struct py_plugin *) plugin->p)->exec = NULL; 238 239 if (!(plugin->info = malloc(sizeof *plugin->info))) { 240 wminput_err("malloc error"); 241 goto ERR_HND; 242 } 243 if (!(plugin->data = malloc(sizeof *plugin->data))) { 244 wminput_err("malloc error"); 245 goto ERR_HND; 246 } 247 if (!(((struct py_plugin *)plugin->p)->init = 248 PyObject_GetAttrString(handle, "wmplugin_init"))) { 249 PyErr_Print(); 250 goto ERR_HND; 251 } 252 if (!PyCallable_Check(((struct py_plugin *)plugin->p)->init)) { 253 wminput_err("Unable to load plugin init function: not callable"); 254 goto ERR_HND; 255 } 256 if (!(((struct py_plugin *)plugin->p)->exec = 257 PyObject_GetAttrString(handle, "wmplugin_exec"))) { 258 PyErr_Print(); 259 goto ERR_HND; 260 } 261 if (!PyCallable_Check(((struct py_plugin *)plugin->p)->exec)) { 262 wminput_err("Unable to load plugin exec function:
