Warning, file /multimedia/kdenlive/src/lib/external/media_ctrl/mediactrl.c was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 mediactrl.c -- Jog Shuttle device support 0003 SPDX-FileCopyrightText: 2001-2007 Dan Dennedy <dan@dennedy.org> 0004 0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include <asm/types.h> 0009 #include <errno.h> 0010 #include <fcntl.h> 0011 #include <stdint.h> 0012 #include <stdio.h> 0013 #include <stdlib.h> 0014 #include <string.h> 0015 #include <sys/ioctl.h> 0016 #include <sys/stat.h> 0017 #include <sys/time.h> 0018 #if defined(Q_OS_LINUX) 0019 #include <asm/types.h> 0020 #endif 0021 #include <fcntl.h> 0022 #include <unistd.h> 0023 0024 #include "mediactrl.h" 0025 0026 static char *_shuttle_name = (char *)"Shuttle"; 0027 static char *_jog_name = (char *)"Jog"; 0028 0029 /* 0030 ShuttlePro v2 keys 0031 */ 0032 static struct media_ctrl_key mc_shuttle_pro_v2_keys[] = { 0033 {0x100, "Button 1", MEDIA_CTRL_F1}, {0x101, "Button 2", MEDIA_CTRL_F2}, {0x102, "Button 3", MEDIA_CTRL_F3}, {0x103, "Button 4", MEDIA_CTRL_F4}, 0034 {0x104, "Button 5", MEDIA_CTRL_B1}, {0x105, "Button 6", MEDIA_CTRL_B2}, {0x106, "Button 7", MEDIA_CTRL_B3}, {0x107, "Button 8", MEDIA_CTRL_B4}, 0035 {0x108, "Button 9", MEDIA_CTRL_B5}, {0x109, "Button 10", MEDIA_CTRL_B6}, {0x10a, "Button 11", MEDIA_CTRL_B7}, {0x10b, "Button 12", MEDIA_CTRL_B8}, 0036 {0x10c, "Button 13", MEDIA_CTRL_B9}, {0x10d, "Button 14", MEDIA_CTRL_B10}, {0x10e, "Button 15", MEDIA_CTRL_B11}, {0, NULL, 0}}; 0037 0038 /* 0039 ShuttlePro keys 0040 */ 0041 static struct media_ctrl_key mc_shuttle_pro_keys[] = {{0x100, "Button 1", MEDIA_CTRL_F1}, {0x101, "Button 2", MEDIA_CTRL_F2}, 0042 {0x102, "Button 3", MEDIA_CTRL_F3}, {0x103, "Button 4", MEDIA_CTRL_F4}, 0043 {0x104, "Button 5", MEDIA_CTRL_B4}, {0x105, "Button 6", MEDIA_CTRL_B2}, 0044 {0x106, "Button 7", MEDIA_CTRL_B1}, {0x107, "Button 8", MEDIA_CTRL_B3}, 0045 {0x108, "Button 9", MEDIA_CTRL_B5}, {0x109, "Button 10", MEDIA_CTRL_B6}, 0046 {0x10a, "Button 11", MEDIA_CTRL_B7}, {0x10b, "Button 12", MEDIA_CTRL_B8}, 0047 {0x10c, "Button 13", MEDIA_CTRL_B9}, {0, NULL, 0}}; 0048 0049 /* 0050 ShuttleXPress keys 0051 */ 0052 static struct media_ctrl_key mc_shuttle_xpress_keys[] = {{0x104, "Button B1", MEDIA_CTRL_B1}, {0x105, "Button B2", MEDIA_CTRL_B2}, 0053 {0x106, "Button B3", MEDIA_CTRL_B3}, {0x107, "Button B4", MEDIA_CTRL_B4}, 0054 {0x108, "Button B5", MEDIA_CTRL_B5}, {0, NULL, 0}}; 0055 0056 /* 0057 JLCooper MCS3 Keys 0058 */ 0059 static struct media_ctrl_key mc_jlcooper_mcs3_keys[] = {{0x107, "F1", MEDIA_CTRL_F1}, 0060 {0x101, "F2", MEDIA_CTRL_F2}, 0061 {0x105, "F3", MEDIA_CTRL_F3}, 0062 {0x102, "F4", MEDIA_CTRL_F4}, 0063 {0x103, "F5", MEDIA_CTRL_F5}, 0064 {0x104, "F6", MEDIA_CTRL_F6}, 0065 {0x10d, "W1", MEDIA_CTRL_B6}, 0066 {0x10e, "W2", MEDIA_CTRL_B4}, 0067 {0x100, "W3", MEDIA_CTRL_B2}, 0068 {0x106, "W4", MEDIA_CTRL_B1}, 0069 {0x110, "W5", MEDIA_CTRL_B3}, 0070 {0x111, "W6", MEDIA_CTRL_B5}, 0071 {0x115, "W7", MEDIA_CTRL_B7}, 0072 {0x116, "STICK_LEFT", MEDIA_CTRL_STICK_LEFT}, 0073 {0x113, "STICK_RIGHT", MEDIA_CTRL_STICK_RIGHT}, 0074 {0x114, "STICK_UP", MEDIA_CTRL_STICK_UP}, 0075 {0x112, "STICK_DOWN", MEDIA_CTRL_STICK_DOWN}, 0076 {0x10f, "Rewind", MEDIA_CTRL_REWIND}, 0077 {0x108, "Fast Forward", MEDIA_CTRL_FAST_FORWARD}, 0078 {0x109, "Stop", MEDIA_CTRL_STOP}, 0079 {0x10a, "Play", MEDIA_CTRL_PLAY}, 0080 {0x10b, "Record", MEDIA_CTRL_RECORD}, 0081 {0, NULL, 0}}; 0082 0083 /* 0084 Griffin PowerMate 0085 */ 0086 static struct media_ctrl_key mc_powermate_keys[] = {{BTN_0, "Button", MEDIA_CTRL_B1}, {0, NULL, 0}}; 0087 0088 /* 0089 X-Keys Jog/Shuttle 0090 */ 0091 static struct media_ctrl_key mc_x_keys[] = {{0x102, "Button L1", MEDIA_CTRL_F1}, 0092 {0x103, "Button L2", MEDIA_CTRL_F9}, 0093 {0x104, "Button L3", MEDIA_CTRL_B1}, 0094 {0x105, "Button L4", MEDIA_CTRL_B3}, 0095 {0x106, "Button L5", MEDIA_CTRL_B5}, 0096 {0x10a, "Button L6", MEDIA_CTRL_F2}, 0097 {0x10b, "Button L7", MEDIA_CTRL_F10}, 0098 {0x10c, "Button L8", MEDIA_CTRL_B2}, 0099 {0x10d, "Button L9", MEDIA_CTRL_B4}, 0100 {0x10e, "Button L10", MEDIA_CTRL_B6}, 0101 {0x112, "Button C1", MEDIA_CTRL_F3}, 0102 {0x11a, "Button C2", MEDIA_CTRL_F4}, 0103 {0x122, "Button C3", MEDIA_CTRL_F5}, 0104 {0x12a, "Button C4", MEDIA_CTRL_F6}, 0105 {0x113, "Button C5", MEDIA_CTRL_F11}, 0106 {0x11b, "Button C6", MEDIA_CTRL_F12}, 0107 {0x123, "Button C7", MEDIA_CTRL_F13}, 0108 {0x12b, "Button C8", MEDIA_CTRL_F14}, 0109 {0x132, "Button R1", MEDIA_CTRL_F7}, 0110 {0x133, "Button R2", MEDIA_CTRL_F15}, 0111 {0x134, "Button R3", MEDIA_CTRL_B7}, 0112 {0x135, "Button R4", MEDIA_CTRL_B9}, 0113 {0x136, "Button R5", MEDIA_CTRL_B11}, 0114 {0x13a, "Button R6", MEDIA_CTRL_F8}, 0115 {0x13b, "Button R7", MEDIA_CTRL_F16}, 0116 {0x13c, "Button R8", MEDIA_CTRL_B8}, 0117 {0x13d, "Button R9", MEDIA_CTRL_B10}, 0118 {0x13e, "Button R10", MEDIA_CTRL_B12}, 0119 {0, NULL, 0}}; 0120 0121 struct media_ctrl_key *media_ctrl_get_key(struct media_ctrl *ctrl, int code, int *index) 0122 { 0123 int i = 0; 0124 struct media_ctrl_key *keys = ctrl->device->keys; 0125 0126 while (keys[i].key != 0) { 0127 if (keys[i].key == code) { 0128 if (index != NULL) *index = i; 0129 return &keys[i]; 0130 } 0131 i++; 0132 } 0133 0134 return NULL; 0135 } 0136 0137 int media_ctrl_get_keys_count(struct media_ctrl *ctrl) 0138 { 0139 int i = 0; 0140 struct media_ctrl_key *keys = ctrl->device->keys; 0141 0142 while (keys[i].key != 0) { 0143 i++; 0144 } 0145 0146 return i; 0147 } 0148 0149 void translate_contour_hid_event(struct media_ctrl *ctrl, struct input_event *ev, struct media_ctrl_event *me) 0150 { 0151 me->type = 0; 0152 0153 if (ev->type == EV_REL) { 0154 int cv; 0155 /* First check the outer dial */ 0156 if (ev->code == REL_WHEEL) { 0157 0158 cv = (signed int)ev->value; 0159 if (cv == 1 || cv == -1) cv = 0; 0160 0161 if (cv == ctrl->lastshu) return; 0162 ctrl->lastshu = cv; 0163 0164 /* TODO: review this change */ 0165 if (cv > 0) cv -= 1; 0166 if (cv < 0) cv += 1; 0167 0168 // printf("Shuttle: %d\n", cv); 0169 me->type = MEDIA_CTRL_EVENT_SHUTTLE; 0170 me->value = cv * 2; 0171 me->name = _shuttle_name; 0172 0173 } else if (ev->code == REL_DIAL) { 0174 int lv; 0175 0176 if (ctrl->lastval == -1) ctrl->lastval = ev->value; 0177 lv = ctrl->lastval; 0178 cv = ev->value; 0179 0180 if (lv == cv) return; 0181 0182 ctrl->lastval = cv; 0183 0184 if (cv < 10 && lv > 0xF0) cv += 0x100; 0185 if (lv < 10 && cv > 0xF0) lv += 0x100; 0186 0187 me->type = MEDIA_CTRL_EVENT_JOG; 0188 me->value = cv - lv; 0189 me->name = _jog_name; 0190 0191 ctrl->jogpos += me->value; 0192 // printf("Jog: %06ld (%d)\n", ctrl->jogpos, me->value); 0193 } 0194 return; 0195 } 0196 if (ev->type == EV_KEY) { 0197 int index; 0198 struct media_ctrl_key *key = media_ctrl_get_key(ctrl, ev->code, &index); 0199 if (key == NULL) return; 0200 0201 me->type = MEDIA_CTRL_EVENT_KEY; 0202 me->code = key->code; 0203 me->value = ev->value; 0204 me->name = (char *)key->name; 0205 me->index = index; 0206 0207 // printf("Key: %04x %02x: %s\n", ev->code, ev->value, key->name); 0208 } 0209 } 0210 0211 void translate_compliant(struct media_ctrl *ctrl, struct input_event *ev, struct media_ctrl_event *me) 0212 { 0213 me->type = 0; 0214 0215 // printf("Translate %02x %02x\n", ev->type, ev->code ); 0216 0217 if (ev->type == EV_REL) { 0218 if (ev->code == REL_DIAL) { 0219 0220 me->type = MEDIA_CTRL_EVENT_JOG; 0221 me->value = (signed int)ev->value; 0222 me->name = _jog_name; 0223 0224 ctrl->jogpos += me->value; 0225 // printf("Jog: %06ld (%d)\n", ctrl->jogpos, me->value); 0226 } 0227 return; 0228 } 0229 if (ev->type == EV_ABS) { 0230 // printf("ABS\n" ); 0231 if (ev->code == 0x1c || ev->code == ABS_THROTTLE) { 0232 // printf("ABS_MISC\n" ); 0233 me->type = MEDIA_CTRL_EVENT_SHUTTLE; 0234 me->value = (signed int)ev->value; 0235 me->name = _shuttle_name; 0236 0237 ctrl->shuttlepos = me->value; 0238 // printf("Shuttle: %06d (%d)\n", ctrl->shuttlepos, me->value); 0239 } 0240 } else if (ev->type == EV_KEY) { 0241 int index; 0242 struct media_ctrl_key *key = media_ctrl_get_key(ctrl, ev->code, &index); 0243 if (key == NULL) return; 0244 0245 me->type = MEDIA_CTRL_EVENT_KEY; 0246 me->code = key->code; 0247 me->value = ev->value; 0248 me->name = (char *)key->name; 0249 me->index = index; 0250 0251 // printf("Key: %04x %02x: %s\n", ev->code, ev->value, key->name); 0252 } 0253 } 0254 0255 struct media_ctrl_device supported_devices[] = { 0256 {0x0b33, 0x0030, "Contour Design ShuttlePRO v2", mc_shuttle_pro_v2_keys, translate_contour_hid_event}, 0257 {0x0b33, 0x0020, "Contour Design ShuttleXpress", mc_shuttle_xpress_keys, translate_contour_hid_event}, 0258 {0x0b33, 0x0010, "Contour Design ShuttlePro", mc_shuttle_pro_keys, translate_contour_hid_event}, 0259 {0x0b33, 0x0011, "Contour Design ShuttlePro", mc_shuttle_pro_keys, translate_contour_hid_event}, /* Hercules OEM */ 0260 {0x05f3, 0x0240, "Contour Design ShuttlePro", mc_shuttle_pro_keys, translate_contour_hid_event}, 0261 {0x0760, 0x0001, "JLCooper MCS3", mc_jlcooper_mcs3_keys, translate_compliant}, 0262 {0x077d, 0x0410, "Griffin PowerMate", mc_powermate_keys, translate_compliant}, 0263 {0x05f3, 0x0241, "X-Keys Editor", mc_x_keys, translate_contour_hid_event}, 0264 {0, 0, 0, 0, 0}}; 0265 0266 void media_ctrl_read_event(struct media_ctrl *ctrl, struct media_ctrl_event *me) 0267 { 0268 ssize_t n; 0269 struct input_event ev; 0270 0271 // struct media_ctrl_event me; 0272 0273 if (ctrl->fd > 0) { 0274 n = read(ctrl->fd, &ev, sizeof(ev)); 0275 } else { 0276 return; 0277 } 0278 0279 if (n != sizeof(ev)) { 0280 // printf("JogShuttle::inputCallback: read: (%d) %s\n", errno, strerror(errno)); 0281 close(ctrl->fd); 0282 ctrl->fd = -1; 0283 return; 0284 } 0285 0286 if (ctrl->device && ctrl->device->translate) 0287 ctrl->device->translate(ctrl, &ev, me); 0288 else 0289 me->type = 0; 0290 0291 if (me->type == MEDIA_CTRL_EVENT_JOG) { 0292 struct timeval timev; 0293 gettimeofday(&timev, NULL); 0294 unsigned long now = (unsigned long)timev.tv_usec + (1000000 * (unsigned long)timev.tv_sec); 0295 if (now < ctrl->last_jog_time + 40000) { 0296 // printf("*** Fast Jog %02d %05d ***\n", me->value, now - ctrl->last_jog_time); 0297 ctrl->jogrel = me->value; 0298 me->type = MEDIA_CTRL_EVENT_NONE; 0299 } else { 0300 me->value += ctrl->jogrel; 0301 ctrl->jogrel = 0; 0302 ctrl->last_jog_time = now; 0303 // printf("*** Jog %02d ***\n", me->value); 0304 } 0305 } 0306 } 0307 0308 int probe_device(struct media_ctrl *mc) 0309 { 0310 short devinfo[4]; 0311 int i = 0; 0312 0313 if (ioctl(mc->fd, EVIOCGID, &devinfo)) { 0314 perror("evdev ioctl"); 0315 return 0; 0316 } 0317 0318 do { 0319 if (supported_devices[i].vendor == devinfo[1] && supported_devices[i].product == devinfo[2]) { 0320 0321 mc->device = &supported_devices[i]; 0322 // printf("Success on /dev/input/event%d: %s\n", mc->eventno, mc->device->name); 0323 // mc->fd = fd; 0324 // mc->translate = mc->device.translate_function; 0325 // mc = malloc(sizeof(struct media_ctrl)); 0326 mc->jogpos = 0; 0327 mc->lastval = -1; 0328 mc->last_jog_time = 0; 0329 return 1; 0330 } 0331 // mc->device = NULL; 0332 0333 } while (supported_devices[++i].vendor != 0); 0334 0335 return 0; 0336 } 0337 0338 void find_first_device(struct media_ctrl *mc) 0339 { 0340 char buf[256]; 0341 int i; 0342 0343 for (i = 0; i < 32; i++) { 0344 sprintf(buf, "/dev/input/event%d", i); 0345 int fd = open(buf, O_RDONLY); 0346 if (fd < 0) { 0347 perror(buf); 0348 } else { 0349 mc->fd = fd; 0350 mc->eventno = i; 0351 if (probe_device(mc)) { 0352 return; 0353 } 0354 close(fd); 0355 mc->fd = -1; 0356 } 0357 } 0358 } 0359 0360 void media_ctrl_close(struct media_ctrl *mc) 0361 { 0362 if (mc->fd > 0) close(mc->fd); 0363 memset(mc, 0, sizeof(struct media_ctrl)); 0364 } 0365 0366 void media_ctrl_open(struct media_ctrl *mc) 0367 { 0368 find_first_device(mc); 0369 } 0370 0371 void media_ctrl_open_dev(struct media_ctrl *mc, const char *devname) 0372 { 0373 int fd; 0374 0375 fd = open(devname, O_RDONLY); 0376 if (fd < 0) { 0377 perror(devname); 0378 mc->fd = -1; 0379 } else { 0380 mc->fd = fd; 0381 // mc->eventno = i; 0382 if (probe_device(mc)) { 0383 return; 0384 } 0385 close(fd); 0386 mc->fd = -1; 0387 } 0388 }