From a15f2d6df476e302c479e469bfa693317d732eff Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Sun, 10 Feb 2013 14:41:57 +0000 Subject: refactoring git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@3212 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/General/hotkey/CMakeLists.txt | 2 +- src/plugins/General/hotkey/hotkey.pro | 4 +- src/plugins/General/hotkey/hotkeymanager.cpp | 323 ----------------------- src/plugins/General/hotkey/hotkeymanager_x11.cpp | 323 +++++++++++++++++++++++ 4 files changed, 326 insertions(+), 326 deletions(-) delete mode 100644 src/plugins/General/hotkey/hotkeymanager.cpp create mode 100644 src/plugins/General/hotkey/hotkeymanager_x11.cpp (limited to 'src/plugins/General') diff --git a/src/plugins/General/hotkey/CMakeLists.txt b/src/plugins/General/hotkey/CMakeLists.txt index 33aa48ffb..47aa3a291 100644 --- a/src/plugins/General/hotkey/CMakeLists.txt +++ b/src/plugins/General/hotkey/CMakeLists.txt @@ -40,7 +40,7 @@ ENDIF(XKBLIB_H_FOUND) SET(libhotkey_SRCS settingsdialog.cpp hotkeyfactory.cpp - hotkeymanager.cpp + hotkeymanager_x11.cpp hotkeydialog.cpp ) diff --git a/src/plugins/General/hotkey/hotkey.pro b/src/plugins/General/hotkey/hotkey.pro index 7a3bd3e4d..3e2443f6f 100644 --- a/src/plugins/General/hotkey/hotkey.pro +++ b/src/plugins/General/hotkey/hotkey.pro @@ -42,9 +42,9 @@ HEADERS += hotkeyfactory.h \ hotkeydialog.h SOURCES += hotkeyfactory.cpp \ - hotkeymanager.cpp \ settingsdialog.cpp \ - hotkeydialog.cpp + hotkeydialog.cpp \ + hotkeymanager_x11.cpp INCLUDEPATH += ../../../../src diff --git a/src/plugins/General/hotkey/hotkeymanager.cpp b/src/plugins/General/hotkey/hotkeymanager.cpp deleted file mode 100644 index 98cb8330d..000000000 --- a/src/plugins/General/hotkey/hotkeymanager.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009-2012 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * Copyright (C) 2003-2007 by Justin Karneges and Michail Pishchagin * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#define Visual XVisual -extern "C" -{ -#include -#include -#include -#include -#ifdef HAVE_XKBLIB_H -#include -#endif -} -#undef CursorShape -#undef Status -#undef Bool -#undef None -#undef KeyPress -#undef Visual - -#include -#include -#include -#include -#include "hotkeymanager.h" - -quint32 Hotkey::defaultKey() -{ - return defaultKey(action); -} - -quint32 Hotkey::defaultKey(int act) -{ - //default key bindings - QMap keyMap; - keyMap[PLAY] = XF86XK_AudioPlay; - keyMap[STOP] = XF86XK_AudioStop; - keyMap[PAUSE] = XF86XK_AudioPause; - keyMap[PLAY_PAUSE] = 0; - keyMap[NEXT] = XF86XK_AudioNext; - keyMap[PREVIOUS] = XF86XK_AudioPrev; - keyMap[SHOW_HIDE] = 0; - keyMap[VOLUME_UP] = XF86XK_AudioRaiseVolume; - keyMap[VOLUME_DOWN] = XF86XK_AudioLowerVolume; - keyMap[FORWARD] = 0; - keyMap[REWIND] = 0; - keyMap[JUMP_TO_TRACK] = 0; - return keyMap[act]; -} - -HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent) -{ - QCoreApplication::instance()->installEventFilter(this); - WId rootWindow = QX11Info::appRootWindow(); - QSettings settings(Qmmp::configFile(), QSettings::IniFormat); //load settings - settings.beginGroup("Hotkey"); - for (int i = Hotkey::PLAY, j = 0; i <= Hotkey::JUMP_TO_TRACK; ++i, ++j) - { - quint32 key = settings.value(QString("key_%1").arg(i), Hotkey::defaultKey(i)).toUInt(); - quint32 mod = settings.value(QString("modifiers_%1").arg(i), 0).toUInt(); - - if (key) - { - foreach(long mask_mod, ignModifiersList()) - { - Hotkey *hotkey = new Hotkey; - hotkey->action = i; - hotkey->key = key; - hotkey->code = XKeysymToKeycode(QX11Info::display(), hotkey->key); - if(!hotkey->code) - continue; - XGrabKey(QX11Info::display(), hotkey->code, mod | mask_mod, rootWindow, False, - GrabModeAsync, GrabModeAsync); - hotkey->mod = mod | mask_mod; - m_grabbedKeys << hotkey; - } - } - } - settings.endGroup(); - XSync(QX11Info::display(), False); - // XSetErrorHandler(); -} - -HotkeyManager::~HotkeyManager() -{ - foreach(Hotkey *key, m_grabbedKeys) - { - if(key->code) - XUngrabKey(QX11Info::display(), key->code, key->mod, QX11Info::appRootWindow()); - } - while (!m_grabbedKeys.isEmpty()) - delete m_grabbedKeys.takeFirst (); -} - -const QString HotkeyManager::getKeyString(quint32 key, quint32 modifiers) -{ - QString strModList[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" }; - quint32 modList[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; - QString keyStr; - for (int j = 0; j < 7; j++) - { - if (modifiers & modList[j]) - keyStr.append(strModList[j] + "+"); - } - keyStr.append(XKeysymToString(key)); - return keyStr; -} - -bool HotkeyManager::eventFilter(QObject* o, QEvent* e) -{ - //receive events from active and root windows only - if (e->type() == QEvent::KeyPress && (o == qApp->desktop () || o == qApp->activeWindow ())) - { - QKeyEvent* k = static_cast(e); - quint32 key = keycodeToKeysym(k->nativeScanCode()); - quint32 mod = k->nativeModifiers (); - SoundCore *core = SoundCore::instance(); - MediaPlayer *player = MediaPlayer::instance(); - foreach(Hotkey *hotkey, m_grabbedKeys) - { - if (hotkey->key != key || hotkey->mod != mod) - continue; - qDebug("HotkeyManager: [%s] pressed", qPrintable(getKeyString(key, mod))); - - switch (hotkey->action) - { - case Hotkey::PLAY: - player->play(); - break; - case Hotkey::STOP: - player->stop(); - break; - case Hotkey::PAUSE: - core->pause(); - break; - case Hotkey::PLAY_PAUSE: - if (core->state() == Qmmp::Stopped) - MediaPlayer::instance()->play(); - else if (core->state() != Qmmp::FatalError) - core->pause(); - break; - case Hotkey::NEXT: - player->next(); - break; - case Hotkey::PREVIOUS: - player->previous(); - break; - case Hotkey::SHOW_HIDE: - UiHelper::instance()->toggleVisibility(); - break; - case Hotkey::VOLUME_UP: - case Hotkey::VOLUME_DOWN: - { - int volume = qMax(core->leftVolume(), core->rightVolume()); - int balance = 0; - int left = core->leftVolume(); - int right = core->rightVolume(); - if (left || right) - balance = (right - left)*100/volume; - if(hotkey->action == Hotkey::VOLUME_UP) - volume = qMin (100, volume + 5); - else - volume = qMax (0, volume - 5); - core->setVolume(volume-qMax(balance,0)*volume/100, - volume+qMin(balance,0)*volume/100); - } - break; - case Hotkey::FORWARD: - core->seek(core->elapsed() + 5000); - break; - case Hotkey::REWIND: - core->seek(qMax(qint64(0), core->elapsed() - 5000)); - break; - case Hotkey::JUMP_TO_TRACK: - UiHelper::instance()->jumpToTrack(); - break; - - } - qApp->processEvents(); - } - } - return QObject::eventFilter(o, e); -} -long HotkeyManager::m_alt_mask = 0; -long HotkeyManager::m_meta_mask = 0; -long HotkeyManager::m_super_mask = 0; -long HotkeyManager::m_hyper_mask = 0; -long HotkeyManager::m_numlock_mask = 0; -bool HotkeyManager::m_haveMods = false; - -//copied from globalshortcutmanager_x11.cpp by Justin Karneges and Michail Pishchagin (Psi project) -void HotkeyManager::ensureModifiers() -{ - if (m_haveMods) - return; - - Display* appDpy = QX11Info::display(); - XModifierKeymap* map = XGetModifierMapping(appDpy); - if (map) - { - // XkbKeycodeToKeysym helper code adapeted from xmodmap - int min_keycode, max_keycode, keysyms_per_keycode = 1; - XDisplayKeycodes (appDpy, &min_keycode, &max_keycode); - XFree(XGetKeyboardMapping (appDpy, min_keycode, (max_keycode - min_keycode + 1), &keysyms_per_keycode)); - - int i, maskIndex = 0, mapIndex = 0; - for (maskIndex = 0; maskIndex < 8; maskIndex++) - { - for (i = 0; i < map->max_keypermod; i++) - { - if (map->modifiermap[mapIndex]) - { - KeySym sym; - int symIndex = 0; - do - { -#ifdef HAVE_XKBLIB_H - sym = XkbKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], symIndex, 0); -#else - sym = XKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], symIndex); -#endif - symIndex++; - } - while ( !sym && symIndex < keysyms_per_keycode); - if (!m_alt_mask && (sym == XK_Alt_L || sym == XK_Alt_R)) - { - m_alt_mask = 1 << maskIndex; - } - if (!m_meta_mask && (sym == XK_Meta_L || sym == XK_Meta_R)) - { - m_meta_mask = 1 << maskIndex; - } - if (!m_super_mask && (sym == XK_Super_L || sym == XK_Super_R)) - { - m_super_mask = 1 << maskIndex; - } - if (!m_hyper_mask && (sym == XK_Hyper_L || sym == XK_Hyper_R)) - { - m_hyper_mask = 1 << maskIndex; - } - if (!m_numlock_mask && (sym == XK_Num_Lock)) - { - m_numlock_mask = 1 << maskIndex; - } - } - mapIndex++; - } - } - - XFreeModifiermap(map); - - // logic from qt source see gui/kernel/qkeymapper_x11.cpp - if (!m_meta_mask || m_meta_mask == m_alt_mask) - { - // no meta keys... s,meta,super, - m_meta_mask = m_super_mask; - if (!m_meta_mask || m_meta_mask == m_alt_mask) - { - // no super keys either? guess we'll use hyper then - m_meta_mask = m_hyper_mask; - } - } - } - else - { - // assume defaults - m_alt_mask = Mod1Mask; - m_meta_mask = Mod4Mask; - } - - m_haveMods = true; -} - -QList HotkeyManager::ignModifiersList() -{ - ensureModifiers(); - QList ret; - if (m_numlock_mask) - { - ret << 0 << LockMask << m_numlock_mask << (LockMask | m_numlock_mask); - } - else - { - ret << 0 << LockMask; - } - return ret; -} - -quint32 HotkeyManager::keycodeToKeysym(quint32 keycode) -{ -#ifdef HAVE_XKBLIB_H - return XkbKeycodeToKeysym(QX11Info::display(), keycode, 0, 0); -#else - return XKeycodeToKeysym(QX11Info::display(), keycode,0); -#endif -} diff --git a/src/plugins/General/hotkey/hotkeymanager_x11.cpp b/src/plugins/General/hotkey/hotkeymanager_x11.cpp new file mode 100644 index 000000000..5f96617ea --- /dev/null +++ b/src/plugins/General/hotkey/hotkeymanager_x11.cpp @@ -0,0 +1,323 @@ +/*************************************************************************** + * Copyright (C) 2009-2013 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * Copyright (C) 2003-2007 by Justin Karneges and Michail Pishchagin * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#define Visual XVisual +extern "C" +{ +#include +#include +#include +#include +#ifdef HAVE_XKBLIB_H +#include +#endif +} +#undef CursorShape +#undef Status +#undef Bool +#undef None +#undef KeyPress +#undef Visual + +#include +#include +#include +#include +#include "hotkeymanager.h" + +quint32 Hotkey::defaultKey() +{ + return defaultKey(action); +} + +quint32 Hotkey::defaultKey(int act) +{ + //default key bindings + QMap keyMap; + keyMap[PLAY] = XF86XK_AudioPlay; + keyMap[STOP] = XF86XK_AudioStop; + keyMap[PAUSE] = XF86XK_AudioPause; + keyMap[PLAY_PAUSE] = 0; + keyMap[NEXT] = XF86XK_AudioNext; + keyMap[PREVIOUS] = XF86XK_AudioPrev; + keyMap[SHOW_HIDE] = 0; + keyMap[VOLUME_UP] = XF86XK_AudioRaiseVolume; + keyMap[VOLUME_DOWN] = XF86XK_AudioLowerVolume; + keyMap[FORWARD] = 0; + keyMap[REWIND] = 0; + keyMap[JUMP_TO_TRACK] = 0; + return keyMap[act]; +} + +HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent) +{ + QCoreApplication::instance()->installEventFilter(this); + WId rootWindow = QX11Info::appRootWindow(); + QSettings settings(Qmmp::configFile(), QSettings::IniFormat); //load settings + settings.beginGroup("Hotkey"); + for (int i = Hotkey::PLAY, j = 0; i <= Hotkey::JUMP_TO_TRACK; ++i, ++j) + { + quint32 key = settings.value(QString("key_%1").arg(i), Hotkey::defaultKey(i)).toUInt(); + quint32 mod = settings.value(QString("modifiers_%1").arg(i), 0).toUInt(); + + if (key) + { + foreach(long mask_mod, ignModifiersList()) + { + Hotkey *hotkey = new Hotkey; + hotkey->action = i; + hotkey->key = key; + hotkey->code = XKeysymToKeycode(QX11Info::display(), hotkey->key); + if(!hotkey->code) + continue; + XGrabKey(QX11Info::display(), hotkey->code, mod | mask_mod, rootWindow, False, + GrabModeAsync, GrabModeAsync); + hotkey->mod = mod | mask_mod; + m_grabbedKeys << hotkey; + } + } + } + settings.endGroup(); + XSync(QX11Info::display(), False); + // XSetErrorHandler(); +} + +HotkeyManager::~HotkeyManager() +{ + foreach(Hotkey *key, m_grabbedKeys) + { + if(key->code) + XUngrabKey(QX11Info::display(), key->code, key->mod, QX11Info::appRootWindow()); + } + while (!m_grabbedKeys.isEmpty()) + delete m_grabbedKeys.takeFirst (); +} + +const QString HotkeyManager::getKeyString(quint32 key, quint32 modifiers) +{ + QString strModList[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" }; + quint32 modList[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; + QString keyStr; + for (int j = 0; j < 7; j++) + { + if (modifiers & modList[j]) + keyStr.append(strModList[j] + "+"); + } + keyStr.append(XKeysymToString(key)); + return keyStr; +} + +bool HotkeyManager::eventFilter(QObject* o, QEvent* e) +{ + //receive events from active and root windows only + if (e->type() == QEvent::KeyPress && (o == qApp->desktop () || o == qApp->activeWindow ())) + { + QKeyEvent* k = static_cast(e); + quint32 key = keycodeToKeysym(k->nativeScanCode()); + quint32 mod = k->nativeModifiers (); + SoundCore *core = SoundCore::instance(); + MediaPlayer *player = MediaPlayer::instance(); + foreach(Hotkey *hotkey, m_grabbedKeys) + { + if (hotkey->key != key || hotkey->mod != mod) + continue; + qDebug("HotkeyManager: [%s] pressed", qPrintable(getKeyString(key, mod))); + + switch (hotkey->action) + { + case Hotkey::PLAY: + player->play(); + break; + case Hotkey::STOP: + player->stop(); + break; + case Hotkey::PAUSE: + core->pause(); + break; + case Hotkey::PLAY_PAUSE: + if (core->state() == Qmmp::Stopped) + MediaPlayer::instance()->play(); + else if (core->state() != Qmmp::FatalError) + core->pause(); + break; + case Hotkey::NEXT: + player->next(); + break; + case Hotkey::PREVIOUS: + player->previous(); + break; + case Hotkey::SHOW_HIDE: + UiHelper::instance()->toggleVisibility(); + break; + case Hotkey::VOLUME_UP: + case Hotkey::VOLUME_DOWN: + { + int volume = qMax(core->leftVolume(), core->rightVolume()); + int balance = 0; + int left = core->leftVolume(); + int right = core->rightVolume(); + if (left || right) + balance = (right - left)*100/volume; + if(hotkey->action == Hotkey::VOLUME_UP) + volume = qMin (100, volume + 5); + else + volume = qMax (0, volume - 5); + core->setVolume(volume-qMax(balance,0)*volume/100, + volume+qMin(balance,0)*volume/100); + } + break; + case Hotkey::FORWARD: + core->seek(core->elapsed() + 5000); + break; + case Hotkey::REWIND: + core->seek(qMax(qint64(0), core->elapsed() - 5000)); + break; + case Hotkey::JUMP_TO_TRACK: + UiHelper::instance()->jumpToTrack(); + break; + + } + qApp->processEvents(); + } + } + return QObject::eventFilter(o, e); +} +long HotkeyManager::m_alt_mask = 0; +long HotkeyManager::m_meta_mask = 0; +long HotkeyManager::m_super_mask = 0; +long HotkeyManager::m_hyper_mask = 0; +long HotkeyManager::m_numlock_mask = 0; +bool HotkeyManager::m_haveMods = false; + +//copied from globalshortcutmanager_x11.cpp by Justin Karneges and Michail Pishchagin (Psi project) +void HotkeyManager::ensureModifiers() +{ + if (m_haveMods) + return; + + Display* appDpy = QX11Info::display(); + XModifierKeymap* map = XGetModifierMapping(appDpy); + if (map) + { + // XkbKeycodeToKeysym helper code adapeted from xmodmap + int min_keycode, max_keycode, keysyms_per_keycode = 1; + XDisplayKeycodes (appDpy, &min_keycode, &max_keycode); + XFree(XGetKeyboardMapping (appDpy, min_keycode, (max_keycode - min_keycode + 1), &keysyms_per_keycode)); + + int i, maskIndex = 0, mapIndex = 0; + for (maskIndex = 0; maskIndex < 8; maskIndex++) + { + for (i = 0; i < map->max_keypermod; i++) + { + if (map->modifiermap[mapIndex]) + { + KeySym sym; + int symIndex = 0; + do + { +#ifdef HAVE_XKBLIB_H + sym = XkbKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], symIndex, 0); +#else + sym = XKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], symIndex); +#endif + symIndex++; + } + while ( !sym && symIndex < keysyms_per_keycode); + if (!m_alt_mask && (sym == XK_Alt_L || sym == XK_Alt_R)) + { + m_alt_mask = 1 << maskIndex; + } + if (!m_meta_mask && (sym == XK_Meta_L || sym == XK_Meta_R)) + { + m_meta_mask = 1 << maskIndex; + } + if (!m_super_mask && (sym == XK_Super_L || sym == XK_Super_R)) + { + m_super_mask = 1 << maskIndex; + } + if (!m_hyper_mask && (sym == XK_Hyper_L || sym == XK_Hyper_R)) + { + m_hyper_mask = 1 << maskIndex; + } + if (!m_numlock_mask && (sym == XK_Num_Lock)) + { + m_numlock_mask = 1 << maskIndex; + } + } + mapIndex++; + } + } + + XFreeModifiermap(map); + + // logic from qt source see gui/kernel/qkeymapper_x11.cpp + if (!m_meta_mask || m_meta_mask == m_alt_mask) + { + // no meta keys... s,meta,super, + m_meta_mask = m_super_mask; + if (!m_meta_mask || m_meta_mask == m_alt_mask) + { + // no super keys either? guess we'll use hyper then + m_meta_mask = m_hyper_mask; + } + } + } + else + { + // assume defaults + m_alt_mask = Mod1Mask; + m_meta_mask = Mod4Mask; + } + + m_haveMods = true; +} + +QList HotkeyManager::ignModifiersList() +{ + ensureModifiers(); + QList ret; + if (m_numlock_mask) + { + ret << 0 << LockMask << m_numlock_mask << (LockMask | m_numlock_mask); + } + else + { + ret << 0 << LockMask; + } + return ret; +} + +quint32 HotkeyManager::keycodeToKeysym(quint32 keycode) +{ +#ifdef HAVE_XKBLIB_H + return XkbKeycodeToKeysym(QX11Info::display(), keycode, 0, 0); +#else + return XKeycodeToKeysym(QX11Info::display(), keycode,0); +#endif +} -- cgit v1.2.3-13-gbd6f