~ubuntu-branches/ubuntu/saucy/joystick/saucy-proposed

« back to all changes in this revision

Viewing changes to utils/fftest.c

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2013-05-06 23:03:26 UTC
  • mfrom: (3.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20130506230326-po18icz4mtaa25k1
Tags: 1:1.4.6-1
* New upstream release:
  - Disable CRTSCTS on ELO touchscreens. Closes: #699030. Thanks Thierry
    Bultel!
  - Handle long device names correctly. Closes: #706744. Thanks Ralf
    Jung!
* Drop hardening.patch, merged upstream.
* Standards-Version 3.9.4, no change required.
* Switch to my Debian address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <sys/ioctl.h>
36
36
#include <linux/input.h>
37
37
 
38
 
#define BITS_PER_LONG (sizeof(long) * 8)
39
 
#define OFF(x)  ((x)%BITS_PER_LONG)
40
 
#define BIT(x)  (1UL<<OFF(x))
41
 
#define LONG(x) ((x)/BITS_PER_LONG)
42
 
#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
 
38
#include "bitmaskros.h"
 
39
 
43
40
 
44
41
#define N_EFFECTS 6
45
42
 
55
52
int main(int argc, char** argv)
56
53
{
57
54
        struct ff_effect effects[N_EFFECTS];
58
 
        struct input_event play, stop;
 
55
        struct input_event play, stop, gain;
59
56
        int fd;
60
 
        char device_file_name[64];
61
 
        unsigned long features[4];
 
57
        const char * device_file_name = "/dev/input/event0";
 
58
        unsigned char relFeatures[1 + REL_MAX/8/sizeof(unsigned char)];
 
59
        unsigned char absFeatures[1 + ABS_MAX/8/sizeof(unsigned char)];
 
60
        unsigned char ffFeatures[1 + FF_MAX/8/sizeof(unsigned char)];
62
61
        int n_effects;  /* Number of effects the device can play at the same time */
63
62
        int i;
64
63
 
65
64
        printf("Force feedback test program.\n");
66
65
        printf("HOLD FIRMLY YOUR WHEEL OR JOYSTICK TO PREVENT DAMAGES\n\n");
67
66
 
68
 
        strncpy(device_file_name, "/dev/input/event0", 64);
69
 
 
70
67
        for (i=1; i<argc; ++i) {
71
68
                if (strncmp(argv[i], "--help", 64) == 0) {
72
69
                        printf("Usage: %s /dev/input/eventXX\n", argv[0]);
74
71
                        exit(1);
75
72
                }
76
73
                else {
77
 
                        strncpy(device_file_name, argv[i], 64);
 
74
                        device_file_name = argv[i];
78
75
                }
79
76
        }
80
77
 
87
84
        printf("Device %s opened\n", device_file_name);
88
85
 
89
86
        /* Query device */
90
 
        if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features) < 0) {
91
 
                perror("Ioctl query");
92
 
                exit(1);
93
 
        }
94
 
 
95
 
        printf("Axes query: ");
96
 
 
97
 
        if (test_bit(ABS_X, features)) printf("Axis X ");
98
 
        if (test_bit(ABS_Y, features)) printf("Axis Y ");
99
 
        if (test_bit(ABS_WHEEL, features)) printf("Wheel ");
100
 
 
101
 
        printf("\nEffects: ");
102
 
 
103
 
        if (test_bit(FF_CONSTANT, features)) printf("Constant ");
104
 
        if (test_bit(FF_PERIODIC, features)) printf("Periodic ");
105
 
        if (test_bit(FF_SPRING, features)) printf("Spring ");
106
 
        if (test_bit(FF_FRICTION, features)) printf("Friction ");
107
 
        if (test_bit(FF_RUMBLE, features)) printf("Rumble ");
108
 
 
109
 
        printf("\nNumber of simultaneous effects: ");
110
 
 
111
 
        if (ioctl(fd, EVIOCGEFFECTS, &n_effects) < 0) {
 
87
        printf("Features:\n");
 
88
 
 
89
        /* Absolute axes */
 
90
        memset(absFeatures, 0, sizeof(absFeatures)*sizeof(unsigned char));
 
91
        if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absFeatures)*sizeof(unsigned char)), absFeatures) == -1) {
 
92
                perror("Ioctl absolute axes features query");
 
93
                exit(1);
 
94
        }
 
