Merge lp:~didrocks/unity/exit-on-soft-acceleration into lp:unity

Proposed by Didier Roche-Tolomelli
Status: Merged
Merged at revision: 528
Proposed branch: lp:~didrocks/unity/exit-on-soft-acceleration
Merge into: lp:unity
Diff against target: 169 lines (+138/-0)
1 file modified
targets/mutter/main.c (+138/-0)
To merge this branch: bzr merge lp:~didrocks/unity/exit-on-soft-acceleration
Reviewer Review Type Date Requested Status
Neil J. Patel (community) Approve
Review via email: mp+36224@code.launchpad.net

Description of the change

This branch fixes bug #614088:
it detects if software acceleration rather than hw is available and if so, try to logout from the session after a dialog prompt, changing the selected session in gdm to gnome.

To post a comment you must log in.
Revision history for this message
Neil J. Patel (njpatel) wrote :

Code looks good, approved!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'targets/mutter/main.c'
2--- targets/mutter/main.c 2010-07-20 13:07:00 +0000
3+++ targets/mutter/main.c 2010-09-21 21:54:40 +0000
4@@ -22,6 +22,9 @@
5 #include <glib.h>
6 #include <gdk/gdk.h>
7 #include <gdk/gdkx.h>
8+#include <dbus/dbus-glib.h>
9+
10+#include <GL/gl.h>
11 #include <clutter/x11/clutter-x11.h>
12
13 #include "unity-mutter.h"
14@@ -63,6 +66,10 @@
15
16 static void unity_mutter_constructed (GObject *object);
17
18+static void change_user_session (const char *session_name);
19+static gboolean session_logout_success (void);
20+static gboolean rendering_available (void);
21+
22 static void unity_mutter_minimize (MutterPlugin *self,
23 MutterWindow *window);
24 static void unity_mutter_maximize (MutterPlugin *self,
25@@ -128,6 +135,15 @@
26 {
27 UnityMutter *self = UNITY_MUTTER (object);
28
29+ if (!rendering_available ())
30+ {
31+ g_warning ("No rendering avaible for unity, prompting for changing session");
32+ change_user_session ("gnome");
33+ // if we can't logout, fallback to trying to run unity...
34+ if (session_logout_success ())
35+ exit (0); // 0 or will be respawn as required_component
36+ }
37+
38 self->plugin = unity_plugin_new ();
39 g_signal_connect (self->plugin, "restore-input-region",
40 G_CALLBACK (on_restore_input_region), self);
41@@ -136,6 +152,128 @@
42 }
43
44 static void
45+change_user_session (const char *session_name)
46+{
47+
48+ GKeyFile *key_file;
49+ GError *error;
50+ char *filename;
51+ gsize length;
52+ gchar *contents;
53+
54+ filename = g_build_filename (g_get_home_dir(), ".dmrc", NULL);
55+ error = NULL;
56+
57+ key_file = g_key_file_new ();
58+ g_key_file_load_from_file (key_file, filename,
59+ G_KEY_FILE_KEEP_COMMENTS |
60+ G_KEY_FILE_KEEP_TRANSLATIONS,
61+ NULL);
62+ g_key_file_set_string (key_file, "Desktop", "Session",
63+ session_name);
64+
65+ contents = g_key_file_to_data (key_file, &length, &error);
66+ if (contents == NULL)
67+ {
68+ g_debug ("Can't create content for .dmrc file: %s", error->message);
69+ g_key_file_free (key_file);
70+ g_free (filename);
71+ return;
72+ }
73+
74+ if (!g_file_set_contents (filename, contents, length, &error))
75+ {
76+ g_debug ("Can't update .dmrc file: %s", error->message);
77+ g_error_free (error);
78+ }
79+
80+ g_free (contents);
81+ g_key_file_free (key_file);
82+ g_free (filename);
83+
84+}
85+
86+static gboolean
87+session_logout_success (void)
88+{
89+ GtkWidget* dialog_warn_logout;
90+ gint response;
91+
92+ dialog_warn_logout = gtk_message_dialog_new (NULL,
93+ GTK_DIALOG_MODAL,
94+ GTK_MESSAGE_WARNING,
95+ GTK_BUTTONS_OK,
96+ _("No required driver detected for unity."),
97+ NULL);
98+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG(dialog_warn_logout),
99+ _("You will need to choose the Ubuntu Desktop session once you select your user name."));
100+ response = gtk_dialog_run (GTK_DIALOG(dialog_warn_logout));
101+ gtk_widget_destroy (dialog_warn_logout);
102+
103+ if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_DELETE_EVENT)
104+ {
105+ DBusGConnection * sbus;
106+ DBusGProxy * sm_proxy;
107+ GError * error = NULL;
108+ gboolean res = FALSE;
109+
110+ sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
111+ if (sbus == NULL)
112+ {
113+ g_warning ("Unable to get DBus session bus.");
114+ return FALSE;
115+ }
116+ sm_proxy = dbus_g_proxy_new_for_name_owner (sbus,
117+ "org.gnome.SessionManager",
118+ "/org/gnome/SessionManager",
119+ "org.gnome.SessionManager",
120+ &error);
121+ if (sm_proxy == NULL)
122+ {
123+ g_warning ("Unable to get DBus proxy to SessionManager interface: %s", error->message);
124+ g_error_free (error);
125+ return FALSE;
126+ }
127+ g_clear_error (&error);
128+
129+ res = dbus_g_proxy_call_with_timeout (sm_proxy, "Logout", INT_MAX, &error,
130+ G_TYPE_UINT, 1, G_TYPE_INVALID, G_TYPE_INVALID);
131+ if (!res)
132+ {
133+ if (error != NULL)
134+ g_warning ("SessionManager action failed: %s", error->message);
135+ else
136+ g_warning ("SessionManager action failed: unknown error");
137+
138+ g_object_unref(sm_proxy);
139+ g_error_free(error);
140+ return FALSE;
141+ }
142+
143+ g_object_unref(sm_proxy);
144+ g_warning ("logout");
145+ return TRUE;
146+ }
147+ g_warning ("Logout denied, trying to start unity");
148+ return FALSE;
149+}
150+
151+/* take an optimistic approach: only return FALSE when we are sure it's FALSE */
152+static gboolean
153+rendering_available (void)
154+{
155+ gchar *renderer = NULL;
156+ const char *glRenderer = (const char *) glGetString(GL_RENDERER);
157+ renderer = g_ascii_strdown (glRenderer, -1);
158+ g_debug ("OpenGL renderer string: %s\n", glRenderer);
159+
160+ if (renderer && strstr (renderer, "software"))
161+ return FALSE;
162+
163+ return TRUE;
164+}
165+
166+static void
167 on_restore_input_region (UnityPlugin *plugin, gboolean fullscreen)
168 {
169 MutterPlugin *self;