Skip to content

Commit

Permalink
Gestures: fix running on win XP
Browse files Browse the repository at this point in the history
Potential fix, by dynamically linking SetGestureConfig
  • Loading branch information
DeepSOIC committed Apr 6, 2015
1 parent 176f3e6 commit 963b993
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 24 deletions.
46 changes: 31 additions & 15 deletions src/Gui/View3DInventorViewer.cpp
Expand Up @@ -219,16 +219,25 @@ class Gui::ViewerEventFilter : public QObject
if (obj->isWidgetType()) {
View3DInventorViewer* v = dynamic_cast<View3DInventorViewer*>(obj);
if(v) {
if(! v->isWinGesturesTuned) {
v->isWinGesturesTuned = true;
/* Internally, Qt seems to set up the gestures upon showing the
* widget (but after this event is processed), thus invalidating
* our settings. This piece takes care to retune gestures on the
* next event after the show event.
*/
if(v->winGestureTuneState == View3DInventorViewer::ewgtsNeedTuning) {
try{
WinNativeGestureRecognizerPinch::TuneWindowsGestures(v);
v->winGestureTuneState = View3DInventorViewer::ewgtsTuned;
} catch (Base::Exception &e) {
Base::Console().Warning("Failed to TuneWindowsGestures. Error: %s\n",e.what());
v->winGestureTuneState = View3DInventorViewer::ewgtsDisabled;
} catch (...){
Base::Console().Warning("Failed to TuneWindowsGestures.\n");
Base::Console().Warning("Failed to TuneWindowsGestures. Unknown error.\n");
v->winGestureTuneState = View3DInventorViewer::ewgtsDisabled;
}
}
if (event->type() == QEvent::Show)
v->isWinGesturesTuned = false;//internally, Qt seems to set up the gestures upon showing the widget (but after this event is processed), thus invalidating our settings. Needs to be re-tuned asap.
if (event->type() == QEvent::Show && v->winGestureTuneState == View3DInventorViewer::ewgtsTuned)
v->winGestureTuneState = View3DInventorViewer::ewgtsNeedTuning;

}
}
Expand Down Expand Up @@ -485,18 +494,25 @@ void View3DInventorViewer::init()
getEventFilter()->registerInputDevice(new SpaceNavigatorDevice);
getEventFilter()->registerInputDevice(new GesturesDevice(this));

this->grabGesture(Qt::PanGesture);
this->grabGesture(Qt::PinchGesture);
#ifdef GESTURE_MESS
{
static WinNativeGestureRecognizerPinch* recognizer;//static to avoid creating more than one recognizer, thus causing memory leak and gradual slowdown
if(recognizer == 0){
recognizer = new WinNativeGestureRecognizerPinch;
recognizer->registerRecognizer(recognizer); //From now on, Qt owns the pointer.
this->winGestureTuneState = View3DInventorViewer::ewgtsDisabled;
try{
this->grabGesture(Qt::PanGesture);
this->grabGesture(Qt::PinchGesture);
#ifdef GESTURE_MESS
{
static WinNativeGestureRecognizerPinch* recognizer;//static to avoid creating more than one recognizer, thus causing memory leak and gradual slowdown
if(recognizer == 0){
recognizer = new WinNativeGestureRecognizerPinch;
recognizer->registerRecognizer(recognizer); //From now on, Qt owns the pointer.
}
}
this->winGestureTuneState = View3DInventorViewer::ewgtsNeedTuning;
#endif
} catch (Base::Exception &e) {
Base::Console().Warning("Failed to set up gestures. Error: %s\n", e.what());
} catch (...) {
Base::Console().Warning("Failed to set up gestures. Unknown error.\n");
}
this->isWinGesturesTuned = false;
#endif

//create the cursors
QBitmap cursor = QBitmap::fromData(QSize(ROTATE_WIDTH, ROTATE_HEIGHT), rotate_bitmap);
Expand Down
13 changes: 7 additions & 6 deletions src/Gui/View3DInventorViewer.h
Expand Up @@ -357,12 +357,13 @@ class GuiExport View3DInventorViewer : public Quarter::SoQTQuarterAdaptor, publi
SbBool processSoEventBase(const SoEvent * const ev);
void printDimension();
void selectAll();
/** A flag. If false, gestures on windows will get tuned(or re-tuned)
* upon the first event that arrives to eventFilter. This is needed to
* tune windows gestures after Qt does it internally, since its settings
* are not all right for us.
*/
bool isWinGesturesTuned;

enum eWinGestureTuneState{
ewgtsDisabled, //suppress tuning/re-tuning after errors
ewgtsNeedTuning, //gestures are to be retuned upon next event
ewgtsTuned
};
eWinGestureTuneState winGestureTuneState;//See ViewerEventFilter::eventFilter function for explanation

private:
static void setViewportCB(void * userdata, SoAction * action);
Expand Down
27 changes: 24 additions & 3 deletions src/Gui/WinNativeGestureRecognizers.cpp
Expand Up @@ -41,6 +41,7 @@

#include <qgesture.h>
#include <private/qevent_p.h>
#include <Base/Exception.h>

QT_BEGIN_NAMESPACE

Expand Down Expand Up @@ -188,10 +189,28 @@ void WinNativeGestureRecognizerPinch::reset(QGesture* gesture)
q->fingerDistance = 0;
}

//function prototype for dymanic linking
typedef BOOL ( __stdcall * ptrSetGestureConfig) (
HWND , // window for which configuration is specified
DWORD , // reserved, must be 0
UINT , // count of GESTURECONFIG structures
PGESTURECONFIG , // array of GESTURECONFIG structures, dwIDs will be processed in the
// order specified and repeated occurances will overwrite previous ones
UINT ); // sizeof(GESTURECONFIG)

void WinNativeGestureRecognizerPinch::TuneWindowsGestures(QWidget* target)
{
//modify windows-specific gesture options
#if WINVER >= _WIN32_WINNT_WIN7
//dynamic linking - required to be able to run on windows pre-7
HINSTANCE hinstLib = LoadLibraryA("user32.dll");
if (hinstLib == 0)
throw Base::Exception("LoadLibrary(user32.dll) failed. Could not tune Windows gestures.");

ptrSetGestureConfig dllSetGestureConfig = reinterpret_cast<ptrSetGestureConfig> (GetProcAddress(hinstLib,"SetGestureConfig"));
if (dllSetGestureConfig == 0)
throw Base::Exception("DLL entry point for SetGestureConfig not found in user32.dll. Could not tune Windows gestures.");

HWND w = target->winId();

//fill in the options
Expand All @@ -205,10 +224,12 @@ void WinNativeGestureRecognizerPinch::TuneWindowsGestures(QWidget* target)
cfgs[1].dwWant = GC_ROTATE;

//set the options
bool ret = SetGestureConfig(w, 0, nCfg, cfgs, sizeof(GESTURECONFIG));
assert(ret); //if(!ret) throw
bool ret = dllSetGestureConfig(w, 0, nCfg, cfgs, sizeof(GESTURECONFIG));
assert(ret);
if(!ret){
DWORD err = GetLastError();//for debugging
DWORD err = GetLastError();
QString errMsg = QString::fromLatin1("Error in SetGestureConfig. GetLastError = %1").arg(err);
throw Base::Exception(errMsg.toLatin1());
}
#endif
}
Expand Down

0 comments on commit 963b993

Please sign in to comment.