95
 
 
96
        printf("  * Absolute axes: ");
 
97
 
 
98
        if (testBit(ABS_X, absFeatures)) printf("X, ");
 
99
        if (testBit(ABS_Y, absFeatures)) printf("Y, ");
 
100
        if (testBit(ABS_Z, absFeatures)) printf("Z, ");
 
101
        if (testBit(ABS_RX, absFeatures)) printf("RX, ");
 
102
        if (testBit(ABS_RY, absFeatures)) printf("RY, ");
 
103
        if (testBit(ABS_RZ, absFeatures)) printf("RZ, ");
 
104
        if (testBit(ABS_THROTTLE, absFeatures)) printf("Throttle, ");
 
105
        if (testBit(ABS_RUDDER, absFeatures)) printf("Rudder, ");
 
106
        if (testBit(ABS_WHEEL, absFeatures)) printf("Wheel, ");
 
107
        if (testBit(ABS_GAS, absFeatures)) printf("Gas, ");
 
108
        if (testBit(ABS_BRAKE, absFeatures)) printf("Brake, ");
 
109
        if (testBit(ABS_HAT0X, absFeatures)) printf("Hat 0 X, ");
 
110
        if (testBit(ABS_HAT0Y, absFeatures)) printf("Hat 0 Y, ");
 
111
        if (testBit(ABS_HAT1X, absFeatures)) printf("Hat 1 X, ");
 
112
        if (testBit(ABS_HAT1Y, absFeatures)) printf("Hat 1 Y, ");
 
113
        if (testBit(ABS_HAT2X, absFeatures)) printf("Hat 2 X, ");
 
114
        if (testBit(ABS_HAT2Y, absFeatures)) printf("Hat 2 Y, ");
 
115
        if (testBit(ABS_HAT3X, absFeatures)) printf("Hat 3 X, ");
 
116
        if (testBit(ABS_HAT3Y, absFeatures)) printf("Hat 3 Y, ");
 
117
        if (testBit(ABS_PRESSURE, absFeatures)) printf("Pressure, ");
 
118
        if (testBit(ABS_DISTANCE, absFeatures)) printf("Distance, ");
 
119
        if (testBit(ABS_TILT_X, absFeatures)) printf("Tilt X, ");
 
120
        if (testBit(ABS_TILT_Y, absFeatures)) printf("Tilt Y, ");
 
121
        if (testBit(ABS_TOOL_WIDTH, absFeatures)) printf("Tool width, ");
 
122
        if (testBit(ABS_VOLUME, absFeatures)) printf("Volume, ");
 
123
        if (testBit(ABS_MISC, absFeatures)) printf("Misc ,");
 
124
 
 
125
        printf("\n    [");
 
126
        for (i=0; i<sizeof(absFeatures)/sizeof(unsigned char);i++)
 
127
            printf("%02X ", absFeatures[i]);
 
128
        printf("]\n");
 
129
 
 
130
        /* Relative axes */
 
131
        memset(relFeatures, 0, sizeof(relFeatures)*sizeof(unsigned char));
 
132
        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relFeatures)*sizeof(unsigned char)), relFeatures) == -1) {
 
133
                perror("Ioctl relative axes features query");
 
134
                exit(1);
 
135
        }
 
136
 
 
137
        printf("  * Relative axes: ");
 
138
 
 
139
        if (testBit(REL_X, relFeatures)) printf("X, ");
 
140
        if (testBit(REL_Y, relFeatures)) printf("Y, ");
 
141
        if (testBit(REL_Z, relFeatures)) printf("Z, ");
 
142
        if (testBit(REL_RX, relFeatures)) printf("RX, ");
 
143
        if (testBit(REL_RY, relFeatures)) printf("RY, ");
 
144
        if (testBit(REL_RZ, relFeatures)) printf("RZ, ");
 
145
        if (testBit(REL_HWHEEL, relFeatures)) printf("HWheel, ");
 
