summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Xconfig/glx.pm272
1 files changed, 272 insertions, 0 deletions
diff --git a/lib/Xconfig/glx.pm b/lib/Xconfig/glx.pm
new file mode 100644
index 0000000..35ad413
--- /dev/null
+++ b/lib/Xconfig/glx.pm
@@ -0,0 +1,272 @@
+package Xconfig::glx;
+
+use diagnostics;
+use strict;
+
+use common;
+use any;
+
+my $compositing_server_config = '/etc/sysconfig/compositing-server';
+my $compositing_wm_config = '/etc/sysconfig/compositing-wm';
+
+our @gl_compositing_types = (
+ {
+ type => "none",
+ name => N_("No 3D desktop effects"),
+ },
+ {
+ type => "metisse",
+ name => N_("Metisse"),
+ methods => [ qw(Xmetisse) ],
+ wms => [ qw(metisse-start-fvwm) ],
+ },
+ {
+ type => "cube",
+ name => N_("3D desktop (cube workspace)"),
+ methods => [ qw(native Xgl) ],
+ wms => [ qw(compiz beryl) ],
+ },
+);
+
+our @gl_compositing_servers = (
+ {
+ method => "native",
+ name => N_("native support"),
+ packages => [],
+ description => N_("Some drivers provide native support for OpenGL compositing (using AIGLX for example). If your system supports it, it is the preferred solution."),
+ },
+ {
+ method => "Xgl",
+ name => "Xgl",
+ packages => [ 'x11-server-xgl' ],
+ description => N_("Xgl is an additional graphical server that adds 3D desktop support."),
+ },
+ {
+ method => "Xmetisse",
+ name => "Metisse (experimental)",
+ packages => [ 'x11-server-xmetisse' ],
+ description => N_("Metisse is an experimental X-based window system."),
+ },
+);
+
+our @gl_compositing_wms = (
+ {
+ wm => 'compiz',
+ configuration_tool => 'gset-compiz',
+ packages => [ 'compiz', 'compiz-decorator-gtk', 'gset-compiz' ],
+ desktop_packages => {
+ KDE => [ 'compiz-decorator-kde' ],
+ },
+ name => 'Compiz',
+ description => N_("Compiz is the reference compositing window manager."),
+ },
+ {
+ wm => 'beryl',
+ configuration_tool => 'beryl-settings',
+ packages => [ 'beryl-core', 'beryl-manager' ],
+ desktop_packages => {
+ KDE => [ 'aquamarine' ],
+ GNOME => [ 'heliodor' ],
+ },
+ name => 'Beryl',
+ description => N_("Beryl is a fork of compiz and provides bleeding-edge features."),
+ },
+ {
+ wm => 'metisse-start-fvwm',
+ configuration_tool => '',
+ packages => [ 'metisse' ],
+ name => 'Metisse FVWM',
+ description => N_("Metisse FVWM is a FVWM window manager modified for Metisse."),
+ },
+);
+
+sub parse_glxinfo {
+ my (%options) = @_;
+
+ my $glx_info = {};
+ my $extensions_section;
+
+ my @glxinfo = $options{file} ? cat_($options{file}) : do {
+ require run_program;
+ my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
+ local $ENV{LD_LIBRARY_PATH} = $options{Mesa} && "/usr/$lib/mesa";
+ run_program::rooted_get_stdout($::prefix, '/usr/bin/glxinfo', '2>', '/dev/null');
+ };
+ foreach (@glxinfo) {
+ chomp;
+ if (/^direct rendering: Yes/) {
+ $glx_info->{capabilities}{direct_rendering} = 1;
+ } elsif (my ($type, $value) = /^(.*) string: (.*)$/) {
+ $type =~ s/\s/_/g;
+ $glx_info->{strings}{$type} = $value;
+ } elsif (/^(.*) extensions:/) {
+ $extensions_section = $1;
+ $extensions_section =~ s/\s/_/g;
+ } elsif (/^\s/) {
+ if ($extensions_section) {
+ push @{$glx_info->{extensions}{$extensions_section}}, grep { $_ } split(/,?\s+/);
+ }
+ } else {
+ undef $extensions_section;
+ }
+ }
+ $glx_info;
+}
+
+my @glx_blacklist = qw(nv sis tdfx vmware);
+
+sub is_in_metisse() {
+ my $display = $ENV{DISPLAY};
+ $display =~ s/\..*//;
+ $display && any {
+ member($display, split("\0", cat_("/proc/" . $_ . "/cmdline")));
+ } fuzzy_pidofs("Xmetisse");
+}
+
+sub get_glx_status {
+ my ($o_mesa_file, $o_system_file) = @_;
+
+ my ($driver, $resolution);
+ require Xconfig::xfree;
+ eval {
+ my $raw_X = Xconfig::xfree->read;
+ $driver = $raw_X->get_Driver;
+ $resolution = $raw_X->get_resolution;
+ };
+ $resolution ||= {};
+ member($driver, @glx_blacklist) and return {};
+
+ my ($mesa_glx_info, $system_glx_info);
+ if ($o_mesa_file) {
+ $mesa_glx_info = parse_glxinfo(file => $o_mesa_file);
+ $system_glx_info = $o_system_file ? parse_glxinfo(file => $o_system_file) : $mesa_glx_info;
+ } else {
+ $system_glx_info = parse_glxinfo();
+ $mesa_glx_info = parse_glxinfo(Mesa => 1);
+ }
+
+ my $glx_status = {};
+
+ $glx_status->{context}{Mesa} = $system_glx_info->{strings}{OpenGL_renderer} =~ /Mesa/;
+ $glx_status->{context}{MesaDRI} = $system_glx_info->{strings}{OpenGL_renderer} =~ /Mesa DRI/;
+ $glx_status->{context}{Xgl} =
+ $system_glx_info->{strings}{server_glx_vendor} eq 'SGI' &&
+ member('GLX_EXT_texture_from_pixmap', @{$mesa_glx_info->{extensions}{GLX}}) && (
+ #- avoid nv, but detect i810 and fglrx
+ member('GL_ARB_fragment_program', @{$mesa_glx_info->{extensions}{OpenGL}}) ||
+ !$glx_status->{context}{Mesa} && member('GLX_SGIX_fbconfig', @{$system_glx_info->{extensions}{GLX}})
+ );
+ $glx_status->{context}{Xmetisse} = is_in_metisse();
+
+ $glx_status->{capabilities}{direct_rendering} =
+ $system_glx_info->{capabilities}{direct_rendering} ||
+ $glx_status->{context}{Xgl} ||
+ $glx_status->{context}{Xmetisse};
+
+ $glx_status->{capabilities}{Xgl} =
+ $glx_status->{context}{Xgl} ||
+ $glx_status->{capabilities}{direct_rendering} && (
+ !$glx_status->{context}{MesaDRI} ||
+ member('GLX_MESA_allocate_memory', @{$system_glx_info->{extensions}{GLX}})
+ ) && (
+ #- Xgl turns black with i810 and 16 bits
+ $driver ne 'i810' || $resolution->{Depth} eq '24'
+ );
+
+ $glx_status->{capabilities}{native} =
+ $glx_status->{capabilities}{direct_rendering} &&
+ member('GLX_EXT_texture_from_pixmap', @{$system_glx_info->{extensions}{client_glx}}) &&
+ member('GLX_EXT_texture_from_pixmap', @{$system_glx_info->{extensions}{server_glx}});
+
+ $glx_status->{capabilities}{Xmetisse} = $glx_status->{capabilities}{direct_rendering};
+
+ #- no support in configuration tools yet
+ # $glx_status->{capabilities}{'3d-desktop'} = $glx_status->{capabilities}{direct_rendering};
+
+ $glx_status;
+}
+
+sub detect() {
+ my $compositing_server = +{ getVarsFromSh($::prefix . $compositing_server_config) };
+ my $compositing_wm = +{ getVarsFromSh($::prefix . $compositing_wm_config) };
+ my $glx = { capabilities => get_glx_status()->{capabilities} };
+ $glx->{supported} = $glx->{capabilities}{direct_rendering};
+ $glx->{compositing} = $compositing_wm->{COMPOSITING_WM_START} eq 'yes' || $compositing_wm->{COMPOSITING_WM_START} eq 'auto' && $glx->{supported};
+ $glx->{wm} = $compositing_wm->{COMPOSITING_WM};
+ $glx->{method} =
+ $glx->{compositing} ? (
+ $glx->{capabilities}{native} && member($compositing_server->{COMPOSITING_SERVER_START}, qw(auto no)) && !$compositing_server->{COMPOSITING_SERVER} ?
+ 'native' :
+ $glx->{capabilities}{Xgl} && member($compositing_server->{COMPOSITING_SERVER_START}, qw(auto yes)) && $compositing_server->{COMPOSITING_SERVER} eq 'Xgl' ?
+ 'Xgl' :
+ $glx->{capabilities}{Xmetisse} && member($compositing_server->{COMPOSITING_SERVER_START}, qw(auto yes)) && $compositing_server->{COMPOSITING_SERVER} eq 'Xmetisse' ?
+ 'Xmetisse' :
+ ''
+ ) : '';
+ $glx;
+}
+
+sub detect_may_install {
+ my ($in) = @_;
+ $in->do_pkgs->ensure_is_installed('mesa-demos', '/usr/bin/glxinfo') or return;
+ Xconfig::glx::detect();
+}
+
+sub detect_types {
+ my ($glx) = @_;
+ my @available_types = (
+ grep {
+ !$_->{methods} ||
+ any { $glx->{capabilities}{$_} } @{$_->{methods}};
+ } @gl_compositing_types
+ );
+ my $type = find { member($glx->{method}, @{$_->{methods}}) } @available_types;
+ \@available_types, $type;
+}
+
+sub choose_interactive {
+ my ($in, $glx) = @_;
+
+ my ($available, $type) = detect_types($glx);
+
+ $in->ask_from_({ title => N("3D Desktop effects") }, [
+ { label => N("3D Desktop effects"), title => 1 },
+ if_(!$glx->{supported},
+ { label => N("Your system does not support 3D desktop effects.") }),
+ { type => 'list', val => \$type, allow_empty_list => 1,
+ list => $available, format => sub { translate($_[0]{name}) } },
+ ]) or return;
+
+ $glx->{method} = find { $glx->{capabilities}{$_} } @{$type->{methods}};
+ $glx->{wm} = first(@{$type->{wms}});
+
+ 1;
+}
+
+sub install {
+ my ($in, $glx) = @_;
+ my $server = find { $_->{method} eq $glx->{method} } @gl_compositing_servers;
+ my $wm = find { $_->{wm} eq $glx->{wm} } @gl_compositing_wms;
+ my @sessions = any::sessions();
+ my @packages = map {
+ my $entry = $_;
+ @{$entry->{packages}},
+ map { @{$entry->{desktop_packages}{$_} || []} } @sessions;
+ } grep { $_ } $server, $wm;
+ $in->do_pkgs->ensure_are_installed(\@packages);
+}
+
+sub write {
+ my ($glx) = @_;
+ my $server_start = member($glx->{method}, 'Xgl', 'Xmetisse');
+ addVarsInSh($::prefix . $compositing_server_config, {
+ COMPOSITING_SERVER_START => bool2yesno($server_start),
+ COMPOSITING_SERVER => $server_start && $glx->{method},
+ });
+ addVarsInSh($::prefix . $compositing_wm_config, {
+ COMPOSITING_WM_START => bool2yesno(member($glx->{method}, qw(native Xgl Xmetisse))),
+ COMPOSITING_WM => $glx->{wm},
+ });
+}
+
+1;