root/branches/dev/wminput/main.c

Revision 124, 17.4 kB (checked in by dsmith, 2 years ago)

wminput plugin refactoring

Line 
1 /* Copyright (C) 2007 L. Donnie Smith <wiimote@abstrakraft.org>
2  *
3  *  This program is free software; you can redistribute it and/or modify
4  *  it under the terms of the GNU General Public License as published by
5  *  the Free Software Foundation; either version 2 of the License, or
6  *  (at your option) any later version.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16  *
17  *  ChangeLog:
18  *  2007-06-05 L. Donnie Smith <cwiid@abstrakraft.org>
19  *  * refactored to isolate plugin logic
20  *
21  *  2007-06-01 Nick <nickishappy@gmail.com>
22  *  * reworked command-line options (added standard options, long options)
23  *
24  *  2007-06-01 L. Donnie Smith <cwiid@abstrakraft.org>
25  *  * added python plugin support
26  *  * pass mesg instead of &mesg to wmplugin_exec
27  *
28  *  2007-05-16 L. Donnie Smith <cwiid@abstrakraft.org>
29  *  * changed cwiid_{connect,disconnect,command} to
30  *    cwiid_{open,close,request_status|set_led|set_rumble|set_rpt_mode}
31  *
32  *  2007-05-14 L. Donnie Smith <cwiid@abstrakraft.org>
33  *  * added timestamp to message callback
34  *
35  *  2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org>
36  *  * update for API overhaul
37  *
38  *  2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org>
39  *  * updated for libcwiid rename
40  *
41  *  2007-04-04 L. Donnie Smith <cwiid@abstrakraft.org>
42  *  * exit on cwiid_error
43  *
44  *  2007-03-03 L. Donnie Smith <cwiid@abstrakraft.org>
45  *  * Initial ChangeLog
46  *  * type audit (stdint, const, char booleans)
47  */
48
49 #include <stdint.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <getopt.h>
53
54 #include <pthread.h>
55 #include <signal.h>
56 #include <sys/types.h>
57 #include <unistd.h>
58
59 #include <cwiid.h>
60
61 #include "conf.h"
62 #include "util.h"
63 #include "wmplugin.h"
64 #include "c_plugin.h"
65 #include "py_plugin.h"
66
67 struct conf conf;
68
69 /* Prototypes */
70 cwiid_mesg_callback_t cwiid_callback;
71 int wminput_set_report_mode();
72 void process_btn_mesg(struct cwiid_btn_mesg *mesg);
73 void process_nunchuk_mesg(struct cwiid_nunchuk_mesg *mesg);
74 void process_classic_mesg(struct cwiid_classic_mesg *mesg);
75 void process_plugin(struct plugin *, int, union cwiid_mesg []);
76
77 /* Globals */
78 cwiid_wiimote_t *wiimote;
79 char init;
80
81 #define DEFAULT_CONFIG_FILE     "default"
82
83 #define HOME_DIR_LEN    128
84
85 void print_usage(void)
86 {
87         printf("wminput is a program that allows you to use a wiimote as a standard input device\n");
88         printf("Usage: %s [OPTIONS]...\n\n", "wminput");
89         printf("Options:\n");
90         printf("\t-h, --help\t\tPrints this output.\n");
91         printf("\t-v, --version\t\toutput version information and exit.\n");
92         printf("\t-c, --config [file]\tChoose config file to use.\n");
93         printf("\t-w, --wait\t\tWait indefinitely for wiimote to connect.\n");
94 }
95
96 int main(int argc, char *argv[])
97 {
98         char wait_forever = 0;
99         char *config_search_dirs[3], *plugin_search_dirs[3];
100         char *config_filename = DEFAULT_CONFIG_FILE;
101         char home_config_dir[HOME_DIR_LEN];
102         char home_plugin_dir[HOME_DIR_LEN];
103         char *tmp;
104         int c, i;
105         char *str_addr;
106         bdaddr_t bdaddr;
107         sigset_t sigset;
108         int signum, ret=0;
109         struct uinput_listen_data uinput_listen_data;
110         pthread_t uinput_listen_thread;
111
112         init = 1;
113
114         /* Parse Options */
115         while (1) {
116                 int option_index = 0;
117
118                 static struct option long_options[] = {
119                         {"help", 0, 0, 'h'},
120                         {"wait", 0, 0, 'w'},
121                         {"config", 1, 0, 'c'},
122                         {"version", 0, 0, 'v'},
123                         {0, 0, 0, 0}
124                 };
125
126                 c = getopt_long (argc, argv, "hwc:v", long_options, &option_index);
127
128                 if (c == -1) {
129                         break;
130                 }
131
132                 switch (c) {
133                 case 'h':
134                         print_usage();
135                         return 0;
136                         break;
137                 case 'w':
138                         wait_forever = 1;
139                         break;
140                 case 'c':
141                         config_filename = optarg;
142                         break;
143                 case 'v':
144                         printf("CWiid Version %s\n", CWIID_VERSION);
145                         return 0;
146                         break;
147                 case '?':
148                         printf("Try `wminput --help` for more information\n");
149                         return 1;
150                         break;
151                 default:
152                         return -1;
153                         break;
154                 }
155         }
156
157         if (c_init()) {
158                 return -1;
159         }
160         if (py_init()) {
161                 return -1;
162         }
163
164         /* Load Config */
165         /* Setup search directory arrays */
166         if ((tmp = getenv("HOME")) == NULL) {
167                 wminput_err("unable to find home directory");
168                 config_search_dirs[0] = WMINPUT_CONFIG_DIR;
169                 plugin_search_dirs[0] = CWIID_PLUGINS_DIR;
170                 config_search_dirs[1] = plugin_search_dirs[1] = NULL;
171         }
172         else {
173                 snprintf(home_config_dir, HOME_DIR_LEN, "%s/.cwiid/wminput", tmp);
174                 snprintf(home_plugin_dir, HOME_DIR_LEN, "%s/.cwiid/plugins", tmp);
175                 config_search_dirs[0] = home_config_dir;
176                 plugin_search_dirs[0] = home_plugin_dir;
177                 config_search_dirs[1] = WMINPUT_CONFIG_DIR;
178                 plugin_search_dirs[1] = CWIID_PLUGINS_DIR;
179                 config_search_dirs[2] = plugin_search_dirs[2] = NULL;
180         }
181
182         if (conf_load(&conf, config_filename, config_search_dirs,
183           plugin_search_dirs)) {
184                 return -1;
185         }
186
187         /* Determine BDADDR */
188         /* priority: command-line option, environment variable, BDADDR_ANY */
189         if (optind < argc) {
190                 if (str2ba(argv[optind], &bdaddr)) {
191                         wminput_err("invalid bdaddr");
192                         bdaddr = *BDADDR_ANY;
193                 }
194                 optind++;
195                 if (optind < argc) {
196                         wminput_err("invalid command-line");
197                         print_usage();
198                         conf_unload(&conf);
199                         return -1;
200                 }
201         }
202         else if ((str_addr = getenv(WIIMOTE_BDADDR)) != NULL) {
203                 if (str2ba(str_addr, &bdaddr)) {
204                         wminput_err("invalid address in %s", WIIMOTE_BDADDR);
205                         bdaddr = *BDADDR_ANY;
206                 }
207         }
208         else {
209                 bdaddr = *BDADDR_ANY;
210         }
211
212         /* TODO: fix wait_forever logic - currently assumes bdaddr is unspecified */
213         /* Wiimote Connect */
214         printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
215         if (wait_forever) {
216                 if (cwiid_find_wiimote(&bdaddr, -1)) {
217                         wminput_err("error finding wiimote");
218                         conf_unload(&conf);
219                         return -1;
220                 }
221         }
222         if ((wiimote = cwiid_open(&bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) {
223                 wminput_err("unable to connect");
224                 conf_unload(&conf);
225                 return -1;
226         }
227         if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) {
228                 wminput_err("error setting callback");
229                 conf_unload(&conf);
230                 return -1;
231         }
232
233         if (c_wiimote(wiimote)) {
234                 conf_unload(&conf);
235                 return -1;
236         }
237         if (py_wiimote(wiimote)) {
238                 conf_unload(&conf);
239                 return -1;
240         }
241
242         /* init plugins */
243         for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) {
244                 switch (conf.plugins[i].type) {
245                 case PLUGIN_C:
246                         if (c_plugin_init(&conf.plugins[i], i)) {
247                                 wminput_err("error on %s init", conf.plugins[i].name);
248                                 conf_unload(&conf);
249                                 cwiid_close(wiimote);
250                                 return -1;
251                         }
252                         break;
253                 case PLUGIN_PYTHON:
254                         if (py_plugin_init(&conf.plugins[i], i)) {
255                                 wminput_err("error %s init", conf.plugins[i].name);
256                                 conf_unload(&conf);
257                                 cwiid_close(wiimote);
258                                 return -1;
259                         }
260                         break;
261                 }
262         }
263
264         if (wminput_set_report_mode()) {
265                 conf_unload(&conf);
266                 cwiid_close(wiimote);
267                 return -1;
268         }
269
270         uinput_listen_data.wiimote = wiimote;
271         uinput_listen_data.conf = &conf;
272         if (pthread_create(&uinput_listen_thread, NULL,
273                            (void *(*)(void *))uinput_listen,
274                            &uinput_listen_data)) {
275                 wminput_err("error starting uinput listen thread");
276                 conf_unload(&conf);
277                 cwiid_close(wiimote);
278                 return -1;
279         }
280
281
282         printf("Ready.\n");
283
284         init = 0;
285
286         /* wait */
287         sigemptyset(&sigset);
288         sigaddset(&sigset, SIGTERM);
289         sigaddset(&sigset, SIGINT);
290         sigprocmask(SIG_BLOCK, &sigset, NULL);
291         sigwait(&sigset, &signum);
292
293         printf("Exiting.\n");
294
295         if (pthread_cancel(uinput_listen_thread)) {
296                 wminput_err("error canceling uinput listen thread");
297                 ret = -1;
298         }
299         else if (pthread_join(uinput_listen_thread, NULL)) {
300                 wminput_err("error joing uinput listen thread");
301                 ret = -1;
302         }
303
304         /* disconnect */
305         if (cwiid_close(wiimote)) {
306                 wminput_err("error on disconnect");
307                 ret = -1;
308         }
309
310         if (conf_unload(&conf)) {
311                 ret = -1;
312         }
313
314         py_deinit();
315
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;
336 }
337
338 int wmplugin_set_rpt_mode(int id, uint8_t flags)
339 {
340         conf.plugins[id].rpt_mode_flags = flags;
341
342         if (!init) {
343                 wminput_set_report_mode();
344         }
345
346         return 0;
347 }
348
349 void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count,
350                     union cwiid_mesg mesg[], struct timespec *timestamp)
351 {
352         int i;
353
354         for (i=0; i < mesg_count; i++) {
355                 switch (mesg[i].type) {
356                 case CWIID_MESG_BTN:
357                         process_btn_mesg((struct cwiid_btn_mesg *) &mesg[i]);
358                         break;
359                 case CWIID_MESG_NUNCHUK:
360                         process_nunchuk_mesg((struct cwiid_nunchuk_mesg *) &mesg[i]);
361                         break;
362                 case CWIID_MESG_CLASSIC:
363                         process_classic_mesg((struct cwiid_classic_mesg *) &mesg[i]);
364                         break;
365                 case CWIID_MESG_ERROR:
366                         if (kill(getpid(),SIGINT)) {
367                                 wminput_err("error sending SIGINT");
368                         }
369                         break;
370                 default:
371                         break;
372                 }
373         }
374         for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) {
375                 process_plugin(&conf.plugins[i], mesg_count, mesg);
376         }
377         send_event(&conf, EV_SYN, SYN_REPORT, 0);
378 }
379
380 void process_btn_mesg(struct cwiid_btn_mesg *mesg)
381 {
382         static uint16_t prev_buttons = 0;
383         uint16_t pressed, released;
384         __s32 axis_value;
385         int i;
386
387         /* Wiimote Button/Key Events */
388         pressed = mesg->buttons & ~prev_buttons;
389         released = ~mesg->buttons & prev_buttons;
390         for (i=0; i < CONF_WM_BTN_COUNT; i++) {
391                 if (conf.wiimote_bmap[i].active) {
392                         if (pressed & conf.wiimote_bmap[i].mask) {
393                                 send_event(&conf, EV_KEY, conf.wiimote_bmap[i].action, 1);
394                         }
395                         else if (released & conf.wiimote_bmap[i].mask) {
396                                 send_event(&conf, EV_KEY, conf.wiimote_bmap[i].action, 0);
397                         }
398                 }
399         }
400         prev_buttons = mesg->buttons;
401
402         /* Wiimote.Dpad.X */
403         if (conf.amap[CONF_WM_AXIS_DPAD_X].active) {
404                 axis_value = 0;
405                 if (mesg->buttons & CWIID_BTN_LEFT) {
406                         axis_value = -1;
407                 }
408                 else if (mesg->buttons & CWIID_BTN_RIGHT) {
409                         axis_value = 1;
410                 }
411                 if (conf.amap[CONF_WM_AXIS_DPAD_X].flags & CONF_INVERT) {
412                         axis_value *= -1;
413                 }
414                 send_event(&conf, conf.amap[CONF_WM_AXIS_DPAD_X].axis_type,
415                            conf.amap[CONF_WM_AXIS_DPAD_X].action, axis_value);
416         }
417
418         /* Wiimote.Dpad.Y */
419         if (conf.amap[CONF_WM_AXIS_DPAD_Y].active) {
420                 axis_value = 0;
421                 if (mesg->buttons & CWIID_BTN_DOWN) {
422                         axis_value = -1;
423                 }
424                 else if (mesg->buttons & CWIID_BTN_UP) {
425                         axis_value = 1;
426                 }
427                 if (conf.amap[CONF_WM_AXIS_DPAD_Y].flags & CONF_INVERT) {
428                         axis_value *= -1;
429                 }
430                 send_event(&conf, conf.amap[CONF_WM_AXIS_DPAD_Y].axis_type,
431                            conf.amap[CONF_WM_AXIS_DPAD_Y].action, axis_value);
432         }
433 }
434
435 void process_nunchuk_mesg(struct cwiid_nunchuk_mesg *mesg)
436 {
437         static uint8_t prev_buttons = 0;
438         uint8_t pressed, released;
439         __s32 axis_value;
440         int i;
441
442         /* Nunchuk Button/Key Events */
443         pressed = mesg->buttons & ~prev_buttons;
444         released = ~mesg->buttons & prev_buttons;
445         for (i=0; i < CONF_NC_BTN_COUNT; i++) {
446                 if (conf.nunchuk_bmap[i].active) {
447                         if (pressed & conf.nunchuk_bmap[i].mask) {
448                                 send_event(&conf, EV_KEY, conf.nunchuk_bmap[i].action, 1);
449                         }
450                         else if (released & conf.nunchuk_bmap[i].mask) {
451                                 send_event(&conf, EV_KEY, conf.nunchuk_bmap[i].action, 0);
452                         }
453                 }
454         }
455         prev_buttons = mesg->buttons;
456
457         /* Nunchuk.Stick.X */
458         if (conf.amap[CONF_NC_AXIS_STICK_X].active) {
459                 axis_value = mesg->stick[CWIID_X];
460                 if (conf.amap[CONF_NC_AXIS_STICK_X].flags & CONF_INVERT) {
461                         axis_value = 0xFF - axis_value;
462                 }
463                 send_event(&conf, conf.amap[CONF_NC_AXIS_STICK_X].axis_type,
464                            conf.amap[CONF_NC_AXIS_STICK_X].action, axis_value);
465         }
466
467         /* Nunchuk.Stick.Y */
468         if (conf.amap[CONF_NC_AXIS_STICK_Y].active) {
469                 axis_value = mesg->stick[CWIID_Y];
470                 if (conf.amap[CONF_NC_AXIS_STICK_Y].flags & CONF_INVERT) {
471                         axis_value = 0xFF - axis_value;
472                 }
473                 send_event(&conf, conf.amap[CONF_NC_AXIS_STICK_Y].axis_type,
474                            conf.amap[CONF_NC_AXIS_STICK_Y].action, axis_value);
475         }
476 }
477
478 void process_classic_mesg(struct cwiid_classic_mesg *mesg)
479 {
480         static uint16_t prev_buttons = 0;
481         uint16_t pressed, released;
482         __s32 axis_value;
483         int i;
484
485         /* Classic Button/Key Events */
486         pressed = mesg->buttons & ~prev_buttons;
487         released = ~mesg->buttons & prev_buttons;
488         for (i=0; i < CONF_CC_BTN_COUNT; i++) {
489                 if (conf.classic_bmap[i].active) {
490                         if (pressed & conf.classic_bmap[i].mask) {
491                                 send_event(&conf, EV_KEY, conf.classic_bmap[i].action, 1);
492                         }
493                         else if (released & conf.classic_bmap[i].mask) {
494                                 send_event(&conf, EV_KEY, conf.classic_bmap[i].action, 0);
495                         }
496                 }
497         }
498         prev_buttons = mesg->buttons;
499
500         /* Classic.Dpad.X */
501         if (conf.amap[CONF_CC_AXIS_DPAD_X].active) {
502                 axis_value = 0;
503                 if (mesg->buttons & CWIID_CLASSIC_BTN_LEFT) {
504                         axis_value = -1;
505                 }
506                 else if (mesg->buttons & CWIID_CLASSIC_BTN_RIGHT) {
507                         axis_value = 1;
508                 }
509                 if (conf.amap[CONF_CC_AXIS_DPAD_X].flags & CONF_INVERT) {
510                         axis_value *= -1;
511                 }
512                 send_event(&conf, conf.amap[CONF_CC_AXIS_DPAD_X].axis_type,
513                            conf.amap[CONF_CC_AXIS_DPAD_X].action, axis_value);
514         }
515
516         /* Classic.Dpad.Y */
517         if (conf.amap[CONF_CC_AXIS_DPAD_Y].active) {
518                 axis_value = 0;
519                 if (mesg->buttons & CWIID_CLASSIC_BTN_DOWN) {
520                         axis_value = -1;
521                 }
522                 else if (mesg->buttons & CWIID_CLASSIC_BTN_UP) {
523                         axis_value = 1;
524                 }
525                 if (conf.amap[CONF_CC_AXIS_DPAD_Y].flags & CONF_INVERT) {
526                         axis_value *= -1;
527                 }
528                 send_event(&conf, conf.amap[CONF_CC_AXIS_DPAD_Y].axis_type,
529                            conf.amap[CONF_CC_AXIS_DPAD_Y].action, axis_value);
530         }
531
532         /* Classic.LStick.X */
533         if (conf.amap[CONF_CC_AXIS_L_STICK_X].active) {
534                 axis_value = mesg->l_stick[CWIID_X];
535                 if (conf.amap[CONF_CC_AXIS_L_STICK_X].flags & CONF_INVERT) {
536                         axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value;
537                 }
538                 send_event(&conf, conf.amap[CONF_CC_AXIS_L_STICK_X].axis_type,
539                            conf.amap[CONF_CC_AXIS_L_STICK_X].action, axis_value);
540         }
541
542         /* Classic.LStick.Y */
543         if (conf.amap[CONF_CC_AXIS_L_STICK_Y].active) {
544                 axis_value = mesg->l_stick[CWIID_Y];
545                 if (conf.amap[CONF_CC_AXIS_L_STICK_Y].flags & CONF_INVERT) {
546                         axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value;
547                 }
548                 send_event(&conf, conf.amap[CONF_CC_AXIS_L_STICK_Y].axis_type,
549                            conf.amap[CONF_CC_AXIS_L_STICK_Y].action, axis_value);
550         }
551
552         /* Classic.RStick.X */
553         if (conf.amap[CONF_CC_AXIS_R_STICK_X].active) {
554                 axis_value = mesg->r_stick[CWIID_X];
555                 if (conf.amap[CONF_CC_AXIS_R_STICK_X].flags & CONF_INVERT) {
556                         axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value;
557                 }
558                 send_event(&conf, conf.amap[CONF_CC_AXIS_R_STICK_X].axis_type,
559                            conf.amap[CONF_CC_AXIS_R_STICK_X].action, axis_value);
560         }
561
562         /* Classic.RStick.Y */
563         if (conf.amap[CONF_CC_AXIS_R_STICK_Y].active) {
564                 axis_value = mesg->r_stick[CWIID_Y];
565                 if (conf.amap[CONF_CC_AXIS_R_STICK_Y].flags & CONF_INVERT) {
566                         axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value;
567                 }
568                 send_event(&conf, conf.amap[CONF_CC_AXIS_R_STICK_Y].axis_type,
569                            conf.amap[CONF_CC_AXIS_R_STICK_Y].action, axis_value);
570         }
571
572         /* Classic.LAnalog */
573         if (conf.amap[CONF_CC_AXIS_L].active) {
574                 axis_value = mesg->l;
575                 if (conf.amap[CONF_CC_AXIS_L].flags & CONF_INVERT) {
576                         axis_value = CWIID_CLASSIC_LR_MAX - axis_value;
577                 }
578                 send_event(&conf, conf.amap[CONF_CC_AXIS_L].axis_type,
579                            conf.amap[CONF_CC_AXIS_L].action, axis_value);
580         }
581
582         /* Classic.RAnalog */
583         if (conf.amap[CONF_CC_AXIS_R].active) {
584                 axis_value = mesg->r;
585                 if (conf.amap[CONF_CC_AXIS_R].flags & CONF_INVERT) {
586                         axis_value = CWIID_CLASSIC_LR_MAX - axis_value;
587                 }
588                 send_event(&conf, conf.amap[CONF_CC_AXIS_R].axis_type,
589                            conf.amap[CONF_CC_AXIS_R].action, axis_value);
590         }
591 }
592
593 void process_plugin(struct plugin *plugin, int mesg_count,
594                     union cwiid_mesg mesg[])
595 {
596         static union cwiid_mesg plugin_mesg[CWIID_MAX_MESG_COUNT];
597         int plugin_mesg_count = 0;
598         int i;
599         uint8_t flag;
600         uint16_t pressed, released;
601         __s32 axis_value;
602
603         for (i=0; i < mesg_count; i++) {
604                 switch (mesg[i].type) {
605                 case CWIID_MESG_STATUS:
606                         flag = CWIID_RPT_STATUS;
607                         break;
608                 case CWIID_MESG_BTN:
609                         flag = CWIID_RPT_BTN;
610                         break;
611                 case CWIID_MESG_ACC:
612                         flag = CWIID_RPT_ACC;
613                         break;
614                 case CWIID_MESG_IR:
615                         flag = CWIID_RPT_IR;
616                         break;
617                 case CWIID_MESG_NUNCHUK:
618                         flag = CWIID_RPT_NUNCHUK;
619                         break;
620                 case CWIID_MESG_CLASSIC:
621                         flag = CWIID_RPT_CLASSIC;
622                         break;
623                 default:
624                         break;
625                 }
626                 if (plugin->rpt_mode_flags & flag) {
627                         /* TODO: copy correct (smaller) message size */
628                         memcpy(&plugin_mesg[plugin_mesg_count++], &mesg[i], sizeof mesg[i]);
629                 }
630         }
631
632         if (plugin_mesg_count > 0) {
633                 switch (plugin->type) {
634                 case PLUGIN_C:
635                         if (c_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) {
636                                 return;
637                         }
638                         break;
639                 case PLUGIN_PYTHON:
640                         if (py_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) {
641                                 return;
642                         }
643                         break;
644                 }
645
646                 /* Plugin Button/Key Events */
647                 pressed = plugin->data->buttons & ~plugin->prev_buttons;
648                 released = ~plugin->data->buttons & plugin->prev_buttons;
649                 for (i=0; i < plugin->info->button_count; i++) {
650                         if (plugin->bmap[i].active) {
651                                 if (pressed & 1<<i) {
652                                         send_event(&conf, EV_KEY, plugin->bmap[i].action, 1);
653                                 }
654                                 else if (released & 1<<i) {
655                                         send_event(&conf, EV_KEY, plugin->bmap[i].action, 0);
656                                 }
657                         }
658                 }
659                 plugin->prev_buttons = plugin->data->buttons;
660
661                 /* Plugin Axis Events */
662                 for (i=0; i < plugin->info->axis_count; i++) {
663                         if (plugin->amap[i].active && plugin->data->axes &&
664                           plugin->data->axes[i].valid) {
665                                 axis_value = plugin->data->axes[i].value;
666                                 if (plugin->amap[i].flags & CONF_INVERT) {
667                                         axis_value = plugin->info->axis_info[i].max +
668                                                      plugin->info->axis_info[i].min - axis_value;
669                                 }
670                                 send_event(&conf, plugin->amap[i].axis_type,
671                                            plugin->amap[i].action, axis_value);
672                         }
673                 }
674         }
675 }
Note: See TracBrowser for help on using the browser.