Tech News
← Back to articles

Ancient X11 scaling technology

read original related products more articles

People keep telling me that X11 doesn’t support DPI scaling, or fractional scaling, or multiple monitors, or something. There’s nothing you can do to make it work. I find this surprising. Why doesn’t it work? I figure the best way to find out is try the impossible and see how far we get.

I’m just going to draw a two inch circle on the screen. This screen, that screen, any screen, the circle should always be two inches. Perhaps not the most exciting task, but I figure it’s isomorphic to any other scaling challenge. Just imagine it’s the letter o or a button we wish to draw at a certain size.

I have gathered around me a few screens of different sizes and resolutions. My laptop screen, and then a bit to the right a desktop monitor, and then somewhere over that way a nice big TV. Specifically:

$ xrandr | grep \ connected eDP connected primary 2880x1800+0+0 (normal left inverted right x axis y axis) 302mm x 189mm DisplayPort-0 connected 2560x1440+2880+0 (normal left inverted right x axis y axis) 590mm x 334mm DisplayPort-1 connected 3840x2160+5440+0 (normal left inverted right x axis y axis) 1600mm x 900mm

I think I just spoiled the ending, but here we go anyway.

I’m going to draw the circle with OpenGL, using a simple shader and OBT. There’s a bunch of not very exciting code to create a window and a GLX context, but eventually we’re going to be looking at the shader. This may not be the best way to draw a circle, but it’s my way. For reference, the full code is in circle.c.

void main ( ) { float thick = radius / 10 ; if ( abs ( center . y - gl_FragCoord . y ) < thick / 2 ) thick = 2 ; float pi = 3 . 14159 ; float d = distance ( gl_FragCoord . xy , center ) ; float angle = atan ( gl_FragCoord . y - center . y , gl_FragCoord . x - center . x ) ; angle /= 2 * pi; angle += 0 . 5 ; angle += 0 . 25 ; if ( angle > 1 . 0 ) angle -= 1 . 0 ; float amt = ( thick - abs ( d - radius ) ) / thick; if ( d < radius + thick && d > radius - thick ) fragment = vec4 ( rgb ( angle ) * amt , 1 . 0 ) ; else discard; }

I got a little carried away and made a pretty color wheel instead of a flat circle.

The key variable is radius which tells us how many pixels from the center the circle should be. But where does the shader get this from?

glUniform1f(0, radius);

... continue reading