summaryrefslogtreecommitdiff
path: root/x.pl.in
diff options
context:
space:
mode:
Diffstat (limited to 'x.pl.in')
-rw-r--r--x.pl.in2209
1 files changed, 0 insertions, 2209 deletions
diff --git a/x.pl.in b/x.pl.in
deleted file mode 100644
index c5124cc..0000000
--- a/x.pl.in
+++ /dev/null
@@ -1,2209 +0,0 @@
-#!/usr/bin/env perl
-#-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-#
-# Common functions for XF86Config file.
-#
-# 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.
-
-$SCRIPTSDIR = "@scriptsdir@";
-if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
-{
- $SCRIPTSDIR = ".";
- $DOTIN = ".in";
-}
-
-require "$SCRIPTSDIR/general.pl$DOTIN";
-require "$SCRIPTSDIR/file.pl$DOTIN";
-require "$SCRIPTSDIR/xml.pl$DOTIN";
-
-use Text::ParseWords;
-use File::Copy;
-use IO::File;
-use POSIX qw(tmpnam);
-use strict;
-
-my $x_version;
-
-# Data type declarations.
-# Keys that *must* be present:
-# 'parse', 'xml_parse', 'xml_print', 'update' , 'delete' 'add'
-
-my $x_unique_string = {
- 'parse' => \&x_parse_unique_string,
- 'xml_parse' => \&x_xml_parse_unique,
- 'xml_print' => \&x_xml_print_unique,
- 'update' => \&x_update_unique_string,
- 'delete' => \&x_del_unique_string,
- 'add' => \&x_add_unique_string,
-};
-
-my $x_unique_int = {
- 'parse' => \&x_parse_unique_int,
- 'xml_parse' => \&x_xml_parse_unique,
- 'xml_print' => \&x_xml_print_unique,
- 'update' => \&x_update_unique_int,
- 'delete' => \&x_del_unique_int,
- 'add' => \&x_add_unique_int,
-};
-
-my $x_list_string = {
- 'parse' => \&x_parse_list_string,
- 'xml_parse' => \&x_xml_parse_list,
- 'xml_print' => \&x_xml_print_list,
- 'update' => \&x_update_list_string,
- 'delete' => \&x_del_list_string,
- 'add' => \&x_add_list_string,
-};
-
-my $x_list_int = {
- 'parse' => \&x_parse_list_int,
- 'xml_parse' => \&x_xml_parse_list,
- 'xml_print' => \&x_xml_print_list,
- 'update' => \&x_update_list_int,
- 'delete' => \&x_del_list_int,
- 'add' => \&x_add_list_int,
-};
-
-my $x_serverlayout_screen = {
- 'parse' => \&x_parse_serverlayout_screen,
- 'xml_parse' => \&x_xml_parse_serverlayout_screen,
- 'xml_print' => \&x_xml_print_serverlayout_screen,
- 'update' => \&x_update_serverlayout_screen,
- 'delete' => \&x_del_serverlayout_screen,
- 'add' => \&x_add_serverlayout_screen,
-};
-
-my $x_modeline = {
- 'parse' => \&x_parse_modeline,
- 'xml_parse' => \&x_xml_parse_modeline,
- 'xml_print' => \&x_xml_print_modeline,
- 'update' => \&x_update_modeline,
- 'delete' => \&x_del_modeline,
- 'add' => \&x_add_modeline,
-};
-
-my $x_range_hz = {
- 'parse' => \&x_parse_range_hz,
- 'xml_parse' => \&x_xml_parse_range_hz,
- 'xml_print' => \&x_xml_print_range_hz,
- 'update' => \&x_update_range_hz,
- 'delete' => \&x_del_range_hz,
- 'add' => \&x_add_range_hz,
-};
-
-# XFree86 version 4 sections:
-# Files
-# ServerFlags
-# Module
-# InputDevice
-# Device
-# VideoAdaptor
-# Monitor
-# Modes
-# Screen
-# ServerLayout
-# DRI
-# Vendor
-
-my $x4_sections = {
- Monitor => {
- KEY => 'Identifier',
- keywords => {
- Identifier => $x_unique_string,
- VendorName => $x_unique_string,
- ModelName => $x_unique_string,
- HorizSync => $x_range_hz,
- VertRefresh => $x_range_hz,
- ModeLine => $x_modeline,
- Gamma => $x_list_int,
- },
- options => {},
- },
- Device => {
- KEY => 'Identifier',
- keywords => {
- Identifier => $x_unique_string,
- Driver => $x_unique_string,
- },
- options => {},
- },
- Screen => {
- KEY => 'Identifier',
- keywords => {
- Identifier => $x_unique_string,
- Device => $x_unique_string,
- Monitor => $x_unique_string,
- DefaultDepth => $x_unique_int,
- },
- options => {},
- Display => {
- KEY => 'Depth',
- keywords => {
- Depth => $x_unique_int,
- Modes => $x_list_string,
- Virtual => $x_list_int,
- }
- }
- },
- ServerLayout => {
- KEY => 'Identifier',
- keywords => {
- Identifier => $x_unique_string,
- Screen => $x_serverlayout_screen,
- },
- options => {},
- }
-};
-
-# XFree86 version 3 sections:
-# Files
-# Module
-# ServerFlags
-# Keyboard
-# Pointer
-# Monitor
-# Device
-# Screen
-# XInput
-
-my $x3_sections = {
- Monitor => {
- KEY => 'Identifier',
- keywords => {
- Identifier => $x_unique_string,
- VendorName => $x_unique_string,
- ModelName => $x_unique_string,
- HorizSync => $x_range_hz,
- VertRefresh => $x_range_hz,
- ModeLine => $x_modeline,
- },
- options => {},
- },
- Device => {
- KEY => 'Identifier',
- keywords => {
- Identifier => $x_unique_string,
- },
- options => {},
- },
- Screen => {
- KEY => 'Driver',
- keywords => {
- Driver => $x_unique_string,
- Device => $x_unique_string,
- Monitor => $x_unique_string,
- DefaultColorDepth => $x_unique_int,
- },
- options => {},
- Display => {
- KEY => 'Depth',
- keywords => {
- Depth => $x_unique_int,
- Modes => $x_list_string,
- Virtual => $x_list_int,
- }
- }
- },
-};
-
-my @x_colordepths = (8, 15, 16, 24);
-my $x_probe_file = "probe.xml";
-
-# Standard modelines (VESA plus couple extras)
-
-my $standard_modes = q (
-
-# 640x350 @ 85Hz (VESA) hsync: 37.9kHz
-ModeLine "640x350@85" 31.5 640 672 736 832 350 382 385 445 +hsync -vsync
-
-# 640x400 @ 85Hz (VESA) hsync: 37.9kHz
-ModeLine "640x400@85" 31.5 640 672 736 832 400 401 404 445 -hsync +vsync
-
-# 720x400 @ 85Hz (VESA) hsync: 37.9kHz
-ModeLine "720x400@85" 35.5 720 756 828 936 400 401 404 446 -hsync +vsync
-
-# 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
-ModeLine "640x480@60" 25.2 640 656 752 800 480 490 492 525 -hsync -vsync
-
-# 640x480 @ 72Hz (VESA) hsync: 37.9kHz
-ModeLine "640x480@72" 31.5 640 664 704 832 480 489 491 520 -hsync -vsync
-
-# 640x480 @ 75Hz (VESA) hsync: 37.5kHz
-ModeLine "640x480@75" 31.5 640 656 720 840 480 481 484 500 -hsync -vsync
-
-# 640x480 @ 85Hz (VESA) hsync: 43.3kHz
-ModeLine "640x480@85" 36.0 640 696 752 832 480 481 484 509 -hsync -vsync
-
-# 800x600 @ 56Hz (VESA) hsync: 35.2kHz
-ModeLine "800x600@56" 36.0 800 824 896 1024 600 601 603 625 +hsync +vsync
-
-# 800x600 @ 60Hz (VESA) hsync: 37.9kHz
-ModeLine "800x600@60" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync
-
-# 800x600 @ 72Hz (VESA) hsync: 48.1kHz
-ModeLine "800x600@72" 50.0 800 856 976 1040 600 637 643 666 +hsync +vsync
-
-# 800x600 @ 75Hz (VESA) hsync: 46.9kHz
-ModeLine "800x600@75" 49.5 800 816 896 1056 600 601 604 625 +hsync +vsync
-
-# 800x600 @ 85Hz (VESA) hsync: 53.7kHz
-ModeLine "800x600@85" 56.3 800 832 896 1048 600 601 604 631 +hsync +vsync
-
-# 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz
-ModeLine "1024x768@43" 44.9 1024 1032 1208 1264 768 768 776 817 +hsync +vsync Interlace
-
-# 1024x768 @ 60Hz (VESA) hsync: 48.4kHz
-ModeLine "1024x768@60" 65.0 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
-
-# 1024x768 @ 70Hz (VESA) hsync: 56.5kHz
-ModeLine "1024x768@70" 75.0 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
-
-# 1024x768 @ 75Hz (VESA) hsync: 60.0kHz
-ModeLine "1024x768@75" 78.8 1024 1040 1136 1312 768 769 772 800 +hsync +vsync
-
-# 1024x768 @ 85Hz (VESA) hsync: 68.7kHz
-ModeLine "1024x768@85" 94.5 1024 1072 1168 1376 768 769 772 808 +hsync +vsync
-
-# 1152x864 @ 75Hz (VESA) hsync: 67.5kHz
-ModeLine "1152x864@75" 108.0 1152 1216 1344 1600 864 865 868 900 +hsync +vsync
-
-# 1280x960 @ 60Hz (VESA) hsync: 60.0kHz
-ModeLine "1280x960@60" 108.0 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync
-
-# 1280x960 @ 85Hz (VESA) hsync: 85.9kHz
-ModeLine "1280x960@85" 148.5 1280 1344 1504 1728 960 961 964 1011 +hsync +vsync
-
-# 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz
-ModeLine "1280x1024@60" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
-
-# 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz
-ModeLine "1280x1024@75" 135.0 1280 1296 1440 1688 1024 1025 1028 1066 +hsync +vsync
-
-# 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz
-ModeLine "1280x1024@85" 157.5 1280 1344 1504 1728 1024 1025 1028 1072 +hsync +vsync
-
-# 1400x1050 @ 60Hz (VESA GFT) hsync: 65.5kHz
-ModeLine "1400x1050@60" 122.0 1400 1488 1640 1880 1050 1052 1064 1082 +hsync +vsync
-
-# 1400x1050 @ 75Hz (VESA GFT) hsync: 82.2kHz
-ModeLine "1400x1050@75" 155.8 1400 1464 1784 1912 1050 1052 1064 1090 +hsync +vsync
-
-# 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz
-ModeLine "1600x1200@60" 162.0 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
-
-# 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz
-ModeLine "1600x1200@65" 175.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
-
-# 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz
-ModeLine "1600x1200@70" 189.0 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
-
-# 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz
-ModeLine "1600x1200@75" 202.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
-
-# 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz
-ModeLine "1600x1200@85" 229.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
-
-# 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz
-ModeLine "1792x1344@60" 204.8 1792 1920 2120 2448 1344 1345 1348 1394 -hsync +vsync
-
-# 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz
-ModeLine "1792x1344@75" 261.0 1792 1888 2104 2456 1344 1345 1348 1417 -hsync +vsync
-
-# 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz
-ModeLine "1856x1392@60" 218.3 1856 1952 2176 2528 1392 1393 1396 1439 -hsync +vsync
-
-# 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz
-ModeLine "1856x1392@75" 288.0 1856 1984 2208 2560 1392 1393 1396 1500 -hsync +vsync
-
-# 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz
-ModeLine "1920x1440@60" 234.0 1920 2048 2256 2600 1440 1441 1444 1500 -hsync +vsync
-
-# 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz
-ModeLine "1920x1440@75" 297.0 1920 2064 2288 2640 1440 1441 1444 1500 -hsync +vsync
-
- );
-BEGIN {
- &gst_report_table ({
- 'x_version' => ['info', _('Detected X version [%s].')],
- 'x_parse' => ['info', _('Configuration file [%s] successfully parsed.')],
- 'x_parse_error' => ['error', _('Error parsing keyword [%s].')],
- 'x_probe_needed' => ['info', _('Going to probe your X server, hold on.')],
- 'x_probe_error' => ['error', _('Error occured on X server probe on colordepth [%s].')],
- 'x_general_warn' => ['warn', _('Internal error: [%s].')],
- }
- );
-}
-
-sub x_version
-{
- return $x_version if $x_version; # Cache
-
- my ($command, $number, $driver);
- my @paths = qw (/etc/X11/X /usr/X11R6/bin/XFree86 /usr/X11R6/bin/X);
-
- foreach my $tmp (@paths) {
- if (-x $tmp) {
- $command = $tmp;
- last;
- }
- }
-
- unless ($command) {
- # TODO: add report;
- &gst_debug_print_line ("Couldn't find X binary.");
- return;
- }
-
- open (FD, "$command -version 2>&1 |");
- while (<FD>) {
- if (/^XFree86 Version (\d+)\.(\d+)\.(\d+)/) {
- $number = $1 . $2 . $3;
- }
- elsif ($number > 0 && $number < 400 && /^[ \t]*(\w+): (accelerated)?[ ]*server/) {
- $driver = $1;
- $driver = 'Accel' if $2;
- last;
- }
- }
- close (FD);
-
- &gst_report ('x_version', $number);
-
- $x_version->{'command'} = $command;
- $x_version->{'sections'} = ($number >= 400) ? $x4_sections : $x3_sections;
- $x_version->{'number'} = $number;
- $x_version->{'driver'} = $driver if $driver;
-
- return $x_version;
-}
-
-# Difference from gst_item_is_in_list is that XF86Config keywords are
-# case-insensitive and "_" characters are ignored.
-# Returns found value from list or 0.
-sub x_keyword_in_list
-{
- my $keyword = shift @_;
-
- $keyword =~ s/\_//g; # We don't care about underscores (_)
-
- foreach my $item (@_) {
- my $pattern = $item;
- $pattern =~ s/(\W)/\\$1/g;
- return $item if ($keyword =~ /^$pattern$/i);
- }
-
- return;
-}
-
-sub x_option_in_list
-{
- my $keyword = shift @_;
-
- $keyword =~ s/\"//g; # We don't care about quotes (")
- $keyword =~ s/^No//i; # and it could start with optional "No"
-
- foreach my $item (@_) {
- my $pattern = $item;
- $pattern =~ s/(\W)/\\$1/g;
- return 1 if ($keyword =~ /^$pattern$/i);
- }
-
- return;
-}
-
-# parse_option
-# Parses "Option" line form XF86Config.
-# Arguments:
-# $line - ref to array containing the actual line split by \s.
-# Returns hash with one key (Option) containing hash with option
-# name as key and option value as val.
-sub parse_option_old
-{
- my $line = shift;
- my ($name, $value);
- my ($val, $bool);
-
- shift @$line; # Remove "Option"
-
- $name = shift @$line;
- $value = shift @$line;
-
- $name =~ s/\"//g;
- $value =~ s/\"//g;
-
- if ($value =~ /^(1|on|true|yes)$/i) {
- $val = 1;
- $bool = 1;
- } elsif ($value =~ /^(0|off|false|no)$/i) {
- $val = 0;
- $bool = 1;
- } else {
- $val = $value;
- }
-
- if ($bool) {
- $val = !$val if ($name =~ s/^No//i);
-
- $val = 'true' if $val;
- $val = 'false' if not $val;
- }
-
- bless [ $name, $val ], "GstXOption";
-}
-
-# ------------------------------------------------------
-# Data type functions
-# ------------------------------------------------------
-
-# Unique string data type.
-sub x_parse_unique_string
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
-
- # Format example: 'Identifier "name"'
-
- my $val = &x_get_token ($buf);
- goto ERROR unless defined ($val);
- goto ERROR unless $val =~ /^\".*\"$/;
-
- $val =~ s/\"//g;
- &gst_debug_print_line ("x_parse_unique_string: warning: '$kw' is unique but" .
- "already has value '$config->{$kw}'.")
- if exists ($config->{$kw});
-
- $config->{$kw} = $val;
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_unique_string: error parsing $kw");
-}
-
-sub x_xml_parse_unique
-{
- my $hash = shift;
- my $kw = shift;
-
- $hash->{$kw} = &gst_xml_get_text (shift @_);
-}
-
-sub x_xml_print_unique
-{
- my ($key, $val) = @_;
- &gst_xml_print_pcdata ($key, $val);
-}
-
-sub x_update_unique_string
-{
- my ($buf, $ptr, $old_val, $new_val) = @_;
- my $token = &x_update_get_token ($buf, $ptr);
- return if ($old_val eq $new_val);
-
- $old_val = "\"" . $old_val . "\"" if $old_val;
- $new_val = "\"" . $new_val . "\"" if $new_val;
-
- &x_update_token ($buf, $ptr, $old_val, $new_val);
-}
-
-sub x_del_unique_string
-{
- my ($buf, $ptr, $kw, $old_val) = @_;
- &x_update_token ($buf, $ptr, $kw);
- &x_update_unique_string ($buf, $ptr, $old_val);
-}
-
-sub x_add_unique_string
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
-
- $new_val = "" unless defined ($new_val);
- &x_update_add_token ($buf, $ptr, $kw) if $kw;
- $new_val = "\"" . $new_val . "\"";
- &x_update_add_token ($buf, $ptr, $new_val, 1);
-}
-
-# Unique int data type.
-sub x_parse_unique_int
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
-
- # Format example: 'Depth depth'
-
- my $val = &x_get_token ($buf);
- goto ERROR unless defined ($val);
- goto ERROR unless $val =~ /^[0-9]+$/;
-
- &gst_debug_print_line ("x_parse_unique_string: warning: '$kw' is unique but" .
- "already has value '$config->{$kw}'.")
- if exists ($config->{$kw});
-
- $config->{$kw} = $val;
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_unique_int: error parsing $kw");
-}
-
-sub x_update_unique_int
-{
- my ($buf, $ptr, $old_val, $new_val) = @_;
- my $token = &x_update_get_token ($buf, $ptr);
-
- if ($old_val != $new_val) {
- &x_update_token ($buf, $ptr, $old_val, $new_val);
- }
-}
-
-sub x_del_unique_int
-{
- my ($buf, $ptr, $kw, $old_val) = @_;
- &x_update_token ($buf, $ptr, $kw);
- &x_update_unique_int ($buf, $ptr, $old_val);
-}
-
-sub x_add_unique_int
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
-
- &x_update_add_token ($buf, $ptr, $kw) if $kw;
- &x_update_add_token ($buf, $ptr, $new_val, 1);
-}
-
-# String list data type.
-sub x_parse_list_string
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
-
- # Format example: 'Modes "mode-name" ...'
-
- my @list;
- while (my $token = &x_peek_token ($buf)) {
- if ($token =~ /^\".*\"$/) {
- $token = &x_get_token ($buf);
- goto ERROR unless defined ($token);
- $token =~ s/\"//g;
- push @list, $token;
- } else {
- last;
- }
- }
-
- goto ERROR if (scalar @list < 1);
-
- foreach (@list) {
- push @{$config->{$kw}}, $_;
- }
-
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_list_string: error parsing $kw");
-}
-
-sub x_xml_parse_list
-{
- my $hash = shift;
- my $kw = shift;
- my $values = shift;
- my $i = 1;
- while (defined (my $tmp = &gst_xml_get_attribute ($values, 'arg' . $i))) {
- push @{$hash->{$kw}}, $tmp;
- $i++;
- }
-}
-
-sub x_xml_print_list
-{
- my $key = shift;
- my $array = shift;
-
- my $str = $key;
- my $i = 1;
- foreach (@$array) {
- $str .= ' arg' . $i . "=\"$_\"";
- $i++;
- }
- &gst_xml_print_line ("<$str/>");
-}
-
-sub x_update_list_string
-{
- my ($buf, $ptr, $old_val, $new_val) = @_;
-
- while (@$old_val) {
- &x_update_unique_string ($buf, $ptr, $$old_val[0], $$new_val[0]);
- shift @$old_val;
- shift @$new_val;
- }
-
- while (@$new_val) {
- $$new_val[0] = "\"" . $$new_val[0] . "\"";
- &x_update_add_token ($buf, $ptr, $$new_val[0], 1);
- shift @$new_val;
- }
-}
-
-sub x_del_list_string
-{
- my ($buf, $ptr, $kw, $old_val) = @_;
- &x_update_token ($buf, $ptr, $kw);
-
- if ($old_val) {
- while (@$old_val) {
- &x_update_unique_string ($buf, $ptr, $old_val);
- shift @$old_val;
- }
- }
-}
-
-sub x_add_list_string
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
-
- &x_update_add_token ($buf, $ptr, $kw);
- &x_update_list_string ($buf, $ptr, [], $new_val);
-}
-
-# Int list data type.
-sub x_parse_list_int
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
-
- # Format example: 'Virtual xdim ydim'
-
- my @list;
- while (my $token = &x_peek_token ($buf)) {
- if ($token =~ /^[0-9\.]+$/) {
- $token = &x_get_token ($buf);
- goto ERROR unless defined ($token);
- push @list, $token;
- } else {
- last;
- }
- }
-
- goto ERROR if (scalar @list < 1);
-
- foreach (@list) {
- push @{$config->{$kw}}, $_;
- }
-
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_list_int: error parsing $kw");
-}
-
-sub x_update_list_int
-{
- my ($buf, $ptr, $old_val, $new_val) = @_;
-
- if ($old_val) {
- while (@$old_val) {
- &x_update_unique_int ($buf, $ptr, $$old_val[0], $$new_val[0]);
- shift @$old_val;
- shift @$new_val;
- }
- }
-
- while (@$new_val) {
- &x_update_add_token ($buf, $ptr, $$new_val[0], 1);
- shift @$new_val;
- }
-}
-
-sub x_del_list_int
-{
- my ($buf, $ptr, $kw, $old_val) = @_;
- &x_update_token ($buf, $ptr, $kw);
-
- if ($old_val) {
- while (@$old_val) {
- &x_update_unique_int ($buf, $ptr, shift @$old_val);
- }
- }
-}
-
-sub x_add_list_int
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
-
- &x_update_add_token ($buf, $ptr, $kw);
-# push @$new_val, "\n";
- &x_update_list_int ($buf, $ptr, undef, $new_val);
-}
-
-# Screen keyword from ServerLayout Section.
-sub x_parse_serverlayout_screen
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
- my ($hash, $token, $tmp);
-
- # Format example: 'Screen screen-num "screen-id" position-information'
-
- my $screens = 0;
- $screens = scalar (keys %{$config->{'Screen'}}) if exists $config->{'Screen'};
-
- # Screen number
- $token = &x_peek_token ($buf);
- goto ERROR unless defined ($token);
- if ($token =~ /^\d+$/) {
- $hash->{'num'} = &x_get_token ($buf);
- } else {
- $hash->{'num'} = $screens;
- }
-
- # Screen id
- $token = &x_peek_token ($buf);
- goto ERROR unless defined ($token);
- $hash->{'id'} = &x_get_token ($buf) if ($token =~ /^\".+\"$/);
- $hash->{'id'} =~ s/\"//g;
-
- # Position
- my $pos = {};
- my @known_pos_xy = qw (Absolute Relative);
- my @known_pos_id = qw (RightOf LeftOf Above Below);
-
- $token = &x_peek_token ($buf);
- goto ERROR unless defined ($token);
-
- if ($tmp = &x_keyword_in_list ($token, @known_pos_xy)) {
- &x_get_token ($buf);
- $pos->{'name'} = $tmp;
-
- foreach my $i (1, 2) {
- $token = &x_peek_token ($buf);
- goto ERROR unless (defined ($token) || $token =~ /^\d+$/);
-
- $pos->{"val$i"} = &x_get_token ($buf);
- }
- $hash->{'pos'} = $pos;
- }
-
- elsif ($tmp = &x_keyword_in_list ($token, @known_pos_id)) {
- &x_get_token ($buf);
- $pos->{'name'} = $tmp;
-
- $token = &x_peek_token ($buf);
- goto ERROR unless (defined ($token) || $token =~ /^\".+\"$/);
-
- $pos->{'val1'} = &x_get_token ($buf);
- $pos->{'val1'} =~ s/\"//g;
- $hash->{'pos'} = $pos;
- }
-
- elsif ($token =~ /^\d+$/) {
- $pos->{'name'} = 'Absolute';
-
- foreach my $i (1, 2) {
- $token = &x_peek_token ($buf);
- goto ERROR unless (defined ($token) || $token =~ /^\d+$/);
-
- $pos->{"val$i"} = &x_get_token ($buf);
- }
- $hash->{'pos'} = $pos;
- }
-
- $config->{'Screen'}->{$hash->{'num'}} =
- {
- 'Identifier' => $hash->{'id'}
- };
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_serverlayout_screen: error parsing $kw");
-}
-
-sub x_xml_parse_serverlayout_screen
-{
- my $hash = shift;
- my $kw = shift;
- my $tag = shift;
-
- $hash->{$kw} = {} unless exists $hash->{$kw};
-
- my $number = &gst_xml_get_attribute ($tag, "number");
- my $screen = { 'Identifier' => &gst_xml_get_attribute ($tag, "name") };
- $hash->{$kw}->{$number} = $screen;
-}
-
-sub x_xml_print_serverlayout_screen
-{
- my ($key, $val) = @_;
-
- foreach my $screen (keys %$val) {
- my $name = $val->{$screen}->{'Identifier'};
- &gst_xml_print_line ("<$key number=\"$screen\" name=\"$name\"/>");
- }
-}
-
-sub x_update_serverlayout_screen
-{
- my ($buf, $ptr, $old_val, $new_val) = @_;
-
- # Just get enough tokens from con file.
- # FIXME: Make it actually WORK.
-
- # Screen number
- my $token = &x_update_get_token ($buf, $ptr);
- unless ($token =~ /^\d+$/) {
- &x_update_unget_token ($buf, $ptr);
- }
-
- # Screen id
- $token = &x_update_get_token ($buf, $ptr);
-
- # Position
- my @known_pos_xy = qw (Absolute Relative);
- my @known_pos_id = qw (RightOf LeftOf Above Below);
- my $tmp;
-
- $token = &x_update_get_token ($buf, $ptr);
- if ($tmp = &x_keyword_in_list ($token, @known_pos_xy)) {
- $token = &x_update_get_token ($buf, $ptr);
- $token = &x_update_get_token ($buf, $ptr);
- }
- elsif ($tmp = &x_keyword_in_list ($token, @known_pos_id)) {
- $token = &x_update_get_token ($buf, $ptr);
- }
- elsif ($token =~ /^\d+$/) {
- $token = &x_update_get_token ($buf, $ptr);
- }
- else {
- $token = &x_update_unget_token ($buf, $ptr);
- }
-}
-
-sub x_del_serverlayout_screen
-{
- my ($buf, $ptr, $kw, $old_val) = @_;
-
- #FIXME: Doesn't do anything.
-# &x_update_token ($buf, $ptr, $kw);
-
- &x_update_serverlayout_screen ($buf, $ptr, $old_val);
-}
-
-sub x_add_serverlayout_screen
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
-
- &x_update_add_token ($buf, $ptr, $kw);
- &x_update_add_token ($buf, $ptr, 0, 1);
-
- &x_add_unique_string ($buf, $ptr, undef, $new_val);
-
- &x_update_add_token ($buf, $ptr, 0, 1);
- &x_update_add_token ($buf, $ptr, 0, 1);
-}
-
-# ModeLines.
-
-sub x_parse_modeline
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
- my @keys = qw (dotclock hdisp hsyncstart hsyncend htotal
- vdisp vsyncstart vsyncend vtotal);
- my @flags = qw (Interlace DoubleScan +HSync -HSync +VSync -VSync
- Composite +CSync -CSync);
-
- my $modeline = {};
- my $token = &x_get_token ($buf);
- goto ERROR unless defined ($token);
- $token =~ s/\"//g;
- $modeline->{'name'} = $token;
-
- foreach my $tmp (@keys) {
- my $token = &x_get_token ($buf);
- goto ERROR unless defined ($token);
- goto ERROR unless $token =~ /^[\d\.]+$/; #digit or '.'
-
- $modeline->{$tmp} = $token;
- }
-
- # Get flags
- while (my $token = &x_peek_token ($buf)) {
- if (my $tmp = &x_keyword_in_list ($token, @flags)) {
- &x_get_token ($buf);
- push @{$modeline->{'flags'}}, $tmp;
- } else {
- last;
- }
- }
-
- push @{$config->{$kw}}, $modeline;
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_modeline: error parsing $kw");
-}
-
-sub x_xml_parse_modeline
-{
- my $hash = shift;
- my $kw = shift;
- my $list = shift;
-
- shift @$list;
-
- while (@$list) {
- my $mode = {};
- shift @$list;
- my $modeline = shift @$list;
-
- shift @$modeline;
- while (@$modeline) {
- my $field = shift @$modeline;
- if ($field ne 'flag') {
- $mode->{$field} = &gst_xml_get_text (shift @$modeline);
- } else {
- push @{$mode->{$field}}, &gst_xml_get_text (shift @$modeline);
- }
- }
- push @{$hash->{$kw}}, $mode;
- }
-}
-
-sub x_xml_print_modeline
-{
- my ($key, $list) = @_;
-
- &gst_xml_container_enter ("ModeLine");
-
- foreach (@$list) {
- my $modeline = $_;
- &gst_xml_container_enter ("Mode");
- foreach my $field (keys %$modeline) {
- my $type = ref ($modeline->{$field});
-
- if (!$type) { &gst_xml_print_pcdata ($field, $modeline->{$field}); }
- elsif ($type eq 'ARRAY') {
- foreach my $flag (@{$modeline->{$field}}) {
- &gst_xml_print_pcdata ('flag', $flag);
- }
- }
- else {
- my $msg = "unknown data type $type";
- &gst_report ('x_general_warn', $msg);
- &gst_debug_print_line ("x_xml_print_modeline: $msg");
- }
- }
- &gst_xml_container_leave ();
- }
- &gst_xml_container_leave ();
-}
-
-sub x_update_modeline
-{
- my ($buf, $ptr, $old_val, $new_val) = @_;
- my $token = &x_update_get_token ($buf, $ptr);
-}
-
-sub x_del_modeline
-{
-}
-
-sub x_add_modeline
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
- my @keys = qw (dotclock hdisp hsyncstart hsyncend htotal
- vdisp vsyncstart vsyncend vtotal);
-
- foreach my $modeline (@$new_val) {
- &x_update_add_token ($buf, $ptr, $kw);
- &x_add_unique_string ($buf, $ptr, undef, $modeline->{'name'});
-
- foreach my $key (@keys) {
- &x_update_add_token ($buf, $ptr, $modeline->{$key}, 1);
- }
-
- foreach my $key (@{$modeline->{'flags'}}) {
- &x_update_add_token ($buf, $ptr, $key, 1);
- }
-
- &x_update_add_token ($buf, $ptr, "\n");
- }
-}
-
-# Hertz range datatype
-sub x_parse_range_hz
-{
- my $config = shift;
- my $buf = shift;
- my $kw = shift;
-
- my @list;
- while (defined (my $token = &x_peek_token ($buf))) {
- my ($min, $max);
- for ($token) {
-
- /^([\d.]+)\-([\d\.]+)$/ and do {
- $min = $1;
- $max = $2;
- &x_get_token ($buf);
- last;
- };
-
- /^[\d\.]+$/ and do {
- $min = &x_get_token ($buf);
- $token = &x_peek_token ($buf);
- if ($token eq '-') {
- &x_get_token ($buf);
- $max = &x_get_token ($buf);
- } else {
- $max = $min;
- }
-
- last;
-
- };
-
- # Default
- last;
- }
-
- if ($min && $max) {
- push @list, [ $min, $max ];
- } else { last; }
- }
-
- goto ERROR if (scalar @list < 1);
-
- foreach (@list) {
- push @{$config->{$kw}}, $_;
- }
-
- return;
-
- ERROR:
- &gst_report ('x_parse_error', $kw);
- &gst_debug_print_line ("x_parse_range_hz: error parsing $kw");
-}
-
-sub x_xml_parse_range_hz
-{
- my $hash, shift;
- my $kw = shift;
-
- push @{$hash->{$kw}}, &gst_xml_get_text (shift @_);
-}
-
-sub x_xml_print_range_hz
-{
- my $key = shift;
- my $array = shift;
-
- foreach my $tmp (@$array) {
- my $val = $$tmp[0];
- $val .= '-' . $$tmp[1] if $$tmp[0] != $$tmp[1];
-
- &gst_xml_print_pcdata ($key, $val);
- }
-}
-
-sub x_update_range_hz
-{
- # TODO:
- my ($buf, $ptr, $old_val, $new_val) = @_;
-}
-
-sub x_del_range_hz
-{
- # TODO:
- my ($buf, $ptr, $kw, $old_val) = @_;
-}
-
-sub x_add_range_hz
-{
- my ($buf, $ptr, $kw, $new_val) = @_;
-
- foreach my $tmp (@$new_val) {
- my $val = $$tmp[0];
- $val .= '-' . $$tmp[1] if $$tmp[0] != $$tmp[1];
- &x_update_add_token ($buf, $ptr, $kw);
- &x_update_add_token ($buf, $ptr, $val, 1);
- }
-}
-
-
-
-# -------------------------------------------------------
-# Parser
-# -------------------------------------------------------
-
-sub x_get_token
-{
- my $buf = shift;
- my $dest_buf = shift;
- my $token;
-
- while (@$buf) {
- my $line = $$buf[0];
-
- if (&gst_ignore_line ($line)) {
- push @$dest_buf, $line if defined ($dest_buf);
- shift @$buf;
- next;
- }
-
- $line =~ s/^(\s+)//;
- push @$dest_buf, $1 if defined ($1);
- my @list = &quotewords ('[ \t]+', 1, $line);
- $token = $list[0];
- chomp $token;
- my $pattern = $token;
- $pattern =~ s/(\W)/\\$1/g;
- $$buf[0] =~ s/$pattern//;
- last;
- }
-
- return $token;
-}
-
-sub x_peek_token
-{
- my $buf = shift;
- my $token;
-
- foreach (@$buf) {
- my $line = $_;
-
- if (&gst_ignore_line ($line)) {
- next;
- }
-
- $line =~ s/^\s+//;
- my @list = &quotewords ('[ \t]+', 1, $line);
- $token = $list[0];
- chomp $token;
- last;
- }
-
- return $token;
-}
-
-sub x_parse_section_start
-{
- my $buf = shift;
- my $sections = shift;
- my $new_buf = shift;
-
- my $token = &x_get_token ($buf, $new_buf);
- $token =~ s/\"//g;
-
- return &x_keyword_in_list ($token, keys %$sections);
-}
-
-sub x_parse
-{
- my $fname = shift;
- my ($tmp);
-
- $x_version = &x_version () unless $x_version;
-
- my $buf = &gst_file_buffer_load ($fname);
- return unless $buf;
-
- # Init section stack
- my $section_ptr;
- my @section_stack = ();
- $section_ptr = $x_version->{'sections'};
- unshift @section_stack, $section_ptr;
-
- # Init config stack
- my $config = {};
- my $config_ptr = $config;
- my @config_stack = ();
- unshift @config_stack, $config_ptr;
-
- while (defined (my $token = &x_get_token ($buf))) {
- for ($token) {
-
- /^(Sub)?Section/i and do {
- if ($tmp = &x_parse_section_start ($buf, $section_ptr)) {
- $section_ptr = $section_ptr->{$tmp};
- unshift @section_stack, $section_ptr;
-
- push @{$config_ptr->{$tmp}}, {};
- $config_ptr = $config_ptr->{$tmp}[$#{$config_ptr->{$tmp}}];
- unshift @config_stack, $config_ptr;
- }
- last;
- };
-
- /^(End(Sub)?Section)/i and do {
- if (scalar @section_stack > 1) {
- shift @section_stack;
- $section_ptr = $section_stack[0];
-
- shift @config_stack;
- $config_ptr = $config_stack[0];
- }
- last;
- };
-
- (scalar @section_stack <= 1) and do {
- # Inside unknown section
- last;
- };
-
- ($tmp = &x_keyword_in_list ($token, keys %{$section_ptr->{'keywords'}})) and do {
- my $func = $section_ptr->{'keywords'}{$tmp}{'parse'};
- &$func ($config_ptr, $buf, $tmp);
- last;
- };
-
- # Default
- 1;
- }
- }
-
- &gst_report ('x_parse', $fname);
- return $config;
-}
-
-# ------------------------------------------------
-# XML Printing.
-# ------------------------------------------------
-
-sub x_xml_print_section
-{
- my $hash = shift;
- my $section = shift;
- my $section_list = shift;
- my $section_ptr = shift;
- my ($key);
-
- return if (!&x_keyword_in_list ($section, @$section_list));
-
- $section_ptr = $x4_sections unless $section_ptr; # Always print using X4_sections.
-
- return unless (exists ($section_ptr->{$section}));
- &gst_xml_container_enter ("$section");
-
- $section_ptr = $section_ptr->{$section};
- foreach $key (keys %$hash) {
- if (exists $section_ptr->{'keywords'}{$key}) {
- my $func = $section_ptr->{'keywords'}{$key}{'xml_print'};
- &$func ($key, $hash->{$key});
- }
-
- elsif (exists $section_ptr->{$key}) {
- foreach my $tmp (@{$hash->{$key}}) {
- &x_xml_print_section ($tmp, $key, $section_list, $section_ptr);
- }
- }
-
- else {
- my $msg = "unknown keyword $key in section $section";
- &gst_report ('x_general_warn', $msg);
- &gst_debug_print_line ("x_xml_print_section: $msg");
- }
- }
-
- &gst_xml_container_leave ();
-}
-
-# --------------------------------------------------------------------
-# XML parser
-# --------------------------------------------------------------------
-
-# Internal
-sub x_xml_parse_section
-{
- my ($config, $tree, $section_desc, $section_name) = @_;
- my ($keywords) = $section_desc->{'keywords'};
- my ($options) = $section_desc->{'options'};
-
- my $hash = {};
- shift @$tree;
-
- while (@$tree) {
- my $func;
-
- if (exists $keywords->{$$tree[0]}) {
- $func = $keywords->{$$tree[0]}{'xml_parse'};
- if ($func eq "") {
-
- # TODO:
- # print STDERR "$tree->[0]\n";
- 1;
- } else {
- &$func ($hash, $$tree[0], $$tree[1]);
- }
- }
-
- elsif (exists $options->{$$tree[0]}) {
- # TODO: implement 'Option' xml parser.
-# $func = $options->{$$tree[0]}[1];
- 1;
- }
-
- elsif (exists $section_desc->{$$tree[0]}) {
- &x_xml_parse_section ($hash, $$tree[1], $section_desc->{$$tree[0]}, $$tree[0]);
- }
-
- shift @$tree;
- shift @$tree;
- }
-
- unshift @{$config->{$section_name}}, $hash;
-}
-
-sub x_xml_parse
-{
- my $tree = shift;
- my $sections = $x4_sections; # XML uses always X4 format.
-
- shift @$tree; # Skip attributes.
-
- my $config = {};
-
- while (@$tree) {
- my ($section);
-
- if ($section = &x_keyword_in_list ($$tree[0], keys %$sections)) {
- &x_xml_parse_section ($config, $$tree[1], $sections->{$section}, $section);
- }
-
- else {
- my $msg = "received unknown xml tag $$tree[0]";
- &gst_report ('xml_unexp_tag', $$tree[0]);
- &gst_debug_print_line ("x_xml_parse: $msg");
- }
-
- shift @$tree;
- shift @$tree;
- }
-
- return $config;
-}
-
-# ----------------------------------------------
-# Update
-# ----------------------------------------------
-
-sub x_update_get_token
-{
- my $buf = shift;
- my $ptr = shift;
-
- for ($ptr->{'line'}; $ptr->{'line'} < @$buf; $ptr->{'line'}++, $ptr->{'col'} = 0) {
- my $line = substr ($$buf[$ptr->{'line'}], $ptr->{'col'});
-
- next if &gst_ignore_line ($line);
-
- $line =~ s/^(\s+)//;
- $ptr->{'col'} += length ($1) if defined ($1);
-
- my @list = &quotewords ('[ \t]+', 1, $line);
- my $token = $list[0];
- $ptr->{'col'} += length ($token);
- $ptr->{'col'} -= chomp $token;
- return $token;
- }
-
- return;
-}
-
-sub x_update_unget_token
-{
- my $buf = shift;
- my $ptr = shift;
-
- my $line = substr ($$buf[$ptr->{'line'}], 0, $ptr->{'col'});
- my @list = &quotewords ('[ \t]+', 1, $line);
- my $token = $list[$#list];
-
- if (scalar @list == 2 && length ($list[0]) == 0 ||
- scalar @list <= 1) {
- --$ptr->{'line'};
- $ptr->{'col'} = length $$buf[$ptr->{'line'}];
- } else {
- $ptr->{'col'} -= length ($token);
- }
-}
-
-sub x_update_token
-{
- my $buf = shift;
- my $ptr = shift;
- my $old_val = shift;
- my $new_val = shift;
-
- my $pattern = $old_val;
- $pattern =~ s/(\W)/\\$1/g;
- substr ($$buf[$ptr->{'line'}], 0, $ptr->{'col'}) =~ s/$pattern$/$new_val/;
-
- if ($$buf[$ptr->{'line'}] =~ /^\s*$/) {
- $$buf[$ptr->{'line'}] = '';
- $ptr->{'col'} = 0;
- } else {
- my $diff = length ($old_val) - length ($new_val);
- $ptr->{'col'} -= $diff;
- }
-}
-
-sub x_update_add_token
-{
- my $buf = shift;
- my $ptr = shift;
- my $val = shift;
- my $same_line = shift;
-# my $new_val = $same_line ? " " : "\n";
- my $new_val = $same_line ? ' ' : '';
- $new_val .= $val;
-
- my $head = substr ($$buf[$ptr->{'line'}], 0, $ptr->{'col'});
- my $tail = substr ($$buf[$ptr->{'line'}], $ptr->{'col'});
-
- $$buf[$ptr->{'line'}] = $head . $new_val . $tail;
- $ptr->{'col'} += length ($new_val);
-}
-
-sub x_update_skip_section
-{
- my ($buf, $ptr) = @_;
- my $depth = 1;
-
- while (defined (my $token = &x_update_get_token ($buf, $ptr))) {
- if ($token =~ /End(Sub)?Section/i) {
- $depth--;
- last if $depth == 0;
- }
-
- $depth++ if $token =~ /(Sub)?Section/i;
- }
-}
-
-sub x_update_del_section
-{
- my ($buf, $ptr) = @_;
-
- my $first = $ptr->{'line'};
- &x_update_skip_section ($buf, $ptr);
- my $last = $ptr->{'line'};
-
- for ($first .. $last) { $$buf[$_] = ''; }
-}
-
-sub x_update_add_section
-{
- my ($buf, $ptr, $section, $section_name, $section_list, $sub_section) = @_;
- my $section_str = $sub_section ? "Subsection" : "Section";
-
- &x_update_add_token ($buf, $ptr, "\n$section_str \"$section_name\"\n");
-
- foreach my $key (keys %$section) {
- if (exists ($section_list->{$section_name}{'keywords'}{$key})) {
- my $func = $section_list->{$section_name}{'keywords'}{$key}{'add'};
- if ($func) {
- &$func ($buf, $ptr, $key, $section->{$key});
- &x_update_add_token ($buf, $ptr, "\n");
- }
- }
-
- elsif (exists ($section_list->{$section_name}{$key})) {
- foreach my $tmp (@{$section->{$key}}) {
- &x_update_add_section ($buf, $ptr, $tmp, $key, $section_list->{$section_name}, 1) if $tmp;
- }
- }
-
- else {
- my $msg = "unknown keyword $key in section $section";
- &gst_report ('x_general_warn', $msg);
- &gst_debug_print_line ("x_update_add_section: $msg");
- }
- }
-
- &x_update_add_token ($buf, $ptr, "End$section_str\n");
-}
-
-sub x_update_section
-{
- my $buf = shift;
- my $ptr = shift;
- my $config = shift;
- my $xml_config = shift;
- my $section_list = shift;
- my $new_section;
-
- # Read section name
- my $section_name = &x_update_get_token ($buf, $ptr);
- $section_name =~ s/\"//g;
- $section_name = &x_keyword_in_list ($section_name, keys %$section_list);
-
- unless ($section_name) {
- &x_update_skip_section ($buf, $ptr);
- return;
- }
-
- $section_list = $section_list->{$section_name};
- my $section = shift @{$config->{$section_name}};
- my $ident_str = $section_list->{KEY};
-
- # Find section from xml config
- for (my $i = 0; $i <= scalar @{$xml_config->{$section_name}}; $i++) {
- next unless exists $xml_config->{$section_name}[$i];
- if ($xml_config->{$section_name}[$i]->{$ident_str} eq $section->{$ident_str}) {
- $new_section = $xml_config->{$section_name}[$i];
- delete $xml_config->{$section_name}[$i];
- last;
- }
- }
-
- unless ($new_section) {
- &x_update_del_section ($buf, $ptr);
- return;
- }
-
- while (defined (my $token = &x_update_get_token ($buf, $ptr))) {
- if ($token =~ /End(Sub)?Section/i) {
- last;
- }
-
- if (my $kw = &x_keyword_in_list ($token, keys %{$section_list->{'keywords'}})) {
- if (exists $new_section->{$kw}) {
- my $func = $section_list->{'keywords'}{$kw}{'update'};
- &$func ($buf, $ptr, $section->{$kw}, $new_section->{$kw}) if $func;
- delete $new_section->{$kw};
- } else {
- my $func = $section_list->{'keywords'}{$kw}{'delete'};
- &$func ($buf, $ptr, $kw, $section->{$kw}) if $func;
- }
-
- next;
- }
-
- if ($token =~ /(Sub)?Section/i) {
- &x_update_section ($buf, $ptr, $section, $new_section, $section_list);
- next;
- }
- }
-
- # Add new values
-
- my $first_time = 1;
- foreach my $kw (keys %$new_section) {
- &x_update_unget_token ($buf, $ptr) if $first_time;
-
- if (exists $section_list->{'keywords'}{$kw}) {
- my $func = $section_list->{'keywords'}{$kw}{'add'};
- &$func ($buf, $ptr, $kw, $new_section->{$kw});
- &x_update_add_token ($buf, $ptr, "\n");
- }
-
- elsif (exists $section_list->{$kw}) {
- foreach my $tmp (@{$new_section->{$kw}}) {
- &x_update_add_section ($buf, $ptr, $tmp, $kw, $section_list, 1) if $tmp;
- }
- }
-
- else {
- my $msg = "unknown keyword $kw in section $section_name";
- &gst_report ('x_general_warn', $msg);
- &gst_debug_print_line ("x_update_section: $msg");
- }
-
- undef $first_time if $first_time;
- }
-
- &x_update_get_token ($buf, $ptr) unless $first_time;
-
- # Remove empty old data structs
- if (scalar @{$xml_config->{$section_name}} < 1) {
- delete $xml_config->{$section_name};
- }
-}
-
-sub x_config_set
-{
- my $fname = shift;
- my $config = shift;
- my $xml_config = shift;
-
- return unless $fname;
- return unless $config;
- return unless $xml_config;
-
- my $section_list = $x_version->{'sections'};
- my $buf = &gst_file_buffer_load ($fname);
- return unless $buf;
-
- my $ptr = {};
- while (defined (my $token = &x_update_get_token ($buf, $ptr))) {
- for ($token) {
- /^(Sub)?Section/i and do { &x_update_section ($buf, $ptr, $config, $xml_config, $section_list) };
-
- # Default:
- }
- }
-
- # Add new sections
- foreach my $key (keys %$xml_config) {
- if (exists ($section_list->{$key})) {
- foreach my $tmp (@{$xml_config->{$key}}) {
- &x_update_add_section ($buf, $ptr, $tmp, $key, $section_list) if $tmp;
- }
- }
- }
-
- &gst_file_buffer_save ($buf, $fname);
-}
-
-
-
-
-
-# ------------------------------------------------------
-# Compat layer
-# ------------------------------------------------------
-
-# internal.
-sub x_get_active_screen
-{
- my $config = shift;
- return unless $config;
-
- # Make sure there is at least one screen
- unless (exists ($config->{'Screen'}) || scalar @{$config->{'Screen'}} > 0) {
- # TODO: No 'Screen's found. give error or add one.
- return;
- }
-
- # First try to get it from ServerLayout.
- if (exists ($config->{'ServerLayout'}) &&
- scalar @{$config->{'ServerLayout'}} > 0) {
- my $active_screen = $config->{'ServerLayout'}[0]{'Screen'};
- $active_screen = $active_screen->{0}->{'Identifier'};
- foreach my $screen (@{$config->{'Screen'}}) {
- if ($screen->{'Identifier'} eq $active_screen) {
- return $screen;
- }
- }
- # TODO: give error that Screen found at ServerLayout doesn;t exist.
- }
-
- # Get active Screen:
-
- my $section = $config->{'Screen'};
- if ($x_version->{'number'} < 400) {
- foreach my $screen (@$section) {
- # Find screen with right 'Identifier'.
- return $screen if ($screen->{'Identifier'} =~ /$x_version->{'driver'}/i);
- }
- }
- else {
- return $$section[0];
- }
-
- # Didn't find screen.
- # TODO: give error or add a screen
-
- return;
-}
-
-# ServerLayout is optional, compose one if none present
-sub x_check_get_serverlayout
-{
- my $config = shift;
- return unless $config;
-
- # No need to 'fix' anything.
- return if ($config->{'ServerLayout'});
-
- my $section = "ServerLayout";
- my $hash = {};
-
- # Add 'Identifier'
- $hash->{'Identifier'} = 'Gst Configured';
-
- # Add 'Screen'
- my $ref = &x_get_active_screen ($config, $x_version);
- if ($ref) {
- $hash->{'Screen'} = { 0 =>
- {
- 'Identifier' => $ref->{'Identifier'}
- }
- };
- }
-
- push @{$config->{$section}}, $hash;
-}
-
-# X3 doesn't have ServerLayout keyword
-sub x_check_set_serverlayout
-{
- my $config = shift;
- return unless $config;
-
- if ($x_version->{'number'} < 400) {
- delete $config->{'GstXServerLayout'} if (exists ($config->{'GstXServerLayout'}));
- }
-}
-
-# internal. X verisions earlier than 4.0 didn't have 'Identifier' in 'Screen' section but
-# 'Driver' was used as one.
-sub x3_fix_screen
-{
- my $config = shift;
- my $get = shift;
-
- return unless $config;
-
- unless (exists ($config->{'Screen'})) {
- # TODO: No 'Screen's found. give error or add one.
- return;
- }
-
- my $section = $config->{'Screen'};
- foreach my $screen (@$section) {
- if ($get) {
- # Driver -> Identifier
- $screen->{'Identifier'} = $screen->{'Driver'};
- delete $screen->{'Driver'};
- } else {
- # Identifier -> Driver
- $screen->{'Driver'} = $screen->{'Identifier'};
- delete $screen->{'Identifier'};
- }
-
- # Color depth
- if ($get) {
- # GET
- if (exists $screen->{'DefaultColorDepth'}) {
- # DefaultColorDepth -> DefaultDepth
- $screen->{'DefaultDepth'} = $screen->{'DefaultColorDepth'};
- delete $screen->{'DefaultColorDepth'};
- } else {
- # Add default depth
- $screen->{'DefaultDepth'} = 8;
- }
- } else {
- # SET
- # DefaultDepth -> DefaultColorDepth
- $screen->{'DefaultColorDepth'} = $screen->{'DefaultDepth'};
- delete $screen->{'DefaultDepth'};
- }
- }
-}
-
-# Internal.
-sub x_get_active_serverlayout
-{
- my $config = shift;
- return unless $config;
-
- if (! $config->{'ServerLayout'} ||
- scalar @{$config->{'ServerLayout'}} < 1) {
- return;
- }
-
- # Active == first
- my $active = $config->{'ServerLayout'}[0];
- unless ($active->{'Identifier'} || $active->{'Screen'}) {
- &gst_debug_print_line ("x_get_active_serverlayout: Incomplete active layout.");
- return;
- }
-
- return $active;
-}
-
-# Internal
-sub x_get_active_display
-{
- my $config = shift;
- return unless $config;
-
- my $screen = &x_get_active_screen ($config);
- return unless $screen;
-
- if (scalar @{$screen->{'Display'}} < 1) {
- &gst_debug_print_line ("x_get_active_display: No 'Display' subsections found.");
- return;
- }
-
- foreach my $disp (@{$screen->{'Display'}}) {
- return $disp if $screen->{'DefaultDepth'} == $disp->{'Depth'};
- }
-
- &gst_debug_print_line ("x_get_active_display: No 'Display' subsection found.");
- return;
-}
-
-# Internal
-sub x_check_display
-{
- my $config = shift;
- return unless $config;
-
- my $display = &x_get_active_display ($config);
- return unless $display;
-
- my $modes = $display->{'Modes'};
- if (scalar @$modes < 1) {
- &gst_debug_print_line ("x_check_display: No 'Modes' found.");
- return;
- }
-
- my ($maxx, $maxy) = (0, 0);
- foreach my $mode (@$modes) {
- my ($x, $y) = ($1, $2) if $mode =~ /^(\d+)x(\d+)$/i;
- $maxx = $x if $x > $maxx;
- $maxy = $y if $y > $maxy;
- }
-
- my $active_mode = $$modes[0];
- my ($x, $y) = ($1, $2) if $active_mode =~ /^(\d+)x(\d+)$/i;
- if ($x < $maxx || $y < $maxy) {
- $display->{'Virtual'} = [ $x, $y ];
- } else {
- delete $display->{'Virtual'};
- }
-}
-
-sub x_config_fix
-{
- my $config = shift;
- my $get = shift;
- return unless $config;
-
- $x_version = &x_version () unless $x_version;
-
- if ($x_version->{'number'} < 400) {
- &x3_fix_screen ($config, $get);
- }
-
- if ($get) {
- &x_check_get_serverlayout ($config);
- } else {
- &x_check_set_serverlayout ($config);
- }
-
- &x_check_display ($config);
-}
-
-
-# -----------------------------------------------------------
-# Probe functions
-# -----------------------------------------------------------
-
-# Internal
-sub x_probe_get_modelines
-{
- my $config = shift;
- my $std_modelines = {};
-
- return unless $config;
-
- my @buf = split ('\n', $standard_modes);
- while (defined (my $token = &x_get_token (\@buf))) {
- &x_parse_modeline ($std_modelines, \@buf, $token);
- }
-
- return $std_modelines;
-}
-
-# Internal
-sub x_probe_get_monitor
-{
- my $config = shift;
- my $screen = shift;
- my $monitor;
-
- return unless $config;
- return unless $screen;
-
- my $active_monitor = $screen->{'Monitor'};
- foreach $monitor (@{$config->{'Monitor'}}) {
- if ($monitor->{'Identifier'} eq $active_monitor) {
- return $monitor;
- }
- }
-
- return;
-}
-
-# Internal
-sub x_probe_add_monitor
-{
- my $config = shift;
- my $monitor = shift;
- my $modes = shift;
-
- return unless $config;
- return unless $monitor;
-
- my $new;
- $new->{'Identifier'} = 'GstTestMonitor';
- $new->{'HorizSync'} = $monitor->{'HorizSync'};
- $new->{'VertRefresh'} = $monitor->{'VertRefresh'};
- $new->{'ModeLine'} = ();
-
- $new->{'ModeLine'} = $modes->{'ModeLine'};
- push @{$config->{'Monitor'}}, $new;
-
- return $new;
-}
-
-# Internal
-sub x_probe_add_screen
-{
- my $config = shift;
- my $screen = shift;
- my $monitor = shift;
-
- return unless $config;
- return unless $screen;
- return unless $monitor;
-
- my $new;
- $new->{'Identifier'} = 'GstTestScreen';
- $new->{'Device'} = $screen->{'Device'};
- $new->{'Monitor'} = 'GstTestMonitor';
-
- foreach my $depth (@x_colordepths) {
- my $display;
-
- $display->{'Depth'} = $depth;
- foreach my $mode (@{$monitor->{'ModeLine'}}) {
- push @{$display->{'Modes'}}, $mode->{'name'};
- }
- push @{$new->{'Display'}}, $display;
- }
-
- push @{$config->{'Screen'}}, $new;
-}
-
-# Internal
-sub x_probe_save
-{
- my $orig_file = shift;
- my $config = shift;
-
- return unless $orig_file;
- return unless $config;
-
- my $cfg_fname;
- do { $cfg_fname = tmpnam () }
- until my $fh = IO::File->new ($cfg_fname, O_RDWR|O_CREAT|O_EXCL);
-
- copy ($orig_file, $cfg_fname);
- my $orig_cfg = &x_parse ($cfg_fname);
-
- &x_config_set ($cfg_fname, $orig_cfg, $config);
-
- return $cfg_fname;
-}
-
-# Internal
-sub x_probe_scan
-{
- my $cfg_file = shift;
- my $depth = shift;
- my $depth_cmd = ($x_version->{'number'} >= 400) ? "-depth " : "-bpp ";
- $depth_cmd .= $depth;
-
- my $command = $x_version->{'command'};
- &gst_debug_print_line ("$command :9 -xf86config $cfg_file -probeonly $depth_cmd -screen GstTestScreen 2>&1 |");
- open (FD, "$command :9 -xf86config $cfg_file -probeonly $depth_cmd -screen GstTestScreen 2>&1 |");
- if (FD) {
- my @content = (<FD>);
- close (FD);
- my @list = grep (/^\(\*\*\) \w+\(0\): Mode \"/, @content);
- return \@list if scalar @list;
- }
-
- return;
-}
-
-# Internal
-sub x_probe_collect
-{
- my $data = shift;
- my $modes = shift;
- my $depth = shift;
-
- if (scalar @$data) {
- my $mode;
- my $list = [];
-
- foreach $mode (@{$modes->{'ModeLine'}}) {
- foreach (@$data) {
- my $modename = $1 if /\"(.+)\"/;
- if ($modename eq $mode->{'name'}) {
- push @$list, $mode;
- last;
- }
- }
- }
- return $list;
- }
-
- &gst_report ('x_probe_error', $depth);
- &gst_debug_print_line ("x_probe_collect: error reading XFree's output at depth $depth.");
- return;
-}
-
-# Internal
-sub x_probe_run
-{
- my $cfg_file = shift;
- my $modes = shift;
-
- return unless $cfg_file;
-
- my $hash;
- foreach my $depth (@x_colordepths) {
- my $proc = &gst_process_fork (\&x_probe_scan, $cfg_file, $depth);
- &gst_process_list_check_ready (15, $proc);
- my $list = &gst_process_result_collect ($proc, \&x_probe_collect, $modes, $depth);
- if ($list && scalar @$list) {
- $hash->{$depth} = $list;
- } else {
- last;
- }
- }
-
- unless ($hash) {
- &gst_report ('x_probe_error', "Error running XFree server");
- return;
- }
-
- return $hash;
-}
-
-# Internal
-sub x_probe_print_xml
-{
- my $list = shift;
-
- return unless $list;
-
- &gst_xml_print_begin ();
- &gst_xml_print_vspace ();
-
- foreach my $depth (keys %$list) {
- &gst_xml_print_line ("<Depth value=\"$depth\">");
- &gst_xml_enter ();
- &x_xml_print_modeline (0, $list->{$depth});
- &gst_xml_leave ();
- &gst_xml_print_line (q(</Depth>));
- }
-
- &gst_xml_print_end ();
-}
-
-# Internal
-sub x_probe_store
-{
- my $config = shift;
- my $list = shift;
-
- return unless $config;
- # TODO: Write monitor and card information also.
-
- my $file = &gst_file_get_data_path () . "/" . $main::tool->{'name'} . "/" . $x_probe_file;
-
- my $fh = &gst_file_open_write_from_names ($file);
- if ($fh) {
- local *STDOUT = $fh;
- &x_probe_print_xml ($list);
- close ($fh);
- }
-}
-
-# Internal
-sub x_probe_load
-{
- my $config = shift;
-
- return unless $config;
- # TODO: Check if monitor || card is changed
-
- my $file = &gst_file_get_data_path () . "/" . $main::tool->{'name'} . "/" . $x_probe_file;
- my $fh = &gst_file_open_read_from_names ($file);
-
- if ($fh) {
- my @content = <$fh>;
- close ($fh);
-
- return @content if (scalar @content > 0);
- }
-
- return;
-}
-
-sub x_probe
-{
- my $orig_file = shift;
- my $config = shift;
- my $direct = shift;
-
- return unless $orig_file;
- return unless $config;
-
- unless ($direct) {
- my @content = &x_probe_load ($config);
- &gst_report ('x_probe_needed') unless @content;
- &gst_report_end ();
- print @content;
- return;
- }
-
- my $modes = &x_probe_get_modelines ($config);
- my $screen = &x_get_active_screen ($config);
- my $monitor = &x_probe_get_monitor ($config, $screen);
-
- $monitor = &x_probe_add_monitor ($config, $monitor, $modes);
- &x_probe_add_screen ($config, $screen, $monitor);
-
- my $cfg_file = &x_probe_save ($orig_file, $config);
- my $list = &x_probe_run ($cfg_file, $modes);
- unlink ($cfg_file);
-
- if ($list) {
- &x_probe_store ($config, $list);
- &gst_report_end ();
- &x_probe_print_xml ($list);
- return;
- }
-
- &gst_report_end ();
-}
-
-
-1;