FreeRDP
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 
33 static const DWORD log_level = WLOG_TRACE;
34 
35 static 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 
43 char* 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 
51 Atom 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 
62 int 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 
71 int 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 
88 int 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 
95 int 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 
108 int 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 
117 int 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 
136 int 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 
149 int 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 
173 BOOL IsGnome(void)
174 {
175  char* env = getenv("DESKTOP_SESSION");
176  return (env != NULL && strcmp(env, "gnome") == 0);
177 }
178 
179 BOOL run_action_script(xfContext* xfc, const char* what, const char* arg, fn_action_script_run fkt,
180  void* user)
181 {
182  BOOL rc = FALSE;
183  FILE* keyScript = NULL;
184  WINPR_ASSERT(xfc);
185 
186  rdpSettings* settings = xfc->common.context.settings;
187  WINPR_ASSERT(settings);
188 
189  const char* ActionScript = freerdp_settings_get_string(settings, FreeRDP_ActionScript);
190 
191  xfc->actionScriptExists = winpr_PathFileExists(ActionScript);
192 
193  if (!xfc->actionScriptExists)
194  goto fail;
195 
196  char command[2048] = { 0 };
197  (void)sprintf_s(command, sizeof(command), "%s %s", ActionScript, what);
198  keyScript = popen(command, "r");
199 
200  if (!keyScript)
201  {
202  WLog_ERR(TAG, "Failed to execute '%s'", command);
203  goto fail;
204  }
205 
206  BOOL read_data = FALSE;
207  char buffer[2048] = { 0 };
208  while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
209  {
210  char* context = NULL;
211  (void)strtok_s(buffer, "\n", &context);
212 
213  if (fkt)
214  {
215  if (!fkt(xfc, buffer, strnlen(buffer, sizeof(buffer)), user, what, arg))
216  goto fail;
217  }
218  read_data = TRUE;
219  }
220 
221  rc = read_data;
222 fail:
223  if (!rc)
224  xfc->actionScriptExists = FALSE;
225  if (keyScript)
226  pclose(keyScript);
227  return rc;
228 }
229 
230 const char* x11_error_to_string(xfContext* xfc, int error, char* buffer, size_t size)
231 {
232  WINPR_ASSERT(xfc);
233  WINPR_ASSERT(size <= INT32_MAX);
234  const int rc = XGetErrorText(xfc->display, error, buffer, (int)size);
235  if (rc)
236  WLog_WARN(TAG, "XGetErrorText returned %d", rc);
237  return buffer;
238 }
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.