~alexandre-hardy/linuxjoymap/linuxjoymap

« back to all changes in this revision

Viewing changes to events.c

  • Committer: Alexandre Hardy
  • Date: 2009-07-17 09:20:57 UTC
  • Revision ID: ah@zenwalk-20090717092057-oxa4o16isawqa7ue
Initial creation of project

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Joystick remapper for the input driver suite.
 
3
 * by Alexandre Hardy 
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 */
 
10
 
 
11
 
 
12
#include <fcntl.h>
 
13
#include <linux/input.h>
 
14
#include <unistd.h>
 
15
#include <poll.h>
 
16
#include <string.h>
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
#include "mapper.h"
 
20
 
 
21
#define MAX_SIGNALS             16
 
22
#define MAX_EVENTS              32
 
23
 
 
24
#define MSECS(t)        (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
 
25
 
 
26
#define TIMEOUT                 20 //(50 times a second)
 
27
 
 
28
#undef press
 
29
#undef release
 
30
 
 
31
struct shift_map {
 
32
        struct program_button_remap *button_press[KEY_MAX+1];
 
33
        struct program_button_remap *button_release[KEY_MAX+1];
 
34
        struct program_axis_remap *axes[ABS_MAX+1];
 
35
};
 
36
 
 
37
struct mapping {
 
38
        int fd; /* /dev/input/event* file descriptor */
 
39
        __u16 vendor;
 
40
        __u16 product;
 
41
        int jsnum;
 
42
        int mapped;
 
43
        //two maps, one for shifted, and one for not shifted
 
44
        struct shift_map map[2];
 
45
};
 
46
 
 
47
static int shifted=0;
 
48
static __u16 shift_vendor;
 
49
static __u16 shift_product;
 
50
static __u16 shift_button;
 
51
struct mapping *events[MAX_EVENTS];
 
52
 
 
53
//install after creating joysticks and code joystick
 
54
//our joysticks are vendor 0xff and product 0x01 and must not be handled
 
55
//our mice are vendor 0xff and product 0x02 and must not be handled
 
56
//our kbd are vendor 0xff and product 0x03 and must not be handled
 
57
//the code joystick is 0xff and product 0x00 
 
58
//the code joystick must be handled by our code
 
59
void install_event_handlers() {
 
60
        int i, j;       
 
61
        char name[256];
 
62
        struct input_id id;
 
63
        for (i=0; i<=MAX_EVENTS; i++) {
 
64
                sprintf(name, "/dev/input/event%d", i);
 
65
                int fd=open(name, O_RDONLY|O_NONBLOCK);
 
66
                if (fd<0) {
 
67
                        events[i]=NULL;
 
68
                } else {
 
69
                        ioctl(fd, EVIOCGID, &id);
 
70
                        if ((id.vendor==0x00ff)&&(id.product!=0x0000)) {
 
71
                                events[i]=NULL;
 
72
                                continue;
 
73
                        }
 
74
                        events[i]=(struct mapping *)malloc(sizeof(struct mapping));
 
75
                        events[i]->fd=fd;
 
76
                        events[i]->vendor=id.vendor;
 
77
                        events[i]->product=id.product;
 
78
                        events[i]->jsnum=-1;
 
79
                        events[i]->mapped=0;
 
80
 
 
81
                        for (j=0; j<KEY_MAX+1; j++) {
 
82
                                events[i]->map[0].button_press[j]=NULL;
 
83
                                events[i]->map[0].button_release[j]=NULL;
 
84
                                events[i]->map[1].button_press[j]=NULL;
 
85
                                events[i]->map[1].button_release[j]=NULL;
 
86
                        }
 
87
                        for (j=0; j<ABS_MAX+1; j++) {
 
88
                                events[i]->map[0].axes[j]=NULL;
 
89
                                events[i]->map[1].axes[j]=NULL;
 
90
                        }
 
91
                }
 
92
        }
 
93
}
 
94
 
 
95
 
 
96
static void process_key(struct mapping *mapper, int key, int value);
 
97
static void process_axis(struct mapping *mapper, int axis, int value);
 
