VirtualBox

source: vbox/trunk/src/VBox/Additions/linux/lightdm-greeter/liblightdm-gobject-1.5.0/greeter.c@ 64530

最後變更 在這個檔案從64530是 45170,由 vboxsync 提交於 12 年 前

Additions/linux: lightdm-greeter to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 46.2 KB
 
1/*
2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <[email protected]>
4 *
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 2 or version 3 of the License.
8 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
9 */
10
11#include "config.h"
12
13#include <stdlib.h>
14#include <string.h>
15#include <security/pam_appl.h>
16
17#include "lightdm/greeter.h"
18
19enum {
20 PROP_0,
21 PROP_DEFAULT_SESSION_HINT,
22 PROP_HIDE_USERS_HINT,
23 PROP_SHOW_MANUAL_LOGIN_HINT,
24 PROP_SHOW_REMOTE_LOGIN_HINT,
25 PROP_LOCK_HINT,
26 PROP_HAS_GUEST_ACCOUNT_HINT,
27 PROP_SELECT_USER_HINT,
28 PROP_SELECT_GUEST_HINT,
29 PROP_AUTOLOGIN_USER_HINT,
30 PROP_AUTOLOGIN_GUEST_HINT,
31 PROP_AUTOLOGIN_TIMEOUT_HINT,
32 PROP_AUTHENTICATION_USER,
33 PROP_IN_AUTHENTICATION,
34 PROP_IS_AUTHENTICATED,
35};
36
37enum {
38 SHOW_PROMPT,
39 SHOW_MESSAGE,
40 AUTHENTICATION_COMPLETE,
41 AUTOLOGIN_TIMER_EXPIRED,
42 LAST_SIGNAL
43};
44static guint signals[LAST_SIGNAL] = { 0 };
45
46typedef struct
47{
48 gboolean connected;
49
50 GIOChannel *to_server_channel, *from_server_channel;
51 guint8 *read_buffer;
52 gsize n_read;
53
54 gsize n_responses_waiting;
55 GList *responses_received;
56
57 GHashTable *hints;
58 guint autologin_timeout;
59
60 gchar *authentication_user;
61 gboolean in_authentication;
62 gboolean is_authenticated;
63 guint32 authenticate_sequence_number;
64 gboolean cancelling_authentication;
65} LightDMGreeterPrivate;
66
67G_DEFINE_TYPE (LightDMGreeter, lightdm_greeter, G_TYPE_OBJECT);
68
69#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterPrivate)
70
71#define HEADER_SIZE 8
72#define MAX_MESSAGE_LENGTH 1024
73
74/* Messages from the greeter to the server */
75typedef enum
76{
77 GREETER_MESSAGE_CONNECT = 0,
78 GREETER_MESSAGE_AUTHENTICATE,
79 GREETER_MESSAGE_AUTHENTICATE_AS_GUEST,
80 GREETER_MESSAGE_CONTINUE_AUTHENTICATION,
81 GREETER_MESSAGE_START_SESSION,
82 GREETER_MESSAGE_CANCEL_AUTHENTICATION,
83 GREETER_MESSAGE_SET_LANGUAGE,
84 GREETER_MESSAGE_AUTHENTICATE_REMOTE
85} GreeterMessage;
86
87/* Messages from the server to the greeter */
88typedef enum
89{
90 SERVER_MESSAGE_CONNECTED = 0,
91 SERVER_MESSAGE_PROMPT_AUTHENTICATION,
92 SERVER_MESSAGE_END_AUTHENTICATION,
93 SERVER_MESSAGE_SESSION_RESULT
94} ServerMessage;
95
96/**
97 * lightdm_greeter_new:
98 *
99 * Create a new greeter.
100 *
101 * Return value: the new #LightDMGreeter
102 **/
103LightDMGreeter *
104lightdm_greeter_new ()
105{
106 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
107}
108
109static gboolean
110timed_login_cb (gpointer data)
111{
112 LightDMGreeter *greeter = data;
113 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
114
115 priv->autologin_timeout = 0;
116 g_signal_emit (G_OBJECT (greeter), signals[AUTOLOGIN_TIMER_EXPIRED], 0);
117
118 return FALSE;
119}
120
121static guint32
122int_length ()
123{
124 return 4;
125}
126
127static void
128write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
129{
130 if (*offset + 4 >= buffer_length)
131 return;
132 buffer[*offset] = value >> 24;
133 buffer[*offset+1] = (value >> 16) & 0xFF;
134 buffer[*offset+2] = (value >> 8) & 0xFF;
135 buffer[*offset+3] = value & 0xFF;
136 *offset += 4;
137}
138
139static void
140write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
141{
142 gint length = 0;
143
144 if (value)
145 length = strlen (value);
146 write_int (buffer, buffer_length, length, offset);
147 if (*offset + length >= buffer_length)
148 return;
149 memcpy (buffer + *offset, value, length);
150 *offset += length;
151}
152
153static guint32
154read_int (guint8 *message, gsize message_length, gsize *offset)
155{
156 guint32 value;
157 guint8 *buffer;
158
159 if (message_length - *offset < int_length ())
160 {
161 g_warning ("Not enough space for int, need %i, got %zi", int_length (), message_length - *offset);
162 return 0;
163 }
164
165 buffer = message + *offset;
166 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
167 *offset += int_length ();
168
169 return value;
170}
171
172static gchar *
173read_string (guint8 *message, gsize message_length, gsize *offset)
174{
175 guint32 length;
176 gchar *value;
177
178 length = read_int (message, message_length, offset);
179 if (message_length - *offset < length)
180 {
181 g_warning ("Not enough space for string, need %u, got %zu", length, message_length - *offset);
182 return g_strdup ("");
183 }
184
185 value = g_malloc (sizeof (gchar) * (length + 1));
186 memcpy (value, message + *offset, length);
187 value[length] = '\0';
188 *offset += length;
189
190 return value;
191}
192
193static guint32
194string_length (const gchar *value)
195{
196 if (value)
197 return int_length () + strlen (value);
198 else
199 return int_length ();
200}
201
202static void
203write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
204{
205 write_int (buffer, buffer_length, id, offset);
206 write_int (buffer, buffer_length, length, offset);
207}
208
209static guint32
210get_message_length (guint8 *message, gsize message_length)
211{
212 gsize offset = 4;
213 return read_int (message, message_length, &offset);
214}
215
216static void
217write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
218{
219 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
220 GIOStatus status;
221 GError *error = NULL;
222 guint32 stated_length;
223
224 /* Double check that we're sending well-formed messages. If we say we're
225 sending more than we do, we end up DOS'ing lightdm as it waits for the
226 rest. If we say we're sending less than we do, we confuse the heck out
227 of lightdm, as it starts reading headers from the middle of our
228 messages. */
229 stated_length = HEADER_SIZE + get_message_length (message, message_length);
230 if (stated_length != message_length)
231 {
232 g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
233 return;
234 }
235
236 status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
237 if (error)
238 g_warning ("Error writing to daemon: %s", error->message);
239 g_clear_error (&error);
240 if (status == G_IO_STATUS_NORMAL)
241 g_debug ("Wrote %zi bytes to daemon", message_length);
242 g_io_channel_flush (priv->to_server_channel, NULL);
243}
244
245static void
246handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
247{
248 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
249 gchar *version;
250 GString *hint_string;
251 int timeout;
252
253 version = read_string (message, message_length, offset);
254 hint_string = g_string_new ("");
255 while (*offset < message_length)
256 {
257 gchar *name, *value;
258
259 name = read_string (message, message_length, offset);
260 value = read_string (message, message_length, offset);
261 g_hash_table_insert (priv->hints, name, value);
262 g_string_append_printf (hint_string, " %s=%s", name, value);
263 }
264
265 g_debug ("Connected version=%s%s", version, hint_string->str);
266 g_free (version);
267 g_string_free (hint_string, TRUE);
268
269 /* Set timeout for default login */
270 timeout = lightdm_greeter_get_autologin_timeout_hint (greeter);
271 if (timeout)
272 {
273 g_debug ("Setting autologin timer for %d seconds", timeout);
274 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
275 }
276}
277
278static void
279handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
280{
281 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
282 guint32 sequence_number, n_messages, i;
283 gchar *username;
284
285 sequence_number = read_int (message, message_length, offset);
286 if (sequence_number != priv->authenticate_sequence_number)
287 {
288 g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
289 return;
290 }
291
292 if (priv->cancelling_authentication)
293 {
294 g_debug ("Ignoring prompt authentication as waiting for it to cancel");
295 return;
296 }
297
298 /* Update username */
299 username = read_string (message, message_length, offset);
300 if (strcmp (username, "") == 0)
301 {
302 g_free (username);
303 username = NULL;
304 }
305 g_free (priv->authentication_user);
306 priv->authentication_user = username;
307
308 g_list_free_full (priv->responses_received, g_free);
309 priv->responses_received = NULL;
310 priv->n_responses_waiting = 0;
311
312 n_messages = read_int (message, message_length, offset);
313 g_debug ("Prompt user with %d message(s)", n_messages);
314
315 for (i = 0; i < n_messages; i++)
316 {
317 int style;
318 gchar *text;
319
320 style = read_int (message, message_length, offset);
321 text = read_string (message, message_length, offset);
322
323 // FIXME: Should stop on prompts?
324 switch (style)
325 {
326 case PAM_PROMPT_ECHO_OFF:
327 priv->n_responses_waiting++;
328 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_SECRET);
329 break;
330 case PAM_PROMPT_ECHO_ON:
331 priv->n_responses_waiting++;
332 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, text, LIGHTDM_PROMPT_TYPE_QUESTION);
333 break;
334 case PAM_ERROR_MSG:
335 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_ERROR);
336 break;
337 case PAM_TEXT_INFO:
338 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, text, LIGHTDM_MESSAGE_TYPE_INFO);
339 break;
340 }
341
342 g_free (text);
343 }
344}
345
346static void
347handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
348{
349 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
350 guint32 sequence_number, return_code;
351 gchar *username;
352
353 sequence_number = read_int (message, message_length, offset);
354
355 if (sequence_number != priv->authenticate_sequence_number)
356 {
357 g_debug ("Ignoring end authentication with invalid sequence number %d", sequence_number);
358 return;
359 }
360
361 username = read_string (message, message_length, offset);
362 return_code = read_int (message, message_length, offset);
363
364 g_debug ("Authentication complete for user %s with return code %d", username, return_code);
365
366 /* Update username */
367 if (strcmp (username, "") == 0)
368 {
369 g_free (username);
370 username = NULL;
371 }
372 g_free (priv->authentication_user);
373 priv->authentication_user = username;
374
375 priv->cancelling_authentication = FALSE;
376 priv->is_authenticated = (return_code == 0);
377
378 priv->in_authentication = FALSE;
379 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
380}
381
382static guint8 *
383read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
384{
385 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
386 gsize n_to_read, n_read;
387 guint8 *buffer;
388 GError *error = NULL;
389
390 /* Read the header, or the whole message if we already have that */
391 n_to_read = HEADER_SIZE;
392 if (priv->n_read >= HEADER_SIZE)
393 n_to_read += get_message_length (priv->read_buffer, priv->n_read);
394
395 do
396 {
397 GIOStatus status;
398 status = g_io_channel_read_chars (priv->from_server_channel,
399 (gchar *) priv->read_buffer + priv->n_read,
400 n_to_read - priv->n_read,
401 &n_read,
402 &error);
403 if (error)
404 g_warning ("Error reading from server: %s", error->message);
405 g_clear_error (&error);
406 if (status != G_IO_STATUS_NORMAL)
407 break;
408
409 g_debug ("Read %zi bytes from daemon", n_read);
410
411 priv->n_read += n_read;
412 } while (priv->n_read < n_to_read && block);
413
414 /* Stop if haven't got all the data we want */
415 if (priv->n_read != n_to_read)
416 return FALSE;
417
418 /* If have header, rerun for content */
419 if (priv->n_read == HEADER_SIZE)
420 {
421 n_to_read = get_message_length (priv->read_buffer, priv->n_read);
422 if (n_to_read > 0)
423 {
424 priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
425 return read_message (greeter, length, block);
426 }
427 }
428
429 buffer = priv->read_buffer;
430 *length = priv->n_read;
431
432 priv->read_buffer = g_malloc (priv->n_read);
433 priv->n_read = 0;
434
435 return buffer;
436}
437
438static gboolean
439from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
440{
441 LightDMGreeter *greeter = data;
442 guint8 *message;
443 gsize message_length, offset;
444 guint32 id;
445
446 message = read_message (greeter, &message_length, FALSE);
447 if (!message)
448 return TRUE;
449
450 offset = 0;
451 id = read_int (message, message_length, &offset);
452 read_int (message, message_length, &offset);
453 switch (id)
454 {
455 case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
456 handle_prompt_authentication (greeter, message, message_length, &offset);
457 break;
458 case SERVER_MESSAGE_END_AUTHENTICATION:
459 handle_end_authentication (greeter, message, message_length, &offset);
460 break;
461 default:
462 g_warning ("Unknown message from server: %d", id);
463 break;
464 }
465 g_free (message);
466
467 return TRUE;
468}
469
470/**
471 * lightdm_greeter_connect_sync:
472 * @greeter: The greeter to connect
473 * @error: return location for a #GError, or %NULL
474 *
475 * Connects the greeter to the display manager. Will block until connected.
476 *
477 * Return value: #TRUE if successfully connected
478 **/
479gboolean
480lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error)
481{
482 LightDMGreeterPrivate *priv;
483 const gchar *fd;
484 guint8 message[MAX_MESSAGE_LENGTH];
485 guint8 *response;
486 gsize response_length, offset = 0;
487 guint32 id;
488
489 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
490
491 priv = GET_PRIVATE (greeter);
492
493 fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
494 if (!fd)
495 {
496 g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
497 return FALSE;
498 }
499 priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
500 g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL);
501
502 fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
503 if (!fd)
504 {
505 g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
506 return FALSE;
507 }
508 priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
509 g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
510 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
511
512 g_debug ("Connecting to display manager...");
513 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
514 write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
515 write_message (greeter, message, offset);
516
517 response = read_message (greeter, &response_length, TRUE);
518 if (!response)
519 return FALSE;
520
521 offset = 0;
522 id = read_int (response, response_length, &offset);
523 read_int (response, response_length, &offset);
524 if (id == SERVER_MESSAGE_CONNECTED)
525 handle_connected (greeter, response, response_length, &offset);
526 g_free (response);
527 if (id != SERVER_MESSAGE_CONNECTED)
528 {
529 g_warning ("Expected CONNECTED message, got %d", id);
530 return FALSE;
531 }
532
533 priv->connected = TRUE;
534
535 return TRUE;
536}
537
538/**
539 * lightdm_greeter_get_hint:
540 * @greeter: A #LightDMGreeter
541 * @name: The hint name to query.
542 *
543 * Get a hint.
544 *
545 * Return value: The value for this hint or #NULL if not set.
546 **/
547const gchar *
548lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name)
549{
550 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
551 return g_hash_table_lookup (GET_PRIVATE (greeter)->hints, name);
552}
553
554/**
555 * lightdm_greeter_get_default_session_hint:
556 * @greeter: A #LightDMGreeter
557 *
558 * Get the default session to use.
559 *
560 * Return value: The session name
561 **/
562const gchar *
563lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
564{
565 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
566 return lightdm_greeter_get_hint (greeter, "default-session");
567}
568
569/**
570 * lightdm_greeter_get_hide_users_hint:
571 * @greeter: A #LightDMGreeter
572 *
573 * Check if user accounts should be shown. If this is TRUE then the list of
574 * accounts should be taken from #LightDMUserList and displayed in the greeter
575 * for the user to choose from. Note that this list can be empty and it is
576 * recommended you show a method for the user to enter a username manually.
577 *
578 * If this option is shown the greeter should only allow these users to be
579 * chosen for login unless the manual login hint is set.
580 *
581 * Return value: #TRUE if the available users should not be shown.
582 */
583gboolean
584lightdm_greeter_get_hide_users_hint (LightDMGreeter *greeter)
585{
586 const gchar *value;
587
588 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
589 value = lightdm_greeter_get_hint (greeter, "hide-users");
590
591 return g_strcmp0 (value, "true") == 0;
592}
593
594/**
595 * lightdm_greeter_get_show_manual_login_hint:
596 * @greeter: A #LightDMGreeter
597 *
598 * Check if a manual login option should be shown. If set the GUI
599 * should provide a way for a username to be entered manually.
600 * Without this hint a greeter which is showing a user list can
601 * limit logins to only those users.
602 *
603 * Return value: #TRUE if a manual login option should be shown.
604 */
605gboolean
606lightdm_greeter_get_show_manual_login_hint (LightDMGreeter *greeter)
607{
608 const gchar *value;
609
610 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
611 value = lightdm_greeter_get_hint (greeter, "show-manual-login");
612
613 return g_strcmp0 (value, "true") == 0;
614}
615
616/**
617 * lightdm_greeter_get_show_remote_login_hint:
618 * @greeter: A #LightDMGreeter
619 *
620 * Check if a remote login option should be shown. If set the GUI
621 * should provide a way for a user to log into a remote desktop server.
622 *
623 * Return value: #TRUE if a remote login option should be shown.
624 */
625gboolean
626lightdm_greeter_get_show_remote_login_hint (LightDMGreeter *greeter)
627{
628 const gchar *value;
629
630 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
631 value = lightdm_greeter_get_hint (greeter, "show-remote-login");
632
633 return g_strcmp0 (value, "true") == 0;
634}
635
636/**
637 * lightdm_greeter_get_lock_hint:
638 * @greeter: A #LightDMGreeter
639 *
640 * Check if the greeter is acting as a lock screen.
641 *
642 * Return value: #TRUE if the greeter was triggered by locking the seat.
643 */
644gboolean
645lightdm_greeter_get_lock_hint (LightDMGreeter *greeter)
646{
647 const gchar *value;
648
649 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
650 value = lightdm_greeter_get_hint (greeter, "lock-screen");
651
652 return g_strcmp0 (value, "true") == 0;
653}
654
655/**
656 * lightdm_greeter_get_has_guest_account_hint:
657 * @greeter: A #LightDMGreeter
658 *
659 * Check if guest sessions are supported.
660 *
661 * Return value: #TRUE if guest sessions are supported.
662 */
663gboolean
664lightdm_greeter_get_has_guest_account_hint (LightDMGreeter *greeter)
665{
666 const gchar *value;
667
668 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
669 value = lightdm_greeter_get_hint (greeter, "has-guest-account");
670
671 return g_strcmp0 (value, "true") == 0;
672}
673
674/**
675 * lightdm_greeter_get_select_user_hint:
676 * @greeter: A #LightDMGreeter
677 *
678 * Get the user to select by default.
679 *
680 * Return value: A username
681 */
682const gchar *
683lightdm_greeter_get_select_user_hint (LightDMGreeter *greeter)
684{
685 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
686 return lightdm_greeter_get_hint (greeter, "select-user");
687}
688
689/**
690 * lightdm_greeter_get_select_guest_hint:
691 * @greeter: A #LightDMGreeter
692 *
693 * Check if the guest account should be selected by default.
694 *
695 * Return value: #TRUE if the guest account should be selected by default.
696 */
697gboolean
698lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter)
699{
700 const gchar *value;
701
702 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
703 value = lightdm_greeter_get_hint (greeter, "select-guest");
704
705 return g_strcmp0 (value, "true") == 0;
706}
707
708/**
709 * lightdm_greeter_get_autologin_user_hint:
710 * @greeter: A #LightDMGreeter
711 *
712 * Get the user account to automatically logg into when the timer expires.
713 *
714 * Return value: The user account to automatically log into.
715 */
716const gchar *
717lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter)
718{
719 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
720 return lightdm_greeter_get_hint (greeter, "autologin-user");
721}
722
723/**
724 * lightdm_greeter_get_autologin_guest_hint:
725 * @greeter: A #LightDMGreeter
726 *
727 * Check if the guest account should be automatically logged into when the timer expires.
728 *
729 * Return value: #TRUE if the guest account should be automatically logged into.
730 */
731gboolean
732lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter)
733{
734 const gchar *value;
735
736 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
737 value = lightdm_greeter_get_hint (greeter, "autologin-guest");
738
739 return g_strcmp0 (value, "true") == 0;
740}
741
742/**
743 * lightdm_greeter_get_autologin_timeout_hint:
744 * @greeter: A #LightDMGreeter
745 *
746 * Get the number of seconds to wait before automaitcally logging in.
747 *
748 * Return value: The number of seconds to wait before automatically logging in or 0 for no timeout.
749 */
750gint
751lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter)
752{
753 const gchar *value;
754 gint timeout = 0;
755
756 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
757 value = lightdm_greeter_get_hint (greeter, "autologin-timeout");
758 if (value)
759 timeout = atoi (value);
760 if (timeout < 0)
761 timeout = 0;
762
763 return timeout;
764}
765
766/**
767 * lightdm_greeter_cancel_autologin:
768 * @greeter: A #LightDMGreeter
769 *
770 * Cancel the automatic login.
771 */
772void
773lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
774{
775 LightDMGreeterPrivate *priv;
776
777 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
778
779 priv = GET_PRIVATE (greeter);
780
781 if (priv->autologin_timeout)
782 g_source_remove (priv->autologin_timeout);
783 priv->autologin_timeout = 0;
784}
785
786/**
787 * lightdm_greeter_authenticate:
788 * @greeter: A #LightDMGreeter
789 * @username: (allow-none): A username or #NULL to prompt for a username.
790 *
791 * Starts the authentication procedure for a user.
792 **/
793void
794lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
795{
796 LightDMGreeterPrivate *priv;
797 guint8 message[MAX_MESSAGE_LENGTH];
798 gsize offset = 0;
799
800 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
801
802 priv = GET_PRIVATE (greeter);
803
804 g_return_if_fail (priv->connected);
805
806 priv->cancelling_authentication = FALSE;
807 priv->authenticate_sequence_number++;
808 priv->in_authentication = TRUE;
809 priv->is_authenticated = FALSE;
810 if (username != priv->authentication_user)
811 {
812 g_free (priv->authentication_user);
813 priv->authentication_user = g_strdup (username);
814 }
815
816 g_debug ("Starting authentication for user %s...", username);
817 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
818 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
819 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
820 write_message (greeter, message, offset);
821}
822
823/**
824 * lightdm_greeter_authenticate_as_guest:
825 * @greeter: A #LightDMGreeter
826 *
827 * Starts the authentication procedure for the guest user.
828 **/
829void
830lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
831{
832 LightDMGreeterPrivate *priv;
833 guint8 message[MAX_MESSAGE_LENGTH];
834 gsize offset = 0;
835
836 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
837
838 priv = GET_PRIVATE (greeter);
839
840 g_return_if_fail (priv->connected);
841
842 priv->cancelling_authentication = FALSE;
843 priv->authenticate_sequence_number++;
844 priv->in_authentication = TRUE;
845 priv->is_authenticated = FALSE;
846 g_free (priv->authentication_user);
847 priv->authentication_user = NULL;
848
849 g_debug ("Starting authentication for guest account...");
850 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
851 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
852 write_message (greeter, message, offset);
853}
854
855/**
856 * lightdm_greeter_authenticate_autologin:
857 * @greeter: A #LightDMGreeter
858 *
859 * Starts the authentication procedure for the automatic login user.
860 **/
861void
862lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
863{
864 const gchar *user;
865
866 user = lightdm_greeter_get_autologin_user_hint (greeter);
867 if (lightdm_greeter_get_autologin_guest_hint (greeter))
868 lightdm_greeter_authenticate_as_guest (greeter);
869 else if (user)
870 lightdm_greeter_authenticate (greeter, user);
871}
872
873/**
874 * lightdm_greeter_authenticate_remote:
875 * @greeter: A #LightDMGreeter
876 * @session: The name of a remote session
877 * @username: (allow-none): A username of #NULL to prompt for a username.
878 *
879 * Start authentication for a remote session type.
880 **/
881void
882lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
883{
884 LightDMGreeterPrivate *priv;
885 guint8 message[MAX_MESSAGE_LENGTH];
886 gsize offset = 0;
887
888 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
889
890 priv = GET_PRIVATE (greeter);
891
892 g_return_if_fail (priv->connected);
893
894 priv->cancelling_authentication = FALSE;
895 priv->authenticate_sequence_number++;
896 priv->in_authentication = TRUE;
897 priv->is_authenticated = FALSE;
898 g_free (priv->authentication_user);
899 priv->authentication_user = NULL;
900
901 if (username)
902 g_debug ("Starting authentication for remote session %s as user %s...", session, username);
903 else
904 g_debug ("Starting authentication for remote session %s...", session);
905 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
906 write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
907 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
908 write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
909 write_message (greeter, message, offset);
910}
911
912/**
913 * lightdm_greeter_respond:
914 * @greeter: A #LightDMGreeter
915 * @response: Response to a prompt
916 *
917 * Provide response to a prompt. May be one in a series.
918 **/
919void
920lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
921{
922 LightDMGreeterPrivate *priv;
923 guint8 message[MAX_MESSAGE_LENGTH];
924 gsize offset = 0;
925
926 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
927 g_return_if_fail (response != NULL);
928
929 priv = GET_PRIVATE (greeter);
930
931 g_return_if_fail (priv->connected);
932 g_return_if_fail (priv->n_responses_waiting > 0);
933
934 priv->n_responses_waiting--;
935 priv->responses_received = g_list_append (priv->responses_received, g_strdup (response));
936
937 if (priv->n_responses_waiting == 0)
938 {
939 guint32 msg_length;
940 GList *iter;
941
942 g_debug ("Providing response to display manager");
943
944 msg_length = int_length ();
945 for (iter = priv->responses_received; iter; iter = iter->next)
946 {
947 msg_length += string_length ((gchar *)iter->data);
948 }
949
950 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
951 write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset);
952 for (iter = priv->responses_received; iter; iter = iter->next)
953 {
954 write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset);
955 }
956 write_message (greeter, message, offset);
957
958 g_list_free_full (priv->responses_received, g_free);
959 priv->responses_received = NULL;
960 }
961}
962
963/**
964 * lightdm_greeter_cancel_authentication:
965 * @greeter: A #LightDMGreeter
966 *
967 * Cancel the current user authentication.
968 **/
969void
970lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
971{
972 LightDMGreeterPrivate *priv;
973 guint8 message[MAX_MESSAGE_LENGTH];
974 gsize offset = 0;
975
976 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
977
978 priv = GET_PRIVATE (greeter);
979
980 g_return_if_fail (priv->connected);
981
982 priv->cancelling_authentication = TRUE;
983 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
984 write_message (greeter, message, offset);
985}
986
987/**
988 * lightdm_greeter_get_in_authentication:
989 * @greeter: A #LightDMGreeter
990 *
991 * Checks if the greeter is in the process of authenticating.
992 *
993 * Return value: #TRUE if the greeter is authenticating a user.
994 **/
995gboolean
996lightdm_greeter_get_in_authentication (LightDMGreeter *greeter)
997{
998 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
999 return GET_PRIVATE (greeter)->in_authentication;
1000}
1001
1002/**
1003 * lightdm_greeter_get_is_authenticated:
1004 * @greeter: A #LightDMGreeter
1005 *
1006 * Checks if the greeter has successfully authenticated.
1007 *
1008 * Return value: #TRUE if the greeter is authenticated for login.
1009 **/
1010gboolean
1011lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter)
1012{
1013 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1014 return GET_PRIVATE (greeter)->is_authenticated;
1015}
1016
1017/**
1018 * lightdm_greeter_get_authentication_user:
1019 * @greeter: A #LightDMGreeter
1020 *
1021 * Get the user that is being authenticated.
1022 *
1023 * Return value: The username of the authentication user being authenticated or #NULL if no authentication in progress.
1024 */
1025const gchar *
1026lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
1027{
1028 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1029 return GET_PRIVATE (greeter)->authentication_user;
1030}
1031
1032/**
1033 * lightdm_greeter_set_language:
1034 * @greeter: A #LightDMGreeter
1035 * @language: The language to use for this user.
1036 *
1037 * Set the language for the currently authenticated user.
1038 **/
1039void
1040lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
1041{
1042 LightDMGreeterPrivate *priv;
1043 guint8 message[MAX_MESSAGE_LENGTH];
1044 gsize offset = 0;
1045
1046 g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1047
1048 priv = GET_PRIVATE (greeter);
1049
1050 g_return_if_fail (priv->connected);
1051
1052 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
1053 write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
1054 write_message (greeter, message, offset);
1055}
1056
1057/**
1058 * lightdm_greeter_start_session_sync:
1059 * @greeter: A #LightDMGreeter
1060 * @session: (allow-none): The session to log into or #NULL to use the default.
1061 * @error: return location for a #GError, or %NULL
1062 *
1063 * Start a session for the authenticated user.
1064 *
1065 * Return value: TRUE if the session was started.
1066 **/
1067gboolean
1068lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error)
1069{
1070 LightDMGreeterPrivate *priv;
1071 guint8 message[MAX_MESSAGE_LENGTH];
1072 guint8 *response;
1073 gsize response_length, offset = 0;
1074 guint32 id, return_code = 1;
1075
1076 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1077
1078 priv = GET_PRIVATE (greeter);
1079
1080 g_return_val_if_fail (priv->connected, FALSE);
1081 g_return_val_if_fail (priv->is_authenticated, FALSE);
1082
1083 if (session)
1084 g_debug ("Starting session %s", session);
1085 else
1086 g_debug ("Starting default session");
1087
1088 write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
1089 write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
1090 write_message (greeter, message, offset);
1091
1092 response = read_message (greeter, &response_length, TRUE);
1093 if (!response)
1094 return FALSE;
1095
1096 offset = 0;
1097 id = read_int (response, response_length, &offset);
1098 read_int (response, response_length, &offset);
1099 if (id == SERVER_MESSAGE_SESSION_RESULT)
1100 return_code = read_int (response, response_length, &offset);
1101 else
1102 g_warning ("Expected SESSION_RESULT message, got %d", id);
1103
1104 g_free (response);
1105
1106 return return_code == 0;
1107}
1108
1109static void
1110lightdm_greeter_init (LightDMGreeter *greeter)
1111{
1112 LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
1113
1114 priv->read_buffer = g_malloc (HEADER_SIZE);
1115 priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1116}
1117
1118static void
1119lightdm_greeter_set_property (GObject *object,
1120 guint prop_id,
1121 const GValue *value,
1122 GParamSpec *pspec)
1123{
1124 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1125}
1126
1127static void
1128lightdm_greeter_get_property (GObject *object,
1129 guint prop_id,
1130 GValue *value,
1131 GParamSpec *pspec)
1132{
1133 LightDMGreeter *self;
1134
1135 self = LIGHTDM_GREETER (object);
1136
1137 switch (prop_id) {
1138 case PROP_DEFAULT_SESSION_HINT:
1139 g_value_set_string (value, lightdm_greeter_get_default_session_hint (self));
1140 break;
1141 case PROP_HIDE_USERS_HINT:
1142 g_value_set_boolean (value, lightdm_greeter_get_hide_users_hint (self));
1143 break;
1144 case PROP_SHOW_MANUAL_LOGIN_HINT:
1145 g_value_set_boolean (value, lightdm_greeter_get_show_manual_login_hint (self));
1146 break;
1147 case PROP_SHOW_REMOTE_LOGIN_HINT:
1148 g_value_set_boolean (value, lightdm_greeter_get_show_remote_login_hint (self));
1149 break;
1150 case PROP_LOCK_HINT:
1151 g_value_set_boolean (value, lightdm_greeter_get_lock_hint (self));
1152 break;
1153 case PROP_HAS_GUEST_ACCOUNT_HINT:
1154 g_value_set_boolean (value, lightdm_greeter_get_has_guest_account_hint (self));
1155 break;
1156 case PROP_SELECT_USER_HINT:
1157 g_value_set_string (value, lightdm_greeter_get_select_user_hint (self));
1158 break;
1159 case PROP_SELECT_GUEST_HINT:
1160 g_value_set_boolean (value, lightdm_greeter_get_select_guest_hint (self));
1161 break;
1162 case PROP_AUTOLOGIN_USER_HINT:
1163 g_value_set_string (value, lightdm_greeter_get_autologin_user_hint (self));
1164 break;
1165 case PROP_AUTOLOGIN_GUEST_HINT:
1166 g_value_set_boolean (value, lightdm_greeter_get_autologin_guest_hint (self));
1167 break;
1168 case PROP_AUTOLOGIN_TIMEOUT_HINT:
1169 g_value_set_int (value, lightdm_greeter_get_autologin_timeout_hint (self));
1170 break;
1171 case PROP_AUTHENTICATION_USER:
1172 g_value_set_string (value, lightdm_greeter_get_authentication_user (self));
1173 break;
1174 case PROP_IN_AUTHENTICATION:
1175 g_value_set_boolean (value, lightdm_greeter_get_in_authentication (self));
1176 break;
1177 case PROP_IS_AUTHENTICATED:
1178 g_value_set_boolean (value, lightdm_greeter_get_is_authenticated (self));
1179 break;
1180 default:
1181 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1182 break;
1183 }
1184}
1185
1186static void
1187marshal_VOID__STRING_INT (GClosure *closure,
1188 GValue *return_value G_GNUC_UNUSED,
1189 guint n_param_values,
1190 const GValue *param_values,
1191 gpointer invocation_hint G_GNUC_UNUSED,
1192 gpointer marshal_data)
1193{
1194 typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1,
1195 gpointer arg_1,
1196 gint arg_2,
1197 gpointer data2);
1198 register GMarshalFunc_VOID__STRING_INT callback;
1199 register GCClosure *cc = (GCClosure*) closure;
1200 register gpointer data1, data2;
1201
1202 g_return_if_fail (n_param_values == 3);
1203
1204 if (G_CCLOSURE_SWAP_DATA (closure))
1205 {
1206 data1 = closure->data;
1207 data2 = g_value_peek_pointer (param_values + 0);
1208 }
1209 else
1210 {
1211 data1 = g_value_peek_pointer (param_values + 0);
1212 data2 = closure->data;
1213 }
1214 callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
1215
1216 callback (data1,
1217 (param_values + 1)->data[0].v_pointer,
1218 (param_values + 2)->data[0].v_int,
1219 data2);
1220}
1221
1222static void
1223lightdm_greeter_finalize (GObject *object)
1224{
1225 LightDMGreeter *self = LIGHTDM_GREETER (object);
1226 LightDMGreeterPrivate *priv = GET_PRIVATE (self);
1227
1228 if (priv->to_server_channel)
1229 g_io_channel_unref (priv->to_server_channel);
1230 if (priv->from_server_channel)
1231 g_io_channel_unref (priv->from_server_channel);
1232 g_free (priv->authentication_user);
1233 g_hash_table_unref (priv->hints);
1234
1235 G_OBJECT_CLASS (lightdm_greeter_parent_class)->finalize (object);
1236}
1237
1238static void
1239lightdm_greeter_class_init (LightDMGreeterClass *klass)
1240{
1241 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1242
1243 g_type_class_add_private (klass, sizeof (LightDMGreeterPrivate));
1244
1245 object_class->set_property = lightdm_greeter_set_property;
1246 object_class->get_property = lightdm_greeter_get_property;
1247 object_class->finalize = lightdm_greeter_finalize;
1248
1249 g_object_class_install_property (object_class,
1250 PROP_DEFAULT_SESSION_HINT,
1251 g_param_spec_string ("default-session-hint",
1252 "default-session-hint",
1253 "Default session hint",
1254 NULL,
1255 G_PARAM_READWRITE));
1256
1257 g_object_class_install_property (object_class,
1258 PROP_HIDE_USERS_HINT,
1259 g_param_spec_boolean ("hide-users-hint",
1260 "hide-users-hint",
1261 "Hide users hint",
1262 FALSE,
1263 G_PARAM_READABLE));
1264
1265 g_object_class_install_property (object_class,
1266 PROP_SHOW_MANUAL_LOGIN_HINT,
1267 g_param_spec_boolean ("show-manual-login-hint",
1268 "show-manual-login-hint",
1269 "Show manual login hint",
1270 FALSE,
1271 G_PARAM_READABLE));
1272
1273 g_object_class_install_property (object_class,
1274 PROP_SHOW_REMOTE_LOGIN_HINT,
1275 g_param_spec_boolean ("show-remote-login-hint",
1276 "show-remote-login-hint",
1277 "Show remote login hint",
1278 FALSE,
1279 G_PARAM_READABLE));
1280
1281 g_object_class_install_property (object_class,
1282 PROP_LOCK_HINT,
1283 g_param_spec_boolean ("lock-hint",
1284 "lock-hint",
1285 "Lock hint",
1286 FALSE,
1287 G_PARAM_READABLE));
1288
1289 g_object_class_install_property (object_class,
1290 PROP_HAS_GUEST_ACCOUNT_HINT,
1291 g_param_spec_boolean ("has-guest-account-hint",
1292 "has-guest-account-hint",
1293 "Has guest account hint",
1294 FALSE,
1295 G_PARAM_READABLE));
1296
1297 g_object_class_install_property (object_class,
1298 PROP_SELECT_USER_HINT,
1299 g_param_spec_string ("select-user-hint",
1300 "select-user-hint",
1301 "Select user hint",
1302 NULL,
1303 G_PARAM_READABLE));
1304
1305 g_object_class_install_property (object_class,
1306 PROP_SELECT_GUEST_HINT,
1307 g_param_spec_boolean ("select-guest-hint",
1308 "select-guest-hint",
1309 "Select guest account hint",
1310 FALSE,
1311 G_PARAM_READABLE));
1312
1313 g_object_class_install_property (object_class,
1314 PROP_AUTOLOGIN_USER_HINT,
1315 g_param_spec_string ("autologin-user-hint",
1316 "autologin-user-hint",
1317 "Autologin user hint",
1318 NULL,
1319 G_PARAM_READABLE));
1320
1321 g_object_class_install_property (object_class,
1322 PROP_AUTOLOGIN_GUEST_HINT,
1323 g_param_spec_boolean ("autologin-guest-hint",
1324 "autologin-guest-hint",
1325 "Autologin guest account hint",
1326 FALSE,
1327 G_PARAM_READABLE));
1328
1329 g_object_class_install_property (object_class,
1330 PROP_AUTOLOGIN_TIMEOUT_HINT,
1331 g_param_spec_int ("autologin-timeout-hint",
1332 "autologin-timeout-hint",
1333 "Autologin timeout hint",
1334 0, G_MAXINT, 0,
1335 G_PARAM_READABLE));
1336
1337 g_object_class_install_property (object_class,
1338 PROP_AUTHENTICATION_USER,
1339 g_param_spec_string ("authentication-user",
1340 "authentication-user",
1341 "The user being authenticated",
1342 NULL,
1343 G_PARAM_READABLE));
1344 g_object_class_install_property (object_class,
1345 PROP_IN_AUTHENTICATION,
1346 g_param_spec_boolean ("in-authentication",
1347 "in-authentication",
1348 "TRUE if a user is being authenticated",
1349 FALSE,
1350 G_PARAM_READABLE));
1351 g_object_class_install_property (object_class,
1352 PROP_IS_AUTHENTICATED,
1353 g_param_spec_boolean ("is-authenticated",
1354 "is-authenticated",
1355 "TRUE if the selected user is authenticated",
1356 FALSE,
1357 G_PARAM_READABLE));
1358
1359 /**
1360 * LightDMGreeter::show-prompt:
1361 * @greeter: A #LightDMGreeter
1362 * @text: Prompt text
1363 * @type: Prompt type
1364 *
1365 * The ::show-prompt signal gets emitted when the greeter should show a
1366 * prompt to the user. The given text should be displayed and an input
1367 * field for the user to provide a response.
1368 *
1369 * Call lightdm_greeter_respond() with the resultant input or
1370 * lightdm_greeter_cancel_authentication() to abort the authentication.
1371 **/
1372 signals[SHOW_PROMPT] =
1373 g_signal_new ("show-prompt",
1374 G_TYPE_FROM_CLASS (klass),
1375 G_SIGNAL_RUN_LAST,
1376 G_STRUCT_OFFSET (LightDMGreeterClass, show_prompt),
1377 NULL, NULL,
1378 marshal_VOID__STRING_INT,
1379 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1380
1381 /**
1382 * LightDMGreeter::show-message:
1383 * @greeter: A #LightDMGreeter
1384 * @text: Message text
1385 * @type: Message type
1386 *
1387 * The ::show-message signal gets emitted when the greeter
1388 * should show a message to the user.
1389 **/
1390 signals[SHOW_MESSAGE] =
1391 g_signal_new ("show-message",
1392 G_TYPE_FROM_CLASS (klass),
1393 G_SIGNAL_RUN_LAST,
1394 G_STRUCT_OFFSET (LightDMGreeterClass, show_message),
1395 NULL, NULL,
1396 marshal_VOID__STRING_INT,
1397 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
1398
1399 /**
1400 * LightDMGreeter::authentication-complete:
1401 * @greeter: A #LightDMGreeter
1402 *
1403 * The ::authentication-complete signal gets emitted when the greeter
1404 * has completed authentication.
1405 *
1406 * Call lightdm_greeter_get_is_authenticated() to check if the authentication
1407 * was successful.
1408 **/
1409 signals[AUTHENTICATION_COMPLETE] =
1410 g_signal_new ("authentication-complete",
1411 G_TYPE_FROM_CLASS (klass),
1412 G_SIGNAL_RUN_LAST,
1413 G_STRUCT_OFFSET (LightDMGreeterClass, authentication_complete),
1414 NULL, NULL,
1415 g_cclosure_marshal_VOID__VOID,
1416 G_TYPE_NONE, 0);
1417
1418 /**
1419 * LightDMGreeter::autologin-timer-expired:
1420 * @greeter: A #LightDMGreeter
1421 *
1422 * The ::timed-login signal gets emitted when the automatic login timer has expired.
1423 * The application should then call lightdm_greeter_login().
1424 **/
1425 signals[AUTOLOGIN_TIMER_EXPIRED] =
1426 g_signal_new ("autologin-timer-expired",
1427 G_TYPE_FROM_CLASS (klass),
1428 G_SIGNAL_RUN_LAST,
1429 G_STRUCT_OFFSET (LightDMGreeterClass, autologin_timer_expired),
1430 NULL, NULL,
1431 g_cclosure_marshal_VOID__VOID,
1432 G_TYPE_NONE, 0);
1433}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette