Merge pull request #26 from stonexjr/Jinrong
Added support for 3Dconnexion Space Navigator
This commit is contained in:
commit
2785c2e9c8
@ -273,9 +273,20 @@ IF(WIN32)
|
|||||||
SET( CMAKE_DEBUG_POSTFIX "d" )
|
SET( CMAKE_DEBUG_POSTFIX "d" )
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|
||||||
|
IF(NOT(MSVC_VERSION LESS "1600"))
|
||||||
|
# minimum requirement for WM_TOUCH device
|
||||||
|
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0601)
|
||||||
|
ADD_DEFINITIONS(-DWINVER=0x0601)
|
||||||
|
ELSEIF(NOT(MSVC_VERSION LESS "1300"))
|
||||||
|
# minimum requirement for spaceball device
|
||||||
|
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501)
|
||||||
|
ADD_DEFINITIONS(-DWINVER=0x0501)
|
||||||
|
ELSE()
|
||||||
# enable the use of Win2000 APIs (needed for really old compilers like MSVC6)
|
# enable the use of Win2000 APIs (needed for really old compilers like MSVC6)
|
||||||
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0500)
|
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0500)
|
||||||
ADD_DEFINITIONS(-DWINVER=0x0500)
|
ADD_DEFINITIONS(-DWINVER=0x0500)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(CMAKE_COMPILER_IS_GNUCC)
|
IF(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
* magellan X-based protocol.
|
* magellan X-based protocol.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <GL/freeglut.h>
|
#include <GL/freeglut.h>
|
||||||
#include "fg_internal.h"
|
#include "fg_internal.h"
|
||||||
|
|
||||||
|
#if(_WIN32_WINNT >= 0x0501)
|
||||||
|
|
||||||
/* -- PRIVATE FUNCTIONS --------------------------------------------------- */
|
/* -- PRIVATE FUNCTIONS --------------------------------------------------- */
|
||||||
|
|
||||||
extern void fgPlatformInitializeSpaceball(void);
|
extern void fgPlatformInitializeSpaceball(void);
|
||||||
@ -28,13 +31,12 @@ void fgInitialiseSpaceball(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fgPlatformInitializeSpaceball();
|
fgPlatformInitializeSpaceball();
|
||||||
|
|
||||||
sball_initialized = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgSpaceballClose(void)
|
void fgSpaceballClose(void)
|
||||||
{
|
{
|
||||||
fgPlatformSpaceballClose();}
|
fgPlatformSpaceballClose();
|
||||||
|
}
|
||||||
|
|
||||||
int fgHasSpaceball(void)
|
int fgHasSpaceball(void)
|
||||||
{
|
{
|
||||||
@ -74,3 +76,28 @@ void fgSpaceballSetWindow(SFG_Window *window)
|
|||||||
fgPlatformSpaceballSetWindow(window);
|
fgPlatformSpaceballSetWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void fgInitialiseSpaceball(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void fgSpaceballClose(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int fgHasSpaceball(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fgSpaceballNumButtons(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fgSpaceballSetWindow(SFG_Window *window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -127,6 +127,12 @@ struct tagSFG_PlatformJoystick
|
|||||||
#define FREEGLUT_MENU_PEN_HBACK_COLORS {0.15f, 0.15f, 0.45f, 1.0f}
|
#define FREEGLUT_MENU_PEN_HBACK_COLORS {0.15f, 0.15f, 0.45f, 1.0f}
|
||||||
|
|
||||||
|
|
||||||
|
/* -- PRIVATE FUNCTION DECLARATIONS ---------------------------------------- */
|
||||||
|
/* Spaceball device functions, defined in fg_spaceball_mswin.c */
|
||||||
|
//Added by Jinrong Xie <stonexjr at gmail.com> 12/24/2014
|
||||||
|
int fgIsSpaceballWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam);
|
||||||
|
void fgSpaceballHandleWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
/* Function to be called on exit */
|
/* Function to be called on exit */
|
||||||
extern void (__cdecl *__glutExitFunc)( int return_value );
|
extern void (__cdecl *__glutExitFunc)( int return_value );
|
||||||
|
|
||||||
|
@ -1543,6 +1543,16 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WM_INPUT
|
||||||
|
case WM_INPUT:
|
||||||
|
/* Added by Jinrong Xie <stonexjr at gmail.com> for SpaceNavigator support on Windows. Dec 2014 */
|
||||||
|
if (fgHasSpaceball())
|
||||||
|
{
|
||||||
|
fgSpaceballHandleWinEvent(hWnd, wParam, lParam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* Handle unhandled messages */
|
/* Handle unhandled messages */
|
||||||
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
|
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
* Written by Evan Felix <karcaw at gmail.com>
|
* Written by Evan Felix <karcaw at gmail.com>
|
||||||
* Creation date: Sat Feb 4, 2012
|
* Creation date: Sat Feb 4, 2012
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2014 Jinrong Xie. All Rights Reserved.
|
||||||
|
* Written by Jinrong Xie <stonexjr at gmail.com>
|
||||||
|
* Modification date: Wed Dec 24, 2014
|
||||||
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
* to deal in the Software without restriction, including without limitation
|
* to deal in the Software without restriction, including without limitation
|
||||||
@ -24,17 +28,51 @@
|
|||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code is a very complicated way of doing nothing.
|
* Modified by Jinrong Xie <stonexjr at gmail.com> 12/24/2014
|
||||||
* But is needed for mswindows platform builds.
|
* for Space Navigator support on Windows.
|
||||||
|
* This code is enhanced by at least supporting 3Dconnexion's
|
||||||
|
* six degree of freedom navigator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if(_WIN32_WINNT >= 0x0501)
|
||||||
|
|
||||||
#include <GL/freeglut.h>
|
#include <GL/freeglut.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "../fg_internal.h"
|
#include "../fg_internal.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SPNAV_EVENT_ANY,
|
||||||
|
SPNAV_EVENT_MOTION_TRANSLATION,
|
||||||
|
SPNAV_EVENT_MOTION_ROTATION,
|
||||||
|
SPNAV_EVENT_BUTTON /* includes both press and release */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int sball_initialized;
|
||||||
|
unsigned int __fgSpaceKeystate = 0;
|
||||||
|
RAWINPUTDEVICE __fgSpaceball = { 0x01, 0x08, 0x00, 0x00 };
|
||||||
|
|
||||||
void fgPlatformInitializeSpaceball(void)
|
void fgPlatformInitializeSpaceball(void)
|
||||||
{
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
sball_initialized = 1;
|
||||||
|
if (!fgStructure.CurrentWindow)
|
||||||
|
{
|
||||||
|
sball_initialized = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
hwnd = fgStructure.CurrentWindow->Window.Handle;
|
||||||
|
|
||||||
|
BOOL ok;
|
||||||
|
UINT cbSize = sizeof(__fgSpaceball);
|
||||||
|
__fgSpaceball.hwndTarget = hwnd;
|
||||||
|
ok = RegisterRawInputDevices(&__fgSpaceball, 1, cbSize);
|
||||||
|
|
||||||
|
if (!ok){
|
||||||
|
__fgSpaceball.hwndTarget = NULL;
|
||||||
|
sball_initialized = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgPlatformSpaceballClose(void)
|
void fgPlatformSpaceballClose(void)
|
||||||
@ -44,7 +82,7 @@ void fgPlatformSpaceballClose(void)
|
|||||||
|
|
||||||
int fgPlatformHasSpaceball(void)
|
int fgPlatformHasSpaceball(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return __fgSpaceball.hwndTarget ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fgPlatformSpaceballNumButtons(void)
|
int fgPlatformSpaceballNumButtons(void)
|
||||||
@ -56,3 +94,103 @@ void fgPlatformSpaceballSetWindow(SFG_Window *window)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fgIsSpaceballWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fgSpaceballHandleWinEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
#define LOGITECH_VENDOR_ID 0x46d
|
||||||
|
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
|
||||||
|
UINT inputCode = (UINT)wParam;
|
||||||
|
UINT size;
|
||||||
|
BYTE *rawInputBuffer;
|
||||||
|
PRAWINPUT pRawInput;
|
||||||
|
UINT res;
|
||||||
|
RID_DEVICE_INFO sRidDeviceInfo;
|
||||||
|
|
||||||
|
if (!sball_initialized)
|
||||||
|
{
|
||||||
|
fgPlatformInitializeSpaceball();
|
||||||
|
if (!sball_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = GetRawInputData(hRawInput, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
|
||||||
|
if (res == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rawInputBuffer = malloc(size * sizeof *rawInputBuffer);
|
||||||
|
pRawInput = (PRAWINPUT)rawInputBuffer;
|
||||||
|
|
||||||
|
res = GetRawInputData(hRawInput, RID_INPUT, pRawInput, &size, sizeof(RAWINPUTHEADER));
|
||||||
|
if (res == -1)
|
||||||
|
return;
|
||||||
|
if (pRawInput->header.dwType != RIM_TYPEHID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sRidDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
|
||||||
|
size = sizeof(RID_DEVICE_INFO);
|
||||||
|
res = GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &sRidDeviceInfo, &size);
|
||||||
|
if (res == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SFG_Window* window = fgWindowByHandle(hwnd);
|
||||||
|
if ((window == NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sRidDeviceInfo.hid.dwVendorId == LOGITECH_VENDOR_ID)
|
||||||
|
{
|
||||||
|
// Motion data comes in two parts: motion type and
|
||||||
|
// displacement/rotation along three axis.
|
||||||
|
// Orientation is a right handed coordinate system with
|
||||||
|
// X goes right, Y goes up and Z goes towards viewer, e.g.
|
||||||
|
// the one used in OpenGL
|
||||||
|
if (pRawInput->data.hid.bRawData[0] ==
|
||||||
|
SPNAV_EVENT_MOTION_TRANSLATION)
|
||||||
|
{ // Translation vector
|
||||||
|
short* pnData = (short*)(&pRawInput->data.hid.bRawData[1]);
|
||||||
|
short X = pnData[0];
|
||||||
|
short Y = -pnData[2];
|
||||||
|
short Z = pnData[1];
|
||||||
|
INVOKE_WCB(*window, SpaceMotion, (X, Y, Z));
|
||||||
|
}
|
||||||
|
else if (pRawInput->data.hid.bRawData[0] ==
|
||||||
|
SPNAV_EVENT_MOTION_ROTATION)
|
||||||
|
{ // Axis aligned rotation vector
|
||||||
|
short* pnData = (short*)(&pRawInput->data.hid.bRawData[1]);
|
||||||
|
short rX = pnData[0];
|
||||||
|
short rY = -pnData[2];
|
||||||
|
short rZ = pnData[1];
|
||||||
|
INVOKE_WCB(*window, SpaceRotation, (rX, rY, rZ));
|
||||||
|
}
|
||||||
|
else if (pRawInput->data.hid.bRawData[0] ==
|
||||||
|
SPNAV_EVENT_BUTTON)
|
||||||
|
{ // State of the keys
|
||||||
|
unsigned long dwKeystate = *(unsigned long*)(&pRawInput->data.hid.bRawData[1]);
|
||||||
|
unsigned int state = GLUT_UP;
|
||||||
|
if (FETCH_WCB(*window, SpaceButton))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
unsigned long stateBefore = __fgSpaceKeystate&(1 << i);
|
||||||
|
unsigned long stateNow = dwKeystate&(1 << i);
|
||||||
|
|
||||||
|
if (stateBefore && !stateNow)
|
||||||
|
INVOKE_WCB(*window, SpaceButton, (stateBefore, GLUT_DOWN));
|
||||||
|
if (!stateBefore && stateNow)
|
||||||
|
INVOKE_WCB(*window, SpaceButton, (stateNow, GLUT_UP));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__fgSpaceKeystate = dwKeystate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user