ndof button handling improvements: Spaceball5000's A,B,C buttons can now be keymapped, ndof modifiers (shift,alt,etc.) are almost ready but still hardcoded to act like keyboard for now. added a check to prevent crash on Linux when device is plugged in after blender starts. also fixed a bug introduced by my last commit that affected the SpaceTraveler and serial devices.

This commit is contained in:
Mike Erwin 2012-02-29 02:44:08 +00:00
parent a71128828f
commit 8600c8df43
3 changed files with 52 additions and 30 deletions

@ -135,10 +135,10 @@ static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
NDOF_BUTTON_LEFT, NDOF_BUTTON_LEFT,
NDOF_BUTTON_RIGHT, NDOF_BUTTON_RIGHT,
NDOF_BUTTON_FRONT, NDOF_BUTTON_FRONT,
NDOF_BUTTON_ESC, // esc key NDOF_BUTTON_ESC,
NDOF_BUTTON_ALT, // alt key NDOF_BUTTON_ALT,
NDOF_BUTTON_SHIFT, // shift key NDOF_BUTTON_SHIFT,
NDOF_BUTTON_CTRL, // ctrl key NDOF_BUTTON_CTRL,
NDOF_BUTTON_FIT, NDOF_BUTTON_FIT,
NDOF_BUTTON_MENU, NDOF_BUTTON_MENU,
NDOF_BUTTON_PLUS, NDOF_BUTTON_PLUS,
@ -159,10 +159,10 @@ static const NDOF_ButtonT SpacePilot_HID_map[] = {
NDOF_BUTTON_LEFT, NDOF_BUTTON_LEFT,
NDOF_BUTTON_RIGHT, NDOF_BUTTON_RIGHT,
NDOF_BUTTON_FRONT, NDOF_BUTTON_FRONT,
NDOF_BUTTON_ESC, // esc key NDOF_BUTTON_ESC,
NDOF_BUTTON_ALT, // alt key NDOF_BUTTON_ALT,
NDOF_BUTTON_SHIFT, // shift key NDOF_BUTTON_SHIFT,
NDOF_BUTTON_CTRL, // ctrl key NDOF_BUTTON_CTRL,
NDOF_BUTTON_FIT, NDOF_BUTTON_FIT,
NDOF_BUTTON_MENU, NDOF_BUTTON_MENU,
NDOF_BUTTON_PLUS, NDOF_BUTTON_PLUS,
@ -187,10 +187,12 @@ static const NDOF_ButtonT Generic_HID_map[] = {
NDOF_BUTTON_C NDOF_BUTTON_C
}; };
static const int genericButtonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT);
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys) GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
: m_system(sys) : m_system(sys)
, m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code , m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code
, m_buttonCount(0) , m_buttonCount(genericButtonCount)
, m_buttonMask(0) , m_buttonMask(0)
, m_hidMap(Generic_HID_map) , m_hidMap(Generic_HID_map)
, m_buttons(0) , m_buttons(0)
@ -218,7 +220,7 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
m_deviceType = NDOF_UnknownDevice; m_deviceType = NDOF_UnknownDevice;
m_hidMap = Generic_HID_map; m_hidMap = Generic_HID_map;
m_buttonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT); m_buttonCount = genericButtonCount;
m_buttonMask = 0; m_buttonMask = 0;
// "mystery device" owners can help build a HID_map for their hardware // "mystery device" owners can help build a HID_map for their hardware
@ -264,13 +266,11 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
m_buttonCount = 21; m_buttonCount = 21;
m_hidMap = SpacePilot_HID_map; m_hidMap = SpacePilot_HID_map;
break; break;
case 0xC621: case 0xC621:
puts("ndof: using Spaceball 5000"); puts("ndof: using Spaceball 5000");
m_deviceType = NDOF_Spaceball5000; m_deviceType = NDOF_Spaceball5000;
m_buttonCount = 12; m_buttonCount = 12;
break; break;
case 0xC623: case 0xC623:
puts("ndof: using SpaceTraveler"); puts("ndof: using SpaceTraveler");
m_deviceType = NDOF_SpaceTraveler; m_deviceType = NDOF_SpaceTraveler;
@ -311,15 +311,8 @@ void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow* window) void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow* window)
{ {
if (button == NDOF_BUTTON_NONE) { GHOST_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST,
// just being exceptionally cautious... "rogue button trying to escape NDOF manager");
// air-tight button masking and proper function key emulation
// should guarantee we never get to this point
#ifdef DEBUG_NDOF_BUTTONS
printf("discarding NDOF_BUTTON_NONE (should not escape the NDOF manager)\n");
#endif
return;
}
GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window); GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData(); GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
@ -351,15 +344,18 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64
GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow(); GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
#ifdef DEBUG_NDOF_BUTTONS #ifdef DEBUG_NDOF_BUTTONS
if (m_deviceType != NDOF_UnknownDevice) printf("ndof: button %d -> ", button_number);
printf("ndof: button %d -> ", button_number);
#endif #endif
NDOF_ButtonT button = m_hidMap[button_number]; NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] : NDOF_BUTTON_NONE;
switch (button) switch (button)
{ {
case NDOF_BUTTON_NONE: break; case NDOF_BUTTON_NONE:
#ifdef DEBUG_NDOF_BUTTONS
printf("discarded\n");
#endif
break;
case NDOF_BUTTON_ESC: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break; case NDOF_BUTTON_ESC: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
case NDOF_BUTTON_ALT: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break; case NDOF_BUTTON_ALT: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break;
case NDOF_BUTTON_SHIFT: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break; case NDOF_BUTTON_SHIFT: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break;

@ -124,8 +124,8 @@ EnumPropertyItem event_ndof_type_items[]= {
{NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "Front", ""}, {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "Front", ""},
{NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "Back", ""}, {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "Back", ""},
/* more views */ /* more views */
{NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "ISO 1", ""}, {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "Isometric 1", ""},
{NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "ISO 2", ""}, {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "Isometric 2", ""},
/* 90 degree rotations */ /* 90 degree rotations */
{NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "Roll CW", ""}, {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "Roll CW", ""},
{NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "Roll CCW", ""}, {NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "Roll CCW", ""},
@ -139,6 +139,11 @@ EnumPropertyItem event_ndof_type_items[]= {
{NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "Dominant", ""}, {NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "Dominant", ""},
{NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""}, {NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""},
{NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "Minus", ""}, {NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "Minus", ""},
/* keyboard emulation */
{NDOF_BUTTON_ESC, "NDOF_BUTTON_ESC", 0, "Esc"},
{NDOF_BUTTON_ALT, "NDOF_BUTTON_ALT", 0, "Alt"},
{NDOF_BUTTON_SHIFT, "NDOF_BUTTON_SHIFT", 0, "Shift"},
{NDOF_BUTTON_CTRL, "NDOF_BUTTON_CTRL", 0, "Ctrl"},
/* general-purpose buttons */ /* general-purpose buttons */
{NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""}, {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""},
{NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "Button 2", ""}, {NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "Button 2", ""},
@ -150,6 +155,9 @@ EnumPropertyItem event_ndof_type_items[]= {
{NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "Button 8", ""}, {NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "Button 8", ""},
{NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "Button 9", ""}, {NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "Button 9", ""},
{NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "Button 10", ""}, {NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "Button 10", ""},
{NDOF_BUTTON_A, "NDOF_BUTTON_A", 0, "Button A", ""},
{NDOF_BUTTON_B, "NDOF_BUTTON_B", 0, "Button B", ""},
{NDOF_BUTTON_C, "NDOF_BUTTON_C", 0, "Button C", ""},
{0, NULL, 0, NULL, NULL}}; {0, NULL, 0, NULL, NULL}};
/* not returned: CAPSLOCKKEY, UNKNOWNKEY */ /* not returned: CAPSLOCKKEY, UNKNOWNKEY */
@ -315,8 +323,8 @@ EnumPropertyItem event_type_items[] = {
{NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "NDOF Front", ""}, {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "NDOF Front", ""},
{NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "NDOF Back", ""}, {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "NDOF Back", ""},
/* more views */ /* more views */
{NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "NDOF ISO 1", ""}, {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "NDOF Isometric 1", ""},
{NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "NDOF ISO 2", ""}, {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "NDOF Isometric 2", ""},
/* 90 degree rotations */ /* 90 degree rotations */
{NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "NDOF Roll CW", ""}, {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "NDOF Roll CW", ""},
{NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "NDOF Roll CCW", ""}, {NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "NDOF Roll CCW", ""},
@ -330,6 +338,11 @@ EnumPropertyItem event_type_items[] = {
{NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "NDOF Dominant", ""}, {NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "NDOF Dominant", ""},
{NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "NDOF Plus", ""}, {NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "NDOF Plus", ""},
{NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "NDOF Minus", ""}, {NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "NDOF Minus", ""},
/* keyboard emulation */
{NDOF_BUTTON_ESC, "NDOF_BUTTON_ESC", 0, "NDOF Esc"},
{NDOF_BUTTON_ALT, "NDOF_BUTTON_ALT", 0, "NDOF Alt"},
{NDOF_BUTTON_SHIFT, "NDOF_BUTTON_SHIFT", 0, "NDOF Shift"},
{NDOF_BUTTON_CTRL, "NDOF_BUTTON_CTRL", 0, "NDOF Ctrl"},
/* general-purpose buttons */ /* general-purpose buttons */
{NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "NDOF Button 1", ""}, {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "NDOF Button 1", ""},
{NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "NDOF Button 2", ""}, {NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "NDOF Button 2", ""},
@ -341,6 +354,9 @@ EnumPropertyItem event_type_items[] = {
{NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "NDOF Button 8", ""}, {NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "NDOF Button 8", ""},
{NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "NDOF Button 9", ""}, {NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "NDOF Button 9", ""},
{NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "NDOF Button 10", ""}, {NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "NDOF Button 10", ""},
{NDOF_BUTTON_A, "NDOF_BUTTON_A", 0, "NDOF Button A", ""},
{NDOF_BUTTON_B, "NDOF_BUTTON_B", 0, "NDOF Button B", ""},
{NDOF_BUTTON_C, "NDOF_BUTTON_C", 0, "NDOF Button C", ""},
{0, NULL, 0, NULL, NULL}}; {0, NULL, 0, NULL, NULL}};
EnumPropertyItem keymap_propvalue_items[] = { EnumPropertyItem keymap_propvalue_items[] = {
@ -584,7 +600,7 @@ static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value)
break; break;
case KMI_TYPE_NDOF: case KMI_TYPE_NDOF:
kmi->type = NDOF_BUTTON_MENU; kmi->type = NDOF_BUTTON_MENU;
kmi->val = KM_NOTHING; kmi->val = KM_PRESS;
break; break;
} }
} }

@ -112,6 +112,11 @@ enum {
NDOF_BUTTON_DOMINANT, NDOF_BUTTON_DOMINANT,
NDOF_BUTTON_PLUS, NDOF_BUTTON_PLUS,
NDOF_BUTTON_MINUS, NDOF_BUTTON_MINUS,
// keyboard emulation
NDOF_BUTTON_ESC,
NDOF_BUTTON_ALT,
NDOF_BUTTON_SHIFT,
NDOF_BUTTON_CTRL,
// general-purpose buttons // general-purpose buttons
NDOF_BUTTON_1, NDOF_BUTTON_1,
NDOF_BUTTON_2, NDOF_BUTTON_2,
@ -123,6 +128,11 @@ enum {
NDOF_BUTTON_8, NDOF_BUTTON_8,
NDOF_BUTTON_9, NDOF_BUTTON_9,
NDOF_BUTTON_10, NDOF_BUTTON_10,
// more general-purpose buttons
NDOF_BUTTON_A,
NDOF_BUTTON_B,
NDOF_BUTTON_C,
// the end
NDOF_LAST NDOF_LAST
}; };