aboutsummaryrefslogblamecommitdiff
path: root/src/plugins/General/hotkey/hotkeymanager_win.cpp
blob: cb9c5b3f09ea290025ff21487748f9bd99640995 (plain) (tree)























































































































































































































































































                                                                                                  
/***************************************************************************
 *   Copyright (C) 2013 by Ilya Kotov                                      *
 *   forkotov02@hotmail.ru                                                 *
 *                                                                         *
 *   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 <QtGlobal>
#ifdef Q_OS_WIN
#include <QSettings>
#include <QX11Info>
#include <QEvent>
#include <QKeyEvent>
#include <QCoreApplication>
#include <QApplication>
#include <QDesktopWidget>
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <winuser.h>
#include <commctrl.h>
#include <qmmp/qmmp.h>
#include <qmmp/soundcore.h>
#include <qmmpui/mediaplayer.h>
#include <qmmpui/uihelper.h>
#include "hotkeymanager.h"

quint32 Hotkey::defaultKey()
{
    return defaultKey(action);
}

quint32 Hotkey::defaultKey(int act)
{
    //default key bindings
    QMap<int, quint32> keyMap;
    keyMap[PLAY] = 0;
    keyMap[STOP] = VK_MEDIA_STOP;
    keyMap[PAUSE] = 0;
    keyMap[PLAY_PAUSE] = VK_MEDIA_PLAY_PAUSE;
    keyMap[NEXT] = VK_MEDIA_NEXT_TRACK;
    keyMap[PREVIOUS] = VK_MEDIA_PREV_TRACK;
    keyMap[SHOW_HIDE] = 0;
    keyMap[VOLUME_UP] = VK_VOLUME_UP;
    keyMap[VOLUME_DOWN] = VK_VOLUME_DOWN;
    keyMap[FORWARD] = 0;
    keyMap[REWIND] = 0;
    keyMap[JUMP_TO_TRACK] = 0;
    return keyMap[act];
}

WPARAM nextId132 = 1;


class KeyFilterWidget : public QWidget
{
public:
    KeyFilterWidget()
    {}

    ~KeyFilterWidget()
    {

    }

bool winEvent(MSG* m, long* result)
{
    if (m->message == WM_HOTKEY)
    {
        qDebug("HOT KEY PRESSED!!!");
        return true;
    }
    return QWidget::winEvent(m, result);
}
};


HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent)
{
    QCoreApplication::instance()->installEventFilter(this);
    KeyFilterWidget *w = new KeyFilterWidget;

    //qDebug("+++%d++++", int(WId));
    QSettings settings(Qmmp::configFile(), QSettings::IniFormat); //load settings
    settings.beginGroup("Hotkey");
    for (int i = Hotkey::PLAY; i <= Hotkey::JUMP_TO_TRACK; ++i)
    {
        qDebug("----");
        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)
        {

            Hotkey *hotkey = new Hotkey;
            hotkey->action = i;
            hotkey->key = key;
            //hotkey->code = keycodeToKeysym(hotkey->key);
            /*if(!hotkey->code)
                continue;*/

            qDebug("1");
            if(RegisterHotKey(w->winId(), MOD_CONTROL^hotkey->key,  MOD_CONTROL, hotkey->key))
            {
                qDebug("registered");
                nextId132++;
            }
            else
            {
                qDebug("failed");
            }
            qDebug("2");

            //hotkey->mod = mod | mask_mod;
            m_grabbedKeys << hotkey;
        }
    }
    settings.endGroup();
}

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)
{
    qDebug("%ux++%ux", key, modifiers);
    QString strModList[] = { "Control", "Shift", "Alt"};
    quint32 modList[] = { HOTKEYF_CONTROL, HOTKEYF_SHIFT, HOTKEYF_ALT};

    MOD_CONTROL, MOD_ALT, HOTKEYF_EXT;

    QString keyStr;
    for (int j = 0; j < 3; j++)
    {
        if (modifiers & modList[j])
            keyStr.append(strModList[j] + "+");
    }

    LONG lScan = MapVirtualKey(key, 0) << 16;

    int nBufferLen = 64;
    std::wstring str;
    int nLen;
    do
    {
        nBufferLen *= 2;
        str.resize(nBufferLen);
        nLen = ::GetKeyNameTextW(lScan, &str[0], nBufferLen);
    }
    while (nLen == nBufferLen);

    keyStr += QString::fromWCharArray(str.c_str());

    return keyStr;
}

bool HotkeyManager::eventFilter(QObject* o, QEvent* e)
{
    if (e->type() == QEvent::KeyPress)
    {
        qDebug("KEY EVENT!!");
    }

    //receive events from active and root windows only
    /*if (e->type() == QEvent::KeyPress && (o == qApp->desktop () || o == qApp->activeWindow ()))
    {
        QKeyEvent* k = static_cast<QKeyEvent*>(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;


void HotkeyManager::ensureModifiers(){}

QList<long> HotkeyManager::ignModifiersList()
{
    ensureModifiers();
    QList<long> ret;
    ret << 0;
    return ret;
}

quint32 HotkeyManager::keycodeToKeysym(quint32 keycode)
{
    return MapVirtualKey(keycode, 1);
}
#endif