Skip to content

Commit

Permalink
Remove AppleTV specific code from AppleRemote.cpp.
Browse files Browse the repository at this point in the history
There was a test in this code for macVersion higher than 10.4, which
can now be assumed to be true.  Strip out this test and all functions
that are no longer needed.
  • Loading branch information
linuxdude42 committed Apr 29, 2020
1 parent 1b04995 commit a702905
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 286 deletions.
280 changes: 1 addition & 279 deletions mythtv/libs/libmythui/devices/AppleRemote.cpp
Expand Up @@ -27,21 +27,11 @@ AppleRemote* AppleRemote::_instance = nullptr;

#define REMOTE_SWITCH_COOKIE 19
#define REMOTE_COOKIE_STR "19_"
#define ATV_COOKIE_STR "17_9_280_"
#define LONG_PRESS_COUNT 10
#define KEY_RESPONSE_TIME 150 /* msecs before we send a key up event */

#define LOC QString("AppleRemote::")

struct ATV_IR_EVENT
{
UInt32 time_ms32;
UInt32 time_ls32; // units of microsecond
UInt32 unknown1;
UInt32 keycode;
UInt32 unknown2;
};

static io_object_t _findAppleRemoteDevice(const char *devName);

AppleRemote * AppleRemote::Get()
Expand All @@ -56,9 +46,6 @@ AppleRemote::~AppleRemote()
{
stopListening();

if (mUsingNewAtv)
delete mCallbackTimer;

if (isRunning())
{
exit(0);
Expand Down Expand Up @@ -131,60 +118,8 @@ void AppleRemote::run()
RunEpilog();
}

// Figure out if we're running on the Apple TV, and what version
static float GetATVversion()
{
SInt32 macVersion;
size_t len = 512;
char hw_model[512] = "unknown";


Gestalt(gestaltSystemVersion, &macVersion);

if ( macVersion > 0x1040 ) // Mac OS 10.5 or greater is
return 0.0; // definitely not an Apple TV

sysctlbyname("hw.model", &hw_model, &len, nullptr, 0);

float version = 0.0;
if ( strstr(hw_model,"AppleTV1,1") )
{
// Find the build version of the AppleTV OS
FILE *inpipe = popen("sw_vers -buildVersion", "r");
char linebuf[1000];
if (inpipe && fgets(linebuf, sizeof(linebuf) - 1, inpipe) )
{
if ( strstr(linebuf,"8N5107") ) version = 1.0;
else if (strstr(linebuf,"8N5239") ) version = 1.1;
else if (strstr(linebuf,"8N5400") ) version = 2.0;
else if (strstr(linebuf,"8N5455") ) version = 2.01;
else if (strstr(linebuf,"8N5461") ) version = 2.02;
else if (strstr(linebuf,"8N5519") ) version = 2.1;
else if (strstr(linebuf,"8N5622") ) version = 2.2;
else
version = 2.3;
}
if (inpipe)
pclose(inpipe);
}
return version;
}

// protected
AppleRemote::AppleRemote() : MThread("AppleRemote")
{
if ( GetATVversion() > 2.2 )
{
LOG(VB_GENERAL, LOG_INFO,
LOC + "AppleRemote() detected Apple TV > v2.3");
mUsingNewAtv = true;
mCallbackTimer = new QTimer();
QObject::connect(mCallbackTimer, SIGNAL(timeout()),
(const QObject*)this, SLOT(TimeoutHandler()));
mCallbackTimer->setSingleShot(true);
mCallbackTimer->setInterval(KEY_RESPONSE_TIME);
}

_initCookieMap();
}

Expand Down Expand Up @@ -225,38 +160,6 @@ void AppleRemote::_initCookieMap()
cookieToButtonMapping["35_31_18_35_31_18_"] = PlayHold;
cookieToButtonMapping["39_"] = ControlSwitched;

// ATV 1.0, 2.0-2.02
cookieToButtonMapping["14_12_11_6_"] = Up;
cookieToButtonMapping["14_13_11_6_"] = Down;
cookieToButtonMapping["14_7_6_14_7_6_"] = Menu;
cookieToButtonMapping["14_8_6_14_8_6_"] = Select;
cookieToButtonMapping["14_9_6_14_9_6_"] = Right;
cookieToButtonMapping["14_10_6_14_10_6_"] = Left;
cookieToButtonMapping["14_6_4_2_"] = RightHold;
cookieToButtonMapping["14_6_3_2_"] = LeftHold;
cookieToButtonMapping["14_6_14_6_"] = MenuHold;
cookieToButtonMapping["18_14_6_18_14_6_"] = PlayHold;

// ATV 1.0, 2.1-2.2
cookieToButtonMapping["15_13_12_"] = Up;
cookieToButtonMapping["15_14_12_"] = Down;
cookieToButtonMapping["15_8_15_8_"] = Menu;
cookieToButtonMapping["15_9_15_9_"] = Select;
cookieToButtonMapping["15_10_15_10_"] = Right;
cookieToButtonMapping["15_11_15_11_"] = Left;
cookieToButtonMapping["15_5_3_"] = RightHold;
cookieToButtonMapping["15_4_3_"] = LeftHold;
cookieToButtonMapping["15_6_15_6_"] = MenuHold;
cookieToButtonMapping["19_15_19_15_"] = PlayHold;

// ATV 2.30
cookieToButtonMapping["17_9_280_80"] = Up;
cookieToButtonMapping["17_9_280_48"] = Down;
cookieToButtonMapping["17_9_280_64"] = Menu;
cookieToButtonMapping["17_9_280_32"] = Select;
cookieToButtonMapping["17_9_280_96"] = Right;
cookieToButtonMapping["17_9_280_16"] = Left;

// 10.6 sequences:
cookieToButtonMapping["33_31_30_21_20_2_"] = Up;
cookieToButtonMapping["33_32_30_21_20_2_"] = Down;
Expand Down Expand Up @@ -436,10 +339,7 @@ void AppleRemote::QueueCallbackFunction(void* target, IOReturn result,
{
auto* remote = static_cast<AppleRemote*>(target);

if (remote->mUsingNewAtv)
remote->_queueCallbackATV23(result);
else
remote->_queueCallbackFunction(result, refcon, sender);
remote->_queueCallbackFunction(result, refcon, sender);
}

void AppleRemote::_queueCallbackFunction(IOReturn result,
Expand Down Expand Up @@ -472,49 +372,6 @@ void AppleRemote::_queueCallbackFunction(IOReturn result,
_handleEventWithCookieString(cookieString.str(), sumOfValues);
}

void AppleRemote::_queueCallbackATV23(IOReturn result)
{
AbsoluteTime zeroTime = {0,0};
SInt32 sumOfValues = 0;
std::stringstream cookieString;
UInt32 key_code = 0;


if (mCallbackTimer->isActive())
{
mCallbackTimer->stop();
}

while (result == kIOReturnSuccess)
{
IOHIDEventStruct event;

result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
if (result != kIOReturnSuccess)
continue;

if ( ((int)event.elementCookie == 280) && (event.longValueSize == 20))
{
auto* atv_ir_event = (ATV_IR_EVENT*)event.longValue;
key_code = atv_ir_event->keycode;
}

if (((int)event.elementCookie) != 5 )
{
sumOfValues += event.value;
cookieString << std::dec << (int)event.elementCookie << "_";
}
}

if (strcmp(cookieString.str().c_str(), ATV_COOKIE_STR) == 0)
{
cookieString << std::dec << (int) ( (key_code & 0x00007F00) >> 8);

sumOfValues = 1;
_handleEventATV23(cookieString.str(), sumOfValues);
}
}

void AppleRemote::_handleEventWithCookieString(std::string cookieString,
SInt32 sumOfValues)
{
Expand All @@ -528,138 +385,3 @@ void AppleRemote::_handleEventWithCookieString(std::string cookieString,
_listener->appleRemoteButton(buttonid, sumOfValues>0);
}
}

// With the ATV from 2.3 onwards, we just get IR events.
// We need to simulate the key up and hold events

void AppleRemote::_handleEventATV23(std::string cookieString,
SInt32 /*sumOfValues*/)
{
std::map<std::string,AppleRemote::Event>::iterator ii;
ii = cookieToButtonMapping.find(cookieString);

if (ii != cookieToButtonMapping.end() )
{
AppleRemote::Event event = ii->second;

if (mLastEvent == Undefined) // new event
{
mEventCount = 1;
// Need to figure out if this is a long press or a short press,
// so can't just send a key down event right now. It will be
// scheduled to run
}
else if (event != mLastEvent) // a new event, faster than timer
{
mEventCount = 1;
mKeyIsDown = true;

if (_listener)
{
// Only send key up events for events that have separateRelease
// defined as true in AppleRemoteListener.cpp
if (mLastEvent == Up || mLastEvent == Down ||
mLastEvent == LeftHold || mLastEvent == RightHold)
{
_listener->appleRemoteButton(mLastEvent,
/*pressedDown*/false);
}
_listener->appleRemoteButton(event, mKeyIsDown);
}
}
else // Same event again
{
AppleRemote::Event newEvent = Undefined;

++mEventCount;

// Can the event have a hold state?
switch (event)
{
case Right:
newEvent = RightHold;
break;
case Left:
newEvent = LeftHold;
break;
case Menu:
newEvent = MenuHold;
break;
case Select:
newEvent = PlayHold;
break;
default:
newEvent = event;
}

if (newEvent == event) // Doesn't have a long press
{
if (mKeyIsDown)
{
if (_listener)
{
// Only send key up events for events that have separateRelease
// defined as true in AppleRemoteListener.cpp
if (mLastEvent == Up || mLastEvent == Down ||
mLastEvent == LeftHold || mLastEvent == RightHold)
{
_listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
}
}
}

mKeyIsDown = true;
if (_listener)
{
_listener->appleRemoteButton(newEvent, mKeyIsDown);
}
}
else if (mEventCount == LONG_PRESS_COUNT)
{
mKeyIsDown = true;
if (_listener)
{
_listener->appleRemoteButton(newEvent, mKeyIsDown);
}
}
}

mLastEvent = event;
mCallbackTimer->start();
}
}

// Calls key down / up events on the ATV > v2.3
void AppleRemote::TimeoutHandler()
{
if (_listener)
{
_listener->appleRemoteButton(mLastEvent, !mKeyIsDown);
}

mKeyIsDown = !mKeyIsDown;

if (!mKeyIsDown)
{
mEventCount = 0;
mLastEvent = Undefined;
}
else
{
// Schedule a key up event for events that have separateRelease
// defined as true in AppleRemoteListener.cpp

if (mLastEvent == Up || mLastEvent == Down ||
mLastEvent == LeftHold || mLastEvent == RightHold)
{
mCallbackTimer->start();
}
else
{
mKeyIsDown = false;
mEventCount = 0;
mLastEvent = Undefined;
}

}
}
7 changes: 0 additions & 7 deletions mythtv/libs/libmythui/devices/AppleRemote.h
Expand Up @@ -72,7 +72,6 @@ class AppleRemote : public QObject, public MThread
int remoteId {0};
Listener* _listener {nullptr};

bool mUsingNewAtv {false};
AppleRemote::Event mLastEvent {AppleRemote::Undefined};
int mEventCount {0};
bool mKeyIsDown {false};
Expand All @@ -87,14 +86,8 @@ class AppleRemote : public QObject, public MThread
void* refcon, void* sender);
void _queueCallbackFunction(IOReturn result,
void* refcon, void* sender);
void _queueCallbackATV23(IOReturn result);
void _handleEventWithCookieString(std::string cookieString,
SInt32 sumOfValues);
void _handleEventATV23(std::string cookieString, SInt32 sumOfValues);

private slots:
// Key up event handling on the ATV v2.3 and above
void TimeoutHandler();
};

#endif // APPLEREMOTE

0 comments on commit a702905

Please sign in to comment.