Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes some problems with monitor hotplug #2942

Merged
merged 12 commits into from
Feb 20, 2024

Conversation

matt335672
Copy link
Member

See #2938

This fixes some monitor hotplug issues with non-GFX codepaths:-

  1. The server_version_message() was working on an out-of-date copy of the client_info. As a result, the X server and the window manager did not agree on the number of screens. This is fixed by updating the client_info copy that the module holds before calling server_version_message().
  2. As a result of 1), an OOB memory access was generated in the VNC module. This is now fixed.

non-GFX

Monitor removal for works OK after applying the patch. However, when adding a monitor we end up with a single screen on the client covering the whole desktop.

GFX

The removal of a monitor sort-of works, but there are major screen corruption problems. When adding a monitor we get a protocol error when we try to use the added monitor.

Analysis

When we add a monitor, or remove a monitor (leaving more than one) mstsc.exe generates a dynamic monitor update request with two monitors included. Up until now we have not been able to generate this use-case.

The problem happens when libxrdp_reset() is called. This forces a single monitor at the client end for a multi-monitor setup. As a result, we can end up with the X server and the client not agreeing on the number of outputs, which is where the protocol errors come from.

I think we're missing a monitor layout PDU from the server to the client. This should be sent after the demand active PDU - see [MSRDPBCGR] 1.3.11, in particular note 9.

There's one other GFX problem which may be cured by fixing the above. After a resize, I get valgrind memory errors:-

=57080== Conditional jump or move depends on uninitialised value(s)
==57080==    at 0x489C257: fpack (xrdp_bitmap32_compress.c:334)
==57080==    by 0x489CB76: xrdp_bitmap32_compress (xrdp_bitmap32_compress.c:518)
==57080==    by 0x489B459: libxrdp_planar_compress (libxrdp.c:2284)
==57080==    by 0x1266A7: xrdp_mm_egfx_send_planar_bitmap (xrdp_mm.c:1049)
==57080==    by 0x12CF59: xrdp_mm_draw_dirty (xrdp_mm.c:3565)
==57080==    by 0x12D3E4: xrdp_mm_check_wait_objs (xrdp_mm.c:3704)
==57080==    by 0x13FFAC: xrdp_wm_check_wait_objs (xrdp_wm.c:2351)
==57080==    by 0x133EDE: xrdp_process_main_loop (xrdp_process.c:287)
==57080==    by 0x11C066: xrdp_process_run (xrdp_listen.c:152)
==57080==    by 0x11D6CB: xrdp_listen_fork (xrdp_listen.c:802)
==57080==    by 0x11DC80: xrdp_listen_main_loop (xrdp_listen.c:987)
==57080==    by 0x10FD61: main (xrdp.c:580)
==57080== 
==57080== Conditional jump or move depends on uninitialised value(s)
==57080==    at 0x489C290: fpack (xrdp_bitmap32_compress.c:346)
==57080==    by 0x489CB76: xrdp_bitmap32_compress (xrdp_bitmap32_compress.c:518)
==57080==    by 0x489B459: libxrdp_planar_compress (libxrdp.c:2284)
==57080==    by 0x1266A7: xrdp_mm_egfx_send_planar_bitmap (xrdp_mm.c:1049)
==57080==    by 0x12CF59: xrdp_mm_draw_dirty (xrdp_mm.c:3565)
==57080==    by 0x12D3E4: xrdp_mm_check_wait_objs (xrdp_mm.c:3704)
==57080==    by 0x13FFAC: xrdp_wm_check_wait_objs (xrdp_wm.c:2351)
==57080==    by 0x133EDE: xrdp_process_main_loop (xrdp_process.c:287)
==57080==    by 0x11C066: xrdp_process_run (xrdp_listen.c:152)
==57080==    by 0x11D6CB: xrdp_listen_fork (xrdp_listen.c:802)
==57080==    by 0x11DC80: xrdp_listen_main_loop (xrdp_listen.c:987)
==57080==    by 0x10FD61: main (xrdp.c:580)
==57080== 

I think the next step is to update libxrdp_reset() to send the monitor configuration (if known) after the demand active PDU. This isn't going to be quick.

Thoughts and suggestions are extremely welcome.

@matt335672
Copy link
Member Author

My mistake - we are sending the monitor configuration. It's just hidden away in xrdp_caps_send_demand_active().

@matt335672
Copy link
Member Author

Out of time today, but working on adding multi-monitor support around libxrdp_reset(). Plan is to test with VNC (as it's simple) then update xup. No idea what to do with Neutrino yet!

@@ -1153,15 +1153,6 @@ libxrdp_reset(struct xrdp_session *session,
return 0;
}

/* if same (and only one monitor on client) don't need to do anything */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this? It doesn't appear to affect multi-mon?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question!

The answer is that at the moment, when we go from two monitors to one, client_info->multimon gets reset. As a result this test succeeds and we don't send the signal back to the state machine that the resize has completed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well then I utterly failed at making this call do what I thought it did, thanks for removing it then!

vnc/vnc.c Outdated
@@ -2133,6 +2133,7 @@ lib_mod_set_param(struct vnc *v, const char *name, const char *value)
(const struct xrdp_client_info *) value;

g_free(v->client_layout.s);
v->client_layout.count = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also set v->client_layout.s to NULL here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite right, although I'm probably going to make v->client_layout.s static anyway as it simplifies the logic quite a bit at the cost of a bit more memory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory is cheap, bugs are not :)

xrdp/xrdp_mm.c Outdated
/* Update the client_info structure with the new description
* and tell the module so it can communicate the new
* screen layout to the backend */
sync_dynamic_monitor_data(wm, &(description->description));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

@Nexarian
Copy link
Contributor

Nexarian commented Feb 9, 2024

Added some comments.

@matt335672
Copy link
Member Author

Thanks @Nexarian

I've got most of Monday to get on with this.

One of the architectural problems we've got is the server_reset() call from the module:-

  1. This doesn't currently allow for the module to request a client resize for anything other than a single monitor scenario.
  2. We've overloaded this function by making the call with bpp == 0 to signal that the resize state machine can move to the WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED state.

I'm going to look into splitting this call into two:-

  1. First call is client_resize() which takes a monitor list rather than width+height. This will just add an entry to your resize state machine queue, thus unifying the two resize mechanisms we have.
  2. Second call is the call to kick the state machine. I've not thought of a name for that yet.

How does that sound?

@Nexarian
Copy link
Contributor

I agree that the server_reset overload I did with bpp == 0 was a hack. It was necessary to make sure that xorgxrdp was truly ready. Before that, any draw commands that xorgxrdp might send would be suspect/corrupted. And yes, it was only focused on a single monitor which now needs to change.

So yes, doing more attention with that is definitely warranted, so yes sounds good!

I'll wait on approving/merging this until you say "this is ready to merge" or some such.

@matt335672
Copy link
Member Author

I've done the following (in a separate branch):-

  1. Added some monitors to the module mod_server_monitor_resize method so that a number of monitors can be passed in.
  2. Split server_reset() into *client_monitor_resize() and server_monitor_resize_done() functions.

client_monitor_resize() now just queues up a packet for the resize state machine, so the only resetting is now done there.

It's still a bit messy, so I've got nothing to release yet.

@Nexarian - a question for you. The X server resize is currently done by calling two methods on the module - mod_server_monitor_resize() and mod_server_version_message(). Is there a good reason why we don't just do this in one call? In xorgxrdp it should be a question of re-allocating the virtual memory and using xrandr to tell the X clients what's going on. Or am I missing something?

@Nexarian
Copy link
Contributor

@matt335672 I wrote this a long time ago, but the reasons are either:

  • Resizing stability concerns. I think for some reason it simply broke resizing if I tried to combine them.
  • Compartmentalization. Simply keeping separate signals as part of keeping each step as atomic as possible.

If you can find a way to combine them without breaking anything, go for it.

@matt335672
Copy link
Member Author

Added a commit which is simple to understand, and necessary to get the monitor layout PDU working correctly with mstsc.exe.

Informally, I think I've cracked the monitor plugging/unplugging issue now - at least it seems to work on my laptop with a single external monitor being plugged and unplugged.

Current code is here. I need to work more on the commit history and do a lot more testing so these are subject to change. It's not really in a reviewable state, but comments welcome anyway:-

xrdp: fix_monitor_hotplug_tmp https://github.com/matt335672/xrdp/tree/fix_monitor_hotplug_tmp
xorgxrdp: fix_monitor_hotplug https://github.com/matt335672/xorgxrdp/tree/fix_monitor_hotplug

At the moment on my setup:-

Protocol backend Hotplug status
non-GFX Xorg Seems to work
non-GFX VNC Seems to work
GFX Xorg Getting a lot of screen corruption following the resize
GFX VNC Seems to work

I've added a new message (302) to the interface from xup to xorgxrdp to send over the monitor list. Consequently I can retire the resize desktop message (300) as it is no longer required.

@Nexarian
Copy link
Contributor

Now you know the pain that is resizing :)

@metalefty
Copy link
Member

metalefty commented Feb 15, 2024

Thanks, I did a quick test on your branch of the GFX+Xorg scenario. To be precise, cherry-picked your commits to v0.10 branch.

I found some resizing issues with using only 1 of N (>=2) monitors.

Prerequisites:
The client must have at least two monitors with different sizes.

  1. Connect from mstsc in fullscreen with "use all my monitors for the remote session" turned off
  2. Move mstsc to another monitor
  3. Make the mstsc window full screen again (resize will happen)
  4. The session will freeze
  5. Disconnect session
  6. Segfault occurs when reconnecting to the session (see log)
xorgxrdp.10.log
[1124380.425] 
X.Org X Server 1.20.11
X Protocol Version 11, Revision 0
[1124380.425] Build Operating System:  4.18.0-477.13.1.el8_8.x86_64 
[1124380.425] Current Operating System: Linux a9xrdp 5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 7 14:54:22 EST 2023 x86_64
[1124380.425] Kernel command line: BOOT_IMAGE=(hd0,gpt3)/vmlinuz-5.14.0-362.8.1.el9_3.x86_64 root=UUID=280b97cf-dfc4-4d92-8670-aa43d13f5b51 ro console=tty0 console=ttyS0,115200n8 no_timer_check biosdevname=0 net.ifnames=0 crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M
[1124380.425] Build Date: 06 June 2023  12:00:00AM
[1124380.425] Build ID: xorg-x11-server 1.20.11-19.el9 
[1124380.425] Current version of pixman: 0.40.0
[1124380.425] 	Before reporting problems, check http://wiki.x.org
	to make sure that you have the latest version.
[1124380.425] Markers: (--) probed, (**) from config file, (==) default setting,
	(++) from command line, (!!) notice, (II) informational,
	(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
[1124380.426] (++) Log file: ".xorgxrdp.10.log", Time: Thu Feb 15 01:05:21 2024
[1124380.426] (++) Using config file: "/etc/X11/xrdp/xorg.conf"
[1124380.426] (==) Using config directory: "/etc/X11/xorg.conf.d"
[1124380.426] (==) Using system config directory "/usr/share/X11/xorg.conf.d"
[1124380.426] (**) Option "defaultserverlayout" "X11 Server"
[1124380.426] (**) ServerLayout "X11 Server"
[1124380.426] (**) |-->Screen "Screen (xrdpdev)" (0)
[1124380.426] (**) |   |-->Monitor "Monitor"
[1124380.427] (**) |   |-->Device "Video Card (xrdpdev)"
[1124380.427] (**) |-->Input Device "xrdpMouse"
[1124380.427] (**) |-->Input Device "xrdpKeyboard"
[1124380.427] (**) Option "DontVTSwitch" "on"
[1124380.427] (**) Option "AutoAddDevices" "off"
[1124380.427] (**) Option "AutoAddGPU" "off"
[1124380.427] (**) Not automatically adding devices
[1124380.427] (==) Automatically enabling devices
[1124380.427] (**) Not automatically adding GPU devices
[1124380.427] (==) Automatically binding GPU devices
[1124380.427] (==) Max clients allowed: 256, resource mask: 0x1fffff
[1124380.427] (==) FontPath set to:
	catalogue:/etc/X11/fontpath.d,
	built-ins
[1124380.427] (==) ModulePath set to "/usr/lib64/xorg/modules"
[1124380.427] (II) Loader magic: 0x556894f08d40
[1124380.427] (II) Module ABI versions:
[1124380.427] 	X.Org ANSI C Emulation: 0.4
[1124380.427] 	X.Org Video Driver: 24.1
[1124380.427] 	X.Org XInput driver : 24.1
[1124380.427] 	X.Org Server Extension : 10.0
[1124380.431] (II) systemd-logind: took control of session /org/freedesktop/login1/session/c21
[1124380.433] (II) no primary bus or device found
[1124380.433] (II) "glx" will be loaded. This was enabled by default and also specified in the config file.
[1124380.433] (II) LoadModule: "dbe"
[1124380.433] (II) Module "dbe" already built-in
[1124380.433] (II) LoadModule: "ddc"
[1124380.433] (II) Module "ddc" already built-in
[1124380.433] (II) LoadModule: "extmod"
[1124380.433] (II) Module "extmod" already built-in
[1124380.433] (II) LoadModule: "glx"
[1124380.433] (II) Loading /usr/lib64/xorg/modules/extensions/libglx.so
[1124380.436] (II) Module glx: vendor="X.Org Foundation"
[1124380.436] 	compiled for 1.20.11, module version = 1.0.0
[1124380.436] 	ABI class: X.Org Server Extension, version 10.0
[1124380.436] (II) LoadModule: "int10"
[1124380.436] (WW) Warning, couldn't open module int10
[1124380.436] (EE) Failed to load module "int10" (module does not exist, 0)
[1124380.436] (II) LoadModule: "record"
[1124380.436] (II) Module "record" already built-in
[1124380.436] (II) LoadModule: "vbe"
[1124380.436] (WW) Warning, couldn't open module vbe
[1124380.436] (EE) Failed to load module "vbe" (module does not exist, 0)
[1124380.436] (II) LoadModule: "xorgxrdp"
[1124380.437] (II) Loading /usr/lib64/xorg/modules/libxorgxrdp.so
[1124380.437] (II) Module XORGXRDP: vendor="X.Org Foundation"
[1124380.437] 	compiled for 1.20.11, module version = 0.9.90
[1124380.437] 	ABI class: X.Org Video Driver, version 24.1
[1124380.437] xorgxrdpSetup:
[1124380.437] (II) LoadModule: "fb"
[1124380.437] (II) Module "fb" already built-in
[1124380.437] (II) LoadModule: "xrdpdev"
[1124380.437] (II) Loading /usr/lib64/xorg/modules/drivers/xrdpdev_drv.so
[1124380.437] (II) Module XRDPDEV: vendor="X.Org Foundation"
[1124380.437] 	compiled for 1.20.11, module version = 0.9.90
[1124380.437] 	ABI class: X.Org Video Driver, version 24.1
[1124380.437] xrdpdevSetup:
[1124380.437] (II) LoadModule: "xrdpmouse"
[1124380.437] (II) Loading /usr/lib64/xorg/modules/input/xrdpmouse_drv.so
[1124380.437] (II) Module XRDPMOUSE: vendor="X.Org Foundation"
[1124380.437] 	compiled for 1.20.11, module version = 0.9.90
[1124380.437] 	Module class: X.Org XInput Driver
[1124380.437] 	ABI class: X.Org XInput driver, version 24.1
[1124380.437] rdpmousePlug:
[1124380.437] (II) LoadModule: "xrdpkeyb"
[1124380.437] (II) Loading /usr/lib64/xorg/modules/input/xrdpkeyb_drv.so
[1124380.438] (II) Module XRDPKEYB: vendor="X.Org Foundation"
[1124380.438] 	compiled for 1.20.11, module version = 0.9.90
[1124380.438] 	Module class: X.Org XInput Driver
[1124380.438] 	ABI class: X.Org XInput driver, version 24.1
[1124380.438] rdpkeybPlug:
[1124380.438] rdpIdentify:
[1124380.438] (II) XRDPDEV: driver for xrdp: XRDPDEV
[1124380.438] rdpDriverFunc: op 10
[1124380.438] (WW) Falling back to old probe method for XRDPDEV
[1124380.438] rdpProbe:
[1124380.438] (II) Loading sub module "fb"
[1124380.438] (II) LoadModule: "fb"
[1124380.438] (II) Module "fb" already built-in
[1124380.438] (II) XRDPDEV(0): using default device
[1124380.438] (WW) VGA arbiter: cannot open kernel arbiter, no multi-card support
[1124380.438] rdpPreInit:
[1124380.438] (**) XRDPDEV(0): Depth 24, (--) framebuffer bpp 32
[1124380.438] (==) XRDPDEV(0): RGB weight 888
[1124380.438] (==) XRDPDEV(0): Using gamma correction (1.0, 1.0, 1.0)
[1124380.438] (==) XRDPDEV(0): Default visual is TrueColor
[1124380.438] (==) XRDPDEV(0): DPI set to (96, 96)
[1124380.438] (II) XRDPDEV(0): 	mode "640x480" ok
[1124380.438] (II) XRDPDEV(0): 	mode "800x600" ok
[1124380.438] (II) XRDPDEV(0): Virtual size is 800x600 (pitch 800)
[1124380.438] (**) XRDPDEV(0):  Default mode "800x600": 36.0 MHz (scaled from 0.0 MHz), 35.2 kHz, 56.2 Hz
[1124380.438] (II) XRDPDEV(0): Modeline "800x600"x0.0   36.00  800 824 896 1024  600 601 603 625 +hsync +vsync (35.2 kHz d)
[1124380.438] rdpScreenInit: virtualX 800 virtualY 600 rgbBits 8 depth 24
[1124380.438] rdpScreenInit: pfbMemory bytes 1920000
[1124380.438] rdpScreenInit: pfbMemory 0x7f9b09a5a010
[1124380.438] rdpSimdInit: assigning yuv functions
[1124380.438] rdpSimdInit: cpuid ax 1 cx 0 return ax 0x00a50f00 bx 0x02010800 cx 0xfed83203 dx 0x178bfbff
[1124380.438] rdpSimdInit: sse2 amd64 yuv functions assigned
[1124380.438] (==) XRDPDEV(0): Backing store enabled
[1124380.438] rdpClientConInit: disconnect idle session after [0] sec
[1124380.438] rdpClientConInit: kill disconnected [0] timeout [0] sec
[1124380.438] rdpXvInit: depth 24
[1124380.438] rdpScreenInit: out
[1124380.438] (II) Initializing extension Generic Event Extension
[1124380.439] (II) Initializing extension SHAPE
[1124380.439] (II) Initializing extension MIT-SHM
[1124380.439] (II) Initializing extension XInputExtension
[1124380.439] (II) Initializing extension XTEST
[1124380.439] (II) Initializing extension BIG-REQUESTS
[1124380.440] (II) Initializing extension SYNC
[1124380.440] (II) Initializing extension XKEYBOARD
[1124380.440] (II) Initializing extension XC-MISC
[1124380.440] (II) Initializing extension SECURITY
[1124380.440] (II) Initializing extension XFIXES
[1124380.441] (II) Initializing extension RENDER
[1124380.441] (II) Initializing extension RANDR
[1124380.441] (II) Initializing extension COMPOSITE
[1124380.441] (II) Initializing extension DAMAGE
[1124380.442] (II) Initializing extension MIT-SCREEN-SAVER
[1124380.442] (II) Initializing extension DOUBLE-BUFFER
[1124380.442] (II) Initializing extension RECORD
[1124380.442] (II) Initializing extension DPMS
[1124380.442] (II) Initializing extension Present
[1124380.442] (II) Initializing extension DRI3
[1124380.442] (II) Initializing extension X-Resource
[1124380.443] (II) Initializing extension XVideo
[1124380.443] (II) Initializing extension XVideo-MotionCompensation
[1124380.443] (II) Initializing extension SELinux
[1124380.443] (II) SELinux: Disabled by boolean
[1124380.443] (II) Initializing extension GLX
[1124380.443] (II) AIGLX: Screen 0 is not DRI2 capable
[1124380.474] (II) IGLX: Loaded and initialized swrast
[1124380.474] (II) GLX: Initialized DRISWRAST GL provider for screen 0
[1124380.474] (II) Initializing extension XFree86-VidModeExtension
[1124380.474] (II) Initializing extension XFree86-DGA
[1124380.474] (II) Initializing extension DRI2
[1124380.475] rdpCreateScreenResources:
[1124380.486] (II) Using input driver 'XRDPMOUSE' for 'xrdpMouse'
[1124380.486] (**) Option "CorePointer"
[1124380.486] (**) xrdpMouse: always reports core events
[1124380.486] rdpmousePreInit: drv 0x556895b1e4c0 info 0x556895def5c0, flags 0x0
[1124380.486] (II) XINPUT: Adding extended input device "xrdpMouse" (type: Mouse, id 6)
[1124380.486] rdpmouseControl: what 0
[1124380.486] rdpmouseDeviceInit:
[1124380.486] rdpmouseCtrl:
[1124380.486] rdpRegisterInputCallback: type 1 proc 0x7f9b0b12d4a0
[1124380.486] (**) xrdpMouse: (accel) keeping acceleration scheme 1
[1124380.486] (**) xrdpMouse: (accel) acceleration profile 0
[1124380.486] (**) xrdpMouse: (accel) acceleration factor: 2.000
[1124380.486] (**) xrdpMouse: (accel) acceleration threshold: 4
[1124380.486] rdpmouseControl: what 1
[1124380.486] rdpmouseDeviceOn:
[1124380.486] (II) Using input driver 'XRDPKEYB' for 'xrdpKeyboard'
[1124380.486] (**) Option "CoreKeyboard"
[1124380.486] (**) xrdpKeyboard: always reports core events
[1124380.486] rdpkeybPreInit: drv 0x556895b1df60 info 0x556895df2740, flags 0x0
[1124380.486] (II) XINPUT: Adding extended input device "xrdpKeyboard" (type: Keyboard, id 7)
[1124380.486] rdpkeybControl: what 0
[1124380.486] rdpkeybDeviceInit:
[1124380.494] rdpkeybChangeKeyboardControl:
[1124380.494] rdpkeybChangeKeyboardControl: autoRepeat on
[1124380.494] rdpRegisterInputCallback: type 0 proc 0x7f9b09c30a00
[1124380.494] rdpkeybControl: what 1
[1124380.494] rdpkeybDeviceOn:
[1124380.498] (II) config/udev: Adding input device Power Button (/dev/input/event0)
[1124380.498] (II) AutoAddDevices is off - not adding device.
[1124380.498] (II) config/udev: Adding input device AT Translated Set 2 keyboard (/dev/input/event1)
[1124380.498] (II) AutoAddDevices is off - not adding device.
[1124380.499] (II) config/udev: Adding input device PS/2 Generic Mouse (/dev/input/event2)
[1124380.499] (II) AutoAddDevices is off - not adding device.
[1124380.499] (II) config/udev: Adding input device PS/2 Generic Mouse (/dev/input/mouse0)
[1124380.499] (II) AutoAddDevices is off - not adding device.
[1124380.499] (II) config/udev: Adding input device PC Speaker (/dev/input/event3)
[1124380.499] (II) AutoAddDevices is off - not adding device.
[1124380.501] rdpDeferredRandR:
[1124380.501] rdpResizeSession: width 1024 height 768
[1124380.502]   calling RRScreenSizeSet
[1124380.502] rdpRRScreenSetSize: width 1024 height 768 mmWidth 271 mmHeight 203
[1124380.502] rdpRRGetInfo:
[1124380.502]   screen resized to 1024x768
[1124380.503]   RRScreenSizeSet ok 1
[1124380.503] rdpResizeSession: width 3840 height 2160
[1124380.503]   calling RRScreenSizeSet
[1124380.503] rdpRRScreenSetSize: width 3840 height 2160 mmWidth 1016 mmHeight 572
[1124380.503] rdpRRGetInfo:
[1124380.503]   screen resized to 3840x2160
[1124380.507]   RRScreenSizeSet ok 1
[1124380.507] rdpRRSetRdpOutputs: numCrtcs 0 numOutputs 0 monitorCount 0
[1124380.507] rdpRRSetRdpOutputs: update output 0 left 0 top 0 width 3840 height 2160
[1124380.508] rdpRRConnectOutput:
[1124380.596] rdpInDeferredRepeatCallback:
[1124380.596] rdpkeybChangeKeyboardControl:
[1124380.596] rdpkeybChangeKeyboardControl: autoRepeat off
[1124381.416] rdpRRGetInfo:
[1124381.428] rdpClientConGotConnection:
[1124381.428] rdpClientConGotConnection: g_sck_accept ok new_sck 7
[1124381.429] rdpClientConGetConnection: idle_disconnect_timeout set to non-positive value, idle timer turned off
[1124381.429] rdpAddClientConToDev: adding first clientCon 0x556895e22a30
[1124381.429] rdpClientConProcessMsgVersion: version 0 0 0 1
[1124381.429] rdpClientConProcessMsgClientInput: obsolete msg 300
[1124381.429] rdpClientConProcessMsgClientInput: invalidate x 0 y 0 cx 3840 cy 2160
[1124381.439] rdpClientConProcessMsgClientInfo:
[1124381.439]   got client info bytes 7192
[1124381.439]   jpeg support 0
[1124381.439]   offscreen support 1
[1124381.439]   offscreen size 10485760
[1124381.439]   offscreen entries 100
[1124381.439] rdpClientConProcessMsgClientInfo: got RFX capture
[1124381.439]   cap_width 3840 cap_height 2176
[1124381.439] rdpClientConAllocateSharedMemory: shmemfd 18 shmemptr 0x7f9af807b000 bytes 33423360
[1124381.439]   client can not do multimon
[1124381.440] rdpRRSetRdpOutputs: numCrtcs 1 numOutputs 1 monitorCount 0
[1124381.440] rdpRRSetRdpOutputs: update output 0 left 0 top 0 width 3840 height 2160
[1124381.440] rdpRRConnectOutput:
[1124381.440]   client can not do offscreen to offscreen blits
[1124381.440]   client can do new(color) cursor
[1124381.440] rdpLoadLayout: keylayout 0xe0010411 variant  display 10
[1124381.447] rdpkeybChangeKeyboardControl:
[1124381.447] rdpkeybChangeKeyboardControl: autoRepeat on
[1124381.448] rdpkeybChangeKeyboardControl:
[1124381.448] rdpkeybChangeKeyboardControl: autoRepeat on
[1124381.452] rdpCapture2: resize the crc list was 0 now 2040
[1124381.553] rdpInDeferredRepeatCallback:
[1124381.553] rdpkeybChangeKeyboardControl:
[1124381.553] rdpkeybChangeKeyboardControl: autoRepeat off
[1124381.553] rdpInDeferredRepeatCallback:
[1124381.553] rdpkeybChangeKeyboardControl:
[1124381.553] rdpkeybChangeKeyboardControl: autoRepeat off
[1124381.910] rdpRRGetInfo:
[1124381.947] rdpkeybChangeKeyboardControl:
[1124381.947] rdpkeybChangeKeyboardControl: autoRepeat on
[1124381.947] rdpkeybChangeKeyboardControl:
[1124381.947] rdpkeybChangeKeyboardControl: autoRepeat on
[1124381.947] rdpkeybChangeKeyboardControl:
[1124381.947] rdpkeybChangeKeyboardControl: autoRepeat on
[1124381.947] rdpkeybChangeKeyboardControl:
[1124381.947] rdpkeybChangeKeyboardControl: autoRepeat on
[1124381.957] rdpRRGetInfo:
[1124381.958] rdpRRCrtcGetGamma: 0x556895e02760 0x556895e111a0 0x556895e115a0 0x556895e113a0
[1124381.958] rdpRRScreenSetSize: width 3840 height 2160 mmWidth 1016 mmHeight 572
[1124381.958] rdpRRScreenSetSize: already this size
[1124381.958] rdpRROutputSetProperty:
[1124381.959] rdpRROutputGetProperty:
[1124381.960] rdpRRCrtcGetGamma: 0x556895e02760 0x556895e111a0 0x556895e115a0 0x556895e113a0
[1124382.032] rdpkeybChangeKeyboardControl:
[1124382.032] rdpkeybChangeKeyboardControl: autoRepeat on
[1124382.032] rdpkeybChangeKeyboardControl:
[1124382.032] rdpkeybChangeKeyboardControl: autoRepeat on
[1124382.047] rdpInDeferredRepeatCallback:
[1124382.047] rdpkeybChangeKeyboardControl:
[1124382.047] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.047] rdpInDeferredRepeatCallback:
[1124382.047] rdpkeybChangeKeyboardControl:
[1124382.047] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.047] rdpInDeferredRepeatCallback:
[1124382.047] rdpkeybChangeKeyboardControl:
[1124382.047] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.047] rdpInDeferredRepeatCallback:
[1124382.047] rdpkeybChangeKeyboardControl:
[1124382.047] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.133] rdpInDeferredRepeatCallback:
[1124382.133] rdpkeybChangeKeyboardControl:
[1124382.133] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.133] rdpInDeferredRepeatCallback:
[1124382.133] rdpkeybChangeKeyboardControl:
[1124382.133] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.615] rdpRROutputGetProperty:
[1124382.615] rdpRRCrtcGetGamma: 0x556895e02760 0x556895e111a0 0x556895e115a0 0x556895e113a0
[1124382.624] rdpRRGetInfo:
[1124382.625] rdpmouseCtrl:
[1124382.793] rdpkeybChangeKeyboardControl:
[1124382.793] rdpkeybChangeKeyboardControl: autoRepeat off
[1124382.793] rdpkeybChangeKeyboardControl:
[1124382.793] rdpkeybChangeKeyboardControl: autoRepeat off
[1124388.973] rdpClientConProcessMsgClientInput: obsolete msg 300
[1124480.562] rdpClientConProcessMsgClientInput: invalidate x 0 y 0 cx 3839 cy 2159
[1124487.347] rdpClientConRecv: g_sck_recv failed(returned 0)
[1124487.348] rdpClientConRecvMsg: error
[1124487.348] rdpClientConCheck: rdpClientConGotData failed
[1124487.348] rdpClientConDisconnect:
[1124487.348] rdpRemoveClientConFromDev: removing clientCon 0x556895e22a30
[1124502.329] rdpClientConGotConnection:
[1124502.329] rdpClientConGotConnection: g_sck_accept ok new_sck 7
[1124502.329] rdpClientConGetConnection: idle_disconnect_timeout set to non-positive value, idle timer turned off
[1124502.329] rdpAddClientConToDev: adding first clientCon 0x556895e22a30
[1124502.331] rdpClientConProcessMsgVersion: version 0 0 0 1
[1124502.331] rdpClientConProcessMsgClientInput: obsolete msg 300
[1124502.331] rdpClientConProcessMsgClientInput: invalidate x 0 y 0 cx 1920 cy 1200
[1124502.346] rdpClientConProcessMsgClientInfo:
[1124502.346]   got client info bytes 7192
[1124502.346]   jpeg support 0
[1124502.346]   offscreen support 1
[1124502.346]   offscreen size 10485760
[1124502.346]   offscreen entries 100
[1124502.346] rdpClientConProcessMsgClientInfo: got RFX capture
[1124502.347]   cap_width 1920 cap_height 1216
[1124502.347] rdpClientConAllocateSharedMemory: shmemfd 18 shmemptr 0x7f9b00117000 bytes 9338880
[1124502.347]   client can not do multimon
[1124502.347] rdpRRSetRdpOutputs: numCrtcs 1 numOutputs 1 monitorCount 0
[1124502.347] rdpRRSetRdpOutputs: update output 0 left 0 top 0 width 3840 height 2160
[1124502.347] rdpRRConnectOutput:
[1124502.347]   client can not do offscreen to offscreen blits
[1124502.347]   client can do new(color) cursor
[1124502.347] rdpLoadLayout: keylayout 0xe0010411 variant  display 10
[1124502.347] rdpkeybChangeKeyboardControl:
[1124502.347] rdpkeybChangeKeyboardControl: autoRepeat on
[1124502.348] rdpkeybChangeKeyboardControl:
[1124502.348] rdpkeybChangeKeyboardControl: autoRepeat off
[1124502.349] rdpkeybChangeKeyboardControl:
[1124502.349] rdpkeybChangeKeyboardControl: autoRepeat on
[1124502.356] rdpCapture2: resize the crc list was 0 now 2040
[1124502.381] (EE) 
[1124502.381] (EE) Backtrace:
[1124502.381] (EE) 0: /usr/libexec/Xorg (xorg_backtrace+0x89) [0x556894e70619]
[1124502.381] (EE) 1: /usr/libexec/Xorg (0x556894c9a000+0x1df149) [0x556894e79149]
[1124502.381] (EE) 2: /lib64/libc.so.6 (0x7f9b0a600000+0x54db0) [0x7f9b0a654db0]
[1124502.382] (EE) 3: /lib64/libc.so.6 (0x7f9b0a600000+0xba18a) [0x7f9b0a6ba18a]
[1124502.382] (EE) 4: /usr/lib64/xorg/modules/libxorgxrdp.so (rdpCapture+0x69c) [0x7f9b09c4421c]
[1124502.382] (EE) 5: /usr/lib64/xorg/modules/libxorgxrdp.so (0x7f9b09c34000+0xd999) [0x7f9b09c41999]
[1124502.382] (EE) 6: /usr/lib64/xorg/modules/libxorgxrdp.so (0x7f9b09c34000+0xf29b) [0x7f9b09c4329b]
[1124502.382] (EE) 7: /usr/libexec/Xorg (0x556894c9a000+0x1d8634) [0x556894e72634]
[1124502.382] (EE) 8: /usr/libexec/Xorg (WaitForSomething+0x2e2) [0x556894e72942]
[1124502.382] (EE) 9: /usr/libexec/Xorg (0x556894c9a000+0x4c3dd) [0x556894ce63dd]
[1124502.383] (EE) 10: /lib64/libc.so.6 (0x7f9b0a600000+0x3feb0) [0x7f9b0a63feb0]
[1124502.383] (EE) 11: /lib64/libc.so.6 (__libc_start_main+0x80) [0x7f9b0a63ff60]
[1124502.383] (EE) 12: /usr/libexec/Xorg (_start+0x25) [0x556894ce6ea5]
[1124502.383] (EE) 
[1124502.383] (EE) Segmentation fault at address 0x7f9b01200000
[1124502.383] (EE) 
Fatal server error:
[1124502.383] (EE) Caught signal 11 (Segmentation fault). Server aborting
[1124502.383] (EE) 
[1124502.383] (EE) 
Please consult the The X.Org Foundation support 
	 at http://wiki.x.org
 for help. 