98
void poll_joystick_loop() {
 
99
        int i, j, n=0;
 
100
        struct pollfd polled_fds[MAX_EVENTS];
 
101
        struct mapping *poll_mapper[MAX_EVENTS];
 
102
        struct input_event ev[64];
 
103
        int rb;
 
104
        for (i=0; i<MAX_EVENTS; i++) {
 
105
                if (events[i] && (events[i]->mapped)) {
 
106
                        poll_mapper[n]=events[i];
 
107
                        polled_fds[n].fd=events[i]->fd;
 
108
                        polled_fds[n++].events=POLLIN;
 
109
                }
 
110
        }
 
111
 
 
112
        poll(polled_fds, n, TIMEOUT);
 
113
        for (i=0; i<n; i++) {
 
114
                if (polled_fds[i].revents&POLLIN) {
 
115
                        rb=1;
 
116
                        while (rb>0) {
 
117
                                rb=read(polled_fds[i].fd, ev, sizeof(struct input_event)*64);
 
118
                                if (rb>0)
 
119
                                for (j=0; j<(int)(rb/sizeof(struct input_event)); j++) {
 
120
                                        if (ev[j].type==EV_KEY) {
 
121
                                                if ((ev[j].code >= BTN_MISC) && (ev[j].value != 2)) 
 
122
                                                        process_key(poll_mapper[i], ev[j].code, ev[j].value); 
 
123
                                        }
 
124
                                        if (ev[j].type==EV_ABS)
 
125
                                                process_axis(poll_mapper[i], ev[j].code, ev[j].value);
 
126
                                }
 
127
                        }
 
128
                }
 
129
        }
 
130
        program_run();
 
131
}
 
132
 
 
133
static int nsignals=0;
 
134
static int signals[MAX_SIGNALS];
 
135
static int sighead=0;
 
136
static int sigtail=0;
 
137
int no_signal(void) {
 
138
        return (nsignals==0);
 
139
}
 
140
 
 
141
int goto_next_signal(void) {
 
142
        int r=signals[sighead];
 
143
        nsignals--;
 
144
        sighead++;
 
145
        sighead=sighead%MAX_SIGNALS;
 
146
        return r;
 
147
}
 
148
 
 
149
void push_signal(int signal) {
 
150
        //silently drop signals if too many are sent
 
151
        if (nsignals>=MAX_SIGNALS) return;
 
152
        nsignals++;
 
153
        signals[sigtail]=signal;
 
154
        sigtail++;
 
155
        sigtail=sigtail%MAX_SIGNALS;
 
156
}
 
157
 
 
158
static void process_key(struct mapping *mapper, int key, int value) {
 
159
        int button=0;
 
160
        int i, j;
 
161
        struct program_button_remap **button_remap;
 
162
 
 
163
        if ((mapper->vendor==shift_vendor)||(mapper->product==shift_product)) {
 
164
                if (key==shift_button) {
 
165
                        shifted=value;
 
166
                        if (shifted!=0) shifted=1;
 
167
                }
 
168
        }
 
169
 
 
170
        if ((mapper->vendor!=0x00ff)||(mapper->product!=0x0000))
 
171
                code_notify_button(mapper->jsnum, key, value);
 
172
        if (value==1) button_remap=mapper->map[shifted].button_press;
 
173
        else if (value==0) button_remap=mapper->map[shifted].button_release;
 
174
        else return;
 
175
        if (button_remap==NULL) return;
 
176
        if (button_remap[key]==NULL) return;
 
177
        
 
178
        j=button_remap[key]->device&0x0F;
 
179
        switch (button_remap[key]->device&0xF0) {
 
180
                case DEVICE_JOYSTICK:
 
181
                        if (button_remap[key]->type==TYPE_BUTTON) {
 
182
                                for (i=0; (i<MAX_SEQUENCE) && (button_remap[key]->sequence[i]!=SEQUENCE_DONE); i++) {
 
183
                                        button=button_remap[key]->sequence[i]&KEYMASK;
 
184
                                        if (button_remap[key]->sequence[i]&RELEASEMASK) value=0;
 
185
                                        else value=1;
 
186
                                        press_joy_button(j, button, value);
 
187
                                        if ((button_remap[key]->flags&FLAG_AUTO_RELEASE)&&(value==1)) {
 
188
                                                press_joy_button(j, button, 0);
 
189
                                        }
 
190
                                }
 
191
                        } else if (button_remap[key]->type==TYPE_AXIS) {
 
192
                                //it is an axis
 
193
                                if (value==1) value=32767;
 
194
                                if (button_remap[key]->flags&FLAG_INVERT) value=-value;
 
195
                                set_joy_axis(j, button_remap[key]->sequence[0], value);         
 
196
                        } 
 
197
                        break;
 
198
                case DEVICE_MOUSE:
 
199
                        if (button_remap[key]->type==TYPE_BUTTON) {
 
200
                                for (i=0; (i<MAX_SEQUENCE) && (button_remap[key]->sequence[i]!=SEQUENCE_DONE); i++) {
 
201
                                        button=button_remap[key]->sequence[i]&KEYMASK;
 
202
                                        if (button_remap[key]->sequence[i]&RELEASEMASK) value=0;
 
203
                                        else value=1;
 
204
                                        press_mouse_button(button, value);
 
205
                                        if ((button_remap[key]->flags&FLAG_AUTO_RELEASE)&&(value==1)) {
 
206
                                                press_mouse_button(button, 0);
 
207
                                        }
 
208
                                }
 
209
                        } else if (button_remap[key]->type==TYPE_AXIS) {
 
210
                                //it is an axis
 
211
                                if (button_remap[key]->flags&FLAG_INVERT) value=-value;
 
212
                                if (button_remap[key]->sequence[0]==ABS_X) 
 
213
                                        move_mouse_x(value);
 
214
                                if (button_remap[key]->sequence[0]==ABS_Y) 
 
215
                                        move_mouse_y(value);
 
216
                                if (button_remap[key]->sequence[0]==ABS_WHEEL) 
 
217
                                        move_mouse_wheel(value);
 
218
                        } 
 
219
                        break;
 
220
                case DEVICE_KBD:
 
221
                        if (button_remap[key]->type==TYPE_BUTTON) {
 
222
                                for (i=0; (i<MAX_SEQUENCE) && (button_remap[key]->sequence[i]!=SEQUENCE_DONE); i++) {
 
223
                                        button=button_remap[key]->sequence[i]&KEYMASK;
 
224
                                        if (button_remap[key]->sequence[i]&RELEASEMASK) value=0;
 
225
                                        else value=1;
 
226
                                        press_key(button, value);
 
227
                                        if ((button_remap[key]->flags&FLAG_AUTO_RELEASE)&&(value==1)) {
 
228
                                                press_key(button, 0);
 
229
                                        }
 
230
                                }
 
231
                        }       
 
232
                        break;
 
233
        }
 
234
}
 
