From 7a65a910b77ad191d69881098c47f9b0c852d92e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 13 Aug 2013 01:33:19 -0700 Subject: Tue Aug 13 01:31:08 PDT 2013 --- .../lxsession-0.4.6.1-logind-support.patch | 608 +++++++++++++++++++++ 1 file changed, 608 insertions(+) create mode 100644 community/lxsession/lxsession-0.4.6.1-logind-support.patch (limited to 'community/lxsession/lxsession-0.4.6.1-logind-support.patch') diff --git a/community/lxsession/lxsession-0.4.6.1-logind-support.patch b/community/lxsession/lxsession-0.4.6.1-logind-support.patch new file mode 100644 index 000000000..2c12a01c5 --- /dev/null +++ b/community/lxsession/lxsession-0.4.6.1-logind-support.patch @@ -0,0 +1,608 @@ +--- lxsession-0.4.6.1/lxsession-logout/dbus-interface.c 2011-07-27 21:26:36.000000000 +0200 ++++ lxsession-0.4.6.1/lxsession-logout-logind/dbus-interface.c 2012-11-13 17:26:30.807070976 +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"); ++} +--- lxsession-0.4.6.1/lxsession-logout/dbus-interface.h 2011-07-27 21:26:36.000000000 +0200 ++++ lxsession-0.4.6.1/lxsession-logout-logind/dbus-interface.h 2012-11-13 17:26:30.807070976 +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 +--- lxsession-0.4.6.1/lxsession-logout/lxsession-logout.c 2011-07-27 21:26:36.000000000 +0200 ++++ lxsession-0.4.6.1/lxsession-logout-logind/lxsession-logout.c 2012-11-13 17:26:30.807070976 +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); -- cgit v1.2.3-54-g00ecf