[1124502.383] (EE) Please also check the log file at ".xorgxrdp.10.log" for additional information.
[1124502.384] (EE) 
[1124502.384] rdpmouseControl: what 4
[1124502.384] rdpkeybControl: what 4
[1124502.384] rdpLeaveVT:
[1124502.385] (EE) Server terminated with error (1). Closing log file.

@matt335672
Copy link
Member Author

Thanks @metalefty. I'll take a look at that now.

This fixes some monitor hotplug issues with non-GFX codepaths.

1) The server_version_message() was working on an out-of-date
   copy of the client_info. As a result, the X server and the
   window manager did not agree on the number of windows
2) As a result of 1), a memory leak was found in the VNC module.
From [MS-RCPBCGR] 3.3.5.12.1:-

> ...The contents of this PDU SHOULD NOT be compressed.
>
> This PDU MUST NOT be sent to a client that has not indicated support for
> it by setting the RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU flag (0x0040)
> in the earlyCapabilityFlags field of the Client Core Data (section
> 2.2.1.3.2).

Also, 2.2.12.1 specifies the source channel must be zero.

In testing, a compressed monitor layout PDU causes mstsc.exe
to exit with a protocol error.
This stores what kind of resizing (if any) can be achieved with
a Deactivation-Reactivation sequence.
This commit DOES NOT compile.