235
 
 
236
static void process_axis(struct mapping *mapper, int axis, int value) {
 
237
        int button=0;
 
238
        int j;
 
239
        struct program_axis_remap **axes_remap;
 
240
 
 
241
        if ((mapper->vendor!=0x00ff)||(mapper->product!=0x0000))
 
242
                code_notify_axis(mapper->jsnum, axis, value);
 
243
        axes_remap=mapper->map[shifted].axes;
 
244
        if (axes_remap==NULL) return;
 
245
        if (axes_remap[axis]==NULL) return;
 
246
        j=axes_remap[axis]->device&0x0F;
 
247
        switch (axes_remap[axis]->device&0xF0) {
 
248
                case DEVICE_JOYSTICK:
 
249
                        if (axes_remap[axis]->type==TYPE_BUTTON) {
 
250
                                //a joystick button
 
251
                                if (value<0)
 
252
                                        button=axes_remap[axis]->minus&KEYMASK;
 
253
                                else
 
254
                                        button=axes_remap[axis]->plus&KEYMASK;
 
255
                                value=1;
 
256
                                press_joy_button(j, button, 1);
 
257
                                if (axes_remap[axis]->flags&FLAG_AUTO_RELEASE) {
 
258
                                        press_joy_button(j, button, 0);
 
259
                                }
 
260
                        } else if (axes_remap[axis]->type==TYPE_AXIS) {
 
261
                                //it is an axis
 
262
                                if (axes_remap[axis]->flags&FLAG_INVERT) value=-value;
 
263
                                set_joy_axis(j, axes_remap[axis]->axis, value);         
 
264
                        } 
 
265
                        break;
 
266
                case DEVICE_MOUSE:
 
267
                        if (axes_remap[axis]->type==TYPE_BUTTON) {
 
268
                                //a joystick button
 
269
                                if (value<0)
 
270
                                        button=axes_remap[axis]->minus&KEYMASK;
 
271
                                else
 
272
                                        button=axes_remap[axis]->plus&KEYMASK;
 
273
                                value=1;
 
274
                                press_mouse_button(button, 1);
 
275
                                if (axes_remap[axis]->flags&FLAG_AUTO_RELEASE) {
 
276
                                        press_mouse_button(button, 0);
 
277
                                }
 
278
                        } else if (axes_remap[axis]->type==TYPE_AXIS) {
 
279
                                //it is an axis
 
280
                                value-=127;
 
281
                                value/=32;
 
282
                                if (axes_remap[axis]->flags&FLAG_INVERT) value=-value;
 
283
                                //if (value>0) value=1;
 
284
                                //if (value<0) value=-1;
 
285
                                if (axes_remap[axis]->axis==ABS_X) 
 
286
                                        move_mouse_x(value);
 
287
                                if (axes_remap[axis]->axis==ABS_Y) 
 
288
                                        move_mouse_y(value);
 
289
                                if (axes_remap[axis]->axis==ABS_WHEEL) 
 
290
                                        move_mouse_wheel(value);
 
291
                        } 
 
292
                        break;
 
293
                case DEVICE_KBD:
 
294
                        if (axes_remap[axis]->type==TYPE_BUTTON) {
 
295
                                //a joystick button
 
296
                                if (value<0)
 
297
                                        button=axes_remap[axis]->minus&KEYMASK;
 
298
                                else
 
299
                                        button=axes_remap[axis]->plus&KEYMASK;
 
300
                                value=1;
 
301
                                press_key(button, 1);
 
302
                                if (axes_remap[axis]->flags&FLAG_AUTO_RELEASE) {
 
303
                                        press_key(button, 0);
 
304
                                }
 
305
                        }       
 
306
                        break;
 
307
        }
 
308
}
 
