Added UIEventEmitter and use it instead of plain UInput::send()

This commit is contained in:
Ingo Ruhnke 2011-07-12 08:43:20 +02:00
parent 88f6a86fd1
commit c160a0ffdc
17 changed files with 181 additions and 60 deletions

12
TODO
View file

@ -67,6 +67,18 @@ $ sudo pbuilder --build --basetgz /var/cache/pbuilder/base-lucid.tgz ../xboxdrv-
Stuff to do before 0.8.1 release:
=================================
* buttonevent/key_button_event_handler.hpp
Problematic, might cause trouble due to lack of sync:
// send both a press and release event after another, aka a "click"
m_codes.send(uinput, true);
m_codes.send(uinput, false);
* MacroButtonEventHandler is still using raw UInput::send(), should
use UIEventEmitterPtr instead, UInput::send_rel_repetitive() should
be removed
* cycle-key is incomplete, should have additional mode that allows
next/prev without sending events, also has issues with stuck buttons
when multiple keys are pressed

View file

@ -61,14 +61,16 @@ AbsAxisEventHandler::from_string(const std::string& str)
AbsAxisEventHandler::AbsAxisEventHandler() :
m_code(UIEvent::invalid()),
m_fuzz(0),
m_flat(0)
m_flat(0),
m_abs_emitter()
{
}
AbsAxisEventHandler::AbsAxisEventHandler(const UIEvent& code, int min, int max, int fuzz, int flat) :
m_code(code),
m_fuzz(fuzz),
m_flat(flat)
m_flat(flat),
m_abs_emitter()
{
set_axis_range(min, max);
}
@ -76,15 +78,17 @@ AbsAxisEventHandler::AbsAxisEventHandler(const UIEvent& code, int min, int max,
void
AbsAxisEventHandler::init(UInput& uinput, int slot, bool extra_devices)
{
assert(!m_abs_emitter);
m_code.resolve_device_id(slot, extra_devices);
uinput.add_abs(m_code.get_device_id(), m_code.code,
m_min, m_max, m_fuzz, m_flat);
m_abs_emitter = uinput.add_abs(m_code.get_device_id(), m_code.code,
m_min, m_max, m_fuzz, m_flat);
}
void
AbsAxisEventHandler::send(UInput& uinput, int value)
{
uinput.send_abs(m_code.get_device_id(), m_code.code, value);
m_abs_emitter->send(value);
}
void

View file

@ -21,6 +21,8 @@
#include "axis_event.hpp"
#include "ui_event_emitter.hpp"
class AbsAxisEventHandler : public AxisEventHandler
{
public:
@ -40,6 +42,8 @@ private:
UIEvent m_code;
int m_fuzz;
int m_flat;
UIEventEmitterPtr m_abs_emitter;
};
#endif

View file

@ -67,7 +67,8 @@ RelAxisEventHandler::RelAxisEventHandler() :
m_value(5),
m_repeat(10),
m_stick_value(0.0f),
m_rest_value(0.0f)
m_rest_value(0.0f),
m_rel_emitter()
{
}
@ -76,7 +77,8 @@ RelAxisEventHandler::RelAxisEventHandler(int device_id, int code, int repeat, fl
m_value(value),
m_repeat(repeat),
m_stick_value(0.0f),
m_rest_value(0.0f)
m_rest_value(0.0f),
m_rel_emitter()
{
}
@ -84,7 +86,7 @@ void
RelAxisEventHandler::init(UInput& uinput, int slot, bool extra_devices)
{
m_code.resolve_device_id(slot, extra_devices);
uinput.add_rel(m_code.get_device_id(), m_code.code);
m_rel_emitter = uinput.add_rel(m_code.get_device_id(), m_code.code);
}
void
@ -120,7 +122,7 @@ RelAxisEventHandler::update(UInput& uinput, int msec_delta)
rel_value += m_rest_value;
m_rest_value = rel_value - truncf(rel_value);
uinput.send_rel(m_code.get_device_id(), m_code.code, static_cast<int>(rel_value));
m_rel_emitter->send(static_cast<int>(rel_value));
}
}

View file

@ -21,6 +21,8 @@
#include "axis_event.hpp"
#include "ui_event_emitter.hpp"
class RelAxisEventHandler : public AxisEventHandler
{
public:
@ -43,6 +45,8 @@ private:
float m_stick_value;
float m_rest_value;
UIEventEmitterPtr m_rel_emitter;
};
#endif

View file