This change alters these module interface calls:-
1) mod_server_monitor_resize() (Call from xrdp to module). Updated.
2) server_reset() (Call from module to xrdp). Replaced.

The mod_server_monitor_resize() call is updated :-
1) to allow a monitor list to be passed in for a multimon resize
2) with an 'in_progress' return value which tells the caller whether or
   not to expect a callback.

The server_reset() call served two purposes up until now:-
1) To allow a module to resize a single monitor session. There
   is no way to request a multi-monitor resize from the module
2) (with bpp == 0) To signal to the mm resize state machine that
   a server screen resize hsa finished.

This is split into two calls:-
1) client_monitor_resize() to allow a mdule to request a
   multimon resize.
2) server_monitor_resize_done(). This is called by a module
   when a resize is completed.
Neutrinordp module now compiles with updated monitor resize
interface
Significant updates for the VNC module:-
1) Support for the new API calls allowing both server and client
   multi-monitor resizes.
2) The s member variable of the vnc_screen_layout structure is no longer
   dynamically allocated.
3) The module server_width and server_height member variables are
   removed as these are just duplicating server_layout.total_width and
   server_layout.total_height.
4) When the server screens are resized, there is no need to restart the
   entire resize state machine as we already know at this point that
   the server supports resizing.
Input message 300 to xorgxrdp which communicated a screen size
has been replaced with message 302 which sends a list of monitors
to xorgxrdp. This simplifies the initialisation and resize logic
somewhat, but a compatible version of xorgxrdp must be used
Clear egfx_up as soon as the channel starts to close so that
xrdp_mm_draw_dirty() doesn't send data to a closed channel.
@matt335672
Copy link
Member Author

