source: ldm/trunk/fuentes/gtkgreet/greeter.c @ 516

Last change on this file since 516 was 516, checked in by mabarracus, 5 years ago

Copy trusty code

File size: 30.6 KB
Line 
1/*
2 * LTSP Graphical GTK Greeter
3 * Copyright (2007) Oliver Grawert <ogra@ubuntu.com>, Canonical Ltd.
4
5 * Author: Oliver Grawert <ogra@canonical.com>
6
7 * 2007, Oliver Grawert <ogra@canonical.com>
8 *       Scott Balneaves <sbalneav@ltsp.org>
9 * 2008, Ryan Niebur <RyanRyan52@gmail.com>
10 *       Warren Togami <wtogami@redhat.com>
11 *       Stéphane Graber <stgraber@ubuntu.com>
12 *       Scott Balneaves <sbalneav@ltsp.org>
13 *       Vagrant Cascadian <vagrant@freegeek.org>
14 *       Oliver Grawert <ogra@canonical.com>
15 *       John Ellson <john.ellson@comcast.net>
16 *       Gideon Romm <gadi@ltsp.org>
17 *       Jigish Gohil <cyberorg@opensuse.org>
18 *       Wolfgang Schweer <schweer@cityweb.de>
19 *       Toshio Kuratomi
20 * 2012, Alkis Georgopoulos <alkisg@gmail.com>
21
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; version 2.
25
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 * GNU General Public License for more details.
30
31 * You should have received a copy of the GNU General Public License
32 * along with this program.  If not, you can find it on the World Wide
33 * Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
34 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
35 * MA 02110-1301, USA.
36
37 */
38
39#define _GNU_SOURCE
40
41#include <arpa/inet.h>
42#include <cairo.h>
43#include <config.h>
44#include <gdk/gdkkeysyms.h>
45#include <glib.h>
46#include <glib/gprintf.h>
47#include <gtk/gtk.h>
48#include <libintl.h>
49#include <locale.h>
50#include <net/if.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <sys/ioctl.h>
55#include <sys/utsname.h>
56#include <unistd.h>
57
58#include "../src/logging.h"
59#include "greeter.h"
60#include "prefs.h"
61#include "prefwin.h"
62#define _(text) gettext(text)
63
64#define TOP_BAR_HEIGHT 30
65#define BOTTOM_BAR_HEIGHT 30
66
67/*
68 *  Make sure that StatusMessages can accommodate many lines of text - auto scrollbars?
69 */
70GtkWidget *UserPrompt;          /* prompt area before the entry */
71GtkWidget *StatusMessages;      /* Status msg area below entry */
72GtkWidget *entry;               /* entry box */
73GtkWidget *choiceCombo;
74GtkListStore *choiceList;
75
76GtkWidget *GuestButton;
77GtkWidget *timeoutbox;
78gboolean timeout_enabled;
79
80GList *host_list = NULL;
81GIOChannel *g_stdout;           /* stdout io channel */
82gchar * ldm_theme_dir;
83
84int allowguest;
85gint login_timeout;
86gint timeout_left;
87
88gchar *
89ldm_theme_file(char * file)
90{
91    gchar * filename;
92    gchar * filename_default;
93    filename = g_strconcat("/", ldm_theme_dir, "/", file, NULL);
94    filename_default = g_strconcat("/", LDM_THEME_DIR, "ltsp", "/", file, NULL);
95    if (access(g_strconcat(filename, ".png", NULL), F_OK ) != -1)
96    {
97        filename = g_strconcat(filename, ".png", NULL);
98    }
99    else if (access(g_strconcat(filename, ".jpg", NULL), F_OK ) != -1)
100    {
101        filename = g_strconcat(filename, ".jpg", NULL);
102    }
103    else if (access(g_strconcat(filename_default, ".png", NULL), F_OK ) != -1)
104    {
105        filename = g_strconcat(filename_default, ".png", NULL);
106    }
107    else if (access(g_strconcat(filename_default, ".jpg", NULL), F_OK ) != -1)
108    {
109        filename = g_strconcat(filename_default, ".jpg", NULL);
110    }
111    return filename;
112}
113GdkPixmap* root_bg = 0;
114void load_root_background(const gchar* filename, gboolean scale, gboolean reload) {
115    if (root_bg != 0){
116        if (reload) {
117            g_object_unref(G_OBJECT (root_bg));
118            root_bg = 0;
119        } else {
120            return;
121        }
122    }
123
124    GtkWidget* image = gtk_image_new_from_file(filename);
125    g_object_ref(G_OBJECT (image));
126    GdkPixbuf* pixbuf = gtk_image_get_pixbuf(GTK_IMAGE (image));
127    double img_width = (double)gdk_pixbuf_get_width(pixbuf);
128    double img_height = (double)gdk_pixbuf_get_height(pixbuf);
129
130    GdkWindow* root = gdk_get_default_root_window();
131    gint width, height;
132    gdk_drawable_get_size(GDK_DRAWABLE (root), &width, &height);
133
134    // create pixmap
135    gdk_drawable_get_size(GDK_DRAWABLE (root), &width, &height);
136    root_bg = gdk_pixmap_new(GDK_DRAWABLE (root), width, height, -1);
137    g_object_ref(G_OBJECT (root_bg));
138
139    // paint pixmap onto bg
140    cairo_t* ctx = gdk_cairo_create(GDK_DRAWABLE (root_bg));
141    if (scale) {
142        cairo_scale(ctx, width/img_width, height/img_height);
143    }
144    gdk_cairo_set_source_pixbuf(ctx, pixbuf, 0, 0);
145    cairo_paint(ctx);
146    cairo_destroy(ctx);
147
148    //g_object_unref(G_OBJECT (bg));
149
150    g_object_unref(G_OBJECT (image));
151}
152
153void
154set_root_background() {
155    GdkWindow* root = gdk_get_default_root_window();
156
157
158    // bg needs to be set and painted, so it refreshes now and in the future
159    gdk_window_set_back_pixmap(GDK_WINDOW (root), GDK_PIXMAP (root_bg), 0);
160    gdk_draw_drawable(GDK_DRAWABLE (root),
161                      gdk_gc_new(GDK_DRAWABLE (root)),
162                      GDK_DRAWABLE (root_bg),
163                      0, 0,
164                      0, 0,
165                      -1, -1);
166}
167
168void
169draw_background(GtkWidget* widget, gpointer data) {
170    GdkWindow* window;
171    gint width, height, x, y;
172
173    window = gtk_widget_get_window(widget);
174    if (window == NULL) {
175        return;
176    }
177    gdk_drawable_get_size(GDK_DRAWABLE (window), &width, &height);
178    gdk_window_get_origin(GDK_WINDOW (window), &x, &y);
179    GdkPixmap* new_bg = gdk_pixmap_new(root_bg, width, height, -1);
180    g_object_ref(G_OBJECT (new_bg));
181    gdk_draw_drawable(GDK_DRAWABLE (new_bg),
182                    gdk_gc_new(GDK_DRAWABLE (new_bg)),
183                    GDK_DRAWABLE (root_bg),
184                    x, y,
185                    0, 0,
186                    width, height);
187    gdk_window_set_back_pixmap(GDK_WINDOW (window), new_bg, 0);
188
189    gtk_widget_queue_draw(GTK_WIDGET (widget));
190}
191
192static void
193destroy(GtkWidget * widget, gpointer data)
194{
195    gtk_main_quit();
196}
197
198static void
199spawn_command(GtkWidget * widget, const gchar *command)
200{
201    GError **error = NULL;
202    g_spawn_command_line_async(command, error);
203}
204
205gboolean
206update_time(GtkWidget * label)
207{
208    gchar *timestring = 0;
209    time_t timet;
210    struct tm *timePtr;
211
212    timet = time(NULL);
213    timePtr = localtime(&timet);
214
215    // use 12 hour clock format if LDM_12HOURCLOCK is set to true
216    if (ldm_getenv_bool("LDM_12HOURCLOCK")) {
217        timestring = g_strdup_printf("<b>%.2d:%.2d</b>",
218                                   (timePtr->tm_hour % 12) ? (timePtr->tm_hour % 12) : 12,
219                                   timePtr->tm_min);
220    }
221    else {
222        timestring = g_strdup_printf("<b>%.2d:%.2d</b>",
223                                   timePtr->tm_hour, timePtr->tm_min);
224    }
225
226    gtk_label_set_markup((GtkLabel *) label, timestring);
227
228    g_free(timestring);
229
230    return TRUE;
231}
232
233gboolean
234update_timeout(GtkWidget * label)
235{
236    gchar *string;
237    int entry_length;
238    entry_length = strlen(gtk_entry_get_text((GtkEntry *)entry));
239    if(entry_length == 0 && timeout_enabled) {
240        if (timeout_left > 1){
241            timeout_left--;
242        } else if (timeout_left == 1) {
243            g_io_channel_write_chars(g_stdout, "@GUEST@\n", -1, NULL, NULL);
244            g_io_channel_flush(g_stdout, NULL);
245            timeout_left = 0;
246            timeout_enabled = FALSE;
247        } else if (timeout_left == 0){
248            timeout_left = login_timeout;
249        }
250        string = g_strdup_printf(_("Automatic login in %d seconds"), timeout_left);
251        gtk_label_set_markup((GtkLabel *) label, string);
252        g_free(string);
253        gtk_widget_show(timeoutbox);
254    } else {
255        timeout_left = 0;
256        gtk_widget_hide(timeoutbox);
257    }
258    return TRUE;
259}
260
261void
262destroy_popup(GtkWidget * widget, GtkWidget * popup)
263{
264    gtk_widget_destroy(popup);
265    return;
266}
267
268gboolean
269xproperty_exists(gchar * property)
270{
271    GdkAtom *actual_property_type = NULL;
272    gint *actual_format = 0;
273    gint *actual_length = 0;
274    guchar **data = NULL;
275    gboolean result;
276
277    result=gdk_property_get(
278        gdk_get_default_root_window(),
279        gdk_atom_intern(property,TRUE),
280        GDK_NONE,
281        0,
282        512,
283        FALSE,
284        actual_property_type,
285        actual_format,
286        actual_length,
287        data);
288    return result;
289}
290
291gboolean
292handle_command(GIOChannel * io_input)
293{
294    GString *buf;
295
296    buf = g_string_new("");
297
298    g_io_channel_read_line_string(io_input, buf, NULL, NULL);
299    g_strstrip(buf->str);
300
301    log_entry("gtkgreet",7,"Got command: %s",buf->str);
302
303    if (!g_ascii_strncasecmp(buf->str, "msg", 3)) {
304        gchar **split_buf;
305        split_buf = g_strsplit(buf->str, " ", 2);
306        gtk_label_set_markup((GtkLabel *) StatusMessages, split_buf[1]);
307        g_strfreev(split_buf);
308    } else if (!g_ascii_strncasecmp(buf->str, "quit", 4)) {
309        if (!xproperty_exists("X11VNC_TICKER")) {
310            GdkCursor *cursor;
311            cursor = gdk_cursor_new(GDK_WATCH);
312            gdk_window_set_cursor(gdk_get_default_root_window(), cursor);
313        }
314        gtk_main_quit();
315    } else if (!g_ascii_strncasecmp(buf->str, "prompt", 6)) {
316        gchar **split_buf;
317        split_buf = g_strsplit(buf->str, " ", 2);
318        gtk_label_set_markup((GtkLabel *) UserPrompt, split_buf[1]);
319        g_strfreev(split_buf);
320    } else if (!g_ascii_strncasecmp(buf->str, "userid", 6)) {
321        timeout_enabled = login_timeout > 0;
322        if(timeout_enabled) {
323            gtk_widget_show(timeoutbox);
324        }
325        gtk_widget_show(entry);
326        gtk_widget_hide(choiceCombo);
327        gtk_entry_set_text(GTK_ENTRY(entry), "");
328        gtk_entry_set_visibility(GTK_ENTRY(entry), TRUE);
329        gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE);
330        gtk_widget_set_sensitive(GTK_WIDGET(GuestButton), TRUE);
331    } else if (!g_ascii_strncasecmp(buf->str, "passwd", 6)) {
332        timeout_enabled = FALSE;
333        timeout_left = 0;
334        gtk_widget_hide(timeoutbox);
335        gtk_entry_set_text(GTK_ENTRY(entry), "");
336        gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
337        gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE);
338        gtk_widget_set_sensitive(GTK_WIDGET(GuestButton), FALSE);
339    } else if (!g_ascii_strncasecmp(buf->str, "hostname", 8)) {
340        gchar *hoststr;
341        update_selected_host();
342        hoststr = g_strdup_printf("%s\n", host);
343        g_io_channel_write_chars(g_stdout, hoststr, -1, NULL, NULL);
344        g_io_channel_flush(g_stdout, NULL);
345        g_free(hoststr);
346        gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE);
347        gtk_widget_set_sensitive(GTK_WIDGET(GuestButton), FALSE);
348    } else if (!g_ascii_strncasecmp(buf->str, "language", 8)) {
349        gchar *langstr;
350        update_selected_lang();
351        langstr = g_strdup_printf("%s\n", language);
352        g_io_channel_write_chars(g_stdout, langstr, -1, NULL, NULL);
353        g_io_channel_flush(g_stdout, NULL);
354        g_free(langstr);
355    } else if (!g_ascii_strncasecmp(buf->str, "session", 7)) {
356        gchar *sessstr;
357        update_selected_sess();
358        sessstr = g_strdup_printf("%s\n", session);
359        g_io_channel_write_chars(g_stdout, sessstr, -1, NULL, NULL);
360        g_io_channel_flush(g_stdout, NULL);
361        g_free(sessstr);
362    } else if (!g_ascii_strncasecmp(buf->str, "choice", 6)) {
363        int i;
364        GtkTreeIter iter;
365
366        // strip newline char
367        buf->len--;
368        buf->str[buf->len] = '\0';
369
370        // choice;choice 1|choice 2|choice 3
371        gchar** choices = g_strsplit(buf->str+7, "|", -1);
372
373        // drop combo box to drop model
374        gtk_list_store_clear(choiceList);
375
376        for (i=0; i<g_strv_length(choices); ++i) {
377            gtk_list_store_append(GTK_LIST_STORE(choiceList), &iter);
378            gtk_list_store_set(GTK_LIST_STORE(choiceList), &iter, 0,
379                               choices[i], -1);
380        }
381
382        g_strfreev(choices);
383
384        gtk_widget_hide(entry);
385        gtk_widget_show(choiceCombo);
386    } else if (!g_ascii_strncasecmp(buf->str, "pref choice", 11)) {
387        int i;
388
389        // strip newline char
390        buf->len--;
391        buf->str[buf->len] = '\0';
392
393        // pref choice;key;title;menu;icon;choice 1|choice 2|choice 3
394        gchar** args = g_strsplit(buf->str, ";", 6);
395        gchar** choices = g_strsplit(args[5], "|", -1);
396
397        GreeterPref *pref = greeter_pref_new(g_strdup(args[1]));
398        pref->type = PREF_CHOICE;
399        pref->title = g_strdup(args[2]);
400        pref->menu = g_strdup(args[3]);
401        pref->icon = g_strdup(args[4]);
402
403        for (i=0; i<g_strv_length(choices); ++i) {
404            pref->choices = g_list_append(pref->choices, g_strdup(choices[i]));
405        }
406
407        g_strfreev(choices);
408        g_strfreev(args);
409    } else if (!g_ascii_strncasecmp(buf->str, "value", 5)) {
410        gchar *name = buf->str + 6;
411        gchar *valstr;
412
413        // strip newline char
414        buf->len--;
415        buf->str[buf->len] = '\0';
416
417        valstr = g_strdup_printf("%s\n", greeter_pref_get_value(name).str_val);
418        g_io_channel_write_chars(g_stdout, valstr, -1, NULL, NULL);
419        g_io_channel_flush(g_stdout, NULL);
420        g_free(valstr);
421    } else if (!g_ascii_strncasecmp(buf->str, "allowguest", 10)) {
422        gchar* valstr = buf->str + 11;
423        allowguest = g_ascii_strncasecmp(valstr, "false", 2);
424        if (!allowguest)
425            gtk_widget_hide(GTK_WIDGET(GuestButton));
426        else
427            gtk_widget_show(GTK_WIDGET(GuestButton));
428    }
429
430    g_string_free(buf, TRUE);
431    return TRUE;
432}
433
434char *
435get_sysname(void)
436{
437    struct utsname name;
438    char *node;
439
440    if (uname(&name) == 0) {
441        node = strdup(name.nodename);
442        return node;
443    }
444    return NULL;
445}
446
447static void
448handle_guestbutton(GtkButton * entry, GdkWindow * window)
449{
450    g_io_channel_write_chars(g_stdout, "@GUEST@\n", -1, NULL, NULL);
451    g_io_channel_flush(g_stdout, NULL);
452}
453
454static void
455handle_choice(GtkComboBox * combo, GdkWindow * window)
456{
457    gchar* selection;
458    gchar* entrystr;
459
460    selection = gtk_combo_box_get_active_text(GTK_COMBO_BOX(choiceCombo));
461    entrystr = g_strdup_printf("%s\n", selection);
462    g_io_channel_write_chars(g_stdout, entrystr, -1, NULL, NULL);
463    g_io_channel_flush(g_stdout, NULL);
464    g_free(entrystr);
465}
466
467static void
468handle_entry(GtkEntry * entry, GdkWindow * window)
469{
470    gchar *entrystr;
471
472    entrystr = g_strdup_printf("%s\n", gtk_entry_get_text(entry));
473    g_io_channel_write_chars(g_stdout, entrystr, -1, NULL, NULL);
474    g_io_channel_flush(g_stdout, NULL);
475    g_free(entrystr);
476    if(gtk_entry_get_visibility(GTK_ENTRY(entry)))
477        gtk_entry_set_text(entry, "");
478}
479
480static gboolean
481menu_append_pref(gpointer akey, gpointer avalue, gpointer adata) {
482    char* key = (char*)akey;
483    GreeterPref* pref = (GreeterPref*)avalue;
484    GtkWidget* menu = (GtkWidget*)adata;
485    GtkWidget *pref_item, *prefico;
486
487    pref_item =
488        gtk_image_menu_item_new_with_mnemonic(_(pref->menu));
489    prefico = gtk_image_new_from_file(ldm_theme_file(pref->icon));
490    gtk_image_menu_item_set_image((GtkImageMenuItem *) pref_item, prefico);
491
492    g_signal_connect(G_OBJECT(pref_item), "activate",
493                     G_CALLBACK(prefwin), key);
494    gtk_menu_shell_append(GTK_MENU_SHELL(menu), pref_item);
495
496    return FALSE;
497}
498
499static void
500popup_menu(GtkWidget * widget, GtkWindow * window)
501{
502    GtkWidget *menu, *lang_item, *sess_item, *host_item, *custom_item,
503        *quit_item, *reboot_item;
504    GtkWidget *sep, *langico, *sessico, *hostico, *customico, *rebootico,
505        *haltico;
506    gchar custom_env_var[20], *custom_mnemonic, *custom_command;
507    int i;
508
509    menu = gtk_menu_new();
510
511    if (getenv("LDM_FORCE_LANGUAGE") == NULL) {
512        lang_item =
513            gtk_image_menu_item_new_with_mnemonic(_("Select _Language ..."));
514        langico = gtk_image_new_from_file(ldm_theme_file("language"));
515        gtk_image_menu_item_set_image((GtkImageMenuItem *) lang_item, langico);
516        g_signal_connect_swapped(G_OBJECT(lang_item), "activate",
517                                 G_CALLBACK(langwin), window);
518        gtk_menu_shell_append(GTK_MENU_SHELL(menu), lang_item);
519    }
520
521    if (getenv("LDM_FORCE_SESSION") == NULL) {
522        sess_item =
523            gtk_image_menu_item_new_with_mnemonic(_("Select _Session ..."));
524        sessico = gtk_image_new_from_file(ldm_theme_file("session"));
525        gtk_image_menu_item_set_image((GtkImageMenuItem *) sess_item, sessico);
526        g_signal_connect_swapped(G_OBJECT(sess_item), "activate",
527                                 G_CALLBACK(sesswin), window);
528        gtk_menu_shell_append(GTK_MENU_SHELL(menu), sess_item);
529    }
530
531    if (ldminfo_size() > 1) {
532        host_item =
533            gtk_image_menu_item_new_with_mnemonic(_("Select _Host ..."));
534        hostico = gtk_image_new_from_file(ldm_theme_file("host"));
535        gtk_image_menu_item_set_image((GtkImageMenuItem *) host_item, hostico);
536        g_signal_connect_swapped(G_OBJECT(host_item), "activate",
537                                 G_CALLBACK(hostwin), window);
538        gtk_menu_shell_append(GTK_MENU_SHELL(menu), host_item);
539    }
540
541    for (i=0; i<=9; i++) {
542        g_sprintf(custom_env_var, "LDM_MENU_ITEM_%d", i);
543        custom_mnemonic=getenv(custom_env_var);
544        if (custom_mnemonic == NULL)
545            continue;
546        custom_item =
547            gtk_image_menu_item_new_with_mnemonic(custom_mnemonic);
548        g_sprintf(custom_env_var, "LDM_MENU_COMMAND_%d", i);
549        custom_command=getenv(custom_env_var);
550        if (custom_command == NULL) {
551            gtk_widget_destroy(custom_item);
552            continue;
553        }
554        customico = gtk_image_new_from_file(ldm_theme_file("backend"));
555        gtk_image_menu_item_set_image((GtkImageMenuItem *) custom_item,
556            customico);
557        g_signal_connect(G_OBJECT(custom_item), "activate",
558                         G_CALLBACK(spawn_command), g_strdup(custom_command));
559        gtk_menu_shell_append(GTK_MENU_SHELL(menu), custom_item);
560    }
561    greeter_pref_foreach(menu_append_pref, menu);
562
563    sep = gtk_separator_menu_item_new();
564    gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
565
566    reboot_item = gtk_image_menu_item_new_with_mnemonic(_("_Reboot"));
567    rebootico = gtk_image_new_from_file(ldm_theme_file("reboot"));
568    gtk_image_menu_item_set_image((GtkImageMenuItem *) reboot_item,
569                                  rebootico);
570    gtk_menu_shell_append(GTK_MENU_SHELL(menu), reboot_item);
571    g_signal_connect(G_OBJECT(reboot_item), "activate",
572                     G_CALLBACK(spawn_command), "/sbin/reboot");
573
574    quit_item = gtk_image_menu_item_new_with_mnemonic(_("Shut_down"));
575    haltico = gtk_image_new_from_file(ldm_theme_file("shutdown"));
576    gtk_image_menu_item_set_image((GtkImageMenuItem *) quit_item, haltico);
577    g_signal_connect(G_OBJECT(quit_item), "activate",
578                     G_CALLBACK(spawn_command), "/sbin/poweroff");
579    gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item);
580
581    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
582                   0, gtk_get_current_event_time());
583
584    gtk_widget_show_all(menu);
585    gtk_menu_reposition(GTK_MENU(menu));
586
587    return;
588}
589
590/*
591 * scopy()
592 *
593 * Copy a string.  Used to move data in and out of our ldminfo structure.
594 * Note: if the source string is null, or points to a valid string of '\0',
595 * both result in a dest string length of 0.
596 */
597
598char *
599scopy(char *dest, char *source)
600{
601    if (!source)
602        *dest = '\0';
603    else {
604        strncpy(dest, source, MAXSTRSZ - 1);
605        *(dest + MAXSTRSZ - 1) = '\0';     /* ensure null termination */
606    }
607
608    return dest;
609}
610
611/*
612 * Remap GDK_Tab to behaves as enter
613 * Inspired by gdm/gui/gdmlogin.c
614 */
615static gboolean
616key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer window)
617{
618    if ((event->keyval == GDK_Tab ||
619         event->keyval == GDK_KP_Tab) &&
620        (event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_SHIFT_MASK)) == 0) {
621            handle_entry(GTK_ENTRY(entry), window);
622            return TRUE;
623    }
624
625    return FALSE;
626}
627
628int
629main(int argc, char *argv[])
630{
631    gint lw;
632
633    GtkWidget *loginWindow, *prefBar;
634    GdkCursor *normcursor, *busycursor;
635    GtkWidget *syslabel, *timelabel;
636    GtkWidget *logo, *EntryBox;
637    GtkWidget *timeoutspacer1, *timeoutspacer2, *timeoutlabel;
638    GtkWidget *entryspacer1, *entryspacer2;
639    GtkWidget *optionico;
640    GtkWidget *optionbutton;
641    GdkWindow *root;
642    GdkPixbuf *pix;
643    gint width, height;
644    GIOChannel *g_stdin;
645    char * ldm_theme;
646
647#ifdef ENABLE_NLS
648    setlocale (LC_ALL, "");
649    bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
650    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
651    textdomain (GETTEXT_PACKAGE);
652#endif
653
654    /* Init log settings */
655    log_init(ldm_getenv_bool("LDM_SYSLOG"),ldm_getenv_int("LDM_LOGLEVEL",-1));
656
657    gtk_init(&argc, &argv);
658    ldm_theme = getenv("LDM_THEME");
659
660    if (ldm_theme)
661    {
662        if(*ldm_theme == '/')
663            ldm_theme_dir = g_strdup(ldm_theme);
664        else
665            ldm_theme_dir = g_strconcat(LDM_THEME_DIR, ldm_theme, NULL);
666    }
667    else
668    {
669        ldm_theme_dir = g_strconcat(LDM_THEME_DIR, "default", NULL);
670    }
671
672    allowguest = ldm_getenv_bool("LDM_GUESTLOGIN");
673    gtk_rc_add_default_file(ldm_theme_file("/greeter-gtkrc"));
674
675    /* Initialize information about hosts */
676    ldminfo_init(&host_list, getenv("LDM_SERVER"));
677
678    normcursor = gdk_cursor_new(GDK_LEFT_PTR);
679    busycursor = gdk_cursor_new(GDK_WATCH);
680
681
682    root = gdk_get_default_root_window();
683    gdk_window_set_cursor(root, busycursor);
684
685    greeter_pref_init();
686
687    /* Set the background */
688    load_root_background(ldm_theme_file("bg"), TRUE, FALSE);
689    set_root_background();
690
691    gdk_drawable_get_size(root, &width, &height);
692
693    /* Setup the time and system labels */
694    {
695        const char *hoststring = 0;
696        syslabel = gtk_label_new("");
697        timelabel = gtk_label_new("");
698#ifdef K12LINUX
699        hoststring =
700            g_strdup_printf("<b>%s</b> (%s)", get_sysname(), getenv("LDMINFO_IPADDR"));
701#else
702        hoststring =
703            g_strdup_printf("<b>%s</b> (%s) //", get_sysname(), getenv("LDMINFO_IPADDR"));
704#endif
705        gtk_label_set_markup((GtkLabel *) syslabel, hoststring);
706        update_time(timelabel);
707
708        g_timeout_add(30000, (GSourceFunc) update_time, timelabel);
709    }
710
711    /**** Create the login window ****/
712    loginWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
713
714    /* Create the options button */
715    {
716
717
718        optionbutton = gtk_button_new_with_mnemonic(_("_Preferences"));
719        optionico = gtk_image_new_from_file(ldm_theme_file("preferences"));
720        gtk_button_set_image((GtkButton *) optionbutton, optionico);
721
722        gtk_button_set_relief((GtkButton *) optionbutton, GTK_RELIEF_NONE);
723        gtk_button_set_focus_on_click((GtkButton *) optionbutton, FALSE);
724
725        g_signal_connect(G_OBJECT(optionbutton), "clicked",
726                         G_CALLBACK(popup_menu), loginWindow);
727    }
728
729    /**** Create the login window ****/
730    gtk_window_set_position(GTK_WINDOW(loginWindow), GTK_WIN_POS_CENTER_ALWAYS);
731    {
732        GtkWidget *guestbox, *guestspacer1, *guestspacer2, *vbox, *vbox2, *hbox;
733        GtkCellRenderer *renderer;
734
735        g_signal_connect(G_OBJECT(loginWindow), "destroy", G_CALLBACK(destroy),
736                         NULL);
737
738        gtk_widget_set_app_paintable(loginWindow, TRUE);
739        g_signal_connect(loginWindow, "configure-event",
740                        G_CALLBACK(draw_background), NULL);
741        //gtk_widget_set_size_request(loginWindow, width/2, height/2);
742        //gtk_widget_realize(loginWindow);
743        gtk_window_set_decorated(GTK_WINDOW (loginWindow), FALSE);
744
745        logo = gtk_image_new_from_file(ldm_theme_file("logo"));
746#ifdef K12LINUX
747        if(access(ldm_theme_file("bottom_right"), R_OK) == 0) {
748            bottom_right = gtk_image_new_from_file(ldm_theme_file("bottom_right"));
749            has_bottom_right_image=TRUE;
750        }
751        else
752            has_bottom_right_image=FALSE;
753#endif
754
755        pix = gtk_image_get_pixbuf((GtkImage *) logo);
756        lw = gdk_pixbuf_get_width(pix);
757
758
759        vbox = gtk_vbox_new(FALSE, 5);
760        vbox2 = gtk_vbox_new(FALSE, 0);
761        EntryBox = gtk_hbox_new(FALSE, 5);
762        hbox = gtk_hbox_new(FALSE, 0);
763
764        UserPrompt = gtk_label_new("");
765
766        if (lw < 180)
767            lw = 180;
768
769        gtk_misc_set_alignment((GtkMisc *) UserPrompt, 1, 0.5);
770        gtk_widget_set_size_request(UserPrompt, (lw / 2), 0);
771
772        StatusMessages = gtk_label_new("");
773        entry = gtk_entry_new();
774        gtk_entry_set_width_chars(GTK_ENTRY(entry), 12);
775        g_signal_connect(G_OBJECT(entry), "activate",
776                         G_CALLBACK(handle_entry), root);
777        // Remap tab on entry to behave as enter
778        g_signal_connect(G_OBJECT(entry), "key_press_event",
779                         G_CALLBACK(key_press_event), loginWindow);
780
781        choiceList = gtk_list_store_new(1, G_TYPE_STRING);
782        choiceCombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(choiceList));
783        renderer = gtk_cell_renderer_text_new();
784        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(choiceCombo),
785                                                   GTK_CELL_RENDERER(renderer),
786                                                   TRUE);
787        gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(choiceCombo),
788                                      GTK_CELL_RENDERER(renderer),
789                                      "text", 0);
790        g_signal_connect(G_OBJECT(choiceCombo), "changed",
791                         G_CALLBACK(handle_choice), root);
792
793        if (getenv("LDM_LOGIN_TIMEOUT") != NULL ) {
794            login_timeout = atoi(getenv("LDM_LOGIN_TIMEOUT"));
795        } else {
796            login_timeout = 0;
797        }
798        timeout_enabled = login_timeout > 0;
799        timeout_left = 0;
800        timeoutspacer1 = gtk_label_new("");
801        timeoutspacer2 = gtk_label_new("");
802        timeoutlabel = gtk_label_new("");
803        timeoutbox = gtk_hbox_new(FALSE, 0);
804        gtk_box_pack_start(GTK_BOX(vbox), timeoutbox, FALSE, FALSE, 0);
805        gtk_box_pack_start(GTK_BOX(timeoutbox), timeoutspacer1, TRUE, FALSE, 0);
806        gtk_box_pack_start(GTK_BOX(timeoutbox), timeoutlabel, FALSE, FALSE, 0);
807        gtk_box_pack_start(GTK_BOX(timeoutbox), timeoutspacer2, TRUE, FALSE, 0);
808        g_timeout_add(1000, (GSourceFunc) update_timeout, timeoutlabel);
809
810        guestspacer1 = gtk_label_new("");
811        guestspacer2 = gtk_label_new("");
812        GuestButton = gtk_button_new_with_label (_("Login as Guest"));
813        g_signal_connect(G_OBJECT(GuestButton), "clicked",
814            G_CALLBACK(handle_guestbutton), root);
815        gtk_button_set_focus_on_click((GtkButton *)GuestButton, FALSE);
816        guestbox = gtk_hbox_new(FALSE, 0);
817        gtk_box_pack_start(GTK_BOX(guestbox), guestspacer1, TRUE, FALSE, 0);
818        gtk_box_pack_start(GTK_BOX(guestbox), GuestButton, FALSE, FALSE, 0);
819        gtk_box_pack_start(GTK_BOX(guestbox), guestspacer2, TRUE, FALSE, 0);
820
821        entryspacer1 = gtk_label_new("");
822        entryspacer2 = gtk_label_new("");
823        gtk_box_pack_start(GTK_BOX(EntryBox), entryspacer1, TRUE, FALSE, 0);
824        gtk_box_pack_start(GTK_BOX(EntryBox), UserPrompt, FALSE, FALSE, 0);
825        gtk_box_pack_start(GTK_BOX(EntryBox), entry, FALSE, FALSE, 0);
826        gtk_box_pack_start(GTK_BOX(EntryBox), choiceCombo, FALSE, FALSE, 0);
827        gtk_box_pack_start(GTK_BOX(EntryBox), entryspacer2, TRUE, FALSE, 0);
828
829        gtk_box_pack_start(GTK_BOX(vbox), logo, FALSE, FALSE, 5);
830        gtk_box_pack_start(GTK_BOX(vbox), EntryBox, TRUE, FALSE, 0);
831        if(allowguest) gtk_box_pack_start(GTK_BOX(vbox), guestbox, FALSE, FALSE, 0);
832        gtk_box_pack_start(GTK_BOX(vbox), timeoutbox, FALSE, FALSE, 0);
833        gtk_box_pack_start(GTK_BOX(vbox), StatusMessages, TRUE, FALSE, 0);
834        gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, FALSE, 0);
835        gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
836
837        gtk_container_add(GTK_CONTAINER(loginWindow), vbox2);
838    }
839
840    /**** Create the preference bar ****/
841    prefBar = gtk_window_new(GTK_WINDOW_TOPLEVEL);
842    {
843        GtkWidget *BottomBarBox;
844
845        gtk_widget_set_app_paintable(GTK_WIDGET (prefBar), TRUE);
846        g_signal_connect(prefBar, "configure-event",
847                        G_CALLBACK(draw_background), NULL);
848        gtk_window_set_decorated(GTK_WINDOW (prefBar), FALSE);
849        gtk_widget_set_size_request(prefBar, width, BOTTOM_BAR_HEIGHT);
850
851        BottomBarBox = gtk_hbox_new(FALSE, 0);
852#ifndef K12LINUX
853        gtk_box_pack_start(GTK_BOX(BottomBarBox),
854                           GTK_WIDGET(optionbutton), FALSE, FALSE, 5);
855
856        gtk_box_pack_end(GTK_BOX(BottomBarBox),
857                         GTK_WIDGET(timelabel), FALSE, FALSE, 5);
858
859        gtk_box_pack_end(GTK_BOX(BottomBarBox),
860                         GTK_WIDGET(syslabel), FALSE, FALSE, 0);
861#else
862        optionbutton_box = gtk_vbox_new(FALSE, 0);
863        optionbutton_spacer = gtk_label_new("");
864        gtk_box_pack_start(GTK_BOX(optionbutton_box), GTK_WIDGET(optionbutton_spacer), TRUE, FALSE, 0);
865        gtk_box_pack_end(GTK_BOX(optionbutton_box), GTK_WIDGET(optionbutton), FALSE, FALSE, 5);
866        gtk_box_pack_start(GTK_BOX(BottomBarBox),
867                           GTK_WIDGET(optionbutton_box), FALSE, FALSE, 5);
868
869        if(has_bottom_right_image == TRUE) {
870            bottom_right_box = gtk_vbox_new(FALSE, 0);
871            bottom_right_spacer = gtk_label_new("");
872            gtk_box_pack_start(GTK_BOX(bottom_right_box), GTK_WIDGET(bottom_right_spacer), TRUE, FALSE, 0);
873            gtk_box_pack_end(GTK_BOX(bottom_right_box), GTK_WIDGET(bottom_right), FALSE, FALSE, 0);
874            gtk_box_pack_end(GTK_BOX(BottomBarBox),
875                             GTK_WIDGET(bottom_right_box), FALSE, FALSE, 0);
876        }
877#endif
878        gtk_container_add(GTK_CONTAINER (prefBar), BottomBarBox);
879    }
880
881#ifdef K12LINUX
882    /**** Create the TopBarBox ****/
883    topBar = gtk_window_new(GTK_WINDOW_TOPLEVEL);
884    {
885        GtkWidget *TopBarBox;
886
887        gtk_window_set_decorated(GTK_WINDOW (topBar), FALSE);
888        gtk_widget_set_size_request(topBar, width, TOP_BAR_HEIGHT);
889
890        TopBarBox = gtk_hbox_new(FALSE, 5);
891        gtk_box_pack_start(GTK_BOX(TopBarBox),
892                         GTK_WIDGET(syslabel), FALSE, FALSE, 5);
893        gtk_box_pack_end(GTK_BOX(TopBarBox),
894                         GTK_WIDGET(timelabel), FALSE, FALSE, 5);
895    }
896#endif
897    /* Show everything */
898
899    gtk_widget_show_all(loginWindow);
900    gtk_widget_show_all(prefBar);
901    gtk_window_move(GTK_WINDOW (prefBar), 0, height - BOTTOM_BAR_HEIGHT);
902#ifdef K12LINUX
903    gtk_widget_show_all(topBar);
904    gtk_window_move(GTK_WINDOW (topBar), 0, 0);
905#endif
906
907    gdk_window_set_cursor(root, normcursor);
908
909#ifdef K12LINUX
910    gtk_widget_grab_focus(GTK_WIDGET(entry));
911#endif
912
913    /*
914     * Start listening to stdin
915     */
916
917    g_stdin = g_io_channel_unix_new(STDIN_FILENO);      /* listen to stdin */
918    g_stdout = g_io_channel_unix_new(STDOUT_FILENO);
919    g_io_add_watch(g_stdin, G_IO_IN, (GIOFunc) handle_command, g_stdin);
920
921    gtk_main();
922
923    log_close();
924    return 0;
925}
Note: See TracBrowser for help on using the repository browser.