Ticket #6422: mythtv-0.24-atv.patch

File mythtv-0.24-atv.patch, 23.5 KB (added by emlyn.bolton@…, 13 years ago)

Proper patch for 0.24-fixes branch

  • mythtv/configure

    diff --git a/mythtv/configure b/mythtv/configure
    index 1efe803..6d012b0 100755
    a b EOF 
    30603060            disable mmx
    30613061            enable disable_mmx_for_debugging   # prevent later call to die
    30623062        fi
     3063                disable ffmpeg
    30633064        disable opengl_vsync
    30643065        disable v4l
    30653066        disable x11
    30663067        # Workaround compile errors from missing gmtime_r/localtime_r/uint def
    30673068        CFLAGS=`echo $CFLAGS | sed 's/-D_POSIX_C_SOURCE=200112//'`
    30683069        ###### Standard ffmpeg configure stuff follows:
    3069         SHFLAGS='-dynamiclib -Wl,-single_module -Wl,-install_name,$(SHLIBDIR)/$(SLIBNAME),-current_version,$(LIBVERSION),-compatibility_version,$(LIBMAJOR) -Wl,-read_only_relocs,suppress'
     3070        SHFLAGS='-dynamiclib -Wl,-single_module -Wl,-install_name,$(SHLIBDIR)/$(SLIBNAME),-current_version,$(LIBVERSION),-compatibility_version,99 -Wl,-read_only_relocs,suppress'
    30703071        strip="${strip} -x"
    30713072        add_ldflags -Wl,-dynamic,-search_paths_first
    30723073        SLIBSUF=".dylib"
    fi 
    45684569
    45694570if test $target_os = darwin; then
    45704571  # Qt, by default builds .app bundles everywhere. Prevent this.
    4571   enabled mac_bundle || echo "CONFIG -= app_bundle" >> $MYTH_CONFIG_MAK
     4572  enabled mac_bundle || echo "CONFIG-= app_bundle" >> $MYTH_CONFIG_MAK
    45724573fi
    45734574
    45744575cat > $TMPH <<EOF
  • mythtv/filters/yadif/yadif.pro

    diff --git a/mythtv/filters/yadif/yadif.pro b/mythtv/filters/yadif/yadif.pro
    index ec45a0a..9011d54 100644
    a b contains(ARCH_X86, yes) { 
    1212}
    1313
    1414macx:debug:DEFINES -= MMX
     15
     16macx {
     17        CC            = gcc-4.0
     18        CXX           = g++-4.0
     19}
  • mythtv/libs/libmyth/libmyth.pro

    diff --git a/mythtv/libs/libmyth/libmyth.pro b/mythtv/libs/libmyth/libmyth.pro
    index fb4f5e6..581fc8b 100644
    a b LIBS += -L../libmythui -lmythui-$${LIBVERSION} 
    8383LIBS += -L../libmythupnp         -lmythupnp-$${LIBVERSION}
    8484LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION}
    8585LIBS += -L../../external/FFmpeg/libavcodec -lmythavcodec
    86 LIBS += -L../../external/FFmpeg/libavcore  -lmythavcodec
     86LIBS += -L../../external/FFmpeg/libavcore  -lmythavcore
    8787LIBS += -L../../external/FFmpeg/libavutil  -lmythavutil
    8888
    8989TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
  • mythtv/libs/libmythtv/darwinfirewiredevice.cpp

    diff --git a/mythtv/libs/libmythtv/darwinfirewiredevice.cpp b/mythtv/libs/libmythtv/darwinfirewiredevice.cpp
    index 6046b86..2b005dc 100644
    a b using namespace std; 
    3030
    3131// Apple Firewire example headers
    3232#include <AVCVideoServices/StringLogger.h>
    33 #include <AVCVideoServices/AVSShared.h>
    3433#include <AVCVideoServices/MPEG2Receiver.h>
    3534
    3635// header not used because it also requires MPEG2Transmitter.h
  • mythtv/libs/libmythtv/decoderbase.h

    diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h
    index e4311e3..6d913c7 100644
    a b class TeletextViewer; 
    1818class MythPlayer;
    1919class AudioPlayer;
    2020
    21 const int kDecoderProbeBufferSize = 128 * 1024;
     21const int kDecoderProbeBufferSize = 65536;
    2222
    2323/// Track types
    2424typedef enum TrackTypes
  • mythtv/libs/libmythtv/privatedecoder_vda.cpp

    diff --git a/mythtv/libs/libmythtv/privatedecoder_vda.cpp b/mythtv/libs/libmythtv/privatedecoder_vda.cpp
    index 0414042..853cf23 100644
    a b bool PrivateDecoderVDA::Init(const QString &decoder, 
    198198#ifdef USING_QUARTZ_VIDEO
    199199    OSType cvPixelFormatType = k422YpCbCr8PixelFormat;
    200200#else
    201     OSType cvPixelFormatType = kCVPixelFormatType_422YpCbCr8;
     201    //OSType cvPixelFormatType = kCVPixelFormatType_422YpCbCr8;
     202        OSType cvPixelFormatType = '2vuy';
    202203#endif
    203204    CFNumberRef pixelFormat  = CFNumberCreate(kCFAllocatorDefault,
    204205                                              kCFNumberSInt32Type,
  • mythtv/libs/libmythui/AppleRemote.cpp

    diff --git a/mythtv/libs/libmythui/AppleRemote.cpp b/mythtv/libs/libmythui/AppleRemote.cpp
    index 76d9e34..1409286 100644
    a b  
    66#include <stdlib.h>
    77#include <ctype.h>
    88#include <sys/errno.h>
     9#include <sys/sysctl.h>
    910#include <sysexits.h>
    1011#include <mach/mach.h>
    1112#include <mach/mach_error.h>
     
    1415#include <IOKit/hid/IOHIDLib.h>
    1516#include <IOKit/hid/IOHIDKeys.h>
    1617#include <CoreFoundation/CoreFoundation.h>
     18#include <CoreServices/CoreServices.h>
    1719
    1820#include <sstream>
     21#include <QTimer>
     22
     23
    1924
    2025#include "mythverbose.h"
    2126
    2227AppleRemote*      AppleRemote::_instance = 0;
    2328const int         AppleRemote::REMOTE_SWITCH_COOKIE = 19;
     29// For ATV v2.3 onwards
     30const int                 LONG_PRESS_COUNT = 10;
     31const int                 KEY_RESPONSE_TIME = 150;      // msecs before we send a key up event
    2432
    2533const QString     LOC = "AppleRemote::";
    2634
     35typedef struct _ATV_IR_EVENT {
     36        UInt32    time_ms32;
     37        UInt32    time_ls32; // units of microsecond
     38        UInt32    unknown1;
     39        UInt32    keycode;
     40        UInt32    unknown2;
     41} ATV_IR_EVENT;
     42
    2743static io_object_t _findAppleRemoteDevice(const char *devName);
    2844
    2945AppleRemote::Listener::~Listener()
    AppleRemote::Listener::~Listener() 
    3248
    3349AppleRemote * AppleRemote::Get()
    3450{
    35     if (_instance == 0)
     51        if (_instance == 0)
    3652        _instance = new AppleRemote();
    3753
    3854    return _instance;
    AppleRemote * AppleRemote::Get() 
    4157AppleRemote::~AppleRemote()
    4258{
    4359    stopListening();
     60        if (usingNewAtv)
     61                delete mCallbackTimer;
    4462}
    4563
    4664bool AppleRemote::isListeningToRemote()
    AppleRemote::AppleRemote() : openInExclusiveMode(true), 
    108126                             hidDeviceInterface(0),
    109127                             queue(0),
    110128                             remoteId(0),
    111                              _listener(0)
     129                             _listener(0),
     130                                                         usingNewAtv(false),
     131                                                         mLastEvent(AppleRemote::Undefined),
     132                                                         mEventCount(0),
     133                                                         mKeyIsDown(false)
    112134{
    113     _initCookieMap();
     135        SInt32 macVersion;
     136        size_t len = 512;
     137        char hw_model[512] = "unknown";
     138       
     139        // Figure out if we're running on the Apple TV, past version 2.3
     140        Gestalt(gestaltSystemVersion, &macVersion);
     141       
     142       
     143        if (macVersion < 0x1050) // OSX 10.4 / AppleTV
     144        {
     145        sysctlbyname("hw.model", &hw_model, &len, NULL, 0);
     146
     147                if ( strstr(hw_model,"AppleTV1,1") )
     148                {
     149                        FILE* inpipe;
     150                       
     151                        //Find the build version of the AppleTV OS
     152                        inpipe = popen("sw_vers -buildVersion", "r");
     153                        char linebuf[1000];
     154                        if (inpipe)
     155                        {
     156                                if ( fgets(linebuf, sizeof(linebuf) - 1, inpipe) )
     157                                {
     158                                        if ( !( strstr(linebuf,"8N5107") || // v1.0
     159                                                        strstr(linebuf,"8N5239") || // v1.1
     160                                                        strstr(linebuf,"8N5400") || // v2.0
     161                                                        strstr(linebuf,"8N5455") || // v2.01
     162                                                        strstr(linebuf,"8N5461") || // v2.02
     163                                                        strstr(linebuf,"8N5519") || // v2.1
     164                                                        strstr(linebuf,"8N5622") )) // v2.2
     165                                        {
     166                                                VERBOSE(VB_IMPORTANT, LOC + "::AppleRemote detected Apple TV > v2.3");
     167                                                usingNewAtv = true;
     168                                                mCallbackTimer = new QTimer(this);
     169                                                connect(mCallbackTimer, SIGNAL(timeout()), this, SLOT(TimeoutHandler()));
     170                                                mCallbackTimer->setSingleShot(true);
     171                                                mCallbackTimer->setInterval(KEY_RESPONSE_TIME);
     172                                        } 
     173                                }
     174                        }
     175                        pclose(inpipe);
     176                }
     177        }
     178       
     179        _initCookieMap();
    114180}
    115181
    116182/// Apple keeps changing the "interface" between the remote and the OS.
    AppleRemote::AppleRemote() : openInExclusiveMode(true), 
    124190///
    125191void AppleRemote::_initCookieMap()
    126192{
    127     // 10.4 sequences:
    128     cookieToButtonMapping["14_12_11_6_5_"]        = Up;
    129     cookieToButtonMapping["14_13_11_6_5_"]        = Down;
    130     cookieToButtonMapping["14_7_6_5_14_7_6_5_"]   = Menu;
    131     cookieToButtonMapping["14_8_6_5_14_8_6_5_"]   = Select;
    132     cookieToButtonMapping["14_9_6_5_14_9_6_5_"]   = Right;
    133     cookieToButtonMapping["14_10_6_5_14_10_6_5_"] = Left;
    134     cookieToButtonMapping["14_6_5_4_2_"]          = RightHold;
    135     cookieToButtonMapping["14_6_5_3_2_"]          = LeftHold;
    136     cookieToButtonMapping["14_6_5_14_6_5_"]       = MenuHold;
    137     cookieToButtonMapping["18_14_6_5_18_14_6_5_"] = PlayHold;
    138     cookieToButtonMapping["19_"]                  = ControlSwitched;
    139 
    140     // 10.5 sequences:
    141     cookieToButtonMapping["31_29_28_18_"]         = Up;
    142     cookieToButtonMapping["31_30_28_18_"]         = Down;
    143     cookieToButtonMapping["31_20_18_31_20_18_"]   = Menu;
    144     cookieToButtonMapping["31_21_18_31_21_18_"]   = Select;
    145     cookieToButtonMapping["31_22_18_31_22_18_"]   = Right;
    146     cookieToButtonMapping["31_23_18_31_23_18_"]   = Left;
    147     cookieToButtonMapping["31_18_4_2_"]           = RightHold;
    148     cookieToButtonMapping["31_18_3_2_"]           = LeftHold;
    149     cookieToButtonMapping["31_18_31_18_"]         = MenuHold;
    150     cookieToButtonMapping["35_31_18_35_31_18_"]   = PlayHold;
    151     cookieToButtonMapping["39_"]                  = ControlSwitched;
    152 
    153     // ATV 1.0, 2.0-2.02
    154     cookieToButtonMapping["14_12_11_6_"]          = Up;
    155     cookieToButtonMapping["14_13_11_6_"]          = Down;
    156     cookieToButtonMapping["14_7_6_14_7_6_"]       = Menu;
    157     cookieToButtonMapping["14_8_6_14_8_6_"]       = Select;
    158     cookieToButtonMapping["14_9_6_14_9_6_"]       = Right;
    159     cookieToButtonMapping["14_10_6_14_10_6_"]     = Left;
    160     cookieToButtonMapping["14_6_4_2_"]            = RightHold;
    161     cookieToButtonMapping["14_6_3_2_"]            = LeftHold;
    162     cookieToButtonMapping["14_6_14_6_"]           = MenuHold;
    163     cookieToButtonMapping["18_14_6_18_14_6_"]     = PlayHold;
    164 
    165     // ATV 1.0, 2.1-2.2
    166     cookieToButtonMapping["15_13_12_"]            = Up;
    167     cookieToButtonMapping["15_14_12_"]            = Down;
    168     cookieToButtonMapping["15_8_15_8_"]           = Menu;
    169     cookieToButtonMapping["15_9_15_9_"]           = Select;
    170     cookieToButtonMapping["15_10_15_10_"]         = Right;
    171     cookieToButtonMapping["15_11_15_11_"]         = Left;
    172     cookieToButtonMapping["15_5_3_"]              = RightHold;
    173     cookieToButtonMapping["15_4_3_"]              = LeftHold;
    174     cookieToButtonMapping["15_6_15_6_"]           = MenuHold;
    175     cookieToButtonMapping["19_15_19_15_"]         = PlayHold;
    176 
    177     // ATV 2.30
    178     cookieToButtonMapping["80"]                   = Up;
    179     cookieToButtonMapping["48"]                   = Down;
    180     cookieToButtonMapping["64"]                   = Menu;
    181     cookieToButtonMapping["32"]                   = Select;
    182     cookieToButtonMapping["96"]                   = Right;
    183     cookieToButtonMapping["16"]                   = Left;
    184 
    185     // 10.6 sequences:
    186     cookieToButtonMapping["33_31_30_21_20_2_"]            = Up;
    187     cookieToButtonMapping["33_32_30_21_20_2_"]            = Down;
    188     cookieToButtonMapping["33_22_21_20_2_33_22_21_20_2_"] = Menu;
    189     cookieToButtonMapping["33_23_21_20_2_33_23_21_20_2_"] = Select;
    190     cookieToButtonMapping["33_24_21_20_2_33_24_21_20_2_"] = Right;
    191     cookieToButtonMapping["33_25_21_20_2_33_25_21_20_2_"] = Left;
    192     cookieToButtonMapping["33_21_20_14_12_2_"]            = RightHold;
    193     cookieToButtonMapping["33_21_20_13_12_2_"]            = LeftHold;
    194     cookieToButtonMapping["33_21_20_2_33_21_20_2_"]       = MenuHold;
    195     cookieToButtonMapping["37_33_21_20_2_37_33_21_20_2_"] = PlayHold;
    196 
    197     // Aluminium remote which has an extra button:
    198     cookieToButtonMapping["33_21_20_8_2_33_21_20_8_2_"]   = PlayPause;
    199     cookieToButtonMapping["33_21_20_3_2_33_21_20_3_2_"]   = Select;
    200     cookieToButtonMapping["33_21_20_11_2_33_21_20_11_2_"] = PlayHold;
     193        if (!usingNewAtv)
     194        {
     195                // 10.4 sequences:
     196                cookieToButtonMapping["14_12_11_6_5_"]        = Up;
     197                cookieToButtonMapping["14_13_11_6_5_"]        = Down;
     198                cookieToButtonMapping["14_7_6_5_14_7_6_5_"]   = Menu;
     199                cookieToButtonMapping["14_8_6_5_14_8_6_5_"]   = Select;
     200                cookieToButtonMapping["14_9_6_5_14_9_6_5_"]   = Right;
     201                cookieToButtonMapping["14_10_6_5_14_10_6_5_"] = Left;
     202                cookieToButtonMapping["14_6_5_4_2_"]          = RightHold;
     203                cookieToButtonMapping["14_6_5_3_2_"]          = LeftHold;
     204                cookieToButtonMapping["14_6_5_14_6_5_"]       = MenuHold;
     205                cookieToButtonMapping["18_14_6_5_18_14_6_5_"] = PlayHold;
     206                cookieToButtonMapping["19_"]                  = ControlSwitched;
     207               
     208                // 10.5 sequences:
     209                cookieToButtonMapping["31_29_28_18_"]         = Up;
     210                cookieToButtonMapping["31_30_28_18_"]         = Down;
     211                cookieToButtonMapping["31_20_18_31_20_18_"]   = Menu;
     212                cookieToButtonMapping["31_21_18_31_21_18_"]   = Select;
     213                cookieToButtonMapping["31_22_18_31_22_18_"]   = Right;
     214                cookieToButtonMapping["31_23_18_31_23_18_"]   = Left;
     215                cookieToButtonMapping["31_18_4_2_"]           = RightHold;
     216                cookieToButtonMapping["31_18_3_2_"]           = LeftHold;
     217                cookieToButtonMapping["31_18_31_18_"]         = MenuHold;
     218                cookieToButtonMapping["35_31_18_35_31_18_"]   = PlayHold;
     219                cookieToButtonMapping["39_"]                  = ControlSwitched;
     220               
     221                // ATV 1.0, 2.0-2.02
     222                cookieToButtonMapping["14_12_11_6_"]          = Up;
     223                cookieToButtonMapping["14_13_11_6_"]          = Down;
     224                cookieToButtonMapping["14_7_6_14_7_6_"]       = Menu;
     225                cookieToButtonMapping["14_8_6_14_8_6_"]       = Select;
     226                cookieToButtonMapping["14_9_6_14_9_6_"]       = Right;
     227                cookieToButtonMapping["14_10_6_14_10_6_"]     = Left;
     228                cookieToButtonMapping["14_6_4_2_"]            = RightHold;
     229                cookieToButtonMapping["14_6_3_2_"]            = LeftHold;
     230                cookieToButtonMapping["14_6_14_6_"]           = MenuHold;
     231                cookieToButtonMapping["18_14_6_18_14_6_"]     = PlayHold;
     232               
     233                // ATV 1.0, 2.1-2.2
     234                cookieToButtonMapping["15_13_12_"]            = Up;
     235                cookieToButtonMapping["15_14_12_"]            = Down;
     236                cookieToButtonMapping["15_8_15_8_"]           = Menu;
     237                cookieToButtonMapping["15_9_15_9_"]           = Select;
     238                cookieToButtonMapping["15_10_15_10_"]         = Right;
     239                cookieToButtonMapping["15_11_15_11_"]         = Left;
     240                cookieToButtonMapping["15_5_3_"]              = RightHold;
     241                cookieToButtonMapping["15_4_3_"]              = LeftHold;
     242                cookieToButtonMapping["15_6_15_6_"]           = MenuHold;
     243                cookieToButtonMapping["19_15_19_15_"]         = PlayHold;
     244       
     245            // 10.6 sequences:
     246                cookieToButtonMapping["33_31_30_21_20_2_"]            = Up;
     247                cookieToButtonMapping["33_32_30_21_20_2_"]            = Down;
     248                cookieToButtonMapping["33_22_21_20_2_33_22_21_20_2_"] = Menu;
     249                cookieToButtonMapping["33_23_21_20_2_33_23_21_20_2_"] = Select;
     250                cookieToButtonMapping["33_24_21_20_2_33_24_21_20_2_"] = Right;
     251                cookieToButtonMapping["33_25_21_20_2_33_25_21_20_2_"] = Left;
     252                cookieToButtonMapping["33_21_20_14_12_2_"]            = RightHold;
     253                cookieToButtonMapping["33_21_20_13_12_2_"]            = LeftHold;
     254                cookieToButtonMapping["33_21_20_2_33_21_20_2_"]       = MenuHold;
     255                cookieToButtonMapping["37_33_21_20_2_37_33_21_20_2_"] = PlayHold;
     256
     257                // Aluminium remote which has an extra button:
     258                cookieToButtonMapping["33_21_20_8_2_33_21_20_8_2_"]   = PlayPause;
     259                cookieToButtonMapping["33_21_20_3_2_33_21_20_3_2_"]   = Select;
     260                cookieToButtonMapping["33_21_20_11_2_33_21_20_11_2_"] = PlayHold;
     261        }
     262        else
     263        {
     264                // ATV 2.30
     265                cookieToButtonMapping["17_9_280_80"]                   = Up;
     266                cookieToButtonMapping["17_9_280_48"]                   = Down;
     267                cookieToButtonMapping["17_9_280_64"]                   = Menu;
     268                cookieToButtonMapping["17_9_280_32"]                   = Select;
     269                cookieToButtonMapping["17_9_280_96"]                   = Right;
     270                cookieToButtonMapping["17_9_280_16"]                   = Left; 
     271        }
    201272}
    202273
    203274static io_object_t _findAppleRemoteDevice(const char *devName)
    bool AppleRemote::_openDevice() 
    316387        VERBOSE(VB_IMPORTANT, LOC + "_openDevice() failed");
    317388        return false;
    318389    }
     390        VERBOSE(VB_IMPORTANT, LOC + "Opened AppleRemote Device");
     391       
    319392    queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
    320393    if (!queue)
    321394    {
    void AppleRemote::_queueCallbackFunction(IOReturn result, 
    373446    SInt32            sumOfValues = 0;
    374447    std::stringstream cookieString;
    375448
    376     while (result == kIOReturnSuccess)
    377     {
    378         IOHIDEventStruct event;
    379 
    380         result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
    381         if (result != kIOReturnSuccess)
    382             break;
    383 
    384         if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie)
    385         {
    386             remoteId=event.value;
    387             _handleEventWithCookieString("19_",0);
    388         }
    389         else
    390         {
    391             sumOfValues+=event.value;
    392             cookieString << std::dec << (int)event.elementCookie << "_";
    393         }
     449        if (!usingNewAtv)
     450        {
     451                while (result == kIOReturnSuccess)
     452                {
     453                        IOHIDEventStruct event;
     454               
     455                        result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
     456                if (result != kIOReturnSuccess)
     457                break;
     458
     459                        if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie)
     460                        {
     461                                remoteId=event.value;
     462                                _handleEventWithCookieString("19_",0);
     463                        }
     464                        else
     465                        {
     466                                sumOfValues+=event.value;
     467                                cookieString << std::dec << (int)event.elementCookie << "_";
     468                        }
     469                }
     470                _handleEventWithCookieString(cookieString.str(), sumOfValues);
    394471    }
    395 
    396     _handleEventWithCookieString(cookieString.str(), sumOfValues);
     472        else // AppleTV from v2.3 onwards
     473        {
     474                if (mCallbackTimer->isActive())
     475                {
     476                        mCallbackTimer->stop();
     477                }
     478               
     479                IOHIDEventStruct event;
     480                UInt32 key_code = 0;
     481               
     482                while (result == kIOReturnSuccess)
     483                {
     484                        result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
     485                        if (result != kIOReturnSuccess) {
     486                                continue;
     487                        }
     488                       
     489                        if ( ((int)event.elementCookie == 280) && (event.longValueSize == 20)) {
     490                                ATV_IR_EVENT* atv_ir_event = (ATV_IR_EVENT*)event.longValue;
     491                                key_code = atv_ir_event->keycode;
     492                        }
     493                       
     494                        if (((int)event.elementCookie) != 5 ) {
     495                                sumOfValues += event.value;
     496                                cookieString << std::dec << (int)event.elementCookie << "_";
     497                        }
     498                }
     499                char endCode[10] = "17_9_280_";
     500                if (strcmp(cookieString.str().c_str(), endCode) == 0) {
     501
     502                        cookieString << std::dec << (int) ( (key_code & 0x00007F00) >> 8);
     503                       
     504                        sumOfValues = 1;
     505                        _handleEventWithCookieString(cookieString.str(), sumOfValues); 
     506                }
     507        }
    397508}
    398509
    399 void AppleRemote::_handleEventWithCookieString(std::string cookieString,
    400                                           SInt32 sumOfValues)
     510void AppleRemote::_handleEventWithCookieString(std::string cookieString, 
     511                                                                                                SInt32 sumOfValues)
    401512{
    402     std::map<std::string,AppleRemote::Event>::iterator ii;
    403 
    404     ii = cookieToButtonMapping.find(cookieString);
    405     if (ii != cookieToButtonMapping.end() && _listener)
     513        std::map<std::string,AppleRemote::Event>::iterator ii;
     514        ii = cookieToButtonMapping.find(cookieString);
     515   
     516       
     517        if (ii != cookieToButtonMapping.end() )
    406518    {
    407         AppleRemote::Event buttonid = ii->second;
    408         if (_listener)
    409             _listener->appleRemoteButton(buttonid, sumOfValues>0);
     519                AppleRemote::Event event = ii->second;
     520               
     521                if (!usingNewAtv) {     
     522                        if (_listener)
     523                        {
     524                                _listener->appleRemoteButton(event, sumOfValues>0);
     525                        }
     526                }
     527                else
     528                {
     529                        // With the ATV from 2.3 onwards, we just get IR events. We need to simulate the
     530                        // key up and hold events
     531                       
     532                        if (mLastEvent == Undefined)    // new event
     533                        {
     534                                mEventCount = 1;
     535                                // Need to figure out if this is a long press or a short press,
     536                                // so can't just send a key down event right now. It will be
     537                                // scheduled to run
     538                        }
     539                        else if (event != mLastEvent)   // a new event, faster than timer
     540                        {
     541                                mEventCount = 1;
     542                                mKeyIsDown = true;
     543                               
     544                                if (_listener)
     545                                {
     546                                        // Only send key up events for events that have separateRelease
     547                                        // defined as true in AppleRemoteListener.cpp
     548                                        if (mLastEvent == Up || mLastEvent == Down ||
     549                                                mLastEvent == LeftHold || mLastEvent == RightHold)
     550                                        {
     551                                                _listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
     552                                        }
     553                                        _listener->appleRemoteButton(event, mKeyIsDown);
     554                                }
     555                        }
     556                        else // Same event again
     557                        {
     558                                mEventCount+=1;
     559                                AppleRemote::Event newEvent = Undefined;
     560                               
     561                                // Can the event have a hold state?
     562                                switch (event)
     563                                {
     564                                        case Right:
     565                                                newEvent = RightHold;
     566                                                break;
     567                                        case Left:
     568                                                newEvent = LeftHold;
     569                                                break;
     570                                        case Menu:
     571                                                newEvent = MenuHold;
     572                                                break;
     573                                        case Select:
     574                                                newEvent = PlayHold;
     575                                                break; 
     576                                        default:
     577                                                newEvent = event;
     578                                }
     579                               
     580                                if (newEvent == event) // Doesn't have a long press
     581                                {
     582                                        if (mKeyIsDown)
     583                                        {
     584                                                if (_listener)
     585                                                {
     586                                                        // Only send key up events for events that have separateRelease
     587                                                        // defined as true in AppleRemoteListener.cpp
     588                                                        if (mLastEvent == Up || mLastEvent == Down ||
     589                                                                mLastEvent == LeftHold || mLastEvent == RightHold)
     590                                                        {
     591                                                                _listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
     592                                                        }
     593                                                }
     594                                        }
     595                                       
     596                                        mKeyIsDown = true;
     597                                        if (_listener)
     598                                        {
     599                                                _listener->appleRemoteButton(newEvent, mKeyIsDown);
     600                                        }
     601                                } 
     602                                else if (mEventCount == LONG_PRESS_COUNT)
     603                                {
     604                                        mKeyIsDown = true;
     605                                        if (_listener)
     606                                        {
     607                                                _listener->appleRemoteButton(newEvent, mKeyIsDown);
     608                                        }
     609                                }
     610                        }
     611                       
     612                        mLastEvent = event;
     613                        mCallbackTimer->start();
     614        }
    410615    }
    411616}
     617
     618// Calls key down / up events on the ATV > v2.3
     619void AppleRemote::TimeoutHandler()
     620{
     621        if (_listener)
     622        {
     623                _listener->appleRemoteButton(mLastEvent, !mKeyIsDown);
     624        }
     625       
     626        mKeyIsDown = !mKeyIsDown;
     627       
     628        if (!mKeyIsDown)
     629        {
     630                mEventCount = 0;
     631                mLastEvent = Undefined;
     632        }
     633        else
     634        {
     635                // Schedule a key up event for events that have separateRelease
     636                // defined as true in AppleRemoteListener.cpp
     637               
     638                if (mLastEvent == Up || mLastEvent == Down ||
     639                        mLastEvent == LeftHold || mLastEvent == RightHold)
     640                {
     641                        mCallbackTimer->start();
     642                }
     643                else
     644                {
     645                        mKeyIsDown = false;
     646                        mEventCount = 0;
     647                        mLastEvent = Undefined;
     648                }
     649
     650        }
     651}
  • mythtv/libs/libmythui/AppleRemote.h

    diff --git a/mythtv/libs/libmythui/AppleRemote.h b/mythtv/libs/libmythui/AppleRemote.h
    index 23b43a3..7a95615 100644
    a b  
    55#include <vector>
    66#include <map>
    77#include <QThread>
     8#include <QTimer>
    89
    910#include <IOKit/IOKitLib.h>
    1011#include <IOKit/IOCFPlugIn.h>
     
    1415
    1516class AppleRemote : public QThread
    1617{
     18        Q_OBJECT
    1719public:
    1820    enum Event
    1921    { // label/meaning on White ... and Aluminium remote
    public: 
    2830        MenuHold,
    2931        PlayHold,  // was PlaySleep
    3032        ControlSwitched,
    31         PlayPause      // Play or Pause
     33        PlayPause,      // Play or Pause
     34                Undefined               // Used to handle the Apple TV > v2.3
    3235    };
    3336
    3437    class Listener
    private: 
    6568    std::map< std::string, Event > cookieToButtonMapping;
    6669    int                    remoteId;
    6770    Listener*              _listener;
     71       
     72        bool                               usingNewAtv;
     73        AppleRemote::Event         mLastEvent;
     74        int                                        mEventCount;
     75        bool                               mKeyIsDown;
     76        QTimer*                            mCallbackTimer;
    6877
    6978    void        _initCookieMap();
    7079    bool        _initCookies();
    private: 
    7786                                       void* refcon, void* sender);
    7887    void        _handleEventWithCookieString(std::string cookieString,
    7988                                             SInt32 sumOfValues);
     89       
     90private slots:
     91        // Key up event handling on the ATV v2.3 and above                                                       
     92        void            TimeoutHandler();
     93       
    8094};
    8195
    8296#endif // APPLEREMOTE
  • mythtv/libs/libmythui/libmythui.pro

    diff --git a/mythtv/libs/libmythui/libmythui.pro b/mythtv/libs/libmythui/libmythui.pro
    index a6153e6..5dba56c 100644
    a b include ( ../../settings.pro ) 
    22
    33TEMPLATE = lib
    44TARGET = mythui-$$LIBVERSION
    5 CONFIG += thread dll
     5CONFIG += qt thread dll
    66target.path = $${LIBDIR}
    77INSTALLS = target
    88