/**************************************************************************** * * * Nite 1.3 - Single Control Sample * * * * Author: Oz Magal * * * ****************************************************************************/ /**************************************************************************** * * * Nite 1.3 * * Copyright (C) 2006 PrimeSense Ltd. All Rights Reserved. * * * * This file has been provided pursuant to a License Agreement containing * * restrictions on its use. This data contains valuable trade secrets * * and proprietary information of PrimeSense Ltd. and is protected by law. * * * ****************************************************************************/ //----------------------------------------------------------------------------- // 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> #include "kbhit.h" #include "signal_catch.h" // xml to initialize OpenNI #define SAMPLE_XML_FILE "../../Data/Sample-Tracking.xml" 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)); } //----------------------------------------------------------------------------- // Callbacks //----------------------------------------------------------------------------- // 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"); } // callback for a new position of any hand void XN_CALLBACK_TYPE OnPointUpdate(const XnVHandPointContext* pContext, void* cxt) { //printf("%d: (%f,%f,%f) [%f]\n", pContext->nID, pContext->ptPosition.X, pContext->ptPosition.Y, pContext->ptPosition.Z, pContext->f Time); //printf("%f,%f,%f\n", pContext->ptPosition.X, pContext->ptPosition.Y, pContext->ptPosition.Z); move_cursor((int)(pContext->ptPosition.X/4),(int) -(pContext->ptPosition.Y/4)); } //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- // 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; 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 XnStatus rc = context.InitFromXmlFile(SAMPLE_XML_FILE); 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); // Start catching signals for quit indications CatchSignals(&g_bQuit); // 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 ((!_kbhit()) && (!g_bQuit)) { if (bRemoting) { ((XnVMultiProcessFlowClient*)pSessionGenerator)->ReadState(); } else { context.WaitAndUpdateAll(); ((XnVSessionManager*)pSessionGenerator)->Update(&context); } } delete pSessionGenerator; context.Shutdown(); ioctl(uinp_fd, UI_DEV_DESTROY); close(uinp_fd); return 0; }