@ -51,15 +51,18 @@ RelRepeatAxisEventHandler::RelRepeatAxisEventHandler(const UIEvent& code, int va
m_value(value),
m_repeat(repeat),
m_stick_value(0),
m_timer(0)
m_timer(0),
m_rel_emitter()
{
}
void
RelRepeatAxisEventHandler::init(UInput& uinput, int slot, bool extra_devices)
{
assert(!m_rel_emitter);
m_code.resolve_device_id(slot, extra_devices);
uinput.add_rel(m_code.get_device_id(), m_code.code);
m_rel_emitter = uinput.add_rel(m_code.get_device_id(), m_code.code);
}
void
@ -91,11 +94,11 @@ RelRepeatAxisEventHandler::update(UInput& uinput, int msec_delta)
{
if (m_stick_value < 0)
{
uinput.send_rel(m_code.get_device_id(), m_code.code, -m_value);
m_rel_emitter->send(-m_value);
}
else
{
uinput.send_rel(m_code.get_device_id(), m_code.code, m_value);
m_rel_emitter->send(m_value);
}
m_timer -= m_repeat;

View file

@ -21,6 +21,8 @@
#include "axis_event.hpp"
#include "ui_event_emitter.hpp"
class RelRepeatAxisEventHandler : public AxisEventHandler
{
public:
@ -42,6 +44,8 @@ private:
float m_stick_value;
int m_timer;
UIEventEmitterPtr m_rel_emitter;
};
#endif

View file

@ -29,7 +29,8 @@ AbsButtonEventHandler::from_string(const std::string& str)
AbsButtonEventHandler::AbsButtonEventHandler(int code) :
m_code(UIEvent::invalid()),
m_value()
m_value(),
m_abs_emitter()
{
assert(!"Not implemented");
// FIXME: Need magic to detect min/max of the axis
@ -45,7 +46,7 @@ AbsButtonEventHandler::send(UInput& uinput, bool value)
{
if (value)
{
uinput.send_abs(m_code.get_device_id(), m_code.code, m_value);
m_abs_emitter->send(m_value);
}
}

View file

@ -21,6 +21,8 @@
#include "button_event.hpp"
#include "ui_event_emitter.hpp"
class AbsButtonEventHandler : public ButtonEventHandler
{
public:
@ -38,6 +40,8 @@ public:
private:
UIEvent m_code;
int m_value;
UIEventEmitterPtr m_abs_emitter;
};
#endif

View file

@ -56,7 +56,8 @@ RelButtonEventHandler::from_string(const std::string& str)
RelButtonEventHandler::RelButtonEventHandler(const UIEvent& code) :
m_code(code),
m_value(3),
m_repeat(100)
m_repeat(100),
m_rel_emitter()
{
}
@ -64,7 +65,7 @@ void
RelButtonEventHandler::init(UInput& uinput, int slot, bool extra_devices)
{
m_code.resolve_device_id(slot, extra_devices);
uinput.add_rel(m_code.get_device_id(), m_code.code);
m_rel_emitter = uinput.add_rel(m_code.get_device_id(), m_code.code);
}
void
@ -74,7 +75,7 @@ RelButtonEventHandler::send(UInput& uinput, bool value)
{
if (value)
{
uinput.send_rel(m_code.get_device_id(), m_code.code, m_value);
m_rel_emitter->send(m_value);
}
}
else

View file

@ -21,6 +21,8 @@
#include "button_event.hpp"
#include "ui_event_emitter.hpp"
class RelButtonEventHandler : public ButtonEventHandler
{
public:
@ -40,6 +42,8 @@ private:
int m_value;
int m_repeat;
UIEventEmitterPtr m_rel_emitter;
};
#endif

42
src/ui_event_emitter.cpp Normal file
View file

@ -0,0 +1,42 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** 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 3 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/>.
*/
#include "ui_event_emitter.hpp"
#include <assert.h>
#include "uinput.hpp"
UIEventEmitter::UIEventEmitter(UInput& uinput,
uint32_t device_id,
int type,
int code) :
m_uinput(uinput),
m_device_id(device_id),
m_type(type),
m_code(code)
{
assert(m_code != -1);
}
void
UIEventEmitter::send(int value)
{
m_uinput.send(m_device_id, m_type, m_code, value);
}
/* EOF */

50
src/ui_event_emitter.hpp Normal file
View file

@ -0,0 +1,50 @@
/*
** Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
**
** 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 3 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 HEADER_XBOXDRV_UI_EVENT_EMITTER_HPP
#define HEADER_XBOXDRV_UI_EVENT_EMITTER_HPP
#include <boost/shared_ptr.hpp>
#include <stdint.h>
class UInput;
class UIEventEmitter;
typedef boost::shared_ptr<UIEventEmitter> UIEventEmitterPtr;
class UIEventEmitter
{
private:
UInput& m_uinput;
uint32_t m_device_id;
int m_type;
int m_code;
public:
UIEventEmitter(UInput& uinput, uint32_t device_id, int type, int code);
void send(int value);
private:
UIEventEmitter(const UIEventEmitter&);
UIEventEmitter& operator=(const UIEventEmitter&);
};
#endif
/* EOF */

View file

@ -41,17 +41,20 @@ UIEventSequence::from_string(const std::string& value)
}
UIEventSequence::UIEventSequence() :
m_sequence()
m_sequence(),
m_emitters()
{
}
UIEventSequence::UIEventSequence(const UIEvents& sequence) :
m_sequence(sequence)
m_sequence(sequence),
m_emitters()
{
}
UIEventSequence::UIEventSequence(const UIEvent& event) :
m_sequence(1, event)
m_sequence(1, event),
m_emitters()
{
}
@ -61,7 +64,7 @@ UIEventSequence::init(UInput& uinput, int slot, bool extra_devices)
for(UIEvents::iterator i = m_sequence.begin(); i != m_sequence.end(); ++i)
{
i->resolve_device_id(slot, extra_devices);
uinput.add_key(i->get_device_id(), i->code);
m_emitters.push_back(uinput.add_key(i->get_device_id(), i->code));
}
}
@ -70,17 +73,17 @@ UIEventSequence::send(UInput& uinput, int value)
{
if (value)
{
for(UIEvents::iterator i = m_sequence.begin(); i != m_sequence.end(); ++i)
for(UIEventEmitters::iterator i = m_emitters.begin(); i != m_emitters.end(); ++i)
{
uinput.send_key(i->get_device_id(), i->code, value);
(*i)->send(value);
}
}
else
{
// on release, send events in reverse order
for(UIEvents::reverse_iterator i = m_sequence.rbegin(); i != m_sequence.rend(); ++i)
for(UIEventEmitters::reverse_iterator i = m_emitters.rbegin(); i != m_emitters.rend(); ++i)
{
uinput.send_key(i->get_device_id(), i->code, value);
(*i)->send(value);
}
}
}

View file

@ -22,6 +22,7 @@
#include <vector>
#include "ui_event.hpp"
#include "ui_event_emitter.hpp"
class UInput;
@ -40,7 +41,9 @@ public:
private:
typedef std::vector<UIEvent> UIEvents;
typedef std::vector<UIEventEmitterPtr> UIEventEmitters;
UIEvents m_sequence;
UIEventEmitters m_emitters;
public:
UIEventSequence();

View file

@ -318,25 +318,31 @@ UInput::create_uinput_device(uint32_t device_id)
}
}
void
UIEventEmitterPtr
UInput::add_key(uint32_t device_id, int ev_code)
{
LinuxUinput* dev = create_uinput_device(device_id);
dev->add_key(ev_code);
return UIEventEmitterPtr(new UIEventEmitter(*this, device_id, EV_KEY, ev_code));
}
void
UIEventEmitterPtr
UInput::add_rel(uint32_t device_id, int ev_code)
{
LinuxUinput* dev = create_uinput_device(device_id);
dev->add_rel(ev_code);
return UIEventEmitterPtr(new UIEventEmitter(*this, device_id, EV_REL, ev_code));
}
void
UIEventEmitterPtr
UInput::add_abs(uint32_t device_id, int ev_code, int min, int max, int fuzz, int flat)
{
LinuxUinput* dev = create_uinput_device(device_id);
dev->add_abs(ev_code, min, max, fuzz, flat);
return UIEventEmitterPtr(new UIEventEmitter(*this, device_id, EV_KEY, ev_code));
}
void
@ -361,30 +367,6 @@ UInput::send(uint32_t device_id, int ev_type, int ev_code, int value)
get_uinput(device_id)->send(ev_type, ev_code, value);
}
void
UInput::send_abs(uint32_t device_id, int ev_code, int value)
{
assert(ev_code != -1);
get_uinput(device_id)->send(EV_ABS, ev_code, value);
}
void
UInput::send_key(uint32_t device_id, int ev_code, bool value)
{
assert(ev_code != -1);
get_uinput(device_id)->send(EV_KEY, ev_code, value);
}
void
UInput::send_rel(uint32_t device_id, int ev_code, int value)
{
assert(ev_code != -1);
if (value != 0)
{
get_uinput(device_id)->send(EV_REL, ev_code, value);
}
}
void
UInput::update(int msec_delta)
{

View file

@ -24,6 +24,7 @@
#include "axis_event.hpp"
#include "linux_uinput.hpp"
#include "ui_event_emitter.hpp"
struct Xbox360Msg;
struct XboxMsg;
@ -92,9 +93,9 @@ public:
/** Device construction functions
@{*/
void add_rel(uint32_t device_id, int ev_code);
void add_abs(uint32_t device_id, int ev_code, int min, int max, int fuzz, int flat);
void add_key(uint32_t device_id, int ev_code);
UIEventEmitterPtr add_rel(uint32_t device_id, int ev_code);
UIEventEmitterPtr add_abs(uint32_t device_id, int ev_code, int min, int max, int fuzz, int flat);
UIEventEmitterPtr add_key(uint32_t device_id, int ev_code);
void add_ff(uint32_t device_id, uint16_t code);
/** needs to be called to finish device creation and create the
@ -105,12 +106,9 @@ public:
/** Send events to the kernel
@{*/
void send(uint32_t device_id, int ev_type, int ev_code, int value);
void send_abs(uint32_t device_id, int ev_code, int value);
void send_key(uint32_t device_id, int ev_code, bool value);
void send_rel(uint32_t device_id, int ev_code, int value);
void send_rel_repetitive(const UIEvent& code, float value, int repeat_interval);
/** should be called to single that all events of the current frame
/** should be called to signal that all events of the current frame
have been send */
void sync();
/** @} */