146
        if (testBit(REL_DIAL, relFeatures)) printf("Dial, ");
 
147
        if (testBit(REL_WHEEL, relFeatures)) printf("Wheel, ");
 
148
        if (testBit(REL_MISC, relFeatures)) printf("Misc, ");
 
149
 
 
150
        printf("\n    [");
 
151
        for (i=0; i<sizeof(relFeatures)/sizeof(unsigned char);i++)
 
152
            printf("%02X ", relFeatures[i]);
 
153
        printf("]\n");
 
154
 
 
155
        /* Force feedback effects */
 
156
        memset(ffFeatures, 0, sizeof(ffFeatures)*sizeof(unsigned char));
 
157
        if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffFeatures)*sizeof(unsigned char)), ffFeatures) == -1) {
 
158
                perror("Ioctl force feedback features query");
 
159
                exit(1);
 
160
        }
 
161
 
 
162
        printf("  * Force feedback effects types: ");
 
163
 
 
164
        if (testBit(FF_CONSTANT, ffFeatures)) printf("Constant, ");
 
165
        if (testBit(FF_PERIODIC, ffFeatures)) printf("Periodic, ");
 
166
        if (testBit(FF_RAMP, ffFeatures)) printf("Ramp, ");
 
167
        if (testBit(FF_SPRING, ffFeatures)) printf("Spring, ");
 
168
        if (testBit(FF_FRICTION, ffFeatures)) printf("Friction, ");
 
169
        if (testBit(FF_DAMPER, ffFeatures)) printf("Damper, ");
 
170
        if (testBit(FF_RUMBLE, ffFeatures)) printf("Rumble, ");
 
171
        if (testBit(FF_INERTIA, ffFeatures)) printf("Inertia, ");
 
172
        if (testBit(FF_GAIN, ffFeatures)) printf("Gain, ");
 
173
        if (testBit(FF_AUTOCENTER, ffFeatures)) printf("Autocenter, ");
 
174
 
 
175
        printf("\n    Force feedback periodic effects: ");
 
176
 
 
177
        if (testBit(FF_SQUARE, ffFeatures)) printf("Square, ");
 
178
        if (testBit(FF_TRIANGLE, ffFeatures)) printf("Triangle, ");
 
179
        if (testBit(FF_SINE, ffFeatures)) printf("Sine, ");
 
180
        if (testBit(FF_SAW_UP, ffFeatures)) printf("Saw up, ");
 
181
        if (testBit(FF_SAW_DOWN, ffFeatures)) printf("Saw down, ");
 
182
        if (testBit(FF_CUSTOM, ffFeatures)) printf("Custom, ");
 
183
 
 
184
        printf("\n    [");
 
185
        for (i=0; i<sizeof(ffFeatures)/sizeof(unsigned char);i++)
 
186
            printf("%02X ", ffFeatures[i]);
 
187
        printf("]\n");
 
188
 
 
189
        printf("  * Number of simultaneous effects: ");
 
190
 
 
191
        if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) {
112
192
                perror("Ioctl number of effects");
113
193
        }
114
194
 
115
 
        printf("%d\n", n_effects);
 
195
        printf("%d\n\n", n_effects);
 
196
 
 
197
        /* Set master gain to 75% if supported */
 
198
        if (testBit(FF_GAIN, ffFeatures)) {
 
199
                memset(&gain, 0, sizeof(gain));
 
200
                gain.type = EV_FF;
 
201
                gain.code = FF_GAIN;
 
202
                gain.value = 0xC000; /* [0, 0xFFFF]) */
 
203
 
 
204
                printf("Setting master gain to 75%% ... ");
 
205
                fflush(stdout);
 
206
                if (write(fd, &gain, sizeof(gain)) != sizeof(gain)) {
 
207
                  perror("Error:");
 
208
                } else {
 
209
                  printf("OK\n");
 
210
                }
 
211
        }
116
212
 
117
213
        /* download a periodic sinusoidal effect */
 
214
        memset(&effects[0],0,sizeof(effects[0]));
118
215
        effects[0].type = FF_PERIODIC;
119
216
        effects[0].id = -1;
