-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Adding egfx base functions. #2338
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Nexarian - a few thoughts for you. I thought I'd comment now as next week is looking a bit hairy time-wise.
xrdp/xrdp_egfx.c
Outdated
int error; | ||
int bytes; | ||
struct stream *s; | ||
char *holdp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some macros to do this stuff in parse.h, namely s_push_layer() and s_pop_layer(). You might want to consider using these for consistency with other code elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, agreed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matt335672 I believe this is resolved.
xrdp/xrdp_egfx.c
Outdated
|
||
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_send_fill_surface:"); | ||
make_stream(s); | ||
init_stream(s, 8192); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this guaranteed to be big enough, or should you scale it depending on num_rects
? Somehing like init_stream(s, 1024 + num_rects * 8);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, unlikely but yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matt335672 I believe this is resolved.
xrdp/xrdp_egfx.c
Outdated
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_send_wire_to_surface1:"); | ||
make_stream(s); | ||
bytes = bitmap_data_length + 8192; | ||
bytes += 5 * (bitmap_data_length / 0xFFFF); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
USHRT_MAX for consistency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess a define like MAX_PART_SIZE would be best
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matt335672 I believe this is resolved.
out_uint32_le(s, 340); | ||
out_uint32_le(s, width); | ||
out_uint32_le(s, height); | ||
out_uint32_le(s, monitor_count == 0 ? 1 : monitor_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I am not an xrdp member, its your choice. But personally I wouldn't apply workarounds for the own code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a workaround for Microsoft's Mac OS Client. We can't ever send a monitorcount of 0, even though internally sometimes it's set that way. So, from Microsoft's perspective, this is important to always be one.
What would you recommend I do instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't ever send a monitorcount of 0
Well, it's RDP, it's about graphical remote desktop. You always have at least one monitor. Sending a monitor config here with 0 monitors is a bug.
If you know, that the monitor config changed, but not know yet the actual monitor layout, then defer sending this PDU until you know the new layout.
Same for the subsequent PDUs, which provide the graphics content (wire_to_surface, etc.).
There is no need to send this PDU until the screen changes or the layout changes are done.
The question would also be: If you have 0 monitors, what size for the graphics output buffer do you use in that situation?
The graphics output buffer only contains user visible surfaces, i.e. surfaces that are mapped to an output (map_surface_to_output).
You can have offscreen surfaces, that are not mapped, that are actually larger than the graphics output buffer itself, in case that is relevant for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that 0 monitors is a bug in XRDP, but it's pretty baked in at this point and probably out of scope for this PR to fix it.
In the past "0 monitors with a session_width and a session_height" just meant "multi-mon is not enabled and we have one single large surface." It didn't actually matter until GFX integration, which cares about monitor numbering more than RLE or RemoteFX appeared to.
That is indeed wrong. I'll write up an issue about what's wrong here and that we should fix it (and hopefully if I have time, what needs to be fixed), then reference it in a TODO.
Sound good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that 0 monitors is a bug in XRDP, but it's pretty baked in at this point and probably out of scope for this PR to fix it.
Sure, xrdp_egfx_send_reset_graphics()
is also not used yet.
Personally, I would, in case that bug is unavoidable, apply the workaround at the earliest point possible (i.e. in future commits, where xrdp_egfx_send_reset_graphics
is actually used). This way, the area of code, where that bug exists would be reduced.
Sound good?
Ultimately, it is up to you how you handle that, because I am not part of the xrdp project. I can only point out wrong or fishy things here.
I'll write up an issue about what's wrong here and that we should fix it (and hopefully if I have time, what needs to be fixed), then reference it in a TODO.
Creating an issue sounds sane to avoid, that the issue is lost, while the bug still exists.
{ | ||
return 1; | ||
} | ||
switch (cmdId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You must be able to handle the Cache Import Offer PDU (and reply to it), even when you don't want to import anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that is not enough or right: Quoting the docs here (1.5.2 Server Implementation Requirements
):
Furthermore, servers implementing the Remote Desktop Protocol: Graphics Pipeline Extension must
be capable of processing the following messages:
- RDPGFX_FRAME_ACKNOWLEDGE_PDU (section 2.2.2.13)
- RDPGFX_CACHE_IMPORT_OFFER_PDU (section 2.2.2.16)
- RDPGFX_CAPS_ADVERTISE_PDU (section 2.2.2.18)
Also, 3.2.5.16 Processing an RDPGFX_CACHE_IMPORT_OFFER_PDU message
:
Once the RDPGFX_CACHE_IMPORT_OFFER_PDU message has been processed, the server MUST
respond by sending the RDPGFX_CACHE_IMPORT_REPLY_PDU (section 2.2.2.17) message to the
client (section 3.2.5.17).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it! I copied your comment into the issue so we don't lose it.
What's the best way to test this? Is there a way to force FreeRDP to send this message so we can test the negotiation? Or is there a mode on the Microsoft clients we can set to trigger it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mstsc sends that PDU (though not always).
ea1462c
to
cd3f134
Compare
00471d0
to
2f7551e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not at all up-to-speed on what EGFX does, so I've restricted my review to looking at possible overflows and leaks. From that perspective, I think this is fine - I haven't found any issues.
return 1; | ||
} | ||
holdp = s->p; | ||
if (capsDataLength == 4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to mention (for others), that caps version 101 is indirectly excluded here, but that's up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
xrdp/xrdp_egfx.c
Outdated
/* RDP_SEGMENTED_DATA */ | ||
out_uint8(s, 0xE0); /* descriptor = SINGLE */ | ||
/* RDP8_BULK_ENCODED_DATA */ | ||
out_uint8(s, 0x04); /* header = PACKET_COMPR_TYPE_RDP8 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small suggestion (not an issue), you could use a define
for the PACKET_COMPR_TYPE_RDP8
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
- This isn't hooked up to anything yet. That will come later with further EGFX commits. - There are some TODO items in this code around the way XRDP handles caps negotiation and monitor storage. - This is a great candidate for unit testing in the future.
ceafa74
to
af8995e
Compare
It seems this has been reviewed well enough to be merged. I don't want to sit on this any further, as I definitely need to get moving on EGFX merge into devel so the benefits can be enjoyed by more standard users of XRDP. For further issues and bug fixes, future PRs where I incorporate more of mainline_merge will be a great candidate. |
No description provided.