2013-06-26 08:15:20 +00:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
|
|
|
|
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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
#ifndef KWIN_INPUT_H
|
|
|
|
#define KWIN_INPUT_H
|
|
|
|
#include <kwinglobals.h>
|
|
|
|
#include <QHash>
|
|
|
|
#include <QObject>
|
|
|
|
#include <QPoint>
|
2013-06-26 09:40:30 +00:00
|
|
|
#include <QEvent>
|
2013-07-01 06:37:59 +00:00
|
|
|
#include <QWeakPointer>
|
2013-07-02 09:44:18 +00:00
|
|
|
#include <config-kwin.h>
|
|
|
|
#if HAVE_XKB
|
|
|
|
#include <xkbcommon/xkbcommon.h>
|
|
|
|
#endif
|
2013-06-26 08:15:20 +00:00
|
|
|
|
2013-07-10 09:41:16 +00:00
|
|
|
class QAction;
|
|
|
|
class QKeySequence;
|
|
|
|
|
2013-06-26 08:15:20 +00:00
|
|
|
namespace KWin
|
|
|
|
{
|
2013-07-10 09:41:16 +00:00
|
|
|
class GlobalShortcutsManager;
|
2013-07-01 06:37:59 +00:00
|
|
|
class Toplevel;
|
2013-07-02 09:44:18 +00:00
|
|
|
class Xkb;
|
2013-06-26 08:15:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This class is responsible for redirecting incoming input to the surface which currently
|
|
|
|
* has input or send enter/leave events.
|
|
|
|
*
|
|
|
|
* In addition input is intercepted before passed to the surfaces to have KWin internal areas
|
|
|
|
* getting input first (e.g. screen edges) and filter the input event out if we currently have
|
|
|
|
* a full input grab.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class InputRedirection : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
enum PointerButtonState {
|
|
|
|
PointerButtonReleased,
|
|
|
|
PointerButtonPressed
|
|
|
|
};
|
|
|
|
enum PointerAxis {
|
|
|
|
PointerAxisVertical,
|
|
|
|
PointerAxisHorizontal
|
|
|
|
};
|
2013-07-02 09:44:18 +00:00
|
|
|
enum KeyboardKeyState {
|
|
|
|
KeyboardKeyReleased,
|
|
|
|
KeyboardKeyPressed
|
|
|
|
};
|
2013-06-26 08:15:20 +00:00
|
|
|
virtual ~InputRedirection();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return const QPointF& The current global pointer position
|
|
|
|
*/
|
|
|
|
const QPointF &globalPointer() const;
|
|
|
|
/**
|
|
|
|
* @brief The last known state of the @p button. If @p button is still unknown the state is
|
|
|
|
* @c PointerButtonReleased.
|
|
|
|
*
|
|
|
|
* @param button The button for which the last known state should be queried.
|
|
|
|
* @return KWin::InputRedirection::PointerButtonState
|
|
|
|
*/
|
|
|
|
PointerButtonState pointerButtonState(uint32_t button) const;
|
2013-06-26 12:32:03 +00:00
|
|
|
Qt::MouseButtons qtButtonStates() const;
|
2013-07-02 09:44:18 +00:00
|
|
|
Qt::KeyboardModifiers keyboardModifiers() const;
|
2013-06-26 08:15:20 +00:00
|
|
|
|
2013-07-10 09:41:16 +00:00
|
|
|
void registerShortcut(const QKeySequence &shortcut, QAction *action);
|
2013-07-14 20:52:58 +00:00
|
|
|
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action);
|
2013-07-15 09:26:56 +00:00
|
|
|
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action);
|
2013-07-10 09:41:16 +00:00
|
|
|
|
2013-06-26 08:15:20 +00:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void processPointerMotion(const QPointF &pos, uint32_t time);
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void processPointerButton(uint32_t button, PointerButtonState state, uint32_t time);
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void processPointerAxis(PointerAxis axis, qreal delta, uint32_t time);
|
2013-07-02 09:44:18 +00:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void processKeyboardKey(uint32_t key, KeyboardKeyState state, uint32_t time);
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void processKeyboardModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
**/
|
|
|
|
void processKeymapChange(int fd, uint32_t size);
|
2013-06-26 08:15:20 +00:00
|
|
|
|
2013-07-01 06:37:59 +00:00
|
|
|
static uint8_t toXPointerButton(uint32_t button);
|
|
|
|
static uint8_t toXPointerButton(PointerAxis axis, qreal delta);
|
|
|
|
|
|
|
|
public Q_SLOTS:
|
|
|
|
void updatePointerWindow();
|
|
|
|
|
2013-06-26 08:15:20 +00:00
|
|
|
Q_SIGNALS:
|
|
|
|
/**
|
|
|
|
* @brief Emitted when the global pointer position changed
|
|
|
|
*
|
|
|
|
* @param pos The new global pointer position.
|
|
|
|
*/
|
|
|
|
void globalPointerChanged(const QPointF &pos);
|
|
|
|
/**
|
|
|
|
* @brief Emitted when the state of a pointer button changed.
|
|
|
|
*
|
|
|
|
* @param button The button which changed
|
|
|
|
* @param state The new button state
|
|
|
|
*/
|
2013-06-26 12:32:03 +00:00
|
|
|
void pointerButtonStateChanged(uint32_t button, InputRedirection::PointerButtonState state);
|
2013-06-26 08:15:20 +00:00
|
|
|
/**
|
|
|
|
* @brief Emitted when a pointer axis changed
|
|
|
|
*
|
|
|
|
* @param axis The axis on which the even occurred
|
|
|
|
* @param delta The delta of the event.
|
|
|
|
*/
|
2013-06-26 12:32:03 +00:00
|
|
|
void pointerAxisChanged(InputRedirection::PointerAxis axis, qreal delta);
|
2013-07-02 10:16:03 +00:00
|
|
|
/**
|
|
|
|
* @brief Emitted when the modifiers changes.
|
|
|
|
*
|
|
|
|
* Only emitted for the mask which is provided by Qt::KeyboardModifiers, if other modifiers
|
|
|
|
* change signal is not emitted
|
|
|
|
*
|
|
|
|
* @param newMods The new modifiers state
|
|
|
|
* @param oldMods The previous modifiers state
|
|
|
|
*/
|
|
|
|
void keyboardModifiersChanged(Qt::KeyboardModifiers newMods, Qt::KeyboardModifiers oldMods);
|
2013-06-26 08:15:20 +00:00
|
|
|
|
|
|
|
private:
|
2013-06-26 09:40:30 +00:00
|
|
|
static QEvent::Type buttonStateToEvent(PointerButtonState state);
|
|
|
|
static Qt::MouseButton buttonToQtMouseButton(uint32_t button);
|
2013-07-01 06:37:59 +00:00
|
|
|
Toplevel *findToplevel(const QPoint &pos);
|
2013-06-26 08:15:20 +00:00
|
|
|
QPointF m_globalPointer;
|
|
|
|
QHash<uint32_t, PointerButtonState> m_pointerButtons;
|
2013-07-02 09:44:18 +00:00
|
|
|
#if HAVE_XKB
|
|
|
|
QScopedPointer<Xkb> m_xkb;
|
|
|
|
#endif
|
2013-07-01 06:37:59 +00:00
|
|
|
/**
|
|
|
|
* @brief The Toplevel which currently receives pointer events
|
|
|
|
*/
|
|
|
|
QWeakPointer<Toplevel> m_pointerWindow;
|
2013-06-26 08:15:20 +00:00
|
|
|
|
2013-07-10 09:41:16 +00:00
|
|
|
GlobalShortcutsManager *m_shortcuts;
|
|
|
|
|
2013-06-26 08:15:20 +00:00
|
|
|
KWIN_SINGLETON(InputRedirection)
|
|
|
|
friend InputRedirection *input();
|
|
|
|
};
|
|
|
|
|
2013-07-02 09:44:18 +00:00
|
|
|
#if HAVE_XKB
|
|
|
|
class Xkb
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Xkb();
|
|
|
|
~Xkb();
|
|
|
|
void installKeymap(int fd, uint32_t size);
|
|
|
|
void updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
|
|
|
|
void updateKey(uint32_t key, InputRedirection::KeyboardKeyState state);
|
|
|
|
xkb_keysym_t toKeysym(uint32_t key);
|
|
|
|
QString toString(xkb_keysym_t keysym);
|
|
|
|
Qt::Key toQtKey(xkb_keysym_t keysym);
|
|
|
|
Qt::KeyboardModifiers modifiers() const;
|
|
|
|
private:
|
|
|
|
xkb_context *m_context;
|
|
|
|
xkb_keymap *m_keymap;
|
|
|
|
xkb_state *m_state;
|
|
|
|
xkb_mod_index_t m_shiftModifier;
|
|
|
|
xkb_mod_index_t m_controlModifier;
|
|
|
|
xkb_mod_index_t m_altModifier;
|
|
|
|
xkb_mod_index_t m_metaModifier;
|
|
|
|
Qt::KeyboardModifiers m_modifiers;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2013-06-26 08:15:20 +00:00
|
|
|
inline
|
|
|
|
InputRedirection *input()
|
|
|
|
{
|
|
|
|
return InputRedirection::s_self;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
const QPointF &InputRedirection::globalPointer() const
|
|
|
|
{
|
|
|
|
return m_globalPointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
InputRedirection::PointerButtonState InputRedirection::pointerButtonState(uint32_t button) const
|
|
|
|
{
|
|
|
|
auto it = m_pointerButtons.constFind(button);
|
|
|
|
if (it != m_pointerButtons.constEnd()) {
|
|
|
|
return it.value();
|
|
|
|
} else {
|
|
|
|
return KWin::InputRedirection::PointerButtonReleased;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-02 09:44:18 +00:00
|
|
|
#if HAVE_XKB
|
|
|
|
inline
|
|
|
|
Qt::KeyboardModifiers Xkb::modifiers() const
|
|
|
|
{
|
|
|
|
return m_modifiers;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-06-26 08:15:20 +00:00
|
|
|
} // namespace KWin
|
|
|
|
|
|
|
|
#endif // KWIN_INPUT_H
|