12 GHOST_DirectManipulationHelper::GHOST_DirectManipulationHelper(
14 Microsoft::WRL::ComPtr<IDirectManipulationManager> directManipulationManager,
15 Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> directManipulationUpdateManager,
16 Microsoft::WRL::ComPtr<IDirectManipulationViewport> directManipulationViewport,
17 Microsoft::WRL::ComPtr<GHOST_DirectManipulationViewportEventHandler>
18 directManipulationEventHandler,
19 DWORD directManipulationViewportHandlerCookie,
20 bool isScrollDirectionInverted)
22 m_scrollDirectionRegKey(
NULL),
23 m_scrollDirectionChangeEvent(
NULL),
24 m_directManipulationManager(directManipulationManager),
25 m_directManipulationUpdateManager(directManipulationUpdateManager),
26 m_directManipulationViewport(directManipulationViewport),
27 m_directManipulationEventHandler(directManipulationEventHandler),
28 m_directManipulationViewportHandlerCookie(directManipulationViewportHandlerCookie),
29 m_isScrollDirectionInverted(isScrollDirectionInverted)
35 #define DM_CHECK_RESULT_AND_EXIT_EARLY(hr, failMessage) \
37 if (!SUCCEEDED(hr)) { \
38 GHOST_PRINT(failMessage); \
43 Microsoft::WRL::ComPtr<IDirectManipulationManager> directManipulationManager;
44 HRESULT hr = ::CoCreateInstance(CLSID_DirectManipulationManager,
47 IID_PPV_ARGS(&directManipulationManager));
51 Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> directManipulationUpdateManager;
52 hr = directManipulationManager->GetUpdateManager(IID_PPV_ARGS(&directManipulationUpdateManager));
55 Microsoft::WRL::ComPtr<IDirectManipulationViewport> directManipulationViewport;
56 hr = directManipulationManager->CreateViewport(
57 nullptr, hWnd, IID_PPV_ARGS(&directManipulationViewport));
60 DIRECTMANIPULATION_CONFIGURATION configuration =
61 DIRECTMANIPULATION_CONFIGURATION_INTERACTION |
62 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_X |
63 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_Y |
64 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_INERTIA |
65 DIRECTMANIPULATION_CONFIGURATION_SCALING;
67 hr = directManipulationViewport->ActivateConfiguration(configuration);
72 hr = directManipulationViewport->SetViewportOptions(
73 DIRECTMANIPULATION_VIEWPORT_OPTIONS_MANUALUPDATE);
78 Microsoft::WRL::ComPtr<GHOST_DirectManipulationViewportEventHandler>
79 directManipulationEventHandler =
80 Microsoft::WRL::Make<GHOST_DirectManipulationViewportEventHandler>(dpi);
81 DWORD directManipulationViewportHandlerCookie;
82 directManipulationViewport->AddEventHandler(
83 hWnd, directManipulationEventHandler.Get(), &directManipulationViewportHandlerCookie);
87 RECT rect = {0, 0, 10000, 10000};
88 hr = directManipulationViewport->SetViewportRect(&rect);
91 hr = directManipulationManager->Activate(hWnd);
94 hr = directManipulationViewport->Enable();
97 directManipulationEventHandler->resetViewport(directManipulationViewport.Get());
99 bool isScrollDirectionInverted = getScrollDirectionFromReg();
102 directManipulationManager,
103 directManipulationUpdateManager,
104 directManipulationViewport,
105 directManipulationEventHandler,
106 directManipulationViewportHandlerCookie,
107 isScrollDirectionInverted);
109 instance->registerScrollDirectionChangeListener();
113 #undef DM_CHECK_RESULT_AND_EXIT_EARLY
116 bool GHOST_DirectManipulationHelper::getScrollDirectionFromReg()
118 DWORD scrollDirectionRegValue, pcbData;
119 HRESULT hr = HRESULT_FROM_WIN32(
120 RegGetValueW(HKEY_CURRENT_USER,
121 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PrecisionTouchPad\\",
125 &scrollDirectionRegValue,
127 if (!SUCCEEDED(hr)) {
128 GHOST_PRINT(
"Failed to get scroll direction from registry\n");
132 return scrollDirectionRegValue == 0;
135 void GHOST_DirectManipulationHelper::registerScrollDirectionChangeListener()
138 if (!m_scrollDirectionRegKey) {
139 HRESULT hr = HRESULT_FROM_WIN32(
140 RegOpenKeyExW(HKEY_CURRENT_USER,
141 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PrecisionTouchPad\\",
144 &m_scrollDirectionRegKey));
145 if (!SUCCEEDED(hr)) {
146 GHOST_PRINT(
"Failed to open scroll direction registry key\n");
151 if (!m_scrollDirectionChangeEvent) {
152 m_scrollDirectionChangeEvent = CreateEventW(
NULL,
true,
false,
NULL);
155 ResetEvent(m_scrollDirectionChangeEvent);
157 HRESULT hr = HRESULT_FROM_WIN32(RegNotifyChangeKeyValue(m_scrollDirectionRegKey,
159 REG_NOTIFY_CHANGE_LAST_SET,
160 m_scrollDirectionChangeEvent,
162 if (!SUCCEEDED(hr)) {
163 GHOST_PRINT(
"Failed to register scroll direction change listener\n");
170 [[maybe_unused]] HRESULT hr = m_directManipulationViewport->SetContact(pointerId);
171 GHOST_ASSERT(SUCCEEDED(hr),
"Viewport set contact failed\n");
173 if (WaitForSingleObject(m_scrollDirectionChangeEvent, 0) == WAIT_OBJECT_0) {
174 m_isScrollDirectionInverted = getScrollDirectionFromReg();
175 registerScrollDirectionChangeListener();
181 if (m_directManipulationEventHandler->dm_status == DIRECTMANIPULATION_RUNNING ||
182 m_directManipulationEventHandler->dm_status == DIRECTMANIPULATION_INERTIA) {
183 [[maybe_unused]] HRESULT hr = m_directManipulationUpdateManager->Update(
nullptr);
184 GHOST_ASSERT(SUCCEEDED(hr),
"DirectManipulationUpdateManager update failed\n");
190 m_directManipulationEventHandler->dpi = dpi;
196 result.isScrollDirectionInverted = m_isScrollDirectionInverted;
198 m_directManipulationEventHandler->accumulated_values = {0, 0, 0};
205 hr = m_directManipulationViewport->Stop();
208 hr = m_directManipulationViewport->RemoveEventHandler(m_directManipulationViewportHandlerCookie);
209 GHOST_ASSERT(SUCCEEDED(hr),
"Viewport remove event handler failed\n");
211 hr = m_directManipulationViewport->Abandon();
212 GHOST_ASSERT(SUCCEEDED(hr),
"Viewport abandon failed\n");
214 hr = m_directManipulationManager->Deactivate(m_hWnd);
215 GHOST_ASSERT(SUCCEEDED(hr),
"DirectManipulationManager deactivate failed\n");
217 if (m_scrollDirectionChangeEvent) {
218 CloseHandle(m_scrollDirectionChangeEvent);
219 m_scrollDirectionChangeEvent =
NULL;
221 if (m_scrollDirectionRegKey) {
222 RegCloseKey(m_scrollDirectionRegKey);
223 m_scrollDirectionRegKey =
NULL;
229 : accumulated_values({0, 0, 0}), dpi(dpi), dm_status(DIRECTMANIPULATION_BUILDING)
234 IDirectManipulationViewport *viewport)
236 if (gesture_state != GESTURE_NONE) {
237 [[maybe_unused]] HRESULT hr = viewport->ZoomToRect(0.0f, 0.0f, 10000.0f, 10000.0f,
FALSE);
241 gesture_state = GESTURE_NONE;
249 IDirectManipulationViewport *viewport,
250 DIRECTMANIPULATION_STATUS current,
251 DIRECTMANIPULATION_STATUS previous)
255 if (current == previous) {
259 if (previous == DIRECTMANIPULATION_ENABLED || current == DIRECTMANIPULATION_READY ||
260 (previous == DIRECTMANIPULATION_INERTIA && current != DIRECTMANIPULATION_INERTIA)) {
268 IDirectManipulationViewport *viewport)
275 IDirectManipulationViewport *viewport, IDirectManipulationContent *content)
279 GHOST_ASSERT(SUCCEEDED(hr),
"DirectManipulationContent get transform failed\n");
281 const float device_scale_factor = dpi / 96.0f;
284 const float x =
transform[4] / device_scale_factor;
285 const float y =
transform[5] / device_scale_factor;
287 const float EPS = 3
e-5;
298 if (gesture_state == GESTURE_NONE) {
299 gesture_state = GESTURE_PAN;
304 if (gesture_state == GESTURE_PAN) {
306 gesture_state = GESTURE_PINCH;
318 switch (gesture_state) {
319 case GESTURE_PINCH: {
320 int32_t dscale = roundf(scale - last_scale);
322 last_scale += dscale;
324 accumulated_values.
scale += dscale;
334 accumulated_values.
x += dx;
335 accumulated_values.
y += dy;
#define GHOST_ASSERT(x, info)
#define DM_CHECK_RESULT_AND_EXIT_EARLY(hr, failMessage)
#define PINCH_SCALE_FACTOR
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object instance
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
void setDPI(uint16_t dpi)
~GHOST_DirectManipulationHelper()
void onPointerHitTest(UINT32 pointerId)
static GHOST_DirectManipulationHelper * create(HWND hWnd, uint16_t dpi)
GHOST_TTrackpadInfo getTrackpadInfo()
void resetViewport(IDirectManipulationViewport *viewport)
HRESULT STDMETHODCALLTYPE OnContentUpdated(IDirectManipulationViewport *viewport, IDirectManipulationContent *content) override
HRESULT STDMETHODCALLTYPE OnViewportUpdated(IDirectManipulationViewport *viewport) override
GHOST_DirectManipulationViewportEventHandler(uint16_t dpi)
HRESULT STDMETHODCALLTYPE OnViewportStatusChanged(IDirectManipulationViewport *viewport, DIRECTMANIPULATION_STATUS current, DIRECTMANIPULATION_STATUS previous) override
ccl_device_inline float2 fabs(const float2 &a)