Commit 92bf3acd authored by Steve Lhomme's avatar Steve Lhomme Committed by Thomas Guillem

vout: win32: handle tilt sensors for VR orientation

Signed-off-by: Thomas Guillem's avatarThomas Guillem <thomas@gllm.fr>
parent e62a4aad
......@@ -234,6 +234,7 @@ libdirect3d9_plugin_la_SOURCES = video_output/win32/direct3d9.c \
video_chroma/copy.c video_chroma/copy.h \
video_output/win32/common.c video_output/win32/common.h \
video_output/win32/events.c video_output/win32/events.h \
video_output/win32/sensors.cpp \
video_output/win32/builtin_shaders.h \
video_output/win32/win32touch.c video_output/win32/win32touch.h \
video_chroma/d3d9_fmt.h
......@@ -265,6 +266,7 @@ libdirect3d11_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
if !HAVE_WINSTORE
libdirect3d11_plugin_la_SOURCES += video_output/win32/events.c \
video_output/win32/events.h \
video_output/win32/sensors.cpp \
video_output/win32/win32touch.c video_output/win32/win32touch.h
libdirect3d11_plugin_la_LIBADD = -lgdi32 $(LIBCOM) -luuid
else
......@@ -288,6 +290,7 @@ libdirectdraw_plugin_la_SOURCES = video_output/win32/directdraw.c \
video_output/win32/common.c video_output/win32/common.h \
video_chroma/copy.c video_chroma/copy.h \
video_output/win32/events.c video_output/win32/events.h \
video_output/win32/sensors.cpp \
video_output/win32/win32touch.c video_output/win32/win32touch.h
libdirectdraw_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
-DMODULE_NAME_IS_directdraw
......@@ -303,6 +306,7 @@ libglwin32_plugin_la_SOURCES = $(OPENGL_COMMONSOURCES) \
video_output/win32/common.c video_output/win32/common.h \
video_chroma/copy.c video_chroma/copy.h \
video_output/win32/events.c video_output/win32/events.h \
video_output/win32/sensors.cpp \
video_output/win32/win32touch.c video_output/win32/win32touch.h
libwgl_plugin_la_SOURCES = video_output/win32/wgl.c $(OPENGL_COMMONSOURCES)
......@@ -328,6 +332,7 @@ libwingdi_plugin_la_SOURCES = video_output/win32/wingdi.c \
video_output/win32/common.c video_output/win32/common.h \
video_chroma/copy.c video_chroma/copy.h \
video_output/win32/events.c video_output/win32/events.h \
video_output/win32/sensors.cpp \
video_output/win32/win32touch.c video_output/win32/win32touch.h
libwingdi_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
-DMODULE_NAME_IS_wingdi
......
......@@ -76,6 +76,9 @@ struct event_thread_t
/* Gestures */
win32_gesture_sys_t *p_gesture;
/* Sensors */
void *p_sensors;
/* Title */
char *psz_title;
......@@ -802,6 +805,8 @@ static int Win32VoutCreateWindow( event_thread_t *p_event )
InitGestures( p_event->hwnd, &p_event->p_gesture );
p_event->p_sensors = HookWindowsSensors(vd, p_event->hwnd);
if( p_event->hparent )
{
LONG i_style;
......@@ -891,6 +896,8 @@ static void Win32VoutCloseWindow( event_thread_t *p_event )
DestroyCursor( p_event->cursor_empty );
UnhookWindowsSensors(p_event->p_sensors);
CloseGestures( p_event->p_gesture);
}
......
......@@ -62,3 +62,12 @@ void EventThreadUpdateSourceAndPlace( event_thread_t *p_event,
void EventThreadUseOverlay( event_thread_t *, bool b_used );
bool EventThreadGetAndResetHasMoved( event_thread_t * );
# ifdef __cplusplus
extern "C" {
# endif
void* HookWindowsSensors(vout_display_t*, HWND);
void UnhookWindowsSensors(void*);
# ifdef __cplusplus
}
# endif
/*****************************************************************************
* sensors.cpp: Windows sensor handling
*****************************************************************************
* Copyright © 2017 Steve Lhomme
* Copyright © 2017 VideoLabs
*
* Authors: Steve Lhomme <robux4@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_vout_wrapper.h>
#include "events.h"
#include <initguid.h>
#include <propsys.h> /* stupid mingw headers don't include this */
#include <sensors.h>
#include <sensorsapi.h>
#include <new>
#ifndef _MSC_VER
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_MAGNETOMETER_ACCURACY, 0x1637d8a2, 0x4248, 0x4275, 0x86, 0x5d, 0x55, 0x8d, 0xe8, 0x4a, 0xed, 0xfd, 22);
#endif
class SensorReceiver : public ISensorEvents
{
public:
SensorReceiver(vout_display_t *vd, const vlc_viewpoint_t & init_viewpoint)
:vd(vd)
,current_pos(init_viewpoint)
{}
virtual ~SensorReceiver()
{}
STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
{
if (ppv == NULL)
{
return E_POINTER;
}
if (iid == __uuidof(IUnknown))
{
*ppv = static_cast<IUnknown*>(this);
}
else if (iid == __uuidof(ISensorEvents))
{
*ppv = static_cast<ISensorEvents*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
ULONG count = InterlockedDecrement(&m_cRef);
if (count == 0)
{
delete this;
return 0;
}
return count;
}
HRESULT STDMETHODCALLTYPE OnStateChanged(ISensor *pSensor, SensorState state)
{
(void)pSensor;
(void)state;
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnDataUpdated(ISensor *pSensor, ISensorDataReport *pNewData)
{
(void)pSensor;
vlc_viewpoint_t old_pos = current_pos;
HRESULT hr;
PROPVARIANT pvRot;
PropVariantInit(&pvRot);
hr = pNewData->GetSensorValue(SENSOR_DATA_TYPE_TILT_X_DEGREES, &pvRot);
if (SUCCEEDED(hr) && pvRot.vt == VT_R4)
{
current_pos.pitch = pvRot.fltVal;
PropVariantClear(&pvRot);
}
hr = pNewData->GetSensorValue(SENSOR_DATA_TYPE_TILT_Y_DEGREES, &pvRot);
if (SUCCEEDED(hr) && pvRot.vt == VT_R4)
{
current_pos.roll = pvRot.fltVal;
PropVariantClear(&pvRot);
}
hr = pNewData->GetSensorValue(SENSOR_DATA_TYPE_TILT_Z_DEGREES, &pvRot);
if (SUCCEEDED(hr) && pvRot.vt == VT_R4)
{
current_pos.yaw = pvRot.fltVal;
PropVariantClear(&pvRot);
}
vlc_viewpoint_t vp = {
old_pos.yaw - current_pos.yaw,
old_pos.pitch - current_pos.pitch,
old_pos.roll - current_pos.roll,
0.0f
};
vout_display_SendEventViewpointMoved(vd, &vp);
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnEvent(ISensor *pSensor, REFGUID eventID, IPortableDeviceValues *pEventData)
{
(void)pSensor;
(void)eventID;
(void)pEventData;
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnLeave(REFSENSOR_ID ID)
{
(void)ID;
return S_OK;
}
private:
vout_display_t *const vd;
vlc_viewpoint_t current_pos;
long m_cRef;
};
void *HookWindowsSensors(vout_display_t *vd, HWND hwnd)
{
ISensor *pSensor = NULL;
ISensorManager *pSensorManager;
HRESULT hr = CoCreateInstance( CLSID_SensorManager,
NULL, CLSCTX_INPROC_SERVER,
IID_ISensorManager, (void**)&pSensorManager );
if (SUCCEEDED(hr))
{
ISensorCollection *pInclinometers;
hr = pSensorManager->GetSensorsByType(SENSOR_TYPE_INCLINOMETER_3D, &pInclinometers);
if (SUCCEEDED(hr))
{
ULONG count;
pInclinometers->GetCount(&count);
msg_Dbg(vd, "Found %lu inclinometer", count);
for (ULONG i=0; i<count; ++i)
{
hr = pInclinometers->GetAt(i, &pSensor);
if (SUCCEEDED(hr))
{
SensorState state = SENSOR_STATE_NOT_AVAILABLE;
hr = pSensor->GetState(&state);
if (SUCCEEDED(hr))
{
if (state == SENSOR_STATE_ACCESS_DENIED)
hr = pSensorManager->RequestPermissions(hwnd, pInclinometers, TRUE);
if (SUCCEEDED(hr))
{
vlc_viewpoint_t start_viewpoint;
vlc_viewpoint_init(&start_viewpoint);
PROPVARIANT pvRot;
PropVariantInit(&pvRot);
hr = pSensor->GetProperty(SENSOR_DATA_TYPE_TILT_X_DEGREES, &pvRot);
if (SUCCEEDED(hr) && pvRot.vt == VT_R4)
{
start_viewpoint.pitch = pvRot.fltVal;
PropVariantClear(&pvRot);
}
hr = pSensor->GetProperty(SENSOR_DATA_TYPE_TILT_Y_DEGREES, &pvRot);
if (SUCCEEDED(hr) && pvRot.vt == VT_R4)
{
start_viewpoint.roll = pvRot.fltVal;
PropVariantClear(&pvRot);
}
hr = pSensor->GetProperty(SENSOR_DATA_TYPE_TILT_Z_DEGREES, &pvRot);
if (SUCCEEDED(hr) && pvRot.vt == VT_R4)
{
start_viewpoint.yaw = pvRot.fltVal;
PropVariantClear(&pvRot);
}
SensorReceiver *received = new(std::nothrow) SensorReceiver(vd, start_viewpoint);
if (received)
{
pSensor->SetEventSink(received);
break;
}
}
}
pSensor->Release();
}
}
pInclinometers->Release();
}
else
msg_Dbg(vd, "inclinometer not found. (hr=0x%lX)", hr);
pSensorManager->Release();
}
return pSensor;
}
void UnhookWindowsSensors(void *vSensor)
{
if (!vSensor)
return;
ISensor *pSensor = static_cast<ISensor*>(vSensor);
pSensor->SetEventSink(NULL);
pSensor->Release();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment