3

I have a 23.8 inch monitor. Output of xrandr =

Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
DP-1 disconnected (normal left inverted right x axis y axis)
HDMI-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
HDMI-2 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm panning 1920x1080+0+0
   1920x1080     60.00*+  50.00    59.94  
   1920x1080i    60.00    50.00    59.94  
   1680x1050     59.88  
   1600x900      60.00  
   1280x1024     75.02    60.02  
   1280x800      59.91  
   1152x864      75.00  
   1280x720      60.00    50.00    59.94  
   1024x768      75.03    60.00  
   832x624       74.55  
   800x600       75.00    60.32  
   720x576       50.00  
   720x576i      50.00  
   720x480       60.00    59.94  
   720x480i      60.00    59.94  
   640x480       75.00    60.00    59.94  
   720x400       70.08  

I want to simulate a smaller sized monitor (~ 15 inch) within my monitor in the following way :

|----------|-----|
|          |     |
|  X       |  Y  |
|          |     |
|      ~15 |     |
|-----------     |
|            23.8|
-----------------

The X region has to behave like a normal monitor and the Y region has to be blank (black screen)

I am trying to do with xrandr but no success. Any ideas how I can crop the screen like above and show the whole of screen content (in a smaller resolution) in region X?

Any help is appreciated

1 Answer 1

2

xrandr can (tell the GPU to) apply an arbitrary transformation matrix in homogenous coordinates (For 2D, that's a 3x3 matrix with the end (g h i below) typically always [0 0 1]):

--transform a,b,c,d,e,f,g,h,i
Specifies a transformation matrix to apply on the output. Automatically a bilinear filter is selected. The mathematical form corresponds to:

a b c
d e f
g h i

The transformation is based on homogeneous coordinates. The matrix multiplied by the coordinate vector of a pixel of the output gives the transformed coordinate vector of a pixel in the graphic buffer. [...]

This hints that from the shrinked display to the larger actual frame buffer one has to multiply by more than 1. So to shrink the framebuffer to a display smaller by 23.8/15 one would multiply (rather than divide) by 23.8/15 the 2x2 upper left part of the matrix to get:

1.5867   0     0
0     1.5867   0
0        0     1

Once this is achieved, one must manually keep the previous virtual screen size (ie: the framebuffer size) as it was or it would just be computed to be larger to still cover the monitor: --fb 1920x1080.

--fb widthxheight
Reconfigures the screen to the specified size. All configured monitors must fit within this size. When this option is not provided, xrandr computes the smallest screen size that will hold the set of configured outputs; this option provides a way to override that behaviour.

This setting is global, not per monitor.

This gives:

$ xrandr --output HDMI-2 --transform 1.5867,0,0,0,1.5867,0,0,0,1 --fb 1920x1080

I was just showing the general case in case you want to apply multiple effects (like also a translation): you'd have to multiply matrices and provide the final resulting matrix only. Actually this transformation being simple there's a dedicated option instead:

--scale xxy
Changes the dimensions of the output picture. Values superior to 1 will lead to a compressed screen (screen dimension bigger than the dimension of the output mode), and values below 1 leads to a zoom in on the output. This option is actually a shortcut version of the --transform option.

So in the end just:

$ xrandr --output HDMI-2 --scale 1.5867x1.5867 --fb 1920x1080

There's a warning because the result doesn't cover the monitor anymore:

xrandr: specified screen 1920x1080 not large enough for output HDMI-2 (3047x1714+0+0)

The output mode didn't change (it could be explictly specified with --mode 1920x1080 --rate 60.00).

6
  • Thanks for the response A.B , I tried this and now the X and Y region do appear as required. The output mode (for region X) is the same as 1920x1080. But if I try to set it as any other mode (--mode 1024x768) then the screen covers the whole monitor and the difference of region X and Y is no longer there. I have not completely understood the maths and my understanding of the scaling is that it will proportion the screen as per the fraction irrespective of the resolution....is that true? ....
    – harsh atal
    Commented Dec 2, 2020 at 16:13
  • ... Is "1.5867" tied to a specific resolution (1920x1080 in this case). Basically I want the resolution in the X region to be 1024x768 OR 800x600. What should I do to achieve that?
    – harsh atal
    Commented Dec 2, 2020 at 16:13
  • Your answer is nice please do not amputate. Based on your answer the following gives acceptable result : - "xrandr --output HDMI-2 --mode 1024x768 --fb 1290x1024 --scale 1.5867x1.5867".
    – harsh atal
    Commented Dec 2, 2020 at 16:57
  • The same command with 800x600 resolution covers the whole of the monitor and does not give output like the X and Y type of screen. ( xrandr --output HDMI-2 --mode 800x600 --fb 1290x1024 --scale 1.5867x1.5867 ) . Why does the command behave differently for 800x600?
    – harsh atal
    Commented Dec 2, 2020 at 17:03
  • Yeah sorry that is 1920 not 1290. For the lower resolution does the scaling parameter not work ? I mean we should still get the output whatever resolution within the X region but in the case of 800x600 command the whole of the monitor is covered...I mean basically how to get 800x600 resolution in the X region while the non X region stays blank?
    – harsh atal
    Commented Dec 2, 2020 at 17:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .