Mageia Bugzilla – Attachment 3278 Details for
Bug 8073
Shutdown & Reboot missing from logout menu in LXDE
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
New Account
|
Forgot Password
[patch]
lxsession logind patch
lxsession-0.4.6.1-logind-support.patch (text/plain), 19.97 KB, created by
Jérôme Dern
on 2012-12-22 15:02:33 CET
(
hide
)
Description:
lxsession logind patch
Filename:
MIME Type:
Creator:
Jérôme Dern
Created:
2012-12-22 15:02:33 CET
Size:
19.97 KB
patch
obsolete
>diff -uNr lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.c lxsession-0.4.6.1/lxsession-logout/dbus-interface.c >--- lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.c 2011-07-27 21:26:36.000000000 +0200 >+++ lxsession-0.4.6.1/lxsession-logout/dbus-interface.c 2012-12-22 14:28:38.647031221 +0100 >@@ -51,13 +51,20 @@ > char * dbus_HAL_Reboot(void); > char * dbus_HAL_Suspend(void); > char * dbus_HAL_Hibernate(void); >+gboolean dbus_logind_CanPowerOff(void); >+gboolean dbus_logind_CanReboot(void); >+gboolean dbus_logind_CanSuspend(void); >+gboolean dbus_logind_CanHibernate(void); >+char * dbus_logind_PowerOff(void); >+char * dbus_logind_Reboot(void); >+char * dbus_logind_Suspend(void); >+char * dbus_logind_Hibernate(void); >+char * dbus_LXDE_Logout(void); > /* End FORWARDS */ > > /* Connect to the system bus. Once a connection is made, it is saved for reuse. */ >-static DBusConnection * dbus_connect(void) >+static DBusConnection * dbus_connect_system(void) > { >- if ((dbus_context.connection == NULL) && ( ! dbus_context.connection_tried)) >- { > DBusError error; > dbus_error_init(&error); > dbus_context.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); >@@ -67,16 +74,57 @@ > dbus_error_free(&error); > } > dbus_context.connection_tried = TRUE; >- } > > return dbus_context.connection; > } > >+static DBusConnection * dbus_connect_session(void) >+{ >+ DBusError error; >+ dbus_error_init(&error); >+ dbus_context.connection = dbus_bus_get(DBUS_BUS_SESSION, &error); >+ if (dbus_context.connection == NULL) >+ { >+ g_warning(G_STRLOC ": Failed to connect to the session message bus: %s", error.message); >+ dbus_error_free(&error); >+ } >+ dbus_context.connection_tried = TRUE; >+ >+ return dbus_context.connection; >+} >+ >+ > /* Send a message. */ >-static DBusMessage * dbus_send_message(DBusMessage * message, char * * error_text) >+static DBusMessage * dbus_send_message_system(DBusMessage * message, char * * error_text) > { > /* Get a connection handle. */ >- DBusConnection * connection = dbus_connect(); >+ DBusConnection * connection = dbus_connect_system(); >+ if (connection == NULL) >+ return FALSE; >+ >+ /* Send the message. */ >+ DBusError error; >+ dbus_error_init(&error); >+ DBusMessage * reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT, &error); >+ dbus_message_unref(message); >+ if (reply == NULL) >+ { >+ if ((error.name == NULL) || (strcmp(error.name, DBUS_ERROR_NO_REPLY) != 0)) >+ { >+ if (error_text != NULL) >+ *error_text = g_strdup(error.message); >+ g_warning(G_STRLOC ": DBUS: %s", error.message); >+ } >+ dbus_error_free(&error); >+ } >+ return reply; >+} >+ >+/* Send a message. */ >+static DBusMessage * dbus_send_message_session(DBusMessage * message, char * * error_text) >+{ >+ /* Get a connection handle. */ >+ DBusConnection * connection = dbus_connect_session(); > if (connection == NULL) > return FALSE; > >@@ -132,6 +180,36 @@ > } > return result; > } >+ >+/* Read a result for a method that returns a string encoded boolean. */ >+static gboolean dbus_read_result_sboolean(DBusMessage * reply) >+{ >+ gboolean result = FALSE; >+ char* string_result; >+ if (reply != NULL) >+ { >+ /* Get the string result. */ >+ DBusError error; >+ dbus_error_init(&error); >+ dbus_bool_t status = dbus_message_get_args( >+ reply, >+ &error, >+ DBUS_TYPE_STRING, &string_result, >+ DBUS_TYPE_INVALID); >+ if ( ! status) >+ { >+ g_warning(G_STRLOC ": DBUS: %s", error.message); >+ dbus_error_free(&error); >+ } >+ else >+ { >+ if (!strcmp(string_result, "yes")) >+ result = TRUE; >+ } >+ dbus_message_unref(reply); >+ } >+ return result; >+} > #endif > > /*** ConsoleKit mechanism ***/ >@@ -152,7 +230,7 @@ > static gboolean dbus_ConsoleKit_query(const char * const query) > { > #ifdef HAVE_DBUS >- return dbus_read_result_boolean(dbus_send_message(dbus_ConsoleKit_formulate_message(query), NULL)); >+ return dbus_read_result_boolean(dbus_send_message_system(dbus_ConsoleKit_formulate_message(query), NULL)); > #else > return FALSE; > #endif >@@ -163,7 +241,7 @@ > { > #ifdef HAVE_DBUS > char * error = NULL; >- dbus_read_result_void(dbus_send_message(dbus_ConsoleKit_formulate_message(command), &error)); >+ dbus_read_result_void(dbus_send_message_system(dbus_ConsoleKit_formulate_message(command), &error)); > return error; > #else > return NULL; >@@ -225,7 +303,7 @@ > DBUS_TYPE_INVALID); > > /* Send the message. */ >- DBusMessage * reply = dbus_send_message(message, NULL); >+ DBusMessage * reply = dbus_send_message_system(message, NULL); > if (reply == NULL) > return FALSE; > >@@ -252,7 +330,7 @@ > { > #ifdef HAVE_DBUS > char * error = NULL; >- dbus_read_result_void(dbus_send_message(dbus_UPower_formulate_command(command), &error)); >+ dbus_read_result_void(dbus_send_message_system(dbus_UPower_formulate_command(command), &error)); > return error; > #else > return NULL; >@@ -329,7 +407,7 @@ > DBusMessage * message = dbus_HAL_formulate_string_property_query(property); > if (message == NULL) > return FALSE; >- DBusMessage * reply = dbus_send_message(message, NULL); >+ DBusMessage * reply = dbus_send_message_system(message, NULL); > if (reply == NULL) > return FALSE; > dbus_message_unref(reply); >@@ -343,7 +421,7 @@ > static gboolean dbus_HAL_boolean_query(const char * const property) > { > #ifdef HAVE_DBUS >- return dbus_read_result_boolean(dbus_send_message(dbus_HAL_formulate_boolean_property_query(property), NULL)); >+ return dbus_read_result_boolean(dbus_send_message_system(dbus_HAL_formulate_boolean_property_query(property), NULL)); > #else > return FALSE; > #endif >@@ -367,7 +445,7 @@ > > /* Send the message and wait for a reply. */ > char * error = NULL; >- dbus_read_result_void(dbus_send_message(message, &error)); >+ dbus_read_result_void(dbus_send_message_system(message, &error)); > return error; > #else > return NULL; >@@ -421,3 +499,185 @@ > { > return dbus_HAL_command("Hibernate"); > } >+ >+/*** logind mechanism ***/ >+ >+#ifdef HAVE_DBUS >+/* Formulate a message to the logind Manager interface to query a property. */ >+static DBusMessage * dbus_logind_formulate_query(const char * const query) >+{ >+ return dbus_message_new_method_call( >+ "org.freedesktop.login1", >+ "/org/freedesktop/login1", >+ "org.freedesktop.login1.Manager", >+ query); >+} >+ >+/* Formulate a message to the logind Manager interface. */ >+static DBusMessage * dbus_logind_formulate_message(const char * const method) >+{ >+ static dbus_bool_t interactive = FALSE; >+ DBusMessage * message = dbus_message_new_method_call( >+ "org.freedesktop.login1", >+ "/org/freedesktop/login1", >+ "org.freedesktop.login1.Manager", >+ method); >+ if (message != NULL) >+ dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); >+ return message; >+} >+#endif >+ >+/* Send a specified query to the logind interface and process a boolean result. */ >+static gboolean dbus_logind_query(const char * const query) >+{ >+#ifdef HAVE_DBUS >+ return dbus_read_result_sboolean(dbus_send_message_system(dbus_logind_formulate_query(query), NULL)); >+#else >+ return FALSE; >+#endif >+} >+ >+/* Send a specified command to the logind interface and process a void result. */ >+static char * dbus_logind_command(const char * const command) >+{ >+#ifdef HAVE_DBUS >+ char * error = NULL; >+ dbus_read_result_void(dbus_send_message_system(dbus_logind_formulate_message(command), &error)); >+ return error; >+#else >+ return NULL; >+#endif >+} >+ >+/* Read the can-poweroff property of logind. */ >+gboolean dbus_logind_CanPowerOff(void) >+{ >+ return dbus_logind_query("CanPowerOff"); >+} >+ >+/* Read the can-reboot property of logind. */ >+gboolean dbus_logind_CanReboot(void) >+{ >+ return dbus_logind_query("CanReboot"); >+} >+ >+/* Read the can-suspend property of logind. */ >+gboolean dbus_logind_CanSuspend(void) >+{ >+ return dbus_logind_query("CanSuspend"); >+} >+ >+/* Read the can-hibernate property of logind. */ >+gboolean dbus_logind_CanHibernate(void) >+{ >+ return dbus_logind_query("CanHibernate"); >+} >+ >+/* Invoke the PowerOff method on logind. */ >+char * dbus_logind_PowerOff(void) >+{ >+ return dbus_logind_command("PowerOff"); >+} >+ >+/* Invoke the Reboot method on logind. */ >+char * dbus_logind_Reboot(void) >+{ >+ return dbus_logind_command("Reboot"); >+} >+ >+/* Invoke the Suspend method on logind. */ >+char * dbus_logind_Suspend(void) >+{ >+ return dbus_logind_command("Suspend"); >+} >+ >+/* Invoke the Hibernate method on logind. */ >+char * dbus_logind_Hibernate(void) >+{ >+ return dbus_logind_command("Hibernate"); >+} >+ >+/*** LXDE mechanism ***/ >+ >+#ifdef HAVE_DBUS >+/* Formulate a message to the LXDE Session Manager interface. */ >+static DBusMessage * dbus_LXDE_formulate_message(const char * const query) >+{ >+ return dbus_message_new_method_call( >+ "org.lxde.SessionManager", >+ "/org/lxde/SessionManager", >+ "org.lxde.SessionManager", >+ query); >+} >+#endif >+ >+/* Send a specified message to the LXDE interface and process a boolean result. */ >+static gboolean dbus_LXDE_query(const char * const query) >+{ >+#ifdef HAVE_DBUS >+ return dbus_read_result_boolean(dbus_send_message_session(dbus_LXDE_formulate_message(query), NULL)); >+#else >+ return FALSE; >+#endif >+} >+ >+/* Send a specified message to the LXDE interface and process a void result. */ >+static char * dbus_LXDE_command(const char * const command) >+{ >+#ifdef HAVE_DBUS >+ char * error = NULL; >+ dbus_read_result_void(dbus_send_message_session(dbus_LXDE_formulate_message(command), &error)); >+ return error; >+#else >+ return NULL; >+#endif >+} >+ >+/* Invoke the Logout method on LXDE. */ >+char * dbus_LXDE_Logout(void) >+{ >+ return dbus_LXDE_command("Logout"); >+} >+ >+/*** Lightdm mechanism ***/ >+ >+#ifdef HAVE_DBUS >+/* Formulate a message to the Lightdm interface. */ >+static DBusMessage * dbus_Lightdm_formulate_message(const char * const query) >+{ >+ return dbus_message_new_method_call( >+ "org.freedesktop.DisplayManager", >+ g_getenv ("XDG_SEAT_PATH"), >+ "org.freedesktop.DisplayManager.Seat", >+ query); >+} >+#endif >+ >+/* Send a specified message to the Lightdm interface and process a boolean result. */ >+static gboolean dbus_Lightdm_query(const char * const query) >+{ >+#ifdef HAVE_DBUS >+ return dbus_read_result_boolean(dbus_send_message_session(dbus_Lightdm_formulate_message(query), NULL)); >+#else >+ return FALSE; >+#endif >+} >+ >+/* Send a specified message to the Lightdm interface and process a void result. */ >+static char * dbus_Lightdm_command(const char * const command) >+{ >+#ifdef HAVE_DBUS >+ char * error = NULL; >+ dbus_read_result_void(dbus_send_message_session(dbus_Lightdm_formulate_message(command), &error)); >+ return error; >+#else >+ return NULL; >+#endif >+} >+ >+/* Invoke the Logout method on LXDE. */ >+char * dbus_Lightdm_SwitchToGreeter(void) >+{ >+ return dbus_Lightdm_command("SwitchToGreeter"); >+} >diff -uNr lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.h lxsession-0.4.6.1/lxsession-logout/dbus-interface.h >--- lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.h 2011-07-27 21:26:36.000000000 +0200 >+++ lxsession-0.4.6.1/lxsession-logout/dbus-interface.h 2012-12-22 14:28:46.367031227 +0100 >@@ -44,4 +44,18 @@ > extern char * dbus_HAL_Suspend(void); > extern char * dbus_HAL_Hibernate(void); > >+/* Interface to logind for shutdown, reboot, suspend, and hibernate. */ >+extern gboolean dbus_logind_CanPowerOff(void); >+extern gboolean dbus_logind_CanRestart(void); >+extern char * dbus_logind_PowerOff(void); >+extern char * dbus_logind_Restart(void); >+extern gboolean dbus_logind_CanSuspend(void); >+extern gboolean dbus_logind_CanHibernate(void); >+extern char * dbus_logind_Suspend(void); >+extern char * dbus_logind_Hibernate(void); >+ >+extern char * dbus_LXDE_Logout(void); >+ >+extern char * dbus_Lightdm_SwitchToGreeter(); >+ > #endif >diff -uNr lxsession-0.4.6.1.orig/lxsession-logout/lxsession-logout.c lxsession-0.4.6.1/lxsession-logout/lxsession-logout.c >--- lxsession-0.4.6.1.orig/lxsession-logout/lxsession-logout.c 2011-07-27 21:26:36.000000000 +0200 >+++ lxsession-0.4.6.1/lxsession-logout/lxsession-logout.c 2012-12-22 14:29:04.994031240 +0100 >@@ -69,12 +69,21 @@ > int reboot_HAL : 1; /* Reboot is available via HAL */ > int suspend_HAL : 1; /* Suspend is available via HAL */ > int hibernate_HAL : 1; /* Hibernate is available via HAL */ >+ int shutdown_logind : 1; /* Shutdown is available via logind */ >+ int reboot_logind : 1; /* Reboot is available via logind */ >+ int suspend_logind : 1; /* Suspend is available via logind */ >+ int hibernate_logind : 1; /* Hibernate is available via logind */ > int switch_user_GDM : 1; /* Switch User is available via GDM */ >- int switch_user_KDM : 1; /* Switch User is available via KDM */ >+ int switch_user_LIGHTDM : 1; /* Switch User is available via GDM */ >+ int switch_user_KDM : 1; /* Switch User is available via LIGHTDM */ > int ltsp : 1; /* Shutdown and reboot is accomplished via LTSP */ >+ >+ int lock_screen : 1; /* Lock screen available */ >+ > } HandlerContext; > > static gboolean lock_screen(void); >+static const gchar* determine_lock_screen(void); > static gboolean verify_running(const char * display_manager, const char * executable); > static void logout_clicked(GtkButton * button, HandlerContext * handler_context); > static void change_root_property(GtkWidget* w, const char* prop_name, const char* value); >@@ -93,13 +102,32 @@ > */ > static gboolean lock_screen(void) > { >- if (!g_spawn_command_line_async("lxlock", NULL)) >+ const gchar* program = determine_lock_screen(); >+ >+ if (program) > { >+ g_spawn_command_line_async(program, NULL); > return TRUE; > } > return FALSE; > } > >+static const gchar* determine_lock_screen(void) >+{ >+ const gchar* program = NULL; >+ >+ if (g_find_program_in_path("xdg-screensaver")) >+ { >+ program = "xdg-screensaver lock"; >+ } >+ else if (g_find_program_in_path("lxlock")) >+ { >+ program = "lxlock"; >+ } >+ return program; >+} >+ >+ > /* Verify that a program is running and that an executable is available. */ > static gboolean verify_running(const char * display_manager, const char * executable) > { >@@ -187,6 +215,8 @@ > error_result = dbus_ConsoleKit_Stop(); > else if (handler_context->shutdown_HAL) > error_result = dbus_HAL_Shutdown(); >+ else if (handler_context->shutdown_logind) >+ error_result = dbus_logind_PowerOff(); > > if (error_result != NULL) > gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); >@@ -208,6 +238,8 @@ > error_result = dbus_ConsoleKit_Restart(); > else if (handler_context->reboot_HAL) > error_result = dbus_HAL_Reboot(); >+ else if (handler_context->reboot_logind) >+ error_result = dbus_logind_Reboot(); > > if (error_result != NULL) > gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); >@@ -225,6 +257,8 @@ > error_result = dbus_UPower_Suspend(); > else if (handler_context->suspend_HAL) > error_result = dbus_HAL_Suspend(); >+ else if (handler_context->suspend_logind) >+ error_result = dbus_logind_Suspend(); > > if (error_result != NULL) > gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); >@@ -242,6 +276,8 @@ > error_result = dbus_UPower_Hibernate(); > else if (handler_context->hibernate_HAL) > error_result = dbus_HAL_Hibernate(); >+ else if (handler_context->hibernate_logind) >+ error_result = dbus_logind_Hibernate(); > > if (error_result != NULL) > gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); >@@ -258,6 +294,17 @@ > g_spawn_command_line_sync("gdmflexiserver --startnew", NULL, NULL, NULL, NULL); > else if (handler_context->switch_user_KDM) > g_spawn_command_line_sync("kdmctl reserve", NULL, NULL, NULL, NULL); >+ else if (handler_context->switch_user_LIGHTDM) >+ dbus_Lightdm_SwitchToGreeter(); >+ gtk_main_quit(); >+} >+ >+/* Handler for "clicked" signal on Lock button. */ >+static void lock_screen_clicked(GtkButton * button, HandlerContext * handler_context) >+{ >+ gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL); >+ >+ lock_screen(); > gtk_main_quit(); > } > >@@ -435,6 +482,28 @@ > handler_context.hibernate_HAL = TRUE; > } > >+ /* Initialize capabilities of the logind mechanism. */ >+ if (!handler_context.shutdown_available && dbus_logind_CanPowerOff()) >+ { >+ handler_context.shutdown_available = TRUE; >+ handler_context.shutdown_logind = TRUE; >+ } >+ if (!handler_context.reboot_available && dbus_logind_CanReboot()) >+ { >+ handler_context.reboot_available = TRUE; >+ handler_context.reboot_logind = TRUE; >+ } >+ if (!handler_context.suspend_available && dbus_logind_CanSuspend()) >+ { >+ handler_context.suspend_available = TRUE; >+ handler_context.suspend_logind = TRUE; >+ } >+ if (!handler_context.hibernate_available && dbus_logind_CanHibernate()) >+ { >+ handler_context.hibernate_available = TRUE; >+ handler_context.hibernate_logind = TRUE; >+ } >+ > /* If we are under GDM, its "Switch User" is available. */ > if (verify_running("gdm", "gdmflexiserver")) > { >@@ -442,6 +511,34 @@ > handler_context.switch_user_GDM = TRUE; > } > >+ /* If we are under GDM3, its "Switch User" is available. */ >+ if (verify_running("gdm3", "gdmflexiserver")) >+ { >+ handler_context.switch_user_available = TRUE; >+ handler_context.switch_user_GDM = TRUE; >+ } >+ >+ /* lightdm also use gdmflexiserver */ >+ if (verify_running("lightdm", "gdmflexiserver")) >+ { >+ handler_context.switch_user_available = TRUE; >+ handler_context.switch_user_GDM = TRUE; >+ } >+ >+ /* lightdm also use gdmflexiserver */ >+ if (verify_running("lightdm", "gdmflexiserver")) >+ { >+ handler_context.switch_user_available = TRUE; >+ handler_context.switch_user_GDM = TRUE; >+ } >+ >+ /* lightdm can also be find by the env */ >+ if (g_getenv("XDG_SEAT_PATH")) >+ { >+ handler_context.switch_user_available = TRUE; >+ handler_context.switch_user_LIGHTDM = TRUE; >+ } >+ > /* If we are under KDM, its "Switch User" is available. */ > if (verify_running("kdm", "kdmctl")) > { >@@ -451,7 +548,18 @@ > > /* LTSP support */ > if (g_getenv("LTSP_CLIENT")) >+ { > handler_context.ltsp = TRUE; >+ handler_context.shutdown_available = TRUE; >+ handler_context.reboot_available = TRUE; >+ } >+ >+ /* Lock screen */ >+ const gchar* very_lock_screen = determine_lock_screen(); >+ if (very_lock_screen) >+ { >+ handler_context.lock_screen = TRUE; >+ } > > /* Make the button images accessible. */ > gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), PACKAGE_DATA_DIR "/lxsession/images"); >@@ -596,6 +704,17 @@ > gtk_box_pack_start(GTK_BOX(controls), switch_user_button, FALSE, FALSE, 4); > } > >+ /* Create the Lock Screen button. */ >+ if (handler_context.lock_screen && !handler_context.ltsp) >+ { >+ GtkWidget * lock_screen_button = gtk_button_new_with_mnemonic(_("L_ock Screen")); >+ GtkWidget * image = gtk_image_new_from_icon_name("system-lock-screen", GTK_ICON_SIZE_BUTTON); >+ gtk_button_set_image(GTK_BUTTON(lock_screen_button), image); >+ gtk_button_set_alignment(GTK_BUTTON(lock_screen_button), 0.0, 0.5); >+ g_signal_connect(G_OBJECT(lock_screen_button), "clicked", G_CALLBACK(lock_screen_clicked), &handler_context); >+ gtk_box_pack_start(GTK_BOX(controls), lock_screen_button, FALSE, FALSE, 4); >+ } >+ > /* Create the Logout button. */ > GtkWidget * logout_button = gtk_button_new_with_mnemonic(_("_Logout")); > GtkWidget * image = gtk_image_new_from_icon_name("system-log-out", GTK_ICON_SIZE_BUTTON);
diff -uNr lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.c lxsession-0.4.6.1/lxsession-logout/dbus-interface.c --- lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.c 2011-07-27 21:26:36.000000000 +0200 +++ lxsession-0.4.6.1/lxsession-logout/dbus-interface.c 2012-12-22 14:28:38.647031221 +0100 @@ -51,13 +51,20 @@ char * dbus_HAL_Reboot(void); char * dbus_HAL_Suspend(void); char * dbus_HAL_Hibernate(void); +gboolean dbus_logind_CanPowerOff(void); +gboolean dbus_logind_CanReboot(void); +gboolean dbus_logind_CanSuspend(void); +gboolean dbus_logind_CanHibernate(void); +char * dbus_logind_PowerOff(void); +char * dbus_logind_Reboot(void); +char * dbus_logind_Suspend(void); +char * dbus_logind_Hibernate(void); +char * dbus_LXDE_Logout(void); /* End FORWARDS */ /* Connect to the system bus. Once a connection is made, it is saved for reuse. */ -static DBusConnection * dbus_connect(void) +static DBusConnection * dbus_connect_system(void) { - if ((dbus_context.connection == NULL) && ( ! dbus_context.connection_tried)) - { DBusError error; dbus_error_init(&error); dbus_context.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); @@ -67,16 +74,57 @@ dbus_error_free(&error); } dbus_context.connection_tried = TRUE; - } return dbus_context.connection; } +static DBusConnection * dbus_connect_session(void) +{ + DBusError error; + dbus_error_init(&error); + dbus_context.connection = dbus_bus_get(DBUS_BUS_SESSION, &error); + if (dbus_context.connection == NULL) + { + g_warning(G_STRLOC ": Failed to connect to the session message bus: %s", error.message); + dbus_error_free(&error); + } + dbus_context.connection_tried = TRUE; + + return dbus_context.connection; +} + + /* Send a message. */ -static DBusMessage * dbus_send_message(DBusMessage * message, char * * error_text) +static DBusMessage * dbus_send_message_system(DBusMessage * message, char * * error_text) { /* Get a connection handle. */ - DBusConnection * connection = dbus_connect(); + DBusConnection * connection = dbus_connect_system(); + if (connection == NULL) + return FALSE; + + /* Send the message. */ + DBusError error; + dbus_error_init(&error); + DBusMessage * reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT, &error); + dbus_message_unref(message); + if (reply == NULL) + { + if ((error.name == NULL) || (strcmp(error.name, DBUS_ERROR_NO_REPLY) != 0)) + { + if (error_text != NULL) + *error_text = g_strdup(error.message); + g_warning(G_STRLOC ": DBUS: %s", error.message); + } + dbus_error_free(&error); + } + return reply; +} + +/* Send a message. */ +static DBusMessage * dbus_send_message_session(DBusMessage * message, char * * error_text) +{ + /* Get a connection handle. */ + DBusConnection * connection = dbus_connect_session(); if (connection == NULL) return FALSE; @@ -132,6 +180,36 @@ } return result; } + +/* Read a result for a method that returns a string encoded boolean. */ +static gboolean dbus_read_result_sboolean(DBusMessage * reply) +{ + gboolean result = FALSE; + char* string_result; + if (reply != NULL) + { + /* Get the string result. */ + DBusError error; + dbus_error_init(&error); + dbus_bool_t status = dbus_message_get_args( + reply, + &error, + DBUS_TYPE_STRING, &string_result, + DBUS_TYPE_INVALID); + if ( ! status) + { + g_warning(G_STRLOC ": DBUS: %s", error.message); + dbus_error_free(&error); + } + else + { + if (!strcmp(string_result, "yes")) + result = TRUE; + } + dbus_message_unref(reply); + } + return result; +} #endif /*** ConsoleKit mechanism ***/ @@ -152,7 +230,7 @@ static gboolean dbus_ConsoleKit_query(const char * const query) { #ifdef HAVE_DBUS - return dbus_read_result_boolean(dbus_send_message(dbus_ConsoleKit_formulate_message(query), NULL)); + return dbus_read_result_boolean(dbus_send_message_system(dbus_ConsoleKit_formulate_message(query), NULL)); #else return FALSE; #endif @@ -163,7 +241,7 @@ { #ifdef HAVE_DBUS char * error = NULL; - dbus_read_result_void(dbus_send_message(dbus_ConsoleKit_formulate_message(command), &error)); + dbus_read_result_void(dbus_send_message_system(dbus_ConsoleKit_formulate_message(command), &error)); return error; #else return NULL; @@ -225,7 +303,7 @@ DBUS_TYPE_INVALID); /* Send the message. */ - DBusMessage * reply = dbus_send_message(message, NULL); + DBusMessage * reply = dbus_send_message_system(message, NULL); if (reply == NULL) return FALSE; @@ -252,7 +330,7 @@ { #ifdef HAVE_DBUS char * error = NULL; - dbus_read_result_void(dbus_send_message(dbus_UPower_formulate_command(command), &error)); + dbus_read_result_void(dbus_send_message_system(dbus_UPower_formulate_command(command), &error)); return error; #else return NULL; @@ -329,7 +407,7 @@ DBusMessage * message = dbus_HAL_formulate_string_property_query(property); if (message == NULL) return FALSE; - DBusMessage * reply = dbus_send_message(message, NULL); + DBusMessage * reply = dbus_send_message_system(message, NULL); if (reply == NULL) return FALSE; dbus_message_unref(reply); @@ -343,7 +421,7 @@ static gboolean dbus_HAL_boolean_query(const char * const property) { #ifdef HAVE_DBUS - return dbus_read_result_boolean(dbus_send_message(dbus_HAL_formulate_boolean_property_query(property), NULL)); + return dbus_read_result_boolean(dbus_send_message_system(dbus_HAL_formulate_boolean_property_query(property), NULL)); #else return FALSE; #endif @@ -367,7 +445,7 @@ /* Send the message and wait for a reply. */ char * error = NULL; - dbus_read_result_void(dbus_send_message(message, &error)); + dbus_read_result_void(dbus_send_message_system(message, &error)); return error; #else return NULL; @@ -421,3 +499,185 @@ { return dbus_HAL_command("Hibernate"); } + +/*** logind mechanism ***/ + +#ifdef HAVE_DBUS +/* Formulate a message to the logind Manager interface to query a property. */ +static DBusMessage * dbus_logind_formulate_query(const char * const query) +{ + return dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + query); +} + +/* Formulate a message to the logind Manager interface. */ +static DBusMessage * dbus_logind_formulate_message(const char * const method) +{ + static dbus_bool_t interactive = FALSE; + DBusMessage * message = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + method); + if (message != NULL) + dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); + return message; +} +#endif + +/* Send a specified query to the logind interface and process a boolean result. */ +static gboolean dbus_logind_query(const char * const query) +{ +#ifdef HAVE_DBUS + return dbus_read_result_sboolean(dbus_send_message_system(dbus_logind_formulate_query(query), NULL)); +#else + return FALSE; +#endif +} + +/* Send a specified command to the logind interface and process a void result. */ +static char * dbus_logind_command(const char * const command) +{ +#ifdef HAVE_DBUS + char * error = NULL; + dbus_read_result_void(dbus_send_message_system(dbus_logind_formulate_message(command), &error)); + return error; +#else + return NULL; +#endif +} + +/* Read the can-poweroff property of logind. */ +gboolean dbus_logind_CanPowerOff(void) +{ + return dbus_logind_query("CanPowerOff"); +} + +/* Read the can-reboot property of logind. */ +gboolean dbus_logind_CanReboot(void) +{ + return dbus_logind_query("CanReboot"); +} + +/* Read the can-suspend property of logind. */ +gboolean dbus_logind_CanSuspend(void) +{ + return dbus_logind_query("CanSuspend"); +} + +/* Read the can-hibernate property of logind. */ +gboolean dbus_logind_CanHibernate(void) +{ + return dbus_logind_query("CanHibernate"); +} + +/* Invoke the PowerOff method on logind. */ +char * dbus_logind_PowerOff(void) +{ + return dbus_logind_command("PowerOff"); +} + +/* Invoke the Reboot method on logind. */ +char * dbus_logind_Reboot(void) +{ + return dbus_logind_command("Reboot"); +} + +/* Invoke the Suspend method on logind. */ +char * dbus_logind_Suspend(void) +{ + return dbus_logind_command("Suspend"); +} + +/* Invoke the Hibernate method on logind. */ +char * dbus_logind_Hibernate(void) +{ + return dbus_logind_command("Hibernate"); +} + +/*** LXDE mechanism ***/ + +#ifdef HAVE_DBUS +/* Formulate a message to the LXDE Session Manager interface. */ +static DBusMessage * dbus_LXDE_formulate_message(const char * const query) +{ + return dbus_message_new_method_call( + "org.lxde.SessionManager", + "/org/lxde/SessionManager", + "org.lxde.SessionManager", + query); +} +#endif + +/* Send a specified message to the LXDE interface and process a boolean result. */ +static gboolean dbus_LXDE_query(const char * const query) +{ +#ifdef HAVE_DBUS + return dbus_read_result_boolean(dbus_send_message_session(dbus_LXDE_formulate_message(query), NULL)); +#else + return FALSE; +#endif +} + +/* Send a specified message to the LXDE interface and process a void result. */ +static char * dbus_LXDE_command(const char * const command) +{ +#ifdef HAVE_DBUS + char * error = NULL; + dbus_read_result_void(dbus_send_message_session(dbus_LXDE_formulate_message(command), &error)); + return error; +#else + return NULL; +#endif +} + +/* Invoke the Logout method on LXDE. */ +char * dbus_LXDE_Logout(void) +{ + return dbus_LXDE_command("Logout"); +} + +/*** Lightdm mechanism ***/ + +#ifdef HAVE_DBUS +/* Formulate a message to the Lightdm interface. */ +static DBusMessage * dbus_Lightdm_formulate_message(const char * const query) +{ + return dbus_message_new_method_call( + "org.freedesktop.DisplayManager", + g_getenv ("XDG_SEAT_PATH"), + "org.freedesktop.DisplayManager.Seat", + query); +} +#endif + +/* Send a specified message to the Lightdm interface and process a boolean result. */ +static gboolean dbus_Lightdm_query(const char * const query) +{ +#ifdef HAVE_DBUS + return dbus_read_result_boolean(dbus_send_message_session(dbus_Lightdm_formulate_message(query), NULL)); +#else + return FALSE; +#endif +} + +/* Send a specified message to the Lightdm interface and process a void result. */ +static char * dbus_Lightdm_command(const char * const command) +{ +#ifdef HAVE_DBUS + char * error = NULL; + dbus_read_result_void(dbus_send_message_session(dbus_Lightdm_formulate_message(command), &error)); + return error; +#else + return NULL; +#endif +} + +/* Invoke the Logout method on LXDE. */ +char * dbus_Lightdm_SwitchToGreeter(void) +{ + return dbus_Lightdm_command("SwitchToGreeter"); +} diff -uNr lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.h lxsession-0.4.6.1/lxsession-logout/dbus-interface.h --- lxsession-0.4.6.1.orig/lxsession-logout/dbus-interface.h 2011-07-27 21:26:36.000000000 +0200 +++ lxsession-0.4.6.1/lxsession-logout/dbus-interface.h 2012-12-22 14:28:46.367031227 +0100 @@ -44,4 +44,18 @@ extern char * dbus_HAL_Suspend(void); extern char * dbus_HAL_Hibernate(void); +/* Interface to logind for shutdown, reboot, suspend, and hibernate. */ +extern gboolean dbus_logind_CanPowerOff(void); +extern gboolean dbus_logind_CanRestart(void); +extern char * dbus_logind_PowerOff(void); +extern char * dbus_logind_Restart(void); +extern gboolean dbus_logind_CanSuspend(void); +extern gboolean dbus_logind_CanHibernate(void); +extern char * dbus_logind_Suspend(void); +extern char * dbus_logind_Hibernate(void); + +extern char * dbus_LXDE_Logout(void); + +extern char * dbus_Lightdm_SwitchToGreeter(); + #endif diff -uNr lxsession-0.4.6.1.orig/lxsession-logout/lxsession-logout.c lxsession-0.4.6.1/lxsession-logout/lxsession-logout.c --- lxsession-0.4.6.1.orig/lxsession-logout/lxsession-logout.c 2011-07-27 21:26:36.000000000 +0200 +++ lxsession-0.4.6.1/lxsession-logout/lxsession-logout.c 2012-12-22 14:29:04.994031240 +0100 @@ -69,12 +69,21 @@ int reboot_HAL : 1; /* Reboot is available via HAL */ int suspend_HAL : 1; /* Suspend is available via HAL */ int hibernate_HAL : 1; /* Hibernate is available via HAL */ + int shutdown_logind : 1; /* Shutdown is available via logind */ + int reboot_logind : 1; /* Reboot is available via logind */ + int suspend_logind : 1; /* Suspend is available via logind */ + int hibernate_logind : 1; /* Hibernate is available via logind */ int switch_user_GDM : 1; /* Switch User is available via GDM */ - int switch_user_KDM : 1; /* Switch User is available via KDM */ + int switch_user_LIGHTDM : 1; /* Switch User is available via GDM */ + int switch_user_KDM : 1; /* Switch User is available via LIGHTDM */ int ltsp : 1; /* Shutdown and reboot is accomplished via LTSP */ + + int lock_screen : 1; /* Lock screen available */ + } HandlerContext; static gboolean lock_screen(void); +static const gchar* determine_lock_screen(void); static gboolean verify_running(const char * display_manager, const char * executable); static void logout_clicked(GtkButton * button, HandlerContext * handler_context); static void change_root_property(GtkWidget* w, const char* prop_name, const char* value); @@ -93,13 +102,32 @@ */ static gboolean lock_screen(void) { - if (!g_spawn_command_line_async("lxlock", NULL)) + const gchar* program = determine_lock_screen(); + + if (program) { + g_spawn_command_line_async(program, NULL); return TRUE; } return FALSE; } +static const gchar* determine_lock_screen(void) +{ + const gchar* program = NULL; + + if (g_find_program_in_path("xdg-screensaver")) + { + program = "xdg-screensaver lock"; + } + else if (g_find_program_in_path("lxlock")) + { + program = "lxlock"; + } + return program; +} + + /* Verify that a program is running and that an executable is available. */ static gboolean verify_running(const char * display_manager, const char * executable) { @@ -187,6 +215,8 @@ error_result = dbus_ConsoleKit_Stop(); else if (handler_context->shutdown_HAL) error_result = dbus_HAL_Shutdown(); + else if (handler_context->shutdown_logind) + error_result = dbus_logind_PowerOff(); if (error_result != NULL) gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); @@ -208,6 +238,8 @@ error_result = dbus_ConsoleKit_Restart(); else if (handler_context->reboot_HAL) error_result = dbus_HAL_Reboot(); + else if (handler_context->reboot_logind) + error_result = dbus_logind_Reboot(); if (error_result != NULL) gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); @@ -225,6 +257,8 @@ error_result = dbus_UPower_Suspend(); else if (handler_context->suspend_HAL) error_result = dbus_HAL_Suspend(); + else if (handler_context->suspend_logind) + error_result = dbus_logind_Suspend(); if (error_result != NULL) gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); @@ -242,6 +276,8 @@ error_result = dbus_UPower_Hibernate(); else if (handler_context->hibernate_HAL) error_result = dbus_HAL_Hibernate(); + else if (handler_context->hibernate_logind) + error_result = dbus_logind_Hibernate(); if (error_result != NULL) gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result); @@ -258,6 +294,17 @@ g_spawn_command_line_sync("gdmflexiserver --startnew", NULL, NULL, NULL, NULL); else if (handler_context->switch_user_KDM) g_spawn_command_line_sync("kdmctl reserve", NULL, NULL, NULL, NULL); + else if (handler_context->switch_user_LIGHTDM) + dbus_Lightdm_SwitchToGreeter(); + gtk_main_quit(); +} + +/* Handler for "clicked" signal on Lock button. */ +static void lock_screen_clicked(GtkButton * button, HandlerContext * handler_context) +{ + gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL); + + lock_screen(); gtk_main_quit(); } @@ -435,6 +482,28 @@ handler_context.hibernate_HAL = TRUE; } + /* Initialize capabilities of the logind mechanism. */ + if (!handler_context.shutdown_available && dbus_logind_CanPowerOff()) + { + handler_context.shutdown_available = TRUE; + handler_context.shutdown_logind = TRUE; + } + if (!handler_context.reboot_available && dbus_logind_CanReboot()) + { + handler_context.reboot_available = TRUE; + handler_context.reboot_logind = TRUE; + } + if (!handler_context.suspend_available && dbus_logind_CanSuspend()) + { + handler_context.suspend_available = TRUE; + handler_context.suspend_logind = TRUE; + } + if (!handler_context.hibernate_available && dbus_logind_CanHibernate()) + { + handler_context.hibernate_available = TRUE; + handler_context.hibernate_logind = TRUE; + } + /* If we are under GDM, its "Switch User" is available. */ if (verify_running("gdm", "gdmflexiserver")) { @@ -442,6 +511,34 @@ handler_context.switch_user_GDM = TRUE; } + /* If we are under GDM3, its "Switch User" is available. */ + if (verify_running("gdm3", "gdmflexiserver")) + { + handler_context.switch_user_available = TRUE; + handler_context.switch_user_GDM = TRUE; + } + + /* lightdm also use gdmflexiserver */ + if (verify_running("lightdm", "gdmflexiserver")) + { + handler_context.switch_user_available = TRUE; + handler_context.switch_user_GDM = TRUE; + } + + /* lightdm also use gdmflexiserver */ + if (verify_running("lightdm", "gdmflexiserver")) + { + handler_context.switch_user_available = TRUE; + handler_context.switch_user_GDM = TRUE; + } + + /* lightdm can also be find by the env */ + if (g_getenv("XDG_SEAT_PATH")) + { + handler_context.switch_user_available = TRUE; + handler_context.switch_user_LIGHTDM = TRUE; + } + /* If we are under KDM, its "Switch User" is available. */ if (verify_running("kdm", "kdmctl")) { @@ -451,7 +548,18 @@ /* LTSP support */ if (g_getenv("LTSP_CLIENT")) + { handler_context.ltsp = TRUE; + handler_context.shutdown_available = TRUE; + handler_context.reboot_available = TRUE; + } + + /* Lock screen */ + const gchar* very_lock_screen = determine_lock_screen(); + if (very_lock_screen) + { + handler_context.lock_screen = TRUE; + } /* Make the button images accessible. */ gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), PACKAGE_DATA_DIR "/lxsession/images"); @@ -596,6 +704,17 @@ gtk_box_pack_start(GTK_BOX(controls), switch_user_button, FALSE, FALSE, 4); } + /* Create the Lock Screen button. */ + if (handler_context.lock_screen && !handler_context.ltsp) + { + GtkWidget * lock_screen_button = gtk_button_new_with_mnemonic(_("L_ock Screen")); + GtkWidget * image = gtk_image_new_from_icon_name("system-lock-screen", GTK_ICON_SIZE_BUTTON); + gtk_button_set_image(GTK_BUTTON(lock_screen_button), image); + gtk_button_set_alignment(GTK_BUTTON(lock_screen_button), 0.0, 0.5); + g_signal_connect(G_OBJECT(lock_screen_button), "clicked", G_CALLBACK(lock_screen_clicked), &handler_context); + gtk_box_pack_start(GTK_BOX(controls), lock_screen_button, FALSE, FALSE, 4); + } + /* Create the Logout button. */ GtkWidget * logout_button = gtk_button_new_with_mnemonic(_("_Logout")); GtkWidget * image = gtk_image_new_from_icon_name("system-log-out", GTK_ICON_SIZE_BUTTON);
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 8073
: 3278 |
3769