root/wminput/main.c @ 6af678616531eb1f3d3d0a052313ef9d8125bac7

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

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

also fix a couple of includes

  • Property mode set to 100644
RevLine 
[2100f14]1/* Copyright (C) 2007 L. Donnie Smith <donnie.smith@gatech.edu>
[15d141c]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
[c033b7a]16 *
[15d141c]17 */
18
[8dfafdd]19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
[3c99e2c]23#include <errno.h>
[c033b7a]24#include <stdint.h>
[15d141c]25#include <stdio.h>
26#include <stdlib.h>
[49e0132]27#include <getopt.h>
[15d141c]28
29#include <pthread.h>
30#include <signal.h>
[09bfa38]31#include <sys/types.h>
[15d141c]32#include <unistd.h>
[6af6786]33#include <bluetooth/bluetooth.h>
[15d141c]34
[805477a]35#include <cwiid.h>
[15d141c]36
37#include "conf.h"
38#include "util.h"
39#include "wmplugin.h"
[49e0132]40#include "c_plugin.h"
[8dfafdd]41
42#ifdef HAVE_PYTHON
[49e0132]43#include "py_plugin.h"
[8dfafdd]44#endif
[15d141c]45
46struct conf conf;
47
48/* Prototypes */
[805477a]49cwiid_mesg_callback_t cwiid_callback;
[15d141c]50int wminput_set_report_mode();
[805477a]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);
[e1e47e1]54void process_plugin(struct plugin *, int, union cwiid_mesg []);
[15d141c]55
56/* Globals */
[805477a]57cwiid_wiimote_t *wiimote;
[c033b7a]58char init;
[15d141c]59
60#define DEFAULT_CONFIG_FILE     "default"
61
62#define HOME_DIR_LEN    128
[49e0132]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");
[c429ed4]70        printf("\t-v, --version\t\tOutput version information and exit.\n");
[49e0132]71        printf("\t-c, --config [file]\tChoose config file to use.\n");
[7e5f213]72        printf("\t-d, --daemon\t\tImplies -q, -r, and -w.\n");
73        printf("\t-q, --quiet\t\tReduce output to errors\n");
[3c99e2c]74        printf("\t-r, --reconnect [wait]\tAutomatically try reconnect after wiimote disconnect.\n");
[49e0132]75        printf("\t-w, --wait\t\tWait indefinitely for wiimote to connect.\n");
76}
77
[3c99e2c]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
[15d141c]87int main(int argc, char *argv[])
88{
[7e5f213]89        char wait_forever = 0, quiet = 0, reconnect = 0, reconnect_wait = 0;
[15d141c]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;
[7e5f213]97        bdaddr_t bdaddr, current_bdaddr;
[15d141c]98        sigset_t sigset;
99        int signum, ret=0;
100        struct uinput_listen_data uinput_listen_data;
101        pthread_t uinput_listen_thread;
102
[c033b7a]103        init = 1;
[15d141c]104
105        /* Parse Options */
[49e0132]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'},
[7e5f213]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'},
[49e0132]117                        {0, 0, 0, 0}
118                };
119
[7e5f213]120                c = getopt_long (argc, argv, "hvc:dqr::w", long_options, &option_index);
[49e0132]121
122                if (c == -1) {
123                        break;
124                }
125
[15d141c]126                switch (c) {
127                case 'h':
[49e0132]128                        print_usage();
[15d141c]129                        return 0;
130                        break;
[7e5f213]131                case 'v':
132                        printf("CWiid Version %s\n", PACKAGE_VERSION);
133                        return 0;
[b9d3519]134                        break;
[15d141c]135                case 'c':
136                        config_filename = optarg;
137                        break;
[7e5f213]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;
[49e0132]158                        break;
[15d141c]159                case '?':
[49e0132]160                        printf("Try `wminput --help` for more information\n");
161                        return 1;
162                        break;
[15d141c]163                default:
[b9d3519]164                        return -1;
[15d141c]165                        break;
166                }
167        }
168
[49e0132]169        if (c_init()) {
170                return -1;
171        }
[8dfafdd]172
173#ifdef HAVE_PYTHON
[49e0132]174        if (py_init()) {
175                return -1;
176        }
[8dfafdd]177#endif
[49e0132]178
[15d141c]179        /* Load Config */
[49e0132]180        /* Setup search directory arrays */
[15d141c]181        if ((tmp = getenv("HOME")) == NULL) {
[a498060]182                wminput_err("Unable to find home directory");
[573bcd0]183                config_search_dirs[0] = WMINPUT_CONFIG_DIR;
184                plugin_search_dirs[0] = CWIID_PLUGINS_DIR;
[15d141c]185                config_search_dirs[1] = plugin_search_dirs[1] = NULL;
186        }
187        else {
[d372b07]188                snprintf(home_config_dir, HOME_DIR_LEN, "%s/.cwiid/wminput", tmp);
189                snprintf(home_plugin_dir, HOME_DIR_LEN, "%s/.cwiid/plugins", tmp);
[15d141c]190                config_search_dirs[0] = home_config_dir;
191                plugin_search_dirs[0] = home_plugin_dir;
[573bcd0]192                config_search_dirs[1] = WMINPUT_CONFIG_DIR;
193                plugin_search_dirs[1] = CWIID_PLUGINS_DIR;
[15d141c]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
[49e0132]202        /* Determine BDADDR */
203        /* priority: command-line option, environment variable, BDADDR_ANY */
[15d141c]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");
[49e0132]212                        print_usage();
[15d141c]213                        conf_unload(&conf);
214                        return -1;
215                }
216        }
[422e116]217        else if ((str_addr = getenv(WIIMOTE_BDADDR)) != NULL) {
[15d141c]218                if (str2ba(str_addr, &bdaddr)) {
[422e116]219                        wminput_err("invalid address in %s", WIIMOTE_BDADDR);
[15d141c]220                        bdaddr = *BDADDR_ANY;
221                }
222        }
223        else {
224                bdaddr = *BDADDR_ANY;
225        }
226
[7e5f213]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 */
[3c99e2c]248                        cwiid_set_err(cwiid_err_connect);
[7e5f213]249                        while (!(wiimote = cwiid_open(&current_bdaddr, CWIID_FLAG_MESG_IFC)));
[3c99e2c]250                        cwiid_set_err(cwiid_err_default);
[7e5f213]251                }
252                else {
253                        if ((wiimote = cwiid_open(&current_bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) {
254                                wminput_err("unable to connect");
[d087284]255                                conf_unload(&conf);
256                                return -1;
257                        }
258                }
[7e5f213]259                if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) {
260                        wminput_err("error setting callback");
[b9d3519]261                        conf_unload(&conf);
262                        return -1;
263                }
[15d141c]264
[7e5f213]265                if (c_wiimote(wiimote)) {
266                        conf_unload(&conf);
267                        return -1;
268                }
[8dfafdd]269#ifdef HAVE_PYTHON
[7e5f213]270                if (py_wiimote(wiimote)) {
271                        conf_unload(&conf);
272                        return -1;
273                }
[8dfafdd]274#endif
[49e0132]275
[7e5f213]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;
[8dfafdd]287#ifdef HAVE_PYTHON
[7e5f213]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;
[8dfafdd]296#endif
[7e5f213]297                        }
[15d141c]298                }
299
[7e5f213]300                if (wminput_set_report_mode()) {
301                        conf_unload(&conf);
302                        cwiid_close(wiimote);
303                        return -1;
304                }
[15d141c]305
[7e5f213]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                }
[15d141c]316
[7e5f213]317                if (!quiet) {
318                        printf("Ready.\n");
319                }
[15d141c]320
[7e5f213]321                init = 0;
[15d141c]322
[7e5f213]323                /* wait */
324                sigprocmask(SIG_BLOCK, &sigset, NULL);
325                sigwait(&sigset, &signum);
326                sigprocmask(SIG_UNBLOCK, &sigset, NULL);
[15d141c]327
[7e5f213]328                if ((signum == SIGTERM) || (signum == SIGINT)) {
329                        reconnect = 0;
330                }
[15d141c]331
[7e5f213]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                }
[15d141c]340
[7e5f213]341                c_wiimote_deinit();
342#ifdef HAVE_PYTHON
343                py_wiimote_deinit();
344#endif
[15d141c]345
[7e5f213]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);
[15d141c]356
357        if (conf_unload(&conf)) {
358                ret = -1;
359        }
360
[7e5f213]361        c_deinit();
[8dfafdd]362#ifdef HAVE_PYTHON
[49e0132]363        py_deinit();
[8dfafdd]364#endif
[15d141c]365
[7e5f213]366        if (!quiet) {
367                printf("Exiting.\n");
368        }
369
[49e0132]370        return ret;
[15d141c]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
[a09a4ee]384        if (cwiid_set_rpt_mode(wiimote, rpt_mode_flags)) {
[a498060]385                wminput_err("Error setting report mode");
[15d141c]386                return -1;
387        }
388
389        return 0;
390}
391
[49e0132]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
[e1e47e1]403void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count,
[cc40e6c]404                    union cwiid_mesg mesg[], struct timespec *timestamp)
[15d141c]405{
406        int i;
407
408        for (i=0; i < mesg_count; i++) {
[e1e47e1]409                switch (mesg[i].type) {
[805477a]410                case CWIID_MESG_BTN:
[e1e47e1]411                        process_btn_mesg((struct cwiid_btn_mesg *) &mesg[i]);
[15d141c]412                        break;
[805477a]413                case CWIID_MESG_NUNCHUK:
[e1e47e1]414                        process_nunchuk_mesg((struct cwiid_nunchuk_mesg *) &mesg[i]);
[15d141c]415                        break;
[805477a]416                case CWIID_MESG_CLASSIC:
[e1e47e1]417                        process_classic_mesg((struct cwiid_classic_mesg *) &mesg[i]);
[15d141c]418                        break;
[805477a]419                case CWIID_MESG_ERROR:
[d087284]420                        if (kill(getpid(),SIGUSR1)) {
421                                wminput_err("Error sending SIGUSR1");
[09bfa38]422                        }
423                        break;
[15d141c]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
[805477a]434void process_btn_mesg(struct cwiid_btn_mesg *mesg)
[15d141c]435{
[c033b7a]436        static uint16_t prev_buttons = 0;
437        uint16_t pressed, released;
438        __s32 axis_value;
[15d141c]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++) {
[c033b7a]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                        }
[15d141c]452                }
453        }
454        prev_buttons = mesg->buttons;
455
456        /* Wiimote.Dpad.X */
[c033b7a]457        if (conf.amap[CONF_WM_AXIS_DPAD_X].active) {
[15d141c]458                axis_value = 0;
[805477a]459                if (mesg->buttons & CWIID_BTN_LEFT) {
[15d141c]460                        axis_value = -1;
461                }
[805477a]462                else if (mesg->buttons & CWIID_BTN_RIGHT) {
[15d141c]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 */
[c033b7a]473        if (conf.amap[CONF_WM_AXIS_DPAD_Y].active) {
[15d141c]474                axis_value = 0;
[805477a]475                if (mesg->buttons & CWIID_BTN_DOWN) {
[15d141c]476                        axis_value = -1;
477                }
[805477a]478                else if (mesg->buttons & CWIID_BTN_UP) {
[15d141c]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
[805477a]489void process_nunchuk_mesg(struct cwiid_nunchuk_mesg *mesg)
[15d141c]490{
[c033b7a]491        static uint8_t prev_buttons = 0;
492        uint8_t pressed, released;
493        __s32 axis_value;
[15d141c]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++) {
[c033b7a]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                        }
[15d141c]507                }
508        }
509        prev_buttons = mesg->buttons;
510
511        /* Nunchuk.Stick.X */
[c033b7a]512        if (conf.amap[CONF_NC_AXIS_STICK_X].active) {
[e1e47e1]513                axis_value = mesg->stick[CWIID_X];
[15d141c]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 */
[c033b7a]522        if (conf.amap[CONF_NC_AXIS_STICK_Y].active) {
[e1e47e1]523                axis_value = mesg->stick[CWIID_Y];
[15d141c]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
[805477a]532void process_classic_mesg(struct cwiid_classic_mesg *mesg)
[15d141c]533{
[c033b7a]534        static uint16_t prev_buttons = 0;
535        uint16_t pressed, released;
536        __s32 axis_value;
[15d141c]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++) {
[c033b7a]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                        }
[15d141c]550                }
551        }
552        prev_buttons = mesg->buttons;
553
554        /* Classic.Dpad.X */
[c033b7a]555        if (conf.amap[CONF_CC_AXIS_DPAD_X].active) {
[15d141c]556                axis_value = 0;
[805477a]557                if (mesg->buttons & CWIID_CLASSIC_BTN_LEFT) {
[15d141c]558                        axis_value = -1;
559                }
[805477a]560                else if (mesg->buttons & CWIID_CLASSIC_BTN_RIGHT) {
[15d141c]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 */
[c033b7a]571        if (conf.amap[CONF_CC_AXIS_DPAD_Y].active) {
[15d141c]572                axis_value = 0;
[805477a]573                if (mesg->buttons & CWIID_CLASSIC_BTN_DOWN) {
[15d141c]574                        axis_value = -1;
575                }
[805477a]576                else if (mesg->buttons & CWIID_CLASSIC_BTN_UP) {
[15d141c]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 */
[c033b7a]587        if (conf.amap[CONF_CC_AXIS_L_STICK_X].active) {
[e1e47e1]588                axis_value = mesg->l_stick[CWIID_X];
[15d141c]589                if (conf.amap[CONF_CC_AXIS_L_STICK_X].flags & CONF_INVERT) {
[805477a]590                        axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value;
[15d141c]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 */
[c033b7a]597        if (conf.amap[CONF_CC_AXIS_L_STICK_Y].active) {
[e1e47e1]598                axis_value = mesg->l_stick[CWIID_Y];
[15d141c]599                if (conf.amap[CONF_CC_AXIS_L_STICK_Y].flags & CONF_INVERT) {
[805477a]600                        axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value;
[15d141c]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 */
[c033b7a]607        if (conf.amap[CONF_CC_AXIS_R_STICK_X].active) {
[e1e47e1]608                axis_value = mesg->r_stick[CWIID_X];
[15d141c]609                if (conf.amap[CONF_CC_AXIS_R_STICK_X].flags & CONF_INVERT) {
[805477a]610                        axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value;
[15d141c]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 */
[c033b7a]617        if (conf.amap[CONF_CC_AXIS_R_STICK_Y].active) {
[e1e47e1]618                axis_value = mesg->r_stick[CWIID_Y];
[15d141c]619                if (conf.amap[CONF_CC_AXIS_R_STICK_Y].flags & CONF_INVERT) {
[805477a]620                        axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value;
[15d141c]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 */
[c033b7a]627        if (conf.amap[CONF_CC_AXIS_L].active) {
[15d141c]628                axis_value = mesg->l;
629                if (conf.amap[CONF_CC_AXIS_L].flags & CONF_INVERT) {
[805477a]630                        axis_value = CWIID_CLASSIC_LR_MAX - axis_value;
[15d141c]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 */
[c033b7a]637        if (conf.amap[CONF_CC_AXIS_R].active) {
[15d141c]638                axis_value = mesg->r;
639                if (conf.amap[CONF_CC_AXIS_R].flags & CONF_INVERT) {
[805477a]640                        axis_value = CWIID_CLASSIC_LR_MAX - axis_value;
[15d141c]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,
[e1e47e1]648                    union cwiid_mesg mesg[])
[15d141c]649{
[49e0132]650        static union cwiid_mesg plugin_mesg[CWIID_MAX_MESG_COUNT];
[15d141c]651        int plugin_mesg_count = 0;
652        int i;
[c033b7a]653        uint8_t flag;
654        uint16_t pressed, released;
655        __s32 axis_value;
[15d141c]656
657        for (i=0; i < mesg_count; i++) {
[e1e47e1]658                switch (mesg[i].type) {
[805477a]659                case CWIID_MESG_STATUS:
660                        flag = CWIID_RPT_STATUS;
[15d141c]661                        break;
[805477a]662                case CWIID_MESG_BTN:
663                        flag = CWIID_RPT_BTN;
[15d141c]664                        break;
[805477a]665                case CWIID_MESG_ACC:
666                        flag = CWIID_RPT_ACC;
[15d141c]667                        break;
[805477a]668                case CWIID_MESG_IR:
669                        flag = CWIID_RPT_IR;
[15d141c]670                        break;
[805477a]671                case CWIID_MESG_NUNCHUK:
672                        flag = CWIID_RPT_NUNCHUK;
[15d141c]673                        break;
[805477a]674                case CWIID_MESG_CLASSIC:
675                        flag = CWIID_RPT_CLASSIC;
[15d141c]676                        break;
677                default:
678                        break;
679                }
680                if (plugin->rpt_mode_flags & flag) {
[49e0132]681                        /* TODO: copy correct (smaller) message size */
682                        memcpy(&plugin_mesg[plugin_mesg_count++], &mesg[i], sizeof mesg[i]);
[15d141c]683                }
684        }
685
686        if (plugin_mesg_count > 0) {
[49e0132]687                switch (plugin->type) {
688                case PLUGIN_C:
689                        if (c_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) {
690                                return;
691                        }
692                        break;
[8dfafdd]693#ifdef HAVE_PYTHON
[49e0132]694                case PLUGIN_PYTHON:
695                        if (py_plugin_exec(plugin, plugin_mesg_count, plugin_mesg)) {
696                                return;
697                        }
698                        break;
[8dfafdd]699#endif
[15d141c]700                }
701
702                /* Plugin Button/Key Events */
[49e0132]703                pressed = plugin->data->buttons & ~plugin->prev_buttons;
704                released = ~plugin->data->buttons & plugin->prev_buttons;
[15d141c]705                for (i=0; i < plugin->info->button_count; i++) {
[c033b7a]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                                }
[15d141c]713                        }
714                }
[49e0132]715                plugin->prev_buttons = plugin->data->buttons;
[15d141c]716
717                /* Plugin Axis Events */
718                for (i=0; i < plugin->info->axis_count; i++) {
[49e0132]719                        if (plugin->amap[i].active && plugin->data->axes &&
720                          plugin->data->axes[i].valid) {
721                                axis_value = plugin->data->axes[i].value;
[15d141c]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.