This is now ready for review and further testing.

You will need neutrinolabs/xorgxrdp#285 as well.

Fixed:-

  • The monitor switching @metalefty mentioned above.
  • Hotplug of monitors for both backends in GFX/non-GFX scenarios works.
  • Screen corruption on GFX hotplugging (3ca3bd1)

Hopefully I've done my rebasing and merging correctly!

@Nexarian
Copy link
Contributor

Awesome, I'll take a look and test over the next few days. I really appreciate all the work you've done on this. Hopefully my code wasn't too maddening :)

@matt335672
Copy link
Member Author

Your code's absolutely fine. I just hope mine is fine for you!

A couple of maybe significant points:-

  • I've focused on mstsc.exe this week for obvious reasons following meta's email. I imagine you'll find some issues with your setup I haven't anticipated.
  • I used XFCE in the end as a target as GNOME was clearly having some issues.

There's more we can do in this area:-

  1. VNC allows for server-side resizes using xrandr commands. I don't think the plumbing is in there for xorgxrdp yet.
  2. I think(!) I understand this area well enough to tackle the GFX resizes which should be a lot faster.

I've left both of these for now so we can concentrate on getting something out-of-the door.

Also, I probably need to update your page on the wiki.

@metalefty
Copy link
Member

metalefty commented Feb 16, 2024

Thanks! I'm not at home for several days so I have only one monitor built in laptop. I will be able to test it tonight if the TV in the hotel I stay at today has HDMI input.

@matt335672
Copy link
Member Author

@Nexarian, @jsorg71 - I've just trying to get to grips with the GFX client resize as an alternative to using a Deactivate-Reactivate sequence, as specified in [MS-RDPEDISP] 1.3.

I've a few questions in areas which you both know a lot more about than I do. I'd be grateful for any enlightenment. I think these changes are out-of-scope for this PR, but should be simple enough to add to another one.

  1. From reading [MS-RDPEGFX], it seems that when we send a RDPGFX_RESET_GRAPHICS_PDU we shouldn't need to delete surfaces which are going to be in the new config as we are just going to recreate them with the same surface ID. It is however not clear to me when we send a RDPGFX_RESET_GRAPHICS_PDU whether we may need to delete existing surfaces not in the new config (e.g. when going from 3 monitors to 2). Any thoughts?
  2. I can't find anywhere in the GFX encoder thread where it stores any state data relating to the geometry. Am I missing something?
  3. When we get frames from xorgxrdp, they're complete in that the START_FRAME and END_FRAME messages are all in the same PDU and get processed as a single unit. Is that right?

My current thinking on the client resize from the xrdp_mm state machine is:-

  1. Set suppress output on the module to prevent more frames coming through.
  2. Bin any contents of the GFX encoder FIFO.
  3. Add commands to reset graphics and remap monitors to the GFX encoder FIFO, and let the encoder send those over while we're busy resizing the server.
  4. Resize the server [if required]
  5. Clear suppress output on the module and send a whole-screen frame.

What do you think? I'm sure I've failed to spot a few dragons here, but it should be reasonably simple to implement as pretty much all the code is already written, in one form or another.

@metalefty
Copy link
Member

metalefty commented Feb 16, 2024

Awesome! Hot-unplug looks good to me but there are some other problems. Resizing is a pain as @Nexarian said :)

I'm using your latest branches.

Coldplug, that is to say, disconnect & reconnect with different monitor counts.
Monitor count changes 1-> 2.

When you have two monitors,

  1. Connect from mstsc in fullscreen with "use all my monitors for the remote session" turned off
  2. Close mstsc to disconnect
  3. Reconnect with the previous session with "use all my monitors for the remote session" turned ON
  4. Xorg segfault
xorgxrdp.10.log
[   552.060] 
X.Org X Server 1.20.11
X Protocol Version 11, Revision 0
[   552.060] Build Operating System:  4.18.0-477.13.1.el8_8.x86_64 
[   552.060] Current Operating System: Linux a9xrdp 5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 7 14:54:22 EST 2023 x86_64
[   552.060] Kernel command line: BOOT_IMAGE=(hd0,gpt3)/vmlinuz-5.14.0-362.8.1.el9_3.x86_64 root=UUID=280b97cf-dfc4-4d92-8670-aa43d13f5b51 ro console=tty0 console=ttyS0,115200n8 no_timer_check biosdevname=0 net.ifnames=0 crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M
[   552.060] Build Date: 06 June 2023  12:00:00AM
[   552.060] Build ID: xorg-x11-server 1.20.11-19.el9 
[   552.060] Current version of pixman: 0.40.0
[   552.060] 	Before reporting problems, check http://wiki.x.org
	to make sure that you have the latest version.
