00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <sys/ioctl.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <sys/time.h>
00025 #include <asm/types.h>
00026 #include <fcntl.h>
00027 #include <unistd.h>
00028 #include <stdint.h>
00029 #include <string.h>
00030 #include <errno.h>
00031
00032 #include <linux/input.h>
00033 #include "mediactrl.h"
00034
00035
00036 static char *_shuttle_name = "Shuttle";
00037 static char *_jog_name = "Jog";
00038
00039
00040
00041
00042 static struct media_ctrl_key mc_shuttle_pro_keys[] = {
00043 { 0x100, "Button 1", MEDIA_CTRL_F1 },
00044 { 0x101, "Button 2", MEDIA_CTRL_F2 },
00045 { 0x102, "Button 3", MEDIA_CTRL_F3 },
00046 { 0x103, "Button 4", MEDIA_CTRL_F4 },
00047 { 0x104, "Button 5", MEDIA_CTRL_B4 },
00048 { 0x105, "Button 6", MEDIA_CTRL_B2 },
00049 { 0x106, "Button 7", MEDIA_CTRL_B1 },
00050 { 0x107, "Button 8", MEDIA_CTRL_B3 },
00051 { 0x108, "Button 9", MEDIA_CTRL_B5 },
00052 { 0x109, "Button 10", MEDIA_CTRL_B6 },
00053 { 0x10a, "Button 11", MEDIA_CTRL_B7 },
00054 { 0x10b, "Button 12", MEDIA_CTRL_B8 },
00055 { 0x10c, "Button 13", MEDIA_CTRL_B9 },
00056 { 0, NULL, 0 }
00057 };
00058
00059
00060
00061
00062
00063 static struct media_ctrl_key mc_shuttle_xpress_keys[] = {
00064 { 0x104, "Button B4", MEDIA_CTRL_B4 },
00065 { 0x105, "Button B2", MEDIA_CTRL_B2 },
00066 { 0x106, "Button B1", MEDIA_CTRL_B1 },
00067 { 0x107, "Button B3", MEDIA_CTRL_B3 },
00068 { 0x108, "Button B5", MEDIA_CTRL_B5 },
00069 { 0, NULL, 0 }
00070 };
00071
00072
00073
00074
00075
00076 static struct media_ctrl_key mc_jlcooper_mcs3_keys[] = {
00077 { 0x107, "F1", MEDIA_CTRL_F1 },
00078 { 0x101, "F2", MEDIA_CTRL_F2 },
00079 { 0x105, "F3", MEDIA_CTRL_F3 },
00080 { 0x102, "F4", MEDIA_CTRL_F4 },
00081 { 0x103, "F5", MEDIA_CTRL_F5 },
00082 { 0x104, "F6", MEDIA_CTRL_F6 },
00083 { 0x10d, "W1", MEDIA_CTRL_B6 },
00084 { 0x10e, "W2", MEDIA_CTRL_B4 },
00085 { 0x100, "W3", MEDIA_CTRL_B2 },
00086 { 0x106, "W4", MEDIA_CTRL_B1 },
00087 { 0x110, "W5", MEDIA_CTRL_B3 },
00088 { 0x111, "W6", MEDIA_CTRL_B5 },
00089 { 0x115, "W7", MEDIA_CTRL_B7 },
00090 { 0x116, "STICK_LEFT", MEDIA_CTRL_STICK_LEFT },
00091 { 0x113, "STICK_RIGHT", MEDIA_CTRL_STICK_RIGHT },
00092 { 0x114, "STICK_UP", MEDIA_CTRL_STICK_UP },
00093 { 0x112, "STICK_DOWN", MEDIA_CTRL_STICK_DOWN },
00094 { 0x10f, "Rewind", MEDIA_CTRL_REWIND },
00095 { 0x108, "Fast Forward", MEDIA_CTRL_FAST_FORWARD },
00096 { 0x109, "Stop", MEDIA_CTRL_STOP },
00097 { 0x10a, "Play", MEDIA_CTRL_PLAY },
00098 { 0x10b, "Record", MEDIA_CTRL_RECORD },
00099 { 0, NULL, 0 }
00100 };
00101
00102
00103
00104
00105
00106 static struct media_ctrl_key mc_powermate_keys[] = {
00107 { BTN_0, "Button", MEDIA_CTRL_B1 },
00108 { 0, NULL, 0 }
00109 };
00110
00111
00112
00113
00114
00115 static struct media_ctrl_key mc_x_keys[] = {
00116 { 0x102, "Button L1", MEDIA_CTRL_F1 },
00117 { 0x103, "Button L2", MEDIA_CTRL_F9 },
00118 { 0x104, "Button L3", MEDIA_CTRL_B1 },
00119 { 0x105, "Button L4", MEDIA_CTRL_B3 },
00120 { 0x106, "Button L5", MEDIA_CTRL_B5 },
00121 { 0x10a, "Button L6", MEDIA_CTRL_F2 },
00122 { 0x10b, "Button L7", MEDIA_CTRL_F10 },
00123 { 0x10c, "Button L8", MEDIA_CTRL_B2 },
00124 { 0x10d, "Button L9", MEDIA_CTRL_B4 },
00125 { 0x10e, "Button L10", MEDIA_CTRL_B6 },
00126 { 0x112, "Button C1", MEDIA_CTRL_F3 },
00127 { 0x11a, "Button C2", MEDIA_CTRL_F4 },
00128 { 0x122, "Button C3", MEDIA_CTRL_F5 },
00129 { 0x12a, "Button C4", MEDIA_CTRL_F6 },
00130 { 0x113, "Button C5", MEDIA_CTRL_F11 },
00131 { 0x11b, "Button C6", MEDIA_CTRL_F12 },
00132 { 0x123, "Button C7", MEDIA_CTRL_F13 },
00133 { 0x12b, "Button C8", MEDIA_CTRL_F14 },
00134 { 0x132, "Button R1", MEDIA_CTRL_F7 },
00135 { 0x133, "Button R2", MEDIA_CTRL_F15 },
00136 { 0x134, "Button R3", MEDIA_CTRL_B7 },
00137 { 0x135, "Button R4", MEDIA_CTRL_B9 },
00138 { 0x136, "Button R5", MEDIA_CTRL_B11 },
00139 { 0x13a, "Button R6", MEDIA_CTRL_F8 },
00140 { 0x13b, "Button R7", MEDIA_CTRL_F16 },
00141 { 0x13c, "Button R8", MEDIA_CTRL_B8 },
00142 { 0x13d, "Button R9", MEDIA_CTRL_B10 },
00143 { 0x13e, "Button R10", MEDIA_CTRL_B12 },
00144 { 0, NULL, 0 }
00145 };
00146
00147 struct media_ctrl_key *media_ctrl_get_key(struct media_ctrl *ctrl, int code, int *index)
00148 {
00149 int i = 0;
00150 struct media_ctrl_key *keys = ctrl->device->keys;
00151
00152 while ( keys[i].key != 0 ) {
00153 if (keys[i].key == code) {
00154 if (index != NULL)
00155 *index = i;
00156 return &keys[i];
00157 }
00158 i++;
00159 }
00160
00161 return NULL;
00162 }
00163
00164
00165 void translate_contour_hid_event(struct media_ctrl *ctrl, struct input_event *ev, struct media_ctrl_event *me)
00166 {
00167
00168 int lv, cv;
00169
00170 me->type = 0;
00171
00172 if (ev->type == EV_REL) {
00173
00174 if (ev->code == REL_WHEEL) {
00175
00176 cv = (signed int)ev->value;
00177 if (cv == 1 || cv == -1 ) cv = 0;
00178
00179
00180 if ( cv == ctrl->lastshu ) return;
00181 ctrl->lastshu = cv;
00182
00183
00184 me->type = MEDIA_CTRL_EVENT_SHUTTLE;
00185 me->value = cv*2;
00186 me->name = _shuttle_name;
00187
00188 } else if (ev->code == REL_DIAL) {
00189
00190 if ( ctrl->lastval == -1 ) ctrl->lastval = ev->value;
00191 lv = ctrl->lastval;
00192 cv = ev->value;
00193
00194 if ( lv == cv ) return;
00195
00196 ctrl->lastval = cv;
00197
00198 if (cv < 10 && lv > 0xF0) cv +=0x100;
00199 if (lv < 10 && cv > 0xF0) lv +=0x100;
00200
00201 me->type = MEDIA_CTRL_EVENT_JOG;
00202 me->value = cv-lv;
00203 me->name = _jog_name;
00204
00205 ctrl->jogpos += me->value;
00206
00207 }
00208 return;
00209 } else if (ev->type == EV_KEY) {
00210 int index;
00211 struct media_ctrl_key *key = media_ctrl_get_key(ctrl, ev->code, &index);
00212 if ( key == NULL ) return;
00213
00214 me->type = MEDIA_CTRL_EVENT_KEY;
00215 me->code = key->code;
00216 me->value = ev->value;
00217 me->name = ( char* )key->name;
00218 me->index = index;
00219
00220
00221
00222 }
00223
00224 }
00225
00226 void translate_compliant(struct media_ctrl *ctrl, struct input_event *ev, struct media_ctrl_event *me)
00227 {
00228 me->type = 0;
00229
00230
00231
00232 if (ev->type == EV_REL) {
00233 if (ev->code == REL_DIAL) {
00234
00235 me->type = MEDIA_CTRL_EVENT_JOG;
00236 me->value = (signed int)ev->value;
00237 me->name = _jog_name;
00238
00239 ctrl->jogpos += me->value;
00240
00241 }
00242 return;
00243 } else if (ev->type == EV_ABS) {
00244
00245 if ( ev->code == 0x1c || ev->code == ABS_THROTTLE ) {
00246
00247 me->type = MEDIA_CTRL_EVENT_SHUTTLE;
00248 me->value = (signed int)ev->value;
00249 me->name = _shuttle_name;
00250
00251 ctrl->shuttlepos = me->value;
00252
00253 }
00254 } else if (ev->type == EV_KEY) {
00255 int index;
00256 struct media_ctrl_key *key = media_ctrl_get_key(ctrl, ev->code, &index);
00257 if ( key == NULL ) return;
00258
00259 me->type = MEDIA_CTRL_EVENT_KEY;
00260 me->code = key->code;
00261 me->value = ev->value;
00262 me->name = ( char* )key->name;
00263 me->index = index;
00264
00265
00266
00267 }
00268 }
00269
00270 struct media_ctrl_device supported_devices[] = {
00271 { 0x0b33, 0x0030, "Contour ShuttlePRO v2", mc_shuttle_pro_keys, translate_contour_hid_event },
00272 { 0x0b33, 0x0020, "Contour ShuttleXPress", mc_shuttle_xpress_keys, translate_contour_hid_event },
00273 { 0x0b33, 0x0010, "Contour ShuttlePro", mc_shuttle_pro_keys, translate_contour_hid_event },
00274 { 0x0b33, 0x0011, "Contour ShuttlePro", mc_shuttle_pro_keys, translate_contour_hid_event },
00275 { 0x05f3, 0x0240, "Contour ShuttlePro", mc_shuttle_pro_keys, translate_contour_hid_event },
00276 { 0x0760, 0x0001, "JLCooper MCS3", mc_jlcooper_mcs3_keys, translate_compliant },
00277 { 0x077d, 0x0410, "Griffin PowerMate", mc_powermate_keys, translate_compliant },
00278 { 0x05f3, 0x0241, "X-Keys Editor", mc_x_keys, translate_contour_hid_event },
00279 { 0, 0, 0 }
00280 };
00281
00282
00283 void media_ctrl_translate(struct media_ctrl *ctrl, struct input_event *ev, struct media_ctrl_event *me)
00284 {
00285 if ( ctrl->device ) ctrl->device->translate(ctrl, ev, me);
00286 }
00287
00288
00289 void media_ctrl_read_event(struct media_ctrl *ctrl, struct media_ctrl_event *me)
00290 {
00291 ssize_t n;
00292 struct input_event ev;
00293
00294
00295
00296 if ( ctrl->fd > 0 ) {
00297 n = read(ctrl->fd, &ev, sizeof(ev));
00298 } else {
00299 return;
00300 }
00301
00302 if (n != sizeof(ev)) {
00303
00304 close(ctrl->fd);
00305 ctrl->fd = 0;
00306 return;
00307 }
00308
00309 if ( ctrl->device && ctrl->device->translate)
00310 ctrl->device->translate(ctrl, &ev, me);
00311 else
00312 me->type = 0;
00313
00314 if ( me->type == MEDIA_CTRL_EVENT_JOG ) {
00315 struct timeval timev;
00316 gettimeofday(&timev, NULL);
00317 unsigned long now = (unsigned long)timev.tv_usec + (1000000*(unsigned long)timev.tv_sec);
00318 if ( now < ctrl->last_jog_time + 40000 ) {
00319
00320 ctrl->jogrel = me->value;
00321 me->type = MEDIA_CTRL_EVENT_NONE;
00322 } else {
00323 me->value += ctrl->jogrel;
00324 ctrl->jogrel = 0;
00325 ctrl->last_jog_time = now;
00326
00327 }
00328 }
00329
00330 return;
00331
00332 }
00333
00334
00335 int probe_device(struct media_ctrl *mc)
00336 {
00337 short devinfo[4];
00338 int i = 0;
00339
00340 if ( ioctl(mc->fd, EVIOCGID, &devinfo) ) {
00341 perror("evdev ioctl");
00342 return 0;
00343 }
00344
00345 do {
00346 if ( supported_devices[i].vendor == devinfo[1]
00347 && supported_devices[i].product == devinfo[2] ) {
00348
00349 mc->device = &supported_devices[i];
00350
00351
00352
00353
00354 mc->jogpos = 0;
00355 mc->lastval = -1;
00356 mc->last_jog_time = 0;
00357 return 1;
00358 } else {
00359
00360 }
00361
00362 } while ( supported_devices[++i].vendor != 0 );
00363
00364 return 0;
00365 }
00366
00367
00368 void media_ctrl_get_device_list()
00369 {
00370
00371 }
00372
00373
00374
00375 void find_first_device(struct media_ctrl *mc)
00376 {
00377 char buf[256];
00378 int fd, i;
00379
00380 for ( i = 0; i < 32; i++ ) {
00381 sprintf(buf, "/dev/input/event%d", i);
00382 fd = open( buf, O_RDONLY );
00383 if ( fd < 0 ) {
00384 perror(buf);
00385 } else {
00386 mc->fd = fd;
00387 mc->eventno = i;
00388 if( probe_device(mc) ) {
00389 return;
00390 } else {
00391 close(fd);
00392 mc->fd = -1;
00393 }
00394 }
00395 }
00396 return;
00397 }
00398
00399
00400 void media_ctrl_close(struct media_ctrl *mc)
00401 {
00402 if (mc->fd > 0)
00403 close( mc->fd );
00404 memset( mc, 0, sizeof( struct media_ctrl ) );
00405 }
00406
00407
00408 void media_ctrl_open(struct media_ctrl *mc)
00409 {
00410 find_first_device(mc);
00411 }