summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/monitor/monitor_common.cpp
blob: 5a1a5fa8377beae8d048f9dd8f4c66ea133f1b44 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// license:BSD-3-Clause
// copyright-holders:Brad Hughes, Aaron Giles, Olivier Galibert, R. Belmont
/*
* monitor_common.cpp
*
*/

#include <algorithm>

#include "monitor_common.h"
#include "modules/osdwindow.h"

std::shared_ptr<osd_monitor_info> monitor_module_base::pick_monitor(osd_options& options, int index)
{
	// get the aspect ratio
	float aspect = get_aspect(options.aspect(), options.aspect(index), TRUE);

	auto monitor = pick_monitor_internal(options, index);
	if (aspect != 0)
	{
		monitor->set_aspect(aspect);
	}

	return monitor;
}

std::shared_ptr<osd_monitor_info> monitor_module_base::monitor_from_handle(std::uint64_t handle)
{
	if (!m_initialized)
		return nullptr;

	auto monitor = m_monitor_index[handle];

	// If we have been initialized, make sure we can find the monitor
	assert(monitor != nullptr);

	return monitor;
}

void monitor_module_base::add_monitor(std::shared_ptr<osd_monitor_info> monitor)
{
	list().push_back(monitor);
	m_monitor_index[monitor->oshandle()] = monitor;
}

std::shared_ptr<osd_monitor_info> monitor_module_base::pick_monitor_internal(osd_options& options, int index)
{
	std::string scrname, scrname2;

	// get the screen option
	scrname = options.screen();
	scrname2 = options.screen(index);

	// decide which one we want to use
	if (scrname2 != "auto")
		scrname = scrname2;

	// look for a match in the name first
	if (!scrname.empty())
	{
		auto mon = std::find_if(std::begin(list()), std::end(list()), [&scrname](auto m)
		{
			return m->devicename() == scrname;
		});

		if (mon != std::end(list()))
		{
			return *mon;
		}
	}

	// didn't find it; alternate monitors until we hit the jackpot
	// this allows for more screens than monitors but will put one on each monitor first
	index %= list().size();
	auto next_monitor = list()[index];
	return next_monitor;
}

float monitor_module_base::get_aspect(const char* defdata, const char* data, int report_error)
{
	int num = 0, den = 1;

	if (strcmp(data, OSDOPTVAL_AUTO) == 0)
	{
		if (strcmp(defdata, OSDOPTVAL_AUTO) == 0)
			return 0;
		data = defdata;
	}
	if (sscanf(data, "%d:%d", &num, &den) != 2 && report_error)
		osd_printf_error("Illegal aspect ratio value = %s\n", data);

	return float(num) / float(den);
}

int monitor_module_base::init(const osd_options& options)
{
	if (!m_initialized)
	{
		int result = init_internal(options);

		if (result == 0)
			m_initialized = true;

		return result;
	}

	return 0;
}

void monitor_module_base::exit()
{
	// free all of our monitor information
	list().clear();
	m_monitor_index.clear();
	m_initialized = false;
}