Ticket #5713: 5713-v2.patch

File 5713-v2.patch, 20.3 KB (added by danielk, 12 years ago)

Oops, missing sendxkey.{h,cpp} in last patch

  • 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

     
    2525QMAKE_CLEAN += $(TARGET)
    2626
    2727# Input
    28 HEADERS += playbackbox.h viewscheduled.h globalsettings.h
    29 HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h
    30 HEADERS += statusbox.h networkcontrol.h custompriority.h
     28HEADERS += playbackbox.h viewscheduled.h
     29HEADERS += globalsettings.h manualschedule.h
     30HEADERS += programrecpriority.h channelrecpriority.h custompriority.h
     31HEADERS += statusbox.h networkcontrol.h sendxkey.h
    3132HEADERS += mediarenderer.h mythfexml.h
    3233HEADERS += mythappearance.h exitprompt.h
    3334
    3435SOURCES += main.cpp playbackbox.cpp viewscheduled.cpp
    35 SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp
    36 SOURCES += channelrecpriority.cpp statusbox.cpp networkcontrol.cpp
     36SOURCES += globalsettings.cpp manualschedule.cpp
     37SOURCES += programrecpriority.cpp channelrecpriority.cpp custompriority.cpp
     38SOURCES += statusbox.cpp networkcontrol.cpp sendxkey.cpp
    3739SOURCES += mediarenderer.cpp mythfexml.cpp
    38 SOURCES += custompriority.cpp
    3940SOURCES += mythappearance.cpp exitprompt.cpp
    4041
    4142macx {
  • programs/mythfrontend/networkcontrol.h

     
    4141  private:
    4242    QString processJump(QStringList tokens);
    4343    QString processKey(QStringList tokens);
     44    QString processXKey(QString command);
    4445    QString processLiveTV(QStringList tokens);
    4546    QString processPlay(QStringList tokens);
    4647    QString processQuery(QStringList tokens);
     
    6162    QString answer;
    6263    QMap <QString, QString> jumpMap;
    6364    QMap <QString, int> keyMap;
     65    QMap <QString, QString> xkeyMap;
    6466
    6567    mutable QMutex  clientLock;
    6668    QTcpSocket     *client;
  • programs/mythfrontend/networkcontrol.cpp

     
    2020#include "mythverbose.h"
    2121#include "mythversion.h"
    2222#include "mythuihelper.h"
     23#include "sendxkey.h"
    2324
    2425#define LOC QString("NetworkControl: ")
    2526#define LOC_ERR QString("NetworkControl Error: ")
     
    186187    keyMap["f22"]                    = Qt::Key_F22;
    187188    keyMap["f23"]                    = Qt::Key_F23;
    188189    keyMap["f24"]                    = Qt::Key_F24;
     190   
     191    xkeyMap["BackSpace"] = "BackSpace";
     192    xkeyMap["Tab"] = "Tab";
     193    xkeyMap["Linefeed"] = "Linefeed";
     194    xkeyMap["Clear"] = "Clear";
     195    xkeyMap["Return"] = "Return";
     196    xkeyMap["Pause"] = "Pause";
     197    xkeyMap["Scroll_Lock"] = "Scroll_Lock";
     198    xkeyMap["Sys_Req"] = "Sys_Req";
     199    xkeyMap["Escape"] = "Escape";
     200    xkeyMap["Delete"] = "Delete";
     201    xkeyMap["Home"] = "Home";
     202    xkeyMap["Left"] = "Left";
     203    xkeyMap["Up"] = "Up";
     204    xkeyMap["Right"] = "Right";
     205    xkeyMap["Down"] = "Down";
     206    xkeyMap["Prior"] = "Prior";
     207    xkeyMap["Page_Up"] = "Page_Up";
     208    xkeyMap["Next"] = "Next";
     209    xkeyMap["Page_Down"] = "Page_Down";
     210    xkeyMap["End"] = "End";
     211    xkeyMap["Begin"] = "Begin";
     212    xkeyMap["Select"] = "Select";
     213    xkeyMap["Print"] = "Print";
     214    xkeyMap["Execute"] = "Execute";
     215    xkeyMap["Insert"] = "Insert";
     216    xkeyMap["Undo"] = "Undo";
     217    xkeyMap["Redo"] = "Redo";
     218    xkeyMap["Menu"] = "Menu";
     219    xkeyMap["Find"] = "Find";
     220    xkeyMap["Cancel"] = "Cancel";
     221    xkeyMap["Help"] = "Help";
     222    xkeyMap["Break"] = "Break";
     223    xkeyMap["Mode_switch"] = "Mode_switch";
     224    xkeyMap["script_switch"] = "script_switch";
     225    xkeyMap["Num_Lock"] = "Num_Lock";
     226    xkeyMap["KP_Space"] = "KP_Space";
     227    xkeyMap["KP_Tab"] = "KP_Tab";
     228    xkeyMap["KP_Enter"] = "KP_Enter";
     229    xkeyMap["KP_F1"] = "KP_F1";
     230    xkeyMap["KP_F2"] = "KP_F2";
     231    xkeyMap["KP_F3"] = "KP_F3";
     232    xkeyMap["KP_F4"] = "KP_F4";
     233    xkeyMap["KP_Home"] = "KP_Home";
     234    xkeyMap["KP_Left"] = "KP_Left";
     235    xkeyMap["KP_Up"] = "KP_Up";
     236    xkeyMap["KP_Right"] = "KP_Right";
     237    xkeyMap["KP_Down"] = "KP_Down";
     238    xkeyMap["KP_Prior"] = "KP_Prior";
     239    xkeyMap["KP_Page_Up"] = "KP_Page_Up";
     240    xkeyMap["KP_Next"] = "KP_Next";
     241    xkeyMap["KP_Page_Down"] = "KP_Page_Down";
     242    xkeyMap["KP_End"] = "KP_End";
     243    xkeyMap["KP_Begin"] = "KP_Begin";
     244    xkeyMap["KP_Insert"] = "KP_Insert";
     245    xkeyMap["KP_Delete"] = "KP_Delete";
     246    xkeyMap["KP_Equal"] = "KP_Equal";
     247    xkeyMap["KP_Multiply"] = "KP_Multiply";
     248    xkeyMap["KP_Add"] = "KP_Add";
     249    xkeyMap["KP_Separator"] = "KP_Separator";
     250    xkeyMap["KP_Subtract"] = "KP_Subtract";
     251    xkeyMap["KP_Decimal"] = "KP_Decimal";
     252    xkeyMap["KP_Divide"] = "KP_Divide";
     253    xkeyMap["KP_0"] = "KP_0";
     254    xkeyMap["KP_1"] = "KP_1";
     255    xkeyMap["KP_2"] = "KP_2";
     256    xkeyMap["KP_3"] = "KP_3";
     257    xkeyMap["KP_4"] = "KP_4";
     258    xkeyMap["KP_5"] = "KP_5";
     259    xkeyMap["KP_6"] = "KP_6";
     260    xkeyMap["KP_7"] = "KP_7";
     261    xkeyMap["KP_8"] = "KP_8";
     262    xkeyMap["KP_9"] = "KP_9";
     263    xkeyMap["F1"] = "F1";
     264    xkeyMap["F2"] = "F2";
     265    xkeyMap["F3"] = "F3";
     266    xkeyMap["F4"] = "F4";
     267    xkeyMap["F5"] = "F5";
     268    xkeyMap["F6"] = "F6";
     269    xkeyMap["F7"] = "F7";
     270    xkeyMap["F8"] = "F8";
     271    xkeyMap["F9"] = "F9";
     272    xkeyMap["F10"] = "F10";
     273    xkeyMap["F11"] = "F11";
     274    xkeyMap["L1"] = "L1";
     275    xkeyMap["F12"] = "F12";
     276    xkeyMap["L2"] = "L2";
     277    xkeyMap["F13"] = "F13";
     278    xkeyMap["L3"] = "L3";
     279    xkeyMap["F14"] = "F14";
     280    xkeyMap["L4"] = "L4";
     281    xkeyMap["F15"] = "F15";
     282    xkeyMap["L5"] = "L5";
     283    xkeyMap["F16"] = "F16";
     284    xkeyMap["L6"] = "L6";
     285    xkeyMap["F17"] = "F17";
     286    xkeyMap["L7"] = "L7";
     287    xkeyMap["F18"] = "F18";
     288    xkeyMap["L8"] = "L8";
     289    xkeyMap["F19"] = "F19";
     290    xkeyMap["L9"] = "L9";
     291    xkeyMap["F20"] = "F20";
     292    xkeyMap["L10"] = "L10";
     293    xkeyMap["F21"] = "F21";
     294    xkeyMap["R1"] = "R1";
     295    xkeyMap["F22"] = "F22";
     296    xkeyMap["R2"] = "R2";
     297    xkeyMap["F23"] = "F23";
     298    xkeyMap["R3"] = "R3";
     299    xkeyMap["F24"] = "F24";
     300    xkeyMap["R4"] = "R4";
     301    xkeyMap["F25"] = "F25";
     302    xkeyMap["R5"] = "R5";
     303    xkeyMap["F26"] = "F26";
     304    xkeyMap["R6"] = "R6";
     305    xkeyMap["F27"] = "F27";
     306    xkeyMap["R7"] = "R7";
     307    xkeyMap["F28"] = "F28";
     308    xkeyMap["R8"] = "R8";
     309    xkeyMap["F29"] = "F29";
     310    xkeyMap["R9"] = "R9";
     311    xkeyMap["F30"] = "F30";
     312    xkeyMap["R10"] = "R10";
     313    xkeyMap["F31"] = "F31";
     314    xkeyMap["R11"] = "R11";
     315    xkeyMap["F32"] = "F32";
     316    xkeyMap["R12"] = "R12";
     317    xkeyMap["F33"] = "F33";
     318    xkeyMap["R13"] = "R13";
     319    xkeyMap["F34"] = "F34";
     320    xkeyMap["R14"] = "R14";
     321    xkeyMap["F35"] = "F35";
     322    xkeyMap["R15"] = "R15";
     323    xkeyMap["Shift_L"] = "Shift_L";
     324    xkeyMap["Shift_R"] = "Shift_R";
     325    xkeyMap["Control_L"] = "Control_L";
     326    xkeyMap["Control_R"] = "Control_R";
     327    xkeyMap["Caps_Lock"] = "Caps_Lock";
     328    xkeyMap["Shift_Lock"] = "Shift_Lock";
     329    xkeyMap["Meta_L"] = "Meta_L";
     330    xkeyMap["Meta_R"] = "Meta_R";
     331    xkeyMap["Alt_L"] = "Alt_L";
     332    xkeyMap["Alt_R"] = "Alt_R";
     333    xkeyMap["Super_L"] = "Super_L";
     334    xkeyMap["Super_R"] = "Super_R";
     335    xkeyMap["Hyper_L"] = "Hyper_L";
     336    xkeyMap["Hyper_R"] = "Hyper_R";
     337    xkeyMap["space"] = "space";
     338    xkeyMap["exclam"] = "exclam";
     339    xkeyMap["quotedbl"] = "quotedbl";
     340    xkeyMap["numbersign"] = "numbersign";
     341    xkeyMap["dollar"] = "dollar";
     342    xkeyMap["percent"] = "percent";
     343    xkeyMap["ampersand"] = "ampersand";
     344    xkeyMap["apostrophe"] = "apostrophe";
     345    xkeyMap["quoteright"] = "quoteright";
     346    xkeyMap["parenleft"] = "parenleft";
     347    xkeyMap["parenright"] = "parenright";
     348    xkeyMap["asterisk"] = "asterisk";
     349    xkeyMap["plus"] = "plus";
     350    xkeyMap["comma"] = "comma";
     351    xkeyMap["minus"] = "minus";
     352    xkeyMap["period"] = "period";
     353    xkeyMap["slash"] = "slash";
     354    xkeyMap["colon"] = "colon";
     355    xkeyMap["semicolon"] = "semicolon";
     356    xkeyMap["less"] = "less";
     357    xkeyMap["equal"] = "equal";
     358    xkeyMap["greater"] = "greater";
     359    xkeyMap["question"] = "question";
     360    xkeyMap["at"] = "at";
     361    xkeyMap["bracketleft"] = "bracketleft";
     362    xkeyMap["backslash"] = "backslash";
     363    xkeyMap["bracketright"] = "bracketright";
     364    xkeyMap["asciicircum"] = "asciicircum";
     365    xkeyMap["underscore"] = "underscore";
     366    xkeyMap["grave"] = "grave";
     367    xkeyMap["quoteleft"] = "quoteleft";
     368    xkeyMap["braceleft"] = "braceleft";
     369    xkeyMap["bar"] = "bar";
     370    xkeyMap["braceright"] = "braceright";
     371    xkeyMap["asciitilde"] = "asciitilde";
     372    xkeyMap["nobreakspace"] = "nobreakspace";
     373    xkeyMap["exclamdown"] = "exclamdown";
     374    xkeyMap["cent"] = "cent";
     375    xkeyMap["sterling"] = "sterling";
     376    xkeyMap["currency"] = "currency";
     377    xkeyMap["yen"] = "yen";
     378    xkeyMap["brokenbar"] = "brokenbar";
     379    xkeyMap["section"] = "section";
     380    xkeyMap["diaeresis"] = "diaeresis";
     381    xkeyMap["copyright"] = "copyright";
     382    xkeyMap["ordfeminine"] = "ordfeminine";
     383    xkeyMap["guillemotleft"] = "guillemotleft";
     384    xkeyMap["notsign"] = "notsign";
     385    xkeyMap["hyphen"] = "hyphen";
     386    xkeyMap["registered"] = "registered";
     387    xkeyMap["macron"] = "macron";
     388    xkeyMap["degree"] = "degree";
     389    xkeyMap["plusminus"] = "plusminus";
     390    xkeyMap["twosuperior"] = "twosuperior";
     391    xkeyMap["threesuperior"] = "threesuperior";
     392    xkeyMap["acute"] = "acute";
     393    xkeyMap["mu"] = "mu";
     394    xkeyMap["paragraph"] = "paragraph";
     395    xkeyMap["periodcentered"] = "periodcentered";
     396    xkeyMap["cedilla"] = "cedilla";
     397    xkeyMap["onesuperior"] = "onesuperior";
     398    xkeyMap["masculine"] = "masculine";
     399    xkeyMap["guillemotright"] = "guillemotright";
     400    xkeyMap["onequarter"] = "onequarter";
     401    xkeyMap["onehalf"] = "onehalf";
     402    xkeyMap["threequarters"] = "threequarters";
     403    xkeyMap["questiondown"] = "questiondown";
     404    xkeyMap["Agrave"] = "Agrave";
     405    xkeyMap["Aacute"] = "Aacute";
     406    xkeyMap["Acircumflex"] = "Acircumflex";
     407    xkeyMap["Atilde"] = "Atilde";
     408    xkeyMap["Adiaeresis"] = "Adiaeresis";
     409    xkeyMap["Aring"] = "Aring";
     410    xkeyMap["AE"] = "AE";
     411    xkeyMap["Ccedilla"] = "Ccedilla";
     412    xkeyMap["Egrave"] = "Egrave";
     413    xkeyMap["Eacute"] = "Eacute";
     414    xkeyMap["Ecircumflex"] = "Ecircumflex";
     415    xkeyMap["Ediaeresis"] = "Ediaeresis";
     416    xkeyMap["Igrave"] = "Igrave";
     417    xkeyMap["Iacute"] = "Iacute";
     418    xkeyMap["Icircumflex"] = "Icircumflex";
     419    xkeyMap["Idiaeresis"] = "Idiaeresis";
     420    xkeyMap["ETH"] = "ETH";
     421    xkeyMap["Eth"] = "Eth";
     422    xkeyMap["Ntilde"] = "Ntilde";
     423    xkeyMap["Ograve"] = "Ograve";
     424    xkeyMap["Oacute"] = "Oacute";
     425    xkeyMap["Ocircumflex"] = "Ocircumflex";
     426    xkeyMap["Otilde"] = "Otilde";
     427    xkeyMap["Odiaeresis"] = "Odiaeresis";
     428    xkeyMap["multiply"] = "multiply";
     429    xkeyMap["Ooblique"] = "Ooblique";
     430    xkeyMap["Ugrave"] = "Ugrave";
     431    xkeyMap["Uacute"] = "Uacute";
     432    xkeyMap["Ucircumflex"] = "Ucircumflex";
     433    xkeyMap["Udiaeresis"] = "Udiaeresis";
     434    xkeyMap["Yacute"] = "Yacute";
     435    xkeyMap["THORN"] = "THORN";
     436    xkeyMap["Thorn"] = "Thorn";
     437    xkeyMap["ssharp"] = "ssharp";
     438    xkeyMap["agrave"] = "agrave";
     439    xkeyMap["aacute"] = "aacute";
     440    xkeyMap["acircumflex"] = "acircumflex";
     441    xkeyMap["atilde"] = "atilde";
     442    xkeyMap["adiaeresis"] = "adiaeresis";
     443    xkeyMap["aring"] = "aring";
     444    xkeyMap["ae"] = "ae";
     445    xkeyMap["ccedilla"] = "ccedilla";
     446    xkeyMap["egrave"] = "egrave";
     447    xkeyMap["eacute"] = "eacute";
     448    xkeyMap["ecircumflex"] = "ecircumflex";
     449    xkeyMap["ediaeresis"] = "ediaeresis";
     450    xkeyMap["igrave"] = "igrave";
     451    xkeyMap["iacute"] = "iacute";
     452    xkeyMap["icircumflex"] = "icircumflex";
     453    xkeyMap["idiaeresis"] = "idiaeresis";
     454    xkeyMap["eth"] = "eth";
     455    xkeyMap["ntilde"] = "ntilde";
     456    xkeyMap["ograve"] = "ograve";
     457    xkeyMap["oacute"] = "oacute";
     458    xkeyMap["ocircumflex"] = "ocircumflex";
     459    xkeyMap["otilde"] = "otilde";
     460    xkeyMap["odiaeresis"] = "odiaeresis";
     461    xkeyMap["division"] = "division";
     462    xkeyMap["oslash"] = "oslash";
     463    xkeyMap["ugrave"] = "ugrave";
     464    xkeyMap["uacute"] = "uacute";
     465    xkeyMap["ucircumflex"] = "ucircumflex";
     466    xkeyMap["udiaeresis"] = "udiaeresis";
     467    xkeyMap["yacute"] = "yacute";
     468    xkeyMap["thorn"] = "thorn";
     469    xkeyMap["ydiaeresis"] = "ydiaeresis";
    189470
    190471    stopCommandThread = false;
    191472    pthread_create(&command_thread, NULL, CommandThread, this);
     
    277558        result = processJump(tokens);
    278559    else if (is_abbrev("key", tokens[0]))
    279560        result = processKey(tokens);
     561    else if (is_abbrev("xkey", tokens[0]))
     562        result = processXKey(command);
    280563    else if (is_abbrev("play", tokens[0]))
    281564        result = processPlay(tokens);
    282565    else if (is_abbrev("query", tokens[0]))
     
    520803    return result;
    521804}
    522805
     806QString NetworkControl::processXKey(QString command)
     807{
     808    QString result = "OK";
     809
     810    QString cmd = command.remove(0, 5);
     811    if (xkeyMap.contains(cmd) || (cmd[0].isLetterOrNumber()))
     812        sendxkey(cmd.toAscii().constData());
     813    else
     814        return QString("ERROR: Invalid syntax at '%1', see 'help xkey' for "
     815                       "usage information").arg(cmd);
     816    return result;
     817}
     818
    523819QString NetworkControl::processPlay(QStringList tokens)
    524820{
    525821    QString result = "OK";
     
    7411037        return listRecordings(tokens[2], tokens[3].toUpper());
    7421038    else if (is_abbrev("recordings", tokens[1]))
    7431039        return listRecordings();
     1040    else if (is_abbrev("focused", tokens[1]))
     1041    {
     1042        char *title;
     1043        get_focused_window(&title);
     1044        result = QString(title);
     1045    delete [] title;
     1046    }
    7441047    else
    7451048        return QString("ERROR: See 'help %1' for usage information")
    7461049                       .arg(tokens[0]);
     
    8031106        }
    8041107        helpText += "\r\n";
    8051108    }
     1109    else if (is_abbrev("xkey", command))
     1110    {
     1111        helpText +=
     1112            "xkey LETTER           - Send the letter key specified\r\n"
     1113            "xkey NUMBER           - Send the number key specified\r\n"
     1114            "xkey CODE             - Send one of the following key codes\r\n"
     1115            "\r\n";
     1116
     1117        QMap<QString, QString>::Iterator it;
     1118        bool first = true;
     1119        for (it = xkeyMap.begin(); it != xkeyMap.end(); ++it)
     1120        {
     1121            if (first)
     1122                first = false;
     1123            else
     1124                helpText += ", ";
     1125
     1126            helpText += it.key();
     1127        }
     1128        helpText += "\r\n";
     1129    }
    8061130    else if (is_abbrev("play", command))
    8071131    {
    8081132        helpText +=
     
    8441168            "query liveTV          - List current TV schedule\r\n"
    8451169            "query liveTV CHANID   - Query current program for specified channel\r\n"
    8461170            "query time            - Query current time on server\r\n"
     1171            "query focused         - Returns the name of the focused window\r\n"
    8471172            "query version         - Query Frontend version details\r\n";
    8481173    }
    8491174    else if (command == "exit")
     
    8631188        "---------------\r\n"
    8641189        "jump               - Jump to a specified location in Myth\r\n"
    8651190        "key                - Send a keypress to the program\r\n"
     1191        "xkey               - Send a keypress to the focused program\r\n"
    8661192        "play               - Playback related commands\r\n"
    8671193        "query              - Queries\r\n"
    8681194        "exit               - Exit Network Control\r\n"