Please note before reviewing the code:
“comms” is namespace of our engine;
class “cVec3” is vector with 3 float components;
class “cVec2i” is vector with 2 int components;
“cThread::ThreadMutex” is alias for “pthread_mutex_t”;
“cLinuxMain_Window” has type “GtkWidget *” and points to the main window;
“cLinuxMain_Display” has been defined as:
static Display *cLinuxMain_Display = NULL;
cLinuxMain_Display = GDK_DISPLAY();
Code: Select all
// cLinuxMain_3Dconnexion
class cLinuxMain_3Dconnexion {
public:
comms::cVec3 Translation;
comms::cVec3 Rotation;
comms::cVec2i ButtonState;
comms::cThread::ThreadMutex Mutex;
cLinuxMain_3Dconnexion() {
Translation.SetZero();
Rotation.SetZero();
ButtonState.Set(0);
}
void Free() {
comms::cThread::DeleteMutex(Mutex);
}
void Init();
private:
Atom m_MotionEvent, m_ButtonPressEvent, m_ButtonReleaseEvent;
bool InitEvents();
bool HandleEvent(const XEvent &Event);
static GdkFilterReturn FilterProc(GdkXEvent *Xevent, GdkEvent *, gpointer);
};
cLinuxMain_3Dconnexion g_3Dconnexion;
// cMain_GetTdxState
void cMain_GetTdxState(comms::cVec3 *Translation, comms::cVec3 *Rotation, comms::cVec2i *ButtonState) {
comms::cThread::LockMutex(g_3Dconnexion.Mutex);
if(Translation != NULL) {
*Translation = g_3Dconnexion.Translation;
}
if(Rotation != NULL) {
*Rotation = g_3Dconnexion.Rotation;
}
if(ButtonState != NULL) {
*ButtonState = g_3Dconnexion.ButtonState;
}
comms::cThread::UnlockMutex(g_3Dconnexion.Mutex);
}
// cLinuxMain_3Dconnexion::Init
void cLinuxMain_3Dconnexion::Init() {
comms::cThread::CreateMutex(Mutex);
if(InitEvents()) {
comms::cLog::Message("3Dconnexion driver has been found");
gdk_window_add_filter(cLinuxMain_Window->window, FilterProc, NULL);
} else {
comms::cLog::Message("No 3Dconnexion driver");
}
}
// cLinuxMain_3Dconnexion::InitEvents
bool cLinuxMain_3Dconnexion::InitEvents() {
m_MotionEvent = XInternAtom(cLinuxMain_Display, "MotionEvent", TRUE);
m_ButtonPressEvent = XInternAtom(cLinuxMain_Display, "ButtonPressEvent", TRUE);
m_ButtonReleaseEvent = XInternAtom(cLinuxMain_Display, "ButtonReleaseEvent", TRUE);
return (m_MotionEvent != 0) && (m_ButtonPressEvent != 0) && (m_ButtonReleaseEvent != 0);
}
// cLinuxMain_3Dconnexion::HandleEvent
bool cLinuxMain_3Dconnexion::HandleEvent(const XEvent &Event) {
int Index;
if(Event.type == ClientMessage) {
if(Event.xclient.message_type == m_MotionEvent) {
comms::cThread::LockMutex(Mutex);
Translation.Set(Event.xclient.data.s[2], Event.xclient.data.s[3], Event.xclient.data.s[4]);
Rotation.Set(Event.xclient.data.s[5], Event.xclient.data.s[6], Event.xclient.data.s[7]);
comms::cThread::UnlockMutex(Mutex);
return true;
} else if(Event.xclient.message_type == m_ButtonPressEvent) {
Index = Event.xclient.data.s[2] - 1;
if(Index >= 0 && Index < 2) {
comms::cThread::LockMutex(Mutex);
ButtonState[Index] = 1;
comms::cThread::UnlockMutex(Mutex);
}
return true;
} else if(Event.xclient.message_type == m_ButtonReleaseEvent) {
Index = Event.xclient.data.s[2] - 1;
if(Index >= 0 && Index < 2) {
comms::cThread::LockMutex(Mutex);
ButtonState[Index] = 0;
comms::cThread::UnlockMutex(Mutex);
}
return true;
}
}
return false;
}
// cLinuxMain_3Dconnexion::FilterProc
GdkFilterReturn cLinuxMain_3Dconnexion::FilterProc(GdkXEvent *Xevent, GdkEvent *, gpointer) {
XEvent *E = (XEvent *)Xevent;
if(g_3Dconnexion.HandleEvent(*E)) {
return GDK_FILTER_REMOVE;
}
return GDK_FILTER_CONTINUE;
}