Ticket #5713: myth-network-sendxkey.patch

File myth-network-sendxkey.patch, 25.8 KB (added by yolanother@…, 11 years ago)

Mythfrontend telnet remote sendxkey patch.

  • programs/mythfrontend/mythfrontend.pro

    diff -rupN mythtv-0.21.0+fixes18207/programs/mythfrontend/mythfrontend.pro mythtv-sendxkey/programs/mythfrontend/mythfrontend.pro
    old new HEADERS += mythappearance.h 
    3131
    3232SOURCES += main.cpp manualbox.cpp playbackbox.cpp viewscheduled.cpp
    3333SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp
    34 SOURCES += channelrecpriority.cpp statusbox.cpp networkcontrol.cpp
     34SOURCES += channelrecpriority.cpp statusbox.cpp sendxkey.cpp networkcontrol.cpp
    3535SOURCES += mediarenderer.cpp
    3636SOURCES += custompriority.cpp
    3737SOURCES += mythappearance.cpp
  • programs/mythfrontend/networkcontrol.cpp

    diff -rupN mythtv-0.21.0+fixes18207/programs/mythfrontend/networkcontrol.cpp mythtv-sendxkey/programs/mythfrontend/networkcontrol.cpp
    old new using namespace std; 
    1616#include "remoteutil.h"
    1717#include "previewgenerator.h"
    1818#include "compat.h"
     19#include "sendxkey.h"
    1920
    2021#define LOC QString("NetworkControl: ")
    2122#define LOC_ERR QString("NetworkControl Error: ")
    NetworkControl::NetworkControl(int port) 
    184185    keyMap["f23"]                    = Qt::Key_F23;
    185186    keyMap["f24"]                    = Qt::Key_F24;
    186187
    187     stopCommandThread = false;
     188    xkeyMap["BackSpace"] = "BackSpace";
     189    xkeyMap["Tab"] = "Tab";
     190    xkeyMap["Linefeed"] = "Linefeed";
     191    xkeyMap["Clear"] = "Clear";
     192    xkeyMap["Return"] = "Return";
     193    xkeyMap["Pause"] = "Pause";
     194    xkeyMap["Scroll_Lock"] = "Scroll_Lock";
     195    xkeyMap["Sys_Req"] = "Sys_Req";
     196    xkeyMap["Escape"] = "Escape";
     197    xkeyMap["Delete"] = "Delete";
     198    xkeyMap["Home"] = "Home";
     199    xkeyMap["Left"] = "Left";
     200    xkeyMap["Up"] = "Up";
     201    xkeyMap["Right"] = "Right";
     202    xkeyMap["Down"] = "Down";
     203    xkeyMap["Prior"] = "Prior";
     204    xkeyMap["Page_Up"] = "Page_Up";
     205    xkeyMap["Next"] = "Next";
     206    xkeyMap["Page_Down"] = "Page_Down";
     207    xkeyMap["End"] = "End";
     208    xkeyMap["Begin"] = "Begin";
     209    xkeyMap["Select"] = "Select";
     210    xkeyMap["Print"] = "Print";
     211    xkeyMap["Execute"] = "Execute";
     212    xkeyMap["Insert"] = "Insert";
     213    xkeyMap["Undo"] = "Undo";
     214    xkeyMap["Redo"] = "Redo";
     215    xkeyMap["Menu"] = "Menu";
     216    xkeyMap["Find"] = "Find";
     217    xkeyMap["Cancel"] = "Cancel";
     218    xkeyMap["Help"] = "Help";
     219    xkeyMap["Break"] = "Break";
     220    xkeyMap["Mode_switch"] = "Mode_switch";
     221    xkeyMap["script_switch"] = "script_switch";
     222    xkeyMap["Num_Lock"] = "Num_Lock";
     223    xkeyMap["KP_Space"] = "KP_Space";
     224    xkeyMap["KP_Tab"] = "KP_Tab";
     225    xkeyMap["KP_Enter"] = "KP_Enter";
     226    xkeyMap["KP_F1"] = "KP_F1";
     227    xkeyMap["KP_F2"] = "KP_F2";
     228    xkeyMap["KP_F3"] = "KP_F3";
     229    xkeyMap["KP_F4"] = "KP_F4";
     230    xkeyMap["KP_Home"] = "KP_Home";
     231    xkeyMap["KP_Left"] = "KP_Left";
     232    xkeyMap["KP_Up"] = "KP_Up";
     233    xkeyMap["KP_Right"] = "KP_Right";
     234    xkeyMap["KP_Down"] = "KP_Down";
     235    xkeyMap["KP_Prior"] = "KP_Prior";
     236    xkeyMap["KP_Page_Up"] = "KP_Page_Up";
     237    xkeyMap["KP_Next"] = "KP_Next";
     238    xkeyMap["KP_Page_Down"] = "KP_Page_Down";
     239    xkeyMap["KP_End"] = "KP_End";
     240    xkeyMap["KP_Begin"] = "KP_Begin";
     241    xkeyMap["KP_Insert"] = "KP_Insert";
     242    xkeyMap["KP_Delete"] = "KP_Delete";
     243    xkeyMap["KP_Equal"] = "KP_Equal";
     244    xkeyMap["KP_Multiply"] = "KP_Multiply";
     245    xkeyMap["KP_Add"] = "KP_Add";
     246    xkeyMap["KP_Separator"] = "KP_Separator";
     247    xkeyMap["KP_Subtract"] = "KP_Subtract";
     248    xkeyMap["KP_Decimal"] = "KP_Decimal";
     249    xkeyMap["KP_Divide"] = "KP_Divide";
     250    xkeyMap["KP_0"] = "KP_0";
     251    xkeyMap["KP_1"] = "KP_1";
     252    xkeyMap["KP_2"] = "KP_2";
     253    xkeyMap["KP_3"] = "KP_3";
     254    xkeyMap["KP_4"] = "KP_4";
     255    xkeyMap["KP_5"] = "KP_5";
     256    xkeyMap["KP_6"] = "KP_6";
     257    xkeyMap["KP_7"] = "KP_7";
     258    xkeyMap["KP_8"] = "KP_8";
     259    xkeyMap["KP_9"] = "KP_9";
     260    xkeyMap["F1"] = "F1";
     261    xkeyMap["F2"] = "F2";
     262    xkeyMap["F3"] = "F3";
     263    xkeyMap["F4"] = "F4";
     264    xkeyMap["F5"] = "F5";
     265    xkeyMap["F6"] = "F6";
     266    xkeyMap["F7"] = "F7";
     267    xkeyMap["F8"] = "F8";
     268    xkeyMap["F9"] = "F9";
     269    xkeyMap["F10"] = "F10";
     270    xkeyMap["F11"] = "F11";
     271    xkeyMap["L1"] = "L1";
     272    xkeyMap["F12"] = "F12";
     273    xkeyMap["L2"] = "L2";
     274    xkeyMap["F13"] = "F13";
     275    xkeyMap["L3"] = "L3";
     276    xkeyMap["F14"] = "F14";
     277    xkeyMap["L4"] = "L4";
     278    xkeyMap["F15"] = "F15";
     279    xkeyMap["L5"] = "L5";
     280    xkeyMap["F16"] = "F16";
     281    xkeyMap["L6"] = "L6";
     282    xkeyMap["F17"] = "F17";
     283    xkeyMap["L7"] = "L7";
     284    xkeyMap["F18"] = "F18";
     285    xkeyMap["L8"] = "L8";
     286    xkeyMap["F19"] = "F19";
     287    xkeyMap["L9"] = "L9";
     288    xkeyMap["F20"] = "F20";
     289    xkeyMap["L10"] = "L10";
     290    xkeyMap["F21"] = "F21";
     291    xkeyMap["R1"] = "R1";
     292    xkeyMap["F22"] = "F22";
     293    xkeyMap["R2"] = "R2";
     294    xkeyMap["F23"] = "F23";
     295    xkeyMap["R3"] = "R3";
     296    xkeyMap["F24"] = "F24";
     297    xkeyMap["R4"] = "R4";
     298    xkeyMap["F25"] = "F25";
     299    xkeyMap["R5"] = "R5";
     300    xkeyMap["F26"] = "F26";
     301    xkeyMap["R6"] = "R6";
     302    xkeyMap["F27"] = "F27";
     303    xkeyMap["R7"] = "R7";
     304    xkeyMap["F28"] = "F28";
     305    xkeyMap["R8"] = "R8";
     306    xkeyMap["F29"] = "F29";
     307    xkeyMap["R9"] = "R9";
     308    xkeyMap["F30"] = "F30";
     309    xkeyMap["R10"] = "R10";
     310    xkeyMap["F31"] = "F31";
     311    xkeyMap["R11"] = "R11";
     312    xkeyMap["F32"] = "F32";
     313    xkeyMap["R12"] = "R12";
     314    xkeyMap["F33"] = "F33";
     315    xkeyMap["R13"] = "R13";
     316    xkeyMap["F34"] = "F34";
     317    xkeyMap["R14"] = "R14";
     318    xkeyMap["F35"] = "F35";
     319    xkeyMap["R15"] = "R15";
     320    xkeyMap["Shift_L"] = "Shift_L";
     321    xkeyMap["Shift_R"] = "Shift_R";
     322    xkeyMap["Control_L"] = "Control_L";
     323    xkeyMap["Control_R"] = "Control_R";
     324    xkeyMap["Caps_Lock"] = "Caps_Lock";
     325    xkeyMap["Shift_Lock"] = "Shift_Lock";
     326    xkeyMap["Meta_L"] = "Meta_L";
     327    xkeyMap["Meta_R"] = "Meta_R";
     328    xkeyMap["Alt_L"] = "Alt_L";
     329    xkeyMap["Alt_R"] = "Alt_R";
     330    xkeyMap["Super_L"] = "Super_L";
     331    xkeyMap["Super_R"] = "Super_R";
     332    xkeyMap["Hyper_L"] = "Hyper_L";
     333    xkeyMap["Hyper_R"] = "Hyper_R";
     334    xkeyMap["space"] = "space";
     335    xkeyMap["exclam"] = "exclam";
     336    xkeyMap["quotedbl"] = "quotedbl";
     337    xkeyMap["numbersign"] = "numbersign";
     338    xkeyMap["dollar"] = "dollar";
     339    xkeyMap["percent"] = "percent";
     340    xkeyMap["ampersand"] = "ampersand";
     341    xkeyMap["apostrophe"] = "apostrophe";
     342    xkeyMap["quoteright"] = "quoteright";
     343    xkeyMap["parenleft"] = "parenleft";
     344    xkeyMap["parenright"] = "parenright";
     345    xkeyMap["asterisk"] = "asterisk";
     346    xkeyMap["plus"] = "plus";
     347    xkeyMap["comma"] = "comma";
     348    xkeyMap["minus"] = "minus";
     349    xkeyMap["period"] = "period";
     350    xkeyMap["slash"] = "slash";
     351    xkeyMap["colon"] = "colon";
     352    xkeyMap["semicolon"] = "semicolon";
     353    xkeyMap["less"] = "less";
     354    xkeyMap["equal"] = "equal";
     355    xkeyMap["greater"] = "greater";
     356    xkeyMap["question"] = "question";
     357    xkeyMap["at"] = "at";
     358    xkeyMap["bracketleft"] = "bracketleft";
     359    xkeyMap["backslash"] = "backslash";
     360    xkeyMap["bracketright"] = "bracketright";
     361    xkeyMap["asciicircum"] = "asciicircum";
     362    xkeyMap["underscore"] = "underscore";
     363    xkeyMap["grave"] = "grave";
     364    xkeyMap["quoteleft"] = "quoteleft";
     365    xkeyMap["braceleft"] = "braceleft";
     366    xkeyMap["bar"] = "bar";
     367    xkeyMap["braceright"] = "braceright";
     368    xkeyMap["asciitilde"] = "asciitilde";
     369    xkeyMap["nobreakspace"] = "nobreakspace";
     370    xkeyMap["exclamdown"] = "exclamdown";
     371    xkeyMap["cent"] = "cent";
     372    xkeyMap["sterling"] = "sterling";
     373    xkeyMap["currency"] = "currency";
     374    xkeyMap["yen"] = "yen";
     375    xkeyMap["brokenbar"] = "brokenbar";
     376    xkeyMap["section"] = "section";
     377    xkeyMap["diaeresis"] = "diaeresis";
     378    xkeyMap["copyright"] = "copyright";
     379    xkeyMap["ordfeminine"] = "ordfeminine";
     380    xkeyMap["guillemotleft"] = "guillemotleft";
     381    xkeyMap["notsign"] = "notsign";
     382    xkeyMap["hyphen"] = "hyphen";
     383    xkeyMap["registered"] = "registered";
     384    xkeyMap["macron"] = "macron";
     385    xkeyMap["degree"] = "degree";
     386    xkeyMap["plusminus"] = "plusminus";
     387    xkeyMap["twosuperior"] = "twosuperior";
     388    xkeyMap["threesuperior"] = "threesuperior";
     389    xkeyMap["acute"] = "acute";
     390    xkeyMap["mu"] = "mu";
     391    xkeyMap["paragraph"] = "paragraph";
     392    xkeyMap["periodcentered"] = "periodcentered";
     393    xkeyMap["cedilla"] = "cedilla";
     394    xkeyMap["onesuperior"] = "onesuperior";
     395    xkeyMap["masculine"] = "masculine";
     396    xkeyMap["guillemotright"] = "guillemotright";
     397    xkeyMap["onequarter"] = "onequarter";
     398    xkeyMap["onehalf"] = "onehalf";
     399    xkeyMap["threequarters"] = "threequarters";
     400    xkeyMap["questiondown"] = "questiondown";
     401    xkeyMap["Agrave"] = "Agrave";
     402    xkeyMap["Aacute"] = "Aacute";
     403    xkeyMap["Acircumflex"] = "Acircumflex";
     404    xkeyMap["Atilde"] = "Atilde";
     405    xkeyMap["Adiaeresis"] = "Adiaeresis";
     406    xkeyMap["Aring"] = "Aring";
     407    xkeyMap["AE"] = "AE";
     408    xkeyMap["Ccedilla"] = "Ccedilla";
     409    xkeyMap["Egrave"] = "Egrave";
     410    xkeyMap["Eacute"] = "Eacute";
     411    xkeyMap["Ecircumflex"] = "Ecircumflex";
     412    xkeyMap["Ediaeresis"] = "Ediaeresis";
     413    xkeyMap["Igrave"] = "Igrave";
     414    xkeyMap["Iacute"] = "Iacute";
     415    xkeyMap["Icircumflex"] = "Icircumflex";
     416    xkeyMap["Idiaeresis"] = "Idiaeresis";
     417    xkeyMap["ETH"] = "ETH";
     418    xkeyMap["Eth"] = "Eth";
     419    xkeyMap["Ntilde"] = "Ntilde";
     420    xkeyMap["Ograve"] = "Ograve";
     421    xkeyMap["Oacute"] = "Oacute";
     422    xkeyMap["Ocircumflex"] = "Ocircumflex";
     423    xkeyMap["Otilde"] = "Otilde";
     424    xkeyMap["Odiaeresis"] = "Odiaeresis";
     425    xkeyMap["multiply"] = "multiply";
     426    xkeyMap["Ooblique"] = "Ooblique";
     427    xkeyMap["Ugrave"] = "Ugrave";
     428    xkeyMap["Uacute"] = "Uacute";
     429    xkeyMap["Ucircumflex"] = "Ucircumflex";
     430    xkeyMap["Udiaeresis"] = "Udiaeresis";
     431    xkeyMap["Yacute"] = "Yacute";
     432    xkeyMap["THORN"] = "THORN";
     433    xkeyMap["Thorn"] = "Thorn";
     434    xkeyMap["ssharp"] = "ssharp";
     435    xkeyMap["agrave"] = "agrave";
     436    xkeyMap["aacute"] = "aacute";
     437    xkeyMap["acircumflex"] = "acircumflex";
     438    xkeyMap["atilde"] = "atilde";
     439    xkeyMap["adiaeresis"] = "adiaeresis";
     440    xkeyMap["aring"] = "aring";
     441    xkeyMap["ae"] = "ae";
     442    xkeyMap["ccedilla"] = "ccedilla";
     443    xkeyMap["egrave"] = "egrave";
     444    xkeyMap["eacute"] = "eacute";
     445    xkeyMap["ecircumflex"] = "ecircumflex";
     446    xkeyMap["ediaeresis"] = "ediaeresis";
     447    xkeyMap["igrave"] = "igrave";
     448    xkeyMap["iacute"] = "iacute";
     449    xkeyMap["icircumflex"] = "icircumflex";
     450    xkeyMap["idiaeresis"] = "idiaeresis";
     451    xkeyMap["eth"] = "eth";
     452    xkeyMap["ntilde"] = "ntilde";
     453    xkeyMap["ograve"] = "ograve";
     454    xkeyMap["oacute"] = "oacute";
     455    xkeyMap["ocircumflex"] = "ocircumflex";
     456    xkeyMap["otilde"] = "otilde";
     457    xkeyMap["odiaeresis"] = "odiaeresis";
     458    xkeyMap["division"] = "division";
     459    xkeyMap["oslash"] = "oslash";
     460    xkeyMap["ugrave"] = "ugrave";
     461    xkeyMap["uacute"] = "uacute";
     462    xkeyMap["ucircumflex"] = "ucircumflex";
     463    xkeyMap["udiaeresis"] = "udiaeresis";
     464    xkeyMap["yacute"] = "yacute";
     465    xkeyMap["thorn"] = "thorn";
     466    xkeyMap["ydiaeresis"] = "ydiaeresis";
     467
     468
     469   stopCommandThread = false;
    188470    pthread_create(&command_thread, NULL, CommandThread, this);
    189471
    190472    gContext->addListener(this);
    void NetworkControl::processNetworkContr 
    247529        result = processJump(tokens);
    248530    else if (is_abbrev("key", tokens[0]))
    249531        result = processKey(tokens);
     532    else if (is_abbrev("xkey", tokens[0]))
     533        result = processKey(tokens, true);
    250534    else if (is_abbrev("play", tokens[0]))
    251535        result = processPlay(tokens);
    252536    else if (is_abbrev("query", tokens[0]))
    QString NetworkControl::processJump(QStr 
    390674    return result;
    391675}
    392676
    393 QString NetworkControl::processKey(QStringList tokens)
     677QString NetworkControl::processKey(QStringList tokens, bool is_xkey)
    394678{
    395679    QString result = "OK";
    396680    QKeyEvent *event = NULL;
    QString NetworkControl::processKey(QStri 
    414698
    415699    unsigned int curToken = 1;
    416700    unsigned int tokenLen = 0;
     701    int keyCode;
     702    int ch;
     703    int buttons;
     704    QString recombined = "";
    417705    while (curToken < tokens.size())
    418706    {
    419         tokenLen = tokens[curToken].length();
    420 
    421         if (tokens[curToken] == "sleep")
    422         {
    423             sleep(1);
    424         }
    425         else if (keyMap.contains(tokens[curToken]))
    426         {
    427             int keyCode = keyMap[tokens[curToken]];
     707        if(is_xkey)
     708        {
     709            recombined += curToken;
     710        }
     711        else
     712        {
     713            tokenLen = tokens[curToken].length();
    428714
    429             event = new QKeyEvent(QEvent::KeyPress, keyCode, 0, NoButton);
    430             QApplication::postEvent(keyDest, event);
     715            if (tokens[curToken] == "sleep")
     716            {
     717                sleep(1);
     718            }
     719            else if (keyMap.contains(tokens[curToken]))
     720            {
     721                int keyCode = keyMap[tokens[curToken]];
    431722
    432             event = new QKeyEvent(QEvent::KeyRelease, keyCode, 0, NoButton);
    433             QApplication::postEvent(keyDest, event);
    434         }
    435         else if (((tokenLen == 1) &&
     723                event = new QKeyEvent(QEvent::KeyPress, keyCode, 0, NoButton);
     724                QApplication::postEvent(keyDest, event);
     725 
     726                event = new QKeyEvent(QEvent::KeyRelease, keyCode, 0, NoButton);
     727                QApplication::postEvent(keyDest, event);
     728           }
     729           else if (((tokenLen == 1) &&
    436730                  (tokens[curToken][0].isLetterOrNumber())) ||
    437731                 ((tokenLen >= 1) &&
    438732                  (tokens[curToken].contains("+"))))
    439         {
    440             QKeySequence a(tokens[curToken]);
    441             int keyCode = a[0];
    442             int ch = (tokens[curToken].ascii())[tokenLen - 1];
    443             int buttons = NoButton;
    444 
    445             if (tokenLen > 1)
    446733            {
    447                 QStringList tokenParts =
    448                     QStringList::split("+", tokens[curToken]);
    449 
    450                 unsigned int partNum = 0;
    451                 while (partNum < (tokenParts.size() - 1))
     734                QKeySequence a(tokens[curToken]);
     735                keyCode = a[0];
     736                ch = (tokens[curToken].ascii())[tokenLen - 1];
     737                buttons = NoButton;
     738   
     739                if (tokenLen > 1)
    452740                {
    453                     if (tokenParts[partNum].upper() == "CTRL")
    454                         buttons |= ControlButton;
    455                     if (tokenParts[partNum].upper() == "SHIFT")
    456                         buttons |= ShiftButton;
    457                     if (tokenParts[partNum].upper() == "ALT")
    458                         buttons |= AltButton;
    459                     if (tokenParts[partNum].upper() == "META")
    460                         buttons |= MetaButton;
    461 
    462                     partNum++;
     741                    QStringList tokenParts =
     742                        QStringList::split("+", tokens[curToken]);
     743 
     744                    unsigned int partNum = 0;
     745                    while (partNum < (tokenParts.size() - 1))
     746                    {
     747                        if (tokenParts[partNum].upper() == "CTRL")
     748                            buttons |= ControlButton;
     749                        if (tokenParts[partNum].upper() == "SHIFT")
     750                            buttons |= ShiftButton;
     751                        if (tokenParts[partNum].upper() == "ALT")
     752                            buttons |= AltButton;
     753                        if (tokenParts[partNum].upper() == "META")
     754                            buttons |= MetaButton;
     755 
     756                        partNum++;
     757                    }
    463758                }
     759                else
     760                {
     761                    if (tokens[curToken] == tokens[curToken].upper())
     762                        buttons = ShiftButton;
     763                }
     764
     765                event = new QKeyEvent(QEvent::KeyPress, keyCode, ch, buttons,
     766                                      tokens[curToken]);
     767                QApplication::postEvent(keyDest, event);
     768
     769                event = new QKeyEvent(QEvent::KeyRelease, keyCode, ch, buttons,
     770                                      tokens[curToken]);
     771                QApplication::postEvent(keyDest, event);
    464772            }
    465773            else
    466             {
    467                 if (tokens[curToken] == tokens[curToken].upper())
    468                     buttons = ShiftButton;
    469             }
    470 
    471             event = new QKeyEvent(QEvent::KeyPress, keyCode, ch, buttons,
    472                                   tokens[curToken]);
    473             QApplication::postEvent(keyDest, event);
    474 
    475             event = new QKeyEvent(QEvent::KeyRelease, keyCode, ch, buttons,
    476                                   tokens[curToken]);
    477             QApplication::postEvent(keyDest, event);
     774                return QString("ERROR: Invalid syntax at '%1', see 'help %2' for "
     775                               "usage information")
     776                               .arg(tokens[curToken]).arg(tokens[0]);
    478777        }
    479         else
    480             return QString("ERROR: Invalid syntax at '%1', see 'help %2' for "
    481                            "usage information")
    482                            .arg(tokens[curToken]).arg(tokens[0]);
    483 
    484778        curToken++;
    485779    }
     780    if(is_xkey)
     781    {
     782        if (keyMap.contains(tokens[1]) || (tokens[0][0].isLetterOrNumber()))
     783                sendxkey(tokens[1].ascii());
     784        else
     785            return QString("ERROR: Invalid syntax at '%1', see 'help %2' for "
     786                               "usage information")
     787                               .arg(tokens[curToken]).arg(tokens[0]);
     788    }
    486789
    487790    return result;
    488791}
    QString NetworkControl::processQuery(QSt 
    692995        return listRecordings(tokens[2], tokens[3].upper());
    693996    else if (is_abbrev("recordings", tokens[1]))
    694997        return listRecordings();
     998    else if (is_abbrev("focused", tokens[1]))
     999    {
     1000        char *title;
     1001        get_focused_window(&title);
     1002        result = QString(title);
     1003        delete [] title;
     1004    }
    6951005    else
    6961006        return QString("ERROR: See 'help %1' for usage information")
    6971007                       .arg(tokens[0]);
    QString NetworkControl::processHelp(QStr 
    7331043                        it.data() + "\r\n";
    7341044        }
    7351045    }
     1046    else if (is_abbrev("xkey", command))
     1047    {
     1048        helpText +=
     1049            "xkey LETTER           - Send the letter key specified\r\n"
     1050            "xkey NUMBER           - Send the number key specified\r\n"
     1051            "xkey CODE             - Send one of the following key codes\r\n"
     1052            "\r\n";
     1053
     1054        QMap<QString, QString>::Iterator it;
     1055        bool first = true;
     1056        for (it = xkeyMap.begin(); it != xkeyMap.end(); ++it)
     1057        {
     1058            if (first)
     1059                first = false;
     1060            else
     1061                helpText += ", ";
     1062
     1063            helpText += it.key();
     1064        }
     1065        helpText += "\r\n";
     1066    }
    7361067    else if (is_abbrev("key", command))
    7371068    {
    7381069        helpText +=
    QString NetworkControl::processHelp(QStr 
    7941125            "                      - List info about the specified program\r\n"
    7951126            "query liveTV          - List current TV schedule\r\n"
    7961127            "query liveTV CHANID   - Query current program for specified channel\r\n"
    797             "query time            - Query current time on server\r\n";
     1128            "query time            - Query current time on server\r\n"
     1129            "query focused         - Returns the name of the focused window\r\n";
    7981130    }
    7991131    else if (command == "exit")
    8001132    {
    QString NetworkControl::processHelp(QStr 
    8131145        "---------------\r\n"
    8141146        "jump               - Jump to a specified location in Myth\r\n"
    8151147        "key                - Send a keypress to the program\r\n"
     1148        "xkey               - Send a keypress to the focused program\r\n"
    8161149        "play               - Playback related commands\r\n"
    8171150        "query              - Queries\r\n"
    8181151        "exit               - Exit Network Control\r\n"
  • programs/mythfrontend/networkcontrol.h

    diff -rupN mythtv-0.21.0+fixes18207/programs/mythfrontend/networkcontrol.h mythtv-sendxkey/programs/mythfrontend/networkcontrol.h
    old new class NetworkControl : public QServerSoc 
    3636
    3737  private:
    3838    QString processJump(QStringList tokens);
    39     QString processKey(QStringList tokens);
     39    QString processKey(QStringList tokens, bool is_xkey = false);
    4040    QString processLiveTV(QStringList tokens);
    4141    QString processPlay(QStringList tokens);
    4242    QString processQuery(QStringList tokens);
    class NetworkControl : public QServerSoc 
    5757    QString answer;
    5858    QMap <QString, QString> jumpMap;
    5959    QMap <QString, int> keyMap;
     60    QMap <QString, QString> xkeyMap;
    6061
    6162    QMutex clientLock;
    6263    QSocket *client;
  • programs/mythfrontend/sendxkey.cpp

    diff -rupN mythtv-0.21.0+fixes18207/programs/mythfrontend/sendxkey.cpp mythtv-sendxkey/programs/mythfrontend/sendxkey.cpp
    old new  
     1/*      $Id: sendxkey.cpp,v 5.6 2001/11/20 15:12:33 ranty Exp $      */
     2
     3/****************************************************************************
     4 ** irxevent.c **************************************************************
     5 ****************************************************************************
     6 *
     7 * sendxkey  - mythfrontend telnet xevent sender
     8 *
     9 * Based off of sendxirevent by Heinrich Langos  <heinrich@null.net> with
     10 * small modifications by Christoph Bartelmus <lirc@bartelmus.de>
     11 *
     12 * irxevent is based on irexec (Copyright (C) 1998 Trent Piepho)
     13 * and irx.c (no copyright notice found)
     14 *
     15 */
     16
     17#ifdef HAVE_CONFIG_H
     18# include <config.h>
     19#endif
     20
     21#include <errno.h>
     22#include <unistd.h>
     23#include <getopt.h>
     24#include <stdarg.h>
     25#include <stdio.h>
     26#include <stdlib.h>
     27#include <string.h>
     28#include <sys/socket.h>
     29#include <sys/un.h>
     30#include <sys/stat.h>
     31#include <sys/types.h>
     32
     33#include <X11/Xlib.h>
     34#include <X11/Xutil.h>
     35#include <sys/time.h>
     36#include <unistd.h>
     37
     38struct keymodlist_t {
     39        char *name;
     40        Mask mask;
     41};
     42static struct keymodlist_t keymodlist[]=
     43{
     44  {"SHIFT",   ShiftMask},
     45  {"CAPS",    LockMask},
     46  {"CTRL",    ControlMask},
     47  {"ALT",     Mod1Mask},{"META",    Mod1Mask},
     48  {"NUMLOCK", Mod2Mask},
     49  {"MOD3",    Mod3Mask},  /* I don't have a clue what key maps to this. */
     50  {"MOD4",    Mod4Mask},  /* I don't have a clue what key maps to this. */
     51  {"SCRLOCK", Mod5Mask},
     52  {NULL,0},
     53};
     54
     55const char *key_delimiter ="-";
     56const char *active_window_name ="CurrentWindow";
     57
     58
     59char *progname;
     60Display *dpy;
     61Window root;
     62XEvent xev;
     63Window w,subw;
     64int initialized = 0;
     65
     66Time fake_timestamp()
     67     /*seems that xfree86 computes the timestamps like this     */
     68     /*strange but it relies on the *1000-32bit-wrap-around     */
     69     /*if anybody knows exactly how to do it, please contact me */
     70{
     71  int  tint;
     72  struct timeval  tv;
     73  struct timezone tz; /* is not used since ages */
     74  gettimeofday(&tv,&tz);
     75  tint=(int)tv.tv_sec*1000;
     76  tint=tint/1000*1000;
     77  tint=tint+tv.tv_usec/1000;
     78  return (Time)tint;
     79}
     80
     81Window find_window()
     82{
     83  Window *children,foo;
     84  int revert_to_return;
     85    XGetInputFocus(dpy, &foo, &revert_to_return);
     86    return(foo);
     87}
     88
     89void make_key(const char *keyname,int x, int y,XKeyEvent *xev)
     90{
     91  char *part, *part2;
     92  struct keymodlist_t *kmlptr;
     93  char temp[strlen(keyname)];
     94  char *ptr = temp;
     95  strcpy(temp, keyname);
     96  part2= new char[128];
     97
     98  xev->type = KeyPress;
     99  xev->display=dpy;
     100  xev->root=root;
     101  xev->subwindow = None;
     102  xev->time=fake_timestamp();
     103  xev->x=x; xev->y=y;
     104  xev->x_root=1; xev->y_root=1;
     105  xev->same_screen = True;
     106
     107  xev->state=0;
     108  while ((part=strsep(&ptr, key_delimiter)))
     109    {
     110      part2=strncpy(part2,part,128);
     111      kmlptr=keymodlist;
     112      while (kmlptr->name)
     113        {
     114          if (!strcasecmp(kmlptr->name, part))
     115            xev->state|=kmlptr->mask;
     116          kmlptr++;
     117        }
     118    }
     119  xev->keycode=XKeysymToKeycode(dpy,XStringToKeysym(part2));
     120  delete [] part2;
     121  return ;
     122}
     123
     124void init_keysender()
     125{
     126  dpy=XOpenDisplay(NULL);
     127  if(dpy==NULL) {
     128    fprintf(stderr,"Can't open DISPLAY.\n");
     129    exit(1);
     130  }
     131  root=RootWindow(dpy,DefaultScreen(dpy));
     132}
     133
     134void get_focused_window(char **window_name)
     135{
     136  if(!initialized)
     137  {
     138    initialized = 1;
     139    init_keysender();
     140  }
     141  Window w = find_window();
     142  XFetchName(dpy, w, window_name);
     143  return;
     144}
     145
     146void sendxkey(const char *keyname)
     147{
     148  int x = 0;
     149  int y = 0;
     150  if(!initialized)
     151  {
     152    initialized = 1;
     153    init_keysender();
     154  }
     155  Window w = find_window();
     156
     157  make_key(keyname ,x,y,(XKeyEvent*)&xev);
     158  xev.xkey.window=w;
     159  xev.xkey.subwindow=0;
     160
     161  XSendEvent(dpy,w,True,KeyPressMask,&xev);
     162  xev.type = KeyRelease;
     163  usleep(2000);
     164  xev.xkey.time = fake_timestamp();
     165  XSendEvent(dpy,w,True,KeyReleaseMask,&xev);
     166  XSync(dpy,True);
     167  return;
     168}
  • programs/mythfrontend/sendxkey.h

    diff -rupN mythtv-0.21.0+fixes18207/programs/mythfrontend/sendxkey.h mythtv-sendxkey/programs/mythfrontend/sendxkey.h
    old new  
     1/****************************************************************************
     2 ** irxevent.h **************************************************************
     3 ****************************************************************************
     4 *
     5 * sendxkey  - mythfrontend telnet xevent sender
     6 *
     7 * Based off of sendxirevent by Heinrich Langos  <heinrich@null.net> with
     8 * small modifications by Christoph Bartelmus <lirc@bartelmus.de>
     9 *
     10 * irxevent is based on irexec (Copyright (C) 1998 Trent Piepho)
     11 * and irx.c (no copyright notice found)
     12 *
     13 */
     14
     15void sendxkey(const char *keyname);
     16void get_focused_window(char **window_name);