309
 
 
310
void remap_axis(struct program_axis_remap *axis) {
 
311
        struct mapping *mapper;
 
312
        int i, shifted;
 
313
 
 
314
        if (axis->program!=PROGRAM_AXIS_REMAP) return;
 
315
        if (axis->srcaxis>ABS_MAX) return;
 
316
        
 
317
        mapper=NULL;
 
318
        for (i=0; i<MAX_EVENTS; i++) {
 
319
                if (events[i])
 
320
                        if ((events[i]->vendor==axis->vendor)&&
 
321
                           (events[i]->product==axis->product))
 
322
                                mapper=events[i];
 
323
        }
 
324
        
 
325
        if (mapper==NULL) return;
 
326
        mapper->mapped=1;
 
327
        ioctl(mapper->fd, EVIOCGRAB, 1);
 
328
 
 
329
        shifted=0;
 
330
        if (axis->flags&FLAG_SHIFT) shifted=1;
 
331
        mapper->map[shifted].axes[axis->srcaxis]=axis;
 
332
}
 
333
 
 
334
void remap_button(struct program_button_remap *btn) {
 
335
        struct mapping *mapper;
 
336
        int i, shifted;
 
337
 
 
338
        if (btn->program!=PROGRAM_BUTTON_REMAP) return;
 
339
        if (btn->srcbutton>KEY_MAX) return;
 
340
        
 
341
        mapper=NULL;
 
342
        for (i=0; i<MAX_EVENTS; i++) {
 
343
                if (events[i])
 
344
                        if ((events[i]->vendor==btn->vendor)&&
 
345
                           (events[i]->product==btn->product))
 
346
                                mapper=events[i];
 
347
        }
 
348
        
 
349
        if (mapper==NULL) return;
 
350
        mapper->mapped=1;
 
351
        ioctl(mapper->fd, EVIOCGRAB, 1);
 
352
 
 
353
        shifted=0;
 
354
        if (btn->flags&FLAG_SHIFT) shifted=1;
 
355
 
 
356
        if (btn->type==TYPE_SHIFT) {
 
357
                shift_vendor=btn->vendor;
 
358
                shift_product=btn->product;
 
359
                shift_button=btn->srcbutton;
 
360
        } else {
 
361
                if (btn->flags&FLAG_RELEASE)
 
362
                        mapper->map[shifted].button_release[btn->srcbutton]=btn;
 
363
                else
 
364
                        mapper->map[shifted].button_press[btn->srcbutton]=btn;
 
365
        }
 
366
}
 
367
 
 
368
void set_joystick_number(__u16 vendor, __u16 product, int device) {
 
369
        struct mapping *mapper;
 
370
        int i;
 
371
        mapper=NULL;
 
372
        for (i=0; i<MAX_EVENTS; i++) {
 
373
                if (events[i])
 
374
                        if ((events[i]->vendor==vendor)&&
 
375
                           (events[i]->product==product))
 
376
                                mapper=events[i];
 
377
        }
 
378
        
 
379
        if (mapper==NULL) return;
 
380
        mapper->mapped=1;
 
381
        mapper->jsnum=device;
 
382
}