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/log.h>
30
31#define TAG CLIENT_TAG("xfreerdp.utils")
32
33static const DWORD log_level = WLOG_TRACE;
34
35static void write_log(wLog* log, DWORD level, const char* fname, const char* fkt, size_t line, ...)
36{
37 va_list ap = { 0 };
38 va_start(ap, line);
39 WLog_PrintMessageVA(log, WLOG_MESSAGE_TEXT, level, line, fname, fkt, ap);
40 va_end(ap);
41}
42
43char* Safe_XGetAtomNameEx(wLog* log, Display* display, Atom atom, const char* varname)
44{
45 WLog_Print(log, log_level, "XGetAtomName(%s, 0x%08" PRIx32 ")", varname, atom);
46 if (atom == None)
47 return strdup("Atom_None");
48 return XGetAtomName(display, atom);
49}
50
51Atom Logging_XInternAtom(wLog* log, Display* display, _Xconst char* atom_name, Bool only_if_exists)
52{
53 Atom atom = XInternAtom(display, atom_name, only_if_exists);
54 if (WLog_IsLevelActive(log, log_level))
55 {
56 WLog_Print(log, log_level, "XInternAtom(0x%08" PRIx32 ", %s, %s) -> 0x%08" PRIx32, display,
57 atom_name, only_if_exists ? "True" : "False", atom);
58 }
59 return atom;
60}
61
62int LogTagAndXChangeProperty_ex(const char* tag, const char* file, const char* fkt, size_t line,
63 Display* display, Window w, Atom property, Atom type, int format,
64 int mode, const unsigned char* data, int nelements)
65{
66 wLog* log = WLog_Get(tag);
67 return LogDynAndXChangeProperty_ex(log, file, fkt, line, display, w, property, type, format,
68 mode, data, nelements);
69}
70
71int LogDynAndXChangeProperty_ex(wLog* log, const char* file, const char* fkt, size_t line,
72 Display* display, Window w, Atom property, Atom type, int format,
73 int mode, const unsigned char* data, int nelements)
74{
75 if (WLog_IsLevelActive(log, log_level))
76 {
77 char* propstr = Safe_XGetAtomName(log, display, property);
78 char* typestr = Safe_XGetAtomName(log, display, type);
79 write_log(log, log_level, file, fkt, line,
80 "XChangeProperty(%p, %d, %s [%d], %s [%d], %d, %d, %p, %d)", display, w, propstr,
81 property, typestr, type, format, mode, data, nelements);
82 XFree(propstr);
83 XFree(typestr);
84 }
85 return XChangeProperty(display, w, property, type, format, mode, data, nelements);
86}
87
88int LogTagAndXDeleteProperty_ex(const char* tag, const char* file, const char* fkt, size_t line,
89 Display* display, Window w, Atom property)
90{
91 wLog* log = WLog_Get(tag);
92 return LogDynAndXDeleteProperty_ex(log, file, fkt, line, display, w, property);
93}
94
95int LogDynAndXDeleteProperty_ex(wLog* log, const char* file, const char* fkt, size_t line,
96 Display* display, Window w, Atom property)
97{
98 if (WLog_IsLevelActive(log, log_level))
99 {
100 char* propstr = Safe_XGetAtomName(log, display, property);
101 write_log(log, log_level, file, fkt, line, "XDeleteProperty(%p, %d, %s [%d])", display, w,
102 propstr, property);
103 XFree(propstr);
104 }
105 return XDeleteProperty(display, w, property);
106}
107
108int LogTagAndXConvertSelection_ex(const char* tag, const char* file, const char* fkt, size_t line,
109 Display* display, Atom selection, Atom target, Atom property,
110 Window requestor, Time time)
111{
112 wLog* log = WLog_Get(tag);
113 return LogDynAndXConvertSelection_ex(log, file, fkt, line, display, selection, target, property,
114 requestor, time);
115}
116
117int LogDynAndXConvertSelection_ex(wLog* log, const char* file, const char* fkt, size_t line,
118 Display* display, Atom selection, Atom target, Atom property,
119 Window requestor, Time time)
120{
121 if (WLog_IsLevelActive(log, log_level))
122 {
123 char* selectstr = Safe_XGetAtomName(log, display, selection);
124 char* targetstr = Safe_XGetAtomName(log, display, target);
125 char* propstr = Safe_XGetAtomName(log, display, property);
126 write_log(log, log_level, file, fkt, line,
127 "XConvertSelection(%p, %s [%d], %s [%d], %s [%d], %d, %lu)", display, selectstr,
128 selection, targetstr, target, propstr, property, requestor, time);
129 XFree(propstr);
130 XFree(targetstr);
131 XFree(selectstr);
132 }
133 return XConvertSelection(display, selection, target, property, requestor, time);
134}
135
136int LogTagAndXGetWindowProperty_ex(const char* tag, const char* file, const char* fkt, size_t line,
137 Display* display, Window w, Atom property, long long_offset,
138 long long_length, int delete, Atom req_type,
139 Atom* actual_type_return, int* actual_format_return,
140 unsigned long* nitems_return, unsigned long* bytes_after_return,
141 unsigned char** prop_return)
142{
143 wLog* log = WLog_Get(tag);
144 return LogDynAndXGetWindowProperty_ex(
145 log, file, fkt, line, display, w, property, long_offset, long_length, delete, req_type,
146 actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
147}
148
149int LogDynAndXGetWindowProperty_ex(wLog* log, const char* file, const char* fkt, size_t line,
150 Display* display, Window w, Atom property, long long_offset,
151 long long_length, int delete, Atom req_type,
152 Atom* actual_type_return, int* actual_format_return,
153 unsigned long* nitems_return, unsigned long* bytes_after_return,
154 unsigned char** prop_return)
155{
156 if (WLog_IsLevelActive(log, log_level))
157 {
158 char* propstr = Safe_XGetAtomName(log, display, property);
159 char* req_type_str = Safe_XGetAtomName(log, display, req_type);
160 write_log(log, log_level, file, fkt, line,
161 "XGetWindowProperty(%p, %d, %s [%d], %ld, %ld, %d, %s [%d], %p, %p, %p, %p, %p)",
162 display, w, propstr, property, long_offset, long_length, delete, req_type_str,
163 req_type, actual_type_return, actual_format_return, nitems_return,
164 bytes_after_return, prop_return);
165 XFree(propstr);
166 XFree(req_type_str);
167 }
168 return XGetWindowProperty(display, w, property, long_offset, long_length, delete, req_type,
169 actual_type_return, actual_format_return, nitems_return,
170 bytes_after_return, prop_return);
171}
172
173BOOL IsGnome(void)
174{
175 // NOLINTNEXTLINE(concurrency-mt-unsafe)
176 char* env = getenv("DESKTOP_SESSION");
177 return (env != NULL && strcmp(env, "gnome") == 0);
178}
179
180BOOL run_action_script(xfContext* xfc, const char* what, const char* arg, fn_action_script_run fkt,
181 void* user)
182{
183 BOOL rc = FALSE;
184 FILE* keyScript = NULL;
185 WINPR_ASSERT(xfc);
186
187 rdpSettings* settings = xfc->common.context.settings;
188 WINPR_ASSERT(settings);
189
190 const char* ActionScript = freerdp_settings_get_string(settings, FreeRDP_ActionScript);
191
192 xfc->actionScriptExists = winpr_PathFileExists(ActionScript);
193
194 if (!xfc->actionScriptExists)
195 {
196 WLog_DBG(TAG, "[ActionScript] no such script '%s'", ActionScript);
197 goto fail;
198 }
199
200 char command[2048] = { 0 };
201 (void)sprintf_s(command, sizeof(command), "%s %s", ActionScript, what);
202 keyScript = popen(command, "r");
203
204 if (!keyScript)
205 {
206 WLog_ERR(TAG, "[ActionScript] Failed to execute '%s'", command);
207 goto fail;
208 }
209
210 BOOL read_data = FALSE;
211 char buffer[2048] = { 0 };
212 while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
213 {
214 char* context = NULL;
215 (void)strtok_s(buffer, "\n", &context);
216
217 if (fkt)
218 {
219 if (!fkt(xfc, buffer, strnlen(buffer, sizeof(buffer)), user, what, arg))
220 goto fail;
221 }
222 read_data = TRUE;
223 }
224
225 rc = read_data;
226 if (!rc)
227 WLog_ERR(TAG, "[ActionScript] No data returned from command '%s'", command);
228fail:
229 if (keyScript)
230 pclose(keyScript);
231 const BOOL res = rc || !xfc->actionScriptExists;
232 if (!rc)
233 xfc->actionScriptExists = FALSE;
234 return res;
235}
236
237const char* x11_error_to_string(xfContext* xfc, int error, char* buffer, size_t size)
238{
239 WINPR_ASSERT(xfc);
240 WINPR_ASSERT(size <= INT32_MAX);
241 const int rc = XGetErrorText(xfc->display, error, buffer, (int)size);
242 if (rc)
243 WLog_WARN(TAG, "XGetErrorText returned %d", rc);
244 return buffer;
245}
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.