File: modeline2fb

package info (click to toggle)
fbset 2.1-23
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 568 kB
  • ctags: 437
  • sloc: ansic: 1,401; yacc: 130; lex: 121; perl: 113; makefile: 94; sh: 10
file content (150 lines) | stat: -rwxr-xr-x 4,409 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/perl

# Simple modeline-to-fb.modes translator
# (c) 1998 by Patrick Reynolds
# distributed under the GNU General Public License
 
# mapping of modeline options to fb.modes options
%options_map = (
  "-hsync" => "hsync low",
  "-vsync" => "vsync low",
  "+hsync" => "hsync high",
  "+vsync" => "vsync high",
  "interlace" => "laced true",
  "doublescan" => "double true"
);

@possible_vxres = ( 640, 800, 1024, 1152, 1280, 1600, 1920, 2048 );

# default settings (override with -d and -r)
$depth = 8;
$rounding = 128;

# parse options
while ($ARGV[0] =~ /^-/) {
  $arg = shift;
  if ($arg eq "-d" || $arg eq "--depth") {
    if (!($arg = shift @ARGV)) {
      usage("-d requires an argument");
    }
    $depth = $arg;
  }
  elsif ($arg eq "-r" || $arg eq "--rounding") {
    if (!($arg = shift @ARGV)) {
      usage("-r requires an argument");
    }
    $rounding = $arg;
  }
  elsif ($arg eq "-x" || $arg eq "--vxres") {
    if (!($arg = shift @ARGV)) {
      usage("-x requires an argument");
    }
    push @possible_vxres, (split/,/,$arg);
    @possible_vxres = sort { $a <=> $b } @possible_vxres;
    print "new vxres: " . (join ",", @possible_vxres) . "\n";
  }
  elsif ($arg eq "-h" || $arg eq "--help") {
    usage();
  }
  else {
    usage("unknown option: $arg");
  }
}

# find out how much video memory is available
open(FBSET, "fbset -i|") || die "could not detect available video memory";
while (<FBSET>) {
  if (/Size\s*:\s*(\d+)/) {
    $size = $1;
    last;
  }
}
if (!$size) { die "could not detect available video memory"; }

# huge kludge (hey, that rhymes!) ...
#   subtract 16384 from the available memory $size
#   why?  the default 640x480 mode uses all but 16384, and when I set it
#   to use more than that, it oopses (!).  So... for safety's sake, and
#   because you probably don't use those 15-25 lines anyway...
$size -= 16384;

print "# modes.fb - video mode descriptions for fbset
#
# See fbset(8) and fb.modes(5) for more information

";

$flag = 0;
# read all XF86Config files
while(<>) {
  chomp;
  next if !(($name, $clock, $xres, $xsyncstart, $xsyncend, $xfres,
                  $yres, $ysyncstart, $ysyncend, $yfres, $extra) =
    /^\s*modeline\s+"([^"]+)"\s+([0-9.]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*(.*)$/i);
  $flag = 1;

  # timing transformations, as described in the fb HOWTO
  $pixtime = int(1000000/$clock);
  $left = $xfres - $xsyncend;
  $right = $xsyncstart - $xres;
  $hsynclen = $xsyncend - $xsyncstart;
  $top = $yfres - $ysyncend;
  $bottom = $ysyncstart - $yres;
  $vsynclen = $ysyncend - $ysyncstart;

  # pick a virtual X and Y resolution
  $vxres = get_vxres($xres);
  if ($vxres < 0) {
    print STDERR "Could not guess a good virtual resolution for mode $name.\n";
    print STDERR "Use the advanced options --rounding and --vxres.\n";
    next;
  }
  $vyres = int($size/$vxres);

  # print out our entry
  print "mode \"$name\"\n";
  print "  geometry   $xres $yres   $vxres $vyres   $depth\n";
  print "  timings    $pixtime   $left $right   $top $bottom   $hsynclen $vsynclen\n";

  # handle extra options at the end of the modeline
  $extra =~ tr/A-Z/a-z/;
  @options = split/\s+/,$extra;
  foreach (@options) {
    if ($options_map{$_}) {
      print "  $options_map{$_}\n";
    }
    else {
      print "  # unknown option: $_\n";
    }
  }
  print "endmode\n\n";
}

if (!$flag) {
  print STDERR "No modelines found.\n";
  print STDERR "Make sure the file you specified was an XF86Config file and\n";
  print STDERR "used the single-line Modeline format.\n\n";
  print STDERR "Use \"$0 --help\" for help.\n";
}

sub get_vxres {
  foreach (@possible_vxres) {
    return $_ if ($_ >= $_[0] && ($_ % $rounding) == 0);
  }
  return -1;
}

sub usage {
  print STDERR "$_[0]\n" if ($_[0]);
  print STDERR "$0 [OPTION] [FILES]\n\n";
  print STDERR "  -d,--depth depth     use a certain display depth (default is 8)\n";
  print STDERR "  -h,--help            what you see here\n\n";
  print STDERR "Advanced options:\n";
  print STDERR "  -r,--rounding div    vxres divisor (default is 128)\n";
  print STDERR "  -x,--vxres X,X,X,... extra possible vxres values\n\n";
  print STDERR "[FILES] refers to one or more XF86Config files.  Note that\n";
  print STDERR "all modelines must be in single-line format.\n\n";
  print STDERR "Example:\n";
  print STDERR "  $0 -d 16 /etc/X11/XF86Config\n";
  exit 0;
}