FreeRDP
Loading...
Searching...
No Matches
sdl_connection_dialog_wrapper.cpp
1
21#include <sstream>
22
23#include <freerdp/freerdp.h>
24#include <freerdp/settings.h>
25#include <freerdp/log.h>
26
27#include "../sdl_utils.hpp"
28#include "sdl_connection_dialog.hpp"
29#include "sdl_connection_dialog_wrapper.hpp"
30
34
35SdlConnectionDialogWrapper::~SdlConnectionDialogWrapper() = default;
36
37void SdlConnectionDialogWrapper::create(rdpContext* context)
38{
39 const auto enabled =
40 freerdp_settings_get_bool(context->settings, FreeRDP_UseCommonStdioCallbacks);
41 _connection_dialog.reset();
42 if (!enabled)
43 _connection_dialog = std::make_unique<SDLConnectionDialog>(context);
44}
45
46void SdlConnectionDialogWrapper::destroy()
47{
48 _connection_dialog.reset();
49}
50
51bool SdlConnectionDialogWrapper::isRunning() const
52{
53 std::unique_lock lock(_mux);
54 if (!_connection_dialog)
55 return false;
56 return _connection_dialog->running();
57}
58
59bool SdlConnectionDialogWrapper::isVisible() const
60{
61 std::unique_lock lock(_mux);
62 if (!_connection_dialog)
63 return false;
64 return _connection_dialog->visible();
65}
66
67bool SdlConnectionDialogWrapper::handleEvent(const SDL_Event& event)
68{
69 std::unique_lock lock(_mux);
70 if (!_connection_dialog)
71 return false;
72 return _connection_dialog->handle(event);
73}
74
75WINPR_ATTR_FORMAT_ARG(1, 0)
76static std::string format(WINPR_FORMAT_ARG const char* fmt, va_list ap)
77{
78 va_list ap1;
79 va_copy(ap1, ap);
80 const int size = vsnprintf(nullptr, 0, fmt, ap1);
81 va_end(ap1);
82
83 if (size < 0)
84 return "";
85
86 std::string msg;
87 msg.resize(static_cast<size_t>(size) + 1);
88
89 va_list ap2;
90 va_copy(ap2, ap);
91 (void)vsnprintf(msg.data(), msg.size(), fmt, ap2);
92 va_end(ap2);
93 return msg;
94}
95
96void SdlConnectionDialogWrapper::setTitle(const char* fmt, ...)
97{
98 va_list ap;
99 va_start(ap, fmt);
100 setTitle(format(fmt, ap));
101 va_end(ap);
102}
103
104void SdlConnectionDialogWrapper::setTitle(const std::string& title)
105{
106 push(EventArg{ title });
107}
108
109void SdlConnectionDialogWrapper::showInfo(const char* fmt, ...)
110{
111 va_list ap;
112 va_start(ap, fmt);
113 showInfo(format(fmt, ap));
114 va_end(ap);
115}
116
117void SdlConnectionDialogWrapper::showInfo(const std::string& info)
118{
119 show(MSG_INFO, info);
120}
121
122void SdlConnectionDialogWrapper::showWarn(const char* fmt, ...)
123{
124 va_list ap;
125 va_start(ap, fmt);
126 showWarn(format(fmt, ap));
127 va_end(ap);
128}
129
130void SdlConnectionDialogWrapper::showWarn(const std::string& info)
131{
132 show(MSG_WARN, info);
133}
134
135void SdlConnectionDialogWrapper::showError(const char* fmt, ...)
136{
137 va_list ap;
138 va_start(ap, fmt);
139 showError(format(fmt, ap));
140 va_end(ap);
141}
142
143void SdlConnectionDialogWrapper::showError(const std::string& error)
144{
145 show(MSG_ERROR, error);
146}
147
148void SdlConnectionDialogWrapper::show(SdlConnectionDialogWrapper::MsgType type,
149 const std::string& msg)
150{
151 push({ type, msg, true });
152}
153
154void SdlConnectionDialogWrapper::show(bool visible)
155{
156 push(EventArg{ visible });
157}
158
159void SdlConnectionDialogWrapper::handleShow()
160{
161 std::unique_lock lock(_mux);
162 while (!_queue.empty())
163 {
164 auto arg = _queue.front();
165 _queue.pop();
166
167 if (arg.hasTitle() && _connection_dialog)
168 {
169 _connection_dialog->setTitle(arg.title().c_str());
170 }
171
172 if (arg.hasType() && arg.hasMessage())
173 {
174 switch (arg.type())
175 {
176 case SdlConnectionDialogWrapper::MSG_INFO:
177 if (_connection_dialog)
178 _connection_dialog->showInfo(arg.message().c_str());
179 else
180 WLog_Print(_log, WLOG_INFO, "%s", arg.message().c_str());
181 break;
182 case SdlConnectionDialogWrapper::MSG_WARN:
183 if (_connection_dialog)
184 _connection_dialog->showWarn(arg.message().c_str());
185 else
186 WLog_Print(_log, WLOG_WARN, "%s", arg.message().c_str());
187 break;
188 case SdlConnectionDialogWrapper::MSG_ERROR:
189 if (_connection_dialog)
190 _connection_dialog->showError(arg.message().c_str());
191 else
192 WLog_Print(_log, WLOG_ERROR, "%s", arg.message().c_str());
193 break;
194 default:
195 break;
196 }
197 }
198
199 if (arg.hasVisibility() && _connection_dialog)
200 {
201 if (arg.visible())
202 _connection_dialog->show();
203 else
204 _connection_dialog->hide();
205 }
206 }
207}
208
209void SdlConnectionDialogWrapper::push(EventArg&& arg)
210{
211 {
212 std::unique_lock lock(_mux);
213 _queue.push(std::move(arg));
214 }
215
216 auto rc = SDL_RunOnMainThread(
217 [](void* user)
218 {
219 auto dlg = static_cast<SdlConnectionDialogWrapper*>(user);
220 dlg->handleShow();
221 },
222 this, false);
223 if (!rc)
224 SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "[%s] SDL_RunOnMainThread failed with %s",
225 __func__, SDL_GetError());
226}
227
228SdlConnectionDialogWrapper::EventArg::EventArg(bool visible) : _visible(visible), _mask(8)
229{
230}
231
232SdlConnectionDialogWrapper::EventArg::EventArg(const std::string& title) : _title(title), _mask(1)
233{
234}
235
236SdlConnectionDialogWrapper::EventArg::EventArg(MsgType type, const std::string& msg, bool visible)
237 : _message(msg), _type(type), _visible(visible), _mask(14)
238{
239}
240
241bool SdlConnectionDialogWrapper::EventArg::hasTitle() const
242{
243 return _mask & 0x01;
244}
245
246const std::string& SdlConnectionDialogWrapper::EventArg::title() const
247{
248 return _title;
249}
250
251bool SdlConnectionDialogWrapper::EventArg::hasMessage() const
252{
253 return _mask & 0x02;
254}
255
256const std::string& SdlConnectionDialogWrapper::EventArg::message() const
257{
258 return _message;
259}
260
261bool SdlConnectionDialogWrapper::EventArg::hasType() const
262{
263 return _mask & 0x04;
264}
265
266SdlConnectionDialogWrapper::MsgType SdlConnectionDialogWrapper::EventArg::type() const
267{
268 return _type;
269}
270
271bool SdlConnectionDialogWrapper::EventArg::hasVisibility() const
272{
273 return _mask & 0x08;
274}
275
276bool SdlConnectionDialogWrapper::EventArg::visible() const
277{
278 return _visible;
279}
280
281std::string SdlConnectionDialogWrapper::EventArg::str() const
282{
283 std::stringstream ss;
284 ss << "{ title:" << _title << ", message:" << _message << ", type:" << _type
285 << ", visible:" << _visible << ", mask:" << _mask << "}";
286 return ss.str();
287}
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.