summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--DOCS/man/en/options.rst3
-rw-r--r--Makefile7
-rw-r--r--core/defaultopts.c3
-rw-r--r--core/input/input.c39
-rw-r--r--core/input/input.h2
-rw-r--r--core/input/keycodes.h17
-rw-r--r--core/m_option.c7
-rw-r--r--core/mplayer.c3
-rw-r--r--core/options.h3
-rw-r--r--demux/demux.c2
-rw-r--r--demux/demux_mkv.c2
-rw-r--r--etc/input.conf23
-rw-r--r--osdep/ar/HIDRemote.h378
-rw-r--r--osdep/ar/HIDRemote.m2068
-rw-r--r--osdep/macosx_application.h3
-rw-r--r--osdep/macosx_application.m200
-rw-r--r--osdep/macosx_application_objc.h21
-rw-r--r--osdep/macosx_events.h29
-rw-r--r--osdep/macosx_events.m218
-rw-r--r--stream/stream_dvd.c1
-rw-r--r--video/out/cocoa_common.h2
-rw-r--r--video/out/cocoa_common.m788
-rw-r--r--video/out/gl_video.c13
-rw-r--r--video/out/gl_video_shaders.glsl1
-rw-r--r--video/out/osx_common.h28
-rw-r--r--video/out/osx_common.m181
27 files changed, 3315 insertions, 728 deletions
diff --git a/.travis.yml b/.travis.yml
index b932ae8463..33e495f86a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,7 @@ compiler:
branches:
only:
- master
+ - ci
before_install: ./travis-deps libass-stable $LIBAV
script: ./configure && make
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index f626f861f6..8239375079 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -80,6 +80,9 @@
configuration files specifying a list of fallbacks may make sense. See
`audio_outputs` for details and descriptions of available drivers.
+--ar, --no-ar
+ Enable/disable AppleIR remote support. Enabled by default.
+
--aspect=<ratio>
Override movie aspect ratio, in case aspect information is incorrect or
missing in the file being played. See also ``--no-aspect``.
diff --git a/Makefile b/Makefile
index 389a519055..ff8eb31341 100644
--- a/Makefile
+++ b/Makefile
@@ -46,9 +46,10 @@ SOURCES-$(LIBPOSTPROC) += video/filter/vf_pp.c
SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c
SOURCES-$(MACOSX_BUNDLE) += osdep/macosx_bundle.m
-SOURCES-$(COCOA) += video/out/osx_common.m \
- video/out/cocoa_common.m \
- osdep/macosx_application.m
+SOURCES-$(COCOA) += video/out/cocoa_common.m \
+ osdep/macosx_application.m \
+ osdep/macosx_events.m \
+ osdep/ar/HIDRemote.m
SOURCES-$(MNG) += demux/demux_mng.c
SOURCES-$(MPG123) += audio/decode/ad_mpg123.c
diff --git a/core/defaultopts.c b/core/defaultopts.c
index 93dad1e624..a8a6b26930 100644
--- a/core/defaultopts.c
+++ b/core/defaultopts.c
@@ -108,6 +108,9 @@ void set_default_mplayer_options(struct MPOpts *opts)
.use_joystick = 1,
.use_lirc = 1,
.use_lircc = 1,
+#ifdef CONFIG_COCOA
+ .use_ar = 1,
+#endif
.default_bindings = 1,
}
};
diff --git a/core/input/input.c b/core/input/input.c
index c9958753cd..4bfc22a08c 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -61,6 +61,10 @@
#include <lirc/lircc.h>
#endif
+#ifdef CONFIG_COCOA
+#include "osdep/macosx_events.h"
+#endif
+
#define MP_MAX_KEY_DOWN 4
struct cmd_bind {
@@ -390,6 +394,21 @@ 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_CENTER, "AR_CENTER" },
+ { MP_AR_CENTER_HOLD, "AR_CENTER_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_VUP_HOLD, "AR_VUP_HOLD" },
+ { MP_AR_VDOWN, "AR_VDOWN" },
+ { MP_AR_VDOWN_HOLD, "AR_VDOWN_HOLD" },
+
{ MP_KEY_POWER, "POWER" },
{ MP_KEY_MENU, "MENU" },
{ MP_KEY_PLAY, "PLAY" },
@@ -532,6 +551,9 @@ 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),
+#ifdef CONFIG_COCOA
+ OPT_FLAG("ar", input.use_ar, CONF_GLOBAL),
+#endif
{ NULL, NULL, 0, 0, 0, 0, NULL}
};
@@ -1474,6 +1496,9 @@ static void read_all_fd_events(struct input_ctx *ictx, int time)
static void read_all_events(struct input_ctx *ictx, int time)
{
getch2_poll();
+#ifdef CONFIG_COCOA
+ cocoa_check_events();
+#endif
read_all_fd_events(ictx, time);
}
@@ -1803,6 +1828,12 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf,
}
#endif
+#ifdef CONFIG_COCOA
+ if (input_conf->use_ar) {
+ cocoa_start_apple_remote();
+ }
+#endif
+
if (input_conf->in_file) {
int mode = O_RDONLY;
#ifndef __MINGW32__
@@ -1834,11 +1865,17 @@ static void clear_queue(struct cmd_queue *queue)
}
}
-void mp_input_uninit(struct input_ctx *ictx)
+void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf)
{
if (!ictx)
return;
+#ifdef CONFIG_COCOA
+ if (input_conf->use_ar) {
+ cocoa_stop_apple_remote();
+ }
+#endif
+
for (int i = 0; i < ictx->num_key_fd; i++) {
if (ictx->key_fds[i].close_func)
ictx->key_fds[i].close_func(ictx->key_fds[i].fd);
diff --git a/core/input/input.h b/core/input/input.h
index 6c33e47fdc..944debd847 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -216,7 +216,7 @@ struct input_conf;
struct input_ctx *mp_input_init(struct input_conf *input_conf,
bool load_default_conf);
-void mp_input_uninit(struct input_ctx *ictx);
+void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf);
struct m_config;
void mp_input_register_options(struct m_config *cfg);
diff --git a/core/input/keycodes.h b/core/input/keycodes.h
index 2e0e5fd33f..b9d2da23b7 100644
--- a/core/input/keycodes.h
+++ b/core/input/keycodes.h
@@ -172,6 +172,23 @@
#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_CENTER (MP_AR_BASE + 2)
+#define MP_AR_CENTER_HOLD (MP_AR_BASE + 3)
+#define MP_AR_NEXT (MP_AR_BASE + 4)
+#define MP_AR_NEXT_HOLD (MP_AR_BASE + 5)
+#define MP_AR_PREV (MP_AR_BASE + 6)
+#define MP_AR_PREV_HOLD (MP_AR_BASE + 7)
+#define MP_AR_MENU (MP_AR_BASE + 8)
+#define MP_AR_MENU_HOLD (MP_AR_BASE + 9)
+#define MP_AR_VUP (MP_AR_BASE + 10)
+#define MP_AR_VUP_HOLD (MP_AR_BASE + 11)
+#define MP_AR_VDOWN (MP_AR_BASE + 12)
+#define MP_AR_VDOWN_HOLD (MP_AR_BASE + 13)
+
/* Special keys */
#define MP_KEY_INTERN (MP_KEY_BASE+0x1000)
#define MP_KEY_CLOSE_WIN (MP_KEY_INTERN+0)
diff --git a/core/m_option.c b/core/m_option.c
index 931b498213..406e4ede0b 100644
--- a/core/m_option.c
+++ b/core/m_option.c
@@ -762,6 +762,13 @@ static int parse_str(const m_option_t *opt, struct bstr name,
goto exit;
}
+ m_opt_string_validate_fn validate = opt->priv;
+ if (validate) {
+ r = validate(opt, name, param);
+ if (r < 0)
+ goto exit;
+ }
+
if (opt->flags & M_OPT_PARSE_ESCAPES) {
char *res = unescape_string(tmp, param);
if (!res) {
diff --git a/core/mplayer.c b/core/mplayer.c
index 4d71b5f55f..baae55b581 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -588,7 +588,7 @@ static MP_NORETURN void exit_player(struct MPContext *mpctx,
timeEndPeriod(1);
#endif
- mp_input_uninit(mpctx->input);
+ mp_input_uninit(mpctx->input, &mpctx->opts.input);
osd_free(mpctx->osd);
@@ -3885,6 +3885,7 @@ static void init_input(struct MPContext *mpctx)
#ifdef CONFIG_COCOA
cocoa_set_input_context(mpctx->input);
+ cocoa_set_key_fifo(mpctx->key_fifo);
#endif
}
diff --git a/core/options.h b/core/options.h
index 31b4bc9136..0504ea0591 100644
--- a/core/options.h
+++ b/core/options.h
@@ -239,6 +239,9 @@ typedef struct MPOpts {
int use_joystick;
int use_lirc;
int use_lircc;
+#ifdef CONFIG_COCOA
+ int use_ar;
+#endif
int default_bindings;
int test;
} input;
diff --git a/demux/demux.c b/demux/demux.c
index 25f31a3f60..5de6b84745 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -1002,7 +1002,7 @@ struct demuxer *demux_open_withparams(struct MPOpts *opts,
// format, instead of reyling on libav to auto-detect the stream's format
// correctly.
switch (file_format) {
- case DEMUXER_TYPE_MPEG_PS:
+ //case DEMUXER_TYPE_MPEG_PS:
//case DEMUXER_TYPE_MPEG_TS:
case DEMUXER_TYPE_Y4M:
case DEMUXER_TYPE_NSV:
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 828479e50f..914ace3a41 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -2075,6 +2075,7 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
}
}
+#if NEED_WAVPACK_PARSE
// Copied from libavformat/matroskadec.c (FFmpeg 310f9dd / 2013-05-30)
// Originally added with Libav commit 9b6f47c
// License: LGPL v2.1 or later
@@ -2153,6 +2154,7 @@ fail:
talloc_free(dst);
return -1;
}
+#endif
static void mkv_parse_packet(mkv_track_t *track, bstr *buffer)
{
diff --git a/etc/input.conf b/etc/input.conf
index 5dbb7c8a06..1cbd2446ba 100644
--- a/etc/input.conf
+++ b/etc/input.conf
@@ -9,8 +9,8 @@
# mpv --input-test --pause dummy.mkv can be used to test which commands keys are
# bound to.
#
-# If you wish to unbind a key, use key ignore.
-# e.g. ENTER ignore
+# If you wish to unbind a key, bind it to the 'ignore' command:
+# KEY ignore
#
# Note that merely removing default key bindings from this file won't remove
# the default bindings mpv was compiled with, unless
@@ -20,7 +20,7 @@
# Lines starting with # are comments. Use SHARP to assign the # key.
#
# Strings need to be quoted and escaped:
-# KEY show_text "This is a single backslash: \\ and a quote: \" !"
+# KEY show_text "This is a single backslash: \\ and a quote: \" !"
#
# You can use modifier-key combinations like Shift+Left or Ctrl+Alt+x with
# modifiers Shift, Ctrl, Alt and Meta, but note that currently reading
@@ -136,7 +136,22 @@ k tv_step_channel -1
n tv_step_norm
u tv_step_chanlist
-#
+# Apple Remote section
+AR_PLAY cycle pause
+AR_PLAY_HOLD quit
+AR_CENTER cycle pause
+AR_CENTER_HOLD quit
+AR_NEXT seek 10
+AR_NEXT_HOLD seek 120
+AR_PREV seek -10
+AR_PREV_HOLD seek -120
+AR_MENU show_progress
+AR_MENU_HOLD cycle mute
+AR_VUP add volume 1
+AR_VUP_HOLD add chapter 1
+AR_VDOWN add volume -1
+AR_VDOWN_HOLD add chapter -1
+
# Joystick section
# WARNING: joystick support has to be explicitly enabled at
# compiletime with --enable-joystick
diff --git a/osdep/ar/HIDRemote.h b/osdep/ar/HIDRemote.h
new file mode 100644
index 0000000000..9dd16faa5a
--- /dev/null
+++ b/osdep/ar/HIDRemote.h
@@ -0,0 +1,378 @@
+//
+// HIDRemote.h
+// HIDRemote V1.2
+//
+// Created by Felix Schwarz on 06.04.07.
+// Copyright 2007-2011 IOSPIRIT GmbH. All rights reserved.
+//
+// The latest version of this class is available at
+// http://www.iospirit.com/developers/hidremote/
+//
+// ** LICENSE *************************************************************************
+//
+// Copyright (c) 2007-2011 IOSPIRIT GmbH (http://www.iospirit.com/)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list
+// of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ************************************************************************************
+
+
+// ************************************************************************************
+// ********************************** DOCUMENTATION ***********************************
+// ************************************************************************************
+//
+// - a reference is available at http://www.iospirit.com/developers/hidremote/reference/
+// - for a guide, please see http://www.iospirit.com/developers/hidremote/guide/
+//
+// ************************************************************************************
+
+
+#import <Cocoa/Cocoa.h>
+
+#include <Carbon/Carbon.h>
+
+#include <unistd.h>
+#include <mach/mach.h>
+#include <sys/types.h>
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/hid/IOHIDKeys.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDUsageTables.h>
+#include <IOKit/hidsystem/IOHIDLib.h>
+#include <IOKit/hidsystem/IOHIDParameter.h>
+#include <IOKit/hidsystem/IOHIDShared.h>
+
+#pragma mark -- Enums / Codes --
+
+typedef enum
+{
+ kHIDRemoteModeNone = 0L,
+ kHIDRemoteModeShared, // Share the remote with others - let's you listen to the remote control events as long as noone has an exclusive lock on it
+ // (RECOMMENDED ONLY FOR SPECIAL PURPOSES)
+
+ kHIDRemoteModeExclusive, // Try to acquire an exclusive lock on the remote (NOT RECOMMENDED)
+
+ kHIDRemoteModeExclusiveAuto // Try to acquire an exclusive lock on the remote whenever the application has focus. Temporarily release control over the
+ // remote when another application has focus (RECOMMENDED)
+} HIDRemoteMode;
+
+typedef enum
+{
+ /* A code reserved for "no button" (needed for tracking) */
+ kHIDRemoteButtonCodeNone = 0L,
+
+ /* Standard codes - available for white plastic and aluminum remote */
+ kHIDRemoteButtonCodeUp,
+ kHIDRemoteButtonCodeDown,
+ kHIDRemoteButtonCodeLeft,
+ kHIDRemoteButtonCodeRight,
+ kHIDRemoteButtonCodeCenter,
+ kHIDRemoteButtonCodeMenu,
+
+ /* Extra codes - Only available for the new aluminum version of the remote */
+ kHIDRemoteButtonCodePlay,
+
+ /* Masks */
+ kHIDRemoteButtonCodeCodeMask = 0xFFL,
+ kHIDRemoteButtonCodeHoldMask = (1L << 16L),
+ kHIDRemoteButtonCodeSpecialMask = (1L << 17L),
+ kHIDRemoteButtonCodeAluminumMask = (1L << 21L), // PRIVATE - only used internally
+
+ /* Hold button standard codes - available for white plastic and aluminum remote */
+ kHIDRemoteButtonCodeUpHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeUp),
+ kHIDRemoteButtonCodeDownHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeDown),
+ kHIDRemoteButtonCodeLeftHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeLeft),
+ kHIDRemoteButtonCodeRightHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeRight),
+ kHIDRemoteButtonCodeCenterHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeCenter),
+ kHIDRemoteButtonCodeMenuHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeMenu),
+
+ /* Hold button extra codes - Only available for aluminum version of the remote */
+ kHIDRemoteButtonCodePlayHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodePlay),
+
+ /* DEPRECATED codes - compatibility with HIDRemote 1.0 */
+ kHIDRemoteButtonCodePlus = kHIDRemoteButtonCodeUp,
+ kHIDRemoteButtonCodePlusHold = kHIDRemoteButtonCodeUpHold,
+ kHIDRemoteButtonCodeMinus = kHIDRemoteButtonCodeDown,
+ kHIDRemoteButtonCodeMinusHold = kHIDRemoteButtonCodeDownHold,
+ kHIDRemoteButtonCodePlayPause = kHIDRemoteButtonCodeCenter,
+ kHIDRemoteButtonCodePlayPauseHold = kHIDRemoteButtonCodeCenterHold,
+
+ /* Special purpose codes */
+ kHIDRemoteButtonCodeIDChanged = (kHIDRemoteButtonCodeSpecialMask|(1L << 18L)), // (the ID of the connected remote has changed, you can safely ignore this)
+ #ifdef _HIDREMOTE_EXTENSIONS
+ #define _HIDREMOTE_EXTENSIONS_SECTION 1
+ #include "HIDRemoteAdditions.h"
+ #undef _HIDREMOTE_EXTENSIONS_SECTION
+ #endif /* _HIDREMOTE_EXTENSIONS */
+} HIDRemoteButtonCode;
+
+typedef enum
+{
+ kHIDRemoteModelUndetermined = 0L, // Assume a white plastic remote
+ kHIDRemoteModelWhitePlastic, // Signal *likely* to be coming from a white plastic remote
+ kHIDRemoteModelAluminum // Signal *definitely* coming from an aluminum remote
+} HIDRemoteModel;
+
+typedef enum
+{
+ kHIDRemoteAluminumRemoteSupportLevelNone = 0L, // This system has no support for the Aluminum Remote at all
+ kHIDRemoteAluminumRemoteSupportLevelEmulation, // This system possibly has support for the Aluminum Remote (via emulation)
+ kHIDRemoteAluminumRemoteSupportLevelNative // This system has native support for the Aluminum Remote
+} HIDRemoteAluminumRemoteSupportLevel;
+
+@class HIDRemote;
+
+#pragma mark -- Delegate protocol (mandatory) --
+@protocol HIDRemoteDelegate
+
+// Notification of button events
+- (void)hidRemote:(HIDRemote *)hidRemote // The instance of HIDRemote sending this
+ eventWithButton:(HIDRemoteButtonCode)buttonCode // Event for the button specified by code
+ isPressed:(BOOL)isPressed // The button was pressed (YES) / released (NO)
+ fromHardwareWithAttributes:(NSMutableDictionary *)attributes; // Information on the device this event comes from
+
+@optional
+
+// Notification of ID changes
+- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when the user switched to a remote control with a different ID
+ remoteIDChangedOldID:(SInt32)old
+ newID:(SInt32)newID
+ forHardwareWithAttributes:(NSMutableDictionary *)attributes;
+
+// Notification about hardware additions/removals
+- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware was found / added to HIDRemote's pool
+ foundNewHardwareWithAttributes:(NSMutableDictionary *)attributes;
+
+- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when initialization of new hardware as requested failed
+ failedNewHardwareWithError:(NSError *)error;
+
+- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when hardware was removed from HIDRemote's pool
+ releasedHardwareWithAttributes:(NSMutableDictionary *)attributes;
+
+// ### WARNING: Unless you know VERY PRECISELY what you are doing, do not implement any of the delegate methods below. ###
+
+// Matching of newly found receiver hardware
+- (BOOL)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware is inspected
+ inspectNewHardwareWithService:(io_service_t)service //
+ prematchResult:(BOOL)prematchResult; // Return YES if HIDRemote should go on with this hardware and try
+ // to use it, or NO if it should not be persued further.
+
+// Exlusive lock lending
+- (BOOL)hidRemote:(HIDRemote *)hidRemote
+ lendExclusiveLockToApplicationWithInfo:(NSDictionary *)applicationInfo;
+
+- (void)hidRemote:(HIDRemote *)hidRemote
+ exclusiveLockReleasedByApplicationWithInfo:(NSDictionary *)applicationInfo;
+
+- (BOOL)hidRemote:(HIDRemote *)hidRemote
+ shouldRetryExclusiveLockWithInfo:(NSDictionary *)applicationInfo;
+
+@end
+
+
+#pragma mark -- Actual header file for class --
+
+@interface HIDRemote : NSObject
+{
+ // IOMasterPort
+ mach_port_t _masterPort;
+
+ // Notification ports
+ IONotificationPortRef _notifyPort;
+ CFRunLoopSourceRef _notifyRLSource;
+
+ // Matching iterator
+ io_iterator_t _matchingServicesIterator;
+
+ // SecureInput notification
+ io_object_t _secureInputNotification;
+
+ // Service attributes
+ NSMutableDictionary *_serviceAttribMap;
+
+ // Mode
+ HIDRemoteMode _mode;
+ BOOL _autoRecover;
+ NSTimer *_autoRecoveryTimer;
+
+ // Delegate
+ NSObject <HIDRemoteDelegate> *_delegate;
+
+ // Last seen ID and remote model
+ SInt32 _lastSeenRemoteID;
+ HIDRemoteModel _lastSeenModel;
+ SInt32 _lastSeenModelRemoteID;
+
+ // Unused button codes
+ NSArray *_unusedButtonCodes;
+
+ // Simulate Plus/Minus Hold
+ BOOL _simulateHoldEvents;
+
+ // SecureEventInput workaround
+ BOOL _secureEventInputWorkAround;
+ UInt64 _lastSecureEventInputPIDSum;
+ uid_t _lastFrontUserSession;
+
+ // Exclusive lock lending
+ BOOL _exclusiveLockLending;
+ BOOL _sendExclusiveResourceReuseNotification;
+ NSNumber *_waitForReturnByPID;
+ NSNumber *_returnToPID;
+ BOOL _isRestarting;
+
+ // Status notifications
+ BOOL _sendStatusNotifications;
+ NSString *_pidString;
+
+ // Status
+ BOOL _applicationIsTerminating;
+ BOOL _isStopping;
+
+ // Thread safety
+ #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */
+ NSThread *_runOnThread;
+ #endif
+}
+
+#pragma mark -- PUBLIC: Shared HID Remote --
++ (HIDRemote *)sharedHIDRemote;
+
+#pragma mark -- PUBLIC: System Information --
++ (BOOL)isCandelairInstalled;
++ (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode;
+- (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel;
+
+#pragma mark -- PUBLIC: Interface / API --
+- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode;
+- (void)stopRemoteControl;
+
+- (BOOL)isStarted;
+- (HIDRemoteMode)startedInMode;
+
+- (unsigned)activeRemoteControlCount;
+
+- (SInt32)lastSeenRemoteControlID;
+
+- (void)setLastSeenModel:(HIDRemoteModel)aModel;
+- (HIDRemoteModel)lastSeenModel;
+
+- (void)setDelegate:(NSObject <HIDRemoteDelegate> *)newDelegate;
+- (NSObject <HIDRemoteDelegate> *)delegate;
+
+- (void)setSimulateHoldEvents:(BOOL)newSimulateHoldEvents;
+- (BOOL)simulateHoldEvents;
+
+- (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers;
+- (NSArray *)unusedButtonCodes;
+
+#pragma mark -- PUBLIC: Expert APIs --
+- (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround;
+- (BOOL)enableSecureEventInputWorkaround;
+
+- (void)setExclusiveLockLendingEnabled:(BOOL)newExclusiveLockLendingEnabled;
+- (BOOL)exclusiveLockLendingEnabled;
+
+- (BOOL)isApplicationTerminating;
+- (BOOL)isStopping;
+
+#pragma mark -- PRIVATE: HID Event handling --
+- (void)_handleButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict;
+- (void)_sendButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict;
+- (void)_hidEventFor:(io_service_t)hidDevice from:(IOHIDQueueInterface **)interface withResult:(IOReturn)result;
+
+#pragma mark -- PRIVATE: Service setup and destruction --
+- (BOOL)_prematchService:(io_object_t)service;
+- (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage;
+- (BOOL)_setupService:(io_object_t)service;
+- (void)_destructService:(io_object_t)service;
+
+#pragma mark -- PRIVATE: Distributed notifiations handling --
+- (void)_postStatusWithAction:(NSString *)action;
+- (void)_handleNotifications:(NSNotification *)notification;
+- (void)_setSendStatusNotifications:(BOOL)doSend;
+- (BOOL)_sendStatusNotifications;
+
+#pragma mark -- PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto --
+- (void)_appStatusChanged:(NSNotification *)notification;
+- (void)_delayedAutoRecovery:(NSTimer *)aTimer;
+
+#pragma mark -- PRIVATE: Notification handling --
+- (void)_serviceMatching:(io_iterator_t)iterator;
+- (void)_serviceNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument;
+- (void)_updateSessionInformation;
+- (void)_secureInputNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument;
+
+@end
+
+#pragma mark -- Information attribute keys --
+extern NSString *kHIDRemoteManufacturer;
+extern NSString *kHIDRemoteProduct;
+extern NSString *kHIDRemoteTransport;
+
+#pragma mark -- Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do) --
+extern NSString *kHIDRemoteCFPluginInterface;
+extern NSString *kHIDRemoteHIDDeviceInterface;
+extern NSString *kHIDRemoteCookieButtonCodeLUT;
+extern NSString *kHIDRemoteHIDQueueInterface;
+extern NSString *kHIDRemoteServiceNotification;
+extern NSString *kHIDRemoteCFRunLoopSource;
+extern NSString *kHIDRemoteLastButtonPressed;
+extern NSString *kHIDRemoteService;
+extern NSString *kHIDRemoteSimulateHoldEventsTimer;
+extern NSString *kHIDRemoteSimulateHoldEventsOriginButtonCode;
+extern NSString *kHIDRemoteAluminumRemoteSupportLevel;
+extern NSString *kHIDRemoteAluminumRemoteSupportOnDemand;
+
+#pragma mark -- Distributed notifications --
+extern NSString *kHIDRemoteDNHIDRemotePing;
+extern NSString *kHIDRemoteDNHIDRemoteRetry;
+extern NSString *kHIDRemoteDNHIDRemoteStatus;
+
+extern NSString *kHIDRemoteDNHIDRemoteRetryGlobalObject;
+
+#pragma mark -- Distributed notifications userInfo keys and values --
+extern NSString *kHIDRemoteDNStatusHIDRemoteVersionKey;
+extern NSString *kHIDRemoteDNStatusPIDKey;
+extern NSString *kHIDRemoteDNStatusModeKey;
+extern NSString *kHIDRemoteDNStatusUnusedButtonCodesKey;
+extern NSString *kHIDRemoteDNStatusRemoteControlCountKey;
+extern NSString *kHIDRemoteDNStatusReturnToPIDKey;
+extern NSString *kHIDRemoteDNStatusActionKey;
+extern NSString *kHIDRemoteDNStatusActionStart;
+extern NSString *kHIDRemoteDNStatusActionStop;
+extern NSString *kHIDRemoteDNStatusActionUpdate;
+extern NSString *kHIDRemoteDNStatusActionNoNeed;
+
+#pragma mark -- Driver compatibility flags --
+typedef enum
+{
+ kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice = 1L,
+} HIDRemoteCompatibilityFlags;
diff --git a/osdep/ar/HIDRemote.m b/osdep/ar/HIDRemote.m
new file mode 100644
index 0000000000..f05628c040
--- /dev/null
+++ b/osdep/ar/HIDRemote.m
@@ -0,0 +1,2068 @@
+//
+// HIDRemote.m
+// HIDRemote V1.2 (27th May 2011)
+//
+// Created by Felix Schwarz on 06.04.07.
+// Copyright 2007-2011 IOSPIRIT GmbH. All rights reserved.
+//
+// The latest version of this class is available at
+// http://www.iospirit.com/developers/hidremote/
+//
+// ** LICENSE *************************************************************************
+//
+// Copyright (c) 2007-2011 IOSPIRIT GmbH (http://www.iospirit.com/)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list
+// of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ************************************************************************************
+
+// ************************************************************************************
+// ********************************** DOCUMENTATION ***********************************
+// ************************************************************************************
+//
+// - a reference is available at http://www.iospirit.com/developers/hidremote/reference/
+// - for a guide, please see http://www.iospirit.com/developers/hidremote/gui