~unity-greeter-team/unity-greeter/12.10

239.1.1 by Michael Terry
add modelines so I don't keep screwing up the tabbing
1
/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*-
2
 *
56 by Robert Ancell
Add copyright headers to the .vala files
3
 * Copyright (C) 2011 Canonical Ltd
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 3 as
7
 * published by the Free Software Foundation.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * Authored by: Robert Ancell <robert.ancell@canonical.com>
18
 */
19
240.1.2 by Michael Terry
fix look of boxes to more closely match latest mockups; change grid size to 40
20
public const int grid_size = 40;
240.1.1 by Michael Terry
dynamically generate login box background; make it a container class for easier reuse
21
1 by Robert Ancell
Stub project for unity-greeter
22
public class UnityGreeter
23
{
545.2.9 by Albert Astals
Make test_mode non static too
24
    public static UnityGreeter singleton;
37 by Robert Ancell
Handle command line args
25
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
26
    public signal void show_message (string text, LightDM.MessageType type);
27
    public signal void show_prompt (string text, LightDM.PromptType type);
28
    public signal void authentication_complete ();
593.1.1 by Michael Terry
have menubar clean up onboard before we start the session
29
    public signal void starting_session ();
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
30
545.2.9 by Albert Astals
Make test_mode non static too
31
    public bool test_mode = false;
32
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
33
    private string state_file;
34
    private KeyFile state;
35
36
    private Cairo.XlibSurface background_surface;
67 by Robert Ancell
Add a config file and load Ambiance theme
37
74.2.2 by Michael Terry
use g-s-d instead of our own logic
38
    private SettingsDaemon settings_daemon;
74.2.1 by Robert Ancell
Work on the power management stuff
39
613 by Michael Terry
Workaround an orca problem where it doesn't notice the currently focused widget on startup. With this fix, it will no longer read your password as you type it.
40
    public bool orca_needs_kick;
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
41
    private MainWindow main_window;
410.2.3 by Michael Terry
move all the user logging in logic into UserList
42
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
43
    private LightDM.Greeter greeter;
410.2.3 by Michael Terry
move all the user logging in logic into UserList
44
285.1.2 by Conor Curran
use libcanberra vala bindings so as we can be explicit as to what theme to use
45
    private Canberra.Context canberra_context;
38 by Robert Ancell
Connect up to LightDM
46
545.2.9 by Albert Astals
Make test_mode non static too
47
    private static Timer log_timer;
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
48
545.2.9 by Albert Astals
Make test_mode non static too
49
    private UnityGreeter (bool test_mode_)
1 by Robert Ancell
Stub project for unity-greeter
50
    {
545.2.9 by Albert Astals
Make test_mode non static too
51
        singleton = this;
52
        test_mode = test_mode_;
53
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
54
        /* Prepare to set the background */
55
        debug ("Creating background surface");
56
        background_surface = create_root_surface (Gdk.Screen.get_default ());
57
61 by Robert Ancell
Fix loading of user list
58
        greeter = new LightDM.Greeter ();
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
59
        greeter.show_message.connect ((text, type) => { show_message (text, type); });
60
        greeter.show_prompt.connect ((text, type) => { show_prompt (text, type); });
614 by Michael Terry
Fix timed login by paying attention to the signal from lightdm. Patch from upstream trunk.
61
        greeter.autologin_timer_expired.connect (() => { greeter.authenticate_autologin (); });
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
62
        greeter.authentication_complete.connect (() => { authentication_complete (); });
237 by Robert Ancell
Don't run the greeter if can't connect to daemon and not in test mode
63
        var connected = false;
64
        try
65
        {
66
            connected = greeter.connect_sync ();
67
        }
68
        catch (Error e)
69
        {
70
            warning ("Failed to connect to LightDM daemon");
71
        }
72
        if (!connected && !test_mode)
73
            Posix.exit (Posix.EXIT_FAILURE);
58 by Robert Ancell
Update to liblightdm-1
74
89 by Robert Ancell
Run gnome-settings-daemon to get power management, a11y, xrandr etc
75
        if (!test_mode)
76
        {
113 by Robert Ancell
Re-enable settings daemon
77
            settings_daemon = new SettingsDaemon ();
561 by Michael Terry
fix some valac-0.18 compiler warnings
78
            settings_daemon.start.begin ();
89 by Robert Ancell
Run gnome-settings-daemon to get power management, a11y, xrandr etc
79
        }
74.2.1 by Robert Ancell
Work on the power management stuff
80
198 by Robert Ancell
Remember the last selected user between logins
81
        var state_dir = Path.build_filename (Environment.get_user_cache_dir (), "unity-greeter");
82
        DirUtils.create_with_parents (state_dir, 0775);
83
430.1.1 by Michael Terry
avoid writing garbage to the state file
84
        state_file = Path.build_filename (state_dir, "state");
198 by Robert Ancell
Remember the last selected user between logins
85
        state = new KeyFile ();
86
        try
87
        {
430.1.1 by Michael Terry
avoid writing garbage to the state file
88
            state.load_from_file (state_file, KeyFileFlags.NONE);
198 by Robert Ancell
Remember the last selected user between logins
89
        }
90
        catch (Error e)
91
        {
92
            if (!(e is FileError.NOENT))
430.1.1 by Michael Terry
avoid writing garbage to the state file
93
                warning ("Failed to load state from %s: %s\n", state_file, e.message);
198 by Robert Ancell
Remember the last selected user between logins
94
        }
95
250.1.1 by Michael Terry
Create MainWindow class and move some code (and UserList) into it
96
        main_window = new MainWindow ();
239.5.1 by Michael Terry
focus new windows as they appear
97
98
        start_fake_wm ();
410.1.37 by Michael Terry
lock memory from being paged to disk
99
        Gdk.threads_add_idle (ready_cb);
15 by Robert Ancell
Get some indicators in
100
    }
410.2.3 by Michael Terry
move all the user logging in logic into UserList
101
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
102
    public string? get_state (string key)
410.2.3 by Michael Terry
move all the user logging in logic into UserList
103
    {
104
        try
105
        {
106
            return state.get_value ("greeter", key);
107
        }
108
        catch (Error e)
109
        {
110
            return null;
111
        }
112
    }
113
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
114
    public void set_state (string key, string value)
410.2.3 by Michael Terry
move all the user logging in logic into UserList
115
    {
116
        state.set_value ("greeter", key, value);
117
        var data = state.to_data ();
118
        try
119
        {
410.1.101 by Michael Terry
merge from trunk
120
            FileUtils.set_contents (state_file, data);
410.2.3 by Michael Terry
move all the user logging in logic into UserList
121
        }
122
        catch (Error e)
123
        {
124
            debug ("Failed to write state: %s", e.message);
125
        }
333 by Robert Ancell
Improve the test users to cover a number of test cases
126
    }
239.4.1 by Michael Terry
add keyboard indicator
127
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
128
    public void push_list (GreeterList widget)
410.1.6 by Michael Terry
add ListStack and a back button to move between lists
129
    {
130
        main_window.push_list (widget);
131
    }
132
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
133
    public void pop_list ()
410.1.69 by Michael Terry
fix session chooser
134
    {
135
        main_window.pop_list ();
136
    }
137
250.1.6 by Michael Terry
merge look-and-feel branch
138
    public static void add_style_class (Gtk.Widget widget)
139
    {
140
        /* Add style context class lightdm-user-list */
141
        var ctx = widget.get_style_context ();
142
        ctx.add_class ("lightdm");
143
    }
144
364.1.1 by Michael Terry
instead of using variant name directly, lookup parent layout's short description
145
    public static LightDM.Layout? get_layout_by_name (string name)
239.4.1 by Michael Terry
add keyboard indicator
146
    {
244 by Robert Ancell
Add a keyboard indicator
147
        foreach (var layout in LightDM.get_layouts ())
239.4.1 by Michael Terry
add keyboard indicator
148
        {
149
            if (layout.name == name)
150
                return layout;
151
        }
152
        return null;
153
    }
154
615 by Michael Terry
Fix likely screen corruption after logging in
155
    public void start_session (string? session, Background bg)
410.2.3 by Michael Terry
move all the user logging in logic into UserList
156
    {
615 by Michael Terry
Fix likely screen corruption after logging in
157
        /* Paint our background onto the root window before we close our own window */
158
        var c = new Cairo.Context (background_surface);
159
        bg.draw_full (c, Background.DrawFlags.NONE);
160
        c = null;
410.2.3 by Michael Terry
move all the user logging in logic into UserList
161
        refresh_background (Gdk.Screen.get_default (), background_surface);
162
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
163
        if (test_mode)
410.2.3 by Michael Terry
move all the user logging in logic into UserList
164
        {
165
                debug ("Successfully logged in!  Quitting...");
166
                Gtk.main_quit ();
167
        }
168
        else
169
        {
593.1.1 by Michael Terry
have menubar clean up onboard before we start the session
170
            starting_session ();
410.2.3 by Michael Terry
move all the user logging in logic into UserList
171
            try
172
            {
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
173
                greeter.start_session_sync (session);
410.2.3 by Michael Terry
move all the user logging in logic into UserList
174
            }
175
            catch (Error e)
176
            {
177
                warning ("Failed to start session: %s", e.message);
178
            }
179
        }
180
    }
181
285.1.1 by Conor Curran
apply diwics patch for playing the new startup sound when it is chosen
182
    private bool ready_cb ()
183
    {
184
        debug ("starting system-ready sound");
285.1.2 by Conor Curran
use libcanberra vala bindings so as we can be explicit as to what theme to use
185
302 by Michael Terry
merge branch that adds system-ready sound
186
        /* Launch canberra */
187
        Canberra.Context.create (out canberra_context);
387.1.1 by Ritesh Khadgaray
fix lp949782 - No way to disable start-up sound
188
388 by Robert Ancell
Add play-ready-sound option to control making a sound when the greeter loads
189
        if (UGSettings.get_boolean (UGSettings.KEY_PLAY_READY_SOUND))
387.1.1 by Ritesh Khadgaray
fix lp949782 - No way to disable start-up sound
190
            canberra_context.play (0,
388 by Robert Ancell
Add play-ready-sound option to control making a sound when the greeter loads
191
                                   Canberra.PROP_CANBERRA_XDG_THEME_NAME,
192
                                   "ubuntu",
193
                                   Canberra.PROP_EVENT_ID,
194
                                   "system-ready");
302 by Michael Terry
merge branch that adds system-ready sound
195
285.1.1 by Conor Curran
apply diwics patch for playing the new startup sound when it is chosen
196
        return false;
197
    }
198
207 by Robert Ancell
Move/resize window when monitors changed, simplify background rendering more
199
    public void show ()
14 by Robert Ancell
Get some indicator stuff working
200
    {
170 by Robert Ancell
Don't show the main window until the background is loaded
201
        debug ("Showing main window");
212 by Robert Ancell
Use focus (), present () doesn't do it correctly
202
        main_window.show ();
203
        main_window.get_window ().focus (Gdk.CURRENT_TIME);
503 by Robert Ancell
Fix coding style errors
204
        main_window.set_keyboard_state ();
170 by Robert Ancell
Don't show the main window until the background is loaded
205
    }
206
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
207
    public bool is_authenticated ()
208
    {
209
        return greeter.is_authenticated;
210
    }
211
212
    public void authenticate (string? userid = null)
213
    {
214
        greeter.authenticate (userid);
215
    }
216
217
    public void authenticate_as_guest ()
218
    {
219
        greeter.authenticate_as_guest ();
220
    }
221
545.2.2 by Albert Astals
more code moved around
222
    public void authenticate_remote (string? session, string? userid)
223
    {
224
        UnityGreeter.singleton.greeter.authenticate_remote (session, userid);
225
    }
226
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
227
    public void cancel_authentication ()
228
    {
229
        greeter.cancel_authentication ();
230
    }
231
232
    public void respond (string response)
233
    {
234
        greeter.respond (response);
235
    }
236
237
    public string authentication_user ()
238
    {
239
        return greeter.authentication_user;
240
    }
241
242
    public string default_session_hint ()
243
    {
244
        return greeter.default_session_hint;
245
    }
246
247
    public string select_user_hint ()
248
    {
249
        return greeter.select_user_hint;
250
    }
251
252
    public bool show_manual_login_hint ()
253
    {
254
        return greeter.show_manual_login_hint;
255
    }
256
571.2.2 by Michael Terry
merge from trunk
257
    public bool show_remote_login_hint ()
258
    {
259
        return greeter.show_remote_login_hint;
260
    }
261
545.2.1 by Albert Astals
Just a lot of stuff, just commiting so i can checkout from the VM
262
    public bool hide_users_hint ()
263
    {
264
        return greeter.hide_users_hint;
265
    }
266
267
    public bool has_guest_account_hint ()
268
    {
269
        return greeter.has_guest_account_hint;
270
    }
271
272
    private Gdk.FilterReturn focus_upon_map (Gdk.XEvent gxevent, Gdk.Event event)
239.5.1 by Michael Terry
focus new windows as they appear
273
    {
430.2.1 by Michael Terry
fix focus-on-map logic
274
        var xevent = (X.Event*)gxevent;
239.5.2 by Michael Terry
fix spacing
275
        if (xevent.type == X.EventType.MapNotify)
276
        {
576.3.1 by Michael Terry
focus main_window when other windows close so that GTK will draw correct focus styles
277
            var display = Gdk.x11_lookup_xdisplay (xevent.xmap.display);
430.2.2 by Michael Terry
Make sure to not focus our onscreen keyboard
278
            var xwin = xevent.xmap.window;
279
            var win = Gdk.X11Window.foreign_new_for_display (display, xwin);
280
537 by Robert Ancell
Fix coding style
281
            /* Check to see if this window is our onboard window, since we don't want to focus it. */
430.2.2 by Michael Terry
Make sure to not focus our onscreen keyboard
282
            X.Window keyboard_xid = 0;
283
            if (main_window.menubar.keyboard_window != null)
284
                keyboard_xid = Gdk.X11Window.get_xid (main_window.menubar.keyboard_window.get_window ());
285
545 by Michael Terry
ignore notifications for focus purposes
286
            if (xwin != keyboard_xid && win.get_type_hint() != Gdk.WindowTypeHint.NOTIFICATION)
287
            {
430.2.2 by Michael Terry
Make sure to not focus our onscreen keyboard
288
                win.focus (Gdk.CURRENT_TIME);
521 by Michael Terry
fix onboard keyboard being hidden by main window again, due to changed focus handler
289
545 by Michael Terry
ignore notifications for focus purposes
290
                /* Make sure to keep keyboard above */
291
                if (main_window.menubar.keyboard_window != null)
292
                    main_window.menubar.keyboard_window.get_window ().raise ();
293
            }
239.5.1 by Michael Terry
focus new windows as they appear
294
        }
576.3.1 by Michael Terry
focus main_window when other windows close so that GTK will draw correct focus styles
295
        else if (xevent.type == X.EventType.UnmapNotify)
296
        {
297
            // Since we aren't keeping track of focus (for example, we don't
298
            // track the Z stack of windows) like a normal WM would, when we
299
            // decide here where to return focus after another window unmaps,
300
            // we don't have much to go on.  X will tell us if we should take
301
            // focus back.  (I could not find an obvious way to determine this,
302
            // but checking if the X input focus is RevertTo.None seems
303
            // reliable.)
304
305
            X.Window xwin;
306
            int revert_to;
307
            xevent.xunmap.display.get_input_focus (out xwin, out revert_to);
308
309
            if (revert_to == X.RevertTo.None)
310
            {
311
                main_window.get_window ().focus (Gdk.CURRENT_TIME);
312
313
                /* Make sure to keep keyboard above */
314
                if (main_window.menubar.keyboard_window != null)
315
                    main_window.menubar.keyboard_window.get_window ().raise ();
316
            }
317
        }
239.5.1 by Michael Terry
focus new windows as they appear
318
        return Gdk.FilterReturn.CONTINUE;
319
    }
320
321
    private void start_fake_wm ()
322
    {
323
        /* We want new windows (e.g. the shutdown dialog) to gain focus.
504 by Robert Ancell
Remove trailing whitespace
324
           We don't really need anything more than that (don't need alt-tab
239.5.1 by Michael Terry
focus new windows as they appear
325
           since any dialog should be "modal" or at least dealt with before
326
           continuing even if not actually marked as modal) */
327
        var root = Gdk.get_default_root_window ();
328
        root.set_events (root.get_events () | Gdk.EventMask.SUBSTRUCTURE_MASK);
430.2.1 by Michael Terry
fix focus-on-map logic
329
        root.add_filter (focus_upon_map);
239.5.1 by Michael Terry
focus new windows as they appear
330
    }
331
361.1.2 by Christopher James Halse Rogers
Move SetWindowBackgroundPixmap call to refresh_background.
332
    private static Cairo.XlibSurface? create_root_surface (Gdk.Screen screen)
71 by Robert Ancell
Set root background
333
    {
334
        var visual = screen.get_system_visual ();
335
361.1.1 by Christopher James Halse Rogers
Don't set up a new X connection for the root pixmap.
336
        unowned X.Display display = Gdk.X11Display.get_xdisplay (screen.get_display ());
337
71 by Robert Ancell
Set root background
338
        var pixmap = X.CreatePixmap (display,
339
                                     Gdk.X11Window.get_xid (screen.get_root_window ()),
555.1.1 by Albert Astals
Use instance members instead of static methods
340
                                     screen.get_width (),
341
                                     screen.get_height (),
71 by Robert Ancell
Set root background
342
                                     visual.get_depth ());
343
344
        /* Convert into a Cairo surface */
361.1.1 by Christopher James Halse Rogers
Don't set up a new X connection for the root pixmap.
345
        var surface = new Cairo.XlibSurface (display,
71 by Robert Ancell
Set root background
346
                                             pixmap,
347
                                             Gdk.X11Visual.get_xvisual (visual),
555.1.1 by Albert Astals
Use instance members instead of static methods
348
                                             screen.get_width (), screen.get_height ());
71 by Robert Ancell
Set root background
349
504 by Robert Ancell
Remove trailing whitespace
350
        return surface;
361.1.2 by Christopher James Halse Rogers
Move SetWindowBackgroundPixmap call to refresh_background.
351
    }
352
410.2.3 by Michael Terry
move all the user logging in logic into UserList
353
    private static void refresh_background (Gdk.Screen screen, Cairo.XlibSurface surface)
361.1.2 by Christopher James Halse Rogers
Move SetWindowBackgroundPixmap call to refresh_background.
354
    {
355
        Gdk.flush ();
356
357
        unowned X.Display display = Gdk.X11Display.get_xdisplay (screen.get_display ());
358
359
        /* Ensure Cairo has actually finished its drawing */
360
        surface.flush ();
71 by Robert Ancell
Set root background
361
        /* Use this pixmap for the background */
361.1.1 by Christopher James Halse Rogers
Don't set up a new X connection for the root pixmap.
362
        X.SetWindowBackgroundPixmap (display,
71 by Robert Ancell
Set root background
363
                                     Gdk.X11Window.get_xid (screen.get_root_window ()),
364
                                     surface.get_drawable ());
365
361.1.2 by Christopher James Halse Rogers
Move SetWindowBackgroundPixmap call to refresh_background.
366
        X.ClearWindow (display, Gdk.X11Window.get_xid (screen.get_root_window ()));
71 by Robert Ancell
Set root background
367
    }
368
160 by Robert Ancell
Add timing to log
369
    private static void log_cb (string? log_domain, LogLevelFlags log_level, string message)
370
    {
371
        string prefix;
372
        switch (log_level & LogLevelFlags.LEVEL_MASK)
373
        {
374
        case LogLevelFlags.LEVEL_ERROR:
375
            prefix = "ERROR:";
376
            break;
377
        case LogLevelFlags.LEVEL_CRITICAL:
378
            prefix = "CRITICAL:";
379
            break;
380
        case LogLevelFlags.LEVEL_WARNING:
381
            prefix = "WARNING:";
382
            break;
383
        case LogLevelFlags.LEVEL_MESSAGE:
384
            prefix = "MESSAGE:";
385
            break;
386
        case LogLevelFlags.LEVEL_INFO:
387
            prefix = "INFO:";
388
            break;
389
        case LogLevelFlags.LEVEL_DEBUG:
390
            prefix = "DEBUG:";
391
            break;
392
        default:
393
            prefix = "LOG:";
394
            break;
395
        }
396
161 by Robert Ancell
Print logs to stderr, not stdout
397
        stderr.printf ("[%+.2fs] %s %s\n", log_timer.elapsed (), prefix, message);
160 by Robert Ancell
Add timing to log
398
    }
399
14 by Robert Ancell
Get some indicator stuff working
400
    public static int main (string[] args)
401
    {
410.1.37 by Michael Terry
lock memory from being paged to disk
402
        /* Protect memory from being paged to disk, as we deal with passwords */
403
        Posix.mlockall (Posix.MCL_CURRENT | Posix.MCL_FUTURE);
404
85 by Robert Ancell
Disable the global menu
405
        /* Disable the stupid global menubar */
406
        Environment.unset_variable ("UBUNTU_MENUPROXY");
407
87.1.5 by Gabor Kelemen
Initialize i18n properly
408
        /* Initialize i18n */
192 by Robert Ancell
Fix translations not being used
409
        Intl.setlocale (LocaleCategory.ALL, "");
87.1.5 by Gabor Kelemen
Initialize i18n properly
410
        Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
411
        Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8");
412
        Intl.textdomain (Config.GETTEXT_PACKAGE);
413
294.2.1 by Luke Yelavich
Load the at-spi registry at greeter start. This is only needed for Orca, and
414
        /* Set up the accessibility stack, in case the user needs it for screen reading etc. */
415
        Environment.set_variable ("GTK_MODULES", "atk-bridge", false);
416
417
        Pid atspi_pid = 0;
418
419
        try
513 by Michael Terry
merge branch that adds nm-applet to session
420
        {
421
            string[] argv;
294.2.1 by Luke Yelavich
Load the at-spi registry at greeter start. This is only needed for Orca, and
422
513 by Michael Terry
merge branch that adds nm-applet to session
423
            Shell.parse_argv ("/usr/lib/at-spi2-core/at-spi-bus-launcher --launch-immediately", out argv);
424
            Process.spawn_async (null,
425
                                 argv,
426
                                 null,
427
                                 SpawnFlags.SEARCH_PATH,
428
                                 null,
429
                                 out atspi_pid);
430
        }
431
        catch (Error e)
432
        {
433
            warning ("Error starting the at-spi registry: %s", e.message);
434
        }
294.2.1 by Luke Yelavich
Load the at-spi registry at greeter start. This is only needed for Orca, and
435
14 by Robert Ancell
Get some indicator stuff working
436
        Gtk.init (ref args);
437
160 by Robert Ancell
Add timing to log
438
        log_timer = new Timer ();
162 by Robert Ancell
Go crazy with the debugging
439
        Log.set_default_handler (log_cb);
440
215 by Robert Ancell
Log more info on startup
441
        debug ("Starting unity-greeter %s UID=%d LANG=%s", Config.VERSION, (int) Posix.getuid (), Environment.get_variable ("LANG"));
160 by Robert Ancell
Add timing to log
442
70 by Robert Ancell
Fit to primary monitor
443
        /* Set the cursor to not be the crap default */
167 by Robert Ancell
Super paranoid logging
444
        debug ("Setting cursor");
38 by Robert Ancell
Connect up to LightDM
445
        Gdk.get_default_root_window ().set_cursor (new Gdk.Cursor (Gdk.CursorType.LEFT_PTR));
70 by Robert Ancell
Fit to primary monitor
446
545.2.9 by Albert Astals
Make test_mode non static too
447
        bool do_show_version = false;
448
        bool do_test_mode = false;
449
        OptionEntry versionOption = { "version", 'v', 0, OptionArg.NONE, ref do_show_version,
450
                /* Help string for command line --version flag */
451
                N_("Show release version"), null };
452
        OptionEntry testOption =  { "test-mode", 0, 0, OptionArg.NONE, ref do_test_mode,
453
                /* Help string for command line --test-mode flag */
454
                N_("Run in test mode"), null };
455
        OptionEntry nullOption = { null };
456
        OptionEntry[] options = { versionOption, testOption, nullOption };
457
167 by Robert Ancell
Super paranoid logging
458
        debug ("Loading command line options");
37 by Robert Ancell
Handle command line args
459
        var c = new OptionContext (/* Arguments and description for --help text */
460
                                   _("- Unity Greeter"));
461
        c.add_main_entries (options, Config.GETTEXT_PACKAGE);
462
        c.add_group (Gtk.get_option_group (true));
463
        try
464
        {
465
            c.parse (ref args);
466
        }
467
        catch (Error e)
468
        {
469
            stderr.printf ("%s\n", e.message);
470
            stderr.printf (/* Text printed out when an unknown command-line argument provided */
471
                           _("Run '%s --help' to see a full list of available command line options."), args[0]);
472
            stderr.printf ("\n");
473
            return Posix.EXIT_FAILURE;
474
        }
545.2.9 by Albert Astals
Make test_mode non static too
475
        if (do_show_version)
37 by Robert Ancell
Handle command line args
476
        {
477
            /* Note, not translated so can be easily parsed */
478
            stderr.printf ("unity-greeter %s\n", Config.VERSION);
479
            return Posix.EXIT_SUCCESS;
480
        }
481
545.2.9 by Albert Astals
Make test_mode non static too
482
        if (do_test_mode)
162 by Robert Ancell
Go crazy with the debugging
483
            debug ("Running in test mode");
484
67 by Robert Ancell
Add a config file and load Ambiance theme
485
        /* Set GTK+ settings */
167 by Robert Ancell
Super paranoid logging
486
        debug ("Setting GTK+ settings");
67 by Robert Ancell
Add a config file and load Ambiance theme
487
        var settings = Gtk.Settings.get_default ();
253.2.1 by Michael Terry
use gsettings instead of /etc/lightdm/unity-greeter.conf
488
        var value = UGSettings.get_string (UGSettings.KEY_THEME_NAME);
489
        if (value != "")
67 by Robert Ancell
Add a config file and load Ambiance theme
490
            settings.set ("gtk-theme-name", value, null);
253.2.1 by Michael Terry
use gsettings instead of /etc/lightdm/unity-greeter.conf
491
        value = UGSettings.get_string (UGSettings.KEY_ICON_THEME_NAME);
492
        if (value != "")
71.1.1 by Michael Terry
set icon theme
493
            settings.set ("gtk-icon-theme-name", value, null);
253.2.1 by Michael Terry
use gsettings instead of /etc/lightdm/unity-greeter.conf
494
        value = UGSettings.get_string (UGSettings.KEY_FONT_NAME);
495
        if (value != "")
67 by Robert Ancell
Add a config file and load Ambiance theme
496
            settings.set ("gtk-font-name", value, null);
253.2.1 by Michael Terry
use gsettings instead of /etc/lightdm/unity-greeter.conf
497
        var double_value = UGSettings.get_double (UGSettings.KEY_XFT_DPI);
498
        if (double_value != 0.0)
499
            settings.set ("gtk-xft-dpi", (int) (1024 * double_value), null);
500
        var boolean_value = UGSettings.get_boolean (UGSettings.KEY_XFT_ANTIALIAS);
501
        settings.set ("gtk-xft-antialias", boolean_value, null);
502
        value = UGSettings.get_string (UGSettings.KEY_XFT_HINTSTYLE);
503
        if (value != "")
67 by Robert Ancell
Add a config file and load Ambiance theme
504
            settings.set ("gtk-xft-hintstyle", value, null);
253.2.1 by Michael Terry
use gsettings instead of /etc/lightdm/unity-greeter.conf
505
        value = UGSettings.get_string (UGSettings.KEY_XFT_RGBA);
506
        if (value != "")
67 by Robert Ancell
Add a config file and load Ambiance theme
507
            settings.set ("gtk-xft-rgba", value, null);
508
167 by Robert Ancell
Super paranoid logging
509
        debug ("Creating Unity Greeter");
545.2.11 by Albert Astals
no need to change this either
510
        var greeter = new UnityGreeter (do_test_mode);
169 by Robert Ancell
Add more logging
511
512
        debug ("Showing greeter");
545.2.11 by Albert Astals
no need to change this either
513
        greeter.show ();
2 by Robert Ancell
Got some user selector stuff working
514
609 by Michael Terry
Start nm-applet after we set INDICATOR_GREETER_MODE so that it knows it's in the greeter and can adjust UI accordingly.
515
        if (!do_test_mode)
516
        {
517
            /* Make nm-applet hide items the user does not have permissions to interact with */
518
            Environment.set_variable ("NM_APPLET_HIDE_POLICY_ITEMS", "1", true);
519
520
            try
521
            {
522
                Process.spawn_command_line_async ("nm-applet");
523
            }
524
            catch (Error e)
525
            {
526
                warning ("Error starting nm-applet: %s", e.message);
527
            }
528
        }
529
167 by Robert Ancell
Super paranoid logging
530
        debug ("Starting main loop");
2 by Robert Ancell
Got some user selector stuff working
531
        Gtk.main ();
532
294.2.1 by Luke Yelavich
Load the at-spi registry at greeter start. This is only needed for Orca, and
533
        if (atspi_pid != 0)
534
        {
535
            Posix.kill (atspi_pid, Posix.SIGKILL);
536
            int status;
537
            Posix.waitpid (atspi_pid, out status, 0);
538
            atspi_pid = 0;
539
        }
540
1 by Robert Ancell
Stub project for unity-greeter
541
        return Posix.EXIT_SUCCESS;
542
    }
2 by Robert Ancell
Got some user selector stuff working
543
}