[   552.060] Markers: (--) probed, (**) from config file, (==) default setting,
	(++) from command line, (!!) notice, (II) informational,
	(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
[   552.060] (++) Log file: ".xorgxrdp.10.log", Time: Fri Feb 16 16:47:24 2024
[   552.060] (++) Using config file: "/etc/X11/xrdp/xorg.conf"
[   552.060] (==) Using config directory: "/etc/X11/xorg.conf.d"
[   552.060] (==) Using system config directory "/usr/share/X11/xorg.conf.d"
[   552.060] (**) Option "defaultserverlayout" "X11 Server"
[   552.060] (**) ServerLayout "X11 Server"
[   552.060] (**) |-->Screen "Screen (xrdpdev)" (0)
[   552.060] (**) |   |-->Monitor "Monitor"
[   552.061] (**) |   |-->Device "Video Card (xrdpdev)"
[   552.061] (**) |-->Input Device "xrdpMouse"
[   552.061] (**) |-->Input Device "xrdpKeyboard"
[   552.061] (**) Option "DontVTSwitch" "on"
[   552.061] (**) Option "AutoAddDevices" "off"
[   552.061] (**) Option "AutoAddGPU" "off"
[   552.061] (**) Not automatically adding devices
[   552.061] (==) Automatically enabling devices
[   552.061] (**) Not automatically adding GPU devices
[   552.061] (==) Automatically binding GPU devices
[   552.061] (==) Max clients allowed: 256, resource mask: 0x1fffff
[   552.061] (==) FontPath set to:
	catalogue:/etc/X11/fontpath.d,
	built-ins
[   552.061] (==) ModulePath set to "/usr/lib64/xorg/modules"
[   552.061] (II) Loader magic: 0x557084412d40
[   552.061] (II) Module ABI versions:
[   552.061] 	X.Org ANSI C Emulation: 0.4
[   552.061] 	X.Org Video Driver: 24.1
[   552.061] 	X.Org XInput driver : 24.1
[   552.061] 	X.Org Server Extension : 10.0
[   552.062] (II) systemd-logind: took control of session /org/freedesktop/login1/session/c8
[   552.062] (II) no primary bus or device found
[   552.062] (II) "glx" will be loaded. This was enabled by default and also specified in the config file.
[   552.062] (II) LoadModule: "dbe"
[   552.063] (II) Module "dbe" already built-in
[   552.063] (II) LoadModule: "ddc"
[   552.063] (II) Module "ddc" already built-in
[   552.063] (II) LoadModule: "extmod"
[   552.063] (II) Module "extmod" already built-in
[   552.063] (II) LoadModule: "glx"
[   552.063] (II) Loading /usr/lib64/xorg/modules/extensions/libglx.so
[   552.063] (II) Module glx: vendor="X.Org Foundation"
[   552.063] 	compiled for 1.20.11, module version = 1.0.0
[   552.063] 	ABI class: X.Org Server Extension, version 10.0
[   552.063] (II) LoadModule: "int10"
[   552.063] (WW) Warning, couldn't open module int10
[   552.064] (EE) Failed to load module "int10" (module does not exist, 0)
[   552.064] (II) LoadModule: "record"
[   552.064] (II) Module "record" already built-in
[   552.064] (II) LoadModule: "vbe"
[   552.064] (WW) Warning, couldn't open module vbe
[   552.064] (EE) Failed to load module "vbe" (module does not exist, 0)
[   552.064] (II) LoadModule: "xorgxrdp"
[   552.064] (II) Loading /usr/lib64/xorg/modules/libxorgxrdp.so
[   552.064] (II) Module XORGXRDP: vendor="X.Org Foundation"
[   552.064] 	compiled for 1.20.11, module version = 0.9.80
[   552.064] 	ABI class: X.Org Video Driver, version 24.1
[   552.064] xorgxrdpSetup:
[   552.064] (II) LoadModule: "fb"
[   552.064] (II) Module "fb" already built-in
[   552.064] (II) LoadModule: "xrdpdev"
[   552.064] (II) Loading /usr/lib64/xorg/modules/drivers/xrdpdev_drv.so
[   552.064] (II) Module XRDPDEV: vendor="X.Org Foundation"
[   552.064] 	compiled for 1.20.11, module version = 0.9.80
[   552.064] 	ABI class: X.Org Video Driver, version 24.1
[   552.064] xrdpdevSetup:
[   552.064] (II) LoadModule: "xrdpmouse"
[   552.064] (II) Loading /usr/lib64/xorg/modules/input/xrdpmouse_drv.so
[   552.064] (II) Module XRDPMOUSE: vendor="X.Org Foundation"
[   552.064] 	compiled for 1.20.11, module version = 0.9.80
[   552.064] 	Module class: X.Org XInput Driver
[   552.064] 	ABI class: X.Org XInput driver, version 24.1
[   552.064] rdpmousePlug:
[   552.064] (II) LoadModule: "xrdpkeyb"
[   552.064] (II) Loading /usr/lib64/xorg/modules/input/xrdpkeyb_drv.so
[   552.064] (II) Module XRDPKEYB: vendor="X.Org Foundation"
[   552.064] 	compiled for 1.20.11, module version = 0.9.80
[   552.064] 	Module class: X.Org XInput Driver
[   552.064] 	ABI class: X.Org XInput driver, version 24.1
[   552.064] rdpkeybPlug:
[   552.064] rdpIdentify:
[   552.064] (II) XRDPDEV: driver for xrdp: XRDPDEV
[   552.064] rdpDriverFunc: op 10
[   552.064] (WW) Falling back to old probe method for XRDPDEV
[   552.064] rdpProbe:
[   552.064] (II) Loading sub module "fb"
[   552.064] (II) LoadModule: "fb"
[   552.064] (II) Module "fb" already built-in
[   552.064] (II) XRDPDEV(0): using default device
[   552.064] (WW) VGA arbiter: cannot open kernel arbiter, no multi-card support
[   552.064] rdpPreInit:
[   552.064] (**) XRDPDEV(0): Depth 24, (--) framebuffer bpp 32
[   552.064] (==) XRDPDEV(0): RGB weight 888
[   552.064] (==) XRDPDEV(0): Using gamma correction (1.0, 1.0, 1.0)
[   552.064] (==) XRDPDEV(0): Default visual is TrueColor
[   552.064] (==) XRDPDEV(0): DPI set to (96, 96)
[   552.064] (II) XRDPDEV(0): 	mode "640x480" ok
[   552.064] (II) XRDPDEV(0): 	mode "800x600" ok
[   552.064] (II) XRDPDEV(0): Virtual size is 800x600 (pitch 800)
[   552.064] (**) XRDPDEV(0):  Default mode "800x600": 36.0 MHz (scaled from 0.0 MHz), 35.2 kHz, 56.2 Hz
[   552.064] (II) XRDPDEV(0): Modeline "800x600"x0.0   36.00  800 824 896 1024  600 601 603 625 +hsync +vsync (35.2 kHz d)
[   552.064] rdpScreenInit: virtualX 800 virtualY 600 rgbBits 8 depth 24
[   552.064] rdpScreenInit: pfbMemory bytes 1920000
[   552.064] rdpScreenInit: pfbMemory 0x7f939b8f7010
[   552.064] rdpSimdInit: assigning yuv functions
[   552.064] rdpSimdInit: cpuid ax 1 cx 0 return ax 0x00a50f00 bx 0x03010800 cx 0xfed83203 dx 0x178bfbff
[   552.064] rdpSimdInit: sse2 amd64 yuv functions assigned
[   552.064] (==) XRDPDEV(0): Backing store enabled
[   552.064] rdpClientConInit: disconnect idle session after [0] sec
[   552.064] rdpClientConInit: kill disconnected [0] timeout [0] sec
[   552.064] rdpXvInit: depth 24
[   552.064] rdpScreenInit: out
[   552.064] (II) Initializing extension Generic Event Extension
[   552.064] (II) Initializing extension SHAPE
[   552.064] (II) Initializing extension MIT-SHM
[   552.064] (II) Initializing extension XInputExtension
[   552.064] (II) Initializing extension XTEST
[   552.064] (II) Initializing extension BIG-REQUESTS
[   552.065] (II) Initializing extension SYNC
[   552.065] (II) Initializing extension XKEYBOARD
[   552.065] (II) Initializing extension XC-MISC
[   552.065] (II) Initializing extension SECURITY
[   552.065] (II) Initializing extension XFIXES
[   552.065] (II) Initializing extension RENDER
[   552.065] (II) Initializing extension RANDR
[   552.065] (II) Initializing extension COMPOSITE
[   552.065] (II) Initializing extension DAMAGE
[   552.065] (II) Initializing extension MIT-SCREEN-SAVER
[   552.065] (II) Initializing extension DOUBLE-BUFFER
[   552.065] (II) Initializing extension RECORD
[   552.065] (II) Initializing extension DPMS
[   552.065] (II) Initializing extension Present
[   552.065] (II) Initializing extension DRI3
[   552.065] (II) Initializing extension X-Resource
[   552.065] (II) Initializing extension XVideo
[   552.065] (II) Initializing extension XVideo-MotionCompensation
[   552.065] (II) Initializing extension SELinux
[   552.065] (II) SELinux: Disabled by boolean
[   552.065] (II) Initializing extension GLX
[   552.065] (II) AIGLX: Screen 0 is not DRI2 capable
[   552.078] (II) IGLX: Loaded and initialized swrast
[   552.078] (II) GLX: Initialized DRISWRAST GL provider for screen 0
[   552.078] (II) Initializing extension XFree86-VidModeExtension
[   552.078] (II) Initializing extension XFree86-DGA
[   552.078] (II) Initializing extension DRI2
[   552.078] rdpCreateScreenResources:
[   552.089] (II) Using input driver 'XRDPMOUSE' for 'xrdpMouse'
[   552.089] (**) Option "CorePointer"
[   552.089] (**) xrdpMouse: always reports core events
[   552.089] rdpmousePreInit: drv 0x5570863a44c0 info 0x5570866754a0, flags 0x0
[   552.089] (II) XINPUT: Adding extended input device "xrdpMouse" (type: Mouse, id 6)
[   552.089] rdpmouseControl: what 0
[   552.089] rdpmouseDeviceInit:
[   552.089] rdpmouseCtrl:
[   552.089] rdpRegisterInputCallback: type 1 proc 0x7f939cfcb4a0
[   552.089] (**) xrdpMouse: (accel) keeping acceleration scheme 1
[   552.089] (**) xrdpMouse: (accel) acceleration profile 0
[   552.089] (**) xrdpMouse: (accel) acceleration factor: 2.000
[   552.089] (**) xrdpMouse: (accel) acceleration threshold: 4
[   552.089] rdpmouseControl: what 1
[   552.089] rdpmouseDeviceOn:
[   552.089] (II) Using input driver 'XRDPKEYB' for 'xrdpKeyboard'
[   552.089] (**) Option "CoreKeyboard"
[   552.089] (**) xrdpKeyboard: always reports core events
[   552.089] rdpkeybPreInit: drv 0x5570863a3f60 info 0x557086678620, flags 0x0
[   552.089] (II) XINPUT: Adding extended input device "xrdpKeyboard" (type: Keyboard, id 7)
[   552.089] rdpkeybControl: what 0
[   552.089] rdpkeybDeviceInit:
[   552.096] rdpkeybChangeKeyboardControl:
[   552.096] rdpkeybChangeKeyboardControl: autoRepeat on
[   552.096] rdpRegisterInputCallback: type 0 proc 0x7f939bacda00
[   552.096] rdpkeybControl: what 1
[   552.096] rdpkeybDeviceOn:
[   552.101] (II) config/udev: Adding input device Power Button (/dev/input/event0)
[   552.101] (II) AutoAddDevices is off - not adding device.
[   552.101] (II) config/udev: Adding input device AT Translated Set 2 keyboard (/dev/input/event1)
[   552.101] (II) AutoAddDevices is off - not adding device.
[   552.101] (II) config/udev: Adding input device PS/2 Generic Mouse (/dev/input/event2)
[   552.101] (II) AutoAddDevices is off - not adding device.
[   552.102] (II) config/udev: Adding input device PS/2 Generic Mouse (/dev/input/mouse0)
[   552.102] (II) AutoAddDevices is off - not adding device.
[   552.102] (II) config/udev: Adding input device PC Speaker (/dev/input/event3)
[   552.102] (II) AutoAddDevices is off - not adding device.
[   552.104] rdpDeferredRandR:
[   552.104] rdpResizeSession: width 1024 height 768
[   552.104]   calling RRScreenSizeSet
[   552.104] rdpRRScreenSetSize: width 1024 height 768 mmWidth 271 mmHeight 203
[   552.104] rdpRRGetInfo:
[   552.104]   screen resized to 1024x768
[   552.105]   RRScreenSizeSet ok 1
[   552.105] rdpResizeSession: width 1920 height 1080
[   552.105]   calling RRScreenSizeSet
[   552.105] rdpRRScreenSetSize: width 1920 height 1080 mmWidth 508 mmHeight 286
[   552.105] rdpRRGetInfo:
[   552.105]   screen resized to 1920x1080
[   552.107]   RRScreenSizeSet ok 1
[   552.107] rdpRRSetRdpOutputs: numCrtcs 0 numOutputs 0 monitorCount 0
[   552.107] rdpRRSetRdpOutputs: update output 0 left 0 top 0 width 1920 height 1080
[   552.107] rdpRRConnectOutput:
[   552.199] rdpInDeferredRepeatCallback:
[   552.199] rdpkeybChangeKeyboardControl:
[   552.199] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.062] rdpRRGetInfo:
[   553.085] rdpClientConGotConnection:
[   553.085] rdpClientConGotConnection: g_sck_accept ok new_sck 7
[   553.085] rdpClientConGetConnection: idle_disconnect_timeout set to non-positive value, idle timer turned off
[   553.085] rdpAddClientConToDev: adding first clientCon 0x5570866a8910
[   553.086] rdpClientConProcessMsgVersion: version 0 0 0 1
[   553.087] rdpClientConProcessMsgClientInput: invalidate x 0 y 0 cx 1920 cy 1080
[   553.106] rdpClientConProcessMsgClientInfo:
[   553.106]   got client info bytes 7192
[   553.106]   jpeg support 0
[   553.106]   offscreen support 1
[   553.106]   offscreen size 10485760
[   553.106]   offscreen entries 100
[   553.106] rdpClientConProcessMsgClientInfo: got RFX capture
[   553.106]   cap_width 1920 cap_height 1088
[   553.106] rdpClientConAllocateSharedMemory: shmemfd 18 shmemptr 0x7f939181d000 bytes 8355840
[   553.106]   client can not do multimon
[   553.106] rdpRRSetRdpOutputs: numCrtcs 1 numOutputs 1 monitorCount 0
[   553.106] rdpRRSetRdpOutputs: update output 0 left 0 top 0 width 1920 height 1080
[   553.106] rdpRRConnectOutput:
[   553.106]   client can not do offscreen to offscreen blits
[   553.106]   client can do new(color) cursor
[   553.106] rdpLoadLayout: keylayout 0xe0010411 variant  display 10
[   553.127] rdpkeybChangeKeyboardControl:
[   553.127] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.128] rdpkeybChangeKeyboardControl:
[   553.128] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.133] rdpCapture2: resize the crc list was 0 now 510
[   553.227] rdpInDeferredRepeatCallback:
[   553.227] rdpkeybChangeKeyboardControl:
[   553.227] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.228] rdpInDeferredRepeatCallback:
[   553.228] rdpkeybChangeKeyboardControl:
[   553.228] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.685] rdpRRGetInfo:
[   553.719] rdpkeybChangeKeyboardControl:
[   553.719] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.719] rdpkeybChangeKeyboardControl:
[   553.719] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.719] rdpkeybChangeKeyboardControl:
[   553.719] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.719] rdpkeybChangeKeyboardControl:
[   553.719] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.730] rdpRRGetInfo:
[   553.731] rdpRRCrtcGetGamma: 0x5570866882b0 0x557086697080 0x557086697480 0x557086697280
[   553.731] rdpRRScreenSetSize: width 1920 height 1080 mmWidth 508 mmHeight 286
[   553.731] rdpRRScreenSetSize: already this size
[   553.731] rdpRROutputSetProperty:
[   553.731] rdpRROutputGetProperty:
[   553.732] rdpRRCrtcGetGamma: 0x5570866882b0 0x557086697080 0x557086697480 0x557086697280
[   553.790] rdpkeybChangeKeyboardControl:
[   553.790] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.790] rdpkeybChangeKeyboardControl:
[   553.790] rdpkeybChangeKeyboardControl: autoRepeat on
[   553.820] rdpInDeferredRepeatCallback:
[   553.820] rdpkeybChangeKeyboardControl:
[   553.820] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.820] rdpInDeferredRepeatCallback:
[   553.820] rdpkeybChangeKeyboardControl:
[   553.820] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.820] rdpInDeferredRepeatCallback:
[   553.820] rdpkeybChangeKeyboardControl:
[   553.820] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.820] rdpInDeferredRepeatCallback:
[   553.820] rdpkeybChangeKeyboardControl:
[   553.820] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.891] rdpInDeferredRepeatCallback:
[   553.891] rdpkeybChangeKeyboardControl:
[   553.891] rdpkeybChangeKeyboardControl: autoRepeat off
[   553.891] rdpInDeferredRepeatCallback:
[   553.891] rdpkeybChangeKeyboardControl:
[   553.891] rdpkeybChangeKeyboardControl: autoRepeat off
[   554.347] rdpRROutputGetProperty:
[   554.347] rdpRRCrtcGetGamma: 0x5570866882b0 0x557086697080 0x557086697480 0x557086697280
[   554.352] rdpRRGetInfo:
[   554.409] rdpmouseCtrl:
[   554.553] rdpkeybChangeKeyboardControl:
[   554.553] rdpkeybChangeKeyboardControl: autoRepeat off
[   554.553] rdpkeybChangeKeyboardControl:
[   554.553] rdpkeybChangeKeyboardControl: autoRepeat off
[   563.406] rdpClientConRecv: g_sck_recv failed(returned -1)
[   563.406] rdpClientConRecvMsg: error
[   563.406] rdpClientConCheck: rdpClientConGotData failed
[   563.406] rdpClientConDisconnect:
[   563.406] rdpRemoveClientConFromDev: removing clientCon 0x5570866a8910
[   572.786] rdpClientConGotConnection:
[   572.786] rdpClientConGotConnection: g_sck_accept ok new_sck 7
[   572.786] rdpClientConGetConnection: idle_disconnect_timeout set to non-positive value, idle timer turned off
[   572.786] rdpAddClientConToDev: adding first clientCon 0x5570869da5b0
[   572.788] rdpClientConProcessMsgVersion: version 0 0 0 1
[   572.788] rdpClientConProcessMsgClientInput: invalidate x 0 y 0 cx 1926 cy 2280
[   572.806] rdpClientConProcessMsgClientInfo:
[   572.806]   got client info bytes 7192
[   572.806]   jpeg support 0
[   572.806]   offscreen support 1
[   572.807]   offscreen size 10485760
[   572.807]   offscreen entries 100
[   572.807] rdpClientConProcessMsgClientInfo: got RFX capture
[   572.807]   cap_width 1984 cap_height 2304
[   572.808] rdpClientConAllocateSharedMemory: shmemfd 18 shmemptr 0x7f938ae90000 bytes 18284544
[   572.808]   client can do multimon
[   572.808]   client monitor data, monitorCount=2
[   572.809]     left 6 top 0 right 1925 bottom 1079
[   572.809]     left 0 top 1080 right 1919 bottom 2279
[   572.809] rdpRRSetRdpOutputs: numCrtcs 1 numOutputs 1 monitorCount 2
[   572.810] rdpRRSetRdpOutputs: update output 0 left 6 top 0 width 1920 height 1080
[   572.810] rdpRRConnectOutput:
[   572.810] rdpRRSetRdpOutputs: update output 1 left 0 top 1080 width 1920 height 1200
[   572.811] rdpRRConnectOutput:
[   572.812]   client can not do offscreen to offscreen blits
[   572.812]   client can do new(color) cursor
[   572.812] rdpLoadLayout: keylayout 0xe0010411 variant  display 10
[   572.812] rdpkeybChangeKeyboardControl:
[   572.813] rdpkeybChangeKeyboardControl: autoRepeat on
[   572.813] rdpkeybChangeKeyboardControl:
[   572.813] rdpkeybChangeKeyboardControl: autoRepeat off
[   572.815] rdpkeybChangeKeyboardControl:
[   572.815] rdpkeybChangeKeyboardControl: autoRepeat on
[   572.820] rdpRRGetInfo:
[   572.821] rdpCapture2: resize the crc list was 0 now 510
[   572.905] rdpRROutputGetProperty:
[   572.910] rdpRRCrtcGetGamma: 0x5570869d3110 0x5570869d3400 0x5570869d3800 0x5570869d3600
[   572.910] rdpRRCrtcSet:
[   572.911] rdpRROutputSetProperty:
[   572.911] rdpRROutputSetProperty:
[   572.916] rdpInDeferredRepeatCallback:
[   572.916] rdpkeybChangeKeyboardControl:
[   572.916] rdpkeybChangeKeyboardControl: autoRepeat off
[   572.916] rdpInDeferredRepeatCallback:
[   572.916] rdpkeybChangeKeyboardControl:
[   572.916] rdpkeybChangeKeyboardControl: autoRepeat off
[   572.938] rdpCapture2: resize the crc list was 0 now 570
[   572.938] (EE) 
[   572.938] (EE) Backtrace:
[   572.938] (EE) 0: /usr/libexec/Xorg (xorg_backtrace+0x89) [0x55708437a619]
[   572.938] (EE) 1: /usr/libexec/Xorg (0x5570841a4000+0x1df149) [0x557084383149]
[   572.938] (EE) 2: /lib64/libc.so.6 (0x7f939c400000+0x54db0) [0x7f939c454db0]
[   572.938] (EE) 3: /usr/lib64/xorg/modules/libxorgxrdp.so (0x7f939bad1000+0xf5f0) [0x7f939bae05f0]
[   572.938] (EE) 4: /usr/lib64/xorg/modules/libxorgxrdp.so (rdpCapture+0x23c) [0x7f939bae0dbc]
[   572.938] (EE) 5: /usr/lib64/xorg/modules/libxorgxrdp.so (0x7f939bad1000+0xd999) [0x7f939bade999]
[   572.938] (EE) 6: /usr/lib64/xorg/modules/libxorgxrdp.so (0x7f939bad1000+0xf131) [0x7f939bae0131]
[   572.938] (EE) 7: /usr/libexec/Xorg (0x5570841a4000+0x1d8634) [0x55708437c634]
[   572.938] (EE) 8: /usr/libexec/Xorg (WaitForSomething+0x2e2) [0x55708437c942]
[   572.938] (EE) 9: /usr/libexec/Xorg (0x5570841a4000+0x4c3dd) [0x5570841f03dd]
[   572.938] (EE) 10: /lib64/libc.so.6 (0x7f939c400000+0x3feb0) [0x7f939c43feb0]
[   572.938] (EE) 11: /lib64/libc.so.6 (__libc_start_main+0x80) [0x7f939c43ff60]
[   572.938] (EE) 12: /usr/libexec/Xorg (_start+0x25) [0x5570841f0ea5]
[   572.938] (EE) 
[   572.938] (EE) Segmentation fault at address 0x7f93927ffe10
[   572.938] (EE) 
Fatal server error:
[   572.938] (EE) Caught signal 11 (Segmentation fault). Server aborting
[   572.938] (EE) 
[   572.938] (EE) 
Please consult the The X.Org Foundation support 
	 at http://wiki.x.org
 for help. 
