Remmina - The GTK+ Remote Desktop Client  v1.4.33
Remmina is a remote desktop client written in GTK+, aiming to be useful for system administrators and travellers, who need to work with lots of remote computers in front of either large monitors or tiny netbooks. Remmina supports multiple network protocols in an integrated and consistent user interface. Currently RDP, VNC, NX, XDMCP and SSH are supported.
rdp_plugin.h
Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2010-2011 Vic Lee
4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * In addition, as a special exception, the copyright holders give
23  * permission to link the code of portions of this program with the
24  * OpenSSL library under certain conditions as described in each
25  * individual source file, and distribute linked combinations
26  * including the two.
27  * You must obey the GNU General Public License in all respects
28  * for all of the code used other than OpenSSL. * If you modify
29  * file(s) with this exception, you may extend this exception to your
30  * version of the file(s), but you are not obligated to do so. * If you
31  * do not wish to do so, delete this exception statement from your
32  * version. * If you delete this exception statement from all source
33  * files in the program, then also delete it here.
34  *
35  */
36 
37 #pragma once
38 
39 #include "common/remmina_plugin.h"
40 #include <freerdp/freerdp.h>
41 #include <freerdp/version.h>
42 #include <freerdp/channels/channels.h>
43 #include <freerdp/codec/color.h>
44 #include <freerdp/codec/rfx.h>
45 #include <freerdp/gdi/gdi.h>
46 #include <freerdp/gdi/dc.h>
47 #include <freerdp/gdi/region.h>
48 #include <freerdp/client/cliprdr.h>
49 #include <freerdp/client/disp.h>
50 #ifdef GDK_WINDOWING_X11
51 #include <gdk/gdkx.h>
52 #elif defined(GDK_WINDOWING_WAYLAND)
53 #include <gdk/gdkwayland.h>
54 #endif
55 
56 #include <winpr/clipboard.h>
57 
69 #define FREERDP_CHECK_VERSION(major,minor,revision) \
70  (FREERDP_VERSION_MAJOR > (major) || \
71  (FREERDP_VERSION_MAJOR == (major) && FREERDP_VERSION_MINOR > (minor)) || \
72  (FREERDP_VERSION_MAJOR == (major) && FREERDP_VERSION_MINOR == (minor) && \
73  FREERDP_VERSION_REVISION >= (revision)))
74 
81 #define AVC_MIN_DESKTOP_WIDTH 644
82 #define AVC_MIN_DESKTOP_HEIGHT 480
83 
84 typedef struct rf_context rfContext;
85 
86 #define GET_PLUGIN_DATA(gp) (rfContext *)g_object_get_data(G_OBJECT(gp), "plugin-data")
87 
101 /* Poor (default) - all disabled */
102 #define DEFAULT_QUALITY_0 0x6f
103 /* Medium - only THEMING, CURSOR_SHADOW and CURSORSETTINGS enabled, all other disabled */
104 #define DEFAULT_QUALITY_1 0x07
105 /* Good - WALLPAPER, FONT_SMOOTHING, DESKTOP_COMPOSITION disabled, all other enabled */
106 #define DEFAULT_QUALITY_2 0x01
107 /* Best - DESKTOP_COMPOSITION disabled, all other enabled */
108 #define DEFAULT_QUALITY_9 0x80
109 
111 
112 #define REMMINA_PLUGIN_INFO(fmt, ...) \
113  remmina_plugin_service->_remmina_info(__func__, fmt, ##__VA_ARGS__)
114 
115 #define REMMINA_PLUGIN_MESSAGE(fmt, ...) \
116  remmina_plugin_service->_remmina_message(__func, fmt, ##__VA_ARGS__)
117 
118 #define REMMINA_PLUGIN_DEBUG(fmt, ...) \
119  remmina_plugin_service->_remmina_debug(__func__, fmt, ##__VA_ARGS__)
120 
121 #define REMMINA_PLUGIN_WARNING(fmt, ...) \
122  remmina_plugin_service->_remmina_warning(__func__, fmt, ##__VA_ARGS__)
123 
124 /* This will intentionally crash Remmina */
125 #define REMMINA_PLUGIN_ERROR(fmt, ...) \
126  remmina_plugin_service->_remmina_error(__func__, fmt, ##__VA_ARGS__)
127 
128 #define REMMINA_PLUGIN_CRITICAL(fmt, ...) \
129  remmina_plugin_service->_remmina_critical(__func__, fmt, ##__VA_ARGS__)
130 #define REMMINA_PLUGIN_AUDIT(fmt, ...) \
131  remmina_plugin_service->_remmina_audit(__func__, fmt, ##__VA_ARGS__)
132 
133 struct rf_clipboard {
135  CliprdrClientContext * context;
136  wClipboard * system;
138 
139  UINT32 format;
141 
142  pthread_mutex_t transfer_clip_mutex;
143  pthread_cond_t transfer_clip_cond;
145  gpointer srv_data;
146  pthread_mutex_t srv_data_mutex;
147 
149 
150  /* Stats for clipboard download */
152 };
153 typedef struct rf_clipboard rfClipboard;
154 
155 
156 struct rf_pointer {
157  rdpPointer pointer;
158  GdkCursor * cursor;
159 };
160 typedef struct rf_pointer rfPointer;
161 
162 #ifdef RF_BITMAP
163 struct rf_bitmap {
164  rdpBitmap bitmap;
165  Pixmap pixmap;
166  cairo_surface_t * surface;
167 };
168 typedef struct rf_bitmap rfBitmap;
169 #endif
170 
171 #ifdef RF_GLYPH
172 struct rf_glyph {
173  rdpGlyph glyph;
174  Pixmap pixmap;
175 };
176 typedef struct rf_glyph rfGlyph;
177 #endif
178 
179 typedef enum {
189 
192  union {
193  struct {
194  BOOL up;
195  BOOL extended;
196  UINT8 key_code;
197  UINT32 unicode_code;
198  BOOL extended1;
199  } key_event;
200  struct {
201  UINT16 flags;
202  UINT16 x;
203  UINT16 y;
204  BOOL extended;
205  } mouse_event;
206  struct {
207  CLIPRDR_FORMAT_LIST *pFormatList;
208  } clipboard_formatlist;
209  struct {
210  BYTE * data;
211  int size;
212  } clipboard_formatdataresponse;
213  struct {
214  CLIPRDR_FORMAT_DATA_REQUEST *pFormatDataRequest;
215  } clipboard_formatdatarequest;
216  struct {
217  gint Flags;
218  gint Left;
219  gint Top;
220  gint width;
221  gint height;
227  } monitor_layout;
228  };
229 };
231 
232 typedef enum {
241 
242 typedef enum {
247 
248 typedef enum {
256 
257 typedef enum {
261 
262 typedef struct {
263  gint x, y, w, h;
264 } region;
265 
268  gboolean sync;
269  gboolean complete;
270  pthread_mutex_t sync_wait_mutex;
271  pthread_cond_t sync_wait_cond;
272  union {
273  struct {
275  gint ninvalid;
276  } reg;
277  struct {
278  rdpContext * context;
281  } cursor;
282  struct {
283  gint left;
284  gint top;
285  RFX_MESSAGE * message;
286  } rfx;
287  struct {
288  gint left;
289  gint top;
290  gint width;
291  gint height;
292  UINT8 * bitmap;
293  } nocodec;
294  struct {
296  GtkTargetList * targetlist;
297  UINT32 format;
299  gpointer data;
300  } clipboard;
301  struct {
303  } event;
304  struct {
305  gint x;
306  gint y;
307  } pos;
308  };
309  /* We can also return values here, usually integers*/
310  int retval;
311  /* Some functions also may return a pointer. */
312  void * retptr;
313 };
314 
316  unsigned orig_keycode;
319 
320 struct rf_context {
321  rdpContext context;
322  DEFINE_RDP_CLIENT_COMMON();
323 
325 
326  /* main */
327  rdpSettings * settings;
328  freerdp * instance;
329 
332  gboolean user_cancelled;
334 
335  CliprdrClientContext * cliprdr;
336  DispClientContext * dispcontext;
337 
338  RDP_PLUGIN_DATA rdpdr_data[5];
339  RDP_PLUGIN_DATA drdynvc_data[5];
340  gchar rdpsnd_options[20];
341 
342  gboolean rdpgfxchan;
343 
344  gboolean connected;
345  gboolean is_reconnecting;
347  /* orphaned: rf_context has still one or more libfreerdp thread active,
348  * but no longer maintained by an open RemminaProtocolWidget/tab.
349  * When the orphaned thread terminates, we must cleanup rf_context.
350  */
351  gboolean orphaned;
354 
355  gboolean sw_gdi;
356  GtkWidget * drawing_area;
359  gdouble scale_x;
360  gdouble scale_y;
363 
364  gint srcBpp;
365  GdkDisplay * display;
366  GdkVisual * visual;
367  cairo_surface_t * surface;
368  cairo_format_t cairo_format;
369  gint bpp;
371  gint * colormap;
372 
374  GHashTable * object_table;
375 
376  GAsyncQueue * ui_queue;
377  pthread_mutex_t ui_queue_mutex;
378  guint ui_handler;
379 
380  GArray * pressed_keys;
381  GAsyncQueue * event_queue;
382  gint event_pipe[2];
383  HANDLE event_handle;
384  UINT16 last_x;
385  UINT16 last_y;
386 
388 
389  GArray * keymap; /* Array of RemminaPluginRdpKeymapEntry */
390 
392 
393  enum { REMMINA_POSTCONNECT_ERROR_OK = 0, REMMINA_POSTCONNECT_ERROR_GDI_INIT = 1, REMMINA_POSTCONNECT_ERROR_NO_H264 } postconnect_error;
394 };
395 
397 
400 void rf_get_fds(RemminaProtocolWidget *gp, void **rfds, int *rcount);
403 
void remmina_rdp_event_event_push(RemminaProtocolWidget *gp, const RemminaPluginRdpEvent *e)
Definition: rdp_event.c:150
CliprdrClientContext * context
Definition: rdp_plugin.h:135
gboolean thread_cancelled
Definition: rdp_plugin.h:333
gboolean is_reconnecting
Definition: rdp_plugin.h:345
gulong clipboard_handler
Definition: rdp_plugin.h:140
RemminaPluginRdpUiClipboardType type
Definition: rdp_plugin.h:295
gint y
Definition: rdp_plugin.h:263
Pixmap pixmap
Definition: rdp_plugin.h:165
guint delayed_monitor_layout_handler
Definition: rdp_plugin.h:361
RemminaPluginRdpUiEeventType
Definition: rdp_plugin.h:257
gboolean user_cancelled
Definition: rdp_plugin.h:332
CLIPRDR_FORMAT_LIST * pFormatList
Definition: rdp_plugin.h:207
gboolean attempt_interactive_authentication
Definition: rdp_plugin.h:391
gdouble scale_y
Definition: rdp_plugin.h:360
RemminaPluginRdpUiType
Definition: rdp_plugin.h:232
cairo_surface_t * surface
Definition: rdp_plugin.h:367
pthread_t remmina_plugin_thread
Definition: rdp_plugin.h:330
RemminaPluginService * remmina_plugin_service
Definition: rdp_plugin.c:112
pthread_mutex_t transfer_clip_mutex
Definition: rdp_plugin.h:142
gboolean rdpgfxchan
Definition: rdp_plugin.h:342
int requestedFormatId
Definition: rdp_plugin.h:137
guint ui_handler
Definition: rdp_plugin.h:378
pthread_mutex_t srv_data_mutex
Definition: rdp_plugin.h:146
void rf_object_free(RemminaProtocolWidget *gp, RemminaPluginRdpUiObject *obj)
GdkDisplay * display
Definition: rdp_plugin.h:365
GAsyncQueue * ui_queue
Definition: rdp_plugin.h:376
RemminaPluginRdpEventType
Definition: rdp_plugin.h:179
pthread_mutex_t sync_wait_mutex
Definition: rdp_plugin.h:270
RemminaProtocolWidget * protocol_widget
Definition: rdp_plugin.h:324
int reconnect_nattempt
Definition: rdp_plugin.h:353
void rf_init(RemminaProtocolWidget *gp)
rfContext * rfi
Definition: rdp_plugin.h:134
GdkVisual * visual
Definition: rdp_plugin.h:366
gdouble scale_x
Definition: rdp_plugin.h:359
gpointer srv_data
Definition: rdp_plugin.h:145
rdpBitmap bitmap
Definition: rdp_plugin.h:164
GtkTargetList * targetlist
Definition: rdp_plugin.h:296
BOOL rf_check_fds(RemminaProtocolWidget *gp)
int reconnect_maxattempts
Definition: rdp_plugin.h:352
RemminaPluginRdpEventType type
Definition: rdp_plugin.h:191
UINT16 last_x
Definition: rdp_plugin.h:384
RemminaPluginRdpUiPointerType type
Definition: rdp_plugin.h:280
pthread_cond_t transfer_clip_cond
Definition: rdp_plugin.h:143
rdpPointer pointer
Definition: rdp_plugin.h:157
Pixmap pixmap
Definition: rdp_plugin.h:174
unsigned translated_keycode
Definition: rdp_plugin.h:317
GtkWidget * drawing_area
Definition: rdp_plugin.h:356
cairo_format_t cairo_format
Definition: rdp_plugin.h:368
RemminaPluginRdpUiClipboardType
Definition: rdp_plugin.h:242
gboolean use_client_keymap
Definition: rdp_plugin.h:362
GArray * keymap
Definition: rdp_plugin.h:389
RemminaPluginRdpUiPointerType
Definition: rdp_plugin.h:248
gint scanline_pad
Definition: rdp_plugin.h:370
UINT16 last_y
Definition: rdp_plugin.h:385
unsigned orig_keycode
Definition: rdp_plugin.h:316
GdkCursor * cursor
Definition: rdp_plugin.h:158
wClipboard * system
Definition: rdp_plugin.h:136
void rf_uninit(RemminaProtocolWidget *gp)
struct remmina_plugin_rdp_keymap_entry RemminaPluginRdpKeymapEntry
gboolean stop_reconnecting_requested
Definition: rdp_plugin.h:346
gint * colormap
Definition: rdp_plugin.h:371
void rf_get_fds(RemminaProtocolWidget *gp, void **rfds, int *rcount)
guint object_id_seq
Definition: rdp_plugin.h:373
GAsyncQueue * event_queue
Definition: rdp_plugin.h:381
pthread_cond_t sync_wait_cond
Definition: rdp_plugin.h:271
rfClipboard clipboard
Definition: rdp_plugin.h:387
HANDLE event_handle
Definition: rdp_plugin.h:383
GHashTable * object_table
Definition: rdp_plugin.h:374
RemminaScaleMode
Definition: types.h:142
CLIPRDR_FORMAT_DATA_REQUEST * pFormatDataRequest
Definition: rdp_plugin.h:214
gint srcBpp
Definition: rdp_plugin.h:364
gboolean connected
Definition: rdp_plugin.h:344
RemminaScaleMode scale
Definition: rdp_plugin.h:331
freerdp * instance
Definition: rdp_plugin.h:328
DispClientContext * dispcontext
Definition: rdp_plugin.h:336
RemminaPluginRdpUiEeventType type
Definition: rdp_plugin.h:302
GArray * pressed_keys
Definition: rdp_plugin.h:380
rdpSettings * settings
Definition: rdp_plugin.h:327
gint scale_height
Definition: rdp_plugin.h:358
Definition: rdp_plugin.h:315
UINT32 format
Definition: rdp_plugin.h:139
UINT32 server_html_format_id
Definition: rdp_plugin.h:148
gboolean orphaned
Definition: rdp_plugin.h:351
struct timeval clientformatdatarequest_tv
Definition: rdp_plugin.h:151
rdpGlyph glyph
Definition: rdp_plugin.h:173
rdpContext context
Definition: rdp_plugin.h:321
gint scale_width
Definition: rdp_plugin.h:357
pthread_mutex_t ui_queue_mutex
Definition: rdp_plugin.h:377
cairo_surface_t * surface
Definition: rdp_plugin.h:166
enum rf_clipboard::@41 srv_clip_data_wait
gboolean sw_gdi
Definition: rdp_plugin.h:355
RemminaPluginRdpUiType type
Definition: rdp_plugin.h:267
CliprdrClientContext * cliprdr
Definition: rdp_plugin.h:335