summaryrefslogtreecommitdiffstats
path: root/lib/Xconfig
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Xconfig')
-rw-r--r--lib/Xconfig/card.pm310
-rw-r--r--lib/Xconfig/main.pm83
-rw-r--r--lib/Xconfig/monitor.pm36
-rw-r--r--lib/Xconfig/parse.pm57
-rw-r--r--lib/Xconfig/plugins.pm232
-rw-r--r--lib/Xconfig/proprietary.pm70
-rw-r--r--lib/Xconfig/resolution_and_depth.pm65
-rw-r--r--lib/Xconfig/various.pm226
-rw-r--r--lib/Xconfig/xfree.pm207
9 files changed, 895 insertions, 391 deletions
diff --git a/lib/Xconfig/card.pm b/lib/Xconfig/card.pm
index 686957d..ea5df29 100644
--- a/lib/Xconfig/card.pm
+++ b/lib/Xconfig/card.pm
@@ -3,11 +3,17 @@ package Xconfig::card; # $Id$
use diagnostics;
use strict;
+use lib '/usr/lib/libDrakX';
use detect_devices;
+use Xconfig::xfree;
use modules;
use common;
+use interactive;
use log;
+my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
+
+sub modules_dir() { "/usr/$lib/xorg/modules" }
my %VideoRams = (
256 => N_("256 kB"),
@@ -21,12 +27,10 @@ my %VideoRams = (
65536 => N_("64 MB or more"),
);
-my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
-
my @xfree4_Drivers = ((arch() =~ /^sparc/ ? qw(sunbw2 suncg14 suncg3 suncg6 sunffb sunleo suntcx) :
- qw(apm ark chips cirrus cyrix glide i128 i740 i810 imstt
- mga neomagic newport nv rendition r128 radeon vesa
- s3 s3virge savage siliconmotion sis tdfx tga trident tseng vmware)),
+ qw(amd apm ark ast chips cirrus cyrix glide i128 i740 i810 imstt
+ mga nsc neomagic newport nv rendition openchrome vesa via
+ s3 s3virge savage siliconmotion sis sisusb tdfx tga trident tseng vmware)),
qw(ati glint vga fbdev));
sub from_raw_X {
@@ -36,7 +40,11 @@ sub from_raw_X {
my $card = {
use_DRI_GLX => eval { any { /dri/ } $raw_X->get_modules },
+ DRI_GLX_SPECIAL => first($raw_X->get_ModulePaths),
%$device,
+ if_($device->{Driver} eq 'nvidia',
+ DriverVersion =>
+ readlink("$::prefix/etc/alternatives/gl_conf") =~ m!nvidia(.*)/! ? $1 : '97xx'),
};
add_to_card__using_Cards($card, $card->{BoardName});
$card;
@@ -56,6 +64,12 @@ sub to_raw_X {
if (arch() =~ /ppc/ && ($_->{Driver} eq 'r128' || $_->{Driver} eq 'radeon')) {
$_->{UseFBDev} = 1;
}
+ if ($_->{Driver} eq 'i810') {
+ $_->{Options}{May_Need_ForceBIOS} = '1';
+ }
+ if (member($_->{Driver}, qw(i810 ati))) {
+ $_->{Options}{XaaNoOffscreenPixmaps} = '1';
+ }
}
$raw_X->set_devices(@cards);
@@ -63,19 +77,21 @@ sub to_raw_X {
$raw_X->get_ServerLayout->{Xinerama} = { commented => !$card->{Xinerama}, Option => 1 }
if defined $card->{Xinerama};
- # cleanup previous special nvidia libglx
- $raw_X->remove_load_module($_) foreach @{$card->{REMOVE_GLX} || []};
+ # cleanup deprecated previous special nvidia explicit libglx
+ $raw_X->remove_load_module(modules_dir() . "$_/libglx.so") foreach '/extensions/nvidia', '/extensions/nvidia_legacy', '/extensions';
+ # remove ModulePath that we added
+ $raw_X->remove_ModulePath(modules_dir() . "/extensions/$_") foreach 'nvidia97xx', 'nvidia96xx', 'nvidia71xx';
+ $raw_X->remove_ModulePath(modules_dir());
+ # then may re-add some
if ($card->{DRI_GLX_SPECIAL}) {
- $raw_X->remove_load_module('glx'); # this doesn't duplicate the above glx line
- # This loads the NVIDIA GLX extension module.
- # IT IS IMPORTANT TO KEEP NAME AS FULL PATH TO libglx.so ELSE
- # IT WILL LOAD XFree86 glx module and the server will crash.
- $raw_X->add_load_module($card->{DRI_GLX_SPECIAL});
- } else {
- $raw_X->set_load_module('glx', $card->{Driver} ne 'fbdev'); #- glx for everyone, except proprietary nvidia and fbdev
- $raw_X->set_load_module('dri', $card->{use_DRI_GLX});
+ $raw_X->add_ModulePath($card->{DRI_GLX_SPECIAL});
}
+ #- if we have some special ModulePath, ensure the last one is the standard ModulePath
+ $raw_X->add_ModulePath(modules_dir()) if $raw_X->get_ModulePaths;
+
+ $raw_X->set_load_module('glx', $card->{Driver} ne 'fbdev'); #- glx for everyone, except fbdev
+ $raw_X->set_load_module('dri', $card->{use_DRI_GLX}); #- dri when needed, except proprietary nvidia
$raw_X->remove_Section('DRI');
@@ -96,14 +112,18 @@ sub probe() {
VendorName => $l[0], BoardName => $l[1],
BusID => "PCI:$_->{pci_bus}:$_->{pci_device}:$_->{pci_function}",
};
- if ($_->{driver} =~ /Card:(.*)/) { $card->{BoardName} = $1; add_to_card__using_Cards($card, $1) }
- elsif ($_->{driver} =~ /Driver:(.*)/) { $card->{Driver} = $1 }
- else { internal_error() }
-
+ if (my ($card_name) = $_->{driver} =~ /Card:(.*)/) {
+ $card->{BoardName} = $card_name;
+ add_to_card__using_Cards($card, $card_name);
+ } elsif ($_->{driver} =~ /Driver:(.*)/) {
+ $card->{Driver} = $1;
+ } else {
+ internal_error();
+ }
$card;
} @c;
- if (@cards >= 2 && $cards[0]{card_name} eq $cards[1]{card_name} && $cards[0]{card_name} eq 'Intel 830') {
+ if (@cards >= 2 && $cards[0]{card_name} eq $cards[1]{card_name} && $cards[0]{card_name} eq 'Intel 830 - 965') {
shift @cards;
}
#- take a default on sparc if nothing has been found.
@@ -178,20 +198,19 @@ sub card_config__not_listed {
add_to_card__using_Cards($card, $s);
} else {
$card->{Driver} = $s;
+ $card->{DRI_GLX} = 0;
}
$card->{manually_chosen} = 1;
1;
}
sub multi_head_choose {
- my ($in, $auto, @cards) = @_;
+ my ($in, $_auto, @cards) = @_;
my @choices = multi_head_choices('', @cards);
my $tc = $choices[0];
- if ($auto) {
- @choices == 1 or return;
- } else {
+ if (@choices > 1) {
$tc = $in->ask_from_listf(N("Multi-head configuration"),
N("Your system supports multiple head configuration.
What do you want to do?"), sub { $_[0]{text} }, \@choices) or return;
@@ -223,12 +242,12 @@ sub configure_auto_install {
};
}
- my ($glx_choice) = xfree_and_glx_choices($card);
- log::explanations("Using $glx_choice->{text}");
- $glx_choice->{code}();
+ install_server($card, $options, $do_pkgs) or return;
+ $card = choose_Driver2_or_not($card, undef);
+
+ Xconfig::various::various_auto_install($raw_X, $card, $old_X);
set_glx_restrictions($card);
- install_server($card, $options, $do_pkgs);
if ($card->{needVideoRam} && !$card->{VideoRam}) {
$card->{VideoRam} = $options->{VideoRam_probed} || 4096;
log::explanations("argh, I need to know VideoRam! Taking " . ($options->{probed_VideoRam} ? "the probed" : "a default") . " value: VideoRam = $card->{VideoRam}");
@@ -246,38 +265,30 @@ sub configure {
if (!$cards[0]{Driver}) {
if ($options->{allowFB}) {
$cards[0]{Driver} = 'fbdev';
- } elsif ($auto) {
- log::explanations("Xconfig::card: auto failed (unknown card and no allowFB)");
- return 0;
}
}
- if (!$auto) {
+ if (!$auto || !$cards[0]{Driver}) {
card_config__not_listed:
card_config__not_listed($in, $cards[0], $options) or return;
}
my $card = multi_head_choose($in, $auto, @cards) or return;
- xfree_and_glx_choose($in, $card, $auto) or return;
+ install_server($card, $options, $do_pkgs) or goto card_config__not_listed;
+
+ $card = choose_Driver2_or_not($card, $in);
+
+ Xconfig::various::various($in, $raw_X, $card, $options, $auto);
+ set_glx_restrictions($card);
- eval { install_server($card, $options, $do_pkgs) };
- if ($@) {
- $in->ask_warn('', N("Can not install Xorg package: %s", $@));
- goto card_config__not_listed;
- }
-
if ($card->{needVideoRam} && !$card->{VideoRam}) {
- if ($auto) {
- log::explanations("Xconfig::card: auto failed (needVideoRam)");
- return;
- }
$card->{VideoRam} = (find { $_ <= $options->{VideoRam_probed} } reverse ikeys %VideoRams) || 4096;
$in->ask_from('', N("Select the memory size of your graphics card"),
[ { val => \$card->{VideoRam},
type => 'list',
list => [ ikeys %VideoRams ],
format => sub { translate($VideoRams{$_[0]}) },
- not_edit => !$::expert } ]) or return;
+ not_edit => 0 } ]) or return;
}
to_raw_X($card, $raw_X);
@@ -287,97 +298,80 @@ sub configure {
sub install_server {
my ($card, $options, $do_pkgs) = @_;
- my $prog = "$::prefix/usr/X11R6/bin/Xorg";
-
my @packages;
- push @packages, 'xorg-x11-server' if ! -x $prog;
-
- #- additional packages to install according available card.
- #- add XFree86-libs-DRI here if using DRI (future split of XFree86 TODO)
- if ($card->{use_DRI_GLX}) {
- push @packages, 'Glide_V5' if $card->{card_name} eq 'Voodoo5 (generic)';
- push @packages, 'Glide_V3-DRI' if member($card->{card_name}, 'Voodoo3 (generic)', 'Voodoo Banshee (generic)');
- push @packages, 'xorg-x11-glide-module' if $card->{card_name} =~ /Voodoo/;
- }
+ my @must_have = "x11-driver-video-$card->{Driver}";
if ($options->{freedriver}) {
delete $card->{Driver2};
}
- my %nvidia_packages = (
- #- using NVIDIA Legacy driver for old NVIDIA cards (TNT, TNT2, Vanta, Quadro, Quadro2, GeForce and GeForce2):
- legacy => [ qw(nvidia_legacy-kernel nvidia_legacy) ],
- #- using current NVIDIA driver for recent NVIDIA cards (Geforce/Quadro 3/4/FX/6x00/NVS):
- new => [ qw(nvidia-kernel nvidia) ],
- );
-
- my %proprietary_Driver2 = (
- nvidia => $nvidia_packages{ $card->{NVIDIA_LEGACY} ? 'legacy' : 'new' },
- fglrx => [ 'ati-kernel', 'ati' ], #- using ATI fglrx driver (Radeon, Fire GL cards only).
- );
- if (my $rpms_needed = $proprietary_Driver2{$card->{Driver2}}) {
- if (my $proprietary_packages = $do_pkgs->check_kernel_module_packages($rpms_needed->[0], $rpms_needed->[1])) {
- push @packages, @$proprietary_packages;
- # prevent having both nvidia & nvidia_legacy driver installed due to incompatibility:
- if ($card->{Driver2} eq 'nvidia') {
- $do_pkgs->remove($_) foreach @{$do_pkgs->check_kernel_module_packages(@{$nvidia_packages{ $card->{NVIDIA_LEGACY} ? 'new' : 'legacy' }})};
- }
- }
- }
-
- $do_pkgs->install(@packages) if @packages;
- -x $prog or die "server not available (should be in $prog)";
-
- my $modules_dir = "/usr/X11R6/$lib/modules";
- my $new_nvidia_libglx = "$modules_dir/extensions/nvidia/libglx.so";
- my $old_nvidia_libglx = "$modules_dir/extensions/libglx.so";
- #- make sure everything is correct at this point, packages have really been installed
- #- and driver and GLX extension is present.
- if ($card->{Driver2} eq 'nvidia' &&
- (-e "$::prefix$modules_dir/drivers/nvidia_drv.o" || -e "$::prefix$modules_dir/drivers/nvidia_drv.so")) {
- #- when there is extensions/libglx.a, it means extensions/libglx.so is not xorg's libglx, so it may be nvidia's
- #- new nvidia packages have libglx.so in extensions/nvidia instead of simply extensions/
- my $libglx_a = -e "$::prefix$modules_dir/extensions/libglx.a";
- my $libglx = find { -l "$::prefix$_" } $new_nvidia_libglx, if_($libglx_a, $old_nvidia_libglx);
- if ($libglx) {
- log::explanations("Using specific NVIDIA driver and GLX extensions");
- $card->{Driver} = 'nvidia';
- $card->{DRI_GLX_SPECIAL} = $libglx;
- }
- }
- if ($card->{Driver2} eq 'fglrx' &&
- -e "$::prefix$modules_dir/dri/fglrx_dri.so" &&
- (-e "$::prefix$modules_dir/drivers/fglrx_drv.o" || -e "$::prefix$modules_dir/drivers/fglrx_drv.so")) {
- log::explanations("Using specific ATI fglrx and DRI drivers");
- $card->{Driver} = 'fglrx';
+ if ($card->{Driver2}) {
+ require Xconfig::proprietary;
+ push @packages, Xconfig::proprietary::pkgs_for_Driver2($card, $do_pkgs);
}
- $card->{REMOVE_GLX} = [ $old_nvidia_libglx, $new_nvidia_libglx ];
- libgl_config($card);
+ $do_pkgs->ensure_are_installed([ @must_have, @packages ], 1) or
+ @must_have == listlength($do_pkgs->are_installed(@must_have))
+ or return;
if ($card->{need_MATROX_HAL}) {
require Xconfig::proprietary;
Xconfig::proprietary::install_matrox_hal($::prefix);
}
+ 1;
}
-sub xfree_and_glx_choose {
- my ($in, $card, $auto) = @_;
-
- my @choices = xfree_and_glx_choices($card);
-
- my $tc =
- $auto ? $choices[0] :
- $in->ask_from_listf_raw({ title => N("Xorg configuration"),
- messages => formatAlaTeX(join("\n\n\n", (grep { $_ } map { $_->{more_messages} } @choices),
- N("Which configuration of Xorg do you want to have?"))),
- interactive_help_id => 'configureX_xfree_and_glx',
- },
- sub { $_[0]{text} }, \@choices) or return;
- log::explanations("Using $tc->{text}");
- $tc->{code}();
- set_glx_restrictions($card);
- 1;
+sub choose_Driver2_or_not {
+ my ($card, $o_in) = @_;
+
+ my $card2;
+ if ($card->{Driver2}) {
+ require Xconfig::proprietary;
+ $card2 = Xconfig::proprietary::may_use_Driver2($card);
+ }
+
+ if ($card2) {
+ !$o_in || $o_in->ask_yesorno('', formatAlaTeX(N("There is a proprietary driver available for your video card which may support additional features.
+Do you wish to use it?")), 1) and $card = $card2;
+ }
+
+ libgl_config_and_more($card);
+ $card;
+}
+
+#- configures which libGL.so.1 to use, using update-alternatives
+#- it also configures nvidia_drv.so (using a slave alternative, cf "update-alternatives --display gl_conf")
+sub libgl_config_and_more {
+ my ($card) = @_;
+
+ if ($card->{Driver} eq 'nvidia') {
+ $card->{DriverVersion} or internal_error("DriverVersion should be set for driver nvidia!");
+ }
+
+ #- ensure old deprecated conf files are not there anymore
+ unlink("/etc/ld.so.conf.d/$_.conf") foreach 'nvidia', 'nvidia_legacy', 'ati';
+
+ my $wanted = $card->{Driver} eq 'fglrx' ? "/etc/ld.so.conf.d/GL/ati.conf" :
+ $card->{Driver} eq 'nvidia' ? "/etc/nvidia$card->{DriverVersion}/ld.so.conf" :
+ '/etc/ld.so.conf.d/GL/' . (arch() =~ /64/ ? 'lib64' : 'lib') . 'mesagl1.conf';
+ my $link = "$::prefix/etc/alternatives/gl_conf";
+ if (readlink($link) ne $wanted) {
+ -e "$::prefix$wanted" or log::l("ERROR: $wanted does not exist, linking $link to it anyway");
+ common::symlinkf_update_alternatives('gl_conf', $wanted);
+ if ($::isStandalone) {
+ log::explanations("ldconfig will be run because the GL library was " . ($wanted ? 'enabled' : 'disabled'));
+ system("/sbin/ldconfig");
+ }
+ }
+ if ($card->{Driver} eq 'fglrx') {
+ log::l("workaround buggy fglrx driver: make dm restart xserver (#29550)");
+ eval { common::update_gnomekderc_no_create("$::prefix/etc/kde/kdm/kdmrc", 'X-:0-Core' => (
+ TerminateServer => "true",
+ )) };
+ eval { update_gnomekderc("$::prefix/etc/X11/gdm/custom.conf", daemon => (
+ AlwaysRestartServer => "true",
+ )) };
+ }
}
sub multi_head_choices {
@@ -415,36 +409,6 @@ sub multi_head_choices {
@choices;
}
-#- Xorg version available, it would be better to parse available package and get version from it.
-sub xorg_version() { '6.9' }
-
-sub xfree_and_glx_choices {
- my ($card) = @_;
-
- my @choices = if_($card->{Driver}, { text => N("Xorg %s", xorg_version()), code => sub {} });
-
- #- no GLX with Xinerama
- return @choices if $card->{Xinerama};
-
- #- ask the expert or any user on second pass user to enable or not hardware acceleration support.
- if ($card->{DRI_GLX}) {
- unshift @choices, { text => N("Xorg %s with 3D hardware acceleration", xorg_version()),
- code => sub { $card->{use_DRI_GLX} = 1 },
- more_messages => N("Your card can have 3D hardware acceleration support with Xorg %s.", xorg_version()),
- };
- }
-
- #- an expert user may want to try to use an EXPERIMENTAL 3D acceleration.
- if ($card->{DRI_GLX_EXPERIMENTAL} && $::expert) {
- push @choices, { text => N("Xorg %s with EXPERIMENTAL 3D hardware acceleration", xorg_version()),
- code => sub { $card->{use_DRI_GLX} = 1 },
- more_messages => N("Your card can have 3D hardware acceleration support with Xorg %s,
-NOTE THIS IS EXPERIMENTAL SUPPORT AND MAY FREEZE YOUR COMPUTER.", xorg_version()),
- };
- }
- @choices;
-}
-
sub set_glx_restrictions {
my ($card) = @_;
@@ -453,52 +417,14 @@ sub set_glx_restrictions {
if ($card->{use_DRI_GLX}) {
$card->{needVideoRam} = 1 if $card->{description} =~ /Matrox.* G[245][05]0/;
($card->{needVideoRam}, $card->{VideoRam}) = (1, 16384)
- if member($card->{card_name}, 'Intel 810', 'Intel 815');
+ if $card->{card_name} eq 'Intel 810 / 815';
#- hack for ATI Rage 128 card using a bttv or peripheral with PCI bus mastering exchange
#- AND using DRI at the same time.
- if (member($card->{card_name}, 'ATI Rage 128', 'ATI Rage 128 TVout', 'ATI Rage 128 Mobility')) {
- $card->{Options}{UseCCEFor2D} = bool2text(modules::probe_category('multimedia/tv'));
+ if ($card->{card_name} eq 'ATI Rage 128 TV-out') {
+ $card->{Options}{UseCCEFor2D} = bool2text(detect_devices::probe_category('multimedia/tv'));
}
}
-
- #- check for Matrox G200 PCI cards, disable AGP in such cases, causes black screen else.
- if (member($card->{card_name}, 'Matrox Millennium 200', 'Matrox Millennium 200', 'Matrox Mystique') && $card->{description} !~ /AGP/) {
- log::explanations("disabling AGP mode for Matrox card, as it seems to be a PCI card");
- log::explanations("this is only used for XFree 3.3.6, see /etc/X11/glx.conf");
- substInFile { s/^\s*#*\s*mga_dma\s*=\s*\d+\s*$/mga_dma = 0\n/ } "$::prefix/etc/X11/glx.conf";
- }
-}
-
-sub libgl_config {
- my ($card) = @_;
-
- my $dir = "$::prefix/etc/ld.so.conf.d";
- my $comment = '# commented-by-DrakX ';
-
- my %driver_to_libgl_config = (
- nvidia => $card->{NVIDIA_LEGACY} ? 'nvidia_legacy.conf' : 'nvidia.conf',
- nvidia_other => !$card->{NVIDIA_LEGACY} ? 'nvidia_legacy.conf' : 'nvidia.conf',
- fglrx => 'ati.conf',
- );
- my $need_to_run_ldconfig;
- my $wanted = $driver_to_libgl_config{$card->{Driver}};
- foreach my $file (values %driver_to_libgl_config) {
- substInFile {
- my ($commented, $s) = /^(\Q$comment\E)?(.*)/;
- if ($file eq $wanted) {
- $_ = "$s\n";
- $need_to_run_ldconfig ||= $commented;
- } else {
- $_ = "$comment$s\n";
- $need_to_run_ldconfig ||= !$commented;
- }
- } "$dir/$file" if -e "$dir/$file";
- }
- if ($::isStandalone && $need_to_run_ldconfig) {
- log::explanations("ldconfig will be run because the GL library was " . ($wanted ? 'enabled' : 'disabled'));
- system("/sbin/ldconfig");
- }
}
sub add_to_card__using_Cards {
@@ -550,8 +476,6 @@ sub readCardsDB {
BAD_FB_RESTORE => sub { $card->{BAD_FB_RESTORE} = 1 },
FB_TVOUT => sub { $card->{FB_TVOUT} = 1 },
UNSUPPORTED => sub { delete $card->{Driver} },
- NVIDIA_LEGACY => sub { $card->{NVIDIA_LEGACY} = 1 },
-
COMMENT => sub {},
};
diff --git a/lib/Xconfig/main.pm b/lib/Xconfig/main.pm
index bdb4cbf..37a02c3 100644
--- a/lib/Xconfig/main.pm
+++ b/lib/Xconfig/main.pm
@@ -5,6 +5,7 @@ use strict;
use Xconfig::monitor;
use Xconfig::card;
+use Xconfig::plugins;
use Xconfig::resolution_and_depth;
use Xconfig::various;
use Xconfig::screen;
@@ -34,7 +35,11 @@ sub configure_resolution {
card => Xconfig::card::from_raw_X($raw_X),
monitors => [ $raw_X->get_monitors ],
};
- $X->{resolution} = Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}) or return;
+ if (my $rc = Xconfig::various::handle_May_Need_ForceBIOS($in, $raw_X)) {
+ return $rc;
+ }
+
+ $X->{resolutions} = Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}) or return;
if ($raw_X->prepare_write ne $before) {
&write($raw_X, $X);
} else {
@@ -50,12 +55,10 @@ sub configure_everything_auto_install {
$options->{VideoRam_probed} = $X->{monitors}[0]{VideoRam_probed};
$X->{card} = Xconfig::card::configure_auto_install($raw_X, $do_pkgs, $old_X, $options) or return;
Xconfig::screen::configure($raw_X) or return;
- $X->{resolution} = Xconfig::resolution_and_depth::configure_auto_install($raw_X, $X->{card}, $X->{monitors}, $old_X);
+ $X->{resolutions} = Xconfig::resolution_and_depth::configure_auto_install($raw_X, $X->{card}, $X->{monitors}, $old_X);
my $action = &write($raw_X, $X);
- Xconfig::various::runlevel(exists $old_X->{xdm} && !$old_X->{xdm} ? 3 : 5);
-
$action;
}
@@ -69,15 +72,13 @@ sub configure_everything {
$ok &&= $X->{card} = Xconfig::card::configure($in, $raw_X, $do_pkgs, $auto, $options);
$ok &&= $X->{monitors} = Xconfig::monitor::configure($in, $raw_X, int($raw_X->get_devices), $probed_info, $auto);
$ok &&= Xconfig::screen::configure($raw_X);
- $ok &&= $X->{resolution} = Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}, $auto);
+ $ok &&= $X->{resolutions} = Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}, $auto);
$ok &&= Xconfig::test::test($in, $raw_X, $X->{card}, '', 'skip_badcard') if !$auto;
if (!$ok) {
return if $auto;
($ok) = configure_chooser_raw($in, $raw_X, $do_pkgs, $options, $X, 1);
}
- $X->{various} ||= Xconfig::various::various($in, $X->{card}, $options, $auto);
-
may_write($in, $raw_X, $X, $ok);
}
@@ -89,7 +90,7 @@ sub configure_chooser_raw {
my $update_texts = sub {
$texts{card} = $X->{card} && $X->{card}{BoardName} || N("Custom");
$texts{monitors} = $X->{monitors} && $X->{monitors}[0]{ModelName} || N("Custom");
- $texts{resolution} = Xconfig::resolution_and_depth::to_string($X->{resolution});
+ $texts{resolutions} = Xconfig::resolution_and_depth::to_string($X->{resolutions}[0]);
$texts{$_} =~ s/(.{20}).*/$1.../ foreach keys %texts; #- ensure not too long
};
@@ -97,7 +98,7 @@ sub configure_chooser_raw {
my $may_set;
my $prompt_for_resolution = sub {
- $may_set->('resolution', Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}));
+ $may_set->('resolutions', Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}));
};
$may_set = sub {
my ($field, $val) = @_;
@@ -108,15 +109,13 @@ sub configure_chooser_raw {
$update_texts->();
if (member($field, 'card', 'monitors')) {
- my ($default_resolution) = Xconfig::resolution_and_depth::choices($raw_X, $X->{resolution}, $X->{card}, $X->{monitors});
- if (find { $default_resolution->{$_} ne $X->{resolution}{$_} } 'X', 'Y', 'Depth') {
+ my ($default_resolution, @other_resolutions) = Xconfig::resolution_and_depth::choices($raw_X, $X->{resolutions}[0], $X->{card}, $X->{monitors});
+ if (Xconfig::resolution_and_depth::to_string($default_resolution) ne
+ Xconfig::resolution_and_depth::to_string($X->{resolutions}[0])) {
$prompt_for_resolution->();
} else {
- if ($default_resolution->{bios} && !$X->{resolution}{bios}) {
- $may_set->('resolution', $default_resolution);
- }
Xconfig::screen::configure($raw_X);
- $raw_X->set_resolution($X->{resolution}) if $X->{resolution};
+ $may_set->('resolutions', Xconfig::resolution_and_depth::set_resolution($raw_X, $default_resolution, @other_resolutions));
}
}
}
@@ -124,6 +123,7 @@ sub configure_chooser_raw {
my $ok;
$in->ask_from_({ interactive_help_id => 'configureX_chooser',
+ title => N("Graphic Card & Monitor Configuration"),
if_($::isStandalone, ok => N("Quit")) },
[
{ label => N("Graphic Card"), val => \$texts{card}, clicked => sub {
@@ -132,7 +132,7 @@ sub configure_chooser_raw {
{ label => N("Monitor"), val => \$texts{monitors}, clicked => sub {
$may_set->('monitors', Xconfig::monitor::configure($in, $raw_X, int($raw_X->get_devices)));
} },
- { label => N("Resolution"), val => \$texts{resolution}, disabled => sub { !$X->{card} || !$X->{monitors} },
+ { label => N("Resolution"), val => \$texts{resolutions}, disabled => sub { !$X->{card} || !$X->{monitors} },
clicked => $prompt_for_resolution },
if_(Xconfig::card::check_bad_card($X->{card}) || $::isStandalone,
{ val => N("Test"), disabled => sub { !$X->{card} || !$X->{monitors} },
@@ -141,9 +141,14 @@ sub configure_chooser_raw {
} },
),
{ val => N("Options"), clicked => sub {
- Xconfig::various::various($in, $X->{card}, $options);
- $X->{various} = 'done';
+ Xconfig::various::various($in, $raw_X, $X->{card}, $options, 0, 'read_existing');
+ Xconfig::card::to_raw_X($X->{card}, $raw_X);
} },
+ if_(Xconfig::plugins::list(),
+ { val => N("Plugins"), clicked => sub {
+ Xconfig::plugins::choose($in, $raw_X);
+ } },
+ ),
]);
$ok, $b_modified;
}
@@ -154,7 +159,7 @@ sub configure_chooser {
my $X = {
card => scalar eval { Xconfig::card::from_raw_X($raw_X) },
monitors => [ $raw_X->get_monitors ],
- resolution => scalar eval { $raw_X->get_resolution },
+ resolutions => [ eval { $raw_X->get_resolutions } ],
};
my $before = $raw_X->prepare_write;
my ($ok) = configure_chooser_raw($in, $raw_X, $do_pkgs, $options, $X);
@@ -171,20 +176,21 @@ sub configure_everything_or_configure_chooser {
my $raw_X = eval { Xconfig::xfree->read };
my $err = $@ && formatError($@);
- $err ||= check_valid($raw_X) if $raw_X && @$raw_X; #- that's ok if config is empty
+ $err ||= check_valid($raw_X) if $raw_X; #- that's ok if config is empty
if ($err) {
log::l("ERROR: bad X config file (error: $err)");
$options->{ignore_bad_conf} or $in->ask_okcancel('',
N("Your Xorg configuration file is broken, we will ignore it.")) or return;
- $raw_X = [];
+ undef $raw_X;
}
my $rc = 'ok';
- if (is_empty_array_ref($raw_X)) {
+ if (!$raw_X) {
$raw_X = Xconfig::default::configure($in->do_pkgs, $o_keyboard, $o_mouse);
$rc = configure_everything($in, $raw_X, $in->do_pkgs, $auto, $options);
} elsif (!$auto) {
- $rc = configure_chooser($in, $raw_X, $in->do_pkgs, $options);
+ $rc = Xconfig::various::handle_May_Need_ForceBIOS($in, $raw_X);
+ $rc ||= configure_chooser($in, $raw_X, $in->do_pkgs, $options);
}
$rc && $raw_X, $rc;
}
@@ -206,9 +212,9 @@ sub write {
export_to_install_X($X) if $::isInstall;
$raw_X->write;
Xconfig::various::check_XF86Config_symlink();
- symlinkf "../../usr/X11R6/bin/Xorg", "$::prefix/etc/X11/X";
- if ($X->{resolution}{bios}) {
- Xconfig::various::setupFB($X->{resolution}{bios});
+ symlinkf "../../usr/bin/Xorg", "$::prefix/etc/X11/X";
+ if ($X->{resolutions}[0]{bios}) {
+ Xconfig::various::setupFB($X->{resolutions}[0]{bios});
'need_reboot';
} else {
'need_restart';
@@ -219,9 +225,9 @@ sub write {
sub export_to_install_X {
my ($X) = @_;
- $::o->{X}{resolution_wanted} = $X->{resolution}{X};
- $::o->{X}{default_depth} = $X->{resolution}{Depth};
- $::o->{X}{bios_vga_mode} = $X->{resolution}{bios};
+ $::o->{X}{resolution_wanted} = $X->{resolutions}[0]{X} . 'x' . $X->{resolutions}[0]{Y};
+ $::o->{X}{default_depth} = $X->{resolutions}[0]{Depth};
+ $::o->{X}{bios_vga_mode} = $X->{resolutions}[0]{bios};
$::o->{X}{monitors} = $X->{monitors} if $X->{monitors}[0]{manually_chosen} && $X->{monitors}[0]{vendor} ne "Plug'n Play";
$::o->{X}{card} = $X->{card} if $X->{card}{manually_chosen};
$::o->{X}{Xinerama} = 1 if $X->{card}{Xinerama};
@@ -240,23 +246,4 @@ sub check_valid {
'';
}
-#- most usefull XFree86-4.0.1 server options. Default values is the first ones.
-our @options_serverflags = (
- 'DontZap' => [ "Off", "On" ],
- 'DontZoom' => [ "Off", "On" ],
- 'DisableVidModeExtension' => [ "Off", "On" ],
- 'AllowNonLocalXvidtune' => [ "Off", "On" ],
- 'DisableModInDev' => [ "Off", "On" ],
- 'AllowNonLocalModInDev' => [ "Off", "On" ],
- 'AllowMouseOpenFail' => [ "False", "True" ],
- 'VTSysReq' => [ "Off", "On" ],
- 'BlankTime' => [ "10", "5", "3", "15", "30" ],
- 'StandByTime' => [ "20", "10", "6", "30", "60" ],
- 'SuspendTime' => [ "30", "15", "9", "45", "90" ],
- 'OffTime' => [ "40", "20", "12", "60", "120" ],
- 'Pixmap' => [ "32", "24" ],
- 'PC98' => [ "auto-detected", "False", "True" ],
- 'NoPM' => [ "False", "True" ],
-);
-
1;
diff --git a/lib/Xconfig/monitor.pm b/lib/Xconfig/monitor.pm
index ba5360b..d376f15 100644
--- a/lib/Xconfig/monitor.pm
+++ b/lib/Xconfig/monitor.pm
@@ -85,8 +85,7 @@ sub choose {
my ($in, $monitor, $head_nb, $card_Driver, $b_auto) = @_;
my $ok = is_valid($monitor);
- if ($b_auto) {
- log::l("Xconfig::monitor: auto failed") if !$ok;
+ if ($b_auto && $ok) {
return $ok;
}
@@ -181,10 +180,35 @@ sub probe {
probe_DDC() || probe_DMI() || probe_using_X($o_card_Driver);
}
+#- some EDID are much too strict:
+#- the HorizSync range is too small to allow smaller resolutions
+sub adjust_HorizSync_from_edid {
+ my ($monitor) = @_;
+
+ my ($hmin, $hmax) = $monitor->{HorizSync} =~ /(\d+)-(\d+)/ or return;
+ if ($hmin > 45) {
+ log::l("replacing HorizSync $hmin-$hmax with 31.5-$hmax (allow 800x600)");
+ $monitor->{HorizSync} = "31.5-$hmax";
+ }
+}
+#- the VertRefresh range is too weird
+sub adjust_VertRefresh_from_edid {
+ my ($monitor) = @_;
+
+ my ($vmin, $vmax) = $monitor->{VertRefresh} =~ /(\d+)-(\d+)/ or return;
+ if ($vmin > 60) {
+ log::l("replacing VertRefresh $vmin-$vmax with 60-$vmax");
+ $monitor->{VertRefresh} = "60-$vmax";
+ }
+}
+
sub probe_DDC() {
my ($edid, $vbe) = any::monitor_full_edid() or return;
my $monitor = eval($edid);
+ adjust_HorizSync_from_edid($monitor);
+ adjust_VertRefresh_from_edid($monitor);
+
if ($vbe =~ /Memory: (\d+)k/) {
$monitor->{VideoRam_probed} = $1;
}
@@ -200,7 +224,10 @@ sub probe_DDC() {
{ val => $_->{ModeLine}, pre_comment => $_->{ModeLine_comment} . "\n" };
}
- if (@$detailed_timings == 1) {
+ if (@$detailed_timings == 1 && $_->{horizontal_active} >= 1024) {
+ #- we don't use detailed_timing when it is 640x480 or 800x600,
+ #- since 14" CRTs often give this even when they handle 1024x768 correctly (and desktop is no good in poor resolutions)
+
#- should we care about {has_preferred_timing} ?
$monitor->{preferred_resolution} = { X => $_->{horizontal_active}, Y => $_->{vertical_active} };
}
@@ -210,6 +237,7 @@ sub probe_DDC() {
$monitor->{VendorName} = "Plug'n Play";
$monitor->{ModelName} = $monitor->{monitor_name};
$monitor->{ModelName} =~ s/"/''/g;
+ $monitor->{ModelName} =~ s/[\0-\x20]/ /g;
}
configure_automatic($monitor) or return;
$monitor;
@@ -241,7 +269,7 @@ sub generic_flat_panel {
{
VendorName => 'Generic',
ModelName => "Flat Panel $resolution",
- HorizSync => '31.5-100', VertRefresh => '60',
+ HorizSync => '31.5-' . ($X > 1920 ? '100' : '90'), VertRefresh => '60',
preferred_resolution => { X => $X, Y => $Y },
};
}
diff --git a/lib/Xconfig/parse.pm b/lib/Xconfig/parse.pm
index 71062a0..e7e97f4 100644
--- a/lib/Xconfig/parse.pm
+++ b/lib/Xconfig/parse.pm
@@ -8,35 +8,35 @@ use common;
sub read_XF86Config {
my ($file) = @_;
- my $raw_X = raw_from_file($file);
- from_raw(@$raw_X);
- $raw_X;
+ my $raw = _rraw_from_file($file);
+ _from_rraw(@$raw);
+ $raw;
}
sub prepare_write_XF86Config {
- my ($raw_X) = @_;
- map { raw_to_string(before_to_string({ %$_ }, 0)) } @$raw_X;
+ my ($raw) = @_;
+ map { _raw_to_string(_before_to_string({ %$_ }, 0)) } @$raw;
}
sub write_XF86Config {
- my ($raw_X, $file) = @_;
- my @blocks = prepare_write_XF86Config($raw_X);
+ my ($raw, $file) = @_;
+ my @blocks = prepare_write_XF86Config($raw);
@blocks ? output($file, @blocks) : unlink $file;
}
sub read_XF86Config_from_string {
my ($s) = @_;
- my $raw_X = raw_from_file('-', [ split "\n", $s ]);
- from_raw(@$raw_X);
- $raw_X;
+ my $raw = _rraw_from_file('-', [ split "\n", $s ]);
+ _from_rraw(@$raw);
+ $raw;
}
#-###############################################################################
#- raw reading/saving
#-###############################################################################
-sub raw_from_file { #- internal
+sub _rraw_from_file {
my ($file, $o_lines) = @_;
- my $raw_X = [];
+ my $rraw = [];
my $lines = $o_lines || [ cat_($file) ];
my $line;
@@ -68,7 +68,7 @@ sub raw_from_file { #- internal
if (/^Section\s+"(.*)"/i) {
die "$file:$line: missing EndSection\n" if @objs;
my $e = { name => $1, l => [], kind => 'Section' };
- push @$raw_X, $e;
+ push @$rraw, $e;
unshift @objs, $e; $obj = '';
$attach_comment->('pre');
} elsif (/^Subsection\s+"(.*)"/i) {
@@ -110,21 +110,26 @@ sub raw_from_file { #- internal
push @{$objs[0]{l}}, $obj;
}
}
- $raw_X;
+ $rraw;
}
-sub raw_to_string {
+sub _simple_val_to_string {
+ my ($name, $e) = @_;
+ my $key = $e->{Option} ? qq(Option "$name") : $name;
+ my $val = defined $e->{val} ? ($e->{Option} && $e->{val} !~ /^"/ ? qq( "$e->{val}") : qq( $e->{val})) : '';
+ ($e->{commented} ? '#' : '') . $key . $val;
+}
+
+sub _raw_to_string {
my ($e, $b_want_spacing) = @_;
my $s = do {
if ($e->{l}) {
- my $inside = join('', map_index { raw_to_string($_, $::i) } @{$e->{l}});
+ my $inside = join('', map_index { _raw_to_string($_, $::i) } @{$e->{l}});
$inside .= $e->{post_comment} || '';
$inside =~ s/^/ /mg;
qq(\n$e->{kind} "$e->{name}"\n) . $inside . "End$e->{kind}";
} else {
- ($e->{commented} ? '#' : '') .
- ($e->{Option} ? qq(Option "$e->{name}") : $e->{name}) .
- (defined $e->{val} ? ($e->{Option} && $e->{val} !~ /^"/ ? qq( "$e->{val}") : qq( $e->{val})) : '');
+ _simple_val_to_string($e->{name}, $e);
}
};
($e->{pre_comment} ? ($b_want_spacing ? "\n" : '') . $e->{pre_comment} : '') . $s . ($e->{comment_on_line} || '') . "\n" . (!$e->{l} && $e->{post_comment} || '');
@@ -147,16 +152,16 @@ my %kind_names = (
WacomEraser => [ qw(Port) ], #-/
ServerLayout => [ qw(Identifier) ],
);
-my @want_string = qw(Identifier DeviceName VendorName ModelName BoardName Driver Device Chipset Monitor Protocol XkbModel XkbLayout XkbOptions XkbCompat Load BusID);
+my @want_string = qw(Identifier DeviceName VendorName ModelName BoardName Driver Device Chipset Monitor Protocol XkbModel XkbLayout XkbOptions XkbCompat Load ModulePath BusID);
%kind_names = map_each { lc $::a => [ map { lc } @$::b ] } %kind_names;
@want_string = map { lc } @want_string;
-sub from_raw {
- sub from_raw__rec {
+sub _from_rraw {
+ sub _from_rraw__rec {
my ($current, $e) = @_;
if ($e->{l}) {
- from_raw($e);
+ _from_rraw($e);
push @{$current->{l}{$e->{name}}}, $e;
} else {
if (member(lc $e->{name}, @want_string)) {
@@ -178,13 +183,13 @@ sub from_raw {
foreach my $e (@_) {
($e->{l}, my $l) = ({}, $e->{l});
- from_raw__rec($e, $_) foreach @$l;
+ _from_rraw__rec($e, $_) foreach @$l;
delete $e->{kind};
}
}
-sub before_to_string {
+sub _before_to_string {
my ($e, $depth) = @_;
if ($e->{l}) {
@@ -195,7 +200,7 @@ sub before_to_string {
$e->{l} = [ map {
my $name = $_;
map {
- before_to_string({ name => $name, %$_ }, $depth+1);
+ _before_to_string({ name => $name, %$_ }, $depth+1);
} deref_array($e->{l}{$name});
} @sorted ];
} elsif (member(lc $e->{name}, @want_string)) {
diff --git a/lib/Xconfig/plugins.pm b/lib/Xconfig/plugins.pm
new file mode 100644
index 0000000..620c2fe
--- /dev/null
+++ b/lib/Xconfig/plugins.pm
@@ -0,0 +1,232 @@
+package Xconfig::plugins; # $Id: plugins.pm 110085 2007-01-18 08:45:14Z pixel $
+
+use diagnostics;
+use strict;
+
+use Xconfig::parse;
+use Xconfig::xfree;
+use common;
+
+my $dir = '/usr/share/libDrakX/x11-plugins';
+
+sub list() {
+ glob_("$dir/*.pl");
+}
+
+sub _load {
+ my ($plugin_pl_file) = @_;
+ my $plugin = eval cat_($plugin_pl_file);
+ $@ and die "bad $plugin_pl_file. error: $@\n";
+
+ #- ensure only one line
+ $plugin->{summary} =~ s/\n/ /g;
+
+ eval { $plugin->{raw} = Xconfig::parse::read_XF86Config_from_string($plugin->{conf}) };
+ $@ and die "bad $plugin_pl_file conf. error: $@\n";
+
+ $plugin;
+}
+
+my $mark = '# Using plugin';
+sub parse_active_plugin {
+ my ($raw_X) = @_;
+
+ $raw_X->{plugins} and internal_error("parse_active_plugin must be done before doing anything with plugins");
+
+ my $first = $raw_X->{raw}[0];
+ if (my @l = $first->{pre_comment} =~ /^\Q$mark\E (.*)/gm) {
+ $raw_X->{plugins} = [ map { { active => 1, summary => $_ } } @l ];
+ }
+}
+sub _mark_active_in_header {
+ my ($raw_X, $summary) = @_;
+ my $first = $raw_X->{raw}[0];
+ $first->{pre_comment} =~ s/\n/\n$mark $summary\n/;
+}
+sub _remove_active_in_header {
+ my ($raw_X, $summary) = @_;
+ my $first = $raw_X->{raw}[0];
+ $first->{pre_comment} =~ s/\Q$mark $summary\E\n//;
+}
+
+sub load {
+ my ($raw_X, $plugin_pl_file) = @_;
+
+ my $plugin = eval { _load($plugin_pl_file) };
+ $@ and log::l("bad plugin $plugin_pl_file: $@"), return;
+
+ if (my $existing = find { $_->{summary} eq $plugin->{summary} } @{$raw_X->{plugins}}) {
+ put_in_hash($existing, $plugin);
+ $existing->{updated} = 1;
+ } else {
+ push @{$raw_X->{plugins}}, $plugin;
+ }
+}
+
+sub val { &Xconfig::xfree::val }
+
+sub apply_plugin {
+ my ($raw_X, $plugin) = @_;
+
+ if ($plugin->{active}) {
+ $plugin->{updated} or return;
+
+ #- removing before re-applying again
+ remove_plugin($raw_X, $plugin);
+ }
+
+ log::l("applying plugin $plugin->{summary}");
+
+ foreach my $e (@{$plugin->{raw}}) {
+ _mark_lines_with_name($plugin->{summary}, $e);
+
+ if (my @sections = _select_sections_to_modify($raw_X, $e)) {
+ #- modifying existing sections
+ #- if there is more than one, modify all of them!
+ _merge_in_section($_, $e->{l}) foreach @sections;
+ } else {
+ #- adding the section
+ $raw_X->add_Section($e->{name}, $e->{l});
+ }
+ }
+
+ _mark_active_in_header($raw_X, $plugin->{summary});
+ $plugin->{active} = 1;
+}
+
+sub _select_sections_to_modify {
+ my ($raw_X, $e) = @_;
+
+ my @sections = $raw_X->get_Sections($e->{name}) or return;
+
+ if ($e->{l}{Identifier}) {
+ if (my @l = grep { val($_->{Identifier}) eq $e->{l}{Identifier}{val} } @sections) {
+ #- only modifying the section(s) matching the Driver (useful for InputDevice)
+ delete $e->{l}{Identifier}; #- do not tag-with-comment this line used only to select the section
+ @l;
+ } else {
+ #- if no matching section, we will create it
+ ();
+ }
+ } elsif ($e->{l}{Driver}) {
+ if (my @l = grep { val($_->{Driver}) eq $e->{l}{Driver}{val} } @sections) {
+ #- only modifying the section(s) matching the Driver (useful for InputDevice)
+ delete $e->{l}{Driver}; #- do not tag-with-comment this line used only to select the section
+ @l;
+ } else {
+ #- hum, modifying existing sections, is that good? :-/
+ @sections;
+ }
+ } else {
+ #- modifying existing sections
+ @sections;
+ }
+}
+
+sub _merge_in_section {
+ my ($h, $h_to_add) = @_;
+
+ foreach my $name (keys %$h_to_add) {
+ if (exists $h->{$name}) {
+ my $pre_comment = join('', map { "#HIDDEN $_->{val}\n" } deref_array($h->{$name}));
+ my ($first, @other) = deref_array($h_to_add->{$name});
+ $first = { pre_comment => $pre_comment, %$first };
+
+ $h->{$name} = ref($h->{$name}) eq 'ARRAY' ? [ $first, @other ] : $first;
+ } else {
+ $h->{$name} = $h_to_add->{$name};
+ }
+ }
+}
+
+sub _mark_lines_with_name {
+ my ($summary, $e) = @_;
+ if ($e->{l}) {
+ _mark_lines_with_name($summary, $_) foreach map { deref_array($_) } values %{$e->{l}};
+ } else {
+ $e->{comment_on_line} = " # $summary";
+ }
+}
+
+sub remove_plugin {
+ my ($raw_X, $plugin) = @_;
+
+ $plugin->{active} or return;
+
+ log::l("removing plugin $plugin->{summary}");
+
+ @{$raw_X->{raw}} = map {
+ _remove_plugin($plugin->{summary}, $_);
+ } @{$raw_X->{raw}};
+
+ _remove_active_in_header($raw_X, $plugin->{summary});
+ $plugin->{active} = 0;
+}
+
+sub _remove_plugin {
+ my ($summary, $e) = @_;
+ if ($e->{l}) {
+ my $removed;
+ foreach my $k (keys %{$e->{l}}) {
+ my $v = $e->{l}{$k};
+ my @v = map { _remove_plugin($summary, $_) } deref_array($v);
+ if (@v) {
+ if (ref($v) eq 'ARRAY') {
+ @$v = @v;
+ } else {
+ $e->{l}{$k} = $v[0];
+ }
+ } else {
+ $removed = 1;
+ delete $e->{l}{$k};
+ }
+ }
+ if_(!$removed || %{$e->{l}}, $e);
+ } elsif ($e->{comment_on_line} eq " # $summary") {
+ if (my @hidden = $e->{pre_comment} =~ /^#HIDDEN (.*)/gm) {
+ delete $e->{comment_on_line};
+ delete $e->{pre_comment};
+ map { { %$e, val => $_ } } @hidden;
+ } else {
+ ();
+ }
+ } else {
+ $e;
+ }
+}
+
+sub apply_or_remove_plugin {
+ my ($raw_X, $plugin, $apply) = @_;
+
+ if ($apply) {
+ apply_plugin($raw_X, $plugin);
+ } else {
+ remove_plugin($raw_X, $plugin);
+ }
+}
+
+sub choose {
+ my ($in, $raw_X) = @_;
+
+ parse_active_plugin($raw_X) if !$raw_X->{plugins};
+
+ load($raw_X, $_) foreach list();
+
+ my $plugins = $raw_X->{plugins};
+ $_->{want_active} = $_->{active} foreach @$plugins;
+
+ $in->ask_from_({},
+ [ { title => 1, label => N("Choose plugins") },
+ map {
+ { type => 'bool', val => \$_->{want_active}, text => $_->{summary} },
+ { val => formatAlaTeX($_->{description}) };
+ } @$plugins ]) or return;
+
+ foreach (@$plugins) {
+ apply_or_remove_plugin($raw_X, $_, $_->{want_active})
+ if $_->{want_active} != $_->{active};
+ }
+
+ 1;
+}
+1;
diff --git a/lib/Xconfig/proprietary.pm b/lib/Xconfig/proprietary.pm
index ed196de..3fae5f9 100644
--- a/lib/Xconfig/proprietary.pm
+++ b/lib/Xconfig/proprietary.pm
@@ -4,7 +4,9 @@ use diagnostics;
use strict;
use common;
+use Xconfig::card;
+my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
sub install_matrox_hal {
my ($prefix) = @_;
@@ -12,7 +14,7 @@ sub install_matrox_hal {
my $tar = "mgadrivers-2.0.tgz";
my $dir_in_tar = "mgadrivers";
- my $dest_dir = "$prefix/usr/X11R6/lib/modules/drivers";
+ my $dest_dir = "$prefix/usr/lib/xorg/modules/drivers";
#- already installed
return if -e "$dest_dir/mga_hal_drv.o" || $::testing;
@@ -31,5 +33,71 @@ sub install_matrox_hal {
rm_rf("$tmpdir/$dir_in_tar");
}
+sub pkg_name_for_Driver2 {
+ my ($card) = @_;
+ $card->{Driver2} eq 'fglrx' ? 'ati' :
+ $card->{Driver2} =~ /^nvidia/ ? $card->{Driver2} : '';
+}
+
+sub pkgs_for_Driver2 {
+ my ($card, $do_pkgs) = @_;
+
+ my $pkg = pkg_name_for_Driver2($card);
+
+ $pkg && $do_pkgs->is_available($pkg) or return;
+
+ my $module_pkgs = $do_pkgs->check_kernel_module_packages($pkg) or
+ log::l("$pkg available, but no kernel module package (for installed kernels, and no dkms)"), return;
+
+ ($pkg, @$module_pkgs);
+}
+
+sub may_use_Driver2 {
+ my ($card) = @_;
+
+ my $modules_dir = Xconfig::card::modules_dir();
+ #- make sure everything is correct at this point, packages have really been installed
+ #- and driver and GLX extension is present.
+
+ my $check_drv = sub {
+ my ($drv, $o_subdir) = @_;
+ my @l = (if_($o_subdir, "$modules_dir/drivers/$o_subdir/$drv.so"),
+ "$modules_dir/drivers/$drv.so",
+ "$modules_dir/drivers/$drv.o");
+ my $has = find { -e "$::prefix$_" } @l;
+ $has or log::l("proprietary $drv driver missing, defaulting to free software driver (we searched for: @l)");
+ $has;
+ };
+
+ my $card2 = {
+ %$card,
+ $card->{Driver2} =~ /^nvidia(.*)/ ?
+ (Driver => 'nvidia', DriverVersion => $1) :
+ (Driver => $card->{Driver2}),
+ };
+
+ if ($card2->{Driver} eq 'nvidia') {
+ $check_drv->('nvidia_drv', "nvidia$card2->{DriverVersion}") or return;
+
+ my $libglx_path = Xconfig::card::modules_dir() . "/extensions/nvidia$card2->{DriverVersion}";
+ -e "$::prefix$libglx_path/libglx.so" or log::l("special NVIDIA libglx missing, defaulting to free software driver"), return;
+
+ log::explanations("Using specific NVIDIA driver and GLX extensions");
+ $card2->{DRI_GLX_SPECIAL} = $libglx_path;
+ $card2->{Options}{IgnoreEDID} = 1 if $card2->{DriverVersion} ne '97xx';
+ $card2;
+ } elsif ($card2->{Driver} eq 'fglrx') {
+ $check_drv->('fglrx_drv') or return;
+ -e "$::prefix$modules_dir/dri/fglrx_dri.so" || -e "$::prefix/usr/$lib/dri/fglrx_dri.so" or
+ log::l("proprietary fglrx_dri.so missing, defaulting to free software driver"), return;
+
+ log::explanations("Using specific ATI fglrx and DRI drivers");
+ $card2->{DRI_GLX} = 1;
+ $card2;
+ } else {
+ undef;
+ }
+}
+
1;
diff --git a/lib/Xconfig/resolution_and_depth.pm b/lib/Xconfig/resolution_and_depth.pm
index 2942664..2564980 100644
--- a/lib/Xconfig/resolution_and_depth.pm
+++ b/lib/Xconfig/resolution_and_depth.pm
@@ -34,7 +34,8 @@ my @bios_vga_modes = (
sub from_bios {
my ($bios) = @_;
- find { $_->{bios} == $bios } @bios_vga_modes;
+ my $bios_int = $bios =~ /^0x(.*)/ ? hex($1) : $bios;
+ find { $_->{bios} == $bios_int } @bios_vga_modes;
}
sub bios_vga_modes() { @bios_vga_modes }
@@ -82,7 +83,7 @@ sub allowed {
my @depths;
if ($card->{Driver} eq 'fglrx') {
@depths = 24;
- } elsif ($card->{BoardName} eq 'RIVA128') {
+ } elsif ($card->{BoardName} eq 'NVIDIA RIVA 128') {
@depths = qw(8 15 24);
} elsif ($card->{use_DRI_GLX}) {
$prefered_depth = 16;
@@ -146,6 +147,8 @@ sub choices {
#- sort it, so we can take the first one when we want the "best"
@resolutions = sort { $b->{X} <=> $a->{X} || $b->{Y} <=> $a->{Y} || $b->{Depth} <=> $a->{Depth} } @resolutions;
+ $_->{ratio} ||= resolution2ratio($_) foreach @resolutions;
+
if ($resolution_wanted->{X} && !$resolution_wanted->{Y}) {
#- assuming ratio 4/3
$resolution_wanted->{Y} = round($resolution_wanted->{X} * 3 / 4);
@@ -203,9 +206,7 @@ sub configure {
} else {
$default_resolution = choose($in, $default_resolution, @resolutions) or return;
}
- set_resolution($raw_X, $default_resolution);
-
- $default_resolution;
+ set_resolution($raw_X, $default_resolution, @resolutions);
}
sub configure_auto_install {
@@ -216,18 +217,25 @@ sub configure_auto_install {
{ X => $X, Y => $Y, Depth => $old_X->{default_depth} };
};
- my ($default_resolution) = choices($raw_X, $resolution_wanted, $card, $monitors);
+ my ($default_resolution, @resolutions) = choices($raw_X, $resolution_wanted, $card, $monitors);
$default_resolution or die "you selected an unusable depth";
- set_resolution($raw_X, $default_resolution);
-
- $default_resolution;
+ set_resolution($raw_X, $default_resolution, @resolutions);
}
sub set_resolution {
- my ($raw_X, $resolution) = @_;
- $raw_X->set_resolution($resolution);
+ my ($raw_X, $resolution, @other) = @_;
+
+ my $ratio = resolution2ratio($resolution, 'non-strict');
+ @other = uniq_ { $_->{X} . 'x' . $_->{Y} } @other;
+ @other = grep { $_->{X} < $resolution->{X} } @other;
+ @other = filter_on_ratio($ratio, @other);
+ my $resolutions = [ $resolution, @other ];
+
+ $raw_X->set_resolutions($resolutions);
set_default_background($resolution);
+ set_915resolution($resolution) if is_915resolution_configured();
+ $resolutions;
}
sub set_default_background {
my ($resolution) = @_;
@@ -251,6 +259,21 @@ sub set_default_background {
symlinkf $l[0][0], "$dir/default.png";
}
+sub is_915resolution_configured() {
+ my $f = "$::prefix/etc/sysconfig/915resolution";
+ -e $f && { getVarsFromSh($f) }->{XRESO};
+}
+sub set_915resolution {
+ my ($resolution) = @_;
+
+ my $f = "$::prefix/etc/sysconfig/915resolution";
+ setVarsInSh($f, {
+ MODE => 'best',
+ XRESO => $resolution->{X},
+ YRESO => $resolution->{Y},
+ });
+ run_program::rooted($::prefix, 'service', '915resolution', 'start');
+}
sub resolution2ratio {
my ($resolution, $b_non_strict) = @_;
@@ -258,22 +281,22 @@ sub resolution2ratio {
$res eq '1280x1024' && $b_non_strict ? '4/3' : $Xconfig::xfree::resolution2ratio{$res};
}
+sub filter_on_ratio {
+ my ($ratio, @l) = @_;
+ grep {
+ !$ratio
+ || $_->{ratio} eq $ratio
+ || $ratio eq '4/3' && "$_->{X}x$_->{Y}" eq '1280x1024';
+ } @l;
+}
+
sub choose_gtk {
my ($in, $card, $default_resolution, @resolutions) = @_;
- $_->{ratio} ||= resolution2ratio($_) foreach @resolutions;
-
my $chosen_Depth = $default_resolution->{Depth};
my $chosen_res = { X => $default_resolution->{X} || 1024, Y => $default_resolution->{Y} };
my $chosen_ratio = resolution2ratio($chosen_res, 'non-strict') || '4/3';
- my $filter_on_ratio = sub {
- grep {
- !$chosen_ratio
- || $_->{ratio} eq $chosen_ratio
- || $chosen_ratio eq '4/3' && "$_->{X}x$_->{Y}" eq '1280x1024';
- } @_;
- };
my $filter_on_Depth = sub {
grep { $_->{Depth} == $chosen_Depth } @_;
};
@@ -305,7 +328,7 @@ sub choose_gtk {
my $proposed_resolutions = [];
my $set_proposed_resolutions = sub {
my ($suggested_res) = @_;
- @matching_ratio = $filter_on_ratio->(@resolutions);
+ @matching_ratio = filter_on_ratio($chosen_ratio, @resolutions);
gtkval_modify(\$proposed_resolutions, [
(reverse uniq_ { $res2text->($_) } @matching_ratio),
if_($chosen_ratio, { text => N_("Other") }),
diff --git a/lib/Xconfig/various.pm b/lib/Xconfig/various.pm
index c38205f..dc74fce 100644
--- a/lib/Xconfig/various.pm
+++ b/lib/Xconfig/various.pm
@@ -18,21 +18,18 @@ sub to_string {
sub info {
my ($raw_X, $card) = @_;
my $info;
- my $xf_ver = Xconfig::card::xorg_version();
- my $title = $card->{use_DRI_GLX} ? N("Xorg %s with 3D hardware acceleration", $xf_ver) :
- N("Xorg %s", $xf_ver);
my $keyboard = eval { $raw_X->get_keyboard } || {};
my @monitors = eval { $raw_X->get_monitors };
my $device = eval { $raw_X->get_device } || {};
my $mouse = eval { first($raw_X->get_mice) } || {};
+ $info .= N("3D hardware acceleration: %s\n", translate(bool2yesno($card->{use_DRI_GLX})));
$info .= N("Keyboard layout: %s\n", $keyboard->{XkbLayout});
$info .= N("Mouse type: %s\n", $mouse->{Protocol});
- $info .= N("Mouse device: %s\n", $mouse->{Device}) if $::expert;
foreach my $monitor (@monitors) {
$info .= N("Monitor: %s\n", $monitor->{ModelName});
- $info .= N("Monitor HorizSync: %s\n", $monitor->{HorizSync}) if $::expert;
- $info .= N("Monitor VertRefresh: %s\n", $monitor->{VertRefresh}) if $::expert;
+ $info .= N("Monitor HorizSync: %s\n", $monitor->{HorizSync});
+ $info .= N("Monitor VertRefresh: %s\n", $monitor->{VertRefresh});
}
$info .= N("Graphics card: %s\n", $device->{VendorName} . ' ' . $device->{BoardName});
$info .= N("Graphics memory: %s kB\n", $device->{VideoRam}) if $device->{VideoRam};
@@ -41,17 +38,155 @@ sub info {
$info .= N("Resolution: %s\n", join('x', @$resolution{'X', 'Y'}));
}
$info .= N("Xorg driver: %s\n", $device->{Driver}) if $device->{Driver};
- "$title\n\n$info";
+ $info;
+}
+
+sub default {
+ my ($card, $various) = @_;
+
+ my $isLaptop = detect_devices::isLaptop();
+
+ add2hash_($various, {
+ isLaptop => $isLaptop,
+ xdm => 1,
+ Composite => !($card->{Driver} eq 'fglrx' || $card->{Driver} eq 'nvidia' && $card->{DriverVersion} eq '71xx'),
+ if_($card->{Driver} eq 'nvidia', RenderAccel => $card->{DriverVersion} eq '97xx', Clone => 0),
+ if_($card->{Driver} eq 'savage', HWCursor => 1),
+ if_($card->{Driver} eq 'i810' && $isLaptop, Clone => 0),
+ if_($card->{Driver} eq 'ati' && $isLaptop, Clone => 1, BIOSHotkeys => 0),
+ if_(exists $card->{DRI_GLX}, use_DRI_GLX => $card->{DRI_GLX} && !$card->{Xinerama}),
+ if_(member($card->{Driver}, qw(i128 ati sis trident via savage)), EXA => 0), #- list taken from http://wiki.x.org/wiki/ExaStatus
+ });
}
sub various {
- my ($in, $card, $options, $b_auto) = @_;
+ my ($in, $raw_X, $card, $options, $b_auto, $b_read_existing) = @_;
tvout($in, $card, $options) if !$b_auto;
- choose_xdm($in, $b_auto);
+
+ my $use_DRI_GLX = member('dri', $raw_X->get_modules);
+
+ my $various = {
+ if_($::isStandalone, xdm => runlevel() == 5),
+ if_($b_read_existing,
+ Composite => ($raw_X->get_Section('Extensions') || {})->{Composite},
+ if_(($card->{Options}{MonitorLayout} || [])->[0] eq '"NONE,CRT+LFP"' ||
+ ($card->{Options}{TwinViewOrientation} || [])->[0] eq '"Clone"',
+ Clone => 1),
+ if_(($card->{Options}{MonitorLayout} || [])->[0] eq '"LVDS,NONE"',
+ Clone => 0),
+ if_($card->{Options}{BIOSHotkeys},
+ BIOSHotkeys => 1),
+ if_($card->{Options}{AccelMethod},
+ EXA => ($card->{Options}{AccelMethod} || [])->[0] eq '"EXA"'),
+ if_($card->{Driver} eq 'nvidia',
+ RenderAccel => !$card->{Options}{RenderAccel},
+ ),
+ HWCursor => !$card->{Options}{SWCursor},
+ if_($card->{DRI_GLX} || $use_DRI_GLX, use_DRI_GLX => $use_DRI_GLX),
+ ),
+ };
+ default($card, $various);
+
+ if (!$b_auto) {
+ choose($in, $various) or return;
+ }
+
+ config($raw_X, $card, $various) && $various;
+}
+
+sub various_auto_install {
+ my ($raw_X, $card, $old_X) = @_;
+
+ my $various = { %$old_X };
+ default($card, $various);
+ config($raw_X, $card, $various);
1;
}
+sub config {
+ my ($raw_X, $card, $various) = @_;
+
+ if ($various->{Composite}) {
+ my $raw = $raw_X->get_Section('Extensions') || $raw_X->add_Section('Extensions', {});
+ $raw->{Composite} = { 'Option' => 1 };
+ if ($card->{Driver} eq 'nvidia') {
+ $card->{Options}{AddARGBGLXVisuals} = undef;
+ }
+ } else {
+ if (my $raw = $raw_X->get_Section('Extensions')) {
+ delete $raw->{Composite};
+ %$raw or $raw_X->remove_Section('Extensions');
+ }
+ if ($card->{Driver} eq 'nvidia') {
+ delete $card->{Options}{AddARGBGLXVisuals};
+ }
+ }
+ if (exists $various->{use_DRI_GLX}) {
+ $card->{use_DRI_GLX} = $various->{use_DRI_GLX};
+ }
+
+ if (exists $various->{RenderAccel}) {
+ if ($various->{RenderAccel}) {
+ delete $card->{Options}{RenderAccel};
+ } else {
+ $card->{Options}{RenderAccel} = 'false';
+ }
+ }
+
+ if (exists $various->{HWCursor}) {
+ if ($various->{HWCursor}) {
+ delete $card->{Options}{SWCursor};
+ } else {
+ $card->{Options}{SWCursor} = undef;
+ }
+ }
+
+ if (exists $various->{BIOSHotkeys}) {
+ if ($various->{BIOSHotkeys}) {
+ $card->{Options}{BIOSHotkeys} = undef;
+ } else {
+ delete $card->{Options}{BIOSHotkeys};
+ }
+ }
+
+ if (exists $various->{EXA}) {
+ if ($various->{EXA}) {
+ $card->{Options}{AccelMethod} = 'EXA';
+ } else {
+ delete $card->{Options}{AccelMethod};
+ }
+ }
+
+ if (exists $various->{Clone}) {
+ if ($card->{Driver} eq 'nvidia') {
+ if ($various->{Clone}) {
+ $card->{Options}{TwinView} = undef;
+ $card->{Options}{TwinViewOrientation} = 'Clone';
+ } else {
+ delete $card->{Options}{TwinView};
+ delete $card->{Options}{TwinViewOrientation};
+ }
+ } elsif ($card->{Driver} eq 'i810') {
+ if ($various->{Clone}) {
+ $card->{Options}{MonitorLayout} = 'NONE,CRT+LFP';
+ } else {
+ delete $card->{Options}{MonitorLayout};
+ }
+ } elsif ($card->{Driver} eq 'ati') {
+ if ($various->{Clone}) {
+ #- the default is Clone
+ delete $card->{Options}{MonitorLayout};
+ } else {
+ #- forcing no display on CRT
+ $card->{Options}{MonitorLayout} = 'LVDS,NONE';
+ }
+ }
+ }
+
+ Xconfig::various::runlevel($various->{xdm} ? 5 : 3);
+}
+
sub runlevel {
my ($o_runlevel) = @_;
my $f = "$::prefix/etc/inittab";
@@ -63,20 +198,39 @@ sub runlevel {
}
}
-sub choose_xdm {
- my ($in, $b_auto) = @_;
- my $xdm = $::isStandalone ? runlevel() == 5 : 1;
+sub choose {
+ my ($in, $various) = @_;
+
+ $in->ask_from_({ title => N("Xorg configuration") }, [
+ { label => N("Graphic card options"), title => 1 },
+ exists $various->{use_DRI_GLX} ?
+ { text => N("3D hardware acceleration"),
+ type => 'bool', val => \$various->{use_DRI_GLX} } : (),
+ { text => N("Enable Translucency (Composite extension)"),
+ type => 'bool', val => \$various->{Composite} },
+ exists $various->{HWCursor} ?
+ { text => N("Use hardware accelerated mouse pointer"),
+ type => 'bool', val => \$various->{HWCursor} } : (),
+ exists $various->{RenderAccel} ?
+ { text => N("Enable RENDER Acceleration (this may cause bugs displaying text)"),
+ type => 'bool', val => \$various->{RenderAccel} } : (),
+ exists $various->{Clone} ?
+ { text => $various->{isLaptop} ?
+ N("Enable duplicate display on the external monitor") :
+ N("Enable duplicate display on the second display"),
+ type => 'bool', val => \$various->{Clone} } : (),
+ exists $various->{BIOSHotkeys} ?
+ { text => N("Enable BIOS hotkey for external monitor switching"),
+ type => 'bool', val => \$various->{BIOSHotkeys} } : (),
+ exists $various->{EXA} ?
+ { text => N("Use EXA instead of XAA (better performance for Render and Composite)"),
+ type => 'bool', val => \$various->{EXA} } : (),
+ { label => N("Graphical interface at startup"), title => 1 },
+ { text => N("Automatically start the graphical interface (Xorg) upon booting"),
+ type => 'bool', val => \$various->{xdm} },
+ ]) or return;
- if (!$b_auto) {
- $xdm = $in->ask_yesorno_({
- title => N("Graphical interface at startup"),
- messages =>
-N("I can setup your computer to automatically start the graphical interface (Xorg) upon booting.
-Would you like Xorg to start when you reboot?"),
- interactive_help_id => 'configureXxdm',
- }, $xdm);
- }
- runlevel($xdm ? 5 : 3);
+ 1;
}
sub tvout {
@@ -171,8 +325,36 @@ sub setupFB {
$_->{vga} = $bios_vga_mode if $_->{vga}; #- replace existing vga= with
}
+ bootloader::update_splash($bootloader);
bootloader::action($bootloader, 'write', $all_hds);
bootloader::action($bootloader, 'when_config_changed');
}
+sub handle_May_Need_ForceBIOS {
+ my ($in, $raw_X) = @_;
+
+ Xconfig::resolution_and_depth::is_915resolution_configured and return;
+
+ any { $_->{Options}{May_Need_ForceBIOS} } $raw_X->get_devices or return;
+
+ my $log = cat_('/var/log/Xorg.0.log');
+ $log =~ /Option "May_Need_ForceBIOS" is not used/ or return;
+
+
+ my @builtin_modes = $log =~ /\*Built-in mode "(\d+x\d+)"/g;
+ my $resolution = $raw_X->get_resolution;
+ !member("$resolution->{X}x$resolution->{Y}", @builtin_modes) or return;
+
+ $in->ask_yesorno('', formatAlaTeX(N("The display resolution being used may not be correct.
+
+If your desktop appears to stretch beyond the edges of the display,
+installing %s may help fix the problem. Install it now?", '915resolution')), 1) or return;
+
+ $in->do_pkgs->ensure_binary_is_installed('915resolution', '915resolution', 1) or return;
+
+ Xconfig::resolution_and_depth::set_915resolution($resolution);
+
+ 'need_restart';
+}
+
1;
diff --git a/lib/Xconfig/xfree.pm b/lib/Xconfig/xfree.pm
index 5cba3ee..1e5eaaa 100644
--- a/lib/Xconfig/xfree.pm
+++ b/lib/Xconfig/xfree.pm
@@ -1,5 +1,7 @@
package Xconfig::xfree; # $Id$
+my ($Revision) = '$Revision$' =~ /(\d+)/;
+
use diagnostics;
use strict;
@@ -8,8 +10,8 @@ use Xconfig::parse;
#- mostly internal only
sub new {
- my ($class, $val) = @_;
- bless $val, $class;
+ my ($class, $raw) = @_;
+ @$raw && bless { raw => $raw }, $class;
}
sub _conf_files() {
@@ -22,11 +24,14 @@ sub _conf_files() {
sub read_and_prepare_write {
my ($class) = @_;
my $file = find { -f $_ } _conf_files();
- my $raw_X = $class->new(Xconfig::parse::read_XF86Config($file));
+ my $raw_X = $class->new(Xconfig::parse::read_XF86Config($file)) or return;
my $before = $raw_X->prepare_write;
- if (my ($Keyboard) = $raw_X->get_InputDevices('Keyboard')) {
- $Keyboard->{Driver}{val} = 'keyboard';
+ if (my ($keyboard) = $raw_X->get_InputDevices('keyboard')) {
+ $keyboard->{Driver}{val} = 'kbd';
+ }
+ if (my ($keyboard) = $raw_X->get_InputDevices('Keyboard')) {
+ $keyboard->{Driver}{val} = 'kbd';
}
#- ugly hack to fix empty ModeLine lines, XFdrake seems to generate some, but where???
@@ -56,35 +61,60 @@ sub write {
#- keep it for old programs still using this name
symlink basename($file), "$::prefix/etc/X11/XF86Config";
}
- Xconfig::parse::write_XF86Config($raw_X, $file);
+ set_Revision($raw_X);
+ Xconfig::parse::write_XF86Config($raw_X->{raw}, $file);
}
sub prepare_write {
my ($raw_X) = @_;
- join('', Xconfig::parse::prepare_write_XF86Config($raw_X));
+ set_Revision($raw_X);
+ join('', Xconfig::parse::prepare_write_XF86Config($raw_X->{raw}));
}
sub empty_config {
my ($class) = @_;
$class->new(Xconfig::parse::read_XF86Config_from_string(our $default_header));
}
+my $mark = '# File generated by XFdrake';
+sub get_Revision {
+ my ($raw_X) = @_;
+ my $first = $raw_X->{raw}[0];
+ $first->{pre_comment} =~ /^\Q$mark\E \(rev (\d+)\)/ && $1;
+}
+sub set_Revision {
+ my ($raw_X) = @_;
+ my $first = $raw_X->{raw}[0];
+ my $first_comment = $first->{pre_comment};
+
+ my $was_there = $first_comment =~ s/^\Q$mark\E.*\n//;
+ $first->{pre_comment} = "$mark (rev $Revision)\n" . ($was_there ? '' : "\n") . $first_comment;
+}
+
################################################################################
# keyboard #####################################################################
################################################################################
my @keyboard_fields = qw(XkbLayout XkbModel XkbDisable XkbOptions XkbCompat);
sub get_keyboard {
my ($raw_X) = @_;
- my $raw_kbd = first(map { $raw_X->get_InputDevices($_) } 'keyboard', 'kbd') or die "no keyboard section";
+ my $raw_kbd = _raw_get_keyboard($raw_X) or die "no keyboard section";
raw_export_section($raw_kbd, \@keyboard_fields);
}
sub set_keyboard {
my ($raw_X, $kbd) = @_;
- my $raw_kbd = first(map { $raw_X->get_InputDevices($_) } 'keyboard', 'kbd') || _new_keyboard_section($raw_X);
+ my $raw_kbd = _raw_get_keyboard($raw_X) || _new_keyboard_section($raw_X);
raw_import_section($raw_kbd, $kbd);
_set_Option('keyboard', $raw_kbd, keys %$kbd);
}
+sub _raw_get_keyboard {
+ my ($raw_X) = @_;
+ first($raw_X->get_Sections('InputDevice', sub {
+ my ($entry) = @_;
+ my $Driver = val($entry->{Driver});
+ $Driver eq 'kbd' || $Driver eq 'evdev' && val($entry->{XkbLayout});
+ }));
+}
sub _new_keyboard_section {
my ($raw_X) = @_;
- my $raw_kbd = { Identifier => { val => 'Keyboard1' }, Driver => { val => 'keyboard' } };
+ my $raw_kbd = { Identifier => { val => 'Keyboard1' }, Driver => { val => 'kbd' } };
$raw_X->add_Section('InputDevice', $raw_kbd);
my $layout = get_ServerLayout($raw_X)->{InputDevice} ||= [];
@@ -97,38 +127,44 @@ sub _new_keyboard_section {
################################################################################
# mouse ########################################################################
################################################################################
-#- example: { Protocol => 'IMPS/2', Device => '/dev/psaux', Emulate3Buttons => undef, Emulate3Timeout => 50, ZAxisMapping => [ '4 5', '6 7' ] }
-my @mouse_fields = qw(Protocol Device ZAxisMapping Emulate3Buttons Emulate3Timeout); #-);
+#- example mouse: { Protocol => 'IMPS/2', Device => '/dev/psaux', Emulate3Buttons => undef, Emulate3Timeout => 50, ZAxisMapping => [ '4 5', '6 7' ] }
+#- example evdev: { vendor => '0x045e', product => '0x008c' }
+my @mouse_fields = qw(Protocol Device ZAxisMapping Emulate3Buttons Emulate3Timeout vendor product); #-);
sub get_mice {
my ($raw_X) = @_;
- my @raw_mice = $raw_X->get_InputDevices('mouse');
+ my @raw_mice = $raw_X->get_Sections('InputDevice', \&_is_mouse);
map { raw_export_section($_, \@mouse_fields) } @raw_mice;
}
sub set_mice {
my ($raw_X, @mice) = @_;
- my @raw_mice = _new_mouse_sections($raw_X, int @mice);
+ my @raw_mice = _new_mouse_sections($raw_X, map { $_->{Protocol} ? 'mouse' : 'evdev' } @mice);
mapn {
my ($raw_mouse, $mouse) = @_;
raw_import_section($raw_mouse, $mouse);
_set_Option('mouse', $raw_mouse, keys %$mouse);
} \@raw_mice, \@mice;
}
+sub _is_mouse {
+ my ($entry) = @_;
+ my $Driver = val($entry->{Driver});
+ $Driver eq 'mouse' || $Driver eq 'evdev' && !val($entry->{XkbLayout});
+}
sub _new_mouse_sections {
- my ($raw_X, $nb_new) = @_;
- $raw_X->remove_InputDevices('mouse');
+ my ($raw_X, @Drivers) = @_;
+ $raw_X->remove_Section('InputDevice', \&_is_mouse);
my $layout = get_ServerLayout($raw_X)->{InputDevice} ||= [];
@$layout = grep { $_->{val} !~ /^"Mouse/ } @$layout;
- $nb_new or return;
+ @Drivers or return;
- my @l = map {
- my $h = { Identifier => { val => "Mouse$_" }, Driver => { val => 'mouse' } };
+ my @l = map_index {
+ my $h = { Identifier => { val => 'Mouse' . ($::i + 1) }, Driver => { val => $_ } };
$raw_X->add_Section('InputDevice', $h);
- } (1 .. $nb_new);
+ } @Drivers;
push @$layout, { val => qq("Mouse1" "CorePointer") };
- push @$layout, { val => qq("Mouse$_" "SendCoreEvents") } foreach 2 .. $nb_new;
+ push @$layout, { val => qq("Mouse$_" "SendCoreEvents") } foreach 2 .. @Drivers;
@l;
}
@@ -139,30 +175,40 @@ sub _new_mouse_sections {
################################################################################
sub get_resolution {
my ($raw_X, $o_Screen) = @_;
+ first(get_resolutions($raw_X, $o_Screen));
+}
+sub get_resolutions {
+ my ($raw_X, $o_Screen) = @_;
my $Screen = $o_Screen || $raw_X->get_default_screen or return {};
my $depth = val($Screen->{DefaultColorDepth} || $Screen->{DefaultDepth});
my $Display = find { !$depth || val($_->{l}{Depth}) eq $depth } @{$Screen->{Display} || []} or return {};
- $Display->{l}{Virtual} && val($Display->{l}{Virtual}) =~ /(\d+)\s+(\d+)/ or
- val($Display->{l}{Modes}) =~ /(\d+)x(\d+)/ or return {};
- { X => $1, Y => $2, Depth => val($Display->{l}{Depth}) };
+ my $s = val($Display->{l}{Virtual} || $Display->{l}{Modes});
+ my @l;
+ while ($s =~ /(\d+)(x|\s+)(\d+)/g) {
+ push @l, { X => $1, Y => $3, Depth => val($Display->{l}{Depth}) };
+ }
+ @l;
}
-sub set_resolution {
- my ($raw_X, $resolution, $o_Screen_) = @_;
+sub set_resolutions {
+ my ($raw_X, $resolutions, $o_Screen) = @_;
- foreach my $Screen ($o_Screen_ ? $o_Screen_ : $raw_X->get_Sections('Screen')) {
+ foreach my $Screen ($o_Screen ? $o_Screen : $raw_X->get_Sections('Screen')) {
$Screen ||= $raw_X->get_default_screen or internal_error('no screen');
- my $Mode_name = (any { $_->{l}{Modes} } @{$Screen->{Display} || []}) ? 'Modes' : 'Virtual';
- my $Mode = sprintf($Mode_name eq 'Modes' ? '"%dx%d"' : '%d %d', @$resolution{'X', 'Y'});
+ #- if the existing config is using Virtual, keep Virtual, otherwise default to Modes
+ my $Mode_name = (any { $_->{l}{Virtual} } @{$Screen->{Display} || []}) ? 'Virtual' : 'Modes';
+
+ my @l = $Mode_name eq 'Modes' ? @$resolutions : first(@$resolutions);
+ my @Modes = map { sprintf($Mode_name eq 'Modes' ? '"%dx%d"' : '%d %d', @$_{'X', 'Y'}) } @l;
delete $Screen->{DefaultDepth};
- $Screen->{DefaultColorDepth} = { val => $resolution->{Depth} eq '32' ? 24 : $resolution->{Depth} };
+ $Screen->{DefaultColorDepth} = { val => $resolutions->[0]{Depth} eq '32' ? 24 : $resolutions->[0]{Depth} };
$Screen->{Display} = [ map {
- { l => { Depth => { val => $_ }, $Mode_name => { val => $Mode } } };
+ { l => { Depth => { val => $_ }, $Mode_name => { val => join(' ', @Modes) } } };
} 8, 15, 16, 24 ];
}
- add_gtf_ModeLines($raw_X, $resolution);
+ add_gtf_ModeLines($raw_X, $resolutions);
}
@@ -250,7 +296,6 @@ sub set_synaptics {
@$layout = grep { $_->{val} !~ /^"SynapticsMouse/ } @$layout;
@synaptics or return;
- add_load_module($raw_X, "synaptics");
each_index {
my $synaptics_mouse = $_;
@@ -261,9 +306,7 @@ sub set_synaptics {
Driver => { val => "synaptics" },
};
my %opts = (
- Device => $synaptics_mouse->{Device},
- Protocol => $synaptics_mouse->{Protocol},
- $synaptics_mouse->{ALPS} ? (
+ if_($synaptics_mouse->{ALPS},
#- from /usr/share/doc/synaptics-0.14.0/README.alps
#- and http://qa.mandrakesoft.com/show_bug.cgi?id=14512
LeftEdge => 120,
@@ -272,9 +315,7 @@ sub set_synaptics {
BottomEdge => 650,
FingerLow => 14,
FingerHigh => 15,
- MaxTapTime => 180,
MaxTapMove => 110,
- EmulateMidButtonTime => 75,
VertScrollDelta => 20,
HorizScrollDelta => 20,
MinSpeed => '0.8',
@@ -284,24 +325,9 @@ sub set_synaptics {
EdgeMotionMaxSpeed => 200,
UpDownScrolling => 1,
CircularScrolling => 1,
- CircScrollDelta => '0.1',
CircScrollTrigger => 2,
UpDownScrolling => 0,
- ) : (
- #- from /usr/share/doc/synaptics-0.14.0/INSTALL
- LeftEdge => 1700,
- RightEdge => 5300,
- TopEdge => 1700,
- BottomEdge => 4200,
- FingerLow => 25,
- FingerHigh => 30,
- MaxTapTime => 180,
- MaxTapMove => 220,
- VertScrollDelta => 100,
- MinSpeed => '0.09',
- MaxSpeed => '0.18',
- AccelFactor => '0.0015',
- ),
+ ), #- use default driver options for non-ALPS
SHMConfig => "on",
);
while (my ($k, $v) = each %opts) {
@@ -356,21 +382,24 @@ sub default_ModeLine() {
}
sub add_gtf_ModeLines {
- my ($raw_X, $resolution) = @_;
+ my ($raw_X, $resolutions) = @_;
my $banner = 'modeline generated by gtf(1) [handled by XFdrake]';
- my $res = $resolution->{X} . 'x' . $resolution->{Y};
+ my $res = $resolutions->[0]{X} . 'x' . $resolutions->[0]{Y};
my @to_add;
if ($res ne '1280x1024' &&
($res eq '1400x1050' || $res eq '1152x864' || $Xconfig::xfree::resolution2ratio{$res} ne '4/3')) {
- @to_add = map {
+ @to_add = map {
+ my $resolution = $_;
+ map {
my $s = run_program::rooted_get_stdout($::prefix, 'gtf', $resolution->{X}, $resolution->{Y}, $_);
if (my ($name, $val) = $s =~ /ModeLine\s*"(.*)"(.*)/i) {
chomp $val;
$name =~ s/\.00//; #- nicer that way
{ val => qq("${name}"$val), pre_comment => "# $banner\n" };
} else { () }
- } reverse(sort_numbers(@Xconfig::xfree::vfreqs));
+ } reverse(sort_numbers(@Xconfig::xfree::vfreqs));
+ } @$resolutions;
}
$raw_X->set_monitors(map {
@@ -465,6 +494,28 @@ sub set_load_module {
}
+################################################################################
+# ModulePath ###################################################################
+################################################################################
+sub get_ModulePaths {
+ my ($raw_X) = @_;
+ my $raw_Files = $raw_X->get_Section('Files') or return;
+ my $Files = raw_export_section($raw_Files, ['ModulePath']);
+ @{$Files->{ModulePath} || []};
+}
+sub add_ModulePath {
+ my ($raw_X, $ModulePath) = @_;
+ my $raw_Files = $raw_X->get_Section('Files') || $raw_X->add_Section('Files', {});
+
+ push @{$raw_Files->{ModulePath}}, { val => $ModulePath } if !member($ModulePath, $raw_X->get_ModulePaths);
+}
+sub remove_ModulePath {
+ my ($raw_X, $ModulePath) = @_;
+ my $raw_Files = $raw_X->get_Section('Files') or return;
+ my @l = grep { $_->{val} ne $ModulePath && $_->{val} ne "$ModulePath/" } @{$raw_Files->{ModulePath}};
+ $raw_Files->{ModulePath} = \@l;
+}
+
#-##############################################################################
#- helpers
#-##############################################################################
@@ -483,7 +534,7 @@ sub get_InputDevices {
}
sub remove_InputDevices {
my ($raw_X, $Driver) = @_;
- $raw_X->remove_Section('InputDevice', sub { val($_[0]{Driver}) ne $Driver });
+ $raw_X->remove_Section('InputDevice', sub { val($_[0]{Driver}) eq $Driver });
}
sub get_ServerLayout {
@@ -524,23 +575,25 @@ sub add_Section {
my %order = map_index { { lc($_) => $::i } } @suggested_ordering;
my $e = { name => $Section, l => $h };
my $added;
- @$raw_X = map {
+ my $raw = $raw_X->{raw};
+ @$raw = map {
if ($order{lc $_->{name}} > $order{lc $Section} && !$added) {
$added = 1;
($e, $_);
} else { $_ }
- } @$raw_X;
- push @$raw_X, $e if !$added;
+ } @$raw;
+ push @$raw, $e if !$added;
$h;
}
sub remove_Section {
my ($raw_X, $Section, $o_when) = @_;
- @$raw_X = grep { $_->{name} ne $Section || $o_when && $o_when->($_->{l}) } @$raw_X;
+ my $raw = $raw_X->{raw};
+ @$raw = grep { $_->{name} ne $Section || $o_when && !$o_when->($_->{l}) } @$raw;
$raw_X;
}
sub get_Sections {
my ($raw_X, $Section, $o_when) = @_;
- map { if_(lc($_->{name}) eq lc($Section) && (!$o_when || $o_when->($_->{l})), $_->{l}) } @$raw_X;
+ map { if_(lc($_->{name}) eq lc($Section) && (!$o_when || $o_when->($_->{l})), $_->{l}) } @{$raw_X->{raw}};
}
sub get_Section {
my ($raw_X, $Section, $o_when) = @_;
@@ -564,7 +617,7 @@ sub val {
sub ModeLine_from_string {
my ($s) = @_;
my $raw_X_for_ModeLine = Xconfig::parse::read_XF86Config_from_string($s);
- get_Section($raw_X_for_ModeLine, 'Monitor')->{ModeLine};
+ get_Section(Xconfig::xfree->new($raw_X_for_ModeLine), 'Monitor')->{ModeLine};
}
@@ -591,7 +644,7 @@ our %ratio2resolutions = (
# 1.25
'5/4' => [ qw(640x512 720x576 1280x1024 1800x1440) ],
- # SXGA=1280x1024 QSXGA=2560x2048
+ # SXGA=1280x1024 QSXGA=2560x2048, HSXGA=5120x4096
# 1.33
'4/3' => [
@@ -599,21 +652,24 @@ our %ratio2resolutions = (
1024x768 1152x864 1280x960 1400x1050
1600x1200 1920x1440 2048x1536), # 768x576 1792x1344 1856x1392
# DBLSCAN: 400x300 416x312 512x384 576x432 700x525 896x672 928x696 960x720
- ], # VGA=640x480, SVGA=800x600, XGA=1024x768, SXGA+=1400x1050, UXGA=1600x1200, QXGA=2048x1536 QSXGA+=2800x2100, QUXGA=3200x2400
+ ], # VGA=640x480, SVGA=800x600, XGA=1024x768, SXGA+=1400x1050,
+ # UXGA=1600x1200, QXGA=2048x1536 QSXGA+=2800x2100, QUXGA=3200x2400,
+ # HUXGA=6400x4800
# 1.5
'3/2' => [ qw(360x240 720x480 1152x768) ], # 576x384 (DBLSCAN of 1152x768)
# 1.6
- '16/10' => [ qw(1280x800 1440x900 1600x1000 1680x1050 1920x1200) ], # 320x200 640x400 960x600 2560x1600
- # WSXGA+=1680x1050, WUXGA=1920x1200, WQUXGA=3840x2400
+ '16/10' => [ qw(1280x800 1440x900 1600x1000 1680x1050 1920x1200 2560x1600) ], # 320x200 640x400 960x600 3840x2400
+ # WSXGA+=1680x1050, WUXGA=1920x1200, WQXGA=2560x1600, WQUXGA=3840x2400, WHUXGA=7680x4800
# 1.67
'15/9' => [ qw(1280x768) ], # 800x480
# WXGA=1280x768 or ??? (should be 1366x768)
# 1.78
- '16/9' => [ qw(1280x720 1600x900 1920x1080) ], # 960x540 1024x576
+ '16/9' => [ qw(1280x720 1600x900 1920x1080) ], # 960x540 1024x576 1360x765
+ # UHDTV=7680x4320
# now more weird things
@@ -628,7 +684,8 @@ our %ratio2resolutions = (
# '17/12' => [ qw(544x384) ] ,
# 1.56
- # '25/16' => [ qw(1600x1024) ], # WSXGA, (DBLSCAN 800x512)
+ # '25/16' => [ qw(1600x1024 3200x2048 6400x4096) ], # (DBLSCAN 800x512)
+ # WSXGA=1600x1024, WQSXGA=3200x2048, WHSXGA=6400x4096
# 1.707
# '128/75' => [ qw(1024x600) ],
@@ -677,18 +734,16 @@ foreach my $ratio (keys %ratio2resolutions) {
}
our $default_header = <<'END';
-# File generated by XFdrake.
-
# **********************************************************************
# Refer to the xorg.conf man page for details about the format of
# this file.
# **********************************************************************
Section "Files"
- # Multiple FontPath entries are allowed (they are concatenated together)
- # By default, Mandrake 6.0 and later now use a font server independent of
- # the X server to render fonts.
+ # font server independent of the X server to render fonts.
FontPath "unix/:-1"
+ # minimal fonts to allow X to run without xfs
+ FontPath "/usr/share/fonts/misc:unscaled"
EndSection
Section "ServerFlags"