diff options
Diffstat (limited to 'input')
-rw-r--r-- | input/appleir.c | 151 | ||||
-rw-r--r-- | input/ar.h | 5 | ||||
-rw-r--r-- | input/input.c | 12 |
3 files changed, 168 insertions, 0 deletions
diff --git a/input/appleir.c b/input/appleir.c new file mode 100644 index 0000000000..a3ec66e8cb --- /dev/null +++ b/input/appleir.c @@ -0,0 +1,151 @@ +/* + * 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/input.h> + +#include "mp_msg.h" +#include "help_mp.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, AR_PLAY }, + { APPLE_IR_PLAY, 2, AR_PLAY_HOLD }, + { APPLE_IR_FORWARD, 1, AR_NEXT }, + { APPLE_IR_FORWARD, 2, AR_NEXT_HOLD }, + { APPLE_IR_BACKWARD, 1, AR_PREV }, + { APPLE_IR_BACKWARD, 2, AR_PREV_HOLD }, + { APPLE_IR_MENU, 1, AR_MENU }, + { APPLE_IR_MENU, 2, AR_MENU_HOLD }, + { APPLE_IR_PLUS, 1, AR_VUP }, + { APPLE_IR_MINUS, 1, AR_VDOWN }, + { -1, -1, -1 } +}; + +int mp_input_appleir_init (char *dev) +{ + int i, fd; + + if (dev) + { + mp_msg (MSGT_INPUT, MSGL_V, MSGTR_INPUT_APPLE_IR_Init, dev); + fd = open (dev, O_RDONLY | O_NONBLOCK); + if (fd < 0) + { + mp_msg (MSGT_INPUT, MSGL_ERR, + MSGTR_INPUT_APPLE_IR_CantOpen, 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_msg (MSGT_INPUT, MSGL_V, MSGTR_INPUT_APPLE_IR_Detect, file); + return fd; + } + close (fd); + } + + mp_msg (MSGT_INPUT, MSGL_ERR, + MSGTR_INPUT_APPLE_IR_CantOpen, strerror (errno)); + } + + return -1; +} + +int mp_input_appleir_read (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/input/ar.h b/input/ar.h index 10c6aac7a4..31bbd0ade9 100644 --- a/input/ar.h +++ b/input/ar.h @@ -35,8 +35,13 @@ #define AR_VUP (AR_BASE + 8) #define AR_VDOWN (AR_BASE + 9) +/* MacOSX Driver */ int mp_input_ar_init(void); int mp_input_ar_read(int fd); void mp_input_ar_close(int fd); +/* Linux Driver */ +int mp_input_appleir_init(char* dev); +int mp_input_appleir_read(int fd); + #endif /* MPLAYER_AR_H */ diff --git a/input/input.c b/input/input.c index c43afbfa4f..da879cc6a7 100644 --- a/input/input.c +++ b/input/input.c @@ -569,6 +569,7 @@ static char* config_file = "input.conf"; static int use_ar = 1; static char* js_dev = NULL; +static char* ar_dev = NULL; static char* in_file = NULL; static int in_file_fd = -1; @@ -579,6 +580,7 @@ static int mp_input_print_cmd_list(m_option_t* cfg); // Our command line options static m_option_t input_conf[] = { { "conf", &config_file, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, + { "ar-dev", &ar_dev, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL }, { "ar-delay", &ar_delay, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL }, { "ar-rate", &ar_rate, CONF_TYPE_INT, CONF_GLOBAL, 0, 0, NULL }, { "keylist", mp_input_print_key_list, CONF_TYPE_FUNC, CONF_GLOBAL, 0, 0, NULL }, @@ -1760,6 +1762,16 @@ mp_input_init(int use_gui) { } #endif +#ifdef HAVE_APPLE_IR + if(use_ar) { + int fd = mp_input_appleir_init(ar_dev); + if(fd < 0) + mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantInitAppleRemote); + else + mp_input_add_key_fd(fd,1,mp_input_appleir_read,(mp_close_func_t)close); + } +#endif + if(in_file) { struct stat st; if(stat(in_file,&st)) |