FreeRDP
Loading...
Searching...
No Matches
xf_utils.c
1
21#include <string.h>
22#include <winpr/assert.h>
23#include <winpr/wtypes.h>
24#include <winpr/path.h>
25
26#include "xf_utils.h"
27#include "xfreerdp.h"
28
29#include <freerdp/utils/helpers.h>
30#include <freerdp/log.h>
31
32#define TAG CLIENT_TAG("xfreerdp.utils")
33
34static const DWORD log_level = WLOG_TRACE;
35
36static const char* error_to_string(wLog* log, Display* display, int error, char* buffer,
37 size_t size)
38{
39 WINPR_ASSERT(size <= INT32_MAX);
40 const int rc = XGetErrorText(display, error, buffer, (int)size);
41 if (rc != Success)
42 WLog_Print(log, WLOG_WARN, "XGetErrorText returned %d", rc);
43 return buffer;
44}
45
46WINPR_ATTR_FORMAT_ARG(6, 7)
47static void write_log(wLog* log, DWORD level, const char* fname, const char* fkt, size_t line,
48 WINPR_FORMAT_ARG const char* fmt, ...)
49{
50 va_list ap = { 0 };
51 va_start(ap, fmt);
52 WLog_PrintTextMessageVA(log, level, line, fname, fkt, fmt, ap);
53 va_end(ap);
54}
55
56static BOOL ignore_code(int rc, size_t count, va_list ap)
57{
58 for (size_t x = 0; x < count; x++)
59 {
60 const int val = va_arg(ap, int);
61 if (rc == val)
62 return TRUE;
63 }
64 return FALSE;
65}
66
67/* libx11 return codes are not really well documented, so checked against
68 * https://gitlab.freedesktop.org/xorg/lib/libx11.git */
69static int write_result_log_va(wLog* log, DWORD level, const char* fname, const char* fkt,
70 size_t line, Display* display, char* name, int rc, size_t count,
71 va_list ap)
72{
73 const BOOL ignore = ignore_code(rc, count, ap);
74 if (!ignore)
75 {
76 char buffer[128] = { 0 };
77
78 if (WLog_IsLevelActive(log, level))
79 {
80 WLog_PrintTextMessage(log, level, line, fname, fkt, "%s returned %s", name,
81 error_to_string(log, display, rc, buffer, sizeof(buffer)));
82 }
83 }
84 return rc;
85}
86
87static int write_result_log_expect_success(wLog* log, DWORD level, const char* fname,
88 const char* fkt, size_t line, Display* display,
89 char* name, int rc)
90{
91 if (rc != Success)
92 {
93 va_list ap;
94 (void)write_result_log_va(log, level, fname, fkt, line, display, name, rc, 0, ap);
95 va_end(ap);
96 }
97 return rc;
98}
99
100static int write_result_log_expect_one(wLog* log, DWORD level, const char* fname, const char* fkt,
101 size_t line, Display* display, char* name, int rc)
102{
103 if (rc != 1)
104 {
105 va_list ap;
106 (void)write_result_log_va(log, level, fname, fkt, line, display, name, rc, 0, ap);
107 va_end(ap);
108 }
109 return rc;
110}
111
112char* Safe_XGetAtomNameEx(wLog* log, Display* display, Atom atom, const char* varname)
113{
114 WLog_Print(log, log_level, "XGetAtomName(%s, 0x%08lx)", varname, atom);
115 if (atom == None)
116 return strdup("Atom_None");
117 return XGetAtomName(display, atom);
118}
119
120Atom Logging_XInternAtom(wLog* log, Display* display, _Xconst char* atom_name, Bool only_if_exists)
121{
122 Atom atom = XInternAtom(display, atom_name, only_if_exists);
123 if (WLog_IsLevelActive(log, log_level))
124 {
125 WLog_Print(log, log_level, "XInternAtom(%p, %s, %s) -> 0x%08" PRIx32, (void*)display,
126 atom_name, only_if_exists ? "True" : "False",
127 WINPR_CXX_COMPAT_CAST(UINT32, atom));
128 }
129 return atom;
130}
131
132const char* x11_error_to_string(xfContext* xfc, int error, char* buffer, size_t size)
133{
134 WINPR_ASSERT(xfc);
135 return error_to_string(xfc->log, xfc->display, error, buffer, size);
136}
137
138int LogDynAndXChangeProperty_ex(wLog* log, const char* file, const char* fkt, size_t line,
139 Display* display, Window w, Atom property, Atom type, int format,
140 int mode, const unsigned char* data, int nelements)
141{
142 if (WLog_IsLevelActive(log, log_level))
143 {
144 char* propstr = Safe_XGetAtomName(log, display, property);
145 char* typestr = Safe_XGetAtomName(log, display, type);
146 write_log(log, log_level, file, fkt, line,
147 "XChangeProperty(%p, %lu, %s [%lu], %s [%lu], %d, %d, %p, %d)", (void*)display, w,
148 propstr, property, typestr, type, format, mode, (const void*)data, nelements);
149 XFree(propstr);
150 XFree(typestr);
151 }
152 const int rc = XChangeProperty(display, w, property, type, format, mode, data, nelements);
153 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XChangeProperty",
154 rc);
155}
156
157int LogDynAndXDeleteProperty_ex(wLog* log, const char* file, const char* fkt, size_t line,
158 Display* display, Window w, Atom property)
159{
160 if (WLog_IsLevelActive(log, log_level))
161 {
162 char* propstr = Safe_XGetAtomName(log, display, property);
163 write_log(log, log_level, file, fkt, line, "XDeleteProperty(%p, %lu, %s [%lu])",
164 (void*)display, w, propstr, property);
165 XFree(propstr);
166 }
167 const int rc = XDeleteProperty(display, w, property);
168 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XDeleteProperty",
169 rc);
170}
171
172int LogDynAndXConvertSelection_ex(wLog* log, const char* file, const char* fkt, size_t line,
173 Display* display, Atom selection, Atom target, Atom property,
174 Window requestor, Time time)
175{
176 if (WLog_IsLevelActive(log, log_level))
177 {
178 char* selectstr = Safe_XGetAtomName(log, display, selection);
179 char* targetstr = Safe_XGetAtomName(log, display, target);
180 char* propstr = Safe_XGetAtomName(log, display, property);
181 write_log(log, log_level, file, fkt, line,
182 "XConvertSelection(%p, %s [%lu], %s [%lu], %s [%lu], %lu, %lu)", (void*)display,
183 selectstr, selection, targetstr, target, propstr, property, requestor, time);
184 XFree(propstr);
185 XFree(targetstr);
186 XFree(selectstr);
187 }
188 const int rc = XConvertSelection(display, selection, target, property, requestor, time);
189 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display,
190 "XConvertSelection", rc);
191}
192
193int LogDynAndXGetWindowProperty_ex(wLog* log, const char* file, const char* fkt, size_t line,
194 Display* display, Window w, Atom property, long long_offset,
195 long long_length, int delete, Atom req_type,
196 Atom* actual_type_return, int* actual_format_return,
197 unsigned long* nitems_return, unsigned long* bytes_after_return,
198 unsigned char** prop_return)
199{
200 if (WLog_IsLevelActive(log, log_level))
201 {
202 char* propstr = Safe_XGetAtomName(log, display, property);
203 char* req_type_str = Safe_XGetAtomName(log, display, req_type);
204 write_log(
205 log, log_level, file, fkt, line,
206 "XGetWindowProperty(%p, %lu, %s [%lu], %ld, %ld, %d, %s [%lu], %p, %p, %p, %p, %p)",
207 (void*)display, w, propstr, property, long_offset, long_length, delete, req_type_str,
208 req_type, (void*)actual_type_return, (void*)actual_format_return, (void*)nitems_return,
209 (void*)bytes_after_return, (void*)prop_return);
210 XFree(propstr);
211 XFree(req_type_str);
212 }
213 const int rc = XGetWindowProperty(display, w, property, long_offset, long_length, delete,
214 req_type, actual_type_return, actual_format_return,
215 nitems_return, bytes_after_return, prop_return);
216 return write_result_log_expect_success(log, WLOG_WARN, file, fkt, line, display,
217 "XGetWindowProperty", rc);
218}
219
220BOOL IsGnome(void)
221{
222 // NOLINTNEXTLINE(concurrency-mt-unsafe)
223 char* env = getenv("DESKTOP_SESSION");
224 return (env != NULL && strcmp(env, "gnome") == 0);
225}
226
227BOOL run_action_script(xfContext* xfc, const char* what, const char* arg, fn_action_script_run fkt,
228 void* user)
229{
230 BOOL rc = FALSE;
231 FILE* keyScript = NULL;
232 WINPR_ASSERT(xfc);
233
234 rdpSettings* settings = xfc->common.context.settings;
235 WINPR_ASSERT(settings);
236
237 const char* ActionScript = freerdp_settings_get_string(settings, FreeRDP_ActionScript);
238
239 xfc->actionScriptExists = winpr_PathFileExists(ActionScript);
240
241 if (!xfc->actionScriptExists)
242 {
243 WLog_DBG(TAG, "[ActionScript] no such script '%s'", ActionScript);
244 goto fail;
245 }
246
247 char command[2048] = { 0 };
248 (void)sprintf_s(command, sizeof(command), "%s %s", ActionScript, what);
249 keyScript = popen(command, "r");
250
251 if (!keyScript)
252 {
253 WLog_ERR(TAG, "[ActionScript] Failed to execute '%s'", command);
254 goto fail;
255 }
256
257 BOOL read_data = FALSE;
258 char buffer[2048] = { 0 };
259 while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
260 {
261 char* context = NULL;
262 (void)strtok_s(buffer, "\n", &context);
263
264 if (fkt)
265 {
266 if (!fkt(xfc, buffer, strnlen(buffer, sizeof(buffer)), user, what, arg))
267 goto fail;
268 }
269 read_data = TRUE;
270 }
271
272 rc = read_data;
273 if (!rc)
274 WLog_ERR(TAG, "[ActionScript] No data returned from command '%s'", command);
275fail:
276 if (keyScript)
277 pclose(keyScript);
278 const BOOL res = rc || !xfc->actionScriptExists;
279 if (!rc)
280 xfc->actionScriptExists = FALSE;
281 return res;
282}
283
284int LogDynAndXCopyArea_ex(wLog* log, const char* file, const char* fkt, size_t line,
285 Display* display, Pixmap src, Window dest, GC gc, int src_x, int src_y,
286 unsigned int width, unsigned int height, int dest_x, int dest_y)
287{
288 if (WLog_IsLevelActive(log, log_level))
289 {
290 XWindowAttributes attr = { 0 };
291 const Status rc = XGetWindowAttributes(display, dest, &attr);
292
293 write_log(log, log_level, file, fkt, line,
294 "XCopyArea(%p, src: {%lu}, dest: [%d]{%lu, %lu, %d}, gc: {%p}, src_x: {%d}, "
295 "src_y: {%d}, "
296 "width: {%u}, "
297 "height: {%u}, dest_x: {%d}, dest_y: {%d})",
298 (void*)display, src, rc, dest, attr.root, attr.depth, (void*)gc, src_x, src_y,
299 width, height, dest_x, dest_y);
300 }
301
302 if ((width == 0) || (height == 0))
303 {
304 const DWORD lvl = WLOG_WARN;
305 if (WLog_IsLevelActive(log, lvl))
306 write_log(log, lvl, file, fkt, line, "XCopyArea(width=%u, height=%u) !", width, height);
307 return Success;
308 }
309
310 const int rc = XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
311 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XCopyArea", rc);
312}
313
314int LogDynAndXPutImage_ex(wLog* log, const char* file, const char* fkt, size_t line,
315 Display* display, Drawable d, GC gc, XImage* image, int src_x, int src_y,
316 int dest_x, int dest_y, unsigned int width, unsigned int height)
317{
318 if (WLog_IsLevelActive(log, log_level))
319 {
320 write_log(log, log_level, file, fkt, line,
321 "XPutImage(%p, d: {%lu}, gc: {%p}, image: [%p]{%d}, src_x: {%d}, src_y: {%d}, "
322 "dest_x: {%d}, "
323 "dest_y: {%d}, width: {%u}, "
324 "height: {%u})",
325 (void*)display, d, (void*)gc, (void*)image, image ? image->depth : -1, src_x,
326 src_y, dest_x, dest_y, width, height);
327 }
328
329 if ((width == 0) || (height == 0))
330 {
331 const DWORD lvl = WLOG_WARN;
332 if (WLog_IsLevelActive(log, lvl))
333 write_log(log, lvl, file, fkt, line, "XPutImage(width=%u, height=%u) !", width, height);
334 return Success;
335 }
336
337 const int rc = XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);
338 return write_result_log_expect_success(log, WLOG_WARN, file, fkt, line, display, "XPutImage",
339 rc);
340}
341
342/* be careful here.
343 * XSendEvent returns Status, but implementation always returns 1
344 */
345Status LogDynAndXSendEvent_ex(wLog* log, const char* file, const char* fkt, size_t line,
346 Display* display, Window w, int propagate, long event_mask,
347 XEvent* event_send)
348{
349 if (WLog_IsLevelActive(log, log_level))
350 {
351 write_log(log, log_level, file, fkt, line,
352 "XSendEvent(d: {%p}, w: {%lu}, propagate: {%d}, event_mask: {%ld}, "
353 "event_send: [%p]{TODO})",
354 (void*)display, w, propagate, event_mask, (void*)event_send);
355 }
356
357 const int rc = XSendEvent(display, w, propagate, event_mask, event_send);
358 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSendEvent", rc);
359}
360
361int LogDynAndXFlush_ex(wLog* log, const char* file, const char* fkt, size_t line, Display* display)
362{
363 if (WLog_IsLevelActive(log, log_level))
364 {
365 write_log(log, log_level, file, fkt, line, "XFlush(%p)", (void*)display);
366 }
367
368 const int rc = XFlush(display);
369 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XFlush", rc);
370}
371
372Window LogDynAndXGetSelectionOwner_ex(wLog* log, const char* file, const char* fkt, size_t line,
373 Display* display, Atom selection)
374{
375 if (WLog_IsLevelActive(log, log_level))
376 {
377 char* selectionstr = Safe_XGetAtomName(log, display, selection);
378 write_log(log, log_level, file, fkt, line, "XGetSelectionOwner(%p, %s)", (void*)display,
379 selectionstr);
380 XFree(selectionstr);
381 }
382 return XGetSelectionOwner(display, selection);
383}
384
385int LogDynAndXDestroyWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
386 Display* display, Window window)
387{
388 if (WLog_IsLevelActive(log, log_level))
389 {
390 write_log(log, log_level, file, fkt, line, "XDestroyWindow(%p, %lu)", (void*)display,
391 window);
392 }
393 const int rc = XDestroyWindow(display, window);
394 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XDestroyWindow",
395 rc);
396}
397
398int LogDynAndXSync_ex(wLog* log, const char* file, const char* fkt, size_t line, Display* display,
399 Bool discard)
400{
401 if (WLog_IsLevelActive(log, log_level))
402 {
403 write_log(log, log_level, file, fkt, line, "XSync(%p, %d)", (void*)display, discard);
404 }
405 const int rc = XSync(display, discard);
406 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSync", rc);
407}
408
409int LogDynAndXChangeWindowAttributes_ex(wLog* log, const char* file, const char* fkt, size_t line,
410 Display* display, Window window, unsigned long valuemask,
411 XSetWindowAttributes* attributes)
412{
413 if (WLog_IsLevelActive(log, log_level))
414 {
415 write_log(log, log_level, file, fkt, line, "XChangeWindowAttributes(%p, %lu, 0x%08lu, %p)",
416 (void*)display, window, valuemask, (void*)attributes);
417 }
418 const int rc = XChangeWindowAttributes(display, window, valuemask, attributes);
419 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display,
420 "XChangeWindowAttributes", rc);
421}
422
423int LogDynAndXSetTransientForHint_ex(wLog* log, const char* file, const char* fkt, size_t line,
424 Display* display, Window window, Window prop_window)
425{
426 if (WLog_IsLevelActive(log, log_level))
427 {
428 write_log(log, log_level, file, fkt, line, "XSetTransientForHint(%p, %lu, %lu)",
429 (void*)display, window, prop_window);
430 }
431 const int rc = XSetTransientForHint(display, window, prop_window);
432 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display,
433 "XSetTransientForHint", rc);
434}
435
436int LogDynAndXCloseDisplay_ex(wLog* log, const char* file, const char* fkt, size_t line,
437 Display* display)
438{
439 if (WLog_IsLevelActive(log, log_level))
440 {
441 write_log(log, log_level, file, fkt, line, "XCloseDisplay(%p)", (void*)display);
442 }
443 const int rc = XCloseDisplay(display);
444 return write_result_log_expect_success(log, WLOG_WARN, file, fkt, line, display,
445 "XCloseDisplay", rc);
446}
447
448XImage* LogDynAndXCreateImage_ex(wLog* log, const char* file, const char* fkt, size_t line,
449 Display* display, Visual* visual, unsigned int depth, int format,
450 int offset, char* data, unsigned int width, unsigned int height,
451 int bitmap_pad, int bytes_per_line)
452{
453 if (WLog_IsLevelActive(log, log_level))
454 {
455 write_log(log, log_level, file, fkt, line, "XCreateImage(%p)", (void*)display);
456 }
457 return XCreateImage(display, visual, depth, format, offset, data, width, height, bitmap_pad,
458 bytes_per_line);
459}
460
461Window LogDynAndXCreateWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
462 Display* display, Window parent, int x, int y, unsigned int width,
463 unsigned int height, unsigned int border_width, int depth,
464 unsigned int class, Visual* visual, unsigned long valuemask,
465 XSetWindowAttributes* attributes)
466{
467 if (WLog_IsLevelActive(log, log_level))
468 {
469 write_log(log, log_level, file, fkt, line, "XCreateWindow(%p)", (void*)display);
470 }
471 return XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual,
472 valuemask, attributes);
473}
474
475GC LogDynAndXCreateGC_ex(wLog* log, const char* file, const char* fkt, size_t line,
476 Display* display, Drawable d, unsigned long valuemask, XGCValues* values)
477{
478 if (WLog_IsLevelActive(log, log_level))
479 {
480 write_log(log, log_level, file, fkt, line, "XCreateGC(%p)", (void*)display);
481 }
482 return XCreateGC(display, d, valuemask, values);
483}
484
485int LogDynAndXFreeGC_ex(wLog* log, const char* file, const char* fkt, size_t line, Display* display,
486 GC gc)
487{
488 if (WLog_IsLevelActive(log, log_level))
489 {
490 write_log(log, log_level, file, fkt, line, "XFreeGC(%p)", (void*)display);
491 }
492 const int rc = XFreeGC(display, gc);
493 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XFreeGC", rc);
494}
495
496Pixmap LogDynAndXCreatePixmap_ex(wLog* log, const char* file, const char* fkt, size_t line,
497 Display* display, Drawable d, unsigned int width,
498 unsigned int height, unsigned int depth)
499{
500 if (WLog_IsLevelActive(log, log_level))
501 {
502 write_log(log, log_level, file, fkt, line, "XCreatePixmap(%p, 0x%08lu, %u, %u, %u)",
503 (void*)display, d, width, height, depth);
504 }
505 return XCreatePixmap(display, d, width, height, depth);
506}
507
508int LogDynAndXFreePixmap_ex(wLog* log, const char* file, const char* fkt, size_t line,
509 Display* display, Pixmap pixmap)
510{
511 if (WLog_IsLevelActive(log, log_level))
512 {
513 write_log(log, log_level, file, fkt, line, "XFreePixmap(%p)", (void*)display);
514 }
515 const int rc = XFreePixmap(display, pixmap);
516 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XFreePixmap", rc);
517}
518
519int LogDynAndXSetSelectionOwner_ex(wLog* log, const char* file, const char* fkt, size_t line,
520 Display* display, Atom selection, Window owner, Time time)
521{
522 if (WLog_IsLevelActive(log, log_level))
523 {
524 char* selectionstr = Safe_XGetAtomName(log, display, selection);
525 write_log(log, log_level, file, fkt, line, "XSetSelectionOwner(%p, %s, 0x%08lu, %lu)",
526 (void*)display, selectionstr, owner, time);
527 XFree(selectionstr);
528 }
529 const int rc = XSetSelectionOwner(display, selection, owner, time);
530 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display,
531 "XSetSelectionOwner", rc);
532}
533
534int LogDynAndXSetForeground_ex(wLog* log, const char* file, const char* fkt, size_t line,
535 Display* display, GC gc, unsigned long foreground)
536{
537 if (WLog_IsLevelActive(log, log_level))
538 {
539 write_log(log, log_level, file, fkt, line, "XSetForeground(%p, %p, 0x%08lu)",
540 (void*)display, (void*)gc, foreground);
541 }
542 const int rc = XSetForeground(display, gc, foreground);
543 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSetForeground",
544 rc);
545}
546
547int LogDynAndXMoveWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
548 Display* display, Window w, int x, int y)
549{
550 if (WLog_IsLevelActive(log, log_level))
551 {
552 write_log(log, log_level, file, fkt, line, "XMoveWindow(%p, 0x%08lu, %d, %d)",
553 (void*)display, w, x, y);
554 }
555 const int rc = XMoveWindow(display, w, x, y);
556 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XMoveWindow", rc);
557}
558
559int LogDynAndXSetFillStyle_ex(wLog* log, const char* file, const char* fkt, size_t line,
560 Display* display, GC gc, int fill_style)
561{
562 if (WLog_IsLevelActive(log, log_level))
563 {
564 write_log(log, log_level, file, fkt, line, "XSetFillStyle(%p, %p, %d)", (void*)display,
565 (void*)gc, fill_style);
566 }
567 const int rc = XSetFillStyle(display, gc, fill_style);
568 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSetFillStyle",
569 rc);
570}
571
572int LogDynAndXSetFunction_ex(wLog* log, const char* file, const char* fkt, size_t line,
573 Display* display, GC gc, int function)
574{
575 if (WLog_IsLevelActive(log, log_level))
576 {
577 write_log(log, log_level, file, fkt, line, "XSetFunction(%p, %p, %d)", (void*)display,
578 (void*)gc, function);
579 }
580 const int rc = XSetFunction(display, gc, function);
581 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSetFunction",
582 rc);
583}
584
585int LogDynAndXRaiseWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
586 Display* display, Window w)
587{
588 if (WLog_IsLevelActive(log, log_level))
589 {
590 write_log(log, log_level, file, fkt, line, "XRaiseWindow(%p, %lu)", (void*)display, w);
591 }
592 const int rc = XRaiseWindow(display, w);
593 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XRaiseWindow",
594 rc);
595}
596
597int LogDynAndXMapWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
598 Display* display, Window w)
599{
600 if (WLog_IsLevelActive(log, log_level))
601 {
602 write_log(log, log_level, file, fkt, line, "XMapWindow(%p, %lu)", (void*)display, w);
603 }
604 const int rc = XMapWindow(display, w);
605 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XMapWindow", rc);
606}
607
608int LogDynAndXUnmapWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
609 Display* display, Window w)
610{
611 if (WLog_IsLevelActive(log, log_level))
612 {
613 write_log(log, log_level, file, fkt, line, "XUnmapWindow(%p, %lu)", (void*)display, w);
614 }
615 const int rc = XUnmapWindow(display, w);
616 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XUnmapWindow",
617 rc);
618}
619
620int LogDynAndXMoveResizeWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
621 Display* display, Window w, int x, int y, unsigned int width,
622 unsigned int height)
623{
624 if (WLog_IsLevelActive(log, log_level))
625 {
626 write_log(log, log_level, file, fkt, line, "XMoveResizeWindow(%p, %lu, %d, %d, %u, %u)",
627 (void*)display, w, x, y, width, height);
628 }
629 const int rc = XMoveResizeWindow(display, w, x, y, width, height);
630 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display,
631 "XMoveResizeWindow", rc);
632}
633
634Status LogDynAndXWithdrawWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
635 Display* display, Window w, int screen_number)
636{
637 if (WLog_IsLevelActive(log, log_level))
638 {
639 write_log(log, log_level, file, fkt, line, "XWithdrawWindow(%p, %lu, %d)", (void*)display,
640 w, screen_number);
641 }
642 const Status rc = XWithdrawWindow(display, w, screen_number);
643 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XWithdrawWindow",
644 rc);
645}
646
647int LogDynAndXResizeWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
648 Display* display, Window w, unsigned int width, unsigned int height)
649{
650 if (WLog_IsLevelActive(log, log_level))
651 {
652 write_log(log, log_level, file, fkt, line, "XResizeWindow(%p, %lu, %u, %u)", (void*)display,
653 w, width, height);
654 }
655 const int rc = XResizeWindow(display, w, width, height);
656 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XResizeWindow",
657 rc);
658}
659
660int LogDynAndXClearWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
661 Display* display, Window w)
662{
663 if (WLog_IsLevelActive(log, log_level))
664 {
665 write_log(log, log_level, file, fkt, line, "XClearWindow(%p, %lu)", (void*)display, w);
666 }
667 const int rc = XClearWindow(display, w);
668 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XClearWindow",
669 rc);
670}
671
672int LogDynAndXSetBackground_ex(wLog* log, const char* file, const char* fkt, size_t line,
673 Display* display, GC gc, unsigned long background)
674{
675 if (WLog_IsLevelActive(log, log_level))
676 {
677 write_log(log, log_level, file, fkt, line, "XSetBackground(%p, %p, %lu)", (void*)display,
678 (void*)gc, background);
679 }
680 const int rc = XSetBackground(display, gc, background);
681 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSetBackground",
682 rc);
683}
684
685int LogDynAndXSetClipMask_ex(wLog* log, const char* file, const char* fkt, size_t line,
686 Display* display, GC gc, Pixmap pixmap)
687{
688 if (WLog_IsLevelActive(log, log_level))
689 {
690 write_log(log, log_level, file, fkt, line, "XSetClipMask(%p, %p, %lu)", (void*)display,
691 (void*)gc, pixmap);
692 }
693 const int rc = XSetClipMask(display, gc, pixmap);
694 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSetClipMask",
695 rc);
696}
697
698int LogDynAndXFillRectangle_ex(wLog* log, const char* file, const char* fkt, size_t line,
699 Display* display, Window w, GC gc, int x, int y, unsigned int width,
700 unsigned int height)
701{
702 if (WLog_IsLevelActive(log, log_level))
703 {
704 write_log(log, log_level, file, fkt, line, "XFillRectangle(%p, %lu, %p, %d, %d, %u, %u)",
705 (void*)display, w, (void*)gc, x, y, width, height);
706 }
707 const int rc = XFillRectangle(display, w, gc, x, y, width, height);
708 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XFillRectangle",
709 rc);
710}
711
712int LogDynAndXSetRegion_ex(wLog* log, const char* file, const char* fkt, size_t line,
713 Display* display, GC gc, Region r)
714{
715 if (WLog_IsLevelActive(log, log_level))
716 {
717 write_log(log, log_level, file, fkt, line, "XSetRegion(%p, %p, %p)", (void*)display,
718 (void*)gc, (void*)r);
719 }
720 const int rc = XSetRegion(display, gc, r);
721 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XSetRegion", rc);
722}
723
724int LogDynAndXReparentWindow_ex(wLog* log, const char* file, const char* fkt, size_t line,
725 Display* display, Window w, Window parent, int x, int y)
726{
727 if (WLog_IsLevelActive(log, log_level))
728 {
729 write_log(log, log_level, file, fkt, line, "XReparentWindow(%p, %lu, %lu, %d, %d)",
730 (void*)display, w, parent, x, y);
731 }
732 const int rc = XReparentWindow(display, w, parent, x, y);
733 return write_result_log_expect_one(log, WLOG_WARN, file, fkt, line, display, "XReparentWindow",
734 rc);
735}
736
737char* getConfigOption(BOOL system, const char* option)
738{
739 char* res = NULL;
740 WINPR_JSON* file = freerdp_GetJSONConfigFile(system, "xfreerdp.json");
741 if (!file)
742 return NULL;
743
744 WINPR_JSON* obj = WINPR_JSON_GetObjectItem(file, option);
745 if (obj)
746 {
747 const char* val = WINPR_JSON_GetStringValue(obj);
748 if (val)
749 res = _strdup(val);
750 }
751 WINPR_JSON_Delete(file);
752
753 return res;
754}
WINPR_API WINPR_JSON * WINPR_JSON_GetObjectItem(const WINPR_JSON *object, const char *string)
Return a pointer to an JSON object item.
Definition json.c:184
WINPR_API const char * WINPR_JSON_GetStringValue(WINPR_JSON *item)
Return the String value of a JSON item.
Definition json.c:234
WINPR_API void WINPR_JSON_Delete(WINPR_JSON *item)
Delete a WinPR JSON wrapper object.
Definition json.c:144
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.