From e4eab186ecb3d38a43b6c7645f2048eda1655478 Mon Sep 17 00:00:00 2001 From: Jeffrey Knockel Date: Sun, 20 Mar 2022 18:52:49 -0400 Subject: [PATCH] Return xrandr-scaled display modes XRandR supports applying transformations to an output's picture including changes to scale. Such scaling is used by some desktop environments under feature names such as "fractional scaling" to accomodate HiDPI devices. Alternatively, such scaling can be enabled by a command such as the following: xrandr --output DP1 --scale 0.5x0.5 --filter nearest XRandR scaling has no "HiDPI awareness" or other way for an application to signal that it wants to work with physical display pixels, and so all we do is scale SDL's returned display modes so that applications receive the number of usable pixels that they expect. --- src/video/x11/SDL_x11modes.c | 15 +++++++++++---- src/video/x11/SDL_x11sym.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index f77c58b6af..59920974d2 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -397,19 +397,26 @@ static SDL_bool SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRC if (info->id == modeID) { XRRCrtcInfo *crtcinfo; Rotation rotation = 0; + XFixed scale_w = 0x10000, scale_h = 0x10000; + XRRCrtcTransformAttributes *attr; crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc); if (crtcinfo) { rotation = crtcinfo->rotation; X11_XRRFreeCrtcInfo(crtcinfo); } + if (X11_XRRGetCrtcTransform(display, crtc, &attr) && attr) { + scale_w = attr->currentTransform.matrix[0][0]; + scale_h = attr->currentTransform.matrix[1][1]; + X11_XFree(attr); + } if (rotation & (XRANDR_ROTATION_LEFT | XRANDR_ROTATION_RIGHT)) { - mode->w = info->height; - mode->h = info->width; + mode->w = (info->height * scale_w + 0xffff) >> 16; + mode->h = (info->width * scale_h + 0xffff) >> 16; } else { - mode->w = info->width; - mode->h = info->height; + mode->w = (info->width * scale_w + 0xffff) >> 16; + mode->h = (info->height * scale_h + 0xffff) >> 16; } mode->refresh_rate = CalculateXRandRRefreshRate(info); ((SDL_DisplayModeData *)mode->driverdata)->xrandr_mode = modeID; diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 9f8f6b69b4..0a5fe38d56 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -309,6 +309,7 @@ SDL_X11_SYM(XRRPropertyInfo*,XRRQueryOutputProperty,(Display *dpy,RROutput outpu SDL_X11_SYM(int,XRRGetOutputProperty,(Display *dpy,RROutput output, Atom property, long offset, long length, Bool _delete, Bool pending, Atom req_type, Atom *actual_type, int *actual_format, unsigned long *nitems, unsigned long *bytes_after, unsigned char **prop),(dpy,output,property,offset,length, _delete, pending, req_type, actual_type, actual_format, nitems, bytes_after, prop),return) SDL_X11_SYM(RROutput,XRRGetOutputPrimary,(Display *dpy,Window window),(dpy,window),return) SDL_X11_SYM(void,XRRSelectInput,(Display *dpy, Window window, int mask),(dpy,window,mask),) +SDL_X11_SYM(Status,XRRGetCrtcTransform,(Display *dpy,RRCrtc crtc,XRRCrtcTransformAttributes **attributes),(dpy,crtc,attributes),return) #endif /* MIT-SCREEN-SAVER support */