From 8600c8df43dbc94b89f7d456b927a0fe2b9be723 Mon Sep 17 00:00:00 2001 From: Mike Erwin Date: Wed, 29 Feb 2012 02:44:08 +0000 Subject: [PATCH] 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. --- intern/ghost/intern/GHOST_NDOFManager.cpp | 46 +++++++++---------- source/blender/makesrna/intern/rna_wm.c | 26 +++++++++-- source/blender/windowmanager/wm_event_types.h | 10 ++++ 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index b16fa8fb90a..694394afcde 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -135,10 +135,10 @@ static const NDOF_ButtonT SpaceExplorer_HID_map[] = { NDOF_BUTTON_LEFT, NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, - NDOF_BUTTON_ESC, // esc key - NDOF_BUTTON_ALT, // alt key - NDOF_BUTTON_SHIFT, // shift key - NDOF_BUTTON_CTRL, // ctrl key + NDOF_BUTTON_ESC, + NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, + NDOF_BUTTON_CTRL, NDOF_BUTTON_FIT, NDOF_BUTTON_MENU, NDOF_BUTTON_PLUS, @@ -159,10 +159,10 @@ static const NDOF_ButtonT SpacePilot_HID_map[] = { NDOF_BUTTON_LEFT, NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, - NDOF_BUTTON_ESC, // esc key - NDOF_BUTTON_ALT, // alt key - NDOF_BUTTON_SHIFT, // shift key - NDOF_BUTTON_CTRL, // ctrl key + NDOF_BUTTON_ESC, + NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, + NDOF_BUTTON_CTRL, NDOF_BUTTON_FIT, NDOF_BUTTON_MENU, NDOF_BUTTON_PLUS, @@ -187,10 +187,12 @@ static const NDOF_ButtonT Generic_HID_map[] = { NDOF_BUTTON_C }; +static const int genericButtonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT); + GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys) : m_system(sys) , m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code - , m_buttonCount(0) + , m_buttonCount(genericButtonCount) , m_buttonMask(0) , m_hidMap(Generic_HID_map) , m_buttons(0) @@ -218,7 +220,7 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ m_deviceType = NDOF_UnknownDevice; m_hidMap = Generic_HID_map; - m_buttonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT); + m_buttonCount = genericButtonCount; m_buttonMask = 0; // "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_hidMap = SpacePilot_HID_map; break; - case 0xC621: puts("ndof: using Spaceball 5000"); m_deviceType = NDOF_Spaceball5000; m_buttonCount = 12; break; - case 0xC623: puts("ndof: using 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) { - if (button == NDOF_BUTTON_NONE) { - // just being exceptionally cautious... - // 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_ASSERT(button > NDOF_BUTTON_NONE && button < NDOF_BUTTON_LAST, + "rogue button trying to escape NDOF manager"); GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window); 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(); #ifdef DEBUG_NDOF_BUTTONS - if (m_deviceType != NDOF_UnknownDevice) - printf("ndof: button %d -> ", button_number); + printf("ndof: button %d -> ", button_number); #endif - NDOF_ButtonT button = m_hidMap[button_number]; + NDOF_ButtonT button = (button_number < m_buttonCount) ? m_hidMap[button_number] : NDOF_BUTTON_NONE; 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_ALT: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break; case NDOF_BUTTON_SHIFT: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break; diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f5bdefa8bd5..44dc90787fa 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -124,8 +124,8 @@ EnumPropertyItem event_ndof_type_items[]= { {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "Front", ""}, {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "Back", ""}, /* more views */ - {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "ISO 1", ""}, - {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "ISO 2", ""}, + {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "Isometric 1", ""}, + {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "Isometric 2", ""}, /* 90 degree rotations */ {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "Roll CW", ""}, {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_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""}, {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 */ {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""}, {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_9, "NDOF_BUTTON_9", 0, "Button 9", ""}, {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}}; /* not returned: CAPSLOCKKEY, UNKNOWNKEY */ @@ -315,8 +323,8 @@ EnumPropertyItem event_type_items[] = { {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "NDOF Front", ""}, {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "NDOF Back", ""}, /* more views */ - {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "NDOF ISO 1", ""}, - {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "NDOF ISO 2", ""}, + {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "NDOF Isometric 1", ""}, + {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "NDOF Isometric 2", ""}, /* 90 degree rotations */ {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "NDOF Roll CW", ""}, {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_PLUS, "NDOF_BUTTON_PLUS", 0, "NDOF Plus", ""}, {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 */ {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "NDOF Button 1", ""}, {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_9, "NDOF_BUTTON_9", 0, "NDOF Button 9", ""}, {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}}; EnumPropertyItem keymap_propvalue_items[] = { @@ -584,7 +600,7 @@ static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value) break; case KMI_TYPE_NDOF: kmi->type = NDOF_BUTTON_MENU; - kmi->val = KM_NOTHING; + kmi->val = KM_PRESS; break; } } diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 170413c13b0..02434d85c51 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -112,6 +112,11 @@ enum { NDOF_BUTTON_DOMINANT, NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS, + // keyboard emulation + NDOF_BUTTON_ESC, + NDOF_BUTTON_ALT, + NDOF_BUTTON_SHIFT, + NDOF_BUTTON_CTRL, // general-purpose buttons NDOF_BUTTON_1, NDOF_BUTTON_2, @@ -123,6 +128,11 @@ enum { NDOF_BUTTON_8, NDOF_BUTTON_9, NDOF_BUTTON_10, + // more general-purpose buttons + NDOF_BUTTON_A, + NDOF_BUTTON_B, + NDOF_BUTTON_C, + // the end NDOF_LAST };