[   572.938] (EE) Please also check the log file at ".xorgxrdp.10.log" for additional information.
[   572.938] (EE) 
[   572.938] rdpmouseControl: what 4
[   572.938] rdpkeybControl: what 4
[   572.938] rdpLeaveVT:
[   572.940] (EE) Server terminated with error (1). Closing log file.

The second problem is hot-replug, hot-plug after hot-unplug. Monitor count changes 2 -> 1 -> 2 in this case. It doesn't return to the original 2-monitor state. The xrdp session has 2 monitors but mstsc doesn't spread to 2 monitors. Windows-to-Windows RDP works fine even in this case. I guess xrdp doesn't notify mstsc that the remote session has 2 monitors.

The third problem is xrdp segfault. I couldn't find a clear procedure to reproduce yet.

xrdp.log
[2024-02-16T16:42:56.446+0000] [INFO ] loaded module 'libxup.so' ok, interface size 10416, version 4
[2024-02-16T16:42:56.448+0000] [DEBUG] xrdp_wm_log_msg: started connecting
[2024-02-16T16:42:56.449+0000] [INFO ] lib_mod_connect: connecting via UNIX socket
[2024-02-16T16:42:56.450+0000] [INFO ] lib_mod_log_peer: xrdp_pid=3688 connected to Xorg_pid=2890 Xorg_uid=1000 Xorg_gid=1000 client=[::ffff:192.168.96.13]:49199
[2024-02-16T16:42:56.452+0000] [DEBUG] xrdp_wm_log_msg: connected ok
[2024-02-16T16:42:56.453+0000] [INFO ] xrdp_wm_log_msg: Connecting to chansrv
[2024-02-16T16:42:56.454+0000] [DEBUG] libxrdp_query_channel - Channel 0 name rdpdr
[2024-02-16T16:42:56.455+0000] [DEBUG] libxrdp_query_channel - Channel 1 name rdpsnd
[2024-02-16T16:42:56.457+0000] [DEBUG] libxrdp_query_channel - Channel 2 name cliprdr
[2024-02-16T16:42:56.458+0000] [DEBUG] libxrdp_query_channel - Channel 3 name drdynvc
[2024-02-16T16:42:56.459+0000] [DEBUG] xrdp_mm_chansrv_connect: chansrv connect successful
[2024-02-16T16:42:56.461+0000] [DEBUG] status from xrdp_mm_connect() : 0
[2024-02-16T16:42:56.462+0000] [DEBUG] Login state change request WMLS_CONNECT_IN_PROGRESS -> WMLS_CLEANUP
[2024-02-16T16:42:56.463+0000] [DEBUG] Closed socket 26 (AF_UNIX)
[2024-02-16T16:42:56.464+0000] [DEBUG] Login state has changed to WMLS_CLEANUP
[2024-02-16T16:42:56.466+0000] [DEBUG] Login state change request WMLS_CLEANUP -> WMLS_INACTIVE
[2024-02-16T16:42:56.467+0000] [DEBUG] Login state has changed to WMLS_INACTIVE
[2024-02-16T16:42:56.468+0000] [INFO ] Received memory_allocation_complete command. width: 1984, height: 2304
[2024-02-16T16:42:56.503+0000] [DEBUG] xrdp_egfx_process: cmdId 0x10 flags 0 pduLength 36862
[2024-02-16T16:42:56.505+0000] [DEBUG] xrdp_egfx_process: unknown cmdId 0x10
[2024-02-16T16:42:56.569+0000] [ERROR] Child 3688 terminated unexpectedly with signal SIGSEGV

