diff options
Diffstat (limited to 'core/input')
-rw-r--r-- | core/input/appleir.c | 153 | ||||
-rw-r--r-- | core/input/ar.c | 469 | ||||
-rw-r--r-- | core/input/ar.h | 35 | ||||
-rw-r--r-- | core/input/input.c | 93 | ||||
-rw-r--r-- | core/input/input.h | 1 | ||||
-rw-r--r-- | core/input/keycodes.h | 17 |
6 files changed, 46 insertions, 722 deletions
diff --git a/core/input/appleir.c b/core/input/appleir.c deleted file mode 100644 index e645ba736a..0000000000 --- a/core/input/appleir.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Linux Apple IR Remote input interface - * - * Copyright (C) 2008 Benjamin Zores <ben at geexbox dot org> - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include "ar.h" -#include "input.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> - -#include <linux/types.h> -#include <linux/input.h> - -#include "core/mp_msg.h" - -#include "keycodes.h" - -#define EVDEV_MAX_EVENTS 32 - -/* ripped from AppleIR driver */ -#define USB_VENDOR_APPLE 0x05ac -#define USB_DEV_APPLE_IR 0x8240 -#define USB_DEV_APPLE_IR_2 0x8242 - -/* Apple IR Remote evdev mapping */ -#define APPLE_IR_MINUS KEY_VOLUMEDOWN -#define APPLE_IR_PLUS KEY_VOLUMEUP -#define APPLE_IR_MENU KEY_MENU -#define APPLE_IR_FORWARD KEY_NEXTSONG -#define APPLE_IR_PLAY KEY_PLAYPAUSE -#define APPLE_IR_BACKWARD KEY_PREVIOUSSONG - -static const struct { - int linux_keycode; - int value; - int mp_keycode; -} apple_ir_mapping[] = { - { APPLE_IR_PLAY, 1, MP_AR_PLAY }, - { APPLE_IR_PLAY, 2, MP_AR_PLAY_HOLD }, - { APPLE_IR_FORWARD, 1, MP_AR_NEXT }, - { APPLE_IR_FORWARD, 2, MP_AR_NEXT_HOLD }, - { APPLE_IR_BACKWARD, 1, MP_AR_PREV }, - { APPLE_IR_BACKWARD, 2, MP_AR_PREV_HOLD }, - { APPLE_IR_MENU, 1, MP_AR_MENU }, - { APPLE_IR_MENU, 2, MP_AR_MENU_HOLD }, - { APPLE_IR_PLUS, 1, MP_AR_VUP }, - { APPLE_IR_MINUS, 1, MP_AR_VDOWN }, - { -1, -1, -1 } -}; - -int mp_input_appleir_init (char *dev) -{ - int i, fd; - - if (dev) - { - mp_tmsg (MSGT_INPUT, MSGL_V, "Initializing Apple IR on %s\n", dev); - fd = open (dev, O_RDONLY | O_NONBLOCK); - if (fd < 0) - { - mp_tmsg (MSGT_INPUT, MSGL_ERR, - "Can't open Apple IR device: %s\n", strerror (errno)); - return -1; - } - - return fd; - } - else - { - /* look for a valid AppleIR device on system */ - for (i = 0; i < EVDEV_MAX_EVENTS; i++) - { - struct input_id id; - char file[64]; - - sprintf (file, "/dev/input/event%d", i); - fd = open (file, O_RDONLY | O_NONBLOCK); - if (fd < 0) - continue; - - ioctl (fd, EVIOCGID, &id); - if (id.bustype == BUS_USB && - id.vendor == USB_VENDOR_APPLE && - (id.product == USB_DEV_APPLE_IR ||id.product == USB_DEV_APPLE_IR_2)) - { - mp_tmsg (MSGT_INPUT, MSGL_V, "Detected Apple IR on %s\n", file); - return fd; - } - close (fd); - } - - mp_tmsg (MSGT_INPUT, MSGL_ERR, - "Can't open Apple IR device: %s\n", strerror (errno)); - } - - return -1; -} - -int mp_input_appleir_read(void *ctx, int fd) -{ - struct input_event ev; - int i, r; - - r = read (fd, &ev, sizeof (struct input_event)); - if (r <= 0 || r < sizeof (struct input_event)) - return MP_INPUT_NOTHING; - - /* check for key press only */ - if (ev.type != EV_KEY) - return MP_INPUT_NOTHING; - - /* EvDev Key values: - * 0: key release - * 1: key press - * 2: key auto-repeat - */ - if (ev.value == 0) - return MP_INPUT_NOTHING; - - /* find Linux evdev -> MPlayer keycode mapping */ - for (i = 0; apple_ir_mapping[i].linux_keycode != -1; i++) - if (apple_ir_mapping[i].linux_keycode == ev.code && - apple_ir_mapping[i].value == ev.value) - return apple_ir_mapping[i].mp_keycode; - - return MP_INPUT_NOTHING; -} diff --git a/core/input/ar.c b/core/input/ar.c deleted file mode 100644 index 4dc1c27f5a..0000000000 --- a/core/input/ar.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Apple Remote input interface - * - * Copyright (C) 2007 Zoltan Ponekker <pontscho at kac.poliod.hu> - * - * (modified a bit by Ulion <ulion2002 at gmail.com>) - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <IOKit/IOCFPlugIn.h> -#include <IOKit/hid/IOHIDLib.h> -#include <Carbon/Carbon.h> - -#include <sys/types.h> -#include <unistd.h> - -#include "input.h" -#include "ar.h" -#include "keycodes.h" - -extern int slave_mode; - -extern const double NSAppKitVersionNumber; - -typedef struct cookie_keycode_map { - char *cookies; - int seq_len; - int keycode; -} cookie_keycode_map_t; - -/* On tiger, 5 always follows 6; on leopard, 18 always follows 19. - * On leopard, there seems to be no cookie value of 5 or 6. - * Following is the shortened cookie sequence list - * keycode cookies_on_tiger cookies_on_leopard *down_state - * AR_PREV_HOLD 14+6+3+2 31+19+3+2 yes - * AR_NEXT_HOLD 14+6+4+2 31+19+4+2 yes - * AR_MENU_HOLD 14+6+14+6 31+19+31+19 - * AR_VUP 14+12+11+6 31+29+28+19 yes - * AR_VDOWN 14+13+11+6 31+30+28+19 yes - * AR_MENU 14+7+6+14+7+6 31+20+19+31+20+19 - * AR_PLAY 14+8+6+14+8+6 31+21+19+31+21+19 - * AR_NEXT 14+9+6+14+9+6 31+22+19+31+22+19 - * AR_PREV 14+10+6+14+10+6 31+23+19+31+23+19 - * AR_PLAY_HOLD 18+14+6+18+14+6 35+31+19+35+31+19 - * - * *down_state: A button with this feature has a pressed event and - * a released event, with which we can trace the state of the button. - * A button without this feature will only return one release event. - * - * hidden keys currently not implemented: - * hold for 5 secs - * MENU_NEXT_HOLD 15+14+6+15+14+6 - * MENU_PREV_HOLD 16+14+6+16+14+6 - * MENU_VUP_HOLD 20+14+6+20+14+6 - * MENU_VDOWN_HOLD 19+14+6+19+14+6 - * - * It seems that pressing 'menu' and 'play' on the Apple Remote for - * 5 seconds will trigger the make-pair function of the remote. - * MENU_PLAY_HOLD 21+15+14+6+15+14+6 - */ - -static const cookie_keycode_map_t ar_codes_tiger[] = { - { "\x0E\x06\x03\x02", 4, MP_AR_PREV_HOLD }, - { "\x0E\x06\x04\x02", 4, MP_AR_NEXT_HOLD }, - { "\x0E\x06\x0E\x06", 4, MP_AR_MENU_HOLD }, - { "\x0E\x0C\x0B\x06", 4, MP_AR_VUP }, - { "\x0E\x0D\x0B\x06", 4, MP_AR_VDOWN }, - { "\x0E\x07\x06\x0E\x07\x06", 6, MP_AR_MENU }, - { "\x0E\x08\x06\x0E\x08\x06", 6, MP_AR_PLAY }, - { "\x0E\x09\x06\x0E\x09\x06", 6, MP_AR_NEXT }, - { "\x0E\x0A\x06\x0E\x0A\x06", 6, MP_AR_PREV }, - { "\x12\x0E\x06\x12\x0E\x06", 6, MP_AR_PLAY_HOLD }, - { NULL, 0, MP_INPUT_NOTHING }, -}; - -static const cookie_keycode_map_t ar_codes_leopard[] = { - { "\x1F\x13\x03\x02", 4, MP_AR_PREV_HOLD }, - { "\x1F\x13\x04\x02", 4, MP_AR_NEXT_HOLD }, - { "\x1F\x13\x1F\x13", 4, MP_AR_MENU_HOLD }, - { "\x1F\x1D\x1C\x13", 4, MP_AR_VUP }, - { "\x1F\x1E\x1C\x13", 4, MP_AR_VDOWN }, - { "\x1F\x14\x13\x1F\x14\x13", 6, MP_AR_MENU }, - { "\x1F\x15\x13\x1F\x15\x13", 6, MP_AR_PLAY }, - { "\x1F\x16\x13\x1F\x16\x13", 6, MP_AR_NEXT }, - { "\x1F\x17\x13\x1F\x17\x13", 6, MP_AR_PREV }, - { "\x23\x1F\x13\x23\x1F\x13", 6, MP_AR_PLAY_HOLD }, - { NULL, 0, MP_INPUT_NOTHING }, -}; - -static int is_leopard; -static const cookie_keycode_map_t *ar_codes; - -static IOHIDQueueInterface **queue; -static IOHIDDeviceInterface **hidDeviceInterface = NULL; -static int initialized = 0; -static int hidDeviceIsOpen; - -/* Maximum number of elements in queue before oldest elements - in queue begin to be lost. Set to 16 to hold at least 2 events. */ -static const int MAX_QUEUE_SIZE = 16; - - -static int FindHIDDevices(mach_port_t masterPort, - io_iterator_t *hidObjectIterator) -{ - CFMutableDictionaryRef hidMatchDictionary; - IOReturn ioReturnValue; - - // Set up a matching dictionary to search the I/O Registry - // by class name for all HID class devices. - hidMatchDictionary = IOServiceMatching("AppleIRController"); - - // Now search I/O Registry for matching devices. - ioReturnValue = IOServiceGetMatchingServices(masterPort, - hidMatchDictionary, - hidObjectIterator); - - // If search is unsuccessful, print message and hang. - if (ioReturnValue != kIOReturnSuccess || - !IOIteratorIsValid(*hidObjectIterator)) { - return -1; - } - return 0; -} - -static int getHIDCookies(IOHIDDeviceInterface122 **handle, - IOHIDElementCookie **cookies, - int *nr_cookies) -{ - CFTypeRef object; - long number; - CFArrayRef elements; - CFDictionaryRef element; - CFIndex i; - - *nr_cookies = 0; - - if (!handle || !(*handle)) - return -1; - - // Copy all elements, since we're grabbing most of the elements - // for this device anyway, and thus, it's faster to iterate them - // ourselves. When grabbing only one or two elements, a matching - // dictionary should be passed in here instead of NULL. - if (((*handle)->copyMatchingElements(handle, NULL, &elements)) != kIOReturnSuccess) - return -1; - - // No elements, still a valid result. - if (CFArrayGetCount(elements)==0) - return 0; - - *cookies = calloc(CFArrayGetCount(elements), sizeof(IOHIDElementCookie)); - if (*cookies == NULL) - return -1; - - for (i=0; i<CFArrayGetCount(elements); i++) { - element = CFArrayGetValueAtIndex(elements, i); - - // Get cookie. - object = CFDictionaryGetValue(element, CFSTR(kIOHIDElementCookieKey)); - if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) - continue; - if (!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &number)) - continue; - (*cookies)[(*nr_cookies)++] = (IOHIDElementCookie)number; - } - - return 0; -} - -static int CreateHIDDeviceInterface(io_object_t hidDevice, - IOHIDDeviceInterface ***hidDeviceInterface) -{ - io_name_t className; - IOCFPlugInInterface **plugInInterface = NULL; - SInt32 score = 0; - - if (IOObjectGetClass(hidDevice, className) != kIOReturnSuccess) - return -1; - - if (IOCreatePlugInInterfaceForService(hidDevice, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score) != kIOReturnSuccess) - return -1; - - // Call a method of the intermediate plugin to create the device interface - if ((*plugInInterface)->QueryInterface(plugInInterface, - CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), - (LPVOID)hidDeviceInterface) != S_OK - || *hidDeviceInterface == NULL || **hidDeviceInterface == NULL) { - (*plugInInterface)->Release(plugInInterface); - return -1; - } - - (*plugInInterface)->Release(plugInInterface); - - return 0; -} - -int mp_input_ar_init(void) -{ - io_iterator_t hidObjectIterator; - io_object_t hidDevice; - int i; - IOHIDElementCookie *cookies = NULL; - int nr_cookies = 0; - - if (initialized) - mp_input_ar_close(-1); - - if (floor(NSAppKitVersionNumber) <= 824 /* NSAppKitVersionNumber10_4 */) { - ar_codes = &ar_codes_tiger[0]; - is_leopard = 0; - } - else { - ar_codes = &ar_codes_leopard[0]; - is_leopard = 1; - } - - if (FindHIDDevices(kIOMasterPortDefault, &hidObjectIterator)) - return -1; - - // Multiple controls could be found, we only use the first usable one. - while ((hidDevice = IOIteratorNext(hidObjectIterator))) { - if (CreateHIDDeviceInterface(hidDevice, &hidDeviceInterface) < 0) { - hidDeviceInterface = NULL; - IOObjectRelease(hidDevice); - continue; - } - if (getHIDCookies((IOHIDDeviceInterface122 **)hidDeviceInterface, - &cookies, - &nr_cookies) < 0) { - (*hidDeviceInterface)->Release(hidDeviceInterface); - hidDeviceInterface = NULL; - IOObjectRelease(hidDevice); - continue; - } - IOObjectRelease(hidDevice); - break; - } - if (hidDeviceInterface == NULL) - goto mp_input_ar_init_error; - - // Open the device. - if ((*hidDeviceInterface)->open(hidDeviceInterface, - kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) - goto mp_input_ar_init_error; - hidDeviceIsOpen = 1; - - if ((queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface)) == NULL - || *queue == NULL) - goto mp_input_ar_init_error; - - // Create the queue. - (*queue)->create(queue, 0, MAX_QUEUE_SIZE); - - // Add elements to the queue to make the queue work. - // On tiger, it's a sequence from 1 to 21, - // maybe it's the range of cookie values. - for (i = 0;i < nr_cookies;i++) - (*queue)->addElement(queue, cookies[i], 0); - - // not used anymore - free(cookies); - - // Start data delivery to the queue. - (*queue)->start(queue); - - // not useful anymore - IOObjectRelease(hidObjectIterator); - - initialized = 1; - return 0; - -mp_input_ar_init_error: - free(cookies); - if (hidDeviceInterface != NULL) { - if (*hidDeviceInterface != NULL) { - (*hidDeviceInterface)->close(hidDeviceInterface); - (*hidDeviceInterface)->Release(hidDeviceInterface); - } - hidDeviceInterface = NULL; - } - IOObjectRelease(hidObjectIterator); - return -1; -} - -static int is_mplayer_front(void) -{ - ProcessSerialNumber myProc, frProc; - Boolean sameProc; - pid_t parentPID; - - if (GetFrontProcess(&frProc) == noErr - && GetCurrentProcess(&myProc) == noErr - && SameProcess(&frProc, &myProc, &sameProc) == noErr) { - if (sameProc) - return 1; - // If MPlayer is running in slave mode, also check parent process. - if (slave_mode && GetProcessPID(&frProc, &parentPID) == noErr) - return parentPID==getppid(); - } - return 0; -} - -int mp_input_ar_read(void *ctx, int fd) -{ - int i, down = 0; - int ret = MP_INPUT_NOTHING; - AbsoluteTime zeroTime = {0,0}; - IOHIDEventStruct event; - static int prev_event = 0; - IOReturn result = kIOReturnSuccess; - - const cookie_keycode_map_t *ar_code; - int cookie_nr = 0; - char cookie_queue[MAX_QUEUE_SIZE]; - int value_queue[MAX_QUEUE_SIZE]; - - if (initialized == 0) - return MP_INPUT_NOTHING; - - while ((result = (*queue)->getNextEvent(queue, &event, zeroTime, 0)) == kIOReturnSuccess) { -#ifdef TEST - printf(" - event cookie: %d, value: %d, long value: %d\n", - (int)event.elementCookie, (int)event.value, (int)event.longValue); -#endif - // Shorten cookie sequence by removing cookies value 5 and 18, - // since 5 always follows 6 (on tiger), 18 follows 19 (on leopard). - if ((int)event.elementCookie == 5 - || ((int)event.elementCookie == 18 && is_leopard)) - continue; - // Check valid cookie range. - if ((int)event.elementCookie > 35 || (int)event.elementCookie < 2) { - cookie_nr = 0; - continue; - } - cookie_queue[cookie_nr] = (char)(int)event.elementCookie; - value_queue[cookie_nr++] = event.value; - // 4 cookies are necessary to make up a valid sequence. - if (cookie_nr>=4) { - // Find matching sequence. - ar_code = ar_codes; - while (ar_code->cookies != NULL && - (cookie_nr < ar_code->seq_len || - 0 != memcmp(ar_code->cookies, - &cookie_queue[cookie_nr-ar_code->seq_len], - ar_code->seq_len))) - ++ar_code; - if (ar_code->cookies != NULL) { - ret = ar_code->keycode; - switch (ret) { - // For these 4 keys, the remote can keep a hold state. - case MP_AR_VUP: - case MP_AR_VDOWN: - case MP_AR_NEXT_HOLD: - case MP_AR_PREV_HOLD: - for (i = cookie_nr-ar_code->seq_len; i < cookie_nr; ++i) { - if (value_queue[i]) { - down = MP_KEY_STATE_DOWN; - break; - } - } - break; - default: - down = 0; - } - } - } - } - - if (!is_mplayer_front()) { - if (hidDeviceIsOpen) { - (*hidDeviceInterface)->close(hidDeviceInterface); - hidDeviceIsOpen = 0; - - // Read out all pending events. - while (result == kIOReturnSuccess) - result = (*queue)->getNextEvent(queue, &event, zeroTime, 0); - } - return MP_INPUT_NOTHING; - } - // If we are switched from running as a foreground process to a - // background process and back again, re-open the device to make - // sure we are not affected by the system or other applications - // using the Apple Remote. - else if (!hidDeviceIsOpen) { - if ((*hidDeviceInterface)->open(hidDeviceInterface, - kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess) - hidDeviceIsOpen = 1; - } - - if (ret > 0) - prev_event = ret; - return ret | down; -} - -int mp_input_ar_close(int fd) -{ - if (initialized == 0) - return 0; - - // Close the device. - (*hidDeviceInterface)->close(hidDeviceInterface); - - // Stop data delivery to queue. - (*queue)->stop(queue); - // Dispose of queue. - (*queue)->dispose(queue); - // Release the queue we allocated. - (*queue)->Release(queue); - - // Release the interface. - (*hidDeviceInterface)->Release(hidDeviceInterface); - - initialized = 0; - return 0; -} - -#ifdef TEST -int main(void) -{ - int ret; - - if (mp_input_ar_init() < 0) { - printf("Unable to initialize Apple Remote.\n"); - return 1; - } - - while (1) { - switch ((ret = mp_input_ar_read(NULL, 0)) & ~MP_KEY_STATE_DOWN) { - case MP_AR_PLAY: printf(" - MP_AR_PLAY."); break; - case MP_AR_PLAY_HOLD: printf(" - MP_AR_PLAY_HOLD."); break; - case MP_AR_NEXT: printf(" - MP_AR_NEXT."); break; - case MP_AR_NEXT_HOLD: printf(" - MP_AR_NEXT_HOLD."); break; - case MP_AR_PREV: printf(" - MP_AR_PREV."); break; - case MP_AR_PREV_HOLD: printf(" - MP_AR_PREV_HOLD."); break; - case MP_AR_MENU: printf(" - MP_AR_MENU."); break; - case MP_AR_MENU_HOLD: printf(" - MP_AR_MENU_HOLD."); break; - case MP_AR_VUP: printf(" - MP_AR_VUP."); break; - case MP_AR_VDOWN: printf(" - MP_AR_VDOWN."); break; - } - if ((ret > 0 )&&(ret & MP_KEY_STATE_DOWN)) - printf(" [hold]"); - if (ret > 0) - printf("\n"); - } - - mp_input_ar_close(0); - return 0; -} -#endif diff --git a/core/input/ar.h b/core/input/ar.h deleted file mode 100644 index dff6d12f8a..0000000000 --- a/core/input/ar.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Apple Remote input interface - * - * Copyright (C) 2007 Zoltan Ponekker <pontscho at kac.poliod.hu> - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_AR_H -#define MPLAYER_AR_H - -/* MacOSX Driver */ -int mp_input_ar_init(void); -int mp_input_ar_read(void *ctx, int fd); -int mp_input_ar_close(int fd); - -/* Linux Driver */ -int mp_input_appleir_init(char* dev); -int mp_input_appleir_read(void *ctx, int fd); - -#endif /* MPLAYER_AR_H */ diff --git a/core/input/input.c b/core/input/input.c index 6419f28bc1..31b807d92f 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -61,9 +61,7 @@ #include <lirc/lircc.h> #endif -#include "ar.h" - -#define MP_MAX_KEY_DOWN 32 +#define MP_MAX_KEY_DOWN 4 struct cmd_bind { int input[MP_MAX_KEY_DOWN + 1]; @@ -130,6 +128,7 @@ static const mp_cmd_t mp_cmds[] = { { MP_CMD_QUIT, "quit", { OARG_INT(0) } }, { MP_CMD_STOP, "stop", }, { MP_CMD_FRAME_STEP, "frame_step", }, + { MP_CMD_FRAME_BACK_STEP, "frame_back_step", }, { MP_CMD_PLAYLIST_NEXT, "playlist_next", { OARG_CHOICE(0, ({"weak", 0}, {"0", 0}, {"force", 1}, {"1", 1})), @@ -221,7 +220,7 @@ static const struct legacy_cmd legacy_cmds[] = { {"audio_delay", "add audio-delay"}, {"switch_audio", "cycle audio"}, {"balance", "add balance"}, - {"vo_fullscreen", "no-osd cycle fullscreen"}, + {"vo_fullscreen", "cycle fullscreen"}, {"panscan", "add panscan"}, {"vo_ontop", "cycle ontop"}, {"vo_border", "cycle border"}, @@ -388,17 +387,6 @@ static const struct key_name key_names[] = { { MP_JOY_BTN8, "JOY_BTN8" }, { MP_JOY_BTN9, "JOY_BTN9" }, - { MP_AR_PLAY, "AR_PLAY" }, - { MP_AR_PLAY_HOLD, "AR_PLAY_HOLD" }, - { MP_AR_NEXT, "AR_NEXT" }, - { MP_AR_NEXT_HOLD, "AR_NEXT_HOLD" }, - { MP_AR_PREV, "AR_PREV" }, - { MP_AR_PREV_HOLD, "AR_PREV_HOLD" }, - { MP_AR_MENU, "AR_MENU" }, - { MP_AR_MENU_HOLD, "AR_MENU_HOLD" }, - { MP_AR_VUP, "AR_VUP" }, - { MP_AR_VDOWN, "AR_VDOWN" }, - { MP_KEY_POWER, "POWER" }, { MP_KEY_MENU, "MENU" }, { MP_KEY_PLAY, "PLAY" }, @@ -528,7 +516,6 @@ static const m_option_t input_conf[] = { { "keylist", print_key_list, CONF_TYPE_PRINT_FUNC, CONF_GLOBAL | CONF_NOCFG }, { "cmdlist", print_cmd_list, CONF_TYPE_PRINT_FUNC, CONF_GLOBAL | CONF_NOCFG }, OPT_STRING("js-dev", input.js_dev, CONF_GLOBAL), - OPT_STRING("ar-dev", input.ar_dev, CONF_GLOBAL), OPT_STRING("file", input.in_file, CONF_GLOBAL), OPT_FLAG("default-bindings", input.default_bindings, CONF_GLOBAL), OPT_FLAG("test", input.test, CONF_GLOBAL), @@ -540,7 +527,6 @@ static const m_option_t mp_input_opts[] = { OPT_FLAG("joystick", input.use_joystick, CONF_GLOBAL), OPT_FLAG("lirc", input.use_lirc, CONF_GLOBAL), OPT_FLAG("lircc", input.use_lircc, CONF_GLOBAL), - OPT_FLAG("ar", input.use_ar, CONF_GLOBAL), { NULL, NULL, 0, 0, 0, 0, NULL} }; @@ -578,7 +564,7 @@ static char *get_key_combo_name(int *keys, int max) while (1) { ret = get_key_name(*keys, ret); if (--max && *++keys) - talloc_asprintf_append_buffer(ret, "-"); + ret = talloc_asprintf_append_buffer(ret, "-"); else break; } @@ -821,7 +807,7 @@ mp_cmd_t *mp_input_parse_cmd(bstr str, const char *loc) if (bstrcasecmp(bstr_splice(str, 0, old_len), (bstr) {(char *)entry->old, old_len}) == 0) { - mp_tmsg(MSGT_INPUT, MSGL_V, "Warning: command '%s' is " + mp_tmsg(MSGT_INPUT, MSGL_WARN, "Warning: command '%s' is " "deprecated, replaced with '%s' at %s.\n", entry->old, entry->new, loc); bstr s = bstr_cut(str, old_len); @@ -1157,11 +1143,9 @@ static struct cmd_bind *section_find_bind_for_key(struct input_ctx *ictx, return bs->cmd_binds ? find_bind_for_key(bs->cmd_binds, n, keys) : NULL; } -static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) +static struct cmd_bind *find_any_bind_for_key(struct input_ctx *ictx, + int n, int *keys) { - if (ictx->test) - return handle_test(ictx, n, keys); - struct cmd_bind *cmd = section_find_bind_for_key(ictx, false, ictx->section, n, keys); if (ictx->default_bindings && cmd == NULL) @@ -1172,6 +1156,20 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) if (ictx->default_bindings && cmd == NULL) cmd = section_find_bind_for_key(ictx, true, "default", n, keys); } + return cmd; +} + +static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) +{ + if (ictx->test) + return handle_test(ictx, n, keys); + + struct cmd_bind *cmd = find_any_bind_for_key(ictx, n, keys); + if (cmd == NULL && n > 1) { + // Hitting two keys at once, and if there's no binding for this + // combination, the key hit last should be checked. + cmd = find_any_bind_for_key(ictx, 1, (int[]){keys[n - 1]}); + } if (cmd == NULL) { char *key_buf = get_key_combo_name(keys, n); @@ -1201,7 +1199,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) * we want to have "a" and "A" instead of "a" and "Shift+A"; but a separate * shift modifier is still kept for special keys like arrow keys. */ - int unmod = code & ~MP_KEY_MODIFIER_MASK; + int unmod = code & ~(MP_KEY_MODIFIER_MASK | MP_KEY_STATE_DOWN); if (unmod >= 32 && unmod < MP_KEY_BASE) code &= ~MP_KEY_MODIFIER_SHIFT; @@ -1223,7 +1221,10 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) ictx->num_key_down++; ictx->last_key_down = GetTimer(); ictx->ar_state = 0; - return NULL; + ret = NULL; + if (!(code & MP_NO_REPEAT_KEY)) + ret = get_cmd_from_keys(ictx, ictx->num_key_down, ictx->key_down); + return ret; } // button released or press of key with no separate down/up events for (j = 0; j < ictx->num_key_down; j++) { @@ -1239,6 +1240,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) j = ictx->num_key_down - 1; ictx->key_down[j] = code; } + bool emit_key = ictx->last_key_down && (code & MP_NO_REPEAT_KEY); if (j == ictx->num_key_down) { // was not already down; add temporarily if (ictx->num_key_down > MP_MAX_KEY_DOWN) { mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many key down events " @@ -1247,12 +1249,12 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) } ictx->key_down[ictx->num_key_down] = code; ictx->num_key_down++; - ictx->last_key_down = 1; + emit_key = true; } // Interpret only maximal point of multibutton event - ret = ictx->last_key_down ? - get_cmd_from_keys(ictx, ictx->num_key_down, ictx->key_down) - : NULL; + ret = NULL; + if (emit_key) + ret = get_cmd_from_keys(ictx, ictx->num_key_down, ictx->key_down); if (doubleclick) { ictx->key_down[j] = code - MP_MOUSE_BTN0_DBL + MP_MOUSE_BTN0; return ret; @@ -1275,6 +1277,8 @@ static mp_cmd_t *check_autorepeat(struct input_ctx *ictx) if (ictx->ar_rate > 0 && ictx->ar_state >= 0 && ictx->num_key_down > 0 && !(ictx->key_down[ictx->num_key_down - 1] & MP_NO_REPEAT_KEY)) { unsigned int t = GetTimer(); + if (ictx->last_ar + 2000000 < t) + ictx->last_ar = t; // First time : wait delay if (ictx->ar_state == 0 && (t - ictx->last_key_down) >= ictx->ar_delay * 1000) @@ -1287,12 +1291,12 @@ static mp_cmd_t *check_autorepeat(struct input_ctx *ictx) return NULL; } ictx->ar_state = 1; - ictx->last_ar = t; + ictx->last_ar = ictx->last_key_down + ictx->ar_delay * 1000; return mp_cmd_clone(ictx->ar_cmd); // Then send rate / sec event } else if (ictx->ar_state == 1 && (t - ictx->last_ar) >= 1000000 / ictx->ar_rate) { - ictx->last_ar = t; + ictx->last_ar += 1000000 / ictx->ar_rate; return mp_cmd_clone(ictx->ar_cmd); } } @@ -1303,11 +1307,13 @@ void mp_input_feed_key(struct input_ctx *ictx, int code) { ictx->got_new_events = true; if (code == MP_INPUT_RELEASE_ALL) { + mp_msg(MSGT_INPUT, MSGL_V, "input: release all\n"); memset(ictx->key_down, 0, sizeof(ictx->key_down)); ictx->num_key_down = 0; ictx->last_key_down = 0; return; } + mp_msg(MSGT_INPUT, MSGL_V, "input: key code=%#x\n", code); struct mp_cmd *cmd = interpret_key(ictx, code); if (!cmd) return; @@ -1364,6 +1370,10 @@ static void read_key_fd(struct input_ctx *ictx, struct input_fd *key_fd) */ static void read_events(struct input_ctx *ictx, int time) { + if (ictx->num_key_down) { + time = FFMIN(time, 1000 / ictx->ar_rate); + time = FFMIN(time, ictx->ar_delay); + } ictx->got_new_events = false; struct input_fd *key_fds = ictx->key_fds; struct input_fd *cmd_fds = ictx->cmd_fds; @@ -1779,27 +1789,6 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf, } #endif -#ifdef CONFIG_APPLE_REMOTE - if (input_conf->use_ar) { - if (mp_input_ar_init() < 0) - mp_tmsg(MSGT_INPUT, MSGL_ERR, "Can't init Apple Remote.\n"); - else - mp_input_add_key_fd(ictx, -1, 0, mp_input_ar_read, - mp_input_ar_close, NULL); - } -#endif - -#ifdef CONFIG_APPLE_IR - if (input_conf->use_ar) { - int fd = mp_input_appleir_init(input_conf->ar_dev); - if (fd < 0) - mp_tmsg(MSGT_INPUT, MSGL_ERR, "Can't init Apple Remote.\n"); - else - mp_input_add_key_fd(ictx, fd, 1, mp_input_appleir_read, - close, NULL); - } -#endif - if (input_conf->in_file) { int mode = O_RDONLY; #ifndef __MINGW32__ diff --git a/core/input/input.h b/core/input/input.h index 30cc2ce9ed..ff79222c9b 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -44,6 +44,7 @@ enum mp_command_type { MP_CMD_TV_SET_FREQ, MP_CMD_TV_SET_NORM, MP_CMD_FRAME_STEP, + MP_CMD_FRAME_BACK_STEP, MP_CMD_SPEED_MULT, MP_CMD_RUN, MP_CMD_SUB_ADD, diff --git a/core/input/keycodes.h b/core/input/keycodes.h index 18ce7ce1cc..2e0e5fd33f 100644 --- a/core/input/keycodes.h +++ b/core/input/keycodes.h @@ -172,19 +172,6 @@ #define MP_MOUSE_BTN19_DBL (MP_MOUSE_BASE_DBL+19) #define MP_MOUSE_BTN_DBL_END (MP_MOUSE_BASE_DBL+20) -// Apple Remote input module -#define MP_AR_BASE (MP_KEY_BASE+0xE0) -#define MP_AR_PLAY (MP_AR_BASE + 0) -#define MP_AR_PLAY_HOLD (MP_AR_BASE + 1) -#define MP_AR_NEXT (MP_AR_BASE + 2) -#define MP_AR_NEXT_HOLD (MP_AR_BASE + 3) -#define MP_AR_PREV (MP_AR_BASE + 4) -#define MP_AR_PREV_HOLD (MP_AR_BASE + 5) -#define MP_AR_MENU (MP_AR_BASE + 6) -#define MP_AR_MENU_HOLD (MP_AR_BASE + 7) -#define MP_AR_VUP (MP_AR_BASE + 8) -#define MP_AR_VDOWN (MP_AR_BASE + 9) - /* Special keys */ #define MP_KEY_INTERN (MP_KEY_BASE+0x1000) #define MP_KEY_CLOSE_WIN (MP_KEY_INTERN+0) @@ -199,8 +186,12 @@ MP_KEY_MODIFIER_ALT | MP_KEY_MODIFIER_META) // Use this when the key shouldn't be auto-repeated (like mouse buttons) +// This is not a modifier, but is part of the keycode itself. #define MP_NO_REPEAT_KEY (1<<28) +// Flag for key events. Multiple down events are idempotent. Release keys by +// sending the key code without this flag, or by send |