120
217
        effects[0].u.periodic.waveform = FF_SINE;
121
 
        effects[0].u.periodic.period = 0.1*0x100;       /* 0.1 second */
122
 
        effects[0].u.periodic.magnitude = 0x4000;       /* 0.5 * Maximum magnitude */
 
218
        effects[0].u.periodic.period = 10;      /* 0.1 second */
 
219
        effects[0].u.periodic.magnitude = 0x7fff;       /* 0.5 * Maximum magnitude */
123
220
        effects[0].u.periodic.offset = 0;
124
221
        effects[0].u.periodic.phase = 0;
125
222
        effects[0].direction = 0x4000;  /* Along X axis */
126
 
        effects[0].u.periodic.envelope.attack_length = 0x100;
127
 
        effects[0].u.periodic.envelope.attack_level = 0;
128
 
        effects[0].u.periodic.envelope.fade_length = 0x100;
129
 
        effects[0].u.periodic.envelope.fade_level = 0;
 
223
        effects[0].u.periodic.envelope.attack_length = 1000;
 
224
        effects[0].u.periodic.envelope.attack_level = 0x7fff;
 
225
        effects[0].u.periodic.envelope.fade_length = 1000;
 
226
        effects[0].u.periodic.envelope.fade_level = 0x7fff;
130
227
        effects[0].trigger.button = 0;
131
228
        effects[0].trigger.interval = 0;
132
229
        effects[0].replay.length = 20000;  /* 20 seconds */
133
 
        effects[0].replay.delay = 0;
 
230
        effects[0].replay.delay = 1000;
134
231
 
