Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/windows/include/display_device/windows/settings_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace display_device::win_utils {
* const auto extended_topology { stripTopologyOfUnavailableDevices(*iface) };
* @examples_end
*/
ActiveTopology createFullExtendedTopology(WinDisplayDeviceInterface &win_dd);
ActiveTopology createFullExtendedTopology(const WinDisplayDeviceInterface &win_dd);

/**
* @brief Get one primary device from the provided topology.
Expand All @@ -49,7 +49,7 @@ namespace display_device::win_utils {
* const auto primary_device_id { getPrimaryDevice(*iface, topology) };
* @examples_end
*/
std::string getPrimaryDevice(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);
std::string getPrimaryDevice(const WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology);

/**
* @brief Compute the new intial state from arbitrary data.
Expand Down
5 changes: 4 additions & 1 deletion src/windows/include/display_device/windows/win_api_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/
#pragma once

// system includes
#include <string_view>

// local includes
#include "win_api_layer_interface.h"

Expand Down Expand Up @@ -44,6 +47,6 @@ namespace display_device {
[[nodiscard]] bool setHdrState(const DISPLAYCONFIG_PATH_INFO &path, HdrState state) override;

/** For details @see WinApiLayerInterface::getDisplayScale */
[[nodiscard]] std::optional<Rational> getDisplayScale(const std::string &display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const override;
[[nodiscard]] std::optional<Rational> getDisplayScale(std::string_view display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const override;
};
} // namespace display_device
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/
#pragma once

// system includes
#include <string_view>

// local includes
#include "types.h"

Expand Down Expand Up @@ -195,6 +198,6 @@ namespace display_device {
* const auto scale = iface->getDisplayScale(iface->getDisplayName(path), source_mode);
* @examples_end
*/
[[nodiscard]] virtual std::optional<Rational> getDisplayScale(const std::string &display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const = 0;
[[nodiscard]] virtual std::optional<Rational> getDisplayScale(std::string_view display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const = 0;
};
} // namespace display_device
8 changes: 2 additions & 6 deletions src/windows/include/display_device/windows/win_api_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

// system includes
#include <set>
#include <string_view>

// local includes
#include "win_api_layer_interface.h"
Expand Down Expand Up @@ -202,12 +203,7 @@ namespace display_device::win_utils {
* const DISPLAYCONFIG_PATH_INFO* active_path = get_active_path(*iface, "MY_DEVICE_ID", paths);
* @examples_end
*/
[[nodiscard]] const DISPLAYCONFIG_PATH_INFO *getActivePath(const WinApiLayerInterface &w_api, const std::string &device_id, const std::vector<DISPLAYCONFIG_PATH_INFO> &paths);

/**
* @see getActivePath (const version) for the description.
*/
[[nodiscard]] DISPLAYCONFIG_PATH_INFO *getActivePath(const WinApiLayerInterface &w_api, const std::string &device_id, std::vector<DISPLAYCONFIG_PATH_INFO> &paths);
[[nodiscard]] const DISPLAYCONFIG_PATH_INFO *getActivePath(const WinApiLayerInterface &w_api, std::string_view device_id, const std::vector<DISPLAYCONFIG_PATH_INFO> &paths);

/**
* @brief Collect arbitrary source data from provided paths.
Expand Down
1 change: 1 addition & 0 deletions src/windows/settings_manager_apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace display_device {
* @brief Function that does nothing.
*/
void noopFn() {
// Intentionally empty guard callback.
}
} // namespace

Expand Down
1 change: 1 addition & 0 deletions src/windows/settings_manager_revert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace display_device {
* @brief Function that does nothing.
*/
void noopFn() {
// Intentionally empty guard callback.
}
} // namespace

Expand Down
4 changes: 2 additions & 2 deletions src/windows/settings_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ namespace display_device::win_utils {
return flattened_topology;
}

ActiveTopology createFullExtendedTopology(WinDisplayDeviceInterface &win_dd) {
ActiveTopology createFullExtendedTopology(const WinDisplayDeviceInterface &win_dd) {
const auto devices {win_dd.enumAvailableDevices()};
if (devices.empty()) {
DD_LOG(error) << "Failed to enumerate available devices for full extended topology!";
Expand All @@ -152,7 +152,7 @@ namespace display_device::win_utils {
return topology;
}

std::string getPrimaryDevice(WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
std::string getPrimaryDevice(const WinDisplayDeviceInterface &win_dd, const ActiveTopology &topology) {
const auto flat_topology {flattenTopology(topology)};
for (const auto &device_id : flat_topology) {
if (win_dd.isPrimary(device_id)) {
Expand Down
9 changes: 5 additions & 4 deletions src/windows/win_api_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <cmath>
#include <cstdint>
#include <iomanip>
#include <string_view>

// local includes
#include "display_device/logging.h"
Expand Down Expand Up @@ -310,7 +311,7 @@ namespace display_device {
* @param value The UTF-16 wide string.
* @return The converted UTF-8 string.
*/
std::string toUtf8(const WinApiLayerInterface &w_api, const std::wstring &value) {
std::string toUtf8(const WinApiLayerInterface &w_api, const std::wstring_view value) {
// No conversion needed if the string is empty
if (value.empty()) {
return {};
Expand Down Expand Up @@ -637,18 +638,18 @@ namespace display_device {
return true;
}

std::optional<Rational> WinApiLayer::getDisplayScale(const std::string &display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const {
std::optional<Rational> WinApiLayer::getDisplayScale(const std::string_view display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const {
// Note: implementation based on https://stackoverflow.com/a/74046173
struct EnumData {
std::string m_display_name;
std::string_view m_display_name;
std::optional<int> m_width;
};

EnumData enum_data {display_name, std::nullopt};
EnumDisplayMonitors(
nullptr,
nullptr,
[](HMONITOR monitor, HDC, LPRECT, LPARAM user_data) -> BOOL {
[](HMONITOR monitor, HDC, LPRECT, LPARAM user_data) {
auto *data = reinterpret_cast<EnumData *>(user_data);
if (data == nullptr) {
// Sanity check
Expand Down
6 changes: 1 addition & 5 deletions src/windows/win_api_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ namespace display_device::win_utils {
return ValidatedDeviceInfo {device_path, device_id};
}

const DISPLAYCONFIG_PATH_INFO *getActivePath(const WinApiLayerInterface &w_api, const std::string &device_id, const std::vector<DISPLAYCONFIG_PATH_INFO> &paths) {
const DISPLAYCONFIG_PATH_INFO *getActivePath(const WinApiLayerInterface &w_api, const std::string_view device_id, const std::vector<DISPLAYCONFIG_PATH_INFO> &paths) {
for (const auto &path : paths) {
const auto device_info {getDeviceInfoForValidPath(w_api, path, ValidatedPathType::Active)};
if (!device_info) {
Expand All @@ -219,10 +219,6 @@ namespace display_device::win_utils {
return nullptr;
}

DISPLAYCONFIG_PATH_INFO *getActivePath(const WinApiLayerInterface &w_api, const std::string &device_id, std::vector<DISPLAYCONFIG_PATH_INFO> &paths) {
return const_cast<DISPLAYCONFIG_PATH_INFO *>(getActivePath(w_api, device_id, const_cast<const std::vector<DISPLAYCONFIG_PATH_INFO> &>(paths)));
}

PathSourceIndexDataMap collectSourceDataForMatchingPaths(const WinApiLayerInterface &w_api, const std::vector<DISPLAYCONFIG_PATH_INFO> &paths) {
PathSourceIndexDataMap path_data;

Expand Down
15 changes: 8 additions & 7 deletions src/windows/win_display_device_modes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ namespace display_device {
return false;
}

const auto source_mode {win_utils::getSourceMode(win_utils::getSourceIndex(*path, display_data->m_modes), display_data->m_modes)};
auto &mutable_path {display_data->m_paths[static_cast<std::size_t>(path - display_data->m_paths.data())]};
const auto source_mode {win_utils::getSourceMode(win_utils::getSourceIndex(mutable_path, display_data->m_modes), display_data->m_modes)};
if (!source_mode) {
DD_LOG(error) << "Active device does not have a source mode: " << device_id << "!";
return false;
Expand All @@ -52,11 +53,11 @@ namespace display_device {

bool refresh_rate_changed;
if (strategy == Strategy::Relaxed) {
refresh_rate_changed = !win_utils::fuzzyCompareRefreshRates(Rational {path->targetInfo.refreshRate.Numerator, path->targetInfo.refreshRate.Denominator}, mode.m_refresh_rate);
refresh_rate_changed = !win_utils::fuzzyCompareRefreshRates(Rational {mutable_path.targetInfo.refreshRate.Numerator, mutable_path.targetInfo.refreshRate.Denominator}, mode.m_refresh_rate);
} else {
// Since we are in strict mode, do not fuzzy compare it
refresh_rate_changed = path->targetInfo.refreshRate.Numerator != mode.m_refresh_rate.m_numerator ||
path->targetInfo.refreshRate.Denominator != mode.m_refresh_rate.m_denominator;
refresh_rate_changed = mutable_path.targetInfo.refreshRate.Numerator != mode.m_refresh_rate.m_numerator ||
mutable_path.targetInfo.refreshRate.Denominator != mode.m_refresh_rate.m_denominator;
}

if (resolution_changed) {
Expand All @@ -66,14 +67,14 @@ namespace display_device {
}

if (refresh_rate_changed) {
path->targetInfo.refreshRate = {mode.m_refresh_rate.m_numerator, mode.m_refresh_rate.m_denominator};
mutable_path.targetInfo.refreshRate = {mode.m_refresh_rate.m_numerator, mode.m_refresh_rate.m_denominator};
new_changes = true;
}

if (new_changes) {
// Clear the target index so that Windows has to select/modify the target to best match the requirements.
win_utils::setTargetIndex(*path, std::nullopt);
win_utils::setDesktopIndex(*path, std::nullopt); // Part of struct containing target index and so it needs to be cleared
win_utils::setTargetIndex(mutable_path, std::nullopt);
win_utils::setDesktopIndex(mutable_path, std::nullopt); // Part of struct containing target index and so it needs to be cleared
}

changes_applied = changes_applied || new_changes;
Expand Down
4 changes: 1 addition & 3 deletions tests/unit/general/test_comparison.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
#include "display_device/types.h"
#include "fixtures/fixtures.h"

namespace {
// Specialized TEST macro(s) for this test file
// Specialized TEST macro(s) for this test file
#define TEST_S(...) DD_MAKE_TEST(TEST, TypeComparison, __VA_ARGS__)
} // namespace

TEST_S(Point) {
EXPECT_EQ(display_device::Point({1, 1}), display_device::Point({1, 1}));
Expand Down
4 changes: 1 addition & 3 deletions tests/unit/general/test_edid_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
#include "display_device/types.h"
#include "fixtures/fixtures.h"

namespace {
// Specialized TEST macro(s) for this test file
// Specialized TEST macro(s) for this test file
#define TEST_S(...) DD_MAKE_TEST(TEST, EdidParsing, __VA_ARGS__)
} // namespace

TEST_S(NoData) {
EXPECT_EQ(display_device::EdidData::parse({}), std::nullopt);
Expand Down
4 changes: 1 addition & 3 deletions tests/unit/general/test_json_converter.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// local includes
#include "fixtures/json_converter_test.h"

namespace {
// Specialized TEST macro(s) for this test file
// Specialized TEST macro(s) for this test file
#define TEST_F_S(...) DD_MAKE_TEST(TEST_F, JsonConverterTest, __VA_ARGS__)
} // namespace

TEST_F_S(EdidData) {
display_device::EdidData item {
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/general/test_logging.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// system includes
#include <exception>
#include <format>
#include <string_view>

// local includes
#include "display_device/logging.h"
Expand Down Expand Up @@ -106,7 +107,7 @@ TEST_S(DefaultLogger) {
using level = display_device::Logger::LogLevel;
auto &logger {display_device::Logger::get()};

const auto write_and_get_cout {[this, &logger](level level, std::string value) -> std::string {
const auto write_and_get_cout {[this, &logger](level level, std::string value) {
m_cout_buffer.str(std::string {}); // reset the buffer
logger.write(level, std::move(value));
return m_cout_buffer.str();
Expand All @@ -130,7 +131,7 @@ TEST_S(CustomCallback) {

std::string output;
logger.setLogLevel(level::verbose);
logger.setCustomCallback([&output](const level level, const std::string &value) {
logger.setCustomCallback([&output](const level level, const std::string_view value) {
output = std::format("{} {}", static_cast<level_t>(level), value);
});

Expand Down
48 changes: 29 additions & 19 deletions tests/unit/general/test_retry_scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <exception>
#include <gmock/gmock.h>
#include <stdexcept>
#include <string_view>
#include <type_traits>

// local includes
#include "display_device/retry_scheduler.h"
Expand Down Expand Up @@ -106,7 +108,7 @@ TEST_F_S(Schedule, SchedulingDurations) {
std::this_thread::sleep_for(1ms);
}

return m_impl.execute([](TestIface &iface) {
return m_impl.execute([](const TestIface &iface) {
int sum {0};
for (const auto timing : iface.m_durations) {
sum += timing;
Expand Down Expand Up @@ -299,8 +301,8 @@ TEST_F_S(Schedule, ExceptionThrown, DuringImmediateCall) {
}

std::string output;
logger.setCustomCallback([&output](auto, const std::string &value) {
output = value;
logger.setCustomCallback([&output](auto, const std::string_view value) {
output = std::string {value};
});

EXPECT_TRUE(m_impl.isScheduled());
Expand Down Expand Up @@ -329,8 +331,8 @@ TEST_F_S(Schedule, ExceptionThrown, DuringScheduledCall) {
auto &logger {display_device::Logger::get()};

std::string output;
logger.setCustomCallback([&output](auto, const std::string &value) {
output = value;
logger.setCustomCallback([&output](auto, const std::string_view value) {
output = std::string {value};
});

bool first_call {true};
Expand Down Expand Up @@ -530,7 +532,9 @@ TEST_F_S(Execute, ConstVsNonConst, WithoutStopToken) {
const auto const_callback_auto = [](const auto &iface) {
iface.constMethod();
};
const auto non_const_callback_auto = [](auto &iface) {
const auto non_const_callback_auto = []<class Iface>(Iface &iface)
requires(!std::is_const_v<Iface>)
{
iface.nonConstMethod();
};

Expand All @@ -541,12 +545,12 @@ TEST_F_S(Execute, ConstVsNonConst, WithoutStopToken) {
non_const_impl.execute(const_callback_auto);
non_const_impl.execute(non_const_callback_auto);

// Verify it compiles with const (commented out code will not compile)
// Verify it compiles with const
const auto &const_impl {m_impl};
const_impl.execute(const_callback);
// const_impl.execute(non_const_callback);
static_assert(!std::is_invocable_v<decltype(non_const_callback), const TestIface &>);
const_impl.execute(const_callback_auto);
// const_impl.execute(non_const_callback_auto);
static_assert(!std::is_invocable_v<decltype(non_const_callback_auto), const TestIface &>);
}

TEST_F_S(Execute, ConstVsNonConst, WithStopToken) {
Expand All @@ -570,15 +574,21 @@ TEST_F_S(Execute, ConstVsNonConst, WithStopToken) {
iface.constMethod();
(void) token.stopRequested();
};
const auto const_non_const_callback_auto = [](const auto &iface, auto &token) {
const auto const_non_const_callback_auto = []<class Iface, class Token>(const Iface &iface, Token &token)
requires(!std::is_const_v<Token>)
{
iface.constMethod();
token.requestStop();
};
const auto non_const_const_callback_auto = [](auto &iface, const auto &token) {
const auto non_const_const_callback_auto = []<class Iface, class Token>(Iface &iface, const Token &token)
requires(!std::is_const_v<Iface>)
{
iface.nonConstMethod();
(void) token.stopRequested();
};
const auto non_const_non_const_callback_auto = [](auto &iface, auto &token) {
const auto non_const_non_const_callback_auto = []<class Iface, class Token>(Iface &iface, Token &token)
requires(!std::is_const_v<Iface> && !std::is_const_v<Token>)
{
iface.nonConstMethod();
token.requestStop();
};
Expand All @@ -594,16 +604,16 @@ TEST_F_S(Execute, ConstVsNonConst, WithStopToken) {
non_const_impl.execute(non_const_const_callback_auto);
non_const_impl.execute(non_const_non_const_callback_auto);

// Verify it compiles with const (commented out code will not compile)
// Verify it compiles with const
const auto &const_impl {m_impl};
const_impl.execute(const_const_callback);
// const_impl.execute(const_non_const_callback);
// const_impl.execute(non_const_const_callback);
// const_impl.execute(non_const_non_const_callback);
static_assert(!std::is_invocable_v<decltype(const_non_const_callback), const TestIface &, const display_device::SchedulerStopToken &>);
static_assert(!std::is_invocable_v<decltype(non_const_const_callback), const TestIface &, const display_device::SchedulerStopToken &>);
static_assert(!std::is_invocable_v<decltype(non_const_non_const_callback), const TestIface &, const display_device::SchedulerStopToken &>);
const_impl.execute(const_const_callback_auto);
// const_impl.execute(const_non_const_callback_auto);
// const_impl.execute(non_const_const_callback_auto);
// const_impl.execute(non_const_non_const_callback_auto);
static_assert(!std::is_invocable_v<decltype(const_non_const_callback_auto), const TestIface &, const display_device::SchedulerStopToken &>);
static_assert(!std::is_invocable_v<decltype(non_const_const_callback_auto), const TestIface &, const display_device::SchedulerStopToken &>);
static_assert(!std::is_invocable_v<decltype(non_const_non_const_callback_auto), const TestIface &, const display_device::SchedulerStopToken &>);
}

TEST_F_S(Stop) {
Expand Down
Loading
Loading