Ticket #10053: mythinputevent-2011-10-18.diff
| File mythinputevent-2011-10-18.diff, 21.9 KB (added by Xavier Hervy <xavier.hervy@…>, 19 months ago) |
|---|
-
mythtv/libs/libmythui/libmythui.pro
diff --git a/mythtv/libs/libmythui/libmythui.pro b/mythtv/libs/libmythui/libmythui.pro index 32b839e..869fdba 100644
a b HEADERS += mythgenerictree.h mythuibuttontree.h mythuiutils.h 30 30 HEADERS += mythvirtualkeyboard.h mythuishape.h mythuiguidegrid.h 31 31 HEADERS += mythrender_base.h mythfontmanager.h mythuieditbar.h 32 32 HEADERS += mythdisplay.h mythuivideo.h mythudplistener.h 33 HEADERS += mythuiexp.h 33 HEADERS += mythuiexp.h mythinputmanager.h mythinputevent.h 34 34 35 35 SOURCES = mythmainwindow.cpp mythpainter.cpp mythimage.cpp mythrect.cpp 36 36 SOURCES += myththemebase.cpp mythpainter_qimage.cpp mythpainter_yuva.cpp … … SOURCES += themeinfo.cpp mythxdisplay.cpp DisplayRes.cpp DisplayResScreen.cpp 47 47 SOURCES += mythgenerictree.cpp mythuibuttontree.cpp mythuiutils.cpp 48 48 SOURCES += mythvirtualkeyboard.cpp mythuishape.cpp mythuiguidegrid.cpp 49 49 SOURCES += mythfontmanager.cpp mythuieditbar.cpp 50 SOURCES += mythdisplay.cpp mythuivideo.cpp mythudplistener.cpp 50 SOURCES += mythdisplay.cpp mythuivideo.cpp mythudplistener.cpp mythinputevent.cpp 51 51 52 52 53 53 inc.path = $${PREFIX}/include/mythtv/libmythui/ … … inc.files += mythuiprogressbar.h mythuiwebbrowser.h mythuiutils.h 64 64 inc.files += x11colors.h mythgenerictree.h mythuibuttontree.h 65 65 inc.files += mythvirtualkeyboard.h mythuishape.h mythuiguidegrid.h 66 66 inc.files += mythuieditbar.h mythuifilebrowser.h mythuivideo.h 67 inc.files += mythuiexp.h mythuiactions.h 67 inc.files += mythuiexp.h mythuiactions.h mythinputevent.h 68 68 69 69 INSTALLS += inc 70 70 -
mythtv/libs/libmythui/lirc.cpp
diff --git a/mythtv/libs/libmythui/lirc.cpp b/mythtv/libs/libmythui/lirc.cpp index aa9b6e0..057ff90 100644
a b using namespace std; 22 22 #include "mythdb.h" 23 23 #include "mythsystem.h" 24 24 #include "lircevent.h" 25 #include "mythinputevent.h" 25 26 #include "lirc_client.h" 26 27 27 28 #include <sys/types.h> … … bool LIRC::Init(void) 297 298 LOG(vtype, LOG_ERR, LOC + 298 299 QString("Failed to read config file '%1'").arg(configFile)); 299 300 300 lirc_deinit(d->lircState);301 /*lirc_deinit(d->lircState); 301 302 d->lircState = NULL; 302 return false; 303 return false;*/ 304 return true; 303 305 } 304 306 } 305 307 … … bool LIRC::IsDoRunSet(void) const 330 332 return doRun; 331 333 } 332 334 335 /** 336 * Send a MythInoutEvent from date 337 * use when no .lircrc found or config can not be converted to QKeyEvnt 338 */ 339 void LIRC::processData(const QByteArray &data) 340 { 341 QString remoteName; 342 QString buttonName; 343 QString code(data); 344 QStringList codes = code.split(" "); 345 if (codes.size() == 4) 346 { 347 buttonName=QString(codes.at(2)); 348 remoteName=QString(codes.at(3)); 349 LOG(VB_GENERAL, LOG_ERR, QString("lircd: %1 %2") 350 .arg(buttonName).arg(remoteName)); 351 MythInputEvent * event = new MythInputEvent("lirc", remoteName, buttonName); 352 QCoreApplication::postEvent(m_mainWindow, event); 353 } 354 } 355 333 356 void LIRC::Process(const QByteArray &data) 334 357 { 335 358 QMutexLocker static_lock(&lirclib_lock); 336 359 337 // lirc_code2char will make code point to a static datafer.. 338 char *code = NULL; 339 int ret = lirc_code2char( 340 d->lircState, d->lircConfig, const_cast<char*>(data.constData()), &code); 341 342 while ((0 == ret) && code) 360 if (d->lircConfig) 343 361 { 344 QString lirctext(code); 345 QString qtcode = code; 346 qtcode.replace("ctrl-", "ctrl+", Qt::CaseInsensitive); 347 qtcode.replace("alt-", "alt+", Qt::CaseInsensitive); 348 qtcode.replace("shift-", "shift+", Qt::CaseInsensitive); 349 qtcode.replace("meta-", "meta+", Qt::CaseInsensitive); 350 QKeySequence a(qtcode); 351 352 // Send a dummy keycode if we couldn't convert the key sequence. 353 // This is done so the main code can output a warning for bad 354 // mappings. 355 if (!a.count()) 356 { 357 QCoreApplication::postEvent( 358 m_mainWindow, new LircKeycodeEvent( 359 QEvent::KeyPress, 0, 360 (Qt::KeyboardModifiers) 361 LircKeycodeEvent::kLIRCInvalidKeyCombo, 362 QString(), lirctext)); 363 } 362 // lirc_code2char will make code point to a static datafer.. 363 char *code = NULL; 364 int ret = lirc_code2char( 365 d->lircState, d->lircConfig, const_cast<char*>(data.constData()), &code); 364 366 365 vector<LircKeycodeEvent*> keyReleases; 366 for (unsigned int i = 0; i < a.count(); i++) 367 LOG(VB_GENERAL, LOG_ERR, QString("lircd: ret %1") 368 .arg(ret)); 369 370 while ((0 == ret) && code) 367 371 { 368 int keycode = a[i]; 369 Qt::KeyboardModifiers mod = Qt::NoModifier; 370 mod |= (Qt::SHIFT & keycode) ? Qt::ShiftModifier : Qt::NoModifier; 371 mod |= (Qt::META & keycode) ? Qt::MetaModifier : Qt::NoModifier; 372 mod |= (Qt::CTRL & keycode) ? Qt::ControlModifier: Qt::NoModifier; 373 mod |= (Qt::ALT & keycode) ? Qt::AltModifier : Qt::NoModifier; 374 375 keycode &= ~Qt::MODIFIER_MASK; 376 377 QString text = ""; 378 if (!mod) 379 text = QString(QChar(keycode)); 380 381 QCoreApplication::postEvent( 382 m_mainWindow, new LircKeycodeEvent( 383 QEvent::KeyPress, keycode, mod, text, lirctext)); 384 385 keyReleases.push_back( 386 new LircKeycodeEvent( 387 QEvent::KeyRelease, keycode, mod, text, lirctext)); 388 } 372 QString lirctext(code); 373 QString qtcode = code; 374 qtcode.replace("ctrl-", "ctrl+", Qt::CaseInsensitive); 375 qtcode.replace("alt-", "alt+", Qt::CaseInsensitive); 376 qtcode.replace("shift-", "shift+", Qt::CaseInsensitive); 377 qtcode.replace("meta-", "meta+", Qt::CaseInsensitive); 378 QKeySequence a(qtcode); 379 380 LOG(VB_GENERAL, LOG_ERR, QString("lircd: %1") 381 .arg(code)); 382 383 // Send a dummy keycode if we couldn't convert the key sequence. 384 // This is done so the main code can output a warning for bad 385 // mappings. 386 if (!a.count()) 387 { 388 LOG(VB_GENERAL, LOG_ERR, QString("lircd: dummy code %1") 389 .arg(QString(data))); 390 processData(data); 391 /*QCoreApplication::postEvent( 392 m_mainWindow, new LircKeycodeEvent( 393 QEvent::KeyPress, 0, 394 (Qt::KeyboardModifiers) 395 LircKeycodeEvent::kLIRCInvalidKeyCombo, 396 QString(), lirctext));*/ 397 } 398 399 vector<LircKeycodeEvent*> keyReleases; 400 for (unsigned int i = 0; i < a.count(); i++) 401 { 402 int keycode = a[i]; 403 Qt::KeyboardModifiers mod = Qt::NoModifier; 404 mod |= (Qt::SHIFT & keycode) ? Qt::ShiftModifier : Qt::NoModifier; 405 mod |= (Qt::META & keycode) ? Qt::MetaModifier : Qt::NoModifier; 406 mod |= (Qt::CTRL & keycode) ? Qt::ControlModifier: Qt::NoModifier; 407 mod |= (Qt::ALT & keycode) ? Qt::AltModifier : Qt::NoModifier; 408 409 keycode &= ~Qt::MODIFIER_MASK; 410 411 QString text = ""; 412 if (!mod) 413 text = QString(QChar(keycode)); 414 415 QCoreApplication::postEvent( 416 m_mainWindow, new LircKeycodeEvent( 417 QEvent::KeyPress, keycode, mod, text, lirctext)); 418 419 keyReleases.push_back( 420 new LircKeycodeEvent( 421 QEvent::KeyRelease, keycode, mod, text, lirctext)); 422 } 389 423 390 for (int i = (int)keyReleases.size() - 1; i>=0; i--)391 QCoreApplication::postEvent(m_mainWindow, keyReleases[i]);424 for (int i = (int)keyReleases.size() - 1; i>=0; i--) 425 QCoreApplication::postEvent(m_mainWindow, keyReleases[i]); 392 426 393 ret = lirc_code2char( 394 d->lircState, d->lircConfig, const_cast<char*>(data.constData()), &code); 427 ret = lirc_code2char( 428 d->lircState, d->lircConfig, const_cast<char*>(data.constData()), &code); 429 } 430 } 431 else 432 { 433 processData(data); 395 434 } 396 435 } 397 436 -
mythtv/libs/libmythui/lirc.h
diff --git a/mythtv/libs/libmythui/lirc.h b/mythtv/libs/libmythui/lirc.h index a75d1a4..f44d703 100644
a b class LIRC : public QObject, public MThread 42 42 virtual void run(void); 43 43 QList<QByteArray> GetCodes(void); 44 44 void Process(const QByteArray &data); 45 void processData(const QByteArray &data); 45 46 46 47 mutable QMutex lock; 47 48 static QMutex lirclib_lock; -
mythtv/libs/libmythui/mythmainwindow.cpp
diff --git a/mythtv/libs/libmythui/mythmainwindow.cpp b/mythtv/libs/libmythui/mythmainwindow.cpp index e69e4fd..2e4fc37 100644
a b using namespace std; 52 52 #include "lircevent.h" 53 53 #include "mythudplistener.h" 54 54 #include "mythrender_base.h" 55 #include "mythinputmanager.h" 55 56 56 57 #ifdef USING_APPLEREMOTE 57 58 #include "AppleRemoteListener.h" … … struct MPData { 115 116 MediaPlayCallback playFn; 116 117 }; 117 118 119 120 class ButtonMapping 121 { 122 public: 123 ButtonMapping(const QString &buttonName):m_buttonName(buttonName),m_jump(0){}; 124 QString buttonName(){return m_buttonName;}; 125 void addMapping(const QString &context, const QString & action) 126 { 127 m_contextMapping[context].append(action); 128 } 129 130 bool getMapping(const QString &context, QStringList &actions) 131 { 132 if (m_contextMapping.count(context) > 0) 133 { 134 actions += m_contextMapping[context]; 135 return true; 136 } 137 return false; 138 }; 139 140 void addJump(JumpData * jump) 141 { 142 m_jump=jump; 143 } 144 145 JumpData * getJump() 146 { 147 return m_jump; 148 } 149 void clearJump(const QString &destination) 150 { 151 if (m_jump && m_jump->destination == destination) 152 m_jump=NULL; 153 } 154 155 private: 156 QString m_buttonName; 157 JumpData * m_jump; 158 QMap<QString,QStringList> m_contextMapping; //i.e context -> action(s) 159 }; 160 161 class RemoteMapping 162 { 163 public: 164 RemoteMapping(const QString &remoteName):m_remoteName(remoteName){} 165 QString remoteName(){return m_remoteName;}; 166 void addMapping(const QString &buttonName, const QString &context, const QString & action) 167 { 168 if (!m_buttonMapping.contains(buttonName)) 169 { 170 m_buttonMapping[buttonName]=new ButtonMapping(buttonName); 171 } 172 m_buttonMapping[buttonName]->addMapping(context, action); 173 } 174 bool getMapping(const QString &buttonName, const QString &context, QStringList &actions) 175 { 176 if (m_buttonMapping.contains(buttonName)) 177 return m_buttonMapping[buttonName]->getMapping(context, actions); 178 return false; 179 } 180 void addJump(const QString &buttonName, JumpData * jump) 181 { 182 if (!m_buttonMapping.contains(buttonName)) 183 { 184 m_buttonMapping[buttonName]=new ButtonMapping(buttonName); 185 } 186 m_buttonMapping[buttonName]->addJump(jump); 187 } 188 JumpData * getJump(const QString &buttonName) 189 { 190 ButtonMapping * buttonMapping = m_buttonMapping.value(buttonName); 191 if (buttonMapping) 192 { 193 return buttonMapping->getJump(); 194 } 195 return NULL; 196 } 197 void clearJump(const QString &destination) 198 { 199 ButtonMapping*buttonMapping; 200 foreach (buttonMapping, m_buttonMapping) 201 buttonMapping->clearJump(destination); 202 } 203 private: 204 QMap<QString,ButtonMapping*> m_buttonMapping; 205 QString m_remoteName; 206 }; 207 208 class InputMapping 209 { 210 public: 211 InputMapping(const QString &inputName) 212 :m_inputName(inputName){}; 213 QString inputName(){return m_inputName;}; 214 void addMapping(const QString &remoteName, const QString &buttonName, const QString &context, const QString & action) 215 { 216 if (!m_remoteMapping.contains(remoteName)) 217 { 218 m_remoteMapping[remoteName]=new RemoteMapping(remoteName); 219 } 220 m_remoteMapping[remoteName]->addMapping(buttonName, context, action); 221 } 222 bool getMapping(const QString &remoteName, const QString &buttonName, const QString &context, QStringList &actions) 223 { 224 if (m_remoteMapping.contains(remoteName)) 225 return m_remoteMapping[remoteName]->getMapping(buttonName, context, actions); 226 return true; 227 } 228 void addJump(const QString &remoteName, const QString &buttonName, JumpData * jump) 229 { 230 if (!m_remoteMapping.contains(remoteName)) 231 { 232 m_remoteMapping[remoteName]=new RemoteMapping(remoteName); 233 } 234 m_remoteMapping[remoteName]->addJump(buttonName, jump); 235 } 236 JumpData * getJump(const QString &remoteName, const QString &buttonName) 237 { 238 if (m_remoteMapping.contains(remoteName)) 239 { 240 return m_remoteMapping[remoteName]->getJump(buttonName); 241 } 242 return NULL; 243 } 244 void clearJump(const QString &destination) 245 { 246 RemoteMapping*remoteMapping; 247 foreach (remoteMapping, m_remoteMapping) 248 remoteMapping->clearJump(destination); 249 } 250 private: 251 QMap <QString,RemoteMapping*> m_remoteMapping; 252 QString m_inputName; 253 }; 254 255 118 256 class MythMainWindowPrivate 119 257 { 120 258 public: … … class MythMainWindowPrivate (this hunk was shorter than expected) 211 351 QMap<int, JumpData*> jumpMap; 212 352 QMap<QString, JumpData> destinationMap; 213 353 QMap<QString, MPData> mediaPluginMap; 354 QMap<QString, InputMapping*> inputsMapping; 214 355 215 356 void (*exitmenucallback)(void); 216 357 … … void MythMainWindow::ExitToMainMenu(void) 1430 1583 } 1431 1584 } 1432 1585 1586 bool MythMainWindow::TranslateKeyPress(const QString &context, 1587 MythInputEvent *e, QStringList &actions, 1588 bool allowJumps) 1589 { 1590 actions.clear(); 1591 1592 QStringList localActions; 1593 1594 JumpData * jump = NULL; 1595 1596 if (allowJumps) 1597 { 1598 InputMapping * inputMapping = d->inputsMapping.value(e->inputName()); 1599 if (inputMapping) 1600 { 1601 jump = inputMapping->getJump(e->remoteName(), 1602 e->buttonName()); 1603 if (jump) 1604 { 1605 inputMapping->getMapping(e->remoteName(), 1606 e->buttonName(), context, localActions); 1607 if (localActions.contains(jump->localAction)) 1608 allowJumps = false; 1609 } 1610 } 1611 } 1612 1613 if (allowJumps && jump && !jump->exittomain && d->exitmenucallback == NULL) 1614 { 1615 d->exitingtomain = true; 1616 d->exitmenucallback = jump->callback; 1617 QCoreApplication::postEvent( 1618 this, new QEvent(MythEvent::kExitToMainMenuEventType)); 1619 return true; 1620 } 1621 1622 if (d->inputsMapping.value(e->inputName())) 1623 { 1624 d->inputsMapping.value(e->inputName())->getMapping(e->remoteName(), 1625 e->buttonName(), context, actions); 1626 1627 d->inputsMapping.value(e->inputName())->getMapping(e->remoteName(), 1628 e->buttonName(), "Global", actions); 1629 } 1630 return false; 1631 } 1632 1433 1633 /** 1434 1634 * \brief Get a list of actions for a keypress in the given context 1435 1635 * \param context The context in which to lookup the keypress for actions. … … bool MythMainWindow::TranslateKeyPress(const QString &context, 1444 1644 QKeyEvent *e, QStringList &actions, 1445 1645 bool allowJumps) 1446 1646 { 1647 MythInputEvent * me = dynamic_cast<MythInputEvent *>(e); 1648 if (me) 1649 { 1650 bool handled = TranslateKeyPress(context,me, actions, allowJumps); 1651 if (handled || actions.size()>0) 1652 return handled; 1653 } 1654 1447 1655 actions.clear(); 1448 1656 1449 1657 // Special case for custom QKeyEvent where the action is embedded directly … … void MythMainWindow::RegisterKey(const QString &context, const QString &action, 1579 1787 { 1580 1788 query.prepare("SELECT keylist, description FROM keybindings WHERE " 1581 1789 "context = :CONTEXT AND action = :ACTION AND " 1582 "hostname = :HOSTNAME ;");1790 "hostname = :HOSTNAME AND input='' AND device='';"); 1583 1791 query.bindValue(":CONTEXT", context); 1584 1792 query.bindValue(":ACTION", action); 1585 1793 query.bindValue(":HOSTNAME", GetMythDB()->GetHostName()); … … void MythMainWindow::RegisterKey(const QString &context, const QString &action, 1617 1825 QString inskey = keybind; 1618 1826 1619 1827 query.prepare("INSERT INTO keybindings (context, action, " 1620 "description, keylist, hostname ) VALUES "1828 "description, keylist, hostname, input, device) VALUES " 1621 1829 "( :CONTEXT, :ACTION, :DESCRIPTION, :KEYLIST, " 1622 ":HOSTNAME );");1830 ":HOSTNAME , '', '');"); 1623 1831 query.bindValue(":CONTEXT", context); 1624 1832 query.bindValue(":ACTION", action); 1625 1833 query.bindValue(":DESCRIPTION", description); … … void MythMainWindow::RegisterKey(const QString &context, const QString &action, 1634 1842 } 1635 1843 1636 1844 BindKey(context, action, keybind); 1845 1846 if (d->m_useDB && query.isConnected()) 1847 { 1848 query.prepare("SELECT input, device, keylist FROM keybindings WHERE " 1849 "context = :CONTEXT AND action = :ACTION AND " 1850 "hostname = :HOSTNAME AND input!='' AND device!='';"); 1851 query.bindValue(":CONTEXT", context); 1852 query.bindValue(":ACTION", action); 1853 query.bindValue(":HOSTNAME", GetMythDB()->GetHostName()); 1854 if (query.exec()) 1855 { 1856 while (query.next()) 1857 { 1858 QString inputName = query.value(0).toString(); 1859 QString remoteName = query.value(1).toString(); 1860 QString buttonName = query.value(2).toString(); 1861 LOG(VB_GENERAL, LOG_ERR, 1862 QString("MythMainWindow::RegisterKey %1 %2 %3") 1863 .arg(inputName).arg(remoteName).arg(buttonName)); 1864 if (!d->inputsMapping.value(inputName)) 1865 d->inputsMapping[inputName]=new InputMapping(inputName); 1866 d->inputsMapping[inputName]->addMapping(remoteName, buttonName, context, action); 1867 } 1868 } 1869 } 1637 1870 } 1638 1871 1639 1872 QString MythMainWindow::GetKey(const QString &context, … … QString MythMainWindow::GetKey(const QString &context, 1660 1893 1661 1894 void MythMainWindow::ClearJump(const QString &destination) 1662 1895 { 1896 InputMapping * inputMapping; 1897 foreach(inputMapping, d->inputsMapping) 1898 inputMapping->clearJump(destination); 1899 1663 1900 /* make sure that the jump point exists (using [] would add it)*/ 1664 1901 if (d->destinationMap.find(destination) == d->destinationMap.end()) 1665 1902 { … … void MythMainWindow::RegisterJump(const QString &destination, 1729 1966 if (query.isConnected()) 1730 1967 { 1731 1968 query.prepare("SELECT keylist FROM jumppoints WHERE " 1732 "destination = :DEST and hostname = :HOST ;");1969 "destination = :DEST and hostname = :HOST and input='' and device='';"); 1733 1970 query.bindValue(":DEST", destination); 1734 1971 query.bindValue(":HOST", GetMythDB()->GetHostName()); 1735 1972 … … void MythMainWindow::RegisterJump(const QString &destination, 1742 1979 QString inskey = keybind; 1743 1980 1744 1981 query.prepare("INSERT INTO jumppoints (destination, description, " 1745 "keylist, hostname ) VALUES ( :DEST, :DESC, :KEYLIST, "1746 ":HOST );");1982 "keylist, hostname, input, device) VALUES ( :DEST, :DESC, :KEYLIST, " 1983 ":HOST, '', '' );"); 1747 1984 query.bindValue(":DEST", destination); 1748 1985 query.bindValue(":DESC", description); 1749 1986 query.bindValue(":KEYLIST", inskey); … … void MythMainWindow::RegisterJump(const QString &destination, 1761 1998 d->destinationMap[destination] = jd; 1762 1999 1763 2000 BindJump(destination, keybind); 2001 2002 //TODO Xavier load additionnal jumppoint for remote 2003 if (query.isConnected()) 2004 { 2005 query.prepare("SELECT input, device, keylist FROM jumppoints WHERE " 2006 "destination = :DEST and hostname = :HOST and input!='' and device!='';"); 2007 query.bindValue(":DEST", destination); 2008 query.bindValue(":HOST", GetMythDB()->GetHostName()); 2009 2010 if (query.exec() && query.next()) 2011 { 2012 QString inputName = query.value(0).toString(); 2013 QString remoteName = query.value(1).toString(); 2014 QString buttonName = query.value(2).toString(); 2015 2016 if (!d->inputsMapping.value(inputName)) 2017 d->inputsMapping[inputName]=new InputMapping(inputName); 2018 d->inputsMapping[inputName]->addJump(remoteName, buttonName, &jd); 2019 } 2020 } 1764 2021 } 1765 2022 1766 2023 void MythMainWindow::ClearAllJumps() -
mythtv/libs/libmythui/mythmainwindow.h
diff --git a/mythtv/libs/libmythui/mythmainwindow.h b/mythtv/libs/libmythui/mythmainwindow.h index 46ea69d..75f4844 100644
a b 6 6 #include "mythuiactions.h" 7 7 #include "mythuitype.h" 8 8 #include "mythscreenstack.h" 9 #include "mythinputevent.h" 9 10 10 11 class QEvent; 11 12 … … class MUI_PUBLIC MythMainWindow : public QWidget 48 49 MythScreenStack *GetStack(const QString &stackname); 49 50 MythScreenStack *GetStackAt(int pos); 50 51 52 bool TranslateKeyPress(const QString &context, MythInputEvent *e, 53 QStringList &actions, bool allowJumps = true) 54 MUNUSED_RESULT; 55 51 56 bool TranslateKeyPress(const QString &context, QKeyEvent *e, 52 57 QStringList &actions, bool allowJumps = true) 53 58 MUNUSED_RESULT;