135
 
        if (ioctl(fd, EVIOCSFF, &effects[0]) < 0) {
136
 
                perror("Upload effects[0]");
 
232
        printf("Uploading effect #0 (Periodic sinusoidal) ... ");
 
233
        fflush(stdout);
 
234
        if (ioctl(fd, EVIOCSFF, &effects[0]) == -1) {
 
235
                perror("Error:");
 
236
        } else {
 
237
                printf("OK (id %d)\n", effects[0].id);
137
238
        }
138
239
        
139
240
        /* download a constant effect */
141
242
        effects[1].id = -1;
142
243
        effects[1].u.constant.level = 0x2000;   /* Strength : 25 % */
143
244
        effects[1].direction = 0x6000;  /* 135 degrees */
144
 
        effects[1].u.constant.envelope.attack_length = 0x100;
145
 
        effects[1].u.constant.envelope.attack_level = 0;
146
 
        effects[1].u.constant.envelope.fade_length = 0x100;
147
 
        effects[1].u.constant.envelope.fade_level = 0;
 
245
        effects[1].u.constant.envelope.attack_length = 1000;
 
246
        effects[1].u.constant.envelope.attack_level = 0x1000;
 
247
        effects[1].u.constant.envelope.fade_length = 1000;
 
248
        effects[1].u.constant.envelope.fade_level = 0x1000;
148
249
        effects[1].trigger.button = 0;
149
250
        effects[1].trigger.interval = 0;
150
251
        effects[1].replay.length = 20000;  /* 20 seconds */
151
252
        effects[1].replay.delay = 0;
152
253
 
153
 
        if (ioctl(fd, EVIOCSFF, &effects[1]) < 0) {
154
 
                perror("Upload effects[1]");
 
254
        printf("Uploading effect #1 (Constant) ... ");
 
255
        fflush(stdout);
 
256
        if (ioctl(fd, EVIOCSFF, &effects[1]) == -1) {
 
257
                perror("Error");
 
258
        } else {
 
259
                printf("OK (id %d)\n", effects[1].id);
155
260
        }
156
261
 
157
 
        /* download an condition spring effect */
 
262
        /* download a condition spring effect */
158
263
        effects[2].type = FF_SPRING;
159
264
        effects[2].id = -1;
160
265
        effects[2].u.condition[0].right_saturation = 0x7fff;
169
274
        effects[2].replay.length = 20000;  /* 20 seconds */
170
275
        effects[2].replay.delay = 0;
171
276
 
172
 
        if (ioctl(fd, EVIOCSFF, &effects[2]) < 0) {
173
 
                perror("Upload effects[2]");
 
277
        printf("Uploading effect #2 (Spring) ... ");
 
278
        fflush(stdout);
 
279
        if (ioctl(fd, EVIOCSFF, &effects[2]) == -1) {
 
280
                perror("Error");
 
281
        } else {
 
282
                printf("OK (id %d)\n", effects[2].id);
174
283
        }
175
284
 
176
 
        /* download an condition damper effect */
 
285
        /* download a condition damper effect */
177
286
        effects[3].type = FF_DAMPER;
178
287
        effects[3].id = -1;
179
288
        effects[3].u.condition[0].right_saturation = 0x7fff;
188
297
        effects[3].replay.length = 20000;  /* 20 seconds */
189
298
        effects[3].replay.delay = 0;
190
299
 
191
 
        if (ioctl(fd, EVIOCSFF, &effects[3]) < 0) {
192
 
                perror("Upload effects[3]");
 
300
        printf("Uploading effect #3 (Damper) ... ");
 
301
        fflush(stdout);
 
302
        if (ioctl(fd, EVIOCSFF, &effects[3]) == -1) {
 
303
                perror("Error");
 
304
        } else {
 
305
                printf("OK (id %d)\n", effects[3].id);
193
306
        }
194
307
 
195
308
        /* a strong rumbling effect */
200
313
        effects[4].replay.length = 5000;
201
314
        effects[4].replay.delay = 1000;
202
315
 
203
 
        if (ioctl(fd, EVIOCSFF, &effects[4]) < 0) {
204
 
                perror("Upload effects[4]");
 
316
        printf("Uploading effect #4 (Strong rumble, with heavy motor) ... ");
 
317
        fflush(stdout);
 
318
        if (ioctl(fd, EVIOCSFF, &effects[4]) == -1) {
 
319
                perror("Error");
 
320
        } else {
 
321
                printf("OK (id %d)\n", effects[4].id);
205
322
        }
206
323
 
207
324
        /* a weak rumbling effect */
212
329
        effects[5].replay.length = 5000;
213
330
        effects[5].replay.delay = 0;
214
331
 
215
 
        if (ioctl(fd, EVIOCSFF, &effects[5]) < 0) {
216
 
                perror("Upload effects[5]");
 
332
        printf("Uploading effect #5 (Weak rumble, with light motor) ... ");
 
333
        fflush(stdout);
 
334
        if (ioctl(fd, EVIOCSFF, &effects[5]) == -1) {
 
335
                perror("Error");
 
336
        } else {
 
337
                printf("OK (id %d)\n", effects[5].id);
217
338
        }
218
339
 
219
340
 
220
341
        /* Ask user what effects to play */
221
342
        do {
222
343
                printf("Enter effect number, -1 to exit\n");
223
 
                scanf("%d", &i);
224
 
                if (i >= 0 && i < N_EFFECTS) {
 
344
                i = -1;
 
345
                if (scanf("%d", &i) == EOF) {
 
346
                        printf("Read error\n");
 
347
                }
 
348
                else if (i >= 0 && i < N_EFFECTS) {
 
349
                        memset(&play,0,sizeof(play));
225
350
                        play.type = EV_FF;
226
351
                        play.code = effects[i].id;
227
352
                        play.value = 1;
238
363
                        int i = *((int *)0);
239
364
                        printf("Crash test: %d\n", i);
240
365
                }
241
 
                else {
 
366
                else if (i != -1) {
242
367
                        printf("No such effect\n");
243
368
                }
244
369
        } while (i>=0);
245
370
 
246
371
        /* Stop the effects */
 
372
        printf("Stopping effects\n");
247
373
        for (i=0; i<N_EFFECTS; ++i) {
 
374
                memset(&stop,0,sizeof(stop));
248
375
                stop.type = EV_FF;
249
376
                stop.code =  effects[i].id;
250
377
                stop.value = 0;
251
378
        
252
379
                if (write(fd, (const void*) &stop, sizeof(stop)) == -1) {
253
 
                        perror("Stop effect");
 
380
                        perror("");
254
381
                        exit(1);
255
382
                }
256
383
        }