init
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
PROJECT(openvibe-plugins-tools)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION ${OV_GLOBAL_VERSION_STRING})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.inl)
|
||||
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
FOLDER ${PLUGINS_FOLDER}
|
||||
COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared")
|
||||
|
||||
# ---------------------------------
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindOpenViBEToolkit")
|
||||
INCLUDE("FindOpenViBEModuleEBML")
|
||||
INCLUDE("FindOpenViBEModuleSystem")
|
||||
INCLUDE("FindThirdPartyGTK")
|
||||
|
||||
INCLUDE("FindThirdPartyX11")
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
INSTALL(DIRECTORY share/ DESTINATION ${DIST_DATADIR}/openvibe/plugins/tools)
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_KeypressEmulator Keypress Emulator
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Description|
|
||||
Emulates a keyboard keypress when receiving a specific stimulation. In principle this box could be used to drive some 3rd party application that allows keyboard control but not any other communication from OpenViBE. Currently this box is implemented only on Windows.
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Inputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Inputs|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Input1|
|
||||
Stimulation stream to listen to.
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Input1|
|
||||
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Setting1|
|
||||
The stimulation that will trigger the keypress.
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Setting1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Setting2|
|
||||
The key to press.
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Setting2|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Setting3|
|
||||
The key modifier (alt, ctrl, ...)
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Setting3|
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Examples|
|
||||
An easy way to test the box is to make it receive stimulations from a Clock Stimulator box, and make a text editor active on the desktop after clicking Play. The characters corresponding to the key should appear in the editor.
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_KeypressEmulator_Miscellaneous|
|
||||
The Keypress Emulator should be enhanced to be able to map an arbitrary number of different stimulations. This development would be relatively straightforward (e.g. look at VRPN boxes for example). Meanwhile if you need several keys pressed, you can use several Keypress Emulator boxes, each configured for a different stimulation+key.
|
||||
* |OVP_DocEnd_BoxAlgorithm_KeypressEmulator_Miscellaneous|
|
||||
*/
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_MessageSpy EBML stream spy
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Description|
|
||||
* The purpose of this box is to spy a message connection and
|
||||
* decode its contents to the log manager. The box loops over
|
||||
* the possible types and keys inside a message and prints
|
||||
* the output.
|
||||
*
|
||||
* This box is mostly useful for debug purpose. It allows
|
||||
* a developper to check what arrives to a box in a human
|
||||
* readable way.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Inputs|
|
||||
* This box can receive as many message inputs as necessary.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Inputs|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Input1|
|
||||
* This is the default input of this box.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Input1|
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Setting1|
|
||||
* Indicates what log level will be used to
|
||||
* print the message contents.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Setting1|
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Examples|
|
||||
There is a simple example scenario provided in box-tutorials/ called messaging.xml.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MessageSpy_Miscellaneous|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MessageSpy_Miscellaneous|
|
||||
*/
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_MouseTracking Mouse Tracking
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Description|
|
||||
Opens a gtk window and track mouse within that window.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Outputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Outputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Outputs|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Output1|
|
||||
Output the raw coordinates of mouse position.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Output1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Output2|
|
||||
Output relative coordinates to previous position of the mouse.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Output2|
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Setting1|
|
||||
Sampling frequency.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Setting1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Setting2|
|
||||
Generated epoch sample count. Set the size of chunk. 1 in most cases : there is only one position at each time.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Setting2|
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Examples|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MouseTracking_Miscellaneous|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MouseTracking_Miscellaneous|
|
||||
*/
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
OVTK_NodeId_Acquisition_Header EBML::CIdentifier(0x00000000, 0x00004239) master
|
||||
OVTK_NodeId_Acquisition_AcquisitionInfo EBML::CIdentifier(0x00000000, 0x00004240) master
|
||||
OVTK_NodeId_Acquisition_ExperimentId EBML::CIdentifier(0x00000000, 0x00004241) uinteger
|
||||
OVTK_NodeId_Acquisition_SubjectAge EBML::CIdentifier(0x00000000, 0x00004242) uinteger
|
||||
OVTK_NodeId_Acquisition_SubjectGender EBML::CIdentifier(0x00000000, 0x00004243) uinteger
|
||||
OVTK_NodeId_Acquisition_ChannelCount EBML::CIdentifier(0x00000000, 0x00004244) uinteger
|
||||
OVTK_NodeId_Acquisition_Sampling EBML::CIdentifier(0x00000000, 0x00004245) uinteger
|
||||
OVTK_NodeId_Acquisition_ChannelNames EBML::CIdentifier(0x00000000, 0x00004246) master
|
||||
OVTK_NodeId_Acquisition_ChannelName EBML::CIdentifier(0x00000000, 0x00004247) string
|
||||
OVTK_NodeId_Acquisition_GainFactors EBML::CIdentifier(0x00000000, 0x00004248) master
|
||||
OVTK_NodeId_Acquisition_GainFactor EBML::CIdentifier(0x00000000, 0x00004249) float
|
||||
OVTK_NodeId_Acquisition_ChannelLocations EBML::CIdentifier(0x00000000, 0x00004250) master
|
||||
OVTK_NodeId_Acquisition_ChannelLocation EBML::CIdentifier(0x00000000, 0x00004251) binary(double)
|
||||
OVTK_NodeId_Acquisition_Buffer EBML::CIdentifier(0x00000000, 0x0000005A) master
|
||||
OVTK_NodeId_Acquisition_Samples EBML::CIdentifier(0x00000000, 0x0000005B) master
|
||||
OVTK_NodeId_Acquisition_SamplesPerChannelCount EBML::CIdentifier(0x00000000, 0x0000005C) uinteger
|
||||
OVTK_NodeId_Acquisition_SampleBlock EBML::CIdentifier(0x00000000, 0x0000005D) binary(float)
|
||||
OVTK_NodeId_Acquisition_Stimulations EBML::CIdentifier(0x00000000, 0x00000060) master
|
||||
OVTK_NodeId_Acquisition_StimulationsCount EBML::CIdentifier(0x00000000, 0x00000061) uinteger
|
||||
OVTK_NodeId_Acquisition_Stimulation EBML::CIdentifier(0x00000000, 0x00000062) master
|
||||
OVTK_NodeId_Acquisition_StimulationSampleIndex EBML::CIdentifier(0x00000000, 0x00000063) uinteger
|
||||
OVTK_NodeId_Acquisition_StimulationIdentifier EBML::CIdentifier(0x00000000, 0x00000064) uinteger
|
||||
|
||||
OVTK_NodeId_Header EBML::CIdentifier(0x002B395F, 0x108ADFAE) master
|
||||
OVTK_NodeId_Header_StreamType EBML::CIdentifier(0x00CDD0F7, 0x46B0278D) uinteger
|
||||
OVTK_NodeId_Header_StreamVersion EBML::CIdentifier(0x006F5A08, 0x7796EBC5) uinteger
|
||||
OVTK_NodeId_Buffer EBML::CIdentifier(0x00CF2101, 0x02375310) master
|
||||
OVTK_NodeId_End EBML::CIdentifier(0x00D9DDC3, 0x0B12873A) master
|
||||
|
||||
OVTK_NodeId_Header_StreamedMatrix EBML::CIdentifier(0x0072F560, 0x7ED2CBED) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_DimensionCount EBML::CIdentifier(0x003FEBD4, 0x2725D428) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension EBML::CIdentifier(0x0000E3C0, 0x3A7D5141) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Size EBML::CIdentifier(0x001302F7, 0x36D8438A) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Label EBML::CIdentifier(0x00153E40, 0x190227E0) string
|
||||
OVTK_NodeId_Buffer_StreamedMatrix EBML::CIdentifier(0x00120663, 0x08FBC165) master
|
||||
OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer EBML::CIdentifier(0x00B18C10, 0x427D098C) binary(double)
|
||||
|
||||
OVTK_NodeId_Header_Signal EBML::CIdentifier(0x007855DE, 0x3748D375) master
|
||||
OVTK_NodeId_Header_Signal_Sampling EBML::CIdentifier(0x00141C43, 0x0C37006B) uinteger
|
||||
|
||||
OVTK_NodeId_Header_Spectrum EBML::CIdentifier(0x00CCFA4B, 0x14F37D4D) master
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyBand EBML::CIdentifier(0x0010983C, 0x21F8BDE5) master
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyBand_Start EBML::CIdentifier(0x00AA5654, 0x2403A2CB) float
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyBand_Stop EBML::CIdentifier(0x00A44C82, 0x05BE50D5) float
|
||||
|
||||
OVTK_NodeId_Buffer_Stimulation EBML::CIdentifier(0x006DEABE, 0x7FC05A20) master
|
||||
OVTK_NodeId_Buffer_Stimulation_NumberOfStimulations EBML::CIdentifier(0x00BB790B, 0x2B8574D8) uinteger
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation EBML::CIdentifier(0x0016EAC6, 0x29FBCAA1) master
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation_ID EBML::CIdentifier(0x006FA5DB, 0x4BAC31E9) uinteger
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation_Date EBML::CIdentifier(0x00B866D8, 0x14DA5374) uinteger
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation_Duration EBML::CIdentifier(0x14EE055F, 0x87FBCC9C) uinteger
|
||||
|
||||
OVTK_NodeId_Header_ChannelUnits EBML::CIdentifier(0x17400C76, 0x16CF14C8) master
|
||||
OVTK_NodeId_Header_ChannelUnits_Dynamic EBML::CIdentifier(0x7307023C, 0x7F754D2E) uinteger
|
||||
|
||||
OVTK_NodeId_Header_ChannelLocalisation EBML::CIdentifier(0xF2CFE60B, 0xEFD63E3B) master
|
||||
OVTK_NodeId_Header_ChannelLocalisation_Dynamic EBML::CIdentifier(0x5338AF5C, 0x07C469C3) uinteger
|
||||
|
||||
OVTK_NodeId_Header_ExperimentInfo EBML::CIdentifier(0x00746BA0, 0x115AE04D) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Experiment EBML::CIdentifier(0x0011D6B7, 0x48F1AA39) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Experiment_ID EBML::CIdentifier(0x006ACD74, 0x1C960C26) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Experiment_Date EBML::CIdentifier(0x002F8FB7, 0x6DA7552D) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject EBML::CIdentifier(0x003EC620, 0x333E0A94) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_ID EBML::CIdentifier(0x00D62974, 0x473D4AA5) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_Name EBML::CIdentifier(0x0041FD0A, 0x6BCD9A99) string
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_Age EBML::CIdentifier(0x00DF7DD9, 0x33336C51) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_Gender EBML::CIdentifier(0x0069BB84, 0x3FC8E149) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context EBML::CIdentifier(0x0018C291, 0x7985DFDD) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_LaboratoryID EBML::CIdentifier(0x003F11B9, 0x26D76D9C) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_LaboratoryName EBML::CIdentifier(0x00EB1F23, 0x51C23B83) string
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_TechnicianID EBML::CIdentifier(0x00874A7F, 0x60DC34C2) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_TechnicianName EBML::CIdentifier(0x00C8C393, 0x31CE5B3E) string
|
||||
|
||||
DummyEnd EBML::CIdentifier(0x00000000, 0x00000000) binary
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
#include "ovpCBoxAlgorithmKeypressEmulator.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
#if defined(TARGET_OS_Windows)
|
||||
#include <winuser.h>
|
||||
#endif
|
||||
|
||||
bool CBoxAlgorithmKeypressEmulator::initialize()
|
||||
{
|
||||
m_decoder.initialize(*this, 0);
|
||||
|
||||
m_triggerStimulation = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
|
||||
m_keyToPress = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
|
||||
|
||||
#if defined(TARGET_OS_Windows)
|
||||
const uint64_t modifier = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
|
||||
if (modifier == OVP_TypeId_Keypress_Modifier_Shift.id()) { m_modifier = VK_SHIFT; }
|
||||
else if (modifier == OVP_TypeId_Keypress_Modifier_Control.id()) { m_modifier = VK_CONTROL; }
|
||||
else if (modifier == OVP_TypeId_Keypress_Modifier_Alt.id()) { m_modifier = VK_MENU; }
|
||||
#elif defined(TARGET_OS_Linux)
|
||||
// @todo implement the whole linux solution
|
||||
// Handle modifier on linux here
|
||||
getLogManager() << Kernel::LogLevel_Error << "This box is only implemented on Windows for the moment\n";
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
||||
bool CBoxAlgorithmKeypressEmulator::uninitialize()
|
||||
{
|
||||
m_decoder.uninitialize();
|
||||
return true;
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
||||
bool CBoxAlgorithmKeypressEmulator::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
||||
bool CBoxAlgorithmKeypressEmulator::process()
|
||||
{
|
||||
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
|
||||
|
||||
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
|
||||
{
|
||||
m_decoder.decode(i);
|
||||
|
||||
if (m_decoder.isHeaderReceived()) { } // NOP
|
||||
if (m_decoder.isBufferReceived())
|
||||
{
|
||||
const IStimulationSet* set = m_decoder.getOutputStimulationSet();
|
||||
for (size_t s = 0; s < set->getStimulationCount(); ++s)
|
||||
{
|
||||
if (set->getStimulationIdentifier(s) == m_triggerStimulation)
|
||||
{
|
||||
#if defined(TARGET_OS_Windows)
|
||||
getLogManager() << Kernel::LogLevel_Debug << "Received " << m_triggerStimulation << ", pressing Windows virtual key " << m_keyToPress
|
||||
<< " with modifier " << m_modifier << ", delay is at least "
|
||||
<< CTime(this->getPlayerContext().getCurrentTime() - set->getStimulationDate(s)) << "\n";
|
||||
|
||||
// @todo the stimulation time is not necessarily RIGHT NOW. A very
|
||||
// accurate solution would call SendInput exactly when the key needs to be pressed. Unfortunately when
|
||||
// we receive the stim chunk, the keypress is already old, and we can't press keys into the past. In this sense
|
||||
// sending immediately might be the best we can do.
|
||||
// Note that the speccing the "time" field of INPUT as nonzero doesn't send keypresses to the past or future.
|
||||
if (m_modifier != 0)
|
||||
{
|
||||
INPUT keypress[3];
|
||||
memset(keypress, 0, sizeof(INPUT) * 3);
|
||||
keypress[0].type = INPUT_KEYBOARD;
|
||||
keypress[0].ki.wVk = WORD(m_modifier);
|
||||
keypress[1].type = INPUT_KEYBOARD;
|
||||
keypress[1].ki.wVk = WORD(m_keyToPress);
|
||||
keypress[2].type = INPUT_KEYBOARD;
|
||||
keypress[2].ki.wVk = WORD(m_modifier);
|
||||
keypress[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
SendInput(3, keypress, sizeof(INPUT));
|
||||
}
|
||||
else
|
||||
{
|
||||
INPUT keypress;
|
||||
memset(&keypress, 0, sizeof(INPUT));
|
||||
keypress.type = INPUT_KEYBOARD;
|
||||
keypress.ki.wVk = WORD(m_keyToPress);
|
||||
SendInput(1, &keypress, sizeof(INPUT));
|
||||
}
|
||||
#elif defined(TARGET_OS_Linux)
|
||||
// @todo
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_decoder.isEndReceived()) { } // NOP
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBoxAlgorithmKeypressEmulator::registerEnums(const Kernel::IPluginModuleContext& ctx)
|
||||
{
|
||||
ctx.getTypeManager().registerEnumerationType(OVP_TypeId_Keypress_Modifier, "Key modifier");
|
||||
ctx.getTypeManager().registerEnumerationEntry(OVP_TypeId_Keypress_Modifier, "None", OVP_TypeId_Keypress_Modifier_None.id());
|
||||
ctx.getTypeManager().registerEnumerationEntry(OVP_TypeId_Keypress_Modifier, "Shift", OVP_TypeId_Keypress_Modifier_Shift.id());
|
||||
ctx.getTypeManager().registerEnumerationEntry(OVP_TypeId_Keypress_Modifier, "Ctrl", OVP_TypeId_Keypress_Modifier_Control.id());
|
||||
ctx.getTypeManager().registerEnumerationEntry(OVP_TypeId_Keypress_Modifier, "Alt", OVP_TypeId_Keypress_Modifier_Alt.id());
|
||||
|
||||
ctx.getTypeManager().registerEnumerationType(OVP_TypeId_Keypress_Key, "Key");
|
||||
|
||||
#if defined(TARGET_OS_Windows)
|
||||
// @note this solution makes the scenario not portable between win<->linux. The challenge is keys such as F1 etc,
|
||||
// otherwise we could just read ascii char and map it to a key.
|
||||
// @fixme we're also not able to expose all the possible keys to the user this way, but the problem seems to be that
|
||||
// GetKeyNameTextA does not give meaningful & different names to all keys for some reason.
|
||||
// - The current appoarch attempts to expose the usual 'english' keys that can be visualized by pango.
|
||||
// - We do not necessarily get arrow keys listed as these may not have a separate representation from
|
||||
// the corresponding 'numpad' keys with the functions we call here; esp. GetKeyNameTextA seems to
|
||||
// depend on the keyboard in use. This limits the scenario portability across keyboards.
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
const UINT mapped = MapVirtualKeyA(UINT(i), MAPVK_VK_TO_VSC);
|
||||
const LONG scanCode = mapped << 16;
|
||||
|
||||
if (scanCode)
|
||||
{
|
||||
CHAR buffer[512];
|
||||
if (GetKeyNameTextA(scanCode, buffer, 512))
|
||||
{
|
||||
std::string tmp(buffer);
|
||||
|
||||
if (tmp.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_*&$%@^#!-+/\\ :;,.'`~()[]\"=") != std::string::npos)
|
||||
{
|
||||
// Some weird characters here, may be difficult to render for pango, ignore this key
|
||||
continue;
|
||||
}
|
||||
|
||||
// GetKeyNameTextA can return the same name for different keys. Only use the first one.
|
||||
if (ctx.getTypeManager().getEnumerationEntryValueFromName(OVP_TypeId_Keypress_Key, buffer) == CIdentifier::undefined().id())
|
||||
{
|
||||
ctx.getTypeManager().registerEnumerationEntry(OVP_TypeId_Keypress_Key, buffer, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(TARGET_OS_Linux)
|
||||
// @todo register the linux keys to the enum here
|
||||
#endif
|
||||
}
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
/**
|
||||
* \class CBoxAlgorithmKeypressEmulator
|
||||
* \author Jussi T. Lindgren / Inria
|
||||
* \date 29.Oct.2019
|
||||
* \brief Emulates keypresses on a keyboard based on input stimulations. Based on a request from Fabien Lotte / POTIOC.
|
||||
*
|
||||
*/
|
||||
class CBoxAlgorithmKeypressEmulator final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { delete this; }
|
||||
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
|
||||
bool processInput(const size_t index) override;
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_KeypressEmulator)
|
||||
|
||||
// Register enums to the kernel used by this box
|
||||
static void registerEnums(const Kernel::IPluginModuleContext& ctx);
|
||||
|
||||
protected:
|
||||
Toolkit::TStimulationDecoder<CBoxAlgorithmKeypressEmulator> m_decoder;
|
||||
|
||||
// @todo for multiple triggers, use std::map<>
|
||||
uint64_t m_triggerStimulation = 0;
|
||||
uint64_t m_keyToPress = 0;
|
||||
uint64_t m_modifier = 0;
|
||||
};
|
||||
|
||||
class CBoxAlgorithmKeypressEmulatorDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { }
|
||||
|
||||
CString getName() const override { return CString("Keypress Emulator"); }
|
||||
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
|
||||
CString getAuthorCompanyName() const override { return CString("Inria"); }
|
||||
CString getShortDescription() const override { return CString("Emulates pressing keyboard keys when receiving stimulations"); }
|
||||
CString getDetailedDescription() const override { return CString(""); }
|
||||
CString getCategory() const override { return CString("Tools"); }
|
||||
CString getVersion() const override { return CString("0.1"); }
|
||||
CString getStockItemName() const override { return CString("gtk-index"); }
|
||||
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_KeypressEmulator; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmKeypressEmulator; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("Stimulations",OV_TypeId_Stimulations);
|
||||
|
||||
// @todo add support for multiple keys, e.g. look at VRPN boxes for howto
|
||||
prototype.addSetting("Trigger", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
|
||||
prototype.addSetting("Key to press", OVP_TypeId_Keypress_Key, "A");
|
||||
prototype.addSetting("Key modifier", OVP_TypeId_Keypress_Modifier, OVP_TypeId_Keypress_Modifier_None.toString());
|
||||
|
||||
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_KeypressEmulatorDesc)
|
||||
};
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#include "ovpCBoxAlgorithmLatencyEvaluation.h"
|
||||
#include <system/ovCTime.h>
|
||||
|
||||
// @note by just repeatedly printing to the console, this box introduces significant latency by itself.
|
||||
// @fixme If it makes sense to enable this box at all, it should be reimplemented as printing to a small GUI widget instead.
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
bool CBoxAlgorithmLatencyEvaluation::initialize()
|
||||
{
|
||||
CString logLevel;
|
||||
getBoxAlgorithmContext()->getStaticBoxContext()->getSettingValue(0, logLevel);
|
||||
m_LogLevel = Kernel::ELogLevel(getBoxAlgorithmContext()->getPlayerContext()->getTypeManager().getEnumerationEntryValueFromName(OV_TypeId_LogLevel, logLevel));
|
||||
|
||||
m_StartTime = System::Time::zgetTime();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmLatencyEvaluation::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmLatencyEvaluation::process()
|
||||
{
|
||||
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
|
||||
const uint64_t time = getPlayerContext().getCurrentTime();
|
||||
|
||||
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
|
||||
{
|
||||
const uint64_t start = boxContext.getInputChunkStartTime(0, i);
|
||||
const uint64_t end = boxContext.getInputChunkEndTime(0, i);
|
||||
const double startLatency = (double((int64_t(time - start) >> 22) * 1000) / 1024.0);
|
||||
const double endLatency = (double((int64_t(time - end) >> 22) * 1000) / 1024.0);
|
||||
|
||||
// getLogManager() << Kernel::LogLevel_Debug << "Timing values [start:end:current]=[" << tStart << ":" << tEnd << ":" << time << "]\n";
|
||||
getLogManager() << m_LogLevel << "Current latency at chunk " << i << " [start:end]=[" << startLatency << ":" << endLatency << "] ms\n";
|
||||
|
||||
boxContext.markInputAsDeprecated(0, i);
|
||||
}
|
||||
|
||||
const uint64_t elapsed = System::Time::zgetTime() - m_StartTime;
|
||||
const double latency = (double((int64_t(elapsed - time) >> 22) * 1000) / 1024.0);
|
||||
|
||||
getLogManager() << m_LogLevel << "Inner latency : " << latency << " ms\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
class CBoxAlgorithmLatencyEvaluation final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { delete this; }
|
||||
|
||||
bool initialize() override;
|
||||
bool uninitialize() override { return true; }
|
||||
bool processInput(const size_t index) override;
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_LatencyEvaluation)
|
||||
|
||||
uint64_t m_StartTime = 0;
|
||||
Kernel::ELogLevel m_LogLevel = Kernel::ELogLevel::LogLevel_None;
|
||||
};
|
||||
|
||||
class CBoxAlgorithmLatencyEvaluationDesc final : public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { }
|
||||
|
||||
CString getName() const override { return CString("Latency evaluation"); }
|
||||
CString getAuthorName() const override { return CString("Yann Renard"); }
|
||||
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
|
||||
CString getShortDescription() const override { return CString("Evaluates i/o jittering and outputs values to log manager"); }
|
||||
|
||||
CString getDetailedDescription() const override
|
||||
{
|
||||
return CString("This box evaluates i/o jittering comparing input chunk' start and end time against current clock time");
|
||||
}
|
||||
|
||||
CString getCategory() const override { return CString("Tools"); }
|
||||
CString getVersion() const override { return CString("1.0"); }
|
||||
CString getStockItemName() const override { return CString("gtk-info"); }
|
||||
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_LatencyEvaluation; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmLatencyEvaluation; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("input", OV_TypeId_EBMLStream);
|
||||
prototype.addSetting("Log level to use", OV_TypeId_LogLevel, "Trace");
|
||||
prototype.addFlag(Kernel::BoxFlag_CanModifyInput);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_LatencyEvaluationDesc)
|
||||
};
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
#if defined(TARGET_HAS_ThirdPartyGTK)
|
||||
|
||||
#include "ovpCBoxAlgorithmMouseTracking.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
|
||||
void motion_event_handler(GtkWidget* widget, GdkEventMotion* event, gpointer data);
|
||||
|
||||
bool CBoxAlgorithmMouseTracking::initialize()
|
||||
{
|
||||
// Feature vector stream encoder
|
||||
m_algo0SignalEncoder.initialize(*this, 0);
|
||||
// Feature vector stream encoder
|
||||
m_algo1SignalEncoder.initialize(*this, 1);
|
||||
|
||||
m_algo0SignalEncoder.getInputMatrix().setReferenceTarget(m_absoluteCoordinateBuffer);
|
||||
m_algo1SignalEncoder.getInputMatrix().setReferenceTarget(m_relativeCoordinateBuffer);
|
||||
|
||||
// Allocates coordinates Matrix
|
||||
m_absoluteCoordinateBuffer = new CMatrix();
|
||||
m_relativeCoordinateBuffer = new CMatrix();
|
||||
|
||||
// Retrieves settings
|
||||
m_sampling = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
|
||||
m_nGeneratedEpochSample = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
|
||||
|
||||
m_nSentSample = 0;
|
||||
m_MouseX = 0;
|
||||
m_MouseY = 0;
|
||||
m_prevX = 0;
|
||||
m_prevY = 0;
|
||||
|
||||
// Creates empty window to get mouse position
|
||||
m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_add_events(m_window, GDK_POINTER_MOTION_MASK);
|
||||
gtk_window_maximize(GTK_WINDOW(m_window));
|
||||
gtk_widget_show_all(m_window);
|
||||
|
||||
g_signal_connect(m_window, "motion-notify-event", G_CALLBACK(motion_event_handler), this);
|
||||
|
||||
m_headerSent = false;
|
||||
|
||||
m_algo0SignalEncoder.getInputSamplingRate() = m_sampling;
|
||||
m_algo1SignalEncoder.getInputSamplingRate() = m_sampling;
|
||||
|
||||
return true;
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
||||
bool CBoxAlgorithmMouseTracking::uninitialize()
|
||||
{
|
||||
m_algo0SignalEncoder.uninitialize();
|
||||
m_algo1SignalEncoder.uninitialize();
|
||||
|
||||
delete m_absoluteCoordinateBuffer;
|
||||
m_absoluteCoordinateBuffer = nullptr;
|
||||
|
||||
delete m_relativeCoordinateBuffer;
|
||||
m_relativeCoordinateBuffer = nullptr;
|
||||
|
||||
gtk_widget_destroy(m_window);
|
||||
m_window = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
||||
|
||||
bool CBoxAlgorithmMouseTracking::processClock(Kernel::CMessageClock& /*msg*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
||||
|
||||
uint64_t CBoxAlgorithmMouseTracking::getClockFrequency()
|
||||
{
|
||||
// Intentional parameter swap to get the frequency
|
||||
m_clockFrequency = CTime(m_nGeneratedEpochSample, m_sampling).time();
|
||||
|
||||
return m_clockFrequency;
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
bool CBoxAlgorithmMouseTracking::process()
|
||||
{
|
||||
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
|
||||
|
||||
//Send header and initialize Matrix
|
||||
if (!m_headerSent)
|
||||
{
|
||||
m_absoluteCoordinateBuffer->resize(2, m_nGeneratedEpochSample);
|
||||
m_absoluteCoordinateBuffer->setDimensionLabel(0, 0, "x");
|
||||
m_absoluteCoordinateBuffer->setDimensionLabel(0, 1, "y");
|
||||
|
||||
m_relativeCoordinateBuffer->resize(2, m_nGeneratedEpochSample);
|
||||
m_relativeCoordinateBuffer->setDimensionLabel(0, 0, "x");
|
||||
m_relativeCoordinateBuffer->setDimensionLabel(0, 1, "y");
|
||||
|
||||
|
||||
m_algo0SignalEncoder.encodeHeader();
|
||||
m_algo1SignalEncoder.encodeHeader();
|
||||
|
||||
m_headerSent = true;
|
||||
|
||||
boxContext.markOutputAsReadyToSend(0, 0, 0);
|
||||
boxContext.markOutputAsReadyToSend(1, 0, 0);
|
||||
}
|
||||
else //Do the process and send coordinates to output
|
||||
{
|
||||
const size_t nSentSample = m_nSentSample;
|
||||
|
||||
|
||||
for (size_t i = 0; i < m_nGeneratedEpochSample; ++i)
|
||||
{
|
||||
m_absoluteCoordinateBuffer->getBuffer()[0 * m_nGeneratedEpochSample + i] = m_MouseX;
|
||||
m_absoluteCoordinateBuffer->getBuffer()[1 * m_nGeneratedEpochSample + i] = m_MouseY;
|
||||
|
||||
m_relativeCoordinateBuffer->getBuffer()[0 * m_nGeneratedEpochSample + i] = m_MouseX - m_prevX;
|
||||
m_relativeCoordinateBuffer->getBuffer()[1 * m_nGeneratedEpochSample + i] = m_MouseY - m_prevY;
|
||||
}
|
||||
|
||||
|
||||
m_prevX = m_MouseX;
|
||||
m_prevY = m_MouseY;
|
||||
|
||||
m_nSentSample += m_nGeneratedEpochSample;
|
||||
|
||||
const uint64_t tStart = CTime(m_sampling, nSentSample).time();
|
||||
const uint64_t tEnd = CTime(m_sampling, m_nSentSample).time();
|
||||
|
||||
m_algo0SignalEncoder.encodeBuffer();
|
||||
m_algo1SignalEncoder.encodeBuffer();
|
||||
|
||||
boxContext.markOutputAsReadyToSend(0, tStart, tEnd);
|
||||
boxContext.markOutputAsReadyToSend(1, tStart, tEnd);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// CALLBACK
|
||||
// Get mouse position
|
||||
void motion_event_handler(GtkWidget* /*widget*/, GdkEventMotion* event, gpointer data)
|
||||
{
|
||||
CBoxAlgorithmMouseTracking* box = static_cast<CBoxAlgorithmMouseTracking*>(data);
|
||||
box->m_MouseX = double(event->x);
|
||||
box->m_MouseY = double(event->y);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(TARGET_HAS_ThirdPartyGTK)
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
/**
|
||||
* \class CBoxAlgorithmMouseTracking
|
||||
* \author Alison Cellard (Inria)
|
||||
* \date Mon Mar 10 15:07:21 2014
|
||||
* \brief The class CBoxAlgorithmMouseTracking describes the box Mouse tracking.
|
||||
*
|
||||
*/
|
||||
class CBoxAlgorithmMouseTracking final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
|
||||
// CBoxAlgorithmMouseTracking();
|
||||
void release() override { delete this; }
|
||||
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
|
||||
bool processClock(Kernel::CMessageClock& msg) override;
|
||||
uint64_t getClockFrequency() override;
|
||||
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_MouseTracking)
|
||||
|
||||
protected:
|
||||
// Feature vector stream encoder
|
||||
Toolkit::TSignalEncoder<CBoxAlgorithmMouseTracking> m_algo0SignalEncoder;
|
||||
// Feature vector stream encoder
|
||||
Toolkit::TSignalEncoder<CBoxAlgorithmMouseTracking> m_algo1SignalEncoder;
|
||||
|
||||
// To check if the header was sent or not
|
||||
bool m_headerSent = false;
|
||||
|
||||
// Requested Sampling frequency
|
||||
size_t m_sampling = 0;
|
||||
// Process clock frequency
|
||||
uint64_t m_clockFrequency = 0;
|
||||
|
||||
// Length of output chunks
|
||||
size_t m_nGeneratedEpochSample = 0;
|
||||
// Absolute coordinates of the mouse pointer, that is, relative to the window in fullscreen
|
||||
CMatrix* m_absoluteCoordinateBuffer = nullptr;
|
||||
// Relative coordinates of the mouse pointer, the coordinates is relative to the previous point
|
||||
CMatrix* m_relativeCoordinateBuffer = nullptr;
|
||||
|
||||
size_t m_nSentSample = 0;
|
||||
|
||||
// Gtk window to track mouse position
|
||||
GtkWidget* m_window = nullptr;
|
||||
|
||||
// X coordinate from the previous position (in pixel, reference is upper left corner of window)
|
||||
double m_prevX = 0;
|
||||
// Y coordinate from the previous position (in pixel, reference is upper left corner of window)
|
||||
double m_prevY = 0;
|
||||
|
||||
|
||||
public:
|
||||
// X coordinate of mouse current position
|
||||
double m_MouseX = 0;
|
||||
// Y coordinate of mouse current position
|
||||
double m_MouseY = 0;
|
||||
};
|
||||
|
||||
|
||||
class CBoxAlgorithmMouseTrackingListener final : public Toolkit::TBoxListener<IBoxListener>
|
||||
{
|
||||
public:
|
||||
bool onSettingValueChanged(Kernel::IBox& /*box*/, const size_t /*index*/) override { return true; }
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class CBoxAlgorithmMouseTrackingDesc
|
||||
* \author Alison Cellard (Inria)
|
||||
* \date Mon Mar 10 15:07:21 2014
|
||||
* \brief Descriptor of the box Mouse tracking.
|
||||
*
|
||||
*/
|
||||
class CBoxAlgorithmMouseTrackingDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { }
|
||||
|
||||
CString getName() const override { return CString("Mouse Tracking"); }
|
||||
CString getAuthorName() const override { return CString("Alison Cellard"); }
|
||||
CString getAuthorCompanyName() const override { return CString("Inria"); }
|
||||
CString getShortDescription() const override { return CString("Track mouse position within the screen"); }
|
||||
|
||||
CString getDetailedDescription() const override { return CString("Return absolute and relative to the previous one mouse position"); }
|
||||
|
||||
CString getCategory() const override { return CString("Tools"); }
|
||||
CString getVersion() const override { return CString("1"); }
|
||||
CString getStockItemName() const override { return CString("gtk-index"); }
|
||||
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_MouseTracking; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmMouseTracking; }
|
||||
|
||||
|
||||
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmMouseTrackingListener; }
|
||||
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addOutput("Absolute coordinate",OV_TypeId_Signal);
|
||||
prototype.addOutput("Previous relative coordinate",OV_TypeId_Signal);
|
||||
|
||||
prototype.addSetting("Sampling Frequency",OV_TypeId_Integer, "16");
|
||||
prototype.addSetting("Generated epoch sample count",OV_TypeId_Integer, "1");
|
||||
|
||||
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_MouseTrackingDesc)
|
||||
};
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
|
||||
#endif
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
// Boxes
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
#define OVP_ClassId_BoxAlgorithm_LatencyEvaluation OpenViBE::CIdentifier(0x0AD11EC1, 0x7EF3690B)
|
||||
#define OVP_ClassId_BoxAlgorithm_LatencyEvaluationDesc OpenViBE::CIdentifier(0x5DB56A54, 0x5380262B)
|
||||
#define OVP_ClassId_BoxAlgorithm_MouseTracking OpenViBE::CIdentifier(0x1E386EE5, 0x203E13C6)
|
||||
#define OVP_ClassId_BoxAlgorithm_MouseTrackingDesc OpenViBE::CIdentifier(0x7A31C11B, 0xF522262E)
|
||||
#define OVP_ClassId_BoxAlgorithm_KeypressEmulator OpenViBE::CIdentifier(0x38503532, 0x19494145)
|
||||
#define OVP_ClassId_BoxAlgorithm_KeypressEmulatorDesc OpenViBE::CIdentifier(0x59286224, 0x99423852)
|
||||
|
||||
// Global defines
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
|
||||
#include "ovp_global_defines.h"
|
||||
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
|
||||
|
||||
#define OV_AttributeId_Box_FlagIsUnstable OpenViBE::CIdentifier(0x666FFFFF, 0x666FFFFF)
|
||||
|
||||
#define OVP_TypeId_Keypress_Key OpenViBE::CIdentifier(0x23E525F9, 0x005F187D)
|
||||
#define OVP_TypeId_Keypress_Modifier OpenViBE::CIdentifier(0x0C4F4585, 0x78B246AC)
|
||||
#define OVP_TypeId_Keypress_Modifier_None OpenViBE::CIdentifier(0x5A70497E, 0x52F57199)
|
||||
#define OVP_TypeId_Keypress_Modifier_Shift OpenViBE::CIdentifier(0x47534AA6, 0x138A1130)
|
||||
#define OVP_TypeId_Keypress_Modifier_Control OpenViBE::CIdentifier(0x67C6455F, 0x08E6134D)
|
||||
#define OVP_TypeId_Keypress_Modifier_Alt OpenViBE::CIdentifier(0x77577AEA, 0x74CD7E3E)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
#include "ovp_defines.h"
|
||||
|
||||
//// #include "box-algorithms/ovpCBoxAlgorithmLatencyEvaluation.h"
|
||||
#include "box-algorithms/ovpCBoxAlgorithmMouseTracking.h"
|
||||
#include "box-algorithms/ovpCBoxAlgorithmKeypressEmulator.h"
|
||||
|
||||
#include "openvibe/CIdentifier.hpp"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
OVP_Declare_Begin()
|
||||
context.getTypeManager().registerEnumerationEntry(OV_TypeId_BoxAlgorithmFlag, OV_AttributeId_Box_FlagIsUnstable.toString(),
|
||||
OV_AttributeId_Box_FlagIsUnstable.id());
|
||||
// OVP_Declare_New(Tools::CBoxAlgorithmLatencyEvaluationDesc);
|
||||
#if defined(TARGET_HAS_ThirdPartyGTK)
|
||||
OVP_Declare_New(CBoxAlgorithmMouseTrackingDesc);
|
||||
#endif
|
||||
|
||||
OVP_Declare_New(CBoxAlgorithmKeypressEmulatorDesc);
|
||||
// @note the following code is a bit long so we've implemented it inside the class
|
||||
CBoxAlgorithmKeypressEmulator::registerEnums(context);
|
||||
|
||||
OVP_Declare_End()
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
Reference in New Issue
Block a user