@matt335672
Copy link
Member Author

Thanks for that - very useful. It'll be tomorrow when I get to look at this.

This prevents valgrind errors when resizing the screen to
a larger size on GFX systems.
@matt335672
Copy link
Member Author

Updates for xrdp and xorgxrdp

The xorgxrdp commit should fix problems 1) and 2) above.
The xrdp commit doesn't fix anything, but makes it possible to run valgrind to locate any memory violations in xrdp.

I still getting some redraw problems on hot plug/unplug. The screen isn't always completely redrawn, and I've not tracked down why yet.

@metalefty
Copy link
Member

Now it works better. What about merging and test?

@matt335672
Copy link
Member Author

Give me a while to track down the redraw problem.

As I write this it's 9AM in the UK and I've got the whole working day to look at this.

I've had a think about it over the weekend, and I think I can see what's happening.

In GFX mode the screen buffer in xrdp_wm is needed for login, but is unused when xorgxrdp is loaded, as the module writes directly to the client, through the encoder thread.

My theory is that when we resize the screen, there's a window where the unused screen buffer can be copied to the client, overwriting what's been put there by xorgxrdp. xorgxrdp doesn't know this has happened, and in progressive mode it just updates bits of the framebuffer rather than the whole lot. This presesnts as a failed redraw.

This explains the messages I was getting from valgrind, and also why I was seeing screen corruption (rather than just black areas) when I added the code to clear down a resized bitmap.

I need to verify that my explanation is correct, and I also need to figure out the best way to disable the xrdp_wm screen buffer in GFX mode when using xorgxrdp. I think the buffer is still needed for VNC, but I'm not certain.

In GFX mode, if we're using xorgxrdp, frame updates are send directly
from the client, bypassing the screen buffer in xrdp_mm.

This commit only allows the xrdp_mm screen buffer to be invalidated
if the painter has drawn into it since the module was loaded. This
prevents the unused (and invalid) frame buffer being pushed to the client
in GFX mode with xorgxrdp.
@matt335672
Copy link
Member Author

A couple more fixes which mix some overwriting issues have been pushed to xrdp and xorgxrdp branches.

I'm still having problems with hot plug/unplug in GFX mode with xorgxrdp. VNC is fine and non-GFX xorgxrdp is fine.

  • Laptop is running Windows 10.
  • Laptop screen resolution is 1366x768. Second monitor is 2048x1152.
  • Start GFX/xorgxrdp with second monitor plugged in. Run a session over all monitors.
  • Unplug the second monitor

Result is:-

tmp

@Nexarian, @jsorg71 - any ideas on this?

@Nexarian
Copy link
Contributor

Nexarian commented Feb 19, 2024

@matt335672 What this looks like is some of the screen didn't get copied over correctly, which implies to me either:

  • Invalidate is called in the wrong spot.
  • You can use the "keyframe" mechanic to solve this and force a fresh re-render of all monitors once everything is back up.

Because RFX Pro does incremental frames, whenever a MS-RDPEDYC message is sent, it scrambles everything, and even though we're re-creating the encoder, an errant frame may still make its way through. I added a KEY_FRAME_REQUESTED message (should be in devel now) that you can use for xorgxrdp to rehydrate the RFX Pro encoder.

Or you may need to manually send the RFX_PRO_KEY message to the encoder directly from XRDP after everything is said and done.

@matt335672
Copy link
Member Author

Thanks @Nexarian - that was very useful as it got me checking all the codepaths and then I had a 'Eureka' moment.

When the shared memory and device memory are resized, we need to clear out the CRC fields as well. Otherwise we think memory areas match when in fact they don't, and they aren't being sent to the client.

Hot plug/unplug on my test system is now working with GFX/xorgxrdp. I'm engineering a proper commit to xorgxrdp which I'll commit later this morning (UK time)

@matt335672
Copy link
Member Author

@metalefty - just added a commit to branch fix_monitor_hotplug for xorgxrdp which resolves my issues with GFX hot plug/unplug.

I think this series of patches also resolves an issue @Nexarian mentioned somewhere which was than starting a GFX session and then connecting from a non-GFX client didn't work. I can't reproduce that here.

I'm read to go for merge and test now.

@metalefty
Copy link
Member

Thank! I will test it by myself. After that, I'll merge it and go for a test on user side.

@metalefty metalefty merged commit 2849dce into neutrinolabs:devel Feb 20, 2024
13 checks passed
@matt335672 matt335672 deleted the fix_monitor_hotplug branch February 20, 2024 17:20
@Nexarian
Copy link
Contributor

Thanks for all your hard work on this @matt335672. I haven't had time to fully digest all the changes you've made, but it looks like a good foundation on which to build the next versions of GFX!

@Nexarian
Copy link
Contributor

Also: You did exactly what I did: Spend time at night tracing the data flow path through my head and on paper and on whiteboards, and trying to determine exactly what might be wrong. Sleeping on it, waking up in the middle of the night with an insight that you have to try, etc. It's really hard to debug in a gdb-style way because seeing the actual frames that go through the system and the changes that happen with them is very difficult. You can't just watch for a variable to have an errant value and then fix the bug!

Anyway, this explains, I think, why most Remote Desktop ecosystems do not support this behavior. It's really hard, but also now a big differentiator for using XRDP!

@matt335672
Copy link
Member Author

I'm certainly looking forward to getting back to some more normal sleep patterns!

It's been an interesting couple of weeks, and given me a bit of insight into some of the more murky corners of the codebase. I'm sure that will come in useful in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants