root/wminput/main.c

Revision 6af678616531eb1f3d3d0a052313ef9d8125bac7, 18.2 kB (checked in by L. Donnie Smith <donnie.smith@…>, 2 years ago)

fix link options for --as-needed (#90)

also fix a couple of includes

  • Property mode set to 100644
Line 
1/* Copyright (C) 2007 L. Donnie Smith <donnie.smith@gatech.edu>
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 */
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <errno.h>
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <getopt.h>
28
29#include <pthread.h>
30#include <signal.h>
31#include <sys/types.h>
32#include <unistd.h>
33#include <bluetooth/bluetooth.h>
34
35#include <cwiid.h>
36
37#include "conf.h"
38#include "util.h"
39#include "wmplugin.h"
40#include "c_plugin.h"
41
42#ifdef HAVE_PYTHON
43#include "py_plugin.h"
44#endif
45
46struct conf conf;
47
48/* Prototypes */
49cwiid_mesg_callback_t cwiid_callback;
50int wminput_set_report_mode();
51void process_btn_mesg(struct cwiid_btn_mesg *mesg);
52void process_nunchuk_mesg(struct cwiid_nunchuk_mesg *mesg);
53void process_classic_mesg(struct cwiid_classic_mesg *mesg);
54void process_plugin(struct plugin *, int, union cwiid_mesg []);
55
56/* Globals */
57cwiid_wiimote_t *wiimote;
58char init;
59
60#define DEFAULT_CONFIG_FILE     "default"
61
62#define HOME_DIR_LEN    128
63
64void print_usage(void)
65{
66        printf("wminput is a program that allows you to use a wiimote as a standard input device\n");
67        printf("Usage: %s [OPTIONS]...\n\n", "wminput");
68        printf("Options:\n");
69        printf("\t-h, --help\t\tPrints this output.\n");
70        printf("\t-v, --version\t\tOutput version information and exit.\n");
71        printf("\t-c, --config [file]\tChoose config file to use.\n");
72        printf("\t-d, --daemon\t\tImplies -q, -r, and -w.\n");
73        printf("\t-q, --quiet\t\tReduce output to errors\n");
74        printf("\t-r, --reconnect [wait]\tAutomatically try reconnect after wiimote disconnect.\n");
75        printf("\t-w, --wait\t\tWait indefinitely for wiimote to connect.\n");
76}
77
78void cwiid_err_connect(struct wiimote *wiimote, const char *str, va_list ap)
79{
80        /* TODO: temporary kludge to stifle error messages from cwiid_open */
81        if (errno != EHOSTDOWN) {
82                vfprintf(stderr, str, ap);
83                fprintf(stderr, "\n");
84        }
85}
86
87int main(int argc, char *argv[])
88{
89        char wait_forever = 0, quiet = 0, reconnect = 0, reconnect_wait = 0;
90        char *config_search_dirs[3], *plugin_search_dirs[3];
91        char *config_filename = DEFAULT_CONFIG_FILE;
92        char home_config_dir[HOME_DIR_LEN];
93        char home_plugin_dir[HOME_DIR_LEN];
94        char *tmp;
95        int c, i;
96        char *str_addr;
97        bdaddr_t bdaddr, current_bdaddr;
98        sigset_t sigset;
99        int signum, ret=0;
100        struct uinput_listen_data uinput_listen_data;
101        pthread_t uinput_listen_thread;
102
103        init = 1;
104
105        /* Parse Options */
106        while (1) {
107                int option_index = 0;
108
109                static struct option long_options[] = {
110                        {"help", 0, 0, 'h'},
111                        {"version", 0, 0, 'v'},
112                        {"config", 1, 0, 'c'},
113                        {"daemon", 0, 0, 'd'},
114                        {"quiet", 0, 0, 'q'},
115                        {"reconnect", 2, 0, 'r'},
116                        {"wait", 0, 0, 'w'},
117                        {0, 0, 0, 0}
118                };
119
120                c = getopt_long (argc, argv, "hvc:dqr::w", long_options, &option_index);
121
122                if (c == -1) {
123                        break;
124                }
125
126                switch (c) {
127                case 'h':
128                        print_usage();
129                        return 0;
130                        break;
131                case 'v':
132                        printf("CWiid Version %s\n", PACKAGE_VERSION);
133                        return 0;
134                        break;
135                case 'c':
136                        config_filename = optarg;
137                        break;
138                case 'd':
139                        wait_forever = 1;
140                        quiet = 1;
141                        reconnect = 1;
142                        break;
143                case 'q':
144                        quiet = 1;
145                        break;
146                case 'r':
147                        reconnect = 1;
148                        if (optarg) {
149                                reconnect_wait = strtol(optarg, &tmp, 10);
150                                if (*tmp != '\0') {
151                                        wminput_err("bad reconnect wait time");
152                                        return -1;
153                                }
154                        }
155                        break;
156                case 'w':
157                        wait_forever = 1;
158                        break;
159                case '?':
160                        printf("Try `wminput --help` for more information\n");
161                        return 1;
162                        break;
163                default:
164                        return -1;
165                        break;
166                }
167        }
168
169        if (c_init()) {
170                return -1;
171        }
172
173#ifdef HAVE_PYTHON
174        if (py_init()) {
175                return -1;
176        }
177#endif
178
179        /* Load Config */
180        /* Setup search directory arrays */
181        if ((tmp = getenv("HOME")) == NULL) {
182                wminput_err("Unable to find home directory");
183                config_search_dirs[0] = WMINPUT_CONFIG_DIR;
184                plugin_search_dirs[0] = CWIID_PLUGINS_DIR;
185                config_search_dirs[1] = plugin_search_dirs[1] = NULL;
186        }
187        else {
188                snprintf(home_config_dir, HOME_DIR_LEN, "%s/.cwiid/wminput", tmp);
189                snprintf(home_plugin_dir, HOME_DIR_LEN, "%s/.cwiid/plugins", tmp);
190                config_search_dirs[0] = home_config_dir;
191                plugin_search_dirs[0] = home_plugin_dir;
192                config_search_dirs[1] = WMINPUT_CONFIG_DIR;
193                plugin_search_dirs[1] = CWIID_PLUGINS_DIR;
194                config_search_dirs[2] = plugin_search_dirs[2] = NULL;
195        }
196
197        if (conf_load(&conf, config_filename, config_search_dirs,
198          plugin_search_dirs)) {
199                return -1;
200        }
201
202        /* Determine BDADDR */
203        /* priority: command-line option, environment variable, BDADDR_ANY */
204        if (optind < argc) {
205                if (str2ba(argv[optind], &bdaddr)) {
206                        wminput_err("invalid bdaddr");
207                        bdaddr = *BDADDR_ANY;
208                }
209                optind++;
210                if (optind < argc) {
211                        wminput_err("invalid command-line");
212                        print_usage();
213                        conf_unload(&conf);
214                        return -1;
215                }
216        }
217        else if ((str_addr = getenv(WIIMOTE_BDADDR)) != NULL) {
218                if (str2ba(str_addr, &bdaddr)) {
219                        wminput_err("invalid address in %s", WIIMOTE_BDADDR);
220                        bdaddr = *BDADDR_ANY;
221                }
222        }
223        else {
224                bdaddr = *BDADDR_ANY;
225        }
226
227        sigemptyset(&sigset);
228        sigaddset(&sigset, SIGTERM);
229        sigaddset(&sigset, SIGINT);
230        sigaddset(&sigset, SIGUSR1);
231
232        do {
233                bacpy(&current_bdaddr, &bdaddr);
234
235                /* Wiimote Connect */
236                if (!quiet) {
237                        printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
238                }
239                if (wait_forever) {
240                        if (!bacmp(&current_bdaddr, BDADDR_ANY)) {
241                                if (cwiid_find_wiimote(&current_bdaddr, -1)) {
242                                        wminput_err("error finding wiimote");
243                                        conf_unload(&conf);
244                                        return -1;
245                                }
246                        }
247                        /* TODO: avoid continuously calling cwiid_open */
248                        cwiid_set_err(cwiid_err_connect);
249                        while (!(wiimote = cwiid_open(&current_bdaddr, CWIID_FLAG_MESG_IFC)));
250                        cwiid_set_err(cwiid_err_default);
251                }
252                else {
253                        if ((wiimote = cwiid_open(&current_bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) {
254                                wminput_err("unable to connect");
255                                conf_unload(&conf);
256                                return -1;
257                        }
258                }
259                if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) {
260                        wminput_err("error setting callback");
261                        conf_unload(&conf);
262                        return -1;
263                }
264
265                if (c_wiimote(wiimote)) {
266                        conf_unload(&conf);
267                        return -1;
268                }
269#ifdef HAVE_PYTHON
270                if (py_wiimote(wiimote)) {
271                        conf_unload(&conf);
272                        return -1;
273                }
274#endif
275
276                /* init plugins */
277                for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) {
278                        switch (conf.plugins[i].type) {
279                        case PLUGIN_C:
280                                if (c_plugin_init(&conf.plugins[i], i)) {
281                                        wminput_err("error on %s init", conf.plugins[i].name);
282                                        conf_unload(&conf);
283                                        cwiid_close(wiimote);
284                                        return -1;
285                                }
286                                break;
287#ifdef HAVE_PYTHON
288                        case PLUGIN_PYTHON:
289                                if (py_plugin_init(&conf.plugins[i], i)) {
290                                        wminput_err("error %s init", conf.plugins[i].name);
291                                        conf_unload(&conf);
292                                        cwiid_close(wiimote);
293                                        return -1;
294                                }
295                                break;
296#endif
297                        }
298                }
299
300                if (wminput_set_report_mode()) {
301                        conf_unload(&conf);
302                        cwiid_close(wiimote);
303                        return -1;
304                }
305
306                uinput_listen_data.wiimote = wiimote;
307                uinput_listen_data.conf = &conf;
308                if (pthread_create(&uinput_listen_thread, NULL,
309                                   (void *(*)(void *))uinput_listen,
310                                   &uinput_listen_data)) {
311                        wminput_err("error starting uinput listen thread");
312                        conf_unload(&conf);
313                        cwiid_close(wiimote);
314                        return -1;
315                }
316
317                if (!quiet) {
318                        printf("Ready.\n");
319                }
320
321                init = 0;
322
323                /* wait */
324                sigprocmask(SIG_BLOCK, &sigset, NULL);
325                sigwait(&sigset, &signum);
326                sigprocmask(SIG_UNBLOCK, &sigset, NULL);
327
328                if ((signum == SIGTERM) || (signum == SIGINT)) {
329                        reconnect = 0;
330                }
331
332                if (pthread_cancel(uinput_listen_thread)) {
333                        wminput_err("Error canceling uinput listen thread");
334                        ret = -1;
335                }
336                else if (pthread_join(uinput_listen_thread, NULL)) {
337                        wminput_err("Error joining uinput listen thread");
338                        ret = -1;
339                }
340
341                c_wiimote_deinit();
342#ifdef HAVE_PYTHON
343                py_wiimote_deinit();
344#endif
345
346                /* disconnect */
347                if (cwiid_close(wiimote)) {
348                        wminput_err("Error on wiimote disconnect");
349                        ret = -1;
350                }
351
352                if (reconnect && reconnect_wait) {
353                        sleep(reconnect_wait);
354                }
355        } while (reconnect);
356
357        if (conf_unload(&conf)) {
358                ret = -1;
359        }
360
361        c_deinit();
362#ifdef HAVE_PYTHON
363        py_deinit();
364#endif
365
366        if (!quiet) {
367                printf("Exiting.\n");
368        }
369
370        return ret;
371}
372
373int wminput_set_report_mode()
374{
375        unsigned char rpt_mode_flags;
376        int i;
377
378        rpt_mode_flags = conf.rpt_mode_flags;
379
380        for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) {
381                rpt_mode_flags |= conf.plugins[i].rpt_mode_flags;
382        }
383
384        if (cwiid_set_rpt_mode(wiimote, rpt_mode_flags)) {
385                wminput_err("Error setting report mode");
386                return -1;
387        }
388
389        return 0;
390}
391
392int wmplugin_set_rpt_mode(int id, uint8_t flags)
393{
394        conf.plugins[id].rpt_mode_flags = flags;
395
396        if (!init) {
397                wminput_set_report_mode();
398        }
399
400        return 0;
401}
402
403void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count,
404                    union cwiid_mesg mesg[], struct timespec *timestamp)
405{
406        int i;
407
408        for (i=0; i < mesg_count; i++) {
409                switch (mesg[i].type) {
410                case CWIID_MESG_BTN:
411                        process_btn_mesg((struct cwiid_btn_mesg *) &mesg[i]);
412                        break;
413                case CWIID_MESG_NUNCHUK:
414                        process_nunchuk_mesg((struct cwiid_nunchuk_mesg *) &mesg[i]);
415                        break;
416                case CWIID_MESG_CLASSIC:
417                        process_classic_mesg((struct cwiid_classic_mesg *) &mesg[i]);
418                        break;
419                case CWIID_MESG_ERROR:
420                        if (kill(getpid(),SIGUSR1)) {
421                                wminput_err("Error sending SIGUSR1");
422                        }
423                        break;
424                default:
425                        break;
426                }
427        }
428        for (i=0; (i < CONF_MAX_PLUGINS) && conf.plugins[i].name; i++) {
429                process_plugin(&conf.plugins[i], mesg_count, mesg);
430        }
431        send_event(&conf, EV_SYN, SYN_REPORT, 0);
432}
433
434void process_btn_mesg(struct cwiid_btn_mesg *mesg)
435{
436        static uint16_t prev_buttons = 0;
437        uint16_t pressed, released;
438        __s32 axis_value;
439        int i;
440
441        /* Wiimote Button/Key Events */
442        pressed = mesg->buttons & ~prev_buttons;
443        released = ~mesg->buttons & prev_buttons;
444        for (i=0; i < CONF_WM_BTN_COUNT; i++) {
445                if (conf.wiimote_bmap[i].active) {
446                        if (pressed & conf.wiimote_bmap[i].mask) {
447                                send_event(&conf, EV_KEY, conf.wiimote_bmap[i].action, 1);
448                        }
449                        else if (released & conf.wiimote_bmap[i].mask) {
450                                send_event(&conf, EV_KEY, conf.wiimote_bmap[i].action, 0);
451                        }
452                }
453        }
454        prev_buttons = mesg->buttons;
455
456        /* Wiimote.Dpad.X */
457        if (conf.amap[CONF_WM_AXIS_DPAD_X].active) {
458                axis_value = 0;
459                if (mesg->buttons & CWIID_BTN_LEFT) {
460                        axis_value = -1;
461                }
462                else if (mesg->buttons & CWIID_BTN_RIGHT) {
463                        axis_value = 1;
464                }
465                if (conf.amap[CONF_WM_AXIS_DPAD_X].flags & CONF_INVERT) {
466                        axis_value *= -1;
467                }
468                send_event(&conf, conf.amap[CONF_WM_AXIS_DPAD_X].axis_type,
469                           conf.amap[CONF_WM_AXIS_DPAD_X].action, axis_value);
470        }
471
472        /* Wiimote.Dpad.Y */
473        if (conf.amap[CONF_WM_AXIS_DPAD_Y].active) {
474                axis_value = 0;
475                if (mesg->buttons & CWIID_BTN_DOWN) {
476                        axis_value = -1;
477                }
478                else if (mesg->buttons & CWIID_BTN_UP) {
479                        axis_value = 1;
480                }
481                if (conf.amap[CONF_WM_AXIS_DPAD_Y].flags & CONF_INVERT) {
482                        axis_value *= -1;
483                }
484                send_event(&conf, conf.amap[CONF_WM_AXIS_DPAD_Y].axis_type,
485                           conf.amap[CONF_WM_AXIS_DPAD_Y].action, axis_value);
486        }
487}
488
489void process_nunchuk_mesg(struct cwiid_nunchuk_mesg *mesg)
490{
491        static uint8_t prev_buttons = 0;
492        uint8_t pressed, released;
493        __s32 axis_value;
494        int i;
495
496        /* Nunchuk Button/Key Events */
497        pressed = mesg->buttons & ~prev_buttons;
498        released = ~mesg->buttons & prev_buttons;
499        for (i=0; i < CONF_NC_BTN_COUNT; i++) {
500                if (conf.nunchuk_bmap[i].active) {
501                        if (pressed & conf.nunchuk_bmap[i].mask) {
502                                send_event(&conf, EV_KEY, conf.nunchuk_bmap[i].action, 1);
503                        }
504                        else if (released & conf.nunchuk_bmap[i].mask) {
505                                send_event(&conf, EV_KEY, conf.nunchuk_bmap[i].action, 0);
506                        }
507                }
508        }
509        prev_buttons = mesg->buttons;
510
511        /* Nunchuk.Stick.X */
512        if (conf.amap[CONF_NC_AXIS_STICK_X].active) {
513                axis_value = mesg->stick[CWIID_X];
514                if (conf.amap[CONF_NC_AXIS_STICK_X].flags & CONF_INVERT) {
515                        axis_value = 0xFF - axis_value;
516                }
517                send_event(&conf, conf.amap[CONF_NC_AXIS_STICK_X].axis_type,
518                           conf.amap[CONF_NC_AXIS_STICK_X].action, axis_value);
519        }
520
521        /* Nunchuk.Stick.Y */
522        if (conf.amap[CONF_NC_AXIS_STICK_Y].active) {
523                axis_value = mesg->stick[CWIID_Y];
524                if (conf.amap[CONF_NC_AXIS_STICK_Y].flags & CONF_INVERT) {
525                        axis_value = 0xFF - axis_value;
526                }
527                send_event(&conf, conf.amap[CONF_NC_AXIS_STICK_Y].axis_type,
528                           conf.amap[CONF_NC_AXIS_STICK_Y].action, axis_value);
529        }
530}
531
532void process_classic_mesg(struct cwiid_classic_mesg *mesg)
533{
534        static uint16_t prev_buttons = 0;
535        uint16_t pressed, released;
536        __s32 axis_value;
537        int i;
538
539        /* Classic Button/Key Events */
540        pressed = mesg->buttons & ~prev_buttons;
541        released = ~mesg->buttons & prev_buttons;
542        for (i=0; i < CONF_CC_BTN_COUNT; i++) {
543                if (conf.classic_bmap[i].active) {
544                        if (pressed & conf.classic_bmap[i].mask) {
545                                send_event(&conf, EV_KEY, conf.classic_bmap[i].action, 1);
546                        }
547                        else if (released & conf.classic_bmap[i].mask) {
548                                send_event(&conf, EV_KEY, conf.classic_bmap[i].action, 0);
549                        }
550                }
551        }
552        prev_buttons = mesg->buttons;
553
554        /* Classic.Dpad.X */
555        if (conf.amap[CONF_CC_AXIS_DPAD_X].active) {
556                axis_value = 0;
557                if (mesg->buttons & CWIID_CLASSIC_BTN_LEFT) {
558                        axis_value = -1;
559                }
560                else if (mesg->buttons & CWIID_CLASSIC_BTN_RIGHT) {
561                        axis_value = 1;
562                }
563                if (conf.amap[CONF_CC_AXIS_DPAD_X].flags & CONF_INVERT) {
564                        axis_value *= -1;
565                }
566                send_event(&conf, conf.amap[CONF_CC_AXIS_DPAD_X].axis_type,
567                           conf.amap[CONF_CC_AXIS_DPAD_X].action, axis_value);
568        }
569
570        /* Classic.Dpad.Y */
571        if (conf.amap[CONF_CC_AXIS_DPAD_Y].active) {
572                axis_value = 0;
573                if (mesg->buttons & CWIID_CLASSIC_BTN_DOWN) {
574                        axis_value = -1;
575                }
576                else if (mesg->buttons & CWIID_CLASSIC_BTN_UP) {
577                        axis_value = 1;
578                }
579                if (conf.amap[CONF_CC_AXIS_DPAD_Y].flags & CONF_INVERT) {
580                        axis_value *= -1;
581                }
582                send_event(&conf, conf.amap[CONF_CC_AXIS_DPAD_Y].axis_type,
583                           conf.amap[CONF_CC_AXIS_DPAD_Y].action, axis_value);
584        }
585
586        /* Classic.LStick.X */
587        if (conf.amap[CONF_CC_AXIS_L_STICK_X].active) {
588                axis_value = mesg->l_stick[CWIID_X];
589                if (conf.amap[CONF_CC_AXIS_L_STICK_X].flags & CONF_INVERT) {
590                        axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value;
591                }
592                send_event(&conf, conf.amap[CONF_CC_AXIS_L_STICK_X].axis_type,
593                           conf.amap[CONF_CC_AXIS_L_STICK_X].action, axis_value);
594        }
595
596        /* Classic.LStick.Y */
597        if (conf.amap[CONF_CC_AXIS_L_STICK_Y].active) {
598                axis_value = mesg->l_stick[CWIID_Y];
599                if (conf.amap[CONF_CC_AXIS_L_STICK_Y].flags & CONF_INVERT) {
600                        axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value;
601                }
602                send_event(&conf, conf.amap[CONF_CC_AXIS_L_STICK_Y].axis_type,
603                           conf.amap[CONF_CC_AXIS_L_STICK_Y].action, axis_value);
604        }
605
606        /* Classic.RStick.X */
607        if (conf.amap[CONF_CC_AXIS_R_STICK_X].active) {
608                axis_value = mesg->r_stick[CWIID_X];
609                if (conf.amap[CONF_CC_AXIS_R_STICK_X].flags & CONF_INVERT) {
610                        axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value;
611                }
612                send_event(&conf, conf.amap[CONF_CC_AXIS_R_STICK_X].axis_type,
613                           conf.amap[CONF_CC_AXIS_R_STICK_X].action, axis_value);
614        }
615
616        /* Classic.RStick.Y */
617        if (conf.amap[CONF_CC_AXIS_R_STICK_Y].active) {
618                axis_value = mesg->r_stick[CWIID_Y];
619                if (conf.amap[CONF_CC_AXIS_R_STICK_Y].flags & CONF_INVERT) {
620                        axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value;
621                }
622                send_event(&conf, conf.amap[CONF_CC_AXIS_R_STICK_Y].axis_type,
623                           conf.amap[CONF_CC_AXIS_R_STICK_Y].action, axis_value);
624        }
625
626        /* Classic.LAnalog */
627        if (conf.amap[CONF_CC_AXIS_L].active) {
628                axis_value = mesg->l;
629                if (conf.amap[CONF_CC_AXIS_L].flags & CONF_INVERT) {
630                        axis_value = CWIID_CLASSIC_LR_MAX - axis_value;
631                }
632                send_event(&conf, conf.amap[CONF_CC_AXIS_L].axis_type,
633                           conf.amap[CONF_CC_AXIS_L].action, axis_value);
634        }
635
636        /* Classic.RAnalog */
637        if (conf.amap[CONF_CC_AXIS_R].active) {
638                axis_value = mesg->r;
639                if (conf.amap[CONF_CC_AXIS_R].flags & CONF_INVERT) {
640                        axis_value = CWIID_CLASSIC_LR_MAX - axis_value;
641                }
642                send_event(&conf, conf.amap[CONF_CC_AXIS_R].axis_type,
643                           conf.amap[CONF_CC_AXIS_R].action, axis_value);
644        }
645}
646
647void process_plugin(struct plugin *plugin, int mesg_count,
648                    union cwiid_mesg mesg[])
649{
650        static union cwiid_mesg plugin_mesg[CWIID_MAX_MESG_COUNT];
651        int plugin_mesg_count = 0;
652        int i;
653        uint8_t flag;
654        uint16_t pressed, released;
655        __s32 axis_value;
656
657        for (i=0; i < mesg_count; i++) {
658                switch (mesg[i].type) {
659                case CWIID_MESG_STATUS:
660                        flag = CWIID_RPT_STATUS;
661                        break;
662                case CWIID_MESG_BTN:
663                        flag = CWIID_RPT_BTN;
664                        break;
665                case CWIID_MESG_ACC:
666                        flag = CWIID_RPT_ACC;
667                        break;
668                case CWIID_MESG_IR:
669                        flag = CWIID_RPT_IR;
670                        break;
671                case CWIID_MESG_NUNCHUK:
672                        flag = CWIID_RPT_NUNCHUK;
673                        break;
674                case CWIID_MESG_CLASSIC:
675                        flag = CWIID_RPT_CLASSIC;
676                        break;
677                default:
678                        break;
679                }
680                if (plugin->rpt_mode_flags & flag) {
681                        /* TODO: copy correct (smaller) message size */
682                        memcpy(&plugin_mesg[plugin_mesg_count++], &mesg[i], sizeof mesg[i]);
683                }
684        }
685
686        if (plugin_mesg_count > 0) {
687                switch (plugin->type) {
688                case PLUGIN_C:
689                        if (c_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) {
690                                return;
691                        }
692                        break;
693#ifdef HAVE_PYTHON
694                case PLUGIN_PYTHON:
695                        if (py_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) {
696                                return;
697                        }
698                        break;
699#endif
700                }
701
702                /* Plugin Button/Key Events */
703                pressed = plugin->data->buttons & ~plugin->prev_buttons;
704                released = ~plugin->data->buttons & plugin->prev_buttons;
705                for (i=0; i < plugin->info->button_count; i++) {
706                        if (plugin->bmap[i].active) {
707                                if (pressed & 1<<i) {
708                                        send_event(&conf, EV_KEY, plugin->bmap[i].action, 1);
709                                }
710                                else if (released & 1<<i) {
711                                        send_event(&conf, EV_KEY, plugin->bmap[i].action, 0);
712                                }
713                        }
714                }
715                plugin->prev_buttons = plugin->data->buttons;
716
717                /* Plugin Axis Events */
718                for (i=0; i < plugin->info->axis_count; i++) {
719                        if (plugin->amap[i].active && plugin->data->axes &&
720                          plugin->data->axes[i].valid) {
721                                axis_value = plugin->data->axes[i].value;
722                                if (plugin->amap[i].flags & CONF_INVERT) {
723                                        axis_value = plugin->info->axis_info[i].max +
724                                                     plugin->info->axis_info[i].min - axis_value;
725                                }
726                                send_event(&conf, plugin->amap[i].axis_type,
727                                           plugin->amap[i].action, axis_value);
728                        }
729                }
730        }
731}
Note: See TracBrowser for help on using the browser.