14GHOST_DirectManipulationHelper::GHOST_DirectManipulationHelper(
16 Microsoft::WRL::ComPtr<IDirectManipulationManager> directManipulationManager,
17 Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> directManipulationUpdateManager,
18 Microsoft::WRL::ComPtr<IDirectManipulationViewport> directManipulationViewport,
19 Microsoft::WRL::ComPtr<GHOST_DirectManipulationViewportEventHandler>
20 directManipulationEventHandler,
21 DWORD directManipulationViewportHandlerCookie,
22 bool isScrollDirectionInverted)
24 m_scrollDirectionRegKey(nullptr),
25 m_scrollDirectionChangeEvent(nullptr),
26 m_directManipulationManager(directManipulationManager),
27 m_directManipulationUpdateManager(directManipulationUpdateManager),
28 m_directManipulationViewport(directManipulationViewport),
29 m_directManipulationEventHandler(directManipulationEventHandler),
30 m_directManipulationViewportHandlerCookie(directManipulationViewportHandlerCookie),
31 m_isScrollDirectionInverted(isScrollDirectionInverted)
37#define DM_CHECK_RESULT_AND_EXIT_EARLY(hr, failMessage) \
39 if (!SUCCEEDED(hr)) { \
40 GHOST_PRINT(failMessage); \
45 Microsoft::WRL::ComPtr<IDirectManipulationManager> directManipulationManager;
46 HRESULT hr = ::CoCreateInstance(CLSID_DirectManipulationManager,
49 IID_PPV_ARGS(&directManipulationManager));
53 Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> directManipulationUpdateManager;
54 hr = directManipulationManager->GetUpdateManager(IID_PPV_ARGS(&directManipulationUpdateManager));
57 Microsoft::WRL::ComPtr<IDirectManipulationViewport> directManipulationViewport;
58 hr = directManipulationManager->CreateViewport(
59 nullptr, hWnd, IID_PPV_ARGS(&directManipulationViewport));
62 DIRECTMANIPULATION_CONFIGURATION configuration =
63 DIRECTMANIPULATION_CONFIGURATION_INTERACTION |
64 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_X |
65 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_Y |
66 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_INERTIA |
67 DIRECTMANIPULATION_CONFIGURATION_SCALING;
69 hr = directManipulationViewport->ActivateConfiguration(configuration);
74 hr = directManipulationViewport->SetViewportOptions(
75 DIRECTMANIPULATION_VIEWPORT_OPTIONS_MANUALUPDATE);
80 Microsoft::WRL::ComPtr<GHOST_DirectManipulationViewportEventHandler>
81 directManipulationEventHandler =
82 Microsoft::WRL::Make<GHOST_DirectManipulationViewportEventHandler>(dpi);
83 DWORD directManipulationViewportHandlerCookie;
84 directManipulationViewport->AddEventHandler(
85 hWnd, directManipulationEventHandler.Get(), &directManipulationViewportHandlerCookie);
89 RECT rect = {0, 0, 10000, 10000};
90 hr = directManipulationViewport->SetViewportRect(&rect);
93 hr = directManipulationManager->Activate(hWnd);
96 hr = directManipulationViewport->Enable();
99 directManipulationEventHandler->resetViewport(directManipulationViewport.Get());
101 bool isScrollDirectionInverted = getScrollDirectionFromReg();
104 directManipulationManager,
105 directManipulationUpdateManager,
106 directManipulationViewport,
107 directManipulationEventHandler,
108 directManipulationViewportHandlerCookie,
109 isScrollDirectionInverted);
111 instance->registerScrollDirectionChangeListener();
115#undef DM_CHECK_RESULT_AND_EXIT_EARLY
118bool GHOST_DirectManipulationHelper::getScrollDirectionFromReg()
120 DWORD scrollDirectionRegValue, pcbData;
121 HRESULT hr = HRESULT_FROM_WIN32(
122 RegGetValueW(HKEY_CURRENT_USER,
123 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PrecisionTouchPad\\",
127 &scrollDirectionRegValue,
129 if (!SUCCEEDED(hr)) {
130 GHOST_PRINT(
"Failed to get scroll direction from registry\n");
134 return scrollDirectionRegValue == 0;
137void GHOST_DirectManipulationHelper::registerScrollDirectionChangeListener()
140 if (!m_scrollDirectionRegKey) {
141 HRESULT hr = HRESULT_FROM_WIN32(
142 RegOpenKeyExW(HKEY_CURRENT_USER,
143 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\PrecisionTouchPad\\",
146 &m_scrollDirectionRegKey));
147 if (!SUCCEEDED(hr)) {
148 GHOST_PRINT(
"Failed to open scroll direction registry key\n");
153 if (!m_scrollDirectionChangeEvent) {
154 m_scrollDirectionChangeEvent = CreateEventW(
nullptr,
true,
false,
nullptr);
157 ResetEvent(m_scrollDirectionChangeEvent);
159 HRESULT hr = HRESULT_FROM_WIN32(RegNotifyChangeKeyValue(m_scrollDirectionRegKey,
161 REG_NOTIFY_CHANGE_LAST_SET,
162 m_scrollDirectionChangeEvent,
164 if (!SUCCEEDED(hr)) {
165 GHOST_PRINT(
"Failed to register scroll direction change listener\n");
172 [[maybe_unused]] HRESULT hr = m_directManipulationViewport->SetContact(pointerId);
173 GHOST_ASSERT(SUCCEEDED(hr),
"Viewport set contact failed\n");
175 if (WaitForSingleObject(m_scrollDirectionChangeEvent, 0) == WAIT_OBJECT_0) {
176 m_isScrollDirectionInverted = getScrollDirectionFromReg();
177 registerScrollDirectionChangeListener();
183 if (m_directManipulationEventHandler->dm_status == DIRECTMANIPULATION_RUNNING ||
184 m_directManipulationEventHandler->dm_status == DIRECTMANIPULATION_INERTIA)
186 [[maybe_unused]] HRESULT hr = m_directManipulationUpdateManager->Update(
nullptr);
187 GHOST_ASSERT(SUCCEEDED(hr),
"DirectManipulationUpdateManager update failed\n");
193 m_directManipulationEventHandler->dpi = dpi;
199 result.isScrollDirectionInverted = m_isScrollDirectionInverted;
201 m_directManipulationEventHandler->accumulated_values = {0, 0, 0};
208 hr = m_directManipulationViewport->Stop();
211 hr = m_directManipulationViewport->RemoveEventHandler(m_directManipulationViewportHandlerCookie);
212 GHOST_ASSERT(SUCCEEDED(hr),
"Viewport remove event handler failed\n");
214 hr = m_directManipulationViewport->Abandon();
215 GHOST_ASSERT(SUCCEEDED(hr),
"Viewport abandon failed\n");
217 hr = m_directManipulationManager->Deactivate(m_hWnd);
218 GHOST_ASSERT(SUCCEEDED(hr),
"DirectManipulationManager deactivate failed\n");
220 if (m_scrollDirectionChangeEvent) {
221 CloseHandle(m_scrollDirectionChangeEvent);
222 m_scrollDirectionChangeEvent =
nullptr;
224 if (m_scrollDirectionRegKey) {
225 RegCloseKey(m_scrollDirectionRegKey);
226 m_scrollDirectionRegKey =
nullptr;
232 : accumulated_values({0, 0, 0}), dpi(dpi), dm_status(DIRECTMANIPULATION_BUILDING)
237 IDirectManipulationViewport *viewport)
239 if (gesture_state != GESTURE_NONE) {
240 [[maybe_unused]] HRESULT hr = viewport->ZoomToRect(0.0f, 0.0f, 10000.0f, 10000.0f,
FALSE);
244 gesture_state = GESTURE_NONE;
252 IDirectManipulationViewport *viewport,
253 DIRECTMANIPULATION_STATUS current,
254 DIRECTMANIPULATION_STATUS previous)
258 if (current == previous) {
262 if (previous == DIRECTMANIPULATION_ENABLED || current == DIRECTMANIPULATION_READY ||
263 (previous == DIRECTMANIPULATION_INERTIA && current != DIRECTMANIPULATION_INERTIA))
272 IDirectManipulationViewport * )
279 IDirectManipulationViewport * , IDirectManipulationContent *content)
282 HRESULT hr = content->GetContentTransform(transform, ARRAYSIZE(transform));
283 GHOST_ASSERT(SUCCEEDED(hr),
"DirectManipulationContent get transform failed\n");
285 const float device_scale_factor = dpi / 96.0f;
288 const float x = transform[4] / device_scale_factor;
289 const float y = transform[5] / device_scale_factor;
291 const float EPS = 3
e-5;
303 if (gesture_state == GESTURE_NONE) {
304 gesture_state = GESTURE_PAN;
309 if (gesture_state == GESTURE_PAN) {
311 gesture_state = GESTURE_PINCH;
323 switch (gesture_state) {
324 case GESTURE_PINCH: {
325 int32_t dscale = roundf(scale - last_scale);
327 last_scale += dscale;
329 accumulated_values.
scale += dscale;
333 int32_t dx = roundf(x - last_x);
334 int32_t dy = roundf(y - last_y);
339 accumulated_values.
x += dx;
340 accumulated_values.
y += dy;
#define GHOST_ASSERT(x, info)
#define DM_CHECK_RESULT_AND_EXIT_EARLY(hr, failMessage)
#define PINCH_SCALE_FACTOR
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
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)