Write an RDP client that resets screen pixels

I would like to implement an RDP client in C++ , which can get the color value of all the pixels on the screen and upload them to a file. I know this is fundamentally different from how RDP works, but I need it for my application. I'm trying to use freerdp , but I'm not sure how I can efficiently write a client that simply flushes all the pixels in the file.

So far, my best attempt is to use the gdi_GetPixel_32bpp function, but, of course, calling this function for each pixel is in turn far from efficient.

A solution using a different library will also be evaluated.

+6
source share
4 answers

This is pretty easy to do in a very efficient way using libfreerdp-gdi. FreeRDP can display everything in a software buffer, which can then be uploaded to a file, and you can do this completely in memory without the X11 environment if you want. Since Linux is mentioned, one quick way to get started would be to use xfreerdp with the / gdi: sw option to use libfreerdp-gdi (the default is an X11-based implementation) and then reset the pixels as updates. You can connect to xf_sw_end_paint, which is called at the end of the update array. You have access to an invalid region and pixel buffer (everything in the rdpGdi * gdi structure). Important fields are gdi-> primary_buffer, gdi-> dstBpp, gdi-> bytesPerPixel, gdi-> width and gdi-> height. In most cases, you get an XRGB32 buffer that is easy to handle. In doubt, look at gdi_init () to initialize the internal buffer.

+1
source

Well, you could try this (discarding unverified pseudocode):

 HGDI_DC memDC = gdi_CreateCompatibleDC ( hDC ); HGDI_BITMAP memBM = gdi_CreateCompatibleBitmap ( hDC, screenWidth, screenHeight ); gdi_SelectObject ( memDC, memBM ); gdi_BitBlt(memDC, 0, 0, screenWidth, screenHeight, hDC, 0, 0, GDI_SRCCOPY); 

You should now have a full array of pixel data in memBM->data . memBM-> has the following size: memBM->width * memBM->height * memBM->bytesPerPixel

Hope this helps you at least a little.

0
source

If you start the VNC X server and run the full RDP client screen inside it (without a window manager, etc.), the drawing sequence should look something like this:

  • RDP client receives update from a remote session
  • The RDP client translates the update into X11 messages, most likely sent over the shared memory transport memory.
  • The VNC server accepts X11 requests and uses them to render a bitmap

therefore, the overhead should just be the X11 protocol, which is admittedly awkward, but at least should be sent through a shared memory segment.

Honestly, I would try this null-coding approach and see if performance is really a problem.

0
source

WebRTC may have some code that you can look at, for example, screen capture or window capture .

Capturing the desktop is more difficult because it (1) differs in that it takes up minimal content, and (2) captures the mouse. Since the desktop is just a special β€œwindow” obtained using ::GetDesktopWindow() , and its DC can be obtained using this window or only GetDC(NULL) , you can use window capture and ignore more complex bits. Check out the Capture window capture feature for details, as well as some helpful tips on handling Aero and other layout / shutdown issues.

0
source

All Articles