1 |
package Xconfig::various; # $Id: various.pm 269742 2010-06-02 09:25:35Z cfergeau $ |
2 |
|
3 |
use diagnostics; |
4 |
use strict; |
5 |
|
6 |
use Xconfig::card; |
7 |
use Xconfig::default; |
8 |
use Xconfig::resolution_and_depth; |
9 |
use common; |
10 |
|
11 |
|
12 |
sub to_string { |
13 |
my ($raw_X) = @_; |
14 |
|
15 |
$raw_X->is_fbdev ? 'frame-buffer' : Xconfig::resolution_and_depth::to_string($raw_X->get_resolution); |
16 |
} |
17 |
|
18 |
sub info { |
19 |
my ($raw_X, $card) = @_; |
20 |
my $info; |
21 |
my $keyboard = eval { $raw_X->get_keyboard } || {}; |
22 |
my @monitors = eval { $raw_X->get_monitors }; |
23 |
my $device = eval { $raw_X->get_device } || {}; |
24 |
my $mouse = eval { first($raw_X->get_mice) } || {}; |
25 |
|
26 |
$info .= N("Disable Ctrl-Alt-Backspace: %s\n", configure_ServerFlag($raw_X, 'DontZap') eq 'False' ? N("no") : N("yes")); |
27 |
$info .= N("3D hardware acceleration: %s\n", translate(bool2yesno($card->{use_DRI_GLX} || $card->{DRI_GLX_SPECIAL}))); |
28 |
$info .= N("Keyboard layout: %s\n", $keyboard->{XkbLayout}); |
29 |
$info .= N("Mouse type: %s\n", $mouse->{Protocol}); |
30 |
foreach my $monitor (@monitors) { |
31 |
$info .= N("Monitor: %s\n", $monitor->{ModelName}); |
32 |
$info .= N("Monitor HorizSync: %s\n", $monitor->{HorizSync}); |
33 |
$info .= N("Monitor VertRefresh: %s\n", $monitor->{VertRefresh}); |
34 |
} |
35 |
$info .= N("Graphics card: %s\n", $device->{VendorName} . ' ' . $device->{BoardName}); |
36 |
$info .= N("Graphics memory: %s kB\n", $device->{VideoRam}) if $device->{VideoRam}; |
37 |
if (my $resolution = eval { $raw_X->get_resolution }) { |
38 |
$info .= N("Color depth: %s\n", translate($Xconfig::resolution_and_depth::depth2text{$resolution->{Depth}})) if $resolution->{Depth}; |
39 |
$info .= N("Resolution: %s\n", Xconfig::resolution_and_depth::to_string($resolution)); |
40 |
} |
41 |
$info .= N("Xorg driver: %s\n", $device->{Driver}) if $device->{Driver}; |
42 |
$info; |
43 |
} |
44 |
|
45 |
sub default { |
46 |
my ($card, $various) = @_; |
47 |
|
48 |
my $isLaptop = detect_devices::isLaptop(); |
49 |
|
50 |
add2hash_($various, { |
51 |
isLaptop => $isLaptop, |
52 |
xdm => 1, |
53 |
DontZap => 0, |
54 |
Composite => !($card->{Driver} eq 'nvidia' && $card->{DriverVersion} eq '71xx'), |
55 |
if_($card->{Driver} eq 'nvidia', RenderAccel => !member($card->{DriverVersion}, qw(71xx 96xx)), |
56 |
Clone => 0, ForceModeDVI => 0), |
57 |
if_($card->{Driver} eq 'savage', HWCursor => 1), |
58 |
if_($card->{Driver} eq 'intel' && $isLaptop, Clone => 0), |
59 |
if_($card->{Driver} eq 'ati' && $isLaptop, Clone => 1, BIOSHotkeys => 0), |
60 |
if_(exists $card->{DRI_GLX}, use_DRI_GLX => $card->{DRI_GLX} && !$card->{Xinerama}), |
61 |
if_(member($card->{Driver}, qw(i128 ati sis trident via savage)), EXA => 0), #- list taken from http://wiki.x.org/wiki/ExaStatus |
62 |
}); |
63 |
} |
64 |
|
65 |
sub various { |
66 |
my ($in, $raw_X, $card, $options, $b_auto, $b_read_existing) = @_; |
67 |
|
68 |
tvout($in, $card, $options) if !$b_auto; |
69 |
|
70 |
my $use_DRI_GLX = member('dri', $raw_X->get_modules); |
71 |
|
72 |
my $various = { |
73 |
if_($::isStandalone, xdm => runlevel() == 5), |
74 |
if_($b_read_existing, |
75 |
Composite => $raw_X->get_extension('Composite') ne 'Disable', |
76 |
if_($card->{Options}{MonitorLayout} eq 'NONE,CRT+LFP' || |
77 |
$card->{Options}{TwinViewOrientation} eq 'Clone', |
78 |
Clone => 1), |
79 |
if_($card->{Options}{MonitorLayout} eq 'LVDS,NONE', |
80 |
Clone => 0), |
81 |
if_($card->{Options}{BIOSHotkeys}, |
82 |
BIOSHotkeys => 1), |
83 |
if_($card->{Options}{AccelMethod}, |
84 |
EXA => $card->{Options}{AccelMethod} eq 'EXA'), |
85 |
if_($card->{Options}{ModeValidation}, |
86 |
ForceModeDVI => 1), |
87 |
if_($card->{Driver} eq 'nvidia', |
88 |
RenderAccel => !$card->{Options}{RenderAccel}, |
89 |
), |
90 |
HWCursor => !$card->{Options}{SWCursor}, |
91 |
DontZap => (configure_ServerFlag($raw_X, 'DontZap') eq 'False' ? 0 : 1), |
92 |
if_($card->{DRI_GLX} || $use_DRI_GLX, use_DRI_GLX => $use_DRI_GLX), |
93 |
), |
94 |
}; |
95 |
default($card, $various); |
96 |
|
97 |
if (!$b_auto) { |
98 |
choose($in, $various) or return; |
99 |
} |
100 |
|
101 |
config($raw_X, $card, $various) && $various; |
102 |
} |
103 |
|
104 |
sub various_auto_install { |
105 |
my ($raw_X, $card, $old_X) = @_; |
106 |
|
107 |
my $various = { %$old_X }; |
108 |
default($card, $various); |
109 |
config($raw_X, $card, $various); |
110 |
1; |
111 |
} |
112 |
|
113 |
sub config { |
114 |
my ($raw_X, $card, $various) = @_; |
115 |
|
116 |
if (exists $various->{DontZap}) { |
117 |
configure_ServerFlag($raw_X, 'DontZap', $various->{DontZap} eq 1 ? 'True' : 'False'); |
118 |
} |
119 |
if ($various->{Composite}) { |
120 |
$raw_X->remove_extension('Composite'); |
121 |
if ($card->{Driver} eq 'nvidia') { |
122 |
$card->{Options}{AddARGBGLXVisuals} = undef; |
123 |
} |
124 |
} else { |
125 |
$raw_X->set_extension('Composite', 'Disable'); |
126 |
|
127 |
if ($card->{Driver} eq 'nvidia') { |
128 |
delete $card->{Options}{AddARGBGLXVisuals}; |
129 |
} |
130 |
} |
131 |
if (exists $various->{use_DRI_GLX}) { |
132 |
$card->{use_DRI_GLX} = $various->{use_DRI_GLX}; |
133 |
} |
134 |
|
135 |
if (exists $various->{RenderAccel}) { |
136 |
if ($various->{RenderAccel}) { |
137 |
delete $card->{Options}{RenderAccel}; |
138 |
} else { |
139 |
$card->{Options}{RenderAccel} = 'false'; |
140 |
} |
141 |
} |
142 |
|
143 |
if (exists $various->{HWCursor}) { |
144 |
if ($various->{HWCursor}) { |
145 |
delete $card->{Options}{SWCursor}; |
146 |
} else { |
147 |
$card->{Options}{SWCursor} = undef; |
148 |
} |
149 |
} |
150 |
|
151 |
if (exists $various->{BIOSHotkeys}) { |
152 |
if ($various->{BIOSHotkeys}) { |
153 |
$card->{Options}{BIOSHotkeys} = undef; |
154 |
} else { |
155 |
delete $card->{Options}{BIOSHotkeys}; |
156 |
} |
157 |
} |
158 |
|
159 |
if (exists $various->{EXA}) { |
160 |
if ($card->{Driver} eq 'intel') { |
161 |
# the intel driver is able to automatically pick UXA/EXA |
162 |
# when xorg.conf has no accel method defined, but XAA |
163 |
# has to be explicitly selected, that's why the logic |
164 |
# is reversed compared to the other drivers |
165 |
if ($various->{EXA}) { |
166 |
delete $card->{Options}{AccelMethod}; |
167 |
} else { |
168 |
$card->{Options}{AccelMethod} = 'XAA'; |
169 |
} |
170 |
} else { |
171 |
if ($various->{EXA}) { |
172 |
$card->{Options}{AccelMethod} = 'EXA'; |
173 |
} else { |
174 |
delete $card->{Options}{AccelMethod}; |
175 |
} |
176 |
} |
177 |
} |
178 |
|
179 |
if (exists $various->{ForceModeDVI}) { |
180 |
if ($card->{Driver} eq 'nvidia') { |
181 |
if ($various->{ForceModeDVI}) { |
182 |
$card->{Options}{ExactModeTimingsDVI} = undef; |
183 |
$card->{Options}{ModeValidation} = 'NoWidthAlignmentCheck, NoDFPNativeResolutionCheck'; |
184 |
} else { |
185 |
delete $card->{Options}{ExactModeTimingsDVI}; |
186 |
delete $card->{Options}{ModeValidation}; |
187 |
} |
188 |
} |
189 |
} |
190 |
|
191 |
if (exists $various->{Clone}) { |
192 |
if ($card->{Driver} eq 'nvidia') { |
193 |
if ($various->{Clone}) { |
194 |
$card->{Options}{TwinView} = undef; |
195 |
$card->{Options}{TwinViewOrientation} = 'Clone'; |
196 |
delete $card->{Options}{DynamicTwinView}; |
197 |
} else { |
198 |
delete $card->{Options}{TwinView}; |
199 |
delete $card->{Options}{TwinViewOrientation}; |
200 |
#- below disables runtime setting of TwinView via nvidia-settings |
201 |
#- it helps on Compiz (#39171) |
202 |
$card->{Options}{DynamicTwinView} = 'false'; |
203 |
} |
204 |
} elsif ($card->{Driver} eq 'intel') { |
205 |
if ($various->{Clone}) { |
206 |
$card->{Options}{MonitorLayout} = 'NONE,CRT+LFP'; |
207 |
} else { |
208 |
delete $card->{Options}{MonitorLayout}; |
209 |
} |
210 |
} elsif ($card->{Driver} eq 'ati') { |
211 |
if ($various->{Clone}) { |
212 |
#- the default is Clone |
213 |
delete $card->{Options}{MonitorLayout}; |
214 |
} else { |
215 |
#- forcing no display on CRT |
216 |
$card->{Options}{MonitorLayout} = 'LVDS,NONE'; |
217 |
} |
218 |
} |
219 |
} |
220 |
|
221 |
Xconfig::various::runlevel($various->{xdm} ? 5 : 3); |
222 |
} |
223 |
|
224 |
sub runlevel { |
225 |
my ($o_runlevel) = @_; |
226 |
my $f = "$::prefix/etc/inittab"; |
227 |
-r $f or log::l("missing inittab!!!"), return; |
228 |
if ($o_runlevel) { |
229 |
substInFile { s/^id:\d:initdefault:\s*$/id:$o_runlevel:initdefault:\n/ } $f if !$::testing; |
230 |
} else { |
231 |
cat_($f) =~ /^id:(\d):initdefault:\s*$/m && $1; |
232 |
} |
233 |
} |
234 |
|
235 |
sub choose { |
236 |
my ($in, $various) = @_; |
237 |
|
238 |
$in->ask_from_({ title => N("Xorg configuration") }, [ |
239 |
{ label => N("Global options"), title => 1 }, |
240 |
{ text => N("Disable Ctrl-Alt-Backspace"), |
241 |
type => 'bool', val => \$various->{DontZap} }, |
242 |
{ label => N("Graphic card options"), title => 1 }, |
243 |
{ text => N("Enable Translucency (Composite extension)"), |
244 |
type => 'bool', val => \$various->{Composite} }, |
245 |
exists $various->{HWCursor} ? |
246 |
{ text => N("Use hardware accelerated mouse pointer"), |
247 |
type => 'bool', val => \$various->{HWCursor} } : (), |
248 |
exists $various->{RenderAccel} ? |
249 |
{ text => N("Enable RENDER Acceleration (this may cause bugs displaying text)"), |
250 |
type => 'bool', val => \$various->{RenderAccel} } : (), |
251 |
exists $various->{Clone} ? |
252 |
{ text => $various->{isLaptop} ? |
253 |
N("Enable duplicate display on the external monitor") : |
254 |
N("Enable duplicate display on the second display"), |
255 |
type => 'bool', val => \$various->{Clone} } : (), |
256 |
exists $various->{ForceModeDVI} ? |
257 |
{ text => N("Force display mode of DVI"), |
258 |
type => 'bool', val => \$various->{ForceModeDVI} } : (), |
259 |
exists $various->{BIOSHotkeys} ? |
260 |
{ text => N("Enable BIOS hotkey for external monitor switching"), |
261 |
type => 'bool', val => \$various->{BIOSHotkeys} } : (), |
262 |
exists $various->{EXA} ? |
263 |
{ text => N("Use EXA instead of XAA (better performance for Render and Composite)"), |
264 |
type => 'bool', val => \$various->{EXA} } : (), |
265 |
{ label => N("Graphical interface at startup"), title => 1 }, |
266 |
{ text => N("Automatically start the graphical interface (Xorg) upon booting"), |
267 |
type => 'bool', val => \$various->{xdm} }, |
268 |
]) or return; |
269 |
|
270 |
1; |
271 |
} |
272 |
|
273 |
sub tvout { |
274 |
my ($in, $card, $options) = @_; |
275 |
|
276 |
$card->{FB_TVOUT} && $options->{allowFB} or return; |
277 |
|
278 |
$in->ask_yesorno('', N("Your graphic card seems to have a TV-OUT connector. |
279 |
It can be configured to work using frame-buffer. |
280 |
|
281 |
For this you have to plug your graphic card to your TV before booting your computer. |
282 |
Then choose the \"TVout\" entry in the bootloader |
283 |
|
284 |
Do you have this feature?")) or return; |
285 |
|
286 |
#- rough default value (rationale: http://download.nvidia.com/XFree86_40/1.0-2960/README.txt) |
287 |
require timezone; |
288 |
my $norm = timezone::read()->{timezone} =~ /America/ ? 'NTSC' : 'PAL'; |
289 |
|
290 |
$norm = $in->ask_from_list('', N("What norm is your TV using?"), [ 'NTSC', 'PAL' ], $norm) or return; |
291 |
|
292 |
configure_FB_TVOUT($in->do_pkgs, { norm => $norm }); |
293 |
} |
294 |
|
295 |
sub configure_FB_TVOUT { |
296 |
my ($do_pkgs, $use_FB_TVOUT) = @_; |
297 |
|
298 |
my $raw_X = Xconfig::default::configure($do_pkgs); |
299 |
return if is_empty_array_ref($raw_X); |
300 |
|
301 |
$raw_X->set_monitors({ HorizSync => '30-50', VertRefresh => ($use_FB_TVOUT->{norm} eq 'NTSC' ? 60 : 50), |
302 |
ModeLine => [ |
303 |
{ val => '"640x480" 29.50 640 675 678 944 480 530 535 625', pre_comment => "# PAL\n" }, |
304 |
{ val => '"800x600" 36.00 800 818 820 960 600 653 655 750' }, |
305 |
{ val => '"640x480" 28.195793 640 656 658 784 480 520 525 600', pre_comment => "# NTSC\n" }, |
306 |
{ val => '"800x600" 38.769241 800 812 814 880 600 646 649 735' }, |
307 |
] }); |
308 |
$raw_X->set_devices({ Driver => 'fbdev' }); |
309 |
|
310 |
my ($device) = $raw_X->get_devices; |
311 |
my ($monitor) = $raw_X->get_monitors; |
312 |
$raw_X->set_screens({ Device => $device->{Identifier}, Monitor => $monitor->{Identifier} }); |
313 |
|
314 |
my $Screen = $raw_X->get_default_screen; |
315 |
$Screen->{Display} = [ map { { l => { Depth => { val => $_ } } } } 8, 16 ]; |
316 |
|
317 |
$raw_X->write("$::prefix/etc/X11/xorg.conf.tvout"); |
318 |
|
319 |
check_xorg_conf_symlink(); |
320 |
|
321 |
{ |
322 |
require bootloader; |
323 |
require fsedit; |
324 |
require detect_devices; |
325 |
my $all_hds = $::isInstall ? $::o->{all_hds} : fsedit::get_hds(); |
326 |
my $bootloader = $::isInstall ? $::o->{bootloader} : bootloader::read($all_hds); |
327 |
|
328 |
if (my $tvout = bootloader::duplicate_kernel_entry($bootloader, 'TVout')) { |
329 |
$tvout->{append} .= " XFree=tvout"; |
330 |
bootloader::install($bootloader, $all_hds); |
331 |
} |
332 |
} |
333 |
} |
334 |
|
335 |
sub configure_ServerFlag { |
336 |
my ($raw_X, $option, $value) = @_; |
337 |
my $ServerFlags = $raw_X->get_Section('ServerFlags'); |
338 |
my $option_ref = $ServerFlags->{$option}->[0]; |
339 |
if ($value) { |
340 |
$option_ref->{val} = $value; |
341 |
$option_ref->{commented} = 0; |
342 |
$option_ref->{Option} = 1; |
343 |
} |
344 |
return undef if $option_ref->{commented} eq 1; |
345 |
$option_ref->{val}; |
346 |
} |
347 |
|
348 |
sub check_xorg_conf_symlink() { |
349 |
my $f = "$::prefix/etc/X11/xorg.conf"; |
350 |
if (!-l $f && -e "$f.tvout") { |
351 |
rename $f, "$f.standard"; |
352 |
symlink "xorg.conf.standard", $f; |
353 |
} |
354 |
} |
355 |
|
356 |
sub setupFB { |
357 |
my ($bios_vga_mode) = @_; |
358 |
|
359 |
require bootloader; |
360 |
my ($bootloader, $all_hds); |
361 |
|
362 |
if ($::isInstall && !$::globetrotter) { |
363 |
($bootloader, $all_hds) = ($::o->{bootloader}, $::o->{all_hds}); |
364 |
$bootloader && $bootloader->{method} or return; |
365 |
} else { |
366 |
require fsedit; |
367 |
require fs; |
368 |
require bootloader; |
369 |
$all_hds = fsedit::get_hds(); |
370 |
fs::get_info_from_fstab($all_hds); |
371 |
|
372 |
$bootloader = bootloader::read($all_hds) or return; |
373 |
} |
374 |
|
375 |
foreach (@{$bootloader->{entries}}) { |
376 |
$_->{vga} = $bios_vga_mode if $_->{vga}; #- replace existing vga= with |
377 |
} |
378 |
|
379 |
bootloader::update_splash($bootloader); |
380 |
bootloader::action($bootloader, 'write', $all_hds); |
381 |
bootloader::action($bootloader, 'when_config_changed'); |
382 |
} |
383 |
|
384 |
1; |