summaryrefslogtreecommitdiffstats
path: root/perl-install/harddrake
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/harddrake')
-rw-r--r--perl-install/harddrake/autoconf.pm155
-rwxr-xr-xperl-install/harddrake/check_snd.pl20
-rw-r--r--perl-install/harddrake/data.pm578
-rw-r--r--perl-install/harddrake/sound.pm668
-rw-r--r--perl-install/harddrake/v4l.pm496
5 files changed, 1917 insertions, 0 deletions
diff --git a/perl-install/harddrake/autoconf.pm b/perl-install/harddrake/autoconf.pm
new file mode 100644
index 000000000..fba5078cd
--- /dev/null
+++ b/perl-install/harddrake/autoconf.pm
@@ -0,0 +1,155 @@
+package harddrake::autoconf;
+
+use common;
+
+sub xconf {
+ my ($modules_conf, $o, $o_skip_fb_setup, $o_resolution_wanted) = @_;
+
+ log::l('automatic XFree configuration');
+
+ require Xconfig::default;
+ require do_pkgs;
+ my $do_pkgs = do_pkgs_standalone->new;
+ $o->{raw_X} = Xconfig::default::configure($do_pkgs);
+
+ my $old_x = { if_($o_resolution_wanted, resolution_wanted => $o_resolution_wanted) };
+
+ require Xconfig::main;
+ Xconfig::main::configure_everything_auto_install($o->{raw_X}, $do_pkgs, $old_x, { allowFB => listlength(cat_("/proc/fb")), skip_fb_setup => $o_skip_fb_setup });
+
+ #- always disable compositing desktop effects when configuring a new video card
+ require Xconfig::glx;
+ Xconfig::glx::write({});
+
+ modules::load_category($modules_conf, 'various/agpgart');
+}
+
+sub setup_ethernet_device {
+ my ($in, $device) = @_;
+
+ require network::connection;
+ require network::connection::ethernet;
+ require network::connection::wireless;
+ my @connection_types = qw(network::connection::ethernet network::connection::wireless);
+ my @all_connections = map { $_->get_connections(automatic_only => 1) } @connection_types;
+ my $interface = network::connection::ethernet::device_to_interface($device)
+ or return;
+ my $connection = find { $_->get_interface eq $interface } @all_connections
+ or return;
+
+ require network::connection_manager;
+ my $net = {};
+ network::network::read_net_conf($net);
+ my $cmanager = network::connection_manager->new($in, $net);
+ $cmanager->set_connection($connection);
+
+ # this will installed required packages
+ $cmanager->setup_connection;
+}
+
+sub network_conf {
+ my ($modules_conf, $in, $added) = @_;
+ $modules_conf->remove_alias_regexp('^(wlan|eth)[0-9]*$');
+ modules::load_category($modules_conf, 'network/main|gigabit|usb|wireless|firewire|pcmcia');
+
+ setup_ethernet_device($in, $_) foreach @{$added || {}};
+
+ require network::connection::ethernet;
+ network::connection::ethernet::configure_eth_aliases($modules_conf);
+ require network::rfswitch;
+ network::rfswitch::configure();
+ require network::shorewall;
+ network::shorewall::update_interfaces_list();
+ $modules_conf->write;
+}
+
+sub mouse_conf {
+ my ($modules_conf) = @_;
+ require do_pkgs;
+ require mouse;
+ mouse::write_conf(do_pkgs_standalone->new, $modules_conf, my $mouse = mouse::detect($modules_conf), 1);
+ mouse::load_modules($mouse);
+}
+
+sub pcmcia {
+ my ($pcic) = @_;
+ require modules;
+ modules::set_preload_modules("pcmcia", if_($pcic, $pcic));
+}
+
+sub bluetooth {
+ my ($enable) = @_;
+ # do not disable bluetooth service if adapter disappears
+ # (for example if disabled by Fn keys)
+ # systemd will automatically disable the service if needed
+ return if !$enable;
+
+#- FIXME: make sure these packages are installed when needed
+# if ($enable) {
+# require do_pkgs;
+# my $do_pkgs = do_pkgs_standalone->new;
+# $do_pkgs->ensure_is_installed("bluez-utils", "/usr/bin/rfcomm");
+# }
+ require services;
+ services::set_status("bluetooth", $enable);
+ my $kbluetoothd_cfg = '/etc/kde/kbluetoothrc';
+ update_gnomekderc($kbluetoothd_cfg,
+ 'General',
+ 'AutoStart' => bool2text($enable)) if -f $kbluetoothd_cfg;
+}
+
+sub laptop {
+ my ($on_laptop) = @_;
+#- FIXME: make sure these packages are installed when needed
+# require do_pkgs;
+# my $do_pkgs = do_pkgs_standalone->new;
+# if ($on_laptop) {
+# $do_pkgs->ensure_is_installed("cpufreq", "/etc/rc.d/init.d/cpufreq");
+# $do_pkgs->ensure_is_installed("apmd", "/usr/bin/apm");
+# $do_pkgs->ensure_is_installed("hotkeys", "/usr/bin/hotkeys");
+# $do_pkgs->ensure_is_installed("laptop-mode-tools", "/usr/sbin/laptop_mode");
+# } else {
+# $do_pkgs->ensure_is_installed("numlock", "/etc/rc.d/init.d/numlock");
+# }
+ require services;
+ services::set_status("apmd", -e "/proc/apm");
+ services::set_status("laptop-mode", $on_laptop);
+ services::set_status("numlock", !$on_laptop);
+}
+
+sub cpufreq() {
+ require cpufreq;
+ modules::set_preload_modules("cpufreq", cpufreq::get_modules());
+}
+
+sub floppy() {
+ require detect_devices;
+ modules::set_preload_modules("floppy", if_(detect_devices::floppy(), "floppy"));
+}
+
+sub fix_aliases {
+ my ($modules_conf) = @_;
+ require modalias;
+ my %new_aliases;
+ #- first pass: find module targets whose modalias is not valid anymore
+ foreach my $module ($modules_conf->modules) {
+ if (my $aliased_to = $modules_conf->get_alias($module)) {
+ my @valid_modaliases = modalias::get_modules($module, 'skip_config') or next;
+ my ($found, $others) = partition { $_ eq $aliased_to } @valid_modaliases;
+ $new_aliases{$aliased_to} = @{$others || []} == 1 && $others->[0] if is_empty_array_ref($found);
+ }
+ }
+ #- second pass: adapt module targets that are not valid anymore
+ foreach my $module ($modules_conf->modules) {
+ if (my $aliased_to = $modules_conf->get_alias($module)) {
+ if (my $new = exists $new_aliases{$aliased_to} && $new_aliases{$aliased_to}) {
+ $modules_conf->set_alias($module, $new);
+ } else {
+ $modules_conf->remove_alias($module);
+ }
+ }
+ }
+ $modules_conf->write;
+}
+
+1;
diff --git a/perl-install/harddrake/check_snd.pl b/perl-install/harddrake/check_snd.pl
new file mode 100755
index 000000000..4721bed40
--- /dev/null
+++ b/perl-install/harddrake/check_snd.pl
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+use strict;
+use lib qw(/usr/lib/libDrakX);
+
+use common;
+use harddrake::sound;
+use list_modules;
+
+
+my @listed_modules = @{$list_modules::l{multimedia}{sound}};
+my @drivers = (keys %harddrake::sound::oss2alsa, keys %harddrake::sound::alsa2oss);
+my @alternatives = uniq map { @$_ } values %harddrake::sound::oss2alsa, values %harddrake::sound::alsa2oss;
+
+# check harddrake::sound's data structures're coherent
+print "unknown alternative drivers : [", join(', ', difference2(\@alternatives, \@drivers)), "]\n";
+
+# check that list_modules and harddrake::sound are synced
+print "non real sound modules (submodules, tv, usb, ...) : [", join(', ', difference2(\@drivers, \@listed_modules)), "]\n";
+print "forgotten sound modules : [", join(', ', difference2(\@listed_modules, \@drivers)), "]\n";
diff --git a/perl-install/harddrake/data.pm b/perl-install/harddrake/data.pm
new file mode 100644
index 000000000..8d4d4de21
--- /dev/null
+++ b/perl-install/harddrake/data.pm
@@ -0,0 +1,578 @@
+package harddrake::data;
+
+use strict;
+use detect_devices;
+use common;
+use modules;
+
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(version tree);
+our ($version, $sbindir, $bindir) = ("10", "/usr/sbin", "/usr/bin");
+
+my @devices = (detect_devices::probeall(), detect_devices::getSCSI());
+
+foreach my $dev (@devices) {
+ # normalize device IDs for devices that came from mouse.pm:
+ next if !defined $dev->{Synaptics};
+ foreach my $field (qw(vendor id subvendor subid)) {
+ next if !defined $dev->{$field};
+ $dev->{$field} = hex($dev->{$field});
+ }
+}
+
+# Update me each time you handle one more devices class (aka configurator)
+sub unknown() {
+ grep { $_->{media_type} !~ /BRIDGE|class\|Mouse|DISPLAY|Hub|MEMORY_RAM|MULTIMEDIA_(VIDEO|AUDIO|OTHER)|NETWORK|Printer|SERIAL_(USB|SMBUS)|STORAGE_(IDE|OTHER|RAID|SCSI)|SYSTEM_(OTHER|SDHCI)|tape|UPS/
+ && !member($_->{driver}, qw(cpia_usb cyber2000fb forcedeth ibmcam megaraid mod_quickcam nvnet ohci1394 ov511 ov518_decomp scanner ultracam usbvideo usbvision))
+ && $_->{driver} !~ /^ISDN|Mouse:USB|Removable:zip|class\|Mouse|sata|www.linmodems.org|kbd|mouse|sysrq|usbhid/
+ && $_->{type} ne 'network'
+ && $_->{description} !~ /Alcatel|ADSL Modem/;
+ } @devices;
+}
+
+my @alrd_dected;
+sub f {
+ my @devs = grep { !member(pciusb_id($_), @alrd_dected) } grep { $_ } @_;
+ push @alrd_dected, map { pciusb_id($_) } @devs;
+ @devs;
+}
+
+
+# tree format ("CLASS_ID", "type", "type_icon", configurator, detect_sub)
+# NEVER, NEVER alter CLASS_ID or you'll see harddrake2 service detect changes
+# in hw configuration ... :-(
+
+# FIXME: add translated items
+
+sub is_removable { member($_[0], qw(FLOPPY ZIP DVDROM CDROM BURNER)) }
+sub is_auto_configurable_media { !detect_devices::isKeyUsb($_[0]) }
+
+sub set_removable_configurator {
+ my ($class, $device) = @_;
+ is_removable($class) ? "/usr/sbin/diskdrake --removable=$device->{device}" : undef;
+ }
+
+my $modules_conf = modules::any_conf->read;
+
+# Format is (HW class ID, l18n class name, icon, config tool , is_to_be_detected_on_boot)
+our @tree =
+ (
+ {
+ class => "SATA_STORAGE",
+ string => N("SATA controllers"),
+ icon => "ide_hd.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{driver} !~ /^pata/ } detect_devices::probe_category('disk/sata')),
+ f(grep { $_->{description} =~ /AHCI/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "RAID_STORAGE",
+ string => N("RAID controllers"),
+ icon => "ide_hd.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('disk/hardware_raid')),
+ f(grep { $_->{media_type} =~ /STORAGE_RAID/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "ATA_STORAGE",
+ string => N("(E)IDE/ATA controllers"),
+ icon => "ide_hd.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('disk/ide')),
+ f(grep { $_->{driver} =~ /^pata/ && $_->{media_type} =~ /IDE|STORAGE_SATA/ } @devices),
+ f(grep { $_->{media_type} =~ /STORAGE_(IDE|OTHER)/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "CARD_READER",
+ string => N("Card readers"),
+ icon => "ide_hd.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('disk/card_reader')) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "FIREWIRE_CONTROLLER",
+ string => N("Firewire controllers"),
+ icon => "usb.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{driver} =~ /firewire_ohci|ohci1394/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "PCMCIA_CONTROLLER",
+ string => N("PCMCIA controllers"),
+ icon => "hw-pcmcia.png",
+ configurator => "",
+ detector => sub { f(detect_devices::pcmcia_controller_probe()) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "SCSI_CONTROLLER",
+ string => N("SCSI controllers"),
+ icon => "scsi.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('disk/scsi'), grep { $_->{media_type} =~ /STORAGE_SCSI/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "USB_CONTROLLER",
+ string => N("USB controllers"),
+ icon => "usb.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{media_type} eq 'SERIAL_USB' } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "USB_HUB",
+ string => N("USB ports"),
+ icon => "hw-usb.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{media_type} =~ /Hub/ } @devices) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "SMB_CONTROLLER",
+ string => N("SMBus controllers"),
+ icon => "hw-smbus.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{media_type} =~ /SERIAL_SMBUS/ } @devices) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "BRIDGE",
+ string => N("Bridges and system controllers"),
+ icon => "memory.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{media_type} =~ /BRIDGE|MEMORY_RAM|SYSTEM_(OTHER|SDHCI)|MEMORY_OTHER|SYSTEM_PIC|COMMUNICATION_OTHER/
+ || $_->{description} =~ /Parallel Port Adapter/;
+ } @devices) },
+ checked_on_boot => 0,
+ },
+
+
+ {
+ class => "FLOPPY",
+ string => N("Floppy"),
+ icon => "floppy.png",
+ configurator => "",
+ detector => \&detect_devices::floppies,
+ checked_on_boot => 1,
+ automatic => 1,
+ },
+
+ {
+ class => "ZIP",
+ string => N("Zip"),
+ icon => "floppy.png",
+ configurator => "",
+ detector => sub {
+ my ($options) = @_;
+ if ($options->{PARALLEL_ZIP_DETECTION}) {
+ modules::load_parallel_zip($modules_conf) and $modules_conf->write;
+ }
+ detect_devices::zips();
+ },
+ checked_on_boot => 1,
+ automatic => 1,
+ },
+
+ {
+ class => "HARDDISK",
+ string => N("Hard Disk"),
+ icon => "harddisk.png",
+ configurator => "$sbindir/diskdrake",
+ detector => sub { f(detect_devices::hds()) },
+ checked_on_boot => 0,
+ automatic => 1,
+ },
+
+ {
+ class => "USB_STORAGE",
+ string => N("USB Mass Storage Devices"),
+ icon => "usb.png",
+ configurator => "",
+ detector => sub { f(grep { member($_->{driver}, qw(usb_storage ub Removable:memory_card)) } @devices) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "CDROM",
+ string => N("CDROM"),
+ icon => "cd.png",
+ configurator => "",
+ detector => sub { f(grep { !(detect_devices::isBurner($_) || detect_devices::isDvdDrive($_)) } &detect_devices::cdroms) },
+ checked_on_boot => 1,
+ automatic => 1,
+ },
+
+ {
+ class => "BURNER",
+ string => N("CD/DVD burners"),
+ icon => "cd.png",
+ configurator => "",
+ detector => sub { f(detect_devices::burners()) },
+ checked_on_boot => 1,
+ automatic => 1,
+ },
+
+ {
+ class => "DVDROM",
+ string => N("DVD-ROM"),
+ icon => "cd.png",
+ configurator => "",
+ detector => sub { f(grep { ! detect_devices::isBurner($_) } detect_devices::dvdroms()) },
+ checked_on_boot => 1,
+ automatic => 1,
+ },
+
+ {
+ class => "TAPE",
+ string => N("Tape"),
+ icon => "tape.png",
+ configurator => "",
+ detector => \&detect_devices::tapes,
+ checked_on_boot => 0,
+ },
+
+ # AGP devices must be detected prior to video cards because some DRM drivers doesn't like be loaded
+ # after agpgart thus order in /etc/modprobe.preload is important (modules.pm should enforce such sorting):
+ {
+ class => "AGP",
+ string => N("AGP controllers"),
+ icon => "memory.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('various/agpgart')) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "VIDEO",
+ string => N("Videocard"),
+ icon => "video.png",
+ configurator => "$sbindir/XFdrake",
+ detector => sub { f(grep { $_->{driver} =~ /^(Card|Server):/ || $_->{media_type} =~ /DISPLAY_VGA/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "DVB",
+ string => N("DVB card"),
+ icon => "tv.png",
+ detector => sub { f(detect_devices::probe_category('multimedia/dvb')) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "TV",
+ string => N("Tvcard"),
+ icon => "tv.png",
+ configurator => "/usr/sbin/drakxtv",
+ detector => sub { f(detect_devices::probe_category('multimedia/tv')),
+ f(grep { $_->{media_type} =~ /MULTIMEDIA_VIDEO/ && $_->{bus} eq 'PCI' } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "MULTIMEDIA_OTHER",
+ string => N("Other MultiMedia devices"),
+ icon => "multimedia.png",
+ configurator => "",
+ detector => sub { f(grep { $_->{media_type} =~ /MULTIMEDIA_OTHER/ } @devices) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "AUDIO",
+ string => N("Soundcard"),
+ icon => "sound.png",
+ configurator => "$sbindir/draksound",
+ detector => sub {
+ require list_modules;
+ my @modules = list_modules::category2modules('multimedia/sound');
+ f(grep { $_->{media_type} =~ /MULTIMEDIA_AUDIO|PROCESSOR_CO/ || member($_->{driver}, @modules)
+ || $_->{description} =~ /^\|?HDA |PC Speaker/ } @devices);
+ },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "WEBCAM",
+ string => N("Webcam"),
+ icon => "webcam.png",
+ configurator => "",
+ detector => sub {
+ require list_modules;
+ my @modules = (list_modules::category2modules('multimedia/webcam'), 'Removable:camera');
+ f(grep { $_->{media_type} =~ /MULTIMEDIA_VIDEO|Video\|Video Control|Imaging|Camera/ && $_->{bus} ne 'PCI'
+ || member($_->{driver}, @modules) || $_->{driver} =~ /^gpsca/ } @devices);
+ },
+ # managed by hotplug:
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "CPU",
+ string => N("Processors"),
+ icon => "cpu.png",
+ configurator => "",
+ detector => sub { detect_devices::getCPUs() },
+ # maybe should we install schedutils?
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "ISDN",
+ string => N("ISDN adapters"),
+ icon => "modem.png",
+ configurator => "$sbindir/drakconnect",
+ detector => sub { require network::connection::isdn; my $isdn = network::connection::isdn::detect_backend($modules_conf); if_(@$isdn, f(@$isdn)) },
+ # we do not check these b/c this need user interaction (auth, ...):
+ checked_on_boot => 0,
+ },
+
+
+ {
+ class => "USB_AUDIO",
+ string => N("USB sound devices"),
+ icon => "sound.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('multimedia/usb_sound')) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "RADIO",
+ string => N("Radio cards"),
+ icon => "tv.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('multimedia/radio')) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "ATM",
+ string => N("ATM network cards"),
+ icon => "hw_network.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('network/atm')) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "WAN",
+ string => N("WAN network cards"),
+ icon => "hw_network.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('network/wan')) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "BLUETOOTH",
+ string => N("Bluetooth devices"),
+ icon => "hw_network.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('bus/bluetooth')), f(grep { $_->{description} =~ /Bluetooth Dongle/ } @devices) },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "ETHERNET",
+ string => N("Ethernetcard"),
+ icon => "hw_network.png",
+ configurator => "$sbindir/drakconnect",
+ detector => sub {
+ require list_modules;
+ my @net_modules = list_modules::category2modules(list_modules::ethernet_categories());
+ f(grep {
+ $_->{media_type} && $_->{media_type} =~ /^NETWORK/
+ || $_->{type} && $_->{type} eq 'network'
+ || member($_->{driver}, @net_modules)
+ || $_->{description} =~ /WLAN/;
+ } @devices);
+ },
+ checked_on_boot => 1,
+ },
+
+ {
+ class => "MODEM",
+ string => N("Modem"),
+ icon => "modem.png",
+ configurator => "$sbindir/drakconnect",
+ detector => sub { f(detect_devices::getModem($modules_conf)), f(grep { $_->{description} =~ /SoftModem/ } @devices) },
+ # we do not check these b/c this need user interaction (auth, ...):
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "ADSL",
+ string => N("ADSL adapters"),
+ icon => "modem.png",
+ configurator => "$sbindir/drakconnect",
+ detector => sub { f(detect_devices::get_xdsl_usb_devices()),
+ f(grep { $_->{description} =~ /Cohiba 3887 rev0/ } @devices);
+ },
+ # we do not check these b/c this need user interaction (auth, ...):
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "MEMORY",
+ string => N("Memory"),
+ icon => "hw-memory.png",
+ configurator => "",
+ detector => sub { grep { member($_->{name}, 'Cache', 'Memory Module') || $_->{name} eq 'Memory Device' && $_->{Size} ne 'No Module Installed' } detect_devices::dmidecode() },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "PRINTER",
+ string => N("Printer"),
+ icon => "hw_printer.png",
+ configurator => "$sbindir/printerdrake",
+ detector => sub {},
+ # we do not check these b/c this need user interaction (auth, ...):
+ checked_on_boot => 0,
+ },
+
+
+
+ {
+ class => "GAMEPORT",
+ string =>
+ #-PO: these are joysticks controllers:
+ N("Game port controllers"),
+ icon => "joystick.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('multimedia/gameport')) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "JOYSTICK",
+ string => N("Joystick"),
+ icon => "joystick.png",
+ configurator => "",
+ detector => sub { f(detect_devices::probe_category('input/joystick')), f(grep { $_->{description} =~ /Joystick/i } @devices) },
+ checked_on_boot => 0,
+ },
+
+
+ {
+ class => "KEYBOARD",
+ string => N("Keyboard"),
+ icon => "hw-keyboard.png",
+ configurator => "$sbindir/keyboarddrake",
+ detector => sub {
+ f(grep { $_->{description} =~ /Keyboard/i || $_->{media_type} =~ /Keyboard/i ||
+ # USB devices are filtered out since we already catch them through probeall():
+ $_->{bus} ne 'usb' && $_->{driver} =~ /^event|kbd|^usbhid/ && $_->{description} !~ /PC Speaker/;
+ } @devices);
+ },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "MISC_INPUT",
+ string => N("Tablet and touchscreen"),
+ icon => "hw_mouse.png",
+ detector => sub { f(detect_devices::probe_category('input/tablet'), detect_devices::probe_category('input/touchscreen')) },
+ configurator => "$sbindir/mousedrake",
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "MOUSE",
+ string => N("Mouse"),
+ icon => "hw_mouse.png",
+ configurator => "$sbindir/mousedrake",
+ detector => sub {
+ f(grep { $_->{driver} =~ /^Mouse:|^Tablet:|^mouse/ || $_->{media_type} =~ /class\|Mouse/ ||
+ # USB devices are filtered out since we already catch them through probeall():
+ $_->{bus} ne 'usb' && $_->{Handlers}{mouse};
+ } @devices);
+ },
+ checked_on_boot => 1,
+ automatic => 1,
+ },
+
+ {
+ class => "BIOMETRIC",
+ string => N("Biometry"),
+ icon => "ups.png",
+ detector => sub { f(grep { $_->{description} =~ /fingerprint|biometric/i } @devices) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "UPS",
+ string => N("UPS"),
+ icon => "ups.png",
+ configurator => "$sbindir/drakups",
+ detector => sub { f(detect_devices::getUPS()) },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "SCANNER",
+ string => N("Scanner"),
+ icon => "scanner.png",
+ configurator => "$sbindir/scannerdrake",
+ detector => sub {
+ require scanner; f(map { $_->{val}{drakx_device} } f(scanner::detect()));
+ },
+ checked_on_boot => 0,
+ },
+
+ {
+ class => "UNKNOWN",
+ string => N("Unknown/Others"),
+ icon => "unknown.png",
+ configurator => "",
+ detector => sub { f(unknown()) },
+ checked_on_boot => 0,
+ },
+
+ );
+
+sub pciusb_id {
+ my ($dev) = @_;
+ my %alt = (
+ bus => 'usb_bus',
+ description => 'usb_description',
+ id => 'usb_id',
+ pci_bus => 'usb_pci_bus',
+ pci_device => 'usb_pci_device',
+ vendor => 'usb_vendor',
+ );
+ my @fields = ('bus', if_($dev->{bus} =~ /pci/, qw(pci_bus pci_device)), qw(vendor id subvendor subid),
+ if_($dev->{bus} !~ /usb/i, 'description'));
+ join(':', map { uc($dev->{$alt{$_}} || $dev->{$_}) } @fields);
+}
+
+
+sub custom_id {
+ my ($device, $str) = @_;
+ return if !ref($device);
+ defined($device->{device}) ? $device->{device} :
+ (defined($device->{processor}) ?
+ N("cpu # ") . $device->{processor} . ": " . $device->{'model name'} :
+ $device->{"Socket Designation"} ?
+ "$device->{name} (" . $device->{"Socket Designation"} . ")" :
+ $device->{name} || $device->{description} || $device->{Vendor} || $str);
+}
+
+1;
diff --git a/perl-install/harddrake/sound.pm b/perl-install/harddrake/sound.pm
new file mode 100644
index 000000000..cdf24c219
--- /dev/null
+++ b/perl-install/harddrake/sound.pm
@@ -0,0 +1,668 @@
+package harddrake::sound;
+
+# TODO:
+# o ensure sound is not user (either dsp/midi/sequencer/mixer)
+# o fix sound/alsa services
+
+use strict;
+use common;
+use run_program;
+use modules;
+use list_modules;
+use detect_devices;
+use log;
+
+sub is_pulseaudio_enabled {
+ my ($in) = @_;
+ my $soundprofile = common::read_alternative('soundprofile');
+ return $in->do_pkgs->is_installed('task-pulseaudio') && $soundprofile =~ /pulse$/;
+}
+
+sub set_pulseaudio {
+ my ($val) = @_;
+
+ my $alterative = '/etc/sound/profiles/' . ($val ? 'pulse' : 'alsa');
+ return if ! -d $alterative;
+
+ common::symlinkf_update_alternatives('soundprofile', $alterative);
+
+ # (cg) This config file will eventually be dropped, but it is still needed for now
+ # as several packages/patches depend on it.
+ my $config_file = "$::prefix/etc/sysconfig/pulseaudio";
+ $val = 'PULSE_SERVER_TYPE=' . ($val ? 'personal' : 'none') . "\n";
+ my $done;
+ substInFile {
+ if (/^PULSE_SERVER_TYPE=/) {
+ $_ = $val;
+ $done = 1;
+ }
+ } $config_file;
+ append_to_file($config_file, $val) if !$done;
+}
+
+
+my $pa_startup_scriptfile = "$::prefix/etc/pulse/default.pa";
+
+sub is_pulseaudio_glitchfree_enabled() {
+ return -f $pa_startup_scriptfile &&
+ cat_($pa_startup_scriptfile) !~ /^load-module\s+module-(udev|hal)-detect\s+tsched=0/m;
+}
+
+sub set_pulseaudio_glitchfree {
+ my ($val) = @_;
+
+ return if ! -f $pa_startup_scriptfile;
+
+ substInFile {
+ if ($val) {
+ s/^(load-module\s+module-(udev|hal)-detect)\s+tsched=0/$1/;
+ } else {
+ s/^(load-module\s+module-(udev|hal)-detect).*/$1 tsched=0/;
+ }
+ } $pa_startup_scriptfile;
+}
+
+sub is_pipewire_wireplumber_enabled {
+ my ($in) = @_;
+ return $in->do_pkgs->is_installed('pipewire') && $in->do_pkgs->is_installed('wireplumber');
+}
+
+sub is_pipewire_media_session_enabled {
+ my ($in) = @_;
+ return $in->do_pkgs->is_installed('pipewire') && $in->do_pkgs->is_installed('pipewire-media-session');
+}
+
+sub rooted {
+ run_program::rooted($::prefix, @_);
+}
+
+sub unload { modules::unload(@_) if $::isStandalone }
+
+sub load {
+ my ($modules_conf, $name) = @_;
+ modules::load_and_configure($modules_conf, $name) if $::isStandalone;
+}
+
+sub _pidof {
+ my ($name) = @_;
+ rooted('/usr/bin/pidof', $name);
+}
+
+# return the pid of a running command
+sub _pidof_pid {
+ my ($name) = @_;
+ my ($pid) = chomp_(run_program::rooted_get_stdout($::prefix, '/usr/bin/pidof', $name));
+
+ return $pid;
+}
+
+# return the username of a running command
+sub _user_pid {
+ my ($name) = @_;
+ my ($pid) = _pidof_pid($name);
+ my $user;
+
+ if ($pid) {
+ ($user) = chomp_(run_program::rooted_get_stdout($::prefix, '/usr/bin/ps', '-o', 'uname=', '-p', $pid));
+ }
+
+ return $user;
+}
+
+# stop pulseaudio for the running user
+sub stop_pulseaudio {
+ my ($pulseaudio_user) = _user_pid('/usr/bin/pulseaudio');
+
+ if ($pulseaudio_user) {
+ if (-x $::prefix . '/usr/bin/pulseaudio') {
+ rooted('/usr/bin/su', '-l', $pulseaudio_user, '-c', '/usr/bin/pulseaudio --kill');
+ }
+ }
+
+ # try stopping again (in case the /usr/bin/pulseaudio process is still running, but the executable no longer available)
+ my ($pulseaudio_user) = _user_pid('/usr/bin/pulseaudio');
+ if ($pulseaudio_user) {
+ my ($pulseaudio_pid) = _pidof_pid('/usr/bin/pulseaudio');
+ if ($pulseaudio_pid) {
+ rooted('/usr/bin/su', '-l', $pulseaudio_user, '-c', '/usr/bin/kill -TERM ' . $pulseaudio_pid);
+ }
+ }
+ return $pulseaudio_user;
+}
+
+# stop pipewire services for the running user
+sub stop_pipewire {
+ my ($pipewire_user) = _user_pid('/usr/bin/pipewire');
+
+ if ($pipewire_user) {
+ rooted('/usr/bin/systemctl', '--machine=' . $pipewire_user . '@.host', '--user', 'stop', 'pipewire-pulse.service', 'pipewire-pulse.socket', 'pipewire.service', 'pipewire.socket');
+ }
+
+ return $pipewire_user;
+}
+
+# start pulseaudio for the specified user
+sub start_pulseaudio {
+ my ($pulseaudio_user) = @_;
+
+ if ($pulseaudio_user) {
+ rooted('/usr/bin/su', '-l', $pulseaudio_user, '-c', '/usr/bin/pulseaudio --start');
+ }
+}
+
+# start pipewire services for the specified user
+sub start_pipewire {
+ my ($pipewire_user) = @_;
+
+ if ($pipewire_user) {
+ rooted('/usr/bin/systemctl', '--machine=' . $pipewire_user . '@.host', '--user', 'start', 'pipewire.socket', 'pipewire.service', 'pipewire-pulse.socket', 'pipewire-pulse.service');
+ }
+}
+
+# stop wireplumber services for the running user
+sub stop_wireplumber {
+ my ($pipewire_user) = _user_pid('/usr/bin/wireplumber');
+
+ if ($pipewire_user) {
+ rooted('/usr/bin/systemctl', '--machine=' . $pipewire_user . '@.host', '--user', 'stop', 'wireplumber.service');
+ }
+
+ return $pipewire_user;
+}
+
+# start wireplumber
+sub start_wireplumber {
+ my ($pipewire_user) = @_;
+
+ if ($pipewire_user) {
+ rooted('/usr/bin/systemctl', '--machine=' . $pipewire_user . '@.host', '--user', 'start', 'wireplumber.service');
+ }
+}
+
+# stop pipewire-media-session services for the running user
+sub stop_pipewire_media_session {
+ my ($pipewire_user) = _user_pid('/usr/bin/pipewire-media-session');
+
+ if ($pipewire_user) {
+ rooted('/usr/bin/systemctl', '--machine=' . $pipewire_user . '@.host', '--user', 'stop', 'pipewire-media-session.service');
+ }
+
+ return $pipewire_user;
+}
+
+# start pipewire-media-session services for the specified user
+sub start_pipewire_media_session {
+ my ($pipewire_user) = @_;
+
+ if ($pipewire_user) {
+ rooted('/usr/bin/systemctl', '--machine=' . $pipewire_user . '@.host', '--user', 'start', 'pipewire-media-session.service');
+ }
+}
+
+sub configure_pipewire_wireplumber {
+ my ($in) = @_;
+ my ($pipewire_wp_user);
+
+ # preserve pulseaudio user
+ my ($pulseaudio_user) = _user_pid('/usr/bin/pulseaudio');
+
+ # stop pipewire and pipewire-media-session services (if any) before removing any packages
+ # and preserve pipewire-media-session user
+ $pipewire_wp_user = stop_pipewire_media_session();
+ stop_pipewire();
+
+ my $plasma_installed = $in->do_pkgs->is_installed('plasma-desktop');
+ my @pkgs = (
+ 'task-pipewire',
+ 'wireplumber',
+ );
+ if (!$in->do_pkgs->is_installed('pavucontrol-qt')) {
+ if ($plasma_installed) {
+ push(@pkgs, 'pavucontrol-qt');
+ }
+ else {
+ push(@pkgs, 'pavucontrol');
+ }
+ }
+
+
+ my $required_installed = $in->do_pkgs->ensure_are_installed(
+ \@pkgs
+ );
+
+ if (!$required_installed)
+ {
+ $in->ask_warn(N("Couldn't install the required packages"),
+ N("Please check the repositories are correctly configured")
+ );
+ return;
+ }
+
+ set_pulseaudio(0);
+
+ # first of all disabling what has to be disabled to avoid conflicts
+ if ($in->do_pkgs->is_installed('pipewire-media-session')) {
+ rooted('/usr/bin/systemctl', '--global', 'disable', 'pipewire-media-session.service');
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire')) {
+ foreach ('pipewire.socket', 'pipewire.service') {
+ rooted('/usr/bin/systemctl', '--global', 'enable', $_);
+ }
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire-pulseaudio')) {
+ foreach ('pipewire-pulse.socket', 'pipewire-pulse.service') {
+ rooted('/usr/bin/systemctl', '--global', 'enable', $_);
+ }
+ }
+
+ if ($in->do_pkgs->is_installed('wireplumber')) {
+ rooted('/usr/bin/systemctl', '--global', 'enable', 'wireplumber.service');
+ }
+
+
+ # stop pulseaudio process if still floating after the switch
+ stop_pulseaudio();
+
+ if ($pulseaudio_user) {
+ # restart pipewire and wireplumber with the same user as initial pulseaudio
+ start_pipewire($pulseaudio_user);
+ start_wireplumber($pulseaudio_user);
+ }
+ else {
+ if ($pipewire_wp_user) {
+ # restart pipewire and wireplumber with the same user as pipewire-media-session
+ start_pipewire($pipewire_wp_user);
+ start_wireplumber($pipewire_wp_user);
+ }
+ }
+
+ #Plasma tricks
+ if ($plasma_installed) {
+ $in->do_pkgs->ensure_is_installed('kpipewire');
+ }
+}
+
+sub configure_pipewire_media_session {
+ my ($in) = @_;
+ my ($pipewire_ms_user);
+
+ # preserve pulseaudio user
+ my ($pulseaudio_user) = _user_pid('/usr/bin/pulseaudio');
+
+ # stop pipewire and wireplumber services (if any) before removing any package
+ # and preserve wireplumber user
+ $pipewire_ms_user = stop_wireplumber();
+ stop_pipewire();
+
+
+ my $plasma_installed = $in->do_pkgs->is_installed('plasma-desktop');
+ my @pkgs = (
+ 'task-pipewire',
+ 'pipewire-media-session',
+ );
+ if (!$in->do_pkgs->is_installed('pavucontrol-qt')) {
+ if ($plasma_installed) {
+ push(@pkgs, 'pavucontrol-qt');
+ }
+ else {
+ push(@pkgs, 'pavucontrol');
+ }
+ }
+
+ my $required_installed = $in->do_pkgs->ensure_are_installed(
+ \@pkgs
+ );
+
+ if (!$required_installed)
+ {
+ $in->ask_warn(N("Couldn't install the required packages"),
+ N("Please check the repositories are correctly configured")
+ );
+ return;
+ }
+
+ set_pulseaudio(0);
+
+ # first of all disabling what has to be disabled to avoid conflicts
+ if ($in->do_pkgs->is_installed('wireplumber')) {
+ rooted('/usr/bin/systemctl', '--global', 'disable', 'wireplumber.service');
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire')) {
+ foreach ('pipewire.socket', 'pipewire.service') {
+ rooted('/usr/bin/systemctl', '--global', 'enable', $_);
+ }
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire-pulseaudio')) {
+ foreach ('pipewire-pulse.socket', 'pipewire-pulse.service') {
+ rooted('/usr/bin/systemctl', '--global', 'enable', $_);
+ }
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire-media-session')) {
+ rooted('/usr/bin/systemctl', '--global', 'enable', 'pipewire-media-session.service');
+ }
+
+ # stop pulseaudio process if still floating after the switch
+ stop_pulseaudio();
+
+ if ($pulseaudio_user) {
+ # restart pipewire and wireplumber with the same user as initial pulseaudio
+ start_pipewire($pulseaudio_user);
+ start_pipewire_media_session($pulseaudio_user);
+ }
+ else {
+ if ($pipewire_ms_user) {
+ # restart pipewire and wireplumber with the same user as pipewire-media-session
+ start_pipewire($pipewire_ms_user);
+ start_pipewire_media_session($pipewire_ms_user);
+ }
+ }
+
+ #Plasma tricks
+ if ($plasma_installed) {
+ $in->do_pkgs->ensure_is_installed('kpipewire');
+ }
+}
+
+sub disable_all_pipewire {
+ my ($in) = @_;
+
+ if ($in->do_pkgs->is_installed('wireplumber')) {
+ rooted('/usr/bin/systemctl', '--global', 'disable', 'wireplumber.service');
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire-media-session')) {
+ rooted('/usr/bin/systemctl', '--global', 'disable', 'pipewire-media-session.service');
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire-pulseaudio')) {
+ foreach ('pipewire-pulse.socket', 'pipewire-pulse.service') {
+ rooted('/usr/bin/systemctl', '--global', 'disable', $_);
+ }
+ }
+
+ if ($in->do_pkgs->is_installed('pipewire')) {
+ foreach ('pipewire.socket', 'pipewire.service') {
+ rooted('/usr/bin/systemctl', '--global', 'disable', $_);
+ }
+ }
+}
+
+sub configure_pulseaudio {
+ my ($in) = @_;
+
+ # preserve pipewire running user
+ my ($pipewire_user) = _user_pid('/usr/bin/pipewire');
+
+ # stop pipewire, wireplumber and pipewire-media-session services (if any) before removing any packages
+ my ($wireplumber_user) = stop_wireplumber();
+ my ($pipewire_media_session_user) = stop_pipewire_media_session();
+ my ($pipewire_user_preserve) = stop_pipewire();
+
+ # now packages
+ $in->do_pkgs->remove('pipewire-alsa');
+
+ my $plasma_installed = $in->do_pkgs->is_installed('plasma-desktop');
+ my @pkgs = 'task-pulseaudio';
+ if (!$in->do_pkgs->is_installed('pavucontrol-qt')) {
+ if ($plasma_installed) {
+ push(@pkgs, 'pavucontrol-qt');
+ }
+ else {
+ push(@pkgs, 'pavucontrol');
+ }
+ }
+
+ my $required_installed = $in->do_pkgs->ensure_are_installed(
+ \@pkgs
+ );
+
+ if (!$required_installed)
+ {
+ $in->ask_warn(N("Couldn't install the required packages"),
+ N("Please check the repositories are correctly configured")
+ );
+
+ # restore previous pipewire (if any) processes if something goes wrong with pulseaudio installation
+ if ($pipewire_user_preserve) {
+ start_pipewire($pipewire_user_preserve);
+ }
+
+ if ($wireplumber_user) {
+ start_wireplumber($wireplumber_user);
+ }
+
+ if ($pipewire_media_session_user) {
+ start_pipewire_media_session($pipewire_media_session_user);
+ }
+
+ return;
+ }
+
+
+ # disable all the pipewire stuff before managing packages
+ disable_all_pipewire($in);
+
+ # start pulseaudio with same pipewire preserved user
+ if ($pipewire_user) {
+ start_pulseaudio($pipewire_user);
+ }
+}
+
+sub config {
+ my ($in, $modules_conf, $device) = @_;
+ my $driver = $device->{current_driver} || $device->{driver};
+
+ my @alternative = $driver ne $device->{driver} ? $device->{driver} : ();
+ if ($driver eq "unknown") {
+ $in->ask_warn(N("No known driver"),
+ N("There's no known driver for your sound card (%s)",
+ $device->{description}));
+ } else {
+ push @alternative, $driver;
+ my %des = modules::category2modules_and_description('multimedia/sound');
+
+ my $is_pulseaudio_enabled_val = is_pulseaudio_enabled($in);
+ my $is_pulseaudio_glitchfree_enabled_val = is_pulseaudio_glitchfree_enabled();
+
+ my $audiosystem = 'None';
+ if ($is_pulseaudio_enabled_val && $is_pulseaudio_glitchfree_enabled_val) {
+ $audiosystem = 'PulseAudioGF';
+ } elsif ($is_pulseaudio_enabled_val) {
+ $audiosystem = 'PulseAudio';
+ } elsif (is_pipewire_wireplumber_enabled($in) || _pidof('/usr/bin/wireplumber')) {
+ $audiosystem = 'PipeWireWP';
+ } elsif (is_pipewire_media_session_enabled($in) || _pidof('/usr/bin/pipewire-media-session')) {
+ $audiosystem = 'PipeWireMS';
+ }
+
+ my $write_config = sub {
+ if ($audiosystem eq 'None') {
+ #### ALSA alone
+ disable_all_pipewire($in);
+ set_pulseaudio(0);
+ set_pulseaudio_glitchfree(0);
+ # TODO check if adding autospawn = no to /etc/pulse/client.conf is needed
+ } elsif ($audiosystem eq 'PulseAudio') {
+ #### PulseAudio
+ configure_pulseaudio($in);
+ set_pulseaudio(1);
+ set_pulseaudio_glitchfree(0);
+ my $lib = get_libdir();
+ $in->do_pkgs->ensure_is_installed($lib . 'alsa-plugins-pulseaudio',
+ '/usr/' . $lib . '/alsa-lib/libasound_module_pcm_pulse.so');
+ } elsif ($audiosystem eq 'PulseAudioGF') {
+ #### PulseAudio with Glitch-Free mode
+ configure_pulseaudio($in);
+ set_pulseaudio(1);
+ set_pulseaudio_glitchfree(1);
+ my $lib = get_libdir();
+ $in->do_pkgs->ensure_is_installed($lib . 'alsa-plugins-pulseaudio',
+ '/usr/' . $lib . '/alsa-lib/libasound_module_pcm_pulse.so');
+ } elsif ($audiosystem eq 'PipeWireWP') {
+ #### PipeWire with WirePlumber
+ configure_pipewire_wireplumber($in);
+ } elsif ($audiosystem eq 'PipeWireMS') {
+ #### PipeWire with PipeWire Media Session
+ configure_pipewire_media_session($in);
+ } else {
+ #### Unmanaged value
+ #TODO Error here
+ }
+
+ $in->ask_warn('', N("You need to reboot for changes to take effect")) if $::isStandalone;
+
+ };
+
+ my $warn_both = ($in->do_pkgs->is_installed('pipewire') && $in->do_pkgs->is_installed('pulseaudio') && (-e $::prefix . '/etc/systemd/user/sockets.target.wants/pipewire.socket' || -e $::prefix . '/etc/systemd/user/sockets.target.wants/pipewire.service')) ?
+ N("Warning: both pulseaudio and pipewire are installed and can conflict each other. Please fix your config by applying a choice") :
+ "";
+
+ my $is_pipewire_available = $in->do_pkgs->is_available('task-pipewire');
+ my $warn_pipewire_unavailable = !$is_pipewire_available ?
+ N("Warning: task-pipewire is not available in any media sources, so only pulseaudio could be set up. Please fix your repo configuration.") :
+ "";
+
+ my @service_list = (
+ 'None',
+ 'PulseAudio',
+ 'PulseAudioGF',
+ );
+ if ($is_pipewire_available) {
+ push @service_list, 'PipeWireWP';
+ push @service_list, 'PipeWireMS';
+ }
+ my @common = (
+ {
+ label => N("Select the sound server"),
+ title => 1,
+ },
+ {
+ val => \$audiosystem,
+ list => \@service_list,
+ format => sub {
+ my ($choice) = @_;
+ +{
+ 'None' => N("None"),
+ 'PulseAudio' => N("PulseAudio"),
+ 'PulseAudioGF' => N("PulseAudio with Glitch-Free mode"),
+ 'PipeWireWP' => N("PipeWire with WirePlumber"),
+ 'PipeWireMS' => N("PipeWire with PipeWire Media Session"),
+ }->{$choice};
+ },
+ type => 'list',
+ },
+ {
+ advanced => 1,
+ val => N("Reset sound mixer to default values"),
+ clicked => sub { run_program::run('reset_sound') }
+ },
+ {
+ val => N("Troubleshooting"), disabled => sub {},
+ clicked => sub { &trouble($in) }
+ },
+ );
+
+ my @messages = ("<b><i>" . $device->{description} . "</i></b>",
+ N("Your card uses the <b>\"%s\"</b> driver\n", $driver));
+
+ if ($warn_both) {
+ push @messages, ("<b>" . $warn_both . "</b>");
+ }
+ if (!$is_pipewire_available) {
+ push @messages, "<b>" . $warn_pipewire_unavailable . "</b>";
+ }
+ if ($driver eq 'unknown') {
+ if ($in->ask_from_({
+ title => N("No alternative driver"),
+ messages => N("There's no known OSS/ALSA alternative driver for your sound card (%s) which currently uses \"%s\"",
+ $device->{description}, $driver),
+ },
+ \@common,
+ )) {
+ $write_config->();
+ }
+ } elsif ($in->ask_from_({ title => N("Sound configuration"),
+ interactive_help_id => 'soundConfig',
+ messages => \@messages
+ },
+ \@common,
+ ))
+ {
+ $write_config->();
+ }
+ }
+}
+
+sub trouble {
+ my ($in) = @_;
+ $in->ask_warn(N("Sound troubleshooting"),
+ formatAlaTeX(
+ #-PO: keep the double empty lines between sections, this is formatted a la LaTeX
+ N("Below are some basic tips to help debug audio problems, but for accurate and up-to-date tips and tricks, please see:
+
+https://wiki.mageia.org/en/Support:DebuggingSoundProblems
+
+
+
+- General Recommendation: Enable PulseAudio. If you have opted to not to use PulseAudio, we would strongly advise you enable it. For the vast majority of desktop use cases, PulseAudio is the recommended and best supported option.
+
+
+
+- \"kmix\" (KDE), \"gnome-control-center sound\" (GNOME) and \"pavucontrol\" (generic) will launch graphical applications to allow you to view your sound devices and adjust volume levels
+
+
+- \"ps aux | grep pulseaudio\" will check that PulseAudio is running.
+
+
+- \"pactl stat\" will check that you can connect to the PulseAudio daemon correctly.
+
+
+- \"pactl list sink-inputs\" will tell you which programs are currently playing sound via PulseAudio.
+
+
+- \"systemctl status osspd.service\" will tell you the current state of the OSS Proxy Daemon. This is used to enable sound from legacy applications which use the OSS sound API. You should install the \"ossp\" package if you need this functionality.
+
+
+- \"pacmd ls\" will give you a LOT of debug information about the current state of your audio.
+
+
+- \"lspcidrake -v | grep -i audio\" will tell you which low-level driver your card uses by default.
+
+
+- \"/usr/sbin/lsmod | grep snd\" will enable you to check which sound related kernel modules (drivers) are loaded.
+
+
+- \"alsamixer -c 0\" will give you a text-based mixer to the low level ALSA mixer controls for first sound card
+
+
+- \"/usr/sbin/fuser -v /dev/snd/pcm* /dev/dsp\" will tell which programs are currently using the sound card directly (normally this should only show PulseAudio)
+")));
+}
+
+sub configure_one_sound_slot {
+ my ($modules_conf, $index, $driver) = @_;
+ $modules_conf->set_sound_slot("sound-slot-$index", $driver);
+ $modules_conf->set_options($driver, "xbox=1") if $driver eq "snd_intel8x0" && detect_devices::is_xbox();
+ $modules_conf->set_options('snd-ac97-codec', "power_save=1") if $driver =~ /^snd/ && detect_devices::isLaptop();
+}
+
+sub configure_sound_slots {
+ my ($modules_conf) = @_;
+ my $altered = 0;
+ each_index {
+ my $default_driver = $modules_conf->get_alias("sound-slot-$::i");
+ if (!member($default_driver, $_->{driver})) {
+ $altered ||= $default_driver;
+ configure_one_sound_slot($modules_conf, $::i, $_->{driver});
+ }
+ } detect_devices::getSoundDevices();
+ $modules_conf->write if $altered && $::isStandalone;
+}
+
+
+1;
diff --git a/perl-install/harddrake/v4l.pm b/perl-install/harddrake/v4l.pm
new file mode 100644
index 000000000..bd7c649bb
--- /dev/null
+++ b/perl-install/harddrake/v4l.pm
@@ -0,0 +1,496 @@
+package harddrake::v4l;
+
+use strict;
+
+use common;
+use detect_devices;
+use log;
+use modules;
+
+# please update me on bttv update :
+
+my $default = N("Auto-detect");
+# TODO: split %tuners_lst in per driver perl source files that get transformed in Storable files
+my %tuners_lst =
+ (
+ -1 => $default,
+ 0 => "Temic|PAL (4002 FH5)",
+ 1 => "Philips|PAL_I (FI1246 and compatibles)",
+ 2 => "Philips|NTSC (FI1236, FM1236 and compatibles)",
+ 3 => "Philips|(SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
+ 4 => "NoTuner",
+ 5 => "Philips|PAL_BG (FI1216 and compatibles)",
+ 6 => "Temic|NTSC (4032 FY5)",
+ 7 => "Temic|PAL_I (4062 FY5)",
+ 8 => "Temic|NTSC (4036 FY5)",
+ 9 => "Alps|HSBH1",
+ 10 => "Alps|TSBE1",
+ 11 => "Alps|TSBB5",
+ 12 => "Alps|TSBE5",
+ 13 => "Alps|TSBC5",
+ 14 => "Temic|PAL_BG (4006FH5)",
+ 15 => "Alps|TSCH6",
+ 16 => "Temic|PAL_DK (4016 FY5)",
+ 17 => "Philips|NTSC_M (MK2)",
+ 18 => "Temic|PAL_I (4066 FY5)",
+ 19 => "Temic|PAL* auto (4006 FN5)",
+ 20 => "Temic|PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
+ 21 => "Temic|NTSC (4039 FR5)",
+ 22 => "Temic|PAL/SECAM multi (4046 FM5)",
+ 23 => "Philips|PAL_DK (FI1256 and compatibles)",
+ 24 => "Philips|PAL/SECAM multi (FQ1216ME)",
+ 25 => "LG|PAL_I+FM (TAPC-I001D)",
+ 26 => "LG|PAL_I (TAPC-I701D)",
+ 27 => "LG|NTSC+FM (TPI8NSR01F)",
+ 28 => "LG|PAL_BG+FM (TPI8PSB01D)",
+ 29 => "LG|PAL_BG (TPI8PSB11D)",
+ 30 => "Temic|PAL* auto + FM (4009 FN5)",
+ 31 => "SHARP NTSC_JP (2U5JF5540)",
+ 32 => "Samsung|PAL TCPM9091PD27",
+ 33 => "MT20xx universal",
+ 34 => "Temic|PAL_BG (4106 FH5)",
+ 35 => "Temic|PAL_DK/SECAM_L (4012 FY5)",
+ 36 => "Temic|NTSC (4136 FY5)",
+ 37 => "LG|PAL (newer TAPC series)",
+ 38 => "Philips|PAL/SECAM multi (FM1216ME)",
+ 39 => "LG|NTSC (newer TAPC series)",
+ 40 => "HITACHI V7-J180AT",
+ 41 => "Philips|PAL_MK (FI1216 MK)",
+ 42 => "Philips|1236D ATSC/NTSC daul in",
+ 43 => "Philips|NTSC MK3 (FM1236MK3 or FM1236/F)",
+ 44 => "Philips|4 in 1 (ATI TV Wonder Pro/Conexant)",
+ 45 => "Microtune|4049 FM5",
+ 46 => "Panasonic VP27s/ENGE4324D",
+ 47 => "LG|NTSC (TAPE series)",
+ 48 => "Tena|TNF 8831 BGFF",
+ 49 => "Microtune|4042 FI5 ATSC/NTSC dual in",
+ 50 => "TCL 2002N",
+ 51 => "Philips|PAL/SECAM_D (FM 1256 I-H3)",
+ 52 => "Thomson|DDT 7610 (ATSC/NTSC)",
+ 53 => "Philips|FQ1286",
+ 54 => "tda8290+75",
+ 55 => "LG|PAL (TAPE series)",
+ 56 => "Philips|PAL/SECAM multi (FQ1216AME MK4)",
+ 57 => "Philips|FQ1236A MK4",
+ 58 => "Ymec|TVision|TVF-8531MF",
+ 59 => "Ymec|TVision|TVF-5533MF",
+ 60 => "Thomson|DDT 7611 (ATSC/NTSC)",
+ 61 => "Tena|TNF9533-D/IF/TNF9533-B/DF",
+ 62 => "Philips|TEA5767HN FM Radio",
+ 63 => "Philips|FMD1216ME MK3 Hybrid Tuner",
+ 64 => "LG|TDVS-H062F/TUA6034",
+ 65 => "Ymec|TVF66T5-B/DFF",
+ 66 => "LG|NTSC (TALN mini series)",
+ 67 => "Philips|TD1316 Hybrid Tuner",
+ 68 => "Philips|TUV1236D ATSC/NTSC dual in",
+ 69 => "Tena|TNF 5335 MF",
+ 70 => "Samsung|TCPN 2121P30A",
+ 71 => "Xceive xc3028",
+
+
+ );
+
+# Tweaked from Cardlist
+my $cards_lst = {
+ 'bttv' => {
+ $default => -1,
+ N("Unknown|Generic") => 0,
+ "M|Miro|PCTV" => 1,
+ "H|Hauppauge|bt848" => 2,
+ "S|STB|Hauppauge 878" => 3,
+ "I|Intel|Create and Share PCI (bttv type 4)" => 4,
+ "I|Intel|Smart Video Recorder III (bttv type 4)" => 4,
+ "D|Diamond DTV2000" => 5,
+ "A|AVerMedia|TVPhone" => 6,
+ "M|MATRIX Vision|MV-Delta" => 7,
+ "L|Lifeview|FlyVideo II (Bt848) LR26" => 8,
+ "G|Guillemot|MAXI TV Video PCI2 LR26" => 27,
+ "G|Genius/Kye Video Wonder Pro II (848 or 878)" => 8,
+ "I|IMS/IXmicro TurboTV" => 9,
+ "H|Hauppauge|bt878" => 10,
+ "M|Miro|PCTV pro" => 11,
+ "A|ADS Technologies|Channel Surfer TV (bt848)" => 12,
+ "A|AVerMedia|TVCapture 98" => 13,
+ "A|Aimslab|Video Highway Xtreme (VHX)" => 14,
+ "Zoltrix|TV-Max" => 15,
+ "P|Prolink|Pixelview PlayTV (bt878)" => 16,
+ "L|Leadtek|WinView 601" => 17,
+ "A|AVEC|Intercapture" => 18,
+ "L|Lifeview|FlyKit LR38 Bt848 (capture only)" => 19,
+ "L|Lifeview|FlyVideo II EZ" => 19,
+ "C|CEI Raffles Card" => 20,
+ "L|Lifeview|FlyVideo 98" => 21,
+ "L|Lucky Star Image World ConferenceTV LR50" => 21,
+ "A|Askey|CPH050" => 22,
+ "P|Phoebe Micro|Tv Master + FM" => 22,
+ "M|Modular|Technology MM205 PCTV (bt878)" => 23,
+ "A|Askey|CPH06X (bt878)" => 24,
+ "G|Guillemot|Maxi TV Video 3" => 24,
+ "A|Askey|CPH05X (bt878)" => 24,
+ N("Unknown|CPH05X (bt878) [many vendors]") => 24,
+ N("Unknown|CPH06X (bt878) [many vendors]") => 24,
+ "T|Terratec|Terra TV+ Version 1.0 (Bt848)" => 25,
+ "V|Vobis TV-Boostar" => 25,
+ "T|Terratec|TV-Boostar" => 25,
+ "H|Hauppauge|WinCam newer (bt878)" => 26,
+ "L|Lifeview|FlyVideo 98" => 27,
+ "G|Guillemot|MAXI TV Video PCI2 LR50" => 27,
+ "T|Terratec|TerraTV+" => 28,
+ "I|Imagenation PXC200" => 29,
+ "L|Lifeview|FlyVideo 98 LR50" => 30,
+ "Formac|iProTV" => 31,
+ "Formac|iProTV I (bt848)" => 31,
+ "I|Intel|Create and Share PCI (bttv type 32)" => 32,
+ "I|Intel|Smart Video Recorder III (bttv type 32)" => 32,
+ "T|Terratec|TerraTValue" => 33,
+ "L|Leadtek|WinFast TV 2000" => 34,
+ "L|Leadtek|WinFast VC 100" => 35,
+ "L|Lifeview|FlyVideo 98 LR50" => 35,
+ "C|Chronos Video Shuttle II" => 35,
+ "L|Lifeview|FlyVideo 98FM LR50" => 36,
+ "T|Typhoon|TView TV/FM Tuner" => 36,
+ "P|Prolink|PixelView PlayTV pro" => 37,
+ "P|Prolink|PixelView PlayTV Theater" => 37,
+ "A|Askey|CPH06X TView99" => 38,
+ "P|Pinnacle|PCTV Studio/Rave" => 39,
+ "S|STB|STB2 TV PCI FM, P/N 6000704" => 40,
+ "A|AVerMedia|TVPhone 98" => 41,
+ "P|ProVideo|PV951" => 42,
+ "L|Little OnAir TV" => 43,
+ "S|Sigma TVII-FM" => 44,
+ "M|MATRIX Vision|MV-Delta 2" => 45,
+ "Zoltrix|Genie TV/FM" => 46,
+ "T|Terratec|TV/Radio+" => 47,
+ "A|Askey|CPH03x" => 48,
+ "D|Dynalink Magic TView" => 48,
+ "I|IODATA|GV-BCTV3/PCI" => 49,
+ "P|Prolink|PixelView PlayTV PAK" => 50,
+ "L|Lenco|MXTV-9578 CP" => 50,
+ "P|Prolink|PV-BT878P+4E" => 50,
+ "L|Lenco|MXTV-9578CP (Bt878)" => 50,
+ "E|Eagle Wireless Capricorn2 (bt878A)" => 51,
+ "P|Pinnacle|PCTV Studio Pro" => 52,
+ "T|Typhoon|KNC1 TV Station RDS" => 53,
+ "T|Typhoon|TV Tuner RDS (black package)" => 53,
+ "T|Typhoon|TView RDS + FM Stereo" => 53,
+ "L|Lifeview|FlyVideo 2000" => 54,
+ "L|Lifeview|FlyVideo A2" => 54,
+ "L|Lifetec|LT 9415 TV [LR90]" => 54,
+ "A|Askey|CPH031" => 55,
+ "L|Lenco|MXR-9571 (Bt848)" => 55,
+ "Bestbuy|Easy TV" => 55,
+ "L|Lifeview|FlyVideo 98FM LR50" => 56,
+ "G|GrandTec|Grand Video Capture (Bt848)" => 57,
+ "A|Askey|CPH060" => 58,
+ "P|Phoebe Micro|TV Master Only (No FM)" => 58,
+ "A|Askey|CPH03x TV Capturer" => 59,
+ "M|Modular|Technology MM100 PCTV" => 60,
+ "A|AG|Electronics GMV1" => 61,
+ "A|Askey|CPH061" => 62,
+ "Bestbuy|Easy TV (bt878)" => 62,
+ "L|Lifetec|LT9306" => 62,
+ "M|Medion MD9306" => 62,
+ "A|ATI|TV-Wonder" => 63,
+ "A|ATI|TV-Wonder VE" => 64,
+ "L|Lifeview|FlyVideo 2000S LR90" => 65,
+ "T|Terratec|TValueRadio" => 66,
+ "I|IODATA|GV-BCTV4/PCI" => 67,
+ "3Dfx|VoodooTV FM (Euro)" => 68,
+ "3Dfx|VoodooTV 200 (USA)" => 68,
+ "A|Active|Imaging AIMMS" => 69,
+ "P|Prolink|Pixelview PV-BT878P+ (Rev.4C)" => 70,
+ "L|Lifeview|FlyVideo 98EZ (capture only) LR51" => 71,
+# "G|Genius/Kye|Video Wonder/Genius Internet Video Kit" => 71,
+ "P|Prolink|Pixelview PV-BT878P+ (Rev.9B) (PlayTV Pro rev.9B FM+NICAM)" => 72,
+ "T|Typhoon|TV Tuner Pal BG (blue package)" => 72,
+ "S|Sensoray 311" => 73,
+ "RemoteVision|MX (RV605)" => 74,
+ "P|Powercolor|MTV878" => 75,
+ "P|Powercolor|MTV878R" => 75,
+ "P|Powercolor|MTV878F" => 75,
+ "C|Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)" => 76,
+ "G|GrandTec|Multi Capture Card (Bt878)" => 77,
+ "Jetway TV/Capture JW-TV878-FBK" => 78,
+ "K|Kworld KW-TV878RF" => 78,
+ "D|DSP Design TCVIDEO" => 79,
+ "H|Hauppauge|WinTV PVR" => 80,
+ "G|GV-BCTV5/PCI" => 81,
+ "Osprey|100/150 (878)" => 82,
+ "Osprey|100/150 (848)" => 83,
+ "Osprey|101 (848)" => 84,
+ "Osprey|101/151" => 85,
+ "Osprey|101/151 w/ svid" => 86,
+ "Osprey|200/201/250/251" => 87,
+ "Osprey|200/250" => 88,
+ "Osprey|210/220" => 89,
+ "Osprey|500" => 90,
+ "Osprey|540" => 91,
+ "Osprey|2000" => 92,
+ "I|IDS Eagle" => 93,
+ "P|Pinnacle|PCTV Sat" => 94,
+ "Formac|ProTV II (bt878)" => 95,
+ "M|MachTV" => 96,
+ "E|Euresys|Picolo" => 97,
+ "P|ProVideo|PV150" => 98,
+ "A|AD-TVK503" => 99,
+ "H|Hercules Smart TV Stereo" => 100,
+ "P|Pace TV & Radio Card" => 101,
+ "I|IVC|200" => 102,
+ "G|GrandTec|Grand X-Guard / Trust 814PCI" => 103,
+ "N|Nebula Electronics DigiTV" => 104,
+ "P|ProVideo|PV143" => 105,
+ "P|PHYTEC|VD-009-X1 MiniDIN (bt878)" => 106,
+ "P|PHYTEC|VD-009-X1 Combi (bt878)" => 107,
+ "P|PHYTEC|VD-009 MiniDIN (bt878)" => 108,
+ "P|PHYTEC|VD-009 Combi (bt878)" => 109,
+ "I|IVC|100" => 110,
+ "I|IVC|120G" => 111,
+ "P|pcHDTV HD-2000 TV" => 112,
+ "T|Twinhan DST + clones" => 113,
+ "L|Leadtek|Winfast VC100" => 114,
+ "T|Teppro TEV-560/InterVision IV-560" => 115,
+ "S|SIMUS GVC1100" => 116,
+ "N|NGS NGSTV+" => 117,
+ "L|LMLBT4" => 118,
+ "T|Tekram M205 PRO" => 119,
+ "C|Conceptronic|CONTVFMi" => 120,
+ "E|Euresys|Picolo Tetra" => 121,
+ "S|Spirit TV Tuner" => 122,
+ "A|AverMedia|AVerTV DVB-T 771" => 123,
+ "A|AverMedia|AverTV DVB-T 761" => 124,
+ "M|MATRIX Vision|Sigma-SQ" => 125,
+ "M|MATRIX Vision|Sigma-SLC" => 126,
+ "A|APAC Viewcomp 878(AMAX)" => 127,
+ "D|DViCO|FusionHDTV DVB-T Lite" => 128,
+ "V|V-Gear MyVCD" => 129,
+ "S|Super TV Tuner" => 130,
+ "T|Tibet Systems 'Progress DVR' CS16" => 131,
+ "K|Kodicom|4400R (master)" => 132,
+ "K|Kodicom|4400R (slave)" => 133,
+ "A|Adlink|RTV24" => 134,
+ "D|DViCO|FusionHDTV 5 Lite" => 135,
+ "A|Acorp|Y878F" => 136,
+ "C|Conceptronic|CTVFMi v2" => 137,
+ "P|Prolink|Pixelview PV-BT878P+ (Rev.2E)" => 138,
+ "P|Prolink|PixelView PlayTV MPEG2 PV-M4900" => 139,
+ "Osprey|440" => 140,
+ "A|Asound|Skyeye PCTV" => 141,
+ "S|Sabrent TV-FM (bttv version)" => 142,
+ "H|Hauppauge|ImpactVCB (bt878)" => 143,
+ "M|MagicTV" => 144,
+
+ },
+
+ 'cx88' => {
+ N("Unknown|Generic") => 0,
+ "Hauppauge|WinTV 34xxx models" => 1,
+ "GDI Black Gold" => 2,
+ "PixelView|???" => 3,
+ "ATI|TV Wonder Pro" => 4,
+ "Leadtek|Winfast 2000XP Expert" => 5,
+ "AVerTV|Studio 303 (M126) " => 6,
+ 'MSI|TV-@nywhere Master' => 7,
+ "Leadtek|Winfast DV2000" => 8,
+ "Leadtek|PVR 2000" => 9,
+ "IODATA|GV-VCP3/PCI" => 10,
+ "Prolink PlayTV PVR" => 11,
+ "ASUS PVR-416" => 12,
+ 'MSI|TV-@nywhere' => 13,
+ "VStream|XPert DVB-T" => 14,
+ "KWorld|XPert DVB-T" => 14,
+ "DViCO|FusionHDTV DVB-T1" => 15,
+ "KWorld|LTV883RF" => 16,
+ "DViCO|FusionHDTV 3 Gold" => 17,
+ "Hauppauge|Nova-T DVB-T" => 18,
+ "Conexant DVB-T reference design" => 19,
+ "Provideo PV259" => 20,
+ "DViCO|FusionHDTV DVB-T Plus" => 21,
+ "digitalnow|DNTV Live! DVB-T" => 22,
+ "pcHDTV HD3000 HDTV" => 23,
+ "Hauppauge|WinTV 28xxx (Roslyn) models" => 24,
+ "Digital-Logic MICROSPACE Entertainment Center (MEC)" => 25,
+ "IODATA|GV/BCTV7E" => 26,
+ "PixelView|PlayTV Ultra Pro (Stereo)" => 27,
+ "DViCO|FusionHDTV 3 Gold-T" => 28,
+ "ADS Tech Instant TV DVB-T PCI" => 29,
+ "TerraTec Cinergy 1400 DVB-T" => 30,
+ "DViCO|FusionHDTV 5 Gold" => 31,
+ "AverMedia UltraTV Media Center PCI 550" => 32,
+ "KWorld|V-Stream Xpert DVD" => 33,
+ "ATI|HDTV Wonder" => 34,
+ "WinFast DTV1000-T" => 35,
+ "AVerTV|303 (M126)" => 36,
+ "Hauppauge|Nova-S-Plus DVB-S" => 37,
+ "Hauppauge|Nova-SE2 DVB-S" => 38,
+ "KWorld|VB-S 100" => 39,
+ "Hauppauge|WinTV-HVR1100 DVB-T/Hybrid" => 40,
+ "Hauppauge|WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]" => 41,
+ "digitalnow|DNTV Live! DVB-T Pro" => 42,
+ "VStream|XPert DVB-T with cx22702" => 43,
+ "KWorld|XPert DVB-T with cx22702" => 43,
+ "DViCO|FusionHDTV DVB-T Dual Digital" => 44,
+ "KWorld|HardwareMpegTV XPert" => 45,
+
+ },
+
+ 'saa7134' => {
+ N("Unknown|Generic") => 0,
+ "Proteus Pro [philips reference design]" => 1,
+ "LifeView|FlyVIDEO3000" => 2,
+ "LifeView|FlyVIDEO2000" => 3,
+ "EMPRESS" => 4,
+ "SKNet|Monster TV" => 5,
+ "Tevion|MD 9717" => 6,
+ "KNC|One TV-Station RDS" => 7,
+ "Typhoon|TV Tuner RDS" => 7,
+ "Terratec|Cinergy 400 TV" => 8,
+ "Medion|5044" => 9,
+ "Kworld|SAA7130-TVPCI" => 10,
+ "KuroutoShikou SAA7130-TVPCI" => 10,
+ "Terratec|Cinergy 600 TV" => 11,
+ "Medion|7134" => 12,
+ "Typhoon|TV+Radio 90031" => 13,
+ "ELSA|EX-VISION 300TV" => 14,
+ "ELSA|EX-VISION 500TV" => 15,
+ "ASUS|TV-FM 7134" => 16,
+ "AOPEN VA1000 POWER" => 17,
+ "BMK|MPEX No Tuner" => 18,
+ "Compro|VideoMate TV" => 19,
+ "Matrox CronosPlus" => 20,
+ "10MOONS PCI TV CAPTURE CARD" => 21,
+ "Medion|2819" => 22,
+ "AverMedia|M156" => 22,
+ "BMK|MPEX Tuner" => 23,
+ "KNC|One TV-Station DVR" => 24,
+ "ASUS|TV-FM 7133" => 25,
+ "Pinnacle|PCTV Stereo (saa7134)" => 26,
+ "Manli|MuchTV M-TV002/Behold TV 403 FM" => 27,
+ "Manli|MuchTV M-TV001/Behold TV 401" => 28,
+ "Nagase Sangyo TransGear 3000TV" => 29,
+ "Elitegroup|ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)" => 30,
+ "Elitegroup|ECS TVP3XP FM1236 Tuner Card (NTSC,FM)" => 31,
+ "AVACS SmartTV" => 32,
+ "AverMedia|DVD EZMaker" => 33,
+ "Noval Prime TV 7133" => 34,
+ "AverMedia|AverTV Studio 305" => 35,
+ "UPMOST PURPLE TV" => 36,
+ "Items MuchTV Plus / IT-005" => 37,
+ "Terratec|Cinergy 200 TV" => 38,
+ "LifeView|FlyTV Platinum Mini" => 39,
+ "Compro|VideoMate TV PVR/FM" => 40,
+ "Compro|VideoMate TV Gold+" => 41,
+ "Sabrent SBT-TVFM (saa7130)" => 42,
+ "Zolid Xpert TV7134" => 43,
+ "Empire PCI TV-Radio LE" => 44,
+ "AverMedia|AVerTV Studio 307" => 45,
+ "AverMedia|Cardbus TV/Radio" => 46,
+ "Terratec|Cinergy 400 mobile" => 47,
+ "Terratec|Cinergy 600 TV MK3" => 48,
+ "Compro|VideoMate Gold+ Pal" => 49,
+ "Pinnacle|PCTV 300i DVB-T + PAL" => 50,
+ "ProVideo PV952" => 51,
+ "AverMedia|AverTV/305" => 52,
+ "ASUS|TV-FM 7135" => 53,
+ "LifeView|FlyTV Platinum FM" => 54,
+ "LifeView|FlyDVB-T DUO" => 55,
+ "AverMedia|AVerTV 307" => 56,
+ "AverMedia|AVerTV GO 007 FM" => 57,
+ "ADS Tech Instant TV (saa7135)" => 58,
+ "Kworld|V-Stream Xpert TV PVR7134" => 59,
+ "Tevion|V-Stream Xpert TV PVR7134" => 59,
+ "Typhoon|DVB-T Duo Digital/Analog Cardbus" => 60,
+ "Philips|TOUGH DVB-T reference design" => 61,
+ "Compro|VideoMate TV Gold+II" => 62,
+ "Kworld|Xpert TV PVR7134" => 63,
+ "FlyTV mini Asus Digimatrix" => 64,
+ "Kworld|V-Stream Studio TV Terminator" => 65,
+ "Yuan TUN-900 (saa7135)" => 66,
+ "Beholder BeholdTV 409 FM" => 67,
+ "GoTView 7135 PCI" => 68,
+ "Philips|EUROPA V3 reference design" => 69,
+ "Compro|Videomate DVB-T300" => 70,
+ "Compro|Videomate DVB-T200" => 71,
+ "RTD|Embedded Technologies VFG7350" => 72,
+ "RTD|Embedded Technologies VFG7330" => 73,
+ "LifeView|FlyTV Platinum Mini2" => 74,
+ "AverMedia|AVerTVHD MCE A180" => 75,
+ "SKNet|MonsterTV Mobile" => 76,
+ "Pinnacle|PCTV 40i/50i/110i (saa7133)" => 77,
+ "ASUSTeK P7131 Dual" => 78,
+ "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)" => 79,
+ "ASUS|Digimatrix TV" => 80,
+ "Philips|Tiger reference design" => 81,
+ 'MSI TV@Anywhere plus' => 82,
+ "Terratec|Cinergy 250 PCI TV" => 83,
+ "LifeView|FlyDVB Trio" => 84,
+ "AverTV DVB-T 777" => 85,
+ "LifeView|FlyDVB-T" => 86,
+ "ADS Instant TV Duo Cardbus PTV331" => 87,
+ "Tevion|DVB-T 220RF" => 88,
+ "ELSA|EX-VISION 700TV" => 89,
+ "Kworld|ATSC110" => 90,
+
+ }
+};
+
+my %pll_lst =
+ (
+ -1 => N("Default"),
+ 0 => "do not use pll",
+ 1 => "28 Mhz Crystal (X)",
+ 2 => "35 Mhz Crystal"
+ );
+
+sub config {
+ my ($in, $modules_conf, $driver) = @_;
+
+ my $min_gbuffers = 2;
+ my $max_gbuffers = 32;
+
+ my %conf = (gbuffers => 4, card => $default, tuner => -1, radio => 0, pll => -1);
+
+ return if !$cards_lst->{$driver};
+ my %cards_list = %{$cards_lst->{$driver}};
+ my %rvs_cards_list = reverse %cards_list;
+
+ # get the existing options (if there are any)
+ my $current = $modules_conf->get_options($driver);
+
+ foreach (split(/\s+/,$current)) {
+ $conf{$1} = $2 if /^(gbuffers|tuner|radio|pll)=(.+)/;
+ $conf{$1} = $rvs_cards_list{$2} if /^(card)=(.+)/;
+ }
+
+ #Sanity checks on defaults
+ $conf{gbuffers} = max($min_gbuffers, $conf{gbuffers});
+ $conf{gbuffers} = min($max_gbuffers, $conf{gbuffers});
+ $conf{card} = $default if !defined $cards_list{$conf{card}};
+ $conf{tuner} = -1 if !defined $tuners_lst{$conf{tuner}};
+ if ($driver eq 'bttv') {
+ $conf{pll} = -1 if !defined $pll_lst{$conf{tuner}};
+ $conf{radio} = 0 if $conf{radio} !~ /(0|1)/;
+ }
+
+
+ if ($in->ask_from("BTTV configuration", N("For most modern TV cards, the bttv module of the GNU/Linux kernel just auto-detect the rights parameters.
+If your card is misdetected, you can force the right tuner and card types here. Just select your TV card parameters if needed."),
+ [
+ { label => N("Card model:"), val => \$conf{card}, list => [ keys %cards_list ], default => -1, sort =>1, separator => '|' },
+ { label => N("Tuner type:"), val => \$conf{tuner}, list => [keys %tuners_lst], format => sub { $tuners_lst{$_[0]} }, sort => 1, separator => '|' },
+ ]
+ ))
+ {
+ $conf{card} = $cards_list{$conf{card}};
+ if (my $options = join(' ', if_($driver eq 'bttv', 'radio=' . ($conf{radio} ? 1 : 0)), map { if_($conf{$_} ne -1, "$_=$conf{$_}") } qw(card pll tuner gbuffers))) {
+ log::l(qq([harddrake::v4l] set "$options" options for $driver));
+# log::explanations("modified file /etc/modprobe.conf ($options)") if $::isStandalone;
+ $modules_conf->set_options($driver, $options);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+
+1;