Ticket #5713: myth-network-xkey-svn.patch

File myth-network-xkey-svn.patch, 20.0 KB (added by yolanother@…, 11 years ago)

This version of the patch should apply cleanly to svn 18282.

  • programs/mythfrontend/sendxkey.h

     
     1/****************************************************************************
     2 ** irxevent.h **************************************************************
     3 ****************************************************************************
     4 *
     5 * sendxkey  - mythfrontend telnet xevent sender
     6 * Latest modification by Yolan <yolanother@gmail.com> for the network plugin.
     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);
  • programs/mythfrontend/sendxkey.cpp

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

     
    2525# Input
    2626HEADERS += manualbox.h playbackbox.h viewscheduled.h globalsettings.h
    2727HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h
    28 HEADERS += statusbox.h networkcontrol.h custompriority.h
     28HEADERS += statusbox.h sendxkey.h networkcontrol.h custompriority.h
    2929HEADERS += mediarenderer.h mythfexml.h
    3030HEADERS += 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 mythfexml.cpp
    3636SOURCES += custompriority.cpp
    3737SOURCES += mythappearance.cpp
  • programs/mythfrontend/networkcontrol.h

     
    3535  private:
    3636    QString processJump(QStringList tokens);
    3737    QString processKey(QStringList tokens);
     38    QString processXKey(QString command);
    3839    QString processLiveTV(QStringList tokens);
    3940    QString processPlay(QStringList tokens);
    4041    QString processQuery(QStringList tokens);
     
    5556    QString answer;
    5657    QMap <QString, QString> jumpMap;
    5758    QMap <QString, int> keyMap;
     59    QMap <QString, QString> xkeyMap;
    5860
    5961    QMutex clientLock;
    6062    Q3Socket *client;
  • programs/mythfrontend/networkcontrol.cpp

     
    1919#include "previewgenerator.h"
    2020#include "compat.h"
    2121#include "mythuihelper.h"
     22#include "sendxkey.h"
    2223
    2324#define LOC QString("NetworkControl: ")
    2425#define LOC_ERR QString("NetworkControl Error: ")
     
    187188    keyMap["f22"]                    = Qt::Key_F22;
    188189    keyMap["f23"]                    = Qt::Key_F23;
    189190    keyMap["f24"]                    = Qt::Key_F24;
     191   
     192    xkeyMap["BackSpace"] = "BackSpace";
     193    xkeyMap["Tab"] = "Tab";
     194    xkeyMap["Linefeed"] = "Linefeed";
     195    xkeyMap["Clear"] = "Clear";
     196    xkeyMap["Return"] = "Return";
     197    xkeyMap["Pause"] = "Pause";
     198    xkeyMap["Scroll_Lock"] = "Scroll_Lock";
     199    xkeyMap["Sys_Req"] = "Sys_Req";
     200    xkeyMap["Escape"] = "Escape";
     201    xkeyMap["Delete"] = "Delete";
     202    xkeyMap["Home"] = "Home";
     203    xkeyMap["Left"] = "Left";
     204    xkeyMap["Up"] = "Up";
     205    xkeyMap["Right"] = "Right";
     206    xkeyMap["Down"] = "Down";
     207    xkeyMap["Prior"] = "Prior";
     208    xkeyMap["Page_Up"] = "Page_Up";
     209    xkeyMap["Next"] = "Next";
     210    xkeyMap["Page_Down"] = "Page_Down";
     211    xkeyMap["End"] = "End";
     212    xkeyMap["Begin"] = "Begin";
     213    xkeyMap["Select"] = "Select";
     214    xkeyMap["Print"] = "Print";
     215    xkeyMap["Execute"] = "Execute";
     216    xkeyMap["Insert"] = "Insert";
     217    xkeyMap["Undo"] = "Undo";
     218    xkeyMap["Redo"] = "Redo";
     219    xkeyMap["Menu"] = "Menu";
     220    xkeyMap["Find"] = "Find";
     221    xkeyMap["Cancel"] = "Cancel";
     222    xkeyMap["Help"] = "Help";
     223    xkeyMap["Break"] = "Break";
     224    xkeyMap["Mode_switch"] = "Mode_switch";
     225    xkeyMap["script_switch"] = "script_switch";
     226    xkeyMap["Num_Lock"] = "Num_Lock";
     227    xkeyMap["KP_Space"] = "KP_Space";
     228    xkeyMap["KP_Tab"] = "KP_Tab";
     229    xkeyMap["KP_Enter"] = "KP_Enter";
     230    xkeyMap["KP_F1"] = "KP_F1";
     231    xkeyMap["KP_F2"] = "KP_F2";
     232    xkeyMap["KP_F3"] = "KP_F3";
     233    xkeyMap["KP_F4"] = "KP_F4";
     234    xkeyMap["KP_Home"] = "KP_Home";
     235    xkeyMap["KP_Left"] = "KP_Left";
     236    xkeyMap["KP_Up"] = "KP_Up";
     237    xkeyMap["KP_Right"] = "KP_Right";
     238    xkeyMap["KP_Down"] = "KP_Down";
     239    xkeyMap["KP_Prior"] = "KP_Prior";
     240    xkeyMap["KP_Page_Up"] = "KP_Page_Up";
     241    xkeyMap["KP_Next"] = "KP_Next";
     242    xkeyMap["KP_Page_Down"] = "KP_Page_Down";
     243    xkeyMap["KP_End"] = "KP_End";
     244    xkeyMap["KP_Begin"] = "KP_Begin";
     245    xkeyMap["KP_Insert"] = "KP_Insert";
     246    xkeyMap["KP_Delete"] = "KP_Delete";
     247    xkeyMap["KP_Equal"] = "KP_Equal";
     248    xkeyMap["KP_Multiply"] = "KP_Multiply";
     249    xkeyMap["KP_Add"] = "KP_Add";
     250    xkeyMap["KP_Separator"] = "KP_Separator";
     251    xkeyMap["KP_Subtract"] = "KP_Subtract";
     252    xkeyMap["KP_Decimal"] = "KP_Decimal";
     253    xkeyMap["KP_Divide"] = "KP_Divide";
     254    xkeyMap["KP_0"] = "KP_0";
     255    xkeyMap["KP_1"] = "KP_1";
     256    xkeyMap["KP_2"] = "KP_2";
     257    xkeyMap["KP_3"] = "KP_3";
     258    xkeyMap["KP_4"] = "KP_4";
     259    xkeyMap["KP_5"] = "KP_5";
     260    xkeyMap["KP_6"] = "KP_6";
     261    xkeyMap["KP_7"] = "KP_7";
     262    xkeyMap["KP_8"] = "KP_8";
     263    xkeyMap["KP_9"] = "KP_9";
     264    xkeyMap["F1"] = "F1";
     265    xkeyMap["F2"] = "F2";
     266    xkeyMap["F3"] = "F3";
     267    xkeyMap["F4"] = "F4";
     268    xkeyMap["F5"] = "F5";
     269    xkeyMap["F6"] = "F6";
     270    xkeyMap["F7"] = "F7";
     271    xkeyMap["F8"] = "F8";
     272    xkeyMap["F9"] = "F9";
     273    xkeyMap["F10"] = "F10";
     274    xkeyMap["F11"] = "F11";
     275    xkeyMap["L1"] = "L1";
     276    xkeyMap["F12"] = "F12";
     277    xkeyMap["L2"] = "L2";
     278    xkeyMap["F13"] = "F13";
     279    xkeyMap["L3"] = "L3";
     280    xkeyMap["F14"] = "F14";
     281    xkeyMap["L4"] = "L4";
     282    xkeyMap["F15"] = "F15";
     283    xkeyMap["L5"] = "L5";
     284    xkeyMap["F16"] = "F16";
     285    xkeyMap["L6"] = "L6";
     286    xkeyMap["F17"] = "F17";
     287    xkeyMap["L7"] = "L7";
     288    xkeyMap["F18"] = "F18";
     289    xkeyMap["L8"] = "L8";
     290    xkeyMap["F19"] = "F19";
     291    xkeyMap["L9"] = "L9";
     292    xkeyMap["F20"] = "F20";
     293    xkeyMap["L10"] = "L10";
     294    xkeyMap["F21"] = "F21";
     295    xkeyMap["R1"] = "R1";
     296    xkeyMap["F22"] = "F22";
     297    xkeyMap["R2"] = "R2";
     298    xkeyMap["F23"] = "F23";
     299    xkeyMap["R3"] = "R3";
     300    xkeyMap["F24"] = "F24";
     301    xkeyMap["R4"] = "R4";
     302    xkeyMap["F25"] = "F25";
     303    xkeyMap["R5"] = "R5";
     304    xkeyMap["F26"] = "F26";
     305    xkeyMap["R6"] = "R6";
     306    xkeyMap["F27"] = "F27";
     307    xkeyMap["R7"] = "R7";
     308    xkeyMap["F28"] = "F28";
     309    xkeyMap["R8"] = "R8";
     310    xkeyMap["F29"] = "F29";
     311    xkeyMap["R9"] = "R9";
     312    xkeyMap["F30"] = "F30";
     313    xkeyMap["R10"] = "R10";
     314    xkeyMap["F31"] = "F31";
     315    xkeyMap["R11"] = "R11";
     316    xkeyMap["F32"] = "F32";
     317    xkeyMap["R12"] = "R12";
     318    xkeyMap["F33"] = "F33";
     319    xkeyMap["R13"] = "R13";
     320    xkeyMap["F34"] = "F34";
     321    xkeyMap["R14"] = "R14";
     322    xkeyMap["F35"] = "F35";
     323    xkeyMap["R15"] = "R15";
     324    xkeyMap["Shift_L"] = "Shift_L";
     325    xkeyMap["Shift_R"] = "Shift_R";
     326    xkeyMap["Control_L"] = "Control_L";
     327    xkeyMap["Control_R"] = "Control_R";
     328    xkeyMap["Caps_Lock"] = "Caps_Lock";
     329    xkeyMap["Shift_Lock"] = "Shift_Lock";
     330    xkeyMap["Meta_L"] = "Meta_L";
     331    xkeyMap["Meta_R"] = "Meta_R";
     332    xkeyMap["Alt_L"] = "Alt_L";
     333    xkeyMap["Alt_R"] = "Alt_R";
     334    xkeyMap["Super_L"] = "Super_L";
     335    xkeyMap["Super_R"] = "Super_R";
     336    xkeyMap["Hyper_L"] = "Hyper_L";
     337    xkeyMap["Hyper_R"] = "Hyper_R";
     338    xkeyMap["space"] = "space";
     339    xkeyMap["exclam"] = "exclam";
     340    xkeyMap["quotedbl"] = "quotedbl";
     341    xkeyMap["numbersign"] = "numbersign";
     342    xkeyMap["dollar"] = "dollar";
     343    xkeyMap["percent"] = "percent";
     344    xkeyMap["ampersand"] = "ampersand";
     345    xkeyMap["apostrophe"] = "apostrophe";
     346    xkeyMap["quoteright"] = "quoteright";
     347    xkeyMap["parenleft"] = "parenleft";
     348    xkeyMap["parenright"] = "parenright";
     349    xkeyMap["asterisk"] = "asterisk";
     350    xkeyMap["plus"] = "plus";
     351    xkeyMap["comma"] = "comma";
     352    xkeyMap["minus"] = "minus";
     353    xkeyMap["period"] = "period";
     354    xkeyMap["slash"] = "slash";
     355    xkeyMap["colon"] = "colon";
     356    xkeyMap["semicolon"] = "semicolon";
     357    xkeyMap["less"] = "less";
     358    xkeyMap["equal"] = "equal";
     359    xkeyMap["greater"] = "greater";
     360    xkeyMap["question"] = "question";
     361    xkeyMap["at"] = "at";
     362    xkeyMap["bracketleft"] = "bracketleft";
     363    xkeyMap["backslash"] = "backslash";
     364    xkeyMap["bracketright"] = "bracketright";
     365    xkeyMap["asciicircum"] = "asciicircum";
     366    xkeyMap["underscore"] = "underscore";
     367    xkeyMap["grave"] = "grave";
     368    xkeyMap["quoteleft"] = "quoteleft";
     369    xkeyMap["braceleft"] = "braceleft";
     370    xkeyMap["bar"] = "bar";
     371    xkeyMap["braceright"] = "braceright";
     372    xkeyMap["asciitilde"] = "asciitilde";
     373    xkeyMap["nobreakspace"] = "nobreakspace";
     374    xkeyMap["exclamdown"] = "exclamdown";
     375    xkeyMap["cent"] = "cent";
     376    xkeyMap["sterling"] = "sterling";
     377    xkeyMap["currency"] = "currency";
     378    xkeyMap["yen"] = "yen";
     379    xkeyMap["brokenbar"] = "brokenbar";
     380    xkeyMap["section"] = "section";
     381    xkeyMap["diaeresis"] = "diaeresis";
     382    xkeyMap["copyright"] = "copyright";
     383    xkeyMap["ordfeminine"] = "ordfeminine";
     384    xkeyMap["guillemotleft"] = "guillemotleft";
     385    xkeyMap["notsign"] = "notsign";
     386    xkeyMap["hyphen"] = "hyphen";
     387    xkeyMap["registered"] = "registered";
     388    xkeyMap["macron"] = "macron";
     389    xkeyMap["degree"] = "degree";
     390    xkeyMap["plusminus"] = "plusminus";
     391    xkeyMap["twosuperior"] = "twosuperior";
     392    xkeyMap["threesuperior"] = "threesuperior";
     393    xkeyMap["acute"] = "acute";
     394    xkeyMap["mu"] = "mu";
     395    xkeyMap["paragraph"] = "paragraph";
     396    xkeyMap["periodcentered"] = "periodcentered";
     397    xkeyMap["cedilla"] = "cedilla";
     398    xkeyMap["onesuperior"] = "onesuperior";
     399    xkeyMap["masculine"] = "masculine";
     400    xkeyMap["guillemotright"] = "guillemotright";
     401    xkeyMap["onequarter"] = "onequarter";
     402    xkeyMap["onehalf"] = "onehalf";
     403    xkeyMap["threequarters"] = "threequarters";
     404    xkeyMap["questiondown"] = "questiondown";
     405    xkeyMap["Agrave"] = "Agrave";
     406    xkeyMap["Aacute"] = "Aacute";
     407    xkeyMap["Acircumflex"] = "Acircumflex";
     408    xkeyMap["Atilde"] = "Atilde";
     409    xkeyMap["Adiaeresis"] = "Adiaeresis";
     410    xkeyMap["Aring"] = "Aring";
     411    xkeyMap["AE"] = "AE";
     412    xkeyMap["Ccedilla"] = "Ccedilla";
     413    xkeyMap["Egrave"] = "Egrave";
     414    xkeyMap["Eacute"] = "Eacute";
     415    xkeyMap["Ecircumflex"] = "Ecircumflex";
     416    xkeyMap["Ediaeresis"] = "Ediaeresis";
     417    xkeyMap["Igrave"] = "Igrave";
     418    xkeyMap["Iacute"] = "Iacute";
     419    xkeyMap["Icircumflex"] = "Icircumflex";
     420    xkeyMap["Idiaeresis"] = "Idiaeresis";
     421    xkeyMap["ETH"] = "ETH";
     422    xkeyMap["Eth"] = "Eth";
     423    xkeyMap["Ntilde"] = "Ntilde";
     424    xkeyMap["Ograve"] = "Ograve";
     425    xkeyMap["Oacute"] = "Oacute";
     426    xkeyMap["Ocircumflex"] = "Ocircumflex";
     427    xkeyMap["Otilde"] = "Otilde";
     428    xkeyMap["Odiaeresis"] = "Odiaeresis";
     429    xkeyMap["multiply"] = "multiply";
     430    xkeyMap["Ooblique"] = "Ooblique";
     431    xkeyMap["Ugrave"] = "Ugrave";
     432    xkeyMap["Uacute"] = "Uacute";
     433    xkeyMap["Ucircumflex"] = "Ucircumflex";
     434    xkeyMap["Udiaeresis"] = "Udiaeresis";
     435    xkeyMap["Yacute"] = "Yacute";
     436    xkeyMap["THORN"] = "THORN";
     437    xkeyMap["Thorn"] = "Thorn";
     438    xkeyMap["ssharp"] = "ssharp";
     439    xkeyMap["agrave"] = "agrave";
     440    xkeyMap["aacute"] = "aacute";
     441    xkeyMap["acircumflex"] = "acircumflex";
     442    xkeyMap["atilde"] = "atilde";
     443    xkeyMap["adiaeresis"] = "adiaeresis";
     444    xkeyMap["aring"] = "aring";
     445    xkeyMap["ae"] = "ae";
     446    xkeyMap["ccedilla"] = "ccedilla";
     447    xkeyMap["egrave"] = "egrave";
     448    xkeyMap["eacute"] = "eacute";
     449    xkeyMap["ecircumflex"] = "ecircumflex";
     450    xkeyMap["ediaeresis"] = "ediaeresis";
     451    xkeyMap["igrave"] = "igrave";
     452    xkeyMap["iacute"] = "iacute";
     453    xkeyMap["icircumflex"] = "icircumflex";
     454    xkeyMap["idiaeresis"] = "idiaeresis";
     455    xkeyMap["eth"] = "eth";
     456    xkeyMap["ntilde"] = "ntilde";
     457    xkeyMap["ograve"] = "ograve";
     458    xkeyMap["oacute"] = "oacute";
     459    xkeyMap["ocircumflex"] = "ocircumflex";
     460    xkeyMap["otilde"] = "otilde";
     461    xkeyMap["odiaeresis"] = "odiaeresis";
     462    xkeyMap["division"] = "division";
     463    xkeyMap["oslash"] = "oslash";
     464    xkeyMap["ugrave"] = "ugrave";
     465    xkeyMap["uacute"] = "uacute";
     466    xkeyMap["ucircumflex"] = "ucircumflex";
     467    xkeyMap["udiaeresis"] = "udiaeresis";
     468    xkeyMap["yacute"] = "yacute";
     469    xkeyMap["thorn"] = "thorn";
     470    xkeyMap["ydiaeresis"] = "ydiaeresis";
    190471
    191472    stopCommandThread = false;
    192473    pthread_create(&command_thread, NULL, CommandThread, this);
     
    251532        result = processJump(tokens);
    252533    else if (is_abbrev("key", tokens[0]))
    253534        result = processKey(tokens);
     535    else if (is_abbrev("xkey", tokens[0]))
     536        result = processXKey(command);
    254537    else if (is_abbrev("play", tokens[0]))
    255538        result = processPlay(tokens);
    256539    else if (is_abbrev("query", tokens[0]))
     
    495778    return result;
    496779}
    497780
     781QString NetworkControl::processXKey(QString command)
     782{
     783    QString result = "OK";
     784
     785    QString cmd = command.remove(0, 5);
     786    if (xkeyMap.contains(cmd) || (cmd[0].isLetterOrNumber()))
     787        sendxkey(cmd.ascii());
     788    else
     789        return QString("ERROR: Invalid syntax at '%1', see 'help xkey' for "
     790                       "usage information").arg(cmd);
     791    return result;
     792}
     793
    498794QString NetworkControl::processPlay(QStringList tokens)
    499795{
    500796    QString result = "OK";
     
    7161012        return listRecordings(tokens[2], tokens[3].upper());
    7171013    else if (is_abbrev("recordings", tokens[1]))
    7181014        return listRecordings();
     1015    else if (is_abbrev("focused", tokens[1]))
     1016    {
     1017        char *title;
     1018        get_focused_window(&title);
     1019        result = QString(title);
     1020    delete [] title;
     1021    }
    7191022    else
    7201023        return QString("ERROR: See 'help %1' for usage information")
    7211024                       .arg(tokens[0]);
     
    7781081        }
    7791082        helpText += "\r\n";
    7801083    }
     1084    else if (is_abbrev("xkey", command))
     1085    {
     1086        helpText +=
     1087            "xkey LETTER           - Send the letter key specified\r\n"
     1088            "xkey NUMBER           - Send the number key specified\r\n"
     1089            "xkey CODE             - Send one of the following key codes\r\n"
     1090            "\r\n";
     1091
     1092        QMap<QString, QString>::Iterator it;
     1093        bool first = true;
     1094        for (it = xkeyMap.begin(); it != xkeyMap.end(); ++it)
     1095        {
     1096            if (first)
     1097                first = false;
     1098            else
     1099                helpText += ", ";
     1100
     1101            helpText += it.key();
     1102        }
     1103        helpText += "\r\n";
     1104    }
    7811105    else if (is_abbrev("play", command))
    7821106    {
    7831107        helpText +=
     
    8191143            "query liveTV          - List current TV schedule\r\n"
    8201144            "query liveTV CHANID   - Query current program for specified channel\r\n"
    8211145            "query time            - Query current time on server\r\n"
     1146            "query focused         - Returns the name of the focused window\r\n";
    8221147            "query version         - Query Frontend version details\r\n";
    8231148    }
    8241149    else if (command == "exit")
     
    8381163        "---------------\r\n"
    8391164        "jump               - Jump to a specified location in Myth\r\n"
    8401165        "key                - Send a keypress to the program\r\n"
     1166        "xkey               - Send a keypress to the focused program\r\n"
    8411167        "play               - Playback related commands\r\n"
    8421168        "query              - Queries\r\n"
    8431169        "exit               - Exit Network Control\r\n"