#!/usr/bin/env perl
#-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-

# Display configurator. Designed to be architecture and distribution independent.
#
# Copyright (C) 2000-2001 Ximian, Inc.
#
# Authors: Tambet Ingo <tambet@ximian.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published
# by the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

# Best viewed with 100 columns of width.

# Configuration files affected:
#
# /etc/X11/XF86Config

# Running programs affected:
#

BEGIN {
  $SCRIPTSDIR = "/usr/share/setup-tool-backends/scripts";
  if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
  {
      $SCRIPTSDIR = ".";
      $DOTIN = ".in";
  }
  
  require "$SCRIPTSDIR/general.pl$DOTIN";
  require "$SCRIPTSDIR/platform.pl$DOTIN";
  require "$SCRIPTSDIR/file.pl$DOTIN";
  require "$SCRIPTSDIR/x.pl$DOTIN";
}

use File::Copy;
use IO::File;
use POSIX qw(tmpnam);

# --- Tool information --- #

$name = "display";
$version = "1.4.2";
@platforms = qw(redhat-6.2 redhat-7.0 redhat-7.1 redhat-7.2
                
                mandrake-7.2 mandrake-8.0
                
                turbolinux-7.0);

$description =<<"end_of_description;";
       Configures XFree86 version 4.
end_of_description;

# --- Platform handling --- #

$standard_locations =
{
  'XFree3' => '/etc/X11/XF86Config',
  'XFree4' => '/etc/X11/XF86Config-4',
#  'XFree4' => '/home/tambet/XF86Config-4-seth',
};

# Most of these (well, all but Red Hat) could, and probably are
# wrong. FIXME
$platmap =
{
  'redhat-6.0'     => $standard_locations,
  'redhat-6.1'     => $standard_locations,
  'redhat-6.2'     => $standard_locations,
  'redhat-7.0'     => $standard_locations,
  'redhat-7.1'     => $standard_locations,
  'redhat-7.2'     => $standard_locations,
  'mandrake-7.2'   => $standard_locations,
  'mandrake-8.0'   => $standard_locations,
  'suse-7.0'       => $standard_locations,
  'turbolinux-7.0' => $standard_locations,
};

@display_sections = qw(Device Monitor Screen Display ServerLayout);

sub distro_file
{
  my $x_version = &x_version ();
  my $ver = ($x_version->{'number'} >= 400) ? 'XFree4' : 'XFree3';
  my $tmp = $platmap->{$gst_dist};

  return $tmp->{$ver};
}

# --- XML parsing ---
# Scan XML from standard input to an internal tree.

sub xml_parse
{
  my $fname = shift;
  my ($tree, $hash);

  $tree = &gst_xml_scan ($fname);

  # Find the first interesting value.
  while ($$tree[0] eq undef) {
    shift @$tree;
  }

  while (@$tree) {
    if ($$tree[0] eq $name) { $hash = &x_xml_parse ($$tree[1], $hash); }
    
    shift @$tree;
    shift @$tree;
  }

  return($hash);
}

sub xml_print
{
  my $config = shift;
  my ($section, $hash);

  &gst_xml_print_begin ();
  &gst_xml_print_vspace ();

  foreach $section (keys %$config) {
    my ($arrayref) = $$config{$section};

    foreach $hash (@$arrayref) {      
      &x_xml_print_section ($hash, $section, \@display_sections);
      &gst_xml_print_vspace ();
    }
  }
  
  &gst_xml_print_end ();
}

# Top-level actions.

sub get
{
  my $config = &x_parse (&distro_file ());  

  &x_config_fix ($config, 1);

  &gst_report_end ();
  &xml_print ($config);
}

sub set
{
  my $config = &x_parse (&distro_file ());
  my $xml_config = &xml_parse ();
  &x_config_fix ($xml_config, 0);
  
  &x_config_set (&distro_file (), $config, $xml_config);
  &gst_report_end ();
}

sub filter
{
  my $config = &xml_parse ();
  
  &gst_report_end ();
  &xml_print ($config);
}

sub test
{
  my $testX_cmd = "$SCRIPTSDIR/testX";
  my $real_file = &distro_file ();

  my $tmp_file;
  do { $tmp_file = tmpnam () }
  until my $fh = IO::File->new ($tmp_file, O_RDWR|O_CREAT|O_EXCL);

  copy ($real_file, $tmp_file);

  my $config = &x_parse ($tmp_file);
  my $xml_config = &xml_parse ();
  &x_config_fix ($xml_config, 0);

  &x_config_set ($tmp_file, $config, $xml_config);

  $res = &gst_file_run ("$testX_cmd --config=$tmp_file");
  unlink ($tmp_file);

  &gst_report_end ();
}

sub probe
{
  my ($tool, $direct) = @_;
  my $cfg_file = &distro_file ();
  return unless $cfg_file;

  my $config = &x_parse ($cfg_file);
  &x_config_fix ($config, 0);
  &x_probe ($cfg_file, $config, $direct);
}

# --- Main --- #

# get, set and filter are special cases that don't need more parameters than a ref to their function.
# Read general.pl.in:gst_run_directive to know about the format of this hash.

$directives = {
  "get"    => [ \&get,    [], "" ],
  "set"    => [ \&set,    [], "" ],
  "filter" => [ \&filter, [], "" ],
  "test"   => [ \&test,   [], "Test settings." ],
  "probe"  => [ \&probe,  [ "direct*" ], "Return list of valid standard modelines." ],
};

$tool = &gst_init ($name, $version, $description, $directives, @ARGV);
&gst_platform_ensure_supported ($tool, @platforms);
&gst_run ($tool);
