1 |
package Xconfig::main; # $Id: main.pm 261482 2009-10-06 10:15:34Z cfergeau $ |
2 |
|
3 |
use diagnostics; |
4 |
use strict; |
5 |
|
6 |
use Xconfig::monitor; |
7 |
use Xconfig::card; |
8 |
use Xconfig::plugins; |
9 |
use Xconfig::resolution_and_depth; |
10 |
use Xconfig::various; |
11 |
use Xconfig::screen; |
12 |
use Xconfig::test; |
13 |
use Xconfig::xfree; |
14 |
use common; |
15 |
|
16 |
|
17 |
sub configure_monitor { |
18 |
my ($in) = @_; |
19 |
|
20 |
my $raw_X = Xconfig::xfree->read; |
21 |
Xconfig::monitor::configure($in, $raw_X, int($raw_X->get_devices)) or return; |
22 |
if ($raw_X->is_modified) { |
23 |
$raw_X->write; |
24 |
'need_restart'; |
25 |
} else { |
26 |
''; |
27 |
} |
28 |
} |
29 |
|
30 |
sub configure_resolution { |
31 |
my ($in) = @_; |
32 |
|
33 |
my $raw_X = Xconfig::xfree->read; |
34 |
my $X = { |
35 |
card => Xconfig::card::from_raw_X($raw_X), |
36 |
monitors => [ $raw_X->get_monitors ], |
37 |
}; |
38 |
|
39 |
$X->{resolutions} = Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}) or return; |
40 |
if ($raw_X->is_modified) { |
41 |
&write($raw_X, $X); |
42 |
} else { |
43 |
''; |
44 |
} |
45 |
} |
46 |
|
47 |
|
48 |
sub configure_everything_auto_install { |
49 |
my ($raw_X, $do_pkgs, $old_X, $options) = @_; |
50 |
my $X = {}; |
51 |
$X->{monitors} = Xconfig::monitor::configure_auto_install($raw_X, $old_X) or return; |
52 |
$options->{VideoRam_probed} = $X->{monitors}[0]{VideoRam_probed}; |
53 |
$X->{card} = Xconfig::card::configure_auto_install($raw_X, $do_pkgs, $old_X, $options) or return; |
54 |
Xconfig::screen::configure($raw_X) or return; |
55 |
$X->{resolutions} = Xconfig::resolution_and_depth::configure_auto_install($raw_X, $X->{card}, $X->{monitors}, $old_X); |
56 |
|
57 |
my $action = &write($raw_X, $X, $options->{skip_fb_setup}); |
58 |
|
59 |
$action; |
60 |
} |
61 |
|
62 |
sub configure_everything { |
63 |
my ($in, $raw_X, $do_pkgs, $auto, $options) = @_; |
64 |
my $X = {}; |
65 |
my $ok = 1; |
66 |
|
67 |
my $probed_info = Xconfig::monitor::probe($raw_X->get_Driver); |
68 |
$options->{VideoRam_probed} = $probed_info->{VideoRam_probed}; |
69 |
$ok &&= $X->{card} = Xconfig::card::configure($in, $raw_X, $do_pkgs, $auto, $options); |
70 |
$ok &&= $X->{monitors} = Xconfig::monitor::configure($in, $raw_X, int($raw_X->get_devices), $probed_info, $auto); |
71 |
$ok &&= Xconfig::screen::configure($raw_X); |
72 |
$ok &&= $X->{resolutions} = Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors}, $auto, {}); |
73 |
$ok &&= Xconfig::test::test($in, $raw_X, $X->{card}, '', 'skip_badcard') if !$auto; |
74 |
|
75 |
if (!$ok) { |
76 |
return if $auto; |
77 |
($ok) = configure_chooser_raw($in, $raw_X, $do_pkgs, $options, $X, 1); |
78 |
} |
79 |
may_write($in, $raw_X, $X, $ok); |
80 |
} |
81 |
|
82 |
sub configure_chooser_raw { |
83 |
my ($in, $raw_X, $do_pkgs, $options, $X, $b_modified) = @_; |
84 |
|
85 |
my %texts; |
86 |
|
87 |
my $update_texts = sub { |
88 |
$texts{card} = $X->{card} && $X->{card}{BoardName} || N("Custom"); |
89 |
$texts{monitors} = $X->{monitors} && $X->{monitors}[0]{ModelName} || N("Custom"); |
90 |
$texts{resolutions} = Xconfig::resolution_and_depth::to_string($X->{resolutions}[0]); |
91 |
|
92 |
$texts{$_} =~ s/(.{20}).*/$1.../ foreach keys %texts; #- ensure not too long |
93 |
}; |
94 |
$update_texts->(); |
95 |
|
96 |
my $may_set; |
97 |
my $prompt_for_resolution = sub { |
98 |
$may_set->('resolutions', Xconfig::resolution_and_depth::configure($in, $raw_X, $X->{card}, $X->{monitors})); |
99 |
}; |
100 |
$may_set = sub { |
101 |
my ($field, $val) = @_; |
102 |
if ($val) { |
103 |
$X->{$field} = $val; |
104 |
$X->{"modified_$field"} = 1; |
105 |
$b_modified = 1; |
106 |
$update_texts->(); |
107 |
|
108 |
if (member($field, 'card', 'monitors')) { |
109 |
my ($default_resolution, @other_resolutions) = Xconfig::resolution_and_depth::choices($raw_X, $X->{resolutions}[0], $X->{card}, $X->{monitors}); |
110 |
if (Xconfig::resolution_and_depth::to_string($default_resolution) ne |
111 |
Xconfig::resolution_and_depth::to_string($X->{resolutions}[0])) { |
112 |
$prompt_for_resolution->(); |
113 |
} else { |
114 |
Xconfig::screen::configure($raw_X); |
115 |
$may_set->('resolutions', Xconfig::resolution_and_depth::set_resolution($raw_X, $X->{card}, $X->{monitors}, $default_resolution, @other_resolutions)); |
116 |
} |
117 |
} |
118 |
} |
119 |
}; |
120 |
|
121 |
my $ok; |
122 |
$in->ask_from_({ interactive_help_id => 'configureX_chooser', |
123 |
title => N("Graphic Card & Monitor Configuration"), |
124 |
if_($::isStandalone, ok => N("Quit")) }, |
125 |
[ |
126 |
{ label => N("Graphic Card"), val => \$texts{card}, clicked => sub { |
127 |
$may_set->('card', Xconfig::card::configure($in, $raw_X, $do_pkgs, 0, $options)); |
128 |
} }, |
129 |
{ label => N("_: This is a display device\nMonitor"), val => \$texts{monitors}, clicked => sub { |
130 |
$may_set->('monitors', Xconfig::monitor::configure($in, $raw_X, int($raw_X->get_devices))); |
131 |
} }, |
132 |
{ label => N("Resolution"), val => \$texts{resolutions}, disabled => sub { !$X->{card} || !$X->{monitors} }, |
133 |
clicked => $prompt_for_resolution }, |
134 |
if_(Xconfig::card::check_bad_card($X->{card}) || $::isStandalone, |
135 |
{ val => N("Test"), disabled => sub { !$X->{card} || !$X->{monitors} }, |
136 |
clicked => sub { |
137 |
$ok = Xconfig::test::test($in, $raw_X, $X->{card}, 'auto', 0); |
138 |
} }, |
139 |
), |
140 |
{ val => N("Options"), clicked => sub { |
141 |
Xconfig::various::various($in, $raw_X, $X->{card}, $options, 0, 'read_existing'); |
142 |
Xconfig::card::to_raw_X($X->{card}, $raw_X); |
143 |
} }, |
144 |
if_(Xconfig::plugins::list(), |
145 |
{ val => N("Plugins"), clicked => sub { |
146 |
Xconfig::plugins::choose($in, $raw_X); |
147 |
} }, |
148 |
), |
149 |
]); |
150 |
$ok, $b_modified; |
151 |
} |
152 |
|
153 |
sub configure_chooser { |
154 |
my ($in, $raw_X, $do_pkgs, $options) = @_; |
155 |
|
156 |
my $X = { |
157 |
card => scalar eval { Xconfig::card::from_raw_X($raw_X) }, |
158 |
monitors => [ $raw_X->get_monitors ], |
159 |
resolutions => [ eval { $raw_X->get_resolutions } ], |
160 |
}; |
161 |
my ($ok) = configure_chooser_raw($in, $raw_X, $do_pkgs, $options, $X); |
162 |
|
163 |
if ($raw_X->is_modified) { |
164 |
may_write($in, $raw_X, $X, $ok); |
165 |
} else { |
166 |
''; |
167 |
} |
168 |
} |
169 |
|
170 |
sub configure_everything_or_configure_chooser { |
171 |
my ($in, $options, $auto, $o_keyboard, $o_mouse) = @_; |
172 |
|
173 |
my $raw_X = eval { Xconfig::xfree->read }; |
174 |
my $err = $@ && formatError($@); |
175 |
$err ||= _check_valid($raw_X) if $raw_X; #- that's ok if config is empty |
176 |
if ($err) { |
177 |
log::l("ERROR: bad X config file (error: $err)"); |
178 |
$options->{ignore_bad_conf} or $in->ask_okcancel('', |
179 |
N("Your Xorg configuration file is broken, we will ignore it.")) or return; |
180 |
undef $raw_X; |
181 |
} |
182 |
|
183 |
my $rc = 'ok'; |
184 |
if (!$raw_X) { |
185 |
$raw_X = Xconfig::default::configure($in->do_pkgs, $o_keyboard, $o_mouse); |
186 |
$rc = configure_everything($in, $raw_X, $in->do_pkgs, $auto, $options); |
187 |
} elsif (!$auto) { |
188 |
$rc = configure_chooser($in, $raw_X, $in->do_pkgs, $options); |
189 |
} |
190 |
$rc && $raw_X, $rc; |
191 |
} |
192 |
|
193 |
|
194 |
sub may_write { |
195 |
my ($in, $raw_X, $X, $ok) = @_; |
196 |
|
197 |
$ok ||= $in->ask_yesorno('', N("Keep the changes? |
198 |
The current configuration is: |
199 |
|
200 |
%s", Xconfig::various::info($raw_X, $X->{card})), 1); |
201 |
|
202 |
$ok && &write($raw_X, $X); |
203 |
} |
204 |
|
205 |
sub write { |
206 |
my ($raw_X, $X, $o_skip_fb_setup) = @_; |
207 |
export_to_install_X($X) if $::isInstall; |
208 |
my $only_resolution = $raw_X->is_only_resolution_modified; |
209 |
$raw_X->write; |
210 |
Xconfig::various::check_xorg_conf_symlink(); |
211 |
if ($X->{resolutions}[0]{bios}) { |
212 |
Xconfig::various::setupFB($X->{resolutions}[0]{bios}) if !$o_skip_fb_setup;; |
213 |
'need_reboot'; |
214 |
} elsif (my $resolution = $only_resolution && eval { $raw_X->get_resolution }) { |
215 |
'need_xrandr' . sprintf(' --size %dx%d', @$resolution{'X', 'Y'}); |
216 |
} else { |
217 |
'need_restart'; |
218 |
} |
219 |
} |
220 |
|
221 |
|
222 |
sub export_to_install_X { |
223 |
my ($X) = @_; |
224 |
|
225 |
my $resolution = $X->{resolutions}[0]; |
226 |
$::o->{X}{resolution_wanted} = $resolution->{automatic} ? 'automatic' : $resolution->{X} . 'x' . $resolution->{Y}; |
227 |
$::o->{X}{default_depth} = $resolution->{Depth} if $resolution->{Depth}; |
228 |
$::o->{X}{bios_vga_mode} = $resolution->{bios} if $resolution->{bios}; |
229 |
$::o->{X}{monitors} = $X->{monitors} if $X->{monitors}[0]{manually_chosen} && $X->{monitors}[0]{vendor} ne "Plug'n Play"; |
230 |
$::o->{X}{card} = $X->{card} if $X->{card}{manually_chosen}; |
231 |
$::o->{X}{Xinerama} = 1 if $X->{card}{Xinerama}; |
232 |
} |
233 |
|
234 |
sub _check_valid { |
235 |
my ($raw_X) = @_; |
236 |
|
237 |
my %_sections = map { |
238 |
my @l = $raw_X->get_Sections($_) or return "missing section $_"; |
239 |
$_ => \@l; |
240 |
} qw(Device Screen ServerLayout); |
241 |
|
242 |
''; |
243 |
} |
244 |
|
245 |
1; |