Generalised input framework for raw mice, gamepads, trackers (incl. HMDs like Oculus Rift)
This commit is contained in:
parent
6480e82e3b
commit
bd0683d101
|
|
@ -3641,6 +3641,21 @@ if (not RUNTIME):
|
|||
TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph'])
|
||||
TargetAdd('libp3dgraph_igate.obj', input='libp3dgraph.in', opts=["DEPENDENCYONLY"])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/device/
|
||||
#
|
||||
|
||||
if (not RUNTIME):
|
||||
OPTS=['DIR:panda/src/device', 'BUILDING:PANDA']
|
||||
TargetAdd('p3device_composite1.obj', opts=OPTS, input='p3device_composite1.cxx')
|
||||
TargetAdd('p3device_composite2.obj', opts=OPTS, input='p3device_composite2.cxx')
|
||||
|
||||
OPTS=['DIR:panda/src/device']
|
||||
IGATEFILES=GetDirectoryContents('panda/src/device', ["*.h", "*_composite*.cxx"])
|
||||
TargetAdd('libp3device.in', opts=OPTS, input=IGATEFILES)
|
||||
TargetAdd('libp3device.in', opts=['IMOD:panda3d.core', 'ILIB:libp3device', 'SRCDIR:panda/src/device'])
|
||||
TargetAdd('libp3device_igate.obj', input='libp3device.in', opts=["DEPENDENCYONLY"])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/display/
|
||||
#
|
||||
|
|
@ -3665,21 +3680,6 @@ if (not RUNTIME):
|
|||
TargetAdd('subprocessWindowBuffer.obj', opts=OPTS, input='subprocessWindowBuffer.cxx')
|
||||
TargetAdd('libp3subprocbuffer.ilb', input='subprocessWindowBuffer.obj')
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/device/
|
||||
#
|
||||
|
||||
if (not RUNTIME):
|
||||
OPTS=['DIR:panda/src/device', 'BUILDING:PANDA']
|
||||
TargetAdd('p3device_composite1.obj', opts=OPTS, input='p3device_composite1.cxx')
|
||||
TargetAdd('p3device_composite2.obj', opts=OPTS, input='p3device_composite2.cxx')
|
||||
|
||||
OPTS=['DIR:panda/src/device']
|
||||
IGATEFILES=GetDirectoryContents('panda/src/device', ["*.h", "*_composite*.cxx"])
|
||||
TargetAdd('libp3device.in', opts=OPTS, input=IGATEFILES)
|
||||
TargetAdd('libp3device.in', opts=['IMOD:panda3d.core', 'ILIB:libp3device', 'SRCDIR:panda/src/device'])
|
||||
TargetAdd('libp3device_igate.obj', input='libp3device.in', opts=["DEPENDENCYONLY"])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/pnmtext/
|
||||
#
|
||||
|
|
|
|||
|
|
@ -44,10 +44,7 @@ is_valid() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnalogNode::
|
||||
get_num_controls() const {
|
||||
_analog->acquire();
|
||||
int result = _analog->get_num_controls();
|
||||
_analog->unlock();
|
||||
return result;
|
||||
return _analog->get_num_controls();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -60,10 +57,7 @@ get_num_controls() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double AnalogNode::
|
||||
get_control_state(int index) const {
|
||||
_analog->acquire();
|
||||
double result = _analog->get_control_state(index);
|
||||
_analog->unlock();
|
||||
return result;
|
||||
return _analog->get_control_state(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -75,10 +69,7 @@ get_control_state(int index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AnalogNode::
|
||||
is_control_known(int index) const {
|
||||
_analog->acquire();
|
||||
bool result = _analog->is_control_known(index);
|
||||
_analog->unlock();
|
||||
return result;
|
||||
return _analog->is_control_known(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ AnalogNode(ClientBase *client, const string &device_name) :
|
|||
DataNode(device_name)
|
||||
{
|
||||
_xy_output = define_output("xy", EventStoreVec2::get_class_type());
|
||||
_xy = new EventStoreVec2(LPoint2(0.0f, 0.0f));
|
||||
_xy = new EventStoreVec2(LPoint2(0));
|
||||
|
||||
nassertv(client != (ClientBase *)NULL);
|
||||
PT(ClientDevice) device =
|
||||
|
|
@ -49,7 +49,23 @@ AnalogNode(ClientBase *client, const string &device_name) :
|
|||
return;
|
||||
}
|
||||
|
||||
_analog = DCAST(ClientAnalogDevice, device);
|
||||
_analog = device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnalogNode::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnalogNode::
|
||||
AnalogNode(InputDevice *device) :
|
||||
DataNode(device->get_name()),
|
||||
_analog(device)
|
||||
{
|
||||
_xy_output = define_output("xy", EventStoreVec2::get_class_type());
|
||||
_xy = new EventStoreVec2(LPoint2(0));
|
||||
|
||||
nassertv(device != (InputDevice *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -74,9 +90,7 @@ write(ostream &out, int indent_level) const {
|
|||
DataNode::write(out, indent_level);
|
||||
|
||||
if (_analog != (ClientAnalogDevice *)NULL) {
|
||||
_analog->acquire();
|
||||
_analog->write_controls(out, indent_level + 2);
|
||||
_analog->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,8 +114,6 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
|||
_analog->poll();
|
||||
|
||||
LPoint2 out(0.0f, 0.0f);
|
||||
|
||||
_analog->acquire();
|
||||
for (int i = 0; i < max_outputs; i++) {
|
||||
if (_outputs[i]._index >= 0 &&
|
||||
_analog->is_control_known(_outputs[i]._index)) {
|
||||
|
|
@ -112,7 +124,6 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
|||
}
|
||||
}
|
||||
}
|
||||
_analog->unlock();
|
||||
_xy->set_value(out);
|
||||
output.set_data(_xy_output, EventParameter(_xy));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
class EXPCL_PANDA_DEVICE AnalogNode : public DataNode {
|
||||
PUBLISHED:
|
||||
AnalogNode(ClientBase *client, const string &device_name);
|
||||
AnalogNode(InputDevice *device);
|
||||
virtual ~AnalogNode();
|
||||
|
||||
INLINE bool is_valid() const;
|
||||
|
|
@ -73,7 +74,7 @@ private:
|
|||
enum { max_outputs = 2 };
|
||||
OutputData _outputs[max_outputs];
|
||||
|
||||
PT(ClientAnalogDevice) _analog;
|
||||
PT(InputDevice) _analog;
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ButtonNode::
|
||||
is_valid() const {
|
||||
return (_button != (ClientButtonDevice *)NULL) && _button->is_connected();
|
||||
return (_device != (ClientButtonDevice *)NULL) && _device->is_connected();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -36,10 +36,7 @@ is_valid() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int ButtonNode::
|
||||
get_num_buttons() const {
|
||||
_button->acquire();
|
||||
int result = _button->get_num_buttons();
|
||||
_button->unlock();
|
||||
return result;
|
||||
return _device->get_num_buttons();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -58,9 +55,7 @@ get_num_buttons() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ButtonNode::
|
||||
set_button_map(int index, ButtonHandle button) {
|
||||
_button->acquire();
|
||||
_button->set_button_map(index, button);
|
||||
_button->unlock();
|
||||
_device->set_button_map(index, button);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -73,10 +68,7 @@ set_button_map(int index, ButtonHandle button) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ButtonNode::
|
||||
get_button_map(int index) const {
|
||||
_button->acquire();
|
||||
ButtonHandle result = _button->get_button_map(index);
|
||||
_button->unlock();
|
||||
return result;
|
||||
return _device->get_button_map(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -88,10 +80,7 @@ get_button_map(int index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ButtonNode::
|
||||
get_button_state(int index) const {
|
||||
_button->acquire();
|
||||
bool result = _button->get_button_state(index);
|
||||
_button->unlock();
|
||||
return result;
|
||||
return _device->get_button_state(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -103,8 +92,5 @@ get_button_state(int index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ButtonNode::
|
||||
is_button_known(int index) const {
|
||||
_button->acquire();
|
||||
bool result = _button->is_button_known(index);
|
||||
_button->unlock();
|
||||
return result;
|
||||
return _device->is_button_known(index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ ButtonNode(ClientBase *client, const string &device_name) :
|
|||
DataNode(device_name)
|
||||
{
|
||||
_button_events_output = define_output("button_events", ButtonEventList::get_class_type());
|
||||
_button_events = new ButtonEventList;
|
||||
|
||||
nassertv(client != (ClientBase *)NULL);
|
||||
PT(ClientDevice) device =
|
||||
|
|
@ -49,7 +48,21 @@ ButtonNode(ClientBase *client, const string &device_name) :
|
|||
return;
|
||||
}
|
||||
|
||||
_button = DCAST(ClientButtonDevice, device);
|
||||
_device = device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonNode::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonNode::
|
||||
ButtonNode(InputDevice *device) :
|
||||
DataNode(device->get_name()),
|
||||
_device(device)
|
||||
{
|
||||
_button_events_output = define_output("button_events", ButtonEventList::get_class_type());
|
||||
_device = device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -59,7 +72,7 @@ ButtonNode(ClientBase *client, const string &device_name) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
ButtonNode::
|
||||
~ButtonNode() {
|
||||
// When the _button pointer destructs, the ClientButtonDevice
|
||||
// When the _device pointer destructs, the ClientButtonDevice
|
||||
// disconnects itself from the ClientBase, and everything that needs
|
||||
// to get turned off does. Magic.
|
||||
}
|
||||
|
|
@ -73,11 +86,9 @@ void ButtonNode::
|
|||
output(ostream &out) const {
|
||||
DataNode::output(out);
|
||||
|
||||
if (_button != (ClientButtonDevice *)NULL) {
|
||||
if (_device != (InputDevice *)NULL) {
|
||||
out << " (";
|
||||
_button->acquire();
|
||||
_button->output_buttons(out);
|
||||
_button->unlock();
|
||||
_device->output_buttons(out);
|
||||
out << ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -91,10 +102,8 @@ void ButtonNode::
|
|||
write(ostream &out, int indent_level) const {
|
||||
DataNode::write(out, indent_level);
|
||||
|
||||
if (_button != (ClientButtonDevice *)NULL) {
|
||||
_button->acquire();
|
||||
_button->write_buttons(out, indent_level + 2);
|
||||
_button->unlock();
|
||||
if (_device != (InputDevice *)NULL) {
|
||||
_device->write_buttons(out, indent_level + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,14 +124,7 @@ void ButtonNode::
|
|||
do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
||||
DataNodeTransmit &output) {
|
||||
if (is_valid()) {
|
||||
_button->poll();
|
||||
_button->acquire();
|
||||
|
||||
(*_button_events) = (*_button->get_button_events());
|
||||
|
||||
_button->get_button_events()->clear();
|
||||
_button->unlock();
|
||||
|
||||
output.set_data(_button_events_output, EventParameter(_button_events));
|
||||
PT(ButtonEventList) bel = _device->get_button_events();
|
||||
output.set_data(_button_events_output, EventParameter(bel));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
#include "clientBase.h"
|
||||
#include "clientButtonDevice.h"
|
||||
#include "dataNode.h"
|
||||
#include "buttonEventList.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ButtonNode
|
||||
|
|
@ -41,6 +39,7 @@
|
|||
class EXPCL_PANDA_DEVICE ButtonNode : public DataNode {
|
||||
PUBLISHED:
|
||||
ButtonNode(ClientBase *client, const string &device_name);
|
||||
ButtonNode(InputDevice *device);
|
||||
virtual ~ButtonNode();
|
||||
|
||||
INLINE bool is_valid() const;
|
||||
|
|
@ -58,7 +57,7 @@ public:
|
|||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
PT(ClientButtonDevice) _button;
|
||||
PT(InputDevice) _device;
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
|
|
@ -69,7 +68,6 @@ protected:
|
|||
private:
|
||||
// outputs
|
||||
int _button_events_output;
|
||||
PT(ButtonEventList) _button_events;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -13,18 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::AnalogState::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ClientAnalogDevice::AnalogState::
|
||||
AnalogState() :
|
||||
_state(0.0),
|
||||
_known(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::Constructor
|
||||
// Access: Protected
|
||||
|
|
@ -35,65 +23,3 @@ ClientAnalogDevice(ClientBase *client, const string &device_name):
|
|||
ClientDevice(client, get_class_type(), device_name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::get_num_controls
|
||||
// Access: Public
|
||||
// Description: Returns the number of analog controls known to the
|
||||
// ClientAnalogDevice. This number may change as
|
||||
// more controls are discovered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int ClientAnalogDevice::
|
||||
get_num_controls() const {
|
||||
return _controls.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::set_control_state
|
||||
// Access: Public
|
||||
// Description: Sets the state of the indicated analog index. The
|
||||
// caller should ensure that acquire() is in effect while
|
||||
// this call is made. This should be a number in the
|
||||
// range -1.0 to 1.0, representing the current position
|
||||
// of the control within its total range of movement.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ClientAnalogDevice::
|
||||
set_control_state(int index, double state) {
|
||||
ensure_control_index(index);
|
||||
nassertv(index >= 0 && index < (int)_controls.size());
|
||||
_controls[index]._state = state;
|
||||
_controls[index]._known = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::get_control_state
|
||||
// Access: Public
|
||||
// Description: Returns the current position of indicated analog
|
||||
// control (identified by its index number), or 0.0 if
|
||||
// the control is unknown. The normal range of a single
|
||||
// control is -1.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double ClientAnalogDevice::
|
||||
get_control_state(int index) const {
|
||||
if (index >= 0 && index < (int)_controls.size()) {
|
||||
return _controls[index]._state;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::is_control_known
|
||||
// Access: Public
|
||||
// Description: Returns true if the state of the indicated analog
|
||||
// control is known, or false if we have never heard
|
||||
// anything about this particular control.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClientAnalogDevice::
|
||||
is_control_known(int index) const {
|
||||
if (index >= 0 && index < (int)_controls.size()) {
|
||||
return _controls[index]._known;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,25 +19,6 @@
|
|||
|
||||
TypeHandle ClientAnalogDevice::_type_handle;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::ensure_control_index
|
||||
// Access: Private
|
||||
// Description: Guarantees that there is a slot in the array for the
|
||||
// indicated index number, by filling the array up to
|
||||
// that index if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientAnalogDevice::
|
||||
ensure_control_index(int index) {
|
||||
nassertv(index >= 0);
|
||||
|
||||
_controls.reserve(index + 1);
|
||||
while ((int)_controls.size() <= index) {
|
||||
_controls.push_back(AnalogState());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::write
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -45,32 +26,6 @@ ensure_control_index(int index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ClientAnalogDevice::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << get_type() << " " << get_device_name() << ":\n";
|
||||
indent(out, indent_level) << get_type() << " " << get_name() << ":\n";
|
||||
write_controls(out, indent_level + 2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientAnalogDevice::write_analogs
|
||||
// Access: Public
|
||||
// Description: Writes a multi-line description of the current analog
|
||||
// control states.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientAnalogDevice::
|
||||
write_controls(ostream &out, int indent_level) const {
|
||||
bool any_controls = false;
|
||||
Controls::const_iterator ai;
|
||||
for (ai = _controls.begin(); ai != _controls.end(); ++ai) {
|
||||
const AnalogState &state = (*ai);
|
||||
if (state._known) {
|
||||
any_controls = true;
|
||||
|
||||
indent(out, indent_level)
|
||||
<< (int)(ai - _controls.begin()) << ". " << state._state << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_controls) {
|
||||
indent(out, indent_level)
|
||||
<< "(no known analog controls)\n";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,30 +36,7 @@ protected:
|
|||
INLINE ClientAnalogDevice(ClientBase *client, const string &device_name);
|
||||
|
||||
public:
|
||||
INLINE int get_num_controls() const;
|
||||
|
||||
INLINE void set_control_state(int index, double state);
|
||||
INLINE double get_control_state(int index) const;
|
||||
INLINE bool is_control_known(int index) const;
|
||||
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
void write_controls(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
void ensure_control_index(int index);
|
||||
|
||||
protected:
|
||||
class AnalogState {
|
||||
public:
|
||||
INLINE AnalogState();
|
||||
|
||||
double _state;
|
||||
bool _known;
|
||||
};
|
||||
|
||||
typedef pvector<AnalogState> Controls;
|
||||
Controls _controls;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -144,7 +144,6 @@ get_device(TypeHandle device_type, const string &device_name) {
|
|||
|
||||
if (device != (ClientDevice *)NULL) {
|
||||
dbn.insert(DevicesByName::value_type(device_name, device));
|
||||
device->_is_connected = true;
|
||||
}
|
||||
|
||||
return device;
|
||||
|
|
|
|||
|
|
@ -12,113 +12,3 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::ButtonState::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ClientButtonDevice::ButtonState::
|
||||
ButtonState() :
|
||||
_handle(ButtonHandle::none()),
|
||||
_state(S_unknown)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::get_num_buttons
|
||||
// Access: Public
|
||||
// Description: Returns the number of buttons known to the
|
||||
// ClientButtonDevice. This includes those buttons
|
||||
// whose state has been seen, as well as buttons that
|
||||
// have been associated with a ButtonHandle even if
|
||||
// their state is unknown. This number may change as
|
||||
// more buttons are discovered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int ClientButtonDevice::
|
||||
get_num_buttons() const {
|
||||
return _buttons.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::set_button_map
|
||||
// Access: Public
|
||||
// Description: Associates the indicated ButtonHandle with the button
|
||||
// of the indicated index number. When the given button
|
||||
// index changes state, a corresponding ButtonEvent will
|
||||
// be generated with the given ButtonHandle. Pass
|
||||
// ButtonHandle::none() to turn off any association.
|
||||
//
|
||||
// It is not necessary to call this if you simply want
|
||||
// to query the state of the various buttons by index
|
||||
// number; this is only necessary in order to generate
|
||||
// ButtonEvents when the buttons change state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ClientButtonDevice::
|
||||
set_button_map(int index, ButtonHandle button) {
|
||||
ensure_button_index(index);
|
||||
nassertv(index >= 0 && index < (int)_buttons.size());
|
||||
_buttons[index]._handle = button;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::get_button_map
|
||||
// Access: Public
|
||||
// Description: Returns the ButtonHandle that was previously
|
||||
// associated with the given index number by
|
||||
// a call to set_button_map(), or ButtonHandle::none()
|
||||
// if no button was associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ClientButtonDevice::
|
||||
get_button_map(int index) const {
|
||||
if (index >= 0 && index < (int)_buttons.size()) {
|
||||
return _buttons[index]._handle;
|
||||
} else {
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::get_button_state
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated button (identified by
|
||||
// its index number) is currently known to be down, or
|
||||
// false if it is up or unknown.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClientButtonDevice::
|
||||
get_button_state(int index) const {
|
||||
if (index >= 0 && index < (int)_buttons.size()) {
|
||||
return (_buttons[index]._state == S_down);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::is_button_known
|
||||
// Access: Public
|
||||
// Description: Returns true if the state of the indicated button is
|
||||
// known, or false if we have never heard anything about
|
||||
// this particular button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClientButtonDevice::
|
||||
is_button_known(int index) const {
|
||||
if (index >= 0 && index < (int)_buttons.size()) {
|
||||
return _buttons[index]._state != S_unknown;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::get_button_events
|
||||
// Access: Public
|
||||
// Description: Returns the list of recently-generated ButtonEvents.
|
||||
// This must be periodically cleared, or the buttons
|
||||
// will accumulate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonEventList *ClientButtonDevice::
|
||||
get_button_events() const {
|
||||
return _button_events;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,47 +28,6 @@ ClientButtonDevice::
|
|||
ClientButtonDevice(ClientBase *client, const string &device_name):
|
||||
ClientDevice(client, get_class_type(), device_name)
|
||||
{
|
||||
_button_events = new ButtonEventList();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::set_button_state
|
||||
// Access: Public
|
||||
// Description: Sets the state of the indicated button index, where
|
||||
// true indicates down, and false indicates up. This
|
||||
// may generate a ButtonEvent if the button has an
|
||||
// associated ButtonHandle. The caller should ensure
|
||||
// that acquire() is in effect while this call is made.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientButtonDevice::
|
||||
set_button_state(int index, bool down) {
|
||||
ensure_button_index(index);
|
||||
nassertv(index >= 0 && index < (int)_buttons.size());
|
||||
_buttons[index]._state = down ? S_down : S_up;
|
||||
|
||||
ButtonHandle handle = _buttons[index]._handle;
|
||||
if (handle != ButtonHandle::none()) {
|
||||
_button_events->add_event(ButtonEvent(handle, down ? ButtonEvent::T_down : ButtonEvent::T_up));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::ensure_button_index
|
||||
// Access: Private
|
||||
// Description: Guarantees that there is a slot in the array for the
|
||||
// indicated index number, by filling the array up to
|
||||
// that index if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientButtonDevice::
|
||||
ensure_button_index(int index) {
|
||||
nassertv(index >= 0);
|
||||
|
||||
_buttons.reserve(index + 1);
|
||||
while ((int)_buttons.size() <= index) {
|
||||
_buttons.push_back(ButtonState());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -78,7 +37,7 @@ ensure_button_index(int index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ClientButtonDevice::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << " " << get_device_name() << " (";
|
||||
out << get_type() << " " << get_name() << " (";
|
||||
output_buttons(out);
|
||||
out << ")";
|
||||
}
|
||||
|
|
@ -90,74 +49,6 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ClientButtonDevice::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << get_type() << " " << get_device_name() << ":\n";
|
||||
indent(out, indent_level) << get_type() << " " << get_name() << ":\n";
|
||||
write_buttons(out, indent_level + 2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::output_buttons
|
||||
// Access: Public
|
||||
// Description: Writes a one-line string of all of the current button
|
||||
// states.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientButtonDevice::
|
||||
output_buttons(ostream &out) const {
|
||||
bool any_buttons = false;
|
||||
Buttons::const_iterator bi;
|
||||
for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
|
||||
const ButtonState &state = (*bi);
|
||||
if (state._state != S_unknown) {
|
||||
if (any_buttons) {
|
||||
out << ", ";
|
||||
}
|
||||
any_buttons = true;
|
||||
out << (int)(bi - _buttons.begin()) << "=";
|
||||
if (state._state == S_up) {
|
||||
out << "up";
|
||||
} else {
|
||||
out << "down";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_buttons) {
|
||||
out << "no known buttons";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientButtonDevice::write_buttons
|
||||
// Access: Public
|
||||
// Description: Writes a multi-line description of the current button
|
||||
// states.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientButtonDevice::
|
||||
write_buttons(ostream &out, int indent_level) const {
|
||||
bool any_buttons = false;
|
||||
Buttons::const_iterator bi;
|
||||
for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
|
||||
const ButtonState &state = (*bi);
|
||||
if (state._state != S_unknown) {
|
||||
any_buttons = true;
|
||||
|
||||
indent(out, indent_level)
|
||||
<< (int)(bi - _buttons.begin()) << ". ";
|
||||
|
||||
if (state._handle != ButtonHandle::none()) {
|
||||
out << "(" << state._handle << ") ";
|
||||
}
|
||||
|
||||
if (state._state == S_up) {
|
||||
out << "up";
|
||||
} else {
|
||||
out << "down";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_buttons) {
|
||||
indent(out, indent_level)
|
||||
<< "(no known buttons)\n";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,46 +39,9 @@ protected:
|
|||
ClientButtonDevice(ClientBase *client, const string &device_name);
|
||||
|
||||
public:
|
||||
INLINE int get_num_buttons() const;
|
||||
|
||||
INLINE void set_button_map(int index, ButtonHandle button);
|
||||
INLINE ButtonHandle get_button_map(int index) const;
|
||||
|
||||
void set_button_state(int index, bool down);
|
||||
INLINE bool get_button_state(int index) const;
|
||||
INLINE bool is_button_known(int index) const;
|
||||
|
||||
INLINE ButtonEventList *get_button_events() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
void output_buttons(ostream &out) const;
|
||||
void write_buttons(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
void ensure_button_index(int index);
|
||||
|
||||
protected:
|
||||
enum State {
|
||||
S_unknown,
|
||||
S_up,
|
||||
S_down
|
||||
};
|
||||
|
||||
class ButtonState {
|
||||
public:
|
||||
INLINE ButtonState();
|
||||
|
||||
ButtonHandle _handle;
|
||||
State _state;
|
||||
};
|
||||
|
||||
typedef pvector<ButtonState> Buttons;
|
||||
Buttons _buttons;
|
||||
|
||||
PT(ButtonEventList) _button_events;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
@ -95,7 +58,6 @@ public:
|
|||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
friend class ButtonState;
|
||||
};
|
||||
|
||||
#include "clientButtonDevice.I"
|
||||
|
|
|
|||
|
|
@ -24,17 +24,6 @@ get_client() const {
|
|||
return _client;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientDevice::is_connected
|
||||
// Access: Public
|
||||
// Description: Returns true if the device is still connected to its
|
||||
// ClientBase, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ClientDevice::
|
||||
is_connected() const {
|
||||
return _is_connected;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientDevice::get_device_type
|
||||
// Access: Public
|
||||
|
|
@ -50,45 +39,3 @@ INLINE TypeHandle ClientDevice::
|
|||
get_device_type() const {
|
||||
return _device_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientDevice::get_device_name
|
||||
// Access: Public
|
||||
// Description: Returns the device name reported to the ClientBase.
|
||||
// This has some implementation-defined meaning to
|
||||
// identify particular devices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &ClientDevice::
|
||||
get_device_name() const {
|
||||
return _device_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientDevice::acquire
|
||||
// Access: Public
|
||||
// Description: Grabs the mutex associated with this particular
|
||||
// device. The device will not update asynchronously
|
||||
// while the mutex is held, allowing the user to copy
|
||||
// the data out without fear of getting a partial update
|
||||
// during the copy.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ClientDevice::
|
||||
acquire() {
|
||||
#ifdef OLD_HAVE_IPC
|
||||
_lock.acquire();
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientDevice::unlock
|
||||
// Access: Public
|
||||
// Description: Releases the mutex associated with this particular
|
||||
// device. This should be called after all the data has
|
||||
// been successfully copied out. See acquire().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ClientDevice::
|
||||
unlock() {
|
||||
#ifdef OLD_HAVE_IPC
|
||||
_lock.unlock();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,15 +27,14 @@ TypeHandle ClientDevice::_type_handle;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
ClientDevice::
|
||||
ClientDevice(ClientBase *client, TypeHandle device_type,
|
||||
const string &device_name) :
|
||||
const string &device_name, int device_flags) :
|
||||
InputDevice(device_name, DC_unknown, device_flags),
|
||||
_client(client),
|
||||
_device_type(device_type),
|
||||
_device_name(device_name)
|
||||
_device_type(device_type)
|
||||
{
|
||||
// We have to explicitly ref the client pointer, since we can't use
|
||||
// a PT(ClientBase) for circular include reasons.
|
||||
_client->ref();
|
||||
_is_connected = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -49,7 +48,7 @@ ClientDevice(ClientBase *client, TypeHandle device_type,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
ClientDevice::
|
||||
~ClientDevice() {
|
||||
nassertv(!_is_connected);
|
||||
nassertv(!is_connected());
|
||||
|
||||
// And now we explicitly unref the client pointer.
|
||||
unref_delete(_client);
|
||||
|
|
@ -72,19 +71,17 @@ ClientDevice::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ClientDevice::
|
||||
disconnect() {
|
||||
if (_is_connected) {
|
||||
acquire();
|
||||
if (is_connected()) {
|
||||
bool disconnected =
|
||||
_client->disconnect_device(_device_type, _device_name, this);
|
||||
_is_connected = false;
|
||||
unlock();
|
||||
_client->disconnect_device(_device_type, get_name(), this);
|
||||
set_connected(false);
|
||||
nassertv(disconnected);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientDevice::poll
|
||||
// Access: Public
|
||||
// Function: ClientDevice::do_poll
|
||||
// Access: Public, Virtual, Final
|
||||
// Description: Causes the connected ClientBase to poll all of its
|
||||
// clients, if necessary. This will be a no-op if the
|
||||
// client is running in forked mode, or if it has
|
||||
|
|
@ -94,7 +91,7 @@ disconnect() {
|
|||
// data in this ClientDevice to ensure that it is fresh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClientDevice::
|
||||
poll() {
|
||||
do_poll() {
|
||||
_client->poll();
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +102,7 @@ poll() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ClientDevice::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << " " << get_device_name();
|
||||
out << get_type() << " " << get_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -16,12 +16,7 @@
|
|||
#define CLIENTDEVICE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "typedReferenceCount.h"
|
||||
|
||||
#ifdef OLD_HAVE_IPC
|
||||
#include <ipc_mutex.h>
|
||||
#endif
|
||||
#include "inputDevice.h"
|
||||
|
||||
class ClientBase;
|
||||
|
||||
|
|
@ -32,24 +27,20 @@ class ClientBase;
|
|||
// This is an abstract interface; the actual
|
||||
// implementations are in ClientTrackerDevice, etc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DEVICE ClientDevice : public TypedReferenceCount {
|
||||
class EXPCL_PANDA_DEVICE ClientDevice : public InputDevice {
|
||||
protected:
|
||||
ClientDevice(ClientBase *client, TypeHandle device_type,
|
||||
const string &device_name);
|
||||
const string &device_name, int device_flags=0);
|
||||
|
||||
public:
|
||||
virtual ~ClientDevice();
|
||||
|
||||
INLINE ClientBase *get_client() const;
|
||||
INLINE TypeHandle get_device_type() const;
|
||||
INLINE const string &get_device_name() const;
|
||||
|
||||
INLINE bool is_connected() const;
|
||||
void disconnect();
|
||||
|
||||
void poll();
|
||||
INLINE void acquire();
|
||||
INLINE void unlock();
|
||||
virtual void do_poll() FINAL;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
|
@ -57,21 +48,15 @@ public:
|
|||
private:
|
||||
ClientBase *_client;
|
||||
TypeHandle _device_type;
|
||||
string _device_name;
|
||||
bool _is_connected;
|
||||
|
||||
#ifdef OLD_HAVE_IPC
|
||||
mutex _lock;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
InputDevice::init_type();
|
||||
register_type(_type_handle, "ClientDevice",
|
||||
TypedReferenceCount::get_class_type());
|
||||
InputDevice::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -20,18 +20,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ClientTrackerDevice::
|
||||
ClientTrackerDevice(ClientBase *client, const string &device_name):
|
||||
ClientDevice(client, get_class_type(), device_name)
|
||||
ClientDevice(client, get_class_type(), device_name, IDF_has_tracker)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClientTrackerDevice::get_data
|
||||
// Access: Public
|
||||
// Description: Returns the TrackerData that this device is
|
||||
// reporting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TrackerData &ClientTrackerDevice::
|
||||
get_data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,12 +30,6 @@ class EXPCL_PANDA_DEVICE ClientTrackerDevice : public ClientDevice {
|
|||
protected:
|
||||
INLINE ClientTrackerDevice(ClientBase *client, const string &device_name);
|
||||
|
||||
public:
|
||||
INLINE const TrackerData &get_data() const;
|
||||
|
||||
protected:
|
||||
TrackerData _data;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
#include "clientDialDevice.h"
|
||||
#include "clientTrackerDevice.h"
|
||||
#include "dialNode.h"
|
||||
#include "mouseAndKeyboard.h"
|
||||
#include "evdevInputDevice.h"
|
||||
#include "inputDevice.h"
|
||||
#include "linuxJoystickDevice.h"
|
||||
#include "trackerNode.h"
|
||||
#include "virtualMouse.h"
|
||||
|
||||
|
|
@ -64,7 +66,12 @@ init_libdevice() {
|
|||
ClientDialDevice::init_type();
|
||||
ClientTrackerDevice::init_type();
|
||||
DialNode::init_type();
|
||||
MouseAndKeyboard::init_type();
|
||||
InputDevice::init_type();
|
||||
TrackerNode::init_type();
|
||||
VirtualMouse::init_type();
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
EvdevInputDevice::init_type();
|
||||
LinuxJoystickDevice::init_type();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,7 @@ is_valid() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DialNode::
|
||||
get_num_dials() const {
|
||||
_dial->acquire();
|
||||
int result = _dial->get_num_dials();
|
||||
_dial->unlock();
|
||||
return result;
|
||||
return _dial->get_num_dials();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -49,10 +46,7 @@ get_num_dials() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double DialNode::
|
||||
read_dial(int index) {
|
||||
_dial->acquire();
|
||||
double result = _dial->read_dial(index);
|
||||
_dial->unlock();
|
||||
return result;
|
||||
return _dial->read_dial(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -64,8 +58,5 @@ read_dial(int index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DialNode::
|
||||
is_dial_known(int index) const {
|
||||
_dial->acquire();
|
||||
bool result = _dial->is_dial_known(index);
|
||||
_dial->unlock();
|
||||
return result;
|
||||
return _dial->is_dial_known(index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
// Filename: evdevInputDevice.I
|
||||
// Created by: rdb (24Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
// Filename: evdevInputDevice.cxx
|
||||
// Created by: rdb (24Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "evdevInputDevice.h"
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
|
||||
#include "gamepadButton.h"
|
||||
#include "keyboardButton.h"
|
||||
#include "mouseButton.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)&7)))
|
||||
|
||||
TypeHandle EvdevInputDevice::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::Constructor
|
||||
// Access: Published
|
||||
// Description: Creates a new device using the Linux joystick
|
||||
// device using the given file descriptor. It will
|
||||
// be closed when this object destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EvdevInputDevice::
|
||||
EvdevInputDevice(int fd) :
|
||||
_fd(fd) {
|
||||
init_device();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::Constructor
|
||||
// Access: Published
|
||||
// Description: Creates a new device using the Linux joystick
|
||||
// device using the given device filename.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EvdevInputDevice::
|
||||
EvdevInputDevice(const string &fn) {
|
||||
_fd = open(fn.c_str(), O_RDONLY | O_NONBLOCK);
|
||||
|
||||
if (_fd >= 0) {
|
||||
init_device();
|
||||
} else {
|
||||
_is_connected = false;
|
||||
device_cat.error()
|
||||
<< "Opening raw input device: " << strerror(errno) << " " << fn << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EvdevInputDevice::
|
||||
~EvdevInputDevice() {
|
||||
if (_fd != -1) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::do_poll
|
||||
// Access: Private, Virtual
|
||||
// Description: Polls the input device for new activity, to ensure
|
||||
// it contains the latest events. This will only have
|
||||
// any effect for some types of input devices; others
|
||||
// may be updated automatically, and this method will
|
||||
// be a no-op.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EvdevInputDevice::
|
||||
do_poll() {
|
||||
if (_fd != -1) {
|
||||
while (process_events()) {}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::init_device
|
||||
// Access: Private
|
||||
// Description: Reads basic properties from the device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EvdevInputDevice::
|
||||
init_device() {
|
||||
uint8_t evtypes[EV_MAX/8 + 1];
|
||||
char name[256];
|
||||
char uniq[256];
|
||||
if (ioctl(_fd, EVIOCGNAME(sizeof(name)), name) < 0 ||
|
||||
ioctl(_fd, EVIOCGPHYS(sizeof(uniq)), uniq) < 0 ||
|
||||
ioctl(_fd, EVIOCGBIT(0, EV_MAX), &evtypes) < 0) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
_is_connected = false;
|
||||
device_cat.error() << "Opening raw input device: ioctl failed\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (char *p=name; *p; p++) {
|
||||
if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) {
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
for (char *p=uniq; *p; p++) {
|
||||
if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) {
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
|
||||
_name = ((string)name) + "." + uniq;
|
||||
|
||||
if (test_bit(EV_REL, evtypes)) {
|
||||
_flags |= IDF_has_pointer;
|
||||
}
|
||||
|
||||
if (test_bit(EV_FF, evtypes)) {
|
||||
_flags |= IDF_has_vibration;
|
||||
}
|
||||
|
||||
_is_connected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::process_events
|
||||
// Access: Private
|
||||
// Description: Reads a number of events from the device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EvdevInputDevice::
|
||||
process_events() {
|
||||
// Read 8 events at a time.
|
||||
struct input_event events[8];
|
||||
|
||||
int n_read = read(_fd, events, sizeof(events));
|
||||
if (n_read < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
// No data available for now.
|
||||
|
||||
} else if (errno == ENODEV || errno == EINVAL) {
|
||||
// The device ceased to exist, so we better close it.
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
_is_connected = false;
|
||||
errno = 0;
|
||||
|
||||
} else {
|
||||
device_cat.error() << "read: " << strerror(errno) << "\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n_read == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
n_read /= sizeof(struct input_event);
|
||||
|
||||
int x = _pointer_data.get_x();
|
||||
int y = _pointer_data.get_y();
|
||||
double time = ClockObject::get_global_clock()->get_frame_time();
|
||||
ButtonHandle button;
|
||||
|
||||
for (int i = 0; i < n_read; ++i) {
|
||||
switch (events[i].type) {
|
||||
case EV_SYN:
|
||||
break;
|
||||
|
||||
case EV_REL:
|
||||
if (events[i].code == REL_X) x += events[i].value;
|
||||
if (events[i].code == REL_Y) y += events[i].value;
|
||||
break;
|
||||
|
||||
case EV_ABS:
|
||||
if (events[i].code == ABS_X) x = events[i].value;
|
||||
if (events[i].code == ABS_Y) y = events[i].value;
|
||||
break;
|
||||
|
||||
case EV_KEY:
|
||||
button = map_button(events[i].code);
|
||||
_button_events->add_event(ButtonEvent(button, events[i].value ? ButtonEvent::T_down : ButtonEvent::T_up, time));
|
||||
break;
|
||||
|
||||
default:
|
||||
//cerr << "event " << events[i].type << " - " << events[i].code << " - " << events[i].value << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
set_pointer(true, x, y, time);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EvdevInputDevice::map_button
|
||||
// Access: Public, Static
|
||||
// Description: Maps an evdev code to a ButtonHandle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle EvdevInputDevice::
|
||||
map_button(int code) {
|
||||
if (code >= 0 && code < 0x80) {
|
||||
// See linux/input.h for the source of this mapping.
|
||||
static const ButtonHandle keyboard_map[] = {
|
||||
ButtonHandle::none(),
|
||||
KeyboardButton::escape(),
|
||||
KeyboardButton::ascii_key('1'),
|
||||
KeyboardButton::ascii_key('2'),
|
||||
KeyboardButton::ascii_key('3'),
|
||||
KeyboardButton::ascii_key('4'),
|
||||
KeyboardButton::ascii_key('5'),
|
||||
KeyboardButton::ascii_key('6'),
|
||||
KeyboardButton::ascii_key('7'),
|
||||
KeyboardButton::ascii_key('8'),
|
||||
KeyboardButton::ascii_key('9'),
|
||||
KeyboardButton::ascii_key('0'),
|
||||
KeyboardButton::ascii_key('-'),
|
||||
KeyboardButton::ascii_key('='),
|
||||
KeyboardButton::backspace(),
|
||||
KeyboardButton::tab(),
|
||||
KeyboardButton::ascii_key('q'),
|
||||
KeyboardButton::ascii_key('w'),
|
||||
KeyboardButton::ascii_key('e'),
|
||||
KeyboardButton::ascii_key('r'),
|
||||
KeyboardButton::ascii_key('t'),
|
||||
KeyboardButton::ascii_key('y'),
|
||||
KeyboardButton::ascii_key('u'),
|
||||
KeyboardButton::ascii_key('i'),
|
||||
KeyboardButton::ascii_key('o'),
|
||||
KeyboardButton::ascii_key('p'),
|
||||
KeyboardButton::ascii_key('['),
|
||||
KeyboardButton::ascii_key(']'),
|
||||
KeyboardButton::enter(),
|
||||
KeyboardButton::lcontrol(),
|
||||
KeyboardButton::ascii_key('a'),
|
||||
KeyboardButton::ascii_key('s'),
|
||||
KeyboardButton::ascii_key('d'),
|
||||
KeyboardButton::ascii_key('f'),
|
||||
KeyboardButton::ascii_key('g'),
|
||||
KeyboardButton::ascii_key('h'),
|
||||
KeyboardButton::ascii_key('j'),
|
||||
KeyboardButton::ascii_key('k'),
|
||||
KeyboardButton::ascii_key('l'),
|
||||
KeyboardButton::ascii_key(';'),
|
||||
KeyboardButton::ascii_key('\''),
|
||||
KeyboardButton::ascii_key('`'),
|
||||
KeyboardButton::lshift(),
|
||||
KeyboardButton::ascii_key('\\'),
|
||||
KeyboardButton::ascii_key('z'),
|
||||
KeyboardButton::ascii_key('x'),
|
||||
KeyboardButton::ascii_key('c'),
|
||||
KeyboardButton::ascii_key('v'),
|
||||
KeyboardButton::ascii_key('b'),
|
||||
KeyboardButton::ascii_key('n'),
|
||||
KeyboardButton::ascii_key('m'),
|
||||
KeyboardButton::ascii_key(','),
|
||||
KeyboardButton::ascii_key('.'),
|
||||
KeyboardButton::ascii_key('/'),
|
||||
KeyboardButton::rshift(),
|
||||
KeyboardButton::ascii_key('*'),
|
||||
KeyboardButton::lalt(),
|
||||
KeyboardButton::space(),
|
||||
KeyboardButton::caps_lock(),
|
||||
KeyboardButton::f1(),
|
||||
KeyboardButton::f2(),
|
||||
KeyboardButton::f3(),
|
||||
KeyboardButton::f4(),
|
||||
KeyboardButton::f5(),
|
||||
KeyboardButton::f6(),
|
||||
KeyboardButton::f7(),
|
||||
KeyboardButton::f8(),
|
||||
KeyboardButton::f9(),
|
||||
KeyboardButton::f10(),
|
||||
KeyboardButton::num_lock(),
|
||||
KeyboardButton::scroll_lock(),
|
||||
KeyboardButton::ascii_key('7'),
|
||||
KeyboardButton::ascii_key('8'),
|
||||
KeyboardButton::ascii_key('9'),
|
||||
KeyboardButton::ascii_key('-'),
|
||||
KeyboardButton::ascii_key('4'),
|
||||
KeyboardButton::ascii_key('5'),
|
||||
KeyboardButton::ascii_key('6'),
|
||||
KeyboardButton::ascii_key('+'),
|
||||
KeyboardButton::ascii_key('1'),
|
||||
KeyboardButton::ascii_key('2'),
|
||||
KeyboardButton::ascii_key('3'),
|
||||
KeyboardButton::ascii_key('0'),
|
||||
KeyboardButton::ascii_key('.'),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
KeyboardButton::f11(),
|
||||
KeyboardButton::f12(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
KeyboardButton::enter(),
|
||||
KeyboardButton::rcontrol(),
|
||||
KeyboardButton::ascii_key('/'),
|
||||
KeyboardButton::print_screen(),
|
||||
KeyboardButton::ralt(),
|
||||
ButtonHandle::none(),
|
||||
KeyboardButton::home(),
|
||||
KeyboardButton::up(),
|
||||
KeyboardButton::page_up(),
|
||||
KeyboardButton::left(),
|
||||
KeyboardButton::right(),
|
||||
KeyboardButton::end(),
|
||||
KeyboardButton::down(),
|
||||
KeyboardButton::page_down(),
|
||||
KeyboardButton::insert(),
|
||||
KeyboardButton::del(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
KeyboardButton::pause(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
ButtonHandle::none(),
|
||||
KeyboardButton::lmeta(),
|
||||
KeyboardButton::rmeta(),
|
||||
KeyboardButton::menu(),
|
||||
};
|
||||
return keyboard_map[code];
|
||||
|
||||
} else if (code < 0x100) {
|
||||
return ButtonHandle::none();
|
||||
|
||||
} else if ((code & 0xfff0) == BTN_MOUSE) {
|
||||
// The number for these is reversed in Panda.
|
||||
if (code == BTN_RIGHT) {
|
||||
return MouseButton::three();
|
||||
} else if (code == BTN_MIDDLE) {
|
||||
return MouseButton::two();
|
||||
} else {
|
||||
return MouseButton::button(code - BTN_MOUSE);
|
||||
}
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case BTN_A:
|
||||
return GamepadButton::action_a();
|
||||
|
||||
case BTN_B:
|
||||
return GamepadButton::action_b();
|
||||
|
||||
case BTN_C:
|
||||
return GamepadButton::action_c();
|
||||
|
||||
case BTN_X:
|
||||
return GamepadButton::action_x();
|
||||
|
||||
case BTN_Y:
|
||||
return GamepadButton::action_y();
|
||||
|
||||
case BTN_Z:
|
||||
return GamepadButton::action_z();
|
||||
|
||||
case BTN_TL:
|
||||
return GamepadButton::lshoulder();
|
||||
|
||||
case BTN_TR:
|
||||
return GamepadButton::rshoulder();
|
||||
|
||||
case BTN_TL2:
|
||||
return GamepadButton::ltrigger();
|
||||
|
||||
case BTN_TR2:
|
||||
return GamepadButton::rtrigger();
|
||||
|
||||
case BTN_SELECT:
|
||||
return GamepadButton::back();
|
||||
|
||||
case BTN_START:
|
||||
return GamepadButton::start();
|
||||
|
||||
case BTN_MODE:
|
||||
return GamepadButton::guide();
|
||||
|
||||
case BTN_THUMBL:
|
||||
return GamepadButton::lstick();
|
||||
|
||||
case BTN_THUMBR:
|
||||
return GamepadButton::rstick();
|
||||
|
||||
case BTN_TRIGGER_HAPPY1:
|
||||
return GamepadButton::dpad_left();
|
||||
|
||||
case BTN_TRIGGER_HAPPY2:
|
||||
return GamepadButton::dpad_right();
|
||||
|
||||
case BTN_TRIGGER_HAPPY3:
|
||||
return GamepadButton::dpad_up();
|
||||
|
||||
case BTN_TRIGGER_HAPPY4:
|
||||
return GamepadButton::dpad_down();
|
||||
|
||||
default:
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// Filename: evdevInputDevice.h
|
||||
// Created by: rdb (24Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EVDEVINPUTDEVICE_H
|
||||
#define EVDEVINPUTDEVICE_H
|
||||
|
||||
#include "inputDevice.h"
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EvdevInputDevice
|
||||
// Description : This is a type of device that uses the Linux
|
||||
// /dev/input/event# API to read data from a raw mouse.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DEVICE EvdevInputDevice : public InputDevice {
|
||||
PUBLISHED:
|
||||
EvdevInputDevice(int fd);
|
||||
EvdevInputDevice(const string &device);
|
||||
virtual ~EvdevInputDevice();
|
||||
|
||||
private:
|
||||
virtual void do_poll();
|
||||
|
||||
bool init_device();
|
||||
bool process_events();
|
||||
|
||||
private:
|
||||
int _fd;
|
||||
|
||||
public:
|
||||
static ButtonHandle map_button(int code);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
InputDevice::init_type();
|
||||
register_type(_type_handle, "EvdevInputDevice",
|
||||
InputDevice::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "evdevInputDevice.I"
|
||||
|
||||
#endif // PHAVE_LINUX_INPUT_H
|
||||
|
||||
#endif // EVDEVINPUTDEVICE_H
|
||||
|
|
@ -0,0 +1,445 @@
|
|||
// Filename: inputDevice.I
|
||||
// Created by: drose (24May00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::Default Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InputDevice::
|
||||
InputDevice() :
|
||||
_flags(0),
|
||||
_device_class(DC_unknown),
|
||||
_is_connected(false),
|
||||
_event_sequence(0),
|
||||
_enable_pointer_events(false),
|
||||
_battery_level(-1),
|
||||
_max_battery_level(-1)
|
||||
{
|
||||
_button_events = new ButtonEventList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_name
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string InputDevice::
|
||||
get_name() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::is_connected
|
||||
// Access: Public
|
||||
// Description: Returns true if the device is still connected and
|
||||
// able to receive data, false otherwise. May return
|
||||
// false positives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
is_connected() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _is_connected;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_device_class
|
||||
// Access: Public
|
||||
// Description: Returns an identification of the general type of
|
||||
// device. If this could not be determined, returns
|
||||
// DC_unknown.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InputDevice::DeviceClass InputDevice::
|
||||
get_device_class() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _device_class;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_pointer
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
has_pointer() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_flags & IDF_has_pointer) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_keyboard
|
||||
// Access: Public
|
||||
// Description: Returns true if the device has a physical keyboard
|
||||
// designed for text entry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
has_keyboard() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_flags & IDF_has_keyboard) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_tracker
|
||||
// Access: Public
|
||||
// Description: Returns true if the device features a tracker that
|
||||
// can track position and/or orientation in 3D space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
has_tracker() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_flags & IDF_has_tracker) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_battery
|
||||
// Access: Public
|
||||
// Description: Returns true if the device may be able to provide
|
||||
// information about its battery life.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
has_battery() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_flags & IDF_has_battery) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_axis
|
||||
// Access: Public
|
||||
// Description: Returns true if the device has the given axis.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
INLINE bool InputDevice::
|
||||
has_axis(Axis axis) const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_has_axes & (1 << axis)) != 0);
|
||||
}*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_pointer
|
||||
// Access: Public
|
||||
// Description: Returns the PointerData associated with the input
|
||||
// device's pointer. This only makes sense if
|
||||
// has_pointer() also returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PointerData InputDevice::
|
||||
get_pointer() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _pointer_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_tracker
|
||||
// Access: Public
|
||||
// Description: Returns the TrackerData associated with the input
|
||||
// device's tracker. This only makes sense if
|
||||
// has_tracker() also returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TrackerData InputDevice::
|
||||
get_tracker() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _tracker_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_battery_level
|
||||
// Access: Public
|
||||
// Description: Returns a rough indication of the battery level,
|
||||
// ranging from 0 (completely empty battery) to the
|
||||
// number reported by get_max_battery_level(), which
|
||||
// represents a full battery.
|
||||
// If this information is not known, returns -1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE short InputDevice::
|
||||
get_battery_level() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _battery_level;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_max_battery_level
|
||||
// Access: Public
|
||||
// Description: Returns the maximum value that may be reported by
|
||||
// get_battery_level(), representing a full battery.
|
||||
// Returns -1 if no battery information is known.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE short InputDevice::
|
||||
get_max_battery_level() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _max_battery_level;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_num_buttons
|
||||
// Access: Public
|
||||
// Description: Returns the number of buttons known to the
|
||||
// ClientButtonDevice. This includes those buttons
|
||||
// whose state has been seen, as well as buttons that
|
||||
// have been associated with a ButtonHandle even if
|
||||
// their state is unknown. This number may change as
|
||||
// more buttons are discovered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int InputDevice::
|
||||
get_num_buttons() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _buttons.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_button_map
|
||||
// Access: Public
|
||||
// Description: Associates the indicated ButtonHandle with the button
|
||||
// of the indicated index number. When the given button
|
||||
// index changes state, a corresponding ButtonEvent will
|
||||
// be generated with the given ButtonHandle. Pass
|
||||
// ButtonHandle::none() to turn off any association.
|
||||
//
|
||||
// It is not necessary to call this if you simply want
|
||||
// to query the state of the various buttons by index
|
||||
// number; this is only necessary in order to generate
|
||||
// ButtonEvents when the buttons change state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void InputDevice::
|
||||
set_button_map(int index, ButtonHandle button) {
|
||||
LightMutexHolder holder(_lock);
|
||||
nassertv(index >= 0);
|
||||
if (index >= (int)_buttons.size()) {
|
||||
_buttons.resize(index + 1, ButtonState());
|
||||
}
|
||||
|
||||
_buttons[index]._handle = button;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_button_map
|
||||
// Access: Public
|
||||
// Description: Returns the ButtonHandle that was previously
|
||||
// associated with the given index number by
|
||||
// a call to set_button_map(), or ButtonHandle::none()
|
||||
// if no button was associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle InputDevice::
|
||||
get_button_map(int index) const {
|
||||
if (index >= 0 && index < (int)_buttons.size()) {
|
||||
return _buttons[index]._handle;
|
||||
} else {
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_button_state
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated button (identified by
|
||||
// its index number) is currently known to be down, or
|
||||
// false if it is up or unknown.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
get_button_state(int index) const {
|
||||
if (index >= 0 && index < (int)_buttons.size()) {
|
||||
return (_buttons[index]._state == S_down);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::is_button_known
|
||||
// Access: Public
|
||||
// Description: Returns true if the state of the indicated button is
|
||||
// known, or false if we have never heard anything about
|
||||
// this particular button.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
is_button_known(int index) const {
|
||||
if (index >= 0 && index < (int)_buttons.size()) {
|
||||
return _buttons[index]._state != S_unknown;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_num_controls
|
||||
// Access: Public
|
||||
// Description: Returns the number of analog controls known to the
|
||||
// InputDevice. This number may change as
|
||||
// more controls are discovered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int InputDevice::
|
||||
get_num_controls() const {
|
||||
return _controls.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_control_map
|
||||
// Access: Public
|
||||
// Description: Associates the indicated ControlAxis with the
|
||||
// control of the indicated index number. Pass
|
||||
// C_none to turn off any association.
|
||||
//
|
||||
// It is not necessary to call this if you simply want
|
||||
// to query the state of the various controls by index
|
||||
// number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void InputDevice::
|
||||
set_control_map(int index, ControlAxis axis) {
|
||||
LightMutexHolder holder(_lock);
|
||||
nassertv(index >= 0);
|
||||
if (index >= (int)_controls.size()) {
|
||||
_controls.resize(index + 1, AnalogState());
|
||||
}
|
||||
|
||||
_controls[index]._axis = axis;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_control_map
|
||||
// Access: Public
|
||||
// Description: Returns the ControlAxis that was previously
|
||||
// associated with the given index number by
|
||||
// a call to set_control_map(), or C_none
|
||||
// if no control was associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InputDevice::ControlAxis InputDevice::
|
||||
get_control_map(int index) const {
|
||||
if (index >= 0 && index < (int)_controls.size()) {
|
||||
return _controls[index]._axis;
|
||||
} else {
|
||||
return C_none;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_control_state
|
||||
// Access: Public
|
||||
// Description: Returns the current position of indicated analog
|
||||
// control (identified by its index number), or 0.0 if
|
||||
// the control is unknown. The normal range of a single
|
||||
// control is -1.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double InputDevice::
|
||||
get_control_state(int index) const {
|
||||
if (index >= 0 && index < (int)_controls.size()) {
|
||||
return _controls[index]._state;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::is_control_known
|
||||
// Access: Public
|
||||
// Description: Returns true if the state of the indicated analog
|
||||
// control is known, or false if we have never heard
|
||||
// anything about this particular control.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
is_control_known(int index) const {
|
||||
if (index >= 0 && index < (int)_controls.size()) {
|
||||
return _controls[index]._known;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::enable_pointer_events
|
||||
// Access: Public
|
||||
// Description: Enables the generation of mouse-movement events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void InputDevice::
|
||||
enable_pointer_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
_enable_pointer_events = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::disable_pointer_events
|
||||
// Access: Public
|
||||
// Description: Disables the generation of mouse-movement events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void InputDevice::
|
||||
disable_pointer_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
_enable_pointer_events = false;
|
||||
_pointer_events.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_connected
|
||||
// Access: Protected
|
||||
// Description: Called to indicate that the device has been
|
||||
// disconnected or connected from its host.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void InputDevice::
|
||||
set_connected(bool connected) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_is_connected = connected;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::operator ==
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
operator == (const InputDevice &) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::operator !=
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
operator != (const InputDevice &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::operator <
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool InputDevice::
|
||||
operator < (const InputDevice &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::ButtonState::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InputDevice::ButtonState::
|
||||
ButtonState() :
|
||||
_handle(ButtonHandle::none()),
|
||||
_state(S_unknown)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::AnalogState::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InputDevice::AnalogState::
|
||||
AnalogState() :
|
||||
_axis(C_none),
|
||||
_state(0.0),
|
||||
_known(false)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,517 @@
|
|||
// Filename: inputDevice.cxx
|
||||
// Created by: drose (24May00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "inputDevice.h"
|
||||
|
||||
TypeHandle InputDevice::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::Constructor
|
||||
// Access: Private
|
||||
// Description: Defines a new InputDevice for the window. Most
|
||||
// windows will have exactly one InputDevice: a
|
||||
// keyboard/mouse pair. Some may also add joystick
|
||||
// data, or additional mice or something.
|
||||
//
|
||||
// This private constructor is only used internally by
|
||||
// the named constructors, below.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InputDevice::
|
||||
InputDevice(const string &name, DeviceClass dev_class, int flags) :
|
||||
_name(name),
|
||||
_flags(flags),
|
||||
_device_class(dev_class),
|
||||
_is_connected(true),
|
||||
_event_sequence(0),
|
||||
_enable_pointer_events(false),
|
||||
_battery_level(-1),
|
||||
_max_battery_level(-1)
|
||||
{
|
||||
_button_events = new ButtonEventList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InputDevice::
|
||||
InputDevice(const InputDevice ©) {
|
||||
*this = copy;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
operator = (const InputDevice ©) {
|
||||
LightMutexHolder holder(_lock);
|
||||
LightMutexHolder holder1(copy._lock);
|
||||
_name = copy._name;
|
||||
_flags = copy._flags;
|
||||
_is_connected = copy._is_connected;
|
||||
_event_sequence = copy._event_sequence;
|
||||
_enable_pointer_events = copy._enable_pointer_events;
|
||||
_pointer_data = copy._pointer_data;
|
||||
_button_events = copy._button_events;
|
||||
_pointer_events = copy._pointer_events;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InputDevice::
|
||||
~InputDevice() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::poll
|
||||
// Access: Public, Virtual
|
||||
// Description: Polls the input device for new activity, to ensure
|
||||
// it contains the latest events. This will only have
|
||||
// any effect for some types of input devices; others
|
||||
// may be updated automatically, and this method will
|
||||
// be a no-op.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
poll() {
|
||||
LightMutexHolder holder(_lock);
|
||||
do_poll();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_button_event
|
||||
// Access: Public
|
||||
// Description: Returns true if this device has a pending button
|
||||
// event (a mouse button or keyboard button down/up),
|
||||
// false otherwise. If this returns true, the
|
||||
// particular event may be extracted via
|
||||
// get_button_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool InputDevice::
|
||||
has_button_event() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return !_button_events.is_null() && _button_events->get_num_events() > 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_button_events
|
||||
// Access: Public
|
||||
// Description: Returns the list of recently-generated ButtonEvents.
|
||||
// The list is also cleared.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(ButtonEventList) InputDevice::
|
||||
get_button_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
PT(ButtonEventList) result = new ButtonEventList;
|
||||
swap(_button_events, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::has_pointer_event
|
||||
// Access: Public
|
||||
// Description: Returns true if this device has a pending pointer
|
||||
// event (a mouse movement), or false otherwise. If
|
||||
// this returns true, the particular event may be
|
||||
// extracted via get_pointer_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool InputDevice::
|
||||
has_pointer_event() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return (_pointer_events != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::get_pointer_events
|
||||
// Access: Public
|
||||
// Description: Returns a PointerEventList containing all the recent
|
||||
// pointer events. Clears the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PointerEventList) InputDevice::
|
||||
get_pointer_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
PT(PointerEventList) result = _pointer_events;
|
||||
_pointer_events.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_pointer
|
||||
// Access: Protected
|
||||
// Description: Records that a mouse movement has taken place.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
set_pointer(bool inwin, double x, double y, double time) {
|
||||
nassertv(_lock.debug_is_locked());
|
||||
_pointer_data._in_window = inwin;
|
||||
_pointer_data._xpos = x;
|
||||
_pointer_data._ypos = y;
|
||||
|
||||
if (_enable_pointer_events) {
|
||||
int seq = _event_sequence++;
|
||||
if (_pointer_events.is_null()) {
|
||||
_pointer_events = new PointerEventList();
|
||||
}
|
||||
_pointer_events->add_event(_pointer_data._in_window,
|
||||
_pointer_data._xpos,
|
||||
_pointer_data._ypos,
|
||||
seq, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_pointer_out_of_window
|
||||
// Access: Protected
|
||||
// Description: Records that the mouse pointer has left the window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
set_pointer_out_of_window(double time) {
|
||||
nassertv(_lock.debug_is_locked());
|
||||
_pointer_data._in_window = false;
|
||||
|
||||
if (_enable_pointer_events) {
|
||||
int seq = _event_sequence++;
|
||||
if (_pointer_events.is_null()) {
|
||||
_pointer_events = new PointerEventList();
|
||||
}
|
||||
_pointer_events->add_event(_pointer_data._in_window,
|
||||
_pointer_data._xpos,
|
||||
_pointer_data._ypos,
|
||||
seq, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_button_state
|
||||
// Access: Protected
|
||||
// Description: Sets the state of the indicated button index, where
|
||||
// true indicates down, and false indicates up. This
|
||||
// may generate a ButtonEvent if the button has an
|
||||
// associated ButtonHandle. The caller should ensure
|
||||
// that acquire() is in effect while this call is made.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
set_button_state(int index, bool down) {
|
||||
nassertv(_lock.debug_is_locked());
|
||||
nassertv(index >= 0);
|
||||
if (index >= (int)_buttons.size()) {
|
||||
_buttons.resize(index + 1, ButtonState());
|
||||
}
|
||||
|
||||
_buttons[index]._state = down ? S_down : S_up;
|
||||
|
||||
ButtonHandle handle = _buttons[index]._handle;
|
||||
if (handle != ButtonHandle::none()) {
|
||||
_button_events->add_event(ButtonEvent(handle, down ? ButtonEvent::T_down : ButtonEvent::T_up));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_control_state
|
||||
// Access: Protected
|
||||
// Description: Sets the state of the indicated analog index. The
|
||||
// caller should ensure that acquire() is in effect while
|
||||
// this call is made. This should be a number in the
|
||||
// range -1.0 to 1.0, representing the current position
|
||||
// of the control within its total range of movement.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
set_control_state(int index, double state) {
|
||||
nassertv(_lock.debug_is_locked());
|
||||
nassertv(index >= 0);
|
||||
if (index >= (int)_controls.size()) {
|
||||
_controls.resize(index + 1, AnalogState());
|
||||
}
|
||||
|
||||
_controls[index]._state = state;
|
||||
_controls[index]._known = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::set_tracker
|
||||
// Access: Protected
|
||||
// Description: Records that a tracker movement has taken place.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
set_tracker(const LPoint3 &pos, const LOrientation &orient, double time) {
|
||||
nassertv(_lock.debug_is_locked());
|
||||
|
||||
_tracker_data.set_pos(pos);
|
||||
_tracker_data.set_orient(orient);
|
||||
_tracker_data.set_time(time);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::output
|
||||
// Access: Public
|
||||
// Description: Writes a one-line string describing the device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
output(ostream &out) const {
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
out << _name << " (";
|
||||
|
||||
if (!_is_connected) {
|
||||
out << "dis";
|
||||
}
|
||||
|
||||
out << "connected)";
|
||||
|
||||
if (_device_class != DC_unknown) {
|
||||
out << ", " << _device_class;
|
||||
}
|
||||
|
||||
if (_buttons.size() > 0) {
|
||||
out << ", " << _buttons.size() << " buttons";
|
||||
}
|
||||
|
||||
if (_controls.size() > 0) {
|
||||
out << ", " << _controls.size() << " controls";
|
||||
}
|
||||
|
||||
if (_flags & IDF_has_pointer) {
|
||||
out << ", pointer";
|
||||
}
|
||||
if (_flags & IDF_has_keyboard) {
|
||||
out << ", keyboard";
|
||||
}
|
||||
if (_flags & IDF_has_tracker) {
|
||||
out << ", tracker";
|
||||
}
|
||||
if (_flags & IDF_has_vibration) {
|
||||
out << ", vibration";
|
||||
}
|
||||
if (_flags & IDF_has_battery) {
|
||||
out << ", battery";
|
||||
|
||||
if (_battery_level > 0 && _max_battery_level > 0) {
|
||||
out << " [";
|
||||
short i = 0;
|
||||
for (; i < _battery_level - 1; ++i) {
|
||||
out << '=';
|
||||
}
|
||||
out << '/';
|
||||
for (; i < _max_battery_level; ++i) {
|
||||
out << ' ';
|
||||
}
|
||||
out << ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::output_buttons
|
||||
// Access: Public
|
||||
// Description: Writes a one-line string of all of the current button
|
||||
// states.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
output_buttons(ostream &out) const {
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
bool any_buttons = false;
|
||||
Buttons::const_iterator bi;
|
||||
for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
|
||||
const ButtonState &state = (*bi);
|
||||
if (state._state != S_unknown) {
|
||||
if (any_buttons) {
|
||||
out << ", ";
|
||||
}
|
||||
any_buttons = true;
|
||||
out << (int)(bi - _buttons.begin()) << "=";
|
||||
if (state._state == S_up) {
|
||||
out << "up";
|
||||
} else {
|
||||
out << "down";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_buttons) {
|
||||
out << "no known buttons";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::write_buttons
|
||||
// Access: Public
|
||||
// Description: Writes a multi-line description of the current button
|
||||
// states.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
write_buttons(ostream &out, int indent_level) const {
|
||||
bool any_buttons = false;
|
||||
Buttons::const_iterator bi;
|
||||
for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
|
||||
const ButtonState &state = (*bi);
|
||||
if (state._state != S_unknown) {
|
||||
any_buttons = true;
|
||||
|
||||
indent(out, indent_level)
|
||||
<< (int)(bi - _buttons.begin()) << ". ";
|
||||
|
||||
if (state._handle != ButtonHandle::none()) {
|
||||
out << "(" << state._handle << ") ";
|
||||
}
|
||||
|
||||
if (state._state == S_up) {
|
||||
out << "up";
|
||||
} else {
|
||||
out << "down";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_buttons) {
|
||||
indent(out, indent_level)
|
||||
<< "(no known buttons)\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::write_controls
|
||||
// Access: Public
|
||||
// Description: Writes a multi-line description of the current analog
|
||||
// control states.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
write_controls(ostream &out, int indent_level) const {
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
bool any_controls = false;
|
||||
Controls::const_iterator ai;
|
||||
for (ai = _controls.begin(); ai != _controls.end(); ++ai) {
|
||||
const AnalogState &state = (*ai);
|
||||
if (state._known) {
|
||||
any_controls = true;
|
||||
|
||||
indent(out, indent_level)
|
||||
<< (int)(ai - _controls.begin()) << ". " << state._state << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_controls) {
|
||||
indent(out, indent_level)
|
||||
<< "(no known analog controls)\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDevice::do_poll
|
||||
// Access: Protected, Virtual
|
||||
// Description: Polls the input device for new activity, to ensure
|
||||
// it contains the latest events. This will only have
|
||||
// any effect for some types of input devices; others
|
||||
// may be updated automatically, and this method will
|
||||
// be a no-op.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDevice::
|
||||
do_poll() {
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator << (ostream &out, InputDevice::DeviceClass dc) {
|
||||
switch (dc) {
|
||||
case InputDevice::DC_unknown:
|
||||
out << "unknown";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_virtual:
|
||||
out << "virtual";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_keyboard:
|
||||
out << "keyboard";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_mouse:
|
||||
out << "mouse";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_touch:
|
||||
out << "touch";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_gamepad:
|
||||
out << "gamepad";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_flight_stick:
|
||||
out << "flight_stick";
|
||||
break;
|
||||
|
||||
case InputDevice::DC_steering_wheel:
|
||||
out << "steering_wheel";
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator << (ostream &out, InputDevice::ControlAxis axis) {
|
||||
switch (axis) {
|
||||
case InputDevice::C_none:
|
||||
out << "none";
|
||||
break;
|
||||
|
||||
case InputDevice::C_left_x:
|
||||
out << "left_x";
|
||||
break;
|
||||
|
||||
case InputDevice::C_left_y:
|
||||
out << "left_y";
|
||||
break;
|
||||
|
||||
case InputDevice::C_left_trigger:
|
||||
out << "left_trigger";
|
||||
break;
|
||||
|
||||
case InputDevice::C_right_x:
|
||||
out << "right_x";
|
||||
break;
|
||||
|
||||
case InputDevice::C_right_y:
|
||||
out << "right_y";
|
||||
break;
|
||||
|
||||
case InputDevice::C_right_trigger:
|
||||
out << "right_trigger";
|
||||
break;
|
||||
|
||||
case InputDevice::C_x:
|
||||
out << "x";
|
||||
break;
|
||||
|
||||
case InputDevice::C_y:
|
||||
out << "y";
|
||||
break;
|
||||
|
||||
case InputDevice::C_trigger:
|
||||
out << "trigger";
|
||||
break;
|
||||
|
||||
case InputDevice::C_throttle:
|
||||
out << "throttle";
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
// Filename: inputDevice.h
|
||||
// Created by: drose (24May00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INPUTDEVICE_H
|
||||
#define INPUTDEVICE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "buttonEvent.h"
|
||||
#include "buttonEventList.h"
|
||||
#include "pointerEvent.h"
|
||||
#include "pointerEventList.h"
|
||||
#include "mouseData.h"
|
||||
#include "trackerData.h"
|
||||
#include "clockObject.h"
|
||||
|
||||
#include "pdeque.h"
|
||||
#include "pvector.h"
|
||||
#include "lightMutex.h"
|
||||
#include "lightMutexHolder.h"
|
||||
|
||||
typedef MouseData PointerData;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : InputDevice
|
||||
// Description : This is a structure representing a single input
|
||||
// device. Input devices may have zero or more
|
||||
// buttons, pointers, or controls associated with them,
|
||||
// and optionally a tracker.
|
||||
//
|
||||
// These devices are brought under a common interface
|
||||
// because there is such a large range of devices out
|
||||
// there that may support any number of these types of
|
||||
// controls, we couldn't even begin to cover them with
|
||||
// type-specific subclasses.
|
||||
//
|
||||
// Use the various has_() and get_num_() methods to
|
||||
// determine information about the device capabilities.
|
||||
// For instance, has_keyboard() will give an indication
|
||||
// that you can receive keystroke events from this
|
||||
// device, and get_num_buttons() will tell you that
|
||||
// the device may send button events.
|
||||
//
|
||||
// There is the DeviceType enumeration, however, which
|
||||
// will (if known) contain identification about the
|
||||
// general category of devices this fits in, such as
|
||||
// keyboard, mouse, gamepad, or flight stick.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
|
||||
PUBLISHED:
|
||||
// This enum contains information that can be used to identify the
|
||||
// type of input device.
|
||||
enum DeviceClass {
|
||||
DC_unknown,
|
||||
|
||||
// This means that the device doesn't correspond to a physical
|
||||
// device, but rather to a dynamic source of input events.
|
||||
DC_virtual,
|
||||
|
||||
// A physical, alphabetical keyboard.
|
||||
DC_keyboard,
|
||||
|
||||
DC_mouse,
|
||||
DC_touch,
|
||||
|
||||
// A gamepad with action buttons, a D-pad, and thumbsticks.
|
||||
DC_gamepad,
|
||||
|
||||
DC_flight_stick,
|
||||
DC_steering_wheel,
|
||||
};
|
||||
|
||||
protected:
|
||||
InputDevice(const string &name, DeviceClass dev_class, int flags);
|
||||
|
||||
public:
|
||||
InputDevice();
|
||||
InputDevice(const InputDevice ©);
|
||||
void operator = (const InputDevice ©);
|
||||
~InputDevice();
|
||||
|
||||
PUBLISHED:
|
||||
enum ControlAxis {
|
||||
C_none,
|
||||
|
||||
// Gamepad
|
||||
C_left_x,
|
||||
C_left_y,
|
||||
C_left_trigger,
|
||||
C_right_x,
|
||||
C_right_y,
|
||||
C_right_trigger,
|
||||
|
||||
// Flight stick
|
||||
C_x,
|
||||
C_y,
|
||||
C_trigger,
|
||||
C_throttle,
|
||||
};
|
||||
|
||||
INLINE string get_name() const;
|
||||
INLINE bool is_connected() const;
|
||||
INLINE DeviceClass get_device_class() const;
|
||||
|
||||
// The human-readable name of this input device.
|
||||
MAKE_PROPERTY(name, get_name);
|
||||
|
||||
// This is false if we know that the device is not currently connected.
|
||||
// May report false positives if we can't know this with certainty.
|
||||
MAKE_PROPERTY(connected, is_connected);
|
||||
|
||||
// This contains an identification of the general type of device. If
|
||||
// this could not be determined, it is set to DC_unknown.
|
||||
MAKE_PROPERTY(device_class, get_device_class);
|
||||
|
||||
INLINE bool has_pointer() const;
|
||||
INLINE bool has_keyboard() const;
|
||||
INLINE bool has_tracker() const;
|
||||
INLINE bool has_battery() const;
|
||||
|
||||
INLINE PointerData get_pointer() const;
|
||||
INLINE TrackerData get_tracker() const;
|
||||
|
||||
INLINE short get_battery_level() const;
|
||||
INLINE short get_max_battery_level() const;
|
||||
|
||||
INLINE int get_num_buttons() const;
|
||||
INLINE void set_button_map(int index, ButtonHandle button);
|
||||
INLINE ButtonHandle get_button_map(int index) const;
|
||||
INLINE bool get_button_state(int index) const;
|
||||
INLINE bool is_button_known(int index) const;
|
||||
|
||||
INLINE int get_num_controls() const;
|
||||
INLINE void set_control_map(int index, ControlAxis axis);
|
||||
INLINE ControlAxis get_control_map(int index) const;
|
||||
INLINE double get_control_state(int index) const;
|
||||
INLINE bool is_control_known(int index) const;
|
||||
|
||||
INLINE void enable_pointer_events();
|
||||
INLINE void disable_pointer_events();
|
||||
|
||||
void poll();
|
||||
|
||||
bool has_button_event() const;
|
||||
PT(ButtonEventList) get_button_events();
|
||||
bool has_pointer_event() const;
|
||||
PT(PointerEventList) get_pointer_events();
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
protected:
|
||||
void set_pointer(bool inwin, double x, double y, double time);
|
||||
void set_pointer_out_of_window(double time);
|
||||
void set_button_state(int index, bool down);
|
||||
void set_control_state(int index, double state);
|
||||
void set_tracker(const LPoint3 &pos, const LOrientation &orient, double time);
|
||||
|
||||
virtual void do_poll();
|
||||
|
||||
public:
|
||||
INLINE void set_connected(bool connected);
|
||||
|
||||
// We need these methods to make VC++ happy when we try to
|
||||
// instantiate a pvector<InputDevice>. They don't do
|
||||
// anything useful.
|
||||
INLINE bool operator == (const InputDevice &other) const;
|
||||
INLINE bool operator != (const InputDevice &other) const;
|
||||
INLINE bool operator < (const InputDevice &other) const;
|
||||
|
||||
void output_buttons(ostream &out) const;
|
||||
void write_buttons(ostream &out, int indent_level) const;
|
||||
void write_controls(ostream &out, int indent_level) const;
|
||||
|
||||
protected:
|
||||
enum InputDeviceFlags {
|
||||
// The device provides absolute screen coordinates.
|
||||
IDF_has_pointer = 0x01,
|
||||
|
||||
// The device has an interface for providing text input.
|
||||
IDF_has_keyboard = 0x02,
|
||||
|
||||
// The device has a motion tracker, such as an HMD.
|
||||
IDF_has_tracker = 0x04,
|
||||
|
||||
// The device can produce force feedback.
|
||||
IDF_has_vibration = 0x08,
|
||||
|
||||
// The device provides information about battery life.
|
||||
IDF_has_battery = 0x10,
|
||||
};
|
||||
|
||||
protected:
|
||||
typedef pdeque<ButtonEvent> ButtonEvents;
|
||||
|
||||
LightMutex _lock;
|
||||
|
||||
string _name;
|
||||
DeviceClass _device_class;
|
||||
int _flags;
|
||||
int _event_sequence;
|
||||
bool _is_connected;
|
||||
bool _enable_pointer_events;
|
||||
PointerData _pointer_data;
|
||||
PT(ButtonEventList) _button_events;
|
||||
PT(PointerEventList) _pointer_events;
|
||||
|
||||
public:
|
||||
enum State {
|
||||
S_unknown,
|
||||
S_up,
|
||||
S_down
|
||||
};
|
||||
|
||||
class ButtonState {
|
||||
public:
|
||||
INLINE ButtonState();
|
||||
|
||||
ButtonHandle _handle;
|
||||
State _state;
|
||||
};
|
||||
typedef pvector<ButtonState> Buttons;
|
||||
Buttons _buttons;
|
||||
|
||||
class AnalogState {
|
||||
public:
|
||||
INLINE AnalogState();
|
||||
|
||||
ControlAxis _axis;
|
||||
double _state;
|
||||
bool _known;
|
||||
};
|
||||
typedef pvector<AnalogState> Controls;
|
||||
Controls _controls;
|
||||
|
||||
short _battery_level;
|
||||
short _max_battery_level;
|
||||
|
||||
TrackerData _tracker_data;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "InputDevice",
|
||||
TypedReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const InputDevice &device) {
|
||||
device.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
ostream &operator << (ostream &out, InputDevice::DeviceClass dc);
|
||||
ostream &operator << (ostream &out, InputDevice::ControlAxis axis);
|
||||
|
||||
#include "inputDevice.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Filename: inputDeviceManager.I
|
||||
// Created by: rdb (09Dec15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::get_global_ptr
|
||||
// Access: Published, Static
|
||||
// Description: Returns the singleton instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InputDeviceManager *InputDeviceManager::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == (InputDeviceManager *)NULL) {
|
||||
_global_ptr = new InputDeviceManager;
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
// Filename: inputDeviceManager.cxx
|
||||
// Created by: rdb (09Dec15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "inputDeviceManager.h"
|
||||
#include "linuxJoystickDevice.h"
|
||||
#include "throw_event.h"
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
InputDeviceManager *InputDeviceManager::_global_ptr = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::Constructor
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InputDeviceManager::
|
||||
InputDeviceManager() : _inotify_fd(-1) {
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
// Scan /dev/input for a list of input devices.
|
||||
DIR *dir = opendir("/dev/input");
|
||||
if (dir) {
|
||||
dirent *entry = readdir(dir);
|
||||
while (entry != NULL) {
|
||||
if (entry->d_type == DT_CHR) {
|
||||
string name(entry->d_name);
|
||||
if (!consider_add_linux_device(name)) {
|
||||
// We can't access it. That's pretty normal for most devices.
|
||||
if (device_cat.is_debug()) {
|
||||
device_cat.debug()
|
||||
<< "Ignoring input device /dev/input/" << name << ": "
|
||||
<< strerror(errno) << "\n";
|
||||
}
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
entry = readdir(dir);
|
||||
}
|
||||
closedir(dir);
|
||||
} else {
|
||||
device_cat.error()
|
||||
<< "Error opening directory /dev/input: " << strerror(errno) << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Use inotify to watch /dev/input for hotplugging of devices.
|
||||
_inotify_fd = inotify_init1(O_NONBLOCK);
|
||||
|
||||
if (_inotify_fd < 0) {
|
||||
device_cat.error()
|
||||
<< "Error initializing inotify: " << strerror(errno) << "\n";
|
||||
|
||||
} else if (inotify_add_watch(_inotify_fd, "/dev/input", IN_CREATE | IN_ATTRIB | IN_DELETE) < 0) {
|
||||
device_cat.error()
|
||||
<< "Error adding inotify watch on /dev/input: " << strerror(errno) << "\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::Destructor
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InputDeviceManager::
|
||||
~InputDeviceManager() {
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
if (_inotify_fd >= 0) {
|
||||
close(_inotify_fd);
|
||||
_inotify_fd = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::consider_add_linux_device
|
||||
// Access: Private
|
||||
// Description: Checks whether the given device is accessible, and
|
||||
// if so, adds it. Returns false on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool InputDeviceManager::
|
||||
consider_add_linux_device(const string &name) {
|
||||
// Get the full path name first.
|
||||
string path = "/dev/input/";
|
||||
path += name;
|
||||
|
||||
if (access(path.c_str(), R_OK) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_devices_by_path.count(name)) {
|
||||
// We already have this device.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it's a joystick or game controller device.
|
||||
if (name.size() > 2 && name[0] == 'j' && name[1] == 's' && isdigit(name[2])) {
|
||||
PT(InputDevice) device = new LinuxJoystickDevice(path);
|
||||
if (device_cat.is_info()) {
|
||||
device_cat.info()
|
||||
<< "Discovered input device " << *device << "\n";
|
||||
}
|
||||
|
||||
_devices_by_path[name] = device;
|
||||
_all_devices.push_back(MOVE(device));
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::add_device
|
||||
// Access: Public
|
||||
// Description: Called when a new device has been discovered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDeviceManager::
|
||||
add_device(InputDevice *device) {
|
||||
{
|
||||
LightMutexHolder holder(_lock);
|
||||
_all_devices.push_back(device);
|
||||
}
|
||||
throw_event("device-added", device);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::remove_device
|
||||
// Access: Public
|
||||
// Description: Called when a device has been removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDeviceManager::
|
||||
remove_device(InputDevice *device) {
|
||||
{
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
InputDevices::iterator it;
|
||||
it = std::find(_all_devices.begin(), _all_devices.end(), device);
|
||||
nassertv_always(it != _all_devices.end());
|
||||
|
||||
_all_devices.erase(it);
|
||||
}
|
||||
|
||||
throw_event("device-removed", device);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InputDeviceManager::poll
|
||||
// Access: Public
|
||||
// Description: Polls the system to see if there are any new devices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InputDeviceManager::
|
||||
poll() {
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
// We use inotify to tell us whether a device was added, removed,
|
||||
// or has changed permissions to allow us to access it.
|
||||
unsigned int avail;
|
||||
ioctl(_inotify_fd, FIONREAD, &avail);
|
||||
if (avail == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[avail];
|
||||
int n_read = read(_inotify_fd, buffer, avail);
|
||||
if (n_read < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
// No data available for now.
|
||||
|
||||
} else {
|
||||
device_cat.error() << "read: " << strerror(errno) << "\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
// Iterate over the events in the buffer.
|
||||
char *ptr = buffer;
|
||||
char *end = buffer + avail;
|
||||
while (ptr < end) {
|
||||
inotify_event *event = (inotify_event *)ptr;
|
||||
|
||||
string name(event->name);
|
||||
|
||||
if (event->mask & IN_DELETE) {
|
||||
// The device was deleted. If we have it, remove it.
|
||||
DevicesByPath::iterator it = _devices_by_path.find(name);
|
||||
if (it != _devices_by_path.end()) {
|
||||
PT(InputDevice) device = it->second;
|
||||
device->set_connected(false);
|
||||
|
||||
InputDevices::iterator it2;
|
||||
_devices_by_path.erase(it);
|
||||
it2 = std::find(_all_devices.begin(), _all_devices.end(), device);
|
||||
_all_devices.erase(it2);
|
||||
|
||||
if (device_cat.is_info()) {
|
||||
device_cat.info()
|
||||
<< "Removed input device " << *device << "\n";
|
||||
}
|
||||
throw_event("device-removed", device.p());
|
||||
}
|
||||
|
||||
} else if (event->mask & (IN_CREATE | IN_ATTRIB)) {
|
||||
// The device was created, or it was chmodded to be accessible.
|
||||
DevicesByPath::iterator it = _devices_by_path.find(name);
|
||||
if (it == _devices_by_path.end()) {
|
||||
// We don't know about this device yet.
|
||||
if (!consider_add_linux_device(name) && (event->mask & IN_CREATE) != 0) {
|
||||
if (device_cat.is_debug()) {
|
||||
device_cat.debug()
|
||||
<< "Ignoring input device /dev/input/" << name << ": "
|
||||
<< strerror(errno) << "\n";
|
||||
}
|
||||
}
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ptr += sizeof(inotify_event) + event->len;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// Filename: inputDeviceManager.h
|
||||
// Created by: rdb (09Dec15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INPUTDEVICEMANAGER_H
|
||||
#define INPUTDEVICEMANAGER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "lightMutex.h"
|
||||
#include "inputDevice.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : InputDeviceManager
|
||||
// Description : This class keeps track of all the devices on a
|
||||
// system, and sends out events when a device has been
|
||||
// hot-plugged.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DEVICE InputDeviceManager {
|
||||
private:
|
||||
InputDeviceManager();
|
||||
~InputDeviceManager();
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
bool consider_add_linux_device(const string &name);
|
||||
#endif
|
||||
|
||||
public:
|
||||
void add_device(InputDevice *device);
|
||||
void remove_device(InputDevice *device);
|
||||
|
||||
PUBLISHED:
|
||||
void poll();
|
||||
|
||||
INLINE static InputDeviceManager *get_global_ptr();
|
||||
|
||||
private:
|
||||
LightMutex _lock;
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
int _inotify_fd;
|
||||
|
||||
typedef pmap<string, InputDevice*> DevicesByPath;
|
||||
DevicesByPath _devices_by_path;
|
||||
#endif
|
||||
|
||||
typedef pvector<PT(InputDevice)> InputDevices;
|
||||
InputDevices _all_devices;
|
||||
|
||||
static InputDeviceManager *_global_ptr;
|
||||
};
|
||||
|
||||
#include "inputDeviceManager.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Filename: linuxJoystickDevice.I
|
||||
// Created by: rdb (21Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
// Filename: linuxJoystickDevice.cxx
|
||||
// Created by: rdb (21Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "linuxJoystickDevice.h"
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
|
||||
#include "gamepadButton.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/joystick.h>
|
||||
|
||||
TypeHandle LinuxJoystickDevice::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinuxJoystickDevice::Constructor
|
||||
// Access: Private
|
||||
// Description: Creates a new device using the Linux joystick
|
||||
// device using the given device filename.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LinuxJoystickDevice::
|
||||
LinuxJoystickDevice(const string &device) :
|
||||
_fd(-1),
|
||||
_device(device)
|
||||
{
|
||||
LightMutexHolder holder(_lock);
|
||||
if (!open_device()) {
|
||||
device_cat.error()
|
||||
<< "Could not open joystick device " << _device
|
||||
<< ": " << strerror(errno) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinuxJoystickDevice::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LinuxJoystickDevice::
|
||||
~LinuxJoystickDevice() {
|
||||
if (_fd != -1) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinuxJoystickDevice::do_poll
|
||||
// Access: Private, Virtual
|
||||
// Description: Polls the input device for new activity, to ensure
|
||||
// it contains the latest events. This will only have
|
||||
// any effect for some types of input devices; others
|
||||
// may be updated automatically, and this method will
|
||||
// be a no-op.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LinuxJoystickDevice::
|
||||
do_poll() {
|
||||
if (_fd != -1) {
|
||||
while (process_events()) {}
|
||||
} else {
|
||||
open_device();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinuxJoystickDevice::open_device
|
||||
// Access: Private
|
||||
// Description: Opens or reopens the joystick device, and reads out
|
||||
// the button and axis mappings.
|
||||
// Assumes the lock has been held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LinuxJoystickDevice::
|
||||
open_device() {
|
||||
nassertr(_lock.debug_is_locked(), false);
|
||||
|
||||
_fd = open(_device.c_str(), O_RDONLY | O_NONBLOCK);
|
||||
|
||||
if (_fd == -1) {
|
||||
_is_connected = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the name from the device.
|
||||
char name[128];
|
||||
name[0] = 0;
|
||||
ioctl(_fd, JSIOCGNAME(sizeof(name)), name);
|
||||
_name = name;
|
||||
|
||||
// Get the number of axes.
|
||||
PN_uint8 num_axes = 0, num_buttons = 0;
|
||||
ioctl(_fd, JSIOCGAXES, &num_axes);
|
||||
ioctl(_fd, JSIOCGBUTTONS, &num_buttons);
|
||||
|
||||
_buttons.resize(num_buttons);
|
||||
_controls.resize(num_axes);
|
||||
|
||||
if (num_buttons > 0) {
|
||||
PN_uint16 btnmap[512];
|
||||
ioctl(_fd, JSIOCGBTNMAP, btnmap);
|
||||
|
||||
for (char i = 0; i < num_buttons; ++i) {
|
||||
ButtonHandle handle = ButtonHandle::none();
|
||||
switch (btnmap[i]) {
|
||||
case BTN_A:
|
||||
handle = GamepadButton::action_a();
|
||||
_device_class = DC_gamepad;
|
||||
break;
|
||||
|
||||
case BTN_B:
|
||||
handle = GamepadButton::action_b();
|
||||
break;
|
||||
|
||||
case BTN_C:
|
||||
handle = GamepadButton::action_c();
|
||||
break;
|
||||
|
||||
case BTN_X:
|
||||
handle = GamepadButton::action_x();
|
||||
break;
|
||||
|
||||
case BTN_Y:
|
||||
handle = GamepadButton::action_y();
|
||||
break;
|
||||
|
||||
case BTN_Z:
|
||||
handle = GamepadButton::action_z();
|
||||
break;
|
||||
|
||||
case BTN_TL:
|
||||
handle = GamepadButton::lshoulder();
|
||||
break;
|
||||
|
||||
case BTN_TR:
|
||||
handle = GamepadButton::rshoulder();
|
||||
break;
|
||||
|
||||
case BTN_TL2:
|
||||
handle = GamepadButton::ltrigger();
|
||||
break;
|
||||
|
||||
case BTN_TR2:
|
||||
handle = GamepadButton::rtrigger();
|
||||
break;
|
||||
|
||||
case BTN_SELECT:
|
||||
handle = GamepadButton::back();
|
||||
break;
|
||||
|
||||
case BTN_START:
|
||||
handle = GamepadButton::start();
|
||||
break;
|
||||
|
||||
case BTN_MODE:
|
||||
handle = GamepadButton::guide();
|
||||
break;
|
||||
|
||||
case BTN_THUMBL:
|
||||
handle = GamepadButton::lstick();
|
||||
break;
|
||||
|
||||
case BTN_THUMBR:
|
||||
handle = GamepadButton::rstick();
|
||||
break;
|
||||
|
||||
case BTN_TRIGGER_HAPPY1:
|
||||
handle = GamepadButton::dpad_left();
|
||||
break;
|
||||
|
||||
case BTN_TRIGGER_HAPPY2:
|
||||
handle = GamepadButton::dpad_right();
|
||||
break;
|
||||
|
||||
case BTN_TRIGGER_HAPPY3:
|
||||
handle = GamepadButton::dpad_up();
|
||||
break;
|
||||
|
||||
case BTN_TRIGGER_HAPPY4:
|
||||
handle = GamepadButton::dpad_down();
|
||||
break;
|
||||
|
||||
default:
|
||||
handle = ButtonHandle::none();
|
||||
break;
|
||||
}
|
||||
_buttons[i]._handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_axes > 0) {
|
||||
PN_uint8 axmap[512];
|
||||
ioctl(_fd, JSIOCGAXMAP, axmap);
|
||||
|
||||
for (char i = 0; i < num_axes; ++i) {
|
||||
ControlAxis axis = C_none;
|
||||
|
||||
switch (axmap[i]) {
|
||||
case ABS_X:
|
||||
if (_device_class == DC_gamepad) {
|
||||
axis = C_left_x;
|
||||
} else {
|
||||
axis = C_x;
|
||||
}
|
||||
break;
|
||||
|
||||
case ABS_Y:
|
||||
if (_device_class == DC_gamepad) {
|
||||
axis = C_left_y;
|
||||
} else {
|
||||
axis = C_y;
|
||||
}
|
||||
break;
|
||||
|
||||
case ABS_Z:
|
||||
if (_device_class == DC_gamepad) {
|
||||
axis = C_left_trigger;
|
||||
} else {
|
||||
axis = C_trigger;
|
||||
}
|
||||
break;
|
||||
|
||||
case ABS_RX:
|
||||
axis = C_right_x;
|
||||
break;
|
||||
|
||||
case ABS_RY:
|
||||
axis = C_right_y;
|
||||
break;
|
||||
|
||||
case ABS_RZ:
|
||||
axis = C_right_trigger;
|
||||
break;
|
||||
|
||||
default:
|
||||
axis = C_none;
|
||||
break;
|
||||
}
|
||||
_controls[i]._axis = axis;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the init events.
|
||||
_is_connected = true;
|
||||
while (process_events()) {};
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinuxJoystickDevice::process_events
|
||||
// Access: Private
|
||||
// Description: Reads a number of events from the joystick.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool LinuxJoystickDevice::
|
||||
process_events() {
|
||||
// Read 8 events at a time.
|
||||
struct js_event events[8];
|
||||
|
||||
int n_read = read(_fd, events, sizeof(events));
|
||||
if (n_read < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
// No data available for now.
|
||||
|
||||
} else if (errno == ENODEV) {
|
||||
// The device ceased to exist, so we better close it.
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
_is_connected = false;
|
||||
errno = 0;
|
||||
|
||||
} else {
|
||||
device_cat.error() << "read: " << strerror(errno) << "\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n_read == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
n_read /= sizeof(struct js_event);
|
||||
|
||||
for (int i = 0; i < n_read; ++i) {
|
||||
int index = events[i].number;
|
||||
|
||||
if (events[i].type & JS_EVENT_BUTTON) {
|
||||
set_button_state(index, (events[i].value != 0));
|
||||
|
||||
} else if (events[i].type & JS_EVENT_AXIS) {
|
||||
ControlAxis axis = _controls[index]._axis;
|
||||
|
||||
if (axis == C_left_trigger || axis == C_right_trigger || axis == C_trigger) {
|
||||
// We'd like to use 0.0 to indicate the resting position.
|
||||
set_control_state(index, (events[i].value + 32767) / 65534.0);
|
||||
} else {
|
||||
set_control_state(index, events[i].value / 32767.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// Filename: linuxJoystickDevice.h
|
||||
// Created by: rdb (21Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LINUXJOYSTICKDEVICE_H
|
||||
#define LINUXJOYSTICKDEVICE_H
|
||||
|
||||
#include "inputDevice.h"
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LinuxJoystickDevice
|
||||
// Description : This is a type of device that uses the Linux
|
||||
// /dev/input/js# API to read data from a game controller.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DEVICE LinuxJoystickDevice : public InputDevice {
|
||||
PUBLISHED:
|
||||
LinuxJoystickDevice(const string &device);
|
||||
virtual ~LinuxJoystickDevice();
|
||||
|
||||
private:
|
||||
virtual void do_poll();
|
||||
|
||||
bool open_device();
|
||||
bool process_events();
|
||||
|
||||
private:
|
||||
int _fd;
|
||||
string _device;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
InputDevice::init_type();
|
||||
register_type(_type_handle, "LinuxJoystickDevice",
|
||||
InputDevice::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "linuxJoystickDevice.I"
|
||||
|
||||
#endif // PHAVE_LINUX_INPUT_H
|
||||
|
||||
#endif // LINUXJOYSTICKDEVICE_H
|
||||
|
|
@ -5,4 +5,7 @@
|
|||
#include "clientDevice.cxx"
|
||||
#include "clientDialDevice.cxx"
|
||||
#include "clientTrackerDevice.cxx"
|
||||
|
||||
#include "evdevInputDevice.cxx"
|
||||
#include "inputDevice.cxx"
|
||||
#include "inputDeviceManager.cxx"
|
||||
#include "linuxJoystickDevice.cxx"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include "analogNode.cxx"
|
||||
#include "buttonNode.cxx"
|
||||
#include "dialNode.cxx"
|
||||
#include "mouseAndKeyboard.cxx"
|
||||
#include "trackerData.cxx"
|
||||
#include "trackerNode.cxx"
|
||||
#include "virtualMouse.cxx"
|
||||
|
|
|
|||
|
|
@ -20,10 +20,9 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TrackerNode::
|
||||
is_valid() const {
|
||||
return (_tracker != (ClientTrackerDevice *)NULL) && _tracker->is_connected();
|
||||
return (!_tracker.is_null()/* && _tracker->is_connected()*/);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TrackerNode::get_pos
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ TrackerNode(ClientBase *client, const string &device_name) :
|
|||
return;
|
||||
}
|
||||
|
||||
_tracker = DCAST(ClientTrackerDevice, device);
|
||||
_tracker = device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -60,18 +60,19 @@ TrackerNode(ClientBase *client, const string &device_name) :
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TrackerNode::
|
||||
TrackerNode(ClientTrackerDevice *device) :
|
||||
DataNode(device->get_device_name()),
|
||||
TrackerNode(InputDevice *device) :
|
||||
DataNode(device->get_name()),
|
||||
_tracker(device)
|
||||
{
|
||||
_transform_output = define_output("transform", TransformState::get_class_type());
|
||||
|
||||
_transform = TransformState::make_identity();
|
||||
|
||||
nassertv(device != (ClientTrackerDevice *)NULL);
|
||||
ClientBase *client = device->get_client();
|
||||
nassertv(client != (ClientBase *)NULL);
|
||||
set_tracker_coordinate_system(client->get_coordinate_system());
|
||||
nassertv(device != (InputDevice *)NULL);
|
||||
nassertv(device->has_tracker());
|
||||
|
||||
//TODO: get coordinate system from tracker object?
|
||||
set_tracker_coordinate_system(CS_default);
|
||||
set_graph_coordinate_system(CS_default);
|
||||
}
|
||||
|
||||
|
|
@ -105,9 +106,7 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
|||
DataNodeTransmit &output) {
|
||||
if (is_valid()) {
|
||||
_tracker->poll();
|
||||
_tracker->acquire();
|
||||
_data = _tracker->get_data();
|
||||
_tracker->unlock();
|
||||
_data = _tracker->get_tracker();
|
||||
|
||||
_data.get_orient().extract_to_matrix(_mat);
|
||||
if (_tracker_cs != _graph_cs) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "clientBase.h"
|
||||
#include "trackerData.h"
|
||||
#include "clientTrackerDevice.h"
|
||||
#include "inputDevice.h"
|
||||
#include "dataNode.h"
|
||||
#include "luse.h"
|
||||
#include "linmath_events.h"
|
||||
|
|
@ -27,16 +27,16 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TrackerNode
|
||||
// Description : This is the primary interface to a Tracker object
|
||||
// associated with a ClientBase. It reads the position
|
||||
// and orientation information from the tracker and
|
||||
// makes it available as a transformation on the data
|
||||
// graph.
|
||||
// Description : This class reads the position and orientation
|
||||
// information from a tracker device and makes it
|
||||
// available as a transformation on the data graph.
|
||||
// It is also the primary interface to a Tracker object
|
||||
// associated with a ClientBase.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DEVICE TrackerNode : public DataNode {
|
||||
PUBLISHED:
|
||||
TrackerNode(ClientBase *client, const string &device_name);
|
||||
TrackerNode(ClientTrackerDevice *device);
|
||||
TrackerNode(InputDevice *device);
|
||||
virtual ~TrackerNode();
|
||||
|
||||
INLINE bool is_valid() const;
|
||||
|
|
@ -66,7 +66,7 @@ private:
|
|||
CPT(TransformState) _transform;
|
||||
|
||||
private:
|
||||
PT(ClientTrackerDevice) _tracker;
|
||||
PT(InputDevice) _tracker;
|
||||
TrackerData _data;
|
||||
LMatrix4 _mat;
|
||||
CoordinateSystem _tracker_cs, _graph_cs;
|
||||
|
|
|
|||
|
|
@ -54,22 +54,6 @@ CallbackGraphicsWindow::
|
|||
~CallbackGraphicsWindow() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::get_input_device
|
||||
// Access: Published
|
||||
// Description: Returns a writable reference to the nth input device
|
||||
// (mouse). This is intended to be used for the window
|
||||
// implementation to record mouse and keyboard input
|
||||
// information for the Panda system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice &CallbackGraphicsWindow::
|
||||
get_input_device(int device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), _input_devices[0]);
|
||||
return _input_devices[device];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CallbackGraphicsWindow::create_input_device
|
||||
// Access: Published
|
||||
|
|
@ -79,9 +63,7 @@ get_input_device(int device) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int CallbackGraphicsWindow::
|
||||
create_input_device(const string &name) {
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, name);
|
||||
return add_input_device(device);
|
||||
return add_input_device(GraphicsWindowInputDevice::pointer_and_keyboard(this, name));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -182,7 +182,6 @@ PUBLISHED:
|
|||
INLINE void clear_render_callback();
|
||||
INLINE CallbackObject *get_render_callback() const;
|
||||
|
||||
GraphicsWindowInputDevice &get_input_device(int device);
|
||||
int create_input_device(const string &name);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@
|
|||
#include "graphicsPipe.h"
|
||||
#include "graphicsOutput.h"
|
||||
#include "graphicsBuffer.h"
|
||||
#include "graphicsWindow.h"
|
||||
#include "graphicsDevice.h"
|
||||
#include "graphicsWindow.h"
|
||||
#include "graphicsWindowInputDevice.h"
|
||||
#include "graphicsWindowProcCallbackData.h"
|
||||
#include "mouseAndKeyboard.h"
|
||||
#include "nativeWindowHandle.h"
|
||||
#include "parasiteBuffer.h"
|
||||
#include "pandaSystem.h"
|
||||
|
|
@ -501,7 +503,9 @@ init_libdisplay() {
|
|||
GraphicsPipe::init_type();
|
||||
GraphicsStateGuardian::init_type();
|
||||
GraphicsWindow::init_type();
|
||||
GraphicsWindowInputDevice::init_type();
|
||||
GraphicsWindowProcCallbackData::init_type();
|
||||
MouseAndKeyboard::init_type();
|
||||
NativeWindowHandle::init_type();
|
||||
ParasiteBuffer::init_type();
|
||||
StandardMunger::init_type();
|
||||
|
|
|
|||
|
|
@ -288,6 +288,20 @@ get_num_input_devices() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_input_device
|
||||
// Access: Published
|
||||
// Description: Returns the nth input device associated with the
|
||||
// window. Typically, a window will have exactly one
|
||||
// input device: the keyboard/mouse pair.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InputDevice *GraphicsWindow::
|
||||
get_input_device(int device) const {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), NULL);
|
||||
return _input_devices[device];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_input_device_name
|
||||
// Access: Published
|
||||
|
|
@ -299,7 +313,7 @@ get_input_device_name(int device) const {
|
|||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), "");
|
||||
result = _input_devices[device].get_name();
|
||||
result = _input_devices[device]->get_name();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -317,7 +331,7 @@ has_pointer(int device) const {
|
|||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
|
||||
result = _input_devices[device].has_pointer();
|
||||
result = _input_devices[device]->has_pointer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -334,7 +348,7 @@ has_keyboard(int device) const {
|
|||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
|
||||
result = _input_devices[device].has_keyboard();
|
||||
result = _input_devices[device]->has_keyboard();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -359,7 +373,7 @@ void GraphicsWindow::
|
|||
enable_pointer_events(int device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].enable_pointer_events();
|
||||
_input_devices[device]->enable_pointer_events();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -371,7 +385,7 @@ void GraphicsWindow::
|
|||
disable_pointer_events(int device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].disable_pointer_events();
|
||||
_input_devices[device]->disable_pointer_events();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -379,11 +393,11 @@ disable_pointer_events(int device) {
|
|||
// Access: Published
|
||||
// Description: See GraphicsWindowInputDevice::enable_pointer_mode
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindow::
|
||||
/*void GraphicsWindow::
|
||||
enable_pointer_mode(int device, double speed) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].enable_pointer_mode(speed);
|
||||
_input_devices[device]->enable_pointer_mode(speed);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -395,8 +409,8 @@ void GraphicsWindow::
|
|||
disable_pointer_mode(int device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertv(device >= 0 && device < (int)_input_devices.size());
|
||||
_input_devices[device].disable_pointer_mode();
|
||||
}
|
||||
_input_devices[device]->disable_pointer_mode();
|
||||
}*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_pointer
|
||||
|
|
@ -412,7 +426,7 @@ get_pointer(int device) const {
|
|||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData());
|
||||
result = _input_devices[device].get_pointer();
|
||||
result = _input_devices[device]->get_pointer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -443,81 +457,6 @@ close_ime() {
|
|||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::has_button_event
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated device has a pending
|
||||
// button event (a mouse button or keyboard button
|
||||
// down/up), false otherwise. If this returns true, the
|
||||
// particular event may be extracted via
|
||||
// get_button_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindow::
|
||||
has_button_event(int device) const {
|
||||
bool result;
|
||||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
|
||||
result = _input_devices[device].has_button_event();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_button_event
|
||||
// Access: Public
|
||||
// Description: Assuming a previous call to has_button_event()
|
||||
// returned true, this returns the pending button event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonEvent GraphicsWindow::
|
||||
get_button_event(int device) {
|
||||
ButtonEvent result;
|
||||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), ButtonEvent());
|
||||
nassertr(_input_devices[device].has_button_event(), ButtonEvent());
|
||||
result = _input_devices[device].get_button_event();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::has_pointer_event
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated device has a pending
|
||||
// pointer event (a mouse movement). If this returns
|
||||
// true, the particular event may be extracted via
|
||||
// get_pointer_events().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindow::
|
||||
has_pointer_event(int device) const {
|
||||
bool result;
|
||||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), false);
|
||||
result = _input_devices[device].has_pointer_event();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_pointer_events
|
||||
// Access: Public
|
||||
// Description: Assuming a previous call to has_pointer_event()
|
||||
// returned true, this returns the pending pointer event list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PointerEventList) GraphicsWindow::
|
||||
get_pointer_events(int device) {
|
||||
PT(PointerEventList) result;
|
||||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), NULL);
|
||||
nassertr(_input_devices[device].has_pointer_event(), NULL);
|
||||
result = _input_devices[device].get_pointer_events();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::verify_window_sizes
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -860,11 +799,15 @@ system_changed_size(int x_size, int y_size) {
|
|||
// Returns the index of the new device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsWindow::
|
||||
add_input_device(const GraphicsWindowInputDevice &device) {
|
||||
add_input_device(InputDevice *device) {
|
||||
LightMutexHolder holder(_input_lock);
|
||||
int index = (int)_input_devices.size();
|
||||
_input_devices.push_back(device);
|
||||
_input_devices.back().set_device_index(index);
|
||||
|
||||
if (device->is_of_type(GraphicsWindowInputDevice::get_class_type())) {
|
||||
((GraphicsWindowInputDevice *)device)->set_device_index(index);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,10 +82,12 @@ PUBLISHED:
|
|||
|
||||
INLINE WindowHandle *get_window_handle() const;
|
||||
MAKE_PROPERTY(window_handle, get_window_handle);
|
||||
|
||||
|
||||
// Mouse and keyboard routines
|
||||
int get_num_input_devices() const;
|
||||
InputDevice *get_input_device(int i) const;
|
||||
string get_input_device_name(int device) const;
|
||||
MAKE_SEQ(get_input_devices, get_num_input_devices, get_input_device);
|
||||
MAKE_SEQ(get_input_device_names, get_num_input_devices, get_input_device_name);
|
||||
bool has_pointer(int device) const;
|
||||
bool has_keyboard(int device) const;
|
||||
|
|
@ -93,20 +95,14 @@ PUBLISHED:
|
|||
|
||||
void enable_pointer_events(int device);
|
||||
void disable_pointer_events(int device);
|
||||
void enable_pointer_mode(int device, double speed);
|
||||
void disable_pointer_mode(int device);
|
||||
/*void enable_pointer_mode(int device, double speed);
|
||||
void disable_pointer_mode(int device);*/
|
||||
|
||||
MouseData get_pointer(int device) const;
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
virtual void close_ime();
|
||||
|
||||
public:
|
||||
// No need to publish these.
|
||||
bool has_button_event(int device) const;
|
||||
ButtonEvent get_button_event(int device);
|
||||
bool has_pointer_event(int device) const;
|
||||
PT(PointerEventList) get_pointer_events(int device);
|
||||
|
||||
virtual void add_window_proc( const GraphicsWindowProc* wnd_proc_object ){};
|
||||
virtual void remove_window_proc( const GraphicsWindowProc* wnd_proc_object ){};
|
||||
virtual void clear_window_procs(){};
|
||||
|
|
@ -146,8 +142,8 @@ protected:
|
|||
void system_changed_size(int x_size, int y_size);
|
||||
|
||||
protected:
|
||||
int add_input_device(const GraphicsWindowInputDevice &device);
|
||||
typedef vector_GraphicsWindowInputDevice InputDevices;
|
||||
int add_input_device(InputDevice *device);
|
||||
typedef pvector<PT(InputDevice)> InputDevices;
|
||||
InputDevices _input_devices;
|
||||
LightMutex _input_lock;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,73 +12,14 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::Default Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GraphicsWindowInputDevice::
|
||||
GraphicsWindowInputDevice() {
|
||||
LightMutexHolder holder(_lock);
|
||||
_flags = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_name
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string GraphicsWindowInputDevice::
|
||||
get_name() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::has_pointer
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsWindowInputDevice::
|
||||
has_pointer() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_flags & IDF_has_pointer) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::has_keyboard
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsWindowInputDevice::
|
||||
has_keyboard() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return ((_flags & IDF_has_keyboard) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_pointer
|
||||
// Access: Public
|
||||
// Description: Returns the MouseData associated with the input
|
||||
// device's pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MouseData GraphicsWindowInputDevice::
|
||||
get_pointer() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _mouse_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_raw_pointer
|
||||
// Access: Public
|
||||
// Description: Returns the MouseData associated with the input
|
||||
// device's pointer, in raw form (ie, prior to any
|
||||
// pointer_mode interpretation).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MouseData GraphicsWindowInputDevice::
|
||||
get_raw_pointer() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return _true_mouse_data;
|
||||
GraphicsWindowInputDevice() : _host(NULL) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -90,140 +31,9 @@ get_raw_pointer() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_device_index(int index) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_device_index = index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::enable_pointer_events
|
||||
// Access: Public
|
||||
// Description: Enables the generation of mouse-movement events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
enable_pointer_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
_enable_pointer_events = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::disable_pointer_events
|
||||
// Access: Public
|
||||
// Description: Disables the generation of mouse-movement events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
disable_pointer_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
_enable_pointer_events = false;
|
||||
_pointer_events.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::button_down
|
||||
// Access: Published
|
||||
// Description: Records that the indicated button has been depressed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
button_down(ButtonHandle button) {
|
||||
button_down(button, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::button_resume_down
|
||||
// Access: Published
|
||||
// Description: Records that the indicated button was depressed
|
||||
// earlier, and we only just detected the event after
|
||||
// the fact. This is mainly useful for tracking the
|
||||
// state of modifier keys.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
button_resume_down(ButtonHandle button) {
|
||||
button_resume_down(button, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::button_up
|
||||
// Access: Published
|
||||
// Description: Records that the indicated button has been released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
button_up(ButtonHandle button) {
|
||||
button_up(button, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::keystroke
|
||||
// Access: Published
|
||||
// Description: Records that the indicated keystroke has been
|
||||
// generated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
keystroke(int keycode) {
|
||||
keystroke(keycode, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::focus_lost
|
||||
// Access: Published
|
||||
// Description: This should be called when the window focus is lost,
|
||||
// so that we may miss upcoming button events
|
||||
// (especially "up" events) for the next period of time.
|
||||
// It generates keyboard and mouse "up" events for those
|
||||
// buttons that we previously sent unpaired "down"
|
||||
// events, so that the Panda application will believe
|
||||
// all buttons are now released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
focus_lost() {
|
||||
focus_lost(ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::raw_button_down
|
||||
// Access: Published
|
||||
// Description: Records that the indicated button has been depressed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
raw_button_down(ButtonHandle button) {
|
||||
raw_button_down(button, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::raw_button_up
|
||||
// Access: Published
|
||||
// Description: Records that the indicated button has been released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
raw_button_up(ButtonHandle button) {
|
||||
raw_button_up(button, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_pointer_in_window
|
||||
// Access: Published
|
||||
// Description: To be called by a particular kind of GraphicsWindow
|
||||
// to indicate that the pointer is within the window, at
|
||||
// the given pixel coordinates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_pointer_in_window(double x, double y) {
|
||||
// mutex is handled in set pointer .. convience function
|
||||
set_pointer(true, x, y, ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_pointer_out_of_window
|
||||
// Access: Published
|
||||
// Description: To be called by a particular kind of GraphicsWindow
|
||||
// to indicate that the pointer is no longer within the
|
||||
// window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_pointer_out_of_window() {
|
||||
// mutex is handled in set pointer .. convience function
|
||||
set_pointer(false, _mouse_data._xpos, _mouse_data._ypos,
|
||||
ClockObject::get_global_clock()->get_frame_time());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_pointer_in_window
|
||||
// Access: Published
|
||||
|
|
@ -233,8 +43,8 @@ set_pointer_out_of_window() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_pointer_in_window(double x, double y, double time) {
|
||||
// mutex is handled in set pointer .. convience function
|
||||
set_pointer(true, x, y, time);
|
||||
LightMutexHolder holder(_lock);
|
||||
InputDevice::set_pointer(true, x, y, time);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -246,36 +56,6 @@ set_pointer_in_window(double x, double y, double time) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsWindowInputDevice::
|
||||
set_pointer_out_of_window(double time) {
|
||||
// mutex is handled in set pointer .. convience function
|
||||
set_pointer(false, _mouse_data._xpos, _mouse_data._ypos, time);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::operator ==
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsWindowInputDevice::
|
||||
operator == (const GraphicsWindowInputDevice &) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::operator !=
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsWindowInputDevice::
|
||||
operator != (const GraphicsWindowInputDevice &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::operator <
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsWindowInputDevice::
|
||||
operator < (const GraphicsWindowInputDevice &) const {
|
||||
return false;
|
||||
LightMutexHolder holder(_lock);
|
||||
InputDevice::set_pointer_out_of_window(time);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,17 +18,7 @@
|
|||
#include "mouseButton.h"
|
||||
#include "keyboardButton.h"
|
||||
|
||||
#define EXPCL EXPCL_PANDA_DISPLAY
|
||||
#define EXPTP EXPTP_PANDA_DISPLAY
|
||||
#define TYPE GraphicsWindowInputDevice
|
||||
#define NAME vector_GraphicsWindowInputDevice
|
||||
|
||||
#include "vector_src.cxx"
|
||||
|
||||
// Tell GCC that we'll take care of the instantiation explicitly here.
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif
|
||||
TypeHandle GraphicsWindowInputDevice::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::Constructor
|
||||
|
|
@ -43,14 +33,8 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice::
|
||||
GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags) :
|
||||
_host(host),
|
||||
_name(name),
|
||||
_flags(flags),
|
||||
_device_index(0),
|
||||
_event_sequence(0),
|
||||
_pointer_mode_enable(false),
|
||||
_pointer_speed(1.0),
|
||||
_enable_pointer_events(false)
|
||||
InputDevice(name, DC_virtual, flags),
|
||||
_host(host)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -60,9 +44,9 @@ GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags) :
|
|||
// Description: This named constructor returns an input device that
|
||||
// only has a pointing device, no keyboard.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice GraphicsWindowInputDevice::
|
||||
PT(GraphicsWindowInputDevice) GraphicsWindowInputDevice::
|
||||
pointer_only(GraphicsWindow *host, const string &name) {
|
||||
return GraphicsWindowInputDevice(host, name, IDF_has_pointer);
|
||||
return new GraphicsWindowInputDevice(host, name, IDF_has_pointer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -71,9 +55,9 @@ pointer_only(GraphicsWindow *host, const string &name) {
|
|||
// Description: This named constructor returns an input device that
|
||||
// only has a keyboard, no pointing device.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice GraphicsWindowInputDevice::
|
||||
PT(GraphicsWindowInputDevice) GraphicsWindowInputDevice::
|
||||
keyboard_only(GraphicsWindow *host, const string &name) {
|
||||
return GraphicsWindowInputDevice(host, name, IDF_has_keyboard);
|
||||
return new GraphicsWindowInputDevice(host, name, IDF_has_keyboard);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -82,9 +66,9 @@ keyboard_only(GraphicsWindow *host, const string &name) {
|
|||
// Description: This named constructor returns an input device that
|
||||
// has both a keyboard and pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice GraphicsWindowInputDevice::
|
||||
PT(GraphicsWindowInputDevice) GraphicsWindowInputDevice::
|
||||
pointer_and_keyboard(GraphicsWindow *host, const string &name) {
|
||||
return
|
||||
return new
|
||||
GraphicsWindowInputDevice(host, name, IDF_has_pointer | IDF_has_keyboard);
|
||||
}
|
||||
|
||||
|
|
@ -94,9 +78,8 @@ pointer_and_keyboard(GraphicsWindow *host, const string &name) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsWindowInputDevice::
|
||||
GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©)
|
||||
{
|
||||
*this = copy;
|
||||
GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©) {
|
||||
*this = copy;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -105,22 +88,9 @@ GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©)
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
operator = (const GraphicsWindowInputDevice ©)
|
||||
{
|
||||
LightMutexHolder holder(_lock);
|
||||
LightMutexHolder holder1(copy._lock);
|
||||
operator = (const GraphicsWindowInputDevice ©) {
|
||||
_host = copy._host;
|
||||
_name = copy._name;
|
||||
_flags = copy._flags;
|
||||
_device_index = copy._device_index;
|
||||
_event_sequence = copy._event_sequence;
|
||||
_pointer_mode_enable = copy._pointer_mode_enable;
|
||||
_pointer_speed = copy._pointer_speed;
|
||||
_enable_pointer_events = copy._enable_pointer_events;
|
||||
_mouse_data = copy._mouse_data;
|
||||
_true_mouse_data = copy._true_mouse_data;
|
||||
_button_events = copy._button_events;
|
||||
_pointer_events = copy._pointer_events;
|
||||
InputDevice::operator = (copy);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -132,151 +102,6 @@ GraphicsWindowInputDevice::
|
|||
~GraphicsWindowInputDevice() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::has_button_event
|
||||
// Access: Public
|
||||
// Description: Returns true if this device has a pending button
|
||||
// event (a mouse button or keyboard button down/up),
|
||||
// false otherwise. If this returns true, the
|
||||
// particular event may be extracted via
|
||||
// get_button_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindowInputDevice::
|
||||
has_button_event() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return !_button_events.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_button_event
|
||||
// Access: Public
|
||||
// Description: Assuming a previous call to has_button_event()
|
||||
// returned true, this returns the pending button event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonEvent GraphicsWindowInputDevice::
|
||||
get_button_event() {
|
||||
LightMutexHolder holder(_lock);
|
||||
ButtonEvent be = _button_events.front();
|
||||
_button_events.pop_front();
|
||||
return be;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::has_pointer_event
|
||||
// Access: Public
|
||||
// Description: Returns true if this device has a pending pointer
|
||||
// event (a mouse movement), or false otherwise. If
|
||||
// this returns true, the particular event may be
|
||||
// extracted via get_pointer_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsWindowInputDevice::
|
||||
has_pointer_event() const {
|
||||
LightMutexHolder holder(_lock);
|
||||
return (_pointer_events != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::get_pointer_events
|
||||
// Access: Public
|
||||
// Description: Returns a PointerEventList containing all the recent
|
||||
// pointer events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PointerEventList) GraphicsWindowInputDevice::
|
||||
get_pointer_events() {
|
||||
LightMutexHolder holder(_lock);
|
||||
PT(PointerEventList) result = _pointer_events;
|
||||
_pointer_events = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::enable_pointer_mode
|
||||
// Access: Public
|
||||
// Description: There are two modes: raw mode, and pointer mode.
|
||||
// In pointer mode, the mouse stops when it reaches the
|
||||
// edges of the window. In raw mode, the mouse ignores
|
||||
// the screen boundaries and can continue indefinitely,
|
||||
// even into negative coordinates. In raw mode, each
|
||||
// "blip" from the mouse hardware corresponds to a
|
||||
// change of 1 unit in the mouse's (x,y) coordinate.
|
||||
// In pointer mode, a variety of speed adjustment factors
|
||||
// and concepts like "mouse acceleration" may be applied.
|
||||
//
|
||||
// Mouse zero represents the system mouse pointer. This
|
||||
// is by definition a pointer, not a raw mouse. It is
|
||||
// an error to try to enable or disable pointer mode on
|
||||
// mouse zero.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
enable_pointer_mode(double speed) {
|
||||
LightMutexHolder holder(_lock);
|
||||
nassertv(_device_index != 0);
|
||||
_pointer_mode_enable = true;
|
||||
_pointer_speed = speed;
|
||||
_mouse_data._xpos = _host->get_x_size() * 0.5;
|
||||
_mouse_data._ypos = _host->get_y_size() * 0.5;
|
||||
_mouse_data._in_window = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::disable_pointer_mode
|
||||
// Access: Public
|
||||
// Description: see enable_pointer_mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
disable_pointer_mode() {
|
||||
LightMutexHolder holder(_lock);
|
||||
nassertv(_device_index != 0);
|
||||
_pointer_mode_enable = false;
|
||||
_pointer_speed = 1.0;
|
||||
_mouse_data = _true_mouse_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::set_pointer
|
||||
// Access: Published
|
||||
// Description: Records that a mouse movement has taken place.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
set_pointer(bool inwin, double x, double y, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
double delta_x = x - _true_mouse_data._xpos;
|
||||
double delta_y = y - _true_mouse_data._ypos;
|
||||
_true_mouse_data._in_window = inwin;
|
||||
_true_mouse_data._xpos = x;
|
||||
_true_mouse_data._ypos = y;
|
||||
|
||||
if (_pointer_mode_enable) {
|
||||
double pointer_x = _mouse_data._xpos;
|
||||
double pointer_y = _mouse_data._ypos;
|
||||
pointer_x += (delta_x * _pointer_speed);
|
||||
pointer_y += (delta_y * _pointer_speed);
|
||||
double xhi = _host->get_x_size();
|
||||
double yhi = _host->get_y_size();
|
||||
if (pointer_x < 0.0) pointer_x = 0.0;
|
||||
if (pointer_y < 0.0) pointer_y = 0.0;
|
||||
if (pointer_x > xhi) pointer_x = xhi;
|
||||
if (pointer_y > yhi) pointer_y = yhi;
|
||||
_mouse_data._in_window = true;
|
||||
_mouse_data._xpos = pointer_x;
|
||||
_mouse_data._ypos = pointer_y;
|
||||
} else {
|
||||
_mouse_data = _true_mouse_data;
|
||||
}
|
||||
|
||||
if (_enable_pointer_events) {
|
||||
int seq = _event_sequence++;
|
||||
if (_pointer_events == 0) {
|
||||
_pointer_events = new PointerEventList();
|
||||
}
|
||||
_pointer_events->add_event(_mouse_data._in_window,
|
||||
_mouse_data._xpos,
|
||||
_mouse_data._ypos,
|
||||
seq, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::button_down
|
||||
// Access: Published
|
||||
|
|
@ -285,7 +110,7 @@ set_pointer(bool inwin, double x, double y, double time) {
|
|||
void GraphicsWindowInputDevice::
|
||||
button_down(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_down, time));
|
||||
_button_events->add_event(ButtonEvent(button, ButtonEvent::T_down, time));
|
||||
_buttons_held.insert(button);
|
||||
}
|
||||
|
||||
|
|
@ -300,7 +125,7 @@ button_down(ButtonHandle button, double time) {
|
|||
void GraphicsWindowInputDevice::
|
||||
button_resume_down(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_resume_down, time));
|
||||
_button_events->add_event(ButtonEvent(button, ButtonEvent::T_resume_down, time));
|
||||
_buttons_held.insert(button);
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +137,7 @@ button_resume_down(ButtonHandle button, double time) {
|
|||
void GraphicsWindowInputDevice::
|
||||
button_up(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_up, time));
|
||||
_button_events->add_event(ButtonEvent(button, ButtonEvent::T_up, time));
|
||||
_buttons_held.erase(button);
|
||||
}
|
||||
|
||||
|
|
@ -325,7 +150,7 @@ button_up(ButtonHandle button, double time) {
|
|||
void GraphicsWindowInputDevice::
|
||||
keystroke(int keycode, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(keycode, time));
|
||||
_button_events->add_event(ButtonEvent(keycode, time));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -340,7 +165,7 @@ void GraphicsWindowInputDevice::
|
|||
candidate(const wstring &candidate_string, size_t highlight_start,
|
||||
size_t highlight_end, size_t cursor_pos) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(candidate_string,
|
||||
_button_events->add_event(ButtonEvent(candidate_string,
|
||||
highlight_start, highlight_end,
|
||||
cursor_pos));
|
||||
}
|
||||
|
|
@ -361,7 +186,7 @@ focus_lost(double time) {
|
|||
LightMutexHolder holder(_lock);
|
||||
ButtonsHeld::iterator bi;
|
||||
for (bi = _buttons_held.begin(); bi != _buttons_held.end(); ++bi) {
|
||||
_button_events.push_back(ButtonEvent(*bi, ButtonEvent::T_up, time));
|
||||
_button_events->add_event(ButtonEvent(*bi, ButtonEvent::T_up, time));
|
||||
}
|
||||
_buttons_held.clear();
|
||||
}
|
||||
|
|
@ -374,7 +199,7 @@ focus_lost(double time) {
|
|||
void GraphicsWindowInputDevice::
|
||||
raw_button_down(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_raw_down, time));
|
||||
_button_events->add_event(ButtonEvent(button, ButtonEvent::T_raw_down, time));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -385,5 +210,5 @@ raw_button_down(ButtonHandle button, double time) {
|
|||
void GraphicsWindowInputDevice::
|
||||
raw_button_up(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_raw_up, time));
|
||||
_button_events->add_event(ButtonEvent(button, ButtonEvent::T_raw_up, time));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,139 +16,79 @@
|
|||
#define GRAPHICSWINDOWINPUTDEVICE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "buttonEvent.h"
|
||||
#include "pointerEvent.h"
|
||||
#include "pointerEventList.h"
|
||||
#include "mouseData.h"
|
||||
#include "clockObject.h"
|
||||
|
||||
#include "pdeque.h"
|
||||
#include "pvector.h"
|
||||
#include "lightMutex.h"
|
||||
#include "lightMutexHolder.h"
|
||||
#include "inputDevice.h"
|
||||
|
||||
// Forward declarations
|
||||
class GraphicsWindow;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GraphicsWindowInputDevice
|
||||
// Description : This is a structure representing a single input
|
||||
// device that may be associated with a window.
|
||||
// Typically this will be a keyboard/mouse pair, and
|
||||
// there will be exactly one of these associated with
|
||||
// each window, but other variants are possible.
|
||||
// Description : This is a virtual input device that represents
|
||||
// the keyboard and mouse pair that is associated with
|
||||
// a particular window. It collects mouse and keyboard
|
||||
// events from the windowing system while the window is
|
||||
// in focus.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DISPLAY GraphicsWindowInputDevice {
|
||||
class EXPCL_PANDA_DISPLAY GraphicsWindowInputDevice : public InputDevice {
|
||||
private:
|
||||
GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags);
|
||||
|
||||
public:
|
||||
static GraphicsWindowInputDevice pointer_only(GraphicsWindow *host, const string &name);
|
||||
static GraphicsWindowInputDevice keyboard_only(GraphicsWindow *host, const string &name);
|
||||
static GraphicsWindowInputDevice pointer_and_keyboard(GraphicsWindow *host, const string &name);
|
||||
static PT(GraphicsWindowInputDevice) pointer_only(GraphicsWindow *host, const string &name);
|
||||
static PT(GraphicsWindowInputDevice) keyboard_only(GraphicsWindow *host, const string &name);
|
||||
static PT(GraphicsWindowInputDevice) pointer_and_keyboard(GraphicsWindow *host, const string &name);
|
||||
|
||||
INLINE GraphicsWindowInputDevice();
|
||||
GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©);
|
||||
void operator = (const GraphicsWindowInputDevice ©);
|
||||
~GraphicsWindowInputDevice();
|
||||
|
||||
INLINE string get_name() const;
|
||||
INLINE bool has_pointer() const;
|
||||
INLINE bool has_keyboard() const;
|
||||
|
||||
INLINE void set_device_index(int index);
|
||||
|
||||
INLINE MouseData get_pointer() const;
|
||||
INLINE MouseData get_raw_pointer() const;
|
||||
|
||||
INLINE void enable_pointer_events();
|
||||
INLINE void disable_pointer_events();
|
||||
|
||||
void enable_pointer_mode(double speed);
|
||||
void disable_pointer_mode();
|
||||
|
||||
bool has_button_event() const;
|
||||
ButtonEvent get_button_event();
|
||||
bool has_pointer_event() const;
|
||||
PT(PointerEventList) get_pointer_events();
|
||||
|
||||
PUBLISHED:
|
||||
// The following interface is for the various kinds of
|
||||
// GraphicsWindows to record the data incoming on the device.
|
||||
INLINE void button_down(ButtonHandle button);
|
||||
INLINE void button_resume_down(ButtonHandle button);
|
||||
INLINE void button_up(ButtonHandle button);
|
||||
INLINE void keystroke(int keycode);
|
||||
INLINE void focus_lost();
|
||||
INLINE void raw_button_down(ButtonHandle button);
|
||||
INLINE void raw_button_up(ButtonHandle button);
|
||||
INLINE void set_pointer_in_window(double x, double y);
|
||||
INLINE void set_pointer_out_of_window();
|
||||
void button_down(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void button_resume_down(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void button_up(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
|
||||
void button_down(ButtonHandle button, double time);
|
||||
void button_resume_down(ButtonHandle button, double time);
|
||||
void button_up(ButtonHandle button, double time);
|
||||
void keystroke(int keycode, double time);
|
||||
void keystroke(int keycode, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void candidate(const wstring &candidate_string, size_t highlight_start,
|
||||
size_t highlight_end, size_t cursor_pos);
|
||||
void focus_lost(double time);
|
||||
void raw_button_down(ButtonHandle button, double time);
|
||||
void raw_button_up(ButtonHandle button, double time);
|
||||
|
||||
INLINE void set_pointer_in_window(double x, double y, double time);
|
||||
INLINE void set_pointer_out_of_window(double time);
|
||||
void set_pointer(bool inwin, double x, double y, double time);
|
||||
void focus_lost(double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
|
||||
public:
|
||||
// We need these methods to make VC++ happy when we try to
|
||||
// instantiate a pvector<GraphicsWindowInputDevice>. They don't do
|
||||
// anything useful.
|
||||
INLINE bool operator == (const GraphicsWindowInputDevice &other) const;
|
||||
INLINE bool operator != (const GraphicsWindowInputDevice &other) const;
|
||||
INLINE bool operator < (const GraphicsWindowInputDevice &other) const;
|
||||
void raw_button_down(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void raw_button_up(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
|
||||
INLINE void set_pointer_in_window(double x, double y, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
INLINE void set_pointer_out_of_window(double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
|
||||
private:
|
||||
enum InputDeviceFlags {
|
||||
IDF_has_pointer = 0x01,
|
||||
IDF_has_keyboard = 0x02
|
||||
};
|
||||
typedef pdeque<ButtonEvent> ButtonEvents;
|
||||
|
||||
LightMutex _lock;
|
||||
|
||||
GraphicsWindow *_host;
|
||||
|
||||
string _name;
|
||||
int _flags;
|
||||
int _device_index;
|
||||
int _event_sequence;
|
||||
|
||||
bool _pointer_mode_enable;
|
||||
double _pointer_speed;
|
||||
|
||||
bool _enable_pointer_events;
|
||||
MouseData _mouse_data;
|
||||
MouseData _true_mouse_data;
|
||||
ButtonEvents _button_events;
|
||||
PT(PointerEventList) _pointer_events;
|
||||
|
||||
typedef pset<ButtonHandle> ButtonsHeld;
|
||||
ButtonsHeld _buttons_held;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
InputDevice::init_type();
|
||||
register_type(_type_handle, "GraphicsWindowInputDevice",
|
||||
InputDevice::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "graphicsWindowInputDevice.I"
|
||||
|
||||
#define EXPCL EXPCL_PANDA_DISPLAY
|
||||
#define EXPTP EXPTP_PANDA_DISPLAY
|
||||
#define TYPE GraphicsWindowInputDevice
|
||||
#define NAME vector_GraphicsWindowInputDevice
|
||||
|
||||
#include "vector_src.h"
|
||||
|
||||
// Tell GCC that we'll take care of the instantiation explicitly here.
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ MouseAndKeyboard(GraphicsWindow *window, int device, const string &name) :
|
|||
_pixel_xy = new EventStoreVec2(LPoint2(0.0f, 0.0f));
|
||||
_pixel_size = new EventStoreVec2(LPoint2(0.0f, 0.0f));
|
||||
_xy = new EventStoreVec2(LPoint2(0.0f, 0.0f));
|
||||
_button_events = new ButtonEventList;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -93,20 +92,18 @@ get_source_device() const {
|
|||
void MouseAndKeyboard::
|
||||
do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
||||
DataNodeTransmit &output) {
|
||||
if (_window->has_button_event(_device)) {
|
||||
// Fill up the button events.
|
||||
_button_events->clear();
|
||||
while (_window->has_button_event(_device)) {
|
||||
ButtonEvent be = _window->get_button_event(_device);
|
||||
_button_events->add_event(be);
|
||||
}
|
||||
output.set_data(_button_events_output, EventParameter(_button_events));
|
||||
|
||||
PT(InputDevice) device = _window->get_input_device(_device);
|
||||
|
||||
if (device->has_button_event()) {
|
||||
PT(ButtonEventList) bel = device->get_button_events();
|
||||
output.set_data(_button_events_output, EventParameter(bel));
|
||||
}
|
||||
if (_window->has_pointer_event(_device)) {
|
||||
PT(PointerEventList) pel = _window->get_pointer_events(_device);
|
||||
if (device->has_pointer_event()) {
|
||||
PT(PointerEventList) pel = device->get_pointer_events();
|
||||
output.set_data(_pointer_events_output, EventParameter(pel));
|
||||
}
|
||||
|
||||
|
||||
// Get the window size.
|
||||
WindowProperties properties = _window->get_properties();
|
||||
if (properties.has_size()) {
|
||||
|
|
@ -116,18 +113,18 @@ do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
|
|||
_pixel_size->set_value(LPoint2(w, h));
|
||||
output.set_data(_pixel_size_output, EventParameter(_pixel_size));
|
||||
|
||||
if (_window->has_pointer(_device)) {
|
||||
const MouseData &mdata = _window->get_pointer(_device);
|
||||
if (device->has_pointer()) {
|
||||
const MouseData &mdata = device->get_pointer();
|
||||
|
||||
if (mdata._in_window) {
|
||||
// Get mouse motion in pixels.
|
||||
_pixel_xy->set_value(LPoint2(mdata._xpos, mdata._ypos));
|
||||
output.set_data(_pixel_xy_output, EventParameter(_pixel_xy));
|
||||
|
||||
|
||||
// Normalize pixel motion to range [-1,1].
|
||||
PN_stdfloat xf = (PN_stdfloat)(2 * mdata._xpos) / (PN_stdfloat)w - 1.0f;
|
||||
PN_stdfloat yf = 1.0f - (PN_stdfloat)(2 * mdata._ypos) / (PN_stdfloat)h;
|
||||
|
||||
|
||||
_xy->set_value(LPoint2(xf, yf));
|
||||
output.set_data(_xy_output, EventParameter(_xy));
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ PUBLISHED:
|
|||
|
||||
PT(GraphicsWindow) get_source_window() const;
|
||||
int get_source_device() const;
|
||||
|
||||
|
||||
protected:
|
||||
// Inherited from DataNode
|
||||
virtual void do_transmit_data(DataGraphTraverser *trav,
|
||||
|
|
@ -69,7 +69,6 @@ private:
|
|||
PT(EventStoreVec2) _pixel_xy;
|
||||
PT(EventStoreVec2) _pixel_size;
|
||||
PT(EventStoreVec2) _xy;
|
||||
PT(ButtonEventList) _button_events;
|
||||
|
||||
PT(GraphicsWindow) _window;
|
||||
int _device;
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include "graphicsWindowProc.cxx"
|
||||
#include "graphicsWindowProcCallbackData.cxx"
|
||||
#include "graphicsWindowInputDevice.cxx"
|
||||
#include "mouseAndKeyboard.cxx"
|
||||
#include "nativeWindowHandle.cxx"
|
||||
#include "parasiteBuffer.cxx"
|
||||
#include "standardMunger.cxx"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "datagram.h"
|
||||
#include "doubleBitMask.h"
|
||||
#include "factoryParam.h"
|
||||
#include "gamepadButton.h"
|
||||
#include "namable.h"
|
||||
#include "nodeCachedReferenceCount.h"
|
||||
#include "paramValue.h"
|
||||
|
|
@ -225,6 +226,7 @@ init_libputil() {
|
|||
WritableConfigurable::init_type();
|
||||
WritableParam::init_type();
|
||||
|
||||
GamepadButton::init_gamepad_buttons();
|
||||
KeyboardButton::init_keyboard_buttons();
|
||||
MouseButton::init_mouse_buttons();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
// Filename: gamepadButton.cxx
|
||||
// Created by: rdb (21Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gamepadButton.h"
|
||||
#include "buttonRegistry.h"
|
||||
|
||||
#define DEFINE_GAMEPAD_BUTTON_HANDLE(KeyName) \
|
||||
static ButtonHandle _##KeyName; \
|
||||
ButtonHandle GamepadButton::KeyName() { return _##KeyName; }
|
||||
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(lstick)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(rstick)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(lshoulder)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(rshoulder)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(ltrigger)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(rtrigger)
|
||||
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(dpad_left)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(dpad_right)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(dpad_up)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(dpad_down)
|
||||
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(back)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(guide)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(start)
|
||||
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(action_a)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(action_b)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(action_c)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(action_x)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(action_y)
|
||||
DEFINE_GAMEPAD_BUTTON_HANDLE(action_z)
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GamepadButton::init_gamepad_buttons
|
||||
// Access: Public, Static
|
||||
// Description: This is intended to be called only once, by the
|
||||
// static initialization performed in config_util.cxx.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GamepadButton::
|
||||
init_gamepad_buttons() {
|
||||
ButtonRegistry::ptr()->register_button(_lstick, "lstick");
|
||||
ButtonRegistry::ptr()->register_button(_rstick, "rstick");
|
||||
ButtonRegistry::ptr()->register_button(_lshoulder, "lshoulder");
|
||||
ButtonRegistry::ptr()->register_button(_rshoulder, "rshoulder");
|
||||
ButtonRegistry::ptr()->register_button(_ltrigger, "ltrigger");
|
||||
ButtonRegistry::ptr()->register_button(_rtrigger, "rtrigger");
|
||||
|
||||
ButtonRegistry::ptr()->register_button(_dpad_left, "dpad_left");
|
||||
ButtonRegistry::ptr()->register_button(_dpad_right, "dpad_right");
|
||||
ButtonRegistry::ptr()->register_button(_dpad_up, "dpad_up");
|
||||
ButtonRegistry::ptr()->register_button(_dpad_down, "dpad_down");
|
||||
|
||||
ButtonRegistry::ptr()->register_button(_back, "back");
|
||||
ButtonRegistry::ptr()->register_button(_guide, "guide");
|
||||
ButtonRegistry::ptr()->register_button(_start, "start");
|
||||
|
||||
ButtonRegistry::ptr()->register_button(_action_a, "action_a");
|
||||
ButtonRegistry::ptr()->register_button(_action_b, "action_b");
|
||||
ButtonRegistry::ptr()->register_button(_action_c, "action_c");
|
||||
ButtonRegistry::ptr()->register_button(_action_x, "action_x");
|
||||
ButtonRegistry::ptr()->register_button(_action_y, "action_y");
|
||||
ButtonRegistry::ptr()->register_button(_action_z, "action_z");
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// Filename: gamepadButton.h
|
||||
// Created by: rdb (21Aug15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GAMEPADBUTTON_H
|
||||
#define GAMEPADBUTTON_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "buttonHandle.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GamepadButton
|
||||
// Description : This class is just used as a convenient namespace for
|
||||
// grouping all of these handy functions that return
|
||||
// buttons which map to gamepad buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PUTIL GamepadButton {
|
||||
PUBLISHED:
|
||||
static ButtonHandle lstick();
|
||||
static ButtonHandle rstick();
|
||||
static ButtonHandle lshoulder();
|
||||
static ButtonHandle rshoulder();
|
||||
static ButtonHandle ltrigger();
|
||||
static ButtonHandle rtrigger();
|
||||
|
||||
static ButtonHandle dpad_left();
|
||||
static ButtonHandle dpad_right();
|
||||
static ButtonHandle dpad_up();
|
||||
static ButtonHandle dpad_down();
|
||||
|
||||
static ButtonHandle back();
|
||||
static ButtonHandle guide();
|
||||
static ButtonHandle start();
|
||||
|
||||
static ButtonHandle action_a();
|
||||
static ButtonHandle action_b();
|
||||
static ButtonHandle action_c();
|
||||
static ButtonHandle action_x();
|
||||
static ButtonHandle action_y();
|
||||
static ButtonHandle action_z();
|
||||
|
||||
public:
|
||||
static void init_gamepad_buttons();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -28,4 +28,3 @@
|
|||
#include "factoryBase.cxx"
|
||||
#include "factoryParam.cxx"
|
||||
#include "factoryParams.cxx"
|
||||
#include "globalPointerRegistry.cxx"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include "gamepadButton.cxx"
|
||||
#include "globalPointerRegistry.cxx"
|
||||
#include "ioPtaDatagramFloat.cxx"
|
||||
#include "ioPtaDatagramInt.cxx"
|
||||
#include "ioPtaDatagramShort.cxx"
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ OSStatus TinyOsxGraphicsWindow::handleTextInput (EventHandlerCallRef myHandler,
|
|||
}
|
||||
|
||||
for (unsigned int x = 0; x < actualSize/sizeof(UniChar); ++x) {
|
||||
_input_devices[0].keystroke(text[x]);
|
||||
_input_devices[0]->keystroke(text[x]);
|
||||
}
|
||||
DisposePtr((char *)text);
|
||||
}
|
||||
|
|
@ -492,10 +492,10 @@ TinyOsxGraphicsWindow::TinyOsxGraphicsWindow(GraphicsEngine *engine, GraphicsPip
|
|||
_current_icon(NULL),
|
||||
_ID(id_seed++),
|
||||
_originalMode(NULL) {
|
||||
GraphicsWindowInputDevice device =
|
||||
PT(InputDevice) device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard/mouse");
|
||||
_input_devices.push_back(device);
|
||||
_input_devices[0].set_pointer_in_window(0, 0);
|
||||
device->set_pointer_in_window(0, 0);
|
||||
_last_key_modifiers = 0;
|
||||
_last_buttons = 0;
|
||||
|
||||
|
|
@ -579,7 +579,7 @@ bool TinyOsxGraphicsWindow::set_icon_filename(const Filename &icon_filename) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TinyOsxGraphicsWindow::
|
||||
set_pointer_in_window(int x, int y) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
_input_devices[0]->set_pointer_in_window(x, y);
|
||||
|
||||
if (_cursor_hidden != _display_hide_cursor) {
|
||||
if (_cursor_hidden) {
|
||||
|
|
@ -600,7 +600,7 @@ set_pointer_in_window(int x, int y) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TinyOsxGraphicsWindow::
|
||||
set_pointer_out_of_window() {
|
||||
_input_devices[0].set_pointer_out_of_window();
|
||||
_input_devices[0]->set_pointer_out_of_window();
|
||||
|
||||
if (_display_hide_cursor) {
|
||||
CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
|
|
@ -1333,13 +1333,13 @@ void TinyOsxGraphicsWindow::SystemPointToLocalPoint(Point &qdGlobalPoint) {
|
|||
_wheel_delta += this_wheel_delta;
|
||||
SInt32 wheel_scale = osx_mouse_wheel_scale;
|
||||
while (_wheel_delta > wheel_scale) {
|
||||
_input_devices[0].button_down(MouseButton::wheel_up());
|
||||
_input_devices[0].button_up(MouseButton::wheel_up());
|
||||
_input_devices[0]->button_down(MouseButton::wheel_up());
|
||||
_input_devices[0]->button_up(MouseButton::wheel_up());
|
||||
_wheel_delta -= wheel_scale;
|
||||
}
|
||||
while (_wheel_delta < -wheel_scale) {
|
||||
_input_devices[0].button_down(MouseButton::wheel_down());
|
||||
_input_devices[0].button_up(MouseButton::wheel_down());
|
||||
_input_devices[0]->button_down(MouseButton::wheel_down());
|
||||
_input_devices[0]->button_up(MouseButton::wheel_down());
|
||||
_wheel_delta += wheel_scale;
|
||||
}
|
||||
}
|
||||
|
|
@ -1519,25 +1519,25 @@ HandleButtonDelta(UInt32 new_buttons) {
|
|||
|
||||
if (changed & 0x01) {
|
||||
if (new_buttons & 0x01) {
|
||||
_input_devices[0].button_down(MouseButton::one());
|
||||
_input_devices[0]->button_down(MouseButton::one());
|
||||
} else {
|
||||
_input_devices[0].button_up(MouseButton::one());
|
||||
_input_devices[0]->button_up(MouseButton::one());
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & 0x04) {
|
||||
if (new_buttons & 0x04) {
|
||||
_input_devices[0].button_down(MouseButton::two());
|
||||
_input_devices[0]->button_down(MouseButton::two());
|
||||
} else {
|
||||
_input_devices[0].button_up(MouseButton::two());
|
||||
_input_devices[0]->button_up(MouseButton::two());
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & 0x02) {
|
||||
if (new_buttons & 0x02) {
|
||||
_input_devices[0].button_down(MouseButton::three());
|
||||
_input_devices[0]->button_down(MouseButton::three());
|
||||
} else {
|
||||
_input_devices[0].button_up(MouseButton::three());
|
||||
_input_devices[0]->button_up(MouseButton::three());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1745,7 +1745,7 @@ void TinyOsxGraphicsWindow::set_properties_now(WindowProperties &properties) {
|
|||
if (properties.has_cursor_hidden()) {
|
||||
_properties.set_cursor_hidden(properties.get_cursor_hidden());
|
||||
_cursor_hidden = properties.get_cursor_hidden();
|
||||
if (_cursor_hidden && _input_devices[0].has_pointer()) {
|
||||
if (_cursor_hidden && _input_devices[0]->has_pointer()) {
|
||||
if (!_display_hide_cursor) {
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
_display_hide_cursor = true;
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@ TinySDLGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
_pitch = 0;
|
||||
update_pixel_factor();
|
||||
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
||||
add_input_device(device);
|
||||
add_input_device(GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -184,35 +182,35 @@ process_events() {
|
|||
switch(evt.type) {
|
||||
case SDL_KEYDOWN:
|
||||
if (evt.key.keysym.unicode) {
|
||||
_input_devices[0].keystroke(evt.key.keysym.unicode);
|
||||
_input_devices[0]->keystroke(evt.key.keysym.unicode);
|
||||
}
|
||||
button = get_keyboard_button(evt.key.keysym.sym);
|
||||
if (button != ButtonHandle::none()) {
|
||||
_input_devices[0].button_down(button);
|
||||
_input_devices[0]->button_down(button);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
button = get_keyboard_button(evt.key.keysym.sym);
|
||||
if (button != ButtonHandle::none()) {
|
||||
_input_devices[0].button_up(button);
|
||||
_input_devices[0]->button_up(button);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
button = get_mouse_button(evt.button.button);
|
||||
_input_devices[0].set_pointer_in_window(evt.button.x, evt.button.y);
|
||||
_input_devices[0].button_down(button);
|
||||
_input_devices[0]->set_pointer_in_window(evt.button.x, evt.button.y);
|
||||
_input_devices[0]->button_down(button);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
button = get_mouse_button(evt.button.button);
|
||||
_input_devices[0].set_pointer_in_window(evt.button.x, evt.button.y);
|
||||
_input_devices[0].button_up(button);
|
||||
_input_devices[0]->set_pointer_in_window(evt.button.x, evt.button.y);
|
||||
_input_devices[0]->button_up(button);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
_input_devices[0].set_pointer_in_window(evt.motion.x, evt.motion.y);
|
||||
_input_devices[0]->set_pointer_in_window(evt.motion.x, evt.motion.y);
|
||||
break;
|
||||
|
||||
case SDL_VIDEORESIZE:
|
||||
|
|
|
|||
|
|
@ -215,9 +215,7 @@ process_events() {
|
|||
if (_xwindow == (X11_Window)0) {
|
||||
return;
|
||||
}
|
||||
|
||||
poll_raw_mice();
|
||||
|
||||
|
||||
XEvent event;
|
||||
XKeyEvent keyrelease_event;
|
||||
bool got_keyrelease_event = false;
|
||||
|
|
@ -294,18 +292,18 @@ process_events() {
|
|||
case ButtonPress:
|
||||
// This refers to the mouse buttons.
|
||||
button = get_mouse_button(event.xbutton);
|
||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input_devices[0].button_down(button);
|
||||
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input->button_down(button);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
button = get_mouse_button(event.xbutton);
|
||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input_devices[0].button_up(button);
|
||||
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input->button_up(button);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
_input_devices[0].set_pointer_in_window(event.xmotion.x, event.xmotion.y);
|
||||
_input->set_pointer_in_window(event.xmotion.x, event.xmotion.y);
|
||||
break;
|
||||
|
||||
case KeyPress:
|
||||
|
|
@ -322,11 +320,11 @@ process_events() {
|
|||
break;
|
||||
|
||||
case EnterNotify:
|
||||
_input_devices[0].set_pointer_in_window(event.xcrossing.x, event.xcrossing.y);
|
||||
_input->set_pointer_in_window(event.xcrossing.x, event.xcrossing.y);
|
||||
break;
|
||||
|
||||
case LeaveNotify:
|
||||
_input_devices[0].set_pointer_out_of_window();
|
||||
_input->set_pointer_out_of_window();
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
|
|
@ -335,7 +333,7 @@ process_events() {
|
|||
break;
|
||||
|
||||
case FocusOut:
|
||||
_input_devices[0].focus_lost();
|
||||
_input->focus_lost();
|
||||
properties.set_foreground(false);
|
||||
system_changed_properties(properties);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ vrpn_analog_callback(void *userdata, const vrpn_ANALOGCB info) {
|
|||
Devices::iterator di;
|
||||
for (di = self->_devices.begin(); di != self->_devices.end(); ++di) {
|
||||
VrpnAnalogDevice *device = (*di);
|
||||
device->acquire();
|
||||
for (int i = 0; i < info.num_channel; i++) {
|
||||
if (vrpn_cat.is_debug()) {
|
||||
if (device->get_control_state(i) != info.channel[i]) {
|
||||
|
|
@ -125,6 +124,5 @@ vrpn_analog_callback(void *userdata, const vrpn_ANALOGCB info) {
|
|||
}
|
||||
device->set_control_state(i, info.channel[i]);
|
||||
}
|
||||
device->unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,8 +119,6 @@ vrpn_button_callback(void *userdata, const vrpn_BUTTONCB info) {
|
|||
Devices::iterator di;
|
||||
for (di = self->_devices.begin(); di != self->_devices.end(); ++di) {
|
||||
VrpnButtonDevice *device = (*di);
|
||||
device->acquire();
|
||||
device->set_button_state(info.button, info.state != 0);
|
||||
device->unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,8 +120,6 @@ vrpn_dial_callback(void *userdata, const vrpn_DIALCB info) {
|
|||
Devices::iterator di;
|
||||
for (di = self->_devices.begin(); di != self->_devices.end(); ++di) {
|
||||
VrpnDialDevice *device = (*di);
|
||||
device->acquire();
|
||||
device->push_dial(info.dial, info.change);
|
||||
device->unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,11 +123,10 @@ vrpn_position_callback(void *userdata, const vrpn_TRACKERCB info) {
|
|||
VrpnTrackerDevice *device = (*di);
|
||||
if (device->get_sensor() == info.sensor &&
|
||||
device->get_data_type() == VrpnTrackerDevice::DT_position) {
|
||||
device->acquire();
|
||||
device->_data.set_time(VrpnClient::convert_to_secs(info.msg_time));
|
||||
device->_data.set_pos(LPoint3(info.pos[0], info.pos[1], info.pos[2]));
|
||||
device->_data.set_orient(LOrientation(info.quat[3], info.quat[0], info.quat[1], info.quat[2]));
|
||||
device->unlock();
|
||||
device->set_tracker(LPoint3(info.pos[0], info.pos[1], info.pos[2]),
|
||||
LOrientation(info.quat[3], info.quat[0],
|
||||
info.quat[1], info.quat[2]),
|
||||
VrpnClient::convert_to_secs(info.msg_time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -152,13 +151,10 @@ vrpn_velocity_callback(void *userdata, const vrpn_TRACKERVELCB info) {
|
|||
VrpnTrackerDevice *device = (*di);
|
||||
if (device->get_sensor() == info.sensor &&
|
||||
device->get_data_type() == VrpnTrackerDevice::DT_velocity) {
|
||||
device->acquire();
|
||||
device->_data.set_time(VrpnClient::convert_to_secs(info.msg_time));
|
||||
device->_data.set_pos(LPoint3(info.vel[0], info.vel[1], info.vel[2]));
|
||||
device->_data.set_orient(LOrientation(info.vel_quat[3], info.vel_quat[0],
|
||||
info.vel_quat[1], info.vel_quat[2]));
|
||||
device->_data.set_dt(info.vel_quat_dt);
|
||||
device->unlock();
|
||||
device->set_tracker(LPoint3(info.vel[0], info.vel[1], info.vel[2]),
|
||||
LOrientation(info.vel_quat[3], info.vel_quat[0],
|
||||
info.vel_quat[1], info.vel_quat[2]),
|
||||
VrpnClient::convert_to_secs(info.msg_time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -183,13 +179,10 @@ vrpn_acceleration_callback(void *userdata, const vrpn_TRACKERACCCB info) {
|
|||
VrpnTrackerDevice *device = (*di);
|
||||
if (device->get_sensor() == info.sensor &&
|
||||
device->get_data_type() == VrpnTrackerDevice::DT_acceleration) {
|
||||
device->acquire();
|
||||
device->_data.set_time(VrpnClient::convert_to_secs(info.msg_time));
|
||||
device->_data.set_pos(LPoint3(info.acc[0], info.acc[1], info.acc[2]));
|
||||
device->_data.set_orient(LOrientation(info.acc_quat[3], info.acc_quat[0],
|
||||
info.acc_quat[1], info.acc_quat[2]));
|
||||
device->_data.set_dt(info.acc_quat_dt);
|
||||
device->unlock();
|
||||
device->set_tracker(LPoint3(info.acc[0], info.acc[1], info.acc[2]),
|
||||
LOrientation(info.acc_quat[3], info.acc_quat[0],
|
||||
info.acc_quat[1], info.acc_quat[2]),
|
||||
VrpnClient::convert_to_secs(info.msg_time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2786,9 +2786,9 @@ handle_raw_input(HRAWINPUT hraw) {
|
|||
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
|
||||
_input_devices[i].set_pointer_in_window(adjx, adjy);
|
||||
} else {
|
||||
int oldx = _input_devices[i].get_raw_pointer().get_x();
|
||||
int oldy = _input_devices[i].get_raw_pointer().get_y();
|
||||
_input_devices[i].set_pointer_in_window(oldx + adjx, oldy + adjy);
|
||||
//int oldx = _input_devices[i].get_raw_pointer().get_x();
|
||||
//int oldy = _input_devices[i].get_raw_pointer().get_y();
|
||||
//_input_devices[i].set_pointer_in_window(oldx + adjx, oldy + adjy);
|
||||
}
|
||||
|
||||
if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) {
|
||||
|
|
|
|||
|
|
@ -28,14 +28,10 @@
|
|||
#include "nativeWindowHandle.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "get_x11.h"
|
||||
#include "evdevInputDevice.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
static int xcursor_read(XcursorFile *file, unsigned char *buf, int len) {
|
||||
|
|
@ -69,8 +65,6 @@ static int xcursor_seek(XcursorFile *file, long offset, int whence) {
|
|||
|
||||
TypeHandle x11GraphicsWindow::_type_handle;
|
||||
|
||||
#define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)&7)))
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -107,9 +101,9 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
_override_redirect = False;
|
||||
_wm_delete_window = x11_pipe->_wm_delete_window;
|
||||
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
||||
PT(GraphicsWindowInputDevice) device = GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
||||
add_input_device(device);
|
||||
_input = device;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -143,26 +137,26 @@ move_pointer(int device, int x, int y) {
|
|||
if (device == 0) {
|
||||
// Move the system mouse pointer.
|
||||
if (!_properties.get_foreground() ||
|
||||
!_input_devices[0].get_pointer().get_in_window()) {
|
||||
!_input->get_pointer().get_in_window()) {
|
||||
// If the window doesn't have input focus, or the mouse isn't
|
||||
// currently within the window, forget it.
|
||||
return false;
|
||||
}
|
||||
|
||||
const MouseData &md = _input_devices[0].get_pointer();
|
||||
const MouseData &md = _input->get_pointer();
|
||||
if (!md.get_in_window() || md.get_x() != x || md.get_y() != y) {
|
||||
if (!_dga_mouse_enabled) {
|
||||
XWarpPointer(_display, None, _xwindow, 0, 0, 0, 0, x, y);
|
||||
}
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
_input->set_pointer_in_window(x, y);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// Move a raw mouse.
|
||||
if ((device < 1)||(device >= _input_devices.size())) {
|
||||
if (device < 1 || device >= _input_devices.size()) {
|
||||
return false;
|
||||
}
|
||||
_input_devices[device].set_pointer_in_window(x, y);
|
||||
//_input_devices[device]->set_pointer_in_window(x, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -249,8 +243,6 @@ process_events() {
|
|||
return;
|
||||
}
|
||||
|
||||
poll_raw_mice();
|
||||
|
||||
XEvent event;
|
||||
XKeyEvent keyrelease_event;
|
||||
bool got_keyrelease_event = false;
|
||||
|
|
@ -311,25 +303,25 @@ process_events() {
|
|||
// This refers to the mouse buttons.
|
||||
button = get_mouse_button(event.xbutton);
|
||||
if (!_dga_mouse_enabled) {
|
||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
}
|
||||
_input_devices[0].button_down(button);
|
||||
_input->button_down(button);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
button = get_mouse_button(event.xbutton);
|
||||
if (!_dga_mouse_enabled) {
|
||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
}
|
||||
_input_devices[0].button_up(button);
|
||||
_input->button_up(button);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
if (_dga_mouse_enabled) {
|
||||
const MouseData &md = _input_devices[0].get_raw_pointer();
|
||||
_input_devices[0].set_pointer_in_window(md.get_x() + event.xmotion.x_root, md.get_y() + event.xmotion.y_root);
|
||||
const MouseData &md = _input->get_pointer();
|
||||
_input->set_pointer_in_window(md.get_x() + event.xmotion.x_root, md.get_y() + event.xmotion.y_root);
|
||||
} else {
|
||||
_input_devices[0].set_pointer_in_window(event.xmotion.x, event.xmotion.y);
|
||||
_input->set_pointer_in_window(event.xmotion.x, event.xmotion.y);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -348,15 +340,15 @@ process_events() {
|
|||
|
||||
case EnterNotify:
|
||||
if (_dga_mouse_enabled) {
|
||||
const MouseData &md = _input_devices[0].get_raw_pointer();
|
||||
_input_devices[0].set_pointer_in_window(md.get_x(), md.get_y());
|
||||
const MouseData &md = _input->get_pointer();
|
||||
_input->set_pointer_in_window(md.get_x(), md.get_y());
|
||||
} else {
|
||||
_input_devices[0].set_pointer_in_window(event.xcrossing.x, event.xcrossing.y);
|
||||
_input->set_pointer_in_window(event.xcrossing.x, event.xcrossing.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case LeaveNotify:
|
||||
_input_devices[0].set_pointer_out_of_window();
|
||||
_input->set_pointer_out_of_window();
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
|
|
@ -365,7 +357,7 @@ process_events() {
|
|||
break;
|
||||
|
||||
case FocusOut:
|
||||
_input_devices[0].focus_lost();
|
||||
_input->focus_lost();
|
||||
properties.set_foreground(false);
|
||||
changed_properties = true;
|
||||
break;
|
||||
|
|
@ -751,7 +743,7 @@ set_properties_now(WindowProperties &properties) {
|
|||
XQueryPointer(_display, _xwindow, &event.xbutton.root,
|
||||
&event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root,
|
||||
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||
}
|
||||
} else {
|
||||
x11display_cat.info() << "XF86DGA extension not available\n";
|
||||
|
|
@ -1295,66 +1287,43 @@ open_raw_mice() {
|
|||
bool any_mice = false;
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
uint8_t evtypes[EV_MAX/8 + 1];
|
||||
ostringstream fnb;
|
||||
fnb << "/dev/input/event" << i;
|
||||
string fn = fnb.str();
|
||||
int fd = open(fn.c_str(), O_RDONLY | O_NONBLOCK, 0);
|
||||
if (fd >= 0) {
|
||||
any_present = true;
|
||||
char name[256];
|
||||
char phys[256];
|
||||
char uniq[256];
|
||||
if ((ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)||
|
||||
(ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0)||
|
||||
(ioctl(fd, EVIOCGPHYS(sizeof(uniq)), uniq) < 0)||
|
||||
(ioctl(fd, EVIOCGBIT(0, EV_MAX), &evtypes) < 0)) {
|
||||
close(fd);
|
||||
x11display_cat.error() <<
|
||||
"Opening raw mice: ioctl failed on " << fn << "\n";
|
||||
} else {
|
||||
if (test_bit(EV_REL, evtypes) || test_bit(EV_ABS, evtypes)) {
|
||||
for (char *p=name; *p; p++) {
|
||||
if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) {
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
for (char *p=uniq; *p; p++) {
|
||||
if (((*p<'a')||(*p>'z')) && ((*p<'A')||(*p>'Z')) && ((*p<'0')||(*p>'9'))) {
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
string full_id = ((string)name) + "." + uniq;
|
||||
MouseDeviceInfo inf;
|
||||
inf._fd = fd;
|
||||
inf._input_device_index = _input_devices.size();
|
||||
inf._io_buffer = "";
|
||||
_mouse_device_info.push_back(inf);
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_only(this, full_id);
|
||||
add_input_device(device);
|
||||
x11display_cat.info() << "Raw mouse " <<
|
||||
inf._input_device_index << " detected: " << full_id << "\n";
|
||||
any_mice = true;
|
||||
} else {
|
||||
close(fd);
|
||||
}
|
||||
EvdevInputDevice *device = new EvdevInputDevice(fd);
|
||||
nassertd(device != NULL) continue;
|
||||
|
||||
if (device->has_pointer()) {
|
||||
add_input_device(device);
|
||||
|
||||
x11display_cat.info()
|
||||
<< "Raw mouse " << _input_devices.size()
|
||||
<< " detected: " << device->get_name() << "\n";
|
||||
|
||||
any_mice = true;
|
||||
any_present = true;
|
||||
}
|
||||
} else {
|
||||
if ((errno == ENOENT)||(errno == ENOTDIR)) {
|
||||
if (errno == ENOENT || errno == ENOTDIR) {
|
||||
break;
|
||||
} else {
|
||||
any_present = true;
|
||||
x11display_cat.error() <<
|
||||
"Opening raw mice: " << strerror(errno) << " " << fn << "\n";
|
||||
x11display_cat.error()
|
||||
<< "Opening raw mice: " << strerror(errno) << " " << fn << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_present) {
|
||||
if (any_mice) {
|
||||
_properties.set_raw_mice(true);
|
||||
|
||||
} else if (!any_present) {
|
||||
x11display_cat.error() <<
|
||||
"Opening raw mice: files not found: /dev/input/event*\n";
|
||||
} else if (!any_mice) {
|
||||
|
||||
} else {
|
||||
x11display_cat.error() <<
|
||||
"Opening raw mice: no mouse devices detected in /dev/input/event*\n";
|
||||
}
|
||||
|
|
@ -1364,69 +1333,6 @@ open_raw_mice() {
|
|||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::poll_raw_mice
|
||||
// Access: Private
|
||||
// Description: Reads events from the raw mouse device files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void x11GraphicsWindow::
|
||||
poll_raw_mice() {
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
for (int di = 0; di < _mouse_device_info.size(); ++di) {
|
||||
MouseDeviceInfo &inf = _mouse_device_info[di];
|
||||
|
||||
// Read all bytes into buffer.
|
||||
if (inf._fd >= 0) {
|
||||
while (1) {
|
||||
char tbuf[1024];
|
||||
int nread = read(inf._fd, tbuf, sizeof(tbuf));
|
||||
if (nread > 0) {
|
||||
inf._io_buffer += string(tbuf, nread);
|
||||
} else {
|
||||
if ((nread < 0) && ((errno == EWOULDBLOCK) || (errno==EAGAIN))) {
|
||||
break;
|
||||
}
|
||||
close(inf._fd);
|
||||
inf._fd = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process events.
|
||||
int nevents = inf._io_buffer.size() / sizeof(struct input_event);
|
||||
if (nevents == 0) {
|
||||
continue;
|
||||
}
|
||||
const input_event *events = (const input_event *)(inf._io_buffer.c_str());
|
||||
GraphicsWindowInputDevice &dev = _input_devices[inf._input_device_index];
|
||||
int x = dev.get_raw_pointer().get_x();
|
||||
int y = dev.get_raw_pointer().get_y();
|
||||
for (int i = 0; i < nevents; i++) {
|
||||
if (events[i].type == EV_REL) {
|
||||
if (events[i].code == REL_X) x += events[i].value;
|
||||
if (events[i].code == REL_Y) y += events[i].value;
|
||||
} else if (events[i].type == EV_ABS) {
|
||||
if (events[i].code == ABS_X) x = events[i].value;
|
||||
if (events[i].code == ABS_Y) y = events[i].value;
|
||||
} else if (events[i].type == EV_KEY) {
|
||||
if ((events[i].code >= BTN_MOUSE) && (events[i].code < BTN_MOUSE + 8)) {
|
||||
int btn = events[i].code - BTN_MOUSE;
|
||||
dev.set_pointer_in_window(x, y);
|
||||
if (events[i].value) {
|
||||
dev.button_down(MouseButton::button(btn));
|
||||
} else {
|
||||
dev.button_up(MouseButton::button(btn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inf._io_buffer.erase(0, nevents * sizeof(struct input_event));
|
||||
dev.set_pointer_in_window(x, y);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::handle_keystroke
|
||||
// Access: Private
|
||||
|
|
@ -1436,7 +1342,7 @@ poll_raw_mice() {
|
|||
void x11GraphicsWindow::
|
||||
handle_keystroke(XKeyEvent &event) {
|
||||
if (!_dga_mouse_enabled) {
|
||||
_input_devices[0].set_pointer_in_window(event.x, event.y);
|
||||
_input->set_pointer_in_window(event.x, event.y);
|
||||
}
|
||||
|
||||
if (_ic) {
|
||||
|
|
@ -1454,14 +1360,14 @@ handle_keystroke(XKeyEvent &event) {
|
|||
// Now each of the returned wide characters represents a
|
||||
// keystroke.
|
||||
for (int i = 0; i < len; i++) {
|
||||
_input_devices[0].keystroke(buffer[i]);
|
||||
_input->keystroke(buffer[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Without an input context, just get the ascii keypress.
|
||||
ButtonHandle button = get_button(event, true);
|
||||
if (button.has_ascii_equivalent()) {
|
||||
_input_devices[0].keystroke(button.get_ascii_equivalent());
|
||||
_input->keystroke(button.get_ascii_equivalent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1475,30 +1381,32 @@ handle_keystroke(XKeyEvent &event) {
|
|||
void x11GraphicsWindow::
|
||||
handle_keypress(XKeyEvent &event) {
|
||||
if (!_dga_mouse_enabled) {
|
||||
_input_devices[0].set_pointer_in_window(event.x, event.y);
|
||||
_input->set_pointer_in_window(event.x, event.y);
|
||||
}
|
||||
|
||||
// Now get the raw unshifted button.
|
||||
ButtonHandle button = get_button(event, false);
|
||||
if (button != ButtonHandle::none()) {
|
||||
if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
|
||||
_input_devices[0].button_down(KeyboardButton::control());
|
||||
_input->button_down(KeyboardButton::control());
|
||||
}
|
||||
if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
|
||||
_input_devices[0].button_down(KeyboardButton::shift());
|
||||
_input->button_down(KeyboardButton::shift());
|
||||
}
|
||||
if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
|
||||
_input_devices[0].button_down(KeyboardButton::alt());
|
||||
_input->button_down(KeyboardButton::alt());
|
||||
}
|
||||
if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) {
|
||||
_input_devices[0].button_down(KeyboardButton::meta());
|
||||
_input->button_down(KeyboardButton::meta());
|
||||
}
|
||||
_input_devices[0].button_down(button);
|
||||
_input->button_down(button);
|
||||
}
|
||||
|
||||
ButtonHandle raw_button = map_raw_button(event.keycode);
|
||||
if (raw_button != ButtonHandle::none()) {
|
||||
_input_devices[0].raw_button_down(raw_button);
|
||||
if (event.keycode >= 9 && event.keycode <= 135) {
|
||||
ButtonHandle raw_button = map_raw_button(event.keycode);
|
||||
if (raw_button != ButtonHandle::none()) {
|
||||
_input->raw_button_down(raw_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1511,30 +1419,32 @@ handle_keypress(XKeyEvent &event) {
|
|||
void x11GraphicsWindow::
|
||||
handle_keyrelease(XKeyEvent &event) {
|
||||
if (!_dga_mouse_enabled) {
|
||||
_input_devices[0].set_pointer_in_window(event.x, event.y);
|
||||
_input->set_pointer_in_window(event.x, event.y);
|
||||
}
|
||||
|
||||
// Now get the raw unshifted button.
|
||||
ButtonHandle button = get_button(event, false);
|
||||
if (button != ButtonHandle::none()) {
|
||||
if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
|
||||
_input_devices[0].button_up(KeyboardButton::control());
|
||||
_input->button_up(KeyboardButton::control());
|
||||
}
|
||||
if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
|
||||
_input_devices[0].button_up(KeyboardButton::shift());
|
||||
_input->button_up(KeyboardButton::shift());
|
||||
}
|
||||
if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
|
||||
_input_devices[0].button_up(KeyboardButton::alt());
|
||||
_input->button_up(KeyboardButton::alt());
|
||||
}
|
||||
if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) {
|
||||
_input_devices[0].button_up(KeyboardButton::meta());
|
||||
_input->button_up(KeyboardButton::meta());
|
||||
}
|
||||
_input_devices[0].button_up(button);
|
||||
_input->button_up(button);
|
||||
}
|
||||
|
||||
ButtonHandle raw_button = map_raw_button(event.keycode);
|
||||
if (raw_button != ButtonHandle::none()) {
|
||||
_input_devices[0].raw_button_up(raw_button);
|
||||
if (event.keycode >= 9 && event.keycode <= 135) {
|
||||
ButtonHandle raw_button = map_raw_button(event.keycode);
|
||||
if (raw_button != ButtonHandle::none()) {
|
||||
_input->raw_button_up(raw_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1617,7 +1527,7 @@ get_button(XKeyEvent &key_event, bool allow_shift) {
|
|||
// can do this in just the ASCII set, because we handle
|
||||
// international keyboards elsewhere (via an input context).
|
||||
if ((key_event.state & (ShiftMask | LockMask)) != 0) {
|
||||
if (key >= XK_a and key <= XK_z) {
|
||||
if (key >= XK_a && key <= XK_z) {
|
||||
key += (XK_A - XK_a);
|
||||
}
|
||||
}
|
||||
|
|
@ -1962,117 +1872,16 @@ map_button(KeySym key) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle x11GraphicsWindow::
|
||||
map_raw_button(KeyCode key) const {
|
||||
switch (key) {
|
||||
case 9: return KeyboardButton::escape();
|
||||
case 10: return KeyboardButton::ascii_key('1');
|
||||
case 11: return KeyboardButton::ascii_key('2');
|
||||
case 12: return KeyboardButton::ascii_key('3');
|
||||
case 13: return KeyboardButton::ascii_key('4');
|
||||
case 14: return KeyboardButton::ascii_key('5');
|
||||
case 15: return KeyboardButton::ascii_key('6');
|
||||
case 16: return KeyboardButton::ascii_key('7');
|
||||
case 17: return KeyboardButton::ascii_key('8');
|
||||
case 18: return KeyboardButton::ascii_key('9');
|
||||
case 19: return KeyboardButton::ascii_key('0');
|
||||
case 20: return KeyboardButton::ascii_key('-');
|
||||
case 21: return KeyboardButton::ascii_key('=');
|
||||
case 22: return KeyboardButton::backspace();
|
||||
case 23: return KeyboardButton::tab();
|
||||
case 24: return KeyboardButton::ascii_key('q');
|
||||
case 25: return KeyboardButton::ascii_key('w');
|
||||
case 26: return KeyboardButton::ascii_key('e');
|
||||
case 27: return KeyboardButton::ascii_key('r');
|
||||
case 28: return KeyboardButton::ascii_key('t');
|
||||
case 29: return KeyboardButton::ascii_key('y');
|
||||
case 30: return KeyboardButton::ascii_key('u');
|
||||
case 31: return KeyboardButton::ascii_key('i');
|
||||
case 32: return KeyboardButton::ascii_key('o');
|
||||
case 33: return KeyboardButton::ascii_key('p');
|
||||
case 34: return KeyboardButton::ascii_key('[');
|
||||
case 35: return KeyboardButton::ascii_key(']');
|
||||
case 36: return KeyboardButton::enter();
|
||||
case 37: return KeyboardButton::lcontrol();
|
||||
case 38: return KeyboardButton::ascii_key('a');
|
||||
case 39: return KeyboardButton::ascii_key('s');
|
||||
case 40: return KeyboardButton::ascii_key('d');
|
||||
case 41: return KeyboardButton::ascii_key('f');
|
||||
case 42: return KeyboardButton::ascii_key('g');
|
||||
case 43: return KeyboardButton::ascii_key('h');
|
||||
case 44: return KeyboardButton::ascii_key('j');
|
||||
case 45: return KeyboardButton::ascii_key('k');
|
||||
case 46: return KeyboardButton::ascii_key('l');
|
||||
case 47: return KeyboardButton::ascii_key(';');
|
||||
case 48: return KeyboardButton::ascii_key('\'');
|
||||
case 49: return KeyboardButton::ascii_key('`');
|
||||
case 50: return KeyboardButton::lshift();
|
||||
case 51: return KeyboardButton::ascii_key('\\');
|
||||
case 52: return KeyboardButton::ascii_key('z');
|
||||
case 53: return KeyboardButton::ascii_key('x');
|
||||
case 54: return KeyboardButton::ascii_key('c');
|
||||
case 55: return KeyboardButton::ascii_key('v');
|
||||
case 56: return KeyboardButton::ascii_key('b');
|
||||
case 57: return KeyboardButton::ascii_key('n');
|
||||
case 58: return KeyboardButton::ascii_key('m');
|
||||
case 59: return KeyboardButton::ascii_key(',');
|
||||
case 60: return KeyboardButton::ascii_key('.');
|
||||
case 61: return KeyboardButton::ascii_key('/');
|
||||
case 62: return KeyboardButton::rshift();
|
||||
case 63: return KeyboardButton::ascii_key('*');
|
||||
case 64: return KeyboardButton::lalt();
|
||||
case 65: return KeyboardButton::space();
|
||||
case 66: return KeyboardButton::caps_lock();
|
||||
case 67: return KeyboardButton::f1();
|
||||
case 68: return KeyboardButton::f2();
|
||||
case 69: return KeyboardButton::f3();
|
||||
case 70: return KeyboardButton::f4();
|
||||
case 71: return KeyboardButton::f5();
|
||||
case 72: return KeyboardButton::f6();
|
||||
case 73: return KeyboardButton::f7();
|
||||
case 74: return KeyboardButton::f8();
|
||||
case 75: return KeyboardButton::f9();
|
||||
case 76: return KeyboardButton::f10();
|
||||
case 77: return KeyboardButton::num_lock();
|
||||
case 78: return KeyboardButton::scroll_lock();
|
||||
case 79: return KeyboardButton::ascii_key('7');
|
||||
case 80: return KeyboardButton::ascii_key('8');
|
||||
case 81: return KeyboardButton::ascii_key('9');
|
||||
case 82: return KeyboardButton::ascii_key('-');
|
||||
case 83: return KeyboardButton::ascii_key('4');
|
||||
case 84: return KeyboardButton::ascii_key('5');
|
||||
case 85: return KeyboardButton::ascii_key('6');
|
||||
case 86: return KeyboardButton::ascii_key('+');
|
||||
case 87: return KeyboardButton::ascii_key('1');
|
||||
case 88: return KeyboardButton::ascii_key('2');
|
||||
case 89: return KeyboardButton::ascii_key('3');
|
||||
case 90: return KeyboardButton::ascii_key('0');
|
||||
case 91: return KeyboardButton::ascii_key('.');
|
||||
|
||||
case 95: return KeyboardButton::f11();
|
||||
case 96: return KeyboardButton::f12();
|
||||
|
||||
case 104: return KeyboardButton::enter();
|
||||
case 105: return KeyboardButton::rcontrol();
|
||||
case 106: return KeyboardButton::ascii_key('/');
|
||||
case 107: return KeyboardButton::print_screen();
|
||||
case 108: return KeyboardButton::ralt();
|
||||
|
||||
case 110: return KeyboardButton::home();
|
||||
case 111: return KeyboardButton::up();
|
||||
case 112: return KeyboardButton::page_up();
|
||||
case 113: return KeyboardButton::left();
|
||||
case 114: return KeyboardButton::right();
|
||||
case 115: return KeyboardButton::end();
|
||||
case 116: return KeyboardButton::down();
|
||||
case 117: return KeyboardButton::page_down();
|
||||
case 118: return KeyboardButton::insert();
|
||||
case 119: return KeyboardButton::del();
|
||||
|
||||
case 127: return KeyboardButton::pause();
|
||||
|
||||
case 133: return KeyboardButton::lmeta();
|
||||
case 134: return KeyboardButton::rmeta();
|
||||
case 135: return KeyboardButton::menu();
|
||||
#ifdef PHAVE_LINUX_INPUT_H
|
||||
// Most X11 servers are configured to use the evdev driver, which
|
||||
// adds 8 to the underlying evdev keycodes (not sure why).
|
||||
// In any case, this means we can use the same mapping as our raw
|
||||
// input code, which uses evdev directly.
|
||||
int index = key - 8;
|
||||
if (index >= 0) {
|
||||
return EvdevInputDevice::map_button(index);
|
||||
}
|
||||
#endif
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ protected:
|
|||
static Bool check_event(X11_Display *display, XEvent *event, char *arg);
|
||||
|
||||
void open_raw_mice();
|
||||
void poll_raw_mice();
|
||||
|
||||
private:
|
||||
X11_Cursor get_cursor(const Filename &filename);
|
||||
|
|
@ -89,6 +88,7 @@ protected:
|
|||
Colormap _colormap;
|
||||
XIC _ic;
|
||||
XVisualInfo *_visual_info;
|
||||
GraphicsWindowInputDevice *_input;
|
||||
|
||||
bool _have_xrandr;
|
||||
#ifdef HAVE_XRANDR
|
||||
|
|
|
|||
Loading…
Reference in New Issue