6 #include <sys/socket.h>
16 #include <linux/input.h>
18 #include <freerdp/version.h>
19 #include <freerdp/freerdp.h>
20 #include <freerdp/listener.h>
21 #include <freerdp/update.h>
22 #include <freerdp/input.h>
23 #include <freerdp/codec/color.h>
24 #include <freerdp/codec/rfx.h>
25 #include <freerdp/codec/nsc.h>
26 #include <freerdp/locale/keyboard.h>
27 #include <winpr/input.h>
28 #include <winpr/ssl.h>
31 #include <tbm_surface.h>
32 #include <tbm_surface_internal.h>
33 #include <e_info_server_input.h>
39 #include "e_mod_main.h"
40 #include "e_mod_rdp.h"
44 #define E_RDP_WIDTH 1280
45 #define E_RDP_HEIGHT 720
46 #define E_RDP_DEVICE_NAME "rdp_input"
47 #define E_MOD_RDP_CONFIG_VERSION 2
48 #define E_MOD_RDP_NAME_LEN 64
49 #define MAX_FREERDP_FDS 10
50 #define DEFAULT_PIXEL_FORMAT PIXEL_FORMAT_BGRA32
53 #define SVGA_TIME 0.075
56 #define WXGA_TIME 0.18
57 #define SXGAP_TIME 0.18
62 RDP_PEER_ACTIVATED = (1 << 0),
63 RDP_PEER_OUTPUT_ENABLED = (1 << 1),
66 typedef struct _E_Rdp_Output E_Rdp_Output;
67 typedef struct _E_Rdp_Backend E_Rdp_Backend;
68 typedef struct _E_Rdp_Peer_Context E_Rdp_Peer_Context;
69 typedef struct _E_Rdp_Peer_Item E_Rdp_Peer_Item;
70 typedef struct _E_Rdp_Peer_Context E_Rdp_Peer_Context;
72 static E_Rdp_Config_Data *g_rdp_config;
73 static E_Rdp_Backend *g_rdp_backend;
74 static unsigned int refresh_raw_frame_id;
75 static E_Pointer_Hook *pointer_hook = NULL;
79 E_Output *primary_output;
80 Ecore_Timer *frame_timer;
81 pixman_image_t *showing_surface;
82 tbm_surface_h prepare_tbm_surface;
83 tbm_surface_h showing_tbm_surface;
84 tbm_surface_h backup_tbm_surface;
97 Eina_Bool frame_changed;
98 Eina_Bool cursor_changed;
102 Eina_Bool mouse_moved;
103 Eina_Bool buffer_changed;
105 Eina_Bool buffer_reuse;
106 Eina_Rectangle cursor_crop_dst;
107 Eina_Rectangle cursor_damage_rect;
112 struct wl_list peers;
115 struct _E_Rdp_Backend
117 freerdp_listener *listener;
118 struct wl_event_source *listener_events[MAX_FREERDP_FDS];
119 E_Rdp_Output *output;
126 int no_clients_resize;
127 int force_no_compression;
133 struct _E_Rdp_Peer_Item
141 struct _E_Rdp_Peer_Context
145 E_Rdp_Backend *rdpBackend;
146 struct wl_event_source *events[MAX_FREERDP_FDS];
147 RFX_CONTEXT *rfx_context;
148 wStream *encode_stream;
150 NSC_CONTEXT *nsc_context;
152 E_Rdp_Peer_Item item;
155 struct rdp_to_xkb_keyboard_layout
157 UINT32 rdpLayoutCode;
158 const char *xkbLayout;
159 const char *xkbVariant;
163 _e_rdp_tbm_image_create(E_Rdp_Output *output, int w, int h, int color)
165 tbm_surface_h tbm_surface = NULL;
167 tbm_surface = tbm_surface_internal_create_with_flags(w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
174 static pixman_format_code_t
175 _e_rdp_pixman_format_get(tbm_format format)
179 case TBM_FORMAT_ARGB8888:
180 return PIXMAN_a8r8g8b8;
182 case TBM_FORMAT_XRGB8888:
183 return PIXMAN_x8r8g8b8;
192 static pixman_image_t *
193 _e_rdp_pixman_image_create(tbm_surface_h tbm_surface)
196 tbm_surface_info_s info;
197 pixman_image_t *pix_surface = NULL;
198 pixman_format_code_t pix_format = 0;
200 EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
202 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_WRITE, &info);
206 pix_format = _e_rdp_pixman_format_get(info.format);
209 ERR("not supported format");
213 pix_surface = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
214 if (pix_surface == NULL)
215 ERR("create pixman image failed");
218 tbm_surface_unmap(tbm_surface);
223 e_rdp_peer_refresh_rfx(pixman_region32_t *damage, pixman_image_t *image, freerdp_peer *peer)
225 int width, height, nrects, i;
226 pixman_box32_t *region, *rects;
229 rdpUpdate *update = peer->update;
230 SURFACE_BITS_COMMAND cmd = { 0 };
231 E_Rdp_Peer_Context *context = (E_Rdp_Peer_Context *)peer->context;
233 Stream_Clear(context->encode_stream);
234 Stream_SetPosition(context->encode_stream, 0);
236 width = (damage->extents.x2 - damage->extents.x1);
237 height = (damage->extents.y2 - damage->extents.y1);
239 cmd.skipCompression = TRUE;
240 cmd.cmdType = CMDTYPE_STREAM_SURFACE_BITS;
241 cmd.destLeft = damage->extents.x1;
242 cmd.destTop = damage->extents.y1;
243 cmd.destRight = damage->extents.x2;
244 cmd.destBottom = damage->extents.y2;
246 cmd.bmp.codecID = peer->settings->RemoteFxCodecId;
247 cmd.bmp.width = width;
248 cmd.bmp.height = height;
250 ptr = pixman_image_get_data(image) + damage->extents.x1 + damage->extents.y1 * (pixman_image_get_stride(image) / sizeof(uint32_t));
252 rects = pixman_region32_rectangles(damage, &nrects);
253 context->rfx_rects = realloc(context->rfx_rects, nrects * sizeof *rfxRect);
254 if (context->rfx_rects == NULL)
256 ERR("realloc failed");
260 for (i = 0; i < nrects; i++)
263 rfxRect = &context->rfx_rects[i];
265 rfxRect->x = (region->x1 - damage->extents.x1);
266 rfxRect->y = (region->y1 - damage->extents.y1);
267 rfxRect->width = (region->x2 - region->x1);
268 rfxRect->height = (region->y2 - region->y1);
271 rfx_compose_message(context->rfx_context, context->encode_stream, context->rfx_rects, nrects, (BYTE *)ptr, width, height, pixman_image_get_stride(image));
273 cmd.bmp.bitmapDataLength = Stream_GetPosition(context->encode_stream);
274 cmd.bmp.bitmapData = Stream_Buffer(context->encode_stream);
277 start = ecore_time_get();
279 update->SurfaceBits(update->context, &cmd);
281 end = ecore_time_get();
282 INF("pixman refresh time rfx: %.1f ms", (end - start) * 1000);
288 e_rdp_peer_refresh_nsc(pixman_region32_t *damage, pixman_image_t *image, freerdp_peer *peer)
292 rdpUpdate *update = peer->update;
293 SURFACE_BITS_COMMAND cmd = { 0 };
294 E_Rdp_Peer_Context *context = (E_Rdp_Peer_Context *)peer->context;
296 Stream_Clear(context->encode_stream);
297 Stream_SetPosition(context->encode_stream, 0);
299 width = (damage->extents.x2 - damage->extents.x1);
300 height = (damage->extents.y2 - damage->extents.y1);
302 cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
303 cmd.skipCompression = TRUE;
304 cmd.destLeft = damage->extents.x1;
305 cmd.destTop = damage->extents.y1;
306 cmd.destRight = damage->extents.x2;
307 cmd.destBottom = damage->extents.y2;
309 cmd.bmp.codecID = peer->settings->NSCodecId;
310 cmd.bmp.width = width;
311 cmd.bmp.height = height;
313 ptr = pixman_image_get_data(image) + damage->extents.x1 + damage->extents.y1 * (pixman_image_get_stride(image) / sizeof(uint32_t));
315 nsc_compose_message(context->nsc_context, context->encode_stream, (BYTE *)ptr, width, height, pixman_image_get_stride(image));
317 cmd.bmp.bitmapDataLength = Stream_GetPosition(context->encode_stream);
318 cmd.bmp.bitmapData = Stream_Buffer(context->encode_stream);
321 start = ecore_time_get();
323 update->SurfaceBits(update->context, &cmd);
325 end = ecore_time_get();
326 INF("pixman refresh time nsc: %.1f ms", (end - start) * 1000);
331 pixman_image_flipped_subrect(const pixman_box32_t *rect, pixman_image_t *img, BYTE *dest)
333 int stride = pixman_image_get_stride(img);
335 int toCopy = (rect->x2 - rect->x1) * 4;
336 int height = (rect->y2 - rect->y1);
337 const BYTE *src = (const BYTE *)pixman_image_get_data(img);
338 src += ((rect->y2-1) * stride) + (rect->x1 * 4);
340 for (h = 0; h < height; h++, src -= stride, dest += toCopy)
341 memcpy(dest, src, toCopy);
345 e_rdp_peer_refresh_raw(pixman_region32_t *region, pixman_image_t *image, freerdp_peer *peer)
347 rdpUpdate *update = peer->update;
348 SURFACE_BITS_COMMAND cmd = { 0 };
349 SURFACE_FRAME_MARKER marker;
350 pixman_box32_t *rect, subrect;
352 int heightIncrement, remainingHeight, top;
354 rect = pixman_region32_rectangles(region, &nrects);
358 if (refresh_raw_frame_id == 1024)
359 refresh_raw_frame_id = 0;
360 refresh_raw_frame_id++;
362 marker.frameId = refresh_raw_frame_id;
363 marker.frameAction = SURFACECMD_FRAMEACTION_BEGIN;
364 update->SurfaceFrameMarker(peer->context, &marker);
366 cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
372 start = ecore_time_get();
375 for (i = 0; i < nrects; i++, rect++)
377 /*INF("rect(%d,%d, %d,%d)", rect->x1, rect->y1, rect->x2, rect->y2);*/
378 cmd.destLeft = rect->x1;
379 cmd.destRight = rect->x2;
380 cmd.bmp.width = (rect->x2 - rect->x1);
382 heightIncrement = peer->settings->MultifragMaxRequestSize / (16 + cmd.bmp.width * 4);
383 remainingHeight = rect->y2 - rect->y1;
386 subrect.x1 = rect->x1;
387 subrect.x2 = rect->x2;
389 while (remainingHeight)
391 cmd.bmp.height = (remainingHeight > heightIncrement) ? heightIncrement : remainingHeight;
393 cmd.destBottom = top + cmd.bmp.height;
394 cmd.bmp.bitmapDataLength = cmd.bmp.width * cmd.bmp.height * 4;
395 cmd.bmp.bitmapData = (BYTE *)realloc(cmd.bmp.bitmapData, cmd.bmp.bitmapDataLength);
398 subrect.y2 = top + cmd.bmp.height;
399 pixman_image_flipped_subrect(&subrect, image, cmd.bmp.bitmapData);
401 /*INF("* sending (%d,%d, %d,%d)", subrect.x1, subrect.y1, subrect.x2, subrect.y2); */
402 update->SurfaceBits(peer->context, &cmd);
404 remainingHeight -= cmd.bmp.height;
405 top += cmd.bmp.height;
409 end = ecore_time_get();
410 INF("pixman refresh time raw: %.1f ms", (end - start) * 1000);
413 free(cmd.bmp.bitmapData);
415 marker.frameAction = SURFACECMD_FRAMEACTION_END;
416 update->SurfaceFrameMarker(peer->context, &marker);
420 e_rdp_peer_refresh_region(pixman_region32_t *region, freerdp_peer *peer, pixman_image_t *pix_surface)
422 rdpSettings *settings = peer->settings;
424 if (settings->RemoteFxCodec)
425 e_rdp_peer_refresh_rfx(region, pix_surface, peer);
426 else if (settings->NSCodec)
427 e_rdp_peer_refresh_nsc(region, pix_surface, peer);
429 e_rdp_peer_refresh_raw(region, pix_surface, peer);
433 _e_rdp_output_image_showing_rect_get(Eina_Rectangle *out_rect, Eina_Rectangle *dst_rect, Eina_Rectangle *showing_rect)
435 showing_rect->x = dst_rect->x;
436 showing_rect->y = dst_rect->y;
438 if (dst_rect->x >= out_rect->w)
440 else if (dst_rect->x + dst_rect->w > out_rect->w)
441 showing_rect->w = out_rect->w - dst_rect->x;
443 showing_rect->w = dst_rect->w;
445 if (dst_rect->y >= out_rect->h)
447 else if (dst_rect->y + dst_rect->h > out_rect->h)
448 showing_rect->h = out_rect->h - dst_rect->y;
450 showing_rect->h = dst_rect->h;
454 _e_rdp_output_image_src_crop_get(E_Hwc_Window *hwc_window, Eina_Rectangle *fit, Eina_Rectangle *showing_rect, int primary_w, int primary_h)
456 float ratio_x, ratio_y;
457 Eina_Rectangle out_rect;
458 Eina_Rectangle dst_rect;
467 out_rect.w = primary_w;
468 out_rect.h = primary_h;
470 dst_rect.x = hwc_window->current.info.dst_pos.x;
471 dst_rect.y = hwc_window->current.info.dst_pos.y;
472 dst_rect.w = hwc_window->current.info.dst_pos.w;
473 dst_rect.h = hwc_window->current.info.dst_pos.h;
475 _e_rdp_output_image_showing_rect_get(&out_rect, &dst_rect, showing_rect);
477 fit->x = hwc_window->current.info.src_config.pos.x;
478 fit->y = hwc_window->current.info.src_config.pos.y;
480 if (hwc_window->current.info.transform % 2 == 0)
482 ratio_x = (float)hwc_window->current.info.src_config.pos.w / dst_rect.w;
483 ratio_y = (float)hwc_window->current.info.src_config.pos.h / dst_rect.h;
485 fit->w = showing_rect->w * ratio_x;
486 fit->h = showing_rect->h * ratio_y;
490 ratio_x = (float)hwc_window->current.info.src_config.pos.w / dst_rect.h;
491 ratio_y = (float)hwc_window->current.info.src_config.pos.h / dst_rect.w;
493 fit->w = showing_rect->h * ratio_x;
494 fit->h = showing_rect->w * ratio_y;
499 _e_rdp_output_center_rect_get (int src_w, int src_h, int dst_w, int dst_h, Eina_Rectangle *fit)
503 if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !fit)
506 rw = (float)src_w / dst_w;
507 rh = (float)src_h / dst_h;
514 fit->y = (dst_h - fit->h) / 2;
520 fit->x = (dst_w - fit->w) / 2;
538 _e_rdp_output_image_dst_crop_get(E_Hwc_Window *hwc_window, int src_w, int src_h, int w, int h,
539 Eina_Rectangle *pos, Eina_Rectangle *showing_pos, Eina_Rectangle *dst_crop, int rotate)
546 if (hwc_window->current.info.src_config.pos.w == w && hwc_window->current.info.src_config.pos.h == h &&
547 pos->x == 0 && pos->y == 0 && pos->w == src_w && pos->h == src_h)
549 dst_crop->x = pos->x;
550 dst_crop->y = pos->y;
551 dst_crop->w = pos->w;
552 dst_crop->h = pos->h;
554 else if ((w == pos->w) && (h == pos->h) && (showing_pos->w == pos->w) && (showing_pos->h == pos->h))
556 dst_crop->x = hwc_window->current.info.dst_pos.x + pos->x;
557 dst_crop->y = hwc_window->current.info.dst_pos.y + pos->y;
558 dst_crop->w = hwc_window->current.info.dst_pos.w;
559 dst_crop->h = hwc_window->current.info.dst_pos.h;
561 else if (rotate == 0)
563 dst_crop->x = showing_pos->x * pos->w / w + pos->x;
564 dst_crop->y = showing_pos->y * pos->h / h + pos->y;
565 dst_crop->w = showing_pos->w * pos->w / w;
566 dst_crop->h = showing_pos->h * pos->h / h;
570 dst_crop->x = pos->x;
571 dst_crop->y = pos->y;
572 dst_crop->w = pos->w;
573 dst_crop->h = pos->h;
578 _e_rdp_output_image_composite(pixman_image_t *src_img, pixman_image_t *dst_img,
579 int sx, int sy, int sw, int sh,
580 int dx, int dy, int dw, int dh,
581 Eina_Bool over, int rotate, int hflip, int vflip)
583 double scale_x, scale_y;
585 pixman_transform_t t;
586 struct pixman_f_transform ft;
589 pixman_f_transform_init_identity(&ft);
593 pixman_f_transform_scale(&ft, NULL, -1, 1);
594 pixman_f_transform_translate(&ft, NULL, dw, 0);
599 pixman_f_transform_scale(&ft, NULL, 1, -1);
600 pixman_f_transform_translate(&ft, NULL, 0, dh);
603 rotate_step = (rotate + 360) / 90 % 4;
606 int c, s, tx = 0, ty = 0;
610 c = 0, s = -1, tx = -dw;
613 c = -1, s = 0, tx = -dw, ty = -dh;
616 c = 0, s = 1, ty = -dh;
619 pixman_f_transform_translate(&ft, NULL, tx, ty);
620 pixman_f_transform_rotate(&ft, NULL, c, s);
623 if (rotate_step % 2 == 0)
625 scale_x = (double)sw / dw;
626 scale_y = (double)sh / dh;
630 scale_x = (double)sw / dh;
631 scale_y = (double)sh / dw;
634 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
635 pixman_f_transform_translate(&ft, NULL, sx, sy);
636 pixman_transform_from_pixman_f_transform(&t, &ft);
637 pixman_image_set_transform(src_img, &t);
639 if (!over) op = PIXMAN_OP_SRC;
640 else op = PIXMAN_OP_OVER;
642 pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
647 _e_rdp_pixman_output_image_cusror_damage_area_get(E_Rdp_Output *output, Eina_Rectangle *rect)
649 if (output->cursor_crop_dst.x == 0 && output->cursor_crop_dst.y == 0 &&
650 output->cursor_crop_dst.w == 0 && output->cursor_crop_dst.h == 0)
652 output->cursor_damage_rect.x = 0;
653 output->cursor_damage_rect.y = 0;
654 output->cursor_damage_rect.w = output->w;
655 output->cursor_damage_rect.h = output->h;
660 if (output->cursor_crop_dst.x < rect->x)
662 output->cursor_damage_rect.x = output->cursor_crop_dst.x;
663 output->cursor_damage_rect.w = rect->x - output->cursor_crop_dst.x + rect->w;
667 output->cursor_damage_rect.x = rect->x;
668 output->cursor_damage_rect.w = output->cursor_crop_dst.x - rect->x + output->cursor_crop_dst.w;
670 if (output->cursor_damage_rect.x + output->cursor_damage_rect.w > output->w)
671 output->cursor_damage_rect.w = output->w - output->cursor_damage_rect.x;
674 if (output->cursor_crop_dst.y < rect->y)
676 output->cursor_damage_rect.y = output->cursor_crop_dst.y;
677 output->cursor_damage_rect.h = rect->y - output->cursor_crop_dst.y + rect->h;
681 output->cursor_damage_rect.y = rect->y;
682 output->cursor_damage_rect.h = output->cursor_crop_dst.y - rect->y + output->cursor_crop_dst.h;
684 if (output->cursor_damage_rect.y + output->cursor_damage_rect.h > output->h)
685 output->cursor_damage_rect.h = output->h - output->cursor_damage_rect.y;
690 _e_rdp_pixman_output_image_composite_cursor(E_Rdp_Output *output, E_Hwc_Window *hwc_window, pixman_image_t *pix_surface, int pix_w, int pix_h, int primary_w, int primary_h)
692 Eina_Rectangle showing_pos = {0, };
693 Eina_Rectangle dst_pos = {0, };
694 Eina_Rectangle src_crop = {0, };
695 Eina_Rectangle dst_crop = {0, };
696 void *src_ptr = NULL;
697 int src_stride, img_w, img_h;
698 pixman_image_t *pix_shm_src = NULL;
700 if (!hwc_window->cursor.buffer)
703 src_ptr = hwc_window->cursor.img_ptr;
704 src_stride = hwc_window->cursor.img_stride;
705 img_w = hwc_window->cursor.img_w;
706 img_h = hwc_window->cursor.img_h;
708 pix_shm_src = pixman_image_create_bits(PIXMAN_a8r8g8b8, img_w, img_h, (uint32_t*)src_ptr, src_stride);
711 ERR("create pixman image failed");
715 _e_rdp_output_image_src_crop_get(hwc_window, &src_crop, &showing_pos, primary_w, primary_h);
716 if (_e_rdp_output_center_rect_get(primary_w, primary_h, pix_w, pix_h, &dst_pos) == EINA_FALSE)
718 pixman_image_unref(pix_shm_src);
721 _e_rdp_output_image_dst_crop_get(hwc_window, img_w, img_h, primary_w, primary_h, &dst_pos, &showing_pos, &dst_crop, 0);
723 _e_rdp_output_image_composite(pix_shm_src, pix_surface,
724 src_crop.x, src_crop.y, src_crop.w, src_crop.h,
725 dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h,
728 pixman_image_unref(pix_shm_src);
730 output->mouse_x = hwc_window->current.info.dst_pos.x;
731 output->mouse_y = hwc_window->current.info.dst_pos.y;
733 _e_rdp_pixman_output_image_cusror_damage_area_get(output, &dst_crop);
734 output->cursor_crop_dst.x = dst_crop.x;
735 output->cursor_crop_dst.y = dst_crop.y;
736 output->cursor_crop_dst.w = dst_crop.w;
737 output->cursor_crop_dst.h = dst_crop.h;
743 _e_rdp_pixman_output_image_composite(E_Rdp_Output *output, E_Hwc_Window *hwc_window, pixman_image_t *pix_surface, int pix_w, int pix_h, int primary_w, int primary_h)
745 Eina_Rectangle showing_pos = {0, };
746 Eina_Rectangle dst_pos = {0, };
747 Eina_Rectangle src_crop = {0, };
748 Eina_Rectangle dst_crop = {0, };
749 tbm_surface_h tbm_surface = NULL;
750 tbm_surface_info_s info;
751 pixman_image_t *pix_surface_src = NULL;
752 pixman_format_code_t pix_format = 0;
754 tbm_surface = hwc_window->display.buffer.tsurface;
758 tbm_surface_internal_ref(tbm_surface);
760 if (tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info) != TBM_SURFACE_ERROR_NONE)
762 tbm_surface_internal_unref(tbm_surface);
766 pix_format = _e_rdp_pixman_format_get(info.format);
769 ERR("not supported format");
773 pix_surface_src = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
774 if (pix_surface_src == NULL)
776 ERR("create pixman image failed");
780 _e_rdp_output_image_src_crop_get(hwc_window, &src_crop, &showing_pos, primary_w, primary_h);
781 _e_rdp_output_center_rect_get(primary_w, primary_h, pix_w, pix_h, &dst_pos);
782 if (_e_rdp_output_center_rect_get(primary_w, primary_h, pix_w, pix_h, &dst_pos) == EINA_FALSE)
784 pixman_image_unref(pix_surface_src);
787 _e_rdp_output_image_dst_crop_get(hwc_window, info.width, info.height, primary_w, primary_h, &dst_pos, &showing_pos, &dst_crop, 0);
789 _e_rdp_output_image_composite(pix_surface_src, pix_surface,
790 src_crop.x, src_crop.y, src_crop.w, src_crop.h,
791 dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h,
794 pixman_image_unref(pix_surface_src);
795 tbm_surface_unmap(tbm_surface);
796 tbm_surface_internal_unref(tbm_surface);
801 tbm_surface_unmap(tbm_surface);
802 tbm_surface_internal_unref(tbm_surface);
807 _e_rdp_cb_hwc_window_sort(const void *d1, const void *d2)
809 E_Hwc_Window *hwc_window1 = (E_Hwc_Window *)d1;
810 E_Hwc_Window *hwc_window2 = (E_Hwc_Window *)d2;
811 int zpos1 = 0, zpos2 = 0;
813 if (!hwc_window1) return(1);
814 if (!hwc_window2) return(-1);
816 if (hwc_window1->state == E_HWC_WINDOW_STATE_NONE)
819 zpos1 = hwc_window1->zpos;
821 if (hwc_window2->state == E_HWC_WINDOW_STATE_NONE)
824 zpos2 = hwc_window2->zpos;
826 return (zpos1 - zpos2);
830 _e_rdp_tbm_surface_copy(tbm_surface_h src_tbm_surface, tbm_surface_info_s *src_info, tbm_surface_h dst_tbm_surface, tbm_surface_info_s *dst_info)
833 # define LIBGOMP_COPY_THREAD_NUM 4
834 # define LIBGOMP_COPY_PAGE_SIZE getpagesize()
835 # define PAGE_ALIGN(addr) ((addr)&(~((LIBGOMP_COPY_PAGE_SIZE)-1)))
836 if (src_info->planes[0].size > (LIBGOMP_COPY_THREAD_NUM * LIBGOMP_COPY_PAGE_SIZE))
839 step[0] = PAGE_ALIGN(src_info->planes[0].size / LIBGOMP_COPY_THREAD_NUM);
840 step[1] = src_info->planes[0].size - (step[0] * (LIBGOMP_COPY_THREAD_NUM - 1));
842 omp_set_num_threads(LIBGOMP_COPY_THREAD_NUM);
848 memcpy(dst_info->planes[0].ptr,
849 src_info->planes[0].ptr,
854 memcpy(dst_info->planes[0].ptr + step[0],
855 src_info->planes[0].ptr + step[0],
860 memcpy(dst_info->planes[0].ptr + (step[0] * 2),
861 src_info->planes[0].ptr + (step[0] * 2),
866 memcpy(dst_info->planes[0].ptr + (step[0] * 3),
867 src_info->planes[0].ptr + (step[0] * 3),
874 memcpy(dst_info->planes[0].ptr, src_info->planes[0].ptr, src_info->planes[0].size);
877 #else /* HAVE_LIBGOMP */
878 memcpy(dst_info->planes[0].ptr, src_info->planes[0].ptr, src_info->planes[0].size);
879 #endif /* end of HAVE_LIBGOMP */
883 _e_rdp_backup_buffer_create(E_Rdp_Output *output, tbm_surface_h src_tbm_surface, tbm_surface_info_s *src_info)
885 tbm_surface_h new_tsurface = NULL;
886 tbm_surface_info_s info;
887 int ret = TBM_SURFACE_ERROR_NONE;
889 new_tsurface = tbm_surface_create(src_info->width, src_info->height, src_info->format);
892 ERR("tbm_surface_create failed");
896 ret = tbm_surface_map(new_tsurface, TBM_SURF_OPTION_WRITE, &info);
897 if (ret != TBM_SURFACE_ERROR_NONE)
899 ERR("tbm_surface_map failed");
900 tbm_surface_destroy(new_tsurface);
904 _e_rdp_tbm_surface_copy(src_tbm_surface, src_info, new_tsurface, &info);
906 tbm_surface_unmap(new_tsurface);
908 if (output->backup_tbm_surface)
909 tbm_surface_destroy(output->backup_tbm_surface);
910 output->backup_tbm_surface = new_tsurface;
913 static pixman_image_t *
914 _e_rdp_pixman_output_image_get_all(E_Rdp_Output *output, Eina_List *visible_list, E_Hwc_Window *hwc_window_cursor, int e_output_w, int e_output_h)
916 tbm_surface_h tbm_surface = NULL;
917 tbm_surface_info_s info;
918 pixman_image_t *pix_surface = NULL;
919 pixman_format_code_t pix_format = 0;
921 E_Hwc_Window *hwc_window = NULL;
922 Eina_Bool target_window = EINA_TRUE;
926 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
927 EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output, NULL);
928 EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output->hwc, NULL);
930 hwc = output->primary_output->hwc;
932 tbm_surface = _e_rdp_tbm_image_create(output, output->w, output->h, 0x00000000);
933 if (tbm_surface == NULL)
935 ERR("create tbm surface failed");
936 output->prepare_tbm_surface = NULL;
940 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &info);
943 ERR("tbm_surface_map failed");
944 tbm_surface_destroy(tbm_surface);
945 output->prepare_tbm_surface = NULL;
949 pix_format = _e_rdp_pixman_format_get(info.format);
952 ERR("not supported format");
956 pix_surface = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
957 if (pix_surface == NULL)
959 ERR("create pixman image failed");
963 EINA_LIST_FOREACH(visible_list, l, hwc_window)
965 if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT)
969 target_window = EINA_FALSE;
970 _e_rdp_pixman_output_image_composite(output, (E_Hwc_Window *)hwc->target_hwc_window, pix_surface, info.width, info.height, e_output_w, e_output_h);
975 _e_rdp_pixman_output_image_composite(output, hwc_window, pix_surface, info.width, info.height, e_output_w, e_output_h);
978 if (output->refresh_count == 0)
979 _e_rdp_backup_buffer_create(output, tbm_surface, &info);
981 if (hwc_window_cursor != NULL)
982 _e_rdp_pixman_output_image_composite_cursor(output, hwc_window_cursor, pix_surface, info.width, info.height, e_output_w, e_output_h);
984 tbm_surface_unmap(tbm_surface);
986 output->prepare_tbm_surface = tbm_surface;
991 tbm_surface_unmap(tbm_surface);
992 tbm_surface_destroy(tbm_surface);
993 output->prepare_tbm_surface = NULL;
998 _e_rdp_pixman_output_image_erase_cursor(E_Rdp_Output *output)
1000 pixman_image_t *pix_backup = NULL;
1001 tbm_surface_info_s info, dst_info;
1002 pixman_format_code_t pix_format = 0;
1003 pixman_region32_t clip_region;
1004 pixman_transform_t t;
1005 struct pixman_f_transform ft;
1008 EINA_SAFETY_ON_NULL_RETURN_VAL(output->backup_tbm_surface, EINA_FALSE);
1009 EINA_SAFETY_ON_NULL_RETURN_VAL(output->showing_tbm_surface, EINA_FALSE);
1010 if (output->cursor_crop_dst.w == 0 && output->cursor_crop_dst.h == 0)
1013 err = tbm_surface_map(output->showing_tbm_surface, TBM_SURF_OPTION_WRITE, &dst_info);
1016 ERR("tbm_surface_map failed");
1020 err = tbm_surface_map(output->backup_tbm_surface, TBM_SURF_OPTION_READ, &info);
1023 ERR("tbm_surface_map failed");
1024 tbm_surface_unmap(output->showing_tbm_surface);
1028 pix_format = _e_rdp_pixman_format_get(info.format);
1029 if (pix_format == 0)
1031 ERR("not supported format");
1032 tbm_surface_unmap(output->showing_tbm_surface);
1033 tbm_surface_unmap(output->backup_tbm_surface);
1037 pix_backup = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
1038 if (pix_backup == NULL)
1040 ERR("create pixman image failed");
1041 tbm_surface_unmap(output->showing_tbm_surface);
1042 tbm_surface_unmap(output->backup_tbm_surface);
1046 pixman_image_ref(output->showing_surface);
1048 pixman_region32_init_rect(&clip_region, output->cursor_crop_dst.x, output->cursor_crop_dst.y, output->cursor_crop_dst.w, output->cursor_crop_dst.h);
1049 pixman_image_set_clip_region32(pix_backup, &clip_region);
1050 pixman_image_set_source_clipping(pix_backup, TRUE);
1051 pixman_image_set_has_client_clip (pix_backup, TRUE);
1052 pixman_f_transform_init_identity(&ft);
1053 pixman_f_transform_scale(&ft, NULL, 1, 1);
1054 pixman_f_transform_translate(&ft, NULL, 0, 0);
1055 pixman_transform_from_pixman_f_transform(&t, &ft);
1056 pixman_image_set_transform(pix_backup, &t);
1057 pixman_image_composite(PIXMAN_OP_OVER, pix_backup, NULL, output->showing_surface, 0, 0, 0, 0, 0, 0, output->w, output->h);
1059 pixman_image_unref(pix_backup);
1060 pixman_image_unref(output->showing_surface);
1061 tbm_surface_unmap(output->showing_tbm_surface);
1062 tbm_surface_unmap(output->backup_tbm_surface);
1067 static pixman_image_t *
1068 _e_rdp_pixman_output_image_get_cursor(E_Rdp_Output *output, E_Hwc_Window *hwc_window_cursor, int e_output_w, int e_output_h)
1070 tbm_surface_h tbm_surface = NULL;
1071 tbm_surface_info_s src_info, info;
1072 pixman_image_t *pix_surface = NULL;
1073 pixman_format_code_t pix_format = 0;
1075 Eina_Bool ret = EINA_FALSE;
1077 if ((output->mouse_x == hwc_window_cursor->current.info.dst_pos.x) &&
1078 (output->mouse_y == hwc_window_cursor->current.info.dst_pos.y))
1080 // INF("same position. do not update. (%dx%d)", output->mouse_x, output->mouse_y);
1084 if (_e_rdp_pixman_output_image_erase_cursor(output))
1086 err = tbm_surface_map(output->showing_tbm_surface, TBM_SURF_OPTION_WRITE, &info);
1088 ERR("tbm_surface_map failed");
1091 ret = _e_rdp_pixman_output_image_composite_cursor(output, hwc_window_cursor, output->showing_surface, info.width, info.height, e_output_w, e_output_h);
1092 tbm_surface_unmap(output->showing_tbm_surface);
1095 if (ret == EINA_TRUE)
1097 output->buffer_reuse = EINA_TRUE;
1098 pix_surface = output->showing_surface;
1099 output->prepare_tbm_surface = output->showing_tbm_surface;
1103 if (!output->buffer_reuse)
1105 err = tbm_surface_map(output->backup_tbm_surface, TBM_SURF_OPTION_READ, &src_info);
1108 ERR("tbm_surface_map failed");
1112 tbm_surface = _e_rdp_tbm_image_create(output, output->w, output->h, 0x00000000);
1113 if (tbm_surface == NULL)
1115 ERR("create tbm surface failed");
1116 output->prepare_tbm_surface = NULL;
1117 tbm_surface_unmap(output->backup_tbm_surface);
1121 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_WRITE, &info);
1124 ERR("tbm_surface_map failed");
1125 tbm_surface_destroy(tbm_surface);
1126 output->prepare_tbm_surface = NULL;
1127 tbm_surface_unmap(output->backup_tbm_surface);
1131 _e_rdp_tbm_surface_copy(output->backup_tbm_surface, &src_info, tbm_surface, &info);
1133 pix_format = _e_rdp_pixman_format_get(info.format);
1134 if (pix_format == 0)
1136 ERR("not supported format");
1137 tbm_surface_unmap(tbm_surface);
1138 tbm_surface_destroy(tbm_surface);
1139 output->prepare_tbm_surface = NULL;
1143 pix_surface = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
1144 if (pix_surface == NULL)
1146 ERR("create pixman image failed");
1147 tbm_surface_unmap(tbm_surface);
1148 tbm_surface_destroy(tbm_surface);
1149 output->prepare_tbm_surface = NULL;
1153 _e_rdp_pixman_output_image_composite_cursor(output, hwc_window_cursor, pix_surface, info.width, info.height, e_output_w, e_output_h);
1155 tbm_surface_unmap(tbm_surface);
1156 tbm_surface_unmap(output->backup_tbm_surface);
1158 output->prepare_tbm_surface = tbm_surface;
1164 static pixman_image_t *
1165 _e_rdp_pixman_output_image_get(E_Rdp_Output *output)
1167 E_Output *e_output = NULL;
1169 E_Hwc_Window *hwc_window = NULL;
1170 E_Hwc_Window *hwc_window_cursor = NULL;
1172 Eina_List *visible_list = NULL;
1173 int e_output_w, e_output_h;
1174 pixman_image_t *pix_surface = NULL;
1176 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
1178 e_output = output->primary_output;
1179 EINA_SAFETY_ON_NULL_RETURN_VAL(e_output, NULL);
1181 hwc = e_output->hwc;
1182 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
1184 e_output_w = e_output->config.mode.w;
1185 e_output_h = e_output->config.mode.h;
1187 EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
1189 if (!hwc_window) continue;
1190 if (hwc_window->is_target) continue;
1191 if (hwc_window->is_video) continue;
1192 if (hwc_window->state == E_HWC_WINDOW_STATE_NONE || hwc_window->zpos == -999) continue;
1194 if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT)
1196 visible_list = eina_list_append(visible_list, hwc_window);
1200 if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE)
1201 visible_list = eina_list_append(visible_list, hwc_window);
1203 if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CURSOR)
1205 if (hwc_window->cursor.buffer)
1207 hwc_window_cursor = hwc_window;
1212 if (eina_list_count(visible_list) == 0)
1214 ERR("no visible hwc_window for capture");
1217 visible_list = eina_list_sort(visible_list, eina_list_count(visible_list), _e_rdp_cb_hwc_window_sort);
1219 if (output->buffer_changed)
1221 pix_surface = _e_rdp_pixman_output_image_get_all(output, visible_list, hwc_window_cursor, e_output_w, e_output_h);
1223 else if ((output->mouse_moved) && (hwc_window_cursor != NULL))
1225 pix_surface = _e_rdp_pixman_output_image_get_cursor(output, hwc_window_cursor, e_output_w, e_output_h);
1232 _e_rdp_frame_timer(void *data)
1234 E_Rdp_Output *output;
1235 pixman_image_t *pix_surface = NULL;
1237 pixman_region32_t damage;
1238 E_Rdp_Peer_Item *rdp_peer, *tmp;
1239 freerdp_peer *client = NULL;
1241 EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_CANCEL);
1243 output = (E_Rdp_Output *)data;
1245 output->refresh_count--;
1246 if (output->refresh_count < 0)
1248 output->frame_timer = NULL;
1249 output->refresh_count = 0;
1250 output->mouse_moved = EINA_FALSE;
1251 output->buffer_changed = EINA_FALSE;
1253 return ECORE_CALLBACK_CANCEL;
1257 double start, end_capture, end_refresh;
1258 start = ecore_time_get();
1261 pix_surface = _e_rdp_pixman_output_image_get(output);
1262 if (pix_surface == NULL)
1265 end_capture = ecore_time_get();
1266 INF("pixman capture time (no result): %.1f ms", (end_capture - start) * 1000);
1268 return ECORE_CALLBACK_RENEW;
1272 end_capture = ecore_time_get();
1273 INF("pixman capture time: %.1f ms", (end_capture - start) * 1000);
1276 if (output->buffer_reuse)
1278 box.x1 = output->cursor_damage_rect.x;
1279 box.y1 = output->cursor_damage_rect.y;
1280 box.x2 = output->cursor_damage_rect.x + output->cursor_damage_rect.w;
1281 box.y2 = output->cursor_damage_rect.y + output->cursor_damage_rect.h;
1291 pixman_region32_init_with_extents(&damage, &box);
1293 wl_list_for_each_safe(rdp_peer, tmp, &output->peers, link)
1295 client = rdp_peer->peer;
1299 if ((rdp_peer->flags & RDP_PEER_ACTIVATED) &&
1300 (rdp_peer->flags & RDP_PEER_OUTPUT_ENABLED))
1301 e_rdp_peer_refresh_region(&damage, client, pix_surface);
1303 pixman_region32_fini(&damage);
1305 if (!output->buffer_reuse)
1307 if (output->showing_surface)
1308 pixman_image_unref(output->showing_surface);
1309 output->showing_surface = pix_surface;
1311 if (output->showing_tbm_surface)
1312 tbm_surface_destroy(output->showing_tbm_surface);
1315 output->showing_tbm_surface = output->prepare_tbm_surface;
1316 output->prepare_tbm_surface = NULL;
1317 output->buffer_reuse = EINA_FALSE;
1320 end_refresh = ecore_time_get();
1321 INF("pixman refresh time: %.1f ms", (end_refresh - end_capture) * 1000);
1324 return ECORE_CALLBACK_RENEW;
1328 _e_rdp_free_keyfile(E_Rdp_Backend *b, rdpSettings *settings)
1331 free(settings->RdpKeyFile);
1334 free(settings->CertificateFile);
1335 free(settings->PrivateKeyFile);
1340 _e_rdp_cb_client_buffer_change(void *data, int type, void *event)
1342 E_Rdp_Backend *b = NULL;
1343 E_Rdp_Output *output = NULL;
1344 E_Event_Client *ev = event;
1345 E_Client *ec = NULL;
1347 E_Hwc_Window *hwc_window = NULL;
1349 Eina_Bool find = EINA_FALSE;
1351 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1352 EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
1355 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), ECORE_CALLBACK_PASS_ON);
1356 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->pixmap, ECORE_CALLBACK_PASS_ON);
1359 EINA_SAFETY_ON_NULL_RETURN_VAL(b, ECORE_CALLBACK_PASS_ON);
1360 EINA_SAFETY_ON_NULL_RETURN_VAL(b->output, ECORE_CALLBACK_PASS_ON);
1362 if (b->client_count == 0)
1363 return ECORE_CALLBACK_PASS_ON;
1365 EINA_SAFETY_ON_NULL_RETURN_VAL(output, ECORE_CALLBACK_PASS_ON);
1366 EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output, ECORE_CALLBACK_PASS_ON);
1367 EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output->hwc, ECORE_CALLBACK_PASS_ON);
1369 hwc = output->primary_output->hwc;
1371 EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
1373 if (!hwc_window) continue;
1374 if (hwc_window->is_target) continue;
1375 if (hwc_window->is_video) continue;
1376 if (hwc_window->state == E_HWC_WINDOW_STATE_NONE || hwc_window->zpos == -999) continue;
1378 if (hwc_window == ec->hwc_window)
1385 if (find == EINA_FALSE)
1386 return ECORE_CALLBACK_PASS_ON;
1388 if (!output->frame_timer)
1390 output->refresh_count = 5;
1391 output->frame_timer = ecore_timer_add(output->refresh_time, _e_rdp_frame_timer, output);
1394 output->refresh_count = 5;
1395 output->buffer_changed = EINA_TRUE;
1397 return ECORE_CALLBACK_PASS_ON;
1401 _e_rdp_cb_client_uniconify(void *data, int type, void *event)
1403 E_Rdp_Backend *b = NULL;
1404 E_Rdp_Output *output = NULL;
1405 E_Event_Client *ev = event;
1406 E_Client *ec = NULL;
1408 E_Hwc_Window *hwc_window = NULL;
1410 Eina_Bool find = EINA_FALSE;
1412 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1413 EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
1416 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), ECORE_CALLBACK_PASS_ON);
1417 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->pixmap, ECORE_CALLBACK_PASS_ON);
1420 EINA_SAFETY_ON_NULL_RETURN_VAL(b, ECORE_CALLBACK_PASS_ON);
1421 EINA_SAFETY_ON_NULL_RETURN_VAL(b->output, ECORE_CALLBACK_PASS_ON);
1423 if (b->client_count == 0)
1424 return ECORE_CALLBACK_PASS_ON;
1426 EINA_SAFETY_ON_NULL_RETURN_VAL(output, ECORE_CALLBACK_PASS_ON);
1427 EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output, ECORE_CALLBACK_PASS_ON);
1428 EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output->hwc, ECORE_CALLBACK_PASS_ON);
1430 hwc = output->primary_output->hwc;
1432 EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
1434 if (!hwc_window) continue;
1435 if (hwc_window->is_target) continue;
1436 if (hwc_window->is_video) continue;
1438 if (hwc_window == ec->hwc_window)
1445 if (find == EINA_FALSE)
1446 return ECORE_CALLBACK_PASS_ON;
1448 if (!output->frame_timer)
1449 output->frame_timer = ecore_timer_add(output->refresh_time, _e_rdp_frame_timer, output);
1450 output->refresh_count = 5;
1451 output->buffer_changed = EINA_TRUE;
1453 return ECORE_CALLBACK_PASS_ON;
1457 _e_rdp_cb_pointer_mouse_move(void *data, E_Pointer *ptr)
1459 E_Rdp_Backend *b = NULL;
1460 E_Rdp_Output *output = NULL;
1462 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(ptr)));
1463 EINA_SAFETY_ON_FALSE_RETURN(e_comp->pointer);
1466 EINA_SAFETY_ON_NULL_RETURN(b);
1467 EINA_SAFETY_ON_NULL_RETURN(b->output);
1470 if (b->client_count == 0)
1473 if (!output->frame_timer)
1475 output->refresh_count = 5;
1476 output->frame_timer = ecore_timer_add(output->refresh_time, _e_rdp_frame_timer, output);
1479 output->refresh_count = 5;
1480 output->mouse_moved = EINA_TRUE;
1484 _e_rdp_refresh_time_set(uint32_t w, uint32_t h)
1493 if (w >= 1400 || h >= 900)
1495 else if (w >= 1024 || h >= 720)
1497 else if (w >= 800 || h >= 600)
1504 e_rdp_peer_capabilities(freerdp_peer *client)
1510 e_rdp_peer_post_connect(freerdp_peer *client)
1516 e_rdp_peer_activate(freerdp_peer *client)
1518 E_Rdp_Peer_Context *peerCtx;
1520 E_Rdp_Output *output;
1521 rdpSettings *settings;
1522 rdpPointerUpdate *pointer;
1523 E_Rdp_Peer_Item *peersItem;
1525 pixman_region32_t damage;
1526 POINTER_SYSTEM_UPDATE pointer_system;
1527 tbm_surface_h tbm_surface = NULL;
1528 pixman_image_t *pix_surface = NULL;
1530 EINA_SAFETY_ON_NULL_RETURN_VAL(client, FALSE);
1531 EINA_SAFETY_ON_NULL_RETURN_VAL(client->context, FALSE);
1532 EINA_SAFETY_ON_NULL_RETURN_VAL(client->settings, FALSE);
1534 peerCtx = (E_Rdp_Peer_Context *)client->context;
1535 EINA_SAFETY_ON_NULL_RETURN_VAL(peerCtx, FALSE);
1537 b = peerCtx->rdpBackend;
1538 EINA_SAFETY_ON_NULL_RETURN_VAL(b, FALSE);
1540 peersItem = &peerCtx->item;
1541 EINA_SAFETY_ON_NULL_RETURN_VAL(peersItem, FALSE);
1544 settings = client->settings;
1546 if (!settings->SurfaceCommandsEnabled)
1548 ERR("client doesn't support required SurfaceCommands");
1552 if (b->force_no_compression && settings->CompressionEnabled)
1554 ERR("Forcing compression off");
1555 settings->CompressionEnabled = FALSE;
1558 if (output->w != settings->DesktopWidth || output->h != settings->DesktopHeight)
1560 if (b->no_clients_resize)
1562 /* RDP peers don't dictate their resolution to e */
1563 if (!settings->DesktopResize)
1565 /* peer does not support desktop resize */
1566 ERR("%s: client doesn't support resizing, closing connection", __FUNCTION__);
1571 settings->DesktopWidth = output->w;
1572 settings->DesktopHeight = output->h;
1573 client->update->DesktopResize(client->context);
1578 output->w = settings->DesktopWidth;
1579 output->h = settings->DesktopHeight;
1583 output->mouse_scale_w = (float)output->primary_w / output->w;
1584 output->mouse_scale_h = (float)output->primary_h / output->h;
1586 rfx_context_reset(peerCtx->rfx_context, output->w, output->h);
1587 nsc_context_reset(peerCtx->nsc_context, output->w, output->h);
1588 if (peersItem->flags & RDP_PEER_ACTIVATED)
1591 /* when here it's the first reactivation, we need to setup a little more */
1592 DBG("kbd_layout:0x%x kbd_type:0x%x kbd_subType:0x%x kbd_functionKeys:0x%x",
1593 settings->KeyboardLayout, settings->KeyboardType, settings->KeyboardSubType, settings->KeyboardFunctionKey);
1595 peersItem->flags |= RDP_PEER_ACTIVATED;
1598 /* disable pointer on the client side */
1599 pointer = client->update->pointer;
1600 pointer_system.type = SYSPTR_NULL;
1601 pointer->PointerSystem(client->context, &pointer_system);
1603 if (b->client_count == 1)
1605 tbm_surface = _e_rdp_tbm_image_create(output, output->w, output->h, 0xFFFFCCFF);
1606 if (tbm_surface == NULL)
1608 ERR("create sample tbm surface failed");
1611 pix_surface = _e_rdp_pixman_image_create(tbm_surface);
1612 if (pix_surface == NULL)
1614 ERR("create sample pixman failed");
1615 tbm_surface_destroy(tbm_surface);
1619 /* sends a full refresh */
1624 pixman_region32_init_with_extents(&damage, &box);
1626 e_rdp_peer_refresh_region(&damage, client, pix_surface);
1628 pixman_region32_fini(&damage);
1630 output->showing_surface = pix_surface;
1631 output->showing_tbm_surface = tbm_surface;
1633 if (output->frame_timer != NULL)
1634 ecore_timer_del(output->frame_timer);
1635 output->refresh_time = _e_rdp_refresh_time_set(output->w, output->h);
1636 output->refresh_count = 5;
1637 output->frame_timer = ecore_timer_add(output->refresh_time, _e_rdp_frame_timer, output);
1638 output->buffer_changed = EINA_TRUE;
1640 e_video_debug_display_primary_plane_set(EINA_TRUE);
1644 output->refresh_count = 5;
1645 output->buffer_changed = EINA_TRUE;
1652 e_rdp_suppress_output(rdpContext *context, BYTE allow, const RECTANGLE_16 *area)
1654 E_Rdp_Peer_Context *peerContext = (E_Rdp_Peer_Context *)context;
1657 peerContext->item.flags |= RDP_PEER_OUTPUT_ENABLED;
1659 peerContext->item.flags &= (~RDP_PEER_OUTPUT_ENABLED);
1665 e_rdp_input_synchronize_event(rdpInput *input, UINT32 flags)
1667 E_Rdp_Peer_Context *peerContext = (E_Rdp_Peer_Context *)input->context;
1668 E_Rdp_Output *output = peerContext->rdpBackend->output;
1669 E_Rdp_Backend *b = NULL;
1671 DBG("e_rdp_input_synchronize_event");
1674 EINA_SAFETY_ON_NULL_RETURN_VAL(b, FALSE);
1675 EINA_SAFETY_ON_NULL_RETURN_VAL(b->output, FALSE);
1677 if (output != b->output)
1680 if (b->client_count == 0)
1683 if (!output->frame_timer)
1685 output->refresh_count = 5;
1686 output->frame_timer = ecore_timer_add(output->refresh_time, _e_rdp_frame_timer, output);
1689 output->refresh_count = 5;
1690 output->buffer_changed = EINA_TRUE;
1696 e_rdp_mouse_event(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y)
1698 int e_output_w, e_output_h;
1699 int move_x = 0, move_y = 0;
1701 uint32_t button = 0;
1704 E_Rdp_Peer_Context *peerContext = (E_Rdp_Peer_Context *)input->context;
1705 E_Rdp_Output *output = peerContext->rdpBackend->output;
1706 E_Output *e_output = output->primary_output;
1707 e_output_w = e_output->config.mode.w;
1708 e_output_h = e_output->config.mode.h;
1709 motionless = peerContext->rdpBackend->motionless;
1711 if (flags & PTR_FLAGS_MOVE && !motionless)
1713 if (x < e_output_w && y < e_output_h)
1715 state = E_INFO_EVENT_STATE_MOTION;
1716 move_x = (int)((int)(x - output->prev_x) * output->mouse_scale_w);
1717 move_y = (int)((int)(y - output->prev_y) * output->mouse_scale_h);
1723 if (flags & PTR_FLAGS_BUTTON1)
1725 else if (flags & PTR_FLAGS_BUTTON2)
1727 else if (flags & PTR_FLAGS_BUTTON3)
1728 button = BTN_MIDDLE;
1731 state = (flags & PTR_FLAGS_DOWN) ? E_INFO_EVENT_STATE_PRESS : E_INFO_EVENT_STATE_RELEASE;
1733 if (flags & PTR_FLAGS_WHEEL)
1736 value = (flags & 0xff) / 120.0;
1738 button = E_INFO_BUTTON_WHEEL;
1739 state = E_INFO_EVENT_STATE_MOTION;
1741 if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
1744 move_x = (int)value;
1748 e_info_server_input_mousegen(button, move_x, move_y, state);
1751 if (!(flags & PTR_FLAGS_MOVE))
1753 if (x < e_output_w && y < e_output_h)
1755 move_x = (int)((int)(x - output->prev_x) * output->mouse_scale_w);
1756 move_y = (int)((int)(y - output->prev_y) * output->mouse_scale_h);
1761 e_info_server_input_mousegen(0, move_x, move_y, E_INFO_EVENT_STATE_MOTION);
1762 e_info_server_input_mousegen(button, move_x, move_y, state);
1770 e_rdp_extended_mouse_event(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y)
1773 DBG("e_rdp_extended_mouse_event");
1778 e_rdp_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
1783 char name[16] = {0,};
1785 E_Rdp_Peer_Context *peerContext = (E_Rdp_Peer_Context *)input->context;
1787 if (!(peerContext->item.flags & RDP_PEER_ACTIVATED))
1790 if (flags & KBD_FLAGS_DOWN)
1792 key_state = E_INFO_EVENT_STATE_PRESS;
1795 else if (flags & KBD_FLAGS_RELEASE)
1797 key_state = E_INFO_EVENT_STATE_RELEASE;
1804 DBG("rdp key kernel fullcode = %d", full_code);
1806 // Todo. check extended role
1808 e_info_server_input_keygen(name, full_code + 8, key_state);
1815 e_rdp_input_unicode_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
1817 DBG("Client sent a unicode keyboard event (flags:0x%X code:0x%X)", flags, code);
1822 e_rdp_client_activity(int fd, uint32_t mask, void *data)
1824 freerdp_peer *client = (freerdp_peer *)data;
1825 E_Rdp_Peer_Context *peerCtx;
1827 E_Rdp_Output *output;
1829 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1830 EINA_SAFETY_ON_NULL_RETURN_VAL(client->context, 0);
1832 if (client->CheckFileDescriptor(client))
1834 // DBG("enable client activity %p", client);
1838 INF("unable to checkDescriptor for %p", client);
1839 peerCtx = (E_Rdp_Peer_Context *)client->context;
1840 EINA_SAFETY_ON_NULL_GOTO(peerCtx, out_clean);
1842 b = peerCtx->rdpBackend;
1843 EINA_SAFETY_ON_NULL_GOTO(b, out_clean);
1845 if (peerCtx->item.flags & RDP_PEER_ACTIVATED)
1849 if (output && b->client_count == 0)
1851 if (output->frame_timer)
1853 ecore_timer_del(output->frame_timer);
1854 output->frame_timer = NULL;
1856 if (output->showing_surface)
1858 pixman_image_unref(output->showing_surface);
1859 output->showing_surface = NULL;
1861 if (output->prepare_tbm_surface)
1863 tbm_surface_destroy(output->prepare_tbm_surface);
1864 output->prepare_tbm_surface = NULL;
1866 if (output->showing_tbm_surface)
1868 tbm_surface_destroy(output->showing_tbm_surface);
1869 output->showing_tbm_surface = NULL;
1871 if (output->backup_tbm_surface)
1873 tbm_surface_destroy(output->backup_tbm_surface);
1874 output->backup_tbm_surface = NULL;
1877 e_video_debug_display_primary_plane_set(EINA_FALSE);
1881 freerdp_peer_context_free(client);
1882 freerdp_peer_free(client);
1887 e_rdp_peer_context_new(freerdp_peer *client, E_Rdp_Peer_Context *context)
1889 context->item.peer = client;
1890 context->item.flags = RDP_PEER_OUTPUT_ENABLED;
1892 context->rfx_context = rfx_context_new(TRUE);
1893 if (!context->rfx_context)
1896 context->rfx_context->mode = RLGR3;
1897 context->rfx_context->width = client->settings->DesktopWidth;
1898 context->rfx_context->height = client->settings->DesktopHeight;
1899 rfx_context_set_pixel_format(context->rfx_context, DEFAULT_PIXEL_FORMAT);
1901 context->nsc_context = nsc_context_new();
1902 if (!context->nsc_context)
1905 nsc_context_set_parameters(context->nsc_context, NSC_COLOR_FORMAT, DEFAULT_PIXEL_FORMAT);
1906 context->encode_stream = Stream_New(NULL, 65536);
1907 if (!context->encode_stream)
1908 goto out_error_stream;
1913 rfx_context_free(context->rfx_context);
1915 nsc_context_free(context->nsc_context);
1920 e_rdp_peer_context_free(freerdp_peer *client, E_Rdp_Peer_Context *context)
1926 wl_list_remove(&context->item.link);
1927 for (i = 0; i < MAX_FREERDP_FDS; i++)
1929 if (context->events[i])
1930 wl_event_source_remove(context->events[i]);
1933 Stream_Free(context->encode_stream, TRUE);
1934 nsc_context_free(context->nsc_context);
1935 rfx_context_free(context->rfx_context);
1936 free(context->rfx_rects);
1941 e_rdp_peer_init(freerdp_peer *client, E_Rdp_Backend *b)
1944 void *rfds[MAX_FREERDP_FDS];
1946 struct wl_event_loop *loop;
1947 char *device_name = NULL, *result = NULL;
1948 unsigned int device_type = 0x0;
1949 rdpSettings *settings;
1951 E_Rdp_Peer_Context *peerCtx;
1953 client->ContextSize = sizeof(E_Rdp_Peer_Context);
1954 client->ContextNew = (psPeerContextNew)e_rdp_peer_context_new;
1955 client->ContextFree = (psPeerContextFree)e_rdp_peer_context_free;
1956 freerdp_peer_context_new(client);
1958 peerCtx = (E_Rdp_Peer_Context *)client->context;
1959 peerCtx->rdpBackend = b;
1961 settings = client->settings;
1964 settings->RdpKeyFile = strdup(b->rdp_key);
1968 settings->CertificateFile = strdup(b->server_cert);
1969 settings->PrivateKeyFile = strdup(b->server_key);
1973 settings->TlsSecurity = FALSE;
1975 settings->NlaSecurity = FALSE;
1977 if (!client->Initialize(client))
1979 ERR("peer initialization failed");
1980 _e_rdp_free_keyfile(b, settings);
1984 settings->OsMajorType = OSMAJORTYPE_UNIX;
1985 settings->OsMinorType = OSMINORTYPE_NATIVE_WAYLAND;
1986 settings->ColorDepth = 32;
1987 settings->RefreshRect = TRUE;
1988 settings->RemoteFxCodec = TRUE;
1989 settings->NSCodec = TRUE;
1990 settings->FrameMarkerCommandEnabled = TRUE;
1991 settings->SurfaceFrameMarkerEnabled = TRUE;
1993 client->Capabilities = e_rdp_peer_capabilities;
1994 client->PostConnect = e_rdp_peer_post_connect;
1995 client->Activate = e_rdp_peer_activate;
1997 client->update->SuppressOutput = (pSuppressOutput)e_rdp_suppress_output;
1999 device_type = E_INPUT_SEAT_POINTER | E_INPUT_SEAT_TOUCH | E_INPUT_SEAT_KEYBOARD;
2000 device_name = E_RDP_DEVICE_NAME;
2001 result = e_info_server_input_init_device(device_type, device_name);
2003 if (e_util_strcmp(result, E_INFO_INPUT_RESULT_NONE))
2005 e_info_server_input_deinit_device();
2006 result = e_info_server_input_init_device(device_type, device_name);
2009 DBG("rdp peer init | init input device | result = %s", result);
2011 input = client->input;
2012 input->SynchronizeEvent = e_rdp_input_synchronize_event;
2013 input->MouseEvent = e_rdp_mouse_event;
2014 input->ExtendedMouseEvent = e_rdp_extended_mouse_event;
2015 input->KeyboardEvent = e_rdp_input_keyboard_event;
2016 input->UnicodeKeyboardEvent = e_rdp_input_unicode_keyboard_event;
2018 if (!client->GetFileDescriptor(client, rfds, &rcount))
2020 ERR("unable to retrieve client fds");
2021 goto error_initialize;
2024 if (rcount > MAX_FREERDP_FDS)
2026 ERR("check fds max count. count:%d, max:%d", rcount, MAX_FREERDP_FDS);
2027 goto error_initialize;
2030 loop = wl_display_get_event_loop(e_comp_wl->wl.disp);
2031 for (i = 0; i < rcount; i++)
2033 fd = (int)(long)(rfds[i]);
2035 peerCtx->events[i] = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, e_rdp_client_activity, client);
2037 for ( ; i < MAX_FREERDP_FDS; i++)
2038 peerCtx->events[i] = 0;
2040 wl_list_insert(&b->output->peers, &peerCtx->item.link);
2044 _e_rdp_free_keyfile(b, settings);
2045 client->Close(client);
2050 e_rdp_incoming_peer(freerdp_listener *instance, freerdp_peer *client)
2052 E_Rdp_Backend *b = (E_Rdp_Backend *)instance->param4;
2054 if (e_rdp_peer_init(client, b) < 0)
2056 ERR("error when treating incoming peer");
2064 e_rdp_listener_activity(int fd, uint32_t mask, void *data)
2066 freerdp_listener* instance = (freerdp_listener *)data;
2068 if (!(mask & WL_EVENT_READABLE))
2071 if (!instance->CheckFileDescriptor(instance))
2073 ERR("failed to check FreeRDP file descriptor");
2081 e_rdp_implant_listener(E_Rdp_Backend *b, freerdp_listener *instance)
2085 void* rfds[MAX_FREERDP_FDS];
2086 struct wl_event_loop *loop;
2088 if (!instance->GetFileDescriptor(instance, rfds, &rcount))
2090 ERR("Failed to get FreeRDP file descriptor");
2094 loop = wl_display_get_event_loop(e_comp_wl->wl.disp);
2095 for (i = 0; i < rcount; i++)
2097 fd = (int)(long)(rfds[i]);
2098 b->listener_events[i] = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, e_rdp_listener_activity, instance);
2101 for ( ; i < MAX_FREERDP_FDS; i++)
2102 b->listener_events[i] = 0;
2108 e_rdp_output_destroy(E_Rdp_Output *output)
2110 EINA_SAFETY_ON_NULL_RETURN(output);
2112 if (output->showing_surface)
2113 pixman_image_unref(output->showing_surface);
2114 if (output->prepare_tbm_surface)
2115 tbm_surface_destroy(output->prepare_tbm_surface);
2116 if (output->showing_tbm_surface)
2117 tbm_surface_destroy(output->showing_tbm_surface);
2118 if (output->backup_tbm_surface)
2119 tbm_surface_destroy(output->backup_tbm_surface);
2125 e_rdp_output_create(void)
2127 E_Rdp_Output *output = NULL;
2129 E_Output_Mode *emode = NULL;
2130 Eina_Bool mode = EINA_FALSE;
2132 output = E_NEW(E_Rdp_Output, 1);
2133 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
2135 output->primary_output = e_output_find_by_index(0);
2137 EINA_LIST_FOREACH(output->primary_output->info.modes, l, emode)
2141 output->primary_w = emode->w;
2142 output->primary_h = emode->h;
2143 output->w = emode->w / 2;
2144 output->h = emode->h / 2;
2149 if (mode == EINA_FALSE)
2151 output->w = E_RDP_WIDTH;
2152 output->h = E_RDP_HEIGHT;
2155 output->prev_x = output->prev_y = 0;
2157 wl_list_init(&output->peers);
2163 e_rdp_backend_destroy(void)
2165 E_Rdp_Backend *b = NULL;
2166 E_Rdp_Peer_Item *rdp_peer, *tmp;
2167 Ecore_Event_Handler *h = NULL;
2171 EINA_SAFETY_ON_NULL_RETURN(b);
2175 e_pointer_hook_del(pointer_hook);
2176 pointer_hook = NULL;
2180 EINA_LIST_FREE(b->handlers, h)
2181 ecore_event_handler_del(h);
2185 if (b->output->frame_timer)
2187 ecore_timer_del(b->output->frame_timer);
2188 b->output->frame_timer = NULL;
2191 wl_list_for_each_safe(rdp_peer, tmp, &b->output->peers, link)
2193 freerdp_peer* client = rdp_peer->peer;
2195 client->Disconnect(client);
2196 freerdp_peer_context_free(client);
2197 freerdp_peer_free(client);
2200 for (i = 0; i < MAX_FREERDP_FDS; i++)
2201 if (b->listener_events[i])
2202 wl_event_source_remove(b->listener_events[i]);
2204 freerdp_listener_free(b->listener);
2206 e_rdp_output_destroy(b->output);
2212 free(b->server_cert);
2213 free(b->server_key);
2220 e_rdp_backend_create(E_Rdp_Conf_Edd *config)
2224 b = E_NEW(E_Rdp_Backend, 1);
2225 EINA_SAFETY_ON_NULL_RETURN_VAL(b, EINA_FALSE);
2227 b->no_clients_resize = config->no_clients_resize;
2228 b->force_no_compression = config->force_no_compression;
2229 b->motionless = config->motionless;
2231 if (config->rdp_key)
2233 b->rdp_key = strdup(config->rdp_key);
2238 /* activate TLS only if certificate/key are available */
2239 if (config->server_cert && config->server_key)
2241 DBG("TLS support activated");
2242 b->server_cert = strdup(config->server_cert);
2243 b->server_key = strdup(config->server_key);
2244 if (!b->server_cert || !b->server_key)
2249 b->output = e_rdp_output_create();
2252 ERR("output create failed");
2253 goto err_output_create;
2256 b->listener = freerdp_listener_new();
2257 b->listener->PeerAccepted = e_rdp_incoming_peer;
2258 b->listener->param4 = b;
2259 if (!b->listener->Open(b->listener, NULL, config->port))
2261 ERR("unable to bind rdp socket");
2265 if (e_rdp_implant_listener(b, b->listener) == EINA_FALSE)
2268 E_LIST_HANDLER_APPEND(b->handlers, E_EVENT_CLIENT_BUFFER_CHANGE, _e_rdp_cb_client_buffer_change, g_rdp_backend);
2269 E_LIST_HANDLER_APPEND(b->handlers, E_EVENT_CLIENT_UNICONIFY, _e_rdp_cb_client_uniconify, g_rdp_backend);
2270 pointer_hook = e_pointer_hook_add(E_POINTER_HOOK_MOUSE_MOVE, _e_rdp_cb_pointer_mouse_move, g_rdp_backend);
2277 freerdp_listener_free(b->listener);
2279 e_rdp_output_destroy(b->output);
2285 free(b->server_cert);
2287 free(b->server_key);
2296 e_mod_rdp_init(void)
2298 int major, minor, revision;
2299 Eina_Bool ret = EINA_FALSE;
2301 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
2302 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->wl.disp, EINA_FALSE);
2304 #if FREERDP_VERSION_MAJOR >= 2
2305 winpr_InitializeSSL(0);
2308 freerdp_get_version(&major, &minor, &revision);
2309 if (major < E_MOD_RDP_CONFIG_VERSION)
2311 ERR("Not supported version");
2314 INF("freerdp version : %d.%d.%d", major, minor, revision);
2318 g_rdp_config = E_NEW(E_Rdp_Config_Data, 1);
2319 EINA_SAFETY_ON_NULL_RETURN_VAL(g_rdp_config, EINA_FALSE);
2321 ret = e_rdp_conf_init(g_rdp_config);
2322 EINA_SAFETY_ON_FALSE_GOTO(ret, conf_err);
2324 ret = e_rdp_backend_create(g_rdp_config->conf);
2325 EINA_SAFETY_ON_FALSE_GOTO(ret, create_err);
2330 e_rdp_conf_deinit(g_rdp_config);
2332 E_FREE(g_rdp_config);
2338 e_mod_rdp_deinit(void)
2340 e_info_server_input_deinit_device();
2341 e_rdp_backend_destroy();
2344 e_rdp_conf_deinit(g_rdp_config);
2345 E_FREE(g_rdp_config);