aboutsummaryrefslogtreecommitdiff
path: root/tools/EventClients
diff options
context:
space:
mode:
Diffstat (limited to 'tools/EventClients')
-rw-r--r--tools/EventClients/Clients/AppleRemote/AppleRemote.cpp645
-rw-r--r--tools/EventClients/Clients/AppleRemote/AppleRemote.h80
-rw-r--r--tools/EventClients/Clients/AppleRemote/Makefile25
-rw-r--r--tools/EventClients/Clients/AppleRemote/XBox360.h576
-rw-r--r--tools/EventClients/Clients/AppleRemote/iremoted.c518
5 files changed, 0 insertions, 1844 deletions
diff --git a/tools/EventClients/Clients/AppleRemote/AppleRemote.cpp b/tools/EventClients/Clients/AppleRemote/AppleRemote.cpp
deleted file mode 100644
index 1cd8baa730..0000000000
--- a/tools/EventClients/Clients/AppleRemote/AppleRemote.cpp
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * AppleRemote.cpp
- * AppleRemote
- *
- *
- */
-
-#include <stdio.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <sys/errno.h>
-#include <sysexits.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/sysctl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include "AppleRemote.h"
-#include "../../lib/c++/xbmcclient.h"
-
-#define DEFAULT_MAX_CLICK_DURATION 0.5
-
-#define LOG if (m_bVerbose) printf
-
-#define APPLICATION_NAME "XBMC"
-
-enum {
- IR_Select,
- IR_SelectHold,
- IR_Right,
- IR_Left,
- IR_Up,
- IR_Down,
- IR_RightHold,
- IR_LeftHold,
- IR_Menu,
- IR_MenuHold
-};
-enum {
- IR_Event_Term_ATV1X = 5,
- IR_Event_Term_ATV20X = 5,
- IR_Event_Term_ATV21 = 8,
- IR_Event_Term_10_4 = 5,
- IR_Event_Term_10_5 = 18
-};
-// magic HID key cookies AppleTV running r1.x (same as 10.4)
-static std::string key_cookiesATV1X[] =
-{
- "8_", //SelectHold = "18_"
- "18_",
- "9_",
- "10_",
- "12_",
- "13_",
- "4_",
- "3_",
- "7_",
- "5_"
-};
-// magic HID key cookies AppleTV running r2.0x
-static std::string key_cookiesATV20X[] =
-{
- "8_", //SelectHold = "18_"
- "18_",
- "9_",
- "10_",
- "12_",
- "13_",
- "4_",
- "3_",
- "5_",
- "7_"
-};
-// magic HID key cookies for AppleTV running r2.1
-static std::string key_cookiesATV21[] =
-{
- "9_", //SelectHold = "19_"
- "19_",
- "10_",
- "11_",
- "13_",
- "14_",
- "5_",
- "4_",
- "6_",
- "8_"
-};
-// magic HID key cookies for 10.4
-static std::string key_cookies10_4[] =
-{
- "8_", //SelectHold = "18_"
- "18_",
- "9_",
- "10_",
- "12_",
- "13_",
- "4_",
- "3_",
- "7_",
- "5_"
-};
-
-// magic HID key cookies for 10.5
-static std::string key_cookies10_5[] =
-{
- "21_", //SelectHold = "35_"
- "35_",
- "22_",
- "23_",
- "29_",
- "30_",
- "4_",
- "3_",
- "20_",
- "18_"
-};
-
-AppleRemote::AppleRemote() :m_bVerbose(false),
- m_remoteMode(REMOTE_NORMAL),
- m_dMaxClickDuration(DEFAULT_MAX_CLICK_DURATION),
- m_socket(-1),
- m_timer(NULL)
-{
- m_serverAddress = "localhost";
- m_appPath = "";
- m_appHome = "";
-}
-
-AppleRemote::~AppleRemote()
-{
- DeInitialize();
-}
-
-void AppleRemote::RegisterCommand(const std::string &strSequence, CPacketBUTTON *pPacket)
-{
- LOG("Registering command %s\n", strSequence.c_str());
- m_mapCommands[strSequence] = pPacket;
-}
-
-void AppleRemote::Initialize()
-{
- std::string *key;
- std::string prefix;
-
- LOG("initializing apple remote\n");
-
- DeInitialize();
-
- m_socket = socket(AF_INET, SOCK_DGRAM, 0);
- if (m_socket < 0)
- {
- fprintf(stderr, "Error opening UDP socket! error: %d\n", errno);
- exit(1);
- }
-
- LOG("udp socket (%d) opened\n", m_socket);
-
- // Runtime Version Check
- SInt32 MacVersion;
-
- Gestalt(gestaltSystemVersion, &MacVersion);
-
- if (MacVersion < 0x1050)
- {
- // OSX 10.4/AppleTV
- size_t len = 512;
- char buffer[512];
- std::string hw_model = "unknown";
-
- if (sysctlbyname("hw.model", &buffer, &len, NULL, 0) == 0)
- hw_model = buffer;
-
- if (hw_model == "AppleTV1,1")
- {
- FILE *inpipe;
- bool atv_version_found = false;
- char linebuf[1000];
-
- //Find the build version of the AppleTV OS
- inpipe = popen("sw_vers -buildVersion", "r");
- if (inpipe)
- {
- //get output
- if(fgets(linebuf, sizeof(linebuf) - 1, inpipe))
- {
- if( strstr(linebuf,"8N5107") || strstr(linebuf,"8N5239"))
- {
- // r1.0 or r1.1
- atv_version_found = true;
- fprintf(stderr, "Using key code for AppleTV r1.x\n");
- key = key_cookiesATV1X;
- m_button_event_terminator = IR_Event_Term_ATV1X;
- }
- else if (strstr(linebuf,"8N5400") || strstr(linebuf,"8N5455") || strstr(linebuf,"8N5461"))
- {
- // r2.0, r2.01 or r2.02
- atv_version_found = true;
- fprintf(stderr, "Using key code for AppleTV r2.0x\n");
- key = key_cookiesATV20X;
- m_button_event_terminator = IR_Event_Term_ATV20X;
- }
- else if( strstr(linebuf,"8N5519"))
- {
- // r2.10
- atv_version_found = true;
- fprintf(stderr, "Using key code for AppleTV r2.1\n");
- key = key_cookiesATV21;
- m_button_event_terminator = IR_Event_Term_ATV21;
-
- }
- else if( strstr(linebuf,"8N5622"))
- {
- // r2.10
- atv_version_found = true;
- fprintf(stderr, "Using key code for AppleTV r2.2\n");
- key = key_cookiesATV21;
- m_button_event_terminator = IR_Event_Term_ATV21;
- }
- }
- pclose(inpipe);
- }
-
- if(!atv_version_found){
- //handle fallback or just exit
- fprintf(stderr, "AppletTV software version could not be determined.\n");
- fprintf(stderr, "Defaulting to using key code for AppleTV r2.1\n");
- key = key_cookiesATV21;
- m_button_event_terminator = IR_Event_Term_ATV21;
- }
- }
- else
- {
- fprintf(stderr, "Using key code for OSX 10.4\n");
- key = key_cookies10_4;
- m_button_event_terminator = IR_Event_Term_10_4;
- }
- }
- else
- {
- // OSX 10.5
- fprintf(stderr, "Using key code for OSX 10.5\n");
- key = key_cookies10_5;
- m_button_event_terminator = IR_Event_Term_10_5;
- }
- m_launch_xbmc_button = key[IR_MenuHold];
-
- RegisterCommand(key[IR_Select], new CPacketBUTTON(5, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(key[IR_SelectHold],new CPacketBUTTON(7, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(key[IR_Right], new CPacketBUTTON(4, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(key[IR_Left], new CPacketBUTTON(3, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(key[IR_Up], new CPacketBUTTON(1, "JS0:AppleRemote", BTN_DOWN));
- RegisterCommand(key[IR_Down], new CPacketBUTTON(2, "JS0:AppleRemote", BTN_DOWN));
- RegisterCommand(key[IR_RightHold], new CPacketBUTTON(4, "JS0:AppleRemote", BTN_DOWN));
- RegisterCommand(key[IR_LeftHold], new CPacketBUTTON(3, "JS0:AppleRemote", BTN_DOWN));
-
- RegisterCommand(key[IR_Menu], new CPacketBUTTON(6, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
-
- // Menu Hold will be used both for sending "Back" and for starting universal remote combinations (if universal mode is on)
- RegisterCommand(key[IR_MenuHold], new CPacketBUTTON(8, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
-
- // Universal commmands:
- RegisterCommand(key[IR_MenuHold] + key[IR_Down], new CPacketBUTTON("Back", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
-
- prefix = key[IR_MenuHold] + key[IR_Select];
- RegisterCommand(prefix + key[IR_Right], new CPacketBUTTON("Info", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Left], new CPacketBUTTON("Title", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Up], new CPacketBUTTON("PagePlus", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Down], new CPacketBUTTON("PageMinus", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Select],new CPacketBUTTON("Display", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
-
- prefix = key[IR_MenuHold] + key[IR_Up];
-
- RegisterCommand(prefix + key[IR_Select],new CPacketBUTTON("Stop", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Left], new CPacketBUTTON("Power", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Right], new CPacketBUTTON("Zero", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Up], new CPacketBUTTON("Play", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
- RegisterCommand(prefix + key[IR_Down], new CPacketBUTTON("Pause", "R1", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE));
-
- // for universal mode - some keys are part of a key combination.
- // when those keys are pressed, we'll wait for more to come - until a valid combination was entered or a timeout expired.
- // the keys "leading" a combination are added to the prefix vector.
- // all we need to do to turn universal mode off is clear the prefix vector and then every command will be sent immidiately.
- if (m_remoteMode == REMOTE_UNIVERSAL)
- {
- LOG("universal mode on. registering prefixes: %s\n", key[IR_MenuHold].c_str());
- m_universalPrefixes.push_back( key[IR_MenuHold] );
- }
- else
- {
- LOG("universal mode off.\n");
- m_universalPrefixes.clear();
- }
-
- m_strCombination.clear();
- m_bSendUpRequired = false;
-}
-
-void AppleRemote::DeInitialize()
-{
- LOG("uninitializing apple remote\n");
-
- ResetTimer();
-
- if (m_socket > 0)
- close(m_socket);
-
- m_socket = -1;
-
- LOG("deleting commands map\n");
- std::map<std::string, CPacketBUTTON *>::iterator iter = m_mapCommands.begin();
- while (iter != m_mapCommands.end())
- {
- delete iter->second;
- iter++;
- }
- m_mapCommands.clear();
- m_strCombination.clear();
-}
-
-void AppleRemote::SetTimer()
-{
- if (m_timer)
- ResetTimer();
-
- LOG("setting timer to expire in %.2f secs. \n", m_dMaxClickDuration);
- CFRunLoopTimerContext context = { 0, this, 0, 0, 0 };
- m_timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + m_dMaxClickDuration, 0, 0, 0, TimerCallBack, &context);
- CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_timer, kCFRunLoopCommonModes);
-}
-
-void AppleRemote::ResetTimer()
-{
- if (m_timer)
- {
- LOG("removing timer\n");
-
- CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), m_timer, kCFRunLoopCommonModes);
- CFRunLoopTimerInvalidate(m_timer);
- CFRelease(m_timer);
- }
-
- m_timer = NULL;
-}
-
-void AppleRemote::SetMaxClickDuration(double dDuration)
-{
- m_dMaxClickDuration = dDuration;
- LOG("setting click max duration to %.2f seconds\n", dDuration);
-}
-
-void AppleRemote::TimerCallBack (CFRunLoopTimerRef timer, void *info)
-{
- if (!info)
- {
- fprintf(stderr, "Error. invalid argument to timer callback\n");
- return;
- }
-
- AppleRemote *pRemote = (AppleRemote *)info;
- pRemote->SendCommand(pRemote->m_strCombination);
- pRemote->m_strCombination.clear();
- pRemote->ResetTimer();
-}
-
-bool AppleRemote::SendCommand(const std::string &key)
-{
- CPacketBUTTON *pPacket = m_mapCommands[key];
- if (pPacket)
- {
- LOG("Sending command for Key (%s)\n", key.c_str());
- CAddress addr(m_serverAddress.c_str());
- pPacket->Send(m_socket, addr);
-
- if ( 0 == (pPacket->GetFlags() & BTN_NO_REPEAT) )
- m_bSendUpRequired = true;
- else
- m_bSendUpRequired = false;
- }
-
- return pPacket != NULL;
-}
-
-void AppleRemote::LaunchApp()
-{
- // the path to xbmc.app is passed as an arg,
- // use this to launch from a menu press
- LOG("Trying to start XBMC: [%s]\n", m_appPath.c_str());
- if (!m_appPath.empty())
- {
- std::string strCmd;
-
- // build a finder open command
- strCmd = "XBMC_HOME=";
- strCmd += m_appHome;
- strCmd += " ";
- strCmd += m_appPath;
- strCmd += " &";
- LOG("xbmc open command: [%s]\n", strCmd.c_str());
- system(strCmd.c_str());
- }
-}
-
-void AppleRemote::SendPacket(CPacketBUTTON &packet)
-{
- CAddress addr(m_serverAddress.c_str());
- packet.Send(m_socket, addr);
-}
-
-void AppleRemote::OnKeyDown(const std::string &key)
-{
- if (!IsProgramRunning(APPLICATION_NAME) && (m_serverAddress == "localhost" || m_serverAddress == "127.0.0.1"))
- {
- if (key == m_launch_xbmc_button)
- LaunchApp();
-
- return;
- }
-
- LOG("key down: %s\n", key.c_str());
- if (m_remoteMode == REMOTE_NORMAL) {
- SendCommand(key);
- }
- else if (m_remoteMode == REMOTE_UNIVERSAL)
- {
- bool bCombinationStart = false;
- bool bNeedTimer = false;
- if (m_strCombination.empty())
- {
- bNeedTimer = true;
- for (size_t i=0; i<m_universalPrefixes.size(); i++)
- {
- if (m_universalPrefixes[i] == key)
- {
- LOG("start of combination (key=%s)\n", key.c_str());
- bCombinationStart = true;
- break;
- }
- }
- }
-
- m_strCombination += key;
-
- if (bCombinationStart)
- SetTimer();
- else
- {
- if (SendCommand(m_strCombination))
- {
- m_strCombination.clear();
- ResetTimer();
- }
- else if (bNeedTimer)
- SetTimer();
- }
- }
-}
-
-void AppleRemote::OnKeyUp(const std::string &key)
-{
- LOG("key up: %s\n", key.c_str());
- if (m_bSendUpRequired)
- {
- LOG("sending key-up event\n");
- CPacketBUTTON btn;
- CAddress addr(m_serverAddress.c_str());
- btn.Send(m_socket, addr);
- }
- else
- {
- LOG("no need to send UP event\n");
- }
-}
-
-void AppleRemote::SetVerbose(bool bVerbose)
-{
- m_bVerbose = bVerbose;
-}
-
-bool AppleRemote::IsVerbose()
-{
- return m_bVerbose;
-}
-
-void AppleRemote::SetMaxClickTimeout(double dTimeout)
-{
- m_dMaxClickDuration = dTimeout;
-}
-
-void AppleRemote::SetServerAddress(const std::string &strAddress)
-{
- m_serverAddress = strAddress;
-}
-
-void AppleRemote::SetAppPath(const std::string &strAddress)
-{
- m_appPath = strAddress;
-}
-
-void AppleRemote::SetAppHome(const std::string &strAddress)
-{
- m_appHome = strAddress;
-}
-
-const std::string &AppleRemote::GetServerAddress()
-{
- return m_serverAddress;
-}
-
-void AppleRemote::SetRemoteMode(RemoteModes mode)
-{
- m_remoteMode = mode;
-}
-
-bool AppleRemote::IsProgramRunning(const char* strProgram, int ignorePid)
-{
- kinfo_proc* mylist = (kinfo_proc *)malloc(sizeof(kinfo_proc));
- size_t mycount = 0;
- bool ret = false;
-
- GetBSDProcessList(&mylist, &mycount);
- for(size_t k = 0; k < mycount && ret == false; k++)
- {
- kinfo_proc *proc = NULL;
- proc = &mylist[k];
-
- //LOG("proc->kp_proc.p_comm: %s\n", proc->kp_proc.p_comm);
- // Process names are at most sixteen characters long.
- if (strncmp(proc->kp_proc.p_comm, strProgram, 16) == 0)
- {
- if (ignorePid == 0 || ignorePid != proc->kp_proc.p_pid)
- {
- //LOG("found: %s\n", proc->kp_proc.p_comm);
- ret = true;
- }
- }
- }
- free(mylist);
- return ret;
-}
-
-int AppleRemote::GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
- // Returns a list of all BSD processes on the system. This routine
- // allocates the list and puts it in *procList and a count of the
- // number of entries in *procCount. You are responsible for freeing
- // this list (use "free" from System framework).
- // On success, the function returns 0.
- // On error, the function returns a BSD errno value.
-{
- int err;
- kinfo_proc * result;
- bool done;
- static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
- // Declaring name as const requires us to cast it when passing it to
- // sysctl because the prototype doesn't include the const modifier.
- size_t length;
-
- assert( procList != NULL);
- assert(procCount != NULL);
-
- *procCount = 0;
-
- // We start by calling sysctl with result == NULL and length == 0.
- // That will succeed, and set length to the appropriate length.
- // We then allocate a buffer of that size and call sysctl again
- // with that buffer. If that succeeds, we're done. If that fails
- // with ENOMEM, we have to throw away our buffer and loop. Note
- // that the loop causes use to call sysctl with NULL again; this
- // is necessary because the ENOMEM failure case sets length to
- // the amount of data returned, not the amount of data that
- // could have been returned.
-
- result = NULL;
- done = false;
- do {
- assert(result == NULL);
-
- // Call sysctl with a NULL buffer.
-
- length = 0;
- err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
- NULL, &length,
- NULL, 0);
- if (err == -1) {
- err = errno;
- }
-
- // Allocate an appropriately sized buffer based on the results
- // from the previous call.
-
- if (err == 0) {
- result = (kinfo_proc* )malloc(length);
- if (result == NULL) {
- err = ENOMEM;
- }
- }
-
- // Call sysctl again with the new buffer. If we get an ENOMEM
- // error, toss away our buffer and start again.
-
- if (err == 0) {
- err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
- result, &length,
- NULL, 0);
- if (err == -1) {
- err = errno;
- }
- if (err == 0) {
- done = true;
- } else if (err == ENOMEM) {
- assert(result != NULL);
- free(result);
- result = NULL;
- err = 0;
- }
- }
- } while (err == 0 && ! done);
-
- // Clean up and establish post conditions.
-
- if (err != 0 && result != NULL) {
- free(result);
- result = NULL;
- }
- *procList = result;
- if (err == 0) {
- *procCount = length / sizeof(kinfo_proc);
- }
-
- assert( (err == 0) == (*procList != NULL) );
-
- return err;
-}
-
-int AppleRemote::GetButtonEventTerminator(void)
-{
- return(m_button_event_terminator);
-}
diff --git a/tools/EventClients/Clients/AppleRemote/AppleRemote.h b/tools/EventClients/Clients/AppleRemote/AppleRemote.h
deleted file mode 100644
index 45e3a427bc..0000000000
--- a/tools/EventClients/Clients/AppleRemote/AppleRemote.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * AppleRemote.h
- * AppleRemote
- *
- *
- */
-#ifndef __APPLE__REMOTE__H__
-#define __APPLE__REMOTE__H__
-
-#include <ctype.h>
-#include <Carbon/Carbon.h>
-
-#include <vector>
-#include <map>
-#include <string>
-
-typedef enum { REMOTE_NONE, REMOTE_NORMAL, REMOTE_UNIVERSAL } RemoteModes;
-typedef struct kinfo_proc kinfo_proc;
-
-class CPacketBUTTON;
-class AppleRemote
-{
-public:
- AppleRemote();
- virtual ~AppleRemote();
-
- void Initialize();
- void DeInitialize();
-
- void ResetTimer();
- void SetTimer();
-
- void OnKeyDown(const std::string &key);
- void OnKeyUp(const std::string &key);
-
- int GetButtonEventTerminator(void);
-
- void SetMaxClickDuration(double dDuration);
-
- void SetVerbose(bool bVerbose);
- bool IsVerbose();
-
- void SetMaxClickTimeout(double dTimeout);
- void SetServerAddress(const std::string &strAddress);
- void SetAppPath(const std::string &strAddress);
- void SetAppHome(const std::string &strAddress);
- void SetRemoteMode(RemoteModes mode);
-
- const std::string &GetServerAddress();
-
- static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount);
- bool IsProgramRunning(const char* strProgram, int ignorePid=0);
- void LaunchApp();
-
- void SendPacket(CPacketBUTTON &packet);
-
-protected:
- static void TimerCallBack (CFRunLoopTimerRef timer, void *info);
- void RegisterCommand(const std::string &strSequence, CPacketBUTTON *pPacket);
- bool SendCommand(const std::string &key);
- void ParseConfig();
-
- bool m_bVerbose;
- bool m_bSendUpRequired;
- RemoteModes m_remoteMode;
- double m_dMaxClickDuration;
- int m_socket;
- std::string m_strCombination;
- std::string m_serverAddress;
- std::string m_appPath;
- std::string m_appHome;
-
- std::map<std::string, CPacketBUTTON *> m_mapCommands;
- std::vector<std::string> m_universalPrefixes;
- std::string m_launch_xbmc_button;
- int m_button_event_terminator;
- CFRunLoopTimerRef m_timer;
-};
-
-#endif
diff --git a/tools/EventClients/Clients/AppleRemote/Makefile b/tools/EventClients/Clients/AppleRemote/Makefile
deleted file mode 100644
index 63518afe16..0000000000
--- a/tools/EventClients/Clients/AppleRemote/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-CXX=g++
-CC=g++
-
-CFLAGS+=-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4
-CFLAGS+=-Wall
-LDFLAGS+=-framework IOKit -framework Carbon -framework ForceFeedback
-
-OBJS = iremoted.o AppleRemote.o
-
-TARGET = ../../../osx/XBMCHelper
-CLEAN_FILES=$(TARGET)
-
-all: $(TARGET)
-
-$(TARGET): $(OBJS)
- g++ $(LDFLAGS) $(OBJS) -o $(TARGET)
-
-.cpp.o:
- $(CXX) -c $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o ${<:.cpp=.o}
-
-.c.o:
- $(CC) -c $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o ${<:.c=.o}
-
-clean:
- $(RM) -rf *.o ../../../osx/XBMCHelper
diff --git a/tools/EventClients/Clients/AppleRemote/XBox360.h b/tools/EventClients/Clients/AppleRemote/XBox360.h
deleted file mode 100644
index 88d6a0cb94..0000000000
--- a/tools/EventClients/Clients/AppleRemote/XBox360.h
+++ /dev/null
@@ -1,576 +0,0 @@
-#ifndef __XBOX360_H__
-#define __XBOX360_H__
-
-#include <IOKit/usb/IOUSBLib.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/hid/IOHIDLib.h>
-#include <IOKit/hid/IOHIDKeys.h>
-#include <IOKit/hid/IOHIDUsageTables.h>
-
-#include <ForceFeedback/ForceFeedback.h>
-
-#include <pthread.h>
-#include <string>
-#include <list>
-
-#include "AppleRemote.h"
-#include "../../lib/c++/xbmcclient.h"
-
-#define SAFELY(expr) if ((expr) != kIOReturnSuccess) { printf("ERROR: \"%s\".\n", #expr); return; }
-
-extern AppleRemote g_appleRemote;
-
-class XBox360Controller
-{
- public:
-
- static XBox360Controller* XBox360Controller::Create(io_service_t device, int deviceNum, bool deviceWireless)
- {
- XBox360Controller* controller = new XBox360Controller();
- IOReturn ret;
- IOCFPlugInInterface **plugInInterface;
- SInt32 score=0;
-
- ret = IOCreatePlugInInterfaceForService(device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score);
- if (ret == kIOReturnSuccess)
- {
- ret = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), (LPVOID*)&controller->hidDevice);
- (*plugInInterface)->Release(plugInInterface);
- if (ret == kIOReturnSuccess)
- {
- controller->forceFeedback=0;
- FFCreateDevice(device, &controller->forceFeedback);
- controller->index = deviceNum;
- controller->deviceHandle = device;
- controller->wireless = deviceWireless;
-
- char str[128];
- sprintf(str, "%s Controller %d", deviceWireless ? "Wireless" : "Wired", deviceNum);
- controller->name = str;
-
- return controller;
- }
- }
-
- return 0;
- }
-
- ~XBox360Controller()
- {
- if (deviceHandle != 0) IOObjectRelease(deviceHandle);
- if (hidDevice != 0) (*hidDevice)->Release(hidDevice);
- if (forceFeedback != 0) FFReleaseDevice(forceFeedback);
- }
-
- void start()
- {
- int i,j;
- CFRunLoopSourceRef eventSource;
-
- // Get serial.
- FFEFFESCAPE escape;
- unsigned char c;
- std::string serial;
-
- serial = getSerialNumber();
- //printf("SERIAL: %s, forceFeedback: 0x%08lx\n", serial.c_str(), forceFeedback);
-
- CFArrayRef elements;
- SAFELY((*hidDevice)->copyMatchingElements(hidDevice, NULL, &elements));
-
- for(i=0; i<CFArrayGetCount(elements); i++)
- {
- CFDictionaryRef element = (CFDictionaryRef)CFArrayGetValueAtIndex(elements, i);
- long usage, usagePage, longCookie;
-
- // Get cookie.
- if (getVal(element, CFSTR(kIOHIDElementCookieKey), longCookie) &&
- getVal(element, CFSTR(kIOHIDElementUsageKey), usage) &&
- getVal(element, CFSTR(kIOHIDElementUsagePageKey), usagePage))
- {
- IOHIDElementCookie cookie = (IOHIDElementCookie)longCookie;
-
- // Match up items
- switch (usagePage)
- {
- case 0x01: // Generic Desktop
- j=0;
- switch (usage)
- {
- case 0x35: j++; // Right trigger
- case 0x32: j++; // Left trigger
- case 0x34: j++; // Right stick Y
- case 0x33: j++; // Right stick X
- case 0x31: j++; // Left stick Y
- case 0x30: // Left stick X
- axis[j] = cookie;
- break;
- default:
- break;
- }
- break;
-
- case 0x09: // Button
- if (usage >= 1 && usage <= 15)
- {
- // Button 1-11
- buttons[usage-1] = cookie;
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- // Start queue.
- SAFELY((*hidDevice)->open(hidDevice, 0));
-
- hidQueue = (*hidDevice)->allocQueue(hidDevice);
- if (hidQueue == NULL)
- {
- printf("Unable to allocate queue\n");
- return;
- }
-
- // Create queue, set callback.
- SAFELY((*hidQueue)->create(hidQueue, 0, 32));
- SAFELY((*hidQueue)->createAsyncEventSource(hidQueue, &eventSource));
- SAFELY((*hidQueue)->setEventCallout(hidQueue, CallbackFunction, this, NULL));
-
- // Add to runloop.
- CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopCommonModes);
-
- // Add the elements.
- for(i=0; i<6; i++)
- (*hidQueue)->addElement(hidQueue, axis[i], 0);
- for(i=0; i<15; i++)
- (*hidQueue)->addElement(hidQueue, buttons[i], 0);
-
- // Start.
- SAFELY((*hidQueue)->start(hidQueue));
-
-#if 0
- // Read existing properties
- {
-// CFDictionaryRef dict=(CFDictionaryRef)IORegistryEntryCreateCFProperty(registryEntry,CFSTR("DeviceData"),NULL,0);
- CFDictionaryRef dict = (CFDictionaryRef)[GetController(GetSerialNumber(registryEntry)) retain];
- if(dict!=0) {
- CFBooleanRef boolValue;
- CFNumberRef intValue;
-
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertLeftX"),(void*)&boolValue)) {
- [leftStickInvertX setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState];
- } else NSLog(@"No value for InvertLeftX");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertLeftY"),(void*)&boolValue)) {
- [leftStickInvertY setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState];
- } else NSLog(@"No value for InvertLeftY");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("RelativeLeft"),(void*)&boolValue)) {
- BOOL enable=CFBooleanGetValue(boolValue);
- [leftLinked setState:enable?NSOnState:NSOffState];
- [leftStick setLinked:enable];
- } else NSLog(@"No value for RelativeLeft");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadzoneLeft"),(void*)&intValue)) {
- UInt16 i;
-
- CFNumberGetValue(intValue,kCFNumberShortType,&i);
- [leftStickDeadzone setIntValue:i];
- [leftStick setDeadzone:i];
- } else NSLog(@"No value for DeadzoneLeft");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertRightX"),(void*)&boolValue)) {
- [rightStickInvertX setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState];
- } else NSLog(@"No value for InvertRightX");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("InvertRightY"),(void*)&boolValue)) {
- [rightStickInvertY setState:CFBooleanGetValue(boolValue)?NSOnState:NSOffState];
- } else NSLog(@"No value for InvertRightY");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("RelativeRight"),(void*)&boolValue)) {
- BOOL enable=CFBooleanGetValue(boolValue);
- [rightLinked setState:enable?NSOnState:NSOffState];
- [rightStick setLinked:enable];
- } else NSLog(@"No value for RelativeRight");
- if(CFDictionaryGetValueIfPresent(dict,CFSTR("DeadzoneRight"),(void*)&intValue)) {
- UInt16 i;
-
- CFNumberGetValue(intValue,kCFNumberShortType,&i);
- [rightStickDeadzone setIntValue:i];
- [rightStick setDeadzone:i];
- } else NSLog(@"No value for DeadzoneRight");
- CFRelease(dict);
- } else NSLog(@"No settings found");
- }
-
- // Set LED and manual motor control
- // [self updateLED:0x0a];
- [self setMotorOverride:TRUE];
- [self testMotorsLarge:0 small:0];
- largeMotor=0;
- smallMotor=0;
-
- // Battery level?
- {
- NSBundle *bundle = [NSBundle bundleForClass:[self class]];
- NSString *path;
- CFTypeRef prop;
-
- path = nil;
- if (IOObjectConformsTo(registryEntry, "WirelessHIDDevice"))
- {
- prop = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("BatteryLevel"), NULL, 0);
- if (prop != nil)
- {
- unsigned char level;
-
- if (CFNumberGetValue(prop, kCFNumberCharType, &level))
- path = [bundle pathForResource:[NSString stringWithFormat:@"batt%i", level / 64] ofType:@"tif"];
- CFRelease(prop);
- }
- }
- if (path == nil)
- path = [bundle pathForResource:@"battNone" ofType:@"tif"];
- [batteryLevel setImage:[[[NSImage alloc] initByReferencingFile:path] autorelease]];
- }
- }
- #endif
-
- c = 0x0a;
- if (serial.length() > 0)
- {
- #if 0
- for (int i = 0; i < 4; i++)
- {
- if ((leds[i] == nil) || ([leds[i] caseInsensitiveCompare:serial] == NSOrderedSame))
- {
- c = 0x06 + i;
- if (leds[i] == nil)
- {
- //leds[i] = [serial retain];
- printf("Added controller with LED %i\n", i);
- }
- break;
- }
- }
- #endif
- }
- c = 0x06;
- escape.dwSize = sizeof(escape);
- escape.dwCommand = 0x02;
- escape.cbInBuffer = sizeof(c);
- escape.lpvInBuffer = &c;
- escape.cbOutBuffer = 0;
- escape.lpvOutBuffer = NULL;
- if (FFDeviceEscape(forceFeedback, &escape) != FF_OK)
- printf("Error: FF\n");
- }
-
- void stop()
- {
- if (hidQueue != 0)
- {
- // Stop the queue.
- (*hidQueue)->stop(hidQueue);
-
- // Remove from the run loop.
- CFRunLoopSourceRef eventSource = (*hidQueue)->getAsyncEventSource(hidQueue);
- if ((eventSource != 0) && CFRunLoopContainsSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopCommonModes))
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopCommonModes);
-
- // Whack.
- (*hidQueue)->Release(hidQueue);
- hidQueue = 0;
- }
-
- if (hidDevice != 0)
- (*hidDevice)->close(hidDevice);
- }
-
- std::string getName() { return name; }
-
- private:
-
- XBox360Controller()
- {
- for (int i=0; i<15; i++)
- buttons[i] = 0;
-
- for (int i=0; i<6; i++)
- axis[i] = 0;
- }
-
- std::string getSerialNumber()
- {
- CFTypeRef value = IORegistryEntrySearchCFProperty(deviceHandle, kIOServicePlane, CFSTR("SerialNumber"), kCFAllocatorDefault, kIORegistryIterateRecursively);
- std::string ret = std::string(CFStringGetCStringPtr((CFStringRef)value, kCFStringEncodingMacRoman));
- CFRelease(value);
-
- return ret;
- }
-
- void updateLED(int ledIndex)
- {
- FFEFFESCAPE escape;
- unsigned char c;
-
- if (forceFeedback ==0 )
- return;
-
- c = ledIndex;
- escape.dwSize = sizeof(escape);
- escape.dwCommand = 0x02;
- escape.cbInBuffer = sizeof(c);
- escape.lpvInBuffer = &c;
- escape.cbOutBuffer = 0;
- escape.lpvOutBuffer = NULL;
-
- if (FFDeviceEscape(forceFeedback, &escape) != FF_OK)
- printf("ERROR: FFDeviceEscape.\n");
- }
-
- static void CallbackFunction(void* me, IOReturn result, void* refCon, void* sender)
- {
- ((XBox360Controller* )me)->handleCallback(result, refCon, sender);
- }
-
- void handleCallback(IOReturn result, void* refCon, void* sender)
- {
- AbsoluteTime zeroTime={0,0};
- IOHIDEventStruct event;
- bool found = false;
- int i;
-
- if (sender != hidQueue)
- return;
-
- while (result == kIOReturnSuccess)
- {
- result = (*hidQueue)->getNextEvent(hidQueue, &event, zeroTime, 0);
- if (result != kIOReturnSuccess)
- continue;
-
- // Check axis
- for (i=0, found=FALSE; (i<6) && (!found); i++)
- {
- if (event.elementCookie == axis[i])
- {
- int amount = 0;
- if (i == 4 || i == 5)
- amount = event.value * (32768/256) + 32768;
- else
- amount = 65536 - (event.value + 32768) - 1;
-
- // Clip.
- if (amount > 65535)
- amount = 65535;
- if (amount < 0)
- amount = 0;
-
- if (g_appleRemote.IsVerbose())
- printf("Axis %d %d.\n", i+1, amount);
- CPacketBUTTON btn(i+1, "JS1:Wireless 360 Controller", BTN_AXIS | BTN_NO_REPEAT | BTN_USE_AMOUNT | BTN_QUEUE, amount);
- g_appleRemote.SendPacket(btn);
-
- found = true;
- }
- }
-
- if (found) continue;
-
- // Check buttons
- for (i=0, found=FALSE; (i<15) && (!found); i++)
- {
- if (event.elementCookie == buttons[i])
- {
- if (g_appleRemote.IsVerbose())
- printf("Button: %d %d.\n", i+1, (int)event.value);
-
- if (i+1 == 11 && !g_appleRemote.IsProgramRunning("XBMC", 0) &&
- (g_appleRemote.GetServerAddress() == "127.0.0.1" || g_appleRemote.GetServerAddress() == "localhost") &&
- event.value)
- {
- g_appleRemote.LaunchApp();
- return;
- }
-
- int flags = event.value ? BTN_DOWN : BTN_UP;
- CPacketBUTTON btn(i+1, "JS1:Wireless 360 Controller", flags, 0);
- g_appleRemote.SendPacket(btn);
- found = true;
- }
- }
-
- if (found) continue;
-
- // Cookie wasn't for us?
- }
- }
-
- bool getVal(CFDictionaryRef element, const CFStringRef key, long& value)
- {
- CFTypeRef object = CFDictionaryGetValue(element, key);
-
- if ((object == NULL) || (CFGetTypeID(object) != CFNumberGetTypeID())) return false;
- if (!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &value)) return false;
-
- return true;
- }
-
- IOHIDDeviceInterface122 **hidDevice;
- FFDeviceObjectReference forceFeedback;
- io_service_t deviceHandle;
-
- IOHIDQueueInterface **hidQueue;
- IOHIDElementCookie axis[6];
- IOHIDElementCookie buttons[15];
-
- std::string name;
- int index;
- bool wireless;
-};
-
-
-class XBox360
-{
- public:
-
- XBox360()
- {
- }
-
- void start()
- {
- pthread_create(&_itsThread, NULL, Run, (void *)this);
- }
-
- void join()
- {
- void* val = 0;
- pthread_join(_itsThread, &val);
- }
-
- protected:
-
- static void* Run(void* param)
- {
- ((XBox360* )param)->run();
- return 0;
- }
-
- void run()
- {
- printf("XBOX360: Registering for notifications.\n");
- io_object_t object;
-
- // Register for wired notifications.
- IONotificationPortRef notificationObject = IONotificationPortCreate(kIOMasterPortDefault);
- IOServiceAddMatchingNotification(notificationObject, kIOFirstMatchNotification, IOServiceMatching(kIOUSBDeviceClassName), callbackHandleDevice, this, &_itsOnIteratorWired);
- callbackHandleDevice(this, _itsOnIteratorWired);
-
- IOServiceAddMatchingNotification(notificationObject, kIOTerminatedNotification, IOServiceMatching(kIOUSBDeviceClassName), callbackHandleDevice, this, &_itsOffIteratorWired);
- while ((object = IOIteratorNext(_itsOffIteratorWired)) != 0)
- IOObjectRelease(object);
-
- // Wireless notifications.
- IOServiceAddMatchingNotification(notificationObject, kIOFirstMatchNotification, IOServiceMatching("WirelessHIDDevice"), callbackHandleDevice, this, &_itsOnIteratorWireless);
- callbackHandleDevice(this, _itsOnIteratorWireless);
-
- IOServiceAddMatchingNotification(notificationObject, kIOTerminatedNotification, IOServiceMatching("WirelessHIDDevice"), callbackHandleDevice, this, &_itsOffIteratorWireless);
- while ((object = IOIteratorNext(_itsOffIteratorWireless)) != 0)
- IOObjectRelease(object);
-
- // Add notifications to the run loop.
- CFRunLoopSourceRef notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationObject);
- CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode);
-
- // Run.
- CFRunLoopRun();
- printf("XBOX360: Exiting.\n");
- }
-
- private:
-
- // Callback for Xbox360 device notifications.
- static void callbackHandleDevice(void* param, io_iterator_t iterator)
- {
- io_service_t object = 0;
- bool update = false;
-
- while ((object = IOIteratorNext(iterator))!=0)
- {
- IOObjectRelease(object);
- update = true;
- }
-
- if (update)
- ((XBox360* )param)->updateDeviceList();
- }
-
- void updateDeviceList()
- {
- io_iterator_t iterator;
- io_object_t hidDevice;
-
- // Scrub and whack old items.
- stopDevices();
-
- for (std::list<XBox360Controller*>::iterator i = controllerList.begin(); i != controllerList.end(); ++i)
- delete *i;
- controllerList.clear();
-
- // Add new items
- CFMutableDictionaryRef hidDictionary = IOServiceMatching(kIOHIDDeviceKey);
- IOReturn ioReturn = IOServiceGetMatchingServices(kIOMasterPortDefault, hidDictionary, &iterator);
-
- if ((ioReturn != kIOReturnSuccess) || (iterator==0))
- {
- printf("No devices.\n");
- return;
- }
-
- for (int count = 1; (hidDevice = IOIteratorNext(iterator)); )
- {
- bool deviceWired = IOObjectConformsTo(hidDevice, "Xbox360ControllerClass");
- bool deviceWireless = IOObjectConformsTo(hidDevice, "WirelessHIDDevice");
-
- if (deviceWired || deviceWireless)
- {
- XBox360Controller* controller = XBox360Controller::Create(hidDevice, count, deviceWireless);
- if (controller)
- {
- // Add to list.
- printf("Adding device: %s.\n", controller->getName().c_str());
- controllerList.push_back(controller);
- count++;
- }
- }
- else
- {
- IOObjectRelease(hidDevice);
- }
- }
-
- IOObjectRelease(iterator);
-
- // Make sure all devices are started.
- startDevices();
- }
-
- void stopDevices()
- {
- for (std::list<XBox360Controller*>::iterator i = controllerList.begin(); i != controllerList.end(); ++i)
- (*i)->stop();
- }
-
- void startDevices()
- {
- for (std::list<XBox360Controller*>::iterator i = controllerList.begin(); i != controllerList.end(); ++i)
- (*i)->start();
- }
-
- std::list<XBox360Controller*> controllerList;
- pthread_t _itsThread;
- io_iterator_t _itsOnIteratorWired, _itsOffIteratorWired;
- io_iterator_t _itsOnIteratorWireless, _itsOffIteratorWireless;
-};
-
-#endif
diff --git a/tools/EventClients/Clients/AppleRemote/iremoted.c b/tools/EventClients/Clients/AppleRemote/iremoted.c
deleted file mode 100644
index 42b3258d03..0000000000
--- a/tools/EventClients/Clients/AppleRemote/iremoted.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * iremoted.c
- * Display events received from the Apple Infrared Remote.
- *
- * gcc -Wall -o iremoted iremoted.c -framework IOKit -framework Carbon
- *
- * Copyright (c) 2006-2008 Amit Singh. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
- */
-
-#define PROGNAME "iremoted"
-#define PROGVERS "2.0"
-
-#include <stdio.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <sys/errno.h>
-#include <sysexits.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/sysctl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <mach-o/dyld.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/hid/IOHIDLib.h>
-#include <IOKit/hid/IOHIDKeys.h>
-#include <IOKit/hid/IOHIDUsageTables.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Carbon/Carbon.h>
-
-#include <iostream>
-#include <fstream>
-#include <map>
-#include <string>
-#include <iterator>
-#include <sstream>
-#include <set>
-
-#include "AppleRemote.h"
-#include "XBox360.h"
-
-using namespace std;
-
-void ParseOptions(int argc, char** argv);
-void ReadConfig();
-
-static struct option long_options[] = {
- { "help", no_argument, 0, 'h' },
- { "server", required_argument, 0, 's' },
- { "universal", no_argument, 0, 'u' },
- { "multiremote",no_argument, 0, 'm' },
- { "timeout", required_argument, 0, 't' },
- { "verbose", no_argument, 0, 'v' },
- { "externalConfig", no_argument, 0, 'x' },
- { "appPath", required_argument, 0, 'a' },
- { "appHome", required_argument, 0, 'z' },
- { 0, 0, 0, 0 },
-};
-
-static const char *options = "hsumtvxaz";
-
-IOHIDElementCookie buttonNextID = 0;
-IOHIDElementCookie buttonPreviousID = 0;
-
-std::set<IOHIDElementCookie> g_registeredCookies;
-
-AppleRemote g_appleRemote;
-
-void usage(void);
-inline void print_errmsg_if_io_err(int expr, char *msg);
-inline void print_errmsg_if_err(int expr, char *msg);
-void QueueCallbackFunction(void *target, IOReturn result,
- void *refcon, void *sender);
-bool addQueueCallbacks(IOHIDQueueInterface **hqi);
-void processQueue(IOHIDDeviceInterface **hidDeviceInterface);
-void doRun(IOHIDDeviceInterface **hidDeviceInterface);
-void getHIDCookies(IOHIDDeviceInterface122 **handle);
-void createHIDDeviceInterface(io_object_t hidDevice,
- IOHIDDeviceInterface ***hdi);
-void setupAndRun(void);
-
-void
-usage(void)
-{
- printf("%s (version %s)\n", PROGNAME, PROGVERS);
- printf(" Sends Apple Remote events to XBMC.\n\n");
- printf("Usage: %s [OPTIONS...]\n\nOptions:\n", PROGNAME);
- printf(" -h, --help print this help message and exit.\n");
- printf(" -s, --server <addr> send events to the specified IP.\n");
- printf(" -u, --universal runs in Universal Remote mode.\n");
- printf(" -t, --timeout <ms> timeout length for sequences (default: 500ms).\n");
- printf(" -a, --appPath path to XBMC.app (MenuPress launch support).\n");
- printf(" -z, --appHome path to XBMC.app/Content/Resources/XBMX \n");
- printf(" -v, --verbose prints lots of debugging information.\n");
-}
-
-inline void
-print_errmsg_if_io_err(int expr, char *msg)
-{
- IOReturn err = (expr);
-
- if (err != kIOReturnSuccess) {
- fprintf(stderr, "*** %s - %s(%x, %d).\n", msg, mach_error_string(err),
- err, err & 0xffffff);
- fflush(stderr);
- exit(EX_OSERR);
- }
-}
-
-inline void
-print_errmsg_if_err(int expr, char *msg)
-{
- if (expr) {
- fprintf(stderr, "*** %s.\n", msg);
- fflush(stderr);
- exit(EX_OSERR);
- }
-}
-
-void
-QueueCallbackFunction(void *target, IOReturn result, void *refcon, void *sender)
-{
- HRESULT ret = kIOReturnSuccess;
- AbsoluteTime zeroTime = {0,0};
- IOHIDQueueInterface **hqi;
- IOHIDEventStruct event;
-
- std::set<int> events;
- bool bKeyDown = false;
- while (ret == kIOReturnSuccess) {
- hqi = (IOHIDQueueInterface **)sender;
- ret = (*hqi)->getNextEvent(hqi, &event, zeroTime, 0);
- if (ret != kIOReturnSuccess)
- continue;
-
- //printf("%d %d %d\n", (int)event.elementCookie, (int)event.value, (int)event.longValue);
-
- if (event.value > 0)
- bKeyDown = true;
-
- events.insert((int)event.elementCookie);
- }
-
- if (events.size() > 1)
- {
- std::set<int>::iterator iter = events.find( g_appleRemote.GetButtonEventTerminator() );
- if (iter != events.end())
- events.erase(iter);
- }
-
- std::string strEvents;
- std::set<int>::const_iterator iter = events.begin();
- while (iter != events.end())
- {
- //printf("*iter = %d\n", *iter);
- char strEvent[10];
- snprintf(strEvent, 10, "%d_", *iter);
- strEvents += strEvent;
- iter++;
- }
-
- if (bKeyDown)
- g_appleRemote.OnKeyDown(strEvents);
- else
- g_appleRemote.OnKeyUp(strEvents);
-}
-
-bool
-addQueueCallbacks(IOHIDQueueInterface **hqi)
-{
- IOReturn ret;
- CFRunLoopSourceRef eventSource;
- IOHIDQueueInterface ***privateData;
-
- privateData = (IOHIDQueueInterface ***)malloc(sizeof(*privateData));
- *privateData = hqi;
-
- ret = (*hqi)->createAsyncEventSource(hqi, &eventSource);
- if (ret != kIOReturnSuccess)
- return false;
-
- ret = (*hqi)->setEventCallout(hqi, QueueCallbackFunction,
- NULL, &privateData);
- if (ret != kIOReturnSuccess)
- return false;
-
- CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource,
- kCFRunLoopDefaultMode);
- return true;
-}
-
-void
-processQueue(IOHIDDeviceInterface **hidDeviceInterface)
-{
- HRESULT result;
- IOHIDQueueInterface **queue;
-
- queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
- if (!queue) {
- fprintf(stderr, "Failed to allocate event queue.\n");
- return;
- }
-
- (void)(*queue)->create(queue, 0, 99);
-
- std::set<IOHIDElementCookie>::const_iterator iter = g_registeredCookies.begin();
- while (iter != g_registeredCookies.end())
- {
- (void)(*queue)->addElement(queue, *iter, 0);
- iter++;
- }
-
- addQueueCallbacks(queue);
-
- result = (*queue)->start(queue);
-
- CFRunLoopRun();
-
- result = (*queue)->stop(queue);
-
- result = (*queue)->dispose(queue);
-
- (*queue)->Release(queue);
-}
-
-void
-doRun(IOHIDDeviceInterface **hidDeviceInterface)
-{
- IOReturn ioReturnValue;
-
- ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice);
- if (ioReturnValue == kIOReturnExclusiveAccess) {
- printf("exclusive lock failed\n");
- }
-
- processQueue(hidDeviceInterface);
-
- if (ioReturnValue == KERN_SUCCESS)
- ioReturnValue = (*hidDeviceInterface)->close(hidDeviceInterface);
- (*hidDeviceInterface)->Release(hidDeviceInterface);
-}
-
-void
-getHIDCookies(IOHIDDeviceInterface122 **handle)
-{
- IOHIDElementCookie cookie;
- CFTypeRef object;
- long number;
- long usage;
- long usagePage;
- CFArrayRef elements;
- CFDictionaryRef element;
- IOReturn result;
-
- if (!handle || !(*handle))
- return ;
-
- result = (*handle)->copyMatchingElements(handle, NULL, &elements);
-
- if (result != kIOReturnSuccess) {
- fprintf(stderr, "Failed to copy cookies.\n");
- exit(1);
- }
-
- CFIndex i;
- for (i = 0; i < CFArrayGetCount(elements); i++) {
- element = (CFDictionaryRef)CFArrayGetValueAtIndex(elements, i);
- object = (CFDictionaryGetValue(element, CFSTR(kIOHIDElementCookieKey)));
- if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
- continue;
- if(!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, &number))
- continue;
- cookie = (IOHIDElementCookie)number;
- object = CFDictionaryGetValue(element, CFSTR(kIOHIDElementUsageKey));
- if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
- continue;
- if (!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &number))
- continue;
- usage = number;
- object = CFDictionaryGetValue(element,CFSTR(kIOHIDElementUsagePageKey));
- if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
- continue;
- if (!CFNumberGetValue((CFNumberRef)object, kCFNumberLongType, &number))
- continue;
- usagePage = number;
- if (usagePage == 0x06 && usage == 0x22 ) // event code "39". menu+select for 5 secs
- g_registeredCookies.insert(cookie);
- else if (usagePage == 0xff01 && usage == 0x23 ) // event code "35". long click - select
- g_registeredCookies.insert(cookie);
- else if (usagePage == kHIDPage_GenericDesktop && usage >= 0x80 && usage <= 0x8d ) // regular keys
- g_registeredCookies.insert(cookie);
- else if (usagePage == kHIDPage_Consumer && usage >= 0xB0 && usage <= 0xBF)
- g_registeredCookies.insert(cookie);
- else if (usagePage == kHIDPage_Consumer && usage == kHIDUsage_Csmr_Menu ) // event code "18". long "menu"
- g_registeredCookies.insert(cookie);
- }
-}
-
-void
-createHIDDeviceInterface(io_object_t hidDevice, IOHIDDeviceInterface ***hdi)
-{
- io_name_t className;
- IOCFPlugInInterface **plugInInterface = NULL;
- HRESULT plugInResult = S_OK;
- SInt32 score = 0;
- IOReturn ioReturnValue = kIOReturnSuccess;
-
- ioReturnValue = IOObjectGetClass(hidDevice, className);
- print_errmsg_if_io_err(ioReturnValue, "Failed to get class name.");
-
- ioReturnValue = IOCreatePlugInInterfaceForService(
- hidDevice,
- kIOHIDDeviceUserClientTypeID,
- kIOCFPlugInInterfaceID,
- &plugInInterface,
- &score);
-
- if (ioReturnValue != kIOReturnSuccess)
- return;
-
- plugInResult = (*plugInInterface)->QueryInterface(
- plugInInterface,
- CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
- (LPVOID*)hdi);
- print_errmsg_if_err(plugInResult != S_OK,
- "Failed to create device interface.\n");
-
- (*plugInInterface)->Release(plugInInterface);
-}
-
-void
-setupAndRun(void)
-{
- CFMutableDictionaryRef hidMatchDictionary = NULL;
- io_service_t hidService = (io_service_t)0;
- io_object_t hidDevice = (io_object_t)0;
- IOHIDDeviceInterface **hidDeviceInterface = NULL;
- IOReturn ioReturnValue = kIOReturnSuccess;
-
- //hidMatchDictionary = IOServiceNameMatching("AppleIRController");
- hidMatchDictionary = IOServiceMatching("AppleIRController");
- hidService = IOServiceGetMatchingService(kIOMasterPortDefault,
- hidMatchDictionary);
-
- if (!hidService) {
- fprintf(stderr, "Apple Infrared Remote not found.\n");
- exit(1);
- }
-
- hidDevice = (io_object_t)hidService;
-
- createHIDDeviceInterface(hidDevice, &hidDeviceInterface);
- getHIDCookies((IOHIDDeviceInterface122 **)hidDeviceInterface);
- ioReturnValue = IOObjectRelease(hidDevice);
- print_errmsg_if_io_err(ioReturnValue, "Failed to release HID.");
-
- if (hidDeviceInterface == NULL) {
- fprintf(stderr, "No HID.\n");
- exit(1);
- }
-
- g_appleRemote.Initialize();
- doRun(hidDeviceInterface);
-
- if (ioReturnValue == KERN_SUCCESS)
- ioReturnValue = (*hidDeviceInterface)->close(hidDeviceInterface);
-
- (*hidDeviceInterface)->Release(hidDeviceInterface);
-}
-
-void Reconfigure(int nSignal)
-{
- if (nSignal == SIGHUP) {
- //fprintf(stderr, "Reconfigure\n");
- ReadConfig();
- } else {
- exit(0);
- }
-}
-
-void ReadConfig()
-{
- // Compute filename.
- string strFile = getenv("HOME");
- strFile += "/Library/Application Support/XBMC/XBMCHelper.conf";
-
- // Open file.
- ifstream ifs(strFile.c_str());
- if (!ifs)
- return;
-
- // Read file.
- stringstream oss;
- oss << ifs.rdbuf();
-
- if (!ifs && !ifs.eof())
- return;
-
- // Tokenize.
- string strData(oss.str());
- istringstream is(strData);
- vector<string> args = vector<string>(istream_iterator<string>(is), istream_iterator<string>());
-
- // Convert to char**.
- int argc = args.size() + 1;
- char** argv = new char*[argc + 1];
- int i = 0;
- argv[i++] = "XBMCHelper";
-
- for (vector<string>::iterator it = args.begin(); it != args.end(); )
- argv[i++] = (char* )(*it++).c_str();
-
- argv[i] = 0;
-
- // Parse the arguments.
- ParseOptions(argc, argv);
-
- delete[] argv;
-}
-
-void ParseOptions(int argc, char** argv)
-{
- int c, option_index = 0;
- bool readExternal = false;
-
- while ((c = getopt_long(argc, argv, options, long_options, &option_index)) != -1)
- {
- switch (c) {
- case 'h':
- usage();
- exit(0);
- break;
- case 'v':
- g_appleRemote.SetVerbose(true);
- break;
- case 's':
- g_appleRemote.SetServerAddress(optarg);
- break;
- case 'u':
- g_appleRemote.SetRemoteMode(REMOTE_UNIVERSAL);
- break;
- case 'm':
- break;
- case 't':
- if (optarg)
- g_appleRemote.SetMaxClickTimeout( atof(optarg) * 0.001 );
- break;
- case 'a':
- g_appleRemote.SetAppPath(optarg);
- break;
- case 'z':
- g_appleRemote.SetAppHome(optarg);
- break;
- case 'x':
- readExternal = true;
- break;
- default:
- usage();
- exit(1);
- break;
- }
- }
- //reset getopts state
- optreset = 1;
- optind = 0;
-
- if (readExternal == true)
- ReadConfig();
-}
-
-int
-main (int argc, char **argv)
-{
- ParseOptions(argc,argv);
-
- signal(SIGHUP, Reconfigure);
- signal(SIGINT, Reconfigure);
- signal(SIGTERM, Reconfigure);
-
- XBox360 xbox360;
- xbox360.start();
-
- setupAndRun();
-
- xbox360.join();
-
- return 0;
-}