summaryrefslogtreecommitdiffstats
path: root/lib/Xconfig/xfree.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Xconfig/xfree.pm')
-rw-r--r--lib/Xconfig/xfree.pm207
1 files changed, 131 insertions, 76 deletions
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"