mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
Camera (Windows): init support
This commit is contained in:
+3
-1
@@ -662,7 +662,7 @@ elseif(WIN32)
|
||||
src/detection/wm/wm_windows.cpp
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/detection/camera/camera_windows.c
|
||||
src/detection/camera/camera_windows.cpp
|
||||
src/util/windows/getline.c
|
||||
src/util/windows/com.cpp
|
||||
src/util/windows/registry.c
|
||||
@@ -944,6 +944,8 @@ elseif(WIN32)
|
||||
PRIVATE "dwmapi"
|
||||
PRIVATE "gdi32"
|
||||
PRIVATE "iphlpapi"
|
||||
PRIVATE "mf"
|
||||
PRIVATE "mfplat"
|
||||
PRIVATE "ole32"
|
||||
PRIVATE "oleaut32"
|
||||
PRIVATE "ws2_32"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "camera.h"
|
||||
|
||||
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
extern "C" {
|
||||
#include "camera.h"
|
||||
#include "common/library.h"
|
||||
}
|
||||
#include "util/windows/com.hpp"
|
||||
#include "util/windows/unicode.hpp"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
|
||||
template <typename Fn>
|
||||
struct on_scope_exit {
|
||||
on_scope_exit(Fn &&fn): _fn(std::move(fn)) {}
|
||||
~on_scope_exit() { this->_fn(); }
|
||||
|
||||
private:
|
||||
Fn _fn;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
// TODO: check if supported by Windows Server Core
|
||||
|
||||
const char* error = ffInitCom();
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
IMFAttributes* FF_AUTO_RELEASE_COM_OBJECT attrs = nullptr;
|
||||
if (FAILED(MFCreateAttributes(&attrs, 1)))
|
||||
return "MFCreateAttributes() failed";
|
||||
|
||||
if (FAILED(attrs->SetGUID(
|
||||
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
||||
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
|
||||
)))
|
||||
return "SetGUID(MF_*) failed";
|
||||
|
||||
IMFActivate** devices = NULL;
|
||||
uint32_t count;
|
||||
|
||||
if (FAILED(MFEnumDeviceSources(attrs, &devices, &count)))
|
||||
return "MFEnumDeviceSources() failed";
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
IMFActivate* device = devices[i];
|
||||
|
||||
wchar_t buffer[256];
|
||||
uint32_t length = 0;
|
||||
if (FAILED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buffer, sizeof(buffer), &length)) || length == 0)
|
||||
continue;
|
||||
|
||||
FFCameraResult* camera = (FFCameraResult*) ffListAdd(result);
|
||||
ffStrbufInitNWS(&camera->name, length, buffer);
|
||||
ffStrbufInit(&camera->vendor);
|
||||
ffStrbufInit(&camera->id);
|
||||
camera->width = 0;
|
||||
camera->height = 0;
|
||||
|
||||
if (SUCCEEDED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buffer, sizeof(buffer), &length)) && length > 0)
|
||||
ffStrbufSetNWS(&camera->id, length, buffer);
|
||||
|
||||
IMFMediaSource* FF_AUTO_RELEASE_COM_OBJECT source = nullptr;
|
||||
if (FAILED(device->ActivateObject(IID_PPV_ARGS(&source))))
|
||||
continue;
|
||||
|
||||
on_scope_exit destroySource([&] { source->Shutdown(); });
|
||||
|
||||
IMFPresentationDescriptor* FF_AUTO_RELEASE_COM_OBJECT pd = nullptr;
|
||||
if (FAILED(source->CreatePresentationDescriptor(&pd)))
|
||||
continue;
|
||||
|
||||
IMFStreamDescriptor* FF_AUTO_RELEASE_COM_OBJECT sd = NULL;
|
||||
BOOL selected;
|
||||
if (FAILED(pd->GetStreamDescriptorByIndex(0, &selected, &sd)))
|
||||
continue;
|
||||
|
||||
IMFMediaTypeHandler* FF_AUTO_RELEASE_COM_OBJECT handler = NULL;
|
||||
if (FAILED(sd->GetMediaTypeHandler(&handler)))
|
||||
continue;
|
||||
|
||||
// Assume first type is the maximum resolution
|
||||
IMFMediaType* FF_AUTO_RELEASE_COM_OBJECT type = NULL;
|
||||
if (FAILED(handler->GetMediaTypeByIndex(0, &type)))
|
||||
continue;
|
||||
|
||||
MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &camera->width, &camera->height);
|
||||
}
|
||||
|
||||
CoTaskMemFree(devices);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1,16 +1,12 @@
|
||||
#include <oaidl.h>
|
||||
#include <propidl.h>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <string_view>
|
||||
|
||||
struct FFWmiVariant: VARIANT
|
||||
template <typename TVariant>
|
||||
struct FFBaseVariant: TVariant
|
||||
{
|
||||
explicit FFWmiVariant() { VariantInit(this); }
|
||||
~FFWmiVariant() { VariantClear(this); }
|
||||
|
||||
FFWmiVariant(const FFWmiVariant&) = delete;
|
||||
FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization
|
||||
|
||||
bool hasValue() {
|
||||
return this->vt != VT_EMPTY;
|
||||
}
|
||||
@@ -33,11 +29,11 @@ struct FFWmiVariant: VARIANT
|
||||
return this->cVal;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int16_t>) {
|
||||
assert(vt == VT_I2);
|
||||
assert(this->vt == VT_I2);
|
||||
return this->iVal;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int32_t>) {
|
||||
assert(this->vt == VT_I4 || vt == VT_INT);
|
||||
assert(this->vt == VT_I4 || this->vt == VT_INT);
|
||||
return this->intVal;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int64_t>) {
|
||||
@@ -55,7 +51,7 @@ struct FFWmiVariant: VARIANT
|
||||
return this->uiVal;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, uint32_t>) {
|
||||
assert(this->vt == VT_UI4 || vt == VT_UINT);
|
||||
assert(this->vt == VT_UI4 || this->vt == VT_UINT);
|
||||
return this->uintVal;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, uint64_t>) {
|
||||
@@ -135,3 +131,21 @@ struct FFWmiVariant: VARIANT
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct FFWmiVariant: FFBaseVariant<VARIANT>
|
||||
{
|
||||
FFWmiVariant(const FFWmiVariant&) = delete;
|
||||
FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization
|
||||
explicit FFWmiVariant() { VariantInit(this); }
|
||||
~FFWmiVariant() { VariantClear(this); }
|
||||
};
|
||||
static_assert(sizeof(FFWmiVariant) == sizeof(VARIANT), "");
|
||||
|
||||
struct FFPropVariant: FFBaseVariant<PROPVARIANT>
|
||||
{
|
||||
FFPropVariant(const FFPropVariant&) = delete;
|
||||
FFPropVariant(FFPropVariant&&); // don't define it to enforce NRVO optimization
|
||||
explicit FFPropVariant() { PropVariantInit(this); }
|
||||
~FFPropVariant() { PropVariantClear(this); }
|
||||
};
|
||||
static_assert(sizeof(FFPropVariant) == sizeof(PROPVARIANT), "");
|
||||
|
||||
Reference in New Issue
Block a user