Mentions légales du service

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • openvibe/extras
  • papadop/extras
  • adesbois/extras
  • fleray/extras
4 results
Show changes
Commits on Source (1)
...@@ -11,7 +11,8 @@ target_link_libraries(${PROJECT_NAME} ...@@ -11,7 +11,8 @@ target_link_libraries(${PROJECT_NAME}
Boost::boost Boost::boost
Boost::system Boost::system
Boost::thread Boost::thread
lua) lua
)
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
find_library(LIB_RT rt) find_library(LIB_RT rt)
...@@ -20,6 +21,9 @@ if(UNIX AND NOT APPLE) ...@@ -20,6 +21,9 @@ if(UNIX AND NOT APPLE)
else() else()
message(WARNING " FAILED to find rt...") message(WARNING " FAILED to find rt...")
endif() endif()
find_package(X11)
target_link_libraries(${PROJECT_NAME} X11::Xtst)
endif() endif()
set_target_properties(${PROJECT_NAME} PROPERTIES set_target_properties(${PROJECT_NAME} PROPERTIES
......
///-------------------------------------------------------------------------------------------------
///
/// \file CKeyboardStimulator.hpp
/// \author Thomas Prampart (INRIA/IRISA).
/// \version 1.1.
/// \copyright Copyright (C) 2022 Inria
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///
///-------------------------------------------------------------------------------------------------
#include <X11/Xlib.h>
#include <X11/extensions/record.h>
#include <iostream>
#include <thread>
typedef struct {
unsigned char type;
unsigned char detail;
} XRecordDatum;
typedef struct {
Display* ctrlDisplay;
Display* dataDisplay;
XRecordContext context;
XRecordRange* range;
std::function<void(int,bool)> processKeyCB;
} Context;
static void Handle (XPointer p, XRecordInterceptData *pRecord)
{
Context* ctx = (Context*)p;
if (pRecord->category == XRecordFromServer) {
XRecordDatum *data = (XRecordDatum *)pRecord->data;
KeySym k = XKeycodeToKeysym(ctx->ctrlDisplay, data->detail, 0);
if (data->type == KeyPress || data->type == KeyRelease) {
ctx->processKeyCB(k, data->type == KeyPress);
}
}
::XRecordFreeData(pRecord);
}
class CKeyboardHandler
{
public:
CKeyboardHandler(std::function<void(int, bool)> processKeyCallback) {
m_ctx.processKeyCB = processKeyCallback;
}
void recorderThread() {
m_ctx.dataDisplay = XOpenDisplay(nullptr);
m_ctx.ctrlDisplay = XOpenDisplay(nullptr);
if(m_ctx.dataDisplay && m_ctx.ctrlDisplay)
{
XRecordClientSpec clients = XRecordAllClients;
m_ctx.range = ::XRecordAllocRange();
m_ctx.range->device_events = XRecordRange8{KeyPress, ButtonRelease};
m_ctx.context = ::XRecordCreateContext(m_ctx.dataDisplay, 0, &clients, 1, &m_ctx.range, 1);
// Only returns when XRecordDisableContext is called in stop() method
XRecordEnableContext(m_ctx.dataDisplay, m_ctx.context, Handle, (XPointer)&m_ctx);
XRecordFreeContext(m_ctx.dataDisplay, m_ctx.context);
XCloseDisplay(m_ctx.ctrlDisplay);
XCloseDisplay(m_ctx.dataDisplay);
}
}
void start() {
m_thread = std::thread(&CKeyboardHandler::recorderThread, this);
}
void stop() {
XRecordDisableContext(m_ctx.ctrlDisplay, m_ctx.context);
XFlush(m_ctx.ctrlDisplay);
m_thread.join();
XFree(m_ctx.range);
}
std::thread m_thread;
Context m_ctx;
};
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
/// ///
///------------------------------------------------------------------------------------------------- ///-------------------------------------------------------------------------------------------------
#if defined(TARGET_HAS_ThirdPartyGTK)
#include "CKeyboardStimulator.hpp" #include "CKeyboardStimulator.hpp"
#include <fstream> #include <fstream>
...@@ -34,29 +32,17 @@ namespace OpenViBE { ...@@ -34,29 +32,17 @@ namespace OpenViBE {
namespace Plugins { namespace Plugins {
namespace Stimulation { namespace Stimulation {
//! Callback for the close window button
//static void keyboard_stimulator_gtk_widget_do_nothing(GtkWidget* widget) { }
// Called when a key is pressed on the keyboard CKeyboardStimulator::CKeyboardStimulator():
static gboolean KeyPressCB(GtkWidget* /*widget*/, const GdkEventKey* key, gpointer data) keyboardHandler(std::bind(&CKeyboardStimulator::ProcessKey, this, std::placeholders::_1, std::placeholders::_2))
{ { }
reinterpret_cast<CKeyboardStimulator*>(data)->ProcessKey(key->keyval, true);
return true;
}
// Called when a key is released on the keyboard
static gboolean KeyReleaseCB(GtkWidget* /*widget*/, const GdkEventKey* key, gpointer data)
{
reinterpret_cast<CKeyboardStimulator*>(data)->ProcessKey(key->keyval, false);
return true;
}
/** /**
* Called when a key has been pressed. * Called when a key has been pressed.
* \param key The gdk value to the pressed key. * \param key The gdk value to the pressed key.
* \param state state of the pressed key * \param state state of the pressed key
* */ * */
void CKeyboardStimulator::ProcessKey(const guint key, const bool state) void CKeyboardStimulator::ProcessKey(int key, bool state)
{ {
//if there is one entry, adds the stimulation to the list of stims to be sent //if there is one entry, adds the stimulation to the list of stims to be sent
if (m_keyToStimulation.count(key) != 0 && state != m_keyToStimulation[key].status) { if (m_keyToStimulation.count(key) != 0 && state != m_keyToStimulation[key].status) {
...@@ -154,8 +140,6 @@ bool CKeyboardStimulator::initialize() ...@@ -154,8 +140,6 @@ bool CKeyboardStimulator::initialize()
gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(builder, "keyboard_stimulator-label")), ss.str().c_str()); gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(builder, "keyboard_stimulator-label")), ss.str().c_str());
g_signal_connect(m_widget, "key-press-event", G_CALLBACK(KeyPressCB), this);
g_signal_connect(m_widget, "key-release-event", G_CALLBACK(KeyReleaseCB), this);
g_object_unref(builder); g_object_unref(builder);
m_visualizationCtx = dynamic_cast<VisualizationToolkit::IVisualizationContext*>(this->createPluginObject(OVP_ClassId_Plugin_VisualizationCtx)); m_visualizationCtx = dynamic_cast<VisualizationToolkit::IVisualizationContext*>(this->createPluginObject(OVP_ClassId_Plugin_VisualizationCtx));
...@@ -167,6 +151,9 @@ bool CKeyboardStimulator::initialize() ...@@ -167,6 +151,9 @@ bool CKeyboardStimulator::initialize()
this->getLogManager() << Kernel::LogLevel_Warning << "Unable to connect to AS's TCP Tagging plugin, stimuli wont be forwarded.\n"; this->getLogManager() << Kernel::LogLevel_Warning << "Unable to connect to AS's TCP Tagging plugin, stimuli wont be forwarded.\n";
} }
keyboardHandler.start();
std::cout << "Keyboard handler started" << std::endl;
return true; return true;
} }
...@@ -189,6 +176,8 @@ bool CKeyboardStimulator::uninitialize() ...@@ -189,6 +176,8 @@ bool CKeyboardStimulator::uninitialize()
m_visualizationCtx = nullptr; m_visualizationCtx = nullptr;
} }
keyboardHandler.stop();
return true; return true;
} }
...@@ -214,7 +203,9 @@ bool CKeyboardStimulator::processClock(Kernel::CMessageClock& msg) ...@@ -214,7 +203,9 @@ bool CKeyboardStimulator::processClock(Kernel::CMessageClock& msg)
const CStimulationSet* stimulationSet = m_encoder.getInputStimulationSet(); const CStimulationSet* stimulationSet = m_encoder.getInputStimulationSet();
stimulationSet->clear(); // The encoder may retain the buffer from the previous round, clear it stimulationSet->clear(); // The encoder may retain the buffer from the previous round, clear it
for (size_t i = 0; i < m_stimulationToSend.size(); ++i) { stimulationSet->push_back(m_stimulationToSend[i], currentTime, 0); } for (size_t i = 0; i < m_stimulationToSend.size(); ++i) {
stimulationSet->push_back(m_stimulationToSend[i], currentTime, 0);
}
m_stimulationToSend.clear(); m_stimulationToSend.clear();
m_encoder.encodeBuffer(); m_encoder.encodeBuffer();
...@@ -231,4 +222,3 @@ bool CKeyboardStimulator::processClock(Kernel::CMessageClock& msg) ...@@ -231,4 +222,3 @@ bool CKeyboardStimulator::processClock(Kernel::CMessageClock& msg)
} // namespace Stimulation } // namespace Stimulation
} // namespace Plugins } // namespace Plugins
} // namespace OpenViBE } // namespace OpenViBE
#endif
...@@ -22,9 +22,7 @@ ...@@ -22,9 +22,7 @@
#pragma once #pragma once
#if defined(TARGET_HAS_ThirdPartyGTK) #include "../../defines.hpp"
#include "../defines.hpp"
#include <openvibe/ov_all.h> #include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h> #include <toolkit/ovtk_all.h>
...@@ -34,9 +32,17 @@ ...@@ -34,9 +32,17 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <functional>
#include <visualization-toolkit/ovviz_all.h> #include <visualization-toolkit/ovviz_all.h>
#ifdef __linux__
#include "CKeyboardHandlerLinux.hpp"
#endif
#ifdef WIN32
//#include "CKeyboardHandlerWindows.hpp"
#endif
namespace TCPTagging { namespace TCPTagging {
class IStimulusSender; // fwd declare class IStimulusSender; // fwd declare
} }
...@@ -44,10 +50,11 @@ class IStimulusSender; // fwd declare ...@@ -44,10 +50,11 @@ class IStimulusSender; // fwd declare
namespace OpenViBE { namespace OpenViBE {
namespace Plugins { namespace Plugins {
namespace Stimulation { namespace Stimulation {
class CKeyboardStimulator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm> class CKeyboardStimulator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{ {
public: public:
CKeyboardStimulator() { } CKeyboardStimulator();
void release() override { delete this; } void release() override { delete this; }
...@@ -60,7 +67,7 @@ public: ...@@ -60,7 +67,7 @@ public:
bool process() override { return true; } bool process() override { return true; }
bool ParseConfigurationFile(const char* filename); bool ParseConfigurationFile(const char* filename);
void ProcessKey(const guint key, const bool state); void ProcessKey(int key, bool state);
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, Box_KeyboardStimulator) _IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, Box_KeyboardStimulator)
...@@ -77,7 +84,7 @@ protected: ...@@ -77,7 +84,7 @@ protected:
} key_t; } key_t;
//! Stores keyvalue/stimulation couples //! Stores keyvalue/stimulation couples
std::map<guint, key_t> m_keyToStimulation; std::map<int, key_t> m_keyToStimulation;
//! Vector of the stimulations to send when possible //! Vector of the stimulations to send when possible
std::vector<uint64_t> m_stimulationToSend; std::vector<uint64_t> m_stimulationToSend;
...@@ -94,6 +101,8 @@ protected: ...@@ -94,6 +101,8 @@ protected:
size_t m_unknownKeyCode = 0; size_t m_unknownKeyCode = 0;
VisualizationToolkit::IVisualizationContext* m_visualizationCtx = nullptr; VisualizationToolkit::IVisualizationContext* m_visualizationCtx = nullptr;
CKeyboardHandler keyboardHandler;
}; };
/** /**
...@@ -134,5 +143,3 @@ public: ...@@ -134,5 +143,3 @@ public:
} // namespace Stimulation } // namespace Stimulation
} // namespace Plugins } // namespace Plugins
} // namespace OpenViBE } // namespace OpenViBE
#endif
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "box-algorithms/CBoxAlgorithmP300SpellerStimulator.hpp" #include "box-algorithms/CBoxAlgorithmP300SpellerStimulator.hpp"
#include "box-algorithms/CBoxAlgorithmRunCommand.hpp" #include "box-algorithms/CBoxAlgorithmRunCommand.hpp"
#include "box-algorithms/CBoxAlgorithmThresholdCrossingDetector.hpp" #include "box-algorithms/CBoxAlgorithmThresholdCrossingDetector.hpp"
#include "box-algorithms/CKeyboardStimulator.hpp" #include "box-algorithms/keyboard-stimulator/CKeyboardStimulator.hpp"
#include "box-algorithms/CBoxAlgorithmStimulationValidator.hpp" #include "box-algorithms/CBoxAlgorithmStimulationValidator.hpp"
#include "box-algorithms/CBoxStimulationConverter.hpp" #include "box-algorithms/CBoxStimulationConverter.hpp"
......