From c1326932f4dcf34dc4c0a4f942c9881eac279eea Mon Sep 17 00:00:00 2001 From: Christopher Pitstick Date: Sat, 2 Jul 2022 14:15:11 -0400 Subject: [PATCH] Support set monitor info and scale This is a shameless copy of https://github.com/neutrinolabs/xorgxrdp/pull/172 for my own prototyping and editing purposes. We need to figure out how to get xf86SetDpi working. --- module/rdpClientCon.c | 17 +++--- module/rdpRandR.c | 117 +++++++++++++++++++++++++++++++----------- module/rdpRandR.h | 2 +- 3 files changed, 98 insertions(+), 38 deletions(-) diff --git a/module/rdpClientCon.c b/module/rdpClientCon.c index f35743c2..3f7ee26d 100644 --- a/module/rdpClientCon.c +++ b/module/rdpClientCon.c @@ -1003,27 +1003,32 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon) box.x2 = dev->minfo[0].right; box.y2 = dev->minfo[0].bottom; /* adjust monitor info so it's not negative */ - for (index = 1; index < dev->monitorCount; index++) + for (index = 1; index < dev->monitorCount; ++index) { box.x1 = min(box.x1, dev->minfo[index].left); box.y1 = min(box.y1, dev->minfo[index].top); box.x2 = max(box.x2, dev->minfo[index].right); box.y2 = max(box.y2, dev->minfo[index].bottom); } - for (index = 0; index < dev->monitorCount; index++) + for (index = 0; index < dev->monitorCount; ++index) { dev->minfo[index].left -= box.x1; dev->minfo[index].top -= box.y1; dev->minfo[index].right -= box.x1; dev->minfo[index].bottom -= box.y1; - LLOGLN(0, (" left %d top %d right %d bottom %d", + + LLOGLN(0, (" left %d top %d right %d bottom %d pWidth %d pHeight %d " + "orientation %d", dev->minfo[index].left, dev->minfo[index].top, dev->minfo[index].right, - dev->minfo[index].bottom)); + dev->minfo[index].bottom, + dev->minfo[index].physical_width, + dev->minfo[index].physical_height, + dev->minfo[index].orientation)); } - rdpRRSetRdpOutputs(dev); + rdpRRSetRdpOutputs(dev, clientCon); RRTellChanged(dev->pScreen); } else @@ -1032,7 +1037,7 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon) clientCon->doMultimon = 0; dev->doMultimon = 0; dev->monitorCount = 0; - rdpRRSetRdpOutputs(dev); + rdpRRSetRdpOutputs(dev, clientCon); RRTellChanged(dev->pScreen); } diff --git a/module/rdpRandR.c b/module/rdpRandR.c index f96da0a0..e9919be9 100644 --- a/module/rdpRandR.c +++ b/module/rdpRandR.c @@ -41,12 +41,16 @@ RandR draw calls #include #include #include +#include +#include +#include #include "rdp.h" #include "rdpDraw.h" #include "rdpReg.h" #include "rdpMisc.h" #include "rdpRandR.h" +#include "rdpClientCon.h" #if defined(XORGXRDP_GLAMOR) #include @@ -364,9 +368,42 @@ rdpRRSetPanning(ScreenPtr pScreen, RRCrtcPtr crtc, BoxPtr totalArea, return TRUE; } +/******************************************************************************/ +static void +rdpRRSetOutputPhysicalSize(const char* func, RROutputPtr output, + struct monitor_info *monitor) +{ + if (monitor->physical_height == 0 || monitor->physical_width == 0) + { + return; + } + if (!RROutputSetPhysicalSize(output, + monitor->physical_width, monitor->physical_height)) + { + LLOGLN(0, ("%s: RROutputSetPhysicalSize failed", func)); + } +} + +/******************************************************************************/ +static Rotation +rdpGetRotation(uint32_t orientation) +{ + switch (orientation) + { + case 90: + return RR_Rotate_90; + case 180: + return RR_Rotate_180; + case 270: + return RR_Rotate_270; + default: + return RR_Rotate_0; + } +} + /******************************************************************************/ static RROutputPtr -rdpRRAddOutput(rdpPtr dev, const char *aname, int x, int y, int width, int height) +rdpRRAddOutput(rdpPtr dev, const char *aname, struct monitor_info *monitor) { RRModePtr mode; RRCrtcPtr crtc; @@ -375,6 +412,10 @@ rdpRRAddOutput(rdpPtr dev, const char *aname, int x, int y, int width, int heigh char name[64]; const int vfreq = 50; int i; + int width = (monitor->right - monitor->left + 1); + int height = (monitor->bottom - monitor->top + 1); + int x = monitor->left; + int y = monitor->top; sprintf (name, "%dx%d", width, height); memset (&modeInfo, 0, sizeof(modeInfo)); @@ -416,6 +457,7 @@ rdpRRAddOutput(rdpPtr dev, const char *aname, int x, int y, int width, int heigh RRModeDestroy(mode); return 0; } + rdpRRSetOutputPhysicalSize(__func__, output, monitor); if (!RROutputSetClones(output, NULL, 0)) { LLOGLN(0, ("rdpRRAddOutput: RROutputSetClones failed")); @@ -432,19 +474,24 @@ rdpRRAddOutput(rdpPtr dev, const char *aname, int x, int y, int width, int heigh { LLOGLN(0, ("rdpRRAddOutput: RROutputSetConnection failed")); } - RRCrtcNotify(crtc, mode, x, y, RR_Rotate_0, NULL, 1, &output); + RRCrtcNotify(crtc, mode, x, y, rdpGetRotation(monitor->orientation), + NULL, 1, &output); return output; } /******************************************************************************/ static RROutputPtr rdpRRUpdateOutput(RROutputPtr output, RRCrtcPtr crtc, - int x, int y, int width, int height) + struct monitor_info *monitor) { RRModePtr mode; xRRModeInfo modeInfo; char name[64]; const int vfreq = 50; + int width = monitor->right - monitor->left + 1; + int height = monitor->bottom - monitor->top + 1; + int x = monitor->left; + int y = monitor->top; LLOGLN(0, ("rdpRRUpdateOutput:")); sprintf (name, "%dx%d", width, height); @@ -465,7 +512,9 @@ rdpRRUpdateOutput(RROutputPtr output, RRCrtcPtr crtc, { LLOGLN(0, ("rdpRRUpdateOutput: RROutputSetModes failed")); } - RRCrtcNotify(crtc, mode, x, y, RR_Rotate_0, NULL, 1, &output); + rdpRRSetOutputPhysicalSize(__func__, output, monitor); + RRCrtcNotify(crtc, mode, x, y, rdpGetRotation(monitor->orientation), + NULL, 1, &output); RROutputChanged(output, 1); return output; } @@ -516,14 +565,10 @@ rdpRRRemoveExtra(rrScrPrivPtr pRRScrPriv, int count) /******************************************************************************/ int -rdpRRSetRdpOutputs(rdpPtr dev) +rdpRRSetRdpOutputs(rdpPtr dev, rdpClientCon *clientCon) { rrScrPrivPtr pRRScrPriv; int index; - int left; - int top; - int width; - int height; char text[256]; RROutputPtr output; @@ -532,29 +577,40 @@ rdpRRSetRdpOutputs(rdpPtr dev) pRRScrPriv->numCrtcs, pRRScrPriv->numOutputs, dev->monitorCount)); if (dev->monitorCount <= 0) { - left = 0; - top = 0; - width = dev->width; - height = dev->height; + struct monitor_info monitor; + memset(&monitor, 0, sizeof(monitor)); + monitor.top = 0; + monitor.left = 0; + monitor.right = dev->width - 1; + monitor.bottom = dev->height - 1; + monitor.physical_width + = clientCon->client_info.display_sizes.session_width; + monitor.physical_height + = clientCon->client_info.display_sizes.session_height; + monitor.orientation = 0; + monitor.desktop_scale_factor = 100; + monitor.device_scale_factor = 100; + if (pRRScrPriv->numCrtcs > 0) { /* update */ LLOGLN(0, ("rdpRRSetRdpOutputs: update output %d " - "left %d top %d width %d height %d", - 0, left, top, width, height)); + "left %d top %d right %d bottom %d", + 0, monitor.left, monitor.top, + monitor.right, monitor.bottom)); output = rdpRRUpdateOutput(pRRScrPriv->outputs[0], pRRScrPriv->crtcs[0], - left, top, width, height); + &monitor); } else { /* add */ LLOGLN(0, ("rdpRRSetRdpOutputs: add output %d " - "left %d top %d width %d height %d", - 0, left, top, width, height)); + "left %d top %d right %d bottom %d", + 0, monitor.left, monitor.top, + monitor.right, monitor.bottom)); snprintf(text, 255, "rdp%d", 0); - output = rdpRRAddOutput(dev, text, - left, top, width, height); + output = rdpRRAddOutput(dev, text, &monitor); } if (output == NULL) { @@ -568,29 +624,28 @@ rdpRRSetRdpOutputs(rdpPtr dev) { for (index = 0; index < dev->monitorCount; index++) { - left = dev->minfo[index].left; - top = dev->minfo[index].top; - width = dev->minfo[index].right - dev->minfo[index].left + 1; - height = dev->minfo[index].bottom - dev->minfo[index].top + 1; if (index < pRRScrPriv->numCrtcs) { /* update */ LLOGLN(0, ("rdpRRSetRdpOutputs: update output %d " - "left %d top %d width %d height %d", - index, left, top, width, height)); + "left %d top %d right %d bottom %d scale %d", + index, dev->minfo[index].left, dev->minfo[index].top, + dev->minfo[index].right, dev->minfo[index].bottom, + dev->minfo[index].desktop_scale_factor)); output = rdpRRUpdateOutput(pRRScrPriv->outputs[index], pRRScrPriv->crtcs[index], - left, top, width, height); + &dev->minfo[index]); } else { /* add */ LLOGLN(0, ("rdpRRSetRdpOutputs: add output %d " - "left %d top %d width %d height %d", - index, left, top, width, height)); + "left %d top %d right %d bottom %d scale %d", + index, dev->minfo[index].left, dev->minfo[index].top, + dev->minfo[index].right, dev->minfo[index].bottom, + dev->minfo[index].desktop_scale_factor)); snprintf(text, 255, "rdp%d", index); - output = rdpRRAddOutput(dev, text, - left, top, width, height); + output = rdpRRAddOutput(dev, text, &dev->minfo[index]); } if ((output != 0) && (dev->minfo[index].is_primary)) { diff --git a/module/rdpRandR.h b/module/rdpRandR.h index 4709c6e4..bf2121dd 100644 --- a/module/rdpRandR.h +++ b/module/rdpRandR.h @@ -61,6 +61,6 @@ extern _X_EXPORT Bool rdpRRSetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea, BoxPtr trackingArea, INT16* border); extern _X_EXPORT int -rdpRRSetRdpOutputs(rdpPtr dev); +rdpRRSetRdpOutputs(rdpPtr dev, rdpClientCon *clientCon); #endif