static void
save_yourself_done_callback (SmsConn   conn,
                             SmPointer manager_data,
                             Bool      success)
{
        GsmXSMPClient *client = manager_data;

        g_debug ("GsmXSMPClient: Client '%s' received SaveYourselfDone(success = %s)",
                 client->priv->description,
                 success ? "True" : "False");

	if (client->priv->current_save_yourself != -1) {
		SmsSaveComplete (client->priv->conn);
		client->priv->current_save_yourself = -1;
	}

        /* If success is false then the application couldn't save data. Nothing
         * the session manager can do about, though. FIXME: we could display a
         * dialog about this, I guess. */
        gsm_client_end_session_response (GSM_CLIENT (client),
                                         TRUE, FALSE, FALSE,
                                         NULL);

        if (client->priv->next_save_yourself) {
                int      save_type = client->priv->next_save_yourself;
                gboolean allow_interact = client->priv->next_save_yourself_allow_interact;

                client->priv->next_save_yourself = -1;
                client->priv->next_save_yourself_allow_interact = -1;
                do_save_yourself (client, save_type, allow_interact);
        }
}
static void
interact_request_callback (SmsConn   conn,
                           SmPointer manager_data,
                           int       dialog_type)
{
        GsmXSMPClient *client = manager_data;
#if 0
        gboolean       res;
        GError        *error;
#endif

        g_debug ("GsmXSMPClient: Client '%s' received InteractRequest(%s)",
                 client->priv->description,
                 dialog_type == SmDialogNormal ? "Dialog" : "Errors");

        gsm_client_end_session_response (GSM_CLIENT (client),
                                         FALSE, FALSE, FALSE,
                                         _("This program is blocking logout."));

#if 0
        /* Can't just call back with Interact because session client
           grabs the keyboard!  So, we try to get it to release
           grabs by telling it we've cancelled the shutdown.
           This grabbing is clearly bullshit and is not supported by
           the client spec or protocol spec.
        */
        res = xsmp_cancel_end_session (GSM_CLIENT (client), &error);
        if (! res) {
                g_warning ("Unable to cancel end session: %s", error->message);
                g_error_free (error);
        }
#endif
        xsmp_interact (GSM_CLIENT (client));
}
static void
handle_end_session_response (GsmDBusClient *client,
                             DBusMessage   *message)
{
        const char     *sender;
        DBusMessage    *reply;
        DBusError       error;
        dbus_bool_t     is_ok;
        const char     *reason;

        dbus_error_init (&error);
        if (! dbus_message_get_args (message, &error,
                                     DBUS_TYPE_BOOLEAN, &is_ok,
                                     DBUS_TYPE_STRING, &reason,
                                     DBUS_TYPE_INVALID)) {
                if (dbus_error_is_set (&error)) {
                        g_warning ("Invalid method call: %s", error.message);
                        dbus_error_free (&error);
                }
                raise_error (client->priv->connection,
                             message,
                             DBUS_ERROR_FAILED,
                             "There is a syntax error in the invocation of the method EndSessionResponse");
                return;
        }

        g_debug ("GsmDBusClient: got EndSessionResponse is-ok:%d reason=%s", is_ok, reason);

        /* make sure it is from our client */
        sender = dbus_message_get_sender (message);
        if (sender == NULL
            || IS_STRING_EMPTY (client->priv->bus_name)
            || strcmp (sender, client->priv->bus_name) != 0) {

                raise_error (client->priv->connection,
                             message,
                             DBUS_ERROR_FAILED,
                             "Caller not recognized as the client");
                return;
        }

        reply = dbus_message_new_method_return (message);
        if (reply == NULL) {
                g_error ("No memory");
        }

        gsm_client_end_session_response (GSM_CLIENT (client),
                                         is_ok, FALSE, FALSE, reason);


        if (! dbus_connection_send (client->priv->connection, reply, NULL)) {
                g_error ("No memory");
        }

        dbus_message_unref (reply);
}
static void
interact_done_callback (SmsConn   conn,
                        SmPointer manager_data,
                        Bool      cancel_shutdown)
{
        GsmXSMPClient *client = manager_data;

        g_debug ("GsmXSMPClient: Client '%s' received InteractDone(cancel_shutdown = %s)",
                 client->priv->description,
                 cancel_shutdown ? "True" : "False");

        gsm_client_end_session_response (GSM_CLIENT (client),
                                         TRUE, FALSE, cancel_shutdown,
                                         NULL);
}
static void
save_yourself_phase2_request_callback (SmsConn   conn,
                                       SmPointer manager_data)
{
        GsmXSMPClient *client = manager_data;

        g_debug ("GsmXSMPClient: Client '%s' received SaveYourselfPhase2Request",
                 client->priv->description);

        client->priv->current_save_yourself = -1;

        /* this is a valid response to SaveYourself and therefore
           may be a response to a QES or ES */
        gsm_client_end_session_response (GSM_CLIENT (client),
                                         TRUE, TRUE, FALSE,
                                         NULL);
}