in reply to Getting screen resolution

The following code example parses the output of xdpyinfo(1x) program. You need the base X client utilities from XFree86 installed (don't know about compatibility with other X distributions).

#!/usr/bin/perl use Data::Dumper; my ($scr, $curr_scr, %screens); open my $fh, "xdpyinfo|" or die; while (<$fh>) { $scr = $1 if m/^\s*screen\s+#(\d+):/; $curr_scr = $1 if m/^\s*default screen number:\s+(\d+)/; @{$screens{$scr}}{'x','y'} = ($1, $2) if m/^\s*dimensions:\s+(\d+)x(\d+)/; } close $fh; print "Current screen: $curr_scr\n\n"; print Dumper \%screens;

with the following output on an Xnest with four screens :

Current screen: 2 $VAR1 = { '1' => { 'y' => '576', 'x' => '768' }, '3' => { 'y' => '576', 'x' => '768' }, '0' => { 'y' => '576', 'x' => '768' }, '2' => { 'y' => '576', 'x' => '768' } };

I don't know how/if the Xinerama screens map to historic X server screens, though (I'm not familiar with Xinerama). Try and see if it works.

Replies are listed 'Best First'.
Re: Re: Getting screen resolution
by lilphil (Scribe) on Feb 11, 2004 at 03:38 UTC
    Thanks to all.

    Unfortunatly, as it turns out, xwininfo, xdpyinfo and X11::Protocol report a single screen under xinerama (2432x1064 in my case), but this is a good start.
    I think Ao's idea will work, although it could be difficult to ensure the windows maximise over the top of the task bar. I'm going to have a think about that one, largely because i've never used Perl/TK :)

    Any further ideas welcome.
    Thanks,
    Phil

      Sorry for the delay - 2004 was before my time on PerlMonks...

      Today, xrandr would be the tool of choice:

      qwurx [shmem] ~ > xrandr Screen 0: minimum 320 x 200, current 2944 x 1200, maximum 4096 x 4096 VGA-0 connected 1920x1200+0+0 (normal left inverted right x axis y axi +s) 518mm x 324mm 1920x1200 60.0*+ 1280x1024 75.0 1152x864 75.0 1024x768 75.1 70.1 60.0 832x624 74.6 800x600 72.2 75.0 60.3 56.2 640x480 72.8 75.0 66.7 60.0 720x400 70.1 0x0 0.0 DVI-0 disconnected (normal left inverted right x axis y axis) LVDS connected 1024x768+1920+0 (normal left inverted right x axis y ax +is) 0mm x 0mm 1024x768 60.0*+ 60.0 800x600 60.3 56.2 640x480 59.9

      I'd parse that as follows, to get the current Xinerama screen portion a toplevel is in. Crude hack...

      my ($W, $H); # width and height of current display { (my $screennumber = $ENV{DISPLAY}) =~ s/:(\w+\.)?//; my $screenfound = 0; open my $fh, '-|', 'xdpyinfo' or die "Can't run xdpyinfo: $!\n"; while(<$fh>) { $screenfound++ if /screen #$screennumber:/; next unless $screenfound; if(/dimensions:\s+(\d+)x(\d+)/) { ($W,$H) = ($1,$2); 1 while <I>; } } close $fh; } # get_area - get the current Xinerama screen portion # # input: $window - a Toplevel Tk window # return: # $ox: offset x # $oy: offset y # $w: width # $w: height sub get_area { my $window = shift; chomp (my $xrandr = `which xrandr`); my ($ox, $oy, $w, $h); if ($xrandr) { open my $fh, '-|', $xrandr or die "Can't run xrandr: $!\n"; my @a; while(<$fh>) { /\bconnected (\d+)x(\d+)\+(\d+)\+(\d+)/ and push @a, { w => $1, h => $2, x => $3, y => $4 }; } if (1 < @a) { # find current offset my @g = $window->geometry =~ /(\d+)x(\d+)([\+-])(\d+)\+(\d ++)/; $g[3] += $W-$g[0] if $g[2] eq '-'; splice @g,2,1; my %g; @g{qw(w h x y)} = @g; my ($min,$max) = ($a[0]->{w} >= $a[1]->{w} && $a[0]->{h} >= $a[1]->{h}) ? reverse @a : @a; if( $g{x} >= $min->{x} && $g{y} >= $min->{y} && $g{x}+$g{w} <= $min->{x}+$min->{w} && $g{y}+$g{h} <= $min->{y}+$min->{h} ) { $ox = $min->{x}; $oy = $min->{y}; $w = $min->{w}; $h = $min->{h}; } else { $ox = $max->{x}; $oy = $max->{y}; $w = $max->{w}; $h = $max->{h}; } } } ($ox, $oy, $w, $h); }

      Heh... does this post make sense, more than five years later? ;-)

        Heh, thanks shmem - I have absolutely no idea what I was doing this for now though! I seem to recall it was something about patching together pictures for desktop backgrounds...