00001 #include "mythmainwindow.h"
00002 #include "mythmainwindow_internal.h"
00003
00004
00005 #include <cmath>
00006 #include <pthread.h>
00007
00008
00009 #include <algorithm>
00010 #include <vector>
00011 using namespace std;
00012
00013
00014 #ifdef USE_OPENGL_PAINTER
00015 #include <QGLWidget>
00016 #endif
00017
00018 #include <QWaitCondition>
00019 #include <QApplication>
00020 #include <QTimer>
00021 #include <QDesktopWidget>
00022 #include <QHash>
00023 #include <QFile>
00024 #include <QDir>
00025 #include <QEvent>
00026 #include <QKeyEvent>
00027 #include <QKeySequence>
00028 #include <QSize>
00029
00030
00031 #include "unistd.h"
00032 #ifdef QWS
00033 #include <qwindowsystem_qws.h>
00034 #endif
00035 #ifdef Q_WS_MACX_OLDQT
00036 #include <HIToolbox/Menus.h>
00037 #endif
00038
00039
00040 #include "mythdb.h"
00041 #include "mythverbose.h"
00042 #include "mythevent.h"
00043 #include "mythdirs.h"
00044 #include "compat.h"
00045 #include "mythsignalingtimer.h"
00046 #include "mythcorecontext.h"
00047
00048
00049 #include "myththemebase.h"
00050 #include "screensaver.h"
00051 #include "lirc.h"
00052 #include "lircevent.h"
00053
00054 #ifdef USING_APPLEREMOTE
00055 #include "AppleRemoteListener.h"
00056 #endif
00057
00058 #ifdef USE_JOYSTICK_MENU
00059 #include "jsmenu.h"
00060 #include "jsmenuevent.h"
00061 #endif
00062
00063 #include "mythscreentype.h"
00064 #include "mythpainter.h"
00065 #ifdef USE_OPENGL_PAINTER
00066 #include "mythpainter_ogl.h"
00067 #endif
00068 #include "mythpainter_qt.h"
00069 #include "mythgesture.h"
00070 #include "mythuihelper.h"
00071
00072 #ifdef USING_VDPAU
00073 #include "mythpainter_vdpau.h"
00074 #endif
00075
00076 #ifdef USING_MINGW
00077 #include "mythpainter_d3d9.h"
00078 #endif
00079
00080 #define GESTURE_TIMEOUT 1000
00081
00082 #define LOC QString("MythMainWindow: ")
00083 #define LOC_WARN QString("MythMainWindow, Warning: ")
00084 #define LOC_ERR QString("MythMainWindow, Error: ")
00085
00086 class KeyContext
00087 {
00088 public:
00089 void AddMapping(int key, QString action)
00090 {
00091 actionMap[key].append(action);
00092 }
00093
00094 bool GetMapping(int key, QStringList &actions)
00095 {
00096 if (actionMap.count(key) > 0)
00097 {
00098 actions += actionMap[key];
00099 return true;
00100 }
00101 return false;
00102 }
00103
00104 QMap<int, QStringList> actionMap;
00105 };
00106
00107 struct JumpData
00108 {
00109 void (*callback)(void);
00110 QString destination;
00111 QString description;
00112 bool exittomain;
00113 QString localAction;
00114 };
00115
00116 struct MPData {
00117 QString description;
00118 MediaPlayCallback playFn;
00119 };
00120
00121 class MythMainWindowPrivate
00122 {
00123 public:
00124 MythMainWindowPrivate() :
00125 wmult(1.0f), hmult(1.0f),
00126 screenwidth(0), screenheight(0),
00127 xbase(0), ybase(0),
00128 does_fill_screen(false),
00129 ignore_lirc_keys(false),
00130 ignore_joystick_keys(false),
00131 lircThread(NULL),
00132 #ifdef USE_JOYSTICK_MENU
00133 joystickThread(NULL),
00134 #endif
00135
00136 #ifdef USING_APPLEREMOTE
00137 appleRemoteListener(NULL),
00138 appleRemote(NULL),
00139 #endif
00140 exitingtomain(false),
00141 popwindows(false),
00142
00143 m_useDB(true),
00144
00145 exitmenucallback(NULL),
00146
00147 exitmenumediadevicecallback(NULL),
00148 mediadeviceforcallback(NULL),
00149
00150 escapekey(0),
00151
00152 sysEventHandler(NULL),
00153
00154 drawTimer(NULL),
00155 mainStack(NULL),
00156
00157 painter(NULL),
00158
00159 #ifdef USE_OPENGL_PAINTER
00160 render(NULL),
00161 #endif
00162
00163 AllowInput(true),
00164
00165 gestureTimer(NULL),
00166
00167 paintwin(NULL),
00168
00169 oldpaintwin(NULL),
00170 oldpainter(NULL),
00171
00172 m_drawDisabledDepth(0),
00173 m_drawEnabled(true),
00174
00175 m_themeBase(NULL)
00176 {
00177 }
00178
00179 int TranslateKeyNum(QKeyEvent *e);
00180
00181 float wmult, hmult;
00182 int screenwidth, screenheight;
00183
00184 QRect screenRect;
00185 QRect uiScreenRect;
00186
00187 int xbase, ybase;
00188 bool does_fill_screen;
00189
00190 bool ignore_lirc_keys;
00191 bool ignore_joystick_keys;
00192
00193 LIRC *lircThread;
00194
00195 #ifdef USE_JOYSTICK_MENU
00196 JoystickMenuThread *joystickThread;
00197 #endif
00198
00199 #ifdef USING_APPLEREMOTE
00200 AppleRemoteListener *appleRemoteListener;
00201 AppleRemote *appleRemote;
00202 #endif
00203
00204 bool exitingtomain;
00205 bool popwindows;
00206
00207 bool m_useDB;
00208
00209 QHash<QString, KeyContext *> keyContexts;
00210 QMap<int, JumpData*> jumpMap;
00211 QMap<QString, JumpData> destinationMap;
00212 QMap<QString, MPData> mediaPluginMap;
00213
00214 void (*exitmenucallback)(void);
00215
00216 void (*exitmenumediadevicecallback)(MythMediaDevice* mediadevice);
00217 MythMediaDevice * mediadeviceforcallback;
00218
00219 int escapekey;
00220
00221 QObject *sysEventHandler;
00222
00223 MythSignalingTimer *drawTimer;
00224 QVector<MythScreenStack *> stackList;
00225 MythScreenStack *mainStack;
00226
00227 MythPainter *painter;
00228
00229 #ifdef USE_OPENGL_PAINTER
00230 MythRenderOpenGL *render;
00231 #endif
00232
00233 bool AllowInput;
00234
00235 QRegion repaintRegion;
00236
00237 MythGesture gesture;
00238 QTimer *gestureTimer;
00239
00240
00241 std::vector<QWidget *> widgetList;
00242
00243 QWidget *paintwin;
00244
00245 QWidget *oldpaintwin;
00246 MythPainter *oldpainter;
00247
00248 QMutex m_drawDisableLock;
00249 QMutex m_setDrawEnabledLock;
00250 QWaitCondition m_setDrawEnabledWait;
00251 uint m_drawDisabledDepth;
00252 bool m_drawEnabled;
00253
00254 MythThemeBase *m_themeBase;
00255 };
00256
00257
00258 int MythMainWindowPrivate::TranslateKeyNum(QKeyEvent* e)
00259 {
00260 int keynum = e->key();
00261
00262 if ((keynum != Qt::Key_Shift ) && (keynum !=Qt::Key_Control ) &&
00263 (keynum != Qt::Key_Meta ) && (keynum !=Qt::Key_Alt ) &&
00264 (keynum != Qt::Key_Super_L) && (keynum !=Qt::Key_Super_R ) &&
00265 (keynum != Qt::Key_Hyper_L) && (keynum !=Qt::Key_Hyper_R ) &&
00266 (keynum != Qt::Key_AltGr ) && (keynum !=Qt::Key_CapsLock ) &&
00267 (keynum != Qt::Key_NumLock) && (keynum !=Qt::Key_ScrollLock ))
00268 {
00269 Qt::KeyboardModifiers modifiers;
00270
00271 if ((modifiers = e->modifiers()) != Qt::NoModifier)
00272 {
00273 int modnum = (((modifiers & Qt::ShiftModifier) &&
00274 (keynum > 0x7f) &&
00275 (keynum != Qt::Key_Backtab)) ? Qt::SHIFT : 0) |
00276 ((modifiers & Qt::ControlModifier) ? Qt::CTRL : 0) |
00277 ((modifiers & Qt::MetaModifier) ? Qt::META : 0) |
00278 ((modifiers & Qt::AltModifier) ? Qt::ALT : 0);
00279 modnum &= ~Qt::UNICODE_ACCEL;
00280 return (keynum |= modnum);
00281 }
00282 }
00283
00284 return keynum;
00285 }
00286
00287 static MythMainWindow *mainWin = NULL;
00288 static QMutex mainLock;
00289
00298 MythMainWindow *MythMainWindow::getMainWindow(const bool useDB)
00299 {
00300 if (mainWin)
00301 return mainWin;
00302
00303 QMutexLocker lock(&mainLock);
00304
00305 if (!mainWin)
00306 {
00307 mainWin = new MythMainWindow(useDB);
00308 gCoreContext->SetGUIObject(mainWin);
00309 }
00310
00311 return mainWin;
00312 }
00313
00314 void MythMainWindow::destroyMainWindow(void)
00315 {
00316 gCoreContext->SetGUIObject(NULL);
00317 delete mainWin;
00318 mainWin = NULL;
00319 }
00320
00321 MythMainWindow *GetMythMainWindow(void)
00322 {
00323 return MythMainWindow::getMainWindow();
00324 }
00325
00326 bool HasMythMainWindow(void)
00327 {
00328 return (mainWin);
00329 }
00330
00331 void DestroyMythMainWindow(void)
00332 {
00333 MythMainWindow::destroyMainWindow();
00334 }
00335
00336 MythPainter *GetMythPainter(void)
00337 {
00338 return MythMainWindow::getMainWindow()->GetCurrentPainter();
00339 }
00340
00341 #ifdef USE_OPENGL_PAINTER
00342 MythPainterWindowGL::MythPainterWindowGL(MythMainWindow *win,
00343 MythMainWindowPrivate *priv,
00344 MythRenderOpenGL *rend)
00345 : QGLWidget(rend, win),
00346 parent(win), d(priv), render(rend)
00347 {
00348 setAutoBufferSwap(false);
00349 }
00350
00351 void MythPainterWindowGL::paintEvent(QPaintEvent *pe)
00352 {
00353 d->repaintRegion = d->repaintRegion.unite(pe->region());
00354 parent->drawScreen();
00355 }
00356 #endif
00357
00358 #ifdef USING_VDPAU
00359 MythPainterWindowVDPAU::MythPainterWindowVDPAU(MythMainWindow *win,
00360 MythMainWindowPrivate *priv)
00361 : QGLWidget(win),
00362 parent(win), d(priv)
00363 {
00364 setAutoBufferSwap(false);
00365 }
00366
00367 void MythPainterWindowVDPAU::paintEvent(QPaintEvent *pe)
00368 {
00369 d->repaintRegion = d->repaintRegion.unite(pe->region());
00370 parent->drawScreen();
00371 }
00372 #endif
00373
00374 #ifdef USING_MINGW
00375 MythPainterWindowD3D9::MythPainterWindowD3D9(MythMainWindow *win,
00376 MythMainWindowPrivate *priv)
00377 : QGLWidget(win),
00378 parent(win), d(priv)
00379 {
00380 setAutoBufferSwap(false);
00381 }
00382
00383 void MythPainterWindowD3D9::paintEvent(QPaintEvent *pe)
00384 {
00385 d->repaintRegion = d->repaintRegion.unite(pe->region());
00386 parent->drawScreen();
00387 }
00388 #endif
00389
00390 MythPainterWindowQt::MythPainterWindowQt(MythMainWindow *win,
00391 MythMainWindowPrivate *priv)
00392 : QWidget(win),
00393 parent(win), d(priv)
00394 {
00395 }
00396
00397 void MythPainterWindowQt::paintEvent(QPaintEvent *pe)
00398 {
00399 d->repaintRegion = d->repaintRegion.unite(pe->region());
00400 parent->drawScreen();
00401 }
00402
00403 MythMainWindow::MythMainWindow(const bool useDB)
00404 : QWidget(NULL)
00405 {
00406 d = new MythMainWindowPrivate;
00407
00408 setObjectName("mainwindow");
00409
00410 d->AllowInput = false;
00411
00412
00413 d->m_useDB = useDB;
00414 d->painter = NULL;
00415 d->paintwin = NULL;
00416 d->oldpainter = NULL;
00417 d->oldpaintwin = NULL;
00418
00419
00420
00421 d->ignore_lirc_keys = false;
00422 d->ignore_joystick_keys = false;
00423 d->exitingtomain = false;
00424 d->popwindows = true;
00425 d->exitmenucallback = false;
00426 d->exitmenumediadevicecallback = false;
00427 d->mediadeviceforcallback = NULL;
00428 d->escapekey = Qt::Key_Escape;
00429 d->mainStack = NULL;
00430 d->sysEventHandler = NULL;
00431
00432 installEventFilter(this);
00433
00434 d->lircThread = NULL;
00435 StartLIRC();
00436
00437 #ifdef USE_JOYSTICK_MENU
00438 d->ignore_joystick_keys = false;
00439
00440 QString joy_config_file = GetConfDir() + "/joystickmenurc";
00441
00442 d->joystickThread = NULL;
00443 d->joystickThread = new JoystickMenuThread(this);
00444 if (!d->joystickThread->Init(joy_config_file))
00445 d->joystickThread->start();
00446 #endif
00447
00448 #ifdef USING_APPLEREMOTE
00449 d->appleRemoteListener = new AppleRemoteListener(this);
00450 d->appleRemote = AppleRemote::Get();
00451
00452 d->appleRemote->setListener(d->appleRemoteListener);
00453 d->appleRemote->startListening();
00454 if (d->appleRemote->isListeningToRemote())
00455 d->appleRemote->start();
00456 #endif
00457
00458 InitKeys();
00459
00460 d->gestureTimer = new QTimer(this);
00461 connect(d->gestureTimer, SIGNAL(timeout()), this, SLOT(mouseTimeout()));
00462
00463 d->drawTimer = new MythSignalingTimer(this, SLOT(animate()));
00464 d->drawTimer->start(1000 / 70);
00465
00466 d->AllowInput = true;
00467
00468 d->repaintRegion = QRegion(QRect(0,0,0,0));
00469
00470 d->m_drawEnabled = true;
00471 }
00472
00473 MythMainWindow::~MythMainWindow()
00474 {
00475 d->drawTimer->stop();
00476
00477 while (!d->stackList.isEmpty())
00478 {
00479 delete d->stackList.back();
00480 d->stackList.pop_back();
00481 }
00482
00483 delete d->m_themeBase;
00484
00485 while (!d->keyContexts.isEmpty())
00486 {
00487 KeyContext *context = *d->keyContexts.begin();
00488 d->keyContexts.erase(d->keyContexts.begin());
00489 delete context;
00490 }
00491
00492 #ifdef USE_LIRC
00493 if (d->lircThread)
00494 {
00495 d->lircThread->deleteLater();
00496 d->lircThread = NULL;
00497 }
00498 #endif
00499
00500 #ifdef USE_JOYSTICK_MENU
00501 if (d->joystickThread)
00502 {
00503 if (d->joystickThread->isRunning())
00504 {
00505 d->joystickThread->Stop();
00506 d->joystickThread->wait();
00507 }
00508
00509 delete d->joystickThread;
00510 d->joystickThread = NULL;
00511 }
00512 #endif
00513
00514 #ifdef USING_APPLEREMOTE
00515
00516
00517 if (d->appleRemote->isRunning())
00518 d->appleRemote->stopListening();
00519
00520 delete d->appleRemoteListener;
00521 #endif
00522
00523 delete d;
00524 }
00525
00526 MythPainter *MythMainWindow::GetCurrentPainter(void)
00527 {
00528 return d->painter;
00529 }
00530
00531 QWidget *MythMainWindow::GetPaintWindow(void)
00532 {
00533 return d->paintwin;
00534 }
00535
00536 void MythMainWindow::AddScreenStack(MythScreenStack *stack, bool main)
00537 {
00538 d->stackList.push_back(stack);
00539 if (main)
00540 d->mainStack = stack;
00541 }
00542
00543 void MythMainWindow::PopScreenStack()
00544 {
00545 delete d->stackList.back();
00546 d->stackList.pop_back();
00547 }
00548
00549 MythScreenStack *MythMainWindow::GetMainStack(void)
00550 {
00551 return d->mainStack;
00552 }
00553
00554 MythScreenStack *MythMainWindow::GetStack(const QString &stackname)
00555 {
00556 QVector<MythScreenStack *>::Iterator it;
00557 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00558 {
00559 if ((*it)->objectName() == stackname)
00560 return *it;
00561 }
00562 return NULL;
00563 }
00564
00565 void MythMainWindow::RegisterSystemEventHandler(QObject *eventHandler)
00566 {
00567 d->sysEventHandler = eventHandler;
00568 }
00569
00570 QObject *MythMainWindow::GetSystemEventHandler(void)
00571 {
00572 return d->sysEventHandler;
00573 }
00574
00575 void MythMainWindow::animate(void)
00576 {
00577
00578 if (currentWidget() || !d->m_drawEnabled)
00579 return;
00580
00581 if (!d->paintwin)
00582 return;
00583
00584 d->drawTimer->blockSignals(true);
00585
00586 bool redraw = false;
00587
00588 if (!d->repaintRegion.isEmpty())
00589 redraw = true;
00590
00591 QVector<MythScreenStack *>::Iterator it;
00592 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00593 {
00594 QVector<MythScreenType *> drawList;
00595 (*it)->GetDrawOrder(drawList);
00596
00597 QVector<MythScreenType *>::Iterator screenit;
00598 for (screenit = drawList.begin(); screenit != drawList.end();
00599 ++screenit)
00600 {
00601 (*screenit)->Pulse();
00602
00603 if ((*screenit)->NeedsRedraw())
00604 {
00605 QRegion topDirty = (*screenit)->GetDirtyArea();
00606 (*screenit)->ResetNeedsRedraw();
00607 d->repaintRegion = d->repaintRegion.unite(topDirty);
00608 redraw = true;
00609 }
00610 }
00611 }
00612
00613 if (redraw)
00614 d->paintwin->update(d->repaintRegion);
00615
00616 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00617 (*it)->ScheduleInitIfNeeded();
00618
00619 d->drawTimer->blockSignals(false);
00620 }
00621
00622 void MythMainWindow::drawScreen(void)
00623 {
00624
00625 if (currentWidget() || !d->m_drawEnabled)
00626 return;
00627
00628 if (!d->painter->SupportsClipping())
00629 d->repaintRegion = d->repaintRegion.unite(d->uiScreenRect);
00630 else
00631 {
00632
00633
00634 d->repaintRegion = d->repaintRegion.intersect(d->uiScreenRect);
00635
00636
00637
00638 QVector<MythScreenStack *>::Iterator it;
00639 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00640 {
00641 QVector<MythScreenType *> redrawList;
00642 (*it)->GetDrawOrder(redrawList);
00643
00644 QVector<MythScreenType *>::Iterator screenit;
00645 for (screenit = redrawList.begin(); screenit != redrawList.end();
00646 ++screenit)
00647 {
00648 if ((*screenit)->NeedsRedraw())
00649 {
00650 QRegion topDirty = (*screenit)->GetDirtyArea();
00651 QVector<QRect> wrects = topDirty.rects();
00652 for (int i = 0; i < wrects.size(); i++)
00653 {
00654 bool foundThisRect = false;
00655 QVector<QRect> drects = d->repaintRegion.rects();
00656 for (int j = 0; j < drects.size(); j++)
00657 {
00658 if (drects[j].contains(wrects[i]))
00659 {
00660 foundThisRect = true;
00661 break;
00662 }
00663 }
00664
00665 if (!foundThisRect)
00666 return;
00667 }
00668 }
00669 }
00670 }
00671 }
00672
00673 d->painter->Begin(d->paintwin);
00674
00675 QVector<QRect> rects = d->repaintRegion.rects();
00676
00677 for (int i = 0; i < rects.size(); i++)
00678 {
00679 if (rects[i].width() == 0 || rects[i].height() == 0)
00680 continue;
00681
00682 if (rects[i] != d->uiScreenRect)
00683 d->painter->SetClipRect(rects[i]);
00684
00685 QVector<MythScreenStack *>::Iterator it;
00686 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00687 {
00688 QVector<MythScreenType *> redrawList;
00689 (*it)->GetDrawOrder(redrawList);
00690
00691 QVector<MythScreenType *>::Iterator screenit;
00692 for (screenit = redrawList.begin(); screenit != redrawList.end();
00693 ++screenit)
00694 {
00695 (*screenit)->Draw(d->painter, 0, 0, 255, rects[i]);
00696 }
00697 }
00698 }
00699
00700 d->painter->End();
00701
00702 d->repaintRegion = QRegion(QRect(0, 0, 0, 0));
00703 }
00704
00705 void MythMainWindow::closeEvent(QCloseEvent *e)
00706 {
00707 if (e->spontaneous())
00708 {
00709 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, d->escapekey,
00710 Qt::NoModifier);
00711 QCoreApplication::postEvent(this, key);
00712 e->ignore();
00713 }
00714 else
00715 QWidget::closeEvent(e);
00716 }
00717
00718 bool MythMainWindow::screenShot(QString fname, int x, int y,
00719 int x2, int y2, int w, int h)
00720 {
00721 bool ret = false;
00722
00723 QString extension = fname.section('.', -1, -1);
00724 if (extension == "jpg")
00725 extension = "JPEG";
00726 else
00727 extension = "PNG";
00728
00729 VERBOSE(VB_GENERAL, "MythMainWindow::screenShot saving winId " +
00730 QString("%1 to %2 (%3 x %4) [ %5/%6 - %7/%8] type %9")
00731 .arg((long)QApplication::desktop()->winId())
00732 .arg(fname)
00733 .arg(w).arg(h)
00734 .arg(x).arg(y)
00735 .arg(x2).arg(y2)
00736 .arg(extension));
00737
00738 QPixmap p;
00739 p = QPixmap::grabWindow( QApplication::desktop()->winId(), x, y, x2, y2);
00740
00741 QImage img = p.toImage();
00742
00743 if ( w == 0 )
00744 w = img.width();
00745
00746 if ( h == 0 )
00747 h = img.height();
00748
00749 VERBOSE(VB_GENERAL, QString("Scaling to %1 x %2 from %3 x %4")
00750 .arg(w)
00751 .arg(h)
00752 .arg(img.width())
00753 .arg(img.height()));
00754
00755 img = img.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation);
00756
00757 if (img.save(fname, extension.toAscii(), 100))
00758 {
00759 VERBOSE(VB_GENERAL, "MythMainWindow::screenShot succeeded");
00760 ret = true;
00761 }
00762 else
00763 {
00764 VERBOSE(VB_GENERAL, "MythMainWindow::screenShot Failed!");
00765 ret = false;
00766 }
00767
00768 return ret;
00769 }
00770
00771 bool MythMainWindow::screenShot(int x, int y, int x2, int y2)
00772 {
00773 QString fPath = GetMythDB()->GetSetting("ScreenShotPath","/tmp/");
00774 QString fName = QString("/%1/myth-screenshot-%2.png")
00775 .arg(fPath)
00776 .arg(QDateTime::currentDateTime()
00777 .toString("yyyy-MM-ddThh-mm-ss.zzz"));
00778
00779 return screenShot(fName, x, y, x2, y2, 0, 0);
00780 }
00781
00782 bool MythMainWindow::screenShot(QString fname, int w, int h)
00783 {
00784 QWidget *active = QApplication::activeWindow();
00785 if (active)
00786 {
00787 QRect sLoc = active->geometry();
00788 return screenShot(fname, sLoc.left(),sLoc.top(),
00789 sLoc.width(), sLoc.height(), w, h);
00790 }
00791 return false;
00792 }
00793
00794
00795 bool MythMainWindow::screenShot(void)
00796 {
00797 QWidget *active = QApplication::activeWindow();
00798 if (active)
00799 {
00800 QRect sLoc = active->geometry();
00801 return screenShot(sLoc.left(),sLoc.top(), sLoc.width(), sLoc.height());
00802 }
00803 return false;
00804 }
00805
00806 bool MythMainWindow::event(QEvent *e)
00807 {
00808 if (e->type() == QEvent::Show && !e->spontaneous())
00809 {
00810 QCoreApplication::postEvent(
00811 this, new QEvent(MythEvent::kMythPostShowEventType));
00812 }
00813
00814 if (e->type() == MythEvent::kMythPostShowEventType)
00815 {
00816 raise();
00817 activateWindow();
00818 return true;
00819 }
00820
00821 #ifdef USING_APPLEREMOTE
00822 if (d->appleRemote)
00823 {
00824 if (e->type() == QEvent::WindowActivate)
00825 d->appleRemote->startListening();
00826
00827 if (e->type() == QEvent::WindowDeactivate)
00828 d->appleRemote->stopListening();
00829 }
00830 #endif
00831
00832 return QWidget::event(e);
00833 }
00834
00835 void MythMainWindow::Init(void)
00836 {
00837 bool hideCursor = GetMythDB()->GetNumSetting("HideMouseCursor", 1);
00838 #ifdef QWS
00839 QWSServer::setCursorVisible(!hideCursor);
00840 #endif
00841
00842 GetMythUI()->GetScreenSettings(d->xbase, d->screenwidth, d->wmult,
00843 d->ybase, d->screenheight, d->hmult);
00844
00845 if (GetMythDB()->GetNumSetting("GuiOffsetX") > 0 ||
00846 GetMythDB()->GetNumSetting("GuiWidth") > 0 ||
00847 GetMythDB()->GetNumSetting("GuiOffsetY") > 0 ||
00848 GetMythDB()->GetNumSetting("GuiHeight") > 0)
00849 d->does_fill_screen = false;
00850 else
00851 d->does_fill_screen = true;
00852
00853
00854 Qt::WindowFlags flags = Qt::Window;
00855
00856 if (!GetMythDB()->GetNumSetting("RunFrontendInWindow", 0))
00857 {
00858 VERBOSE(VB_GENERAL, "Using Frameless Window");
00859 flags |= Qt::FramelessWindowHint;
00860 }
00861
00862
00863 #ifdef WIN32
00864 flags |= Qt::MSWindowsOwnDC;
00865 #endif
00866
00867 setWindowFlags(flags);
00868
00869 if (d->does_fill_screen && !GetMythUI()->IsGeometryOverridden())
00870 {
00871 VERBOSE(VB_GENERAL, "Using Full Screen Window");
00872 setWindowState(Qt::WindowFullScreen);
00873 }
00874
00875 d->screenRect = QRect(d->xbase, d->ybase, d->screenwidth, d->screenheight);
00876 d->uiScreenRect = QRect(0, 0, d->screenwidth, d->screenheight);
00877
00878 setGeometry(d->xbase, d->ybase, d->screenwidth, d->screenheight);
00879 setFixedSize(QSize(d->screenwidth, d->screenheight));
00880
00881 GetMythUI()->ThemeWidget(this);
00882 Show();
00883
00884
00885 setCursor((hideCursor) ? (Qt::BlankCursor) : (Qt::ArrowCursor));
00886
00887 move(d->xbase, d->ybase);
00888
00889 if (d->paintwin)
00890 {
00891 d->oldpaintwin = d->paintwin;
00892 d->paintwin = NULL;
00893 d->drawTimer->stop();
00894 }
00895
00896 if (d->painter)
00897 {
00898 d->oldpainter = d->painter;
00899 d->painter = NULL;
00900 }
00901
00902 QString painter = GetMythDB()->GetSetting("ThemePainter", "qt");
00903 #ifdef USE_OPENGL_PAINTER
00904 if (painter == "opengl")
00905 {
00906 VERBOSE(VB_GENERAL, "Using the OpenGL painter");
00907 d->painter = new MythOpenGLPainter();
00908 QGLFormat fmt;
00909 fmt.setDepth(false);
00910 d->render = new MythRenderOpenGL(fmt);
00911 d->paintwin = new MythPainterWindowGL(this, d, d->render);
00912 QGLWidget *qgl = dynamic_cast<QGLWidget *>(d->paintwin);
00913 if (qgl && !qgl->isValid())
00914 {
00915 VERBOSE(VB_IMPORTANT, "Failed to create OpenGL painter. "
00916 "Check your OpenGL installation.");
00917 delete d->painter;
00918 d->painter = NULL;
00919 delete d->paintwin;
00920 d->paintwin = NULL;
00921 }
00922 }
00923 else
00924 #endif
00925 #ifdef USING_VDPAU
00926 if (painter == "vdpau")
00927 {
00928 VERBOSE(VB_GENERAL, "Using the VDPAU painter");
00929 d->painter = new MythVDPAUPainter();
00930 d->paintwin = new MythPainterWindowVDPAU(this, d);
00931 }
00932 #endif
00933 #ifdef USING_MINGW
00934 if (painter == "d3d9")
00935 {
00936 VERBOSE(VB_GENERAL, "Using the D3D9 painter");
00937 d->painter = new MythD3D9Painter();
00938 d->paintwin = new MythPainterWindowD3D9(this, d);
00939 }
00940 #endif
00941
00942 if (!d->painter && !d->paintwin)
00943 {
00944 VERBOSE(VB_GENERAL, "Using the Qt painter");
00945 d->painter = new MythQtPainter();
00946 d->paintwin = new MythPainterWindowQt(this, d);
00947 }
00948
00949 if (!d->paintwin)
00950 {
00951 VERBOSE(VB_IMPORTANT, "MythMainWindow failed to create a "
00952 "painter window.");
00953 return;
00954 }
00955
00956 d->paintwin->move(0, 0);
00957 d->paintwin->setFixedSize(size());
00958 d->paintwin->raise();
00959 d->paintwin->show();
00960
00961 GetMythUI()->UpdateImageCache();
00962 if (d->m_themeBase)
00963 d->m_themeBase->Reload();
00964 else
00965 d->m_themeBase = new MythThemeBase();
00966 }
00967
00968 void MythMainWindow::InitKeys()
00969 {
00970 RegisterKey("Global", "UP", QT_TRANSLATE_NOOP("MythControls",
00971 "Up Arrow"), "Up");
00972 RegisterKey("Global", "DOWN", QT_TRANSLATE_NOOP("MythControls",
00973 "Down Arrow"), "Down");
00974 RegisterKey("Global", "LEFT", QT_TRANSLATE_NOOP("MythControls",
00975 "Left Arrow"), "Left");
00976 RegisterKey("Global", "RIGHT", QT_TRANSLATE_NOOP("MythControls",
00977 "Right Arrow"), "Right");
00978 RegisterKey("Global", "NEXT", QT_TRANSLATE_NOOP("MythControls",
00979 "Move to next widget"), "Tab");
00980 RegisterKey("Global", "PREVIOUS", QT_TRANSLATE_NOOP("MythControls",
00981 "Move to preview widget"), "Backtab");
00982 RegisterKey("Global", "SELECT", QT_TRANSLATE_NOOP("MythControls",
00983 "Select"), "Return,Enter,Space");
00984 RegisterKey("Global", "BACKSPACE", QT_TRANSLATE_NOOP("MythControls",
00985 "Backspace"), "Backspace");
00986 RegisterKey("Global", "ESCAPE", QT_TRANSLATE_NOOP("MythControls",
00987 "Escape"), "Esc");
00988 RegisterKey("Global", "MENU", QT_TRANSLATE_NOOP("MythControls",
00989 "Pop-up menu"), "M");
00990 RegisterKey("Global", "INFO", QT_TRANSLATE_NOOP("MythControls",
00991 "More information"), "I");
00992 RegisterKey("Global", "DELETE", QT_TRANSLATE_NOOP("MythControls",
00993 "Delete"), "D");
00994 RegisterKey("Global", "EDIT", QT_TRANSLATE_NOOP("MythControls",
00995 "Edit"), "E");
00996
00997 RegisterKey("Global", "PAGEUP", QT_TRANSLATE_NOOP("MythControls",
00998 "Page Up"), "PgUp");
00999 RegisterKey("Global", "PAGEDOWN", QT_TRANSLATE_NOOP("MythControls",
01000 "Page Down"), "PgDown");
01001 RegisterKey("Global", "PAGETOP", QT_TRANSLATE_NOOP("MythControls",
01002 "Page to top of list"), "");
01003 RegisterKey("Global", "PAGEMIDDLE", QT_TRANSLATE_NOOP("MythControls",
01004 "Page to middle of list"), "");
01005 RegisterKey("Global", "PAGEBOTTOM", QT_TRANSLATE_NOOP("MythControls",
01006 "Page to bottom of list"), "");
01007
01008 RegisterKey("Global", "PREVVIEW", QT_TRANSLATE_NOOP("MythControls",
01009 "Previous View"), "Home");
01010 RegisterKey("Global", "NEXTVIEW", QT_TRANSLATE_NOOP("MythControls",
01011 "Next View"), "End");
01012
01013 RegisterKey("Global", "HELP", QT_TRANSLATE_NOOP("MythControls",
01014 "Help"), "F1");
01015 RegisterKey("Global", "EJECT", QT_TRANSLATE_NOOP("MythControls"
01016 ,"Eject Removable Media"), "");
01017
01018 RegisterKey("Global", "CUT", QT_TRANSLATE_NOOP("MythControls",
01019 "Cut text from textedit"), "Ctrl+X");
01020 RegisterKey("Global", "COPY", QT_TRANSLATE_NOOP("MythControls"
01021 ,"Copy text from textedit"), "Ctrl+C");
01022 RegisterKey("Global", "PASTE", QT_TRANSLATE_NOOP("MythControls",
01023 "Paste text into textedit"), "Ctrl+V");
01024
01025 RegisterKey("Global", "0", QT_TRANSLATE_NOOP("MythControls","0"), "0");
01026 RegisterKey("Global", "1", QT_TRANSLATE_NOOP("MythControls","1"), "1");
01027 RegisterKey("Global", "2", QT_TRANSLATE_NOOP("MythControls","2"), "2");
01028 RegisterKey("Global", "3", QT_TRANSLATE_NOOP("MythControls","3"), "3");
01029 RegisterKey("Global", "4", QT_TRANSLATE_NOOP("MythControls","4"), "4");
01030 RegisterKey("Global", "5", QT_TRANSLATE_NOOP("MythControls","5"), "5");
01031 RegisterKey("Global", "6", QT_TRANSLATE_NOOP("MythControls","6"), "6");
01032 RegisterKey("Global", "7", QT_TRANSLATE_NOOP("MythControls","7"), "7");
01033 RegisterKey("Global", "8", QT_TRANSLATE_NOOP("MythControls","8"), "8");
01034 RegisterKey("Global", "9", QT_TRANSLATE_NOOP("MythControls","9"), "9");
01035
01036 RegisterKey("Global", "SYSEVENT01", QT_TRANSLATE_NOOP("MythControls",
01037 "Trigger System Key Event #1"), "");
01038 RegisterKey("Global", "SYSEVENT02", QT_TRANSLATE_NOOP("MythControls",
01039 "Trigger System Key Event #2"), "");
01040 RegisterKey("Global", "SYSEVENT03", QT_TRANSLATE_NOOP("MythControls",
01041 "Trigger System Key Event #3"), "");
01042 RegisterKey("Global", "SYSEVENT04", QT_TRANSLATE_NOOP("MythControls",
01043 "Trigger System Key Event #4"), "");
01044 RegisterKey("Global", "SYSEVENT05", QT_TRANSLATE_NOOP("MythControls",
01045 "Trigger System Key Event #5"), "");
01046 RegisterKey("Global", "SYSEVENT06", QT_TRANSLATE_NOOP("MythControls",
01047 "Trigger System Key Event #6"), "");
01048 RegisterKey("Global", "SYSEVENT07", QT_TRANSLATE_NOOP("MythControls",
01049 "Trigger System Key Event #7"), "");
01050 RegisterKey("Global", "SYSEVENT08", QT_TRANSLATE_NOOP("MythControls",
01051 "Trigger System Key Event #8"), "");
01052 RegisterKey("Global", "SYSEVENT09", QT_TRANSLATE_NOOP("MythControls",
01053 "Trigger System Key Event #9"), "");
01054 RegisterKey("Global", "SYSEVENT10", QT_TRANSLATE_NOOP("MythControls",
01055 "Trigger System Key Event #10"), "");
01056
01057
01058 RegisterKey("Browser", "ZOOMIN", QT_TRANSLATE_NOOP("MythControls",
01059 "Zoom in on browser window"), ".,>");
01060 RegisterKey("Browser", "ZOOMOUT", QT_TRANSLATE_NOOP("MythControls",
01061 "Zoom out on browser window"), ",,<");
01062 RegisterKey("Browser", "TOGGLEINPUT", QT_TRANSLATE_NOOP("MythControls",
01063 "Toggle where keyboard input goes to"), "F1");
01064
01065 RegisterKey("Browser", "MOUSEUP", QT_TRANSLATE_NOOP("MythControls",
01066 "Move mouse pointer up"), "2");
01067 RegisterKey("Browser", "MOUSEDOWN", QT_TRANSLATE_NOOP("MythControls",
01068 "Move mouse pointer down"), "8");
01069 RegisterKey("Browser", "MOUSELEFT", QT_TRANSLATE_NOOP("MythControls",
01070 "Move mouse pointer left"), "4");
01071 RegisterKey("Browser", "MOUSERIGHT", QT_TRANSLATE_NOOP("MythControls",
01072 "Move mouse pointer right"), "6");
01073 RegisterKey("Browser", "MOUSELEFTBUTTON", QT_TRANSLATE_NOOP("MythControls",
01074 "Mouse Left button click"), "5");
01075
01076 RegisterKey("Browser", "PAGEDOWN", QT_TRANSLATE_NOOP("MythControls",
01077 "Scroll down half a page"), "9");
01078 RegisterKey("Browser", "PAGEUP", QT_TRANSLATE_NOOP("MythControls",
01079 "Scroll up half a page"), "3");
01080 RegisterKey("Browser", "PAGELEFT", QT_TRANSLATE_NOOP("MythControls",
01081 "Scroll left half a page"), "7");
01082 RegisterKey("Browser", "PAGERIGHT", QT_TRANSLATE_NOOP("MythControls",
01083 "Scroll right half a page"), "1");
01084
01085 RegisterKey("Browser", "NEXTLINK", QT_TRANSLATE_NOOP("MythControls",
01086 "Move selection to next link"), "Z");
01087 RegisterKey("Browser", "PREVIOUSLINK", QT_TRANSLATE_NOOP("MythControls",
01088 "Move selection to previous link"), "Q");
01089 RegisterKey("Browser", "FOLLOWLINK", QT_TRANSLATE_NOOP("MythControls",
01090 "Follow selected link"), "Return,Space,Enter");
01091 RegisterKey("Browser", "HISTORYBACK", QT_TRANSLATE_NOOP("MythControls",
01092 "Go back to previous page"), "R,Backspace");
01093 RegisterKey("Browser", "HISTORYFORWARD", QT_TRANSLATE_NOOP("MythControls",
01094 "Go forward to previous page"), "F");
01095
01096 RegisterKey("Main Menu", "EXIT", QT_TRANSLATE_NOOP("MythControls",
01097 "System Exit"), "Esc");
01098 }
01099
01100 void MythMainWindow::ResetKeys()
01101 {
01102 ClearKeyContext("Global");
01103 ClearKeyContext("Browser");
01104 ClearKeyContext("Main Menu");
01105 InitKeys();
01106 }
01107
01108 void MythMainWindow::ReinitDone(void)
01109 {
01110 delete d->oldpainter;
01111 d->oldpainter = NULL;
01112
01113 delete d->oldpaintwin;
01114 d->oldpaintwin = NULL;
01115
01116 d->paintwin->move(0, 0);
01117 d->paintwin->setFixedSize(size());
01118 d->paintwin->raise();
01119 d->paintwin->show();
01120
01121 d->drawTimer->start(1000 / 70);
01122 }
01123
01124 void MythMainWindow::Show(void)
01125 {
01126 show();
01127 #ifdef Q_WS_MACX_OLDQT
01128 if (d->does_fill_screen)
01129 HideMenuBar();
01130 else
01131 ShowMenuBar();
01132 #endif
01133 }
01134
01135
01136 void MythMainWindow::attach(QWidget *child)
01137 {
01138 #ifdef USING_MINGW
01139 #warning TODO FIXME MythMainWindow::attach() does not always work on MS Windows!
01140
01141
01142
01143
01144 VERBOSE(VB_IMPORTANT,
01145 QString("MythMainWindow::attach old: %1, new: %2, thread: %3")
01146 .arg(currentWidget() ? currentWidget()->objectName() : "none")
01147 .arg(child->objectName())
01148 .arg(::GetCurrentThreadId()));
01149 #endif
01150 if (currentWidget())
01151 currentWidget()->setEnabled(false);
01152
01153 d->widgetList.push_back(child);
01154 child->winId();
01155 child->raise();
01156 child->setFocus();
01157 }
01158
01159 void MythMainWindow::detach(QWidget *child)
01160 {
01161 std::vector<QWidget*>::iterator it =
01162 std::find(d->widgetList.begin(), d->widgetList.end(), child);
01163
01164 if (it == d->widgetList.end())
01165 {
01166 VERBOSE(VB_IMPORTANT, "Could not find widget to detach");
01167 return;
01168 }
01169
01170 d->widgetList.erase(it);
01171 QWidget *current = currentWidget();
01172
01173 if (current)
01174 {
01175 current->setEnabled(true);
01176 current->setFocus();
01177 }
01178
01179 if (d->exitingtomain)
01180 {
01181 QCoreApplication::postEvent(
01182 this, new QEvent(MythEvent::kExitToMainMenuEventType));
01183 }
01184 }
01185
01186 QWidget *MythMainWindow::currentWidget(void)
01187 {
01188 if (d->widgetList.size() > 0)
01189 return d->widgetList.back();
01190 return NULL;
01191 }
01192
01193
01194 uint MythMainWindow::PushDrawDisabled(void)
01195 {
01196 QMutexLocker locker(&d->m_drawDisableLock);
01197 d->m_drawDisabledDepth++;
01198 if (d->m_drawDisabledDepth && d->m_drawEnabled)
01199 SetDrawEnabled(false);
01200 return d->m_drawDisabledDepth;
01201 }
01202
01203 uint MythMainWindow::PopDrawDisabled(void)
01204 {
01205 QMutexLocker locker(&d->m_drawDisableLock);
01206 if (d->m_drawDisabledDepth)
01207 {
01208 d->m_drawDisabledDepth--;
01209 if (!d->m_drawDisabledDepth && !d->m_drawEnabled)
01210 SetDrawEnabled(true);
01211 }
01212 return d->m_drawDisabledDepth;
01213 }
01214
01215 void MythMainWindow::SetDrawEnabled(bool enable)
01216 {
01217 QMutexLocker locker(&d->m_setDrawEnabledLock);
01218
01219 if (!gCoreContext->IsUIThread())
01220 {
01221 QCoreApplication::postEvent(
01222 this, new MythEvent(
01223 (enable) ?
01224 MythEvent::kEnableDrawingEventType :
01225 MythEvent::kDisableDrawingEventType));
01226
01227 while (QCoreApplication::hasPendingEvents())
01228 d->m_setDrawEnabledWait.wait(&d->m_setDrawEnabledLock);
01229
01230 return;
01231 }
01232
01233 setUpdatesEnabled(enable);
01234 d->m_drawEnabled = enable;
01235
01236 if (enable)
01237 d->drawTimer->start(1000 / 70);
01238 else
01239 d->drawTimer->stop();
01240
01241 d->m_setDrawEnabledWait.wakeAll();
01242 }
01243
01244 void MythMainWindow::SetEffectsEnabled(bool enable)
01245 {
01246 QVector<MythScreenStack *>::Iterator it;
01247 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
01248 {
01249 if (enable)
01250 (*it)->EnableEffects();
01251 else
01252 (*it)->DisableEffects();
01253 }
01254 }
01255
01256 bool MythMainWindow::IsExitingToMain(void) const
01257 {
01258 return d->exitingtomain;
01259 }
01260
01261 void MythMainWindow::ExitToMainMenu(void)
01262 {
01263 bool jumpdone = !(d->popwindows);
01264
01265 d->exitingtomain = true;
01266
01267
01268 QWidget *current = currentWidget();
01269 if (current && d->exitingtomain && d->popwindows)
01270 {
01271 if (current->objectName() != QString("mainmenu"))
01272 {
01273 if (current->objectName() == QString("video playback window"))
01274 {
01275 MythEvent *me = new MythEvent("EXIT_TO_MENU");
01276 QCoreApplication::postEvent(current, me);
01277 }
01278 else if (current->inherits("MythDialog"))
01279 {
01280 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, d->escapekey,
01281 Qt::NoModifier);
01282 QObject *key_target = getTarget(*key);
01283 QCoreApplication::postEvent(key_target, key);
01284 }
01285 return;
01286 }
01287 else
01288 jumpdone = true;
01289 }
01290
01291 MythScreenStack *toplevel = GetMainStack();
01292 if (toplevel && d->popwindows)
01293 {
01294 MythScreenType *screen = toplevel->GetTopScreen();
01295 if (screen && screen->objectName() != QString("mainmenu"))
01296 {
01297 if (screen->objectName() == QString("video playback window"))
01298 {
01299 MythEvent *me = new MythEvent("EXIT_TO_MENU");
01300 QCoreApplication::postEvent(screen, me);
01301 }
01302 else
01303 {
01304 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, d->escapekey,
01305 Qt::NoModifier);
01306 QCoreApplication::postEvent(this, key);
01307 }
01308 return;
01309 }
01310 else
01311 jumpdone = true;
01312 }
01313
01314 if (jumpdone)
01315 {
01316 d->exitingtomain = false;
01317 d->popwindows = true;
01318 if (d->exitmenucallback)
01319 {
01320 void (*callback)(void) = d->exitmenucallback;
01321 d->exitmenucallback = NULL;
01322 callback();
01323 }
01324 else if (d->exitmenumediadevicecallback)
01325 {
01326 void (*callback)(MythMediaDevice*) = d->exitmenumediadevicecallback;
01327 MythMediaDevice * mediadevice = d->mediadeviceforcallback;
01328 d->mediadeviceforcallback = NULL;
01329 callback(mediadevice);
01330 }
01331 }
01332 }
01333
01344 bool MythMainWindow::TranslateKeyPress(const QString &context,
01345 QKeyEvent *e, QStringList &actions,
01346 bool allowJumps)
01347 {
01348 actions.clear();
01349 int keynum = d->TranslateKeyNum(e);
01350
01351 QStringList localActions;
01352 if (allowJumps && (d->jumpMap.count(keynum) > 0) &&
01353 (!d->jumpMap[keynum]->localAction.isEmpty()) &&
01354 (d->keyContexts.value(context)) &&
01355 (d->keyContexts.value(context)->GetMapping(keynum, localActions)))
01356 {
01357 if (localActions.contains(d->jumpMap[keynum]->localAction))
01358 allowJumps = false;
01359 }
01360
01361 if (allowJumps && d->jumpMap.count(keynum) > 0 &&
01362 !d->jumpMap[keynum]->exittomain && d->exitmenucallback == NULL)
01363 {
01364 void (*callback)(void) = d->jumpMap[keynum]->callback;
01365 callback();
01366 return true;
01367 }
01368
01369 if (allowJumps &&
01370 d->jumpMap.count(keynum) > 0 && d->exitmenucallback == NULL)
01371 {
01372 d->exitingtomain = true;
01373 d->exitmenucallback = d->jumpMap[keynum]->callback;
01374 QCoreApplication::postEvent(
01375 this, new QEvent(MythEvent::kExitToMainMenuEventType));
01376 return true;
01377 }
01378
01379 if (d->keyContexts.value(context))
01380 d->keyContexts.value(context)->GetMapping(keynum, actions);
01381
01382 if (context != "Global")
01383 d->keyContexts.value("Global")->GetMapping(keynum, actions);
01384
01385 return false;
01386 }
01387
01388 void MythMainWindow::ClearKey(const QString &context, const QString &action)
01389 {
01390 KeyContext * keycontext = d->keyContexts.value(context);
01391 if (keycontext == NULL) return;
01392
01393 QMutableMapIterator<int, QStringList> it(keycontext->actionMap);
01394 while (it.hasNext())
01395 {
01396 it.next();
01397 QStringList list = it.value();
01398
01399 list.removeAll(action);
01400 if (list.isEmpty())
01401 it.remove();
01402 }
01403 }
01404
01405 void MythMainWindow::ClearKeyContext(const QString &context)
01406 {
01407 KeyContext *keycontext = d->keyContexts.value(context);
01408 if (keycontext != NULL)
01409 keycontext->actionMap.clear();
01410 }
01411
01412 void MythMainWindow::BindKey(const QString &context, const QString &action,
01413 const QString &key)
01414 {
01415 QKeySequence keyseq(key);
01416
01417 if (!d->keyContexts.contains(context))
01418 d->keyContexts.insert(context, new KeyContext());
01419
01420 for (unsigned int i = 0; i < keyseq.count(); i++)
01421 {
01422 int keynum = keyseq[i];
01423 keynum &= ~Qt::UNICODE_ACCEL;
01424
01425 QStringList dummyaction("");
01426 if (d->keyContexts.value(context)->GetMapping(keynum, dummyaction))
01427 {
01428 VERBOSE(VB_GENERAL, QString("Key %1 is bound to multiple actions "
01429 "in context %2.")
01430 .arg(key).arg(context));
01431 }
01432
01433 d->keyContexts.value(context)->AddMapping(keynum, action);
01434
01435
01436
01437
01438 if (action == "ESCAPE" && context == "Global" && i == 0)
01439 d->escapekey = keynum;
01440 }
01441 }
01442
01443 void MythMainWindow::RegisterKey(const QString &context, const QString &action,
01444 const QString &description, const QString &key)
01445 {
01446 QString keybind = key;
01447
01448 MSqlQuery query(MSqlQuery::InitCon());
01449
01450 if (d->m_useDB && query.isConnected())
01451 {
01452 query.prepare("SELECT keylist, description FROM keybindings WHERE "
01453 "context = :CONTEXT AND action = :ACTION AND "
01454 "hostname = :HOSTNAME ;");
01455 query.bindValue(":CONTEXT", context);
01456 query.bindValue(":ACTION", action);
01457 query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
01458
01459 if (query.exec() && query.next())
01460 {
01461 keybind = query.value(0).toString();
01462 QString db_description = query.value(1).toString();
01463
01464
01465 if (db_description != description)
01466 {
01467 VERBOSE(VB_IMPORTANT, "Updating keybinding description...");
01468 query.prepare(
01469 "UPDATE keybindings "
01470 "SET description = :DESCRIPTION "
01471 "WHERE context = :CONTEXT AND "
01472 " action = :ACTION AND "
01473 " hostname = :HOSTNAME");
01474
01475 query.bindValue(":DESCRIPTION", description);
01476 query.bindValue(":CONTEXT", context);
01477 query.bindValue(":ACTION", action);
01478 query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
01479
01480 if (!query.exec() && !(GetMythDB()->SuppressDBMessages()))
01481 {
01482 MythDB::DBError("Update Keybinding", query);
01483 }
01484 }
01485 }
01486 else
01487 {
01488 QString inskey = keybind;
01489
01490 query.prepare("INSERT INTO keybindings (context, action, "
01491 "description, keylist, hostname) VALUES "
01492 "( :CONTEXT, :ACTION, :DESCRIPTION, :KEYLIST, "
01493 ":HOSTNAME );");
01494 query.bindValue(":CONTEXT", context);
01495 query.bindValue(":ACTION", action);
01496 query.bindValue(":DESCRIPTION", description);
01497 query.bindValue(":KEYLIST", inskey);
01498 query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
01499
01500 if (!query.exec() && !(GetMythDB()->SuppressDBMessages()))
01501 {
01502 MythDB::DBError("Insert Keybinding", query);
01503 }
01504 }
01505 }
01506
01507 BindKey(context, action, keybind);
01508 }
01509
01510 QString MythMainWindow::GetKey(const QString &context,
01511 const QString &action) const
01512 {
01513 MSqlQuery query(MSqlQuery::InitCon());
01514 if (!query.isConnected())
01515 return "?";
01516
01517 query.prepare("SELECT keylist "
01518 "FROM keybindings "
01519 "WHERE context = :CONTEXT AND "
01520 " action = :ACTION AND "
01521 " hostname = :HOSTNAME");
01522 query.bindValue(":CONTEXT", context);
01523 query.bindValue(":ACTION", action);
01524 query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
01525
01526 if (!query.exec() || !query.isActive() || !query.next())
01527 return "?";
01528
01529 return query.value(0).toString();
01530 }
01531
01532 void MythMainWindow::ClearJump(const QString &destination)
01533 {
01534
01535 if (d->destinationMap.find(destination) == d->destinationMap.end())
01536 {
01537 VERBOSE(VB_GENERAL, "Cannot clear ficticious jump point"+destination);
01538 return;
01539 }
01540
01541 QMutableMapIterator<int, JumpData*> it(d->jumpMap);
01542 while (it.hasNext())
01543 {
01544 it.next();
01545 JumpData *jd = it.value();
01546 if (jd->destination == destination)
01547 it.remove();
01548 }
01549 }
01550
01551
01552 void MythMainWindow::BindJump(const QString &destination, const QString &key)
01553 {
01554
01555 if (d->destinationMap.find(destination) == d->destinationMap.end())
01556 {
01557 VERBOSE(VB_GENERAL,"Cannot bind to ficticious jump point"+destination);
01558 return;
01559 }
01560
01561 QKeySequence keyseq(key);
01562
01563 for (unsigned int i = 0; i < keyseq.count(); i++)
01564 {
01565 int keynum = keyseq[i];
01566 keynum &= ~Qt::UNICODE_ACCEL;
01567
01568 if (d->jumpMap.count(keynum) == 0)
01569 {
01570
01571
01572
01573 d->jumpMap[keynum] = &d->destinationMap[destination];
01574 }
01575 else
01576 {
01577 VERBOSE(VB_GENERAL, QString("Key %1 is already bound to a jump "
01578 "point.").arg(key));
01579 }
01580 }
01581
01582
01583
01584
01585 }
01586
01587 void MythMainWindow::RegisterJump(const QString &destination,
01588 const QString &description,
01589 const QString &key, void (*callback)(void),
01590 bool exittomain, QString localAction)
01591 {
01592 QString keybind = key;
01593
01594 MSqlQuery query(MSqlQuery::InitCon());
01595 if (query.isConnected())
01596 {
01597 query.prepare("SELECT keylist FROM jumppoints WHERE "
01598 "destination = :DEST and hostname = :HOST ;");
01599 query.bindValue(":DEST", destination);
01600 query.bindValue(":HOST", GetMythDB()->GetHostName());
01601
01602 if (query.exec() && query.next())
01603 {
01604 keybind = query.value(0).toString();
01605 }
01606 else
01607 {
01608 QString inskey = keybind;
01609
01610 query.prepare("INSERT INTO jumppoints (destination, description, "
01611 "keylist, hostname) VALUES ( :DEST, :DESC, :KEYLIST, "
01612 ":HOST );");
01613 query.bindValue(":DEST", destination);
01614 query.bindValue(":DESC", description);
01615 query.bindValue(":KEYLIST", inskey);
01616 query.bindValue(":HOST", GetMythDB()->GetHostName());
01617
01618 if (!query.exec() || !query.isActive())
01619 {
01620 MythDB::DBError("Insert Jump Point", query);
01621 }
01622 }
01623 }
01624
01625 JumpData jd =
01626 { callback, destination, description, exittomain, localAction };
01627 d->destinationMap[destination] = jd;
01628
01629 BindJump(destination, keybind);
01630 }
01631
01632 void MythMainWindow::JumpTo(const QString& destination, bool pop)
01633 {
01634 if (destination == "ScreenShot")
01635 screenShot();
01636 else if (d->destinationMap.count(destination) > 0 && d->exitmenucallback == NULL)
01637 {
01638 d->exitingtomain = true;
01639 d->popwindows = pop;
01640 d->exitmenucallback = d->destinationMap[destination].callback;
01641 QCoreApplication::postEvent(
01642 this, new QEvent(MythEvent::kExitToMainMenuEventType));
01643 return;
01644 }
01645 }
01646
01647 bool MythMainWindow::DestinationExists(const QString& destination) const
01648 {
01649 return (d->destinationMap.count(destination) > 0) ? true : false;
01650 }
01651
01652 void MythMainWindow::RegisterMediaPlugin(const QString &name,
01653 const QString &desc,
01654 MediaPlayCallback fn)
01655 {
01656 if (d->mediaPluginMap.count(name) == 0)
01657 {
01658 VERBOSE(VB_GENERAL, QString("Registering %1 as a media playback "
01659 "plugin.").arg(name));
01660 MPData mpd = {desc, fn};
01661 d->mediaPluginMap[name] = mpd;
01662 }
01663 else
01664 {
01665 VERBOSE(VB_GENERAL, QString("%1 is already registered as a media "
01666 "playback plugin.").arg(name));
01667 }
01668 }
01669
01670 bool MythMainWindow::HandleMedia(const QString &handler, const QString &mrl,
01671 const QString &plot, const QString &title,
01672 const QString &subtitle,
01673 const QString &director, int season,
01674 int episode, int lenMins,
01675 const QString &year)
01676 {
01677 QString lhandler(handler);
01678 if (lhandler.isEmpty())
01679 lhandler = "Internal";
01680
01681
01682 if (d->mediaPluginMap.count(lhandler))
01683 {
01684 d->mediaPluginMap[lhandler].playFn(mrl, plot, title, subtitle,
01685 director, season, episode, lenMins,
01686 year);
01687 return true;
01688 }
01689
01690 return false;
01691 }
01692
01693 void MythMainWindow::AllowInput(bool allow)
01694 {
01695 d->AllowInput = allow;
01696 }
01697
01698 void MythMainWindow::mouseTimeout(void)
01699 {
01700 MythGestureEvent *e;
01701
01702
01703 if (d->gesture.recording())
01704 {
01705 d->gesture.stop();
01706 }
01707
01708
01709 e = d->gesture.gesture();
01710
01711 if (e->gesture() < MythGestureEvent::Click)
01712 QCoreApplication::postEvent(this, e);
01713 }
01714
01715 bool MythMainWindow::eventFilter(QObject *, QEvent *e)
01716 {
01717 MythGestureEvent *ge;
01718
01719
01720 if (!d->AllowInput)
01721 return true;
01722
01723 switch (e->type())
01724 {
01725 case QEvent::KeyPress:
01726 {
01727 QKeyEvent *ke = dynamic_cast<QKeyEvent*>(e);
01728
01729
01730 if (!ke)
01731 ke = static_cast<QKeyEvent *>(e);
01732
01733 if (currentWidget())
01734 {
01735 ke->accept();
01736 QWidget *current = currentWidget();
01737 if (current && current->isEnabled())
01738 qApp->notify(current, ke);
01739
01740 break;
01741 }
01742
01743 QVector<MythScreenStack *>::Iterator it;
01744 for (it = d->stackList.end()-1; it != d->stackList.begin()-1; --it)
01745 {
01746 MythScreenType *top = (*it)->GetTopScreen();
01747 if (top)
01748 {
01749 if (top->keyPressEvent(ke))
01750 return true;
01751
01752
01753
01754 if ((*it)->objectName() == "popup stack")
01755 break;
01756 }
01757 }
01758 break;
01759 }
01760 case QEvent::MouseButtonPress:
01761 {
01762 if (!d->gesture.recording())
01763 {
01764 d->gesture.start();
01765 d->gesture.record(dynamic_cast<QMouseEvent*>(e)->pos());
01766
01767
01768 d->gestureTimer->start(GESTURE_TIMEOUT);
01769
01770 return true;
01771 }
01772 break;
01773 }
01774 case QEvent::MouseButtonRelease:
01775 {
01776 if (d->gestureTimer->isActive())
01777 d->gestureTimer->stop();
01778
01779 if (currentWidget())
01780 break;
01781
01782 if (d->gesture.recording())
01783 {
01784 d->gesture.stop();
01785 ge = d->gesture.gesture();
01786
01787
01788 if (ge->gesture() == MythGestureEvent::Click)
01789 {
01790 QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(e);
01791 if (!mouseEvent)
01792 return false;
01793
01794 QVector<MythScreenStack *>::iterator it;
01795 QPoint p = mouseEvent->pos();
01796
01797 ge->SetPosition(p);
01798
01799 MythGestureEvent::Button button = MythGestureEvent::NoButton;
01800 switch (mouseEvent->button())
01801 {
01802 case Qt::LeftButton :
01803 button = MythGestureEvent::LeftButton;
01804 break;
01805 case Qt::RightButton :
01806 button = MythGestureEvent::RightButton;
01807 break;
01808 case Qt::MidButton :
01809 button = MythGestureEvent::MiddleButton;
01810 break;
01811 case Qt::XButton1 :
01812 button = MythGestureEvent::Aux1Button;
01813 break;
01814 case Qt::XButton2 :
01815 button = MythGestureEvent::Aux2Button;
01816 break;
01817 default :
01818 button = MythGestureEvent::NoButton;
01819 }
01820
01821 ge->SetButton(button);
01822
01823 for (it = d->stackList.end()-1; it != d->stackList.begin()-1;
01824 --it)
01825 {
01826 MythScreenType *screen = (*it)->GetTopScreen();
01827
01828 if (!screen || !screen->ContainsPoint(p))
01829 continue;
01830
01831 if (screen->gestureEvent(ge))
01832 break;
01833
01834
01835
01836
01837
01838
01839
01840
01841 if ((*it)->objectName() == "popup stack")
01842 break;
01843 }
01844
01845 delete ge;
01846 }
01847 else
01848 QCoreApplication::postEvent(this, ge);
01849
01850 return true;
01851 }
01852 break;
01853 }
01854 case QEvent::MouseMove:
01855 {
01856 if (d->gesture.recording())
01857 {
01858
01859 d->gestureTimer->stop();
01860 d->gestureTimer->start(GESTURE_TIMEOUT);
01861
01862 d->gesture.record(dynamic_cast<QMouseEvent*>(e)->pos());
01863 return true;
01864 }
01865 break;
01866 }
01867 case QEvent::Wheel:
01868 {
01869 QWheelEvent* qmw = dynamic_cast<QWheelEvent*>(e);
01870 int delta = qmw->delta();
01871 if (delta>0)
01872 {
01873 qmw->accept();
01874 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up,
01875 Qt::NoModifier);
01876 QObject *key_target = getTarget(*key);
01877 if (!key_target)
01878 QCoreApplication::postEvent(this, key);
01879 else
01880 QCoreApplication::postEvent(key_target, key);
01881 }
01882 if (delta<0)
01883 {
01884 qmw->accept();
01885 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down,
01886 Qt::NoModifier);
01887 QObject *key_target = getTarget(*key);
01888 if (!key_target)
01889 QCoreApplication::postEvent(this, key);
01890 else
01891 QCoreApplication::postEvent(key_target, key);
01892 }
01893 break;
01894 }
01895 default:
01896 break;
01897 }
01898
01899 return false;
01900 }
01901
01902 void MythMainWindow::customEvent(QEvent *ce)
01903 {
01904 if (ce->type() == MythGestureEvent::kEventType)
01905 {
01906 MythGestureEvent *ge = static_cast<MythGestureEvent*>(ce);
01907 MythScreenStack *toplevel = GetMainStack();
01908 if (toplevel && !currentWidget())
01909 {
01910 MythScreenType *screen = toplevel->GetTopScreen();
01911 if (screen)
01912 screen->gestureEvent(ge);
01913 }
01914 VERBOSE(VB_IMPORTANT, QString("Gesture: %1")
01915 .arg(QString(*ge).toLocal8Bit().constData()));
01916 }
01917 else if (ce->type() == MythEvent::kExitToMainMenuEventType &&
01918 d->exitingtomain)
01919 {
01920 ExitToMainMenu();
01921 }
01922 else if (ce->type() == ExternalKeycodeEvent::kEventType)
01923 {
01924 ExternalKeycodeEvent *eke = static_cast<ExternalKeycodeEvent *>(ce);
01925 int keycode = eke->getKeycode();
01926
01927 QKeyEvent key(QEvent::KeyPress, keycode, Qt::NoModifier);
01928
01929 QObject *key_target = getTarget(key);
01930 if (!key_target)
01931 QCoreApplication::sendEvent(this, &key);
01932 else
01933 QCoreApplication::sendEvent(key_target, &key);
01934 }
01935 #if defined(USE_LIRC) || defined(USING_APPLEREMOTE)
01936 else if (ce->type() == LircKeycodeEvent::kEventType &&
01937 !d->ignore_lirc_keys)
01938 {
01939 LircKeycodeEvent *lke = static_cast<LircKeycodeEvent *>(ce);
01940
01941 if (LircKeycodeEvent::kLIRCInvalidKeyCombo == lke->modifiers())
01942 {
01943 VERBOSE(VB_IMPORTANT, QString("MythMainWindow, Warning: ") +
01944 QString("Attempt to convert LIRC key sequence '%1' "
01945 "to a Qt key sequence failed.")
01946 .arg(lke->lirctext()));
01947 }
01948 else
01949 {
01950 GetMythUI()->ResetScreensaver();
01951 if (GetMythUI()->GetScreenIsAsleep())
01952 return;
01953
01954 QKeyEvent key(lke->keytype(), lke->key(),
01955 lke->modifiers(), lke->text());
01956
01957 QObject *key_target = getTarget(key);
01958 if (!key_target)
01959 QCoreApplication::sendEvent(this, &key);
01960 else
01961 QCoreApplication::sendEvent(key_target, &key);
01962 }
01963 }
01964 #endif
01965 #ifdef USE_JOYSTICK_MENU
01966 else if (ce->type() == JoystickKeycodeEvent::kEventType &&
01967 !d->ignore_joystick_keys)
01968 {
01969 JoystickKeycodeEvent *jke = static_cast<JoystickKeycodeEvent *>(ce);
01970 int keycode = jke->getKeycode();
01971
01972 if (keycode)
01973 {
01974 GetMythUI()->ResetScreensaver();
01975 if (GetMythUI()->GetScreenIsAsleep())
01976 return;
01977
01978 Qt::KeyboardModifiers mod = Qt::KeyboardModifiers(keycode & Qt::MODIFIER_MASK);
01979 int k = (keycode & ~Qt::MODIFIER_MASK);
01980 QString text;
01981
01982 if (k & Qt::UNICODE_ACCEL)
01983 {
01984 QChar c(k & ~Qt::UNICODE_ACCEL);
01985 text = QString(c);
01986 }
01987
01988 QKeyEvent key(jke->isKeyDown() ? QEvent::KeyPress :
01989 QEvent::KeyRelease, k, mod, text);
01990
01991 QObject *key_target = getTarget(key);
01992 if (!key_target)
01993 QCoreApplication::sendEvent(this, &key);
01994 else
01995 QCoreApplication::sendEvent(key_target, &key);
01996 }
01997 else
01998 {
01999 VERBOSE(VB_IMPORTANT,
02000 QString("JoystickMenuClient warning: attempt to convert "
02001 "'%1' to a key sequence failed. Fix your key "
02002 "mappings.")
02003 .arg(jke->getJoystickMenuText().toLocal8Bit().constData()));
02004 }
02005 }
02006 #endif
02007 else if (ce->type() == ScreenSaverEvent::kEventType)
02008 {
02009 ScreenSaverEvent *sse = static_cast<ScreenSaverEvent *>(ce);
02010 switch (sse->getSSEventType())
02011 {
02012 case ScreenSaverEvent::ssetDisable:
02013 {
02014 GetMythUI()->DoDisableScreensaver();
02015 break;
02016 }
02017 case ScreenSaverEvent::ssetRestore:
02018 {
02019 GetMythUI()->DoRestoreScreensaver();
02020 break;
02021 }
02022 case ScreenSaverEvent::ssetReset:
02023 {
02024 GetMythUI()->DoResetScreensaver();
02025 break;
02026 }
02027 default:
02028 {
02029 VERBOSE(VB_IMPORTANT,
02030 QString("Unknown ScreenSaverEvent type: %1")
02031 .arg(sse->getSSEventType()));
02032 }
02033 }
02034 }
02035 else if (ce->type() == MythEvent::kPushDisableDrawingEventType)
02036 {
02037 PushDrawDisabled();
02038 }
02039 else if (ce->type() == MythEvent::kPopDisableDrawingEventType)
02040 {
02041 PopDrawDisabled();
02042 }
02043 else if (ce->type() == MythEvent::kDisableDrawingEventType)
02044 {
02045 SetDrawEnabled(false);
02046 }
02047 else if (ce->type() == MythEvent::kEnableDrawingEventType)
02048 {
02049 SetDrawEnabled(true);
02050 }
02051 else if (ce->type() == MythEvent::kLockInputDevicesEventType)
02052 {
02053 LockInputDevices(true);
02054 }
02055 else if (ce->type() == MythEvent::kUnlockInputDevicesEventType)
02056 {
02057 LockInputDevices(false);
02058 }
02059 else if ((MythEvent::Type)(ce->type()) == MythEvent::MythEventMessage)
02060 {
02061 MythEvent *me = (MythEvent *)ce;
02062 QString message = me->Message();
02063
02064 if (message.left(12) == "HANDLE_MEDIA")
02065 {
02066 QStringList tokens = message.split(' ', QString::SkipEmptyParts);
02067 HandleMedia(tokens[1],
02068 message.mid(tokens[0].length() +
02069 tokens[1].length() + 2));
02070 }
02071 }
02072 }
02073
02074 QObject *MythMainWindow::getTarget(QKeyEvent &key)
02075 {
02076 QObject *key_target = NULL;
02077
02078 if (!currentWidget())
02079 return key_target;
02080
02081 key_target = QWidget::keyboardGrabber();
02082
02083 if (!key_target)
02084 {
02085 QWidget *focus_widget = qApp->focusWidget();
02086 if (focus_widget && focus_widget->isEnabled())
02087 {
02088 key_target = focus_widget;
02089
02090
02091
02092 if (key.key() == d->escapekey && focus_widget->topLevelWidget())
02093 key_target = focus_widget->topLevelWidget();
02094 }
02095 }
02096
02097 if (!key_target)
02098 key_target = this;
02099
02100 return key_target;
02101 }
02102
02103 int MythMainWindow::NormalizeFontSize(int pointSize)
02104 {
02105 float floatSize = pointSize;
02106 float desired = 100.0;
02107
02108 #ifdef USING_MINGW
02109
02110 int logicalDpiY = 100;
02111 HDC hdc = GetDC(NULL);
02112 if (hdc)
02113 {
02114 logicalDpiY = GetDeviceCaps(hdc, LOGPIXELSY);
02115 ReleaseDC(NULL, hdc);
02116 }
02117 #else
02118 int logicalDpiY = this->logicalDpiY();
02119 #endif
02120
02121
02122 floatSize = floatSize * desired / logicalDpiY;
02123
02124 floatSize = floatSize * d->hmult;
02125
02126 pointSize = (int)(floatSize + 0.5);
02127
02128 return pointSize;
02129 }
02130
02131 MythRect MythMainWindow::NormRect(const MythRect &rect)
02132 {
02133 MythRect ret;
02134 ret.setWidth((int)(rect.width() * d->wmult));
02135 ret.setHeight((int)(rect.height() * d->hmult));
02136 ret.moveTopLeft(QPoint((int)(rect.x() * d->wmult),
02137 (int)(rect.y() * d->hmult)));
02138 ret = ret.normalized();
02139
02140 return ret;
02141 }
02142
02143 QPoint MythMainWindow::NormPoint(const QPoint &point)
02144 {
02145 QPoint ret;
02146 ret.setX((int)(point.x() * d->wmult));
02147 ret.setY((int)(point.y() * d->hmult));
02148
02149 return ret;
02150 }
02151
02152 QSize MythMainWindow::NormSize(const QSize &size)
02153 {
02154 QSize ret;
02155 ret.setWidth((int)(size.width() * d->wmult));
02156 ret.setHeight((int)(size.height() * d->hmult));
02157
02158 return ret;
02159 }
02160
02161 int MythMainWindow::NormX(const int x)
02162 {
02163 return (int)(x * d->wmult);
02164 }
02165
02166 int MythMainWindow::NormY(const int y)
02167 {
02168 return (int)(y * d->hmult);
02169 }
02170
02171 void MythMainWindow::SetScalingFactors(float wmult, float hmult)
02172 {
02173 d->wmult = wmult;
02174 d->hmult = hmult;
02175 }
02176
02177 QRect MythMainWindow::GetUIScreenRect(void)
02178 {
02179 return d->uiScreenRect;
02180 }
02181
02182 void MythMainWindow::SetUIScreenRect(QRect &rect)
02183 {
02184 d->uiScreenRect = rect;
02185 }
02186
02187 void MythMainWindow::StartLIRC(void)
02188 {
02189 #ifdef USE_LIRC
02190 if (d->lircThread)
02191 {
02192 d->lircThread->deleteLater();
02193 d->lircThread = NULL;
02194 }
02195
02196 QString config_file = GetConfDir() + "/lircrc";
02197 if (!QFile::exists(config_file))
02198 config_file = QDir::homePath() + "/.lircrc";
02199
02200
02201 QString lirc_socket = "/dev/lircd";
02202 if (!QFile::exists(lirc_socket))
02203 lirc_socket = "/var/run/lirc/lircd";
02204
02205 d->lircThread = new LIRC(
02206 this,
02207 GetMythDB()->GetSetting("LircSocket", lirc_socket),
02208 "mythtv", config_file,
02209 GetMythDB()->GetSetting("LircKeyPressedApp", ""));
02210
02211 if (d->lircThread->Init())
02212 {
02213 d->lircThread->start();
02214 }
02215 else
02216 {
02217 d->lircThread->deleteLater();
02218 d->lircThread = NULL;
02219 }
02220 #endif
02221 }
02222
02223 void MythMainWindow::LockInputDevices( bool locked )
02224 {
02225 if( locked )
02226 VERBOSE(VB_IMPORTANT, "Locking input devices");
02227 else
02228 VERBOSE(VB_IMPORTANT, "Unlocking input devices");
02229
02230 #ifdef USE_LIRC
02231 d->ignore_lirc_keys = locked;
02232 #endif
02233
02234 #ifdef USE_JOYSTICK_MENU
02235 d->ignore_joystick_keys = locked;
02236 #endif
02237 }
02238
02239