#include "lightdm/greeter.h"
+G_DEFINE_QUARK (lightdm_greeter_error, lightdm_greeter_error)
+
enum {
PROP_0,
PROP_DEFAULT_SESSION_HINT,
GAsyncReadyCallback callback;
gpointer user_data;
gboolean complete;
+ gboolean connected;
guint32 return_code;
gchar *dir;
} Request;
#define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request))
G_DEFINE_TYPE_WITH_CODE (Request, request, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, request_iface_init));
+GType
+lightdm_greeter_error_get_type (void)
+{
+ static GType enum_type = 0;
+
+ if (G_UNLIKELY(enum_type == 0)) {
+ static const GEnumValue values[] = {
+ { LIGHTDM_GREETER_ERROR_CONNECTION_FAILED, "LIGHTDM_GREETER_ERROR_CONNECTION_FAILED", "connection-failed" },
+ { LIGHTDM_GREETER_ERROR_SESSION_FAILED, "LIGHTDM_GREETER_ERROR_SESSION_FAILED", "session-failed" },
+ { 0, NULL, NULL }
+ };
+ enum_type = g_enum_register_static (g_intern_static_string ("LightDMGreeterError"), values);
+ }
+
+ return enum_type;
+}
+
+GType
+lightdm_prompt_type_get_type (void)
+{
+ static GType enum_type = 0;
+
+ if (G_UNLIKELY(enum_type == 0)) {
+ static const GEnumValue values[] = {
+ { LIGHTDM_PROMPT_TYPE_QUESTION, "LIGHTDM_PROMPT_TYPE_QUESTION", "question" },
+ { LIGHTDM_PROMPT_TYPE_SECRET, "LIGHTDM_PROMPT_TYPE_SECRET", "secret" },
+ { 0, NULL, NULL }
+ };
+ enum_type = g_enum_register_static (g_intern_static_string ("LightDMPromptType"), values);
+ }
+
+ return enum_type;
+}
+
+GType
+lightdm_message_type_get_type (void)
+{
+ static GType enum_type = 0;
+
+ if (G_UNLIKELY(enum_type == 0)) {
+ static const GEnumValue values[] = {
+ { LIGHTDM_MESSAGE_TYPE_INFO, "LIGHTDM_MESSAGE_TYPE_INFO", "info" },
+ { LIGHTDM_MESSAGE_TYPE_ERROR, "LIGHTDM_MESSAGE_TYPE_ERROR", "error" },
+ { 0, NULL, NULL }
+ };
+ enum_type = g_enum_register_static (g_intern_static_string ("LightDMMessageType"), values);
+ }
+
+ return enum_type;
+}
+
+
/**
* lightdm_greeter_new:
*
write_int (buffer, buffer_length, length, offset);
if (*offset + length >= buffer_length)
return;
- memcpy (buffer + *offset, value, length);
+ if (value)
+ memcpy (buffer + *offset, value, length);
*offset += length;
}
send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
{
LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
- GIOStatus status;
+ gchar *data;
+ gsize data_length;
GError *error = NULL;
guint32 stated_length;
return FALSE;
}
- status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
- if (error)
- g_warning ("Error writing to daemon: %s", error->message);
- g_clear_error (&error);
- if (status != G_IO_STATUS_NORMAL)
- return FALSE;
+ data = (gchar *) message;
+ data_length = message_length;
+ while (data_length > 0)
+ {
+ GIOStatus status;
+ gsize n_written;
+
+ status = g_io_channel_write_chars (priv->to_server_channel, data, data_length, &n_written, &error);
+ if (error)
+ g_warning ("Error writing to daemon: %s", error->message);
+ g_clear_error (&error);
+ if (status != G_IO_STATUS_NORMAL)
+ return FALSE;
+ data_length -= n_written;
+ data += n_written;
+ }
g_debug ("Wrote %zi bytes to daemon", message_length);
- g_io_channel_flush (priv->to_server_channel, NULL);
+ g_io_channel_flush (priv->to_server_channel, &error);
+ if (error)
+ g_warning ("Failed to flush data to daemon: %s", error->message);
+ g_clear_error (&error);
return TRUE;
}
while (*offset < message_length)
{
gchar *name, *value;
-
+
name = read_string (message, message_length, offset);
value = read_string (message, message_length, offset);
g_hash_table_insert (priv->hints, name, value);
request = g_list_nth_data (priv->connect_requests, 0);
if (request)
{
+ request->connected = TRUE;
request_complete (request, G_OBJECT (greeter));
priv->connect_requests = g_list_remove (priv->connect_requests, request);
g_object_unref (request);
}
/**
- * lightdm_greeter_connect:
+ * lightdm_greeter_connect_to_daemon:
* @greeter: The greeter to connect
* @cancellable: (allow-none): A #GCancellable or %NULL.
* @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL.
*
* Asynchronously connects the greeter to the display manager.
*
- * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_connect_finish() to get the result of the operation.
+ * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_connect_to_daemon_finish() to get the result of the operation.
*
- * See lightdm_greeter_connect_sync() for the synchronous version.
+ * See lightdm_greeter_connect_to_daemon_sync() for the synchronous version.
**/
void
-lightdm_greeter_connect (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+lightdm_greeter_connect_to_daemon (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
LightDMGreeterPrivate *priv;
Request *request;
}
/**
- * lightdm_greeter_connect_finish:
+ * lightdm_greeter_connect_to_daemon_finish:
+ * @greeter: The greeter the the request was done with
* @result: A #GAsyncResult.
* @error: return location for a #GError, or %NULL
*
- * Finishes an operation started with lightdm_greeter_connect().
+ * Finishes an operation started with lightdm_greeter_connect_to_daemon().
*
* Return value: #TRUE if successfully connected
**/
gboolean
-lightdm_greeter_connect_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
+lightdm_greeter_connect_to_daemon_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
{
- g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
- return REQUEST (result)->complete;
+ Request *request = REQUEST (result);
+
+ g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
+
+ if (request->connected)
+ return TRUE;
+ else
+ {
+ g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED, "Failed to connect to daemon");
+ return FALSE;
+ }
}
/**
- * lightdm_greeter_connect_sync:
+ * lightdm_greeter_connect_to_daemon_sync:
* @greeter: The greeter to connect
* @error: return location for a #GError, or %NULL
*
* Return value: #TRUE if successfully connected
**/
gboolean
-lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
+lightdm_greeter_connect_to_daemon_sync (LightDMGreeter *greeter, GError **error)
{
LightDMGreeterPrivate *priv;
Request *request;
g_free (message);
} while (!request->complete);
- g_object_unref (request);
+ return lightdm_greeter_connect_to_daemon_finish (greeter, G_ASYNC_RESULT (request), error);
+}
- return request->complete;
+/**
+ * lightdm_greeter_connect_sync:
+ * @greeter: The greeter to connect
+ * @error: return location for a #GError, or %NULL
+ *
+ * Connects the greeter to the display manager. Will block until connected.
+ *
+ * Return value: #TRUE if successfully connected
+ *
+ * Deprecated: 1.11.1: Use lightdm_greeter_connect_to_daemon_sync() instead
+ **/
+gboolean
+lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
+{
+ return lightdm_greeter_connect_to_daemon_sync (greeter, error);
}
/**
*
* Get a hint.
*
- * Return value: The value for this hint or #NULL if not set.
+ * Return value: (nullable): The value for this hint or #NULL if not set.
**/
const gchar *
lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
* accounts should be taken from #LightDMUserList and displayed in the greeter
* for the user to choose from. Note that this list can be empty and it is
* recommended you show a method for the user to enter a username manually.
- *
+ *
* If this option is shown the greeter should only allow these users to be
* chosen for login unless the manual login hint is set.
*
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
value = lightdm_greeter_get_hint (greeter, "has-guest-account");
-
+
return g_strcmp0 (value, "true") == 0;
}
*
* Get the user to select by default.
*
- * Return value: A username
+ * Return value: (nullable): A username or %NULL if no particular user should be selected.
*/
const gchar *
lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
value = lightdm_greeter_get_hint (greeter, "select-guest");
-
+
return g_strcmp0 (value, "true") == 0;
}
* lightdm_greeter_get_autologin_user_hint:
* @greeter: A #LightDMGreeter
*
- * Get the user account to automatically logg into when the timer expires.
+ * Get the user account to automatically log into when the timer expires.
*
- * Return value: The user account to automatically log into.
+ * Return value: (nullable): The user account to automatically log into or %NULL if none configured.
*/
const gchar *
lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
value = lightdm_greeter_get_hint (greeter, "autologin-guest");
-
+
return g_strcmp0 (value, "true") == 0;
}
priv->cancelling_authentication = FALSE;
priv->authenticate_sequence_number++;
- priv->in_authentication = TRUE;
+ priv->in_authentication = TRUE;
priv->is_authenticated = FALSE;
if (username != priv->authentication_user)
{
*
* Get the user that is being authenticated.
*
- * Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
+ * Return value: (nullable): The username of the authentication user being authenticated or #NULL if no authentication in progress.
*/
const gchar *
lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
gboolean
lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
{
+ Request *request = REQUEST (result);
+
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
- return REQUEST (result)->return_code == 0;
+
+ if (request->return_code == 0)
+ return TRUE;
+ else
+ {
+ g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_SESSION_FAILED, "Session returned error code %d", request->return_code);
+ return FALSE;
+ }
}
/**
{
LightDMGreeterPrivate *priv;
Request *request;
- guint32 return_code;
g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
g_free (message);
} while (!request->complete);
- return_code = request->return_code;
- g_object_unref (request);
-
- return return_code == 0;
+ return lightdm_greeter_start_session_finish (greeter, G_ASYNC_RESULT (request), error);
}
/**
* @result: A #GAsyncResult.
* @greeter: A #LightDMGreeter
*
+ * Function to call from lightdm_greeter_ensure_shared_data_dir callback.
*
* Return value: The path to the shared directory, free with g_free.
**/
fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
if (fd)
{
+ GError *error = NULL;
+
priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
- g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL);
+ g_io_channel_set_encoding (priv->to_server_channel, NULL, &error);
+ if (error)
+ g_warning ("Failed to set encoding on to server channel to binary: %s\n", error->message);
+ g_clear_error (&error);
}
else
g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
if (fd)
{
+ GError *error = NULL;
+
priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
- g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
+ g_io_channel_set_encoding (priv->from_server_channel, NULL, &error);
+ if (error)
+ g_warning ("Failed to set encoding on from server channel to binary: %s\n", error->message);
+ g_clear_error (&error);
g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
}
else
"default-session-hint",
"Default session hint",
NULL,
- G_PARAM_READWRITE));
+ G_PARAM_READABLE));
g_object_class_install_property (object_class,
PROP_HIDE_USERS_HINT,
* lightdm_greeter_cancel_authentication() to abort the authentication.
**/
signals[SHOW_PROMPT] =
- g_signal_new ("show-prompt",
+ g_signal_new (LIGHTDM_GREETER_SIGNAL_SHOW_PROMPT,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
NULL, NULL,
NULL,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ G_TYPE_NONE, 2, G_TYPE_STRING, lightdm_prompt_type_get_type ());
/**
* LightDMGreeter::show-message:
* should show a message to the user.
**/
signals[SHOW_MESSAGE] =
- g_signal_new ("show-message",
+ g_signal_new (LIGHTDM_GREETER_SIGNAL_SHOW_MESSAGE,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
NULL, NULL,
NULL,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ G_TYPE_NONE, 2, G_TYPE_STRING, lightdm_message_type_get_type ());
/**
* LightDMGreeter::authentication-complete:
* was successful.
**/
signals[AUTHENTICATION_COMPLETE] =
- g_signal_new ("authentication-complete",
+ g_signal_new (LIGHTDM_GREETER_SIGNAL_AUTHENTICATION_COMPLETE,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
* The application should then call lightdm_greeter_login().
**/
signals[AUTOLOGIN_TIMER_EXPIRED] =
- g_signal_new ("autologin-timer-expired",
+ g_signal_new (LIGHTDM_GREETER_SIGNAL_AUTOLOGIN_TIMER_EXPIRED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
* resettable using lightdm_greeter_set_resettable().
**/
signals[IDLE] =
- g_signal_new ("idle",
+ g_signal_new (LIGHTDM_GREETER_SIGNAL_IDLE,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (LightDMGreeterClass, idle),
* resettable using lightdm_greeter_set_resettable().
**/
signals[RESET] =
- g_signal_new ("reset",
+ g_signal_new (LIGHTDM_GREETER_SIGNAL_RESET,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (LightDMGreeterClass, reset),
Request *request = REQUEST (object);
g_free (request->dir);
- if (request->cancellable)
- g_object_unref (request->cancellable);
+ g_clear_object (&request->cancellable);
G_OBJECT_CLASS (request_parent_class)->finalize (object);
}
return NULL;
}
-static gboolean
-request_is_tagged (GAsyncResult *res, gpointer source_tag)
-{
- return FALSE;
-}
-
static void
request_iface_init (GAsyncResultIface *iface)
{
iface->get_user_data = request_get_user_data;
iface->get_source_object = request_get_source_object;
- iface->is_tagged = request_is_tagged;
}