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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont
//============================================================
//
// osdlib.h
//
// SDLMAME by Olivier Galibert and R. Belmont
//
// - Common low level routines
// - Source files also provide the following from osdcore.h
//
// - osd_ticks
// - osd_sleep
//============================================================
#ifndef __OSDLIB__
#define __OSDLIB__
#include <string>
#include <type_traits>
#include <vector>
#include <memory>
/*-----------------------------------------------------------------------------
osd_process_kill: kill the current process
Parameters:
None.
Return value:
None.
-----------------------------------------------------------------------------*/
void osd_process_kill(void);
/*-----------------------------------------------------------------------------
osd_setenv: set environment variable
Parameters:
name - name of environment variable
value - value to write
overwrite - overwrite if it exists
Return value:
0 on success
-----------------------------------------------------------------------------*/
int osd_setenv(const char *name, const char *value, int overwrite);
/*-----------------------------------------------------------------------------
osd_get_clipboard_text: retrieves text from the clipboard
Return value:
the returned string needs to be free-ed!
-----------------------------------------------------------------------------*/
char *osd_get_clipboard_text(void);
/*-----------------------------------------------------------------------------
dynamic_module: load functions from optional shared libraries
Notes:
- Supports Mac OS X, Unix and Windows (both desktop and Windows
Store universal applications)
- A symbol can be searched in a list of libraries (e.g. more
revisions of a same library)
-----------------------------------------------------------------------------*/
namespace osd {
class dynamic_module
{
public:
typedef std::unique_ptr<dynamic_module> ptr;
static ptr open(std::vector<std::string> &&libraries);
virtual ~dynamic_module() { };
template <typename T>
typename std::enable_if<std::is_pointer<T>::value, T>::type bind(char const *symbol)
{
return reinterpret_cast<T>(get_symbol_address(symbol));
}
protected:
typedef void (*generic_fptr_t)();
virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
};
} // namespace osd
//=========================================================================================================================
// Dynamic API helpers. Useful in creating a singleton object that can be called with DYNAMIC_CALL macro for an entire API
// Usage for defining an API is below
//
// DYNAMIC_API_BEGIN(dxgi, "dxgi.dll")
// DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**)
// DYNAMIC_API_END(dxgi)
//
// Calling then looks like: DYNAMIC_CALL(dxgi, CreateDXGIFactory1, p1, p2, etc)
//=========================================================================================================================
#if !defined(OSD_UWP)
#define DYNAMIC_API_BEGIN(apiname, ...) namespace osd { namespace dynamicapi { \
class apiname##_api { \
private: \
osd::dynamic_module::ptr m_module = osd::dynamic_module::open( { __VA_ARGS__ } ); \
static std::unique_ptr<apiname##_api> s_instance; \
static std::once_flag s_once; \
public: \
static apiname##_api &instance() { \
std::call_once( apiname##_api::s_once, [](std::unique_ptr<apiname##_api> &inst) { \
inst = std::make_unique<apiname##_api>(); }, std::ref(s_instance)); \
return *apiname##_api::s_instance.get(); }
#define DYNAMIC_API_FN(ret, conv, apifunc, ...) ret(conv *m_##apifunc##_pfn)( __VA_ARGS__ ) = m_module->bind<ret(conv *)( __VA_ARGS__ )>(#apifunc);
#define DYNAMIC_API_END(apiname) }; \
std::once_flag apiname##_api::s_once; \
std::unique_ptr<apiname##_api> apiname##_api::s_instance = nullptr; }}
#define DYNAMIC_CALL(apiname, fname, ...) (*osd::dynamicapi::apiname##_api::instance().m_##fname##_pfn) ( __VA_ARGS__ )
#define DYNAMIC_API_TEST(apiname, fname) (osd::dynamicapi::apiname##_api::instance().m_##fname##_pfn != nullptr)
#else
#define DYNAMIC_API_BEGIN(apiname, ...)
#define DYNAMIC_API_FN(ret, conv, apifunc, ...)
#define DYNAMIC_API_END(apiname)
#define DYNAMIC_CALL(apiname, fname, ...) fname( __VA_ARGS__ )
#define DYNAMIC_API_TEST(apiname, fname) (true)
#endif
#endif /* __OSDLIB__ */
|