Merge pull request #4090 from MSOpenTech:highgui_winrt
commit
0824ed595b
5 changed files with 461 additions and 10042 deletions
@ -1,568 +0,0 @@ |
|||||||
//
|
|
||||||
// Copyright (C) Microsoft Corporation
|
|
||||||
// All rights reserved.
|
|
||||||
// Modified for native C++ WRL support by Gregory Morse
|
|
||||||
//
|
|
||||||
// Code in Details namespace is for internal usage within the library code
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef _PLATFORM_AGILE_H_ |
|
||||||
#define _PLATFORM_AGILE_H_ |
|
||||||
|
|
||||||
#ifdef _MSC_VER |
|
||||||
#pragma once |
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
#include <algorithm> |
|
||||||
#include <wrl\client.h> |
|
||||||
|
|
||||||
template <typename T, bool TIsNotAgile> class Agile; |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
struct UnwrapAgile |
|
||||||
{ |
|
||||||
static const bool _IsAgile = false; |
|
||||||
}; |
|
||||||
template <typename T> |
|
||||||
struct UnwrapAgile<Agile<T, false>> |
|
||||||
{ |
|
||||||
static const bool _IsAgile = true; |
|
||||||
}; |
|
||||||
template <typename T> |
|
||||||
struct UnwrapAgile<Agile<T, true>> |
|
||||||
{ |
|
||||||
static const bool _IsAgile = true; |
|
||||||
}; |
|
||||||
|
|
||||||
#define IS_AGILE(T) UnwrapAgile<T>::_IsAgile |
|
||||||
|
|
||||||
#define __is_winrt_agile(T) (std::is_same<T, HSTRING__>::value || std::is_base_of<Microsoft::WRL::FtmBase, T>::value || std::is_base_of<IAgileObject, T>::value) //derived from Microsoft::WRL::FtmBase or IAgileObject
|
|
||||||
|
|
||||||
#define __is_win_interface(T) (std::is_base_of<IUnknown, T>::value || std::is_base_of<IInspectable, T>::value) //derived from IUnknown or IInspectable
|
|
||||||
|
|
||||||
#define __is_win_class(T) (std::is_same<T, HSTRING__>::value || std::is_base_of<Microsoft::WRL::Details::RuntimeClassBase, T>::value) //derived from Microsoft::WRL::RuntimeClass or HSTRING
|
|
||||||
|
|
||||||
namespace Details |
|
||||||
{ |
|
||||||
IUnknown* __stdcall GetObjectContext(); |
|
||||||
HRESULT __stdcall GetProxyImpl(IUnknown*, REFIID, IUnknown*, IUnknown**); |
|
||||||
HRESULT __stdcall ReleaseInContextImpl(IUnknown*, IUnknown*); |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
__declspec(no_refcount) inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy) |
|
||||||
#else |
|
||||||
inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
return GetProxyImpl(*reinterpret_cast<IUnknown**>(&ObjectIn), __uuidof(T*), ContextCallBack, reinterpret_cast<IUnknown**>(Proxy)); |
|
||||||
#else |
|
||||||
return GetProxyImpl(*reinterpret_cast<IUnknown**>(&const_cast<T*>(ObjectIn)), __uuidof(T*), ContextCallBack, reinterpret_cast<IUnknown**>(Proxy)); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
inline HRESULT ReleaseInContext(T *ObjectIn, IUnknown *ContextCallBack) |
|
||||||
{ |
|
||||||
return ReleaseInContextImpl(ObjectIn, ContextCallBack); |
|
||||||
} |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
class AgileHelper |
|
||||||
{ |
|
||||||
__abi_IUnknown* _p; |
|
||||||
bool _release; |
|
||||||
public: |
|
||||||
AgileHelper(__abi_IUnknown* p, bool release = true) : _p(p), _release(release) |
|
||||||
{ |
|
||||||
} |
|
||||||
AgileHelper(AgileHelper&& other) : _p(other._p), _release(other._release) |
|
||||||
{ |
|
||||||
_other._p = nullptr; |
|
||||||
_other._release = true; |
|
||||||
} |
|
||||||
AgileHelper operator=(AgileHelper&& other) |
|
||||||
{ |
|
||||||
_p = other._p; |
|
||||||
_release = other._release; |
|
||||||
_other._p = nullptr; |
|
||||||
_other._release = true; |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
~AgileHelper() |
|
||||||
{ |
|
||||||
if (_release && _p) |
|
||||||
{ |
|
||||||
_p->__abi_Release(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
__declspec(no_refcount) __declspec(no_release_return) |
|
||||||
T* operator->() |
|
||||||
{ |
|
||||||
return reinterpret_cast<T*>(_p); |
|
||||||
} |
|
||||||
|
|
||||||
__declspec(no_refcount) __declspec(no_release_return) |
|
||||||
operator T * () |
|
||||||
{ |
|
||||||
return reinterpret_cast<T*>(_p); |
|
||||||
} |
|
||||||
private: |
|
||||||
AgileHelper(const AgileHelper&); |
|
||||||
AgileHelper operator=(const AgileHelper&); |
|
||||||
}; |
|
||||||
template <typename T> |
|
||||||
struct __remove_hat |
|
||||||
{ |
|
||||||
typedef T type; |
|
||||||
}; |
|
||||||
template <typename T> |
|
||||||
struct __remove_hat<T*> |
|
||||||
{ |
|
||||||
typedef T type; |
|
||||||
}; |
|
||||||
template <typename T> |
|
||||||
struct AgileTypeHelper |
|
||||||
{ |
|
||||||
typename typedef __remove_hat<T>::type type; |
|
||||||
typename typedef __remove_hat<T>::type* agileMemberType; |
|
||||||
}; |
|
||||||
} // namespace Details
|
|
||||||
|
|
||||||
#pragma warning(push) |
|
||||||
#pragma warning(disable: 4451) // Usage of ref class inside this context can lead to invalid marshaling of object across contexts
|
|
||||||
|
|
||||||
template < |
|
||||||
typename T, |
|
||||||
bool TIsNotAgile = (__is_win_class(typename Details::AgileTypeHelper<T>::type) && !__is_winrt_agile(typename Details::AgileTypeHelper<T>::type)) || |
|
||||||
__is_win_interface(typename Details::AgileTypeHelper<T>::type) |
|
||||||
> |
|
||||||
class Agile |
|
||||||
{ |
|
||||||
static_assert(__is_win_class(typename Details::AgileTypeHelper<T>::type) || __is_win_interface(typename Details::AgileTypeHelper<T>::type), "Agile can only be used with ref class or interface class types"); |
|
||||||
typename typedef Details::AgileTypeHelper<T>::agileMemberType TypeT; |
|
||||||
TypeT _object; |
|
||||||
::Microsoft::WRL::ComPtr<IUnknown> _contextCallback; |
|
||||||
ULONG_PTR _contextToken; |
|
||||||
|
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
enum class AgileState |
|
||||||
{ |
|
||||||
NonAgilePointer = 0, |
|
||||||
AgilePointer = 1, |
|
||||||
Unknown = 2 |
|
||||||
}; |
|
||||||
AgileState _agileState; |
|
||||||
#endif |
|
||||||
|
|
||||||
void CaptureContext() |
|
||||||
{ |
|
||||||
_contextCallback = Details::GetObjectContext(); |
|
||||||
__abi_ThrowIfFailed(CoGetContextToken(&_contextToken)); |
|
||||||
} |
|
||||||
|
|
||||||
void SetObject(TypeT object) |
|
||||||
{ |
|
||||||
// Capture context before setting the pointer
|
|
||||||
// If context capture fails then nothing to cleanup
|
|
||||||
Release(); |
|
||||||
if (object != nullptr) |
|
||||||
{ |
|
||||||
::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile; |
|
||||||
HRESULT hr = reinterpret_cast<IUnknown*>(object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile); |
|
||||||
// Don't Capture context if object is agile
|
|
||||||
if (hr != S_OK) |
|
||||||
{ |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
_agileState = AgileState::NonAgilePointer; |
|
||||||
#endif |
|
||||||
CaptureContext(); |
|
||||||
} |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
else |
|
||||||
{ |
|
||||||
_agileState = AgileState::AgilePointer; |
|
||||||
} |
|
||||||
#endif |
|
||||||
} |
|
||||||
_object = object; |
|
||||||
} |
|
||||||
|
|
||||||
public: |
|
||||||
Agile() throw() : _object(nullptr), _contextToken(0) |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
, _agileState(AgileState::Unknown) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
Agile(nullptr_t) throw() : _object(nullptr), _contextToken(0) |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
, _agileState(AgileState::Unknown) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
explicit Agile(TypeT object) throw() : _object(nullptr), _contextToken(0) |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
, _agileState(AgileState::Unknown) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
// Assumes that the source object is from the current context
|
|
||||||
SetObject(object); |
|
||||||
} |
|
||||||
|
|
||||||
Agile(const Agile& object) throw() : _object(nullptr), _contextToken(0) |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
, _agileState(AgileState::Unknown) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
// Get returns pointer valid for current context
|
|
||||||
SetObject(object.Get()); |
|
||||||
} |
|
||||||
|
|
||||||
Agile(Agile&& object) throw() : _object(nullptr), _contextToken(0) |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
, _agileState(AgileState::Unknown) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
// Assumes that the source object is from the current context
|
|
||||||
Swap(object); |
|
||||||
} |
|
||||||
|
|
||||||
~Agile() throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
} |
|
||||||
|
|
||||||
TypeT Get() const |
|
||||||
{ |
|
||||||
// Agile object, no proxy required
|
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
if (_agileState == AgileState::AgilePointer || _object == nullptr) |
|
||||||
#else |
|
||||||
if (_contextToken == 0 || _contextCallback == nullptr || _object == nullptr) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
return _object; |
|
||||||
} |
|
||||||
|
|
||||||
// Do the check for same context
|
|
||||||
ULONG_PTR currentContextToken; |
|
||||||
__abi_ThrowIfFailed(CoGetContextToken(¤tContextToken)); |
|
||||||
if (currentContextToken == _contextToken) |
|
||||||
{ |
|
||||||
return _object; |
|
||||||
} |
|
||||||
|
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
// Different context and holding on to a non agile object
|
|
||||||
// Do the costly work of getting a proxy
|
|
||||||
TypeT localObject; |
|
||||||
__abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject)); |
|
||||||
|
|
||||||
if (_agileState == AgileState::Unknown) |
|
||||||
#else |
|
||||||
// Object is agile if it implements IAgileObject
|
|
||||||
// GetAddressOf captures the context with out knowing the type of object that it will hold
|
|
||||||
if (_object != nullptr) |
|
||||||
#endif |
|
||||||
{ |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
// Object is agile if it implements IAgileObject
|
|
||||||
// GetAddressOf captures the context with out knowing the type of object that it will hold
|
|
||||||
::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile; |
|
||||||
HRESULT hr = reinterpret_cast<IUnknown*>(localObject)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile); |
|
||||||
#else |
|
||||||
::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile; |
|
||||||
HRESULT hr = reinterpret_cast<IUnknown*>(_object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile); |
|
||||||
#endif |
|
||||||
if (hr == S_OK) |
|
||||||
{ |
|
||||||
auto pThis = const_cast<Agile*>(this); |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
pThis->_agileState = AgileState::AgilePointer; |
|
||||||
#endif |
|
||||||
pThis->_contextToken = 0; |
|
||||||
pThis->_contextCallback = nullptr; |
|
||||||
return _object; |
|
||||||
} |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
else |
|
||||||
{ |
|
||||||
auto pThis = const_cast<Agile*>(this); |
|
||||||
pThis->_agileState = AgileState::NonAgilePointer; |
|
||||||
} |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
#if _MSC_VER < 1800 |
|
||||||
// Different context and holding on to a non agile object
|
|
||||||
// Do the costly work of getting a proxy
|
|
||||||
TypeT localObject; |
|
||||||
__abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject)); |
|
||||||
#endif |
|
||||||
return localObject; |
|
||||||
} |
|
||||||
|
|
||||||
TypeT* GetAddressOf() throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
CaptureContext(); |
|
||||||
return &_object; |
|
||||||
} |
|
||||||
|
|
||||||
TypeT* GetAddressOfForInOut() throw() |
|
||||||
{ |
|
||||||
CaptureContext(); |
|
||||||
return &_object; |
|
||||||
} |
|
||||||
|
|
||||||
TypeT operator->() const throw() |
|
||||||
{ |
|
||||||
return Get(); |
|
||||||
} |
|
||||||
|
|
||||||
Agile& operator=(nullptr_t) throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
Agile& operator=(TypeT object) throw() |
|
||||||
{ |
|
||||||
Agile(object).Swap(*this); |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
Agile& operator=(Agile object) throw() |
|
||||||
{ |
|
||||||
// parameter is by copy which gets pointer valid for current context
|
|
||||||
object.Swap(*this); |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
#if _MSC_VER < 1800 |
|
||||||
Agile& operator=(IUnknown* lp) throw() |
|
||||||
{ |
|
||||||
// bump ref count
|
|
||||||
::Microsoft::WRL::ComPtr<IUnknown> spObject(lp); |
|
||||||
|
|
||||||
// put it into Platform Object
|
|
||||||
Platform::Object object; |
|
||||||
*(IUnknown**)(&object) = spObject.Detach(); |
|
||||||
|
|
||||||
SetObject(object); |
|
||||||
return *this; |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
void Swap(Agile& object) |
|
||||||
{ |
|
||||||
std::swap(_object, object._object); |
|
||||||
std::swap(_contextCallback, object._contextCallback); |
|
||||||
std::swap(_contextToken, object._contextToken); |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
std::swap(_agileState, object._agileState); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
// Release the interface and set to NULL
|
|
||||||
void Release() throw() |
|
||||||
{ |
|
||||||
if (_object) |
|
||||||
{ |
|
||||||
// Cast to IInspectable (no QI)
|
|
||||||
IUnknown* pObject = *(IUnknown**)(&_object); |
|
||||||
// Set * to null without release
|
|
||||||
*(IUnknown**)(&_object) = nullptr; |
|
||||||
|
|
||||||
ULONG_PTR currentContextToken; |
|
||||||
__abi_ThrowIfFailed(CoGetContextToken(¤tContextToken)); |
|
||||||
if (_contextToken == 0 || _contextCallback == nullptr || _contextToken == currentContextToken) |
|
||||||
{ |
|
||||||
pObject->Release(); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
Details::ReleaseInContext(pObject, _contextCallback.Get()); |
|
||||||
} |
|
||||||
_contextCallback = nullptr; |
|
||||||
_contextToken = 0; |
|
||||||
#if _MSC_VER >= 1800 |
|
||||||
_agileState = AgileState::Unknown; |
|
||||||
#endif |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool operator==(nullptr_t) const throw() |
|
||||||
{ |
|
||||||
return _object == nullptr; |
|
||||||
} |
|
||||||
|
|
||||||
bool operator==(const Agile& other) const throw() |
|
||||||
{ |
|
||||||
return _object == other._object && _contextToken == other._contextToken; |
|
||||||
} |
|
||||||
|
|
||||||
bool operator<(const Agile& other) const throw() |
|
||||||
{ |
|
||||||
if (reinterpret_cast<void*>(_object) < reinterpret_cast<void*>(other._object)) |
|
||||||
{ |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
return _object == other._object && _contextToken < other._contextToken; |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
template <typename T> |
|
||||||
class Agile<T, false> |
|
||||||
{ |
|
||||||
static_assert(__is_win_class(typename Details::AgileTypeHelper<T>::type) || __is_win_interface(typename Details::AgileTypeHelper<T>::type), "Agile can only be used with ref class or interface class types"); |
|
||||||
typename typedef Details::AgileTypeHelper<T>::agileMemberType TypeT; |
|
||||||
TypeT _object; |
|
||||||
|
|
||||||
public: |
|
||||||
Agile() throw() : _object(nullptr) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
Agile(nullptr_t) throw() : _object(nullptr) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
explicit Agile(TypeT object) throw() : _object(object) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
Agile(const Agile& object) throw() : _object(object._object) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
Agile(Agile&& object) throw() : _object(nullptr) |
|
||||||
{ |
|
||||||
Swap(object); |
|
||||||
} |
|
||||||
|
|
||||||
~Agile() throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
} |
|
||||||
|
|
||||||
TypeT Get() const |
|
||||||
{ |
|
||||||
return _object; |
|
||||||
} |
|
||||||
|
|
||||||
TypeT* GetAddressOf() throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
return &_object; |
|
||||||
} |
|
||||||
|
|
||||||
TypeT* GetAddressOfForInOut() throw() |
|
||||||
{ |
|
||||||
return &_object; |
|
||||||
} |
|
||||||
|
|
||||||
TypeT operator->() const throw() |
|
||||||
{ |
|
||||||
return Get(); |
|
||||||
} |
|
||||||
|
|
||||||
Agile& operator=(nullptr_t) throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
Agile& operator=(TypeT object) throw() |
|
||||||
{ |
|
||||||
if (_object != object) |
|
||||||
{ |
|
||||||
_object = object; |
|
||||||
} |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
Agile& operator=(Agile object) throw() |
|
||||||
{ |
|
||||||
object.Swap(*this); |
|
||||||
return *this; |
|
||||||
} |
|
||||||
|
|
||||||
#if _MSC_VER < 1800 |
|
||||||
Agile& operator=(IUnknown* lp) throw() |
|
||||||
{ |
|
||||||
Release(); |
|
||||||
// bump ref count
|
|
||||||
::Microsoft::WRL::ComPtr<IUnknown> spObject(lp); |
|
||||||
|
|
||||||
// put it into Platform Object
|
|
||||||
Platform::Object object; |
|
||||||
*(IUnknown**)(&object) = spObject.Detach(); |
|
||||||
|
|
||||||
_object = object; |
|
||||||
return *this; |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
// Release the interface and set to NULL
|
|
||||||
void Release() throw() |
|
||||||
{ |
|
||||||
_object = nullptr; |
|
||||||
} |
|
||||||
|
|
||||||
void Swap(Agile& object) |
|
||||||
{ |
|
||||||
std::swap(_object, object._object); |
|
||||||
} |
|
||||||
|
|
||||||
bool operator==(nullptr_t) const throw() |
|
||||||
{ |
|
||||||
return _object == nullptr; |
|
||||||
} |
|
||||||
|
|
||||||
bool operator==(const Agile& other) const throw() |
|
||||||
{ |
|
||||||
return _object == other._object; |
|
||||||
} |
|
||||||
|
|
||||||
bool operator<(const Agile& other) const throw() |
|
||||||
{ |
|
||||||
return reinterpret_cast<void*>(_object) < reinterpret_cast<void*>(other._object); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
#pragma warning(pop) |
|
||||||
|
|
||||||
template<class U> |
|
||||||
bool operator==(nullptr_t, const Agile<U>& a) throw() |
|
||||||
{ |
|
||||||
return a == nullptr; |
|
||||||
} |
|
||||||
|
|
||||||
template<class U> |
|
||||||
bool operator!=(const Agile<U>& a, nullptr_t) throw() |
|
||||||
{ |
|
||||||
return !(a == nullptr); |
|
||||||
} |
|
||||||
|
|
||||||
template<class U> |
|
||||||
bool operator!=(nullptr_t, const Agile<U>& a) throw() |
|
||||||
{ |
|
||||||
return !(a == nullptr); |
|
||||||
} |
|
||||||
|
|
||||||
template<class U> |
|
||||||
bool operator!=(const Agile<U>& a, const Agile<U>& b) throw() |
|
||||||
{ |
|
||||||
return !(a == b); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
#endif // _PLATFORM_AGILE_H_
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,438 @@ |
|||||||
|
#include "precomp.hpp" |
||||||
|
|
||||||
|
#if defined WINRT && !defined WINRT_8_0 |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <assert.h> |
||||||
|
|
||||||
|
struct CvWindow; |
||||||
|
|
||||||
|
typedef struct CvTrackbar |
||||||
|
{ |
||||||
|
int signature; |
||||||
|
void* hwnd; // TODO: use proper handle type
|
||||||
|
char* name; |
||||||
|
CvTrackbar* next; |
||||||
|
CvWindow* parent; |
||||||
|
int* data; |
||||||
|
int pos; |
||||||
|
int maxval; |
||||||
|
void (*notify)(int); |
||||||
|
void (*notify2)(int, void*); |
||||||
|
void* userdata; |
||||||
|
int id; |
||||||
|
} |
||||||
|
CvTrackbar; |
||||||
|
|
||||||
|
|
||||||
|
typedef struct CvWindow |
||||||
|
{ |
||||||
|
int signature; |
||||||
|
void* hwnd; // TODO: use proper handle type
|
||||||
|
char* name; |
||||||
|
CvWindow* prev; |
||||||
|
CvWindow* next; |
||||||
|
|
||||||
|
HGDIOBJ image; |
||||||
|
int flags; |
||||||
|
|
||||||
|
CvMouseCallback on_mouse; |
||||||
|
void* on_mouse_param; |
||||||
|
|
||||||
|
struct
|
||||||
|
{ |
||||||
|
void* toolbar; // TODO: use proper handle type
|
||||||
|
int pos; |
||||||
|
int rows; |
||||||
|
CvTrackbar* first; |
||||||
|
} |
||||||
|
toolbar; |
||||||
|
|
||||||
|
int width; |
||||||
|
int height; |
||||||
|
} |
||||||
|
CvWindow; |
||||||
|
|
||||||
|
static CvWindow* hg_windows = 0; |
||||||
|
|
||||||
|
// typedef int (CV_CDECL * CvWin32WindowCallback)(HWND, UINT, WPARAM, LPARAM, int*);
|
||||||
|
|
||||||
|
static CvWindow* icvFindWindowByName(const char* name) { |
||||||
|
CvWindow* window = hg_windows; |
||||||
|
|
||||||
|
for (; window != 0 && strcmp(name, window->name) != 0; window = window->next) |
||||||
|
; |
||||||
|
|
||||||
|
return window; |
||||||
|
} |
||||||
|
|
||||||
|
static CvTrackbar* |
||||||
|
icvFindTrackbarByName(const CvWindow* window, const char* name) { |
||||||
|
CvTrackbar* trackbar = window->toolbar.first; |
||||||
|
|
||||||
|
for (; trackbar != 0 && strcmp(trackbar->name, name) != 0; trackbar = trackbar->next) |
||||||
|
; |
||||||
|
|
||||||
|
return trackbar; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL int cvInitSystem( int, char** ) |
||||||
|
{ |
||||||
|
static int wasInitialized = 0; |
||||||
|
|
||||||
|
if (!wasInitialized) |
||||||
|
{ |
||||||
|
hg_windows = 0; |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL int cvStartWindowThread(){ |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL int cvNamedWindow( const char* name, int flags ) |
||||||
|
{ |
||||||
|
int result = 0; |
||||||
|
CV_FUNCNAME( "cvNamedWindow" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
__END__; |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL void cvDestroyWindow( const char* name ) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvDestroyWindow" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
|
||||||
|
if(!name) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL name string" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName(name); |
||||||
|
if( !window ) |
||||||
|
EXIT; |
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL void cvShowImage( const char* name, const CvArr* arr ) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvShowImage" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
SIZE size = { 0, 0 }; |
||||||
|
int channels = 0; |
||||||
|
void* dst_ptr = 0; |
||||||
|
const int channels_def = 3; |
||||||
|
int origin = 0; |
||||||
|
CvMat stub, dst, *image; |
||||||
|
bool changed_size = false; |
||||||
|
|
||||||
|
if( !name ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName(name); |
||||||
|
if(!window) |
||||||
|
{ |
||||||
|
cvNamedWindow(name, CV_WINDOW_AUTOSIZE); |
||||||
|
window = icvFindWindowByName(name); |
||||||
|
} |
||||||
|
|
||||||
|
if( !window || !arr ) |
||||||
|
EXIT; |
||||||
|
|
||||||
|
if( CV_IS_IMAGE_HDR( arr )) |
||||||
|
origin = ((IplImage*)arr)->origin; |
||||||
|
|
||||||
|
CV_CALL( image = cvGetMat( arr, &stub )); |
||||||
|
|
||||||
|
#ifdef HAVE_OPENGL |
||||||
|
if (window->useGl) |
||||||
|
{ |
||||||
|
cv::imshow(name, cv::cvarrToMat(image)); |
||||||
|
return; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
if (window->image) |
||||||
|
{ |
||||||
|
//TODO: validate image
|
||||||
|
} |
||||||
|
|
||||||
|
if (size.cx != image->width || size.cy != image->height || channels != channels_def) |
||||||
|
{ |
||||||
|
changed_size = true; |
||||||
|
|
||||||
|
//TODO: handle image resize
|
||||||
|
} |
||||||
|
|
||||||
|
cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3, |
||||||
|
dst_ptr, (size.cx * channels + 3) & -4 ); |
||||||
|
cvConvertImage( image, &dst, origin == 0 ? CV_CVTIMG_FLIP : 0 ); |
||||||
|
|
||||||
|
if (changed_size) |
||||||
|
//TODO: handle consequent image resize
|
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL void cvResizeWindow(const char* name, int width, int height ) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvResizeWindow" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
|
||||||
|
if( !name ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName(name); |
||||||
|
if(!window) |
||||||
|
EXIT; |
||||||
|
|
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL void cvMoveWindow( const char* name, int x, int y ) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvMoveWindow" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
RECT rect; |
||||||
|
|
||||||
|
if( !name ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName(name); |
||||||
|
if(!window) |
||||||
|
EXIT; |
||||||
|
|
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL void cvDestroyAllWindows(void) |
||||||
|
{ |
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL int cvWaitKey( int delay ) |
||||||
|
{ |
||||||
|
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx
|
||||||
|
int time0 = GetTickCount64(); |
||||||
|
|
||||||
|
for(;;) |
||||||
|
{ |
||||||
|
CvWindow* window; |
||||||
|
|
||||||
|
if ((delay > 0 && abs((int)(GetTickCount64() - time0)) >= delay) || hg_windows == 0) |
||||||
|
return -1; |
||||||
|
|
||||||
|
if (delay <= 0) |
||||||
|
{ |
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
} |
||||||
|
|
||||||
|
for( window = hg_windows; window != 0; window = window->next ) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL int |
||||||
|
cvCreateTrackbar( const char* trackbar_name, const char* window_name, |
||||||
|
int* val, int count, CvTrackbarCallback on_notify ) |
||||||
|
{ |
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL int |
||||||
|
cvCreateTrackbar2( const char* trackbar_name, const char* window_name, |
||||||
|
int* val, int count, CvTrackbarCallback2 on_notify2, |
||||||
|
void* userdata ) |
||||||
|
{ |
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
CV_IMPL void |
||||||
|
cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvSetMouseCallback" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window = 0; |
||||||
|
|
||||||
|
if( !window_name ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL window name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName(window_name); |
||||||
|
if( !window ) |
||||||
|
EXIT; |
||||||
|
|
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) |
||||||
|
{ |
||||||
|
int pos = -1; |
||||||
|
|
||||||
|
CV_FUNCNAME( "cvGetTrackbarPos" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
CvTrackbar* trackbar = 0; |
||||||
|
|
||||||
|
if( trackbar_name == 0 || window_name == 0 ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName( window_name ); |
||||||
|
if( window ) |
||||||
|
trackbar = icvFindTrackbarByName( window, trackbar_name ); |
||||||
|
|
||||||
|
if( trackbar ) |
||||||
|
pos = trackbar->pos; |
||||||
|
|
||||||
|
__END__; |
||||||
|
|
||||||
|
return pos; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvSetTrackbarPos" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
CvTrackbar* trackbar = 0; |
||||||
|
|
||||||
|
if( trackbar_name == 0 || window_name == 0 ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName( window_name ); |
||||||
|
if( window ) |
||||||
|
trackbar = icvFindTrackbarByName( window, trackbar_name ); |
||||||
|
|
||||||
|
if( trackbar ) |
||||||
|
{ |
||||||
|
if( pos < 0 ) |
||||||
|
pos = 0; |
||||||
|
|
||||||
|
if( pos > trackbar->maxval ) |
||||||
|
pos = trackbar->maxval; |
||||||
|
|
||||||
|
//TODO: update trackbar
|
||||||
|
} |
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval) |
||||||
|
{ |
||||||
|
CV_FUNCNAME( "cvSetTrackbarMax" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
if (maxval >= 0) |
||||||
|
{ |
||||||
|
CvWindow* window = 0; |
||||||
|
CvTrackbar* trackbar = 0; |
||||||
|
if (trackbar_name == 0 || window_name == 0) |
||||||
|
{ |
||||||
|
CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); |
||||||
|
} |
||||||
|
|
||||||
|
window = icvFindWindowByName(window_name); |
||||||
|
if (window) |
||||||
|
{ |
||||||
|
trackbar = icvFindTrackbarByName(window, trackbar_name); |
||||||
|
if (trackbar) |
||||||
|
{ |
||||||
|
// The position will be min(pos, maxval).
|
||||||
|
trackbar->maxval = maxval; |
||||||
|
|
||||||
|
//TODO: update trackbar
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
__END__; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL void* cvGetWindowHandle( const char* window_name ) |
||||||
|
{ |
||||||
|
void* hwnd = 0; |
||||||
|
|
||||||
|
CV_FUNCNAME( "cvGetWindowHandle" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window; |
||||||
|
|
||||||
|
if( window_name == 0 ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL window name" ); |
||||||
|
|
||||||
|
window = icvFindWindowByName( window_name ); |
||||||
|
if( window ) |
||||||
|
hwnd = (void*)window->hwnd; |
||||||
|
|
||||||
|
__END__; |
||||||
|
|
||||||
|
return hwnd; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
CV_IMPL const char* cvGetWindowName( void* window_handle ) |
||||||
|
{ |
||||||
|
const char* window_name = ""; |
||||||
|
|
||||||
|
CV_FUNCNAME( "cvGetWindowName" ); |
||||||
|
|
||||||
|
__BEGIN__; |
||||||
|
|
||||||
|
CvWindow* window = 0; |
||||||
|
|
||||||
|
if( window_handle == 0 ) |
||||||
|
CV_ERROR( CV_StsNullPtr, "NULL window" ); |
||||||
|
|
||||||
|
// window = TODO: find window by handle
|
||||||
|
if( window ) |
||||||
|
window_name = window->name; |
||||||
|
|
||||||
|
__END__; |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
#endif //defined WINRT && !defined WINRT_8_0
|
Loading…
Reference in new issue