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