Skip to content

Instantly share code, notes, and snippets.

@pranavkantgaur
Forked from trtg/main.cpp
Last active August 29, 2015 14:05
Show Gist options
  • Select an option

  • Save pranavkantgaur/88d9f09b8e02196588da to your computer and use it in GitHub Desktop.

Select an option

Save pranavkantgaur/88d9f09b8e02196588da to your computer and use it in GitHub Desktop.
NITE mouse control
/*******************************************************************************
* *
* PrimeSense NITE 1.3 - Single Control Sample *
* Copyright (C) 2010 PrimeSense Ltd. *
* *
*******************************************************************************/
// NOTE: It is a bug fixed version of https://gist.github.com/trtg/3922745
//-----------------------------------------------------------------------------
// Headers
//-----------------------------------------------------------------------------
// General headers
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
// OpenNI headers
#include <XnOpenNI.h>
// NITE headers
#include <XnVSessionManager.h>
#include "XnVMultiProcessFlowClient.h"
#include <XnVWaveDetector.h>
// xml to initialize OpenNI
#define SAMPLE_XML_FILE "Sample-Tracking.xml"
//-----------------------------------------------------------------------------
// Callbacks
//-----------------------------------------------------------------------------
static int uinp_fd = -1;
struct uinput_user_dev uinp; // uInput device structure
struct input_event event; // Input device structure
XnBool g_bQuit = false;
int setup_uinput_device()
{
int i=0;
uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
if (!uinp_fd)
{
printf("Unable to open /dev/uinput\n");
return -1;
}
memset(&uinp,0,sizeof(uinp)); // Intialize the uInput device to NULL
strncpy(uinp.name, "Kinect Mouse", UINPUT_MAX_NAME_SIZE);
uinp.id.version = 4;
uinp.id.bustype = BUS_USB;
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
ioctl(uinp_fd, UI_SET_RELBIT, REL_X);
ioctl(uinp_fd, UI_SET_RELBIT, REL_Y);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_TOUCH);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_BACK);
write(uinp_fd, &uinp, sizeof(uinp));
if (ioctl(uinp_fd, UI_DEV_CREATE))
{
printf("Unable to create UINPUT device.");
return -1;
}
return 1;
}
void move_cursor(int x, int y )
{
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_REL;
event.code = REL_X;
event.value = x;
write(uinp_fd, &event, sizeof(event));
event.type = EV_REL;
event.code = REL_Y;
event.value = y;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
}
// Callback for when the focus is in progress
void XN_CALLBACK_TYPE SessionProgress(const XnChar* strFocus, const XnPoint3D& ptFocusPoint, XnFloat fProgress, void* UserCxt)
{
printf("Session progress (%6.2f,%6.2f,%6.2f) - %6.2f [%s]\n", ptFocusPoint.X, ptFocusPoint.Y, ptFocusPoint.Z, fProgress, strFocus);
}
// callback for session start
void XN_CALLBACK_TYPE SessionStart(const XnPoint3D& ptFocusPoint, void* UserCxt)
{
printf("Session started. Please wave (%6.2f,%6.2f,%6.2f)...\n", ptFocusPoint.X, ptFocusPoint.Y, ptFocusPoint.Z);
}
// Callback for session end
void XN_CALLBACK_TYPE SessionEnd(void* UserCxt)
{
printf("Session ended. Please perform focus gesture to start session\n");
}
// Callback for wave detection
void XN_CALLBACK_TYPE OnWaveCB(void* cxt)
{
printf("Wave!\n");
return;
}
static int prev_x_pos=0;
static int prev_y_pos=0;
// callback for a new position of any hand
void XN_CALLBACK_TYPE OnPointUpdate(const XnVHandPointContext* pContext, void* cxt)
{
move_cursor((int)(pContext->ptPosition.X-prev_x_pos),(int) -(pContext->ptPosition.Y-prev_y_pos));
prev_x_pos=pContext->ptPosition.X;
prev_y_pos=pContext->ptPosition.Y;
return;
}
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
XnBool fileExists(const char *fn)
{
XnBool exists;
xnOSDoesFileExist(fn, &exists);
return exists;
}
// this sample can run either as a regular sample, or as a client for multi-process (remote mode)
int main(int argc, char** argv)
{
xn::Context context;
xn::ScriptNode scriptNode;
XnVSessionGenerator* pSessionGenerator;
XnBool bRemoting = FALSE;
if (argc > 1)
{
// remote mode
context.Init();
printf("Running in 'Remoting' mode (Section name: %s)\n", argv[1]);
bRemoting = TRUE;
// Create multi-process client
pSessionGenerator = new XnVMultiProcessFlowClient(argv[1]);
XnStatus rc = ((XnVMultiProcessFlowClient*)pSessionGenerator)->Initialize();
if (rc != XN_STATUS_OK)
{
printf("Initialize failed: %s\n", xnGetStatusString(rc));
delete pSessionGenerator;
return 1;
}
}
else
{
// Local mode
// Create context
const char *fn = NULL;
if (fileExists(SAMPLE_XML_FILE)) fn = SAMPLE_XML_FILE;
else
{
printf("Could not find '%s'. Aborting.\n" , SAMPLE_XML_FILE);
return XN_STATUS_ERROR;
}
XnStatus rc = context.InitFromXmlFile(fn, scriptNode);
if (rc != XN_STATUS_OK)
{
printf("Couldn't initialize: %s\n", xnGetStatusString(rc));
return 1;
}
// Create the Session Manager
pSessionGenerator = new XnVSessionManager();
rc = ((XnVSessionManager*)pSessionGenerator)->Initialize(&context, "Click", "RaiseHand");
if (rc != XN_STATUS_OK)
{
printf("Session Manager couldn't initialize: %s\n", xnGetStatusString(rc));
delete pSessionGenerator;
return 1;
}
// Initialization done. Start generating
context.StartGeneratingAll();
}
// Register session callbacks
pSessionGenerator->RegisterSession(NULL, &SessionStart, &SessionEnd, &SessionProgress);
// init & register wave control
XnVWaveDetector wc;
wc.RegisterWave(NULL, OnWaveCB);
wc.RegisterPointUpdate(NULL, OnPointUpdate);
pSessionGenerator->AddListener(&wc);
printf("Please perform focus gesture to start session\n");
printf("Hit any key to exit\n");
setup_uinput_device();
// Main loop
while (!xnOSWasKeyboardHit())
{
if (bRemoting)
{
((XnVMultiProcessFlowClient*)pSessionGenerator)->ReadState();
}
else
{
context.WaitAnyUpdateAll();
((XnVSessionManager*)pSessionGenerator)->Update(&context);
}
}
delete pSessionGenerator;
context.Shutdown();
ioctl(uinp_fd, UI_DEV_DESTROY);
close(uinp_fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment